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/set_state.dart";
|
||||||
import "package:nexus/models/requests/upload_media.dart";
|
import "package:nexus/models/requests/upload_media.dart";
|
||||||
import "package:nexus/models/room.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/spec_versions_response.dart";
|
||||||
import "package:nexus/models/sync_data.dart";
|
import "package:nexus/models/sync_data.dart";
|
||||||
import "package:nexus/src/third_party/gomuks.g.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 {
|
Future<String> joinRoom(JoinRoomRequest request) async =>
|
||||||
final response = await _sendCommand("join_room", request.toJson());
|
(await _sendCommand("join_room", request.toJson()))["room_id"];
|
||||||
return response["room_id"];
|
|
||||||
}
|
Future<RoomSummary> getRoomSummary(JoinRoomRequest request) async =>
|
||||||
|
.fromJson(await _sendCommand("get_room_summary", request.toJson()));
|
||||||
|
|
||||||
Future<void> leaveRoom(Room room) async {
|
Future<void> leaveRoom(Room room) async {
|
||||||
if (room.metadata == null) return;
|
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);
|
final file = await ref.watch(SettingsFileController.provider.future);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return Settings.fromJson(json.decode(await file.readAsString()));
|
return .fromJson(json.decode(await file.readAsString()));
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
return Settings();
|
return .new();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> set(Settings settings) async {
|
Future<void> set(Settings settings) async {
|
||||||
state = AsyncData(settings);
|
state = .data(settings);
|
||||||
final file = await ref.watch(SettingsFileController.provider.future);
|
final file = await ref.watch(SettingsFileController.provider.future);
|
||||||
await file.writeAsString(json.encode(settings.toJson()));
|
await file.writeAsString(json.encode(settings.toJson()));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ part "join_room.g.dart";
|
||||||
abstract class JoinRoomRequest with _$JoinRoomRequest {
|
abstract class JoinRoomRequest with _$JoinRoomRequest {
|
||||||
const factory JoinRoomRequest({
|
const factory JoinRoomRequest({
|
||||||
required String roomIdOrAlias,
|
required String roomIdOrAlias,
|
||||||
required IList<String> via,
|
@Default(IList.empty()) IList<String> via,
|
||||||
}) = _JoinRoomRequest;
|
}) = _JoinRoomRequest;
|
||||||
|
|
||||||
factory JoinRoomRequest.fromJson(Map<String, Object?> json) =>
|
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/material.dart";
|
||||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||||
|
import "package:nexus/controllers/room_summary.dart";
|
||||||
import "package:nexus/controllers/user.dart";
|
import "package:nexus/controllers/user.dart";
|
||||||
import "package:nexus/helpers/extensions/link_to_mention.dart";
|
import "package:nexus/helpers/extensions/link_to_mention.dart";
|
||||||
import "package:nexus/helpers/extensions/show_user_popover.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 {
|
class MentionChip extends ConsumerWidget {
|
||||||
final String? roomId;
|
final String? roomId;
|
||||||
|
|
@ -12,29 +15,48 @@ class MentionChip extends ConsumerWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final mention = content.mention;
|
final mention = content.mention;
|
||||||
final membership = mention?.startsWith("@") == true
|
final data = switch (mention?.characters.firstOrNull) {
|
||||||
? ref
|
"@" =>
|
||||||
.watch(
|
ref
|
||||||
UserController.provider(.new(roomId: roomId, userId: mention!)),
|
.watch(
|
||||||
)
|
UserController.provider(.new(roomId: roomId, userId: mention!)),
|
||||||
.whenOrNull(data: (data) => data)
|
)
|
||||||
: null;
|
.whenOrNull(data: (data) => data),
|
||||||
|
|
||||||
|
"#" || "!" =>
|
||||||
|
ref
|
||||||
|
.watch(
|
||||||
|
RoomSummaryController.provider(.new(roomIdOrAlias: mention!)),
|
||||||
|
)
|
||||||
|
.whenOrNull(data: (data) => data),
|
||||||
|
|
||||||
|
_ => null,
|
||||||
|
};
|
||||||
|
|
||||||
return mention == null
|
return mention == null
|
||||||
? SizedBox.shrink()
|
? SizedBox.shrink()
|
||||||
: InkWell(
|
: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (membership != null) {
|
if (data case MembershipContent membership) {
|
||||||
context.showUserPopover(membership, mention, roomId: roomId);
|
context.showUserPopover(membership, mention, roomId: roomId);
|
||||||
|
} else if (data case RoomSummary summary) {
|
||||||
|
// TODO: Handle summary
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: IgnorePointer(
|
child: IgnorePointer(
|
||||||
child: Chip(
|
child: Chip(
|
||||||
label: Text(
|
label: Text(
|
||||||
(membership?.displayName == null
|
switch (data) {
|
||||||
? null
|
RoomSummary summary =>
|
||||||
: "@${membership!.displayName}") ??
|
(summary.name == null ? null : "#${summary.name}") ??
|
||||||
mention,
|
summary.canonicalAlias ??
|
||||||
|
summary.roomId,
|
||||||
|
MembershipContent membership =>
|
||||||
|
membership.displayName == null
|
||||||
|
? mention
|
||||||
|
: "@${membership.displayName}",
|
||||||
|
_ => mention,
|
||||||
|
},
|
||||||
style: .new(
|
style: .new(
|
||||||
fontWeight: .bold,
|
fontWeight: .bold,
|
||||||
color: Theme.of(context).colorScheme.onPrimary,
|
color: Theme.of(context).colorScheme.onPrimary,
|
||||||
|
|
|
||||||
|
|
@ -311,7 +311,7 @@ class RoomChat extends HookConsumerWidget {
|
||||||
await Clipboard.setData(
|
await Clipboard.setData(
|
||||||
ClipboardData(
|
ClipboardData(
|
||||||
text:
|
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(
|
await Clipboard.setData(
|
||||||
.new(
|
.new(
|
||||||
text:
|
text: "matrix:roomid/${room!.metadata?.id.substring(1)}$vias",
|
||||||
"matrix:roomid/${room!.metadata?.id.substring(1)}$vias)",
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue