add rooms to mention chips
Needs handling for event links, plus clickability
This commit is contained in:
parent
9c488e8981
commit
a9993013f5
8 changed files with 87 additions and 23 deletions
|
|
@ -38,6 +38,7 @@ import "package:nexus/models/requests/set_membership.dart";
|
|||
import "package:nexus/models/requests/set_state.dart";
|
||||
import "package:nexus/models/requests/upload_media.dart";
|
||||
import "package:nexus/models/room.dart";
|
||||
import "package:nexus/models/room_summary.dart";
|
||||
import "package:nexus/models/spec_versions_response.dart";
|
||||
import "package:nexus/models/sync_data.dart";
|
||||
import "package:nexus/src/third_party/gomuks.g.dart";
|
||||
|
|
@ -213,10 +214,11 @@ class ClientController extends AsyncNotifier<int> {
|
|||
}
|
||||
}
|
||||
|
||||
Future<String> joinRoom(JoinRoomRequest request) async {
|
||||
final response = await _sendCommand("join_room", request.toJson());
|
||||
return response["room_id"];
|
||||
}
|
||||
Future<String> joinRoom(JoinRoomRequest request) async =>
|
||||
(await _sendCommand("join_room", request.toJson()))["room_id"];
|
||||
|
||||
Future<RoomSummary> getRoomSummary(JoinRoomRequest request) async =>
|
||||
.fromJson(await _sendCommand("get_room_summary", request.toJson()));
|
||||
|
||||
Future<void> leaveRoom(Room room) async {
|
||||
if (room.metadata == null) return;
|
||||
|
|
|
|||
18
lib/controllers/room_summary.dart
Normal file
18
lib/controllers/room_summary.dart
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import "package:hooks_riverpod/hooks_riverpod.dart";
|
||||
import "package:nexus/controllers/client.dart";
|
||||
import "package:nexus/models/requests/join_room.dart";
|
||||
import "package:nexus/models/room_summary.dart";
|
||||
|
||||
class RoomSummaryController extends AsyncNotifier<RoomSummary> {
|
||||
final JoinRoomRequest request;
|
||||
RoomSummaryController(this.request);
|
||||
|
||||
@override
|
||||
Future<RoomSummary> build() =>
|
||||
ref.watch(ClientController.provider.notifier).getRoomSummary(request);
|
||||
|
||||
static final provider = AsyncNotifierProvider.family
|
||||
.autoDispose<RoomSummaryController, RoomSummary, JoinRoomRequest>(
|
||||
RoomSummaryController.new,
|
||||
);
|
||||
}
|
||||
|
|
@ -9,14 +9,14 @@ class SettingsController extends AsyncNotifier<Settings> {
|
|||
final file = await ref.watch(SettingsFileController.provider.future);
|
||||
|
||||
try {
|
||||
return Settings.fromJson(json.decode(await file.readAsString()));
|
||||
return .fromJson(json.decode(await file.readAsString()));
|
||||
} catch (_) {
|
||||
return Settings();
|
||||
return .new();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> set(Settings settings) async {
|
||||
state = AsyncData(settings);
|
||||
state = .data(settings);
|
||||
final file = await ref.watch(SettingsFileController.provider.future);
|
||||
await file.writeAsString(json.encode(settings.toJson()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ part "join_room.g.dart";
|
|||
abstract class JoinRoomRequest with _$JoinRoomRequest {
|
||||
const factory JoinRoomRequest({
|
||||
required String roomIdOrAlias,
|
||||
required IList<String> via,
|
||||
@Default(IList.empty()) IList<String> via,
|
||||
}) = _JoinRoomRequest;
|
||||
|
||||
factory JoinRoomRequest.fromJson(Map<String, Object?> json) =>
|
||||
|
|
|
|||
23
lib/models/room_summary.dart
Normal file
23
lib/models/room_summary.dart
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import "package:freezed_annotation/freezed_annotation.dart";
|
||||
import "package:nexus/models/content/create.dart";
|
||||
import "package:nexus/models/join_rule.dart";
|
||||
part "room_summary.freezed.dart";
|
||||
part "room_summary.g.dart";
|
||||
|
||||
@freezed
|
||||
abstract class RoomSummary with _$RoomSummary {
|
||||
const factory RoomSummary({
|
||||
required String roomId,
|
||||
@JsonKey(name: "num_joined_members") required int joinedMembers,
|
||||
JoinRule? joinRule,
|
||||
String? name,
|
||||
Uri? avatarUrl,
|
||||
String? canonicalAlias,
|
||||
String? topic,
|
||||
String? roomVersion,
|
||||
@JsonKey(unknownEnumValue: RoomType.room) RoomType? roomType,
|
||||
}) = _RoomSummary;
|
||||
|
||||
factory RoomSummary.fromJson(Map<String, Object?> json) =>
|
||||
_$RoomSummaryFromJson(json);
|
||||
}
|
||||
|
|
@ -1,8 +1,11 @@
|
|||
import "package:flutter/material.dart";
|
||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||
import "package:nexus/controllers/room_summary.dart";
|
||||
import "package:nexus/controllers/user.dart";
|
||||
import "package:nexus/helpers/extensions/link_to_mention.dart";
|
||||
import "package:nexus/helpers/extensions/show_user_popover.dart";
|
||||
import "package:nexus/models/content/membership.dart";
|
||||
import "package:nexus/models/room_summary.dart";
|
||||
|
||||
class MentionChip extends ConsumerWidget {
|
||||
final String? roomId;
|
||||
|
|
@ -12,29 +15,48 @@ class MentionChip extends ConsumerWidget {
|
|||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final mention = content.mention;
|
||||
final membership = mention?.startsWith("@") == true
|
||||
? ref
|
||||
.watch(
|
||||
UserController.provider(.new(roomId: roomId, userId: mention!)),
|
||||
)
|
||||
.whenOrNull(data: (data) => data)
|
||||
: null;
|
||||
final data = switch (mention?.characters.firstOrNull) {
|
||||
"@" =>
|
||||
ref
|
||||
.watch(
|
||||
UserController.provider(.new(roomId: roomId, userId: mention!)),
|
||||
)
|
||||
.whenOrNull(data: (data) => data),
|
||||
|
||||
"#" || "!" =>
|
||||
ref
|
||||
.watch(
|
||||
RoomSummaryController.provider(.new(roomIdOrAlias: mention!)),
|
||||
)
|
||||
.whenOrNull(data: (data) => data),
|
||||
|
||||
_ => null,
|
||||
};
|
||||
|
||||
return mention == null
|
||||
? SizedBox.shrink()
|
||||
: InkWell(
|
||||
onTap: () {
|
||||
if (membership != null) {
|
||||
if (data case MembershipContent membership) {
|
||||
context.showUserPopover(membership, mention, roomId: roomId);
|
||||
} else if (data case RoomSummary summary) {
|
||||
// TODO: Handle summary
|
||||
}
|
||||
},
|
||||
child: IgnorePointer(
|
||||
child: Chip(
|
||||
label: Text(
|
||||
(membership?.displayName == null
|
||||
? null
|
||||
: "@${membership!.displayName}") ??
|
||||
mention,
|
||||
switch (data) {
|
||||
RoomSummary summary =>
|
||||
(summary.name == null ? null : "#${summary.name}") ??
|
||||
summary.canonicalAlias ??
|
||||
summary.roomId,
|
||||
MembershipContent membership =>
|
||||
membership.displayName == null
|
||||
? mention
|
||||
: "@${membership.displayName}",
|
||||
_ => mention,
|
||||
},
|
||||
style: .new(
|
||||
fontWeight: .bold,
|
||||
color: Theme.of(context).colorScheme.onPrimary,
|
||||
|
|
|
|||
|
|
@ -311,7 +311,7 @@ class RoomChat extends HookConsumerWidget {
|
|||
await Clipboard.setData(
|
||||
ClipboardData(
|
||||
text:
|
||||
"matrix:roomid/${room.metadata?.id.substring(1)}/e/${event.eventId}$vias)",
|
||||
"matrix:roomid/${room.metadata?.id.substring(1)}/e/${event.eventId}$vias",
|
||||
),
|
||||
);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -35,8 +35,7 @@ class RoomMenu extends ConsumerWidget {
|
|||
|
||||
await Clipboard.setData(
|
||||
.new(
|
||||
text:
|
||||
"matrix:roomid/${room!.metadata?.id.substring(1)}$vias)",
|
||||
text: "matrix:roomid/${room!.metadata?.id.substring(1)}$vias",
|
||||
),
|
||||
);
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in a new issue