parent
5ee3449f02
commit
c8e1aef74b
5 changed files with 115 additions and 4 deletions
|
|
@ -371,6 +371,12 @@ class ClientController extends AsyncNotifier<int> {
|
|||
Future<void> exchangeToken(OAuthExchangeTokenRequest request) async =>
|
||||
await _sendCommand("oauth_exchange_token", request.toJson());
|
||||
|
||||
Future<IList<String>> getMutualRooms(String userId) async => IList(
|
||||
((await _sendCommand("get_mutual_rooms", {"user_id": userId}))["joined"]
|
||||
as List?)
|
||||
?.cast<String>(),
|
||||
);
|
||||
|
||||
Future<SpecVersionsResponse> getSpecVersions() async =>
|
||||
.fromJson(await _sendCommand("get_versions"));
|
||||
|
||||
|
|
|
|||
15
lib/controllers/mutual_rooms.dart
Normal file
15
lib/controllers/mutual_rooms.dart
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import "package:fast_immutable_collections/fast_immutable_collections.dart";
|
||||
import "package:hooks_riverpod/hooks_riverpod.dart";
|
||||
import "package:nexus/controllers/client.dart";
|
||||
|
||||
class MutualRoomsController(final String userId)
|
||||
extends AsyncNotifier<IList<String>> {
|
||||
@override
|
||||
Future<IList<String>> build() =>
|
||||
ref.read(ClientController.provider.notifier).getMutualRooms(userId);
|
||||
|
||||
static final provider = AsyncNotifierProvider.family
|
||||
.autoDispose<MutualRoomsController, IList<String>, String>(
|
||||
MutualRoomsController.new,
|
||||
);
|
||||
}
|
||||
72
lib/widgets/mutual_rooms_sheet.dart
Normal file
72
lib/widgets/mutual_rooms_sheet.dart
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
import "package:fast_immutable_collections/fast_immutable_collections.dart";
|
||||
import "package:hooks_riverpod/hooks_riverpod.dart";
|
||||
import "package:material_ui/material_ui.dart";
|
||||
import "package:nexus/controllers/mutual_rooms.dart";
|
||||
import "package:nexus/controllers/rooms.dart";
|
||||
import "package:nexus/controllers/sidebar_page.dart";
|
||||
import "package:nexus/helpers/extensions/better_when.dart";
|
||||
import "package:nexus/helpers/extensions/focus_room.dart";
|
||||
import "package:nexus/widgets/avatar_or_hash.dart";
|
||||
import "package:nexus/widgets/sheet_layout.dart";
|
||||
|
||||
/// The rooms the user shares with [userId].
|
||||
class const MutualRoomsSheet(final String userId, {super.key})
|
||||
extends ConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) => SheetLayout(
|
||||
title: Text("Mutual Rooms"),
|
||||
actions: [
|
||||
TextButton(onPressed: Navigator.of(context).pop, child: Text("Close")),
|
||||
],
|
||||
children: [
|
||||
ref
|
||||
.watch(MutualRoomsController.provider(userId))
|
||||
.betterWhen(
|
||||
data: (roomIds) {
|
||||
final rooms = ref.watch(
|
||||
RoomsController.provider.select(
|
||||
(allRooms) => roomIds
|
||||
.map((roomId) => allRooms[roomId]?.metadata)
|
||||
.nonNulls
|
||||
.toIList(),
|
||||
),
|
||||
);
|
||||
|
||||
return rooms.isEmpty
|
||||
? Text("No mutual rooms")
|
||||
: Column(
|
||||
children: rooms
|
||||
.map(
|
||||
(room) => ListTile(
|
||||
leading: AvatarOrHash(
|
||||
room.avatar,
|
||||
room.name ?? "Unnamed Room",
|
||||
fallback: Icon(Icons.numbers),
|
||||
),
|
||||
title: Text(
|
||||
room.name ?? "Unnamed Room",
|
||||
overflow: .ellipsis,
|
||||
),
|
||||
onTap: () async {
|
||||
final container = ProviderScope.containerOf(
|
||||
context,
|
||||
);
|
||||
// Closes the user popover under this too
|
||||
Navigator.of(context)
|
||||
.popUntil((route) => route.isFirst);
|
||||
await container.focusRoom(room.id);
|
||||
container
|
||||
.read(
|
||||
SidebarPageController.provider.notifier,
|
||||
)
|
||||
.set(.rooms);
|
||||
},
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
@ -38,7 +38,6 @@ class const ReadReceiptsSheet(
|
|||
final name = member?.displayName ?? receipt.userId.localpart;
|
||||
|
||||
return ListTile(
|
||||
contentPadding: .zero,
|
||||
leading: AvatarOrHash(member?.avatarUrl, name, dimension: 40),
|
||||
title: Text(name, overflow: .ellipsis),
|
||||
subtitle: Text(receipt.userId, overflow: .ellipsis),
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import "package:intl/intl.dart";
|
|||
import "package:m3e_buttons/m3e_buttons.dart";
|
||||
import "package:nexus/controllers/client.dart";
|
||||
import "package:nexus/controllers/client_state.dart";
|
||||
import "package:nexus/controllers/mutual_rooms.dart";
|
||||
import "package:nexus/controllers/power_level.dart";
|
||||
import "package:nexus/controllers/profile.dart";
|
||||
import "package:nexus/controllers/rooms.dart";
|
||||
|
|
@ -18,6 +19,7 @@ import "package:nexus/helpers/extensions/show_adaptive_sheet.dart";
|
|||
import "package:nexus/helpers/extensions/get_localpart.dart";
|
||||
import "package:nexus/widgets/error_dialog.dart";
|
||||
import "package:nexus/widgets/loading.dart";
|
||||
import "package:nexus/widgets/mutual_rooms_sheet.dart";
|
||||
import "package:nexus/models/membership_action.dart";
|
||||
import "package:nexus/widgets/avatar_or_hash.dart";
|
||||
import "package:nexus/main.dart";
|
||||
|
|
@ -141,9 +143,6 @@ final class const UserBottomSheet(
|
|||
loading: () => Text(""),
|
||||
data: (profileResponse) => Column(
|
||||
children: [
|
||||
if (profileResponse.profile.timezone == null &&
|
||||
profileResponse.profile.pronouns.isEmpty)
|
||||
Text(""),
|
||||
Wrap(
|
||||
crossAxisAlignment: .center,
|
||||
alignment: .center,
|
||||
|
|
@ -195,6 +194,26 @@ final class const UserBottomSheet(
|
|||
),
|
||||
),
|
||||
|
||||
if (userId != ref.watch(ClientStateController.provider)?.userId)
|
||||
switch (ref.watch(MutualRoomsController.provider(userId))) {
|
||||
AsyncData(value: final roomIds) => switch (ref.watch(
|
||||
RoomsController.provider.select(
|
||||
(rooms) => roomIds.where(rooms.containsKey).length,
|
||||
),
|
||||
)) {
|
||||
0 => SizedBox.shrink(),
|
||||
final count => TextButton(
|
||||
onPressed: () => context.showAdaptiveSheet(
|
||||
(_) => MutualRoomsSheet(userId),
|
||||
),
|
||||
child: Text(
|
||||
"$count mutual ${Intl.plural(count, one: "room", other: "rooms")}",
|
||||
),
|
||||
),
|
||||
},
|
||||
_ => SizedBox.shrink(),
|
||||
},
|
||||
|
||||
SizedBox(height: 8),
|
||||
if (userId !=
|
||||
ref.watch(ClientStateController.provider)?.userId) ...[
|
||||
|
|
|
|||
Loading…
Reference in a new issue