diff --git a/lib/controllers/settings_sections.dart b/lib/controllers/settings_sections.dart index 85958e3..57b15e5 100644 --- a/lib/controllers/settings_sections.dart +++ b/lib/controllers/settings_sections.dart @@ -10,6 +10,7 @@ import "package:nexus/controllers/client.dart"; import "package:nexus/controllers/client_state.dart"; import "package:nexus/controllers/settings.dart"; import "package:nexus/controllers/unified_push.dart"; +import "package:nexus/controllers/spec_versions.dart"; import "package:nexus/models/account_data.dart"; import "package:nexus/models/settings_category.dart"; import "package:nexus/main.dart"; @@ -20,9 +21,6 @@ class SettingsSectionsController @override Future>> build() async { final settings = await ref.watch(SettingsController.provider.future); - final specVersionsResponse = await ref - .watch(ClientController.provider.notifier) - .getSpecVersions(); return .new({ "General": .new([ @@ -52,6 +50,7 @@ class SettingsSectionsController title: "Use Dynamic Theme", icon: Icons.palette, description: "Toggle on or off Dynamic Theme. Only available on Android, Linux, Windows, or MacOS.", + description: "Toggle on or off Dynamic Theme. Only available on Android, Linux, Windows, or MacOS.", builder: (title, description, icon) => SwitchListTile( title: Text(title), subtitle: Text(description), @@ -78,6 +77,7 @@ class SettingsSectionsController .new( title: "Linux Mobile Mode", description: "Enables some fixes for Linux mobile, e.g. disabling dragging appbar for moving window.", + description: "Enables some fixes for Linux mobile, e.g. disabling dragging appbar for moving window.", icon: Icons.construction, builder: (title, description, icon) => SwitchListTile( title: Text(title), @@ -145,38 +145,51 @@ class SettingsSectionsController .new( title: "Invite Blocking", description: "Block invites, either completely, or block only invites from users without shared private rooms (depends on server support).", + description: "Block invites, either completely, or block only invites from users without shared private rooms (depends on server support).", builder: (title, description, icon) => Consumer( - builder: (context, ref, _) => - DialogListTile( - icon: Icon(icon), - title: title, - subtitle: Text(description), - initialValue: ref - .watch(AccountDataController.provider) - .invitePermissionConfig - .defaultAction, - options: specVersionsResponse.unstableFeatures.msc4494 - ? DefaultInviteAction.values - : IList(DefaultInviteAction.values) - .remove(.denyPublic) - .toList(), - getName: (option) => switch (option) { - .allow => "Allow", - .deny => "Deny", - .denyPublic => "Deny public", - }, - onChanged: (value) => ref - .watch(ClientController.provider.notifier) - .setAccountData( - .new( - type: AccountData.invitePermissionConfigKey, - content: InvitePermissionConfig( - defaultAction: value, - ), - ), - ) - .onError(showError), + builder: (context, ref, _) { + final specVersionsResponse = ref.watch( + SpecVersionsController.provider, + ); + return DialogListTile( + icon: Icon(icon), + title: title, + subtitle: Text(description), + initialValue: ref + .watch(AccountDataController.provider) + .invitePermissionConfig + .defaultAction, + options: + specVersionsResponse.maybeWhen( + data: (data) => data.unstableFeatures.msc4494, + orElse: () => true, + ) + ? DefaultInviteAction.values + : IList(DefaultInviteAction.values) + .remove(.denyPublic) + .toList(), + getName: (option) => switch (option) { + .allow => "Allow", + .deny => "Deny", + .denyPublic => "Deny public", + }, + onChanged: specVersionsResponse.maybeWhen( + data: (_) => + (value) => ref + .watch(ClientController.provider.notifier) + .setAccountData( + .new( + type: AccountData.invitePermissionConfigKey, + content: InvitePermissionConfig( + defaultAction: value, + ), + ), + ) + .onError(showError), + orElse: () => null, ), + ); + }, ), icon: Icons.person_off, ), @@ -197,6 +210,8 @@ class SettingsSectionsController onPressed: () async { Navigator.of(context) .popUntil((route) => route.isFirst); + Navigator.of(context) + .popUntil((route) => route.isFirst); await WidgetsBinding.instance.endOfFrame; diff --git a/lib/controllers/spec_versions.dart b/lib/controllers/spec_versions.dart new file mode 100644 index 0000000..1f879bd --- /dev/null +++ b/lib/controllers/spec_versions.dart @@ -0,0 +1,15 @@ +import "package:hooks_riverpod/hooks_riverpod.dart"; +import "package:nexus/controllers/client.dart"; +import "package:nexus/models/spec_versions_response.dart"; + +class SpecVersionsController extends AsyncNotifier { + @override + Future build() => + ref.watch(ClientController.provider.notifier).getSpecVersions(); + + static final provider = + AsyncNotifierProvider.autoDispose< + SpecVersionsController, + SpecVersionsResponse + >(SpecVersionsController.new); +} diff --git a/lib/pages/settings.dart b/lib/pages/settings.dart index a454993..ed9dc59 100644 --- a/lib/pages/settings.dart +++ b/lib/pages/settings.dart @@ -170,30 +170,34 @@ class const SettingsPage({super.key}) extends ConsumerWidget { ) : Row( children: [ - NavigationRailM3E( - type: .alwaysExpand, - trailing: searchBar, - scrollable: true, - sections: sections - .mapTo( - (categoryGroup, categories) => - NavigationRailM3ESection( - header: DividerText(categoryGroup), - destinations: categories - .map( - (category) => - NavigationRailM3EDestination( - icon: Icon(category.icon), - label: category.title, - ), - ) - .toList(), - ), - ) - .toList(), - selectedIndex: selected.value, - onDestinationSelected: (value) => - selected.value = value, + MaterialUiCompatibilityBridge( + child: NavigationRailM3E( + type: .alwaysExpand, + trailing: searchBar, + scrollable: true, + sections: sections + .mapTo( + ( + categoryGroup, + categories, + ) => NavigationRailM3ESection( + header: DividerText(categoryGroup), + destinations: categories + .map( + (category) => + NavigationRailM3EDestination( + icon: Icon(category.icon), + label: category.title, + ), + ) + .toList(), + ), + ) + .toList(), + selectedIndex: selected.value, + onDestinationSelected: (value) => + selected.value = value, + ), ), VerticalDivider(), Expanded(