diff --git a/lib/controllers/client.dart b/lib/controllers/client.dart index db33340..766fe1e 100644 --- a/lib/controllers/client.dart +++ b/lib/controllers/client.dart @@ -482,6 +482,18 @@ class ClientController(final String? accountId) extends AsyncNotifier { Future deleteAlias(String alias) => _sendCommand("delete_alias", {"alias": alias}); + Future getRoomPublished(String roomId) async => + (await _sendCommand("get_room_visibility", { + "room_id": roomId, + }))["visibility"] == + "public"; + + Future setRoomPublished(String roomId, bool published) => + _sendCommand("publish_room", { + "room_id": roomId, + "visibility": published ? "public" : "private", + }); + /// The room [alias] points to, or null if it doesn't exist. Future resolveAlias(String alias) async { try { diff --git a/lib/controllers/room_published.dart b/lib/controllers/room_published.dart new file mode 100644 index 0000000..b560575 --- /dev/null +++ b/lib/controllers/room_published.dart @@ -0,0 +1,21 @@ +import "package:hooks_riverpod/hooks_riverpod.dart"; +import "package:nexus/controllers/client.dart"; + +/// Whether a room is published to the user's server's room directory. +class RoomPublishedController(final String roomId) extends AsyncNotifier { + @override + Future build() => + ref.read(ClientController.provider.notifier).getRoomPublished(roomId); + + Future set(bool published) async { + await ref + .read(ClientController.provider.notifier) + .setRoomPublished(roomId, published); + ref.invalidateSelf(); + } + + static final provider = AsyncNotifierProvider.family + .autoDispose( + RoomPublishedController.new, + ); +} diff --git a/lib/controllers/room_settings_sections.dart b/lib/controllers/room_settings_sections.dart index 817f0ee..7136e05 100644 --- a/lib/controllers/room_settings_sections.dart +++ b/lib/controllers/room_settings_sections.dart @@ -10,6 +10,7 @@ import "package:nexus/controllers/power_level.dart"; import "package:nexus/controllers/power_levels_saving.dart"; import "package:nexus/controllers/room_image_packs.dart"; import "package:nexus/controllers/room_power_levels.dart"; +import "package:nexus/controllers/room_published.dart"; import "package:nexus/controllers/rooms.dart"; import "package:nexus/controllers/space_edges.dart"; import "package:nexus/helpers/extensions/join_rule_name.dart"; @@ -555,6 +556,39 @@ class RoomSettingsSectionsController(final String roomId) : null, ), ), + .new( + title: "Publish to Room Directory", + description: "List the room in your homeserver's directory.", + icon: Icons.travel_explore, + builder: (title, description, icon) => HookConsumer( + builder: (context, ref, _) { + final saving = Saving.use(); + final published = ref.watch( + RoomPublishedController.provider(roomId), + ); + + return SwitchListTile( + secondary: Icon(icon), + title: Text(title), + subtitle: Text(description), + value: published.value ?? false, + onChanged: + canSetAliases && published.hasValue && !saving.active + ? (value) => saving.run( + () => ref + .read( + RoomPublishedController.provider( + roomId, + ).notifier, + ) + .set(value) + .onError(showError), + ) + : null, + ); + }, + ), + ), ]), ), .new(