From 0813597a5360ca323991d1cc785434644abc6ecd Mon Sep 17 00:00:00 2001 From: istalri Date: Sat, 25 Jul 2026 19:04:56 +0200 Subject: [PATCH 001/176] Small refactor of emoji controller and widget Isolated deserialization of the large emoji json to not keep main thread busy to long Refactored textController logic in EmojiPickerButton to make popping mid buid impossible. The bug from the comment should be impossible now (The bug could be reproduce with future.delayed and microtask but) --- lib/controllers/emoji.dart | 8 +++- lib/widgets/emoji_picker_button.dart | 60 +++++++++++++++++----------- 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/lib/controllers/emoji.dart b/lib/controllers/emoji.dart index caea3de..0c89896 100644 --- a/lib/controllers/emoji.dart +++ b/lib/controllers/emoji.dart @@ -1,6 +1,7 @@ import "dart:convert"; import "package:emoji_text_field/models/emoji_category.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart"; +import "package:flutter/foundation.dart"; import "package:flutter/material.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:http/http.dart"; @@ -19,9 +20,12 @@ class EmojiController extends AsyncNotifier { throw Exception("Failed to load emoji data"); } - final data = json.decode(response.body); + return compute(_parseEmojiJson, response.body); + } - final entries = (data as List) + static EmojiTuple _parseEmojiJson(String body) { + final data = json.decode(body) as List; + final entries = data .cast>() .map(Emoji.fromJson) .toIList(); diff --git a/lib/widgets/emoji_picker_button.dart b/lib/widgets/emoji_picker_button.dart index 2ac906a..3516590 100644 --- a/lib/widgets/emoji_picker_button.dart +++ b/lib/widgets/emoji_picker_button.dart @@ -20,32 +20,46 @@ class EmojiPickerButton extends HookConsumerWidget { Widget build(_, WidgetRef ref) => IconButton( onPressed: () async { onPressed?.call(); - final controller = this.controller ?? .new(); + + final tempController = controller ?? TextEditingController(); + final shouldDispose = controller == null; + var hasPopped = false; + + void handler() { + if (tempController.text.isEmpty || hasPopped) return; + hasPopped = true; + + onSelection?.call(tempController.text); + + WidgetsBinding.instance.addPostFrameCallback((_) { + if (context.mounted) Navigator.of(context).maybePop(); + }); + } final emojis = await ref.watch(EmojiController.provider.future); - if (context.mounted) { - showModalBottomSheet( - context: context, - builder: (context) => EmojiKeyboardView( - config: .new( - showRecentTab: false, - customCategories: emojis.$1.unlock, - customKeywords: emojis.$2.unlock, - backgroundColor: Theme.of(context).colorScheme.surfaceContainer, - height: 600, - ), - textController: controller - ..addListener(() { - // Without this, there will sometimes be a debugLocked is not true error sometimes - // It might be preferable to use a microtask instead of a `Future.delayed`. - Future.delayed(.zero, () { - if (context.mounted) Navigator.of(context).pop(); - }); - onSelection?.call(controller.text); - }), - ), - ); + if (!context.mounted) { + if (shouldDispose) tempController.dispose(); + return; } + + await showModalBottomSheet( + context: context, + builder: (sheetContext) => EmojiKeyboardView( + config: .new( + showRecentTab: false, + customCategories: emojis.$1.unlock, + customKeywords: emojis.$2.unlock, + backgroundColor: Theme.of( + sheetContext, + ).colorScheme.surfaceContainer, + height: 600, + ), + textController: tempController..addListener(handler), + ), + ); + + tempController.removeListener(handler); + if (shouldDispose) tempController.dispose(); }, icon: Icon(Icons.emoji_emotions), ); From 16fdf0c4202ea16c30fee06a842a55e604cf3aff Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Mon, 27 Jul 2026 15:46:08 -0400 Subject: [PATCH 002/176] download audio and video using gomuks --- .gitmodules | 2 +- gomuks | 2 +- lib/helpers/extensions/get_headers.dart | 7 ------ lib/widgets/players/audio.dart | 33 +++++++++++++++---------- lib/widgets/players/video.dart | 20 ++++++++------- lib/widgets/renderers/message.dart | 23 ++++++++++++++--- 6 files changed, 52 insertions(+), 35 deletions(-) delete mode 100644 lib/helpers/extensions/get_headers.dart diff --git a/.gitmodules b/.gitmodules index dc5e02e..145276a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "gomuks"] path = gomuks - url = https://github.com/henry-hiles/gomuks + url = https://github.com/gomuks/gomuks branch = main diff --git a/gomuks b/gomuks index 1f11743..0f8fb26 160000 --- a/gomuks +++ b/gomuks @@ -1 +1 @@ -Subproject commit 1f11743884a64765b1444b250377a09ebcaba93c +Subproject commit 0f8fb261ab57977fa24a4f63b7aafbb9a4ff1b7b diff --git a/lib/helpers/extensions/get_headers.dart b/lib/helpers/extensions/get_headers.dart deleted file mode 100644 index 0fcec48..0000000 --- a/lib/helpers/extensions/get_headers.dart +++ /dev/null @@ -1,7 +0,0 @@ -import "package:flutter_riverpod/flutter_riverpod.dart"; -import "package:nexus/controllers/header.dart"; - -extension GetHeaders on WidgetRef { - Map get headers => - watch(HeaderController.provider).requireValue; -} diff --git a/lib/widgets/players/audio.dart b/lib/widgets/players/audio.dart index 0c96579..22a91f7 100644 --- a/lib/widgets/players/audio.dart +++ b/lib/widgets/players/audio.dart @@ -1,17 +1,17 @@ import "dart:async"; - import "package:flutter/material.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:media_kit/media_kit.dart"; -import "package:nexus/helpers/extensions/get_headers.dart"; +import "package:nexus/controllers/client.dart"; import "package:nexus/models/info/audio.dart"; class AudioPlayer extends HookConsumerWidget { - final Uri url; + final Uri uri; final AudioInfo? info; + final bool encrypted; - const AudioPlayer(this.url, this.info, {super.key}); + const AudioPlayer(this.uri, this.info, {this.encrypted = false, super.key}); @override Widget build(BuildContext context, WidgetRef ref) { @@ -24,11 +24,12 @@ class AudioPlayer extends HookConsumerWidget { final duration = useState(Duration.zero); useEffect(() { + player.platform?.state = player.platform!.state.copyWith(buffering: true); scheduleMicrotask(() async { - await player.open( - Media(url.toString(), httpHeaders: ref.headers), - play: false, - ); + final video = await ref + .watch(ClientController.provider.notifier) + .downloadMedia(.new(mxc: uri, encrypted: encrypted)); + await player.open(Media(video.path), play: false); player.stream.playing.listen((value) { playing.value = value; @@ -67,12 +68,18 @@ class AudioPlayer extends HookConsumerWidget { padding: .only(left: 8, right: 16), child: Row( children: [ - IconButton( - onPressed: player.playOrPause, - icon: Icon( - playing.value ? Icons.pause_circle : Icons.play_circle, + if (player.state.buffering) + SizedBox.square( + dimension: 24, + child: CircularProgressIndicator(padding: .all(4)), + ) + else + IconButton( + onPressed: player.playOrPause, + icon: Icon( + playing.value ? Icons.pause_circle : Icons.play_circle, + ), ), - ), SizedBox(width: 8), Text( format(position.value), diff --git a/lib/widgets/players/video.dart b/lib/widgets/players/video.dart index 8083860..cd4e569 100644 --- a/lib/widgets/players/video.dart +++ b/lib/widgets/players/video.dart @@ -2,16 +2,17 @@ import "dart:async"; import "package:flutter/material.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; +import "package:nexus/controllers/client.dart"; import "package:nexus/models/info/video.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:media_kit/media_kit.dart"; import "package:media_kit_video/media_kit_video.dart"; -import "package:nexus/helpers/extensions/get_headers.dart"; class VideoPlayer extends HookConsumerWidget { final VideoInfo? info; - final Uri url; - const VideoPlayer(this.url, this.info, {super.key}); + final Uri uri; + final bool encrypted; + const VideoPlayer(this.uri, this.info, {this.encrypted = false, super.key}); @override Widget build(BuildContext context, WidgetRef ref) { @@ -21,12 +22,13 @@ class VideoPlayer extends HookConsumerWidget { final controller = useMemoized(() => VideoController(player)); useEffect(() { - scheduleMicrotask( - () => player.open( - Media(url.toString(), httpHeaders: ref.headers), - play: false, - ), - ); + player.platform?.state = player.platform!.state.copyWith(buffering: true); + scheduleMicrotask(() async { + final video = await ref + .watch(ClientController.provider.notifier) + .downloadMedia(.new(mxc: uri, encrypted: encrypted)); + await player.open(Media(video.path), play: false); + }); return player.dispose; }, []); diff --git a/lib/widgets/renderers/message.dart b/lib/widgets/renderers/message.dart index 6d660af..0e0f6fa 100644 --- a/lib/widgets/renderers/message.dart +++ b/lib/widgets/renderers/message.dart @@ -226,10 +226,25 @@ class MessageRenderer extends ConsumerWidget { ConstrainedBox( constraints: .loose(.square(500)), child: switch (event.content) { - VideoMessageContent(:final info) => - VideoPlayer(url, info), - AudioMessageContent(:final info) => - AudioPlayer(url, info), + VideoMessageContent( + :final info, + :final file, + ) => + VideoPlayer( + url, + info, + encrypted: file != null, + ), + AudioMessageContent( + :final info, + :final file, + ) => + AudioPlayer( + url, + info, + + encrypted: file != null, + ), FileMessageContent( :final info, :final filename, From eca9d3b411dc47c94254b4c60cbbf2d70146a1da Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Mon, 27 Jul 2026 16:01:40 -0400 Subject: [PATCH 003/176] use gomuks for URL previews --- lib/controllers/client.dart | 9 +++--- lib/controllers/header.dart | 20 ------------- lib/controllers/url_preview.dart | 48 +++++++----------------------- lib/main.dart | 2 -- lib/widgets/renderers/message.dart | 3 +- lib/widgets/url_preview.dart | 5 ++-- 6 files changed, 18 insertions(+), 69 deletions(-) delete mode 100644 lib/controllers/header.dart diff --git a/lib/controllers/client.dart b/lib/controllers/client.dart index 2cb1d66..97c3ed6 100644 --- a/lib/controllers/client.dart +++ b/lib/controllers/client.dart @@ -17,6 +17,7 @@ import "package:nexus/main.dart"; import "package:nexus/models/content/message.dart"; import "package:nexus/models/event.dart"; import "package:nexus/models/oauth_auth_code_response.dart"; +import "package:nexus/models/open_graph_data.dart"; import "package:nexus/models/paginate.dart"; import "package:nexus/models/requests/download_media.dart"; import "package:nexus/models/requests/get_event.dart"; @@ -215,11 +216,6 @@ class ClientController extends AsyncNotifier { return response["room_id"]; } - Future getAccessToken() async { - final response = await _sendCommand("get_account_info", {}); - return response?["access_token"]; - } - Future leaveRoom(Room room) async { if (room.metadata == null) return; await _sendCommand("leave_room", {"room_id": room.metadata!.id}); @@ -255,6 +251,9 @@ class ClientController extends AsyncNotifier { return json == null ? null : .fromJson(json); } + Future getUrlPreview(Uri url) async => + .fromJson(await _sendCommand("get_url_preview", {"url": url.toString()})); + Future paginate(PaginateRequest request) async => .fromJson(await _sendCommand("paginate", request.toJson())); diff --git a/lib/controllers/header.dart b/lib/controllers/header.dart deleted file mode 100644 index 3e173ad..0000000 --- a/lib/controllers/header.dart +++ /dev/null @@ -1,20 +0,0 @@ -import "package:flutter_riverpod/flutter_riverpod.dart"; -import "package:nexus/controllers/client.dart"; -import "package:nexus/controllers/client_state.dart"; - -class HeaderController extends AsyncNotifier> { - @override - Future> build() async { - if (ref.watch(ClientStateController.provider)?.isLoggedIn != true) { - return {}; - } - final client = ref.watch(ClientController.provider.notifier); - final accessToken = await client.getAccessToken(); - return {"authorization": "Bearer $accessToken"}; - } - - static final provider = - AsyncNotifierProvider>( - HeaderController.new, - ); -} diff --git a/lib/controllers/url_preview.dart b/lib/controllers/url_preview.dart index 2a81a3c..4e7d3a0 100644 --- a/lib/controllers/url_preview.dart +++ b/lib/controllers/url_preview.dart @@ -1,50 +1,22 @@ -import "dart:convert"; import "package:flutter_riverpod/flutter_riverpod.dart"; -import "package:http/http.dart"; -import "package:nexus/controllers/client_state.dart"; -import "package:nexus/controllers/header.dart"; +import "package:nexus/controllers/client.dart"; import "package:nexus/models/open_graph_data.dart"; class UrlPreviewController extends AsyncNotifier { - final String link; - UrlPreviewController(this.link); + final Uri url; + UrlPreviewController(this.url); @override Future build() async { - try { - final homeserver = ref.watch( - ClientStateController.provider.select((value) => value?.homeserverUrl), - ); + if (url.host == "matrix.to") return null; - if (homeserver != null && !link.contains("matrix.to")) { - { - final response = await get( - .parse(homeserver) - .resolve("/_matrix/client/v1/media/preview_url") - .replace(queryParameters: {"url": link}), - headers: await ref.watch(HeaderController.provider.future), - ); - - if (response.statusCode == 200) { - final decodedValue = json.decode(response.body); - if (decodedValue is! Map) return null; - - return .fromJson( - decodedValue, - ).copyWith(imageUrl: decodedValue["og:image"]); - } - } - } - } catch (_) { - return null; - } - return null; + return await ref + .watch(ClientController.provider.notifier) + .getUrlPreview(url); } static final provider = - AsyncNotifierProvider.family< - UrlPreviewController, - OpenGraphData?, - String - >(UrlPreviewController.new); + AsyncNotifierProvider.family( + UrlPreviewController.new, + ); } diff --git a/lib/main.dart b/lib/main.dart index f50d22d..53cc57b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -6,7 +6,6 @@ import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:media_kit/media_kit.dart"; import "package:nexus/controllers/client.dart"; import "package:nexus/controllers/client_state.dart"; -import "package:nexus/controllers/header.dart"; import "package:nexus/controllers/multi_provider.dart"; import "package:nexus/controllers/settings.dart"; import "package:nexus/controllers/shared_prefs.dart"; @@ -144,7 +143,6 @@ class App extends StatelessWidget { IListConst([ SharedPrefsController.provider, ClientController.provider, - HeaderController.provider, ]), ), ) diff --git a/lib/widgets/renderers/message.dart b/lib/widgets/renderers/message.dart index 0e0f6fa..09ef00b 100644 --- a/lib/widgets/renderers/message.dart +++ b/lib/widgets/renderers/message.dart @@ -273,7 +273,8 @@ class MessageRenderer extends ConsumerWidget { (element) => element is UrlElement, ) case final UrlElement link?) - UrlPreview(link.url), + if (Uri.tryParse(link.url) case final Uri url?) + UrlPreview(url), ReactionRow(event), ], diff --git a/lib/widgets/url_preview.dart b/lib/widgets/url_preview.dart index 5831300..3a20e19 100644 --- a/lib/widgets/url_preview.dart +++ b/lib/widgets/url_preview.dart @@ -6,7 +6,7 @@ import "package:nexus/helpers/launch_helper.dart"; import "package:nexus/helpers/mxc_image.dart"; class UrlPreview extends ConsumerWidget { - final String link; + final Uri link; const UrlPreview(this.link, {super.key}); @override @@ -18,8 +18,7 @@ class UrlPreview extends ConsumerWidget { data: (preview) => preview == null ? SizedBox.shrink() : InkWell( - onTap: () => - ref.watch(LaunchHelper.provider).launchUrl(.parse(link)), + onTap: () => ref.watch(LaunchHelper.provider).launchUrl(link), child: Card( margin: .symmetric(vertical: 4), color: Theme.of( From 5f13d3fbf5cb76872aa95b3d2918addf087a8168 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Mon, 27 Jul 2026 22:02:20 -0400 Subject: [PATCH 004/176] don't show errors when url preview fails --- lib/controllers/url_preview.dart | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/controllers/url_preview.dart b/lib/controllers/url_preview.dart index 4e7d3a0..1b17870 100644 --- a/lib/controllers/url_preview.dart +++ b/lib/controllers/url_preview.dart @@ -1,3 +1,4 @@ +import "package:flutter/widgets.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/controllers/client.dart"; import "package:nexus/models/open_graph_data.dart"; @@ -10,9 +11,14 @@ class UrlPreviewController extends AsyncNotifier { Future build() async { if (url.host == "matrix.to") return null; - return await ref - .watch(ClientController.provider.notifier) - .getUrlPreview(url); + try { + return await ref + .watch(ClientController.provider.notifier) + .getUrlPreview(url); + } catch (error, stackTrace) { + debugPrintStack(label: error.toString(), stackTrace: stackTrace); + return null; + } } static final provider = From 2a1cc33ee3a2e073af6f997913090be9e51d6440 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 28 Jul 2026 15:13:14 -0400 Subject: [PATCH 005/176] add macos ci hopefully this works first try :3 --- .github/workflows/macos.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/macos.yml diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml new file mode 100644 index 0000000..105f778 --- /dev/null +++ b/.github/workflows/macos.yml @@ -0,0 +1,31 @@ +name: "Build APK" + +on: + push: + branches: ["main"] + tags: ["*"] + workflow_dispatch: + +jobs: + build-apk: + runs-on: macos-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + submodules: recursive + + - name: Lix GHA Installer Action + uses: samueldr/lix-gha-installer-action@v2026-02-22 + with: + extra_nix_config: experimental-features = nix-command flakes flake-self-attrs + + - name: Build app + run: nix develop --command bash -c "flutter pub get && dart scripts/generate.dart && flutter pub run build_runner build && flutter build macos --release" + + - name: Upload installer artifact + uses: actions/upload-artifact@v6 + with: + name: App + path: build/macos/Build/Products/Release/Nexus.app \ No newline at end of file From afd6168535a03f7bb329cfc04f9de01d93fa32b2 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 28 Jul 2026 15:15:02 -0400 Subject: [PATCH 006/176] fix macos CI name [skip ci] --- .github/workflows/macos.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 105f778..e7040fa 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -1,4 +1,4 @@ -name: "Build APK" +name: "Build MacOS App" on: push: @@ -7,7 +7,7 @@ on: workflow_dispatch: jobs: - build-apk: + build-app: runs-on: macos-latest steps: From 60968f5f3eeb6685fa73f4bf7ae88c1439dd7de5 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 28 Jul 2026 15:29:41 -0400 Subject: [PATCH 007/176] make macos builder build app from nix --- .github/workflows/macos.yml | 8 +++----- linux/nix/pkg/default.nix | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index e7040fa..9d76b1b 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -13,8 +13,6 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v6 - with: - submodules: recursive - name: Lix GHA Installer Action uses: samueldr/lix-gha-installer-action@v2026-02-22 @@ -22,10 +20,10 @@ jobs: extra_nix_config: experimental-features = nix-command flakes flake-self-attrs - name: Build app - run: nix develop --command bash -c "flutter pub get && dart scripts/generate.dart && flutter pub run build_runner build && flutter build macos --release" + run: nix build .#default - name: Upload installer artifact uses: actions/upload-artifact@v6 with: - name: App - path: build/macos/Build/Products/Release/Nexus.app \ No newline at end of file + name: flatpak-${{ matrix.arch }} + path: result/Nexus.app \ No newline at end of file diff --git a/linux/nix/pkg/default.nix b/linux/nix/pkg/default.nix index 4e00959..c026606 100644 --- a/linux/nix/pkg/default.nix +++ b/linux/nix/pkg/default.nix @@ -44,7 +44,7 @@ flutter.buildFlutterApplication { meta = { description = "A simple and user-friendly Matrix client"; mainProgram = "nexus"; - platforms = lib.platforms.linux; + platforms = lib.platforms.unix; maintainers = with lib.maintainers; [ quadradical ]; }; } From 06075f75c561b5a1bdad0cb3c52c1ba9bf9a58f3 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 28 Jul 2026 15:49:27 -0400 Subject: [PATCH 008/176] make gomuks nix package build to a .dylib on macos --- linux/nix/pkg/gomuks.nix | 41 +++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/linux/nix/pkg/gomuks.nix b/linux/nix/pkg/gomuks.nix index 40fe29c..9d7770b 100644 --- a/linux/nix/pkg/gomuks.nix +++ b/linux/nix/pkg/gomuks.nix @@ -1,31 +1,38 @@ { src, + stdenv, buildGoModule, }: -buildGoModule (finalAttrs: { - pname = "gomuks-ffi"; - version = "submodule"; +buildGoModule ( + finalAttrs: + let + filename = "libgomuks${stdenv.hostPlatform.extensions.sharedLibrary}"; + in + { + pname = "gomuks-ffi"; + version = "submodule"; - doCheck = false; + doCheck = false; - src = "${src}/gomuks"; + src = "${src}/gomuks"; - vendorHash = "sha256-4QU51WGiNKYm7z/ajnas2qQaMK5BgyHwPfmNpQvW0qg="; + vendorHash = "sha256-4QU51WGiNKYm7z/ajnas2qQaMK5BgyHwPfmNpQvW0qg="; - buildPhase = '' - runHook preBuild + buildPhase = '' + runHook preBuild - go build -buildmode=c-shared -o libgomuks.so -tags goolm,noheic,sqlite_fts5 ./pkg/ffi + go build -buildmode=c-shared -o ${filename} -tags goolm,noheic,sqlite_fts5 ./pkg/ffi - runHook postBuild - ''; + runHook postBuild + ''; - installPhase = '' - runHook preInstall + installPhase = '' + runHook preInstall - install -Dm0644 libgomuks.so -t $out/lib + install -Dm0644 ${filename} -t $out/lib - runHook postInstall - ''; -}) + runHook postInstall + ''; + } +) From 9298eb815db74bbc7e7b9a78a785f2a9e958e006 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 28 Jul 2026 15:57:39 -0400 Subject: [PATCH 009/176] use libclang.dylib on macos --- scripts/generate.dart | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/scripts/generate.dart b/scripts/generate.dart index 0b0cf7c..c381230 100644 --- a/scripts/generate.dart +++ b/scripts/generate.dart @@ -24,7 +24,18 @@ void main(List args) async { ).generate( libclangDylib: libclangPath == null ? null - : Uri.file(join(libclangPath, "libclang.so")), + : Uri.file( + join( + libclangPath, + "libclang.${(Platform.isLinux || Platform.isAndroid) + ? "so" + : Platform.isMacOS + ? "dylib" + : Platform.isWindows + ? "dll" + : throw UnsupportedError("Unsupported Platform")}", + ), + ), ); print("Done!"); } From b2813a0eb511b891d35d8fbcefbf69feb3d7184e Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 28 Jul 2026 17:04:06 -0400 Subject: [PATCH 010/176] use devshell for macos --- .github/workflows/macos.yml | 6 +++--- linux/nix/devshell.nix | 6 ++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 9d76b1b..958458b 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -20,10 +20,10 @@ jobs: extra_nix_config: experimental-features = nix-command flakes flake-self-attrs - name: Build app - run: nix build .#default + run: nix develop --command bash -c "flutter pub get && dart scripts/generate.dart && flutter pub run build_runner build && flutter build macos --release" - name: Upload installer artifact uses: actions/upload-artifact@v6 with: - name: flatpak-${{ matrix.arch }} - path: result/Nexus.app \ No newline at end of file + name: App + path: build/macos/Build/Products/Release/Nexus.app \ No newline at end of file diff --git a/linux/nix/devshell.nix b/linux/nix/devshell.nix index ae77467..c29ac4d 100644 --- a/linux/nix/devshell.nix +++ b/linux/nix/devshell.nix @@ -35,8 +35,6 @@ pkgs.mkShell { env = rec { LIBCLANG_PATH = lib.makeLibraryPath [ pkgs.libclang ]; - LD_LIBRARY_PATH = "./build/native_assets/linux:${lib.makeLibraryPath [ pkgs.zlib ]}"; - CPATH = lib.makeSearchPath "include" [ pkgs.glibc.dev ]; ANDROID_HOME = "${android.androidsdk}/libexec/android-sdk"; ANDROID_SDK_ROOT = ANDROID_HOME; @@ -44,5 +42,9 @@ pkgs.mkShell { TOOLS = "${ANDROID_HOME}/build-tools/${"36.0.0"}"; GRADLE_OPTS = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${TOOLS}/aapt2"; + } + // lib.optionalAttrs pkgs.stdenv.isLinux { + CPATH = lib.makeSearchPath "include" [ pkgs.glibc.dev ]; + LD_LIBRARY_PATH = "./build/native_assets/linux:${lib.makeLibraryPath [ pkgs.zlib ]}"; }; } From e8b90591d5145dad3ecfab957060f3c9f8b79f7a Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 28 Jul 2026 17:13:55 -0400 Subject: [PATCH 011/176] only include wayland in devshell on macos --- linux/nix/devshell.nix | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/linux/nix/devshell.nix b/linux/nix/devshell.nix index c29ac4d..812082c 100644 --- a/linux/nix/devshell.nix +++ b/linux/nix/devshell.nix @@ -18,20 +18,22 @@ let }; in pkgs.mkShell { - packages = with pkgs; [ - go - git - jdk17 - libGL - wayland - (flutter.override { - extraPkgConfigPackages = [ - mpv-unwrapped - libass - ]; - }) - android.platform-tools - ]; + packages = + with pkgs; + [ + go + git + jdk17 + libGL + (flutter.override { + extraPkgConfigPackages = [ + mpv-unwrapped + libass + ]; + }) + android.platform-tools + ] + ++ lib.optional pkgs.stdenv.isLinux wayland; env = rec { LIBCLANG_PATH = lib.makeLibraryPath [ pkgs.libclang ]; From 9bf664624a041f5c408aac0f1d4691a67498d1cd Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 28 Jul 2026 17:43:51 -0400 Subject: [PATCH 012/176] clone submodules on macos --- .github/workflows/macos.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 958458b..e7040fa 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -13,6 +13,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v6 + with: + submodules: recursive - name: Lix GHA Installer Action uses: samueldr/lix-gha-installer-action@v2026-02-22 From 8c25228bd987a52d417bf9e8854bd1bee28b45ae Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 28 Jul 2026 20:39:03 -0400 Subject: [PATCH 013/176] comment out macos CI auto running [skip ci] --- .github/workflows/macos.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index e7040fa..8ed63cf 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -1,9 +1,10 @@ name: "Build MacOS App" on: - push: - branches: ["main"] - tags: ["*"] + # TODO: Uncomment this once the MacOS workflow actually works + # push: + # branches: ["main"] + # tags: ["*"] workflow_dispatch: jobs: From 80fa9673bb8dc9a5ced879ad4d901a2acea238bf Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 29 Jul 2026 11:58:12 -0400 Subject: [PATCH 014/176] fix pending attachments disappearing when new events are sent --- lib/controllers/attachment.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/controllers/attachment.dart b/lib/controllers/attachment.dart index e33493e..220b5b3 100644 --- a/lib/controllers/attachment.dart +++ b/lib/controllers/attachment.dart @@ -17,7 +17,7 @@ class AttachmentController extends Notifier<(String, MessageContent?)?> { final filename = basename(file.path); state = (filename, null); - final room = ref.watch( + final room = ref.read( RoomsController.provider.select((value) => value[roomId]), ); From f0f426a6479fa6a93cae50e05be318d8ff3f73e6 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 29 Jul 2026 12:06:19 -0400 Subject: [PATCH 015/176] improve matcher for encrypted media --- lib/controllers/attachment.dart | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/lib/controllers/attachment.dart b/lib/controllers/attachment.dart index 220b5b3..2a99ee5 100644 --- a/lib/controllers/attachment.dart +++ b/lib/controllers/attachment.dart @@ -17,18 +17,16 @@ class AttachmentController extends Notifier<(String, MessageContent?)?> { final filename = basename(file.path); state = (filename, null); - final room = ref.read( - RoomsController.provider.select((value) => value[roomId]), + final isEncrypted = ref.read( + RoomsController.provider.select( + (value) => + value[roomId]?.state[EventType.encryption.type]?.isNotEmpty == true, + ), ); final content = await ref .watch(ClientController.provider.notifier) - .uploadMedia( - .new( - path: file.path, - encrypt: room?.state[EventType.encryption.type]?.isNotEmpty == true, - ), - ); + .uploadMedia(.new(path: file.path, encrypt: isEncrypted)); state = (filename, content); } From d7f49568a7dd5d7ccff8986986668458b2712464 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 29 Jul 2026 12:11:57 -0400 Subject: [PATCH 016/176] move attachment sending check to be earlier fixes sending with keyboard before attachment uploaded --- lib/controllers/room_chat.dart | 8 +++----- lib/widgets/composer/composer.dart | 5 ++++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/controllers/room_chat.dart b/lib/controllers/room_chat.dart index 558817c..3e531bb 100644 --- a/lib/controllers/room_chat.dart +++ b/lib/controllers/room_chat.dart @@ -125,11 +125,9 @@ class RoomChatController extends AsyncNotifier?> { if (relationType == .edit) { baseContent = relation?.content; } else { - final attachment = ref.watch(AttachmentController.provider(roomId)); - if (attachment != null && attachment.$2 == null) return; - - baseContent = attachment?.$2; - ref.invalidate(AttachmentController.provider(roomId)); + final provider = AttachmentController.provider(roomId); + baseContent = ref.watch(provider)?.$2; + ref.invalidate(provider); } var taggedMessage = text; diff --git a/lib/widgets/composer/composer.dart b/lib/widgets/composer/composer.dart index c63d939..ca3de8a 100644 --- a/lib/widgets/composer/composer.dart +++ b/lib/widgets/composer/composer.dart @@ -59,7 +59,10 @@ class Composer extends HookConsumerWidget { final attachment = ref.watch(AttachmentController.provider(roomId)); void send() { - if (controller.value.text.isEmpty && attachment == null) return; + if (controller.value.text.isEmpty && attachment == null || + attachment != null && attachment.$2 == null) { + return; + } onSend( controller.value.formattedText, shouldMention: shouldMention.value, From 9831446c666d98d547071e691f96b1b2a87be57e Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 29 Jul 2026 16:18:07 -0400 Subject: [PATCH 017/176] add a little padding to send errors --- lib/widgets/renderers/event.dart | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/widgets/renderers/event.dart b/lib/widgets/renderers/event.dart index bcca961..2eb8bc3 100644 --- a/lib/widgets/renderers/event.dart +++ b/lib/widgets/renderers/event.dart @@ -216,10 +216,13 @@ class EventRenderer extends HookConsumerWidget { if (event.content is! MessageContent) ReactionRow(event), if (event.sendError != null && event.sendError != "not sent") - Text( - event.sendError!, - style: theme.textTheme.labelSmall?.copyWith( - color: theme.colorScheme.error, + Padding( + padding: .only(bottom: 4), + child: Text( + event.sendError!, + style: theme.textTheme.labelSmall?.copyWith( + color: theme.colorScheme.error, + ), ), ), ].map((child) => Padding(padding: .only(left: 4), child: child)), From 419d75ca83f0a63a191983fc3f69fdbcd55247bf Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 29 Jul 2026 19:46:39 -0400 Subject: [PATCH 018/176] wrap messages with unknown message types --- lib/widgets/renderers/message.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/widgets/renderers/message.dart b/lib/widgets/renderers/message.dart index 09ef00b..012dcc9 100644 --- a/lib/widgets/renderers/message.dart +++ b/lib/widgets/renderers/message.dart @@ -286,9 +286,8 @@ class MessageRenderer extends ConsumerWidget { "This message is redacted", style: errorStyle, ) - : Row( + : Wrap( spacing: 8, - mainAxisSize: .min, children: [ Text( "Unknown message type:", From f3c31db244fe98b3cb2a0a1c302e6911643f44cd Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 29 Jul 2026 21:57:03 -0400 Subject: [PATCH 019/176] update build requirements --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d191d6e..6eb021b 100644 --- a/README.md +++ b/README.md @@ -127,15 +127,16 @@ If you want to try out Nexus, grab one of the following artifacts from CI: #### Linux - With Nix: Either use direnv and `direnv allow`, or `nix flake develop` -- Without Nix: Install Flutter, Go, Git, Libclang, and Glibc. Do not use any Snap packages, they cause various compilation issues. +- Without Nix: Install Flutter, Go, Git, Libclang, Libass, MPV, and Glibc. Do not use any Snap packages, they cause various compilation issues. #### Windows You will need: - Flutter -- Android SDK + NDK - Git +- Libass +- MPV - Go - Visual Studio 2022 (Desktop development with C++) - [MSYS2/MinGW-w64 GCC](https://www.msys2.org/) (for CGO) From fc4aa5a10d79a899e8b4b77bef7d3eef77bc1cb1 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Fri, 31 Jul 2026 10:20:06 -0400 Subject: [PATCH 020/176] persist member list opened status --- lib/controllers/member_list_opened.dart | 22 ++++++++++++++++++++++ lib/widgets/room_chat.dart | 10 ++++++---- 2 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 lib/controllers/member_list_opened.dart diff --git a/lib/controllers/member_list_opened.dart b/lib/controllers/member_list_opened.dart new file mode 100644 index 0000000..e3509f0 --- /dev/null +++ b/lib/controllers/member_list_opened.dart @@ -0,0 +1,22 @@ +import "package:flutter_riverpod/flutter_riverpod.dart"; +import "package:nexus/controllers/shared_prefs.dart"; + +class MemberListOpenedController extends Notifier { + static const String key = "memberListOpened"; + + @override + bool build() => + ref.watch(SharedPrefsController.provider).requireValue.getBool(key) ?? + true; + + Future set(bool value) async { + final prefs = ref.watch(SharedPrefsController.provider).requireValue; + state = value; + + prefs.setBool(key, value); + } + + static final provider = NotifierProvider( + MemberListOpenedController.new, + ); +} diff --git a/lib/widgets/room_chat.dart b/lib/widgets/room_chat.dart index 0fdd7c7..b1f29c4 100644 --- a/lib/widgets/room_chat.dart +++ b/lib/widgets/room_chat.dart @@ -7,6 +7,7 @@ import "package:measure_size/measure_size.dart"; import "package:nexus/controllers/account_data.dart"; import "package:nexus/controllers/client.dart"; import "package:nexus/controllers/client_state.dart"; +import "package:nexus/controllers/member_list_opened.dart"; import "package:nexus/controllers/pinned_ids.dart"; import "package:nexus/controllers/power_level.dart"; import "package:nexus/controllers/rooms.dart"; @@ -46,9 +47,8 @@ class RoomChat extends HookConsumerWidget { final composerSize = useState(64); - final memberListOpened = useState(showMembersByDefault); - final userId = ref.watch(ClientStateController.provider)?.userId; + final memberListOpened = ref.watch(MemberListOpenedController.provider); final theme = Theme.of(context); final nothing = Center( @@ -448,7 +448,9 @@ class RoomChat extends HookConsumerWidget { isDesktop: isDesktop, onOpenDrawer: Scaffold.of(context).openDrawer, onOpenMemberList: (thisContext) { - memberListOpened.value = !memberListOpened.value; + ref + .watch(MemberListOpenedController.provider.notifier) + .set(!memberListOpened); Scaffold.of(thisContext).openEndDrawer(); }, onOpenPinnedMessagesList: () { @@ -553,7 +555,7 @@ class RoomChat extends HookConsumerWidget { ), ), - if (memberListOpened.value == true && showMembersByDefault) + if (memberListOpened == true && showMembersByDefault) MemberList(roomId), ], ), From 115bec5f055a9fa3892bc4d7f2ec95e5f5e43b9d Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Fri, 31 Jul 2026 11:55:48 -0400 Subject: [PATCH 021/176] slightly tweak readme [skip ci] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6eb021b..57b42d8 100644 --- a/README.md +++ b/README.md @@ -203,7 +203,7 @@ Development instructions can be found in [DEVELOPMENT.md](./DEVELOPMENT.md). ## Community -Join the [Nexus Client Matrix Room](https://matrix.to/#/#nexus:federated.nexus) for questions or help with developing or using Nexus Client. +Join the [Nexus Client Matrix room](https://matrix.to/#/#nexus:federated.nexus) for questions or help with developing or using Nexus Client. # Credits From 941e1c0e69aa1aa40936d4c63266fa9909a5e711 Mon Sep 17 00:00:00 2001 From: istalri Date: Sat, 1 Aug 2026 00:58:57 +0200 Subject: [PATCH 022/176] WIP: New Emoji Picker --- gomuks | 2 +- lib/controllers/emoji.dart | 145 +++++---- lib/models/{emoji.dart => gemoji.dart} | 12 +- lib/widgets/composer/composer.dart | 35 ++- lib/widgets/emoji_picker_button.dart | 66 ---- lib/widgets/emote_picker.dart | 399 +++++++++++++++++++++++++ lib/widgets/room_chat.dart | 24 +- 7 files changed, 543 insertions(+), 140 deletions(-) rename lib/models/{emoji.dart => gemoji.dart} (59%) delete mode 100644 lib/widgets/emoji_picker_button.dart create mode 100644 lib/widgets/emote_picker.dart diff --git a/gomuks b/gomuks index 1f11743..c06eb1c 160000 --- a/gomuks +++ b/gomuks @@ -1 +1 @@ -Subproject commit 1f11743884a64765b1444b250377a09ebcaba93c +Subproject commit c06eb1cbda2d49ff199a351e2d55df6ff7ab602b diff --git a/lib/controllers/emoji.dart b/lib/controllers/emoji.dart index 0c89896..f1a5c79 100644 --- a/lib/controllers/emoji.dart +++ b/lib/controllers/emoji.dart @@ -1,17 +1,47 @@ import "dart:convert"; -import "package:emoji_text_field/models/emoji_category.dart"; +import "package:collection/collection.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:flutter/foundation.dart"; import "package:flutter/material.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:http/http.dart"; -import "package:nexus/models/emoji.dart"; +import "package:nexus/models/gemoji.dart"; -typedef EmojiTuple = (IMap, IMap>); +class EmoteSection { + final String category; + final String label; + final IconData icon; + final List items; + final bool isRecent; -class EmojiController extends AsyncNotifier { + const EmoteSection({ + required this.category, + required this.label, + required this.icon, + required this.items, + this.isRecent = false, + }); +} + +class EmoteItem { + final String id; + final String display; + final List keywords; + final int useCounter; + final Image? customImage; + + const EmoteItem({ + required this.id, + required this.display, + required this.keywords, + required this.useCounter, + this.customImage, + }); +} + +class EmojiController extends AsyncNotifier> { @override - Future build() async { + Future> build() async { final response = await get( .https("github.com", "github/gemoji/raw/refs/heads/master/db/emoji.json"), ); @@ -20,69 +50,72 @@ class EmojiController extends AsyncNotifier { throw Exception("Failed to load emoji data"); } - return compute(_parseEmojiJson, response.body); + return compute(parseEmojiJson, response.body); } - static EmojiTuple _parseEmojiJson(String body) { + static IList parseEmojiJson(String body) { final data = json.decode(body) as List; - final entries = data + final allEntries = data .cast>() - .map(Emoji.fromJson) + .map(Gemoji.fromJson) .toIList(); - final categoryMap = entries.fold>>( - .new(), - (acc, entry) => acc.update( - entry.category, - (list) => list.add(entry.emoji), - ifAbsent: () => .new([entry.emoji]), - ), - ); + final groupedByCategory = groupBy(allEntries, (g) => g.category); - final keywordMap = entries.fold>>( + final result = groupedByCategory.entries.fold>( .new(), - (acc, entry) => acc.add( - entry.emoji, - .new([...entry.tags, ...entry.aliases, entry.description]), - ), - ); - - final customCategories = IMap.fromEntries( - categoryMap.entries.map( - (entry) => MapEntry( - entry.key, - EmojiCategory( - name: entry.key, - icon: switch (entry.key) { - "Smileys & Emotion" => Icons.emoji_emotions, - "People & Body" => Icons.emoji_people, - "Animals & Nature" => Icons.emoji_nature, - "Food & Drink" => Icons.emoji_food_beverage, - "Travel & Places" => Icons.travel_explore, - "Activities" => Icons.sports_soccer, - "Objects" => Icons.emoji_objects, - "Symbols" => Icons.emoji_symbols, - "Flags" => Icons.emoji_flags, - _ => Icons.category, - }, - emojis: entry.value.toList(growable: false), - ), + (resultList, entry) => resultList.add( + EmoteSection( + category: entry.key, + label: entry.key, + icon: getIconForCategory(entry.key), + items: entry.value + .map( + (gemoji) => EmoteItem( + id: gemoji.emoji, + display: gemoji.emoji, + keywords: [ + ...gemoji.tags, + ...gemoji.aliases, + ...gemoji.description.split(" "), + ], + useCounter: 0, + ), + ) + .toList(), + isRecent: false, ), ), ); - final customKeywords = IMap( - .fromEntries( - keywordMap.entries.map( - (e) => .new(e.key, e.value.toList(growable: false)), - ), - ), - ); - - return (customCategories, customKeywords); + return result; } - static final provider = AsyncNotifierProvider( - EmojiController.new, - ); + static final provider = + AsyncNotifierProvider>( + EmojiController.new, + ); + + static IconData getIconForCategory(String category) { + switch (category.toLowerCase()) { + case "smileys & emotion": + return Icons.sentiment_very_satisfied; + case "people & body": + return Icons.face; + case "food & drink": + return Icons.restaurant; + case "travel & places": + return Icons.flag; + case "activities": + return Icons.sports_soccer; + case "objects": + return Icons.lightbulb; + case "symbols": + return Icons.circle; + case "flags": + return Icons.flag; + default: + return Icons.emoji_emotions_outlined; + } + } } diff --git a/lib/models/emoji.dart b/lib/models/gemoji.dart similarity index 59% rename from lib/models/emoji.dart rename to lib/models/gemoji.dart index 8e4eac6..084a1ca 100644 --- a/lib/models/emoji.dart +++ b/lib/models/gemoji.dart @@ -1,17 +1,17 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:freezed_annotation/freezed_annotation.dart"; -part "emoji.freezed.dart"; -part "emoji.g.dart"; +part "gemoji.freezed.dart"; +part "gemoji.g.dart"; @freezed -abstract class Emoji with _$Emoji { - const factory Emoji({ +abstract class Gemoji with _$Gemoji { + const factory Gemoji({ required String emoji, required String category, required IList aliases, required String description, required IList tags, - }) = _Emoji; + }) = _Gemoji; - factory Emoji.fromJson(Map json) => _$EmojiFromJson(json); + factory Gemoji.fromJson(Map json) => _$GemojiFromJson(json); } diff --git a/lib/widgets/composer/composer.dart b/lib/widgets/composer/composer.dart index c63d939..281db0d 100644 --- a/lib/widgets/composer/composer.dart +++ b/lib/widgets/composer/composer.dart @@ -14,8 +14,8 @@ import "package:nexus/models/event.dart"; import "package:nexus/models/relation_type.dart"; import "package:nexus/widgets/composer/mention_overlay.dart"; import "package:nexus/widgets/composer/relation_preview.dart"; -import "package:nexus/widgets/emoji_picker_button.dart"; import "package:nexus/main.dart"; +import "package:nexus/widgets/emote_picker.dart"; class Composer extends HookConsumerWidget { final String roomId; @@ -123,10 +123,35 @@ class Composer extends HookConsumerWidget { ), ) ? [ - EmojiPickerButton( - context: context, - onSelection: (_) => node?.requestFocus(), - controller: controller.value, + IconButton( + icon: Icon(Icons.emoji_emotions), + tooltip: "Insert emoji", + onPressed: () { + showEmotePickerBottomSheet( + context: context, + roomId: roomId, + onSelect: (emojiId) { + final textController = controller.value; + final selection = textController.selection; + final newText = textController.text + .replaceRange( + selection.start, + selection.end, + emojiId, + ); + + textController.value = TextEditingValue( + text: newText, + selection: TextSelection.collapsed( + offset: + selection.start + emojiId.length, + ), + ); + + node?.requestFocus(); + }, + ); + }, ), PopupMenuButton( tooltip: "Add media", diff --git a/lib/widgets/emoji_picker_button.dart b/lib/widgets/emoji_picker_button.dart deleted file mode 100644 index 3516590..0000000 --- a/lib/widgets/emoji_picker_button.dart +++ /dev/null @@ -1,66 +0,0 @@ -import "package:emoji_text_field/emoji_text_field.dart"; -import "package:flutter/material.dart"; -import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:nexus/controllers/emoji.dart"; - -class EmojiPickerButton extends HookConsumerWidget { - final TextEditingController? controller; - final void Function(String emoji)? onSelection; - final VoidCallback? onPressed; - final BuildContext context; - const EmojiPickerButton({ - this.controller, - this.onPressed, - this.onSelection, - required this.context, - super.key, - }); - - @override - Widget build(_, WidgetRef ref) => IconButton( - onPressed: () async { - onPressed?.call(); - - final tempController = controller ?? TextEditingController(); - final shouldDispose = controller == null; - var hasPopped = false; - - void handler() { - if (tempController.text.isEmpty || hasPopped) return; - hasPopped = true; - - onSelection?.call(tempController.text); - - WidgetsBinding.instance.addPostFrameCallback((_) { - if (context.mounted) Navigator.of(context).maybePop(); - }); - } - - final emojis = await ref.watch(EmojiController.provider.future); - if (!context.mounted) { - if (shouldDispose) tempController.dispose(); - return; - } - - await showModalBottomSheet( - context: context, - builder: (sheetContext) => EmojiKeyboardView( - config: .new( - showRecentTab: false, - customCategories: emojis.$1.unlock, - customKeywords: emojis.$2.unlock, - backgroundColor: Theme.of( - sheetContext, - ).colorScheme.surfaceContainer, - height: 600, - ), - textController: tempController..addListener(handler), - ), - ); - - tempController.removeListener(handler); - if (shouldDispose) tempController.dispose(); - }, - icon: Icon(Icons.emoji_emotions), - ); -} diff --git a/lib/widgets/emote_picker.dart b/lib/widgets/emote_picker.dart new file mode 100644 index 0000000..881526c --- /dev/null +++ b/lib/widgets/emote_picker.dart @@ -0,0 +1,399 @@ +import "dart:math" as math; + +import "package:fast_immutable_collections/fast_immutable_collections.dart"; +import "package:flutter/material.dart"; +import "package:flutter/rendering.dart"; +import "package:flutter_hooks/flutter_hooks.dart"; +import "package:hooks_riverpod/hooks_riverpod.dart"; +import "package:nexus/controllers/emoji.dart"; + +class EmotePicker extends HookConsumerWidget { + final String? roomId; + final void Function(String emoteId) onSelect; + final VoidCallback? onClose; + + const EmotePicker({ + super.key, + this.roomId, + this.onClose, + required this.onSelect, + }); + + @override + Widget build(BuildContext context, WidgetRef ref) { + return Scaffold( + backgroundColor: Colors.transparent, + body: Container( + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surface, + borderRadius: BorderRadius.vertical(top: Radius.circular(16)), + ), + constraints: BoxConstraints( + maxHeight: MediaQuery.of(context).size.height * 0.6, + minHeight: math.min(MediaQuery.of(context).size.height * 0.6, 400), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + // Drag handle + Padding( + padding: EdgeInsets.symmetric(vertical: 8), + child: Container( + width: 40, + height: 4, + decoration: BoxDecoration( + color: Colors.grey.withValues(alpha: 0.3), + borderRadius: BorderRadius.circular(2), + ), + ), + ), + Divider(height: 1), + // Content + Expanded( + child: ListView( + children: [ + EmoteCategoryList( + roomId: roomId, + onSelect: onSelect, + fetchSections: (rid, query) => + fetchEmojiSections(ref, rid, query), + placeholderText: "emojis & emotes", + ), + ], + ), + ), + ], + ), + ), + ); + } +} + +class EmoteCategoryList extends HookWidget { + final String? roomId; + final void Function(String) onSelect; + final Future> Function(String? roomId, String query) + fetchSections; + final String placeholderText; + + const EmoteCategoryList({ + super.key, + required this.roomId, + required this.onSelect, + required this.fetchSections, + required this.placeholderText, + }); + + @override + Widget build(BuildContext context) { + final searchController = useTextEditingController(text: ""); + final searchFocus = useFocusNode(); + final searchText = useState(""); + + useEffect(() { + void listener() { + searchText.value = searchController.text; + } + + searchController.addListener(listener); + return () => searchController.removeListener(listener); + }, [searchController]); + + final isSearching = searchText.value.isNotEmpty; + final sectionsFuture = useMemoized( + () => fetchSections(roomId, searchText.value), + [searchText.value], + ); + final sectionsSnapshot = useFuture(sectionsFuture); + final sections = sectionsSnapshot.data ?? [].toIList(); + + final scrollController = useScrollController(); + + final sectionKeysMap = useState({}); + + final activeCategoryId = useState(null); + + useEffect(() { + if (sections.isEmpty) return null; + + bool active = true; + void listener() { + if (!active || !scrollController.hasClients) return; + + final scrollPixels = scrollController.offset; + String? current; + + for (final section in sections) { + final key = sectionKeysMap.value.putIfAbsent( + section.category, + () => GlobalKey(), + ); + if (key.currentContext?.findRenderObject() == null) continue; + + final ro = key.currentContext!.findRenderObject()!; + if (!ro.attached) continue; + + try { + final vp = RenderAbstractViewport.of(ro); + final reveal = vp.getOffsetToReveal(ro, 0.0).offset; + + if (reveal <= scrollPixels + 80) { + current = section.category; + } else { + break; + } + } catch (_) { + continue; + } + } + + if (current != null && current != activeCategoryId.value) { + activeCategoryId.value = current; + } + } + + scrollController.addListener(listener); + + WidgetsBinding.instance.addPostFrameCallback((_) { + if (active) listener(); + }); + + return () { + active = false; + scrollController.removeListener(listener); + }; + }, [sections, scrollController]); + + return Column( + children: [ + Padding( + padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8), + child: TextField( + controller: searchController, + focusNode: searchFocus, + decoration: InputDecoration( + hintText: "Search $placeholderText...", + prefixIcon: Icon(Icons.search), + suffixIcon: isSearching + ? IconButton( + icon: Icon(Icons.clear), + onPressed: () { + searchController.clear(); + searchFocus.requestFocus(); + }, + ) + : null, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ), + Expanded( + child: Row( + children: [ + if (!isSearching) ...[ + SizedBox( + width: 100, + child: ListView.builder( + itemCount: sections.length, + itemBuilder: (context, index) { + final section = sections[index]; + final isActive = + activeCategoryId.value == section.category; + + return Material( + color: Colors.transparent, + child: InkWell( + onTap: () { + activeCategoryId.value = section.category; + final key = sectionKeysMap.value[section.category]; + if (key?.currentContext != null) { + Scrollable.ensureVisible( + key!.currentContext!, + alignment: 0.0, + duration: const Duration(milliseconds: 250), + ); + } + }, + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 12, + vertical: 10, + ), + decoration: BoxDecoration( + border: Border( + left: BorderSide( + width: 2, + color: isActive + ? Theme.of(context).colorScheme.primary + : Colors.transparent, + ), + ), + color: isActive + ? Theme.of(context).colorScheme.primary + .withValues(alpha: 0.08) + : Colors.transparent, + ), + child: Text( + section.isRecent ? "Recent" : section.label, + style: TextStyle( + fontSize: 13, + fontWeight: isActive ? FontWeight.w600 : null, + color: isActive + ? Theme.of(context).colorScheme.primary + : Theme.of( + context, + ).colorScheme.onSurfaceVariant, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + ), + ); + }, + ), + ), + const VerticalDivider(width: 1), + ], + Expanded( + child: + sectionsSnapshot.connectionState == ConnectionState.waiting + ? const Center(child: CircularProgressIndicator()) + : sections.isEmpty + ? Center(child: Text("No $placeholderText found")) + : CustomScrollView( + controller: scrollController, + slivers: [ + for (final section in sections) ...[ + SliverToBoxAdapter( + key: sectionKeysMap.value.putIfAbsent( + section.category, + () => GlobalKey(), + ), + child: Container( + padding: const EdgeInsets.only( + left: 12, + top: 12, + bottom: 8, + ), + child: Text( + section.isRecent + ? "Recently Used" + : section.label, + style: TextStyle( + fontSize: 13, + fontWeight: FontWeight.w600, + color: Theme.of( + context, + ).colorScheme.onSurfaceVariant, + ), + ), + ), + ), + SliverPadding( + padding: const EdgeInsets.symmetric( + horizontal: 8, + ), + sliver: SliverGrid( + gridDelegate: + const SliverGridDelegateWithMaxCrossAxisExtent( + maxCrossAxisExtent: 44, + crossAxisSpacing: 4, + mainAxisSpacing: 4, + ), + delegate: SliverChildBuilderDelegate(( + context, + index, + ) { + final item = section.items[index]; + return GestureDetector( + onTap: () => onSelect(item.id), + child: Container( + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular( + 6, + ), + ), + child: Text( + item.display, + style: const TextStyle(fontSize: 24), + ), + ), + ); + }, childCount: section.items.length), + ), + ), + ], + const SliverPadding( + padding: EdgeInsets.only(bottom: 24), + ), + ], + ), + ), + ], + ), + ), + ], + ); + } +} + +Future> fetchEmojiSections( + WidgetRef ref, + String? roomId, + String query, +) async { + final emotes = await ref.watch(EmojiController.provider.future); + final q = query.toLowerCase(); + + if (q.isEmpty) { + return emotes; + } + + return emotes + .map((cat) { + final filtered = cat.items + .where( + (e) => + e.keywords.any((k) => k.contains(q)) || e.id.contains(query), + ) + .toList(); + return filtered.isNotEmpty + ? EmoteSection( + category: cat.category, + label: cat.label, + icon: cat.icon, + items: filtered, + isRecent: cat.isRecent, + ) + : null; + }) + .whereType() + .toIList(); +} + +Future showEmotePickerBottomSheet({ + required BuildContext context, + String? roomId, + required void Function(String) onSelect, +}) async { + await showModalBottomSheet( + context: context, + isScrollControlled: true, + backgroundColor: Colors.transparent, + useSafeArea: true, + enableDrag: true, + isDismissible: true, + constraints: BoxConstraints( + maxHeight: MediaQuery.of(context).size.height * 0.75, + maxWidth: 600, + ), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.vertical(top: Radius.circular(16)), + ), + builder: (context) => EmotePicker(roomId: roomId, onSelect: onSelect), + ); +} diff --git a/lib/widgets/room_chat.dart b/lib/widgets/room_chat.dart index 0fdd7c7..f679cf6 100644 --- a/lib/widgets/room_chat.dart +++ b/lib/widgets/room_chat.dart @@ -16,7 +16,7 @@ import "package:nexus/models/content/message.dart"; import "package:nexus/models/event.dart"; import "package:nexus/models/relation_type.dart"; import "package:nexus/widgets/composer/composer.dart"; -import "package:nexus/widgets/emoji_picker_button.dart"; +import "package:nexus/widgets/emote_picker.dart"; import "package:nexus/widgets/pinned_events_drawer.dart"; import "package:nexus/widgets/renderers/event.dart"; import "package:nexus/widgets/member_list.dart"; @@ -239,11 +239,23 @@ class RoomChat extends HookConsumerWidget { icon: Text(emoji), ), ), - EmojiPickerButton( - context: context, - onPressed: Navigator.of(context).pop, - onSelection: (emoji) => - notifier.sendReaction(emoji, event).onError(showError), + GestureDetector( + onTap: () { + Navigator.of(context).pop(); // Close popup menu + showEmotePickerBottomSheet( + context: context, + roomId: roomId, + onSelect: (emojiId) async { + await notifier + .sendReaction(emojiId, event) + .onError(showError); + }, + ); + }, + child: Padding( + padding: EdgeInsets.all(8), + child: Icon(Icons.emoji_emotions), + ), ), ], ), From f97c5548a3f5a7a65fbb3a092690090c61cf7b7c Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 4 Aug 2026 21:04:55 -0400 Subject: [PATCH 023/176] add invite blocking support plus msc4494 support To accomplish this I also reworked how account data is stored and added a method to fetch capabilities, and another method to set account data --- .gitmodules | 2 +- gomuks | 2 +- lib/controllers/account_data.dart | 22 +++++--- lib/controllers/client.dart | 8 +++ lib/controllers/settings_sections.dart | 50 +++++++++++++++++++ lib/controllers/spaces.dart | 4 +- lib/models/account_data.dart | 61 +++++++++++++++++++++-- lib/models/requests/set_account_data.dart | 15 ++++++ lib/models/spec_versions_response.dart | 25 ++++++++++ lib/models/sync_data.dart | 3 +- lib/widgets/room_chat.dart | 8 ++- 11 files changed, 176 insertions(+), 24 deletions(-) create mode 100644 lib/models/requests/set_account_data.dart create mode 100644 lib/models/spec_versions_response.dart diff --git a/.gitmodules b/.gitmodules index 145276a..d7c8fca 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "gomuks"] path = gomuks url = https://github.com/gomuks/gomuks - branch = main + branch = timedoutuk/versions-rpc diff --git a/gomuks b/gomuks index 0f8fb26..d382c66 160000 --- a/gomuks +++ b/gomuks @@ -1 +1 @@ -Subproject commit 0f8fb261ab57977fa24a4f63b7aafbb9a4ff1b7b +Subproject commit d382c664a04f3f202b86f859d1868fd4654a39e8 diff --git a/lib/controllers/account_data.dart b/lib/controllers/account_data.dart index 0926e08..c595565 100644 --- a/lib/controllers/account_data.dart +++ b/lib/controllers/account_data.dart @@ -1,16 +1,22 @@ +import "dart:convert"; + import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/models/account_data.dart"; -class AccountDataController extends Notifier> { +class AccountDataController extends Notifier { @override - IMap build() => .new(); + AccountData build() => .new(); - void update(IMap newData) => - state = .new({...state.unlock, ...newData.unlock}); + void update(IMap> newAccountData) => + state = .fromJson({ + ...json.decode(json.encode(state.toJson())), + ...newAccountData + .map((key, value) => MapEntry(key, value["content"])) + .unlock, + }); - static final provider = - NotifierProvider>( - AccountDataController.new, - ); + static final provider = NotifierProvider( + AccountDataController.new, + ); } diff --git a/lib/controllers/client.dart b/lib/controllers/client.dart index 97c3ed6..d0295ae 100644 --- a/lib/controllers/client.dart +++ b/lib/controllers/client.dart @@ -33,10 +33,12 @@ import "package:nexus/models/requests/redact_event.dart"; import "package:nexus/models/requests/report.dart"; import "package:nexus/models/requests/send_event.dart"; import "package:nexus/models/requests/send_message.dart"; +import "package:nexus/models/requests/set_account_data.dart"; 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/spec_versions_response.dart"; import "package:nexus/models/sync_data.dart"; import "package:nexus/src/third_party/gomuks.g.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; @@ -268,6 +270,9 @@ class ClientController extends AsyncNotifier { Future setMembership(SetMembershipRequest request) => _sendCommand("set_membership", request.toJson()); + Future setAccountData(SetAccountDataRequest request) => + _sendCommand("set_account_data", request.toJson()); + Future uploadMedia(UploadMediaRequest request) async => .fromJson(await _sendCommand("upload_media", request.toJson())); @@ -302,6 +307,9 @@ class ClientController extends AsyncNotifier { Future exchangeToken(OAuthExchangeTokenRequest request) async => await _sendCommand("oauth_exchange_token", request.toJson()); + Future getSpecVersions() async => + .fromJson(await _sendCommand("get_versions")); + Future discoverHomeserver(Uri homeserver) async { try { final response = await _sendCommand("discover_homeserver", { diff --git a/lib/controllers/settings_sections.dart b/lib/controllers/settings_sections.dart index 7c9796b..3c9a665 100644 --- a/lib/controllers/settings_sections.dart +++ b/lib/controllers/settings_sections.dart @@ -4,9 +4,11 @@ import "package:flutter/material.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:intl/intl.dart"; import "package:m3e_buttons/m3e_buttons.dart"; +import "package:nexus/controllers/account_data.dart"; import "package:nexus/controllers/client.dart"; import "package:nexus/controllers/client_state.dart"; import "package:nexus/controllers/settings.dart"; +import "package:nexus/models/account_data.dart"; import "package:nexus/models/settings_category.dart"; import "package:nexus/main.dart"; import "package:nexus/widgets/settings/dialog_list_tile.dart"; @@ -16,6 +18,9 @@ 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([ @@ -93,6 +98,51 @@ class SettingsSectionsController if (ref.watch(ClientStateController.provider)?.isLoggedIn == true) "Account": .new([ .new(title: "Profile", icon: Icons.person, settings: .new([])), + .new( + title: "Safety", + icon: Icons.gpp_good, + settings: .new([ + .new( + title: "Invite Blocking", + 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: InvitePermissionConfig.key, + content: InvitePermissionConfig( + defaultAction: value, + ), + ), + ) + .onError(showError), + ), + ), + icon: Icons.person_off, + ), + ]), + ), .new( title: "Other", icon: Icons.key, diff --git a/lib/controllers/spaces.dart b/lib/controllers/spaces.dart index 24113ad..60696da 100644 --- a/lib/controllers/spaces.dart +++ b/lib/controllers/spaces.dart @@ -84,9 +84,7 @@ class SpacesController extends Notifier> { ], }.nonNulls.toISet(); - final directMessages = IMap( - accountData["m.direct"]?.content ?? {}, - ).values.expand((e) => e).toISet(); + final directMessages = accountData.directMessages.values.flattened; final otherRooms = rooms.entries .where( diff --git a/lib/models/account_data.dart b/lib/models/account_data.dart index a325ffe..96ba6a7 100644 --- a/lib/models/account_data.dart +++ b/lib/models/account_data.dart @@ -1,16 +1,69 @@ +import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:freezed_annotation/freezed_annotation.dart"; part "account_data.freezed.dart"; part "account_data.g.dart"; @freezed abstract class AccountData with _$AccountData { + const AccountData._(); + static List? readRecentEmojiValue( + Map json, + String key, + ) => json[key]?["recent_emoji"]; + + static Map>? recentEmojiToJson( + IList recentEmoji, + ) => {"recent_emoji": recentEmoji.map((emoji) => emoji.toJson()).toList()}; + const factory AccountData({ - required String userId, - required String? roomId, - required String type, - required dynamic content, + @JsonKey(name: InvitePermissionConfig.key) + @Default(InvitePermissionConfig()) + InvitePermissionConfig invitePermissionConfig, + + @JsonKey(name: "m.direct") + @Default(IMap.empty()) + IMap> directMessages, + + @JsonKey( + name: "m.recent_emoji", + readValue: AccountData.readRecentEmojiValue, + toJson: AccountData.recentEmojiToJson, + ) + @Default(IList.empty()) + IList recentEmoji, }) = _AccountData; factory AccountData.fromJson(Map json) => _$AccountDataFromJson(json); } + +@freezed +abstract class InvitePermissionConfig with _$InvitePermissionConfig { + static const key = "m.invite_permission_config"; + + const factory InvitePermissionConfig({ + @JsonKey(unknownEnumValue: DefaultInviteAction.allow) + @Default(DefaultInviteAction.allow) + DefaultInviteAction defaultAction, + }) = _InvitePermissionConfig; + + factory InvitePermissionConfig.fromJson(Map json) => + _$InvitePermissionConfigFromJson(json); +} + +@freezed +abstract class RecentEmoji with _$RecentEmoji { + const factory RecentEmoji({required String emoji, required int total}) = + _RecentEmoji; + + factory RecentEmoji.fromJson(Map json) => + _$RecentEmojiFromJson(json); +} + +@JsonEnum(fieldRename: .snake) +enum DefaultInviteAction { + allow, + deny, + @JsonValue("uk.timedout.msc4494.deny_public") + denyPublic, +} diff --git a/lib/models/requests/set_account_data.dart b/lib/models/requests/set_account_data.dart new file mode 100644 index 0000000..ffccdb4 --- /dev/null +++ b/lib/models/requests/set_account_data.dart @@ -0,0 +1,15 @@ +import "package:freezed_annotation/freezed_annotation.dart"; +part "set_account_data.freezed.dart"; +part "set_account_data.g.dart"; + +@freezed +abstract class SetAccountDataRequest with _$SetAccountDataRequest { + const factory SetAccountDataRequest({ + required String type, + required dynamic content, + String? roomId, + }) = _SetAccountDataRequest; + + factory SetAccountDataRequest.fromJson(Map json) => + _$SetAccountDataRequestFromJson(json); +} diff --git a/lib/models/spec_versions_response.dart b/lib/models/spec_versions_response.dart new file mode 100644 index 0000000..07a3ada --- /dev/null +++ b/lib/models/spec_versions_response.dart @@ -0,0 +1,25 @@ +import "package:fast_immutable_collections/fast_immutable_collections.dart"; +import "package:freezed_annotation/freezed_annotation.dart"; +part "spec_versions_response.freezed.dart"; +part "spec_versions_response.g.dart"; + +@freezed +abstract class SpecVersionsResponse with _$SpecVersionsResponse { + const factory SpecVersionsResponse({ + required IList versions, + required UnstableFeatures unstableFeatures, + }) = _SpecVersionsResponse; + + factory SpecVersionsResponse.fromJson(Map json) => + _$SpecVersionsResponseFromJson(json); +} + +@freezed +abstract class UnstableFeatures with _$UnstableFeatures { + const factory UnstableFeatures({ + @JsonKey(name: "uk.timedout.msc4494") @Default(false) bool msc4494, + }) = _UnstableFeatures; + + factory UnstableFeatures.fromJson(Map json) => + _$UnstableFeaturesFromJson(json); +} diff --git a/lib/models/sync_data.dart b/lib/models/sync_data.dart index 0f98bb2..b2699d6 100644 --- a/lib/models/sync_data.dart +++ b/lib/models/sync_data.dart @@ -1,6 +1,5 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:freezed_annotation/freezed_annotation.dart"; -import "package:nexus/models/account_data.dart"; import "package:nexus/models/room.dart"; import "package:nexus/models/space_edge.dart"; part "sync_data.freezed.dart"; @@ -10,7 +9,7 @@ part "sync_data.g.dart"; abstract class SyncData with _$SyncData { const factory SyncData({ @Default(false) bool clearState, - @Default(IMap.empty()) IMap accountData, + @Default(IMap.empty()) IMap> accountData, @Default(IMap.empty()) IMap rooms, @Default(ISet.empty()) ISet leftRooms, // required IList invitedRooms, diff --git a/lib/widgets/room_chat.dart b/lib/widgets/room_chat.dart index b1f29c4..cb1e695 100644 --- a/lib/widgets/room_chat.dart +++ b/lib/widgets/room_chat.dart @@ -214,11 +214,9 @@ class RoomChat extends HookConsumerWidget { ...{ ...ref.watch( AccountDataController.provider.select( - (value) => IList( - value["m.recent_emoji"] - ?.content["recent_emoji"] ?? - [], - ).map((entry) => entry["emoji"]).toIList(), + (value) => value.recentEmoji + .map((entry) => entry.emoji) + .toIList(), ), ), "👍", From 82a0dd90b0b9716473aec1f4ae54f87ca89ab87b Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 4 Aug 2026 21:08:51 -0400 Subject: [PATCH 024/176] update gomuks hash --- linux/nix/pkg/gomuks.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/nix/pkg/gomuks.nix b/linux/nix/pkg/gomuks.nix index 9d7770b..ca94198 100644 --- a/linux/nix/pkg/gomuks.nix +++ b/linux/nix/pkg/gomuks.nix @@ -17,7 +17,7 @@ buildGoModule ( src = "${src}/gomuks"; - vendorHash = "sha256-4QU51WGiNKYm7z/ajnas2qQaMK5BgyHwPfmNpQvW0qg="; + vendorHash = "sha256-fnRuw+zt6Iofv0kqypx+jy1gLvOHTQvJsOwSKu7kGLs="; buildPhase = '' runHook preBuild From d1c2b2dd0a26b94a0f65238923cc131e6f073405 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 5 Aug 2026 16:00:55 -0400 Subject: [PATCH 025/176] show reactions inline in non-message events that are in bubbles, e.g. stickers Fixes #59. --- lib/widgets/renderers/event.dart | 5 ++++- lib/widgets/renderers/message.dart | 3 +-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/widgets/renderers/event.dart b/lib/widgets/renderers/event.dart index 2eb8bc3..a9c703a 100644 --- a/lib/widgets/renderers/event.dart +++ b/lib/widgets/renderers/event.dart @@ -213,7 +213,10 @@ class EventRenderer extends HookConsumerWidget { ), ...[ - if (event.content is! MessageContent) ReactionRow(event), + if (event.content is! MessageContent && + event.content is! StickerContent && + event.content is! EncryptedContent) + ReactionRow(event), if (event.sendError != null && event.sendError != "not sent") Padding( diff --git a/lib/widgets/renderers/message.dart b/lib/widgets/renderers/message.dart index 012dcc9..c684085 100644 --- a/lib/widgets/renderers/message.dart +++ b/lib/widgets/renderers/message.dart @@ -275,8 +275,6 @@ class MessageRenderer extends ConsumerWidget { case final UrlElement link?) if (Uri.tryParse(link.url) case final Uri url?) UrlPreview(url), - - ReactionRow(event), ], ], ), @@ -298,6 +296,7 @@ class MessageRenderer extends ConsumerWidget { ), _ => throw Exception("This is impossible"), }, + if (!textOnly) ReactionRow(event), ], ), ), From 1621e917c09ac90305876d4657a5dc9967fef3ab Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 5 Aug 2026 16:01:07 -0400 Subject: [PATCH 026/176] slight formatting change for video player --- lib/widgets/players/video.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/widgets/players/video.dart b/lib/widgets/players/video.dart index cd4e569..457cdc4 100644 --- a/lib/widgets/players/video.dart +++ b/lib/widgets/players/video.dart @@ -1,5 +1,4 @@ import "dart:async"; - import "package:flutter/material.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:nexus/controllers/client.dart"; From ae5b6e2b402231b07cf0ad0930660c01888b2b22 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 5 Aug 2026 16:28:47 -0400 Subject: [PATCH 027/176] bump gomuks, fix profile issues caused by this --- .gitmodules | 2 +- gomuks | 2 +- lib/controllers/client.dart | 8 ++--- lib/controllers/profile.dart | 10 +++--- lib/controllers/user.dart | 7 ++-- lib/models/event.dart | 2 +- .../{profile.dart => profile_response.dart} | 36 ++++++++++++++----- lib/widgets/user_bottom_sheet.dart | 13 +++---- 8 files changed, 50 insertions(+), 30 deletions(-) rename lib/models/{profile.dart => profile_response.dart} (52%) diff --git a/.gitmodules b/.gitmodules index d7c8fca..145276a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "gomuks"] path = gomuks url = https://github.com/gomuks/gomuks - branch = timedoutuk/versions-rpc + branch = main diff --git a/gomuks b/gomuks index d382c66..2d566a2 160000 --- a/gomuks +++ b/gomuks @@ -1 +1 @@ -Subproject commit d382c664a04f3f202b86f859d1868fd4654a39e8 +Subproject commit 2d566a2b585e2dba882714f7ca741a52afb36237 diff --git a/lib/controllers/client.dart b/lib/controllers/client.dart index d0295ae..aa8c3ae 100644 --- a/lib/controllers/client.dart +++ b/lib/controllers/client.dart @@ -24,7 +24,7 @@ import "package:nexus/models/requests/get_event.dart"; import "package:nexus/models/requests/get_related_events.dart"; import "package:nexus/models/requests/get_room_state.dart"; import "package:nexus/models/requests/join_room.dart"; -import "package:nexus/models/profile.dart"; +import "package:nexus/models/profile_response.dart"; import "package:nexus/models/requests/oauth/exchange_token.dart"; import "package:nexus/models/requests/oauth/get_auth_url.dart"; import "package:nexus/models/requests/oauth/register_client.dart"; @@ -259,10 +259,8 @@ class ClientController extends AsyncNotifier { Future paginate(PaginateRequest request) async => .fromJson(await _sendCommand("paginate", request.toJson())); - Future getProfile(String userId) async { - final json = await _sendCommand("get_profile", {"user_id": userId}); - return .fromJsonWithCatch({...json, "id": userId}); - } + Future getProfile(String userId) async => + .fromJson(await _sendCommand("get_profile", {"user_id": userId})); Future reportEvent(ReportRequest request) => _sendCommand("report_event", request.toJson()); diff --git a/lib/controllers/profile.dart b/lib/controllers/profile.dart index 32525a3..58fa49d 100644 --- a/lib/controllers/profile.dart +++ b/lib/controllers/profile.dart @@ -1,17 +1,19 @@ import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/controllers/client.dart"; -import "package:nexus/models/profile.dart"; +import "package:nexus/models/profile_response.dart"; -class ProfileController extends AsyncNotifier { +class ProfileController extends AsyncNotifier { final String userId; ProfileController(this.userId); @override - Future build() { + Future build() { final client = ref.watch(ClientController.provider.notifier); return client.getProfile(userId); } static final provider = AsyncNotifierProvider.family - .autoDispose(ProfileController.new); + .autoDispose( + ProfileController.new, + ); } diff --git a/lib/controllers/user.dart b/lib/controllers/user.dart index b366c88..c69ebd0 100644 --- a/lib/controllers/user.dart +++ b/lib/controllers/user.dart @@ -27,14 +27,15 @@ class UserController extends AsyncNotifier { return content; } - final profile = await ref.watch( + final profileResponse = await ref.watch( ProfileController.provider(config.userId).future, ); return .new( status: .leave, - avatarUrl: profile.avatarUrl, - displayName: profile.displayName ?? config.userId.localpart, + avatarUrl: profileResponse.profile.avatarUrl, + displayName: + profileResponse.profile.displayName ?? config.userId.localpart, ); } diff --git a/lib/models/event.dart b/lib/models/event.dart index c54dbc5..a5913f7 100644 --- a/lib/models/event.dart +++ b/lib/models/event.dart @@ -2,7 +2,7 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:freezed_annotation/freezed_annotation.dart"; import "package:nexus/models/content/content.dart"; import "package:nexus/models/epoch_date_time_converter.dart"; -import "package:nexus/models/profile.dart"; +import "package:nexus/models/profile_response.dart"; part "event.freezed.dart"; part "event.g.dart"; diff --git a/lib/models/profile.dart b/lib/models/profile_response.dart similarity index 52% rename from lib/models/profile.dart rename to lib/models/profile_response.dart index 6ae1e94..8b7b749 100644 --- a/lib/models/profile.dart +++ b/lib/models/profile_response.dart @@ -1,19 +1,37 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:freezed_annotation/freezed_annotation.dart"; import "package:nexus/models/content/membership.dart"; -part "profile.freezed.dart"; -part "profile.g.dart"; +part "profile_response.freezed.dart"; +part "profile_response.g.dart"; + +@freezed +abstract class ProfileResponse with _$ProfileResponse { + const factory ProfileResponse({ + @JsonKey(fromJson: Profile.fromJson) required Profile profile, + required Bio? bio, + }) = _ProfileResponse; + + factory ProfileResponse.fromJson(Map json) => + _$ProfileResponseFromJson(json); +} + +@freezed +abstract class Bio with _$Bio { + const factory Bio({required String html, String? editSource}) = _Bio; + + factory Bio.fromJson(Map json) => _$BioFromJson(json); +} @freezed abstract class Profile with _$Profile { - static Object? readPronouns(Map map, _) => - map["m.pronouns"] ?? map["io.fsky.nyx.pronouns"]; + static Object? readPronouns(Map map, String key) => + map[key] ?? map["io.fsky.nyx.pronouns"]; - static Object? readTimezone(Map map, _) => - map["m.tz"] ?? map["us.cloke.msc4175.tz"]; + static Object? readTimezone(Map map, String key) => + map[key] ?? map["us.cloke.msc4175.tz"]; const factory Profile({ - required String id, + String? id, String? parseError, Uri? avatarUrl, @@ -26,7 +44,7 @@ abstract class Profile with _$Profile { @JsonKey(readValue: Profile.readTimezone, name: "m.tz") String? timezone, @Default(IList.empty()) - @JsonKey(readValue: Profile.readPronouns, name: "io.fsky.nyx.pronouns") + @JsonKey(readValue: Profile.readPronouns, name: "m.pronouns") IList pronouns, }) = _Profile; @@ -37,7 +55,7 @@ abstract class Profile with _$Profile { try { return Profile.fromJson(json); } catch (error) { - return Profile(id: json["id"], parseError: error.toString()); + return Profile(parseError: error.toString()); } } } diff --git a/lib/widgets/user_bottom_sheet.dart b/lib/widgets/user_bottom_sheet.dart index 6f9f154..15a24a0 100644 --- a/lib/widgets/user_bottom_sheet.dart +++ b/lib/widgets/user_bottom_sheet.dart @@ -123,9 +123,10 @@ class UserBottomSheet extends ConsumerWidget { .watch(ProfileController.provider(userId)) .betterWhen( loading: () => Text(""), - data: (profile) => Column( + data: (profileResponse) => Column( children: [ - if (profile.timezone == null && profile.pronouns.isEmpty) + if (profileResponse.profile.timezone == null && + profileResponse.profile.pronouns.isEmpty) Text(""), Wrap( crossAxisAlignment: .center, @@ -133,7 +134,7 @@ class UserBottomSheet extends ConsumerWidget { spacing: 4, runSpacing: 4, children: [ - ...profile.pronouns + ...profileResponse.profile.pronouns .where( // TODO: Check system language (l10n) (pronoun) => pronoun.language == "en", @@ -157,8 +158,8 @@ class UserBottomSheet extends ConsumerWidget { ) .flattened, - if (profile.timezone != null) ...[ - if (profile.pronouns.isNotEmpty) + if (profileResponse.profile.timezone != null) ...[ + if (profileResponse.profile.pronouns.isNotEmpty) SizedBox( height: 16, child: VerticalDivider( @@ -168,7 +169,7 @@ class UserBottomSheet extends ConsumerWidget { ), ), Text( - profile.timezone!, + profileResponse.profile.timezone!, textAlign: .center, style: textTheme.titleSmall?.copyWith( color: theme.colorScheme.onSurfaceVariant, From 83e80842139eb3bddab0a7c359294fe659b720a3 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 8 Aug 2026 11:31:07 -0400 Subject: [PATCH 028/176] catch parsing errors for invalid replies --- lib/models/event.dart | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/models/event.dart b/lib/models/event.dart index a5913f7..28bf0ae 100644 --- a/lib/models/event.dart +++ b/lib/models/event.dart @@ -17,6 +17,14 @@ abstract class Event with _$Event { return content["m.new_content"] ?? content; } + static String? replyToFromJson(Map json) { + try { + return json["m.relates_to"]?["m.in_reply_to"]?["event_id"]; + } catch (_) { + return null; + } + } + const factory Event({ @JsonKey(name: "rowid") required int rowId, @JsonKey(name: "timeline_rowid") required int timelineRowId, @@ -45,9 +53,7 @@ abstract class Event with _$Event { factory Event.fromJson(Map json) => _$EventFromJson(json).copyWith( - replyTo: getContentFromJson( - json, - )["m.relates_to"]?["m.in_reply_to"]?["event_id"], + replyTo: replyToFromJson(getContentFromJson(json)), pmp: json["content"]?["com.beeper.per_message_profile"] == null ? null : Profile.fromJsonWithCatch( From cf89604ff55ba6a6d2b02660d5b5718f9ceb9f3f Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 8 Aug 2026 13:21:29 -0400 Subject: [PATCH 029/176] update gomuks Fixes error when fetching versions after login --- gomuks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gomuks b/gomuks index 2d566a2..9444dd2 160000 --- a/gomuks +++ b/gomuks @@ -1 +1 @@ -Subproject commit 2d566a2b585e2dba882714f7ca741a52afb36237 +Subproject commit 9444dd293664c300c6e710bb6cddcd9c6cab365d From e32941f062f51599e6857c1383a4a52573dc24b4 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 8 Aug 2026 13:22:51 -0400 Subject: [PATCH 030/176] remove old extraEnv for macos No longer needed. --- hook/build.dart | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/hook/build.dart b/hook/build.dart index 625201d..984f8c6 100644 --- a/hook/build.dart +++ b/hook/build.dart @@ -19,17 +19,7 @@ Future main(List args) => build(args, (input, output) async { break; case OS.macOS: libFileName = "libgomuks.dylib"; - extraEnv = { - "SDKROOT": await getXCodeSDK(), - "CGO_ENABLED": "1", - "GOARCH": switch (targetArch) { - Architecture.arm64 => "arm64", - Architecture.x64 => "amd64", - _ => throw UnsupportedError( - "Unsupported macOS architecture: $targetArch", - ), - }, - }; + extraEnv = {"SDKROOT": await getXCodeSDK()}; break; case OS.windows: libFileName = "libgomuks.dll"; From 76f9175857a730a4371055c1af86048e0650302b Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 8 Aug 2026 13:27:10 -0400 Subject: [PATCH 031/176] update gomuks vendorHash --- linux/nix/pkg/gomuks.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/nix/pkg/gomuks.nix b/linux/nix/pkg/gomuks.nix index ca94198..ffa9d7c 100644 --- a/linux/nix/pkg/gomuks.nix +++ b/linux/nix/pkg/gomuks.nix @@ -17,7 +17,7 @@ buildGoModule ( src = "${src}/gomuks"; - vendorHash = "sha256-fnRuw+zt6Iofv0kqypx+jy1gLvOHTQvJsOwSKu7kGLs="; + vendorHash = "sha256-C03ss88QAnmZu+XxoHhc1M/261xFl8hR/pzLbU37Qe8="; buildPhase = '' runHook preBuild From 2afd5ae258dfcf641f503459c6a0bf37fb1115af Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 8 Aug 2026 16:14:11 -0400 Subject: [PATCH 032/176] put account data keys in model --- lib/controllers/settings_sections.dart | 2 +- lib/models/account_data.dart | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/controllers/settings_sections.dart b/lib/controllers/settings_sections.dart index 3c9a665..37e6284 100644 --- a/lib/controllers/settings_sections.dart +++ b/lib/controllers/settings_sections.dart @@ -130,7 +130,7 @@ class SettingsSectionsController .watch(ClientController.provider.notifier) .setAccountData( .new( - type: InvitePermissionConfig.key, + type: AccountData.invitePermissionConfigKey, content: InvitePermissionConfig( defaultAction: value, ), diff --git a/lib/models/account_data.dart b/lib/models/account_data.dart index 96ba6a7..7df7459 100644 --- a/lib/models/account_data.dart +++ b/lib/models/account_data.dart @@ -15,17 +15,21 @@ abstract class AccountData with _$AccountData { IList recentEmoji, ) => {"recent_emoji": recentEmoji.map((emoji) => emoji.toJson()).toList()}; + static const invitePermissionConfigKey = "m.invite_permission_config"; + static const directKey = "m.direct"; + static const recentEmojiKey = "m.recent_emoji"; + const factory AccountData({ - @JsonKey(name: InvitePermissionConfig.key) + @JsonKey(name: AccountData.invitePermissionConfigKey) @Default(InvitePermissionConfig()) InvitePermissionConfig invitePermissionConfig, - @JsonKey(name: "m.direct") + @JsonKey(name: AccountData.directKey) @Default(IMap.empty()) IMap> directMessages, @JsonKey( - name: "m.recent_emoji", + name: AccountData.recentEmojiKey, readValue: AccountData.readRecentEmojiValue, toJson: AccountData.recentEmojiToJson, ) @@ -39,8 +43,6 @@ abstract class AccountData with _$AccountData { @freezed abstract class InvitePermissionConfig with _$InvitePermissionConfig { - static const key = "m.invite_permission_config"; - const factory InvitePermissionConfig({ @JsonKey(unknownEnumValue: DefaultInviteAction.allow) @Default(DefaultInviteAction.allow) From bd185824f9127e8dbd572820c61e1b019672091d Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 8 Aug 2026 16:18:54 -0400 Subject: [PATCH 033/176] set loading when waiting for token exchange --- lib/pages/select_server.dart | 41 ++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/lib/pages/select_server.dart b/lib/pages/select_server.dart index f7cefb8..853e5fc 100644 --- a/lib/pages/select_server.dart +++ b/lib/pages/select_server.dart @@ -60,27 +60,32 @@ class SelectServerPage extends HookConsumerWidget { AppLinks().uriLinkStream.listen((encodedUri) async { final state = encodedUri.queryParameters["state"]; if (state != codeResponse.state) return; + isLoading.value = true; - final code = encodedUri.queryParameters["code"]; + try { + final code = encodedUri.queryParameters["code"]; - if (code != null) { - await ref - .watch(ClientController.provider.notifier) - .exchangeToken( - .new( - homeserverUrl: newUrl, - codeVerifier: codeResponse.codeVerifier, - redirectUri: .new( - scheme: "nexus.federated.nexus", - path: "/", + if (code != null) { + await ref + .watch(ClientController.provider.notifier) + .exchangeToken( + .new( + homeserverUrl: newUrl, + codeVerifier: codeResponse.codeVerifier, + redirectUri: .new( + scheme: "nexus.federated.nexus", + path: "/", + ), + code: code, + clientId: await ref.watch( + ClientIdController.provider(newUrl).future, + ), ), - code: code, - clientId: await ref.watch( - ClientIdController.provider(newUrl).future, - ), - ), - ) - .onError(showError); + ) + .onError(showError); + } + } finally { + isLoading.value = false; } }); } From bf31f5510a200bc2b25082e4e3a123c922a404f8 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 8 Aug 2026 16:21:58 -0400 Subject: [PATCH 034/176] make room dialog scrollable --- lib/widgets/room_appbar.dart | 80 +++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/lib/widgets/room_appbar.dart b/lib/widgets/room_appbar.dart index 93eca85..69eafaa 100644 --- a/lib/widgets/room_appbar.dart +++ b/lib/widgets/room_appbar.dart @@ -40,48 +40,52 @@ class RoomAppbar extends ConsumerWidget implements PreferredSizeWidget { constraints: .loose(.fromWidth(400)), child: Padding( padding: .all(24), - child: Column( - mainAxisSize: .min, - crossAxisAlignment: .start, - spacing: 8, - children: [ - Row( - spacing: 12, - mainAxisSize: .min, - children: [ - if (room.metadata?.avatar != null) - ExpandableImage( - room.metadata?.avatar == null - ? null - : .new(mxc: room.metadata!.avatar!), - child: AvatarOrHash( - room.metadata?.avatar, + child: SingleChildScrollView( + child: Column( + mainAxisSize: .min, + crossAxisAlignment: .start, + spacing: 8, + children: [ + Row( + spacing: 12, + mainAxisSize: .min, + children: [ + if (room.metadata?.avatar != null) + ExpandableImage( + room.metadata?.avatar == null + ? null + : .new(mxc: room.metadata!.avatar!), + child: AvatarOrHash( + room.metadata?.avatar, + room.metadata?.name ?? "Unnamed Room", + height: 64, + fallback: Icon(Icons.numbers), + ), + ), + Expanded( + child: Text( room.metadata?.name ?? "Unnamed Room", - height: 64, - fallback: Icon(Icons.numbers), - ), - ), - Expanded( - child: Text( - room.metadata?.name ?? "Unnamed Room", - overflow: .ellipsis, - maxLines: 3, - style: Theme.of(context).textTheme.headlineSmall, - ), - ), - ], - ), - if (room.metadata?.topic?.isNotEmpty == true) - LinkifiedText( - room.metadata!.topic!, - style: Theme.of(context).textTheme.bodyLarge - ?.copyWith( - color: Theme.of( + overflow: .ellipsis, + maxLines: 3, + style: Theme.of( context, - ).colorScheme.onSurfaceVariant, + ).textTheme.headlineSmall, ), + ), + ], ), - ], + if (room.metadata?.topic?.isNotEmpty == true) + LinkifiedText( + room.metadata!.topic!, + style: Theme.of(context).textTheme.bodyLarge + ?.copyWith( + color: Theme.of( + context, + ).colorScheme.onSurfaceVariant, + ), + ), + ], + ), ), ), ), From 7bb4d876382034e1e6a0fd015c7c0a38e32217f2 Mon Sep 17 00:00:00 2001 From: Erwan Leboucher Date: Sat, 8 Aug 2026 16:35:56 -0400 Subject: [PATCH 035/176] feat: Add iOS platform support (#60) Co-authored-by: Henry-Hiles Reviewed-on: https://git.federated.nexus/Nexus/nexus/pulls/60 --- .github/workflows/ios.yml | 39 + .github/workflows/macos.yml | 7 +- .metadata | 12 +- altstore-source.json | 22 + hook/build.dart | 79 +- ios/.gitignore | 34 + ios/Flutter/AppFrameworkInfo.plist | 24 + ios/Flutter/Debug.xcconfig | 2 + ios/Flutter/Release.xcconfig | 2 + ios/Podfile | 43 + ios/Podfile.lock | 28 + ios/Runner.xcodeproj/project.pbxproj | 759 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/WorkspaceSettings.xcsettings | 8 + .../xcshareddata/xcschemes/Runner.xcscheme | 119 +++ .../contents.xcworkspacedata | 10 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/WorkspaceSettings.xcsettings | 8 + ios/Runner/AppDelegate.swift | 16 + .../AppIcon.appiconset/Contents.json | 1 + .../Icon-App-1024x1024@1x.png | Bin 0 -> 67996 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 0 -> 712 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 0 -> 1471 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 0 -> 2303 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 0 -> 1079 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 0 -> 2235 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 0 -> 3461 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 0 -> 1471 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 0 -> 3498 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 0 -> 4981 bytes .../AppIcon.appiconset/Icon-App-50x50@1x.png | Bin 0 -> 1884 bytes .../AppIcon.appiconset/Icon-App-50x50@2x.png | Bin 0 -> 3994 bytes .../AppIcon.appiconset/Icon-App-57x57@1x.png | Bin 0 -> 2149 bytes .../AppIcon.appiconset/Icon-App-57x57@2x.png | Bin 0 -> 4667 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 0 -> 4981 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 0 -> 7807 bytes .../AppIcon.appiconset/Icon-App-72x72@1x.png | Bin 0 -> 2955 bytes .../AppIcon.appiconset/Icon-App-72x72@2x.png | Bin 0 -> 6046 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 0 -> 3219 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 0 -> 6372 bytes .../Icon-App-83.5x83.5@2x.png | Bin 0 -> 7088 bytes .../LaunchImage.imageset/Contents.json | 23 + .../LaunchImage.imageset/LaunchImage.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/LaunchImage@2x.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/LaunchImage@3x.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/README.md | 5 + ios/Runner/Base.lproj/LaunchScreen.storyboard | 37 + ios/Runner/Base.lproj/Main.storyboard | 26 + ios/Runner/Info.plist | 79 ++ ios/Runner/Runner-Bridging-Header.h | 1 + ios/Runner/SceneDelegate.swift | 6 + ios/RunnerTests/RunnerTests.swift | 12 + ios/scripts/lipo | 15 + lib/controllers/client.dart | 2 +- lib/helpers/extensions/get_xcode_sdk.dart | 11 +- macos/Flutter/Flutter-Debug.xcconfig | 1 + macos/Flutter/Flutter-Release.xcconfig | 1 + macos/Podfile | 42 + macos/Podfile.lock | 28 + macos/Runner.xcodeproj/project.pbxproj | 126 ++- .../xcshareddata/xcschemes/Runner.xcscheme | 18 + .../contents.xcworkspacedata | 3 + macos/scripts/lipo | 15 + pubspec.lock | 68 +- scripts/generate.dart | 2 +- 66 files changed, 1699 insertions(+), 58 deletions(-) create mode 100644 .github/workflows/ios.yml create mode 100644 altstore-source.json create mode 100644 ios/.gitignore create mode 100644 ios/Flutter/AppFrameworkInfo.plist create mode 100644 ios/Flutter/Debug.xcconfig create mode 100644 ios/Flutter/Release.xcconfig create mode 100644 ios/Podfile create mode 100644 ios/Podfile.lock create mode 100644 ios/Runner.xcodeproj/project.pbxproj create mode 100644 ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme create mode 100644 ios/Runner.xcworkspace/contents.xcworkspacedata create mode 100644 ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 ios/Runner/AppDelegate.swift create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png create mode 100644 ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json create mode 100644 ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png create mode 100644 ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png create mode 100644 ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png create mode 100644 ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md create mode 100644 ios/Runner/Base.lproj/LaunchScreen.storyboard create mode 100644 ios/Runner/Base.lproj/Main.storyboard create mode 100644 ios/Runner/Info.plist create mode 100644 ios/Runner/Runner-Bridging-Header.h create mode 100644 ios/Runner/SceneDelegate.swift create mode 100644 ios/RunnerTests/RunnerTests.swift create mode 100755 ios/scripts/lipo create mode 100644 macos/Podfile create mode 100644 macos/Podfile.lock create mode 100755 macos/scripts/lipo diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml new file mode 100644 index 0000000..015cd13 --- /dev/null +++ b/.github/workflows/ios.yml @@ -0,0 +1,39 @@ +name: "Build iOS App" + +on: + push: + branches: ["main"] + tags: ["*"] + workflow_dispatch: + +jobs: + build-app: + runs-on: macos-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + submodules: recursive + + - name: Lix GHA Installer Action + uses: samueldr/lix-gha-installer-action@v2026-02-22 + with: + extra_nix_config: experimental-features = nix-command flakes flake-self-attrs + + - name: Build app + run: nix develop --command bash -c "flutter pub get && dart scripts/generate.dart && flutter pub run build_runner build && flutter build ios --release --no-codesign" + + # Unsigned IPA: SideStore/AltStore re-sign this on-device with the + # user's own Apple ID at install time, so no certificate is needed here. + - name: Package unsigned IPA + run: | + mkdir Payload + cp -r build/ios/iphoneos/Runner.app Payload/ + zip -r Nexus.ipa Payload + + - name: Upload IPA artifact + uses: actions/upload-artifact@v6 + with: + name: Nexus.ipa + path: Nexus.ipa diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 8ed63cf..e7040fa 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -1,10 +1,9 @@ name: "Build MacOS App" on: - # TODO: Uncomment this once the MacOS workflow actually works - # push: - # branches: ["main"] - # tags: ["*"] + push: + branches: ["main"] + tags: ["*"] workflow_dispatch: jobs: diff --git a/.metadata b/.metadata index 1be1841..f12453b 100644 --- a/.metadata +++ b/.metadata @@ -4,7 +4,7 @@ # This file should be version controlled and should not be manually edited. version: - revision: "nixpkgs000000000000000000000000000000000" + revision: "6b182d2c7585eba26d4edce0f97630effd256c33" channel: "stable" project_type: app @@ -13,11 +13,11 @@ project_type: app migration: platforms: - platform: root - create_revision: nixpkgs000000000000000000000000000000000 - base_revision: nixpkgs000000000000000000000000000000000 - - platform: macos - create_revision: nixpkgs000000000000000000000000000000000 - base_revision: nixpkgs000000000000000000000000000000000 + create_revision: 6b182d2c7585eba26d4edce0f97630effd256c33 + base_revision: 6b182d2c7585eba26d4edce0f97630effd256c33 + - platform: ios + create_revision: 6b182d2c7585eba26d4edce0f97630effd256c33 + base_revision: 6b182d2c7585eba26d4edce0f97630effd256c33 # User provided section diff --git a/altstore-source.json b/altstore-source.json new file mode 100644 index 0000000..4471fb6 --- /dev/null +++ b/altstore-source.json @@ -0,0 +1,22 @@ +{ + "name": "Nexus", + "identifier": "nexus.federated.nexus.source", + "subtitle": "Nexus for iOS", + "description": "Nexus iOS builds for AltStore and SideStore.", + "iconURL": "https://git.federated.nexus/Nexus/nexus/raw/branch/main/assets/icon.png", + "website": "https://git.federated.nexus/Nexus/nexus", + "apps": [ + { + "name": "Nexus", + "bundleIdentifier": "nexus.federated.nexus", + "developerName": "Nexus", + "subtitle": "A Matrix client", + "localizedDescription": "Nexus for iOS. Unsigned builds, resigned at install by AltStore/SideStore.", + "iconURL": "https://git.federated.nexus/Nexus/nexus/raw/branch/main/assets/icon.png", + "category": "social", + "screenshots": [], + "versions": [] + } + ], + "news": [] +} diff --git a/hook/build.dart b/hook/build.dart index 984f8c6..4c89389 100644 --- a/hook/build.dart +++ b/hook/build.dart @@ -13,13 +13,42 @@ Future main(List args) => build(args, (input, output) async { String libFileName; Map extraEnv = {}; + IOSSdk? iosSdk; + String? iosSdkPath; + String? iosTargetTriple; switch (targetOS) { case OS.linux: libFileName = "libgomuks.so"; break; + case OS.iOS: + // Go only supports buildmode=c-archive for ios, not c-shared, so the + // archive built below gets linked into a dylib via a separate clang + // invocation before being registered as a normal asset like macOS. + libFileName = "libgomuks.dylib"; + final iosConfig = codeConfig.iOS; + iosSdk = iosConfig.targetSdk; + final minVersion = iosConfig.targetVersion; + iosSdkPath = await getXCodeTool(sdkType: iosSdk.type); + final archTriple = switch (targetArch) { + Architecture.arm64 => "arm64", + Architecture.x64 => "x86_64", + _ => throw UnsupportedError( + "Unsupported iOS architecture: $targetArch", + ), + }; + iosTargetTriple = iosSdk == IOSSdk.iPhoneSimulator + ? "$archTriple-apple-ios$minVersion.0-simulator" + : "$archTriple-apple-ios$minVersion.0"; + extraEnv = { + "GOOS": "ios", + "CC": await getXCodeTool(sdkType: iosSdk.type, findTool: "clang"), + "CGO_CFLAGS": "-isysroot $iosSdkPath -target $iosTargetTriple", + "CGO_LDFLAGS": "-isysroot $iosSdkPath -target $iosTargetTriple", + }; + break; case OS.macOS: libFileName = "libgomuks.dylib"; - extraEnv = {"SDKROOT": await getXCodeSDK()}; + extraEnv = {"SDKROOT": await getXCodeTool()}; break; case OS.windows: libFileName = "libgomuks.dll"; @@ -86,15 +115,26 @@ Future main(List args) => build(args, (input, output) async { final tags = [ "sqlite_fts5", "goolm", - // goheif/dav1d is not supported on Android, would need to be fixed upstream - if (targetOS == OS.android) "noheic", + // goheif/dav1d is not supported on Android or iOS, would need to be fixed upstream + if (targetOS == OS.android || targetOS == OS.iOS) "noheic", ].join(","); + + final archiveFile = targetOS == OS.iOS + ? buildDir.resolve("${targetArch.name}/libgomuks.a") + : libFile; print( - "Building Gomuks shared library $libFileName (${targetOS.name}/${targetArch.name}) to ${libFile.path}...", + "Building Gomuks shared library $libFileName (${targetOS.name}/${targetArch.name}) to ${archiveFile.path}...", ); final result = await Process.run( "go", - ["build", "-tags", tags, "-o", libFile.path, "-buildmode=c-shared"], + [ + "build", + "-tags", + tags, + "-o", + archiveFile.path, + "-buildmode=${targetOS == OS.iOS ? "c-archive" : "c-shared"}", + ], workingDirectory: gomuksBuildDir.resolve("pkg/ffi/").toFilePath(), environment: { "CGO_ENABLED": "1", @@ -114,6 +154,35 @@ Future main(List args) => build(args, (input, output) async { "Failed to build Gomuks shared library\n${result.stderr}", ); } + + if (targetOS == OS.iOS) { + print("Linking $archiveFile into $libFile..."); + final linkResult = await Process.run("xcrun", [ + "--sdk", + iosSdk!.type, + "clang", + "-dynamiclib", + "-isysroot", + iosSdkPath!, + "-target", + iosTargetTriple!, + "-install_name", + "@rpath/libgomuks.dylib", + "-framework", + "Security", + "-framework", + "CoreFoundation", + "-framework", + "SystemConfiguration", + "-force_load", + archiveFile.path, + "-o", + libFile.path, + ]); + if (linkResult.exitCode != 0) { + throw Exception("Failed to link Gomuks dylib\n${linkResult.stderr}"); + } + } } final generatedFile = "src/third_party/gomuks.g.dart"; diff --git a/ios/.gitignore b/ios/.gitignore new file mode 100644 index 0000000..7a7f987 --- /dev/null +++ b/ios/.gitignore @@ -0,0 +1,34 @@ +**/dgph +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/ephemeral/ +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..391a902 --- /dev/null +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + + diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..ec97fc6 --- /dev/null +++ b/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..c4855bf --- /dev/null +++ b/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/ios/Podfile b/ios/Podfile new file mode 100644 index 0000000..620e46e --- /dev/null +++ b/ios/Podfile @@ -0,0 +1,43 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '13.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) + target 'RunnerTests' do + inherit! :search_paths + end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/ios/Podfile.lock b/ios/Podfile.lock new file mode 100644 index 0000000..b29d5cb --- /dev/null +++ b/ios/Podfile.lock @@ -0,0 +1,28 @@ +PODS: + - Flutter (1.0.0) + - media_kit_libs_ios_video (1.0.4): + - Flutter + - media_kit_video (0.0.1): + - Flutter + +DEPENDENCIES: + - Flutter (from `Flutter`) + - media_kit_libs_ios_video (from `.symlinks/plugins/media_kit_libs_ios_video/ios`) + - media_kit_video (from `.symlinks/plugins/media_kit_video/ios`) + +EXTERNAL SOURCES: + Flutter: + :path: Flutter + media_kit_libs_ios_video: + :path: ".symlinks/plugins/media_kit_libs_ios_video/ios" + media_kit_video: + :path: ".symlinks/plugins/media_kit_video/ios" + +SPEC CHECKSUMS: + Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 + media_kit_libs_ios_video: 5a18affdb97d1f5d466dc79988b13eff6c5e2854 + media_kit_video: 1746e198cb697d1ffb734b1d05ec429d1fcd1474 + +PODFILE CHECKSUM: 3c63482e143d1b91d2d2560aee9fb04ecc74ac7e + +COCOAPODS: 1.17.0 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..57b889d --- /dev/null +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,759 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 2ADFEE6C745FFB2100CC9AFD /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8156A45F510382D558AED93A /* Pods_RunnerTests.framework */; }; + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */; }; + 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; }; + 88D55A5F1C7625122EBEE29D /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 82F9A3759658343C81A0EA4C /* Pods_Runner.framework */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 97C146E61CF9000F007C117D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 97C146ED1CF9000F007C117D; + remoteInfo = Runner; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 22DE4310DAFBE211CDF700B1 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; + 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 363A89F6FA09BCCBDED440CE /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 63516CF65A79A5DDDE64B0D1 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 8156A45F510382D558AED93A /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 82F9A3759658343C81A0EA4C /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + AEB96D8976BD46D6860C7041 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + B8B599FDB72E4713FB7B5A44 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; + FE5E4162842555A83F8A7FD7 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8C0A36760DA8B873D8F6DDCE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 2ADFEE6C745FFB2100CC9AFD /* Pods_RunnerTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */, + 88D55A5F1C7625122EBEE29D /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1CFFAE23B502BCCEB2B191A3 /* Pods */ = { + isa = PBXGroup; + children = ( + AEB96D8976BD46D6860C7041 /* Pods-Runner.debug.xcconfig */, + 363A89F6FA09BCCBDED440CE /* Pods-Runner.release.xcconfig */, + 22DE4310DAFBE211CDF700B1 /* Pods-Runner.profile.xcconfig */, + B8B599FDB72E4713FB7B5A44 /* Pods-RunnerTests.debug.xcconfig */, + FE5E4162842555A83F8A7FD7 /* Pods-RunnerTests.release.xcconfig */, + 63516CF65A79A5DDDE64B0D1 /* Pods-RunnerTests.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; + 331C8082294A63A400263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C807B294A618700263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; + 594EB1F65336CF9C7958F6FA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 82F9A3759658343C81A0EA4C /* Pods_Runner.framework */, + 8156A45F510382D558AED93A /* Pods_RunnerTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 331C8082294A63A400263BE5 /* RunnerTests */, + 1CFFAE23B502BCCEB2B191A3 /* Pods */, + 594EB1F65336CF9C7958F6FA /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + 331C8081294A63A400263BE5 /* RunnerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 331C8080294A63A400263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + EE82EC529EB6C0F1FA480659 /* [CP] Check Pods Manifest.lock */, + 331C807D294A63A400263BE5 /* Sources */, + 331C807F294A63A400263BE5 /* Resources */, + 8C0A36760DA8B873D8F6DDCE /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 331C8086294A63A400263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 0830C6758DA3ECA81FB12386 /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 1D165FDFB9D0D939B041966D /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + packageProductDependencies = ( + 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */, + ); + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 1510; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 331C8080294A63A400263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 97C146ED1CF9000F007C117D; + }; + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + packageReferences = ( + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */, + ); + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + 331C8080294A63A400263BE5 /* RunnerTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 331C807F294A63A400263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 0830C6758DA3ECA81FB12386 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 1D165FDFB9D0D939B041966D /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "export PATH=\"$PROJECT_DIR/scripts:$PATH\"\n/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "export PATH=\"$PROJECT_DIR/scripts:$PATH\"\n/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; + EE82EC529EB6C0F1FA480659 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 331C807D294A63A400263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + 7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 97C146ED1CF9000F007C117D /* Runner */; + targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = PK66NJM372; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = nexus.federated.nexus; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 331C8088294A63A400263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B8B599FDB72E4713FB7B5A44 /* Pods-RunnerTests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = nexus.federated.nexus.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Debug; + }; + 331C8089294A63A400263BE5 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = FE5E4162842555A83F8A7FD7 /* Pods-RunnerTests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = nexus.federated.nexus.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Release; + }; + 331C808A294A63A400263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 63516CF65A79A5DDDE64B0D1 /* Pods-RunnerTests.profile.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = nexus.federated.nexus.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = PK66NJM372; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = nexus.federated.nexus; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = PK66NJM372; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = nexus.federated.nexus; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C8088294A63A400263BE5 /* Debug */, + 331C8089294A63A400263BE5 /* Release */, + 331C808A294A63A400263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCLocalSwiftPackageReference section */ + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; + }; +/* End XCLocalSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */ = { + isa = XCSwiftPackageProductDependency; + productName = FlutterGeneratedPluginSwiftPackage; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..c3fedb2 --- /dev/null +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..21a3cc1 --- /dev/null +++ b/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..c30b367 --- /dev/null +++ b/ios/Runner/AppDelegate.swift @@ -0,0 +1,16 @@ +import Flutter +import UIKit + +@main +@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } + + func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) { + GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry) + } +} diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d0d98aa --- /dev/null +++ b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1 @@ +{"images":[{"size":"20x20","idiom":"iphone","filename":"Icon-App-20x20@2x.png","scale":"2x"},{"size":"20x20","idiom":"iphone","filename":"Icon-App-20x20@3x.png","scale":"3x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@1x.png","scale":"1x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@2x.png","scale":"2x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@3x.png","scale":"3x"},{"size":"40x40","idiom":"iphone","filename":"Icon-App-40x40@2x.png","scale":"2x"},{"size":"40x40","idiom":"iphone","filename":"Icon-App-40x40@3x.png","scale":"3x"},{"size":"57x57","idiom":"iphone","filename":"Icon-App-57x57@1x.png","scale":"1x"},{"size":"57x57","idiom":"iphone","filename":"Icon-App-57x57@2x.png","scale":"2x"},{"size":"60x60","idiom":"iphone","filename":"Icon-App-60x60@2x.png","scale":"2x"},{"size":"60x60","idiom":"iphone","filename":"Icon-App-60x60@3x.png","scale":"3x"},{"size":"20x20","idiom":"ipad","filename":"Icon-App-20x20@1x.png","scale":"1x"},{"size":"20x20","idiom":"ipad","filename":"Icon-App-20x20@2x.png","scale":"2x"},{"size":"29x29","idiom":"ipad","filename":"Icon-App-29x29@1x.png","scale":"1x"},{"size":"29x29","idiom":"ipad","filename":"Icon-App-29x29@2x.png","scale":"2x"},{"size":"40x40","idiom":"ipad","filename":"Icon-App-40x40@1x.png","scale":"1x"},{"size":"40x40","idiom":"ipad","filename":"Icon-App-40x40@2x.png","scale":"2x"},{"size":"50x50","idiom":"ipad","filename":"Icon-App-50x50@1x.png","scale":"1x"},{"size":"50x50","idiom":"ipad","filename":"Icon-App-50x50@2x.png","scale":"2x"},{"size":"72x72","idiom":"ipad","filename":"Icon-App-72x72@1x.png","scale":"1x"},{"size":"72x72","idiom":"ipad","filename":"Icon-App-72x72@2x.png","scale":"2x"},{"size":"76x76","idiom":"ipad","filename":"Icon-App-76x76@1x.png","scale":"1x"},{"size":"76x76","idiom":"ipad","filename":"Icon-App-76x76@2x.png","scale":"2x"},{"size":"83.5x83.5","idiom":"ipad","filename":"Icon-App-83.5x83.5@2x.png","scale":"2x"},{"size":"1024x1024","idiom":"ios-marketing","filename":"Icon-App-1024x1024@1x.png","scale":"1x"}],"info":{"version":1,"author":"xcode"}} \ No newline at end of file diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..0d531c47cab57c41152a5276660d553a1f759041 GIT binary patch literal 67996 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�KCVc( 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 YV!;0R`K!o}3=9kmp00i_>zopr0CuQQn*aa+ literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a3cfb1dbb95846cea09adedcbcbb3adc34d5b350 GIT binary patch literal 1471 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 literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..4d21624833bdd7024bb7ca1b34e53ae39591851e GIT binary patch literal 2235 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 Au>b%7 literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..a3cfb1dbb95846cea09adedcbcbb3adc34d5b350 GIT binary patch literal 1471 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 literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..25f2b47acb36ed5f04b260c4d2344402d045d875 GIT binary patch literal 4981 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 CCbBjF literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..8f79bb96c61979d90168ab162623525614ee4cc5 GIT binary patch literal 1884 zcmeAS@N?(olHy`uVBq!ia0y~yU@!t<4kiW$hKaHA&lngOBuiW)N`mv#O3D+9QW?t2 z%k?tzvWt@w3sUv+i_&Mmvyoz8VEgCk;uumf=k3h+9GRoC$J5ikm*v0T|3CIzy0zVL zLq3&*4jw^GF%z7)R=(hNb#hw4&$@Dz*47|Jo2`p#wVa$fR_RaG3SGL&<#)i+tkABm zo{WWgJ{~%cJB}1~OqSXA`R2aecjn){ee>?m(CNi*cHchv?iYWSyp{j<`*Y|1eDmIX z|NTE{{wxe%_Fq4upBa-;729*+SANsSdPZ&ri3P{5oMowatY@OPQTcvf;#x*Ul?m48 z+VeM?{E&H2#@2oJ(@bW8>E{{q*f&Ty3!nEXvtYKcr4**T5|a1%X*(fzN73tR zMWy#|2S44ecA7&m(j~usdHIUl&r@%-9o*LRv{3r*wT&lsi*LEA3afXh=9s|=`{QgJI)vQ}B;=^V?Ut{l2pXqOkHdE0-rDeBdA;VW?K-=)mG*q8I5TzS zyoEkuU%UMxt~Q=a+H`qcyneX%)&QTvn~&@M7e4(o>7qrzpC2b9Zs`7!k~7hHwne?k z;Zl41&hoq^YR|O#Wxsv5(!Y1H<^2;zR>dv*{jH3i#5rE!b=37#@vBby_bx?u&5hD+ z*#|q)?60J^U46H1!DYW9i>LN)7S4;zXV|dnQsaywcO5lOZ+12dbA!dz=agHPT}*f9 z{%$YQ@jgLy$Er&UR0P_M49f2>P%NItC%q$uHSe0Th~$5#`7+Mxxo$v?0qdFr<>cYHnw`Q$|UpE2dGUdr3O%FWiA)ogdW@|5tGUz@Ip zPIyq$AX4T&UIvW$(rr$o26MDH@bZ(YYX%wERY)&IqP>b;KmJ%^`r zf9E%p zeJfA?3$Ir?VzKj<@wE7>?CBOp#`8|?KmU?{#p6Rx;hB7A|8ogkn<}SO&Lrr%ILqf) zWLmD(o3bUv2aUeXV{HsRR`dAT{>5U)TORRtPkC|c&eto`K4HoU3Q zy?cJuyW@wglQu3>nydQ!EW`5@vt_z(F57K?y`!f^dR1)tvXI@kZtE#MnNu0P;mWLi z-!$7JN-|~{n;!`N$-jfyb9&aDi0kY4m~u}hS|u;Lt+?oEUcj-_QL1tr(ay%x&P1yA zhuO(4klgJT=5Qjj?Cu)3FWDc>3L_mp7Mz&4N;Eq@zN5`(YDDLoXDY25LVv57YZ~ap zuDFrv;IY@@PT8t8t&UbDE&+2Ug;`JY_;9*k<-UfWTF+}$G2;Wr7X(fbl=SwWZZ8_y z^yph`t4@^ZqD9Yy_oOND+eBbx}%#qF`k9RwJrN8Qz zj5wKUT-Bj&G9nQ6# z9}ZS;Jb&5TvChH6rD{R4{i}@0@}GFVdQ&MBb@05yx4$p8QV literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c48dec6982a96a55ec1f37da5d2c155b396f9aea GIT binary patch literal 3994 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 literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..99d44e827a57250d577e55bf8537dc924a398b4a GIT binary patch literal 2149 zcmeAS@N?(olHy`uVBq!ia0y~yV6X&X4kiW$2IeY}OAHJQk|nMYCBgY=CFO}lsSM@i z<$9TU*~Q6;1*v-ZMd`EO*+?-kaIky2IEGZrc{{TA53Snxtw zkfiq8T`js9PZsC?dbnkEvbFxdiu32+->p7S_H4(u(wfOTrm7YGtJ-(``M&w*Ex+F> zUZ2X~ATKoW{q5NcbT}TLGIm<>Ym3~@?Q0kg*gbIO5Nyik3KRG55fF3OAHL=dv%Xgg zbK`rr)isj0gv#el4XyEv3Mg7Si+`%Z8rM6CVW&<_oZ71Sdg-e-MR^Pbh1MreNeJjn zsm$g$D6vZOqKW_Uh|>>mn`DF*aNjw%VcpzxX#u@F_6XN$AJ~>iZWmr7t@TDJ=;+$o zJ384{SAGx4T6foE^^D;4D&Fe#^R+H+n%rmm$o^l3L&3kQ>v>(FcUJOTSex3u>C@-a z>-GEjcezzv{koUq@!4OY1)jY5q5J=JK3M;MqV{fgC;MNoKk4^QG5Hze_t9W`U=i%Ib8MZxbRvB+5NB2tz%zx{%+hR zy$h@6SUmXud(O;=MLZAEj{SVw`lplGX(j_h@0yj`zwW&53}f4V{E<(TW65f1%{8lf z;w!Aa{8`;SCGpgS?DtZ?AK!AW%{5xMYmZdq`u(NLr#9Y{K6B*I>Tl8tYdvnL8#?f@ zb}Bqt;M2${WwuGmTkLcl(UVe4Eyq7p__F~ryiJz%;|Cad$gBkikdG34K zbe_HN|FYfkp(Z8u$-Sa7pt(cwE?7f!Dd{C!ZD z*yQRv?Cy7(wwbX`SK4rVTGPBI=k7f#yvuO6G9o5xRCt7MCFl1a zZ!GZAR4}PM-u26LqK?PY@Wuc4Ge79|XaB2r@sp2a$n`?$YffvT-@kqK+T?R=Zq}MF zJN&c%Hw%0F>Hcy*R-4?c=XjxLlW1J!nk zZ>l`Sz3P1PiuD%cJ^kjsZEJwj%Y)okb06Bwy0Ms_^=_>6gA8rg*{_z_UU|H>F6U&` z^JM0}ON)}<%-znc9bL$kzD{epyxU?~_N6>|uhNbzpSbn>#;_aHrMf;npCFU{BIs{} zcSe8Ae1nG9-fdcw^{#6v&i{JthrkvM*OG*;tkz!>=SIb+J8Cv(d$;-C?3=LuY^+W!CX5S9^+tBp%?Wt*eO=7ZE^UX946!dRjI6XgU>eAMW2g8Id59d$az1XU- z`Itl+%O=<7f9IG^HPK&sF}(cew>-hS_SsAfC-+Q^(91HCeD^V{DEV$iif{jysL#4m zr!L55pRPG9!E7?|LbsW*R(6?R`MQ*o=l{+8UlC$yBGbnjt8|u^VM%XL($0u2nKu^m zwb>fwFV9KYdPmAht=uX5dF!)4VNr2~o9XJ#&yLDod*b*re%-q-lCN)eUb%Q*N1FNW zJlnwk+a_4Q2%ELuMx*)ZqPd1%nv0(V6r4=ac=Pt-s@Z$B)BaAEjo(!{C#h=Q-cNh4 ztmjzeviQ?9_1OJ33;rcelHHqElbFd(%(C`-JM-u=+5U5;-O(ri?kxWiY!xy0nfv~l{|3_et0YgbEqvYM7PdElA>h>2 z2;HdW$u*0M=34be?{MB3b!gh*(5XhzZ~h0yqVhCA~Et$tWgB|8 zKVYcjimNR5|0?Wu;_0*|>+SA*vSqpb+)eAYihs%e>z?#iJN5T>`!mm; j{$KOm&CX}de^y)ZS*hCvzFcNtU|{fc^>bP0l+XkK50W-q literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..6f987f09c14d240e711017c78921a41d72a445ef GIT binary patch literal 4667 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 E05`JnS^xk5 literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..25f2b47acb36ed5f04b260c4d2344402d045d875 GIT binary patch literal 4981 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 CCbBjF literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..fcf969a5deee0a4c3939d6aed25c147462b82ea2 GIT binary patch literal 7807 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 B_$UAX literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..16dea29f2b217371e9303ec1115c28ad41c47785 GIT binary patch literal 2955 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 literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..efda04b713cd76d0b97f5cbd060ba894b0a48c53 GIT binary patch literal 6372 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 literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000..0bedcf2 --- /dev/null +++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0y~yU|@r242}Q* literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0y~yU|@r242}Q* literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0y~yU|@r242}Q* literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000..89c2725 --- /dev/null +++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/ios/Runner/Base.lproj/LaunchScreen.storyboard b/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f2e259c --- /dev/null +++ b/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist new file mode 100644 index 0000000..7680b42 --- /dev/null +++ b/ios/Runner/Info.plist @@ -0,0 +1,79 @@ + + + + + CADisableMinimumFrameDurationOnPhone + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Nexus + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + nexus + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleURLTypes + + + CFBundleURLSchemes + + nexus.federated.nexus + + + + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneClassName + UIWindowScene + UISceneConfigurationName + flutter + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + Main + + + + + UIApplicationSupportsIndirectInputEvents + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/ios/Runner/Runner-Bridging-Header.h b/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..308a2a5 --- /dev/null +++ b/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/ios/Runner/SceneDelegate.swift b/ios/Runner/SceneDelegate.swift new file mode 100644 index 0000000..b9ce8ea --- /dev/null +++ b/ios/Runner/SceneDelegate.swift @@ -0,0 +1,6 @@ +import Flutter +import UIKit + +class SceneDelegate: FlutterSceneDelegate { + +} diff --git a/ios/RunnerTests/RunnerTests.swift b/ios/RunnerTests/RunnerTests.swift new file mode 100644 index 0000000..86a7c3b --- /dev/null +++ b/ios/RunnerTests/RunnerTests.swift @@ -0,0 +1,12 @@ +import Flutter +import UIKit +import XCTest + +class RunnerTests: XCTestCase { + + func testExample() { + // If you add code to the Runner application, consider adding tests here. + // See https://developer.apple.com/documentation/xctest for more information about using XCTest. + } + +} diff --git a/ios/scripts/lipo b/ios/scripts/lipo new file mode 100755 index 0000000..eea1eea --- /dev/null +++ b/ios/scripts/lipo @@ -0,0 +1,15 @@ +#!/bin/sh +# Workaround for NixOS/nixpkgs#405066: frameworks copied from the Nix store +# stay read-only, so lipo can't write its temporary output file when Flutter +# thins them during the build. Make the framework writable before delegating +# to the real lipo. +for arg in "$@"; do + case "$arg" in + */*.framework/*) + fw_dir="${arg%.framework/*}.framework" + chmod -R +w "$fw_dir" 2>/dev/null + ;; + esac +done + +exec /usr/bin/lipo "$@" diff --git a/lib/controllers/client.dart b/lib/controllers/client.dart index aa8c3ae..e31e4f3 100644 --- a/lib/controllers/client.dart +++ b/lib/controllers/client.dart @@ -48,7 +48,7 @@ class ClientController extends AsyncNotifier { @override Future build() async { final Pointer root; - if (Platform.isAndroid) { + if (Platform.isAndroid || Platform.isIOS) { final dir = await getApplicationSupportDirectory(); root = "${dir.path}/gomuks".toNativeUtf8().cast(); } else { diff --git a/lib/helpers/extensions/get_xcode_sdk.dart b/lib/helpers/extensions/get_xcode_sdk.dart index 4c09246..58920c8 100644 --- a/lib/helpers/extensions/get_xcode_sdk.dart +++ b/lib/helpers/extensions/get_xcode_sdk.dart @@ -1,11 +1,14 @@ import "dart:io"; -Future getXCodeSDK() async { - final result = await Process.run("xcrun", ["--show-sdk-path"]); +Future getXCodeTool({String? sdkType, String? findTool}) async { + final result = await Process.run("xcrun", [ + if (sdkType != null) ...["--sdk", sdkType], + if (findTool != null) ...["-f", findTool] else "--show-sdk-path", + ]); if (result.exitCode != 0) { - throw Exception("Failed to get XCode SDK\n${result.stderr}"); + throw Exception("Failed to get ${sdkType ?? "XCode"} ${findTool ?? "SDK"}"); } - return result.stdout.trim(); + return result.stdout.toString().trim(); } diff --git a/macos/Flutter/Flutter-Debug.xcconfig b/macos/Flutter/Flutter-Debug.xcconfig index c2efd0b..4b81f9b 100644 --- a/macos/Flutter/Flutter-Debug.xcconfig +++ b/macos/Flutter/Flutter-Debug.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" diff --git a/macos/Flutter/Flutter-Release.xcconfig b/macos/Flutter/Flutter-Release.xcconfig index c2efd0b..5caa9d1 100644 --- a/macos/Flutter/Flutter-Release.xcconfig +++ b/macos/Flutter/Flutter-Release.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" diff --git a/macos/Podfile b/macos/Podfile new file mode 100644 index 0000000..ff5ddb3 --- /dev/null +++ b/macos/Podfile @@ -0,0 +1,42 @@ +platform :osx, '10.15' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_macos_podfile_setup + +target 'Runner' do + use_frameworks! + + flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) + target 'RunnerTests' do + inherit! :search_paths + end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_macos_build_settings(target) + end +end diff --git a/macos/Podfile.lock b/macos/Podfile.lock new file mode 100644 index 0000000..08cb773 --- /dev/null +++ b/macos/Podfile.lock @@ -0,0 +1,28 @@ +PODS: + - FlutterMacOS (1.0.0) + - media_kit_libs_macos_video (1.0.4): + - FlutterMacOS + - media_kit_video (0.0.1): + - FlutterMacOS + +DEPENDENCIES: + - FlutterMacOS (from `Flutter/ephemeral`) + - media_kit_libs_macos_video (from `Flutter/ephemeral/.symlinks/plugins/media_kit_libs_macos_video/macos`) + - media_kit_video (from `Flutter/ephemeral/.symlinks/plugins/media_kit_video/macos`) + +EXTERNAL SOURCES: + FlutterMacOS: + :path: Flutter/ephemeral + media_kit_libs_macos_video: + :path: Flutter/ephemeral/.symlinks/plugins/media_kit_libs_macos_video/macos + media_kit_video: + :path: Flutter/ephemeral/.symlinks/plugins/media_kit_video/macos + +SPEC CHECKSUMS: + FlutterMacOS: d0db08ddef1a9af05a5ec4b724367152bb0500b1 + media_kit_libs_macos_video: 85a23e549b5f480e72cae3e5634b5514bc692f65 + media_kit_video: fa6564e3799a0a28bff39442334817088b7ca758 + +PODFILE CHECKSUM: 54d867c82ac51cbd61b565781b9fada492027009 + +COCOAPODS: 1.17.0 diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index f87523c..3dbb24b 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -27,6 +27,9 @@ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; + 34AEA7295333B7F48CD3BE4C /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D76F30AE9CCFCA04C354BD4C /* Pods_RunnerTests.framework */; }; + 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; }; + BAF79690465DBAC1A1E19D28 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70FD05041ACDA7E801BB9823 /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -60,11 +63,12 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 18EDDEF1FB58EC56ABDA1BEB /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; 331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; - 33CC10ED2044A3C60003C045 /* nexus.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "nexus.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10ED2044A3C60003C045 /* nexus.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = nexus.app; sourceTree = BUILT_PRODUCTS_DIR; }; 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; @@ -76,8 +80,16 @@ 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 5099E6191AE87E21D356D9C8 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; + 6D9F8F8BBED102075ECF1DF9 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 70FD05041ACDA7E801BB9823 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 8F5ECEC7BF9DD35CB3E7196E /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + 9DDE815F827B87E2C55DF94C /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + CBD1D9203BEE9731F981EEF8 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + D76F30AE9CCFCA04C354BD4C /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -85,6 +97,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 34AEA7295333B7F48CD3BE4C /* Pods_RunnerTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -92,6 +105,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */, + BAF79690465DBAC1A1E19D28 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -125,6 +140,7 @@ 331C80D6294CF71000263BE5 /* RunnerTests */, 33CC10EE2044A3C60003C045 /* Products */, D73912EC22F37F3D000D13A0 /* Frameworks */, + FC780AF47288088B9004ACE2 /* Pods */, ); sourceTree = ""; }; @@ -151,6 +167,7 @@ 33CEB47122A05771004F2AC0 /* Flutter */ = { isa = PBXGroup; children = ( + 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */, 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, @@ -175,10 +192,26 @@ D73912EC22F37F3D000D13A0 /* Frameworks */ = { isa = PBXGroup; children = ( + 70FD05041ACDA7E801BB9823 /* Pods_Runner.framework */, + D76F30AE9CCFCA04C354BD4C /* Pods_RunnerTests.framework */, ); name = Frameworks; sourceTree = ""; }; + FC780AF47288088B9004ACE2 /* Pods */ = { + isa = PBXGroup; + children = ( + 6D9F8F8BBED102075ECF1DF9 /* Pods-Runner.debug.xcconfig */, + 9DDE815F827B87E2C55DF94C /* Pods-Runner.release.xcconfig */, + CBD1D9203BEE9731F981EEF8 /* Pods-Runner.profile.xcconfig */, + 18EDDEF1FB58EC56ABDA1BEB /* Pods-RunnerTests.debug.xcconfig */, + 8F5ECEC7BF9DD35CB3E7196E /* Pods-RunnerTests.release.xcconfig */, + 5099E6191AE87E21D356D9C8 /* Pods-RunnerTests.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -186,6 +219,7 @@ isa = PBXNativeTarget; buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( + C413A8A75594D2165C9D56BD /* [CP] Check Pods Manifest.lock */, 331C80D1294CF70F00263BE5 /* Sources */, 331C80D2294CF70F00263BE5 /* Frameworks */, 331C80D3294CF70F00263BE5 /* Resources */, @@ -204,11 +238,13 @@ isa = PBXNativeTarget; buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + 446C82D5FE82BD05F78EDA6A /* [CP] Check Pods Manifest.lock */, 33CC10E92044A3C60003C045 /* Sources */, 33CC10EA2044A3C60003C045 /* Frameworks */, 33CC10EB2044A3C60003C045 /* Resources */, 33CC110E2044A8840003C045 /* Bundle Framework */, 3399D490228B24CF009A79C7 /* ShellScript */, + C4D158541D7059C07D3CA9B3 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -216,6 +252,9 @@ 33CC11202044C79F0003C045 /* PBXTargetDependency */, ); name = Runner; + packageProductDependencies = ( + 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */, + ); productName = Runner; productReference = 33CC10ED2044A3C60003C045 /* nexus.app */; productType = "com.apple.product-type.application"; @@ -260,6 +299,9 @@ Base, ); mainGroup = 33CC10E42044A3C60003C045; + packageReferences = ( + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */, + ); productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -307,7 +349,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; + shellScript = "export PATH=\"$PROJECT_DIR/scripts:$PATH\"\necho \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; }; 33CC111E2044C6BF0003C045 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; @@ -327,7 +369,68 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; + shellScript = "export PATH=\"$PROJECT_DIR/scripts:$PATH\"\n\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; + }; + 446C82D5FE82BD05F78EDA6A /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + C413A8A75594D2165C9D56BD /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + C4D158541D7059C07D3CA9B3 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -380,6 +483,7 @@ /* Begin XCBuildConfiguration section */ 331C80DB294CF71000263BE5 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 18EDDEF1FB58EC56ABDA1BEB /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; @@ -394,6 +498,7 @@ }; 331C80DC294CF71000263BE5 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 8F5ECEC7BF9DD35CB3E7196E /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; @@ -408,6 +513,7 @@ }; 331C80DD294CF71000263BE5 /* Profile */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 5099E6191AE87E21D356D9C8 /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; @@ -700,6 +806,20 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCLocalSwiftPackageReference section */ + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "FlutterGeneratedPluginSwiftPackage" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; + }; +/* End XCLocalSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */ = { + isa = XCSwiftPackageProductDependency; + productName = FlutterGeneratedPluginSwiftPackage; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 33CC10E52044A3C60003C045 /* Project object */; } diff --git a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index ff47eeb..746b383 100644 --- a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -5,6 +5,24 @@ + + + + + + + + + + + + diff --git a/macos/scripts/lipo b/macos/scripts/lipo new file mode 100755 index 0000000..9e32655 --- /dev/null +++ b/macos/scripts/lipo @@ -0,0 +1,15 @@ +#!/bin/sh +# Workaround for NixOS/nixpkgs#405066: frameworks copied from the Nix store +# stay read-only, so lipo can't write its temporary output file when Flutter +# thins FlutterMacOS.framework during the build. Make the framework writable +# before delegating to the real lipo. +for arg in "$@"; do + case "$arg" in + */*.framework/*) + fw_dir="${arg%.framework/*}.framework" + chmod -R +w "$fw_dir" 2>/dev/null + ;; + esac +done + +exec /usr/bin/lipo "$@" diff --git a/pubspec.lock b/pubspec.lock index c989ed4..c204b95 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -117,18 +117,18 @@ packages: dependency: transitive description: name: build_config - sha256: f2c223156a26eea323e6244b85141d76413a80aeee9fe0b380773789fabaf8ae + sha256: "94eaf6708fe64408c632ef2689ca3777b112f9421306ccf4f8c84d7c5c9f83f8" url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.2" build_daemon: dependency: transitive description: name: build_daemon - sha256: fd754058c342243718d5171a95f352cfc9fcf0cba8cfa26df67cb13a5836db78 + sha256: "79e05eaf15a48d7230b053a4363b8eaac0cc234bbd0134c3229455481f55cbc6" url: "https://pub.dev" source: hosted - version: "4.1.2" + version: "4.1.5" build_runner: dependency: "direct dev" description: @@ -149,10 +149,10 @@ packages: dependency: transitive description: name: built_value - sha256: "34e4067d30ce212937df995f03b69992eea683539ceeac7f679a1f1eba055b56" + sha256: "31b24be6615ec7fcf70b3aa5a7469fe35826485e639a16dd7eb83ba30e4cc6a8" url: "https://pub.dev" source: hosted - version: "8.12.6" + version: "8.12.7" button_m3e: dependency: transitive description: @@ -285,10 +285,10 @@ packages: dependency: transitive description: name: dbus - sha256: "0ce9b0a839e6dee59a37a623d2fc26a35bbbe6404213e419b0d6411023d62645" + sha256: "792974a4007974fbc5c1b5433eb2330a9db3e368c3f906253af4c007d0f49a91" url: "https://pub.dev" source: hosted - version: "0.7.14" + version: "0.7.13" dynamic_color: dependency: "direct main" description: @@ -390,10 +390,10 @@ packages: dependency: transitive description: name: file_selector_android - sha256: "6a26687fa65cbc28a5345c7ae6f227e89f0b47740978a4c475b1a625da7a331b" + sha256: "1d45e9910f68c16eb0c74f0b10097ad81aed516ea28054c027137e8f7d75e840" url: "https://pub.dev" source: hosted - version: "0.5.2+8" + version: "0.5.2+9" file_selector_ios: dependency: transitive description: @@ -666,10 +666,10 @@ packages: dependency: transitive description: name: image - sha256: f9881ff4998044947ec38d098bc7c8316ae1186fa786eddffdb867b9bc94dfce + sha256: "6300175e00616bbc832e2fc91bfa4d776af5402c81c7151bee6905bb08473c52" url: "https://pub.dev" source: hosted - version: "4.8.0" + version: "4.9.1" image_picker: dependency: "direct main" description: @@ -972,10 +972,10 @@ packages: dependency: transitive description: name: objective_c - sha256: "6cb691c686fa2838c6deb34980d426145c2a5d537491cb83d463c33cdbc726ed" + sha256: b7fb95a6d9a4f009edd63dc5ac69f07420b23a16161c6dd8660290b59c602e8e url: "https://pub.dev" source: hosted - version: "9.4.1" + version: "9.5.0" package_config: dependency: transitive description: @@ -1100,10 +1100,10 @@ packages: dependency: transitive description: name: posix - sha256: "185ef7606574f789b40f289c233efa52e96dead518aed988e040a10737febb07" + sha256: bc1bad54ad2b735816e31f8d4600cfde6c7839975085ddfbca48b6c9f7c4044e url: "https://pub.dev" source: hosted - version: "6.5.0" + version: "6.5.2" pub_semver: dependency: transitive description: @@ -1313,18 +1313,18 @@ packages: dependency: transitive description: name: source_gen - sha256: ec37cc0e6694374cbef59ed79685572c870a54ede6fa30a3e420feb3adffea02 + sha256: a603f1fb984a7391ae5978d1b92bfaaa08b350dca5c825256f925818f7943bf5 url: "https://pub.dev" source: hosted - version: "4.2.3" + version: "4.2.4" source_helper: dependency: transitive description: name: source_helper - sha256: "4227d54ceefd0bb8ca4c8fcb96e1719dc53f1ee1b6e2ca9d7a6069da160e4eae" + sha256: "5e6f216fdf6376c9f3852381ae037499797a3385377d388b011dac98d303c67c" url: "https://pub.dev" source: hosted - version: "1.3.12" + version: "1.3.13" source_map_stack_trace: dependency: transitive description: @@ -1401,10 +1401,10 @@ packages: dependency: transitive description: name: synchronized - sha256: "93b153dcb6a26dcddee6ca087dd634b53e38c10b5aa163e8e49501a776456153" + sha256: "61894a1956de6b4fc1aefd0892e109514a1a706cbece3ac59decd90ff5a7a423" url: "https://pub.dev" source: hosted - version: "3.4.1" + version: "3.4.1+1" term_glyph: dependency: transitive description: @@ -1561,10 +1561,10 @@ packages: dependency: transitive description: name: vector_graphics - sha256: "2306c03da2ba81724afeb589c351ebbc0aa7d86005925be8f8735856dbe5e42d" + sha256: "9d0e3b9cb16542ad660daee871e726a10d13a93b7b5391677c3160e8f5e83935" url: "https://pub.dev" source: hosted - version: "1.2.2" + version: "1.2.3" vector_graphics_codec: dependency: transitive description: @@ -1577,10 +1577,10 @@ packages: dependency: transitive description: name: vector_graphics_compiler - sha256: "142a9146f447d15b10bdc00e21d5f4d83e5b32bb5f8f8f5a04c75311344923a3" + sha256: "4dca4feb77dc3ec7f6e27e49c53241eb8217f55e4f9b12599a27f8903bca5682" url: "https://pub.dev" source: hosted - version: "1.2.6" + version: "1.3.0" vector_math: dependency: transitive description: @@ -1601,18 +1601,18 @@ packages: dependency: transitive description: name: wakelock_plus - sha256: "824c5bba0f800e86d32e57d3d1843c531f090005cc89d9a837933e6601093d53" + sha256: "7253bca0fcf40d8413ddfcf4d2a1fa0a82475e79be25a4f2c564b695c9351486" url: "https://pub.dev" source: hosted - version: "1.6.1" + version: "1.7.0" wakelock_plus_platform_interface: dependency: transitive description: name: wakelock_plus_platform_interface - sha256: b13f99e992e7ae6a152e16c5559d3c07ff445b13330192662494e614ca3e7d7b + sha256: "0618d1799f0b28bcf98255b4ee8313e6fc4d38589dc4ee5fe5840d57d1aff6da" url: "https://pub.dev" source: hosted - version: "1.5.1" + version: "1.6.0" watcher: dependency: transitive description: @@ -1657,10 +1657,10 @@ packages: dependency: transitive description: name: win32 - sha256: ba6f4bba816c8d7e3c1580e170f3786d216951cc6b94babc3b814c08d2cb2738 + sha256: a0b93865d5644f11cf6a8c3f6db909f1ec168958b5805f6cc684adea957cd63d url: "https://pub.dev" source: hosted - version: "6.3.0" + version: "6.4.0" window_manager: dependency: "direct main" description: @@ -1681,10 +1681,10 @@ packages: dependency: transitive description: name: xml - sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025" + sha256: "67f0aff7be013d107995e9b75bf4e7f2c3ef2dfdb2c8e68024bba0a7fd5756a4" url: "https://pub.dev" source: hosted - version: "6.6.1" + version: "7.0.1" yaml: dependency: transitive description: diff --git a/scripts/generate.dart b/scripts/generate.dart index c381230..4dc7329 100644 --- a/scripts/generate.dart +++ b/scripts/generate.dart @@ -17,7 +17,7 @@ void main(List args) async { entryPoints: [File(join(repoDir.path, "pkg", "ffi", "gomuksffi.h")).uri], compilerOptions: [ "--no-warnings", - if (Platform.isMacOS) "-I${await getXCodeSDK()}/usr/include", + if (Platform.isMacOS) "-I${await getXCodeTool()}/usr/include", ], ), functions: Functions.includeAll, From 56dbd91c963e3684ed2f4c4c21e4d6112d69b044 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 8 Aug 2026 16:49:25 -0400 Subject: [PATCH 036/176] move lipo wrapper --- macos/scripts/lipo | 15 --------------- {ios/scripts => scripts}/lipo | 0 2 files changed, 15 deletions(-) delete mode 100755 macos/scripts/lipo rename {ios/scripts => scripts}/lipo (100%) diff --git a/macos/scripts/lipo b/macos/scripts/lipo deleted file mode 100755 index 9e32655..0000000 --- a/macos/scripts/lipo +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -# Workaround for NixOS/nixpkgs#405066: frameworks copied from the Nix store -# stay read-only, so lipo can't write its temporary output file when Flutter -# thins FlutterMacOS.framework during the build. Make the framework writable -# before delegating to the real lipo. -for arg in "$@"; do - case "$arg" in - */*.framework/*) - fw_dir="${arg%.framework/*}.framework" - chmod -R +w "$fw_dir" 2>/dev/null - ;; - esac -done - -exec /usr/bin/lipo "$@" diff --git a/ios/scripts/lipo b/scripts/lipo similarity index 100% rename from ios/scripts/lipo rename to scripts/lipo From f7847d587c1ab77cc2f3de4a48c4e3920934b39d Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 8 Aug 2026 16:57:51 -0400 Subject: [PATCH 037/176] only enable autofocus on desktop platforms --- lib/widgets/composer/composer.dart | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/widgets/composer/composer.dart b/lib/widgets/composer/composer.dart index ca3de8a..8b7fec4 100644 --- a/lib/widgets/composer/composer.dart +++ b/lib/widgets/composer/composer.dart @@ -234,7 +234,12 @@ class Composer extends HookConsumerWidget { child: TextField( maxLines: 12, minLines: 1, - autofocus: true, + autofocus: + (Platform.isLinux || + Platform.isMacOS || + Platform.isWindows) + ? true + : false, decoration: .new( hintText: "Your message here...", border: .none, From c84f0e7e935097059fe834e405496b7f08b8fbec Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 8 Aug 2026 17:02:31 -0400 Subject: [PATCH 038/176] dismiss keyboard on scroll of room chat --- lib/widgets/room_chat.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/widgets/room_chat.dart b/lib/widgets/room_chat.dart index cb1e695..fcab5fe 100644 --- a/lib/widgets/room_chat.dart +++ b/lib/widgets/room_chat.dart @@ -466,6 +466,8 @@ class RoomChat extends HookConsumerWidget { child: switch (controllerData) { AsyncData(:final value?) || AsyncLoading(:final value?) => CustomScrollView( + keyboardDismissBehavior: + ScrollViewKeyboardDismissBehavior.onDrag, controller: scrollController, slivers: [ SliverToBoxAdapter( From 7eab09585bd1f56425d87c8d9e95cbecee70dbfd Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 8 Aug 2026 17:51:00 -0400 Subject: [PATCH 039/176] Revert "move lipo wrapper" This reverts commit 56dbd91c963e3684ed2f4c4c21e4d6112d69b044. --- {scripts => ios/scripts}/lipo | 0 macos/scripts/lipo | 15 +++++++++++++++ 2 files changed, 15 insertions(+) rename {scripts => ios/scripts}/lipo (100%) create mode 100755 macos/scripts/lipo diff --git a/scripts/lipo b/ios/scripts/lipo similarity index 100% rename from scripts/lipo rename to ios/scripts/lipo diff --git a/macos/scripts/lipo b/macos/scripts/lipo new file mode 100755 index 0000000..9e32655 --- /dev/null +++ b/macos/scripts/lipo @@ -0,0 +1,15 @@ +#!/bin/sh +# Workaround for NixOS/nixpkgs#405066: frameworks copied from the Nix store +# stay read-only, so lipo can't write its temporary output file when Flutter +# thins FlutterMacOS.framework during the build. Make the framework writable +# before delegating to the real lipo. +for arg in "$@"; do + case "$arg" in + */*.framework/*) + fw_dir="${arg%.framework/*}.framework" + chmod -R +w "$fw_dir" 2>/dev/null + ;; + esac +done + +exec /usr/bin/lipo "$@" From 185c1d2714c1a9eb3faaf4bf22d4f13e693ab914 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 8 Aug 2026 17:53:58 -0400 Subject: [PATCH 040/176] undo lipo changes --- ios/Runner.xcodeproj/project.pbxproj | 4 ++-- ios/scripts/lipo | 15 --------------- macos/Runner.xcodeproj/project.pbxproj | 2 +- macos/scripts/lipo | 15 --------------- 4 files changed, 3 insertions(+), 33 deletions(-) delete mode 100755 ios/scripts/lipo delete mode 100755 macos/scripts/lipo diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 57b889d..ddd29ee 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -336,7 +336,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "export PATH=\"$PROJECT_DIR/scripts:$PATH\"\n/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + shellScript = "ebin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin; }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; @@ -351,7 +351,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "export PATH=\"$PROJECT_DIR/scripts:$PATH\"\n/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; EE82EC529EB6C0F1FA480659 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; diff --git a/ios/scripts/lipo b/ios/scripts/lipo deleted file mode 100755 index eea1eea..0000000 --- a/ios/scripts/lipo +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -# Workaround for NixOS/nixpkgs#405066: frameworks copied from the Nix store -# stay read-only, so lipo can't write its temporary output file when Flutter -# thins them during the build. Make the framework writable before delegating -# to the real lipo. -for arg in "$@"; do - case "$arg" in - */*.framework/*) - fw_dir="${arg%.framework/*}.framework" - chmod -R +w "$fw_dir" 2>/dev/null - ;; - esac -done - -exec /usr/bin/lipo "$@" diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 3dbb24b..57f7241 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -349,7 +349,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "export PATH=\"$PROJECT_DIR/scripts:$PATH\"\necho \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; }; 33CC111E2044C6BF0003C045 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; diff --git a/macos/scripts/lipo b/macos/scripts/lipo deleted file mode 100755 index 9e32655..0000000 --- a/macos/scripts/lipo +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -# Workaround for NixOS/nixpkgs#405066: frameworks copied from the Nix store -# stay read-only, so lipo can't write its temporary output file when Flutter -# thins FlutterMacOS.framework during the build. Make the framework writable -# before delegating to the real lipo. -for arg in "$@"; do - case "$arg" in - */*.framework/*) - fw_dir="${arg%.framework/*}.framework" - chmod -R +w "$fw_dir" 2>/dev/null - ;; - esac -done - -exec /usr/bin/lipo "$@" From a5f42fe56e2ba0062690332d079296b57d3efcf4 Mon Sep 17 00:00:00 2001 From: Erwan Leboucher Date: Sat, 8 Aug 2026 17:56:01 -0400 Subject: [PATCH 041/176] add workaround for lipo issues with Flutter from Nix on MacOS --- .github/workflows/ios.yml | 12 +++++++++++- .github/workflows/macos.yml | 13 +++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml index 015cd13..734deb6 100644 --- a/.github/workflows/ios.yml +++ b/.github/workflows/ios.yml @@ -22,7 +22,17 @@ jobs: extra_nix_config: experimental-features = nix-command flakes flake-self-attrs - name: Build app - run: nix develop --command bash -c "flutter pub get && dart scripts/generate.dart && flutter pub run build_runner build && flutter build ios --release --no-codesign" + run: | + nix develop --command bash -c ' + set -e + flutter pub get + dart scripts/generate.dart + flutter pub run build_runner build + # Nix-provided Flutter'"'"'s bundled frameworks are read-only, which + # breaks lipo when Flutter thins them into build/ (NixOS/nixpkgs#405066). + find "$(dirname "$(dirname "$(readlink -f "$(command -v flutter)")")")" -type d -iname "*.framework" -exec chmod -R u+w {} + 2>/dev/null || true + flutter build ios --release --no-codesign + ' # Unsigned IPA: SideStore/AltStore re-sign this on-device with the # user's own Apple ID at install time, so no certificate is needed here. diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index e7040fa..ccbd70e 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -21,8 +21,17 @@ jobs: with: extra_nix_config: experimental-features = nix-command flakes flake-self-attrs - - name: Build app - run: nix develop --command bash -c "flutter pub get && dart scripts/generate.dart && flutter pub run build_runner build && flutter build macos --release" + - run: | + nix develop --command bash -c ' + set -e + flutter pub get + dart scripts/generate.dart + flutter pub run build_runner build + # Nix-provided Flutter'"'"'s bundled frameworks are read-only, which + # breaks lipo when Flutter thins them into build/ (NixOS/nixpkgs#405066). + find "$(dirname "$(dirname "$(readlink -f "$(command -v flutter)")")")" -type d -iname "*.framework" -exec chmod -R u+w {} + 2>/dev/null || true + flutter build macos --release + ' - name: Upload installer artifact uses: actions/upload-artifact@v6 From 21a0e0db70feacf1d6793d76fc982241d30fce34 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 8 Aug 2026 18:03:57 -0400 Subject: [PATCH 042/176] correctly undo lipo changes --- ios/Runner.xcodeproj/project.pbxproj | 2 +- macos/Runner.xcodeproj/project.pbxproj | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index ddd29ee..065d08b 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -336,7 +336,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "ebin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 57f7241..67876ad 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -349,7 +349,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; }; 33CC111E2044C6BF0003C045 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; @@ -369,7 +369,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "export PATH=\"$PROJECT_DIR/scripts:$PATH\"\n\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; }; 446C82D5FE82BD05F78EDA6A /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; From 5bbd51c4bc8eb5cc2f9b4defe9c5c2f111c62397 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 8 Aug 2026 18:52:49 -0400 Subject: [PATCH 043/176] fix macos permission issues --- .github/workflows/ios.yml | 79 +++++++++++++++++++------------------ .github/workflows/macos.yml | 64 +++++++++++++++--------------- 2 files changed, 73 insertions(+), 70 deletions(-) diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml index 734deb6..dc7fa02 100644 --- a/.github/workflows/ios.yml +++ b/.github/workflows/ios.yml @@ -1,49 +1,50 @@ name: "Build iOS App" on: - push: - branches: ["main"] - tags: ["*"] - workflow_dispatch: + push: + branches: ["main"] + tags: ["*"] + workflow_dispatch: jobs: - build-app: - runs-on: macos-latest + build-app: + runs-on: macos-latest - steps: - - name: Checkout repository - uses: actions/checkout@v6 - with: - submodules: recursive + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + submodules: recursive - - name: Lix GHA Installer Action - uses: samueldr/lix-gha-installer-action@v2026-02-22 - with: - extra_nix_config: experimental-features = nix-command flakes flake-self-attrs + - name: Lix GHA Installer Action + uses: samueldr/lix-gha-installer-action@v2026-02-22 + with: + extra_nix_config: experimental-features = nix-command flakes flake-self-attrs - - name: Build app - run: | - nix develop --command bash -c ' - set -e - flutter pub get - dart scripts/generate.dart - flutter pub run build_runner build - # Nix-provided Flutter'"'"'s bundled frameworks are read-only, which - # breaks lipo when Flutter thins them into build/ (NixOS/nixpkgs#405066). - find "$(dirname "$(dirname "$(readlink -f "$(command -v flutter)")")")" -type d -iname "*.framework" -exec chmod -R u+w {} + 2>/dev/null || true - flutter build ios --release --no-codesign - ' + - name: Build app + run: | + nix develop --command bash -c ' + set -e + flutter pub get + dart scripts/generate.dart + flutter pub run build_runner build - # Unsigned IPA: SideStore/AltStore re-sign this on-device with the - # user's own Apple ID at install time, so no certificate is needed here. - - name: Package unsigned IPA - run: | - mkdir Payload - cp -r build/ios/iphoneos/Runner.app Payload/ - zip -r Nexus.ipa Payload + FLUTTER_ROOT="$(dirname "$(dirname "$(readlink -f "$(command -v flutter)")")")" + sudo find -L "$FLUTTER_ROOT" -type d -iname "*.framework" -exec chmod -R u+w {} + - - name: Upload IPA artifact - uses: actions/upload-artifact@v6 - with: - name: Nexus.ipa - path: Nexus.ipa + flutter build ios --release --no-codesign + ' + + # Unsigned IPA: SideStore/AltStore re-sign this on-device with the + # user's own Apple ID at install time, so no certificate is needed here. + - name: Package unsigned IPA + run: | + mkdir Payload + cp -r build/ios/iphoneos/Runner.app Payload/ + zip -r Nexus.ipa Payload + + - name: Upload IPA artifact + uses: actions/upload-artifact@v6 + with: + name: Nexus.ipa + path: Nexus.ipa diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index ccbd70e..f263d68 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -1,40 +1,42 @@ name: "Build MacOS App" on: - push: - branches: ["main"] - tags: ["*"] - workflow_dispatch: + push: + branches: ["main"] + tags: ["*"] + workflow_dispatch: jobs: - build-app: - runs-on: macos-latest + build-app: + runs-on: macos-latest - steps: - - name: Checkout repository - uses: actions/checkout@v6 - with: - submodules: recursive + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + submodules: recursive - - name: Lix GHA Installer Action - uses: samueldr/lix-gha-installer-action@v2026-02-22 - with: - extra_nix_config: experimental-features = nix-command flakes flake-self-attrs + - name: Lix GHA Installer Action + uses: samueldr/lix-gha-installer-action@v2026-02-22 + with: + extra_nix_config: experimental-features = nix-command flakes flake-self-attrs - - run: | - nix develop --command bash -c ' - set -e - flutter pub get - dart scripts/generate.dart - flutter pub run build_runner build - # Nix-provided Flutter'"'"'s bundled frameworks are read-only, which - # breaks lipo when Flutter thins them into build/ (NixOS/nixpkgs#405066). - find "$(dirname "$(dirname "$(readlink -f "$(command -v flutter)")")")" -type d -iname "*.framework" -exec chmod -R u+w {} + 2>/dev/null || true - flutter build macos --release - ' + - name: Build app + run: | + nix develop --command bash -c ' + set -e + flutter pub get + dart scripts/generate.dart + flutter pub run build_runner build - - name: Upload installer artifact - uses: actions/upload-artifact@v6 - with: - name: App - path: build/macos/Build/Products/Release/Nexus.app \ No newline at end of file + FLUTTER_ROOT="$(dirname "$(dirname "$(readlink -f "$(command -v flutter)")")")" + sudo find -L "$FLUTTER_ROOT" -type d -iname "*.framework" -exec chmod -R u+w {} + + + flutter build macos --release + ' + + - name: Upload installer artifact + uses: actions/upload-artifact@v6 + with: + name: App + path: build/macos/Build/Products/Release/Nexus.app From 85b9007c47bcd785ff004190b6be0ce9b2236b86 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 8 Aug 2026 18:53:12 -0400 Subject: [PATCH 044/176] bump flake --- flake.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/flake.lock b/flake.lock index 41cfb9d..b743efe 100644 --- a/flake.lock +++ b/flake.lock @@ -5,11 +5,11 @@ "nixpkgs-lib": "nixpkgs-lib" }, "locked": { - "lastModified": 1782949081, - "narHash": "sha256-vp6Y/Grm98ESt6ceOkWiHWyZRDV3J1RID4w+6NWK9yA=", + "lastModified": 1785627969, + "narHash": "sha256-4dtXQk/NMePegK/nWp5NSeuZKLATItOq61lpEvmXqGw=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "17c9d6cdfc60c64f4ee8d306f9bc0b4ccb51481e", + "rev": "427bf4bd9435fdf21321c8cc628c24efc14c0f7a", "type": "github" }, "original": { @@ -73,11 +73,11 @@ }, "nixpkgs-lib": { "locked": { - "lastModified": 1782614948, - "narHash": "sha256-ePjCwr1sNm9NYUqywL7QfK3JnlS015msC+eBu2zKlp8=", + "lastModified": 1785031560, + "narHash": "sha256-OmshNvn2vupOFpYinLUu+1Dnpu4n7Q5N3ggGVNHpkUI=", "owner": "nix-community", "repo": "nixpkgs.lib", - "rev": "db3f255737b94216eb71cce308e2912cf6bc2d7c", + "rev": "0e79af5e3d4dcfcd676ab5ba3f95d2e3352e078c", "type": "github" }, "original": { @@ -88,11 +88,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1784497964, - "narHash": "sha256-vlHUuqAcbcH2RKmHbPiuQzbv1pnzzavXnI62RD0bqCU=", + "lastModified": 1785967620, + "narHash": "sha256-IItrdb7Puk05RqOBWZYFC5X6Wl1sJmCfh5MWVHw5iMM=", "owner": "nixos", "repo": "nixpkgs", - "rev": "241313f4e8e508cb9b13278c2b0fa25b9ca27163", + "rev": "b7c2ada94fe99c15b0dbcf4d11fd7850b957a436", "type": "github" }, "original": { From 07f8a35b7414ea2cfc9bb9345ce08ccd12d705ae Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 8 Aug 2026 19:04:41 -0400 Subject: [PATCH 045/176] bump deps, remove hack for fallback theme that is no longer needed --- lib/main.dart | 7 +-- pubspec.lock | 24 +++++--- pubspec.yaml | 166 +++++++++++++++++++++++++------------------------- 3 files changed, 101 insertions(+), 96 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 53cc57b..aabfe47 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -112,7 +112,7 @@ class App extends StatelessWidget { data: (settings) => settings.useDynamicTheming ? lightDynamic : null, ) ?? - ColorScheme.fromSeed(seedColor: Colors.indigo)) + ThemeData.light().colorScheme) .theme, darkTheme: (ref @@ -122,10 +122,7 @@ class App extends StatelessWidget { data: (settings) => settings.useDynamicTheming ? darkDynamic : null, ) ?? - ColorScheme.fromSeed( - seedColor: Colors.indigo, - brightness: Brightness.dark, - )) + ThemeData.dark().colorScheme) .theme, themeMode: ref .watch(SettingsController.provider) diff --git a/pubspec.lock b/pubspec.lock index c204b95..9be2c20 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -293,10 +293,10 @@ packages: dependency: "direct main" description: name: dynamic_color - sha256: "43a5a6679649a7731ab860334a5812f2067c2d9ce6452cf069c5e0c25336c17c" + sha256: "4aeb76de323e8eb660bab5557d826ad7ebbf1434a598f0c6aa8a11a9696a6757" url: "https://pub.dev" source: hosted - version: "1.8.1" + version: "1.9.0" dynamic_polls: dependency: "direct main" description: @@ -366,10 +366,10 @@ packages: dependency: "direct main" description: name: ffigen - sha256: b7803707faeec4ce3c1b0c2274906504b796e3b70ad573577e72333bd1c9b3ba + sha256: "56fc0be88937409839a59c133dfdee4165e80da324c9e39f59013060249ffb44" url: "https://pub.dev" source: hosted - version: "20.1.1" + version: "21.0.0" file: dependency: transitive description: @@ -762,10 +762,10 @@ packages: dependency: "direct dev" description: name: json_serializable - sha256: ffcd10cde35a93b2abbbcc26bd9971f4ca93763e8abe78d855e3c4177797e501 + sha256: e45aefa0324f08c683caafbb94b72837aa6193c61822799c916e45f4a263113d url: "https://pub.dev" source: hosted - version: "6.14.0" + version: "6.14.1" leak_tracker: dependency: transitive description: @@ -819,10 +819,10 @@ packages: dependency: "direct main" description: name: m3e_buttons - sha256: af1b19bd5ec7327d20b5a57c6c91e1ed30ee15a4dbade781c0cdbc72e6b04b5e + sha256: "20b29df165d4d866ffd0d4808090210740690707705f44fc61c9b275bec3af36" url: "https://pub.dev" source: hosted - version: "0.0.4" + version: "0.0.5" m3e_card_list: dependency: "direct main" description: @@ -951,6 +951,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + native_toolchain_c: + dependency: transitive + description: + name: native_toolchain_c + sha256: f9c168717100ae6d9fee9ffb0be379bf1f8b26b0f6bcbd4fdddcd931993a6a72 + url: "https://pub.dev" + source: hosted + version: "0.19.2" navigation_rail_m3e: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 72748b1..adf1ba1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,95 +4,95 @@ version: 0.1.0 publish_to: none flutter: - fonts: - - family: fallback-emoji - fonts: - - asset: assets/fonts/NotoColorEmoji.ttf - - family: fallback-sans - fonts: - - asset: assets/fonts/Roboto.ttf - assets: - - assets/ - uses-material-design: true + fonts: + - family: fallback-emoji + fonts: + - asset: assets/fonts/NotoColorEmoji.ttf + - family: fallback-sans + fonts: + - asset: assets/fonts/Roboto.ttf + assets: + - assets/ + uses-material-design: true environment: - sdk: "^3.12.2" + sdk: "^3.12.2" dependency_overrides: - path_provider_android: 2.2.23 # Pinned to avoid JNI - linkify: - git: - url: https://github.com/appelladev/linkify - ref: fix/consecutive-periods-loose-url + path_provider_android: 2.2.23 # Pinned to avoid JNI + linkify: + git: + url: https://github.com/appelladev/linkify + ref: fix/consecutive-periods-loose-url dependencies: - flutter: - sdk: flutter - flutter_localizations: - sdk: flutter - flutter_riverpod: 3.3.2 - hooks_riverpod: 3.3.2 - intl: 0.20.2 - fast_immutable_collections: 11.2.0 - path_provider: 2.1.6 - url_launcher: 6.3.2 - freezed_annotation: 3.1.0 - image_picker: ^1.2.3 - path: 1.9.1 - dynamic_color: 1.8.1 - collection: 1.19.1 - window_manager: 0.5.2 - color_hash: 1.0.1 - flutter_widget_from_html_core: 0.17.2 - flutter_svg: 2.3.0 - json_annotation: 4.12.0 - shared_preferences: 2.5.5 - fluttertagger: 2.3.2 - dynamic_polls: 0.0.7 - flutter_hooks: 0.21.3+1 - ffi: 2.2.0 - hooks: 2.0.2 - code_assets: 1.2.1 - ffigen: 20.1.1 - timeago: 3.7.1 - http: 1.6.0 - flutter_linkify: 6.0.0 - linkify: 5.0.0 - emoji_text_field: - git: - url: https://github.com/Henry-Hiles/emoji_text_field - flutter_blurhash: 0.9.1 - super_sliver_list: 0.4.1 - media_kit: 1.2.6 - media_kit_video: 2.0.1 - media_kit_libs_video: 1.0.7 - measure_size: 5.0.2 - m3e_buttons: 0.0.4 - navigation_rail_m3e: - git: - url: https://github.com/Henry-Hiles/material_3_expressive - path: packages/navigation_rail_m3e - m3e_card_list: 0.1.0 - xdg_directories: 1.1.0 - package_info_plus: 10.2.1 - app_links: 7.2.1 - file_selector: ^1.1.0 - + flutter: + sdk: flutter + flutter_localizations: + sdk: flutter + flutter_riverpod: 3.3.2 + hooks_riverpod: 3.3.2 + intl: 0.20.2 + fast_immutable_collections: 11.2.0 + path_provider: 2.1.6 + url_launcher: 6.3.2 + freezed_annotation: 3.1.0 + image_picker: ^1.2.3 + path: 1.9.1 + dynamic_color: 1.9.0 + collection: 1.19.1 + window_manager: 0.5.2 + color_hash: 1.0.1 + flutter_widget_from_html_core: 0.17.2 + flutter_svg: 2.3.0 + json_annotation: 4.12.0 + shared_preferences: 2.5.5 + fluttertagger: 2.3.2 + dynamic_polls: 0.0.7 + flutter_hooks: 0.21.3+1 + ffi: 2.2.0 + hooks: 2.0.2 + code_assets: 1.2.1 + ffigen: 21.0.0 + timeago: 3.7.1 + http: 1.6.0 + flutter_linkify: 6.0.0 + linkify: 5.0.0 + emoji_text_field: + git: + url: https://github.com/Henry-Hiles/emoji_text_field + flutter_blurhash: 0.9.1 + super_sliver_list: 0.4.1 + media_kit: 1.2.6 + media_kit_video: 2.0.1 + media_kit_libs_video: 1.0.7 + measure_size: 5.0.2 + m3e_buttons: 0.0.5 + navigation_rail_m3e: + git: + url: https://github.com/Henry-Hiles/material_3_expressive + path: packages/navigation_rail_m3e + m3e_card_list: 0.1.0 + xdg_directories: 1.1.0 + package_info_plus: 10.2.1 + app_links: 7.2.1 + file_selector: ^1.1.0 + dev_dependencies: - build_runner: ^2.15.1 - flutter_lints: 6.0.0 - freezed: 3.2.6-dev.1 - riverpod_lint: 3.1.4 - flutter_launcher_icons: 0.14.4 - json_serializable: 6.14.0 + build_runner: ^2.15.1 + flutter_lints: 6.0.0 + freezed: 3.2.6-dev.1 + riverpod_lint: 3.1.4 + flutter_launcher_icons: 0.14.4 + json_serializable: 6.14.1 flutter_launcher_icons: - ios: true - android: true - image_path: assets/icon.png - adaptive_icon_background: assets/background.png - adaptive_icon_foreground: assets/foreground.png - adaptive_icon_monochrome: assets/monochrome.png - remove_alpha_ios: true - windows: - generate: true \ No newline at end of file + ios: true + android: true + image_path: assets/icon.png + adaptive_icon_background: assets/background.png + adaptive_icon_foreground: assets/foreground.png + adaptive_icon_monochrome: assets/monochrome.png + remove_alpha_ios: true + windows: + generate: true From a2cdc3df685702c7e9ca5fb97dd11eefa9fa497c Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 8 Aug 2026 19:08:20 -0400 Subject: [PATCH 046/176] set CC manually macos --- hook/build.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hook/build.dart b/hook/build.dart index 4c89389..067ccba 100644 --- a/hook/build.dart +++ b/hook/build.dart @@ -48,7 +48,8 @@ Future main(List args) => build(args, (input, output) async { break; case OS.macOS: libFileName = "libgomuks.dylib"; - extraEnv = {"SDKROOT": await getXCodeTool()}; + + extraEnv = {"CC": await getXCodeTool(findTool: "clang")}; break; case OS.windows: libFileName = "libgomuks.dll"; From a0e5d2fb9edc1f510c1ba6c51a94f3a33d304e42 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 8 Aug 2026 19:48:56 -0400 Subject: [PATCH 047/176] make macos-related actions not use nix --- .github/workflows/ios.yml | 26 ++++++++++++-------------- .github/workflows/macos.yml | 32 ++++++++++++-------------------- 2 files changed, 24 insertions(+), 34 deletions(-) diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml index dc7fa02..5f16f9f 100644 --- a/.github/workflows/ios.yml +++ b/.github/workflows/ios.yml @@ -16,24 +16,22 @@ jobs: with: submodules: recursive - - name: Lix GHA Installer Action - uses: samueldr/lix-gha-installer-action@v2026-02-22 + - name: Set up Flutter + uses: subosito/flutter-action@v2 with: - extra_nix_config: experimental-features = nix-command flakes flake-self-attrs + flutter-version: 3.44.4 + + - name: Set up Go + uses: actions/setup-go@v6 + with: + go-version-file: gomuks/go.mod - name: Build app run: | - nix develop --command bash -c ' - set -e - flutter pub get - dart scripts/generate.dart - flutter pub run build_runner build - - FLUTTER_ROOT="$(dirname "$(dirname "$(readlink -f "$(command -v flutter)")")")" - sudo find -L "$FLUTTER_ROOT" -type d -iname "*.framework" -exec chmod -R u+w {} + - - flutter build ios --release --no-codesign - ' + flutter pub get + dart scripts/generate.dart + flutter pub run build_runner build + flutter build ios --release --no-codesign # Unsigned IPA: SideStore/AltStore re-sign this on-device with the # user's own Apple ID at install time, so no certificate is needed here. diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index f263d68..4cbe444 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -16,27 +16,19 @@ jobs: with: submodules: recursive - - name: Lix GHA Installer Action - uses: samueldr/lix-gha-installer-action@v2026-02-22 + - name: Set up Flutter + uses: subosito/flutter-action@v2 with: - extra_nix_config: experimental-features = nix-command flakes flake-self-attrs + flutter-version: 3.44.4 + + - name: Set up Go + uses: actions/setup-go@v6 + with: + go-version-file: gomuks/go.mod - name: Build app run: | - nix develop --command bash -c ' - set -e - flutter pub get - dart scripts/generate.dart - flutter pub run build_runner build - - FLUTTER_ROOT="$(dirname "$(dirname "$(readlink -f "$(command -v flutter)")")")" - sudo find -L "$FLUTTER_ROOT" -type d -iname "*.framework" -exec chmod -R u+w {} + - - flutter build macos --release - ' - - - name: Upload installer artifact - uses: actions/upload-artifact@v6 - with: - name: App - path: build/macos/Build/Products/Release/Nexus.app + flutter pub get + dart scripts/generate.dart + flutter pub run build_runner build + flutter build macos --release From 842ab0a82cb305ee7df333c3df7dec7eec9557d7 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 8 Aug 2026 19:57:03 -0400 Subject: [PATCH 048/176] don't use xcrun clang on macos --- hook/build.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/hook/build.dart b/hook/build.dart index 067ccba..bea580b 100644 --- a/hook/build.dart +++ b/hook/build.dart @@ -48,8 +48,6 @@ Future main(List args) => build(args, (input, output) async { break; case OS.macOS: libFileName = "libgomuks.dylib"; - - extraEnv = {"CC": await getXCodeTool(findTool: "clang")}; break; case OS.windows: libFileName = "libgomuks.dll"; From 6c1d3d889430b1672c67023006156992fc941d71 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 8 Aug 2026 20:08:49 -0400 Subject: [PATCH 049/176] debug macos --- .github/workflows/macos.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 4cbe444..aa286f5 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -26,9 +26,33 @@ jobs: with: go-version-file: gomuks/go.mod + - name: Debug macOS compiler + run: | + echo "CC:" + go env CC + + echo "SDKROOT:" + echo "$SDKROOT" + + echo "xcrun SDK:" + xcrun --sdk macosx --show-sdk-path + + echo "clang:" + xcrun --sdk macosx --find clang + + echo "clang search paths:" + echo '#include ' | \ + xcrun --sdk macosx clang -v -E -x c - >/dev/null + - name: Build app run: | flutter pub get dart scripts/generate.dart flutter pub run build_runner build flutter build macos --release + + - name: Upload installer artifact + uses: actions/upload-artifact@v6 + with: + name: App + path: build/macos/Build/Products/Release/Nexus.app From 75ad6cbd02d4f6671ded1bdf08ba8f78fcc0f172 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 8 Aug 2026 20:20:02 -0400 Subject: [PATCH 050/176] set SDKROOT for macos build --- .github/workflows/macos.yml | 18 ------------------ hook/build.dart | 3 +++ 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index aa286f5..aca9ea0 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -26,24 +26,6 @@ jobs: with: go-version-file: gomuks/go.mod - - name: Debug macOS compiler - run: | - echo "CC:" - go env CC - - echo "SDKROOT:" - echo "$SDKROOT" - - echo "xcrun SDK:" - xcrun --sdk macosx --show-sdk-path - - echo "clang:" - xcrun --sdk macosx --find clang - - echo "clang search paths:" - echo '#include ' | \ - xcrun --sdk macosx clang -v -E -x c - >/dev/null - - name: Build app run: | flutter pub get diff --git a/hook/build.dart b/hook/build.dart index bea580b..07ffe1b 100644 --- a/hook/build.dart +++ b/hook/build.dart @@ -48,6 +48,9 @@ Future main(List args) => build(args, (input, output) async { break; case OS.macOS: libFileName = "libgomuks.dylib"; + + extraEnv = {"SDKROOT": await getXCodeTool()}; + break; case OS.windows: libFileName = "libgomuks.dll"; From b011cc21667645a0c0065b5bb08406c15d09cc9a Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 8 Aug 2026 20:31:09 -0400 Subject: [PATCH 051/176] reformat build hook file [skip ci] --- hook/build.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hook/build.dart b/hook/build.dart index 07ffe1b..66ae366 100644 --- a/hook/build.dart +++ b/hook/build.dart @@ -29,6 +29,7 @@ Future main(List args) => build(args, (input, output) async { iosSdk = iosConfig.targetSdk; final minVersion = iosConfig.targetVersion; iosSdkPath = await getXCodeTool(sdkType: iosSdk.type); + final archTriple = switch (targetArch) { Architecture.arm64 => "arm64", Architecture.x64 => "x86_64", @@ -36,6 +37,7 @@ Future main(List args) => build(args, (input, output) async { "Unsupported iOS architecture: $targetArch", ), }; + iosTargetTriple = iosSdk == IOSSdk.iPhoneSimulator ? "$archTriple-apple-ios$minVersion.0-simulator" : "$archTriple-apple-ios$minVersion.0"; @@ -48,9 +50,7 @@ Future main(List args) => build(args, (input, output) async { break; case OS.macOS: libFileName = "libgomuks.dylib"; - extraEnv = {"SDKROOT": await getXCodeTool()}; - break; case OS.windows: libFileName = "libgomuks.dll"; From 41658c3a9d94e79afa8a81a0d2af4786ea7b6551 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 8 Aug 2026 20:33:41 -0400 Subject: [PATCH 052/176] change output artifact name for macos ci --- .github/workflows/macos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index aca9ea0..4005dc5 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -36,5 +36,5 @@ jobs: - name: Upload installer artifact uses: actions/upload-artifact@v6 with: - name: App + name: Nexus.App path: build/macos/Build/Products/Release/Nexus.app From 1bd677eb238e7fc004460de724f5f34e53a33b9c Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 8 Aug 2026 20:36:48 -0400 Subject: [PATCH 053/176] add MacOS support to readme --- README.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 57b42d8..a5e6292 100644 --- a/README.md +++ b/README.md @@ -15,12 +15,12 @@ A simple and user-friendly Matrix client made with Flutter and a Gomuks backend. ## Progress -- [ ] Platform Support +- [x] Platform Support - [x] Linux - - [x] Windows + - [x] Windows - Currently has some bugs, due to us not having any developers on Windows. If you want to fix these, get in contact with us though the [Nexus Client Matrix room](https://matrix.to/#/#nexus:federated.nexus). - [x] Android - - [ ] MacOS ([#50](https://git.federated.nexus/Nexus/nexus/issues/50)) - - [ ] iOS + - [x] MacOS - Unsigned only, at the moment + - [x] iOS - Unsigned only, at the moment - [ ] Web (may not be possible) - [x] Login (via OAuth) - [x] Rooms / Spaces @@ -116,6 +116,9 @@ If you want to try out Nexus, grab one of the following artifacts from CI: - [Android APK](https://nightly.link/Henry-Hiles/nexus/workflows/android/main/APK.zip) - [Windows EXE](https://nightly.link/Henry-Hiles/nexus/workflows/windows/main/windows-installer.zip) +- [Unsigned iOS IPA](https://nightly.link/Henry-Hiles/nexus/workflows/ios/main/Nexus.ipa.zip) +- [Unsigned MacOS App](https://nightly.link/Henry-Hiles/nexus/workflows/macos/main/Nexus.App.zip) +- [Windows EXE](https://nightly.link/Henry-Hiles/nexus/workflows/windows/main/windows-installer.zip) - Flatpak - [AArch64/Arm64](https://nightly.link/Henry-Hiles/nexus/workflows/flatpak/main/flatpak-aarch64.zip) - [x86_64/AMD64](https://nightly.link/Henry-Hiles/nexus/workflows/flatpak/main/flatpak-x86_64.zip) @@ -126,8 +129,8 @@ If you want to try out Nexus, grab one of the following artifacts from CI: #### Linux -- With Nix: Either use direnv and `direnv allow`, or `nix flake develop` -- Without Nix: Install Flutter, Go, Git, Libclang, Libass, MPV, and Glibc. Do not use any Snap packages, they cause various compilation issues. +- On NixOS: Either use direnv and `direnv allow`, or `nix flake develop` +- On other distros: Install Flutter, Go, Git, Libclang, Libass, MPV, and Glibc. Do not use any Snap packages, they cause various compilation issues. #### Windows From 724171384c3fdbc2618fb37887c6d87da0e53e28 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 8 Aug 2026 20:49:23 -0400 Subject: [PATCH 054/176] change readme wording [skip ci] --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a5e6292..368bb90 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,8 @@ A simple and user-friendly Matrix client made with Flutter and a Gomuks backend. - [x] Linux - [x] Windows - Currently has some bugs, due to us not having any developers on Windows. If you want to fix these, get in contact with us though the [Nexus Client Matrix room](https://matrix.to/#/#nexus:federated.nexus). - [x] Android - - [x] MacOS - Unsigned only, at the moment - - [x] iOS - Unsigned only, at the moment + - [x] MacOS - Unsigned .App only + - [x] iOS - Unsigned .ipa only - [ ] Web (may not be possible) - [x] Login (via OAuth) - [x] Rooms / Spaces From 620440e2a102b7a724b12813b3327d3ea40371a8 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Mon, 10 Aug 2026 22:50:13 -0400 Subject: [PATCH 055/176] Allow logging into homeservers without discovery working --- lib/controllers/client.dart | 2 +- lib/pages/select_server.dart | 56 ++++++++++++++++++++++++------------ 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/lib/controllers/client.dart b/lib/controllers/client.dart index e31e4f3..33af1b5 100644 --- a/lib/controllers/client.dart +++ b/lib/controllers/client.dart @@ -311,7 +311,7 @@ class ClientController extends AsyncNotifier { Future discoverHomeserver(Uri homeserver) async { try { final response = await _sendCommand("discover_homeserver", { - "user_id": "@fake-user:${homeserver.host}", + "user_id": "@fake-user:${homeserver.authority}", }); return Uri.parse(response["m.homeserver"]?["base_url"]); } catch (error) { diff --git a/lib/pages/select_server.dart b/lib/pages/select_server.dart index 853e5fc..e8e689b 100644 --- a/lib/pages/select_server.dart +++ b/lib/pages/select_server.dart @@ -26,6 +26,17 @@ class SelectServerPage extends HookConsumerWidget { final homeserverUrl = useTextEditingController(); Future setHomeserver(Uri? newHomeserver) async { + if (newHomeserver == null) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + "Failed to parse homeserver URL. Are you sure you typed it correctly?", + style: .new(color: theme.colorScheme.onErrorContainer), + ), + backgroundColor: theme.colorScheme.errorContainer, + ), + ); + } isLoading.value = true; try { @@ -33,26 +44,14 @@ class SelectServerPage extends HookConsumerWidget { newHomeserver = Uri.https(newHomeserver!.path); } - final newUrl = newHomeserver == null - ? null - : await ref - .read(ClientController.provider.notifier) - .discoverHomeserver(newHomeserver); + final newUrl = await ref + .read(ClientController.provider.notifier) + .discoverHomeserver(newHomeserver!); if (context.mounted) { - if (newUrl == null) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - "Homeserver verification failed. Is your homeserver down?", - style: .new(color: theme.colorScheme.onErrorContainer), - ), - backgroundColor: theme.colorScheme.errorContainer, - ), - ); - } else { + Future tryLogin(Uri url) async { final codeResponse = await ref.watch( - AuthUrlController.provider(newUrl).future, + AuthUrlController.provider(url).future, ); await ref.watch(LaunchHelper.provider).launchUrl(codeResponse.url); @@ -70,7 +69,7 @@ class SelectServerPage extends HookConsumerWidget { .watch(ClientController.provider.notifier) .exchangeToken( .new( - homeserverUrl: newUrl, + homeserverUrl: url, codeVerifier: codeResponse.codeVerifier, redirectUri: .new( scheme: "nexus.federated.nexus", @@ -78,7 +77,7 @@ class SelectServerPage extends HookConsumerWidget { ), code: code, clientId: await ref.watch( - ClientIdController.provider(newUrl).future, + ClientIdController.provider(url).future, ), ), ) @@ -89,6 +88,25 @@ class SelectServerPage extends HookConsumerWidget { } }); } + + if (newUrl == null) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + "Homeserver verification failed.", + style: .new(color: theme.colorScheme.onErrorContainer), + ), + action: SnackBarAction( + onPressed: () => tryLogin(newHomeserver!), + label: "Attempt log in anyways", + textColor: theme.colorScheme.onErrorContainer, + ), + backgroundColor: theme.colorScheme.errorContainer, + ), + ); + } else { + tryLogin(newUrl); + } } } catch (error, stackTrace) { showError(error, stackTrace); From b9dfbd3ca2905baacd1a6094f505d663148df367 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 11 Aug 2026 10:16:18 -0400 Subject: [PATCH 056/176] update MacOS icons --- .../AppIcon.appiconset/Contents.json | 132 +++++++++--------- .../AppIcon.appiconset/app_icon_1024.png | Bin 102994 -> 84720 bytes .../AppIcon.appiconset/app_icon_128.png | Bin 5680 -> 6314 bytes .../AppIcon.appiconset/app_icon_16.png | Bin 520 -> 700 bytes .../AppIcon.appiconset/app_icon_256.png | Bin 14142 -> 13425 bytes .../AppIcon.appiconset/app_icon_32.png | Bin 1066 -> 1391 bytes .../AppIcon.appiconset/app_icon_512.png | Bin 36406 -> 28715 bytes .../AppIcon.appiconset/app_icon_64.png | Bin 2218 -> 3005 bytes pubspec.yaml | 2 + 9 files changed, 68 insertions(+), 66 deletions(-) diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json index a2ec33f..96d3fee 100644 --- a/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,68 +1,68 @@ { - "images" : [ - { - "size" : "16x16", - "idiom" : "mac", - "filename" : "app_icon_16.png", - "scale" : "1x" + "info": { + "version": 1, + "author": "xcode" }, - { - "size" : "16x16", - "idiom" : "mac", - "filename" : "app_icon_32.png", - "scale" : "2x" - }, - { - "size" : "32x32", - "idiom" : "mac", - "filename" : "app_icon_32.png", - "scale" : "1x" - }, - { - "size" : "32x32", - "idiom" : "mac", - "filename" : "app_icon_64.png", - "scale" : "2x" - }, - { - "size" : "128x128", - "idiom" : "mac", - "filename" : "app_icon_128.png", - "scale" : "1x" - }, - { - "size" : "128x128", - "idiom" : "mac", - "filename" : "app_icon_256.png", - "scale" : "2x" - }, - { - "size" : "256x256", - "idiom" : "mac", - "filename" : "app_icon_256.png", - "scale" : "1x" - }, - { - "size" : "256x256", - "idiom" : "mac", - "filename" : "app_icon_512.png", - "scale" : "2x" - }, - { - "size" : "512x512", - "idiom" : "mac", - "filename" : "app_icon_512.png", - "scale" : "1x" - }, - { - "size" : "512x512", - "idiom" : "mac", - "filename" : "app_icon_1024.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} + "images": [ + { + "size": "16x16", + "idiom": "mac", + "filename": "app_icon_16.png", + "scale": "1x" + }, + { + "size": "16x16", + "idiom": "mac", + "filename": "app_icon_32.png", + "scale": "2x" + }, + { + "size": "32x32", + "idiom": "mac", + "filename": "app_icon_32.png", + "scale": "1x" + }, + { + "size": "32x32", + "idiom": "mac", + "filename": "app_icon_64.png", + "scale": "2x" + }, + { + "size": "128x128", + "idiom": "mac", + "filename": "app_icon_128.png", + "scale": "1x" + }, + { + "size": "128x128", + "idiom": "mac", + "filename": "app_icon_256.png", + "scale": "2x" + }, + { + "size": "256x256", + "idiom": "mac", + "filename": "app_icon_256.png", + "scale": "1x" + }, + { + "size": "256x256", + "idiom": "mac", + "filename": "app_icon_512.png", + "scale": "2x" + }, + { + "size": "512x512", + "idiom": "mac", + "filename": "app_icon_512.png", + "scale": "1x" + }, + { + "size": "512x512", + "idiom": "mac", + "filename": "app_icon_1024.png", + "scale": "2x" + } + ] +} \ No newline at end of file diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png index 82b6f9d9a33e198f5747104729e1fcef999772a5..d4a31c5cc5625b5da69336ca183c2e1e640279b0 100644 GIT binary patch literal 84720 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

y1?+7S4)s`M{4L~M`zbDP1+_|Z<2lQ0HnU9G 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 JS?83{1OTk2^yhH3)Vq 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

y_uhUqwLR%$*pFW?72VBUg9j9 zo12&9oH(12m-F~~?|ZGayhbbglP_y?Y02MSV*CH#0}V|kr41iIvGu`u1z(4QIm?G< z{|znw-#zfggG=W3os;GM`|sWS{;@CQo7ypJiGP*Sh4b^0FW3o}Jiq$-=ItkcwjYdG zsXOiO|4*A|-wgNfo%7$T*Guc;JqN?bd(hdtT+Gf$?Kix zW5;P=)}8-nVob_&`EQ309uRF?eCOMKaN)T9d4%hsWqAjnS$M1ot_1ph};HYAk;Ig^9i~XF<$t~u`KNYp_|Gqpi z-^Kjng46qc3$r>j%wKl*=)C{@H!}aX>s{OQpYw``;G3WSx9-1tW}fNu`N?e?&OW^z zylndQFZ(_i2`ra+m29;}+?MyK!J+apgXCq^uYG6fbxu#Z?yU0Bq))Y2M(4_=|1Y*I z1r6{zFjZMe3G55$K5&6$!*luNe^39EuTnXdZ}zrx`-`)6f%iU$UEkht{(8nq3#Vfr z5A=6eE)Lmy|HIGx-C4HQ>-_&-Wxl?^?AxFEd*A-p|9h49Tt4~6x2$6MkgKsz9(=M} zqqTT)mD~*lww@|R<2_aRVd{T*T0~ARubUz|m0f9)epP~_Ryl-Lr}%KOKnYGfi~@3j8# z`wr=KX5?9aOUS$3PhB>`SL6M z!>135vo5aTQi=*+n8zW-ad-uP+6moTpYK=MfZUT{2x|5j9`g+Aa!6;1+m`x&{)W{5 z_LpY=KR2Vw@!tZwC&s?VmFpjDZ7Kiu*Ykg^T}}1w?H(BOlumov{`HW_w?Fsu zPXF8b++O8!tyJ~D`s6*&=U>_@e0-0Z;(OsOy&vBnIK8~q_r2w|d>J7rr?PG7$tRi> ze_h(lxmztIgL|UMv*@i4BNl%96VAGu@^Sj^o=lGyF{pkwsz%%Yu7uRpl-~3Db+S*IsyWgDs|NAVc z)u#J<{h`&qvU`61_r3l3zv%7H=eajVCZDPbJuG`NH2TVF_v)Kk+w5N56lIF4;7#BO zJtWhoeE7m1iOfFt`Bt^|AHpABTYT&D`J$!p}g9Q+=9iH!cX-u(a4 z^21XepId%u!MBjPg_5$r7Q9-g^6KKn^N)9D^%(tdhzr^ya8piR?oFlQ{M6Vl!qxxm ztIk%HJrT0}pCY4uWZr-O+nfF`KR*B0XTIpm8^3&Snl8SYKTa>VZ`t&@pS@~rbo$dy z^j!*2^CMYkq!yvcpccref#gN1anVXFmP$W62>QmmBGi zlC9oEMb<^+he_rCdvEys|AsmLBWGA?S|``r*Bw;j-*5ZxN__M}iTXRrd;B%{U+TT% zJ(cWH>(OqN^y2i_wz-Q9?Y^9tDgf!+Bf>wIS{?cbGl_2q`w){9nL;Mwu@#=SRh z+pm|O5)lT?xr&13TtRad#ig7HH|_1dE@%F4wTu13ldkp?ADdN}EWXT;Iq}%zw*SSc z`+w?d>tt0kL(S@5E(#YO*iJ4I=+Pi~L+_J6Ipo4MZcS=$ZY{|sVeWzA^r z-Xw9}SozPVUrHV8)i0Ir;@nep>)EwsoIKCXUaVj`&hn^2zf@({q#5%sHP%nHSUHKK z<3N$ngMw z(;qggB9|DX9BBV(AYYp#>HN*u$GASOqVezgR_6cfuFd;jxgu(M{*8J6ObJKXV(!Muf`&1azpdQ=Jp9X+`h8RNr3$ARy2u`r+$1X(@^^N% ze7dasCfh@Q6t_R{6i@B0TgY9J@ICfp=CR0g6aMmDJ~Ll*-Ruj$-v-xPy{#8pns@5V z_w#apucdwKS*vg;;!*mw&~zJ3?p%TOm&>N{?mKgO8Q=QpR+7KAU3|3AC_hDIX$a%T zp36L+KCFs-_IX#I_|3*W8M{_qD7lkS{qKIA%jti+<$_NNGYUrNfLi5iK2F-I6wrC# z^|LSbN!9oI8eL0br51#WM|JI#(O|$4;;C1^wVpko1r|#PG`M^Ja z!xuX?i{GC8pFe)@JXsf)@DQfuxi|mo+wPueYhCtlVNdeu!sj!to3^}FT)(nM%WCEE z*9r2gw)BS`mu69&*sH|8B596dXuI0NyffNY+^rYAlqvsF>%R55y;L%%7^7f>2FP(M z9!}b*WH2Ax4u1PHKJ|IMxT;O!r>f64cKZhZbBNTLvyBVC>`k1jHAnx<>?dbGeEb-vXZzvU*+H+ueGz4Sr+=YzrCf&z_8l@@S9 z*FkQ2lRBHB;-cK6>Hj|YPrepu@x0{4;eG6(%U^Ajb+Y;)Yv67F2e+ait zg;6X^7e`EHpU^kY!-ZbY9tEo(Ryv$ERrD(Vuj$rr)ec*K+9x@;+NScCl`Egk>BOJ~ z$GXov7T&qrYnpQN;h-aosXFO5Qr8#q+gHq;^Ivb~w3AlZ=l&nQe`|)t|A#kzmCWo} z^>adKiG66U{c5?VRn;@iSI0h2HE0m$`M_pae_+Bh!#9VgC<^TP{z2~T&-cj%OPyI< z5*C7Lt%Ysg$GRL$nJiS^>fP3#d!{VYuCf2H)AF0AYWDT}SJ}SLEY+!hbVdA1`n4r} zoafc~)x4G|ud$!ITT1hbtVer7gZ`hpx!*VN{pqe>p9o57ntG0B?J_3!p~*}_?Zv4xFHFVepM-oU*4Z+v~p{ROpp z2NvjnMyMs`G^jDK$umhRFcosdWd2^7zxn*qtMgbs`1hnP3tbs}VVYm<%)@h^&(67` zz3TDRMSM>kLuZ`(eC+2G(QEqI?SDdd*@SEd6HOo~5!?ZOO}o<*KA?NNVU?l5}a+jrEj^YFa? z(R^<&Hr5A+OaZM}Ys_S-IyCFq!YQDU$~klXEttz$U^jo?F~$2`{-ryfG?t!f+-4P= zDQr;qMp4>6?wmz__*~7Si_0p5Pq<48y>t3)bN|x{`!~#&_vw9}v%)57n*6osXC)04 zmqMRx=26^foFBCD@d?&%_LrKkzde0#+2w!MYP+NF9J`ir{(t!0%>Q+3YP;1QpEKK0 zE|7lfbg$@gy|#^C-c0gt<&bn=YOr^8;vSwA$0Q159%atb-+6+qKXYHpPt&|3oBk*N zeik0W3rZjniJ-#h;lc3h;q46H0+Ur4zJ)$MC7WT>`|*>1+GBO2YmOF$)7Iv!x@j@- z`q#HVLfVUdJ61-hPv@*$Va)e=#nHgFnwFmDUo-S)?XWtNCfj!6d*QX&Q{TVVDVACD zvH5g>pC!k>p3;Ex$0xq~bZGfMyOi%Q9(E`8uA9NK;rajYeVZrRKK}M6I9~AYs>knM zw-(M{wr-nZ%B8rLo?!9A+p4s-E;o{|YMv4A8BsoU!L`{3E6Sx-c`lMwY%_@UjVfIG z{pP0s(tT_Ee?`Z5?}UsN&0@GKjfvNBk(U z@Y^gGc<|>p@ku3HUe5Tv+~8We>=xHKnJprc&o=XYt&EJ*KP?)jKH>A`S2Fc&S5-@b zg}a+t}okOb6?QZ&rR2aXUVXzolf4Boou?Cxz4bUbh(C5c~O)U)w@*#bf>Oqv`Lv z+Rfgs+K?ovxP8%<^UiZJ+nkl6H&=gDF7wYiU;iiY#x}YXOW!TKhW0nNUsb&B+WxX4PPZ!U>FjR?b2yxK z7dp4?>nWTj`Z7VbWzF-?BJ=$foH1`#9f={fpkc z^z*jaT&nl`NU-!x^Z5B?2bTq3&YiX7&)%zBb8ZBe>=%1#x^Zuj^!f|sJ2o}E)4rr4 z|EuD=RJyl{SUvxRc{g=mPra9t|L=ZfPW@gt$VN78KL`IC0Ta;Pqt5|eEMaX2IB)Yc)LyUP?moT0 z@%yS%KZISTC?xbN6sJYRr30md#vs$uD-O)Crte3j_3FCzsqe~@}kR|A^%_f z=iRe!hBu}DFWuVqy=VXY7cHOdoF%TUU)}$;`-#E%*B`%a$lWr5t%B9Ha-U7noL47V zY^qX?-pRjp5c()#_F(<7wYNU=9|4a;FA!w3tu;Ng%uQ*742uEhhrr)13+#mxEUUKN z*?YiwYyE}vJM9VwOdfNz?<-h;H~agXIsbnsH`@N6UsGlL`*V1K`kC@m>6Y1ho@bc8 zUpw)Mtb2dvwQT9C*()}Cq+PG-F7f%q(aiRBRZWts+(J&1&ZTG4t;#%DwlHTN+kJ(1 zrn%giFVFUSuK?{%*-!-P%oI7Vrc7-)^qwTji- zl{R!U$jSBJOk{|dRO>LAVfPQ7nS#H>eA@Z{)Ld}0t8d$~+ru2x!L0sQ_(1-5V2FR^ zThLrb{;lQz{xsI_aIcuJkYmj@Mf`VNbImPYqm5r3kKfT2T%5qR{({Pr-$mEDMT5lO zChYRAeQ&+U_J8cBDLSBx1sXHCDqHqOHpa0Dmb@=zv)zwE{zgSehFxKO8 z*(Pbu^^Gd6lC42gOO1d0 z%l@8fk?#~9!xVix^4p5HKmT`!pZA^fY~6eD_b;}-^}T2t^KChM>FHCqZW&&^Cwat%- z8=kNfs2y~PHYgVXsx@GKNB{4a3UA5{^ZRxdhhI>9-DRih94Bt{{N#dt20d1C_f{D2IaiscT?x)-E6QN{ zJn`Gdz}5fiFY9G|`)D>T;pTtq{>=0B(rsDVpm}uAKExIm&}8_DbvsH*)EK_yzV32v z;6G7Q;Qr!sja46O;nGL<4(=4n-(2k(9>a78)EeK@?DlKIt50@KI;Un|yOR4~LweVw zogBuDi}!GLJZ?YJ_Q-X%L|G#HoO<2g@0*sSK#K_5nZBSR!X?3nA)VY&*x9y zx3@d@$x89Ia>^dR-)g0m{m$}_eV>%vYZG8ISk+;BRdy=Z<;#Uzrh9*_I{oPB+HUWA#RdLlhYjEU)L*tZ2Glso z@OSXfcq{4E#Gzx_*t~7xZ@p;F1#cPd@@%g6Xmhc-VcgIE(`WIW;}iXU91F$x!Qi^`qFt(oAwxHcr?$5_l_{1+8rYPv~+RqK9N_)Y!6yQ z{rpj*xjXyLD%=0N7izeJrbd+nB0e7f$>E|J#4>FP!#S286Xw3?JHKn~E77vO8fV*+ z?0A&VR`GQIIIE?-YJQO1yH5U_v+Ljf?6=qYapnI1pKrd*tIv4)S1c;v>%LEK1)uw0 z{kHI)R_3X13;V+-UaXYOXHZZ$JOA9&tHLJ?KdD`te8D&O#q+<8om)CzS}A_}b3bMN zuigJnRLxCW1e$h4+|UD|NK9 zAD>=*jq~=B3CH$+xV-Io{PMrY<$HVA7T;9QIsZTW`0~G>_sxDr*KkY!6o! zt(sCDnK&o2E%ZrgT>B|T*1~@!>sIV?nDOB3%6psU&vLoua=W+e!F;=~*IVY?0_7bC zV@u=8!StDY=B74|th+lzCnopS4msR z%Jct!k6eoM)ZmbRg~@I z3)(GYG>5a`yXkAmZ~1zUTHB-l9Qd<{J$l+^zF!?X*6BnWCzRi=6i|Qq$9=!-wztcE zpE15%{jW0L$@0Bt+h?96+fxa%{`VaIVpCaqTG9SWXt-PY*PAylXgn)lwql>ctd;_e zVhg_w^UMtTU;eT^ZDdn%uSB5w-`8jRIqkQCYmRL!CX5%REx6TvfJ@k-=;RBZ25#XW z-a+3RMff-UNZh@M{kB1Wru~z|xEbF{rz`et{P!~Z`sT%DaxLq2u$;Rw?|=LJTPNmK z%`JcF5kI@SCs*(j`=y_U<$SYK@_q|gY0lnOu@ZD*!exu87d2YWG%FpGEL&Bx&0qz~ za-*xMKQ}Km(_d=4IcJsD-)D!nJ^%mdZ|LgP^T1Qs4#!!(uv|9`=oD@YRcdHIbhu3I zfb2GYncoN7_xy11dETU$`ziCt&&RhF`{b{sMyM>-(a$+tby^^)$MD*WABx*kUxatn z9+>w({{QXGH}Bt=SAQ=!@y4~h6N}H-9h>~?&;HE;`foFDZ;yJra7tSRvqXA?cgE&Z zA*~bCL_L%CF50y2^MdYQ3Br$kza*Uh|Mk}A`z&)I2{s)RUXos%LXB5d8)_fC-~RW3 z<{Fj{iw#~oPUXM8udlz_vMc@PjijE9U!B8am?}R1m%eX1`|nTf+rsIqS65Fik`ViA z-Er0W1(&SHEkW<})SV|Kj5b+33E3$>QR~<5mXB7e4D4%G@BLZ7+wN;P`|MYsb(0Pv zOjVP*n?jvj6TWgJ2t7#NW+Lsl&G9K?2Z!vsdf67hb-;o#Lsxw{PLbD|HPfBOWH8I`y?501gn@J~y4 z^f)DC3j546?h^kt=pNdzPXBYE{`u$HcD@YN{|u*1zdhp;=Ztj=L&8CQSo7SQ|IObV zu)p^>H?`XG-+i{HpYAhWj%|;#%l%jx`+Bv?dFcZdhrO6~t$%XW_}qr-+^;IXelP3v z{RtWZiRa&y1=@V#kis;Jp@S#lk!yk|XTnMgnd6`D#!J}PT<{+0LXPv;NcTV(s+_rl6v zP`+_de;{{$@#{%Uf&z`AN(Fz6Zu2GlKKA|QWgU6FpAMbuG0zx1CDLa-)X52bbtY^5 zrn@W#Y2V{_>mQbQ)#d$Q&CfsmH#Yr09xr?M$k=5Uuj;YyP~!^;O~V!yRP-y{x{D!U;kU$RS480R$yYZz3bYbHBm`{Ng327UaVeT zuVhg3Lv(!!N5X3RV{bkjy%+6ud|&D&mg;}@-_50OmcI$EcMUJh3p_j5#;PbM+N8_1 z(pu=&QK!Femz3U-3P>v3*S7N>k5O`QpX}w@w%8ZPHvKP`yM2H8%}bCS@&U~aY7AKi zf5u;GIiV8PaD&3hN!LoTvKMpnY=7K!?1)TWZ9Q>;;Uhvw$(b1sZu>BPO-y>fR zHtdV}_>kkk&-w?uzP{0V`?KGU1GMVmQMB~U$?MUQ)c^x%GX}sY%DK$yBBIm zbLILRU0rspa&l0jn{~pne(TNYZuh~>xQ(^OuU9~pXe#i6CK{7vQd&9IurxM*3;fxC zBl;P0@iyi)EIlq(m7Ra}3$9VLN_PM4@?D*GIN$N!`{ed1&W zyY>9i%Sr+)o%xR+UoQ1^_J_0|75l?_wg?Ibb^QLa;@BV1c6q+ye>bQ9)D3Y4wU}HI zJeaB;Nl)5W(tUtSXvd{{M#=Mk?lEQz6YzZ>`wW!-3rR_6bECqI4E z3j6V^V8@4Mn?DyAKbPw4{(SoMcdOdE=U%J1mN>FBm!0uG;4q6}@}ADn-PcQPZ#lS> zKFvN~ADgrayesCg@CB9wACd*4E`0g_Fre>}(gYpGIh-F7t6%R~x4U+O;h}l4JqJNE z=5}n+&%XY>o$g-!?vz*o0F%;)(uE!tQ4)cuvhN8b3E|c>8HJmobo&RH}7e` zFq>64gYEb_c44m23w;|l=-96*Uo87$x&PnR5Kxy%LuteDb&G1A^13_p-#fff|4Pld zb%&TzyAB8mS!85i_*lv?m-E8?2T8Aw&OPp4{qL)NQOvs=pZ~8eyY+u_zTf}I`F?M= zDawe)%ctsm|G9f<$?V`IlPm9Ltdmg$`Fx0@Df>ouC2olo7LcJ6<8&iVS;+-vtXx0TGe?p8N>+Z(~dYDQMs%oZjs zh07$%maW;fAi(r8&uZ^i>y};bwYbdlJd^2ObpMOs`p*_CV^~}gW*xY7E9$Df@nznr zU2YEkjTbMN3FmB1`8H7_R%t^NOM%(}+v{u6Z-lSX=4&)fuKo^66wc*QTHpTE|5=^B z>Hd%QwQq7hi0^%;d+t|7)gk`Nm!*Dt@~+*#VY*3ILqz8S38VeX1+p@QoMKE`A8Ksh zfB&A^t>CL-Hahnz3{J1JUu6FOZ|@9~&I3gPH}2h=wtwc0fGh_g@CJ|7UJo|Z_VfL| z^l@5L_;!|pbBCO-uS<7-dxtf)kaJIF{=fH?e@ebRy?!qB_OqY0|F3+zqQWrupjFrg zURjH_(v&SLrC;SMul~I4Uh~&Nsk0l3k6vZDq+*}OJlkYuM}ur=?#`R{{_KDK>F-sm zwNap+$G1*-)zQEqB6xwTK}qZI zvrMLhh=04c++J=}_EgiEC9IR-+w%K)e5?2IU8uWq@WbD-eTO{X{>sD7?@XtQHL0fk1(+Uf_dr<|} zj8Crmd6}>6WHnQaJ8m}H`b?hf8r%POds>!s9C!s<2J+=toG?RYZ>QfWpB#sja|$d4 z1`qyjONmWqGC9s)CU4wk5$^~ZTiKTP`kwmvlz5Zp@_f_&FJxxB|Nplcr@%bU2eL-@ z`^1dwr))BF7FS5O1k*}Z2{b% zlHX%a!#o~gX$4;f6*C2+bOWXzE)ST?3>NI;3#jKP=sQ$f_Tawa!PWfh)41n+`+p&R z-nn@u&*j8rzFvq-mzvCQ{$^Rj*-5=|iP7&j{H$2F;;H_vC(g$dZ`~Gpwmrml|4*IP zdj?J)zdrYVzlY8DQ`(P;=UmzxIoX%jZhP~8?yb-9jaxv2qGyy7R?lw#H`(I+k*V6( zSsap_*R6-RCxGern+sMs>=$M-Ty1Bx`~P;^oBv(jTc7W@+L~q>zuor#{Eeyq{~P|e zBL64IDxu@Df2-IW&IV70d7KaCcSTIk4YYsu^z9 zot=^CYS5T=L8Zkx?w;C>#uCxlZq@&;x0}T7as{vPwPT)fFCmLbq1W(XvGX!fhD@H0 zH6HB@(>6R7*vdylb+=lV|tDTX9|){-QDOEqAzA|GT|- zI*TA^5AQxE0R~TnmFh=X*bdHKz{%k6Tqt-$vEYK)w)@GyZ+(okj=jvX;m!YftFM1P zui-ac*Uvlo@6xwFhYO$i3)@aMX4GL~@14xxn{qYN*_P+xwd1c(bj69c zwcgX|O_jLYQN(J{Xuo1=gXhkT_xR+`b92{$24VW%dLR48Bs^7>Nom6ZmM@|WU)cPF z84mZIT<7_7bNYF{?1@{t9S*VFO9Q*Zm+1|U(47CbdrnT><^>v=Ecj>t{fgVS4Y?8RHRJ$-jK=H6y)KBlOm(RQ&{QuD*B8kwa& z#!GhE&YZS-Vcsog>6*HUwgsT|1&IB=(t^MBoKOww)vwdCV z^8@x7ONDQ=vd&>SFq0uRc0+%7a)CIzV|&Nw4bllAboZ`Gpqf*q;|6KU? zXMbJ(zKxc*KL2koyJfFu6;ZM$gW>bcJmDf$hA`PJdo#qH{#*!L5;M*CZncDzgL7ui zd$y_COIGq6o|XDDaj)LxD<=*1B+rn4wI{UtpR)>hBkKV#(E915!)rMkjDtbvKkR>BPyb~5|8q)9-}ODeKA*DW+;FqN znnAWUU;NQSd%<|S^ULB+?R{uqX0k(EdD+wpOJ3f&yK-M-*hTSc2iZgNtY)NMe|=#8 zUFH=sf&z^hEG29XCR=)0vzZnc?y}(hD%xNXqguL?Q^p$Hc5B~X(D{E+Y(nkt%-4^f zmi=p7w}Zv+cGMq!`#P)Nm&4uX|KgTix#O1mrR}~i`E#rf+~k_fu&}oC$GOjjqLSyr z5+y%Z^PMy@Nq@1E^96tItoCPn+rOv0-&6B{PnH(wAc{sm&KEoleuZU9KK_&DCcN=G z@y$%`H)tXM71e?Z-wr=^`IBlR%n&VOS5dR&d40z5#qW0LMEwok_Wb|lvRnTrmucDm zllaWPssH=c<*U+}TE4U7E}MM9X`d6K2n9O;3;ebJ`mO-7PmrkeZmP|3$H$V43 zT*3Ee_EC>iP&;9R7HDtN4UcSY@X3c_T@2rj?!SMI<$&GK)SVkvF+P_`SlzsC2g|)J zw*TkXW-0%^E3Un#tUrZou62jIOz@%m+fQ~>rZfF0yJxthU-smkUrC7?J)hjJO}|vl zeSUlS(?+MhOwrk(rF6=_uEaM4c!Fxfh)kxcMLyX-R{yD=H|^*qHx?n~f5-HM*05>@pDh^`|x<;=kvGQ6?r)>pLwtK<&)s?dM+Db zhTDvP>V@q1{`x2{k$Gm=Th$!z>c*R+;L9X^WM^cd_)bf> z&&rj&w9eq{AIC!%3M32{GzQ4dnj++V!|8X!soQNP>y&EDZ_oQ*o_YR1$Ar4>1`ZxK zhja#>wtXQR=jnJ~fNH$S`&dIs)8XWv{1rHo-_E&uJ@fxv>C#?zHvRqb z-L6vY_oD{(e;3vMUF4VbpVqFZ&RC%4V6@%T+A%p(!n$>W{hG-E9G^2cz4y{mYd4#^ z@bJ9)x!>a5+@PwG+tC^3bqkuu(P*|uQq}*9p2>a<~7Z9 z2@@3t&3LW%@&+IFny{5KgGpiI$Lop>pr%cv7E?r2{qfGPJip%r@BB7jSd&ULP=?9*LO}qQ~$jmqVahrNSGsl*^TQKjV!J1^L{KR>j4aK}{yDtd- zxuCI(-8f@=(xz{!oU>*of6>^xH}Q`x`}Y@H{tI+n0+nV8OvaoqRu-$x`^UX~d+^N* zH|y^&4P^PH)L_i`ZsXr?&T}{&)LBmdd%v&B)_RTY|BLOir~lQzTYo;q|JLkJiuyl} zh05;URhA_5pxQz>VZ~d97kBpX6%{SWdv3KVe#t(K^~$BaM=va^{LVG)@BYU(_MM#L zo!pwG0h+B++7JXTNDH!A!3F8GX$NlSs4{%J``wnap}kt>NBQiR`%di(SfH)PXz_o3 zb(ZpPetrJWRWg1ubp@@8vU>wFKi{9yZOk}tvnSvG&I8YavbVG_{&8HM5umY1$9|2t z=G&{r=L{yDa!bm*tTW}-=ldLMr69+aNHE&gs+CEvS-+nD^ORW<>@$^_Y6T9=WRTxv z%(y{h|9bBE%6l%CWSy_Cc@**O|B3pS_2=znE$$y)Rk_c1s>M^ICuI#Uv>8`SaQk#$ z;FDx}q>|zpEn{mz;bP;C^&G0-{@kz0=;!<6op~Uo8{9;Y0G-}umT(JFPApY#nEc)T zpKu``8_(R{&u{hLId6L&pa1Xi{jl^mr9a%~SlQmt$G!@JsaNN_G;K{ zxZ5v(mYYEfqg~&Z1K}Bc{=a`rNIS%L>yW^=9~PI)XML`3*8P1QGES(#Vc9PH|Pw5)i2K9a=Ni^jawE|LZo}xUm-@p6}}97zwUy@H_}g^w&qOjV|lHV zQrq$)(m1mGW+rGqq*bAQ4cq(p+nN9Oe||h8`~LFZ2dWSC|1RnMrFqK5`&8Q4tIBrHHC~{t*LZo`v%iP?=b!ucx^ik_zWx5zdB825DPX2~OJ(R3_jQkVimY68Q)hPg{I5yvp>HeRKeWBMTkpR7 zZJCpxCKe-TM}3u+Z_b9?nLbyaHyzQLZmG1vhJ|m|_x}eU_%QrA{N=yJ%(NG^N>6Uu zIF+@({b`>h7{ASC%B7c_-~QD9dVTo)Pj$h2>O3>!)l;HdcGUl|J+jH_Q-Run`?pmN z99#20$?2ev@sdLZXa6udomUOvH*PmFy>i;b$$s7${#^H2)&IIrO#xT2O0bk{xmB1^ zFd~cT`0;e61l5N64EHnaBB{_4m1-HS+7T9a?@F2!~5t@@ZQf_4hB| zSEI8NzKKP)ux|zrley+V9dcn_gBrsv;~cGpAO6?NGTjhaeyh{rJE%i-JcslDuOBP# z{$K1m$Ns_@qc=bIUq2^k@iXji<=Z-!WvY)-zcJUBs{M9iKWBfuU(r5n0~S>5$FT{$?`+|4kK!{d@sW3IaI8xNS1d z*-!iX8oV~k{@an4Z?u=c2-$v*d6nq#UbW2y8k3#(Zs{&-d%ESjSoP=iw*QwbgbtdsG1@LYw&0f2GQU$f zjQ+l^3POw)U*tFZ{WJa6#5<|{?>_v@-=6w^y8MNC|2+;H2zJ~4-=A^%-~KOAH#2-z zZR-lKnrrs{$W}q0ol^vtO^ly%{8wy?h46!FGfsn>d zpWBUUU!4!`6h5B$e}BTc`s?$5J(f>x`8>z`TJEjG0d|+-mg(oOTI^+=$3DYKLZGc8 zc@>A$f7JH7ISjZOu$J?=i=cQ0xA-~F-ke@SP(SP~8zxDV@UP-6(o+Ho~f zP@vI_W!oL((DU~u-&w#11say%WPjJx&9<|%6Z__2oXD6@x#gmX+lBL14SKxp;)58z) z8{RTlh(AbHzrOkKt-V0Mbh1j{w`bM8MP?_G?Y@Rg zy&h`&t@Bd`zZ&BP*#zO`TED#391!5GoztY$ZlGz>ou(jP81Gjc(f)Eq;)-swi+0nD zTXZ|_XF--X`dn6t1_cb8Y6AP5)AwacSjx2R^UJ3dRjECg&t4U#TMEk190~L7zx_TO zUv+!wullu|hploqJpW(ppPN$u$*X++ufy_jR=qu+`wb6Unf=-|C3>3sPoCPnijOuZ z+Y2913-61Yk^1|iX7`cxk$qnUmQ^Rogtw)BOE|xO+TZCH1NU)s9M~jqV|RIe`Tt6N z?kSDG7jiZL@mp1aezUn*Ovi8JszY}k~ z;$wf;)ZP+kTQfPIeSnA!2{N}rElIH4)Jd(lsA&QwaE6rq9AB@HRx0*g$0}qiYv}vSZU0V zb|7#f_@aXwCiDLb$KO6t_xkwPx&M`ppMHMv;`d4hsb#kv+H~G;sEWMu{&Ui?%;P$< z(_TKG$>6+(rQz(B>S?{sQwn7g<@MSYUwL=`d1Ui!{#2_E`Q}njK}&8LICwxiQD5(+*MW{d;j*U$Dv>DR22B{d$Zpw_9|$F z321rZ4Nyj$UEupOiZMWV#;WcH4jop|X-02eOWzdU_GZsp*5?!XQlcY2-wGCY%C~&X z^ZaCHu-vz+%U9lie)VeWTZa06V@9icd?33%@7l0C&p!R?^4Jy4JGP&{?JK#aAJn?K zeLM$tG>U-*qb~!G9ZN9VhnY!Q!JOa%F%5LMf8_1Y|Bs5V*8Q#j+qtvm|Kph#6+c({ zK8o9Z{pg={UraWh-M-NFM6<8m+t;DJhridKvlEo~?Zc3tE?yS?Hhyl^2ElC??UwAl zJE8ToCw}wVH8ww{2XopY#NYHKR*Qf8wbAv?^1Xjdz4u)I z_9wpHCI6qTIA}^NY;r^GL!GPkuUA_tT+0Sc0erDyR)8L?e34_$wyjUg{~mq$#(rGZ@WjmdV1|E=(%$a)7GwCyY$=hny2lq!VH~vL6>|$Eer&m%CSFl!}I;C zgs&~VSW~p{al6T9iL#aJSLxhvmaDzhXw3NUoEqb-JoW{5U!>133x8_0{+`b4`{h@@ z{gJ;q`+p@*D7YP}WB@wHndf-iEYK2@1Xa#GnQ~9k_wAfmyD;T^{mkapnm-p__A>Tc zDcrt&u;zu_r&;O2@!txq9VUA++-KkP=5*ex)l!$j`s{Cs-t0>K|8w5|!>>bKq05LG zICz{Kgc(57R;!E|PTgGL!s3$fk@G;|p7;9aedg3#MeIv2+3=#Iwe--I{MU~|Uv1=b z`crXt!qK85g{?0G^S1Bb%Xduj65Eo!Ywhl>H9dN1LH}fiJA4mvb@H|zmMA@JH)U(* z-1l$O?%Y0Zb4zg9!AE!5w?3a=170W4z_G*^G#1j^e-1p-+{e-3kj_$Y>;GT>Ip^f; zMRx^QYrUvYZ1>YW^hwM*_prq6_MdiVtvI^BY`C+%Q}(-+WID&)o@zBax!ZR7^65-} z_U5u5IM}e|^z`<^D<8N0s)*RWe#`dRg>4%S9`DZCb=2>7{q?7}KF1$%gPv0M5;Ptv zm26bWc1aREAtJyi_+lEvw?FluF@T%dlkLlQHeJ}6B(*hSa^iNew;qdYTCSWAnr3*n z+~Y4t?Vfz=73Xg=gn2ynVen!4@s?rD^V^F0XVNRV7H;n^`?W_&`hI!JdcWWLOp76h z<~OE*#szLJoR|nIG&jhwoSV`9Bmd0L|GD2+?pI>(J{R_)MLcjt(DD_rfpW5uQ!eTq z*?onv(pUc$OLd0u;blg%w>8JzYMx+LXw9I`m?8gqlicUouljHHnT2iqX|uYfd+xXY z-;{5CmM`{!)Tk~Cs+ndnyqLFA1++@4fun~rq5g;ae4ELC@BKJn|2}3Rm#ot><@3iU z>g`Iqs;T|?rybwVEr(xoz5cODqVR?GWzOFqIPjR?0uRdhv`7PTUD}77LuJV~JOXB{;5`BUgX7nn5p`Gd#Kw>;8#x^oVieEXhriTyTX(8k>-{GN$^OpBD* zcYes3ff3}q|IwSBWNxYltOcvq@yFh-MC)<{^xRIiMFkxA|?xb zM1ESxhCX@Nel9M8|K&dYeD#vc+YI*S@7`l~>xt!}nt8o<_%<}2XHluzm>;ThWZwVT z{OQ|3XPPZKthw36fkjAl!`{8R^~M`FUTgqOT!NRxip^x0^MCi-;QIO>pI)4`pQ~*( zq4rDft_8Dytu*&B-hbX;OJios7TIqmMzxA2$n zt#c-aE-W*cE1kFhUNJ}YzpZcP+kms4Lnza>U6p_KJ6si8B@ViEDM@%*4Y(Q*1hou0 z_uEaj&GeJkw+gYg)X5ZY`?P{RDDYU(6XU*33-xa}MeohsGEwo(myZ%<;Zx67ZQ0$Y zdxP&o`M1sky^Y(L4}6O(+noOoDe!@2JjHo+{%K{-# zTVdyNvrYCA`+ue{R%-7`%{_EMaSPWrCib?a_lQfu3?HQV;{lh&$C{#%OgE}wCZ z`2MJjp-yQ--fy$7-M>0)zUk`lmp(jTult*SC1~7Ffk|n@2^JH^4JQ_>-v*^j1xBVH zZ*Kqpx3%}p_PRUowd~(7xwLYzvpah}ht0xw7yNEKdHv&uz_)LS{OXKm>=wcbPu^Gl z-jNPky>)X_z3h+YD>Wd6@dh4{u{?`c*nt`g2OL<=-H>{}Th4y&-_E(;wQUs}-L zXaCCJoM%JCw=A_O#}A!t`{Ja3uT-ATvf-`b41-sno8HO@-(vc^`B%we z%m2Tw#Lr)>0vZ=rQedhDl}q4rZd@E#ru8s<`}26qfAupfKlg>6$qV8?bfNKcs$uR5 zZR-*{=iRSQyeQ#hRd&5*KN9~7-twDxawfyRyq+D~ZysN{T7y6J#^?3S z|2;e*(QsfB$c7~4s&6`dK9E&nnZgg|{l8yrc<=R{5B-Xl?NV%1qc(K<B_}yx%xY=rT>oauR7j(1$s7mSVUBU;; zGzavU3LexwTb;h>?a%hlVpat{hdoz6I`h_OS3A!w*;P*e0>Wp$Tl8mJ%tg5(OSgr5 z`t{F!8uCs$q_5bnp?{^TeW5h}yvy_c3-mx6wcenUroGLVyqW-NZ5~nnux#zaeYd~; z`F}He;q0q^>T^w6?lmsC+;QQ0=JK_buQy!xxt!;fW_Q`S^@;o6&2MIf9{c91cpJ2} zdvD#dK(~ED2kZoIJe|pK!F}#RyH~ng`Br<>tFJ$OE-tDGJMV59sMj_v%i^jeD4TS+ zKbZ3N=l|CHoRoOW(BoTY7#7-#P#_kGlRFesdBFsbWVMKy76%e zm+idN;N1$%*L5WK$-Vw9F#F!W)xJz7cljKCa{OfexjE<4FG2aYKktjDX+w@eyTI7^ z_HFLZ*|G(1f?C*?c+UcDDFU5-`Cvq|es{9IErZI0flJ$jo`PVD<(75icdkG^=}zYTk` zPBb$fe#;P7H&JI=@cQ@WuQu;l@pgCa`TxA`PydK-41}z1KJZEC0?UC=mvu?v3R7#IF`w4JumS6(r9 zXqxAuSg1L*)ZaC96n z0RcRGlp)?UK>#QY8R znm2f)Gr}{}e_yzEPRY`>GWY8O+jl$O-|U)P$Ac}{;ga?} zdvrSv=e5}J{jRB(aQ_!DeY>=of$!}Z>yqSO8-2;0@ceV_o$Ify`mFicnLqh3|zV}&n+NyD|o$sc|$alR-7_VicK{<8i5 zRvX_GHvabKF~9i#ih~~)eLiZF@wISCB>TrHdimmyc@oth@3Xg)+pWJ)Z+@DL;v1I} zd#uVf_Vd(6KQY|jnWMitPllcOkxv7!wakIrjFwwEjh^3Zv;F_xW?Ox@^|o-xXtDy+ zYDkH+1v2R-BN(9w+Rk)*eb2o=(@XDKCl~Db;M~6EjG*>u{mU22?S3=v-E#H$*IfRu z6SHTe?b|-JbQjObhF`m;#JY-wE&lU&<;60FTTNwe%0(q_eU5LP1X_UA(ZI0=wETOC z@ukvv>6bP}P3r)4;~LMd)v5mS`e^mPTK1PMhBBuNznE?9U9A76{l9aM&9m)SFK)4Y zoA}~sN#^Y7{TB7Rt~|_LFLghe?a6$OEuxyU4|+9JZhKn&k3aK#edsmFjvYgeoZQ^A zzl&v^*QT5Ub&DknLR3K6WVJ)WVVgDmHicHd7f)Y)|4;Su2{M2FKk8V_=X}l6aEY_` z?V4R@>f+nq{^C1%`?kk!fk#Pm16SRAuOzwfT-v1UEt~k}O8;+JYr)xI%y=WeEirc4 z{bt+$+up>38*&{73RtdPyY}qwPPubCM6a&lY}mpU_ut`?6n~^Llea&^>3{YgxAwmI z_;FtSKfzClfiej-b*~mYIMe30uDsyzCdFUDM}#Z?H2SV-w#fZfc_P26(sshdsdtR3 zAH4C8y{5S5WBUGpHmehdS)c!ZU!ca2#{4WM;v4Aly!pR?_u)6wVxCpCEwTHWqgD6nbLNF$}{PAmM@(CGxo*>H@3)P9*xt_jrkRS zKm0uF$j$m!nM#X2rLDg0zBNm+PPJja#sQTBd;D1*9oWBJ{^oY?HAbMK5PU_`CLdvj zUECmU0xRc%iNAL4mwWs3d!PIq$0aXCjAWHQZ~W&?{Gng;-E6Zy z&+U>%qZ*IAGtD*6wq7({zqb5Spn3V1vmEa~h@U*b)bRXRI@6D$H$V5E{Prha|M~r7 z`1O^`Ks#@^+J!*A-tdRTZ@%sHyI+62eB&Q?cb>(seb?^^y420kJN?dy^OUZ(n z&)+UAK7C<2ujKN(wKopzn;g7ib4PT<@?5JJ#tF+aZ$wl?v|D{PW_b0 zT>fuH7$kET*g&e8!~BP*uu4tPl<@*LY>GgaX8PaE{D0%Kzxw(!oG~dviTC%!pEPRg zzH>fu+wXs^g-d=Kd%K-6+VgUG^ZBa`4{!fBc>8u^<(fC|{d&)_9GLfCx({?d=wk4F z4oe(Br)KA^GGpydX;xzp+Rc7$j^*STu14-GE(tR^YVP0r_5bFNE%jDM3s}TIekxNw z_iurIkMaHMvb)xAIofW=_j^WOa<(M%Gv{sn+b>>SvbOx+O}Wa_oI_p>*Z2L7DSPzC zT+<2CxB(U9JWR6~W-z+Df&(yzW!=x^**Eq7_5a>f`z*EeVal;5kKa1av5#ARp8N5d z_CHtjZm_s-*T21@-|A(`@k{5;zq{sttCf3QSo6t9?ODr@w@zH=Ezjre5DV_tS#;W(I4tS7+7kyL=5P0GU}pZ~AMli4_SJ=x{I8YI z?g^O_ee0mXGl5O-FEsAB{_^IAJJ;Rg-gJBamaM9Mn8grprr%c=_vsJ+rvJa5s&Bep zz~E3&`%>ON-Tdz#`Sky9kFRG_^@8+dI~q6|4lwlBGTC<@m}gsEW`FTa)&e7t{TYrA z=Kn9xzN!EB^xvN|8FY_a$$KSxZG)lgjSYS`<&SUr6Oh-l<$A0b|8GX?u1~LSw12zM zE-$~FH}~oFjYqF9Jgge#C7Z3g&D4b?{{e6&{1vFzPHKzcdE6-g{BqL z%P&cMSA6ti;pbB&A&aB9zHd|Vn_VkY`7m^f_%%(h_O~n8O9hYfuiJ1>!~9*o#kZ0_ zlJA2ax7yd}RiFCyXMWk~f130Esx|B1oXKGRZ?%5f`aQqcRzuHrmS||OW42)UVyUHU z|L*L?b&p~}=Yq$2Oi^S~5}3&_XW8U335IRVM{I-}{G@h0e(ZC(a`w|bZEr7_wQ6t4 z4wJuiEGL>)GNjNeV_Wq&QAU*E!#A@w4`1-3NMZmcIxo> z$}4hp{<>EobDy2PKj-!KZ#Rn9?>+x+c5xl|HOb^Y%UwUCw|={oyl(6BMX`bL+f&aR zeRfV})zkC;!ZaQqau1Zbecx+NRqorzf46wbf7ZXWFi+R&$#N6Fn!5JeKVH~}*nIQ1 zwvLnI{?b@4kd%w~^MFp0Y1_1#kZ>dJJ`m@oOBCIdE_^Ho89ut@CZj z{}s+67akIM&C)7*!a_=?zko4?9f^HrV7d$yJ@f_QPa**2&FmcS;oOL7i|E<91_eE}8NaHq;Saeo4 zS1fJ9MvLY-(r<6ROV2ufsne#DwNNQ7$GA>C>H1S+?;~P=YL47L_3Bfo>&qRo(RcUT zeu#LO|8Fg);liF98+ohl7f*iocYf^SZ?ZGCBz*+=m{IXUBFh#whjzxiLwnU2W-<7x zfrJ~6_Aqd*;*K|Yv#v6G7H1=Oc~&%gWcy-UAyrZfr&FgYnWKX_!^c6WMw@Xz9gFV5Yp;*Fbg#ny$f z?cEaV>o$Myg0eXeET=7s$@(h#Qv75`XRr7Eu&|Wd+%xxHmak))pnA}=F|FuO{y+b^ z#Po;{`8JhT<6oUma(c7CdFRxN-x&WFGpym<@PENP76mo1D;oWj7R+ZT5xV=VCYx!2 zHhZIMt{r91Bdt)9bDpnW9wzxp9dbBzW*b>bG_Q; zA{py9Ggx-~xm8-{%kcNfx`T(6OF@zDaG2wTIs>oswL)fJP|8@v_~!ehRbHcKhq6U#vDZ-Ir*$V3CeF%-+eunwodctjv&d~Uw`?1?GSzX!F~RV zWc$=BuO(BRPFz;MdUDT)Rr~AfKNS9-{eLHG`)L~o-!9RzH{M^b{|aaMcm4dDvg)s8 z4P0kbz*cP$X0&Cz;Ae9Cv9~b8+k+c(y(We{VCctGwC~{dB#Q z#;SmTn~PTUF06W_rK|Gxht*7h4O?8ZX1S{;>%X|Ip8WpJ^Gcd8N|wzmKmf z|95%98P?1twO4}{%e}O%OFZDcF7A2Ujp7ZnI-fw2#04d$Dy9Xl4Au$jI2-sHZgqM8 zWmzElB}JR1#X((g$B&-Wce}3l?z*_<7gM65+pUv7=6*VRCs1OO#g>gX@>AbFknGFq&PtVkhXvxY;6C(KkwOIf4ESgeSv>-N9_I3T||7V>2f875w z-R*3$V^_ojZ>g`Y?RCm!+1q+|m)CzP+g^RYqLy)qDx|C|Ra~IX@TzI$YOh%gFSPD( zvs*uG5nix_v!Qk2q&5KoCR>*Wi^TbNXUE$<@_YArwMXE?6OSgS<>zCTCCBJzrX#T7U|P&nmvivB#J!k8hTYaEqG<+*%z%e&Xj!FFY zeCC>i>p2UOrmxfbW9E3v`$(WoQM%ody=PWObyj*`myz~OQ-BsV)_ivj%)%$(OHm_fdO{Xc?2%I`%IewTj zyt*_w=)1s+OW|AJ@n&35){WmM<9tDwp}9_B>VAQUCXSdV>WusTc`weZjPf*Xbd6fG z(YH(B$-{e}d|OuEUZTO5;`(XV+-)mP+?v^HbGyX5GVu1RvMe6;{U7F3zdCr_`D4F~ zg!F=TK3C)Go&aKFoi6)ozw_ zvC7+RpoxiXj+*X}qOM?Fz3T(>IP+IwTPsQvH?p||@4J^TbZy;TcQ(s{{O#}E{(kJU z(*Jrcoj)b{vF^Xh0oCwzh3v=q168yjdDtl-K``T^_N@bbyYCBM7iRcd*D__kfB;h~ z$ATHV9&CB|p_pO6i9>L7px`kj-r6TG_jt(HUVXA<_4GshwKs1(*m+pI^uYJS$Ex)f zoVc8)apqZ_A>d+m2c)d` zu1h>HHS_9Jp4}^cEaL3m6QZ80t|y%p74K@3a)RBuVw>&k?Q3P9#NPC|uw?@ON8fsl zZ+kC@{ctsN-IR9B=*dLOhn4?l|8K8Nfi?+kV}9{7%ZzwKWRIk0?*~_xhpt zTZKWdsc!FqO}x|Y==e)!Bnjg^88X1a37vlg6~x*Nn8w`6=_ zU(ea_&w}ri6Uf~gGz2YI`hR=*&)tH%!+Mgp=N9_czYjE@`*()@1F=a=%l^lkxq1H&o^(6AR38+%0!&T|o^yo! z^t$$W&lFI@*U5oHhlwSiVech-&Vt^0*9CJ~928r7U1#cE(UIS(_5a%9;LOlTOTJ~= zWdyTN`K!vm_i4p*855EJkxe<9_s@=8^yB`Q6W{NKRJ_?Qv#}v{=ZVMN^O+qw9FO>X z6gglxQ_kf^w-{T`t*igj-bvZz`AnQ5ID`9k_BQ_={4ra@vY7+~z^#7=QIA?kY3nuJ+N5Z(;xKIFnnW{6@g@dC!;KNsW(q z&)4JYxW*S0hYBn$2OL1-g^d|4P*^X`g#&0>YE>$eD8X#w!8J;^Vuz~#@9v!EKSaO zZr*xjdam)lsgZVPSBvM`ojPy*+pJw_=G*sd`)gjOec#OfVRn7}%});=?z1cATm7rm zv!NraubizY=eV2NssDjba?d~6BQK!F_@e!>^Zuz5m&mho5Wi zSv|Y=edg7?_4oJ!Sk|V1vxMS>bdC(B1?TxXE(wAvNS!j4xWA8fs2w;dyNhXK0(0N8 z5bh0&dh2$#_u2go4te5yjbFO%^ZuU?-|u#Q=KkvkZ@owVfyGbN89zOm+3Bnq%rlv7 zLi<6t!now>jkVScJ_eiuK8a2LdZO-iOWk_WyycKZ!#sYi^HZx{m-+1QULX0q?7i$_ z4{&Lwz@o(T=Y*JCZIeU$zPhg`U$B|;+AW9f zE9Awcy2lBL(@(uBy5YDqApF)6fz#WYZ8}dcnla^W=Il>?mnN6nKA%_nf^+`^`ANF2 zOwwFsrw$$bQ2zGpWCqpT^FJGp&1ZaYvaw={(c}eU6~9<`FLm%cr!3kwVV2!$*(q-r z5`-Q&Utd@LcyjygN!@ceK&=@uMJ7}GH1UTOzl%I(F}yf^c+rv;P=4)}Z=62g>`mT> zY^FI^j!a!~&71?&)A3DN%a?k0*}}3jtD>$=KXF>@>yyv_R0>b+p86Y7N!4oDed}K! zdEf-I^U2GnpBUZoo5&I#yJR7u^$j}cIck{{XS#J zJ=&Zld1_w6=_pIy$e<243x}ys>nE_MYDFsR8~a*wGL*+i7?^)Q<8*w^-z6JV{j>hE z?rUr=x;@SC`#b-8&%V8pUSFUL?yZ7`4dRp+a5lurH$M9Di_^hSZxR=y;sy@Eir#qP z2e-m|ceq_=aoBjQiPu!A{FLwA8=+Ukv~E;>wosX>>M0%YDb{yaU&8Uc@B4q&zxbWF z_5Xr-jqzcZJ~v#5zxBOpqssDUi)EIufpP>QjzqK5gT^>bdfs8Qs!o&R_Loy8!(<5!+}=?{;E`&uA*RDq?cu|bWYs`1w$ z!>=p{4oP@Ab8s}ewlUQ4eb`z#}NH4{P+LsU-@?_pPZ^G?>4D?LbaquWw-5>_JE_$%PfUmD~*kQc-uFMZF#un zmI}jNL-~Lc8tPvcX*_K_bdYiW`@qGw?r*wdq-w+YVWIZ*9i5uGJQ2L+CtDi?BJOa! z;B5G3y>Ax7i~Y%qdcgU?TZmC4;Q8;P4Ew&k+M&k4y;+G%@_QX~_t(W|xs9UzH}!8- zy}iKo+qV6)|8)F6`+pg`{CDnui3{!QIU4e|MSO9R`)zqFrvKNHduG=g&hf0n=QzU(LNe@B&MT6fqBSxD5K z_IPl(khA}5dz!|l(;|y3BnsbrwD@$wE&u1nt>^YCpK#9cpV)nL$D2f^`{z9wT6)SJ zJaYSguy$U@^iK{`&-$gfT`{)Hx%T0tZSYEk?>6R7_5MGq+Ft(O#dSUlDDE4N_Bc%4 zwd_rBonile`Qytt8|rMdPI-c=xD7`Hcbw4Y`QiJ&>p*hg>`I-0gvO%x;uR6nQKzDW zu86I=@^bo}?5Bl)K3m^4{%-$@ul?%3g)h556zH_wk?CVPCMNTsY`mBAb+AAD_CrH~CWSi&?w>YBOzBYdGo(t_vMFO2ip`8A`<8vn~epFsx4M z>x!F9ZUS|I5-uthyjzv{{p|Ih^Oc^Q z!r$Dx_FpW#sKT&oMZS&OGp8yIvs>iONR9i?%djUQO%&1wr>*v)3Qq{a1DOg_q1vh1kAMx)c5^QG-z| zY>Rj4VaEo$GPyN2lZBd>b7pXJ)#o^O|2uen^WA-^cm6JnmnistZ)4S!rOL2Y&-g1Thw~n&-;I7Ka!uC zyQ0ka!Dpu#vM>6c<{w?ixoaQ)ff>3s|MFdy?*1n7E2&!V)07J~*T2d}uq#Y^XjtbX zvgbYHk2G$3-4C0JGM63rli+;sM$^{H3+$PTqRNH+nPUF6eg!phcjYe8069;>g(WR5 zjm_|_>)g$148J~n;N#_esm@Sa5d+SKdz~LlU9MkT|G6!2`=zktyFSYoJaRrOQ8t#-zZn`Y*cx$=;c#)mK!tQ^I;tr}XSXCG}=*stc8Eq5py72bSyKj>j zrnj0h_HDbowgysVHVCZfY*1s!I&}H3U;Xk$f2w`H2M4%->R5;SiVgh7ivP@Fh~I0m zj`PA-mb2={uift$JmZU;Dt#i>f9u7DiZ}mfR?C;UKi{-7y=UnOPc@#SKjy8Yl*@rjGfx9hIl*1Eg+_Kw|8R&9+EUZ9(Cs#8FK>2F)Z`s^>#4R+QVcmHr* zO?Q6(x@6gJD{EDCP=a`&$P^*`!0NxsfkM}*$%`vzuF?~k$og#|hl|d6hjvrtA4;>8 zA{%et>#CVl@uvRsce(HDe;wxFHjA$*7CO+!d5f{ipt6xqCm?}Y~?rHYm*!35*D0<@Yts>I@azFv-a4{Z<+5?|{x77*UU}tyM@)y>~{uZCxYHVHhJM8=W??=M_GB#CA-5xtFe5yNG9`AOd7ZjQEg=C+VuI)EQaepw=>VV)}|e)@geYMJiQG6ne&UgGKfH ztJ#|r($klv&kE>Y{jZ(jA^)zIY@2PIZ=PrSB(dS-m6hDJw>IbpztlLW&2<0w%G-DE z{S}t&Relb3PM)HHt?gQMhFz>>a|>^M*t+tZN6>2N#+^GYeHpIwP7?vu*QYpQzJPim ztHjo)?fBh4w^aM~g6_n}25#GPilXH!4#^%2`cv5{?JiN`v-Nb6#TT~9YcDwqwGOMj z=Bu+Qh%^pwv^kdGpYb&E$=^Vk)t`#4#)x(QSTot`p8ZV;^)@#D$~|A-t4cVyT}Usz z@J!COnXm<>K1eclWQaJ+S|k{vWUV-_w?=*RP-N88IQK$E>#1 z?){Xy%{v=(gmf1Q)N=@!?3H+GYuF-YYAbzBu3`Tq8E*czc^}MKKF7;8>lpJKKQ6uS zBxlQtn1AM94qFB}O&50&pD5Y1ScBuQM87kw^KH=o<=HTK)2RvNpD#CMuXNaY=l;+8&*HzP#~%`T ztok@Hbg0`^ylDc z+~;~=KMR9D!5ZSB58nqgTo-0g%{c3{!BI%=Ywlz+78W_3r!Q6{Tq z&3g;CGuq7mUOD@~?K&3y+eXaxHx0y-4zPt89GZ5NJ8MTU|HS;3GEenwi|bC_`n`y2 zSIzN18~$fa7X9~P)7?yIwYj$r3FH*WcevIc*=bSq>%CA^`P&%<@;hGT{gqiDVdUA` zAn+oY<&QAKN%cf|_1!K(msuS0`AZ&hKAg{R;kQwBb&N#kG^ zWqC%2Z2Y10G~lw?)4yJUEXB<6T3vIc?`}Hz_szQZt;hd0`$@=fyZ7uBAhvZ1T|+syW*JMI2F{aE~6t@%<3gV;0f!bF)>sYiO}Iq_RL*EMq1 z9{g)~yyZ~6T&sP^hICISp_)aDyQMGr|Gz7^-N0o2l(*?wR}yE7_%qdfIAt0oF`=P@ zi&4=)faAw@hA)qlD-<@o44pKK;f38N?s+V~I32$8cPW87%sT`eE`I-Xx$W-sINL`y zhODn2Nu^s!^;B0}X50RBpZi^(n?ir~v9qSH&|5fF^j2qcMdPP>X5r`y=T`sM=xWuj zc(4Cu^AWyH3g>K-yBeZ9-pnpOp}f8%+5XodztS)4%^9(?)EXB3|Mlqom-D*at@ZQb z#WcQ8-TJ$A!-Mnf$2MM@sc?;@;(q$OE80x2k9cQ+rd;J1|BE%S*}trs|2gTrgD^vF zMax&Q20I%KFHg`~0T+h#9DgRo3qLsGTC~-Bzw5%er)xqb>ps`-|9{qgfBsKDk;87< zBKJ~{mb~b%4_FX1pZn+2e=DD}R=(vspK7?stmZ=BlxIs4BVXJRR8v_nGqd@LUlMcq zujc_@`hV2k@YmijYniiiuX>fq-nr?Y6MqIgxT)sKc4Fg9-hB2Qf4E=Y-N!6^cE)Kp zP=Dz{D9f?q$7lcD@j7dsx8@C{pI%#b@XegZ5D{}cc(EXp(}L|BF;A|u{Fqkn`k-** zrnk99x^CN@514ChJGlPFM%#bS?%)5(?|*W${M?h*^+guVVd1cI+Q0qtmJ)w^lRbr* zhws)L;|aR2adY}7NBR2M@yqxt4SMR6ZfHD=_hD&S&UWEt_n*l6>Gfi+_V2zu7OW5c z!T$S<{Lh56q%TdbU5wspqU}OKhA++M-nu0_`JHq4`r`KGThj_IE1U}8;AqTKTyUMC zjQge4;|!(+ehaKtr0tVCqVbQDVJ+hY#{*BJI5--YwjZ!u-FDYJ?s>f6i+VnT6ViGT zdomUzsM&AIT>SgzUH)B*ZzliOu+yFvdu~c#+~NbzR2aD4MNB=e**Ga&;py*$={KDW z(>Lc$*x+bd^2qE9>(5mnR*k-qJ?(lp5F2M@cFeD zXEEeD2K%)%2)tlnYUh*nvR`H`=w>Gk+A_)8a8);Se?*%a!!Fisk3gHisSdQ*_Z$0=dtBH zYm+q7Ai`ZdQ2Pj1eNuQra(GGDrW1eC{pEjfNv?l0J9eMWowxJ9+SKm~`1Ys9@go0p zj>fw!Z9B}P&F)PQ{@GJzwQzU&F;hmq9^W#nDSyE8s8VhTMVnrw2T!+CmG-N=DE;MU z_yX7d`iBgESsLn?0y=uY!$^(S1b2M+0%^HE{{4naqRZXhCO~9sPPp{PjkmY&n!mnU zqyCNkt4i%Z{Er_fPIo)@pSSyW>R*MAoed{gqcavsmRxx7jCCeYO2_sc7Y#o3=uU2R zTV}rh%>9SoUH_lSs5vwL-s`12#}CcVy%8L?etp`PPd__y7G$)`Y$`Lhi{1)a-xI&s zlridP;5R1+jxF+yP4gLU_;d_7ljOwb`^_r8QZo4vCxNUZ^NVi$CC zEbur2?r-f=+R(i)yUi)?&d1)4qdNO#H}dW}WB+ac$9L^_a&E5vSJNIYcgXmAoTkVN zgL5(|N6b&NPN_bd@%*=7^T#4~$Aj6w|L+uHC|z;BEa2#TA8}AI@bKIFWG&&Uzj%Jx`n+1*Y})EEAGZUozHS$ z7Q^371_^b7A9kj0O^v+vkm;eS#=q@%U)O)`e{}zU{6cAw$I0IgGKv^I?s<~5?uz{0 zANK+#gd1{%{b06T|G4yUic^AOH`fNYpobs-T}*xVVxw~2HSzyH=GOn~urCqN*8afU zU)IroZbz#r*NN&bfjh>9*F8N9c{Yhyd0NZ5d2T!_v*Ez8l6N=E9@t+XU*K|M)HJYR~xM@Z&{OS{ei*YB*xvTxa?5{-0++9TYH_qP;u}JejF;&trqW3)St|JEg zB7g5FKK`(4irWG9jSUN2KkEH2ZaBRz_Wd!nFJ%pRvfM{OMYa{wO<{&_$*Xp4s@m1m zpvJI^sW@@MA>o7bRsOZL$1z8A%zz|)K7|il|H~Sr?_0d`dv!o`P zw@lB!`>1Z;x5j`!(b8WMy}us5TO6`tO~hWluF6|MGH<-RackS}n-pP{O`dhH6?AG?CJ=lpu*;*ia7 zg>%XkaI#se)WGyAX205j(tmFmmh*0Zwf4@uqmesJwmDtQuv+1rwd>BNUg~N;`ZkXizYE^0LajL)BzCU9BQfcPz-t&*f;TrU(Ps zOEZp7*nM@s(g)l6y4|;T*Dt!f^5lMS7S&>Urp|Cd^Z$xfSxfu;KnrL67Ts>iKQrm4 zu&XeGZ-Tlov{el4)XBw22Hsi9D$BiZ;v4h-#>H`(!fK|q5@uhEc^+JN9~k#67$&ui&xO(f_yBP)3V~e-n-kZN?+N@vTAeD7Ku%E49VgIVWqthNI zu~dC9U2Y-h=?z*|rm6#J@9yekxW=;M-`B-?TUKbTH5RP9%;;OW<>9O;dTZrU7aV_V z{{OW+U;kfrOOeRG&1`lY&gDnnf8Ct0@j?0&9lJBlp)dXI-aOzaivQBjv-{=L(|0e5 zF8+75_Vl6me@=H*&UgM0JWbqZ?{*va`^)6+{Ngn`(v*85$8TD@pSzjxk{pgH)lyF+ zEgo<`GqRdAtMpV!(M*38`#9Im^i7~X1AlDo_Sti0o%1~ko{(xeaLEMDD4{P^+b ze}fsKb}m2P*A1G>OL(d9!RUWfgY;2A~ zF&B*`<>L>#_h+iS7pz*g`^p)a6vv+`403u7{x7~>eS4;(e$RdJzwTkb-2eQ&TNkoN zReolnSHuVByvoJLr!;l_Kb+&i?UuC0`pB#$6U@vm-QcKytm2Sz`iIYzGAAF8+y;fu zp3iE1W{B9zOrOsYvAy_GY}HjM^HPgFSvPhGfhWITXfXZ$_V%>>Dk~|EbFbYNoLp~S z`g?j(E=z^egk5)cm+#Kpf7L7)G}__hz)`}*c*R%WHuXmB(gfdzKZmWjr&ZeS&cWhz`HZc+yB7aD_y60Q(0WJx zkcBf@MgFh}>B~imh&Ak#iK;uj&Y-bku>q%m)W40j@ej`bJpMcV&*H!CeV`Jk^!}Rq zT=}|x=X-TBC(Mpm*z3vk&SZ__Lv3&E^}!eQx&sgI3yzgxYCmqKu`TY2`g z&U4uG-hUnke})p4I7?9`CkGCbHU>4ueLuaQW;5ML;;|{ONIQ5;Jw7;u3ZofxNz&HMh{L#mM_q{l-^>5(| z{Gt28%+HWhIbD((r zkyGDOtj<{5%L#<2_?^G_eC}=aJF4^dN3Z8Nb5K~BrNv>nz>L|mtt$?3s+XMF`^OA4 zraOyeo#*CDp*t=)-Yb7_fYFyB(&X^`QB*!~?;9M1|$AXq@=b$UBc! zD)p?I<)iqo-`~vr-u}q`SBKo^_^QntoWH!Otn1h?(M|2_5&L`ZyZ_CcdVJSmbs6cp z+x^#nICk%3SO4I=Ow6};LH2ux-_M-t#9plz-6vc7Gq%=#n#}Gpi@XEvtrL$c1*ko* zbzCm6n&o}fAtSbu>p#^Q^?ts|GPkSTAs74-oXKZ79q?y(BQGiW(0%4#i_JB``%W+U&OMK|Bz{-@U)&(hJ3Z&)+g9tPXX_Rp%>TE2 zef<&rAJZ#O$lO+%X!xVcE@a(8d)`;K1s1-rue#GQ`s^$*%?LW+ou%Xe?1m;i*NaJ%d1`u3}zE7d^+s=&+5)Te&>CC z+Sc29%h!aNd<733%yLU8D=W+S`RS?e?b92KLBk@(JGMP3O-f2yrpj&v9%AEY+@{}Eyi~b*} zSYAJE{oB(aM&8ptFe+DZ*4oWqG1)UR#Yxy^+mfJV{v}g?p1SqoIp5s4T#wt!n+`lD-Y-;rSJAIo{ByxscmEra~OLsi?~A8>J%-~`tYYn2|TGaPewcaJVr z{%xjw;oN$|T)*6xyFU9foYA{`F&nbv^q=d4t98B&`#-Mdh zb~Sh3?}Y`=<^8{k-%6Vr{V%xTOr=Iz;*<4H-2Xb&wflAT|B#Qh3o8Cvx8rn7TB}0z znOhkO9O{fGf^`=wrms)l>yWlbq+k2v<&DdHc`8%icEnd+35cHFZFO&xg<{0N{Dw{@ z&ks4*CtB2AFxN=!Xf!il!&z|iYLsw81!xrEf*s2TmID_8zRlkH;#%FGE&3B|Ok2R0 zKCR9@W%~bPe{XLl(}LW9(-XmU_g?TS`r5~(%I`wzS&z0?{%V}JZMAFsw#4S!JDxTE zG5>!s-1M=}IiH?1oacz8seE3y!f~%O5S}f>y*-1P#V&k zv1|2{`3y5&=ef8-)^#>k2|8$&J?ws@&Gh#YgKzHX53~Q5_V19i`PRSQ>E`u?0ncWx zcS~^${38E#{j1sET>n3u+*iEg^7*5GCa{zqENahS_-=FFKZRnIewY3D z_dfzZ$bYhqzny+K(t5_lE2lnd&1mE3vAwII?7IJ{aqa8d$8$#TEMwpO zYi9#ACHQoAJIyRo4O^)q%^|F&E8&uLQlghH<7^+e0=U~~Xv=v)qwJD6lhXpB#>MXa zuMRH}nl{hdgz>^>=LzZ);`jd*X4o0f14=Uv9AEUADuf>VuYR0ymz!Dd{-&e35uX># zo;g=r+a>V!N2P{GxoJN)1$^-Tx#<6gkEajM{THQiLCk7{yL5FN$FlOCi`zC`_{R1! zt@M)JeZB6$3-`4HBX5b#kyA-IJo$XTcck6SD`LM=nNLpXPC3S(ED`AZW|pk*yTjMl zl(sMb>a?h>Ve%#c0VYw7AL0yN&9g#{jS>o+5au;PuFuSt&ChK-u>@z-PeC7L$&Xi zbk_yH`FLo;B@?mVirZ@<_gr{coy(VcYG(ND`JGKG|1+2N+zor1v*^1qX_asr!8q&a3U`FTJ?9Edyx97{dzPU32bl&7SVpCgwP0Cn(4l%;wnh>PzZ7 z?)81#%wk86Hq~4IN&dh2=jwldj_;}8Q=eCIL)JENr*(;!&aZU0w!3?#FPGNin$mP@ z+uno#^&7XH1Z~uW9oEWpg{7&+ZAewlI~~C2>bur+mDi7B;1k zZRXnz$4_cqdyv>?+Z%a!$)eRKzV+n_zjF>>dvz9rXojZ(ON+x^jvu@KxBq#4_O#to zuAJO@$L%g}LD%iQb=$)G?@!LnJ@-xC-ec2w3SMG)L6>EN+JXO{cLkQOS-Y&paeLD1 zu`yv0e|Mz+I*7B|S&QmroaFMog-eli%Gwi?< zPB$yg2`B$bU4T%8ZAU*70u?<%`}PCH3t!kmbR1v64){8Se3&cCC%y-;IuuDM3L*oiK#mfy&0B`%uczB&L`ZzdTFV*W6gfvgfa$B!hVu9K zm|1uIxuN-D(h6yigQYdZk8k+@<0Sj8nx93_=QG`i%u!nj@}C387i}hu0~^#1l&+U7 z)W5gwVs6C?PV>r5@dxWg<8D8H|3%#9UVN_3HkUQagrDeqTA6ZtP0!jj4*lYaB@^9i z-c7l9Ch&W6~( z(`Ok8ff|q;ja33WUK~ArC;rc?lkfgq?u#y9t$(e5r8(|^QqNJz5)I|EZzCMo9Is`k zYG_>aVJ*%1C~v$+ME4+$?i9^O7qU!`7$lJ0a{e;V8~=$_J%{7;a6PU84+!- zTcIo_j2A+8WV4-Kf85#G`E%XTGq$E%uWEuOs|A>9dk<)zx4(V&%g6gg%k{PQU-=X* zVE;vT>(THF-dzV<+2>RyG-mP&#a~FVncZy4=s!2)-c&PT@1~6(j!!tDt|gnVWSW$` zv8QqJ{L~vc6HNMDA3W@sw&qw{^Q}=rE};);MeF0`aEmn;w;#d^Ha4G#HKCj=_r$x-f}7_)$D8Jb-@LWQzvZm zJi&LG@8l=mwhT|%m5j5KY9<}&R#GfnCCYQ?SDMZ$@txT&X|?7_?6EeS1uvgp|KZv2 z=kC4UT@&_!Hk7b5KA&GNC(Ll`7Z0N^!Jde2|q_yu>G@4w;y zy>`v(nrSTUZMSY*JAQ=y@7`M-!a)c6%)V`!GQ)&DY2|fZY1xgr8Ly;cO|SGmJ)~26 zIX&_o_w3#KZ<{>3_j%>*uf+{k8zyxLM4STE7|%9+{QQ`EN;Ma6Y0%DFxu8-jmu-ve zJ2iFn=YQ%p$nJaM%mHq8SM`G;{Pf?e^YI3f>0S0GjjCtGOBZ?wkMLKI`HqGXhLDahwnS)|$9OV}nCVyRMw# zV!7W7=Z79_6&IcHWA4WT(YCu@a-}A)DErS+J&>lcqPCgUu5G51@SO_^o8PlIay&}^ zJ3Zyk+4^Zb{hp4ODtFyX_*C|6##@6r{p8!na$EGDMtllYi9V4&i@henw}C%yX*i2s z%iLeB2ZCG<=$lyE8X8WlD_Ihtb7lUk)pyxIIf+f+_6sF@&TnsS8eenUUj*GERoiet ze@p!dKGC01Q&t!3B_Z5*yND{DWJ+M>1a^mk@|1A$l`^%i|z9XO=viIcD#-l2lBD(Wc zPv%D~l-9cGXL;+v&2Kq3CS{0}w>~@k!L#A~_jNA$Ivj<}ab^5*pBh!{G}T?VKQ%6u z6A$>6w#R2_rqlf|-0lxbySg%CcMc%%*h?H}X^WJ~0&GF@7?KckW^3w`FxF zSfw*_bU&E;n#nNy@!S@2zFfKQZsyg18sTM;){htIU3`!+~jSn187BgyiI<-oq=KFcf$ac@}FS`}J zvtxN$os%~y=BwT7T{21HNQcPXC&69&YM!<(I_St4{o?c*aS7=y66!a$eQ2-KNv#O_ zwpBoF#vy;*`0cr~3+gM5%D#JWBV_f$6n&PK0}RR!#2M}sJ@KemaI-Gw!{fuJ*ea$p z&)lWPP*r`WLTE|knfzN@INzUrvfKD_9b{j$Q^G`rf`69!W!L|IjJ_l7_h~XiWTB)U zU*^KhW2f`|7U+ENDL)@+UEY{jpfQIfVfGerPGR#44d0nOTUx~?7TE2`NqDL7qQ~ST zcj44^F2xVk{ubzLP&jWFbV~eN)EY+nFQID!C*9kVdMCE%X>6460+vn-#SKpcKIof# z<~Om=&z@Oj?=(#&?5^AfHHKZi6{$9H!IeQQyRxpXQvCnojPcZ0lfVUN%Yh_k$X@Z< zH|BRLk3V|OuvF<>pYh&^4gE#is$EaNN|-Nld&Tt2hxUhCiXCOG)97>DIPqB6x9P3* zD;8}&D5^Cr^69<>r}nN8(4RE5S}QNodYSXAsF2Cat1^Pcr|j-^ovkGK``r!0hkEPzw(1zn++1oTw-JbathxcpZMJT*uA_PJkH z()pZqyG6{U(<#k2rtF5tqxHA$XWd)9(O|(f zmK9y=ty&HwxjmSfKF{*O@%Dc8cQSbw-Nk;p>}~+fSTGb#6)^q(k)N0Mth`l8MzCmf zXDet+fm4E@QiCaD-mlH~3-WC$E04bT!Mp0&(Zz>WeP)V&Vl2h|FW^HOXYlz~6W-fr zolduBQ0qT5ui5$1gPpS-Tjq18q+9L>#trXjWd&@!&1P_5UC1i`IYVW_~8lIyonBWBRV@W1GynJYfky8dpYQ|a{RWL z)e90C9{f@GbTD;RW&BK6lWwtAyXeNn8tx}{gr{Aa(elqTcipu7Gub`@+{|?^R&CAu zzHejO*;ECVmIDb&AM*cy%QsdluG=Cp@kShIUtpYKy!E?3*VaZq|Mvd=f2Um2uUwE# z4oNN#raqtlHt)y&d(X~EX~r&#Z25Y1`wAV&YT-NAj!k=iwU8;#WAcxyXPP;qx$N@8 zw?8Y~_)%i=6sxOyr+km7{k62m?zHZ#{EPN0o<5vt`1)HOuTgsW56_0v>mr}4sa>Ak zR9ZcC5qRlu!+%Z&JI)=-#dSszUUdy_WD>D- z>B<|MwSskG_pI)f+$hn%W!5{VqF+v2H=@6W>&n$$w$C*E%lg#wQF-3{lIiiK)2(f4 zOB{niD-#WNfY!L@9jHoUjXo`}&1$EbCBW#*V8Rj6ezkHX&zG0W=gYk>u-OT2QF1ie zxiMrj)%;H0|L$JM1~rHMOU`mK-cxyB8uxPh=`C}gPgjk(asJSKzEc`azR#FXaedyR z-+xoV*?z$d!ReV3%wBBrnQP~9+A2Ep#*v5YjGGk9bES&^KNa4-YwvIMs7{4w(43+~ z z*KDRgC!_CV`*-*=l^FA1+rPxjEXB2G_2pbS@c^+?)0F!EJesAJ%Fbw4%cXE}yWtCQ zqhH%=l6ECr{ooo>P zYeBwNpr7q2>4jfBxuQROx!bWmW;*9ZPt)gDxIebluo}G2yKVN)?u9s;P00_BcYdI; zm2T$7lP6E+MqId)Z}EF)xb&Q#Ei0BORay(axNF{7)|a%Q_M?2Q*G9GjbLyu~sM9dN zaXkDcxc0i$bfDhib;$P?m2VpMD@|I7#nUOPAk_= z=d`EOzSq5&trvNJnMl=2z1&v|*US%&{iWjjTRQVF`(uOp6KnPe*0;9#OzFGHSD3_n z^nbv#le6Yde&;-Y_hnz%OU(VeiTbIa8vV`P-R0BoKig#T)6?P9o7~%<-iW^y0EMBz zhSD8J?Mwb8>o5AOKELMEg!#6=BW3q3QG)cPycrrHJ%Ii{QMa$LXzZT-e)XX}a_820 zz2G-L@mnHVY_spu2sVeM>_3jB>0dIFdvb-d%lF^H`dQm=>;G*m+Ft2=?L(Su#AB@@ zvA+xEur$0XH)peZ+qKX`}

$e#+&mks>|8!lgGariG| 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⪙}wt!=@B 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 diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png index 13b35eba55c6dabc3aac36f33d859266c18fa0d0..aa3e30287758d24b68236e80765a6653aa1ae426 100644 GIT binary patch literal 6314 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 literal 5680 zcmeAS@N?(olHy`uVBq!ia0y~yU}ykg4mJh`hQoG=rx_R+7>k44ofy`glX=O&z~GV^ z;hE;^%b>-;z`()4*q+J20#d@jz#zo{0?Z2-8JNK$j0_A5nBcMv3z!jXkV20>mU0FL z(OI4@jv*C{Z)2+qWRA|vUt1Q=e|pl_2Qt>jB=)N;p25v1UA!}fW9p6-Tni^HdeSyjz~WlDU|`_NdDD(0ZDe4NiitUM#OTQ5k4iS$DP3N!$86Sr&G@-zP(eA4@Z_G#e-l@=2{c-$8UE_2=?=kVgq>(|!1v#zfC$IQ;Rt{}00-MV#lyi$)l zf(-V!Y%j}?Bf%GVs6?i*S^Ceev7OnmY=CNAvf5bmQG~_wTo;v-^z&`5Lyj->d)sH}Z+; zqAS~e9;o)2FZH9HPj(e+W4>QX!@tclEg955a!fnBd9M-+i~WY|>+3QZ{!cyg?D`FUO~vcif7Oxgdi zvzCR(H$SeGjBu2RAm$|HlC1Y-w?TF@s=$m!Wt5eA!e+3CJko4 zH{M%+?AMj;zkeQ%do5XaAZyKm9VR79S?_Q;6g)jOwZ7Yzt7=i*31#*M$4F=A!?Fqo zr|LgA#!?`hBvrPoj@kXmEt@{u*Rl0B69nutySpL|-HeVb*8RM-W~Vg6^!KqsLZPa8 zH|AE(sJMQq?fRMP3!gD0nS2&rY^q_Z)u^md_w{OcI`g0ND{NkT-Btg}ze9eTn`^j= zUg2hy$fg{>$jE7#{IA3>cXc0WV^s{a^n9>ce@|F^$82ZbgC`xEWtUEls9UA4D3{rp`5=AsY_5j?z1q!5p1v2C7;`_*+{bcj>e&Wq zUV)bDJ9TFFoJx;QU-)f%!n63ERhAcKE{o)-`ahey>Cq~wtCr9Dq;GUD`0rX1kY-p8L2sSsUgqJGVq}zS)W(i387^ z1^ABt*|JvbfbXq8y7F#ES#SKwVO#b0w^*CWhvH1-#*?Dk?^R`UBr7iK+Z`szU>0@d z%9Rkd<%<_guV2pa@7c8(FG53p&tz%kyC3`6X^|nj*?k}GY0VFNrOk`%4;cQ)adu_c z^2_{wjd8rISk8i5{~jCbM!eEJv+!{G@#-0A|CTvIR$XOb=!#h%zQD{`1w>k@LXMZqALShtHIE?*DOZ(S(R8>09$fgmXBB z{f|HR94X3p;n$&w%bElmig%q25B&YI#qr+bGyC};=zkIT!NRW1sQTe&&nAWk->X>_ z8G_yxxBD|4XY@C@@N9kSt?!r4nD=;|WPDP*ipfFo^B#sd2fyiE-8cDdY`gwH6S>Q` zVjn71zHSmP82?#v?^wq?1rEHsT+Rgy;xY3dno8U_q~0xe=Q9e zZxn@u8JDr7?~b{BJHN9l?(nyDUB9-kj^^81&u>=wY45r7X8Ui<>tef*W@qCo$MG@7 z;8xA@BbI^x@7#;E*4KEo+IH=aCljW2h6pm0Iq5#OHu1%3gSH-n-RY4YTdkzDnMznfD|x@>Qf@ir6%To_~MkZrt0t$aHopt1iQwpDg!Z zOsL1T$BE8ixbQ50^TwaYX6C4Kq+QjYzwmIm{kHPukAlwk ziL zi;{ah>yWqY=N-M*Srr*VewVp#pL?c;?}p9qpE6taZ95#UFx$rM&ZcSK_b_~@{rC9B zJ=6U+3b|}7Q`zRHsygg{DYWIM%x=SqD29yB=Kf4SLVmyAaQOMw??2rVil%;F!yxcS zSM5V+nyqAp`RAW@_YbcxDQ?|+tzVth!TK2Mhn;&@bM1OEPxMF5>$pD|kAt@ToMdnG zbq>P^iR+IeUVZg{@MWFok1ao0>I)P1T%G*Gr|Oj^CN8SV|%zAtoQsqZr{}RMtb02r+x(thorrMYpK1xVWcg!% zcFc}y{5xN&;e5Z#nbjpqP2b-7Je#|R>p*11pP6>&Cgd%XmQ-%!a(w?;V*2IMy4h@X zS0sNN&t9)SUFLLou z#m$GCA9YI$C&=v&-M#MAx|Q4+-sZQ8)Ej5p%oc0^sA-n|wf}qHts1^VHUgi&?%)zT zKf&)`!WYFF&Mg-XsJ}hMbl`u*L3VZJ3%om|oHnp|TQtqq3wXQ!_?hxu=kj0nbX(u+ z>*z~-Z05g-T|2RWtIk*B=kG?#%aYK8u?R22Gd%XC=_t-^SsYuqk?leMi`h0`4E>!rer&oZlz#fq$I_3&mLK0% z?TamOYZs3C9C-ZlmH(F0I{sWRs$X{0!Tt5^4L^DL;$Loy?dZ;z?d#~^v%9UZPozos zucu-{q?QFsz15lXX=^^~>j!L|FQspk$8w;}_gLEI$;+ibWd2|&cev}%&$?xO;YWk^ z;H~w?-zzVQtv~LtsJF$vuu#UyK<8}Z$7O!|eoBfJ&)r{`7;xd4^+Mt-{yWVSd89Eeu;uM{xCieIk3VX5DA**te%Y z8kq9lt~hO!e^mT**G;_=F1y@+cLRQ>eem2dvm);J2lvmMJm$PNuNeGLz3|>dWZzkT zUXSxDI2uIb&%Ay5^_TLEKffP*D6GEjvBprJ(_~s8M+To;j*N5FZ+?BxRkc6=gm{Ls z9Jri(?b^>RKif99u-xP@VNVEO_LIecU30#Jyl(D4+koH2+CNWay<$yeJfNOrbG$Wd z&F7~<{!BS+^IT@1PKmWtI4i@WX3BVaOFr|#hpY8JES)DaKXjE2Ls;*V%{^xS@0BYj z-8l46IaVk|`-AG;O?>M$S=1MBTHN2yKRf=!Y@4E*mqDqF2iQ7hPJel8{*`K#CwCP7 zg-$yv?V`NGP3g?jX9o)wTT69z8L!`~>814dnEUdSxJZUQM_6w?k+zc*;7=; ztzoNEchTyqThVkLK|m_2>1}V~ zLE}aqp`5o)`=?bVdp$7y@X&eA|F_wT9>4f#cz)j{JB4?5erX#TSme~4SzW1p)6e_$ z6hVflhSbeWN!&8#|9E`ZHY+SSrTRg`!{sBt^8K3NlDRgzT@U zM`4e^gDQEGgS*!1cb4)0X30C3rNPZ$HF3RvPtDhmf5&zneRNUv11C?&%*N|^3pf1U zdfoMTwXW2IIe$f%xEK~cxFobvWXbe%-@2~~G|jWqvE3u7va)Zb@uw3PoiApXJX(=7 zPkZeQSpjQ1*7*#tE0Z$$I2)=H|L41uzm{h#6Z*1)ttQ5pIjWX>d6B%#;nLah0=3M} z&(!u7thKS6%BmpNE!x6xfj7c#w}hQz#D^0*3@<$UzOOFei;V458<_>~l~q0{e#zJn z;o^K$DKF7!iGppl(M#bi^S?h4n)oPB@sk^0&$Ccg1~p?dqhC9=7q|TV9HC?vBQK^} zRLU^>e))$9Fa9}qyVclmT<~^ITB4(qbV6OHA>Ea8-#3AOZ?ff&yn3Ko_-;?RjI;T( z$WVq1VQwd8j|DS|=09lf{jq+PK-0T$zK(U@qmCB1c1p~Oo5eJbBidJ%DWAnYl)Y7d z&P(yta+L>-y^naPTuPVOK6%e71{F4T_PxrV{M=StUugN``p&;f*DB+9!lor|dwgH+ z#S1A}+nY-yE2b^~qLp{b#`NG@{=Y$AzC62cC?hBLtZ%A{FQ01eDkX-f!*}oAoo7;$ z>E1cJggMOQO6T%xYXyuKzIvNxb6fGpvk6*84d;!H*?!>s_wL~HPy1YsJb81?(`a&j z^;#u{9F=|f_xEkywpR2&@9ew`0sGk6y(_l;IB#CIIgWY$f!PP9AAb5*e5X}||AmVy z*R-Y@3;X%cx2xsr_1IZ*hi@(Yu(}MoIzH#f{zkl`*ymb6bTi-v&?Q4B~wDl+YKUZ0rUv}BoT-UDPfdjkM zo{kqU9<+6_J&1TLt{>NvsQk0nfR@S;=$#ji$+l=W9##>KiA3n@` zuFBW_#nhC)&lhrDduZdB9-e2yc*e-^q2B@(M`gpy@}i6h(K$9%A08aM|FUwLXw8m7 z*S!^Gho2uQIjlBeX7?UH))*C8r?h}o_pb=QomDxj*}8a(|A&L@@&dx|E?R8*yJ9)3 zsQLu{fP_;5*&CnTk>+ckzNtW~#bR4?ef5gaJKH{&UR<8fTO6Yqz$<>M$2?~FrZmR~ zye;d`t`zwHuX%mfOVOn#n{@skWxH_l)TvYF51Y()zg)r~yI(lqZ>m81iDT|o*4Fc9 zn`U2|BFONIC4R@kxEKeWEe(5TK4-A=Uvq(7LV5GdV~etwZpg7F{8+hs-Y?d^j_3Io zXJ@8NKT$hl(ZlKSbw8gUVF~=j(C5BBi|NJ&6J}FcSy}!oSFhfEy2E^b(lyHqSFe68 z@%24he&GYFi|SYZq&pc5t0b(Xn{RK+{cU)UZ`)=?`zQ05FC5r=-sba}{R`6fbv%fU zQe~eYvil-KP2YcqS#rLnd(N*nGckFSuu#6}bfd7kUrqkKJ(asJWQ#Al^Edbt;~g%B z`HPt&8zZ<)zntiiH2x=5Y5$~yIpX_&sb}T3Vaan}Oq$Jm<&@Wh$sy)y4d*v1Tggn> zb&prt%%(^8QQDKg6PWoJzFgCd-c}>78GlxoIrV+~B+pR0i4Kk)dw##$UAV^ifBMZ$ zsr8XDF)`*7+5V#*UPKEzP{>#lUEy5{XbuxUAxGD6Pan5$3 zsU5{(YooqO{$Q!zVE5Ho%<{tJ%bW8rFZ0zt@OWoOXvdSC(ZYT1lMk*H)|fwiWeL|# zqZxe>rB6;w)W3fH`hR90r?qRIEPo~QAn5&#jmfvAq^19JOEsw1t@!q|D!%e&`Z5J+ zHHU4Qvd&g27w1}+{}U8`P$?kSkQvc4e`;{j-v<+zAKc|Id8t3I;!)@C{GCsyUEg^B z&{DaB)3fRiJ+M}BT`6VinAOkl)3U>RTi)GYt-;Iv-X5s?dQm6qsOC)(o8Q6d=jQzU zIN9HBr_i3=Tpx>$WV!5XQO@7IbnC^CY0{UYe70$_D)t!7YAv#z_V(W1->06Qp8lWp z8}GDf)28Vil0NG1Wc}pZpDBJT*e7u?*f-y3GZuSqYHq&2@OJL@+LrCrAs_GDO-`A& zyXMl(;4n&I0vahe>IOqHJP%HQARjXE|O_?%f zinD>%18bJV{|eHs7Ih~sOGRA>ig`W#p0~qh6|c(yI}#W_8_u~U+aN3d;`Qs-wsn6h zj(>Z5+nP`QnEBgDuPd6)oJf^jyhrUrl(ffYIhEwi_ckna{C3d8al*t0#p)9SrwN8i zJ~h_3Q|9z4pL%o8}pMc`uBgcDaYGJnV3bN}6H<}h{hp8DyZ=iRS7XSv={=(glZ zFNSmm6-FKA3O%J@*8Lk}H+X;3ToCW#B;7FU2}6UO;K{$@4x7%a7v;a++o8d5-NVf@ z?uU9pY+3z7o86BRUR>3`^QPxOKoG-R^~zJs8NM?mX6~F5cS>!ub#sqg*W2vw-`$&D zE8EpX7Jd9uDrM__%KTaVt|yG24(h+_;T3vNk}mCUVzo;5o<cr5zUo8(;fRyKq&? zMP&uox+Ux<($B587Y_9~u5{|!(#e%((~doKD^4~rc_>o7U~0j>y(e#<{}ZPwDI}=* z?ZMx2?(fyB%p7yq9`9~wWiE_**sy3vjkxr~?QdK?Sr*OHmoxqFBkSz42W#pdTQNy~ zU?@BAr2ksW^mBPL76`|LuG4Sd@>D71m)EJ2H}s6RRab{!nDc?*^zPR#{pl@fZDp6E z`M(sV%~<)TNWjh6dxe-+nEXN^BD>&{=xs&kgurd58uqTr*R z(>|FV{^pXl#gjNqCoKND!m{$4`y0o;$Ok~TwkUn;e+Y5uQ%?o^xA1?H*%WmH{&j;G>H?Ny^wMA-e8!qcUZ2xz3?~JGwzHhcapI}z~dDnu&dKZ{1rpdpI5Se;*>&mWm@7z_nrf^uV n>gOv9kQt=!H1_lOCS3j3^P6W?LRBnhYme6~?g6Vq`pWLR-pX#Tl+2TuVv=4%ShGZv`5Trh*< zY0a;%^A|ooCEs>rvb|*3y}#Y-Sk|zoF<9?_0TN5Qd@MaWW{#wtozWz^rVgXZDU&yhw zk||tmjOlUz(<{Epu8@3@BOj^O_Otw-k>rpQ`Bl(w3zop+gI+Le|fg-}w)z4*}Q$iB}jW)z% diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png index bdb57226d5f2bd20f11934f4903f16459cf52379..03b41d2a2651b099bba80ea4d075c193222eec90 100644 GIT binary patch literal 13425 zcmeAS@N?(olHy`uVBq!ia0y~yU}OMc4mJh`hM1xiX$%Yuk|nMYCBgY=CFO}lsSM@i z<$9TU*~Q6;1*v-ZMd`EO*+?-kmlGfd zNlM>-aGNc9o2s{RX4(?V-z(Przt*GD@1~r&#Bx{Ku6_S{mcE?%vhLN(Utd?R3V-j} zBJiNV;+xB+TMT^d$+9sF7BbR@SsM;-G{nhFO;=f{JB?xObeAhHC$!wU*m6&g>rfHn z!K6TkuS!mKjEa#00!|D~4Gb60&t%EC(v>-@WrjmZ&Lj>q&kHIALd<)fm3JIBX>Q@U zY}3`bbM3jO5*vQyr^@Ov%$X$AwfeQprY~s>SC%E$EOZvScEwth-)Z^1%MS{lY}Gf^ zWl`c-$$vTfIxE9jh7DW{dS1C9LGM|l?k$sCHtWcb03Qect4vmF5SClkh?XTk88%py$^hKX}w0+>}kTTLUX!Q zVi*|288q$(@EWg5e4HrQ+0VsPbwHETb9JtcdJKcbXSG$Yy82E|YsuTU{NUo4XA@LZ zpZ0_+@Ogf)QhA!s@F1UO@*U~GUU%1)f6fjc8iK`4SHIOZjbX5;EH2X7c};*zGW$9SjA_1pHo^7V_3F zyrx;dZR@qrg|@#hJ(zIBs-5Njg^fR#?r5u5={zLc)#0{w+iHOw3^Y`kw+|a_(zqabRR7hDKR!N3?+2&6^owk0xmu>nqQ@X}L%yqS$I+*M{#}w< zo*VnORiV4dU95F|=8Zok8jkxSo(t7yZT0=!%H7cWl6SRum(s6?tE}EvtZbE`u;q`dZ3NxIM4d5S^rnBb=&DFlw-6ep6$-29oJNz%v_Rp zPha6vrmK*0*liQ>7>1l<#>ux*m!Cdln=7~UYF6|r!CiGHH5b1&Ib2ijWS&=a^3wb@ z+cM2|Fx+TyVA{=}Ty$Q#<`er*-~C@SCS7ph__e;JPhLQv=8R%z;Og8{tl|vPAEG?0 z&#&g#zwdx{X=HBq+y#a#dXaY)Nj>{n=)3>g+7suabA!!d7*@?WtoXItJ9|pLl}pIJ zr4@5DEmRgBR(UbABdg}*^9k=Z+?waJgCRt7@v4V%o$B>_7oDqKdUabtP%?AVdBs|D zA@lnyPNZyh7E2Dh%@V_~YVwY@aABu^H$tD=p3RE32>!UU^>hex{^bpoQtDR@cKz8hbz1@B3Z-A}lj|=(39VD@ zX8Io|=`O^o@AN`H@am5Z*A@RBGqPS|Ww3k)&(STnqq1bmIm#l}N3(V?3E6i2SiPd_ z_8z{E)nPXdurA=@IJPC+7kt-~-FAPiN4)0uk2@JcEFQM}Yqr{6 zWSswds<&30!^C}aE)@29i`fUCOD<+yk>ED@SASOQr~A>l?8^%Rtg=5Ye=Mbz=c;qN z{1oc~CrwnJO^D$gn&-IT_%;Drb*FVRLWcs-sScSS?{||UQ>0jsWzgOLF2@C8K z3jVm_xMJP@E5{!*1tj(yxpKBN@9FNE1M906-d`In_^wB-*KU1q)q*Ly!HsOLLVn#zpRaQr5IuU&T%6&Ur1z`%Pt{LOuie(1tQ!|t;U9B&ez|s1;AhSP z#)KIitLDBBe3BoL%ihjAXVZtbGt%sy2DXTIZ}rz>=vnmghA#J|^{$QSpB^q*=;@j= z(Plwnajz1WtEa{x)`mbHrvJ~vTKrbOeXyZbiA#1>;yrGL>tf0EF$@wa>!iakq)ZCC zeK1kj)#dt%wx7}MDmEc6_U&LWXzTJ_-_lZDv4%fg?Zs9_g`)M1XQu`=1~jcmKA6*ySkXG@jkX&uA;l+ z9)mbTn*i$%!T!(BpK!%>R6u!1T-t0N$kI%Q<`(A%pxRE=|;^CjC+b*5mGjT#i_p*a?yO=6>hQ~0haXNBcds4>g ziT|fpUtRR(`M36_55M=v^4O`zYtHS}S>)C`L!MEfZrb_ZI~gKa6cctYlDnaEuC7f< zV&DG^j(v5lYrh!hb1Ye>tH-cL=z34DUSv%2R@tX%vAY*%{QmVmJn6%=t9cc{=I^;u z7I(Zjv!n5Rq4%TH#e1i7H?Vdv?Yh^e`2TsCi)LHO*YVU_u_U6yOWJ+hW zgedV?d=(JLv0ZhzxP9`6HqmpFZpL(aFnwCVc8iB$|D3P2PmMd7SDvu{Y|D4@-s0=x z>x&LXhwpySS^N1d*MyHJ53G#Ns5v0Hmg~x{x3zJb4Ld7Y8xF8Gh?*QOu}b}DwEAsA zzN( zWvW|SW;lEIC|A8LWZWQhS0!JZ_1*MyN1S#s&AiQF^))EQ_~E+a#~;iNzt$wHthf21 z@29Xp2g~Uk#f%!llNe^N+18jUW~A+4B&TuOw&H0E8~^@U4X4i)O+WGIl%vy&Ka%m< z>ovI_x5mH8cVXJO;`#mW`xqJ5Fezv=Ops^DT2UVB7rjA6$9#fwt zl(O}I@FRu=QY`PPl6dyjhRWX9`&*Ukg)YN^eGFgj)F-^WR)71WrP4`rriR;xw%PSA zxi2acx3%J4_l2JcA^*N8GnD4#q@q3lwf(uf2ZZlS9 zP%q=rwB3KF-248yh3gwsjDO~S&5v5g==Ay9({R0{XC~n+#$~L>qAgE8QMvzyIFAS=l}1ao(vTk~holufBW!e*FhWh6FRuV-eA@3YVhxFIcr# zw@%Hk*mdG+Z39bDj?2}Jn*I&{oHI^&tAtiJE=gm3R}nA!mVf%&`~*(Hg_nzRxBofy z=diAS-Gd|NCeCMOm|R}V<=F7sY;8j;kKGju!5u04ymI%QxhXoM2KfK!3 z5cW7~&xG@OTQ}a0)Y!R;DR}w6W9Exiu21C?O6xk~?;@w0XiR6TX_v zj(S#hdfhqp{JK}cwY%H?-(2nBREHhv7x=} zXkv0ZbC~Y7@NkF2JMOCbE+*rn%qgYJMV$wZyjOQO{PXIl#+{0VwP6|D z4a;~_ru#C?`}_6Y(pu~GeIe@}i!upLxVXKrGO(t6{UO!`5k4=uCan2qZ}n8rC;vw< zYhu#r#nnO^R$gXI*VTMoBy?Ipz^6M&cQ(VDJ#t5igu z=V((>yYsz9#I7>1*R?+Ir-S9K>PVIcTi-fI2XR+xHT>&6z1T&htLS_CmfJ@)jkahP ze9Q{h;{I^OabIw+&E>1^k&76F?FAWy1^$%Q3!Qsgvg8_fh_S};GtrSO3-XVDXxCmS zdt_Et+acNBvq$f!`+EdS+0_>E+U&HSc)cNho4CQn)ERfW1n&HIG7(jcxEe3M$$=qm zPklaj)0L{aWefQd?=RD1;t>5hXThs|OLUsmerBu{UZ~&lS?WXco9B|XY`d1~_b7@S z4xJlh^LYKdB~O?dIAT&V+4^lbb>mHDWUR^5{M9$}|7q>%ox6XWDgPs5e{$t>O#$77 zQ{P#H?BAYtu;_vK``hJmuhp-Kux_n)4$nMv=#yva>6zw#6O~K9w||VYKPmOVIe5{3 zBQ}PME1%EobiVa^$tr#0d0X?0TwmHUuvlJK+E!QIDHS-(Iz4W|(mGtK{-8ObrXRJvpw? z@Xt4vQy}1EjtM8@L~VzQ3z$pGZG`4+%2m==ICJg)d2OZ!nMOOq2B{3+UuJshOXH^XRQ}eNy7G1Y$~1>{nf6l(uh0G? zb&Q?)MfJLS4;rs_NA9)h=08_xyeW6zs)v`O*e8|FV_o`l7Jo>oW$WbAU(ct#QjquQ z`{m!|bgbjSr!>xWmfL@^|1&Zy4vF2olwroC85TSDU5@Namb}BN!DYPj-%KBA29?P5 zz2A97H21FX*cREA&^*JUdbTd>g8JI@3sc1BJMYl`SwGnOJmko(EsK(8#4u#cTF)B#JyL_Sx0<1KLjUXezTYOrOT_uoa{1Y=!Qt^9z^F&^hw;yqfW&_h;|wRa~F>t>mxb z)&J%%7cGDI=Iu7YhK0t{c(UxmJsbCV#XP*NxT1DpZ9$0QK|nm9zErbf(I_XxxOll!H4nXU)NRdf;kpO z{CaZSl*iPsT6FOo{-Y&-!%a?q_-GzlKkt8y=c|=^8jQ|c`q>36R@ZuzYft0(le#Fe zVWSG8=aa__#(_T9=dUaO|Ev0y!^Af>FU_Y)?B(E;S-D*w`j?)e{+J5m?(d}tlRxfpdn&&ea4o>TQc`OJAEMH z7gPT#Hj^DY8GHhKuHRp(@Z*+fslunIoM4Zg|F?Lo)p>K~Yt>dxhL^XeczsU&`5<16 z`Qa9Z3;NBwlJ_KJe2o1+`~I``ZMU*^&*5&4%Py2%o~%G+@aT`zzAj%BKOdMPTdMw5LaC!@oMJ3jAMN--FVg=JFP`nYtqz5ai+{JK-~^p$e*!WXi2CeHicUN!yC8=v>9xfla#&t3TN zGS^33;ic@sm6v_lHJmtQXYKvg6ZAVyF!sOq`I5s&SO0LDAJe0zez)F%!`ABZ?^R9= zzsz*Q85dfuemkRAp~YG8(UGp*P5npVyzxsvOU9hAK}^Z%M-ksp`W z$K}}0(m7SPBCqc2C#w%uZ*TU_>fVvIB#j~HySVeO&pGeczR;e)Fr#*Mn8V7|zeTzN z?~5PcRgdBmV9;Wi@^D6)HRFVClfOGFCySev+}O-Lm48dOrK5B2j}Ks-1r?#M7eu|* zt1O*=NMYHvyUz8FdzbJFO<-ZSP+atCr46IsNjv5UX=_=AdfgoPxxGSv?nck({FKHw z>xZ)FpUKy5HAFl5pZoT&OO!#U`(tCV)eL#YOVi&;tIWGN#pB`)r;tWSLvCq#s;$<$Z}kL1FLSWi0mfp1L|Kr$6AooqWN* zOL6|AlUp9He_wDwU4K>MIk)QL0cY6e{*pc|@i)J~y59bJx>gW_(AIeqC%!w{8+O}J z{MM=5#0fo`N>{o68n`Wb!0LaBTcTsdhAq=7-IrxtSR^BFb$)tPLDy-InE4tFZtN%e zDpjAp+-Vm)k?BJHyCPWu16!_?s%B-k*NvGfj>r|WROh*N)j zxo+9Qxz~)Bd+hZob5{4_W(a+k{Lo^~wIjce&iQF95%@6V`Fy^AmhaAe-z=)k(B|C7 zv*v9=-Pz^aa=r@`9(yLT@^ArXYgmtavK= z53jbF^!~ZF8^bSi-F|_Ib4}uRDij$lDt~*zTK%f`2dzEKdUI;(OeESjM`h+5%&4GGV5gLXe;h+%l%AbqKi zckR7P_On`4&1Q)`(UGw#bGbe><&NI3SFwHZ=hNjy6&e1{&M1{nxMhCKv@vn<)324f zUWXE#_}{d2Kj58w+pkA$!M(K&(GQuM=FD7}_(a(-_mtUootop11+GfkPhoz>s&M6| zi9r6kM7^`&W>Me6_DuM^ll$9Yw+QY$4}a!MJm=cm78hK5B(QL9V;Z5OdL)e zFIgjeTZm%8uIecH|bEPN4iU7q7jZjttP-IV$>Tn*0(d-#k(?xw4KIXCz4k%<}} zOEOFz7_VTz=X`HwmEY`r=hJpFSrjJ=F&#hLnd$szQuxlRk0veiA((}z59^@ zhY$PT8Rs%0;=g4DehS*#*LN_mMCR7XNg*x^R6cBFoU`&vuiA0L;%_8~5{? z)3?)$7$)rNjXe|k{UqD$0r>{m#^n z(YIiFWLpYzK#=H?^fTAdy{Sy*fKG#Rv4%~WetK3K79Px&=( z-?*o0+jX*b+RwE2;XJ_b_-d_!>D%S%Tc+OjzUCRfQs)_?!<>)}{`ng7ygtpWHLXbb z*q63mIep{#pND!FR+z54aN(8NvhM1DEuy!Z6*5&%yY86ub_2Vg?or;ey*Op}dDDj_gB^pp!w@MB;B|0%Etu1XlF{$d=<(ka9(WVXo@vHt`{(1K)*X4!$bA&G2&uW-hac-UM z#}k*1OJ^-{K58@XDU-wM-*awkk%{pC+$!zIQs5l#>6*3j4o6<&afTa$M)!Wa6uKY7 ztGKM=e@$9*dYpId=YvIz5^;CUR{Wf~{$2CccUNY3d%AXg|NoZLv-O9X;*1%E0sn6r z*PJ^)_0f%KTnwO&e6iIG|Mu1TcZC(+d7K2Rb+6iDKXKLb>BXPg4_rLw_Wk$Xu81vl z^=i|&9R9bh3sma#x&N(W$+0a@txqWh-C^D!F8ukA$@=&_kBW`Qi)V&UWb;mKPGy>~ z;&Ts6xX!AES9bcnO&L@6q*k$t>r9(DkL96=pwz?i3JWgJ<}+8;U)ek9%RjaKTb55L zi%?^zeZFpi9sgy;{2SIrNn7N!x;>UMHQbP6e=5?sBJ03wWkUmwnVAusyJa7h#`4Zn z_sZ>7WfI8Cm+8^{WGwf7zSk$u+Rd9fMBe|u-Ruz3D*QP6S31X!C6{aGM_hbRxj^RI zlvsw2hMs@Du|Dg+ES5Oy&VF{+!A(ci)|7nsS8wY4`?tv!a}W04X?4;cwH~e2ma_dm z?ew}$+ztvRRaoNJPccQ{3zM3?%yu*UKMeliSt%~e*d+*okajv^6T^B!J zS9B{ZjPXM3sT&V&zCCk&|E1}Bg%r+3M7o{|J@jzGj=Vz)C-5y)Y2%*0%i&3P? z*9*jD=LRqP_=Md_YLAS;gR2INE*vL14m@^W{Gt5ys|9C|m&|PKQeT&7A=I_>RM}a@ z?X$uK?RRZD`FnQJ&1s%DSro24k>)BlGoJs<`~5wsx&Ec|lN`NmN=?uFf4!jeVdfi) zvm(_+KCS;Yx@1j>Jj&oai-CC+OH0RO@rMg1u*KIEF|2#@?ch@FKMJ4U9CkhG^Yo3s z)Bgygy@}s0TfZvx2w$J`#U@Pd^|D|y#uxW@+}UFFAwzG2y}=TFt4leqlNT61uxn@W zy*KkZ(}l>zJMtVf)-7k7++?UbRo(BX+KU+tX){*-e7f_3FH^mZ0hg`%q7Mg+Uq9?g zd)92I&Gf2LmiuV1>b-<_J3b2g#(kW$wC?=7PZ85+Z!$TN5dPU=Pv_59b}p~qDV}he zSe2_XFYAJ?oqC0cp=puN;v;U8-CjLf5o!KB{nvwB?N>#L(!SSFeTJsfY9XPx%%b z(lP_N(x(XR%|6Z%7_!WDRm_FFET-)~ZVej0p7alx}W%lTOBfawAUI!oV z^p|J#Kc>3`&?^s4J&GKihH;oiR4l@qmC_`4i7-(U~i%=oBM z&EybELi&A)Jyr&6r(fG{$c)r2xw<=d`i3cGyI0EBN9A1hH^m<1Iv;oM zd#0TvwLU4ST7LbFtF>Y|>=_E;i8mRUn6`efx^h^%VBQ|-s3+kITrHS5CWaWC%6nV$ zqxO-RgqiiH+lq`9Qa#Hjg_u>OL|hJHUatSisdw|PYM+t~r3RB)8duEfdoa7+Y{uQ( zy63*Rb>V@VzE9(d=4M#;TKF7hBrpas2%&<>y{k74VZ-`R<_iapwzhubZa&-kTEsV9Lz+TNA}g zxTa2fu!wnM@=Bu^jmLfS%~zdQtX;nL+E3a2&UzO4^(!~7Ww>BiwzfLkbJcI1mh_9> z7u=#8XI|x2cyP@9!0PucQn~C`B&-iM^DmeBRx@D&-}GJY8hcMEe>i?*ZGpsm`+on+ z#_bPWv~IYzKJRB+c=mnE(yi;R9F9+%$EdsAmw9DdrjM)Be4`cS@6Yim@#}xwnHL%K zJZar}d*N-O40p;B4t!~wanjY}HPb)8AHp#Sc|M$tEJdp}Ud@Q+?ce45>8167)o+<* zwse=BN!uuH_wFyxo2&XQ?pOSsZ{(bR92`8Gb?&?+6Z1=4YTWN@{Fp1W<%-3^qt6@E z`jtap&QQ&0UjF&(mU#J|?3D}Vb{6)w_UBF5Yq$URG}Eo?+`BWfA~!5$5D4^Np}oy= z?KWj;Ehhf%e*bB%dn0hZIda9U@ByN+@*nGaiJ#CgtppTcXV{^!}0G@ZR9@6gE(tEIcvYAl$-aUsL~m7;~}FM$J!oC@7c9!yN00uCaVwhFa; zbe<*I7-;e+(!14R`QiC5l~*Qvyiil&nPa6V$3MsF>Vs}ItJ=EuFL#%IU01EWaK63t zHerU#!hBM>OV_>&=D8SnUA%94XsKlux`eGzzbbov3lV&j&RpL)ulNPafs z7FIlGtbTZoB+GI>`-=-UzkkuX`-`!|iGxzpi;i!yy1rg(??e9tYsP@x)m~9|mrHEP zbXLyqe6t~B$qR>vk(d5A8lQA7m=eRVe%AYTyB!Tv4KEipaZWgHm36oLy25wmty@`j z_b2d0b2eNout~V~-PrK0x%BlOn{~D1iktyLi?>I%L>2HDR9=7RDGBe&e ziuTCJG~QZ1kL7yr_0sZRbJs`b`mfy3%OIc-VZD|;Lf>(lSzSg!>89zP6F)6-yutAO zK-CWMw(n~s?SekPJC?lmJ;U9DTb!qwU%H`j<;xz1t@<|H^Y&H;d4{~o|66g@tZu_( z28p-3nU942dS%zDARwGCSs9ZMyX1(Y>4rBaF8iK-kZBPA(}>4p9{X|e{k&|^dMzvd zo2))NTfFZ8!;iRoeE;4?AKaa8u2B50hU;pJE=z+)R>*5D|I+zR70+K>bC_&+YKsS> zV%sM3Ml}~N1&OHkdET}UL>oG`GqZ{B6?B_*zB%Fa&jpn?eicty$WX!mj`{t++6T9{ zGRrtKuJ+v|63x+YYi}u!%b71(_WFJ9>v-%Be>tSt^<|cnfROQWpUq0Nm*~+J>L7k>K^yIdy5}fRxnHn*s$gJ zT7y+_3>)$*B(}@sZMxOB^M*`~l9KQ?SFV+5E_QQ1oO^D(uEKst-`B&BlK?0|gM3ygHwW5mg!mjF!sIX{$vT5iKh!LL5sdTjax zH|PdA-H@2}%k-J6R^0+)F16b$pGPjrVr@`ZldWBSBdT*!v+u>d%-UD&P8SQFYu#kt z*H}2w=+HjJ+zp*SuYA@C+{(0|e4mkv4Ck`kB7q zUR7ROacXj^Rnp>Ln_^8tJ^bnI^Q2cDeX8qdmhZDj^S98Mc=cB&moeHrOO9I-(fm`t zO!39t=*J2I+te0pUSWRBO<%TlV&%k1{HpB}-DZesCMlWLEtvfB9p~zhxeO0(9aLQW zQ{(gB180@}kGLAl6w?$jcVBva@)>m>-#yptoJzI@pWp1YmD6F>E`Fb7R}v<_JMwWM z??>h{-Bb4H%ek}65YwDf&@$Qm_6%{&u$5Yj7sTadOlp;TzB6;)6snn1IZ?>1r@>@} zv3;wQ{e_tf4%5<0*M+QdW9Udw`8xIXjP(hHiBF~;OueOWTgkOSqx$iIUytf-U+`x* z^LEdOvpi}Ms?6}~)AVMSwB5VkB8^+tB#6?{%n!&lz*{Ad(sRs&1);U z7!6{R6>DF{J-d5gwUa-)ZQ7*FiA>EZPyTYMO`3Sd?bDG(j54V?D-&6RM41+>eG|wy z5j@7_dduU*+vM9bwoO!$_h6amIK%I|Gmqg!iyH@H!k&9AdBnR(Nv&+Aa@auC6=@{w;O?7JJW-z?^E@YPevfqvADt#>Hy!ITcnlCkF zFXyb?voj|i3Jedhy?3Z4?77#%MXV0-o9ZW2+&H(Oxnaij9vikZ%YSmcU@Y9BwCt}5 z!;wAHgET|dFbH^dXP@3ab#1{hr^?qaz8ySTH6e2%lhcMd^S&iVE!pyLSA*P|o9$0&tCnIeXs1eU9DEJwOHIvJh??8pr(FRmC;RVZCLptAtj1Fb0Hw%jo#{%FcW1 zffKWptkYL-I>~ZspNmA|w$(K=c8T=vzjkhqN2rpjI78HlK#e4}h{Ycx4y>_1Sz}*t z`ov>4?W?tEOubUdmpH#&u2JPH>uJ)Q7Q4hJC^YmyQBV=%0f}Y>(dPy%Gq>#GPueTL z!>r6;gH~nF&l@bM@l9dRQ>;vGN__5F@%QYs4v}^LzQtED8t@1|QId6CezkT^;IiM1 zOoqML?sDmIOO7z+2JlFosSf(cJeQ4OlgkpGcZ?!_L7@kq>iqew3?8CM*jI2&b+JC1 z)CY;%AOEQtKH1B;Y`SvrmV<4M%5S#&ESY4cAskl3*r6V};`48=d;Qn;nlc?aBbpg; zp#Aa0?=ACZhd<=eo)G8F)}nIz`6PiQ$N5Skr5;Kik73|a6Y>_>!~aHF$}B1_xo$(& z=@XCNgn##(mHa9DqpzydxzBOYC49>1B&<Plwv%2gSNN3g;re z{Azf~Z?J#Dvs)97-&p@n*r;vkWU0@ag+DgS1}a<&``#(Y!}h`PK$9cKnS~b(6BU^p z1g>p)xAqLX_FVD1#ut{(ONm=DWpCj#?(_{ochgxePns0)wYFhWJWrE?#Nml6Hm%vo z>5^ENY*lrAUE-n*v3K2-+O}E#V7Xjg*Hz*qE8uq1|MO9&Qh8wx7T;#J4U%EE0{Oh^ z7P&flNU4P}UF6VNchbJvxX{J@YwCJ~c#FqfABqo~TAbVB!Kk)skNv?t9xMNz-Lk9y zX`!6*mA~pMx14S5PcZg7$?71~8pnKMrh0Png*TrYJ3f783W>VQzA^Uh@`Dn*`?dcl zeYSl0)cK^~v(>*76eaC%Bvytf?fuQ~`0JRyQpuI9YA@fHtPaz*H?5qzGLfgYlVi*7 z=Xv@&$`UxtzenBUpVO_Y?62aY;G?eWS|~G3d*QD0uUEdZo2Kt2C1&Wu^RJs@Z^~BN zrOTc$6+CubyZ+CM&Mgzzu1J_z+F6X)mXJ4!`pM&C2A1>-}xy zg?U~Chh%tLEbCxc`;K|ju`dZz4_^@qXP=)^HP?R0>fbyZf@i)cXbBiRX5V!nYhu?m zK@YE%dvnz??aCkPui3IPW{N9=S?QKL|Id895N`bYt0OzxlLHr|{L0yUzH6*~ceunW z>(p;2f7ZLpvVJC9U9)8MZ-aOX<;q2=0>|%6>k3)a=`d;D$|oyxIT(JM&nwQ+m$Gs4Z>jr}9BR+X@w8{huN&6U`%AxHK5m}g|IWRZqt9ew ziu>V(VmvwO7w#H;+M&j9dnZSr2>a8xsg)DEU%+7HP$vS&a)WooC=`2+|g5 zy<$J5uE*Ye^8Upi@3UIi-n1_gsG$n4VmoZgL^$3vNNvnt=MDLE-)m?^^F zVEM23Q{}U5J@=8)iJSkzK<&e?QbY<>CP z*PaYNMFs|vI)LC^q@6V0tr&Gnb zr-U+`i+j^kpH}<$+3s&kqb9R-%y0=4JZ0dl!dB74aN?wbimUyLB3^-$Go!*XM8%JN z<1v4+FfEKlQ=P@<Is)>XPcsx3DF}0)N z;Zz`^Fp%XsAQg4se6 zlhk!tCNX(TV&r5}2-MKH=wVmkqxBp{ByVouJA~g4<>6aD(;s4vi z@)u5?BEC#*(qr}}S3%7{5A%0doMrxNDlCwE!O9u5|GY@rZx-@oruq?KjHO2-y~`I70o0v)wxoikyX-21-3tV2!MdwHRn0b{ja^!LfT z&YIVFT4u+d$tsR$nAx4aG}|?4>FZ~=|GlVq^1Pqd_8V){q3aQalmD`LkI-YM;0^)2@Ix>dE;OZkt? z|B?0n!@JjI?cZbh6Lhq%e-t$ImG|6W8Zni7Zi35=-~WshSvW4HX1jDPVXn@)zUF`A zV<#TZg;l6^H2V8e~HlCJ--{1|L3o5=<#Kmkjlg; zzU1!xMP_08elwU3KW}yNNm80?pdaKi-9TXBlIKE#2CfXwY#t|AWT!I5Mb+H(trk(S zxm56%_fMWZyHETJ;h4KW)+sZ5n9Q%U??}_)|CgGQ^%|nrm?_wsMdUK1bBQW4$nY&U pDPVk1ki#R+z<2x@eVKpiOO*4~!Y@uZ$H2hA;OXk;vd$@?2>?woL^S{a literal 14142 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 delta 1045 zcmaFQwTfecNGZx^prw85kH`QX@Rme0>?T7#J8h7#Q0#8CVz?7#JBC7^E0L zfO!EU12b5Jk%3_W6I@nd0W*RPQn;oq=`#ZZ^At}P$B+olx8Y~~g&jryzs(bm>dO85 zz}Y{H^_08G#|Qrx)X$jU@ThmToX;PRD=$QCrF>o1#qG%WlH{ZmnB2kQ+H`S6X99z2 zhlqhhNPwq(S?&7Uns;C3MGLPMkE?id?o9RP-)F1y)3zOG`}3SbBk#wuOt~c+`7Uu} zHiW2)9;(~4-m`X%lhBt>bHB*GjJ;IdwJ4=OczUxyLBp2$U-C~g&oZcg!I1f0X>m|P z_feZA;?YlXc%`0f__6NrPuE~P3|K3b?DvQg% zEpdwF+F6-Td)vSiiq(RdSFxXn{vr0n#;hxLIhJ8rSBeDH3`VZ8&hHJ;0SvtfPC zkXip;%cG&#Zd1mCXE8E9Dym=ZxN4_=5O``cZHxaY-QGznZ#K=%K5Wa%Y2*8RPOt01 z(4ceYO)iC97S;J{R9I)@$$FA)rTvVqChxCWhh}pbYj`LKg*=#j{e$s5AJI73(BCgR zSnYOaEvhzZteDd`zocZ(mN&(_OW)`)%@Lov{ngC{^}C!L!xy)`DiS?gvPW+H_kgY1 zGk&H$Iu#)^Ke^^xI@)?d~VxoKqD#%(OQ zzn-=F$Is> mJ>vuIeNH4g|I1{lV?HAI@!q3iK8He3e)V+qb6Mw<&;$VV1l>sh diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png index 326c0e72c9d820600887813b3b98d0dd69c5d4e8..9fdcc035260e0695e4d2b2506c6d75b65d627df8 100644 GIT binary patch literal 28715 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 E04nYdx&QzG diff --git a/pubspec.yaml b/pubspec.yaml index adf1ba1..b30678f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -96,3 +96,5 @@ flutter_launcher_icons: remove_alpha_ios: true windows: generate: true + macos: + generate: true From 62fe37c6ae08df96971b2de10de5c56f19682fb2 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 11 Aug 2026 10:17:24 -0400 Subject: [PATCH 057/176] use mobile icons on iOS --- .../Icon-App-1024x1024@1x.png | Bin 67996 -> 79746 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 712 -> 846 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 1471 -> 1722 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 2303 -> 2632 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 1079 -> 1246 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 2235 -> 2507 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 3461 -> 3734 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 1471 -> 1722 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 3498 -> 4068 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 4981 -> 5436 bytes .../AppIcon.appiconset/Icon-App-50x50@1x.png | Bin 1884 -> 2203 bytes .../AppIcon.appiconset/Icon-App-50x50@2x.png | Bin 3994 -> 4310 bytes .../AppIcon.appiconset/Icon-App-57x57@1x.png | Bin 2149 -> 2499 bytes .../AppIcon.appiconset/Icon-App-57x57@2x.png | Bin 4667 -> 5092 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 4981 -> 5436 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 7807 -> 8511 bytes .../AppIcon.appiconset/Icon-App-72x72@1x.png | Bin 2955 -> 3468 bytes .../AppIcon.appiconset/Icon-App-72x72@2x.png | Bin 6046 -> 6677 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 3219 -> 3872 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 6372 -> 7066 bytes .../Icon-App-83.5x83.5@2x.png | Bin 7088 -> 7686 bytes pubspec.yaml | 6 +++--- 22 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png index 0d531c47cab57c41152a5276660d553a1f759041..1682af0dda5f890ea3a58a0fc1c76f0a4290cfcf 100644 GIT binary patch literal 79746 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�KCVc( zlDygAM03HZ59W8+rUfiIoOrQzdDF#J`e~0tjT;OZ85k0LLs|E2yZ3ee)OXia^Z!n6 z*uD4vmFE+W+qT`>zI_Tm0SgUA{VEhaTHMIq~z~fq^vo z!%Y8ZUfuNlucz&6^Dh;TlHb>B3NYvhb=%(S-)vEle{|C8!~|V~w3g-G^)p=eEB#Cl ztkJU4IRq*dOB2?1GcH?dcQR$6&&EG__FE4W|NWu2*zU!i>2o4i2EN;?&|}~yQQh;Ln}H$5J9F`w%I)&kpVhy-TbFh9Uj5YX{dNDn zn;8-&UhxZ(<4f_(fp*!Jy}bNgQhvJ2+FwypO+u$ML`8nvGB9W_>p44B^4TYo$;WPe zKKj2X{K=FFCz9{p;AZ7#oyU5*i6O!8hToC0MIXaTf+qQ_|CN>Svt_+a{ON*{GxyKG zD7iZQvdlH!=_SX{P7(0h__6p{SbJCAqh;HIGt)0UIhA(m?_r;rSCUtr=M&mDf5%y) zzWwG5Gr~>pP2UkBpPRPy_K)*R*PUjNbDaBOGE3ge{=NT~Ix%dJ$Wi~qSAM#Wn_&U3 zO}u-iC7)aJzk3P~vlqUSI53xW%`dNO?Q4@7W^P*E`qSX@@tJlfzk25NrN6Sc%+6`= zaU}jN>s}8IH;aFd7#=XLddp_3b!ADwZ1I-D;-8<3rmPe4N4G=V@e=K6~>9gJTgZdlRN?%~xIBbM;u-soW3emz1b{hPZgu4K>iXr+%4j~;&HWcXfC_J5*PF>n2y zWA!WLS8nSS5~>2#daeo*$M60Bq{vWVFnzV@WJA4-KrLUq3Rm-Z?%1U|GPIaJXrWbA(35n>ueuy zrHOyEHblEPGFgUV1o@>qGsG-NI_-lavE5$O%?5b?)Nd)b+;u zyWu67e79TQ&s_WV{{5`Cx2kvN&$|*--hFnlpGe;x-%FQ{<@H?nn=X%ljJ> z4=A~^x{3+Bd-%}r9@lK=>rS^G?u#sbDjqiZTmA+$Tf?HG_fC|uF3*f#?ZS9~|9H$f zn~AM)4}VDpEMKMQa4g_w;l5I}y*pkX{W9%}+Un2;AIu{6E!^8sGTCXe)NPafwF_s} z)X)C0|Lm{VUb9c7-StVV?~q^mK#cL((tl}z*Kft7y-ImB$0hH{#}kXUYdW3KUD=zX z_3w1rzI@HCF`-BQpYA)aJo|^Z@_D{rOPf!LE@pVpo;>ft#Odt+wu)=?ny{_O|6~iF-u~+cPm;BR`s&i#p31qO{$}RJ-~Oxj=(Kp=HmNcmKp&W2T*2v+CJ%)pG|P>U^5B zccQjMvBvlPMIsD;3Z5w(I$!qnT|{Qg$qbuI8xw+BZbuq=8tJI`{@Z2Vk#Qi5QFZDk z*?rrZ6K?f;r@mQoX4#)-W|#Hjm;IUTQ@{4@-d)SC#c$W2)pu)k#pw+TMP}rSeG5Bq z_(Y||&g03?Gv4f)v-9xl4K5s+w|`E5W%fGWL_h5Mll_Vk9OvBD8Gkx*LiErzjZ3!! z*)d;j+pwWHdpm%NM<4odC!PMqwzdW!A~ z{hUqlrkeG$A8)U&ZGFrBI(FIrtFNz4U=w|GU+n5+*HWRK%Z0zs?`!JRKk!h5LBPo2 zY@%}7R^LCjH_3lpRg#$cp5suM|L4y9>VE}pyZ@hC^U?ja)Z^r6Kk5Fah>vG3?7#a@ z_z=hOkb9qwS!-8Z`dY-cFi1^rX~F}`GY`)^oGU9Jy~Vx8%Y0^C^LG7NQ}*Y$iETMq zS2_Fr{BxbjP9<8tlmGiwBP@++5{7nC_W3Qy;Jx!vsPg*Z2@*}nVF{`J27 zD*dST#`jN}dTk81<<_$--#*VTkl};#hZDtp>PJuPzm&8!w0Md1A;Wp=z3L^apL4Ce z{aR~_eE7V>&Z)-NWWTW(Z8O;~yQj1|bluM%TmF9XN;UuWE7bJ=YMKAL_8KqQdNQkc z?n(RD!}@$p@p3HjZw~k=WIQrbbPmu?uI>xn_WVYccU@c|3wMm&$GLM4q)z$$UW%2$ z-es@owEptffjjc%e|$2}B2em`{ws~lTU#!az7NgVzr8E!zJu*YS&j$)&N1G~Pw6ew z&d>f;I{9V&%s2HvMepu2%RTIy85Vx_|3;JW$q$XDvK3BSEnb+L&g$~+#8c&R-}g}h zPIVGD_cY&pay0jl)Ads&n|^<9(fuu1o%H6mKw(eSJ&}yZ zGCNK^Db<^=|2jAR&o_-Nix0W+u`;xL@!9=5|M#CQZ@I!EU;nq-e)DfW>$|WAWgqYR z-)mxO;6MD`X`lV7ayRaiUbndT8eV&!4>yYN`&oK!)4J)#7P+y$VcAD+h4ob(6TY+A z`kH*u&U?%D-4gu%_V~hIe#`#9`+AqtVY2<^%74Fq9xh#TNp0PO*O4%H4N zvDl#Oc1-N`)yge@1ae)If;X*rFZBQH?+Ewwsg9RVuC4qoR#$)AI!}pWXzqPOE?M#R0ySI3@W*Ysin00kT3 z{%kM(v)%s6jjL;Sm`=R*%V_I=Wgp{8i!%P>=i*+x>yg4HS^Yv zvwzp`JMX``(!A}0=)z>-{|mKOy#FAzh~dFr&SNogEeDITgEUx7ADlfj;l|qk|F~JQ z{@&cXjh{dHfaK=sCvA?`9oX@J>zc`w4fCyXf6p!Jj@P_Bar4>6t@6FOo6qfj^KbS2 zo%d({`<{3{V#&U9Pp0?OZhBk0>+$~*`z^xEZ~k9YH&@JFJ9lo7hwSuKGp+A^EKs_p zl6q|34Q|`*nz!DR**;mT!B7$Z#vn;OI;%cLBU=8>*P;`9xsRn9tb0|sr)5dYs@G2^ zL~rY1-!L;Sb9vs*JM$Pm+!k(Fma<~y=ZhWdv;O8!{(Iwk*1!IxdkZ&ei0T+j|E08& z&+Xm88+Sj=eS09&dHuTU9vqF+BmXapH44+`mRjmtyd}SQZq0hGwA)*IV+5d#i6e zJ5N3Tt8idZ$myWD>QnV^h*v-K|90s3?So79?sJ!a+Omdyk8Y1i=Gw_Y+wT6g_Aj)U z^Rw*K`rAG~S#SMaZ_LH8PyRE@=ear`ir%Gps7L-iE@9MnDgM~w=ToK2_sTd~CGdD0 zSiL1oYW?M3C->aoeS5Uw?SY$ova{rUPQ2PG$#e7Em)xL#p}}_|H1Gb@RSUl%9hrPx z>@R!Y-Jh4OkIY)k@Zh)M{fE(xauwl+uCitDguFNGb4rjsVpJ8Fc=u}&$IFJfH3<)_ zCSUfsCDV~G|1I16w{7#^uuMMi(8PYmguW}cQntoTGs-jj7yI>l&EeC2|8F;*ezBoI zIDp~9-!BIv>i4bRcD#)3O;pX|iNBxvf4b;5%eAm=>!OqKDIc~RlzL;?a3yWp_4Cu8 zu6rx^#IGi?-Q;p6gW~sRU)TJPwP(ItX7R%A?fslD%+uMo$v5YId1)Q;WwW6M!;iYO z`Ze{1OH?kKd@q-1^4wNi6l>+lIpv@Fk$XJTq}FY&nsxQOtlX|YpZ9*~-h1(|uKg$3 zUwhP_?Av?l*L1Vj>u=ZEH|Oa;+cNXt1yO5d{Vnf#uDqyUeZT9XKIeV%{*J|7mYj{a!!S6K4}tW-H&7 zuI5YM^83Dv2*Vz4Q_jbe@1Ek{6~_@ND7f_A!#y2Iy~lW}3`7*~`%6vsw(wu&H1qS0 zJA8AVaV^+Je9JD#;zrESr`r*qm zgHJNIBn3YGyTz$KbyMX39h++Z&JJu_Uw3d;jd5jDZ|%mnxAW}ZUWnhcP=ldjx|egz z?et64aSD4KRw>Lo*!O8~+zGG)#DJkfHoM=GBs*%(a(p z_1*uGxAA;b&2@ug7Rk!zZ}Q$X<9Si#`b2pFLxaHYvg|_<@8Vu5ysR>8$+2l(!E>f~ z?e+aE{U6(&{#&Tc z^y=GXWf2B}q}39>607%$v#tE9u4q5a(V_XXlb+Yf*^lP`omg$~P0r^}d-OrS7eNdT zY~Ht5N~x_430k=(Z0D8rLH}aEfBj$0m)@wnjk&!1$){&B3to#(>~CXYFe-5jVVk_D z>ygCeu65Ouw;nmb(JnJm;Iqf?O4^%gi3}TUl*`7MtYO+J{A5FW3AZwcgqP|MmoieTSLdx6J*=JiYjr z*jrgHh7%W9Cl@_`_(-cm_{6R_ZpHlLl3WJK({eV>?$A}1;||~p7VXoLIeTWK**Yfw zwebuLzJbnRulHOtk31_e`$v+H1^@P@$!i}Zyt(;up^0t77jZM$zr`zqqhG8)z3k}o zU8%p~kI$%W@qJYPrgNje^wGLS`@@Z5dX%3>R2Rz33*`&_zn+_Ug`@d=$L4Gk#RcCS z*>oOH;GD-f%~GjY@$)SA18)vz`!PsJoa=E5Z;XDRa$Li(n)99S*_XYRYYo;EUimuz z*;}pL1wjJSGnbxAzOAhBY0gIdH(`g1W6s578913mMn8?e|MbWEs^1B}qt^Nt&)=^s z!IAg;cU#$x^=JQHHc##kWN>KfE*9yVSQpcOPHWBex8JTNC@x5AQ;y%C^KEZZOY zheb#9ju%KCylS@lM%wh-IlIm-moZ7tpBa$Yp!~u6?+>r~Pw8LZd;Q#aGyXQif-sG( ze%iGMwfqatKWv{^F7nfTV!C$E+j)y$s|tNmzHxWIS#G#|^wawyzt()*_Fwei%=aJO z9=Mr%tjc;$+5cKMMg~c}{7HRflS_osBea(k^1pU!T({xdf=s!a)@Rse9c#SPc&716 z?c1A)zNh4k*^R_6nZ17REVbcE`<&as6SwCp-MU|V=vj;es5ev$U5&KjV+55(_VMpyYa~7Fd8a~%<-erl8eyV@>VMD6vOxesoK{Y>Asv0rbA-fXS^rf*(-{vIKm z(7x^l=N+{V%W@wET)1x{sdW5m-|B4pd0nUH1iwE2HOO&m%M34#1B%YL zeBMx5>m%b6+Y{>%;}h#K`}ysZ`rkTsPV!o_bM8Ey&STK>W#Nx!LG@*scK&Dc+IGu7 z?Jrxu#4K{H!O=Bgm$%6MPAxWnuuaIKW$?^zTDAeNpNoXe5Y62wukEFo|3E-L7%Vj<`u7>PI!MpVSh^|%j4bqXPN$WNHr^Q zVK2@rYV14^GUHie=HxfqBkM1Ud@)b`yR&Cj*I z^>Oy+i014Au?LyzmP|Kh;kj11HZ4-NDmVO7n%>I8hoAWzSZ>T%WFPnJ_to4}|F_os zkL}za^Iz)!^@7{M5=_UpeaoNswjkb7cpqCQ6N8aU%^Zv4={!l!yZ?WkyitZx{=maq z|DWE-s@uKXJox^c-xUvEpFR-7_RQu8_wKvxeXCE)sL4*4ZxLU|6d(8Ey#5*S|C;}! zmA-4sT$L7NSkOCpliEqEY$nHcWA_hpFWlw4yZ6F8o*dRb_jINw_e{iVd{_EdZ{6n(HdF3U++4c|aH#D>V`MLGqms>TP zjx1hknN?R*yG`$Y@v~%sDF?R%-Aagi9jWI$y?x%_!MxD6r z86b3p>5+F?EssFramI$bf0G~1*1jL}^LpqJaX}rvAKmeX z{(qhNYy0{u`)gO%Pkz9t6uq3`LG_Kj(|6hmC-~mzvi#e@%;I+n@bG$?f?HR^pQ{T z1@}j{l|Q~!{uA7`yMEGt(WNtHUKTPpVc1~adb>{NZRmq#>n(e1)8AM|H*S{Qa$fI- z#DdpPCvCm>?%(Zse{|d~1`%t52SBpeXE8&^okskIZq+ zXQsaYqN>Z{*`G#t>){P+HCYBm~;XYGam=O1|%{Q2Y+n|+4;Y0oA)`QLwEdD=F6m;2Q+p~*qVt`(gr zn*Ez+mNDb`#BCD0R<@VT77yXOn6Iz?RV(_)|6`kL6a5)@RxLYKKl$?C?YHXBZ@ch+ z-PQj0MeS<8C+&A;WRUDC2zp~TC-zrio9p###rLd?>u;Vt`?fUKrm5MmukK9#iGV_# z*y6is-)(DOzAlcB-|_5{@$|Ah@fH2s|CB!8c&XW_NNoPW|K&^VcN@+B>-u-&k+)20 zQoFer><-B-y?em4dFGpw4B1?A63p>8&IUZW?Rhx)eC9mX{5-)6t&MVrpUpTC_Rafm z)Ux>PNA1fO8~>X4v0aTJVO@go{hOS7w!K;YT6ChRD8ue0I##c%k?qofglZxy$a`-8cPk zl0~iW@5-K=VfM2_&i*g#z4@ra{$ZcpgY$W3UY@audepqMvO!^kzP#|Qgw*nyZ7aQ_ zR#qy;6jn<;xP6)7_byxEj4sujV^bzAlYa7bR$Xe3nST7@yzF25f9IIlUH^aTw7~YA z48^za+Go7mTe8<=)4r-t=lo7sb2P47o^5}wxmfGpO$!c-^wX9)&SEVBau5Fr%H4D#^2_iC^uiZUHqko|Gk@>mF(q{`o2F- z5qhriwPEv~*?zZv%}L_g+%(m$!fv-UwZ7?w?tZ09o)F~ z+47V8?++a)Xpk*C*xGmF?8+ZSX@1Y1nHaWn%9&bs$;Bz%aS`eobEO?Ec$7Jl}unj@@DLG+yh&{?Pru!~Xwc{i9}H&Bpr8kRij{T`P4~)TY~A z1=mD^b~oL2OkT$!dy!9yJN9-|hymjj@4~0Ivi_ABg)c1$zIK1v&)j|cd3oYizkI)Q z+wH0EKXg8KX|(2yIp@Ihgx}wejf=r!zU92EuKH=$|7fL0UO%n){hV`kZE1L%{8Rs9 zU$?w|nzJD-$zkjH`BrQ0J=T|-`G3yr%dM7Y3-p`+KAV2$cvy08(blthml#Z1RfCq7 z7MnNRpU1#)jwN}0oVk6?W77+o2dlF;e>r+?%)5} zzWHVP?{il()Y)V@(%C<(ITYCXSp8M}{;U71GV7+z-fMbu@%`0hha9R)e_Wm0xO;xC zcGE1!3{cYfZx0wg-Zfv+bN3>(v@f8U@+wDt# zGu@Im>uq!R^4-nxcKCm@_4#@65-fN38R*A1SK8kEAJz2#X=B6RscAdjKZ*-}oqs&a zeC^-n>5ggq|F2FEUC7Yz<(5UFdpg6(0(*0|XCdkJE7l*^O0%7N?I)_-j0#omuq~g^7pT& z*WcDYQscQX!~SP`M*08pv*sT|mHj?f1)mF#uYWD0ck8iPs=ZB?T6BJ^UvR>;!?!I` zj%qL{{C(2DDk0`{;hu(6&MUu{{@->Xhf(f|`Qtz9=gleIJLg`}0=8*#pYoZez5Bd; z`LlYxkBL3%-|`sV@qadX@IG<#&#mq(86um5S6J-cD}7Ibs^0%;_NkY)mfUgn_3Yj2zbA0LKYo>O8OOVt)!m{`3HOL!{^R+`~_*QkX$QY+;Gq9|UJHTlRLXZ+KUIN4otg-<3v>{s*MMAJ z|N1`u#r^nM^F=pwZ~48y`K)Qu-@5-Iw|oDcKBV~k-N#L9PCT4r-s-IXnB^iH+xq&a zdQ2HjUGM+>W5^Hb-XdH2p{$+1T)ZH^e%sv(`+0;utP8(%ntMmC#Beo^l( zhP6SnO~bc&-78@J)GN%eqxNsrzW-MP58UPccWdnp^Q^=1Tg~_WzQ676pU36bK4>xC z-{*87e7)ekNiXvsw>;Z!^ftfZ`y$^L!CwFWZrttr|1|g0x1zlrPKUfp=nUi9!vdW?Fke)72&i>}L|BwH3A0%?MYsxII zSaZ<$LFryMr)%ETM#-E1ZI`Wcnf>EC>(yVAtKAtHUd~PkdNb!v2zXK|(ZcLk`L3!J zVtKXqzDBjJek<~1b3We#>E3m0@44#hTJ7!4|Enmj5`6WYiy`B#OFvdY-SaYe)CA;e~Uuihi=J#Ph{%5HHsSQ zWf%l56*t}N6qxw-?cMr3x>r-PtL)KLl2$iC1K-wHpFUq! zvm|NvZ*!BM*|Hm#wLh8RYbh~bm;b|hNts*iZ$(NX4#ja+`+g4C^~R%W#oM=!O%~su z6;=Q2HlO|Wt^f3vTh(8Z<=eu{$DWdch<=l@80i9;*oqH zk$3FPGlqX$44QIF3rbq|?>ZEJ_My6Ij4a)=1vZA=UrYA?uv)Y7SN-IQ39bc4XLLT$YX5)c zp+WoKXN6M^PHYNrzVTIx^XJ2e&`+yAEuJXeo3ro#x~==KU-@;}Mt_qUC}lnPm9-~S zuc_kX@+&NL9Bq->eVramgP@j+AD;ar)4M%nxZlj`GwMweB~4FpWWkVM6b* z)u%ci2fpxgGT+o$zx(;}dv+;z0~j2BF}QEE+;J$-XZQa`i_nw#Aw^o#%f9=I?=ug( zt*_DK&G@zBuFRqNTsP`}X5?|ak+u%#v0HUwm(eWA$453!RymiHD8E^{yv+FD{r|6j zTxOs5_N{Yy%}J|8<)N3j7fbNZQw~u45isY~7yDJ819Ub2?!UNW@4CgxWs(PC*;s+=1XT5LtQBQx*>eC-CvnPJ2 zFWGD5^iQ!WTy^$Y`RR@!R|EI7ENR*W3g7L`Y3yek_i%RS%b32evV5XktSEobv_bM< ziTpmD4+|O|Gs#aWS{-tG>h9QTYhS0SMXQ!@A7fZFSw+crPDQ5t>2Di1obTSbIif@7 zZPnD48hb8=6KULwvYsFOR3&oU;r-6$4b9Jrue5(s)7k&BO83d*V#WL%_=#Gi2Ld1^1WwlP`WgwNx>{xq;_F#JT!t|9+LH|9r`bzYAU`?&WfBV+$ z@juv??hpU*d+Pr1s^43;hgRSIcHL-}ii4e5Gf!Yjr$=z%^!Mer*VOOX^Ve%qL(sRB zh6%l3OL`Uyxc%}rtqW8Z{r@FC`di_WXZv;cJrrT!Vc4uVUvBzL>-mSy2A6&I>2&BU zko%ir`17RFua`-mHnYfimpkpQFOtvMw}0n@*Rf_l|E2r?-7J3areyFW&8uHuar_L_ zU{IKSYJSS%xhAt!B(HU;)$<-;UM#oBW+Hc7ywTj!y)s4reNGspMDm)SSJ=M1=8gt? z*9wc`62YhG?5F?h?A?3mezrgJEb-q{uiq1Xa3JH3&`*J52FWhdx^%K%{eJvxV~%{% z&1b)pm#IAc?a3d&;9wSNaB{o<@}-lflzcCjkX!IaJk}NA46W^_xSMbb1I)THT zpYnS4rq`V-o_IRGj(ng&$w&F-tMlyN*QvSp>MI|{&iO6=yzF~?O+=2T$9z!2>3r_3Kf$UaKOxNFBB<_= zR_tT={_6GIKdT#7{cmTmY)HsFn6DT4%kZ)7Lhto)K9|(@)&86PWm|T+cUAPIxf;Ls z+?CDj_YrH+rpf1#q9iO^pi}BHKn?F9bshZO-FZ$U1=MTXmcWY%|#skkbWd76nnz!uU*(-Z@ zZqr|O{a%TdQ1x{23w>W+RrR*45#(YxvCN@*i+$9!YH_P2JNG*mE_!r-<#x{)wp;Rw;fvq<-#5NkAtSJJqNC~DBk|_xOlK_{Y$Z4JHgCzEKh=6??Zcj} z)^2KVo-%Io@-^MR!YeLxk%mj;KA#Wf`tLUVTR$&%s{LxM=xhGF>z(#>-`jtpE#ZK~ z3xjFZ=S>41J`0%h;>rEh#{RmEX?uB@S36C7v)Sg~j+g(-3qszluvw9J@5ioQmOXEc zY6AM+$vtd7WhWnc$n=i$FNRp%=(GAuC#&S`DS2L8ZnxdCZua}_k@a!6CMmfW zls>)Yowg-f|L~jEUAF8ys&5oGcvvdG?b#}vm7Ws6TUqx__FI;ymhF|?pX_qlXdce3N-VmPtu@tuOkt@~rx^tIYo{by&G$S8Aic6@kvyXoC;a$I2r z6D`*ylzrcSjrpH|K+7pfrSPTU=bUDLlGjwv@nd)wcU#}=ypn;^g+u1wTG!7#P!PYr z=I$R6BR-#!zt4aDm@)B;#=VxHnCWl3Z(m==Bxz*YbG=qv_@X_hztn$cX_!8B zh1aXw&L`Ym7#SkVV-`HldU-sxB22NC;fp-;Yzx~}>HE+9KlNnx)SFAzS18WeneG4M z+U~o-lP|fui!R_=Usc`E)uSwYR`X!o+qWLpRXN_3zRLsaf3JJ`qU`h6+$V<`n*Z`J zOu4W$SpTk7-n`rHzpdJm`ltSWlP~_}q^t29?bNnqAA~k3i7-qkeeQZQL*H+ag}dkE z{cR6eo+<~=U!^+P{LFqK8H^YUp9C7wLgwNmsLFrL(JyhSNS?~;vJ2)Z|!fx zXU(7bHhk8a`nxH=;#L2>kGqlH*Cgp4fAm$>v1gn|G}mYE{<=KQwq*?$D?`fN%E>xb zJ5RX=Ie$+*n8NDk`}e(7^@`~+fq%~{7#It^nvi<_#-BB>x7Ns1-bV4eVuCv#-(G#}+r>D2zFCJ9&$9{L+1)F4>-wSVXE*DrK3eqm?!7;MS*!p0 zIc>f>y+ObH=Z(C}@9VIu=K*xfYt!k@YW08Tt82Z*FV{XFRc`I zS1VhefA7-is~yfF?N7Hae)U>Vg1PP6-i&Hi67wv_)t1q-J;p^m zVf#Egjs3k@vwmAM+&J^-luCS>&hG!~{=Z&zv+sJJ&(4*+{&Dua8~(c8w_y}mKbOH` zy)3K6Sx$!Cr@!wnDp&h(jI&{Ori`W>(QwUkG>UjP33@tDnBr)Fe*@hQ)lJ+HS47zKzh zO!#{A7^nTN#=<*KR%$T3*dILie@uFRNKW~G57GF)$3u=h6+10_B27W_$!q(=-zL1D zX>&!~*ym;boC)VZP6!ufn8T>D<+pr?yVd{XTH`=NW0Q-;0y}1Pd{WdeI`MMfafKUq z_kRwa8~$uk(f^i`P9}y;eSZQ)d$KIM(l=-{d~5n^?$#sl{nbmA|K0v;?b{hx8xCKZ z<9|NlR`)skC)GEK^e1ygTBu3p?G#tcZUX6U3fx;eA+G_573asB0{c)gWB(k0$(FrI7m>6Yos0{t3caNpwfv2PnE)XmAC>)HS8AKy{u zt$)NV>sN@KeK%ig->?4gMvd|cJJy{nzCR!QyIhd*pmE(XwR0O5F*Ho*3uJJ(#+`gX za)rXV?QtGU_B;rf^Wy3L(DN}{8D@PoeWOy;V%n1qHCTfo7T9y^uQ4GR;H_m%rJ{@+Wpi+rF>TO%at~yYptlm#*0Oi?#iZ z336R0j`-M~Ubu{*VZv4iMutf77zst6r~2s!BNbO@d;B+a;M<_T++I_^Ec?|TW05@x zN~t#PJLbB0SNW~B)wRDUx_x*3-)}b$v`i3P%+RogTe0W$%Uk`IAH@7?X8g3ozv467 z7XAFXN%bd1w^mDWg*D7D)M&W$pE>c$yh-+^UwJ)deRDXmYXL~7`6;*G-lD2PTNln= zz+ABEwZG3-kE1cV8K15T7}%y+J&NS)F4lNCW&QsNt|!#3L|;{t7aNWas0owug84T}EyUMlb0vb%oQ z2U`Z8zMXf{jxL({$Cc6HzvQ<3AB}oS#d{CT`FD&n(prRJf@uPC!}E?3%>oU%m2dd3 zK8-kf<_f40#S}gbtlM&%S*T?{p$+5m@sRnNWfBX#K2e;VrLOC;mRpAa~;D`)+lU2&Guh#;bu4ynRtX7jz zmI?lOTKfH-2brKWbgr*~>Bjoy^QY;TJ=ya5>4e|c-+YTqt5_6~HtViEE5qOAuVqv1 zHkTy1zLbzZ#u7TlkD?scfkH6q z-HBJmv1c6u+vAEubb}7@v}~ZVM1u}A`{4<&s;(NL&~xL9QD4xy%X>C zpPwmw;tIJBfAV#9z5|sbZ{Ee*T+=kx*ZA&#A`O&-`(AtN2WWLH&za?X4;0?q0?ZAu zmUqwZ=Ue%!o?`-Y!8Ea&va?3N=zZK4YfJ1%U$VU*@_$Qyq`mA3l(CHeBx1(RG?)A`AkXG(q~B7e~C0pVa^= zmREY!Eq)Zda|0v`t&#g!HG69Dii}U!6(q_MZYJ@g#SpQVi7FwbC*Pf$IHshmq>{5%xk@+n-LR<_dv{)V+ zb)2e_(KlQ>;ZxIJ$k581)~Duuvq0l{|1Tsz*tjKOx__h>s8|*_ATzgMrj~H9JG+w^ z4=Y28Xw!;2wsCR2lO!@fT~~Os;OCte&XvN`>R&^GQ(oO>?&s5%60?}B8O|_1o85BK zxYd%Cp(RIxi{ZrIBp%7*x8n7VpZA^)>X}I%m^kPEvVC@o?)*>Ka7fVgKv7=#e~;S- z{~14Xc&r>-Ib*tl<`dMLoD72oX@XSXvk6z%`xX?DwVv*)BmAr7?(zuq?ns=LiQv2?}y z8Ovrb_BRgvSx z8^s(HoDQ*kpT#;preR6rtD}p7CS1%bLqu;#)>7~^I!d$7<23H{)L(Rpq9O8Oh@TS?IFkt-IS7>*A=e6fkeygW!4rFk!v(sPmH{g}QzQ#(%DXOpb z3qIl~*gh}sdHq+_x2)_8tjvke|M{I)TqxVTg=c)hR`v3ONc!tdM3-x8+`R%;9>vpnuI{srYVC$KEX0o~R854%m z|0)oh^;p=fI#$muetP-N{e>2RAKyQH!tX3 ztgl^V5$Bv1di}Iw%by4lh6(+r<_R_PJ+6A*>b6V7LPTBbpZ?Wif8CV^2?`OiT`B#d z-fl1dCmOs7*ckuX=oo8i8OKXzE`}4wMO<7hG*4;x8LZFzbe-XiUsiHISzrctO^VR6dEpU33=SUt0SpdyeCK$dFZ(wA z^8?q10pSz=C3o;V@VNJ9)jpdA=j@vg7V8-uEZ(rY9+VH=-e-S}2=CMV8!qxm@RBgd zx6Q?mckKE$t+FCaIkodwKO;wjvgz;AkD|d>L~1l54j%DwILGjE+jj+t;ssaqeM*^C zYiA2zk_YKLJUeCaU5lA2mRi2G32YCJTXgv8Gdez@$Wwt`bJ;)`6-54k1zAt z4cKmkn)7$*H+I#tHQvm&n<;Xg^N9!pPwP50qv{o>B_(FP^z*nMz~E4)W9Ikc;*?(D zj<(!pu>|Hg_XpY5+*_BeXxLR^8sjvkkf4bLr~nEcEZc=PW5&za}6i#>PN zJN@cpV)%6UXQF72mSxnrgg}P3tiSc0dKkVxF*)`BQQ+7A0t=WQY}oSPx_*RI`Ch3_ zOxy09Uec!}Gx>r^xl>g)NHgo=tltVd<&G9F*z-WarGfv#o9mZ7|A{Y1Ti^V^fG2X& z=Wa<2u21a^%))A-uWlJ?zOOQDnef|*k>O|J1j8wgpgzL)8$-SlD#`MO7o`+}A>v(nT01$Schdc^DSv zGl_?L)*n-rb~o9DbqeWuKj&y$eST@5#?;2>uU+<6_jHE-jrtQd3G?C%cAhx{>QjA@ zVP$yI&Y^bn+{rbc9?g08kMFSHtNXKFHO|?671V|bgS2twR z^JMM%=k0MGR9y84xN)r6Tk&kZxYFAy%P051J%#*zE6$a#{CqxPgG^;oL?5J!n*Qdpc#2b409&B%Vs<4d1^6kI&Ln~}U z|6d6)S4fXt-zoqeoRvS;IjNvtb8*BXqbnRm401DH1qa(s@>Y9p@-v%bhMckN$2|={ zn6#{(zP3*h{M6~!vTNSV8MCYej5tIXCh$M@yY%6S($kGhR?2cM!NLC>RoSynir!_B zWm%>iD8Km+XSe=t(4cwrulF`4D;Li{&+zg<`vk`Y3=MnquZPcDpCaH7*?8pqZf^Sv z<~P@_vmd?hR&?uY(TTs#)~wT(i_SkA;WhKY!V5<|PBO=OIAr~EJ`oVW;BasH^VJ{2 zc5+PPuJg5Ar1*hxn?Tv?myX}k4Yn9dFr7P)n5n9#IwjD|AHpuXp6!|Av8L^$kZaGkvW*ZB?1hxtn^ z%`US(6Zs@)q#(jD;k%jFhX*`{FRNrzT;*QA>HqrF<7f{Tb6ev{k0;01cr08Lnctl7 zW1ram3$A&~N)ESANL;DJ<=s9af_R;>7aA#ezU7GMpEy6PY47uINUqh|EWOz z>>`!ppedSz%!}m~SWV){D_?ve99|KqG=XbmqDH>`(n^=lS~;$2W` znkx`xvFzJ)w(@i4Kh?#L<}XaJF;3D_T>k#! z!V5+2w-_F{!it z+Sp^=f>Ypra9h6OeY2UX_45t%Kz))Wpc$C$(7r(gGpKK{Qt!Wl_-?IbU;aB3$ael> z)c?nJvh;ek;_8I*|L4@LSU)!v{cqusWo5X}EI7OD$C}rzYam^O2)~;q?a;~Jwub6Y zRp$S#mc06}=)k8C5%p=d_OzgP^$IgiGDYUk+`}aGqHg|&t?5qJ#8?@g_{J?*G&f1^ zSaI29P?=Dd3v&lDv6Ls5VyMw%h!S;!w_o-@~Kp6-junQ60(;laL(@8++u z=VG|WD#)uO9q{k|zU+q?E5EJx5h&j)u}NvU)=%}VHdDEG|8@t>1BA8jxtI1+X4OpD zzuv#jZD2m!=d&|4%}{L1@BQ&*&kMrs98TO?#PA??!%w+1U*3T0*^z?B4)i4L{eLIH z%d@A^;_Auzko0{~OhLgP93Oo3Si-)?W5Kd7{}m+4R{UIFGV?)?k@a`J_i`<3jJX)@ z9XTkg+^| ztAG09&6gJHO>j=gzTNlajrrBD6PL_ua6ZW8{>1JyEHgfHIIJAIJ7P-N7yX^}72-?+ zo6dpu^E{McDCj$6Xw>ogV`S<#z~8X9St-e=6e;DN*Az3m4d zEIbr1S;?$=^yg}4`GqNeK@RCi;Ng3yw_kke;=3xc$7ik-eapl4VBy5&Zu3^PP6+n_ z_u!3_(vBFjZcY!l;Clho2a$itI(c(zd4(I&@;0H5wAy?6ezZA-M;p~IIW1{iax#4>PlMAh6V=y! zObz81k9jPud0e)4LiLg3oy8@G7u^VW{wNW-&+<0mzoBTMX`(CFP2MZ6pnlZ353)~o zt9}1^lqdL?bi8TvjX4Y#o@+*Ci!kizHq@A^%k-*B@q34RXLZdnMYAox<=fns{a8FF zclC^ydq8tH&`u1qy+bjRgKyc%UEt6bX1IKr;Q)8G{S>R7 zbOZf{Dwi+!ISP4pg!^y*y#LpyWuPIDb|!}nTM{l8dt~lAE^wnrf9|eLT%}=50p8pB zBwR9Iut1XaQHjOBq#1rJobx8tJkch(8`N`3``-k5Wjg5TMzn*LTwo>^=z?>CN zK^+~vS$FI04@Z5nifi3-EA1%n4Q=_7`-}gZSev|w2p5h~i3kHNO)_aRS@C;&p~7D$ z#sj-ETyB10d|Ra`KigMmA>ZSw?>mpp>H5$9$mQt&r8VzXvWl|tu&j0xe7~{gq{d%+ z9yUJF-@WUm?T9JcJME!S!=-zS3;e@CBSjVBi+iV>iet*#Kk>Jbr)p1Efwum!!lp{! z$@|$7&cCQNX)k&=)xUMo+=C1Y&R=+*d2-#nO+EjP{pO#^ea6%mqWTo zNuci0^oUjK!i_Vouy*9IfC|ftWlUGyu6uEwYkd&A{>AY}cM9^d^yjgsw=P(x@b|cY z?IRo#_2vw6*50LB`_TyFHA{@~t;L z(_p9&|E=4zV#~xR#$uK)iVOuYv6ZK7ES5i-ub9BV^uXg>-PHP{B3m2fxxxwzg%g+= zyj=L20)GenjR`joxVXJC-K1g5SNm@Q4d4E!oDF37@OR3!R8>iX^EZF|-+9N=>{j<> z&!7cYuCS*u`1$_5abo0Z`zgb zo4vU`AWb;jJE73zRN8T9|&VU-2bE*K+Cq z_Quy6Cmgr=Jx%u7I z?Zd(+#u$11=VzXt94PZysd-sK0YH-w~kn=ygRovq-IY0cMTxUG=U!C=)k{zfw`I`?Lq-37c&vyWI6AKdhJY`GY&X~f~@GkSft!Ys~U-@rJh%oHY zUl|e>)?;|Tba&k8-_FMZeu2&m6Z6kh+7HPKnDxk-n^!S-v|-Pz|)CO%C6&-dJRoxOILO#Y2U z4|g%^oyz2Aulc{eu~_uk|AJBlhB;xWZ#QVHzw#ztVB?gWOI8d9vm9EJ4$IV8{c;Ou zpYfNysVk)PdFGb>r~e%+HYOcu-)8YZuI&H$mad~044D{W6ge1{he}%ObcM}|Ss3Mz zSv}<}zuVh;4ep{=^{fe3XNGQjeRZGSJdbX@4cFxhz2=;9bi954fvKLeINV&cisIccOX2Wj^Us)gT>lYQqcvOwXOG8f4b%O+>P7(Th|KfBRB6G ztl9MUgy`#M4%7XY*^13zvHxA(z3G2Qp8e5pj}=a|gx>yo!bYxR)vRwB4n6!_QqShh zU3-|}>i^wb-7NwpEDe)Al$Lg^yytoLkmb4_$*HMJLe`}J>i5%JzD4`d;k!RhdL*g- z_%&H)ioofs=jQ%7nbf&&|H1`~r{^thT%G=(gW>x8wPLxIx5b{M{}10|@%3v$L`akN ze*M=+wJ*FESg?9?2uI_rmyvI-Oce2&C@a5o&FbpVYtKSmT|RC(US_m3cFqhN%QwgD zB|=pB8ibUDl6KzNYy78)hp(o+iEYicxe^KA8P|BVbingZcZAn*d$aRvdt^mgrv)7`mSrqiJ-w9gRM_5Goy1(@6_wEI@8rvd1Rf{v;%?+ z54;>0EIRKqsVpr%w~vRRRCmF#ob&%$1p;@^&$W9Se4b0^Kl{Tr?YjJ3r?+YAPW#`i zkn275bzlTv`IfB42RQe?U7n(MV`lhz1`kzFC58h&&I}fvDi7n2 zzB@jBW8t~5(9E8~u+x!mIAzqAS$8}FyF+AX6IAaD*JAbQszPG>S zO5Rm@uV-?`Hzfx1sy%<^Y}QNr-?$_3_kM%D($6lO|5y0HnqgDcsUkl&gT-IcHS%Wsd*78l^QF+V|A!q?gL%U;uZXk8J#+l9x&CkC+248Wwe{&9 znmhDkG>@HajJwUWB;#8d2eS+)+?Q%}K7FCictD~{7$XIZbYuHRo-#(k)C)!m#g;=QvP6d!mLxcn8g{oluC@wWD_p{C=hZz-k)eA7$Q zk5zoHf6CpkZ`1F3pRBc)U0%(+t-w$q!*sxN%OaDoT@|*+`~8_ju1S?eotVkVaP-lw zho95F2PDKAaBv^mdwg5)+myxYLD`n0uS5FE`;+PCTaUVZV3;6eR9G8nTWI6JFhlh5 z-Tz-d#&5H)j0#z@NGEXfU0o4|dPo0BZdv;Tzka@69`@mfN`vWMqx=^Ur!~V_Rg)&g zsJ7pIR_@wTdQjlU`8iv&{!f2;E^Dj(+k*#MPS^w;UM9o$=Z*YxTc!sw$9GC^^QbiV zvbH|a?8nyngQ6d$Pj5V>()sLJicz(73uB)ngN3Km$yT>5x2r$5?zzO?;50eM?J^(3 zq^XaL-iEDx&mGdi&CIzm>TSKrpD0BJ7UyRh?J~M13h@;mRIu2d^n*G4O{ZeqGvg&f zHY(wUzbEfIvObq7$W!R-`IRD!3~5qK2RtuD=x$q7^8c)RrPgzQrWC7HF?WRaTvy-}$f9cmF@0GR@Vy+sIqp&Z@!Kfx*I4?DWyFDM$17F$F|s zvusxiwv_&9{9jo9K6hrd!Tz0dU&r-?|maDg>7M815SxxzS@?XIWrlbE{cZa;YBV#+y z{r-J{EBPi@wyz4mbRg-QJV*4o+kd8=ojd>U?)kH`4lS8_#Q9Osp33k4XXKep-Wqy0 z%daGbA-#p6U{czuu;-7{s)7vH-;oS|Ix*yJ2AA}|EoGT$ZJy;4wp;CY%Q0SWUsvt_ zgTdfOj782rPL`96!RNgV53ubI*papGRQ~Ro@ELbA`&sKkg!q?e?~Hr*`{cX-hIg}; zWv|}V$-rRD%lJU$txN71^|w!!*sGq7v7Bvfyd~7dXqvF@-_=ojD^lyPyoxI0^KNF` z@zCvi&c4)Lb>I4#?=vdgp0vz&apQ~pZlQ_qe-#(ayV`WO_wD7_>(YMJ76nHHexJ2} z(*6I2@U{P~0dK?h>|A$iEoUF!gEImQewVyzl^=wydcD>*|K8olH$weH&h^YuT$yZm zkzv8@zbTK|HFt$2{IutYHv8|qb$`O{mZ$#>JT8YFZIh{c%gn&iaJ8xX-e%_X`3Z09 z+a!cqpA<3_lw69lxtgbHZkDpx@Zv|tIf6_FJe6FPrbX&pj*zrl`KIjQn}wPl-62`4 ztQ+IM-FUR6>+-23?bb=<8gA47K2CTgb%uBU&-CiVAJav4|93tR#NqmP;+<+g<|lg{ zCP=G<-Yja4>8QEY%xL)T&*8ey{nB3lcAm0N4$53P)zA25Mu3QKK@UTE8$-b)kKiSm z-XUVE?^tBlmrdPUu*_(V*V8}k-&Cxak7r(ulX;hV*Y?)#Kl9lxUl&+(cu&k*9lren zJ*yNH15}ixo_x9)Ai}|*sGzt+R^_VWZC+WX13e#l?L9+|IKTY!Y`*Zde^a{_xumZ= z^vV8=4NJrJY_+OXy}Pngett;b9%IaX+@>h)z8LSy*(ED4-rxUs$C_weyUm&Jjp_x? zOyIrzck0W$8HcOB^~=Uzm!CRQ=UL_s{Vv=4zr@#ByKDD_#o9gp##h;L>;L9OlVYx! zf8VAQ6R3RpnfM|$u7*RR4GbU3dR^9^N#9vot(LS^7X$Y8$$TsLW-ibdw&u@;XR-I3*Kd~$@-)1%?+Mdn zi;rK{UpVWwZPS{KfB3^0nGW1OYyM@e-=(wN$MbJzC*OFQ;N^@h3U7CX zeD%8SdT73A+YK+nxPSILKb?;-v7di;m+0B^{wXC4?^zfhycLuBRi<9M=li#!oG^>i zNk`PgR%z<3RtmUvPTY)d-txQi4(v)0n0DiCdD_xj-k5iX(psl3x={Bm-ZMV)_u8e~7XSQt>}~W#CMJd$Mh=Gj?N=`G zU)xmw_urQKFxK7cR(EJ9EoE8R{hCjwbLkVUcV(N^TaUf_&tNcFVD-~`?N2{XPu3^NhA9>Hjl6h%=;HU(35`^vEW?`Gk3G-=Ep}D=U`VJvp_$@8OEgS1SHHZrM|E z^DuKoImog*U7I}gw)^c~yI){iQlF>UANlorPB17$W{0cZUG#CuhqEX2Ur8VC`DE(Y z60!E1oy@;h0fr_;cdz&ANh(J@kG4PjRj@AkjdJ*#qQ2=reG)#M{=f8@P15rpYg5IK z$$u_P-}&>!!kkAu5U+`AW~r>2`KnB6>Y1mSW=xv|lppe~$l7?VG&EpWhlIfSuhQLn z>vmf|xs;G5(BQi+Z%5H(nV_xCe7273?TdKpr9+b5TN@toyzshz<-tvv-67BUnG?{%$56nkz_2HFP3oH3@CRjL-@SsvmhZ6h zR#MOQ&~Wr!s1om!-mt?q<8Fmr$la#Z-9PFKUYo^!jkdnCrTx+Z^$dX%rb{9x9zMS1 z|J^OenI<3DbTaGc`+xO&^kueH`_9+@>b&Su(v%IBUrWnmT|H;Ho^8uA)vs(|5NBq5 zutjY4#k*IJZU4Ra-@%n;8Jp~d&p2m(cfFc$wcyv&&_l%+CSIMWJNaE-m6^(ve|!EZ zJ@e=|T2!t4e_3cAsBQXlhu(+V>z_Pq__gAlC|CHF-kT*mSDvpu9{!+`_)co;S~%n`@ZVyhu)sue7@ECYP{u+M}Io`UrB$>QE1z7M4T&n z%j$#6&VFyXJ^x!oQ~3L9Yn9FgC%$^k@JM88{jo&ElXruWcG~zFv8?E~9L2fx4+u`|C$-vbI|e>t6o6 zx!x^w!s~t??^%|XuR0&jTOsgsoxQqvq~6ZNwE6D}<9r5;6;pfW#r=Brzj+Uf zr?q&PU5noTPvu_3{ymONF*+;_mv2RMJU9C5f4@AlX4&_WIV;vPd(_J{v`Dcx6i+xi zFRt2YQT4KN)g8OG-Fd-(HSYG86Axn&1eWBkPI7+cEVYQwN8rz!`1{)rU$Q-X>pzb| zqEcW=-Pv;|cl~`uYX^5-YrKtQE1z*Gwg;XvtC(rKD)K*?jnnQYZRGc zOjsH&cbOiYB_UWC#h*X^nUl3$zi=DM{CrRKGzNpTj^dXgE-JA}8ix6M z`2xaKPVD-5D0uP$r3wwRGY^+PJ=kVxao9Cu$ElQwr)nJe%3Vq|bo&0s)lUnPS$liY z(_OWC0u0NN|J-}^sOsDNAAjxN#gzVf^wjV5ySo)Ti!U;>?1EX$v2mTBH=b z*Hub3;itWT-x{f3t-Aa>sx97bZ0T*e|MT*i>;D$-;yrxRKK=2zqSt@FKR)+qX^+5z zO9~8g&fbdoaRN7{)|37i6l5WlH4bu%Byq1ehFD$qJs~G;`clFvlD$^8e#=FzIknRn9!!zY2wdj$ z#U*HB!Jkc`8-iqxZu8l7_zQc^KhDNA@m;5{zWe)d`lSVTf;BQ+vi!RW85$TYHiyjo zz3q;u>MmQK=KSrtF=}u2{O9<_T5&$&^Ya~BE=T@&&|H!_b;BS2Z~>+Rl{x3!_wT%0 zVJ7kSGykQFKl`(+KDjfs@jmLf6r;lGtvy9JaQFR~ci(Q^RSXwXcVsR&JZ*c-#?)Px zWEOl5=Qv?@((LI1f#3cveYgH!mk;hvz5Pye_vYt(g}16N{V@%Dx&3cJ*!|bV?|#cG zD=kf_Dqj8d_xVR_&vwgb99W{jFz5I)r#)uke?Rm8jX3#A_S(Ce-Hxhl6E!++#oB+p z-ZWLXu=>KC8nX#^gBG~^2$;qGocVJ7taV!~IHg!N`G&5$_(0m~N8+vIM$d$sWmSj2 zZmr$Z|28gIfz`cf_Mx-C4IX?xU_B*r+P^>Rz4Gtn{Qp<(w31s+>wt>_!yNXB0h7XR zeO$ct8GrMq_Jh`f`MRnE|K%I!iss^4EB?B5_rpY*>>vOM_?8u6e(f>*u{<^2$>8K7I33)}@y} zZrXqQf8c5hLxJ2TJFX44`s^d}!_NPh%gkWuxtQ&#?xbU>*LbD=?yKorYp>|hlEEFf zW?OjseC}|cY6}BKm6l1(LALfH$~KP|7A$tV8e6!S`JlxU<3O38zW>*0?l66~&e^VE zZ#0L;v}w=Z+51>)FEQ+FTFq5oem*~2@!#Rvh!LR;$pPBcK2WN`kwrIdpZs>`LHt`_?fGFMEdi` z>ANdeg&sV&?{{ddP^HePDMoY6Uj}q+dw7ELr*SRQ1FIXGn(t4)?R#1EyWjPR4^~YG z_2$2xY4U-Qf$2f||5vrvQafdB9#3|1cdyG`-N)z|d+@!I*ySl9UamLa-Y%~H?7nd0 zZ~1iwEDfJ0e~mu*_UM!R`?G%+)qi>Z_fM>tgojm7)6(L9E)AWo=l;E1snw@FQ9>}X zORwa|LB)@!K06=(=efS-=En7vPhZyTJ!d@k(eAyUrmpX4h&rQtFne82=bmqENC9kgh?N|1B z+Wf!C-|b^kIT)U+pUhXQ$v6CY+q&5D^Zf7KUX~Ua+%Y2_x~AXm;8Tx$M^r^jsN`Ef7$$>UP4>W<;|_U%igd{sbb5Q zN78#D%lkj&Qm4d;G4}hRBwza$Xm0o1j$xHc;~PB2QP%H@idl+q4gV z+Vr?ITIG&>myoWkKKJ#tSLS}3TbsN0+xyf1VoHkR<}TAZcWLd~FBg^XzKnUYooxmi zOGEkAJ6BHo{{25sExY$eWFT)>aqYU`y+7Th?6%GFv6K42u)tNYF!4x+N|f>^-{iFp z3_CtqE&HwU-*5I|aY+He2eTF%1vM|z*mY>(es=*G{qRQ%b-y2dz;OEK^!C?%R%%~Y z|I_=lz5CY3`Z<1^Q}Q(L?wV;^RWk9uc!HMzgWj>ZOP{=dcm8j`{IA{iGd9n=srqtB zk&H%DVFZ@>lh$o!Jx; zrxqMhdlcxIS)0A#1AF_%H6>4VHrL*twtCy@vpYVEU;DS-+V8~K&Wn6+-_P0qTO&qs z3Ww?QsucO}tp}gY?|#nQ@ad_Mk5bMVvvuKrpDx`qJ*d`Ead&n8NBckSruOxc_Dl(% z1Q_((R(US@^e*YsO}Eb<7yQZ#nENjHUj0O2zX_!!v+h6G?^YygIN2cT$+RuX^_mAx z&1gMxwLxD>6VOt;m*ZO-2Wi9Ldo z|3CTMo#+*Dw(jcweX%KX=bQftnYd<+>fEnip5>a_`+FA6wC71E0=Yx#q>0dXvB~$+ zPTR`(6!3U+28u`?dCe#-+MT@BVMEVcyns zx+8MerJyGo-)1*?Y~C+_-Tv^mNs^o1bG-!!qwwD2 zU&WiwUfEWgyZw7ixyjpyF^T%G9&emnckjK3{Mx^(7l-~YuFIO&dTy3crrA5&oIl?- zX9$;8Ka6r@*x~W|ZN^?%+jn8{In(cphpw;jUdum8XKSe)!yMs_p>I08b&veWYMA=( zS;`r%sZD9;q^8T?zSs0tUiZK9yx8(5Qkz}{{M#$>#t$?CsB_ydcNgPL_1_V{>&wG_ z-CgJQo4Fv2dv$-<-+rmpF`ukgoSSv>P*&N0$IqM3>wQ;e^pRmYaCG;6ng55IztvY; z*;H7WsN9oa>i9EHRxP_#(!8hg`utONJRVxDn_ZTEPG^4gn&HxY?)v|aS{T&kUY@`; z(MUg}y8Gw$l{aU9D|qm!(AHg2?24_x;+k8F8#xOPUzzebFM_M_k$w7yqP_Rue^O6W zwXT0J{%`K5aE3pV{p-P!|sC3^siIM1%Rj6qTmutsfW@ zzL+lNsS)UCS(K<*t{tevz|wR_!?c|{?}{sfMf=Ak`$J-`nlFCc99&crm&c_2&wf&n zr(`<+z4#yP|9t{YR?2f5SaL9k`%mgnv5n~Yf4O>Xy`{##ryDAqnI`m2oxdplmPW(| z<#5ilO;Zha=6BlJNj%W!_V~Yk(>}Ea{QG#P-ZxEF_x7Tv-*(RtzbtpI=h5P7x$CFDeLrG<@A~b(Z@X*%KUV$E zS#Q#N{qZI1@0)k`U#jN+`$qnE=0htdh8-1NzaDSrpFZhlg!uns^W}d%JFx!zmy?{S zM^<{(&zqdD@Kl*?gU}*VX@vx7Nu0|8@NIteTR~ zyMM<1%?|&+>)+8G&F?>|)=T}@zT9FjSkKm-@;Pi%rFHd>g>li7&t5BOXD+A|V9@i{ zp0+mP-=@hXQ=Tk8yr1vQkGT_7y4PFH^M=N$%%@_s+9+oYZm z^-ATynY!M#weLO8JbJ;!aQ*!$JL!VjoS#QU8-88?lEm8aBX!3L^Bg%{j zRe!Ay^gOUVTOC!#T{+`-q`>)8-G6UAoL+AKPPhKIvi`jdefFPD{rcMddg=1|79MWv ziYkkWSskY~80P=jcKp83&*jO#PtJa(v$y@y>FqLAKkYn@-|y}F=UrDb{nP7T`b`JB z(-+PA@_BXr6ywAF+Hp5KtY+U_9DnS){EDSdGx<3m6e%*qtXt}%o2s?lX|qW6;`iQ% zpUmLdZ})c2qQ#umvWz*kz6a{R^vs^TbMb1HfA?h1e)=o@v%i1;k6Fp_KOdRB{l8&l z^_2fF13xZbragO|%C>6b$-f>1-CW=DyX%DHp-=S^H`eFvKAhg(et!MKO0BAkTmEH4 zzv#C8)l^p#^XG@@BiGJ<(+eLQKf6SKf5No@+2Bc2&pvD4?|JXP#=idrx0IQ7lyERi z-f$^EzU)z>)@hHL{2!f#7Hm>XsuqdMYjeY_yR+j89v<8Jf39l!#t-sMzc#6V{E;yA zX!f5~m$+qZuY1b>Gy3^LxOJ|*02@n#XGHFbt8H3a%M3p*thhASfxCEy-PwIVr`xS6 zXIE4>7-Vqm-{HXd3pY81gjwu4vtC6=DJsG<-`4B?|I|;b{g>IwG;lgH%$W1lyR#2V4{xd~T)P`H>ra z#N<@Szu1%ar~bIHqisvU#CVC48GqZGUZ1t!w@d$AHA`ddVXesWEk*l;m|_%5YnAry zStw@ys9j!_-|mw6wq>?z4W7;nGq#*vvT>$K(AN7stN!2HdO!SK&~L`WAsGi(Znzkz zUd_=cvZk-A?h%uNK+0byaXW?sSB>I+$KUdh`)Bp@#pEZ8{g>M+G-x_7%;>wSA=>MD zdU43J`&0h-rp{F1Hho)oaQC8*hZf|24ZC)<{=qKmS9MSRysHoS$Jwr2&%luVKioTZ zt7g>xrD6F;zt;=i|KA$rdRCr8gy}%Z8n>HSQgFIU(9y8C~U zHcLZ+!1c3#H++-l`xcw~`b4|>UoOQY$+df@*Zq0_<#pfliv71={yCOPnJy-83lILx zd>CXF!p@M=pzve!{<`n>iFy)TN0q+qy}a@N^H&N%lOFxJ_WS1jKYOEM-M8yAur$2P zK9ylAv_JdQQ;naCboQ_LWVW#A&sF7_fB(tb3!1$6BidB>vflpd_tJz9J@NIA)A!iD z?9Jm3cl_IO(jvG}?0&7t{aTT|-yPPj3*Kz{b|RyXJkx zn}5eY9^c<*|MTpYifM$UMW+KY=3ub`}?D_L1^XI-pqcU z1TjU1GmHA--o1D#{q2~7+@JXu|Jx-zUNzUNXPK>D#pYe_^|KpG4<=k$YR@YDu;8G& zK#2SYMWe4@t0n86|GVuW#mlR< zMcdxhoBuZC{9J=G7HL+}uUZ{XhHajBmGQ|y=|6v&Oc6$>!AuCTi6e8|66ox{tva7r?V|xR6JF)x6j)DtM;L+9 zt@Xd)Po@L=4&=w)6~A7S=4tzK`o%+&;v%~8?|5y?bA4^T`0MOdmuG&vz_5;urD1hq z+}X3Mcb?6-Yxc&T|G&%OdeKL-_sJSbHokSZ{8;-x$LbAIGJS>j| z3#+m7q>!Ma+}bbSvfoUvw49{)%<)Q-`Qm+^s?qNCS}-i%n&D|0JWU;lBmZ0FwK zcW=Ufv!~s+Jbk0hPSfPw@7HUdbbUB3*RZ(d`J4?sm+v_~5dZ$-n}PJ7Rr{x0{1dcg zgG~P2p6z)rkM_mAa+w`n_sZX57H>^}nLPK4y``&;AY`7DC(J{p(&`b2;q%|I$4>ZtW7B^o{-(0;y3>EY!ASyuv8%om+w?`6OJ^qk+;;s9B>S%(jaEYq>3?>&ami$JE#TGY&6YHCZJp=9>5EkGI_R>{}>4 zZE@?<7ssYu@cQv@CPRT72SfPOFVn3vb>FQyI=9Mk(terRzfWJRzyIw16ie%OQ`dd+ z4*PLqm(169^}+i5P68dC5s~lz9q-l>@Cwkma6frf$rP2dKTBTwReewVb#eWse!Fkc zwFd9mE7Ca_t~=VYFYSw4)N^g|Q}>&D8zp(p7A(JWd)>FH(Dl(@d)MmpamTY9UGrzJ zvYYq~g)72!N?-o+y3PIYD*4_yL#_WlY}ei2gf3a6F)RMV_OGS&+1pB2uN9yEH#hg} z`F|U)%Rf+3V2ELVTz+I~My9IOt163L>=Z9xAUE&UyXU{<0jmkJH|xmpIqS%=>t9LE+}qrHd_2hna1PexE8|f9b~$;hQ<9 z(z0(YX5P^zz_4z4$Ce2%*QP91yv+V`ZQSbc8+!_lI$pJ3^DFjozH@MoPu?2S8Q12t zrbz#MWFNuF$GUe7bMtghg@~U${po)$T{&L4)Gv5$YE_=ztl8J+`fa&%F*4Xx>f)cK zdGQ_BuBC4F477QBkSWHWgW-CxiG^ZMj9V*(3)zJ2j>`_IeoKQH(HlwN(b zQSeZqqRu*=IgLr;g|1BX83zlRbe=UaeypvxT(!Mg@p(K~{L%QAJ1+W(iCtd1w&Zo% zuNQ&eUNG;!cmGh8{Q(sPh8CxZUM_p2^i_@Gx~I#Tbx5q%Sn9^b3u6B^ zHRu+Fi!Ia23AN0gv-zuC#POV&f76uW+2%6aaIT!WHQ{YHQ<9wo+p@x!{twqrO4O5R z`dFqf#8z8>ziG$4?T@WLU5l-J`XlaF{rA(qyo zzL)v(`>D-!mS9E6!a6mP zpb6`;|35bUR~B-8@#o!@Q$n(8)_Zscc`fhsyS(CV-|gb6OwFjcE-USir@Xf8l*?at zdX3`dV_Vw!1x#2PE@TF+?3up!XUMU+8HrQGcCKE}aAVb%;CkzM?{hGR6kbS~G zgMZy)ZUv5@314_c-_Gmmym)vby9_dT59l{bU?_n=FGhvU{R zxmHxes&G1F+DSKO)7h);PKsJ(;iB^Akwo>kkQbnN19xq1`*Zd}hN6mIEEIPIwTQ{2JZZR~e z&ApUn{(Hv6yBC&B-f~~j`uFVoI_vvywhPM5t#l3)vfM6PJiW@Ha^HcTU8)+#?F}pI zou!3$?65p)urMUeZPEVLiH+A6ZgZU>vtBLHfy=nZ|K-y|J@=bS7PluxJz(#s?M|F- zzRzJvm0-XDGwsbzr;0tkm>F|3$MN0clMS)xYT4E|W17qAO+EMCMsB;ZgR5?JN_)1u z)WRLI*LLVfbUxHme-$gra89%+XcvoWoxDsiQ+=z%)X$G((?YmB%GlO?44BT`d|c*% zMcPc!(kAJQeeAwD4cjWNCncG%`zfz6xGCF|D7<#=TlHkGFZWq){^Q&9LCPscujsS; zM~jWOo^3u*uzm8xlUfH)Y!;2Ne|hX>S#{%V%cK{4FLpnFP-Z$$)#uCB8Il|oELY^$ zB$Op>|M-Hx{?^A2%`JZWc}>qfvWdURVzG-+q&jdyQ(Q{T)oZ?sXHR{5;#lx3OkH%l|&*KDnerq+g>QL41#a4ZcIbqF&0CSo`DOhRe* zgO8!*KU1>K?aG*)x8h{fHvZ%kNzJ+Ew;wwf9NP3T-pGx8bzpsX(LN9Lh9BVpTq%nc zx!(!}J&8J8G5cqGwrM)|l^RX`Jd-!IV(;A<7diX>O7QRtTVd{+xZ_&FEQS{Y9 z$pFLjM$JmGXAAFm?Q5!E^oQ~NE7s>3?CA`Tp789rF(q`Fq}w$<)pyDB)C1aCuAcu_ z{3Yf2#f3Ui$&>h)Ul#nU{yR7I)254Q4IkD7*vc?g1TiRGEKL2YJo!kfW((`g#8XPX=t8{9f*h{Do$Pic8KPA3r!6)Z~%Pr)0+HnLK-m z+S|0rH|I*;^u3WY&1KHz59fYY&!78z=GOqPhx1QgJz&tY_xm6IH0CQ&WvLo(a*9rt z)w>z+7)!``Sh<%-wP{(OJf5G;IC1Z8fg;Y5#KpbcuTx_WPf2~%dHA#E!JFkjm;C>C z`c>&+pTI)3DmhCiwaW$6sC3j9$70&GSyUciE+$MfjAZ+Y|2>M{gZmoIP>DmC2?Y zZzZpF{aAfD`B~d5`>VG~6td*^o?3aj_+P8=q|0mVc1-bWe7ZsKe$8h8cPG8KJ=DIr z;kB67A*J)B53BxM_%~xFi)d&`$>tMUhn?6Me2*{F$+i_bwQ1?*ljj&`MX{gja9XkB z`k$DrRJFf`OU0$@7nXcqz{{Y#>4K@x^a_>PHzx$#l(=cM{=&US+&5jn)F!J(f4Cc< zmTuX%*mvsPwMWwWw3Y4`-!5a6jb?tGy#7z6_@(^}%%875KlIA@Ock$8kiB1}`1B{m z+O>g=Q>PgIV`k4{Fz8z~UCMHEOXGQS#s+1N)9sAAV+|77Ji0G>7}a0byt}6M!GRjy zc}}yhZm`_GZo#CPbJRX;;_f?9^X$?4tH;*6wa&j-u9kJX`T;Y~op6T3+$`74)V^$! z^J#U@*WEpp@qwRG?cS+DrFY!}CfIG5!|G8UKd)yG!8t%2tragba-LpLA1ZoPQB$TN z=92f;+ty{0aY{F(H5+!%^>4l;(|1L`VaD_24;@$ip3Wsck!@q$BekpNYU7!dSC%+j zeSXYgi_-HQ`&6deJU#ZPqpKi=`IE(8M+u)Sre9A5w|MXuM89d|5mjJW&oiHy`}c}t z9~xG7&(FKfbgVus%;{rZLE*YV4JbGX$`;ir?BQ9uN8%vQXedzv+d3T zHa)djzlxZ?tzXBMcxGZ&xJkp^iwqKNVh7hG#VA(1+Q%lmqW#X#`h`~=nD3NNn)Yr@ z!{muc-VqlcezOstV|*iL=V^Y1SsXimZ;)K#&URY6#Nq7GM+a|71>e7=wf^I?c~fGz z?>8RX?%4Z((mRjTLtLT-D-@eTE|}lFW`5*fx^utj+MP>&f4Wk~XILnya+TdbnyY8g zMaHKS#5X>D_BrhS+AX|>vqC=R)<2do;k~g-r-8S0%MMP17=d>ueh1|3;a#Wy`}SrA zzBQ|i=5GHLZad||5}^lgWEuCk6s(Lr@{u`J@(|o{DGVGO6tK4b_GkL8~!Di9BBV_Y{t`q!kM$V z>dlwdu5PlpuJmaCJ&|=~T^Tuo8&frFR|S5Rx!}X-bEU;F((1g?4u$)bcB}WVb++dI z@T{M=^P{YoZN6{-_jjk0 z{STiUQ88l=KXCrpz767RmNGYkpYUXPd2w0%?_BB4uN`&ikNr)?`rcO#zl2Oysa{ms zk`#R5VN%Je%km7)Gfy>X{ZhQM-EGR62Cu8WEB+GA4SHIX6JYBKU`^5^T zkk`AmGO-DJxaRqq@9mKmEdO!x(BFT{R(ku1IK4Vw_b7s4=`Cr7*`9KzV_F}~C|M&D zcI=|!SLIi$o6e{CrcK@V>`Ug{`mfJ87=LWL)5<8UpxNW7_s&rA%Zb7on+hJoRFT73 zRk!$i%#)KZZY!~K=X7+_$owa2QGaC1vt=qrPcP_udaf#sLCB+feX6b0`(;L|y{AHC zvfKQfrR-QsK{YPn^vVoMFO{!x7D9F z=Up*%yEA91y|}R)XPoR$?O@q};|uxb8Q2*gRpG3eF7)!}=7|@i8`W++pOfh@y(Q!; zZ?%Q3#OJjuL|?KhowpU_Vf7Pb7TEnPxK^^k>#1&r+{JqnR#X%|VY<37P`2at?@LFw zho^S0n7$o8B+44#Z~Hl_qR^axv+|#+p@g88xoPvp#%tdDVtF z2l_VFzc{xmWrJsSX~Hs&!~@&IteT8#PPy{0aMSNMkt$8KHmoXLp#1%Bnb*qprvd6O z!f$3e%sN=KP(1M7tdMilc89VoPFv6C<2l(@!0JWokD0&Z`QIl=#$ErtL9 delta 1429 zcmdnRyPtc4BnJ}%0|WCMeXEIz>h-LNo-U3d6?3l6h|dWQl{tR?@BMGvvXB4Ua@%Ug z>wgM9B@JE0eH{~g7HNEJb!qOD>NQk*wfJG+@^N}Cb8R!1ay>C1J^IOa3->r3d8D8u+`1P)x;c)#O z&XxsVc7E~@D9gVqDlxr-#c2s+Kpx{7pOsp5a}yX2G+YRcC%MLd{uc3FZe_U%?WU`z#%_M}HLy2lZ!GhTpGW@J#7fK-jGR@Gy5Zc>3FjUQ zumsLdV&5rj`111SNG8Qd=l5@TEqWGk?_lS2so#Em-iP@!r!3<9db=>OVs&~k_iLGa z*5%JX@1H-%%Wd<~;wYmt7cVx-HL2XY6Z?F_J{e~j+kpSS(z~S&bOz59ZkLMKRkcO$ z7R$a;!@5r=EJH8#ocrmn{Bg#mC(0+U^5w-#S63YPepG+wO4YBYN8zAe#ZFyUYfI>@0VL%2e;(g*WRsjW$#=IyRE;6DQ@1mCy$yo@(XnF zmN*Z;eS;f7jRngJWU;n%-O0>}mR;kiDWGhy9 zvo&$U{i_ZWKmV0|db}yccUyUs&Fb0;tzLmoyH9Tae#O#dl|+5cLGRkc&h71!eBD_wSn3eEVnf?Mn6~d6u4!y(X<{cwSbf^jWQ` z%`(+FM{?oim#g)!<*wfM==gekS6du=01)y*W?TO+3=~HIPwZ zme8y{Ia90FZ2a=(oZoAc!;_`vU%D-5w#9B$TcTRzgUDIw;T>uPd+H}YGE%p6tDo|2 zcSzl(gAxgP+TtOL(hqB?dTei6FVFSG>|<}e&GR&mE)~OuC6DGTS>~dutHmh3+4RNd z4cE>-DG+4X`MhbV#f48No?Usqt6%*h_q*iC9~xzq7Gk%GH&;q8+i{6iDKrvrEUc>93swOj>RTWX!Iu^F#T$t>d+&x{fm5bZ2 zA4v~Vo@S8drO3T3sVmfNhh*H;ET-_h^=lMz_at>z>y@5sc3s>qAW*wGfm1l$tSQFx z6QAoICNUS!!!wjTmuB;19F@4TN@d=eo~U~%|3o;?mK?uO&k{F>Pim?NL-C4Tp$8T+ z>{d7$?L0|lS01O;mYP{kYHTwZvhG#+pNfC&v}4oHNj!Ypwys-e@#6Wf?Unhaa}-TD zgS926s=lbpe8{Mya4ujT#L>UzD9r4w#7%xEvK+`T)D{r}`W zeKwbVoSgLf%^ROLX46IMy}VgB=zspptC}S={b0qBEn*BAKgH&sf6^tM)0e?v^tQSA z?R&ZC*Y->{zI#QhURM6UxAMcHpk2=S@wggwPyCA zdFMEa*31j-3!ZI#ezoA3Mmm;P`+mOpj2yHN9f1_lNOPgg&ebxuqPO#o*B B!kqvB diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png index adbdcd54eeb63eee1552bfcc84fe121b480bb854..17d971ee857f2beae679e7bea9171174bee34ea4 100644 GIT binary patch delta 2599 zcmew_ctT`?BnKM<1B2C{n?(~9)$2K5dAc};RLnUV9hoD2T=L&HCCy2@QoT35yIfY| zotJFw%e32-_jK-ME7K?zvkMC}{!C$Veaz~Us(Q&7F_vLp+(_Aul-jURL$u98V-5LAM_s^XB|Nry({f{=c z*Pj>8VQ7gY})N9eUG^>+AXu=Rai2Yd(~O3Gtv4;gzEeBGrW<+)X}tZP^y+itQpPK*FMnxb zW6v~5{F|!eQ^EI8&&<{JRog^9oq*Goy(V&zJC0mgZZe5&{*^WVeOeaJHT9VG<0WgW z$&_jJn@c+N>)n3`OpIGH?QxLIk%dP-nVKdZR#w=vyK`5v_qMNACHa%0*12^*>b|(z zr`D^P%i?gvzGZ4Q+t+huO>EznUe8l>xcx(+(4Rf$cd1HiO>#M@{p-acRWsu)Cmd&- zDf3&wvHEGI|NiW%h%*sW*_u@YIbk3 z`vilqITLd~iR_vt@n&mgTb@p1bn)!24<+T@OE-L4Xmnz6`f~a9TQwg#&V8-j!+v&N z*6VVM4boN@FV5zA_%uRaZL8&+zCXe;FYeYBUfOWx!mi(W(jM2QCof!gXrteO(+{(& znJYG2X1{p!zzxR-EH)4J^S5_xt53GL)~)-n_)E#2fSD-!+^4GG21HzCic2WXQpj-?HzCK0MK9b%HVe+$Z5! z#xHMlHpvw&KFI0%VatE9nnLj_(f3(DY3S>nbCfu}xBHZL#P@20&5IS&f3E!9Y_Vr; zy+*t-tMi(FY6>FGe_wpOv&7d`)XQ?+&pj>6zi)qXhj*s&@5~8%**Ctj@OZ7ikoW(A zZ80<0TW(G%miB8cD&>3@ZFYOw%>55qjSy88iU_ow*2QS`l8igv#BOtCjMjn^tlrz7wpM3PMYnNbK2*!@C}9B zGfaKo9kXhsUY$K|bX|)*^G58B`B1U{ZdNCHm0k-BJsFz4`kz+4`@K-_faxlKyl1b>hQW zD)y8t6AL}cR9YV`X2BP9I5H#L&uK=1{F!L?2>uGg;`w{`=lnXhZ1;(#cWL@kr&N7h zjnz~Yg>AmOiR}NeYV-GJEc^a&*a*))aPaTHD%poCf8Sof{cUkx9?Pen$96vW{-NTT z3+uT*m2$fnJ8TLnJq{iX;Ns6uz5Hz%(_^VV#_jB}r&9#|@-z?Mt#4a3XX@Elf5jWI z?~j^)WB-^`f2fF;gJWK`aogNdxezwV__y1X4_KeywQir&4CAvCif=62x$47?zvXgT z$65opj16U57`(e0pX(p{xOiTWnQ{2``Kx{zHD{#j3W*-=o0{zAj`8)0|Gy+Gp6d~KVoS!kf?M?r z70eS%uQi|fJOz!-C(Zf#`@im^G@U>9poXwjx&P7h0 zmSV!rE?Fz?{n9^X_Pk#9gJGho@0zVK8u#`ueh`zd7M62%gWrcA3l(;+mYiLpAmh;%W4lDi?d;HOr0^!W%b!*lYZ(=rnNicRnOkd$oyD@ap2&!_ueAnW$DFeRayJGA;^>jy>j*tU;AT~zMFp1{`Jgp^K4y$1$bnC-2R@^{UyY3%0^#H*U!S!L^RG` z-<;?A#X`vK)qnRNTjiO9zdh5aT+Qm&9{AH=?$-U->E5Bo*aI|gxtrJ*))dI?_>p~E zDYwvgi{$gv$38n$n0A)c)^`Q$Zr2T6na~r4=0?u*P!M8QC{Xt%WcSQa#fnDn5+s@t>zP{#ul*TEMCTIIrnLFGo zKduoqPvbf>Q|?M@dc%d)m8-Kpa;+%8Q=Rjg^Y^p`CU+Lpxe52X-fL)IVesg0K;9gd z=eaEbH<|anQRFzd_raN^3C0X6qKxK+x|{0-C4Oidyw>YH8soI`;GeE6(`$l$`ES_; zKg~b1_Gnq9&|UAF%&t>zd-(5Vm|-vM#A%T)Yhk##S+PpSh4b+5Zz?UUzf6*hb0+We z-d=rLEk>{{$kgqwp*x4)F3(?Ak`+!yOp90W5mejMrl%;GwPaef>kNn7^wWOz1uxZR zO|||~-;~KWukla&jj{>(=Fh%NpS!_l#ua`??Rm@d6f!h^SS5R{H(Ase{KEK6$x;5w zoV}SP%{+;ot#^)1yHss+t9`+|f%*7sRsLB#)|1|yPo4hp<92qP4SxJ$d-bxOwXF!dkR5(K?F5_C4ZD}d z@*IK_c1^W*Jf}P3(c)#2w-%kdz&&ecNOR6+?e$i+8Z1|IXUsn^cgJjNu{SK49>r6= ow~D3RP&17=eC2u6A90Zl!Lurg)8A_`FfcH9y85}Sb4q9e02HbJP5=M^ delta 2267 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 Jmvv4FO#sERZ`J?+ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png index fee4302899f072ca9dcb884673d74420e4962792..ca7455446c6c4c91869d2b314f1b6e6009fb46a0 100644 GIT binary patch delta 1202 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 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png index 3e7a85939a555c40455520d4c8026294372566b1..16c3d1ea5aba5317d10670b9a7fc5ced5b6e9c6e 100644 GIT binary patch delta 3709 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 delta 3434 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 delta 1429 zcmdnRyPtc4BnJ}%0|WCMeXEIz>h-LNo-U3d6?3l6h|dWQl{tR?@BMGvvXB4Ua@%Ug z>wgM9B@JE0eH{~g7HNEJb!qOD>NQk*wfJG+@^N}Cb8R!1ay>C1J^IOa3->r3d8D8u+`1P)x;c)#O z&XxsVc7E~@D9gVqDlxr-#c2s+Kpx{7pOsp5a}yX2G+YRcC%MLd{uc3FZe_U%?WU`z#%_M}HLy2lZ!GhTpGW@J#7fK-jGR@Gy5Zc>3FjUQ zumsLdV&5rj`111SNG8Qd=l5@TEqWGk?_lS2so#Em-iP@!r!3<9db=>OVs&~k_iLGa z*5%JX@1H-%%Wd<~;wYmt7cVx-HL2XY6Z?F_J{e~j+kpSS(z~S&bOz59ZkLMKRkcO$ z7R$a;!@5r=EJH8#ocrmn{Bg#mC(0+U^5w-#S63YPepG+wO4YBYN8zAe#ZFyUYfI>@0VL%2e;(g*WRsjW$#=IyRE;6DQ@1mCy$yo@(XnF zmN*Z;eS;f7jRngJWU;n%-O0>}mR;kiDWGhy9 zvo&$U{i_ZWKmV0|db}yccUyUs&Fb0;tzLmoyH9Tae#O#dl|+5cLGRkc&h71!eBD_wSn3eEVnf?Mn6~d6u4!y(X<{cwSbf^jWQ` z%`(+FM{?oim#g)!<*wfM==gekS6du=01)y*W?TO+3=~HIPwZ zme8y{Ia90FZ2a=(oZoAc!;_`vU%D-5w#9B$TcTRzgUDIw;T>uPd+H}YGE%p6tDo|2 zcSzl(gAxgP+TtOL(hqB?dTei6FVFSG>|<}e&GR&mE)~OuC6DGTS>~dutHmh3+4RNd z4cE>-DG+4X`MhbV#f48No?Usqt6%*h_q*iC9~xzq7Gk%GH&;q8+i{6iDKrvrEUc>93swOj>RTWX!Iu^F#T$t>d+&x{fm5bZ2 zA4v~Vo@S8drO3T3sVmfNhh*H;ET-_h^=lMz_at>z>y@5sc3s>qAW*wGfm1l$tSQFx z6QAoICNUS!!!wjTmuB;19F@4TN@d=eo~U~%|3o;?mK?uO&k{F>Pim?NL-C4Tp$8T+ z>{d7$?L0|lS01O;mYP{kYHTwZvhG#+pNfC&v}4oHNj!Ypwys-e@#6Wf?Unhaa}-TD zgS926s=lbpe8{Mya4ujT#L>UzD9r4w#7%xEvK+`T)D{r}`W zeKwbVoSgLf%^ROLX46IMy}VgB=zspptC}S={b0qBEn*BAKgH&sf6^tM)0e?v^tQSA z?R&ZC*Y->{zI#QhURM6UxAMcHpk2=S@wggwPyCA zdFMEa*31j-3!ZI#ezoA3Mmm;P`+mOpj2yHN9f1_lNOPgg&ebxuqPO#o*B B!kqvB diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png index 518d3976bfff2f631368fe6e63e1fcfa3c05b5e1..f515ebd3ae908dda76a2add411c64aba9edc7e6c 100644 GIT binary patch delta 4046 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 bo?)r|m7CjZat<;uFfe$!`njxgN@xNAN1VJk diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png index 25f2b47acb36ed5f04b260c4d2344402d045d875..2e49a130da625b874a4c3c8a15cb236067a3c460 100644 GIT binary patch delta 5425 zcmeyWwnuA%BnKM<1A}FX*`h&V`JY5_^D(1Y6<(v?bTK9kN>gsjxUcQ`}nb2T4 z!<%h_cL1ZfzDv)pX%hXhiywu(3{zdH5|(xM)~bx7zNx_>TGLjB9F@72_icmE728dn z;vFkaYjG$YVlX~nz<&77W#ig?b?L9Fc@N9j-u)Z5|9k1;pP_qSE&RRrd;OR7```br zum3-}{^d0D5)pwTzr0FvVjV-(Zdb@W{B<}a)z0|S{s>9ScROV66>_E>Fnn?Uf=75t zpv=Wv$sws`-it#{xGofwiQ39Cagx$1qpj1KWK8O0n2Jp)fdr`-l1yI zhD`;f>Y+2Wg_3GE50j*&a^&s{K540m8Wz#n%cwlmTL7UmU!s4uQ>H(wNe?2{UWW&y&rz6 zTigq1{n*gI%4gX}mLrc0R~eP}zHRmH4xXx6qVmaS!))jKyk|pPKg|<3w6)~=J<}xn zFc<%TsV94P)*s;IeLDTYM$^)c-7Kq&o=!Wz!0^iy8HwAA{8yf8KIdd1YWVMr^ubx{ zC7RcEuRQhSk21&4s+Ff=W=gmezu^g;StHMECgS_gH}sRqm;B7uLk1$MuO>*n^gDZW zSJ!d3`-`+Ddwvk`^Y{5{tzF`jYLghb%dJijEph z7jMeU?~d?u-Sg3Sl@W6m&-Q@0>XR>?{%SJ5x7e?sE6n=bQKJU5T zmZD8dkJ|OGF@+daVjNQuRz@W(!9qO2PcYl8@$vljXJ~g!Z+UG;pFTf&c|++;Y~@$ zcpD!cXlPuc?eW4$ZL7o~v&xEhb8K9~H!3auK83^0U;lDolWD(nZMM`Lk;DcG8}Vty z5wD(K3^=NI;X)fjJ+qbte^+Gqt!&Plj`gNpfu=2Wl_GaP8B{$ofdSA}Ax3!bI&(>Xw zBR#}m(v+(^`)Zw)&2G=WYg2IA^yrOyVMf_oton_%Nqnz1f5?BzETR65#XsvBf#fWS z)LA{%$G->Gim9nJyq7%ttHzzfPv>J|&PLnC*N-xnZ>gV}5FKrJ>P|`LTwZhSgzB4C zcfxi_{a$=L@X~H+RjpX*?FDL#DFJJi9jpX?h9ju@8Q?`@|+&9~8c>=eXs@+{?CJF+63tpAuqY z^S&2K@w{#e_-J$6lQq3w}O55Z0uhm)UqIYQEq5ecM>RuhnF9 zHl1=@&Y;Hfj;_Ar$~$~7zXUg=)onRjogc_hUv=lw)@_11*M14E`A{FRYubmOM|$OQ zGMCM+c*gSM)b0auzwHJ5->^*iIhP^rftBw0!YAo}ZMNAk-V|HAX`gP@i(Qx2v+SIH zuj_BWwBL^pA@B|gmi8{QFrkJa)+Tay83srFNt?E%s$(`TK0M@Vq;3 zcCPA?C~JIZTd@5v&!gwj4Lsjor<65q&Apftp;l4R`ZM=pTb22>Yhv4eUi94H>aBRi zetwy)nj7!B^ZV|kdb1p#&BQTvHuqu0cl+GUE}hM&*KnEeHA1q2wdzgCsq?Y2FPmTZ zoHnj*4AWUq-u&|o%ckqPChG(29IhoVe8)b)@9)Jq=XVG)#_ZpFGHV&9+|Gr9i?nO! zT+Z21$yUBabhhZ%sjP0hL?Xkt)%GCT;`^CG;^8K<$^7r>F`}4-5oT*unRo^azx9{xzu->&hWY?4{Z@Hjo5Xe_E z-S+mPnvh30p1|fy#nv1NX4t0J})MY={@#AEpz`kPPyY;tXE<467I&>+0 zLPovBI-Z-HI~A;(Bwyd;G~ar`+}-YLZ&A%1$@W=kyDFbP7Rbxjc8pcMt7LHbVAvft zzdQ!>53R{Yo0Kdz6&X6EK3g6sw0+M7@BJMP(Y@UF_ug!;|6Q@pvGL3)o8uEM82-KDacGz2tdNeVkFZ}#uyVGaJHLKM z%?-^*%la(x^3Kk0JHMt*a9;&Bub%C#`wQ|kRDyALef4}+w^M9L` z4Hnt!uIan_zC6%f?bP-;xzKeU7a!{_hI(a#cRq5(xBgGvvO;DtV|K8_Nzp}XW6rwO zyK=T4&;RmZzTJ*Vf7khQcPg*vbUof(t-i5(xqQyPEw64#e{wF+OSIVfZ_o6DCLbQO z8U6W`AtJ7>m$~xtO;vrXf-Hw)>-&yvD7L+;b3*gV8rFS3T9voYo6aiaV!rJ}Rhd(4 zYNCKo(agG%{qp{QORh+)J;rgZRM{Zjd|8(4u5>!J@bk~Oizk>Eus?3UM z|Em3Z!!qLwC9;K_KYo`x|Cs%|Mq}B_2`g4?o|~W=WjgsmMXjn^eeQ~Ve%AHZdFI^= z>(kfwurOCTFM0IV(#L;R^wj^4WvQ>yKH9W0_1krU?o!h;DmT_G$u(-?7Cqwg^Ny`( z#i!$k*$$>$*)-iP|C4A!NkV;lM|5=ehNO*__qV5t-29z9X)*Ugo?Yt%WU}KL7Wk^x z{bcH2nH{Mh@%!<0KG(Dfvuf(E9(=(g;d{JZuI~|R6wBvtGfPYFwq{fty*j24q5tS& zcCxqSv9>4q%N-AuZ;f1%b@_y99B1INo7XPxd#`ivHczfmrG4{*jbFcdaD2<`T@@Da zSMRxkMCix(_Qlh;xliZgy&%yLVwZAbiC67&uP#51tMfAWd_Ow8QDR%Q#D7k>cD=XZ zjV&jp&5mzdA!2rL_x-s?Ty%c2`t(L6-M%DYaBN=Z!LC-Oyu76^cqc1uyW{pInoA>` zN$v;t?6c|WDNLQ6S|NMtESkRi$7;4N$@G|X+9)`&c%ZJMmb;v}@Vw@#yo@!iE%OW|_21Rcl-yZSIr~VA)d_}w2V?C*rUqUUQU6`E z&vnaU))}VNR%z>Ic4U9qzl5ja=iv`uZf0|_9gMn^^YiU%?~Ps4p4rGgeqOvQX4Z;U zBa7>Sk0cHz3vOM&VRvWl3`5iNY!AybS<_XH1-45tExN{huau*sbjh|v3%3tPJw?}Y z&)v1#lBd2s)aL(ep2%-JANIbr`n_~q!A zX0K*7GQRd}t2jUDiCdkVg;kTPYkT+k`D(hWt>W&@zjs`#zTiOo{nzJT7cY9hVCm_Q zoidkL?@tL-7L`$+k+J$n_T=rE{07@xW~NPg|Ng_mO2>aq_XVXkm^77c=$MzKn09!} zbIVs(|2?VE$!B?QD|%eoJ?Oc5EZfGAyPK{28_T9UHof%;>EGLPKGEgnpIfrYJ7U++MeI_bH9jQJbA@O$>vjE^7>i(TrPJBypNa>>g#iyBdvDv44yeh zssruIs?04_)l~l##%G+mW+Oju@8#*&_oy&Gx8JhF@%TC2cDeKC?!CVwb?3{@kH4#| zizLdc%?_Ns@Y~3E=T8sL<<-}pRA#B&$hS*%?POCZO_vvW!ErF=sllSBe~;DQ7xXn* zwRp1E%Pk-7u9cf3Kk=feRq#QjPVOb0$K!KO$KQG(!q(3`_vZDpyLghLQ<%O9pLsDM zDs9!@CC3>xoBg$xUS^nC6<<9oZ@$arivO&ar)wmcKIv9n_A2nUpTX`mvKJ@K^i}p? z<~Hi`l>GCb{pNQ$CcizIuY_c67QOAw?5&qtnV@}e$?fzddZp`L>mQzIZsxHm@{QAQ38xeP!q88rL+ZZmsMB~Hi<-YM^*7un_t}RN* zQHp54Q$J%T4`U|(b!FaqTTV6Cu()~|3FGTCUHd|uUv10N*wmVk7kK~5HVxrhcXpPh z?#$Zw-STpmsNG|Jdp4kX=kFE83K8vhzE!Wt`8H8nd!HYRa8dldBu$yHse3!hL!xhq zoo!2P+IfIsQEGGK{P;6F0uJB4@4rLAaapQSk?t|8?!DedR-ZPvnl?$wcCr;;y(tyL zz3$Ys(q$L7%2ypl(=h+T9&zv}Ef{%IV~rpwGUr=A zHal3QaroPjkGc@K;y`Qr~ zl6w~`|3+Qm&x<{|ujWix^7hBequXq+rOr^A@zqZu>T;gvg?lH&S3Eei;m+181vVuo zo7pBlk?_8lrnb(zBK48&9L{$~gO8r>HTt2UvZ(WPzt2fES@zG0*Y0wioyT)Y(jfd& z{msCP9@DpeZC&B&_9msg+_L37|9I*r-AMmpA@FJ*YxG9l{imclkKFj~{NRW5Hch9l z7w(VN7&A6R3ZMDi#1XpeyV%X%Xl2|bqG3h~yMBh7y*Png{tkV4P?8iRK_t_7f*)H~E3+_13{6O4>XWNpi zGwa(G9AB#B{XBiWq3&~6s#(BNE|0%Yw@H`=DQY+E+-2NR#U@kP@bg2)2j?lPKHuI^ zn#pjgb$U;;<|_8rHyO6&nBLeF%Jz__&~w&|Q>CU%JoDI!9~Ky0ZdkMNNoe`9=}gNu z3D3$k&RXK+)^zic#iG-EmfsjwUQp_N@GGE9PKznF{!N=#-^A4!Uwh1QtMH=a5*({Hn= zwc1+MYS#dD_PsmoMneD+fasXca)eMWC;k-&8~ zzo4ln`9CHc*R9`{xV@vo-}uYTwQMpDQB9jU4{sE1TKBl~;`Rd;OA3}SDSs5Wb@{pB zO5af7e^>Pi_1O66SG{zpz{moqcY`tS10IjIWcO2 zdl;K}UoYVN5h`fiBp*EWWLssy-<{W&8!@ZOHP|?;KM zwYsfv+_iM+GXb6LGMjSpw{b;pb4^=NEZ}FAaMPbT^rKSUxp@XM#xooZp3A$Pa1TEj zIa9)=xaVD1&wJI^`M*B#)q`BjbK*;Og`aXnyGvzs$Qtd6oG-eojArg&SlGO-PSIV= z;nhih`Qw^RKWE9g>@9hF)>@r!k=Lf}>9uM*{5lducA4&Zl)l#V`xa)lgDTdF_h#&U zd!0`w@X(IRPr<81~zKC_Eu@`Ho(7h9W7KBwMkSAWl4KSTJ>g(L4D zPClN|)lv|~wD{6(v5EVRT4-XEFO)d5erv{=kN7vB(Awp;WuJ4?ag n644WKH-3g?l=$9}{8;Z=*eY;fQhpHw0|SGntDnm{r-UW|5UxgA delta 4966 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 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png index 8f79bb96c61979d90168ab162623525614ee4cc5..66b9ef2f177ed855dfc146615a964bf3238ca700 100644 GIT binary patch delta 2166 zcmcb^H(PLmBnKM<1B0A>$Hs|@>h&D9o-U3d6?3*mMd!$bOa6PdDS3VQ^>4rGzFTdK z-o8zE4O?QMho@Iz&?O6x6|0;o7brbitN(;Gj%($omX?+WjnS%FEQ?rGT(m-3w@jIG z%r|LL+l@Z`LK*9Czuuj#(%)Qc`{In+w{_`d-_Mx+Rq@`OzR$RLpXKvE+mk=0xBqjh z4`Asykof8d$j0&5akCiQ6Q($(ymtg0n*XTCEQmFbTuF;rM*p{VU&dO(2n+xItn`GP}c z{ygu#{y@6g%%AfjukM`?lFRT~w)BncDf0y;en$0|v%l)vNbfy#=6O&pvx`&ndcPTl zKPxMEEj8=TjQZP^%zv)+F(wKvnmRpc=kl!z=am_1&k9w|QrWWY>!L8JhJO96?^JzR zUmp{Dwk7nA&)J7jugp>=$$2cDSdyL>dcaunyx6fz`7aO1&0w1Uxo$(x@q~VH|MF>z ze5y{Ip0~H*!Pb9POR8#)US~gg<-^1p?)v`NW5v?%7q)DeoqoQDtKQH2F6TsPErHCn zg?rp{uP3Y*cm7>F!KKXGE$~ov!Hw3!jG0nA*O;XAaZE<)1z+{U~B_Iq%$OuFkTn%5kxI+4-wP z3VvlzUGd>rTwdP6-@gNX?fe{2e=M$P=huzO?h&d2VJXL}En8>EF+QyOopWJk#T6yF zCgIb8mp+RHnX@@g65h?`GB;i+{r()MYu~p!eofPt-o^c*=$DR5&VFZ}1xtSOE?Fnf z*0IU>f~9PY(s#KckwszC5}$UaMgN`{_kQ_3VVwuH{s%69l-go#zoqVS#VO;t)n@e* zyge!w2&>Kidv#@}?Y{fpHIB~~Pr9u6Lc5;9v*)1k+8bxq_U_-UcrmIqqjqU;#ggN% zPaT<8SIsM)x71wiFGIRti1GKO4=fnxU3>2=UCDZ==`-8;7T*&=^(WjG$^Gu0yL27f zrAYOMe>amXw># zd;f2d<+?ke2D?^7%0GJkK7Zl%NT=KeTgAr}{4LWSAJ`i&@+6Pj(92cFYDRRI`s_RT z1%VGfJboN%@pE>lgqmZB*~iQEZiU~Z9Y5%Ok}R=h=h-c=>6Uzxo@MmoZLc0>iL4D( z+V^>j{Qi9s_066fc{(e89QTzx{%z_;`z0Iacc%3Qto)R?cD14U%46sE$&@{Q+Q@LO z|71j$l!0&4eg5Nx3u2v|Ssx!?nZZ`UpYZIP;ixYUh(za(=(e z?2(z5-L%tv!Ex;cdLhmwUCYaqR|@{{?wagu{_FL7mxKtV4pZm*))EQz42lh#p4N2t zb~n+K4*iV`2&4Ty?wu4*9%KCNT z^=z$8x2KY&Eo*nUH;6wMON1Sl`*Mht~Bg-@aa4 z8&~tyv%GLx>&o)R-=DXoRW7^hwZ$kffMexu_O(ezSCw6GVm!Ms^26l(u;@h2SdY+u zN<6Gv!~R=kXKy=`d*fa6C+>w;5A9XH_H>in!JRik=V-_$NU@u4&SP?sUbmO?O#G=V zr55L;r1i?S>jf6q+N_THvC-zB&XeH8;(9TQ@2l2EM&`8%7RD{w+3I0*<(vPeS-X}j zb2m7}bV2mN+Q|(`JcR;Hs@{;*G22~2SqkBZ`C_F@3?(XfM9)%;Ee6ln}aqh z3aEY$DisUb$+h%goW^UtpFFKDX^r-^+%x32-8GuTxa8RK#S{^Y~naZK*kl2(@K3$L9sDzEb4eC$v& zW#)Nz#>B?I@(f>GET^!RPxZXmwOp>;uD^ik?gRbx^V82ie);ls#--4E`u^>gw%ucO zk@A1J?~v-rb_)r4*X~_s&WMZgeh6%BoY}T3kUjUTtKWZyMVqweonlY!d{Oc6U;T~w zc|{+5HtTCTRj3$W3O5(%Jh3lvet(?n(sOxsM|VqAM5aGmE*6!j)@5Cvc+U3qR*k+p v=ifG#H_zKAW;N$z%fbr9`+9b}{@L5Lvt4(6du2BR0|SGntDnm{r-UW|n7teW delta 1845 zcmbO&c!zI-BnJ}%1H;5v`DYUq)$7^*dAc};RLprhGd@S=sO<6dwC`p4@AvQ ztE(qtVV;kN&f|_Fg&mV+_IXk`!jTU@tfVZPrm!bpCxbQzy1E)xj)~$ zuQ%U+|4*7f3&WTF*N^CD#$;5*_FVXt-}JGbk()tc!Lci6St=gundog)zTcO)mQhh< zg7vxf{LLmmWFC~Ub>IColUZQ;dB!~U4N}g+=Y7g77&4S^>rLCNZ*%D8$!)Eyx6`uJ zvctCZU6siA?Xz7v&+LZT1{-xn{{RWb1*MyGlT7RHJijB>{p`t9DTOJogyemG+D^#b zQS|y+QR)5L!B4lVo#s%Cbjhz@UcTb?^VAz{2e&mnEtLLyZR3gE;#;n2IZOO~v;Jtj z&28OIz5Gpi8+4;ipZ0ps$7x@+>G4tfCx%X+EkCb4d5ZgSV*lgf4L(_C=j=23Ubk!4 zqOC6!e|{29=9yft{!Kgnw)_X9Uq3oNeQiEvy;+K3j$OR1na=&mQ)1>bHI%K1nmNzz z>-jq|7w=iuDuk}MYMi0tu*bmk7Qg?Ib2aN$i};J4wF#6(p@Xy_lr?>fc@7~0^defr%v;QA+SF0;n z)Rw$|`-$bJS>l>1>$>fqUiY7R*_0{p=XvJWm(B+}?x%K$t$EaIv^}^`WudE?*yXg- zH@hRNRMR<_%ycZQRN7Og7c`pbq!p&IOiVdmX0EMvn?-`T;_ci;tQu$JbI`upeLCx#DyWLxQ2Xj#TKT?_aiddZ%7i zz8o{{->2rF$KOvfpE}w6F4NU~rpKL4HP22MO!)S6=Y}i;hU>MrHau8fuQ_YG&Teg` zJzpx$OkFu|p^wZBcJ>xYXXhvpjE!+B2B&i^zU74dH;lwRdLIHe=DOWagJAb9d$ib{Hl}w zy-U$ubE9-y_Q8%c`zz^fSKqB$aM`cO;;H?ch4Uiw88)oC)HtKaT}O@6o1M+V++cC_ zIpvmR7t`IjzuSv+yiZWwvFg$S6@hjmgYx?e6pN?T^GWYWVa>ayEF$^eX}*lJdU=

5&n>o#mABeo$6A-WoU8J1(siz^`Vd9Ft$!YcyS?#TIPZ@8 zIitY%{dd&Azvl=(yJ6k4tLGZ@Rq_vPNuK)c%N?H&LOwZ>{%1_NtC#Y2uX3}sW;NU0 zt~@3D<=3WbqV-cAEu7Z7gq7Q6Q$+^<`@#$Ft(v23!!)8L_ihVX8vglJb!L|0$Dhp; ze^)ol*?Rkytz98zy4Ze|%Ark{SMItbe34o8w}8&ZgtqCokK}}2?iQV!y?hwTkO1LJT3kzd%A^@@w`*}&%fkf@%WHacqZT3|6Bss zrpjrRGYPsb&hj}HnU-tyrff;^L8EW;SQ~?n)jWQ-f3eu{mPfqZQ(oM<^YzNK&)GYF zF`YmD^^6){ylbxn7^a4?K6YxKJU!SW zYAa}=Hbw8{jSX+Abnl*D_3rp#>!gj#l;)~FKg;ku#cY}Go6C0FU+?H?kzN&>zAR+- zt=oD^Pv%rcZ@4mR-#5+nh?0z1#^witfAa5O_MDz|C*t}#KBnB0iB`$WZYwT&nip{F zbd;(bN3^r?v@?;a{b6>p3nX{@g*lwaEW5kL?Mr?3N3+66hmQp(Cax0Aj*stXGnyLF z`R18Q>xR(ZYUY{-Iy+$?pL|5;iuN~T2;*W z!0`ovQv@Zw{ioZDMm9bA7Tc;5Wx8n5GvPg{N{d&eH!r=)u<4a!11FPwlA({#sR!Tp zy+3oL^T^}f_0C@Dulgk;PNo`HdM?iP4rbAw@c(z|ikrEImT9cnw%nZ|B<78_=(RN~ zG*qNSc2!lg`|W)s|0s;PFM?xX^1_Mi?eX*9?%NZxcGmXCciFG4Fnq@x{l}Q)yU~*E zrx`3(YED@h($ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png index c48dec6982a96a55ec1f37da5d2c155b396f9aea..53af9ff38b49f4413963879ccc96d100ea07d053 100644 GIT binary patch delta 4290 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 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png index 99d44e827a57250d577e55bf8537dc924a398b4a..455803d8ba0558af5e39b372b8b66987429ecfd6 100644 GIT binary patch delta 2465 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 Bx*Y%j delta 2112 zcmX>s{8V6qBnJ}%0|RrF$fb#j>h&D#o-U3d6?5Lstj&oI7d`NP@B7pDH$L7`I%%ix zoMqnEr-?2~Dbc>Hu_84`VV}uL-Brgo5rotFICBDZt<8ioUQ51cs!o3gpW#Ql2ogAuX)3) z@72QG_}*=GjpQw%@_AE3YdoU@ik8mepQ^CN^-f~gsZ$fDwraj!`sz(l9z#K)^~qBb z0y^ z`tU2auZzwYIDeD+spfhTW%=>C7557z&msJ+|W$^O^tPx^gdS8SS)dv@#h z_2;b$57g&f+q3CKy+X^g;B)Wwp6vfNqdwO7LuBK@FE6Eym*>Cglv!MEx?_RIbo<@s z!%{jIyszIFea193F!j%)=T7JMZi=|+a#3EL>v#K>i7%{-8V^Sqy}2G|F@HwP6DbvU z_DN=rX5DN{zP|gtyXxxW-+$Ndo0-gDcGTW}^52)niN1n!TMkz}J1)Go-a&T%>vQYa zSDn8bw@L59syP-9{{NmcGhz|XgS2Bm-?skgWOka#z|gy9rS`8ouRFuowjY1w6XjU4 zT3U0>s-E}?t1o|6cTY(?bs_t`)bGc)oNIH97Vg?36}f(Y>GG+KH>J-UIkftlw8C1C z8|sD*e5{=cj~4hea!Q$PlJXY&-z}kA-*fym=gqcrQy4xR4&HTG;FyC(RZ2j0PP_Za%hmoVFWeIReP`y!=uHcrzi@(=U)?V6B~F{Y*!4o~l{Oro)->I_gitZf(%By^{YcdP%)Pu4}q(i{7ka!Q%W2 zcXxc6rTRql?3*f2aj!bxykfltc~8H&Z`&H+^ztD0)!c_Rvu-TrXT2LM{UAfzb@r=e zwpSjnt;;!C^*oumzVFhaiup)0HP*TlI|@#&75&Dq{< zzBl_OtUnv;mS-^O?j@!FF|66QL;f~2J$-v>8efx`tkrxojROV!+ZWbP&rh1VwDsb_ zFk#EX`BQfMUFKK5F6HF;e>4AAgjkx$^s&Y&o#ka% z(i@btGh$2Tjm3Ozwnq8Ob5ge6sh4t6D|gC%-uf(1SX5l$X1cobv!k-to;d!DU-#~d zp51rEdDf2J$Ap%f`5sVWcTLPBqlYUTlOi=_tVNvYLm0Lg4k3~ z)$6n;_HZ7Pb78M$3f!Olc6EVa*v^!r_n)n1=u11drr}!W{3Y`0`V&{{>%Zb({>yG= zf8Vp+ZN;a&w)+`e>RI#N?U22-?2MY-)iv|K-@c#auh``E_`Si@*%BF7=ExhaF9_Yy zv32KC30vvv|2bRri$&z8?&X+~^!#)FyJa`0p6WSX|E)8DV?)*Eu>aLH$qUY>oZGS~ zI8DbV{BN&d(3?F;&ri3$3|qsdrS~@S?Za+|A5$L|lqn?@Pud}qD(lJ3x~|J|Rprmd z(jq0sYx7!zeyD{DFF6+cOS(qe;Z?QU>eQq-X@+d&?+U(azP1OSS@W=atRZ3R)OOP`>+1)zto`23Ji1J_|D0)e^vSV z$rEe~U-!6$?G0cEICV8bH>!DZ&ElfDR=v?XoOebYnszvJs!{ZtCF>If1ayqmiUM*{ zcq=`RnH^qrywl%k=aH?IS7!8z=NE+DIPfX7c{P*5F`vh(&O1Yu>U+LyePMq+?eCR$ z@201%+o>e>YW72^j59xrp5?55dF7>2+Mfn7@g$x56;}#v7VJK8;-I?OpHGva@f++{F)fyRYnh!(=??>1*Z#Z>F}k z2u__S?4Z*0+phS|)zdrcGtPGj)c-nmFF--oZvHu=yAfAJZS}7U1v7n%dFKE5K(~>? zw|wcmPjj=?GG3#x#B9z{l5ykop?H}$$GmxpKMufKX=o*t>Ry@|GFpX z{?)j)=I62>Z{|+@{oVe|v#0;pe0Q_+S@WOOR(w|Kc7ZRK85kHCJYD@<);T3K0RXBI BF<1Zq diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png index 6f987f09c14d240e711017c78921a41d72a445ef..7a2fd0fa30acf9a4e2db999efc780ae1adf5e8e0 100644 GIT binary patch delta 5078 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 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png index 25f2b47acb36ed5f04b260c4d2344402d045d875..2e49a130da625b874a4c3c8a15cb236067a3c460 100644 GIT binary patch delta 5425 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 delta 4966 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 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png index fcf969a5deee0a4c3939d6aed25c147462b82ea2..c34ad9edd41de0b693bb598b977f3effc5962504 100644 GIT binary patch literal 8511 zcmeAS@N?(olHy`uVBq!ia0y~yVAuk}9Bd2>47O+4j2IXgBuiW)N`mv#O3D+9QW?t2 z%k?tzvWt@w3sUv+i_&Mmvyoz8PB?AaB!-d?p3W z2@0C?tTa2XrQX$(-8QH9x_e5lNaRM@P}R8i%jTSVckEtK%JlNdTZPu^UcYt9EpEE% zu}y2bcjbH*aqUuY6j1QEb3EZ)^{)HZq#G0%9=(t(Iscmd(ehbBj6C;hSpL;~zW4p# z``=66-~A+XkZbApjjH zk4;*m;mB>;DzQ?B(c;AI6MYsWHq<)|w8Zl%H@FYTE6mP3u}JV=~NvEs&G ztJel!99eEyANs>>6&T+0aI5Q@!xvf=1YBmVov*p$$YtUDg(`MOtaxHQl=(W|IsRj{ zy%u-ciskMNZ8n341t4RhlNaB3V1LGn=kAH;hgSYC)_su@%6P2%Q)K%>{ziqcDLbGv@g8-y5c7Lp`9-!j?G!T=J181Unkm`w4C3-=PW;q zXXjz-zlz(N`nH88DP2Em#S^RX)LBCNsdB%!dDHw^4^osprb~%4D2mMbH^bYJThIEJ z*>zBqH?2_I)HlEPfjYDNLW6V1tvdz66-q19YWwURyP4SDWjIGni*#Saz4D(%aOp@j06p@!NLoH&Q(? zb;04;s|7@Ua?Grns~jo|GRZb>*SY79E$%%#*_xY?aBuy`g?v_)&riI_f1Iq`p}D^J zj##2>o1WBUyEo4cy!H`H;(FtLjB(M~-=%phZ|{Y*cN}rw5j0Q!AeWuq-XOX1{byUR z&rEuMML|Vup2m)Vj<82Z0*YD9^Q?0JCa#!K&$dx&KIfcA&jgM>D?W71{(sP8p%{*; z5`W`Kdv?4$#cnvUeqyP_u8i*fDu=Q{|l2k_O0bzv-m>qjSGz{?w+^eiJh`i@XhB>8_$VP;+k^Ujw7q;sj!avixQR8BB~e{bczI=+$8+P=KhrfG z+i$IYc)D-{-(#*6=?g(>$-z@)&!!r!;!-_fR#oH~+;!U6r?aUeDLU@e#Z@8af6cOf z>7HK0An$tqampHTVac$6C4!>$cAtdI%9d&Vc7I=Tvq-kq!n{GCY2Fb7KG$=PB9=)1Jz02{dn$X4dw|5{>Bm!h1p*aH z`_upYohG=Yy4rTpqTWoNNgO$ALkog8Gr!hO>1Znbquivh;AGsys+wI7o?Q`oy7mI+ z9$Bl2QJZvJQjJ=o_sFN1UVEDGK7>*Cv(mI_0$X;Oi97Q?J(I(#=X&7YG?_cQ?ATlV zCi)6w25E^txY#89apj-aAKE?Czp?Wzy>_p-^3HEL7ol{aZYZWDrv>hnC zrufRuZu=i@!85FD!^D%;X#I9Qwf(y0j{0ulsjX+~S=t;fH(3|W+UU9R@cL%=4_*%h z-hKXbQH?J+F1;}4=km2V^|LFvs`B=#t&V%XONg^S@4RcarF^QurK5_sJ_h_N{n4^o z_FDk|l>>pVqg_^B-+6e(JzXDG+kJ}}6BVtc9e49q6s+d{ZT7@LWbNjg#@#lvxify+ zUHNog>E2h-2?gq}Cy2R7ZF2r1Q7m)b=R#JcU0c@mS$35HFW=<^1SRR6O`h$V*r;2t zE)&h~Ap2ADk@!F92@=V&mvmZE_?{U5x?AFX(C5P8>T5Ia@h`oh`iR^7Nn)*~ye;=x zCjn6p(f@MWCRGbq{}wUncfC{Q(o|$J>!aeS8Uw+SoMg*mpUR=D_AXSYQM%gX5cTUV8w*tOvC*`*(z%}Bqq{P

dvmsHJyV^ay`N(O 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%0D^hbIc3V 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 literal 7807 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 B_$UAX diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png index 16dea29f2b217371e9303ec1115c28ad41c47785..5e21545b955675706b84984135d8b817b21eef28 100644 GIT binary patch delta 3441 zcmeAc?~$G$$-&0Jz!3U&v-?Cv^?F`CPZ!6KiaBRvDsyD6%Kp3e=FP*{+po3z-rwd_ z@%5N|p=C;#%9H|ajttK5Os%b2AuB@pf4N65+@|%%d8yojuoVKKAzFdjUpu@)J%lwl z8&w2OB&u&rZvSC-{oB0aec#Uhy7BehnRBd9ChJtD*L|)wzQ5;j_5SbGhyQ2&jt`Nj zZ)R8!mb0WwVb}W`EK^gY1e_ds|EAm$VCsne=FH{yRH9LA$9$gI)#>*St-bvJtf`{H zmInE>!_s0Y!iVQ)o>w}~m*MQMXDPPPsq@jYnTz{scK8MCSt>MfYHD9iK^*7FYvr={ zPrrM4{ov|J%JS=kTx?mKXWx?f9eB&G;m~rKpAq%SJc-VK)*O~rd?zFldAq@-@W4cV zJ(Ko|+UdsfQy%?W$=q6fj_Cor$ajvQCcB^*B zl^yX*UTX5Nenn}aCf}c6Ej;_;Sy+HT&+e-8IGYN@r?z^exq5CN*Wv};Pt3tCi^>+7q zk6oFdEI;Q&%)UOz2}*cU?!{(`jp->~Gkh-oo%P^Es+b~>izgys#^M6|1`_dTVV-lt}8WfU-Q!6R}*VEOY6tc zTMyYz?GTXT%WoHY(IR8bpZY8G_P!s24K82Y1H7FAzg8OT*r~hT@3csxo!pM}WDe^v z@y5r~ay%1tGf%ehn>5A$RzEShzPaKfdwqk+%*13TjZ-ZZyPx+wS#7$|V&g{El}hpF zRA(w}(0X!kdmhi?bvkz&^{+^M3)tcyx+(kd%3a)zm(~jGl53Fqd!S^?h4Q#X9w&FT zO>0>cB6sA*Dl6yNw}RyE-lP=8w$$Iuk1V&=pv;2A?DnD!}LQY zj>@cu>Q}6JRul9@=TI=u|68>lb9afFr0Ll0wPoTu(`Pb6N#kNnr$=v{#MG~rYa(kG zJ<&NJ-1L9dUXQ)|WkdR&n|BITxD}a(+KH%i6uG>f(Yqr}_LI~6V$}xjvIEyYdUHJA zH?6qOlqo;_(vdY5y-h4<*RC?;S-dT@a_hxcUd`!8?>?ws9@l8|@%o#`iy6$PnwXb~ zD|N6wbiZ!;YF@h1hlgvA-U@g(?O37kzHiGHxWq9}y*$^Dd-1Pxk->M{ST-uuXh~cM zWs1K2cNWKCKxn|3i`J-~e%*+paH?C1PR8}i(eRN_P z-wB&+mlM*QDZ>6{+mn1xcXG_>S{<46>2IS*?Y9R!`!*Z@Uy->}$DgC-tXxIkADMtF zN83xce3_H6=0Hho>%tTFuD#3oo6Tr{GqltFzs1HMTsATX{{?&A*<#jGTK_dJ{M3hO zZ`su9GhW|{X?k{eh1(Ohy>rAi6);QBuK984S<)M8!OPDoxP2dpuRr&ooIg}C;ldRk z$;XxLwGAnft-VFv>#Rt1@h3^QiuNFIyb+Z4R#_`4azFAK;JUjO9U#VJS?%TSY zj4zh@OMY5C@O?c!RWQY@=T^kKeOdoX7V~dk&;Mxtav>>8t>3|o>HKFOUf-=P_{DO~ zrZt^64=6b%rE)x$eRgO?sH*(gEsr+7U0U(DMo4q!xyddDf}tM{J(Q5U|8T>~soNQ3 zrl;MlSJC*ogmaNv+UuDd;yXxjW(J|RAs=Ft-c7lx6^g|!LnI`Mz1hg&+ zvMJBtJ8v7%`G{d-{IvZn9zLlzUU0jHepIa7D7WX;^ZJ($)cz*g-k)TsZ56zFr=)I* z=&V+M2~BR6lU$Boi=x(E5_8C%?kcu4R&n8sH~GxIg)Q@MT;MsFpKGUjLWJ?&(Ly`s z{8*8K4>4K$o-N@_TAy(~y*p5-AY$1Jd%G<%UaLe7wNJhE|Id$AQKz4}1dB8#edp}r z)|ywRy69?JShPgF;~Kx%>v9LqX3MsP+^~u&x-}*9k(2d`N$0{Jik|z`?B^!BreMRd zrS0N;?uKH%`W%~fo#)Wv7OE*vzp?Z4O-F}`+_O9mLqVla%3Bmb+?W!#+<* zefiUTi#E^t@^|*>fOl>h7(U#UL}E1!?_S#^hDT)j zFRJ(Bi=anAxigQu%-z=TSfAmd;oZxJJcOr2)=KFJE=gUyZGOa`zfo^g@-**tWZkPv zKebGh_wz$x^WYQ{j=%>G&X@QHAMH=+FWlFt+BD_b<$yij-rIyiH zp;ck!Y6`?3yw?XPSA1 ztK;AOr|y3bn581Canh*caH87WHG_7R};c94~XZBv7sI)ZHB)52p*P+9h0b*L;hNQ}}^p z{631tf*A{njTY*)1+MMgwu|NDT=fN$4him%RPB>Aowxl?Zl~OqW9J-t<~EvqvH5Y! z_CfeNHqI?kyH2`pi2PaKx%a@u`!m$i7(3^cNL8Q-f=1WVC%Jp4Syvp*T%AnwmGn!WBTiUY3}<28^5f%^QhL- z*i^v%?a?j897(z%5lijY%s%>d^KrpxX+?e6uit&tTk&z}+WRd94Do!6OdadFR;fi4 zNW_G+{x4uTAyP6;ebdgw5bYCd9eMXoaGG4%dv=jm=fgDa`7I09gn0x<=|)S0U%I)% z$;{Ghf>c(MQF{GKn{I{NZTFu2nJn<#^&Z1~eVcT~d4>(MO{Sk-!>+|X;nmiCYo>PU zEYv99H@p7*iq4pQth2wKJbgpLdTw~#tonPMI>JA8E!rh?ZO#0OeDxJe^jmc~UG;2Q zLvqXW?k7JiHi^@ysCae1+cV&F{*5<&DfRs0x?USe!wp;2@v5sMfCR5&>n5M=?ah2avGQT32 z=JPGK+PyNZkSlu8d+U9Y`Td*wxeYiD`vxSZedC4fcNb z`mUy@sbF~VV$%LeJhQnDMYHC+vgjS}y?8l8?2^38rr(xQlT`BLbpikY delta 2924 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 Yuk8yZHmiSSU|?YIboFyt=akR{0FY3zO8@`> diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png index 3366fb560a5f633e5214ff7651f454a29926099e..2140e171ae0dfb3ce8eaca1d0055fccd35858ec4 100644 GIT binary patch literal 6677 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 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png index 81c9cb852f08e263f2a16be0a5b8cc17779446bc..a27d85480004b948c4c99e2057e96e9e41ffdbbd 100644 GIT binary patch delta 3848 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 pEw7h6{{Me|%QnGcYhPc)I$ztaD0e0s#7HFERiC diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png index efda04b713cd76d0b97f5cbd060ba894b0a48c53..8b4eb75b95eba764fae60f7c22d22c8f1c124db6 100644 GIT binary patch literal 7066 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 delta 6368 zcmbPb{={&CBnJ}%1H<$M+sh^@s@F@jdAc};RLprBTbUzsy|VuO*)#L*#1>U{D!ERa zqS0xkbNiEE=~(n^!Hrxp?pT8IqG8Z9P5n?)J^6Me7ALCRu-eR#^YL ze((3a@Bi+5|B;~~Y{Q>};k%f%6PiVpvRSlUu5pBQtPxxzV973JT5ErRBbcEtA?puY za*LqajS5~xE)E6*r^>|WLxZrWv_;9%oE!z50^ zTzR4vYcb1HLoqQ48SNQ=7#rMPPU)Opd}Z&>jwxR)1uX97&DkJy*{yeDRC>roje|RU zO77{n%v!ABZ}42C^>YL7YjYlvQ;Bo8`Y&13=(KXS@>6NowTBG??plTNa$K7m7p8mN zVxr~Lq?Vd`Ch7P#QG;VP?HX6tPM(^1O=qGM>&&L^DcOEnvMn=|*Y5kIdDkR+@`*XC z{9WSq8C_mjI%AyxE8DWjW|vb^PdT5hzA7Nzlu)~OWst_w^QNv#1S1$54<9)=flK(s zvdn^$GX>RtuaH$*`H*YZ>N<5^CZA}5VKQjvZxvpSPa->(#7FiTPD-p72p(}TA`-F#yIW&xJu zsX=v-!YhB@Z~bdl#?bKpU+}N3b%7V3sr4sa5qdE1rsSLKV#~{uTW8FjXHYMFy3K>( z`6aD?1#y4A{XZsF%c=b38SBTT>EY(rLftM*&DY$N(@`SySJ|sE+*s((o3~HG<#G!) zxED8ER5E`0Nnw)J>ow~*^*?UgQ=zhT`T6qb<+oSLoni;LxM zzxsW?Jb3x~(?9hBOulT__uKbFJeSeGwSLa}rxshpB3P$$wmf)md-u=D`8~%sm;Cci zdnM~=bkyE@Mpd5wiIaV2kL}r>Dkv)ZRF`#6C$f1-v9rh z@R_|g0_uUBQu`+s`>zN){P8-D3r_ooo+i40SD)~(AHoL9f+VfODu zo2^oI{SS_3ykIT9^!oXy-*P@#-7z;dGWdKi#CoFWOojBv3+>+bZC$7AyxBHluGdsY8LEcal` zkBPTy`}03fzjrd|!*u@Z^}m)s?rK}sc1@Ej|3anh!hf%`PwLx?tVwX#AEM-b-Yx$B z^v92%i}7bfvK|b7cYDVK*Oq|t$pJy9bv7&vt@w8E!uR;O-x3nD0$7s|U1>LW*#G|g z+I+!zJB~h2IsWC%{Fj-V>MN8OAN=TMX8-?p%Ca-@IX7Las@*TWj{LH8Yj3FGkNQ7; z|Fi!->RfHKD{*4RF+t<{&)v>1cURx>+$2D7#X@=~spbAHr_d=zb;>RVwu@$6;{ID-yy=SVjXSf&@9eG?mybQg zb=xJ2>+f6hdx=LEU3((`KJVoBtQ+yJE=n!)_FS!hu%;r#V_tgqG5gw0Ob+({oU>|; z_wTy*Qu5%p&wl^EeY)__Fsy(7zUs-d?4|D2%dF@sEM>E4-~Tt{$76dr|Bke-vocm^ zV-KzIsV_75`{(i3b0wK+tV#VIcMsk)Kd?%8=i1ea8=btl_wU}-;lg41W9R;#n}0q3 z?wWr?$t|t(pyXm3BNchsX?f*klTXV{e9jls8SiUcY49Vq`SxzE_{Yz*c(JGACGX;fnI{%Z{@KiYGT-**g^K~-7`J((Kfkg5+~!w~CBLOQ;~%{Y zU0w6%(!2-Re;-}x$U4Gmz;IP_&M!m7OYis3`t$By!Os6pNlqm%J9V_>*(-l^&by|% zepS@d$FHjFV%(D??=q$LTw3$E%P>HhsVdV+F!j}qPbb+X9X82{}%J;otv`!H~r|} z9;9`(-PGpo8o%fzfw__bYA>|=TV!tBp2a!)wnC7P2anvFhwSeo(my7x)tYHzq_Vd} z$9S*#%Kp{I_GIi?%C=IZ{)=Zx>}KJ>q|F5zY?VSIwf`Rcm@B*J^eVHaX;Md0`yaL-3T)LRU^?H*zvOCJ>KL1YA?P&aRF#njilD?Owm{45OIhp4G?y9(>!E*PMN& zP)T|A?YH+PP0f6060834@b$@$S03HVGTFW7V)}b-t2?V_>L|B&goLxIUyF(=I^*Wn zG{>uU-KqDDZ|o=6J}g*xLxuIr9p{7h#N6w@@)(O=nyVzVcy;9znbwJ?8dqe9su$_3 zto?lbiHGI`gfsWxYhXji!@d>V{{Ug7)?^CS7r|Y5V&` zyFWysTw!^JvC!d7!k*0UYP|YX1y5dBv&M4%Z$oM0)Bl-%tZsKMoqD72^oghgwnr0g zcJ}1FpHlBRF?q4Z;+DKASE3gtGdG%-|-pWp&_cj)`4t@wdfeXG}1ao*l;7*U9)yak0F1OIpaqr>aFy{yBN^Y44C) zIe<r5jgZ|bsocxUbXe(d?~n7<73vp-yWcj>mIXFy=% zjukDn=Ok4bYCfB9tT|mT{5txF{r=-GzaHZ$krz<>zos>EXGc%&`-q^EiL4A6J|eF# zEjjqQ=#1KZxe0N$#`eqVt)%7T{y)BVjH_#T@FXvTPh93!0b)uUXUo6eC?0l}T~S8z zOMgj*wM%I6n~v50E;>)xz)z_MA|y zR&vjeby}MxSfep5s`l2Oe;jl6@xPPud}j4(u7Ow2M{#+Mx{r*@w;QcVP+I%j@@w9{ zJ*<E$ESGk z#qXVaaFX-)!lurY#}Cf*3r%9bxK-}O9wBjalkhVy*IOh-)~e;KV!Me1!oAZG`k-Aa+~5B zErvVA^;)lI>$k}{GzU)MSoom8Ci?x_lx=mc3=G$WEV-)eeD;chpdykyeof7YOaauR#xo^K2eTKR6As8|0V}K;gP(sq zn)kg-tv_09#)%V|kw-apTMC^>?&IlLQu=OTZjKT|%;gB9n!=N(`6e!|-n-qnGU==G z#NcB=Lf1B@2Ued5u0L>8d+Lc7-%O2;r?sy8CbPLja^mZjRT}$(^E|ZnO3lC3lKEw) z4Xd)E>R#oj=KP+kdhWjyYz&f~p3)0{eRjjQ6DM8;_+07vqQ~z)?TW_~mnSd&&JGb{ zFZ>{uJ}`s8$3 zC*{fQVY(r`d~TbKS1!zcwKvRft?nd`51h^0zlxN<|08GOGD-LEwe{EIoL7`<2L8 zLvhz7-LoUkpE#b`q4uhMZT$VmSx@U_Y|IaNx@`Uwpu>H6YB5vZzQy;l@2=KvJ8?30 zuceq5Uy_Dpj%&vD9o=W_R-^@Rg$qA&ahtdC=z`hrxqjzpI^=#{xUF?v=_bzAkG`tA z=3hC~YQDiOV^c+{*D}Gt*Ic2$+rp!Q^j(cNRXt9b+c10c=_Es!zPrbcsr^W>x%zM3 z-TK{=EJbz2cv&up$4!>3G*aeQFKR#b@+M1J@-K(>=gGAP#p+EjtqiI%ohNx;UAY<^B-`!eVn7DRh74k%i;6&{}V!fJY9L>;KCp3 z+f2Wkgel}^$+@`h7CE^@rL?TotS8X_#`S=vS@+l`UX;xae#~Rz=Copwwq=+8mkDQH zs+VLXENbaDy)!gFqZllv}DY1uN%$n9cc~Nf@_vLNiob@)U zEL%UneYKnSONI7#_x1I!essOQdXwPFncsODAAI%wSK0J&(L&h<}$N$LYt`gh0NVPaiX}L;qR@lX5ZWnjv?y|Te_r>h`PRU>KeL^RHANjJSVvmJJ z#82Ms@`W!BzFC^CR-gJ*Onh3|?)V+&zn*sfbU9yp{^E?fQ)ym7>`F5aMua`s5dPqh zU48i8_VwSn7`HztFKi8GlDc|2G$ln>b!Db!?{ksOZ=}qgyyAYZBC(#Y%E~G3nckMg zE_y4UY~YZ;psu|B)-KlM8!zh;cfWqB{Oa=ii~WIHD#ZG{6emqxd{g>ngkIl{%14hl z+&BDu7QFb$)-={1sigYUz=vN zeYXDM)o&7Xca=_?BIBL3SZ1eo;fg6@dn`7JzQ5h|O;h>o^vV2jF}uw#Z)o(qpXS`* z(-v`MQH5NCyI%#ALI5u+Fx?fzF^}8ty&>?L{_7BzKg|m1|R1e(_`YLU7Q0`>??OC7K1>O0o z^?tdFevsdaGZ*Jrix)pv+cPu!-Wd)%mVMmfHj9;a6fJFA01vK(!lWH;)yyj zTPKUx&-DHE{s}q#yRyLEw4+VObgK0G)AKltUxsRGSWm2}Rk=AU+$N8EzQ>;18vRBY z938)xbY$EM-munrvh?Qk*@CNT4%YA4B)sy=oDJ)qXf$l~di3vxe8d-ykBeJeBxMqq zIF|nYEzlkGe(B;pE?i$Xx-|2ux-;6$vFVyA!_3qnpJH(CbzQ|SXX(|`R=rMDnN%=q z%THakXE)X!dGEI|a_@)hcU6uh)UdT2ZR8WPO=>n0%G9tFE7y3lmHETYlm8zlblx(b zRzGXfokK5^lsLH+kDIL!4h=cGAjaj>L6=>%6Kk$2ZLqe!Fm3ZQM=`d9>zx{)wxh`Fnp69bq^WP}gB9eHO$HrlP(w5VXm*k929Xo!qcTIba;gk+;7PhAi zyh_3^c^ow6tF?0bFPU{?PUkamoyVj1dR2MFr zopw^UAH*&xT5zFERc_C*CC>iGBu++a==10l-fMO}F;P!9=*e;uKh4QilHP~dCiXIx zt4NE79zA`2?XtJiHcQ{!^Si#>L%CMcY_<4xhC?%*)LA1~6yjteV((017U*esl$oQk zR~n?V_HA7WOK;c8cL!urnb%k=7W0H<${aYZCaG!ZVqV{QRHu7_$xZLcuCtQ60%k7y zb+*>0DoDbtO`DLhwv0KYETmDbHp=Rz%E%)}X-1q*+6IM}8 zn_YLDubIlTT$pgSN;5d=_sTVue}9`s{bK%DF7VO!|DuWyi}NPQx#~r$?mWQpS0aA- zzKhd8JX&g6m7a4fHAH{K>W%YGE>^nt_GR5W@3Q|bj}rPldOl8npIQBmcki$H&!)1T z&!`XBEps$iE8TSIY=uL~hZGM<#&fFKD8+Z|eJLa*_)JjjO`XoO5`V##jVf8&77MdG zgj_t!9A8YgcJzq5dP2C7EJ7m#}O~bdjF$?uzue`>Xihe=V_C@_OUm-y5@Y z@1}2WtGAoBa8J^i+$0Yv5mWy@mJ%yV#zGsl?q^f#b^EN3F1&Upw8i_{eg-i%ku`=L zf?WUZ8&E@$@M7iN7btzs>E9*%|k1-g^F&c~jFCJvjK} z8Y4$@)TIv(UfsF!<&VAa{9+w3|0V4O_g}yHk^Jr8^u>!UcY5ScW{z5(+P%BnE~G^= z*C^m-=$9%k?s*rI<@svAT;|&xG0BM`xn}zRbGi3&*%z(fV^ru+@3M_~wxX_g#2QCN zfoV54a7=N}GQ20I7?bh*@7np5VHw%m3oNUrXnp-4be?^d-Is{R?0m=j_ext{oWH|p zg=>-6lyJROI~y947u7EbIdCBD`?OPL_XPSL@9BN`U|R3P-S6^hz7($8XLNl2?1aTP z9~#`exgk0IaNnYL|5zv6-FdRZSM$`@`#cefo7^@yrSvAWo{&1oHPN&Qbp{|(8AHK; a_761+-sFV$B{MKEFnGH9xvX3?*VdZx|RDBuiW)N`mv#O3D+9QW?t2 z%k?tzvWt@w3sUv+i_&Mmvyoz8kX_;F;uumf=j~k1f;-{0$M^rw=D)kVG@`v!dz-NO z#>qE0EfqKmIV`2vgACjkF4dJ?AY0{gdnO_(1r|j|s z>#{dTrs>?=^*%ZLQr7za@BY8ov%k+{+rQPe_v-IQyU(8~>wf9gTm9AV_dWhz*Z$|r z?fIsKyb2X5U+n6*4|N^7B@%tc_PD^h7s&z{Ns2}-RPoidc zISMp(F z`M4|NK$>?abG)}We2XXglP`1suf7dtho{{UO`q3v@wIeB^hANpUv-j_rfikmX0z*q z7MDp~`qw$4%k$%f7cDw+izj-@B371FyCY{OdiTm5vwjwznA>JMYtrmTCS7}HWUPBu z$iKhqUgf0h>lYvHOcwB+x>a(UMsiwSS8?9;vKKPkmt(ED>K|%k8|Ul{oO|rt(amel zZa6NY$lq4vKc^}Dpii-AwsDT2D)Yl>lh>Tx;A-M)^YXW3wy}^>zovlGzB|Ip-#>F( zA+*2RcjHRw!0Sxe#yOP=SDLj-TeeDWA{aoPJJ@C7^H0iRMol zXI@=j>^A3NtmzCb{j}URU9YbaVp`P^vlCDAz7lyC^TYmH+KuEB1#`O@+V=fgdq*IB zqO|kxsEFvq?l)b^mkQ@xzsnZ0th4{jABLut>K}8=G@6-??EG5&b&kOEGi%RwIHu&b z>85>_4tQ#iZJc8%u&?FO4;_%-L(HF?4!<8#sPDIS8;5Y|)IV}fT;hUv>gH{g^Vfi0`Qzq-?1TvRXZLS zyP?eSiFVn>IfdcA2jb7Xm!J2>bpC^z5A(PRVmWU9n-N{erN^mUUADpOu$ZIC4n8F{ z8<85>r5iOtX~n-v;asjwc2j!cxw~h|58Vn9_$ZTYoTF);RB_>a_@P@?CE`=w{cQ1n z7&Ir1(=+1sxm!HZDcidWl=nLx*&uW+t}*9^{>(LnUuO#}>a>-K=_*dE=YI6yr&eWR?=i6T@YdV7&j^*V(y}C4WVfhDHmm2>Pfv*!!gAAH=y4_@6%o^?RM?Cif+JDy6 z316Gim3c8Q*#k)1?YmUD9ah6lbM#!Rh(T@JD zlG{!!Hag<)>H3O09hdiS7ZjW+UA)dok1Jv0ocpU}L#tT6pOpvYt}ubZ{4B>CF)I|~ z;=4YE)irmho^-g#n||>@omu>WMbdE>S;bR4nm9NoZI!>8=wMvxaz^4% zTh|1^qkH6<{Ns;oG3(E)Wn3k>JWbwn?~faA`V}PSEK{7_@Y<=yw8J9uMt887VU4?W zNncaP-mZpoS*&Ysi);zi%+Q#;(4&1tZ~iPbwXK#hUA>Fd&DuV{5?Hq72;WN=8;MtL z#XF|Ys@*bi`DcaRrTfCu_0Ape<>lCQcgm z*B-C?bNAZ!4vX_HdXGcC2<^HWIKxvmfz+R%^T;I zo{77!%)Mjn&ED->t1g5nMlVWqof^}`&iy@-fBv?P`R=<4O}DG$!hifZVJP<2csr)1G zgNdKJeyr(qvrNW2`wrxP=oAQ7_`Y<1Y@(XqUL|?q+uECc&0@`Ce19{#;db<00m*Zd zPCBK1ik-*y`r_igN3TD-UlgAo^Y7>kmJ3<&V64k!rKKfTy?n`2~?jH{NGyOkg)Y{Ut^D zoRfK4c~0@4)Dw3q+*h;jFA28u`cxD=C0o(>rCq*s-lr`JDmKh#?D$g(PL&I#atJJ% zxpUi$j^c0A)Q+&GA9eaRRes-Ifw!T5j4o|zms1WpWkGbDeH8G z_h-8FBQ(3TGy#L+|{-ciN0{k3atas-AXQ;icxMJ^orbot} zf2MubQC*WN7c`@^&`&O-_2C4A)1O@byt>VGG4gHEGgb>%t!jpQv-_Rj{$=U0+}0@n zXp#7(4=htRZqo8AO*c*J=8}>8y-SL9e_^;Fm+j8|+kMy%hH{=?m#<{^EAhittx9=Urc*a z7&nK>pe|hfYRlG3HiGkO+y$jhueUW9^kpgMwW+S-*!ugh!LzyE!eY#FC#Juw=8_Rl ze{rnp%rwzJX@9Yes%Jz5o+Ry9|GV5JzFr`0MfX4M8A5lSiz%v1+%Qe+T$gcw-YeFd z$^Wj|Mj!GKb<}G~|NdRT_PgGUi*>7#wUv!pjw)O=3@-?ov!$AK;^Fhx-=Sfm&ZjqYz@C~F!tWs;L5g+dty7v>zH3j_cNwFdwOu{ zX||Rb#VZy2Iwx)`i{i_5lAb(M z({dKH{CDd%SKtS+y^~6W!e7TLNmwLQTdiBMR zV%(2Th&6>Ugg*~oIM146$)ytwDr-tp)!U}5v*5lfaXZvMb;YbC&i*$yZ>3vxhU^gk z^v&Nvy4LFD{f$i>&NnsJdW6m~-frT&bixL=X~jYsHEWM2e`>h&f&D`I{ANkn8((&Y zUGMh3`TD${?;MqmicO7v*SRM}UEG#?`rRlHwzzBKlfPNHt;ijK)I z3Y&riHo6Ob_%ZFa#%hn$?~Xcq`H$TZy#2hR(Z=KO&9xicUFWED+;G?I_;K)VoJjR{ zzvnlPUHxO};xB*K!s8~F(z!a$_dQ2Fn>ySzSp_HW`Sg3;?Om)%jWe!uuKXnMW#;>s zug0rix6Y3fDBP5ybMB_~tre_-lbhJ(TF*yL7P?~%5S(l56*PPpZ2^WU)Z z#iZ6V>s-#fzZw2wg|FX&D|I}#UfkDXZF`~TarjM_*%Dp9%~!f_R#|QB^RPYh*H=y} z+0r#MFl%9beQ}B$d(@s4+Np7=Myeheb3;CYJgNVct7~I+=HzeI=6m;xS}ncOeS6lO zn6T>T)9dfVwY;CtsU+fkE?%s6_K!Ekb~Rs}Zx`ulhphW2(DP7U?W*>PKSI<3pwVZ3?55FDm zT8zm?o$1!@uO4lwV%-{GykL>T7Ow5jnA*RKKl;7C)lhsJzo_z|DJ}=Cb_zHCJFV^b zCjZ-$E1&c@lv-w$GflsrkmY{r{fw*H8vXP1i{cm0e%*W_s-yY^Ki{+m{rjf>`MXKV z{NojWu@6hXPm5f1R&rgv{)bP~CsiyeUZUo=zG>p?m*2QfZJo2Adj01paaQ+T!sTrd zyN%z@>v+67-KpaJKAEU{ufH*}hB{1$^?ozu$jkfNnFBlTeRA=8sXKM&<~wUY{N@*V z{AI$fhoAD+i7wkIlf?Q!dOydbb!Pgjx?igPvEu#TGhwo1e~& zDV%i8%RB$(C2{?@o<|dHD>K%enfU+xvF(PnKbIVl%wBt>MDnkHjb68~+3DS?r>;J& z`Ds6`b(N&rz8aMT*}fvB3A?rko>7F5&g^VO_L57Iy3;qt-<$5T zQ|ZdqvoG0drS?@Cb@0ocn7I0E7hl~`$veUQuKcy?m67viNN+x_7PE8DdYO(hrtONw zZ+o(s{(p^<*lt>RA#g6UwtJ+p!I5PTvz-bj#W^14+d9+l>$+L#|6atZO3dh8oS(LG z#?@PYpWV87Ifn14YW4T!b-Nn${{*cp{d~l9>f1AMRtqhTzkgS<=Cx}je~hO9sX~@8yaoPq}yGT+G(B`#TEOj+-$|;mGgBUoR`yndOJDr(U~Vxc(y(2d9$u{ z|ACz`^RjhCo8Qd0uk#n&SCf)h`O_?s>yRk>lCPUH-!EzVZzuiCI(^lGSvS4&HT(|h zCVy#jbB~{~Bqb*M&nMlV6(5sWp1UP`>n-V>_I>Jm-SeyN*O|8L?aecpR$OIq=6oLa z3DHLjcl929xqqi%;?bLDtJZD%>CM9V<;Uc9@3l{D*UirFDhOTT?Y(R35&ikklBGUu zcW3_5ecW3%ckx^^IkV|(7Z=W24JvHZt+HgZleRWZ|NP@@No3@``E`kjXLWWec^wd7 zNIbhg<(tfms~_fGR^0PGjPL!uyI)oXsdtOrZu_z0cUIw~ORa^MD<5iHKUeue>%^yj zLH;cHJx8axXvS<@qpyBO@-$x+<1*2%?fLDq_a_N?ecPOPc>1k1=2>$s9;hM!=vMQj4JM0)zE4^<`^T&QdXLuM3wGPMm6`R( zo4Sak?zI=DZJuynMEzxzqhUvdamAgui!FENPZ#a@(B5=v&n+-bHv4%zxx3?~_q(%O zmw&z*SzPHEKg)DF%df`2tbcOLdn(G}j%m0(5h{${d(-Hc(DOHOyBv?46j&}>e_Zgn zTS(38D?z`7y=$HYE$IHb{^zsrVG5g{-ILYZQ>@;;v|>|8sGiLQ#ucxtB~QA!+No)< z3#uPJWqN-rn)*@669UX0kSB<<`v_KlO`}^gnU^xU$!^=2_6n&dt7=3tY1W zr3+%W-kiLgZ%ZJ*l3$z0q@VY99=pF^NoLpD|3Qs166;K_={*nMWK|t!m_4ar_wHMk=Wh3(v9zkm z*~fe9$}wTl&D?j7zSwG7oVR7p`qb2KCLf-?3Ju+HC1F~2(>c*FgNLq5X0uGoc_Wyh z<`=I~t;e-o(fHBxdGmK?S?>Q;>Al^tO;h2%>VwbyQ$O85mUeGv-P?u#<{C78vr14q z_ws1A`<(N0cpiF$KeG8I+Tq}O_{e*CowL1WX8TU}@kn!VUR>X#Uj9p~6#Of+na^2_eJu8iVrEi@h_S|^6Q$?+bsruLXdv=Ss z?s;zG^CBdw%rf8`GFYo>r$VcN(eR?Jw@yw>YHz@)fNWfA1|hTsNbuxa#78 z5{Kj4WW0s_(k;~;Wp($k3gx@K?_bH6&MLV4f@kl~w)b~dbp0-Ww$V&E^HSuw+pALk z9J_02maW&rGx6C>EF@RN0b64+HO-{x31?%_Dxm8pbyqCK@|M7q4a?vMY9doW|CcFq|7gXmC zEGiC-oD8O2?;TuA2(U`+?7jT-IH?YylH0oIEyO_YRi&w_ZQ%^(tj=%bl#h?v_t$cr4px`;p_r zq30`jmad!{(B2(vw{U%Hr^Vgd?GN?kqQBdI`u^|NpTIvixA7P4{C=jq`^Rhb(~+|u z>a4Gk{O~>1riW8-;XA&dbeqM6oAmrVF9~MZZGCwD*W=08cy^t?JuP?hHU&qy2}N3kdw14VxQWbnXWD# zDr*#4Q~OZEF7n%k$7Oq;Rz8kg@OuAB9?^HNRi1uY(bM{-^RmmDzb;;S>%$M-wRrIM zj+Kn1=MDBh4}wG5y4uSX?0l}Do+MhhONz~K`t+*rH}y(Wyyy5iPI|Hb|Lg;gT%I{Q zy6srqSM}E6_)$$wsYAZfyZg)*-wpM?J5P67<=6QuTaT_ZUVGvB3-OZ$b%zL9awYXcX?q8~rsxi@b9GOZ}$@ggKSY?a}pE9K=~Z?YC~6@Py{`tK*sH{T4B0{~g8i zMER1ldWS{iiVowM3Xf7&PPzR4y|0$4|I5!Ev#nl0lLC^FH~&&-Yf}gf2b| z%W^z&(#dtsNj5?C!v!^JFN^L3Dz}~9$O#$|GB<1U-pI+)%i+QS9#vWNf^SEQ%o$mK zR-t}Rzb7J#y5C%Q{IuiSMQ$a(X+8go)_uCUq`6~qV$kfv{Y}e1t~*p4{d5~%2&pnw{*Va6AS#rE8#cATohl&3KC8`)M z?p!=Ui{CNx7tfKHlF*4w?CWiK_x!msX|;y8OZ%$L-=e}NO|*Di8v8}3u;KV~{{xHH zFHw}fkiL)k?tkYKTjkqhJ_~ldlPQRtc+2(qKGr=SBDGlggQ_yuifr7-bbL{tnR0HS z*3vqiDHhl7Y6nYgalNy1gQKLqElchb&5XtV&Z{a|imoPhsFpiE(DlD(&oJjt`_e^G zQ?kUDdhOVM`QnPjXFY=FJef7=U)*Fh`49V94*EQBGfc5E9T zxHU`-@LZYwh_C8z^y#mLH}@X?=%M_`ImdoOX6NNtdzN~;+5W{wcf@4fvtKw}I&Xe8 zFe5pBqg;TN!qmI`E1%?b94&V!F$!&w$?M?oyxw)%z2T$rxxHarGbRYUTbKUpp@Y?< zDSHxi%r392dd;Hh#`Au5t=(V7N1HD!->h zP58uck-I~WV?u&Z`~pGtGZH?w92tx=ZrPlsa5w(5qhU$E{x%uz8{x_{;4iuWAZ#zK!?nJXTdvp>&A ze0BH*CHq4zn;x0mKBuJi>Gv_aT_3bQnbxJ3Dn4qvV}AM;Pc+Y7mA7$@ew$WWOnp?z zvPv)Q_$-qZSDh=4|IuD^)}v!}`y11rzYecgwYf2|Y`uc|&5$|2iq$997G+mD%=41T-^pM)=wsC!W3ol1UBs_on5no9lI*d-(?O^kDHt zoV(&SJZlUv-?s9P-t?wtZI@1eUNf`3pgi&HtdS~ zGPS@qJ4v}vE7eXX!nyUe+G~WDt7HeP zx8|FC`LguG&I6HCjt1q|P0)Q($bUrh`K1zL*SXoLaxQapUZFVM;6VG@k$LwKD2aYB`_({GHl~zRoXer-`}6Qrt9(>3)Z=hc|XZc3^Zx|vDa;?*e8YFPt}PFS6&VHZF9%!j`<;> z<-2FSS4i5P`Dnubuv~j(Rlb9vHlA6ty3O-fCx>(~+E!>Y} z_E(>+SiyHIC67~hnnn2+rAN=q@2oi#P*~6x$IkKUg`S4^&%K;Xk5|dgRB*QdO{Q3W z=SopNbBiZ>jlv_1{ogV-=63i$xfWN*k;b6j&`w>S4;tsbpOoni~sK2s^_k>gHw08^)3=E#G KelF{r5}E)dve=&h literal 7088 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 diff --git a/pubspec.yaml b/pubspec.yaml index b30678f..f33538e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -87,13 +87,13 @@ dev_dependencies: json_serializable: 6.14.1 flutter_launcher_icons: - ios: true - android: true image_path: assets/icon.png + ios: true + image_path_ios: assets/mobile.png + android: true adaptive_icon_background: assets/background.png adaptive_icon_foreground: assets/foreground.png adaptive_icon_monochrome: assets/monochrome.png - remove_alpha_ios: true windows: generate: true macos: From 43d2e94d62ba1764148fb7df0dd053cace9e24f8 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 11 Aug 2026 10:39:45 -0400 Subject: [PATCH 058/176] make loadOlder properly guard --- lib/controllers/room_chat.dart | 45 +++++++++++++++++++--------------- lib/widgets/room_chat.dart | 24 +++++++++--------- 2 files changed, 38 insertions(+), 31 deletions(-) diff --git a/lib/controllers/room_chat.dart b/lib/controllers/room_chat.dart index 3e531bb..35038a0 100644 --- a/lib/controllers/room_chat.dart +++ b/lib/controllers/room_chat.dart @@ -75,12 +75,13 @@ class RoomChatController extends AsyncNotifier?> { ); Future loadOlder() async { + state = AsyncLoading(); final timelineKeys = ref .read(RoomsController.provider.select((value) => value[roomId])) ?.timeline .keys; final response = await ref - .watch(ClientController.provider.notifier) + .read(ClientController.provider.notifier) .paginate( .new( roomId: roomId, @@ -90,26 +91,30 @@ class RoomChatController extends AsyncNotifier?> { ), ); - ref - .watch(RoomsController.provider.notifier) - .update( - IMap({ - roomId: Room( - events: IMap.fromIterable( - response.events.addAll(response.relatedEvents), - keyMapper: (event) => event.rowId, - valueMapper: (event) => event, + if (response.events.isEmpty) { + state = .data(state.value); + } else { + ref + .read(RoomsController.provider.notifier) + .update( + IMap({ + roomId: Room( + events: IMap.fromIterable( + response.events.addAll(response.relatedEvents), + keyMapper: (event) => event.rowId, + valueMapper: (event) => event, + ), + hasMore: response.hasMore, + timeline: IMap.fromIterable( + response.events, + keyMapper: (event) => event.timelineRowId, + valueMapper: (event) => event.rowId, + ), ), - hasMore: response.hasMore, - timeline: IMap.fromIterable( - response.events, - keyMapper: (event) => event.timelineRowId, - valueMapper: (event) => event.rowId, - ), - ), - }), - .new(), - ); + }), + .new(), + ); + } return response.hasMore; } diff --git a/lib/widgets/room_chat.dart b/lib/widgets/room_chat.dart index fcab5fe..07cf26d 100644 --- a/lib/widgets/room_chat.dart +++ b/lib/widgets/room_chat.dart @@ -80,6 +80,7 @@ class RoomChat extends HookConsumerWidget { final controllerData = ref.watch(controllerProvider); final topEventBeforeLoad = useState(null); + final hasMore = useState(true); Future jumpToId(String eventId) async { final index = controllerData.value?.indexWhere( @@ -105,7 +106,7 @@ class RoomChat extends HookConsumerWidget { Future loadOlder() async { if (controllerData case AsyncData(:final value?)) { topEventBeforeLoad.value = value.firstOrNull?.eventId; - await notifier.loadOlder(); + hasMore.value = await notifier.loadOlder(); } } @@ -470,19 +471,20 @@ class RoomChat extends HookConsumerWidget { ScrollViewKeyboardDismissBehavior.onDrag, controller: scrollController, slivers: [ - SliverToBoxAdapter( - child: Padding( - padding: .symmetric(vertical: 36), - child: Center( - child: ElevatedButton( - onPressed: controllerData is AsyncData - ? loadOlder - : null, - child: Text("Load More"), + if (hasMore.value) + SliverToBoxAdapter( + child: Padding( + padding: .symmetric(vertical: 36), + child: Center( + child: ElevatedButton( + onPressed: controllerData is AsyncData + ? loadOlder + : null, + child: Text("Load More"), + ), ), ), ), - ), SuperSliverList.builder( listController: listController.value, From 9e24f4cb318f4ee52b267659b264fc34963b0eda Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 11 Aug 2026 18:49:23 -0400 Subject: [PATCH 059/176] add DMG builds --- .github/workflows/macos.yml | 12 ++++++++++++ README.md | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 4005dc5..dd6a4d6 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -38,3 +38,15 @@ jobs: with: name: Nexus.App path: build/macos/Build/Products/Release/Nexus.app + + - name: Create DMG + uses: L-Super/create-dmg-actions@v1 + with: + dmg_name: nexus.dmg + src_dir: Nexus.app + + - name: Upload installer artifact + uses: actions/upload-artifact@v6 + with: + name: ${{ steps.create-dmg.inputs.path }} + path: ${{ github.workspace }}/${{ steps.create-dmg.outputs.dmg_path }} diff --git a/README.md b/README.md index 368bb90..6dc4e47 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,7 @@ If you want to try out Nexus, grab one of the following artifacts from CI: - [Android APK](https://nightly.link/Henry-Hiles/nexus/workflows/android/main/APK.zip) - [Windows EXE](https://nightly.link/Henry-Hiles/nexus/workflows/windows/main/windows-installer.zip) - [Unsigned iOS IPA](https://nightly.link/Henry-Hiles/nexus/workflows/ios/main/Nexus.ipa.zip) -- [Unsigned MacOS App](https://nightly.link/Henry-Hiles/nexus/workflows/macos/main/Nexus.App.zip) +- [Unsigned MacOS DMG](https://nightly.link/Henry-Hiles/nexus/workflows/macos/main/nexus.dmg.zip) - [Windows EXE](https://nightly.link/Henry-Hiles/nexus/workflows/windows/main/windows-installer.zip) - Flatpak - [AArch64/Arm64](https://nightly.link/Henry-Hiles/nexus/workflows/flatpak/main/flatpak-aarch64.zip) From 68f4bb0c031844a02e37e394ece58d1313a901cc Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 11 Aug 2026 19:18:09 -0400 Subject: [PATCH 060/176] update macos status in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6dc4e47..9396528 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ A simple and user-friendly Matrix client made with Flutter and a Gomuks backend. - [x] Linux - [x] Windows - Currently has some bugs, due to us not having any developers on Windows. If you want to fix these, get in contact with us though the [Nexus Client Matrix room](https://matrix.to/#/#nexus:federated.nexus). - [x] Android - - [x] MacOS - Unsigned .App only + - [x] MacOS - Unsigned .dmg/.App only - [x] iOS - Unsigned .ipa only - [ ] Web (may not be possible) - [x] Login (via OAuth) From 6cbf78be6bd4be66ebf2bfe276d2ebdd5bebcc7f Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 11 Aug 2026 19:20:08 -0400 Subject: [PATCH 061/176] change step names for macos [skip ci] --- .github/workflows/macos.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index dd6a4d6..503a740 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -26,14 +26,14 @@ jobs: with: go-version-file: gomuks/go.mod - - name: Build app + - name: Build App run: | flutter pub get dart scripts/generate.dart flutter pub run build_runner build flutter build macos --release - - name: Upload installer artifact + - name: Upload App uses: actions/upload-artifact@v6 with: name: Nexus.App @@ -45,7 +45,7 @@ jobs: dmg_name: nexus.dmg src_dir: Nexus.app - - name: Upload installer artifact + - name: Upload DMG uses: actions/upload-artifact@v6 with: name: ${{ steps.create-dmg.inputs.path }} From 092fc616e6d0fd0facb3aa32e534948a127ec82b Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 11 Aug 2026 19:27:50 -0400 Subject: [PATCH 062/176] fix paths in macos CI --- .github/workflows/macos.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 503a740..c7cfd2e 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -36,17 +36,18 @@ jobs: - name: Upload App uses: actions/upload-artifact@v6 with: - name: Nexus.App + name: Nexus.app path: build/macos/Build/Products/Release/Nexus.app - name: Create DMG + id: create-dmg uses: L-Super/create-dmg-actions@v1 with: - dmg_name: nexus.dmg - src_dir: Nexus.app + dmg_name: nexus + src_dir: build/macos/Build/Products/Release/Nexus.app - name: Upload DMG uses: actions/upload-artifact@v6 with: - name: ${{ steps.create-dmg.inputs.path }} - path: ${{ github.workspace }}/${{ steps.create-dmg.outputs.dmg_path }} + name: nexus.dmg + path: "${{ steps.create-dmg.outputs.dmg_path }}" From 5c16f42d208477b4dac03d59f9e5a60baeef9375 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 11 Aug 2026 19:58:15 -0400 Subject: [PATCH 063/176] pin upload-artifact to a commit --- .github/workflows/macos.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index c7cfd2e..51e981a 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -41,7 +41,7 @@ jobs: - name: Create DMG id: create-dmg - uses: L-Super/create-dmg-actions@v1 + uses: L-Super/create-dmg-actions@28511e988b13ca34096d439159a66d468b8e724f with: dmg_name: nexus src_dir: build/macos/Build/Products/Release/Nexus.app @@ -50,4 +50,4 @@ jobs: uses: actions/upload-artifact@v6 with: name: nexus.dmg - path: "${{ steps.create-dmg.outputs.dmg_path }}" + path: ${{ steps.create-dmg.outputs.dmg_path }} From 9c488e89817bfa49294b54931453ec36a6430e7d Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 11 Aug 2026 20:08:59 -0400 Subject: [PATCH 064/176] only upload .dmgs --- .github/workflows/macos.yml | 6 ------ README.md | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 51e981a..1476116 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -33,12 +33,6 @@ jobs: flutter pub run build_runner build flutter build macos --release - - name: Upload App - uses: actions/upload-artifact@v6 - with: - name: Nexus.app - path: build/macos/Build/Products/Release/Nexus.app - - name: Create DMG id: create-dmg uses: L-Super/create-dmg-actions@28511e988b13ca34096d439159a66d468b8e724f diff --git a/README.md b/README.md index 9396528..0c18acf 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ A simple and user-friendly Matrix client made with Flutter and a Gomuks backend. - [x] Linux - [x] Windows - Currently has some bugs, due to us not having any developers on Windows. If you want to fix these, get in contact with us though the [Nexus Client Matrix room](https://matrix.to/#/#nexus:federated.nexus). - [x] Android - - [x] MacOS - Unsigned .dmg/.App only + - [x] MacOS - Unsigned .dmg only - [x] iOS - Unsigned .ipa only - [ ] Web (may not be possible) - [x] Login (via OAuth) From a9993013f5808d3bae508a0db9be89d796020aa0 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 11 Aug 2026 20:34:43 -0400 Subject: [PATCH 065/176] add rooms to mention chips Needs handling for event links, plus clickability --- lib/controllers/client.dart | 10 ++++--- lib/controllers/room_summary.dart | 18 ++++++++++++ lib/controllers/settings.dart | 6 ++-- lib/models/requests/join_room.dart | 2 +- lib/models/room_summary.dart | 23 +++++++++++++++ lib/widgets/html/mention_chip.dart | 46 ++++++++++++++++++++++-------- lib/widgets/room_chat.dart | 2 +- lib/widgets/room_menu.dart | 3 +- 8 files changed, 87 insertions(+), 23 deletions(-) create mode 100644 lib/controllers/room_summary.dart create mode 100644 lib/models/room_summary.dart diff --git a/lib/controllers/client.dart b/lib/controllers/client.dart index 33af1b5..b7d1eb4 100644 --- a/lib/controllers/client.dart +++ b/lib/controllers/client.dart @@ -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 { } } - Future joinRoom(JoinRoomRequest request) async { - final response = await _sendCommand("join_room", request.toJson()); - return response["room_id"]; - } + Future joinRoom(JoinRoomRequest request) async => + (await _sendCommand("join_room", request.toJson()))["room_id"]; + + Future getRoomSummary(JoinRoomRequest request) async => + .fromJson(await _sendCommand("get_room_summary", request.toJson())); Future leaveRoom(Room room) async { if (room.metadata == null) return; diff --git a/lib/controllers/room_summary.dart b/lib/controllers/room_summary.dart new file mode 100644 index 0000000..d47d8ef --- /dev/null +++ b/lib/controllers/room_summary.dart @@ -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 { + final JoinRoomRequest request; + RoomSummaryController(this.request); + + @override + Future build() => + ref.watch(ClientController.provider.notifier).getRoomSummary(request); + + static final provider = AsyncNotifierProvider.family + .autoDispose( + RoomSummaryController.new, + ); +} diff --git a/lib/controllers/settings.dart b/lib/controllers/settings.dart index 572d2e9..8c107e3 100644 --- a/lib/controllers/settings.dart +++ b/lib/controllers/settings.dart @@ -9,14 +9,14 @@ class SettingsController extends AsyncNotifier { 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 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())); } diff --git a/lib/models/requests/join_room.dart b/lib/models/requests/join_room.dart index 8487298..72cce7f 100644 --- a/lib/models/requests/join_room.dart +++ b/lib/models/requests/join_room.dart @@ -7,7 +7,7 @@ part "join_room.g.dart"; abstract class JoinRoomRequest with _$JoinRoomRequest { const factory JoinRoomRequest({ required String roomIdOrAlias, - required IList via, + @Default(IList.empty()) IList via, }) = _JoinRoomRequest; factory JoinRoomRequest.fromJson(Map json) => diff --git a/lib/models/room_summary.dart b/lib/models/room_summary.dart new file mode 100644 index 0000000..d0ee96b --- /dev/null +++ b/lib/models/room_summary.dart @@ -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 json) => + _$RoomSummaryFromJson(json); +} diff --git a/lib/widgets/html/mention_chip.dart b/lib/widgets/html/mention_chip.dart index f6105e3..57e23b4 100644 --- a/lib/widgets/html/mention_chip.dart +++ b/lib/widgets/html/mention_chip.dart @@ -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, diff --git a/lib/widgets/room_chat.dart b/lib/widgets/room_chat.dart index 07cf26d..01908a8 100644 --- a/lib/widgets/room_chat.dart +++ b/lib/widgets/room_chat.dart @@ -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", ), ); }, diff --git a/lib/widgets/room_menu.dart b/lib/widgets/room_menu.dart index 95936df..e99991f 100644 --- a/lib/widgets/room_menu.dart +++ b/lib/widgets/room_menu.dart @@ -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", ), ); }, From 2d7b067c93acf30d99301aa2978ccacc88e81cc9 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 11 Aug 2026 20:39:04 -0400 Subject: [PATCH 066/176] use mobile icon for macOS this looks better in the macos launcher squircles --- .../AppIcon.appiconset/app_icon_1024.png | Bin 84720 -> 79746 bytes .../AppIcon.appiconset/app_icon_128.png | Bin 6314 -> 5684 bytes .../AppIcon.appiconset/app_icon_16.png | Bin 700 -> 678 bytes .../AppIcon.appiconset/app_icon_256.png | Bin 13425 -> 11971 bytes .../AppIcon.appiconset/app_icon_32.png | Bin 1391 -> 1382 bytes .../AppIcon.appiconset/app_icon_512.png | Bin 28715 -> 26320 bytes .../AppIcon.appiconset/app_icon_64.png | Bin 3005 -> 2791 bytes pubspec.yaml | 1 + 8 files changed, 1 insertion(+) diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png index d4a31c5cc5625b5da69336ca183c2e1e640279b0..1682af0dda5f890ea3a58a0fc1c76f0a4290cfcf 100644 GIT binary patch literal 79746 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

y1?+7S4)s`M{4L~M`zbDP1+_|Z<2lQ0HnU9G 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 JS?83{1OTk2bmpRy zWlo0YWWJ@mlh2u``UWrayq$Szn#qJqKC`E_@c1aq^l_TpW+K4HtjKn{K{jWD&d*7? zo~x6~x9-06S@!?A|1UT6P5tujKiB7(Hz#hXdjB`9>i&28`uqRm>;G(jUFR~PeL|9? zd){7|E`=X*(QBj}zg&7=)9-y#(!S-kd;Pm;n~U2$#3Xm_nR@apJBQKS-x5byPkqtJ z>)P`w`^+AZhM@4agv(xP8(WVFdx-QKbk_d95hs$t8K3-YDFfU34Cd~t&gmjcqVA;$ zNM-~cD=015|Gx0EAH&J5TRZAQrWtkmM)5mNoTQ_aT>e9};6hFRoOq@QtY6}99a7m6 zVAJPvI8klmdY`WgZEqe{DU0J&sQDoW=hJqZ4}H+zGJ3iSpT@22Q8 z@V(f-sMj+i?wr!iFM5-2%)J?y)3x`o$~FsyCi&R{w#AG+@jJLSZc0+y==s}m#iIZI z3hoWNo%I`&4R0;%ny_o}W&2H{4h}B=kNW!5J9Vc99(mnw(79K)k|+C8j?~;wg}gCp z#(#~28GGWcwQNx_>|9$?=GgwO`i|40huaJm=fwxL6%>_Rt3JcBAXH58#?CI!oQ>~v z7ClX$d1RmJF8QTdEuJ|$t$F?C+g>~9!{8i!Yr#da1?NBP=_{$8{=QIiYZlY(%Dk}Kt-Rh@A@V=7u-ql~$CmX^_cK)R z{he<7>YM122{~3LRKB(O2#ELoZ}ZIg$ir?ouX@(aa>gTO>)iJ2xbS`h+mgo&CiniU zPf%ys?X3S(Zu%ijr6r5Gr&sLbY7p^yasR@L^b?s!x&)H6>u;Xfk?UWw*zWMMi<)1v z9!zO+l_s9lW(2)7WMn*=M?o|7g^m{|8tm^eti7^dq7@pGo4*CAPV)+x#*Ox@sF+1tkxi_>*_PKBh*{Vbxl;hp&q4oz5=W)Zu>lmf@9IRG4443ph>@jK*J|%F-Z2p704{aZGzWNlO$`spB zqmuS2;61Ctrx*9{ysDJ&+IS|hwz;QUDy8I#S45ywzQNqIxa}`08T;HBgz8VVD4AS% z%)Gf?KIrieg=(qyOZ^`?{9-xg>+>+rYyMGIPP1a(AbG~=9y6`36*Kn4Ug>agJaA;< zH-XB8;9!REt)dCBds!xy@1M0&%zI;KO#fQf*9!$@+l^~0lz-aY^ZMp+@Q-?o3QPIM zSKm@yI`$?n>;E3YQ02+M{5rh4=xtZMlic<7+DEpXW17P9=d_BDg`Bwf7K!!#VM{)E zJ+ig2|HpUe*3OCBWFNP0P&y5YqKpS2N56cW$CdD;D@tmX>hmY254y7k>Zn=8f43Ssd1f|Lv+?_8{5li1FcR=RW!{c-2a_NoB|E zuAisFU~MKMxxV4Vw`1p9&D89}iZr*0<~sa8!5?@)>EdCJ&t86C{_8xL$-uTQqx|jt zg2cTo)$6rfeKon)FQ{bN({k-r^@8dD%{J|w-)y(-`1Tt~0W9*{=G}hL$sipe)eb| z15dgC=EtY6OyjJ0u*=9K#K1p#3;S`$RsT&|Hm#mu`N?y_6~psRp6aFrn$xOsJ|#JcV8-z_x% z-*@($bYCU!amT!$n?9~h78Izvb@wq#Im?3!cb&Uye?6HmUoc_zex4Qef$mouZ|FDl zKRfq%bBXNn@CEPYedX<#Dt6Oqy4jD6x&IS&zKOSd6S%dX&Gs_CZBp{NhF#Ttv*h2$ z^E_wL5GeenRQ*ow*44#p|MCYnpV!&qE3o6iZ4dc7c{{r;9=Ul<^@+zy zC376I{<>=%moq8dQ_Qw|EpfFW4m9f*4uG+``dnnzwfScpO+S3yd?O1?Z2Hj zgzFm;?%ypw+_q@X{Hw`~@i%xfzs`5I{Ht$SuRrft(>po!8$t}F-+RO(^$%qlvClpK zzvE8FYI|H3Y$_Hdvfwz!?wh=TwY$E%|5&B{$hQ%`VVKK3pFflgmO)l_HA6v)*G55 zwrWOq#P{}q^EI+5M$0Gk>%Vw67-|vMw&PWu#`1snPQ07syQ6wef+s_XV7m1?xmhrcDM94xCXxK3}gXv*bT4eM9l zHr}})?pSFy_r~Wh9%V+}{~5{?ZOwHt@_5?HTQduSM31bx-@N7c-8+pjGlUzCEdFow zyW1lE=CQI1&%L*YJpB7#>R3ckU7(kDZIo$X^GRj>V;|1$UOjX9?BMz(2i88AbpMl0 zpC+S=-nRGe7MAJGx_WxjDJ91E8-b1bcDpNHg}mR;l)md&FHg#~g0t6|T0M;3?{2G{j0vBUw)OAoc=7tFvgInKBE8xF*kd_ku0|zPaL-ga;qY9&;eO5i z%Ld+D35V_`@Bg>#^WUF`;@@fxnPXKTbBPY}>+CkZ5~YXw4>0jcDE@d!pkr92r%vT}@tdCvs9+aB1DS z@Ac=`aH-|lFe(arn@{#M&1iYBaeDHPW3g8?CP;*_uGULcXlQ8o=RIe4^(WJZ$$6m$ zp{E43Smp>HdN8AH`8}EA^K+6TM6cws?5clu^J($Dg%?zPJx-o`oj2?A^z~=faJ@LI z794u;%zH+g`iezbJ1R^UuUfF{?&Z_xg&V>GJ03)p*MEDrQt#yZn*A$RDa^X`{LY_~ zT8#oPS`OF0>3n$6dUe2&B$LgTDn0iIuzadv^m%jlvESVAxEc4EW<-ikkbKKvRexY| zalHE@seQZ4?|3AAoqNgZyx!b*`7?DJe3Dh$UayMbK9Ke2K38z)!PR$Ho(xKG;;>SD z(7RsPx@OO%xyPnWt7kAXuikzy(64LHO>fU|?+I4hirN@X6O?rXffVb_j;>^+}gs!baL`shcJ8fh97NgN4)O%UKjej zpTS^3DC5>;wjbSUe!ZN(>*eM6Qoe;PZQ}R*e`Y5O-_5UCwQ}l-Z=#a*YZ;swmN>Zl zcjN!|E>e#5fJyMtzag9sY13F{*rsoYS$Ox3OZn?34aZaT6}Ft5w>w?)#g1L4yIU%q zR2DvL&sSH=|KW1F{@G>zxy;9fL&Q1Tx^ISulovB@UMQBa_<3H}icoRo8+qsNZWhUG zbvV_$^Xt-zAFVIGuv`q$H28a|m$m*suVKx%@>74-{@0BBzK5ZOWrB^>@3?M9{_pQR zQ%e5-PZX5+9!2IqC%ya05S$+6_$-3^$VI8w@8mXL zV4Sw=kH_ZIoVvf{>+1HMtxDVLe{{pHm?O2(l0A$8kKR3D$?~$ibUZwu^L*9)%Ljj5 zEUcH!-plh~!c5oyK3`5=RQUDf@~uzn^H(I8D~c4RH=n%nkxFHf z8U5va>LL+^9qHbhdND@}yezJ~{vmX#!gf=7QF#13t_Afy2cv$fMXY!+pHr8`DqHoB z;Oiw59w@pm7v}Jgi?vvIJ(%%J>!)A_ZqdKS6I~yit~U?g^!_N1OhHLi+78yJiii6T z1~a-$vO2`c8(KL{0+ai!8Nc^6ri*q*;(Ar(>( z8ePY6z~`d>%_}O&*F`HgWZgV@U1sjQciHTo`gUb6cQWvOPw%~J^NG>ewZ5?7@btWO zEc5xfBfi+={|>3wjc)yNva9m$zMU0%4bFcfGprKd@ft*bvH$V0=*slxj#{&)m8vwP z_}@Mf@kglQ-*mN2EO#eLTr<95n!~l()joE6#`9w~8oxA;$1w$c+cxw3F{y<-vtIA2 z(ql+;6kGw>_*{$+J@dHRT6+S&>i&a`?{8Z5`h8H_eYRfz!NZjd7JYd) zck#!*lz0@ywY2H~Y&Uu7Fdxys{C6V~pRhh*Jt^?v-{x(8zWm#qwr`l#vz+O{^)E`X z5@uD3)sx;!O6&aWow@Az`?#Q#h{K=T)*WXwP5x;TtL?U{eCg8KW*cD!{q%`Bb?LvJ z#~-!x2!+9`=4Iy5#9T-`v2W)D^~`~ zD$KOGY0|Ytwnb}R^gokD{g1C6QA{q^-T!lQ_UWGMn-czSZ~W2l^zxMwUZdq+pOUW| zY&7Yr`1>a}cz*Bx%$&7u<=208$fO7#n796xm1*Uct9Pm_ia)q8oVum=;?AG2au@02 z_2-Z6E~vhFHLfN0-=2RP)-Jb~&TO;Fc^|e*k746CokdT%XG{J!-^YKu>ss>C7qLpG zHmTGwRs7AK=D+yeyeEOb{q(|F4}7$`Bpcf;H(6CnuK$lv{pLq~{nxnXHL1z}IsdmI zskZ*$mz!ZPzLjk^F9>Hid-nv(w0A9Xr{*~AmpYVHpV>P5;dK4q|B92IoLAZv)pcd# zEY;(`#Sfb@erPla%06>8mfeE$>!ND0EvddA3_cVWSF@f`tz5)xIo*D1LpGCw?0YBC zGfy{cKUsRr?9FrAml_}T-d+)U{L{*;O=36go;QcD<8WBRp&WKQ`PUD=o3g)uZfeW> z_Tz8twxWML<@|5!zwK<`W?Jz0Z*1H0dpdJJX+2MzZoK8<_si#R%zJmXEox!!uHYss zv4$P1_%B{^6n3At_;HOG!``3g>lttS-*NUb_k=g=w%a_~F3`tvfLkgk_qXocVD+#? zJ{JDwy)$FU0i>@FfMpqzdtwLDOhWQ zUEtdlx6Q?GGYN1__E=MS{!``i)Q|qrzwK}E%KU9zd|IV{>+_QD76-R6Y&o}mVd1sU z|E$k%mt%PQ-2U(H11o;U1?f%sp{0?2*L?Xcp@s<4rWak0w=tP{JiETqmo8^v_B^GwUGpYncDV>kEG z(zP}9(!$m|XB2$Dvg_L0+1;v)A0{=0oW9-1#J3{R#^leGr=O)ZEnZ>!(cfeKFRmlU z_P0cQXMa$^#%=bbX<6akzp@GE!y9IN{rTsp$JbJwm+uOjR2e5+a}HRtBwaqu@EzZN z9==%{=StlT_qYAL{@A;yq`P~M$yxg>xVhV;HT!+?y89LNUDH;&J#*Q)`tH7+GsGGK zWZV}$+>kDxVz|z0u2Xc;w;7fv`5Z03@(1|Y^DL}VKQeXqf$$jSbFWK`U)@+(`upJW z#>4j8rtZz2=8`YHmf2>v-5L&u=-u*C&;K{^GcJ1k?SfLTrY&#olgP)c8=0J*em&N` z{sx!bgP`e?ca^LR-2Arp z&2xU+JUiBp2Yx@;9bcYuaT{}E%E`NrTU1#O6j~X{e%oE^x8hpR4Z)vN-`0PAsdgr+ zLV#m`!q1pGAEx`JIo8{RFEQ(0Nd9*uDu|&bnBS=No_OWX9onDRRBUq}c}!QddBT6g zq)h#e?bdl_f6_LsV5qQcPWilhU(JM_YtHs11<&!#DQsZ3e|C?lH_T)18Zav`gOc?KRn1*?oRRz0#6A?ss11&dXQqUVdY<Gwg{0?M4d1qpA_y0ydr<5hTZu(3< zFU(Ny``K%IwD;$tZY$Hqx5?ErkBB)LwJflH{VD2b!S@ZB#m_VtXZ6o0`d)Ex-HB|0 zj{jfvI~ZOvo0U5RpPpd#?#$iCEs;zQxPv^_TAp~)oO6Pu@ZyfIBF5$d{>(KtiH|(K zd+vPjuJDi!qr^M8xQ~CGKeRk}cl6kA+m>J#58E6sn|js2_8j@!rXtH(6~bBsqF>ge zW?AR>mn_zMeD~juZpE)z4@AW7+SOfjo%1&-h=Jwi)@yfc^8y!X?@;~I^}bN^&kmlA z=j+NQ3vXJid%@|=--&GuN7{lrrm@VdX}G;8f1yWlLcw-!MwMMPG9UN|}E+ZAE0Kxx>r!9sdLPW~}M{*ZJ}L2Bp*WX*WV&T|BVzUw^5O z&Z9R6zwP1s7|S49#b(|%_iam}xSg7_&0)2(+QwIya&`W{$=%2OpzlN+O9|V{u$I|A zpFh>FalYPVQ~KTFU^wFzO~Dw+WaG;kY_1<38ce>SxvRYYsOy}+hwK>zn(ivTdY5>C w=~~9D>HeA9iUW+bCs@8*yIbNo=YRfcKUvL;3macEFfcH9y85}Sb4q9e0AHIF;{X5v delta 6298 zcmdm@v&wLSN4nP*s!fWQ+TH#9|NXD4q1*4R{{Cuj{V%QOGR8CZ1$4(Y zN{WaZv&?ulL-BygaURA^El;bw88-18c*!tLXu-6?dusxMTsbdlG74Td_mlrbZ+rcBiomA{%P!bXu6-}b#L#gwPCNO}YsJ`|o(o+x(_%%u4snIr)gQIk zfA`ys$s#Get0s6VAKIeka41!@@cQoMKH={}G%p(e@H*(g8CcRTr*6xkbUA&-@v@JSGJEIaC(8c-^J^r%~rT{Tp^X{+k>T{?4-VR~^ft z`URR5CqC9kOkH-Nx=8c!5;ccIAK!6jc=_=fhbnZe)qJAecYFdjr(YD)jBVd{Hn{DN zdQ&CBrKK9bF;?tsnCzS>EE{6q?`m+9w~;*hFG6AxOT~q+6}wkWh)@5ucXA)Yw$tYV zG-{iCmfw?a`*C*4Cv}-)uGbIec->I^PrCo()0sQ^ z{I!@2+T2T~`gyAN`)Eu#Q*QIEgXz=9&ULn#90}ELvV0ZI#dpgsWtuu^c5MG&x6l{) z$M>!)2%Tk9(G#xGVq?U6_1_GETt`m1#5wyNPTpAcAVu*&c?5-(H);p25}0^O z?r}E59iv-6HGLVvd+NOMbdK%a|F=eeUQMb1pY_K(e{O2++gxQPwc4wBx|XQ-iJD%o zlbk^bUcwECSU*2Bm8E-d|I*b<2 zSBJKW>6BQ@dcP`J6D4zC*R~%!uK)ee&%7fck)b=QTRz{5lXG`ZEWcCTjJldvLJU7# z4B!9Xx_Z@yulILdNS|lHDG(GN$`Qg<|L62)<{$5Rub$lR&5)#I@s;y|QQZ2VqBz6X z0-Rbu9;HtG@hSLX;riP*pFTKwJ?Y1hovEy=Z$|`h2zIJ}+%#4v?jaC_JkVLrX2N6k& zTh%dt-dvT)v)=z=)q@$^CVMsPeQh08w(rWvjm@)nhx5vr`7Ap<`OA4kZamk^XTx&~04X%8YnKM~YiD&b{$1?o? z>lp6u+$UAHcEzd(J`6=1AC9}5-QDxieD{8Shb~_|Hvi*YKb<0btxjgI(D7xGS;NdarZJVKhN3|Ga2-4H@!@|Irsg_ zD=%a2S*=?eBB`_MtGQm#ss;Av`d$cR{Nxkh+q1#8u{f&6Vz;Hbvu3(L{RBZ{t!$<@vGp4&KLiwQ(-)OZKVQDX>926? z@~HLc*4lP_S`In-T!Xv zjA~msy)PoS^`iZHE9Fk3&_{NyT06e25vcpJ{NTik^Iv_LSnhTqxuPO3+om#ip~IzT zxsmn44-PDQ_x<#m9tjclaJ_~%KV4QTsJ;spQuvz0;~}-{PsH}Z#tGJpZ2U95pPv2Q zIPYkwo08C}8ye4y&h~k_tbh10T)O8WpZu(!%lrQ=QF|tH)sc1jTq%u=yO(Yo{Pt9E zbhA!PWAYDw>zrNSTkd;8J;NF}?pN5?HXGHUr^cIq^2p2d~TsPcO9v4%xI zLxn{fe@s;U8u`EK`r`}UH$)X&{xhHdHn*VW2-5)p$!B3Je!S-9de3|yz@c}x&~8`d z0|!Mv#|BK=`pJ7oJ2U;{Mn_yv2|Y5&-%agw08G4g(pU7%XxM#5=dCEP)jU( z#i^4MQzCdmRcHOF-Sfg;&N-;z@v`Dm8@BAL@IKUc++C@e+mFGoqrBj0&8*iU>+Ihx zG*sFj_cKZ7;(R_u7O|@tJGP#1RGfCaZ;74w9EQ8z(muOwCKPkabXL|EX{&H1cm6AR zq4nXbwsKPN@}{fVCI-j&m)nU?VOSTxnSZ{W{`$=IALj7B?@(QzRGFl7asDA$@$dzu zWrfVnuD2T#;$OXQ5?b)t_N>_Dt9zcruRnN{FJT486gEa9!M{xDrY|G*ZqlgKIj-=o z;sVFrnZI@?uo$d9lva|Md++l0clC~H-@d!ME-(?&Hx~Sx#QHfq+|8xT@8By_F`nDb z4#C@&{L>R*tT=w^Cy$VjB|m?`5gqfFak}3=IWAlD{~dqmf_002EX-MScG9KG>vMf% zwLRAUnw5UEXBL-caQwzST5fYDFs1H$WSX^X(f>zB>tZ&p`LRged3HLN|Eqlq*2(zD z*3bSTmcmtPbuMpe)%?GKZNI#huV6Xh@+G`gV_%JH>PekM{)lw~|Mi#3&;BCz#;SDP z)0RI$i`&aqTK5JEbvx^Q7FYdW7e0OR#25RYAD()0M?+A<@f|lzWv?>+z4_(wWG@Em z716P$rIzm6b7vLv#+Oot3}#BjX}##SJ|vjh{@3dv z$A!wU)n`LpXWi~@uKczrT(jNv+b8CLq|XN0OT=r+baN^vKKlA(wPD1&jSpp-WS;AO zc)VF&r?*$JLGgQW{vE-GCE2yBF3qmXyTp-jM$i0Ll-v1tCq?rfTdVQ&s&H;?eeW{) zdWYQMV{eo^8vW~IW9HTPvVJ)pyOF8mrs7}wK6`Ub76C^C_VBJZavq~>|8?c#bM;n+z1&$zA0tzP!foDM zGuO@d<}p*xCg;)ZjZJeKotrsLLZ} zpGW2;{CP7kCsDU*YU7-U>k>XWj?#XQmnW3>H!d|zb^XpajjQGQ`eFmdhbuW=o_g#U zEBp23lOWE7*1w(amhuLrr@VVpUu!64X`;69Uyu1l7VeAU&ri1YEr_d`o~`L{=2!AG z^(MWZNX5UilVjDlZnX;AmNw)&XZcIyI&vL$9{Zw92cX@v*1f_CQEEQUvjx<*0z)C8)7zo;IgxR^E=vi;p1OxmI^FLFWj3Lnl|t5WX?CN(m5;gj-_sUWondf|5U*$ zKEk=#xk_Hqw|0xwiuH3}R96Zg@J;(};`#M^_0#&;w(#B7+WL>2_AZ&vWdBmY_@CTm zzbHqpqqmE-naa~Y?cKv!@ZyZx>Cc%$?)J~WEehZKN$J`u!719RQrdPWJ!VxibCyV! zdHw%(J(SIU)ykAdPfyiwPFTS+%hvnV(p?Yc+`4NRR;Z%wq&sWb;`ow(|Mp!u;V)P8 z`t+aG%66sCTk7NG+~Qa)b|^_cQ$0KBLDypoZnKoPu5~1-Hn%r=XK4+nu!f% z$Jcz=`1-G~;`4K_^VjqpeWhG5~8Q*q) zRyufmldiTplY!TrKGC&7k2lS%H+X2WckX2I!gbRskL{AMoZHsjR=>gO>78RvPs*jk zg5E4oJ^6Xnf^V&r6CXJ5oHA3Gu}>$r<96!K^zS`v)ep1zG)|xFp0PpFDLH3*+D^G$ zNoIWCj$gc%oS3U_kWsv5&BYHVjkOHbL!=%)6;^y$bwk{Aa$&8@AL(m9uR6ZH>^t!R zf03?vHj{u3xnDZF zliS`dvR3@`=*yEEH!saS5FY>LKq&XAj|+c_UbuS6!^Bd~DXEl4Wm4Ka4?SPusK3S9 zHRe~Qu>Lcj|7o+D!}Cwm_H3@cbnxIzgWn!-mo)S;bw$hy7T)U_4~)09~b_q zKi{We_U8T3rQFI97b7Bt_$v<;D7ar=(8|pGF~zoZm(^X#U4fZ3E|A7dluirPZ}?h zAt=zFaCUpwVLt6kW^X*Vi*@}C^G;n2 z_j8xFk3Z(-tH);pnZIl01qjPshpy(&t z3o(Kf7nW-Vxz$>AxiN^n>E7LYdx?+Q_X*`2-D}0)`{u~*`Fp}xvVOJj+=v}l{xi>6 zZQnZmZS+UJ-LG0~H|X@Mb}EQPm9#E8vwo4$f`xaMD=k^=8Tv3h(&`Y>ERe+^H~=0odycg~xy-{r3`#|14B~$}87Bi~fshKk}8aF_JswVSaD9 zT~qN-{tf)AH|STjUN(Jg!+Yw0kKLualf)bZq|YzOl)?PIA*0u97QpJZG6gnALCVtTiaJonA@Kua3J$e)~5#zA)E6{zpzF>pSQ>8s9n|VN1l^@ z&8ge+=KuO9-U@PSoa?{7lvoqPw0I5c#{y-cM$7tw8o?b=96ebl&q%aJ2JE#c(dMe( zBfT$U`r4e{*9ZT;SK5)U|0Sb;%d2P2O+pRXg||IVznj?T`myY>&Su{%u35XTcLh)G z^;*$zb7sxeclCO!jo8igH_lo2>XE(64-1hg4B!5k>#peAGx3z=Zo^$+FN7-VV!ChM zdbcBFlGVkc!}TvuIGf3_BT&PtW7d{>U`iCB?xxr5t@q5RxE ziPbhbrAy*&Zoj9Oe3QMuhm&vJUg30?N0$R;EWYvaZc(^jYVsw{`U5Lp-{6j)UNv7z zUF!dX18ggKSC`x}Tx$N=;ERvI{mU7}>bu{5;O_NQZ!pg9KKi%qirbEb>1$UvoaA=< zx?^#!`Oy~YIw{T9*_-6QMX0C3Kr`608vlw~|1FZJlZ{<(_ zF3?%c(rSBo->UbiE3Kxw#X7$&SyCk^{I*ohxR`rJ>Yfk$6HeP{T>1Lo^6~fK+w9Yjl6T#HsRWrWB04dj3$^e{z_(35=}mzKj+zY zoptI<{2KCl)}@9#t2z3x@1EFnub^^;lqmM>PxVSK8^V7qUzl=th3!U(>_^2fG9pcN z3?>vj%bmJv`FW#TN!~(lC!O85!!>7Rn!Ne#s3VIliqtgO-Pea#2u>(%jeW-Z?MQD| z-!wjF-|m`Be*VSU(4#cZZC zYx(w+9(b`|p*xxY%SU9Xn5lR4=0mHVC6EzbAc!sJTN$m&+E zmGAglvr9yL;m)u5Cs&0pJ28tv`+4}f>ZIrmv+~v-tijCjwe?v{q6Sd zet$3Sl|cLj$GIyH&fR_X!9%;1#;>v$>))!=Gp#ssdAsUayGrRu)e`M}>lO7U%@S15 zo2QZ6c)jMqqxq*-MS~n9uE)3CG`zj8oMFc%^)m-nbF9v)b$;cM>nme&&UD);-p^In zjWTn-7_5&;e3!HBV9{;9`SrpFR zJj^(@K%O_!Dr(aCs;@2W>>uVV)=xX!`^$HEejdjv?RgnP*nex;~>~q|Ec2B z#7~{qs`pR3xXf?U#NgNamMiXfJS}+j`#&!QAODW|+QG#B^c$l_AAeyKV>mD4Dn6&F z3*DEdH*P*N*KKjB1&`KwpYYqc?K@(kmheAsnZ0{frCOZJ!+T#j61tDaWXP1waOMnp zajT$0gnj+qUv1}Grs-Z~o8^^>b zk!5QSlo_coKL7J=-tlH@#q+ACY|rgUf7@{8tiz1eAO7BEQx6GT<+b4Vk?upwg-OFzAZcdQelbB<*VC_^!4=Wr&t78s&Bh<)$|<4 z<8`w_WjiZMlnew`th^tz_tBfutKu>X$w=MSl2=q1ve%^@m(J$DRAH2 zF?okkVe*ZcGj^0d?bE1lkYAA4$SoWxCA2tcio*dmPLZ8cwk(UewR1}`Pw<>f;m6x8 zPELOR``+hy-#ez8$9cb6b>X_-w^yvw*M3Pqb7j)$$-g)EOu3e&Q15s}KipJ)_u=QU z(-u0PS(iGU{nTup|FLW?*K$No#J*Z4^l7)ut9VCY$F4HY&|7!(&n(_?P32bqCiMgp zc1sD51zHAX5|6GqbVU4EclmU9--##BJ!Y|n$DDqlvFt79o4#+0IHsPQt;?gz{PkEz zciN-3!XaBNj(uXDlFYqv<@I@m^;I(EZklCBCFFTbb@X$km)tgSs=JyP|He$|r^Nj? z+*3BcXblmm>;1;mmArf3J)Lv9)BvY1`6;Vw=ysow}IgSlR6F+*gaE_Zauh;D{?vf8X0OS3o)|QA%^+ma=;% z*QzZDG5l>ealMLEn!ehf-qWk|A08G7TQ~L8`)N@f%iFK+ZMs|Hu}u4r_<;wUWK>|!`c zLZ7+Y@RVDR9^XG!AFCG`4zUJ$dMyVJ9%W7D37q00aItH`iK`izzhm#Y|86yNn7Vn- z^w0C|SDv$6?@z zP3P5%@?Y=m&|tXk;pQ3lLp>q3tp1_R?nenPuIk@;({msoh+(dJI(2R7>$7e+m7ShS-?T>9bmH?E#6i{|Oe znSS_@b#~cBBtI~e9eC1zt!4VTycr9GV?x*Iw{Ll>l=92#)X5uq#@ni^>%%Y1 z`M_{`_iLB_^p>=?vdhu@UkcM^to&(MsJ-jv6dSd~{fzFyH|N+!%YC@Nifg8`#vhk; z=dWeeIZJHQD!*P)@KMicpG*&bb4lCcNt~t=7Jpq~S^3Rz!}n7Gj=dZI6+UPa-zq%& zlgIP0IHM)ST+`BSriA%a^JQIHT4N@%r=Wbk^!pL>YQA}^_U4g&)NgQu&X%Q~loCIG?= BGS2`2 diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png index 03b41d2a2651b099bba80ea4d075c193222eec90..983d7fad34577d985ad5b8c602077af17d192e34 100644 GIT binary patch literal 11971 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 diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png index 2800ea6610b67fea245740bbdb678308d00df9e2..c8f06766105a59f48baaca6346719b7e5446fcd2 100644 GIT binary patch delta 1326 zcmaFQ^^9wRXFZ3fi(^Q|oTcH>IU=DF|I*6JwpqvS+S0l$`o*@}>sY;5rv!1b2pwhW z?Cf;$QTXNLlw_jf7GHaXUEa`TG5@g{GgcT*S|O3VXQGD3iX~nv_g-9j>1}T2_S<*o z-rOl?e7Wq#$vK-{|4#BeSHI8r|Nptaf3|+^ulL))XSDm#jJhSg^#_Gk*xoxM2vUzPVTlhZa!SWz___uctZ=rTpo#l$$!t( zTYG1|(Y}}T>EP|GRK`=!cq2Sa3@R6YRa+A<@l;{UgDa1|KalueWYjnz=myi9)`{=l zGFa^54hn4$+kaA|e1$^u=Z{OY&u?dF7 z5z%K8y$^T3Nlh!LJJ@6pU34mh@!K4K`&l2ZZokT1kyI_QJKDv?$=x>QU{Hbc&fa`( z^9#n`HM7nz*;+9kQM_rolF4Xy)B(gBLmRBp^xG%?ae8waW`C|`X<;hGct9N>? zBGIaN;LOikoaLn-e*WHlNZsLnKw>fNl7|AiwHh|r~ zVMTE2xyA=8-ekW2Y<2lEpZ0;>w*So!o<8X9*|KZDL*|0>vYiiRaQSV%!PK>}_r$T+ zvA@40Py8>kC#Gda4fm}R-4D1}4lQ|;{kTe9rru!h`r6Xo^*THLc20QTZW{AzbI0y( zws~*3ly52+-DWkL&oaM`|KRKWO^aoIt!v0h=PAlPqS}|kZ!A8i_u!Vc^S`)v*sOYR z*tnO2^UJn#vnHHtIRD4vsVw6%jf7=yHf@Z(8NF8MoNVW#S1nyD*R=Mpds6t#;P06Y z2e-?_e|;s-RPTP^&%7{+g$ts0Y93l_btGIwq0=U=ewEnznj(I2_7oYPu!XB(wkR|ZqS=D(ieg8EKQ!a*a?0jYwe|b*M&sQ1sFZM5f^r%JT`X5!Za=Tt#wSzC^>>=stoBa0AyD#tfeHvGHSR8{`@Vd;E zp#ec>{bp)4G$bTs^07-No7_5RZLgbLbVf)CfP&(oZ6T)5%nX4VMa`o}_T z1r2)+*l@p*b3bg;_jZZ^Pe{E)l~coN@tENAt_ywd&oA50aIa<7o<2_7{?(@p_&lsv z)b*Epzgh59;)jIC_uWxXCYJHP6;3#ke~|0>+@gzGwh;niM#=}KKaUBX-Fxs%WotES zOG-v={f=kOkEZ<>tP%O~KqDZk$R~+w!tqD@(&QMcK9x^sczDaS(coRiXNk*~>Q_8; z`QjBT`o4XtM@s6AxAWGsZC|+Lk;1C_WAE>`UF6wvtdRfbr8B$pe$ITOe64qXyyoZCQo;7CYgL6Nnd|aI}H+8Nm4`pb)R>`}@{EJ$$sIb)Y`R2{D zFB~v3-Z5`&v)%TIFQXkC+OHivm$z-|vJKlUjy!38tYvX^Nl{C|1ouDdv-=qqpFNlN z$6s|#syVmlrrAo31@4Jf;g`=Ed=8z;y5ggwTIG%c;lkW$C%aeQE_>cSf1TrpE@av^`fL_uH-*PTa|kU=HFc>%fP_E;OXk;vd$@?2>{B~ Bi)sJ> delta 1335 zcmaFH^`2{jXT6}Oi(^Q|oU7Agb3#G|j{h%ye|Puoyxq4iZMyyG=A~O4At4I{44itL zbewqjn+zF~YZ_Pw1OqwK?qIuy`p62a) zW&7XRrk}~XylMH{ylC&FIZslGpP!ledA6nT_j#r>B>yj!xLkUm{>-eDE6f#*9IF}6 zs2@0bz?R`GgA~V)rj9)O0*2^MQM?vQvO}z^`Whq|t}S6Ren0t4J7>l84mNp?h6#JF zE4)!xs#S_sGUBXgo_XE)bFoWFauh?*r?}X~-ku>kteF<)>Js~(%fV>9>Y;xt z*PU)yk@770%$~lEWo#3)Eb1BBH!aRdNJo;q>&U-x5Ws#XL#SpOm;*BQh zY4ZB~j~>rg()cd@Bh6is%QmWvBY}Szm&1W+F`uJfa}_SK?0cOkJ>T?O^7+lKJI_ov zEMCf#a9pB^$(s; zlel)JVnb15`k#ajjnJO1?Z=wy>#kh7u+KVJTvt=z`>Ljw#`+)qZWONIoK;a-%DB(U zyyI}MnAo)0AD*V#cKzgXczrVZw$Xga2e-9XUEZ-W-S+oHt)TFS$0iyxzj!CUro?$54M zA6M5$tZ5Oh|5(|x`7u+8PQ1d+3s=SFmPf`JM1S!O(|z`1&tt2*A3W-+d{kDx$W`2b zrDIYu16xzwMf3e3nx>g)P9imv8;)o0_nF;aj89wZ%LR`K2>E&Ii=5_W5z>kmi1?NfW)o zBY%}EJY1lz7x?h}y|ga*lNtRkH`l&?Kc(Vq^5Lq~&F7YiW<6}Qj4amsDkyQ%$~KcpR=~e1v3g9 z+~4}8U3B)cBioa{&wYHW=w`j+?AilU_bo4Y)&F)*e31L+uFn(mUtP%1c(g)Spg)3x zExqPb!G;G7$1hmBGpFTdUCWudX5RucBjfxRfBEEY8j5H!a>p*;u;eNG#5Y=|N{vrD zDxWu%ihtqrcz=}f?Con^mp1pVPrt3M-4Oe6dWwI@%zB$!YGOz8HLRpW4socK)QjJ5 zGdC&un7Z)fzRTW-B}rde7GHPi8omZ9OtWqRUQfmTu}H+m*Z9 zlAdrdI$xi-W}m`B?$o^6`<0RfN~eB1a^F7mVw>pPj+sVsvuv5(`+PX=e)EWzn{NEi zgnb+>BFpR29rAkS1TLO_Ce2&Kd1^s?Qm$yd(5HXVTkc<3dmx2TF8Yye)zTl+=blM= za_^-QbMzYTInT8M7kr84Tp2j8@6f{wlQ$gRnQCU>j!%)fh?UtT|W=4RaLS3iF( zJ}8^N-!zlKpnsieoMv@lc-D%v`F*iFji=u}d3wwLIse`>{$rGRrL^w4YSI!01_lOC LS3j3^P6%C{|SR^ez+i8#n6 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 delta 2963 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 Cl&bgu diff --git a/pubspec.yaml b/pubspec.yaml index f33538e..e74d5d7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -98,3 +98,4 @@ flutter_launcher_icons: generate: true macos: generate: true + image_path: assets/mobile.png From 67cee201b6126f0ff1f491fc861ebc363bbf866f Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 11 Aug 2026 20:52:14 -0400 Subject: [PATCH 067/176] add TODO comment to LinkToMention extension --- lib/helpers/extensions/link_to_mention.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/helpers/extensions/link_to_mention.dart b/lib/helpers/extensions/link_to_mention.dart index f4868d3..8595669 100644 --- a/lib/helpers/extensions/link_to_mention.dart +++ b/lib/helpers/extensions/link_to_mention.dart @@ -9,6 +9,7 @@ extension LinkToMention on String { /// /// Returns the decoded identifier (e.g. "#room:matrix.org") /// or null if this is not a Matrix link. + /// TODO: Needs to be reworked to handle event links. Might be worth just rewriting, I don't like this code. String? get mention { final trimmed = trim(); From 050e42cc6f3cddb6ac9d08aa228ea1e879755f95 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 12 Aug 2026 10:34:28 -0400 Subject: [PATCH 068/176] comp for older macos --- hook/build.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hook/build.dart b/hook/build.dart index 66ae366..a893544 100644 --- a/hook/build.dart +++ b/hook/build.dart @@ -50,7 +50,10 @@ Future main(List args) => build(args, (input, output) async { break; case OS.macOS: libFileName = "libgomuks.dylib"; - extraEnv = {"SDKROOT": await getXCodeTool()}; + extraEnv = { + "SDKROOT": await getXCodeTool(), + "MACOSX_DEPLOYMENT_TARGET": codeConfig.macOS.targetVersion.toString(), + }; break; case OS.windows: libFileName = "libgomuks.dll"; From 01b13b476433240a81176d7891521cf001d1d5a2 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 12 Aug 2026 10:46:32 -0400 Subject: [PATCH 069/176] set min version of macos to 13.0 --- macos/Podfile | 2 +- macos/Runner.xcodeproj/project.pbxproj | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/macos/Podfile b/macos/Podfile index ff5ddb3..65543e2 100644 --- a/macos/Podfile +++ b/macos/Podfile @@ -1,4 +1,4 @@ -platform :osx, '10.15' +platform :osx, '13.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 67876ad..fa18d44 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -567,7 +567,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.15; + MACOSX_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -649,7 +649,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.15; + MACOSX_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -699,7 +699,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.15; + MACOSX_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; From 077044ec19dee2a7ce5dfee0245c41c0ea9e873a Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 22 Aug 2026 13:04:33 -0400 Subject: [PATCH 070/176] Move to Flutter 3.47, use the improvements that come with this (#64) Reviewed-on: https://git.federated.nexus/Nexus/nexus/pulls/64 --- .github/workflows/ios.yml | 2 +- .github/workflows/macos.yml | 2 +- .github/workflows/windows.yml | 100 ++++---- analysis_options.yaml | 25 +- android/app/build.gradle | 77 ------ android/app/build.gradle.kts | 74 ++++++ android/build.gradle | 26 -- android/build.gradle.kts | 25 ++ .../gradle/wrapper/gradle-wrapper.properties | 2 +- android/settings.gradle | 25 -- android/settings.gradle.kts | 26 ++ flake.lock | 6 +- lib/controllers/attachment.dart | 6 +- lib/controllers/auth_url.dart | 6 +- lib/controllers/author.dart | 12 +- lib/controllers/client_id.dart | 5 +- lib/controllers/emoji.dart | 2 +- lib/controllers/event.dart | 6 +- lib/controllers/key.dart | 5 +- lib/controllers/members.dart | 6 +- lib/controllers/members_by_status.dart | 6 +- lib/controllers/members_grouped.dart | 5 +- lib/controllers/multi_provider.dart | 7 +- lib/controllers/pinned_events.dart | 11 +- lib/controllers/pinned_ids.dart | 5 +- lib/controllers/power_level.dart | 6 +- lib/controllers/profile.dart | 6 +- lib/controllers/reactions.dart | 6 +- lib/controllers/room_chat.dart | 7 +- lib/controllers/room_creators.dart | 5 +- lib/controllers/room_summary.dart | 6 +- lib/controllers/settings_sections.dart | 2 +- lib/controllers/spaces.dart | 2 +- lib/controllers/url_preview.dart | 6 +- lib/controllers/via.dart | 5 +- lib/helpers/extensions/scheme_to_theme.dart | 2 +- lib/helpers/extensions/show_about_dialog.dart | 2 +- lib/helpers/extensions/show_context_menu.dart | 2 +- lib/helpers/extensions/show_user_popover.dart | 2 +- lib/helpers/extensions/string_to_color.dart | 2 +- lib/helpers/launch_helper.dart | 5 +- lib/helpers/mxc_image.dart | 8 +- lib/main.dart | 8 +- lib/models/account_data.dart | 62 ++--- lib/models/client_state.dart | 20 +- lib/models/configs/members_by_status.dart | 14 +- lib/models/configs/power_level.dart | 1 + lib/models/configs/reactions.dart | 14 +- lib/models/configs/user.dart | 10 +- lib/models/content/avatar.dart | 2 +- lib/models/content/canonical_alias.dart | 2 +- lib/models/content/content.dart | 17 +- lib/models/content/create.dart | 9 +- lib/models/content/encrypted.dart | 2 +- lib/models/content/encryption.dart | 2 +- lib/models/content/history_visibility.dart | 2 +- lib/models/content/join_rules.dart | 15 +- lib/models/content/membership.dart | 2 +- lib/models/content/message.dart | 2 +- lib/models/content/name.dart | 2 +- lib/models/content/pinned_events.dart | 2 +- lib/models/content/power_levels.dart | 15 +- lib/models/content/reaction.dart | 2 +- lib/models/content/redaction.dart | 2 +- lib/models/content/server_acl.dart | 2 +- lib/models/content/sticker.dart | 2 +- lib/models/content/topic.dart | 29 +-- lib/models/emoji.dart | 19 +- lib/models/event.dart | 80 ++++--- lib/models/homeserver.dart | 15 +- lib/models/info/audio.dart | 17 +- lib/models/info/file.dart | 15 +- lib/models/info/image.dart | 21 +- lib/models/info/video.dart | 21 +- lib/models/lazy_load_summary.dart | 16 +- lib/models/oauth_auth_code_response.dart | 16 +- lib/models/open_graph_data.dart | 20 +- lib/models/paginate.dart | 16 +- lib/models/profile_response.dart | 73 +++--- lib/models/read_receipt.dart | 20 +- lib/models/requests/download_media.dart | 18 +- lib/models/requests/get_event.dart | 16 +- lib/models/requests/get_related_events.dart | 16 +- lib/models/requests/get_room_state.dart | 18 +- lib/models/requests/join_room.dart | 14 +- lib/models/requests/oauth/exchange_token.dart | 20 +- lib/models/requests/oauth/get_auth_url.dart | 24 +- .../requests/oauth/register_client.dart | 35 +-- lib/models/requests/paginate.dart | 16 +- lib/models/requests/report.dart | 16 +- lib/models/requests/send_event.dart | 24 +- lib/models/requests/send_message.dart | 45 ++-- lib/models/requests/set_account_data.dart | 16 +- lib/models/requests/set_membership.dart | 21 +- lib/models/requests/set_state.dart | 25 +- lib/models/requests/upload_media.dart | 35 +-- lib/models/room.dart | 58 ++--- lib/models/room_metadata.dart | 40 ++-- lib/models/room_summary.dart | 28 ++- lib/models/setting.dart | 27 +-- lib/models/settings.dart | 18 +- lib/models/settings_category.dart | 15 +- lib/models/space.dart | 19 +- lib/models/space_edge.dart | 14 +- lib/models/spec_versions_response.dart | 25 +- lib/models/subspace.dart | 9 +- lib/models/sync_data.dart | 23 +- lib/models/sync_status.dart | 16 +- lib/pages/chat.dart | 6 +- lib/pages/select_server.dart | 15 +- lib/pages/settings.dart | 16 +- lib/pages/settings_category.dart | 12 +- lib/pages/verify.dart | 6 +- lib/widgets/appbar.dart | 30 +-- lib/widgets/avatar_or_hash.dart | 22 +- lib/widgets/composer/composer.dart | 46 ++-- lib/widgets/composer/mention_overlay.dart | 23 +- lib/widgets/composer/relation_preview.dart | 26 +- lib/widgets/divider_text.dart | 9 +- lib/widgets/divider_widget.dart | 8 +- lib/widgets/emoji_picker_button.dart | 22 +- lib/widgets/error_dialog.dart | 14 +- lib/widgets/event_preview.dart | 8 +- lib/widgets/expandable_image.dart | 12 +- lib/widgets/file_card.dart | 14 +- lib/widgets/highlight_wrapper.dart | 12 +- lib/widgets/html/code_block.dart | 12 +- lib/widgets/html/html.dart | 16 +- lib/widgets/html/mention_chip.dart | 9 +- lib/widgets/html/quoted.dart | 7 +- lib/widgets/html/spoiler_text.dart | 8 +- lib/widgets/join_dialog.dart | 28 +-- lib/widgets/lazy_loading/message_avatar.dart | 12 +- .../lazy_loading/message_displayname.dart | 26 +- lib/widgets/linkified_text.dart | 14 +- lib/widgets/loading.dart | 7 +- lib/widgets/member_list.dart | 14 +- lib/widgets/message_image.dart | 14 +- lib/widgets/pinned_events_drawer.dart | 19 +- lib/widgets/players/audio.dart | 16 +- lib/widgets/players/video.dart | 15 +- lib/widgets/reaction_row.dart | 12 +- lib/widgets/renderers/event.dart | 33 +-- lib/widgets/renderers/generic_event.dart | 12 +- lib/widgets/renderers/membership.dart | 8 +- lib/widgets/renderers/message.dart | 25 +- lib/widgets/room_appbar.dart | 37 ++- lib/widgets/room_chat.dart | 24 +- lib/widgets/room_menu.dart | 12 +- lib/widgets/settings/dialog_list_tile.dart | 34 +-- lib/widgets/settings/radio_dialog.dart | 25 +- lib/widgets/sidebar.dart | 8 +- lib/widgets/url_preview.dart | 13 +- lib/widgets/user_bottom_sheet.dart | 14 +- linux/nix/devshell.nix | 5 +- pubspec.lock | 222 ++++++++++-------- pubspec.yaml | 33 +-- 157 files changed, 1365 insertions(+), 1456 deletions(-) delete mode 100644 android/app/build.gradle create mode 100644 android/app/build.gradle.kts delete mode 100644 android/build.gradle create mode 100644 android/build.gradle.kts delete mode 100644 android/settings.gradle create mode 100644 android/settings.gradle.kts diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml index 5f16f9f..e14f1bb 100644 --- a/.github/workflows/ios.yml +++ b/.github/workflows/ios.yml @@ -19,7 +19,7 @@ jobs: - name: Set up Flutter uses: subosito/flutter-action@v2 with: - flutter-version: 3.44.4 + flutter-version: 3.47.0 - name: Set up Go uses: actions/setup-go@v6 diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 1476116..53c6746 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -19,7 +19,7 @@ jobs: - name: Set up Flutter uses: subosito/flutter-action@v2 with: - flutter-version: 3.44.4 + flutter-version: 3.47.0 - name: Set up Go uses: actions/setup-go@v6 diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index d9c8dd5..3ef3552 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -1,65 +1,65 @@ name: "Build EXE" on: - push: - branches: ["main"] - tags: ["*"] - workflow_dispatch: + push: + branches: ["main"] + tags: ["*"] + workflow_dispatch: jobs: - build-exe: - runs-on: windows-latest + build-exe: + runs-on: windows-latest - steps: - - name: Checkout repository - uses: actions/checkout@v6 - with: - submodules: recursive + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + submodules: recursive - - name: Set up Flutter - uses: subosito/flutter-action@v2 - with: - flutter-version: 3.44.4 + - name: Set up Flutter + uses: subosito/flutter-action@v2 + with: + flutter-version: 3.47.0 - - name: Set up Go - uses: actions/setup-go@v6 - with: - go-version-file: gomuks/go.mod + - name: Set up Go + uses: actions/setup-go@v6 + with: + go-version-file: gomuks/go.mod - - name: Setup MSYS2 - uses: msys2/setup-msys2@v2 - with: - msystem: MINGW64 - install: >- - mingw-w64-x86_64-gcc + - name: Setup MSYS2 + uses: msys2/setup-msys2@v2 + with: + msystem: MINGW64 + install: >- + mingw-w64-x86_64-gcc - - name: Go build - run: | - cd gomuks/pkg/ffi - go build -tags goolm,sqlite_fts5 -o ../../../libgomuks.dll -buildmode=c-shared + - name: Go build + run: | + cd gomuks/pkg/ffi + go build -tags goolm,sqlite_fts5 -o ../../../libgomuks.dll -buildmode=c-shared - - name: Build with Flutter - run: | - flutter pub get - dart scripts/generate.dart - flutter pub run build_runner build - flutter build windows --release + - name: Build with Flutter + run: | + flutter pub get + dart scripts/generate.dart + flutter pub run build_runner build + flutter build windows --release - - name: Copy MinGW runtime DLLs - shell: msys2 {0} - run: | - cp /mingw64/bin/libgcc_s_seh-1.dll build/windows/x64/runner/Release/ - cp /mingw64/bin/libwinpthread-1.dll build/windows/x64/runner/Release/ - cp /mingw64/bin/libstdc++-6.dll build/windows/x64/runner/Release/ + - name: Copy MinGW runtime DLLs + shell: msys2 {0} + run: | + cp /mingw64/bin/libgcc_s_seh-1.dll build/windows/x64/runner/Release/ + cp /mingw64/bin/libwinpthread-1.dll build/windows/x64/runner/Release/ + cp /mingw64/bin/libstdc++-6.dll build/windows/x64/runner/Release/ - - name: Install Inno Setup - run: choco install innosetup -y + - name: Install Inno Setup + run: choco install innosetup -y - - name: Build Inno Setup installer - run: iscc windows/installer.iss + - name: Build Inno Setup installer + run: iscc windows/installer.iss - - name: Upload installer artifact - uses: actions/upload-artifact@v6 - with: - name: windows-installer - path: windows/dist/Nexus-Setup.exe \ No newline at end of file + - name: Upload installer artifact + uses: actions/upload-artifact@v6 + with: + name: windows-installer + path: windows/dist/Nexus-Setup.exe diff --git a/analysis_options.yaml b/analysis_options.yaml index a8b1078..17adc10 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,12 +1,19 @@ analyzer: - errors: - invalid_annotation_target: ignore - avoid_print: ignore - exclude: - - "build/**" - - "**/*.g.dart" - - "**/*.freezed.dart" + errors: + invalid_annotation_target: ignore + avoid_print: ignore + annotate_overrides: ignore + exclude: + - "build/**" + - "**/*.g.dart" + - "**/*.freezed.dart" + - android/** + - ios/** + - web/** + - windows/** + - macos/** + - linux/** include: package:flutter_lints/flutter.yaml linter: - rules: - prefer_double_quotes: true \ No newline at end of file + rules: + prefer_double_quotes: true diff --git a/android/app/build.gradle b/android/app/build.gradle deleted file mode 100644 index 2e7fb67..0000000 --- a/android/app/build.gradle +++ /dev/null @@ -1,77 +0,0 @@ -plugins { - id "com.android.application" - id "kotlin-android" - // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. - id "dev.flutter.flutter-gradle-plugin" -} - -def localProperties = new Properties() -def localPropertiesFile = rootProject.file("local.properties") -if (localPropertiesFile.exists()) { - localPropertiesFile.withReader("UTF-8") { reader -> - localProperties.load(reader) - } -} - -def flutterVersionCode = localProperties.getProperty("flutter.versionCode") -if (flutterVersionCode == null) { - flutterVersionCode = "1" -} - -def flutterVersionName = localProperties.getProperty("flutter.versionName") -if (flutterVersionName == null) { - flutterVersionName = "1.0" -} - -def keystoreProperties = new Properties() -def keystorePropertiesFile = rootProject.file('key.properties') -if (keystorePropertiesFile.exists()) { - keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) -} - -android { - namespace = "nexus.federated.nexus" - ndkVersion = flutter.ndkVersion - compileSdk = 34 - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 - } - - kotlinOptions { - jvmTarget = "17" - } - - defaultConfig { - applicationId = "nexus.federated.nexus" - minSdk = 29 - targetSdkVersion flutter.targetSdkVersion - versionCode = flutterVersionCode.toInteger() - versionName = flutterVersionName - } - - signingConfigs { - release { - keyAlias "key" - def storePath = keystoreProperties['path'] ?: System.getenv("KEYSTORE_PATH") - storeFile storePath ? file(storePath) : null - keyPassword keystoreProperties['password'] ?: System.getenv("KEYSTORE_PASSWORD") - storePassword keystoreProperties['password'] ?: System.getenv("KEYSTORE_PASSWORD") - } - } - - buildTypes { - release { - signingConfig signingConfigs.release - } - - debug { - applicationIdSuffix = ".debug" - } - } -} - -flutter { - source = "../.." -} diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts new file mode 100644 index 0000000..161d5a5 --- /dev/null +++ b/android/app/build.gradle.kts @@ -0,0 +1,74 @@ +import java.util.Properties + +plugins { + id("com.android.application") + id("dev.flutter.flutter-gradle-plugin") +} + +val keystoreProperties = Properties() +val keystorePropertiesFile = rootProject.file("key.properties") + +if (keystorePropertiesFile.exists()) { + keystorePropertiesFile.inputStream().use { + keystoreProperties.load(it) + } +} + +android { + namespace = "nexus.federated.nexus" + compileSdk = 36 + ndkVersion = flutter.ndkVersion + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + + defaultConfig { + applicationId = "nexus.federated.nexus" + minSdk = 29 + targetSdk = flutter.targetSdkVersion + versionCode = flutter.versionCode + versionName = flutter.versionName + } + + signingConfigs { + create("release") { + keyAlias = "key" + + val storePath = + keystoreProperties["path"]?.toString() + ?: System.getenv("KEYSTORE_PATH") + + storeFile = storePath?.let { file(it) } + + keyPassword = + keystoreProperties["password"]?.toString() + ?: System.getenv("KEYSTORE_PASSWORD") + + storePassword = + keystoreProperties["password"]?.toString() + ?: System.getenv("KEYSTORE_PASSWORD") + } + } + + buildTypes { + release { + signingConfig = signingConfigs.getByName("release") + } + + debug { + applicationIdSuffix = ".debug" + } + } +} + +kotlin { + compilerOptions { + jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 + } +} + +flutter { + source = "../.." +} \ No newline at end of file diff --git a/android/build.gradle b/android/build.gradle deleted file mode 100644 index 11bc662..0000000 --- a/android/build.gradle +++ /dev/null @@ -1,26 +0,0 @@ -allprojects { - repositories { - google() - mavenCentral() - } -} - -rootProject.buildDir = "../build" -subprojects { - project.buildDir = "${rootProject.buildDir}/${project.name}" - - afterEvaluate {project -> - if (project.hasProperty("android")) { - android { - compileSdkVersion 36 - buildToolsVersion '33.0.1' - } - } - } - - project.evaluationDependsOn(":app") -} - -tasks.register("clean", Delete) { - delete rootProject.buildDir -} diff --git a/android/build.gradle.kts b/android/build.gradle.kts new file mode 100644 index 0000000..441eb71 --- /dev/null +++ b/android/build.gradle.kts @@ -0,0 +1,25 @@ +allprojects { + repositories { + google() + mavenCentral() + } +} + +val newBuildDir: Directory = + rootProject.layout.buildDirectory + .dir("../../build") + .get() +rootProject.layout.buildDirectory.value(newBuildDir) + +subprojects { + val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name) + project.layout.buildDirectory.value(newSubprojectBuildDir) +} + +subprojects { + project.evaluationDependsOn(":app") +} + +tasks.register("clean") { + delete(rootProject.layout.buildDirectory) +} \ No newline at end of file diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 74b269f..76d4386d 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-all.zip diff --git a/android/settings.gradle b/android/settings.gradle deleted file mode 100644 index 7cffcd0..0000000 --- a/android/settings.gradle +++ /dev/null @@ -1,25 +0,0 @@ -pluginManagement { - def flutterSdkPath = { - def properties = new Properties() - file("local.properties").withInputStream { properties.load(it) } - def flutterSdkPath = properties.getProperty("flutter.sdk") - assert flutterSdkPath != null, "flutter.sdk not set in local.properties" - return flutterSdkPath - }() - - includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") - - repositories { - google() - mavenCentral() - gradlePluginPortal() - } -} - -plugins { - id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "8.13.0" apply false - id "org.jetbrains.kotlin.android" version "2.2.20" apply false -} - -include ":app" diff --git a/android/settings.gradle.kts b/android/settings.gradle.kts new file mode 100644 index 0000000..b59bc94 --- /dev/null +++ b/android/settings.gradle.kts @@ -0,0 +1,26 @@ +pluginManagement { + val flutterSdkPath = + run { + val properties = java.util.Properties() + file("local.properties").inputStream().use { properties.load(it) } + val flutterSdkPath = properties.getProperty("flutter.sdk") + require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" } + flutterSdkPath + } + + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") + + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +plugins { + id("dev.flutter.flutter-plugin-loader") version "1.0.0" + id("com.android.application") version "9.3.1" apply false + id("org.jetbrains.kotlin.android") version "2.4.10" apply false +} + +include(":app") \ No newline at end of file diff --git a/flake.lock b/flake.lock index b743efe..3544dd7 100644 --- a/flake.lock +++ b/flake.lock @@ -88,11 +88,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1785967620, - "narHash": "sha256-IItrdb7Puk05RqOBWZYFC5X6Wl1sJmCfh5MWVHw5iMM=", + "lastModified": 1786862985, + "narHash": "sha256-FBJRXmbGXiSUDvYEbfLYRkckayyZ6SK1UEqhCrIZ2Cs=", "owner": "nixos", "repo": "nixpkgs", - "rev": "b7c2ada94fe99c15b0dbcf4d11fd7850b957a436", + "rev": "e5bdc4a41d4c072fe1e3787eaa0320a384741d44", "type": "github" }, "original": { diff --git a/lib/controllers/attachment.dart b/lib/controllers/attachment.dart index 2a99ee5..d4a5e09 100644 --- a/lib/controllers/attachment.dart +++ b/lib/controllers/attachment.dart @@ -6,10 +6,8 @@ import "package:nexus/models/content/content.dart"; import "package:nexus/models/content/message.dart"; import "package:path/path.dart"; -class AttachmentController extends Notifier<(String, MessageContent?)?> { - final String roomId; - AttachmentController(this.roomId); - +class AttachmentController(final String roomId) + extends Notifier<(String, MessageContent?)?> { @override Null build() => null; diff --git a/lib/controllers/auth_url.dart b/lib/controllers/auth_url.dart index 156eb81..963df86 100644 --- a/lib/controllers/auth_url.dart +++ b/lib/controllers/auth_url.dart @@ -4,10 +4,8 @@ import "package:nexus/controllers/client_id.dart"; import "package:nexus/models/oauth_auth_code_response.dart"; import "package:nexus/models/requests/oauth/get_auth_url.dart"; -class AuthUrlController extends AsyncNotifier { - final Uri homeserver; - AuthUrlController(this.homeserver); - +class AuthUrlController(final Uri homeserver) + extends AsyncNotifier { @override Future build() async => ref .watch(ClientController.provider.notifier) diff --git a/lib/controllers/author.dart b/lib/controllers/author.dart index bbbe068..f9c9167 100644 --- a/lib/controllers/author.dart +++ b/lib/controllers/author.dart @@ -1,19 +1,17 @@ import "dart:async"; + import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/controllers/user.dart"; import "package:nexus/models/content/membership.dart"; import "package:nexus/models/event.dart"; -class AuthorController extends AsyncNotifier { - final Event event; - AuthorController(this.event); - +class AuthorController(final Event event) + extends AsyncNotifier { @override Future build() async { final member = await ref.watch( - UserController.provider( - .new(roomId: event.roomId, userId: event.sender), - ).future, + UserController.provider(.new(roomId: event.roomId, userId: event.sender)) + .future, ); return .new( diff --git a/lib/controllers/client_id.dart b/lib/controllers/client_id.dart index ac8f5cb..7748f97 100644 --- a/lib/controllers/client_id.dart +++ b/lib/controllers/client_id.dart @@ -1,10 +1,7 @@ import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/controllers/client.dart"; -class ClientIdController extends AsyncNotifier { - final Uri homeserver; - ClientIdController(this.homeserver); - +class ClientIdController(final Uri homeserver) extends AsyncNotifier { @override Future build() => ref .watch(ClientController.provider.notifier) diff --git a/lib/controllers/emoji.dart b/lib/controllers/emoji.dart index caea3de..b0c1bd3 100644 --- a/lib/controllers/emoji.dart +++ b/lib/controllers/emoji.dart @@ -1,7 +1,7 @@ import "dart:convert"; import "package:emoji_text_field/models/emoji_category.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart"; -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:http/http.dart"; import "package:nexus/models/emoji.dart"; diff --git a/lib/controllers/event.dart b/lib/controllers/event.dart index b7b417a..7a1e5dc 100644 --- a/lib/controllers/event.dart +++ b/lib/controllers/event.dart @@ -5,10 +5,8 @@ import "package:nexus/controllers/rooms.dart"; import "package:nexus/models/event.dart"; import "package:nexus/models/requests/get_event.dart"; -class EventController extends AsyncNotifier { - final GetEventRequest request; - EventController(this.request); - +class EventController(final GetEventRequest request) + extends AsyncNotifier { @override Future build() async { final room = ref.watch( diff --git a/lib/controllers/key.dart b/lib/controllers/key.dart index eff3ab2..b78acf8 100644 --- a/lib/controllers/key.dart +++ b/lib/controllers/key.dart @@ -1,10 +1,7 @@ import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/controllers/shared_prefs.dart"; -class KeyController extends Notifier { - final String key; - KeyController(this.key); - +class KeyController(final String key) extends Notifier { static const String spaceKey = "space"; static const String roomKey = "room"; diff --git a/lib/controllers/members.dart b/lib/controllers/members.dart index 8566b40..3c287ea 100644 --- a/lib/controllers/members.dart +++ b/lib/controllers/members.dart @@ -6,10 +6,8 @@ import "package:nexus/models/content/content.dart"; import "package:nexus/models/event.dart"; import "package:nexus/models/requests/get_room_state.dart"; -class MembersController extends AsyncNotifier> { - final String roomId; - MembersController(this.roomId); - +class MembersController(final String roomId) + extends AsyncNotifier> { @override Future> build() async { final room = ref.watch( diff --git a/lib/controllers/members_by_status.dart b/lib/controllers/members_by_status.dart index 613f7b1..82905aa 100644 --- a/lib/controllers/members_by_status.dart +++ b/lib/controllers/members_by_status.dart @@ -5,10 +5,8 @@ import "package:nexus/models/configs/members_by_status.dart"; import "package:nexus/models/content/membership.dart"; import "package:nexus/models/event.dart"; -class MembersByStatusController extends AsyncNotifier> { - final MembersByStatusConfig config; - MembersByStatusController(this.config); - +class MembersByStatusController(final MembersByStatusConfig config) + extends AsyncNotifier> { @override Future> build() => ref.watch( MembersController.provider(config.roomId).selectAsync( diff --git a/lib/controllers/members_grouped.dart b/lib/controllers/members_grouped.dart index 6f41e9d..f903ec4 100644 --- a/lib/controllers/members_grouped.dart +++ b/lib/controllers/members_grouped.dart @@ -8,11 +8,8 @@ import "package:nexus/models/content/content.dart"; import "package:nexus/models/content/power_levels.dart"; import "package:nexus/models/event.dart"; -class MembersGroupedController +class MembersGroupedController(final MembersByStatusConfig config) extends AsyncNotifier>>> { - final MembersByStatusConfig config; - MembersGroupedController(this.config); - @override Future>>> build() async { final room = ref.watch( diff --git a/lib/controllers/multi_provider.dart b/lib/controllers/multi_provider.dart index 52dd8d9..f1ae78c 100644 --- a/lib/controllers/multi_provider.dart +++ b/lib/controllers/multi_provider.dart @@ -1,11 +1,10 @@ import "dart:async"; + import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; -class MultiProviderController extends AsyncNotifier { - MultiProviderController(this.providers); - final IList providers; - +class MultiProviderController(final IList providers) + extends AsyncNotifier { @override Future build() => .wait(providers.map((provider) => ref.watch(provider.future))); diff --git a/lib/controllers/pinned_events.dart b/lib/controllers/pinned_events.dart index 914a301..323a275 100644 --- a/lib/controllers/pinned_events.dart +++ b/lib/controllers/pinned_events.dart @@ -4,10 +4,8 @@ import "package:nexus/controllers/event.dart"; import "package:nexus/controllers/pinned_ids.dart"; import "package:nexus/models/event.dart"; -class PinnedEventsController extends AsyncNotifier> { - final String roomId; - PinnedEventsController(this.roomId); - +class PinnedEventsController(final String roomId) + extends AsyncNotifier> { @override Future> build() async { final pinIds = ref.watch(PinnedIdsController.provider(roomId)); @@ -15,9 +13,8 @@ class PinnedEventsController extends AsyncNotifier> { return (await Future.wait( pinIds.map( (eventId) => ref.watch( - EventController.provider( - .new(eventId: eventId, roomId: roomId), - ).future, + EventController.provider(.new(eventId: eventId, roomId: roomId)) + .future, ), ), )).nonNulls.toIList(); diff --git a/lib/controllers/pinned_ids.dart b/lib/controllers/pinned_ids.dart index 3d1e5da..01358a9 100644 --- a/lib/controllers/pinned_ids.dart +++ b/lib/controllers/pinned_ids.dart @@ -5,10 +5,7 @@ import "package:nexus/controllers/rooms.dart"; import "package:nexus/models/content/content.dart"; import "package:nexus/models/content/pinned_events.dart"; -class PinnedIdsController extends Notifier> { - final String roomId; - PinnedIdsController(this.roomId); - +class PinnedIdsController(final String roomId) extends Notifier> { @override IList build() { final room = ref.watch( diff --git a/lib/controllers/power_level.dart b/lib/controllers/power_level.dart index 2f0c72e..7111e38 100644 --- a/lib/controllers/power_level.dart +++ b/lib/controllers/power_level.dart @@ -6,10 +6,8 @@ import "package:nexus/models/configs/power_level.dart"; import "package:nexus/models/content/content.dart"; import "package:nexus/models/content/power_levels.dart"; -class PowerLevelController extends Notifier { - final PowerLevelConfig config; - PowerLevelController(this.config); - +class PowerLevelController(final PowerLevelConfig config) + extends Notifier { @override bool build() { if (config case EventPowerLevelConfig(:final eventType)) { diff --git a/lib/controllers/profile.dart b/lib/controllers/profile.dart index 58fa49d..6f0291d 100644 --- a/lib/controllers/profile.dart +++ b/lib/controllers/profile.dart @@ -2,10 +2,8 @@ import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/controllers/client.dart"; import "package:nexus/models/profile_response.dart"; -class ProfileController extends AsyncNotifier { - final String userId; - ProfileController(this.userId); - +class ProfileController(final String userId) + extends AsyncNotifier { @override Future build() { final client = ref.watch(ClientController.provider.notifier); diff --git a/lib/controllers/reactions.dart b/lib/controllers/reactions.dart index 615a59d..9a92843 100644 --- a/lib/controllers/reactions.dart +++ b/lib/controllers/reactions.dart @@ -5,10 +5,8 @@ import "package:nexus/controllers/rooms.dart"; import "package:nexus/models/configs/reactions.dart"; import "package:nexus/models/content/reaction.dart"; -class ReactionsController extends AsyncNotifier>> { - final ReactionsConfig config; - ReactionsController(this.config); - +class ReactionsController(final ReactionsConfig config) + extends AsyncNotifier>> { @override Future>> build() async { final eventInfo = ref.watch( diff --git a/lib/controllers/room_chat.dart b/lib/controllers/room_chat.dart index 35038a0..0cd1011 100644 --- a/lib/controllers/room_chat.dart +++ b/lib/controllers/room_chat.dart @@ -1,5 +1,6 @@ import "dart:async"; import "dart:math"; + import "package:collection/collection.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; @@ -15,10 +16,8 @@ import "package:nexus/models/relation_type.dart"; import "package:nexus/models/requests/send_message.dart"; import "package:nexus/models/room.dart"; -class RoomChatController extends AsyncNotifier?> { - final String roomId; - RoomChatController(this.roomId); - +class RoomChatController(final String roomId) + extends AsyncNotifier?> { @override Future?> build() async { final client = ref.watch(ClientController.provider.notifier); diff --git a/lib/controllers/room_creators.dart b/lib/controllers/room_creators.dart index 7db72c2..09acdd7 100644 --- a/lib/controllers/room_creators.dart +++ b/lib/controllers/room_creators.dart @@ -4,10 +4,7 @@ import "package:nexus/models/content/content.dart"; import "package:nexus/models/content/create.dart"; import "package:nexus/models/room.dart"; -class RoomCreatorsController extends Notifier> { - final Room room; - RoomCreatorsController(this.room); - +class RoomCreatorsController(final Room room) extends Notifier> { @override IList build() { final createRowId = room.state[EventType.create.type]?[""]; diff --git a/lib/controllers/room_summary.dart b/lib/controllers/room_summary.dart index d47d8ef..76271a4 100644 --- a/lib/controllers/room_summary.dart +++ b/lib/controllers/room_summary.dart @@ -3,10 +3,8 @@ 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 { - final JoinRoomRequest request; - RoomSummaryController(this.request); - +class RoomSummaryController(final JoinRoomRequest request) + extends AsyncNotifier { @override Future build() => ref.watch(ClientController.provider.notifier).getRoomSummary(request); diff --git a/lib/controllers/settings_sections.dart b/lib/controllers/settings_sections.dart index 37e6284..149fe30 100644 --- a/lib/controllers/settings_sections.dart +++ b/lib/controllers/settings_sections.dart @@ -1,6 +1,6 @@ import "dart:io"; import "package:fast_immutable_collections/fast_immutable_collections.dart"; -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:intl/intl.dart"; import "package:m3e_buttons/m3e_buttons.dart"; diff --git a/lib/controllers/spaces.dart b/lib/controllers/spaces.dart index 60696da..7dc14b0 100644 --- a/lib/controllers/spaces.dart +++ b/lib/controllers/spaces.dart @@ -1,6 +1,6 @@ import "package:collection/collection.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart"; -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/controllers/account_data.dart"; import "package:nexus/controllers/rooms.dart"; diff --git a/lib/controllers/url_preview.dart b/lib/controllers/url_preview.dart index 1b17870..41c3ef4 100644 --- a/lib/controllers/url_preview.dart +++ b/lib/controllers/url_preview.dart @@ -3,10 +3,8 @@ import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/controllers/client.dart"; import "package:nexus/models/open_graph_data.dart"; -class UrlPreviewController extends AsyncNotifier { - final Uri url; - UrlPreviewController(this.url); - +class UrlPreviewController(final Uri url) + extends AsyncNotifier { @override Future build() async { if (url.host == "matrix.to") return null; diff --git a/lib/controllers/via.dart b/lib/controllers/via.dart index d9227ba..39db682 100644 --- a/lib/controllers/via.dart +++ b/lib/controllers/via.dart @@ -7,10 +7,7 @@ import "package:nexus/models/content/membership.dart"; import "package:nexus/models/content/power_levels.dart"; import "package:nexus/models/room.dart"; -class ViaController extends Notifier { - final Room room; - ViaController(this.room); - +class ViaController(final Room room) extends Notifier { @override String build() { final servers = {}; diff --git a/lib/helpers/extensions/scheme_to_theme.dart b/lib/helpers/extensions/scheme_to_theme.dart index bf48535..6beca04 100644 --- a/lib/helpers/extensions/scheme_to_theme.dart +++ b/lib/helpers/extensions/scheme_to_theme.dart @@ -1,4 +1,4 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; extension SchemeToTheme on ColorScheme { ThemeData get theme { diff --git a/lib/helpers/extensions/show_about_dialog.dart b/lib/helpers/extensions/show_about_dialog.dart index 2f24a3e..5bd2740 100644 --- a/lib/helpers/extensions/show_about_dialog.dart +++ b/lib/helpers/extensions/show_about_dialog.dart @@ -1,4 +1,4 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_svg/flutter_svg.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:m3e_card_list/m3e_card_list.dart"; diff --git a/lib/helpers/extensions/show_context_menu.dart b/lib/helpers/extensions/show_context_menu.dart index c860115..589942b 100644 --- a/lib/helpers/extensions/show_context_menu.dart +++ b/lib/helpers/extensions/show_context_menu.dart @@ -1,4 +1,4 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; extension ShowContextMenu on BuildContext { void showContextMenu({ diff --git a/lib/helpers/extensions/show_user_popover.dart b/lib/helpers/extensions/show_user_popover.dart index 1ea3015..f42cd57 100644 --- a/lib/helpers/extensions/show_user_popover.dart +++ b/lib/helpers/extensions/show_user_popover.dart @@ -1,4 +1,4 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:nexus/models/content/membership.dart"; import "package:nexus/widgets/user_bottom_sheet.dart"; diff --git a/lib/helpers/extensions/string_to_color.dart b/lib/helpers/extensions/string_to_color.dart index eaa7714..a21ca82 100644 --- a/lib/helpers/extensions/string_to_color.dart +++ b/lib/helpers/extensions/string_to_color.dart @@ -1,5 +1,5 @@ import "package:color_hash/color_hash.dart"; -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; extension ToColor on String { Color get colorHash => ColorHash(this, lightness: .5, saturation: .7).color; diff --git a/lib/helpers/launch_helper.dart b/lib/helpers/launch_helper.dart index 575395f..89c7015 100644 --- a/lib/helpers/launch_helper.dart +++ b/lib/helpers/launch_helper.dart @@ -2,10 +2,7 @@ import "package:flutter/services.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:url_launcher/url_launcher.dart" as ul; -class LaunchHelper { - final Ref ref; - LaunchHelper(this.ref); - +class LaunchHelper(Ref ref) { Future launchUrl(Uri url, {bool useWebview = false}) async { try { return await ul.launchUrl( diff --git a/lib/helpers/mxc_image.dart b/lib/helpers/mxc_image.dart index 3adb10e..83a345a 100644 --- a/lib/helpers/mxc_image.dart +++ b/lib/helpers/mxc_image.dart @@ -1,14 +1,12 @@ import "dart:ui"; + import "package:flutter/widgets.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/controllers/client.dart"; import "package:nexus/models/requests/download_media.dart"; -class MxcImage extends ImageProvider { - final WidgetRef ref; - final DownloadMediaRequest request; - const MxcImage(this.ref, this.request); - +class MxcImage(final WidgetRef ref, final DownloadMediaRequest request) + extends ImageProvider { @override Future obtainKey(ImageConfiguration configuration) => Future.value(this); diff --git a/lib/main.dart b/lib/main.dart index aabfe47..a87d7f5 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,5 @@ import "dart:io"; + import "package:dynamic_color/dynamic_color.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:flutter/foundation.dart"; @@ -18,7 +19,7 @@ import "package:nexus/pages/verify.dart"; import "package:nexus/widgets/error_dialog.dart"; import "package:nexus/widgets/loading.dart"; import "package:window_manager/window_manager.dart"; -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; final GlobalKey navigatorKey = GlobalKey(); @@ -94,16 +95,13 @@ void main() async { ); } -class App extends StatelessWidget { - const App({super.key}); - +class const App({super.key}) extends StatelessWidget { @override Widget build(BuildContext context) => DynamicColorBuilder( builder: (lightDynamic, darkDynamic) => Consumer( builder: (context, ref, child) => MaterialApp( navigatorKey: navigatorKey, debugShowCheckedModeBanner: false, - // Use indigo to work around bugs in theme generation theme: (ref .watch(SettingsController.provider) diff --git a/lib/models/account_data.dart b/lib/models/account_data.dart index 7df7459..53b4ff2 100644 --- a/lib/models/account_data.dart +++ b/lib/models/account_data.dart @@ -1,11 +1,26 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:freezed_annotation/freezed_annotation.dart"; + part "account_data.freezed.dart"; part "account_data.g.dart"; -@freezed -abstract class AccountData with _$AccountData { - const AccountData._(); +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const AccountData({ + @JsonKey(name: AccountData.invitePermissionConfigKey) + final InvitePermissionConfig invitePermissionConfig = + const InvitePermissionConfig(), + + @JsonKey(name: AccountData.directKey) + final IMap> directMessages = const IMap.empty(), + + @JsonKey( + name: AccountData.recentEmojiKey, + readValue: AccountData.readRecentEmojiValue, + toJson: AccountData.recentEmojiToJson, + ) + final IList recentEmoji = const IList.empty(), +}) with _$AccountData { static List? readRecentEmojiValue( Map json, String key, @@ -19,44 +34,29 @@ abstract class AccountData with _$AccountData { static const directKey = "m.direct"; static const recentEmojiKey = "m.recent_emoji"; - const factory AccountData({ - @JsonKey(name: AccountData.invitePermissionConfigKey) - @Default(InvitePermissionConfig()) - InvitePermissionConfig invitePermissionConfig, - - @JsonKey(name: AccountData.directKey) - @Default(IMap.empty()) - IMap> directMessages, - - @JsonKey( - name: AccountData.recentEmojiKey, - readValue: AccountData.readRecentEmojiValue, - toJson: AccountData.recentEmojiToJson, - ) - @Default(IList.empty()) - IList recentEmoji, - }) = _AccountData; + Map toJson() => _$AccountDataToJson(this); factory AccountData.fromJson(Map json) => _$AccountDataFromJson(json); } -@freezed -abstract class InvitePermissionConfig with _$InvitePermissionConfig { - const factory InvitePermissionConfig({ - @JsonKey(unknownEnumValue: DefaultInviteAction.allow) - @Default(DefaultInviteAction.allow) - DefaultInviteAction defaultAction, - }) = _InvitePermissionConfig; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const InvitePermissionConfig({ + @JsonKey(unknownEnumValue: DefaultInviteAction.allow) + final DefaultInviteAction defaultAction = DefaultInviteAction.allow, +}) with _$InvitePermissionConfig { + Map toJson() => _$InvitePermissionConfigToJson(this); factory InvitePermissionConfig.fromJson(Map json) => _$InvitePermissionConfigFromJson(json); } -@freezed -abstract class RecentEmoji with _$RecentEmoji { - const factory RecentEmoji({required String emoji, required int total}) = - _RecentEmoji; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const RecentEmoji({required final String emoji, required final int total}) + with _$RecentEmoji { + Map toJson() => _$RecentEmojiToJson(this); factory RecentEmoji.fromJson(Map json) => _$RecentEmojiFromJson(json); diff --git a/lib/models/client_state.dart b/lib/models/client_state.dart index 1e15136..ff433ab 100644 --- a/lib/models/client_state.dart +++ b/lib/models/client_state.dart @@ -1,16 +1,18 @@ import "package:freezed_annotation/freezed_annotation.dart"; + part "client_state.freezed.dart"; part "client_state.g.dart"; -@freezed -abstract class ClientState with _$ClientState { - const factory ClientState({ - required bool isInitialized, - required bool isLoggedIn, - required bool isVerified, - required String? userId, - required String? homeserverUrl, - }) = _ClientState; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const ClientState({ + required final bool isInitialized, + required final bool isLoggedIn, + required final bool isVerified, + required final String? userId, + required final String? homeserverUrl, +}) with _$ClientState { + Map toJson() => _$ClientStateToJson(this); factory ClientState.fromJson(Map json) => _$ClientStateFromJson(json); diff --git a/lib/models/configs/members_by_status.dart b/lib/models/configs/members_by_status.dart index 29fc471..6b4aec4 100644 --- a/lib/models/configs/members_by_status.dart +++ b/lib/models/configs/members_by_status.dart @@ -1,14 +1,16 @@ import "package:freezed_annotation/freezed_annotation.dart"; import "package:nexus/models/membership_status.dart"; + part "members_by_status.freezed.dart"; part "members_by_status.g.dart"; -@freezed -abstract class MembersByStatusConfig with _$MembersByStatusConfig { - const factory MembersByStatusConfig({ - required String roomId, - required MembershipStatus status, - }) = _MembersByStatusConfig; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const MembersByStatusConfig({ + required final String roomId, + required final MembershipStatus status, +}) with _$MembersByStatusConfig { + Map toJson() => _$MembersByStatusConfigToJson(this); factory MembersByStatusConfig.fromJson(Map json) => _$MembersByStatusConfigFromJson(json); diff --git a/lib/models/configs/power_level.dart b/lib/models/configs/power_level.dart index ed9c5e8..5722db7 100644 --- a/lib/models/configs/power_level.dart +++ b/lib/models/configs/power_level.dart @@ -1,6 +1,7 @@ import "package:freezed_annotation/freezed_annotation.dart"; import "package:nexus/models/content/content.dart"; import "package:nexus/models/membership_action.dart"; + part "power_level.freezed.dart"; @freezed diff --git a/lib/models/configs/reactions.dart b/lib/models/configs/reactions.dart index 787b28c..b9de793 100644 --- a/lib/models/configs/reactions.dart +++ b/lib/models/configs/reactions.dart @@ -1,13 +1,15 @@ import "package:freezed_annotation/freezed_annotation.dart"; + part "reactions.freezed.dart"; part "reactions.g.dart"; -@freezed -abstract class ReactionsConfig with _$ReactionsConfig { - const factory ReactionsConfig({ - required String roomId, - required int eventRowId, - }) = _ReactionsConfig; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const ReactionsConfig({ + required final String roomId, + required final int eventRowId, +}) with _$ReactionsConfig { + Map toJson() => _$ReactionsConfigToJson(this); factory ReactionsConfig.fromJson(Map json) => _$ReactionsConfigFromJson(json); diff --git a/lib/models/configs/user.dart b/lib/models/configs/user.dart index 0331597..bbbc83d 100644 --- a/lib/models/configs/user.dart +++ b/lib/models/configs/user.dart @@ -1,11 +1,13 @@ import "package:freezed_annotation/freezed_annotation.dart"; + part "user.freezed.dart"; part "user.g.dart"; -@freezed -abstract class UserConfig with _$UserConfig { - const factory UserConfig({required String? roomId, required String userId}) = - _UserConfig; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const UserConfig({final String? roomId, required final String userId}) + with _$UserConfig { + Map toJson() => _$UserConfigToJson(this); factory UserConfig.fromJson(Map json) => _$UserConfigFromJson(json); diff --git a/lib/models/content/avatar.dart b/lib/models/content/avatar.dart index 66d4c47..25167e9 100644 --- a/lib/models/content/avatar.dart +++ b/lib/models/content/avatar.dart @@ -5,7 +5,7 @@ part "avatar.freezed.dart"; part "avatar.g.dart"; @freezed -abstract class AvatarContent extends Content with _$AvatarContent { +sealed class AvatarContent extends Content with _$AvatarContent { AvatarContent._(); factory AvatarContent({ImageInfo? info, Uri? url}) = _AvatarContent; diff --git a/lib/models/content/canonical_alias.dart b/lib/models/content/canonical_alias.dart index 636be13..1a35d92 100644 --- a/lib/models/content/canonical_alias.dart +++ b/lib/models/content/canonical_alias.dart @@ -5,7 +5,7 @@ part "canonical_alias.freezed.dart"; part "canonical_alias.g.dart"; @freezed -abstract class CanonicalAliasContent extends Content +sealed class CanonicalAliasContent extends Content with _$CanonicalAliasContent { CanonicalAliasContent._(); factory CanonicalAliasContent({ diff --git a/lib/models/content/content.dart b/lib/models/content/content.dart index e7b1141..e28ccbf 100644 --- a/lib/models/content/content.dart +++ b/lib/models/content/content.dart @@ -19,9 +19,11 @@ import "package:nexus/models/content/history_visibility.dart"; class Content { final Error? parseError; - Content({this.parseError}); - factory Content.fromJson(Map json) => Content(); + const Content({this.parseError}); + + factory Content.fromJson(Map json) => const Content(); + Map toJson() => {}; static Map readValue(Map json, _) => @@ -34,13 +36,16 @@ class Content { ?.contentFromJson ?? Content.fromJson)(json); } catch (error) { - if (error is Error) return .new(parseError: error); + if (error is Error) return Content(parseError: error); rethrow; } } } -enum EventType { +enum EventType( + final String type, + final Content Function(Map json) contentFromJson, +) { encrypted("m.room.encrypted", EncryptedContent.fromJson), redaction("m.room.redaction", RedactionContent.fromJson), encryption("m.room.encryption", EncryptionContent.fromJson), @@ -61,8 +66,4 @@ enum EventType { reaction("m.reaction", ReactionContent.fromJson), pinnedEvents("m.room.pinned_events", PinnedEventsContent.fromJson), message("m.room.message", MessageContent.fromJson); - - final String type; - final Content Function(Map json) contentFromJson; - const EventType(this.type, this.contentFromJson); } diff --git a/lib/models/content/create.dart b/lib/models/content/create.dart index c534558..b937a94 100644 --- a/lib/models/content/create.dart +++ b/lib/models/content/create.dart @@ -5,7 +5,7 @@ part "create.freezed.dart"; part "create.g.dart"; @freezed -abstract class CreateContent extends Content with _$CreateContent { +sealed class CreateContent extends Content with _$CreateContent { CreateContent._(); factory CreateContent({ @JsonKey(name: "additional_creators") @@ -30,9 +30,10 @@ enum RoomType { space, } -@freezed -abstract class PreviousRoom with _$PreviousRoom { - const factory PreviousRoom({required String roomId}) = _PreviousRoom; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const PreviousRoom({required final String roomId}) with _$PreviousRoom { + Map toJson() => _$PreviousRoomToJson(this); factory PreviousRoom.fromJson(Map json) => _$PreviousRoomFromJson(json); diff --git a/lib/models/content/encrypted.dart b/lib/models/content/encrypted.dart index b33a440..8658a71 100644 --- a/lib/models/content/encrypted.dart +++ b/lib/models/content/encrypted.dart @@ -4,7 +4,7 @@ part "encrypted.freezed.dart"; part "encrypted.g.dart"; @freezed -abstract class EncryptedContent extends Content with _$EncryptedContent { +sealed class EncryptedContent extends Content with _$EncryptedContent { EncryptedContent._(); factory EncryptedContent() = _EncryptedContent; diff --git a/lib/models/content/encryption.dart b/lib/models/content/encryption.dart index 3380632..52c7b34 100644 --- a/lib/models/content/encryption.dart +++ b/lib/models/content/encryption.dart @@ -4,7 +4,7 @@ part "encryption.freezed.dart"; part "encryption.g.dart"; @freezed -abstract class EncryptionContent extends Content with _$EncryptionContent { +sealed class EncryptionContent extends Content with _$EncryptionContent { EncryptionContent._(); factory EncryptionContent({ required String algorithm, diff --git a/lib/models/content/history_visibility.dart b/lib/models/content/history_visibility.dart index 707805c..3cfc011 100644 --- a/lib/models/content/history_visibility.dart +++ b/lib/models/content/history_visibility.dart @@ -4,7 +4,7 @@ part "history_visibility.freezed.dart"; part "history_visibility.g.dart"; @freezed -abstract class HistoryVisibilityContent extends Content +sealed class HistoryVisibilityContent extends Content with _$HistoryVisibilityContent { HistoryVisibilityContent._(); factory HistoryVisibilityContent({ diff --git a/lib/models/content/join_rules.dart b/lib/models/content/join_rules.dart index 1d14eee..3f1c17b 100644 --- a/lib/models/content/join_rules.dart +++ b/lib/models/content/join_rules.dart @@ -6,7 +6,7 @@ part "join_rules.freezed.dart"; part "join_rules.g.dart"; @freezed -abstract class JoinRulesContent extends Content with _$JoinRulesContent { +sealed class JoinRulesContent extends Content with _$JoinRulesContent { JoinRulesContent._(); factory JoinRulesContent({ required JoinRule joinRule, @@ -17,12 +17,13 @@ abstract class JoinRulesContent extends Content with _$JoinRulesContent { _$JoinRulesContentFromJson(json); } -@freezed -abstract class AllowCondition with _$AllowCondition { - const factory AllowCondition({ - String? roomId, - required AllowConditionType type, - }) = _AllowCondition; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const AllowCondition({ + final String? roomId, + required final AllowConditionType type, +}) with _$AllowCondition { + Map toJson() => _$AllowConditionToJson(this); factory AllowCondition.fromJson(Map json) => _$AllowConditionFromJson(json); diff --git a/lib/models/content/membership.dart b/lib/models/content/membership.dart index dbbd123..46be974 100644 --- a/lib/models/content/membership.dart +++ b/lib/models/content/membership.dart @@ -5,7 +5,7 @@ part "membership.freezed.dart"; part "membership.g.dart"; @freezed -abstract class MembershipContent extends Content with _$MembershipContent { +sealed class MembershipContent extends Content with _$MembershipContent { MembershipContent._(); static String? displaynameFromJson(String? displayName) => diff --git a/lib/models/content/message.dart b/lib/models/content/message.dart index e7e8923..36bd725 100644 --- a/lib/models/content/message.dart +++ b/lib/models/content/message.dart @@ -10,7 +10,7 @@ part "message.g.dart"; typedef EncryptedFile = Map; @Freezed(unionKey: "msgtype", fallbackUnion: "default") -abstract class MessageContent extends Content with _$MessageContent { +sealed class MessageContent extends Content with _$MessageContent { MessageContent._(); static String? mediaUrlFromJson(Map json, String key) => json[key] ?? json["file"]?[key]; diff --git a/lib/models/content/name.dart b/lib/models/content/name.dart index 205f6bb..c451d64 100644 --- a/lib/models/content/name.dart +++ b/lib/models/content/name.dart @@ -4,7 +4,7 @@ part "name.freezed.dart"; part "name.g.dart"; @freezed -abstract class NameContent extends Content with _$NameContent { +sealed class NameContent extends Content with _$NameContent { NameContent._(); factory NameContent({required String name}) = _NameContent; diff --git a/lib/models/content/pinned_events.dart b/lib/models/content/pinned_events.dart index 8aea838..9dac5de 100644 --- a/lib/models/content/pinned_events.dart +++ b/lib/models/content/pinned_events.dart @@ -5,7 +5,7 @@ part "pinned_events.freezed.dart"; part "pinned_events.g.dart"; @freezed -abstract class PinnedEventsContent extends Content with _$PinnedEventsContent { +sealed class PinnedEventsContent extends Content with _$PinnedEventsContent { PinnedEventsContent._(); factory PinnedEventsContent({ @Default(IList.empty()) @JsonKey(name: "pinned") IList pinnedEvents, diff --git a/lib/models/content/power_levels.dart b/lib/models/content/power_levels.dart index 3709c38..5ae6561 100644 --- a/lib/models/content/power_levels.dart +++ b/lib/models/content/power_levels.dart @@ -5,7 +5,7 @@ part "power_levels.freezed.dart"; part "power_levels.g.dart"; @freezed -abstract class PowerLevelsContent extends Content with _$PowerLevelsContent { +sealed class PowerLevelsContent extends Content with _$PowerLevelsContent { PowerLevelsContent._(); factory PowerLevelsContent({ @Default(IMap.empty()) IMap events, @@ -24,12 +24,13 @@ abstract class PowerLevelsContent extends Content with _$PowerLevelsContent { _$PowerLevelsContentFromJson(json); } -@freezed -abstract class Notifications with _$Notifications { - const factory Notifications({ - @Default(50) int room, - @Default(IMapConst({})) IMap other, - }) = _Notifications; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const Notifications({ + final int room = 50, + final IMap other = const IMap.empty(), +}) with _$Notifications { + Map toJson() => _$NotificationsToJson(this); factory Notifications.fromJson(Map json) => _$NotificationsFromJson(json); diff --git a/lib/models/content/reaction.dart b/lib/models/content/reaction.dart index 0f81bc0..93c563d 100644 --- a/lib/models/content/reaction.dart +++ b/lib/models/content/reaction.dart @@ -4,7 +4,7 @@ part "reaction.freezed.dart"; part "reaction.g.dart"; @Freezed(toJson: false) -abstract class ReactionContent extends Content with _$ReactionContent { +sealed class ReactionContent extends Content with _$ReactionContent { ReactionContent._(); static String? keyJsonFromJson(Map json, String key) => json["m.relates_to"]?["key"]; diff --git a/lib/models/content/redaction.dart b/lib/models/content/redaction.dart index e9c1a90..2ed6436 100644 --- a/lib/models/content/redaction.dart +++ b/lib/models/content/redaction.dart @@ -4,7 +4,7 @@ part "redaction.freezed.dart"; part "redaction.g.dart"; @freezed -abstract class RedactionContent extends Content with _$RedactionContent { +sealed class RedactionContent extends Content with _$RedactionContent { RedactionContent._(); factory RedactionContent({String? reason, String? redacts}) = _RedactionContent; diff --git a/lib/models/content/server_acl.dart b/lib/models/content/server_acl.dart index 1e50988..3873bf3 100644 --- a/lib/models/content/server_acl.dart +++ b/lib/models/content/server_acl.dart @@ -5,7 +5,7 @@ part "server_acl.freezed.dart"; part "server_acl.g.dart"; @freezed -abstract class ServerACLContent extends Content with _$ServerACLContent { +sealed class ServerACLContent extends Content with _$ServerACLContent { ServerACLContent._(); factory ServerACLContent({ @Default(IList.empty()) IList allow, diff --git a/lib/models/content/sticker.dart b/lib/models/content/sticker.dart index 89d9332..c6fa893 100644 --- a/lib/models/content/sticker.dart +++ b/lib/models/content/sticker.dart @@ -5,7 +5,7 @@ part "sticker.freezed.dart"; part "sticker.g.dart"; @freezed -abstract class StickerContent extends Content with _$StickerContent { +sealed class StickerContent extends Content with _$StickerContent { StickerContent._(); factory StickerContent({ required String body, diff --git a/lib/models/content/topic.dart b/lib/models/content/topic.dart index 8fa5229..c8256e3 100644 --- a/lib/models/content/topic.dart +++ b/lib/models/content/topic.dart @@ -1,11 +1,12 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:freezed_annotation/freezed_annotation.dart"; import "package:nexus/models/content/content.dart"; + part "topic.freezed.dart"; part "topic.g.dart"; @freezed -abstract class TopicContent extends Content with _$TopicContent { +sealed class TopicContent extends Content with _$TopicContent { TopicContent._(); factory TopicContent({ required String topic, @@ -16,24 +17,24 @@ abstract class TopicContent extends Content with _$TopicContent { _$TopicContentFromJson(json); } -@freezed -abstract class TopicContentBlock with _$TopicContentBlock { - factory TopicContentBlock({ - @Default(IList.empty()) - @JsonKey(name: "m.text") - IList representations, - }) = _TopicContentBlock; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const TopicContentBlock({ + final IList representations = const IList.empty(), +}) with _$TopicContentBlock { + Map toJson() => _$TopicContentBlockToJson(this); factory TopicContentBlock.fromJson(Map json) => _$TopicContentBlockFromJson(json); } -@freezed -abstract class TextualRepresentation with _$TextualRepresentation { - factory TextualRepresentation({ - required String body, - @Default("text/plain") String mimetype, - }) = _TextualRepresentation; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const TextualRepresentation({ + required final String body, + final String mimetype = "text/plain", +}) with _$TextualRepresentation { + Map toJson() => _$TextualRepresentationToJson(this); factory TextualRepresentation.fromJson(Map json) => _$TextualRepresentationFromJson(json); diff --git a/lib/models/emoji.dart b/lib/models/emoji.dart index 8e4eac6..149ae18 100644 --- a/lib/models/emoji.dart +++ b/lib/models/emoji.dart @@ -3,15 +3,16 @@ import "package:freezed_annotation/freezed_annotation.dart"; part "emoji.freezed.dart"; part "emoji.g.dart"; -@freezed -abstract class Emoji with _$Emoji { - const factory Emoji({ - required String emoji, - required String category, - required IList aliases, - required String description, - required IList tags, - }) = _Emoji; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class Emoji({ + required final String emoji, + required final String category, + required final IList aliases, + required final String description, + required final IList tags, +}) with _$Emoji { + Map toJson() => _$EmojiToJson(this); factory Emoji.fromJson(Map json) => _$EmojiFromJson(json); } diff --git a/lib/models/event.dart b/lib/models/event.dart index 28bf0ae..d06b41a 100644 --- a/lib/models/event.dart +++ b/lib/models/event.dart @@ -3,11 +3,39 @@ import "package:freezed_annotation/freezed_annotation.dart"; import "package:nexus/models/content/content.dart"; import "package:nexus/models/epoch_date_time_converter.dart"; import "package:nexus/models/profile_response.dart"; + part "event.freezed.dart"; part "event.g.dart"; -@freezed -abstract class Event with _$Event { +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const Event({ + @JsonKey(name: "rowid") required final int rowId, + @JsonKey(name: "timeline_rowid") required final int timelineRowId, + final String? stateKey, + required final String roomId, + required final String eventId, + required final String sender, + @JsonKey(readValue: Event.typeJsonFromJson) required final String type, + @EpochDateTimeConverter() @override required final DateTime timestamp, + final IMap unsigned = const IMap.empty(), + final LocalContent? localContent, + final String? transactionId, + final String? redactedBy, + final String? relatesTo, + final String? relationType, + final String? replyTo, + final String? decryptionError, + final String? sendError, + final IMap reactions = const IMap.empty(), + @JsonKey(name: "last_edit_rowid") @override final int lastEditRowId = 0, + @UnreadTypeConverter() @override final UnreadType? unreadType, + final Profile? pmp, + required final Content content, + required final Content? previousContent, +}) with _$Event { + Map toJson() => _$EventToJson(this); + static String typeJsonFromJson(Map json, _) => json["decrypted_type"] ?? json["type"]; @@ -25,32 +53,6 @@ abstract class Event with _$Event { } } - const factory Event({ - @JsonKey(name: "rowid") required int rowId, - @JsonKey(name: "timeline_rowid") required int timelineRowId, - required String roomId, - required String eventId, - required String sender, - @JsonKey(readValue: Event.typeJsonFromJson) required String type, - String? stateKey, - @EpochDateTimeConverter() required DateTime timestamp, - @Default(IMap.empty()) IMap unsigned, - LocalContent? localContent, - String? transactionId, - String? redactedBy, - String? relatesTo, - String? relationType, - String? replyTo, - String? decryptionError, - String? sendError, - @Default(IMap.empty()) IMap reactions, - @JsonKey(name: "last_edit_rowid") @Default(0) int lastEditRowId, - @UnreadTypeConverter() UnreadType? unreadType, - Profile? pmp, - required Content content, - required Content? previousContent, - }) = _Event; - factory Event.fromJson(Map json) => _$EventFromJson(json).copyWith( replyTo: replyToFromJson(getContentFromJson(json)), @@ -72,17 +74,19 @@ abstract class Event with _$Event { ); } -@freezed -abstract class LocalContent with _$LocalContent { - const factory LocalContent({ - String? sanitizedHtml, - String? editSource, - bool? wasPlaintext, - bool? bigEmoji, - bool? hasMath, - bool? replyFallbackRemoved, - }) = _LocalContent; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const LocalContent({ + final String? sanitizedHtml, + final String? editSource, + final bool? wasPlaintext, + final bool? bigEmoji, + final bool? hasMath, + final bool? replyFallbackRemoved, +}) with _$LocalContent { + Map toJson() => _$LocalContentToJson(this); + @override factory LocalContent.fromJson(Map json) => _$LocalContentFromJson(json); } diff --git a/lib/models/homeserver.dart b/lib/models/homeserver.dart index 903e23d..098dd12 100644 --- a/lib/models/homeserver.dart +++ b/lib/models/homeserver.dart @@ -1,12 +1,11 @@ import "package:freezed_annotation/freezed_annotation.dart"; + part "homeserver.freezed.dart"; @freezed -abstract class Homeserver with _$Homeserver { - const factory Homeserver({ - required String name, - required String description, - required Uri url, - required String iconUrl, - }) = _Homeserver; -} +class const Homeserver({ + @override required final String name, + @override required final String description, + @override required final Uri url, + @override required final String iconUrl, +}) with _$Homeserver; diff --git a/lib/models/info/audio.dart b/lib/models/info/audio.dart index ccfcf7a..ac90282 100644 --- a/lib/models/info/audio.dart +++ b/lib/models/info/audio.dart @@ -1,16 +1,17 @@ import "package:freezed_annotation/freezed_annotation.dart"; import "package:nexus/models/ms_duration.dart"; + part "audio.freezed.dart"; part "audio.g.dart"; -@freezed -abstract class AudioInfo with _$AudioInfo { - /// Information for images, [size] is in bytes. - const factory AudioInfo({ - @MSDuration() Duration? duration, - @JsonKey(name: "mimetype") String? mimeType, - int? size, - }) = _AudioInfo; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const AudioInfo({ + @MSDuration() final Duration? duration, + @JsonKey(name: "mimetype") final String? mimeType, + final int? size, +}) with _$AudioInfo { + Map toJson() => _$AudioInfoToJson(this); factory AudioInfo.fromJson(Map json) => _$AudioInfoFromJson(json); diff --git a/lib/models/info/file.dart b/lib/models/info/file.dart index 1509c99..ce0aa84 100644 --- a/lib/models/info/file.dart +++ b/lib/models/info/file.dart @@ -1,14 +1,15 @@ import "package:freezed_annotation/freezed_annotation.dart"; + part "file.freezed.dart"; part "file.g.dart"; -@freezed -abstract class FileInfo with _$FileInfo { - /// Information for images, [size] is in bytes. - const factory FileInfo({ - @JsonKey(name: "mimetype") String? mimeType, - int? size, - }) = _FileInfo; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const FileInfo({ + @JsonKey(name: "mimetype") final String? mimeType, + final int? size, +}) with _$FileInfo { + Map toJson() => _$FileInfoToJson(this); factory FileInfo.fromJson(Map json) => _$FileInfoFromJson(json); diff --git a/lib/models/info/image.dart b/lib/models/info/image.dart index 9833016..266fb01 100644 --- a/lib/models/info/image.dart +++ b/lib/models/info/image.dart @@ -1,17 +1,18 @@ import "package:freezed_annotation/freezed_annotation.dart"; + part "image.freezed.dart"; part "image.g.dart"; -@freezed -abstract class ImageInfo with _$ImageInfo { - /// Information for images, [size] is in bytes. - const factory ImageInfo({ - @JsonKey(name: "h") double? height, - @JsonKey(name: "w") double? width, - @JsonKey(name: "mimetype") String? mimeType, - @JsonKey(name: "xyz.amorgan.blurhash") String? blurHash, - int? size, - }) = _ImageInfo; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const ImageInfo({ + @JsonKey(name: "h") final double? height, + @JsonKey(name: "w") final double? width, + @JsonKey(name: "mimetype") final String? mimeType, + @JsonKey(name: "xyz.amorgan.blurhash") final String? blurHash, + final int? size, +}) with _$ImageInfo { + Map toJson() => _$ImageInfoToJson(this); factory ImageInfo.fromJson(Map json) => _$ImageInfoFromJson(json); diff --git a/lib/models/info/video.dart b/lib/models/info/video.dart index 6ff3547..31b1fb6 100644 --- a/lib/models/info/video.dart +++ b/lib/models/info/video.dart @@ -1,18 +1,19 @@ import "package:freezed_annotation/freezed_annotation.dart"; import "package:nexus/models/ms_duration.dart"; + part "video.freezed.dart"; part "video.g.dart"; -@freezed -abstract class VideoInfo with _$VideoInfo { - /// Information for images, [size] is in bytes. - const factory VideoInfo({ - @JsonKey(name: "h") int? height, - @JsonKey(name: "w") int? width, - @JsonKey(name: "mimetype") String? mimeType, - @MSDuration() Duration? duration, - int? size, - }) = _VideoInfo; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const VideoInfo({ + @JsonKey(name: "h") final int? height, + @JsonKey(name: "w") final int? width, + @JsonKey(name: "mimetype") final String? mimeType, + @MSDuration() final Duration? duration, + final int? size, +}) with _$VideoInfo { + Map toJson() => _$VideoInfoToJson(this); factory VideoInfo.fromJson(Map json) => _$VideoInfoFromJson(json); diff --git a/lib/models/lazy_load_summary.dart b/lib/models/lazy_load_summary.dart index 0cd250f..f9a814e 100644 --- a/lib/models/lazy_load_summary.dart +++ b/lib/models/lazy_load_summary.dart @@ -1,15 +1,17 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:freezed_annotation/freezed_annotation.dart"; + part "lazy_load_summary.freezed.dart"; part "lazy_load_summary.g.dart"; -@freezed -abstract class LazyLoadSummary with _$LazyLoadSummary { - const factory LazyLoadSummary({ - required IList? heroes, - required int? joinedMemberCount, - required int? invitedMemberCount, - }) = _LazyLoadSummary; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const LazyLoadSummary({ + required final IList? heroes, + required final int? joinedMemberCount, + required final int? invitedMemberCount, +}) with _$LazyLoadSummary { + Map toJson() => _$LazyLoadSummaryToJson(this); factory LazyLoadSummary.fromJson(Map json) => _$LazyLoadSummaryFromJson(json); diff --git a/lib/models/oauth_auth_code_response.dart b/lib/models/oauth_auth_code_response.dart index 5bb3f3f..3074335 100644 --- a/lib/models/oauth_auth_code_response.dart +++ b/lib/models/oauth_auth_code_response.dart @@ -1,14 +1,16 @@ import "package:freezed_annotation/freezed_annotation.dart"; + part "oauth_auth_code_response.freezed.dart"; part "oauth_auth_code_response.g.dart"; -@freezed -abstract class OAuthAuthCodeResponse with _$OAuthAuthCodeResponse { - const factory OAuthAuthCodeResponse({ - required String state, - required String codeVerifier, - required Uri url, - }) = _OAuthAuthCodeResponse; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const OAuthAuthCodeResponse({ + required final String state, + required final String codeVerifier, + required final Uri url, +}) with _$OAuthAuthCodeResponse { + Map toJson() => _$OAuthAuthCodeResponseToJson(this); factory OAuthAuthCodeResponse.fromJson(Map json) => _$OAuthAuthCodeResponseFromJson(json); diff --git a/lib/models/open_graph_data.dart b/lib/models/open_graph_data.dart index d7e840d..a183ef7 100644 --- a/lib/models/open_graph_data.dart +++ b/lib/models/open_graph_data.dart @@ -1,16 +1,18 @@ import "package:freezed_annotation/freezed_annotation.dart"; + part "open_graph_data.freezed.dart"; part "open_graph_data.g.dart"; -@freezed -abstract class OpenGraphData with _$OpenGraphData { - const factory OpenGraphData({ - @JsonKey(name: "og:title") required String? title, - @JsonKey(name: "og:description") required String? description, - @JsonKey(name: "og:image") required Uri? imageUrl, - @JsonKey(name: "og:image:width") required double? width, - @JsonKey(name: "og:image:height") required double? height, - }) = _OpenGraphData; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const OpenGraphData({ + @JsonKey(name: "og:title") required final String? title, + @JsonKey(name: "og:description") required final String? description, + @JsonKey(name: "og:image") required final Uri? imageUrl, + @JsonKey(name: "og:image:width") required final double? width, + @JsonKey(name: "og:image:height") required final double? height, +}) with _$OpenGraphData { + Map toJson() => _$OpenGraphDataToJson(this); factory OpenGraphData.fromJson(Map json) => _$OpenGraphDataFromJson(json); diff --git a/lib/models/paginate.dart b/lib/models/paginate.dart index df0a0f6..dc6eede 100644 --- a/lib/models/paginate.dart +++ b/lib/models/paginate.dart @@ -1,16 +1,18 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:freezed_annotation/freezed_annotation.dart"; import "package:nexus/models/event.dart"; + part "paginate.freezed.dart"; part "paginate.g.dart"; -@freezed -abstract class Paginate with _$Paginate { - const factory Paginate({ - required IList events, - required IList relatedEvents, - required bool hasMore, - }) = _Paginate; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const Paginate({ + required final IList events, + required final IList relatedEvents, + required final bool hasMore, +}) with _$Paginate { + Map toJson() => _$PaginateToJson(this); factory Paginate.fromJson(Map json) => _$PaginateFromJson(json); diff --git a/lib/models/profile_response.dart b/lib/models/profile_response.dart index 8b7b749..8984bcf 100644 --- a/lib/models/profile_response.dart +++ b/lib/models/profile_response.dart @@ -1,53 +1,55 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:freezed_annotation/freezed_annotation.dart"; import "package:nexus/models/content/membership.dart"; + part "profile_response.freezed.dart"; part "profile_response.g.dart"; -@freezed -abstract class ProfileResponse with _$ProfileResponse { - const factory ProfileResponse({ - @JsonKey(fromJson: Profile.fromJson) required Profile profile, - required Bio? bio, - }) = _ProfileResponse; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const ProfileResponse({ + @JsonKey(fromJson: Profile.fromJson) required final Profile profile, + required final Bio? bio, +}) with _$ProfileResponse { + Map toJson() => _$ProfileResponseToJson(this); factory ProfileResponse.fromJson(Map json) => _$ProfileResponseFromJson(json); } -@freezed -abstract class Bio with _$Bio { - const factory Bio({required String html, String? editSource}) = _Bio; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const Bio({required final String html, final String? editSource}) + with _$Bio { + Map toJson() => _$BioToJson(this); factory Bio.fromJson(Map json) => _$BioFromJson(json); } -@freezed -abstract class Profile with _$Profile { +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const Profile({ + final String? id, + final String? parseError, + final Uri? avatarUrl, + + @JsonKey(name: "displayname", fromJson: MembershipContent.displaynameFromJson) + final String? displayName, + + @JsonKey(readValue: Profile.readTimezone, name: "m.tz") + final String? timezone, + + @JsonKey(readValue: Profile.readPronouns, name: "m.pronouns") + final IList pronouns = const IList.empty(), +}) with _$Profile { + Map toJson() => _$ProfileToJson(this); + static Object? readPronouns(Map map, String key) => map[key] ?? map["io.fsky.nyx.pronouns"]; static Object? readTimezone(Map map, String key) => map[key] ?? map["us.cloke.msc4175.tz"]; - const factory Profile({ - String? id, - String? parseError, - Uri? avatarUrl, - - @JsonKey( - name: "displayname", - fromJson: MembershipContent.displaynameFromJson, - ) - String? displayName, - - @JsonKey(readValue: Profile.readTimezone, name: "m.tz") String? timezone, - - @Default(IList.empty()) - @JsonKey(readValue: Profile.readPronouns, name: "m.pronouns") - IList pronouns, - }) = _Profile; - factory Profile.fromJson(Map json) => _$ProfileFromJson(json); @@ -55,15 +57,18 @@ abstract class Profile with _$Profile { try { return Profile.fromJson(json); } catch (error) { - return Profile(parseError: error.toString()); + return _Profile(parseError: error.toString()); } } } -@freezed -abstract class Pronoun with _$Pronoun { - const factory Pronoun({required String language, required String summary}) = - _Pronoun; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const Pronoun({ + required final String language, + required final String summary, +}) with _$Pronoun { + Map toJson() => _$PronounToJson(this); factory Pronoun.fromJson(Map json) => _$PronounFromJson(json); diff --git a/lib/models/read_receipt.dart b/lib/models/read_receipt.dart index d533e2d..ab4edd8 100644 --- a/lib/models/read_receipt.dart +++ b/lib/models/read_receipt.dart @@ -1,17 +1,19 @@ import "package:freezed_annotation/freezed_annotation.dart"; import "package:nexus/models/epoch_date_time_converter.dart"; + part "read_receipt.freezed.dart"; part "read_receipt.g.dart"; -@freezed -abstract class ReadReceipt with _$ReadReceipt { - const factory ReadReceipt({ - String? roomId, - required String userId, - String? threadId, - required String eventId, - @EpochDateTimeConverter() required DateTime timestamp, - }) = _ReadReceipt; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const ReadReceipt({ + final String? roomId, + required final String userId, + final String? threadId, + required final String eventId, + @EpochDateTimeConverter() required final DateTime timestamp, +}) with _$ReadReceipt { + Map toJson() => _$ReadReceiptToJson(this); factory ReadReceipt.fromJson(Map json) => _$ReadReceiptFromJson(json); diff --git a/lib/models/requests/download_media.dart b/lib/models/requests/download_media.dart index b5d5771..c9751f8 100644 --- a/lib/models/requests/download_media.dart +++ b/lib/models/requests/download_media.dart @@ -1,15 +1,17 @@ import "package:freezed_annotation/freezed_annotation.dart"; + part "download_media.freezed.dart"; part "download_media.g.dart"; -@freezed -abstract class DownloadMediaRequest with _$DownloadMediaRequest { - const factory DownloadMediaRequest({ - required Uri mxc, - @Default(false) bool encrypted, - @Default(false) bool isAvatar, - @Default(false) bool thumbnailAvatar, - }) = _DownloadMediaRequest; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const DownloadMediaRequest({ + required final Uri mxc, + final bool encrypted = false, + final bool isAvatar = false, + final bool thumbnailAvatar = false, +}) with _$DownloadMediaRequest { + Map toJson() => _$DownloadMediaRequestToJson(this); factory DownloadMediaRequest.fromJson(Map json) => _$DownloadMediaRequestFromJson(json); diff --git a/lib/models/requests/get_event.dart b/lib/models/requests/get_event.dart index 2665a2a..b4692ee 100644 --- a/lib/models/requests/get_event.dart +++ b/lib/models/requests/get_event.dart @@ -1,14 +1,16 @@ import "package:freezed_annotation/freezed_annotation.dart"; + part "get_event.freezed.dart"; part "get_event.g.dart"; -@freezed -abstract class GetEventRequest with _$GetEventRequest { - const factory GetEventRequest({ - required String roomId, - required String eventId, - @Default(false) bool unredact, - }) = _GetEventRequest; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const GetEventRequest({ + required final String roomId, + required final String eventId, + final bool unredact = false, +}) with _$GetEventRequest { + Map toJson() => _$GetEventRequestToJson(this); factory GetEventRequest.fromJson(Map json) => _$GetEventRequestFromJson(json); diff --git a/lib/models/requests/get_related_events.dart b/lib/models/requests/get_related_events.dart index 52d2716..08be426 100644 --- a/lib/models/requests/get_related_events.dart +++ b/lib/models/requests/get_related_events.dart @@ -1,14 +1,16 @@ import "package:freezed_annotation/freezed_annotation.dart"; + part "get_related_events.freezed.dart"; part "get_related_events.g.dart"; -@freezed -abstract class GetRelatedEventsRequest with _$GetRelatedEventsRequest { - const factory GetRelatedEventsRequest({ - required String roomId, - required String eventId, - required String relationType, - }) = _GetRelatedEventsRequest; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const GetRelatedEventsRequest({ + required final String roomId, + required final String eventId, + required final String relationType, +}) with _$GetRelatedEventsRequest { + Map toJson() => _$GetRelatedEventsRequestToJson(this); factory GetRelatedEventsRequest.fromJson(Map json) => _$GetRelatedEventsRequestFromJson(json); diff --git a/lib/models/requests/get_room_state.dart b/lib/models/requests/get_room_state.dart index d3f52f7..66504da 100644 --- a/lib/models/requests/get_room_state.dart +++ b/lib/models/requests/get_room_state.dart @@ -1,15 +1,17 @@ import "package:freezed_annotation/freezed_annotation.dart"; + part "get_room_state.freezed.dart"; part "get_room_state.g.dart"; -@freezed -abstract class GetRoomStateRequest with _$GetRoomStateRequest { - const factory GetRoomStateRequest({ - required String roomId, - @Default(false) bool refetch, - @Default(false) bool fetchMembers, - @Default(false) bool includeMembers, - }) = _GetRoomStateRequest; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const GetRoomStateRequest({ + required final String roomId, + final bool refetch = false, + final bool fetchMembers = false, + final bool includeMembers = false, +}) with _$GetRoomStateRequest { + Map toJson() => _$GetRoomStateRequestToJson(this); factory GetRoomStateRequest.fromJson(Map json) => _$GetRoomStateRequestFromJson(json); diff --git a/lib/models/requests/join_room.dart b/lib/models/requests/join_room.dart index 72cce7f..350b762 100644 --- a/lib/models/requests/join_room.dart +++ b/lib/models/requests/join_room.dart @@ -1,14 +1,16 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:freezed_annotation/freezed_annotation.dart"; + part "join_room.freezed.dart"; part "join_room.g.dart"; -@freezed -abstract class JoinRoomRequest with _$JoinRoomRequest { - const factory JoinRoomRequest({ - required String roomIdOrAlias, - @Default(IList.empty()) IList via, - }) = _JoinRoomRequest; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const JoinRoomRequest({ + required final String roomIdOrAlias, + final IList via = const IList.empty(), +}) with _$JoinRoomRequest { + Map toJson() => _$JoinRoomRequestToJson(this); factory JoinRoomRequest.fromJson(Map json) => _$JoinRoomRequestFromJson(json); diff --git a/lib/models/requests/oauth/exchange_token.dart b/lib/models/requests/oauth/exchange_token.dart index 9d55c1f..fb47358 100644 --- a/lib/models/requests/oauth/exchange_token.dart +++ b/lib/models/requests/oauth/exchange_token.dart @@ -1,16 +1,18 @@ import "package:freezed_annotation/freezed_annotation.dart"; + part "exchange_token.freezed.dart"; part "exchange_token.g.dart"; -@freezed -abstract class OAuthExchangeTokenRequest with _$OAuthExchangeTokenRequest { - const factory OAuthExchangeTokenRequest({ - required Uri homeserverUrl, - required String codeVerifier, - required Uri redirectUri, - required String code, - required String clientId, - }) = _OAuthExchangeTokenRequest; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const OAuthExchangeTokenRequest({ + required final Uri homeserverUrl, + required final String codeVerifier, + required final Uri redirectUri, + required final String code, + required final String clientId, +}) with _$OAuthExchangeTokenRequest { + Map toJson() => _$OAuthExchangeTokenRequestToJson(this); factory OAuthExchangeTokenRequest.fromJson(Map json) => _$OAuthExchangeTokenRequestFromJson(json); diff --git a/lib/models/requests/oauth/get_auth_url.dart b/lib/models/requests/oauth/get_auth_url.dart index 5ca5b6f..1ff166a 100644 --- a/lib/models/requests/oauth/get_auth_url.dart +++ b/lib/models/requests/oauth/get_auth_url.dart @@ -2,25 +2,27 @@ import "dart:math"; import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:freezed_annotation/freezed_annotation.dart"; + part "get_auth_url.freezed.dart"; part "get_auth_url.g.dart"; -@freezed -abstract class OAuthGetAuthUrl with _$OAuthGetAuthUrl { - const factory OAuthGetAuthUrl({ - required ResponseMode responseMode, - required Uri homeserverUrl, - required Uri redirectUri, - required IList scopes, - required String clientId, - String? userIdHint, - }) = _OAuthGetAuthUrl; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const OAuthGetAuthUrl({ + required final ResponseMode responseMode, + required final Uri homeserverUrl, + required final Uri redirectUri, + required final IList scopes, + required final String clientId, + final String? userIdHint, +}) with _$OAuthGetAuthUrl { + Map toJson() => _$OAuthGetAuthUrlToJson(this); factory OAuthGetAuthUrl.fromJson(Map json) => _$OAuthGetAuthUrlFromJson(json); } -abstract class Scope { +sealed class Scope { static final openid = "openid"; static final email = "email"; static final clientApi = "urn:matrix:client:api:*"; diff --git a/lib/models/requests/oauth/register_client.dart b/lib/models/requests/oauth/register_client.dart index cf4f9e0..e5c1a70 100644 --- a/lib/models/requests/oauth/register_client.dart +++ b/lib/models/requests/oauth/register_client.dart @@ -1,26 +1,27 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:freezed_annotation/freezed_annotation.dart"; + part "register_client.freezed.dart"; part "register_client.g.dart"; -@freezed -abstract class OAuthRegisterClientRequest with _$OAuthRegisterClientRequest { - const factory OAuthRegisterClientRequest({ - required Uri homeserverUrl, - @Default(ApplicationType.web) ApplicationType applicationType, - String? clientName, - required Uri clientUri, - Uri? logoUri, - Uri? policyUri, - Uri? tosUri, - IList? grantTypes, - IList? redirectUris, - IList? responseTypes, +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const OAuthRegisterClientRequest({ + required final Uri homeserverUrl, + final ApplicationType applicationType = ApplicationType.web, + final String? clientName, + required final Uri clientUri, + final Uri? logoUri, + final Uri? policyUri, + final Uri? tosUri, + final IList? grantTypes, + final IList? redirectUris, + final IList? responseTypes, - @Default(AuthMethod.none) - @JsonKey(name: "token_endpoint_auth_method") - AuthMethod? authMethod, - }) = _OAuthRegisterClientRequest; + @JsonKey(name: "token_endpoint_auth_method") + final AuthMethod? authMethod = AuthMethod.none, +}) with _$OAuthRegisterClientRequest { + Map toJson() => _$OAuthRegisterClientRequestToJson(this); factory OAuthRegisterClientRequest.fromJson(Map json) => _$OAuthRegisterClientRequestFromJson(json); diff --git a/lib/models/requests/paginate.dart b/lib/models/requests/paginate.dart index ddc62f3..b3903c6 100644 --- a/lib/models/requests/paginate.dart +++ b/lib/models/requests/paginate.dart @@ -1,14 +1,16 @@ import "package:freezed_annotation/freezed_annotation.dart"; + part "paginate.freezed.dart"; part "paginate.g.dart"; -@freezed -abstract class PaginateRequest with _$PaginateRequest { - const factory PaginateRequest({ - required String roomId, - required int? maxTimelineId, - @Default(20) int limit, - }) = _PaginateRequest; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const PaginateRequest({ + required final String roomId, + required final int? maxTimelineId, + final int limit = 20, +}) with _$PaginateRequest { + Map toJson() => _$PaginateRequestToJson(this); factory PaginateRequest.fromJson(Map json) => _$PaginateRequestFromJson(json); diff --git a/lib/models/requests/report.dart b/lib/models/requests/report.dart index f87b1f1..ed05715 100644 --- a/lib/models/requests/report.dart +++ b/lib/models/requests/report.dart @@ -1,14 +1,16 @@ import "package:freezed_annotation/freezed_annotation.dart"; + part "report.freezed.dart"; part "report.g.dart"; -@freezed -abstract class ReportRequest with _$ReportRequest { - const factory ReportRequest({ - required String roomId, - required String eventId, - String? reason, - }) = _ReportRequest; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const ReportRequest({ + required final String roomId, + required final String eventId, + final String? reason, +}) with _$ReportRequest { + Map toJson() => _$ReportRequestToJson(this); factory ReportRequest.fromJson(Map json) => _$ReportRequestFromJson(json); diff --git a/lib/models/requests/send_event.dart b/lib/models/requests/send_event.dart index 196c0b5..acad57f 100644 --- a/lib/models/requests/send_event.dart +++ b/lib/models/requests/send_event.dart @@ -1,19 +1,21 @@ import "package:freezed_annotation/freezed_annotation.dart"; import "package:nexus/models/content/content.dart"; + part "send_event.freezed.dart"; part "send_event.g.dart"; -@freezed -abstract class SendEventRequest with _$SendEventRequest { - const factory SendEventRequest({ - required String roomId, - required String type, - required Content content, - String? relatesTo, - String? relationType, - @Default(false) bool synchronous, - @Default(false) bool disableEncryption, - }) = _SendEventRequest; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const SendEventRequest({ + required final String roomId, + required final String type, + required final Content content, + final String? relatesTo, + final String? relationType, + final bool synchronous = false, + final bool disableEncryption = false, +}) with _$SendEventRequest { + Map toJson() => _$SendEventRequestToJson(this); factory SendEventRequest.fromJson(Map json) => _$SendEventRequestFromJson(json); diff --git a/lib/models/requests/send_message.dart b/lib/models/requests/send_message.dart index 951198e..e9bbbb2 100644 --- a/lib/models/requests/send_message.dart +++ b/lib/models/requests/send_message.dart @@ -2,43 +2,42 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:freezed_annotation/freezed_annotation.dart"; import "package:nexus/models/content/content.dart"; import "package:nexus/models/relation_type.dart"; + part "send_message.freezed.dart"; part "send_message.g.dart"; -@freezed -abstract class SendMessageRequest with _$SendMessageRequest { - const factory SendMessageRequest({ - required String roomId, - required String text, - Content? baseContent, - @Default(Mentions()) @JsonKey(name: "mentions") Mentions mentions, - @JsonKey(name: "relates_to") Relation? relation, - }) = _SendMessageRequest; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const SendMessageRequest({ + required final String roomId, + required final String text, + final Content? baseContent, + @JsonKey(name: "mentions") final Mentions mentions = const Mentions(), + @JsonKey(name: "relates_to") final Relation? relation, +}) with _$SendMessageRequest { + Map toJson() => _$SendMessageRequestToJson(this); factory SendMessageRequest.fromJson(Map json) => _$SendMessageRequestFromJson(json); } -@freezed -abstract class Mentions with _$Mentions { - const factory Mentions({ - @Default(false) bool room, - @Default(IList.empty()) IList userIds, - }) = _Mentions; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const Mentions({ + final bool room = false, + final IList userIds = const IList.empty(), +}) with _$Mentions { + Map toJson() => _$MentionsToJson(this); factory Mentions.fromJson(Map json) => _$MentionsFromJson(json); } @Freezed(toJson: false) -abstract class Relation with _$Relation { - const Relation._(); - - const factory Relation({ - required String eventId, - required RelationType relationType, - }) = _Relation; - +class const Relation({ + required final String eventId, + required final RelationType relationType, +}) with _$Relation { Map toJson() { switch (relationType) { case RelationType.reply: diff --git a/lib/models/requests/set_account_data.dart b/lib/models/requests/set_account_data.dart index ffccdb4..95ef75c 100644 --- a/lib/models/requests/set_account_data.dart +++ b/lib/models/requests/set_account_data.dart @@ -1,14 +1,16 @@ import "package:freezed_annotation/freezed_annotation.dart"; + part "set_account_data.freezed.dart"; part "set_account_data.g.dart"; -@freezed -abstract class SetAccountDataRequest with _$SetAccountDataRequest { - const factory SetAccountDataRequest({ - required String type, - required dynamic content, - String? roomId, - }) = _SetAccountDataRequest; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const SetAccountDataRequest({ + required final String type, + required final dynamic content, + final String? roomId, +}) with _$SetAccountDataRequest { + Map toJson() => _$SetAccountDataRequestToJson(this); factory SetAccountDataRequest.fromJson(Map json) => _$SetAccountDataRequestFromJson(json); diff --git a/lib/models/requests/set_membership.dart b/lib/models/requests/set_membership.dart index 4bbe8a3..9d88da2 100644 --- a/lib/models/requests/set_membership.dart +++ b/lib/models/requests/set_membership.dart @@ -1,18 +1,19 @@ import "package:freezed_annotation/freezed_annotation.dart"; import "package:nexus/models/membership_action.dart"; + part "set_membership.freezed.dart"; part "set_membership.g.dart"; -@freezed -abstract class SetMembershipRequest with _$SetMembershipRequest { - const factory SetMembershipRequest({ - required String userId, - required String roomId, - - String? reason, - @JsonKey(name: "action") required MembershipAction action, - @Default(false) @JsonKey(name: "msc4293_redact_events") bool redact, - }) = _SetMembershipRequest; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const SetMembershipRequest({ + required final String userId, + required final String roomId, + final String? reason, + @JsonKey(name: "action") required final MembershipAction action, + @JsonKey(name: "msc4293_redact_events") final bool redact = false, +}) with _$SetMembershipRequest { + Map toJson() => _$SetMembershipRequestToJson(this); factory SetMembershipRequest.fromJson(Map json) => _$SetMembershipRequestFromJson(json); diff --git a/lib/models/requests/set_state.dart b/lib/models/requests/set_state.dart index c92763d..d0e3e95 100644 --- a/lib/models/requests/set_state.dart +++ b/lib/models/requests/set_state.dart @@ -1,22 +1,23 @@ import "package:freezed_annotation/freezed_annotation.dart"; import "package:nexus/models/content/content.dart"; import "package:nexus/models/ms_duration.dart"; + part "set_state.freezed.dart"; part "set_state.g.dart"; -@freezed -abstract class SetStateRequest with _$SetStateRequest { - const factory SetStateRequest({ - required String roomId, - required String type, - required String stateKey, - required Content content, +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const SetStateRequest({ + required final String roomId, + required final String type, + required final String stateKey, + required final Content content, - @JsonKey(name: "delay_ms", includeIfNull: false) - @MSDuration() - @Default(null) - Duration? delay, - }) = _SetStateRequest; + @JsonKey(name: "delay_ms", includeIfNull: false) + @MSDuration() + final Duration? delay, +}) with _$SetStateRequest { + Map toJson() => _$SetStateRequestToJson(this); factory SetStateRequest.fromJson(Map json) => _$SetStateRequestFromJson(json); diff --git a/lib/models/requests/upload_media.dart b/lib/models/requests/upload_media.dart index a640bea..d6e69ac 100644 --- a/lib/models/requests/upload_media.dart +++ b/lib/models/requests/upload_media.dart @@ -1,23 +1,26 @@ import "package:freezed_annotation/freezed_annotation.dart"; + part "upload_media.freezed.dart"; part "upload_media.g.dart"; -@freezed -abstract class UploadMediaRequest with _$UploadMediaRequest { - const factory UploadMediaRequest({ - required String path, - required bool encrypt, - String? filename, - @Default(false) @JsonKey(name: "voice_message") bool isVoiceMessage, - @Default(false) bool forceFile, - - // Below params only work if encodeTo is set - String? encodeTo, - int? resizeWidth, - int? resizeHeight, - int? resizePercent, - @Default(80) int quality, - }) = _UploadMediaRequest; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const UploadMediaRequest({ + required final String path, + required final bool encrypt, + final String? filename, + @JsonKey(name: "voice_message") final bool isVoiceMessage = false, + final bool forceFile = false, + final + // Below params only work if encodeTo is set + String? + encodeTo, + final int? resizeWidth, + final int? resizeHeight, + final int? resizePercent, + final int quality = 80, +}) with _$UploadMediaRequest { + Map toJson() => _$UploadMediaRequestToJson(this); factory UploadMediaRequest.fromJson(Map json) => _$UploadMediaRequestFromJson(json); diff --git a/lib/models/room.dart b/lib/models/room.dart index fb21a55..d030043 100644 --- a/lib/models/room.dart +++ b/lib/models/room.dart @@ -3,11 +3,38 @@ import "package:freezed_annotation/freezed_annotation.dart"; import "package:nexus/models/event.dart"; import "package:nexus/models/read_receipt.dart"; import "package:nexus/models/room_metadata.dart"; + part "room.freezed.dart"; part "room.g.dart"; -@freezed -abstract class Room with _$Room { +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const Room({ + @JsonKey(name: "meta") final RoomMetadata? metadata, + + @JsonKey(fromJson: Room.timelineTupleJsonToIMap) + final IMap timeline = const IMap.empty(), + + final ISet sticky = const ISet.empty(), + + @JsonKey(fromJson: Room.eventsJsonToIMap) + final IMap events = const IMap.empty(), + + final bool reset = false, + final bool hasFetchedState = false, + final bool hasFetchedMembers = false, + final IMap> state = const IMap.empty(), + + final IMap> receipts = const IMap.empty(), + final bool dismissNotifications = false, + final bool hasMore = true, + + // IMap accountData, + // IList notifications, +}) with _$Room { + /// [timeline] is an IMap of timelineRowId to eventRowId + /// [events] is an IMap of eventRowId to event + /// [sticky] is an ISet of eventRowId static IMap timelineTupleJsonToIMap(List json) => IMap.fromEntries( json.map( @@ -26,32 +53,7 @@ abstract class Room with _$Room { }), ); - /// [timeline] is an IMap of timelineRowId to eventRowId - /// [events] is an IMap of eventRowId to event - /// [sticky] is an ISet of eventRowId - const factory Room({ - @JsonKey(name: "meta") RoomMetadata? metadata, - @Default(IMap.empty()) - @JsonKey(fromJson: Room.timelineTupleJsonToIMap) - IMap timeline, - @Default(ISet.empty()) ISet sticky, - - @Default(IMap.empty()) - @JsonKey(fromJson: Room.eventsJsonToIMap) - IMap events, - - @Default(false) bool reset, - @Default(false) bool hasFetchedState, - @Default(false) bool hasFetchedMembers, - @Default(IMap.empty()) IMap> state, - - @Default(IMap.empty()) IMap> receipts, - @Default(false) bool dismissNotifications, - @Default(true) bool hasMore, - - // required IMap accountData, - // required IList notifications, - }) = _Room; + Map toJson() => _$RoomToJson(this); factory Room.fromJson(Map json) => _$RoomFromJson(json); } diff --git a/lib/models/room_metadata.dart b/lib/models/room_metadata.dart index 7c16cae..3aafd0e 100644 --- a/lib/models/room_metadata.dart +++ b/lib/models/room_metadata.dart @@ -1,29 +1,31 @@ import "package:freezed_annotation/freezed_annotation.dart"; import "package:nexus/models/epoch_date_time_converter.dart"; import "package:nexus/models/lazy_load_summary.dart"; + part "room_metadata.freezed.dart"; part "room_metadata.g.dart"; -@freezed -abstract class RoomMetadata with _$RoomMetadata { - const factory RoomMetadata({ - @JsonKey(name: "room_id") required String id, +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const RoomMetadata({ + @JsonKey(name: "room_id") required final String id, - // required CreateEventContent creationContent, - // required TombstoneEventContent tombstoneEventContent, - String? name, - Uri? avatar, - String? dmUserId, - String? topic, - String? canonicalAlias, - LazyLoadSummary? lazyLoadSummary, - required bool hasMemberList, - @JsonKey(name: "preview_event_rowid") required int previewEventRowID, - @EpochDateTimeConverter() required DateTime sortingTimestamp, - required int unreadHighlights, - required int unreadNotifications, - required int unreadMessages, - }) = _RoomMetadata; + // CreateEventContent creationContent, + // TombstoneEventContent tombstoneEventContent, + final String? name, + final Uri? avatar, + final String? dmUserId, + final String? topic, + final String? canonicalAlias, + final LazyLoadSummary? lazyLoadSummary, + required final bool hasMemberList, + @JsonKey(name: "preview_event_rowid") required final int previewEventRowID, + @EpochDateTimeConverter() required final DateTime sortingTimestamp, + required final int unreadHighlights, + required final int unreadNotifications, + required final int unreadMessages, +}) with _$RoomMetadata { + Map toJson() => _$RoomMetadataToJson(this); factory RoomMetadata.fromJson(Map json) => _$RoomMetadataFromJson(json); diff --git a/lib/models/room_summary.dart b/lib/models/room_summary.dart index d0ee96b..7c2d6d2 100644 --- a/lib/models/room_summary.dart +++ b/lib/models/room_summary.dart @@ -1,22 +1,24 @@ 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; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const RoomSummary({ + required final String roomId, + @JsonKey(name: "num_joined_members") required final int joinedMembers, + final JoinRule? joinRule, + final String? name, + final Uri? avatarUrl, + final String? canonicalAlias, + final String? topic, + final String? roomVersion, + @JsonKey(unknownEnumValue: RoomType.room) final RoomType? roomType, +}) with _$RoomSummary { + Map toJson() => _$RoomSummaryToJson(this); factory RoomSummary.fromJson(Map json) => _$RoomSummaryFromJson(json); diff --git a/lib/models/setting.dart b/lib/models/setting.dart index 6a49845..2ff541d 100644 --- a/lib/models/setting.dart +++ b/lib/models/setting.dart @@ -1,16 +1,13 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; -class Setting { - final String title; - final String description; - final IconData icon; - final Widget Function(String title, String description, IconData icon) - builder; - - Setting({ - required this.title, - required this.description, - required this.builder, - required this.icon, - }); -} +class Setting({ + required final String title, + required final String description, + required final IconData icon, + required final Widget Function( + String title, + String description, + IconData icon, + ) + builder, +}); diff --git a/lib/models/settings.dart b/lib/models/settings.dart index eddc2da..7f73375 100644 --- a/lib/models/settings.dart +++ b/lib/models/settings.dart @@ -1,15 +1,17 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:freezed_annotation/freezed_annotation.dart"; + part "settings.freezed.dart"; part "settings.g.dart"; -@freezed -abstract class Settings with _$Settings { - const factory Settings({ - @Default(ThemeMode.system) ThemeMode theme, - @Default(true) bool useDynamicTheming, - @Default(false) bool linuxMobileMode, - }) = _Settings; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const Settings({ + final ThemeMode theme = ThemeMode.system, + final bool useDynamicTheming = true, + final bool linuxMobileMode = false, +}) with _$Settings { + Map toJson() => _$SettingsToJson(this); factory Settings.fromJson(Map json) => _$SettingsFromJson(json); diff --git a/lib/models/settings_category.dart b/lib/models/settings_category.dart index 88bfdd0..2dc7076 100644 --- a/lib/models/settings_category.dart +++ b/lib/models/settings_category.dart @@ -1,14 +1,13 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:freezed_annotation/freezed_annotation.dart"; import "package:nexus/models/setting.dart"; + part "settings_category.freezed.dart"; @freezed -abstract class SettingsCategory with _$SettingsCategory { - const factory SettingsCategory({ - required String title, - required IconData icon, - required IList settings, - }) = _SettingsCategory; -} +class const SettingsCategory({ + required final String title, + required final IconData icon, + required final IList settings, +}) with _$SettingsCategory; diff --git a/lib/models/space.dart b/lib/models/space.dart index 73fbbc6..97efe7a 100644 --- a/lib/models/space.dart +++ b/lib/models/space.dart @@ -3,16 +3,15 @@ import "package:flutter/widgets.dart"; import "package:freezed_annotation/freezed_annotation.dart"; import "package:nexus/models/room.dart"; import "package:nexus/models/subspace.dart"; + part "space.freezed.dart"; @freezed -abstract class Space with _$Space { - const factory Space({ - required String id, - required String title, - IconData? icon, - Room? room, - required IList children, - required IList subSpaces, - }) = _Space; -} +class const Space({ + required final String id, + required final String title, + final IconData? icon, + final Room? room, + required final IList children, + required final IList subSpaces, +}) with _$Space; diff --git a/lib/models/space_edge.dart b/lib/models/space_edge.dart index 192af31..ea74130 100644 --- a/lib/models/space_edge.dart +++ b/lib/models/space_edge.dart @@ -1,13 +1,15 @@ import "package:freezed_annotation/freezed_annotation.dart"; + part "space_edge.freezed.dart"; part "space_edge.g.dart"; -@freezed -abstract class SpaceEdge with _$SpaceEdge { - const factory SpaceEdge({ - required String childId, - @Default(false) bool suggested, - }) = _SpaceEdge; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const SpaceEdge({ + required final String childId, + final bool suggested = false, +}) with _$SpaceEdge { + Map toJson() => _$SpaceEdgeToJson(this); factory SpaceEdge.fromJson(Map json) => _$SpaceEdgeFromJson(json); diff --git a/lib/models/spec_versions_response.dart b/lib/models/spec_versions_response.dart index 07a3ada..1f414d2 100644 --- a/lib/models/spec_versions_response.dart +++ b/lib/models/spec_versions_response.dart @@ -1,24 +1,27 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:freezed_annotation/freezed_annotation.dart"; + part "spec_versions_response.freezed.dart"; part "spec_versions_response.g.dart"; -@freezed -abstract class SpecVersionsResponse with _$SpecVersionsResponse { - const factory SpecVersionsResponse({ - required IList versions, - required UnstableFeatures unstableFeatures, - }) = _SpecVersionsResponse; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const SpecVersionsResponse({ + required final IList versions, + required final UnstableFeatures unstableFeatures, +}) with _$SpecVersionsResponse { + Map toJson() => _$SpecVersionsResponseToJson(this); factory SpecVersionsResponse.fromJson(Map json) => _$SpecVersionsResponseFromJson(json); } -@freezed -abstract class UnstableFeatures with _$UnstableFeatures { - const factory UnstableFeatures({ - @JsonKey(name: "uk.timedout.msc4494") @Default(false) bool msc4494, - }) = _UnstableFeatures; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const UnstableFeatures({ + @JsonKey(name: "uk.timedout.msc4494") final bool msc4494 = false, +}) with _$UnstableFeatures { + Map toJson() => _$UnstableFeaturesToJson(this); factory UnstableFeatures.fromJson(Map json) => _$UnstableFeaturesFromJson(json); diff --git a/lib/models/subspace.dart b/lib/models/subspace.dart index 1a1879c..97d1de2 100644 --- a/lib/models/subspace.dart +++ b/lib/models/subspace.dart @@ -1,10 +1,11 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:freezed_annotation/freezed_annotation.dart"; import "package:nexus/models/room.dart"; + part "subspace.freezed.dart"; @freezed -abstract class Subspace with _$Subspace { - const factory Subspace({required Room room, required IList children}) = - _Subspace; -} +class const Subspace({ + required final Room room, + required final IList children, +}) with _$Subspace; diff --git a/lib/models/sync_data.dart b/lib/models/sync_data.dart index b2699d6..a9c10bf 100644 --- a/lib/models/sync_data.dart +++ b/lib/models/sync_data.dart @@ -2,20 +2,21 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:freezed_annotation/freezed_annotation.dart"; import "package:nexus/models/room.dart"; import "package:nexus/models/space_edge.dart"; + part "sync_data.freezed.dart"; part "sync_data.g.dart"; -@freezed -abstract class SyncData with _$SyncData { - const factory SyncData({ - @Default(false) bool clearState, - @Default(IMap.empty()) IMap> accountData, - @Default(IMap.empty()) IMap rooms, - @Default(ISet.empty()) ISet leftRooms, - // required IList invitedRooms, - IMap>? spaceEdges, - IList? topLevelSpaces, - }) = _SyncData; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const SyncData({ + final bool clearState = false, + final IMap> accountData = const IMap.empty(), + final IMap rooms = const IMap.empty(), + final ISet leftRooms = const ISet.empty(), + final IMap>? spaceEdges, + final IList? topLevelSpaces, +}) with _$SyncData { + Map toJson() => _$SyncDataToJson(this); factory SyncData.fromJson(Map json) => _$SyncDataFromJson(json); diff --git a/lib/models/sync_status.dart b/lib/models/sync_status.dart index 7848fbe..57bd882 100644 --- a/lib/models/sync_status.dart +++ b/lib/models/sync_status.dart @@ -1,14 +1,16 @@ import "package:freezed_annotation/freezed_annotation.dart"; + part "sync_status.freezed.dart"; part "sync_status.g.dart"; -@freezed -abstract class SyncStatus with _$SyncStatus { - const factory SyncStatus({ - required SyncStatusType type, - String? error, - required int errorCount, - }) = _SyncStatus; +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const SyncStatus({ + required final SyncStatusType type, + required final String? error, + required final int errorCount, +}) with _$SyncStatus { + Map toJson() => _$SyncStatusToJson(this); factory SyncStatus.fromJson(Map json) => _$SyncStatusFromJson(json); diff --git a/lib/pages/chat.dart b/lib/pages/chat.dart index 316c9af..c58b7a7 100644 --- a/lib/pages/chat.dart +++ b/lib/pages/chat.dart @@ -1,4 +1,4 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:nexus/controllers/emoji.dart"; import "package:nexus/controllers/init_complete.dart"; @@ -8,9 +8,7 @@ import "package:nexus/widgets/sidebar.dart"; import "package:nexus/widgets/room_chat.dart"; import "package:nexus/widgets/loading.dart"; -class ChatPage extends ConsumerWidget { - const ChatPage({super.key}); - +class const ChatPage({super.key}) extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) => LayoutBuilder( builder: (context, constraints) { diff --git a/lib/pages/select_server.dart b/lib/pages/select_server.dart index e8e689b..f894d13 100644 --- a/lib/pages/select_server.dart +++ b/lib/pages/select_server.dart @@ -1,5 +1,5 @@ import "package:app_links/app_links.dart"; -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:flutter_svg/flutter_svg.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; @@ -13,9 +13,7 @@ import "package:nexus/pages/settings.dart"; import "package:nexus/widgets/appbar.dart"; import "package:nexus/widgets/divider_text.dart"; -class SelectServerPage extends HookConsumerWidget { - const SelectServerPage({super.key}); - +class const SelectServerPage({super.key}) extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final theme = Theme.of(context); @@ -181,23 +179,20 @@ class SelectServerPage extends HookConsumerWidget { ...([ .new( name: "Matrix.org", - description: - "The Matrix.org Foundation offers the matrix.org homeserver as an easy entry point for anyone wanting to try out Matrix.", + description: "The Matrix.org Foundation offers the matrix.org homeserver as an easy entry point for anyone wanting to try out Matrix.", url: .https("matrix.org"), iconUrl: "https://raw.githubusercontent.com/element-hq/logos/refs/heads/master/matrix/matrix-favicon${Theme.brightnessOf(context) == Brightness.dark ? "-white" : ""}.png", ), .new( name: "Federated Nexus", - description: - "Federated Nexus is a community resource hosting multiple FOSS (especially federated) services, including Matrix and Forgejo. By the same developers who made Nexus client.", + description: "Federated Nexus is a community resource hosting multiple FOSS (especially federated) services, including Matrix and Forgejo. By the same developers who made Nexus client.", url: .https("federated.nexus"), iconUrl: "https://federated.nexus/images/icon.png", ), .new( name: "Unredacted", - description: - "Unredacted is a 501(c)(3) non-profit organization that builds Internet infrastructure and services to help people evade censorship and protect their right to privacy.", + description: "Unredacted is a 501(c)(3) non-profit organization that builds Internet infrastructure and services to help people evade censorship and protect their right to privacy.", url: .https("unredacted.org", "services/si/matrix"), iconUrl: "https://unredacted.org/favicon.ico", ), diff --git a/lib/pages/settings.dart b/lib/pages/settings.dart index fa4d8da..a454993 100644 --- a/lib/pages/settings.dart +++ b/lib/pages/settings.dart @@ -1,6 +1,6 @@ import "package:collection/collection.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart"; -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:m3e_card_list/m3e_card_list.dart"; @@ -13,9 +13,7 @@ import "package:nexus/widgets/divider_text.dart"; import "package:nexus/widgets/highlight_wrapper.dart"; import "package:super_sliver_list/super_sliver_list.dart"; -class SettingsPage extends ConsumerWidget { - const SettingsPage({super.key}); - +class const SettingsPage({super.key}) extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) => LayoutBuilder( builder: (_, constraints) => HookBuilder( @@ -142,12 +140,12 @@ class SettingsPage extends ConsumerWidget { vertical: 8, ), margin: .symmetric(horizontal: 12), - color: Theme.of( - context, - ).colorScheme.primaryContainer, + color: Theme.of(context) + .colorScheme + .primaryContainer, itemCount: categories.length, - onTap: (index) => - Navigator.of(context).push( + onTap: (index) => Navigator.of(context) + .push( MaterialPageRoute( builder: (context) => SettingsCategoryPage( diff --git a/lib/pages/settings_category.dart b/lib/pages/settings_category.dart index b21d048..8e94c56 100644 --- a/lib/pages/settings_category.dart +++ b/lib/pages/settings_category.dart @@ -1,7 +1,7 @@ import "dart:async"; import "package:collection/collection.dart"; -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:nexus/controllers/settings_sections.dart"; @@ -9,11 +9,11 @@ import "package:nexus/helpers/extensions/better_when.dart"; import "package:nexus/widgets/highlight_wrapper.dart"; import "package:super_sliver_list/super_sliver_list.dart"; -class SettingsCategoryPage extends HookConsumerWidget { - final int index; - final int? initialHighlight; - const SettingsCategoryPage(this.index, {this.initialHighlight, super.key}); - +class const SettingsCategoryPage( + final int index, { + final int? initialHighlight, + super.key, +}) extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final highlight = useState(initialHighlight); diff --git a/lib/pages/verify.dart b/lib/pages/verify.dart index 4eefa6c..42a8dfc 100644 --- a/lib/pages/verify.dart +++ b/lib/pages/verify.dart @@ -1,4 +1,4 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:nexus/controllers/client.dart"; @@ -6,9 +6,7 @@ import "package:nexus/pages/settings.dart"; import "package:nexus/widgets/appbar.dart"; import "package:nexus/helpers/required_validator_helper.dart"; -class VerifyPage extends HookConsumerWidget { - const VerifyPage({super.key}); - +class const VerifyPage({super.key}) extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final passphraseController = useTextEditingController(); diff --git a/lib/widgets/appbar.dart b/lib/widgets/appbar.dart index 9da03aa..a6058ea 100644 --- a/lib/widgets/appbar.dart +++ b/lib/widgets/appbar.dart @@ -1,28 +1,20 @@ import "dart:io"; + import "package:fast_immutable_collections/fast_immutable_collections.dart"; -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:nexus/controllers/settings.dart"; import "package:window_manager/window_manager.dart"; -class Appbar extends ConsumerWidget implements PreferredSizeWidget { - final Widget? leading; - final Widget? title; - final Color? backgroundColor; - final double? scrolledUnderElevation; - final IList actions; - final VoidCallback? onTap; - - const Appbar({ - super.key, - this.title, - this.onTap, - this.backgroundColor, - this.scrolledUnderElevation, - this.leading, - this.actions = const .empty(), - }); - +final class const Appbar({ + final Widget? leading, + final Widget? title, + final Color? backgroundColor, + final double? scrolledUnderElevation, + final IList actions = const .empty(), + final VoidCallback? onTap, + super.key, +}) extends ConsumerWidget implements PreferredSizeWidget { @override Size get preferredSize => const .fromHeight(kToolbarHeight); diff --git a/lib/widgets/avatar_or_hash.dart b/lib/widgets/avatar_or_hash.dart index 75c08b9..982d56e 100644 --- a/lib/widgets/avatar_or_hash.dart +++ b/lib/widgets/avatar_or_hash.dart @@ -1,21 +1,15 @@ import "package:color_hash/color_hash.dart"; -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/helpers/mxc_image.dart"; -class AvatarOrHash extends ConsumerWidget { - final Uri? avatar; - final String title; - final Widget? fallback; - final double height; - const AvatarOrHash( - this.avatar, - this.title, { - this.fallback, - this.height = 24, - super.key, - }); - +final class const AvatarOrHash( + final Uri? avatar, + final String title, { + final Widget? fallback, + final double height = 24, + super.key, +}) extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final box = ColoredBox( diff --git a/lib/widgets/composer/composer.dart b/lib/widgets/composer/composer.dart index 8b7fec4..9a597a4 100644 --- a/lib/widgets/composer/composer.dart +++ b/lib/widgets/composer/composer.dart @@ -1,7 +1,8 @@ import "dart:io"; + import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:file_selector/file_selector.dart"; -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter/services.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:fluttertagger/fluttertagger.dart"; @@ -17,28 +18,20 @@ import "package:nexus/widgets/composer/relation_preview.dart"; import "package:nexus/widgets/emoji_picker_button.dart"; import "package:nexus/main.dart"; -class Composer extends HookConsumerWidget { - final String roomId; - final Event? relatedEvent; - final RelationType relationType; - final VoidCallback onDismiss; - final FocusNode? node; - final Future Function( +class const Composer( + final String roomId, { + required final Event? relatedEvent, + required final RelationType relationType, + required final VoidCallback onDismiss, + required final Future Function( String text, { required bool shouldMention, required IList tags, }) - onSend; - const Composer( - this.roomId, { - required this.relatedEvent, - required this.relationType, - required this.onDismiss, - required this.onSend, - this.node, - super.key, - }); - + onSend, + final FocusNode? node, + super.key, +}) extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final theme = Theme.of(context); @@ -143,9 +136,8 @@ class Composer extends HookConsumerWidget { ), onTap: () async => ref .watch( - AttachmentController.provider( - roomId, - ).notifier, + AttachmentController.provider(roomId) + .notifier, ) .add( (await ref @@ -163,9 +155,8 @@ class Composer extends HookConsumerWidget { ), onTap: () async => ref .watch( - AttachmentController.provider( - roomId, - ).notifier, + AttachmentController.provider(roomId) + .notifier, ) .add( (await ref @@ -179,9 +170,8 @@ class Composer extends HookConsumerWidget { PopupMenuItem( onTap: () async => ref .watch( - AttachmentController.provider( - roomId, - ).notifier, + AttachmentController.provider(roomId) + .notifier, ) .add((await openFile())!) .onError(showError), diff --git a/lib/widgets/composer/mention_overlay.dart b/lib/widgets/composer/mention_overlay.dart index ca4f95a..3dc0604 100644 --- a/lib/widgets/composer/mention_overlay.dart +++ b/lib/widgets/composer/mention_overlay.dart @@ -1,4 +1,4 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:nexus/controllers/members_by_status.dart"; import "package:nexus/controllers/rooms.dart"; @@ -9,19 +9,14 @@ import "package:nexus/models/content/membership.dart"; import "package:nexus/widgets/avatar_or_hash.dart"; import "package:nexus/widgets/loading.dart"; -class MentionOverlay extends ConsumerWidget { - final String? triggerCharacter; - final String query; - final String roomId; - final void Function({required String id, required String name}) addTag; - const MentionOverlay( - this.roomId, { - required this.query, - required this.addTag, - required this.triggerCharacter, - super.key, - }); - +class const MentionOverlay( + final String roomId, { + required final String query, + required final void Function({required String id, required String name}) + addTag, + required final String? triggerCharacter, + super.key, +}) extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final rooms = ref.watch(RoomsController.provider); diff --git a/lib/widgets/composer/relation_preview.dart b/lib/widgets/composer/relation_preview.dart index c9cc271..fca9de6 100644 --- a/lib/widgets/composer/relation_preview.dart +++ b/lib/widgets/composer/relation_preview.dart @@ -1,25 +1,17 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:nexus/models/event.dart"; import "package:nexus/models/relation_type.dart"; import "package:nexus/widgets/event_preview.dart"; -class RelationPreview extends ConsumerWidget { - final Event? relatedEvent; - final RelationType relationType; - final VoidCallback onDismiss; - final bool shouldMention; - final VoidCallback toggleShouldMention; - - const RelationPreview( - this.relatedEvent, { - required this.relationType, - required this.onDismiss, - required this.shouldMention, - required this.toggleShouldMention, - super.key, - }); - +class const RelationPreview( + final Event? relatedEvent, { + required final RelationType relationType, + required final VoidCallback onDismiss, + required final bool shouldMention, + required final VoidCallback toggleShouldMention, + super.key, +}) extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { if (relatedEvent == null) return SizedBox.shrink(); diff --git a/lib/widgets/divider_text.dart b/lib/widgets/divider_text.dart index 2b0f9bd..c44ae11 100644 --- a/lib/widgets/divider_text.dart +++ b/lib/widgets/divider_text.dart @@ -1,11 +1,8 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:nexus/widgets/divider_widget.dart"; -class DividerText extends StatelessWidget { - final String text; - - const DividerText(this.text, {super.key}); - +final class const DividerText(final String text, {super.key}) + extends StatelessWidget { @override Widget build(BuildContext context) => DividerWidget(Text(text, style: Theme.of(context).textTheme.labelLarge)); diff --git a/lib/widgets/divider_widget.dart b/lib/widgets/divider_widget.dart index 6f13bd4..5e4972c 100644 --- a/lib/widgets/divider_widget.dart +++ b/lib/widgets/divider_widget.dart @@ -1,9 +1,7 @@ -import "package:flutter/material.dart"; - -class DividerWidget extends StatelessWidget { - final Widget widget; - const DividerWidget(this.widget, {super.key}); +import "package:material_ui/material_ui.dart"; +final class const DividerWidget(final Widget widget, {super.key}) + extends StatelessWidget { @override Widget build(BuildContext context) => LayoutBuilder( builder: (_, constraints) => Row( diff --git a/lib/widgets/emoji_picker_button.dart b/lib/widgets/emoji_picker_button.dart index 2ac906a..1e20557 100644 --- a/lib/widgets/emoji_picker_button.dart +++ b/lib/widgets/emoji_picker_button.dart @@ -1,21 +1,15 @@ import "package:emoji_text_field/emoji_text_field.dart"; -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:nexus/controllers/emoji.dart"; -class EmojiPickerButton extends HookConsumerWidget { - final TextEditingController? controller; - final void Function(String emoji)? onSelection; - final VoidCallback? onPressed; - final BuildContext context; - const EmojiPickerButton({ - this.controller, - this.onPressed, - this.onSelection, - required this.context, - super.key, - }); - +final class const EmojiPickerButton({ + required final BuildContext context, + final TextEditingController? controller, + final void Function(String emoji)? onSelection, + final VoidCallback? onPressed, + super.key, +}) extends HookConsumerWidget { @override Widget build(_, WidgetRef ref) => IconButton( onPressed: () async { diff --git a/lib/widgets/error_dialog.dart b/lib/widgets/error_dialog.dart index 9b62200..ddc4c98 100644 --- a/lib/widgets/error_dialog.dart +++ b/lib/widgets/error_dialog.dart @@ -1,13 +1,13 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:flutter_riverpod/misc.dart"; -class ErrorDialog extends ConsumerWidget { - final Object error; - final StackTrace? stackTrace; - final ProviderOrFamily? provider; - const ErrorDialog(this.error, this.stackTrace, {this.provider, super.key}); - +final class const ErrorDialog( + final Object error, + final StackTrace? stackTrace, { + final ProviderOrFamily? provider, + super.key, +}) extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { return AlertDialog( diff --git a/lib/widgets/event_preview.dart b/lib/widgets/event_preview.dart index 7a40a75..30dfbfe 100644 --- a/lib/widgets/event_preview.dart +++ b/lib/widgets/event_preview.dart @@ -1,14 +1,12 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:nexus/models/content/message.dart"; import "package:nexus/models/event.dart"; import "package:nexus/widgets/lazy_loading/message_avatar.dart"; import "package:nexus/widgets/lazy_loading/message_displayname.dart"; import "package:nexus/widgets/renderers/event.dart"; -class EventPreview extends StatelessWidget { - final Event event; - const EventPreview(this.event, {super.key}); - +class const EventPreview(final Event event, {super.key}) + extends StatelessWidget { @override Widget build(BuildContext context) => IgnorePointer( child: Padding( diff --git a/lib/widgets/expandable_image.dart b/lib/widgets/expandable_image.dart index ee4f900..0639417 100644 --- a/lib/widgets/expandable_image.dart +++ b/lib/widgets/expandable_image.dart @@ -1,15 +1,15 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:m3e_buttons/m3e_buttons.dart"; import "package:nexus/helpers/mxc_image.dart"; import "package:nexus/models/requests/download_media.dart"; import "package:nexus/widgets/error_dialog.dart"; -class ExpandableImage extends ConsumerWidget { - final Widget child; - final DownloadMediaRequest? request; - const ExpandableImage(this.request, {required this.child, super.key}); - +final class const ExpandableImage( + final DownloadMediaRequest? request, { + required final Widget child, + super.key, +}) extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) => InkWell( onTap: request == null diff --git a/lib/widgets/file_card.dart b/lib/widgets/file_card.dart index afdad89..4c0fdde 100644 --- a/lib/widgets/file_card.dart +++ b/lib/widgets/file_card.dart @@ -1,13 +1,13 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:nexus/helpers/extensions/size_to_string.dart"; import "package:nexus/models/info/file.dart"; -class FileCard extends StatelessWidget { - final Uri uri; - final FileInfo? info; - final String? filename; - const FileCard(this.uri, this.info, {this.filename, super.key}); - +final class const FileCard( + final Uri uri, + final FileInfo? info, { + final String? filename, + super.key, +}) extends StatelessWidget { @override Widget build(BuildContext context) => SizedBox( width: 320, diff --git a/lib/widgets/highlight_wrapper.dart b/lib/widgets/highlight_wrapper.dart index c7e568e..b10e3ff 100644 --- a/lib/widgets/highlight_wrapper.dart +++ b/lib/widgets/highlight_wrapper.dart @@ -1,10 +1,10 @@ -import "package:flutter/material.dart"; - -class HighlightWrapper extends StatelessWidget { - final Widget child; - final bool isHighlighted; - const HighlightWrapper(this.child, {this.isHighlighted = false, super.key}); +import "package:material_ui/material_ui.dart"; +final class const HighlightWrapper( + final Widget child, { + final bool isHighlighted = false, + super.key, +}) extends StatelessWidget { @override Widget build(BuildContext context) => ClipRRect( borderRadius: .all(.circular(12)), diff --git a/lib/widgets/html/code_block.dart b/lib/widgets/html/code_block.dart index a5c3dee..974b74d 100644 --- a/lib/widgets/html/code_block.dart +++ b/lib/widgets/html/code_block.dart @@ -1,12 +1,12 @@ import "dart:math"; -import "package:flutter/material.dart"; - -class CodeBlock extends StatelessWidget { - final String code; - final String lang; - const CodeBlock(this.code, {required this.lang, super.key}); +import "package:material_ui/material_ui.dart"; +class const CodeBlock( + final String code, { + required final String lang, + super.key, +}) extends StatelessWidget { @override Widget build(BuildContext context) { final theme = Theme.of(context); diff --git a/lib/widgets/html/html.dart b/lib/widgets/html/html.dart index 5437285..bdebf8f 100644 --- a/lib/widgets/html/html.dart +++ b/lib/widgets/html/html.dart @@ -1,5 +1,5 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart"; import "package:nexus/helpers/extensions/link_to_mention.dart"; @@ -11,12 +11,12 @@ import "package:nexus/widgets/html/spoiler_text.dart"; import "package:nexus/widgets/html/code_block.dart"; import "package:nexus/widgets/html/quoted.dart"; -class Html extends ConsumerWidget { - final String html; - final String? roomId; - final TextStyle? textStyle; - const Html(this.html, {this.roomId, this.textStyle, super.key}); - +class const Html( + final String html, { + final String? roomId, + final TextStyle? textStyle, + super.key, +}) extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) => HtmlWidget( html, @@ -28,7 +28,7 @@ class Html extends ConsumerWidget { } if (element.attributes.keys.contains("data-mx-spoiler")) { - return InlineCustomWidget(child: SpoilerText(text: element.text)); + return InlineCustomWidget(child: SpoilerText(element.text)); } final height = diff --git a/lib/widgets/html/mention_chip.dart b/lib/widgets/html/mention_chip.dart index 57e23b4..eb10e4b 100644 --- a/lib/widgets/html/mention_chip.dart +++ b/lib/widgets/html/mention_chip.dart @@ -1,4 +1,4 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/controllers/room_summary.dart"; import "package:nexus/controllers/user.dart"; @@ -7,11 +7,8 @@ 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; - final String content; - const MentionChip(this.content, this.roomId, {super.key}); - +class const MentionChip(final String content, final String? roomId, {super.key}) + extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final mention = content.mention; diff --git a/lib/widgets/html/quoted.dart b/lib/widgets/html/quoted.dart index e582b06..3157263 100644 --- a/lib/widgets/html/quoted.dart +++ b/lib/widgets/html/quoted.dart @@ -1,9 +1,6 @@ -import "package:flutter/material.dart"; - -class Quoted extends StatelessWidget { - final Widget child; - const Quoted(this.child, {super.key}); +import "package:material_ui/material_ui.dart"; +class const Quoted(final Widget child, {super.key}) extends StatelessWidget { @override Widget build(BuildContext context) => Container( decoration: BoxDecoration( diff --git a/lib/widgets/html/spoiler_text.dart b/lib/widgets/html/spoiler_text.dart index a7a457b..92a5538 100644 --- a/lib/widgets/html/spoiler_text.dart +++ b/lib/widgets/html/spoiler_text.dart @@ -1,11 +1,7 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_hooks/flutter_hooks.dart"; -class SpoilerText extends HookWidget { - final String text; - - const SpoilerText({super.key, required this.text}); - +class const SpoilerText(final String text, {super.key}) extends HookWidget { @override Widget build(BuildContext context) { final revealed = useState(false); diff --git a/lib/widgets/join_dialog.dart b/lib/widgets/join_dialog.dart index 50b36f2..e818c7d 100644 --- a/lib/widgets/join_dialog.dart +++ b/lib/widgets/join_dialog.dart @@ -1,5 +1,5 @@ import "package:collection/collection.dart"; -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:nexus/controllers/client.dart"; @@ -7,10 +7,7 @@ import "package:nexus/controllers/key.dart"; import "package:nexus/controllers/spaces.dart"; import "package:nexus/helpers/extensions/link_to_mention.dart"; -class JoinDialog extends HookWidget { - final WidgetRef ref; - const JoinDialog(this.ref, {super.key}); - +class const JoinDialog(final WidgetRef ref, {super.key}) extends HookWidget { @override Widget build(BuildContext context) { final roomAlias = useTextEditingController(); @@ -53,9 +50,8 @@ class JoinDialog extends HookWidget { .new( roomIdOrAlias: roomIdOrAlias, via: .new( - Uri.tryParse( - roomAlias.text.replaceAll("/#", ""), - )?.queryParametersAll["via"] ?? + Uri.tryParse(roomAlias.text.replaceAll("/#", "")) + ?.queryParametersAll["via"] ?? [], ), ), @@ -76,9 +72,8 @@ class JoinDialog extends HookWidget { await ref .watch( - KeyController.provider( - KeyController.spaceKey, - ).notifier, + KeyController.provider(KeyController.spaceKey) + .notifier, ) .set( space?.id ?? @@ -100,9 +95,8 @@ class JoinDialog extends HookWidget { if (space == null) { await ref .watch( - KeyController.provider( - KeyController.roomKey, - ).notifier, + KeyController.provider(KeyController.roomKey) + .notifier, ) .set(id); } @@ -115,9 +109,9 @@ class JoinDialog extends HookWidget { if (context.mounted) { scaffoldMessenger.showSnackBar( .new( - backgroundColor: Theme.of( - context, - ).colorScheme.errorContainer, + backgroundColor: Theme.of(context) + .colorScheme + .errorContainer, content: Text( error.toString(), style: .new( diff --git a/lib/widgets/lazy_loading/message_avatar.dart b/lib/widgets/lazy_loading/message_avatar.dart index 93c2554..709d558 100644 --- a/lib/widgets/lazy_loading/message_avatar.dart +++ b/lib/widgets/lazy_loading/message_avatar.dart @@ -1,4 +1,4 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/controllers/author.dart"; import "package:nexus/helpers/extensions/get_localpart.dart"; @@ -6,11 +6,11 @@ import "package:nexus/helpers/extensions/show_user_popover.dart"; import "package:nexus/models/event.dart"; import "package:nexus/widgets/avatar_or_hash.dart"; -class MessageAvatar extends ConsumerWidget { - final Event event; - final double height; - const MessageAvatar(this.event, {this.height = 24, super.key}); - +class const MessageAvatar( + final Event event, { + final double height = 24, + super.key, +}) extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) => switch (ref.watch( AuthorController.provider(event), diff --git a/lib/widgets/lazy_loading/message_displayname.dart b/lib/widgets/lazy_loading/message_displayname.dart index bd5733c..9203f69 100644 --- a/lib/widgets/lazy_loading/message_displayname.dart +++ b/lib/widgets/lazy_loading/message_displayname.dart @@ -1,4 +1,4 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/controllers/author.dart"; import "package:nexus/helpers/extensions/get_localpart.dart"; @@ -6,17 +6,12 @@ import "package:nexus/helpers/extensions/show_user_popover.dart"; import "package:nexus/helpers/extensions/string_to_color.dart"; import "package:nexus/models/event.dart"; -class MessageDisplayname extends ConsumerWidget { - final Event event; - final TextStyle? style; - final bool clickable; - const MessageDisplayname( - this.event, { - this.clickable = true, - this.style, - super.key, - }); - +class const MessageDisplayname( + final Event event, { + final TextStyle? style, + final bool clickable = true, + super.key, +}) extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) => switch (ref.watch( AuthorController.provider(event), @@ -40,14 +35,11 @@ class MessageDisplayname extends ConsumerWidget { maxLines: 1, overflow: .ellipsis, ), - if (event.pmp != null) Text( "(via ${event.sender})", - style: Theme.of(context).textTheme.labelSmall?.copyWith( - color: event.sender.colorHash, - fontWeight: .bold, - ), + style: Theme.of(context).textTheme.labelSmall + ?.copyWith(color: event.sender.colorHash, fontWeight: .bold), maxLines: 1, overflow: .ellipsis, ), diff --git a/lib/widgets/linkified_text.dart b/lib/widgets/linkified_text.dart index 653248c..77ba7a4 100644 --- a/lib/widgets/linkified_text.dart +++ b/lib/widgets/linkified_text.dart @@ -1,14 +1,14 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_linkify/flutter_linkify.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/helpers/launch_helper.dart"; -class LinkifiedText extends ConsumerWidget { - final String text; - final int? maxLines; - final TextStyle? style; - const LinkifiedText(this.text, {this.maxLines, this.style, super.key}); - +final class const LinkifiedText( + final String text, { + final int? maxLines, + final TextStyle? style, + super.key, +}) extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) => Linkify( text: text, diff --git a/lib/widgets/loading.dart b/lib/widgets/loading.dart index fc84563..180cd1b 100644 --- a/lib/widgets/loading.dart +++ b/lib/widgets/loading.dart @@ -1,9 +1,6 @@ -import "package:flutter/material.dart"; - -class Loading extends StatelessWidget { - final double? height; - const Loading({this.height, super.key}); +import "package:material_ui/material_ui.dart"; +class const Loading({super.key, final double? height}) extends StatelessWidget { @override Widget build(BuildContext context) => Center( child: Padding( diff --git a/lib/widgets/member_list.dart b/lib/widgets/member_list.dart index 92bb179..9ddafa3 100644 --- a/lib/widgets/member_list.dart +++ b/lib/widgets/member_list.dart @@ -1,5 +1,5 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:m3e_buttons/m3e_buttons.dart"; @@ -16,10 +16,8 @@ import "package:nexus/widgets/error_dialog.dart"; import "package:nexus/widgets/loading.dart"; import "package:nexus/widgets/user_bottom_sheet.dart"; -class MemberList extends HookConsumerWidget { - final String roomId; - const MemberList(this.roomId, {super.key}); - +class const MemberList(final String roomId, {super.key}) + extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final statusIndex = useState(0); @@ -96,9 +94,9 @@ class MemberList extends HookConsumerWidget { ), SliverM3ECardList( padding: .all(4), - color: Theme.of( - context, - ).colorScheme.surfaceContainerHigh, + color: Theme.of(context) + .colorScheme + .surfaceContainerHigh, margin: .symmetric(horizontal: 12, vertical: 4), itemCount: members.length, itemBuilder: (context, index) => diff --git a/lib/widgets/message_image.dart b/lib/widgets/message_image.dart index 914a252..b04c209 100644 --- a/lib/widgets/message_image.dart +++ b/lib/widgets/message_image.dart @@ -1,4 +1,4 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_blurhash/flutter_blurhash.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/helpers/mxc_image.dart"; @@ -7,12 +7,12 @@ import "package:nexus/models/requests/download_media.dart"; import "package:nexus/widgets/expandable_image.dart"; import "package:nexus/widgets/loading.dart"; -class MessageImage extends ConsumerWidget { - final Uri url; - final i.ImageInfo? info; - final bool encrypted; - const MessageImage(this.url, {this.info, required this.encrypted, super.key}); - +final class const MessageImage( + final Uri url, { + final i.ImageInfo? info, + required final bool encrypted, + super.key, +}) extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final request = DownloadMediaRequest(mxc: url, encrypted: encrypted); diff --git a/lib/widgets/pinned_events_drawer.dart b/lib/widgets/pinned_events_drawer.dart index 7cb9fe3..046e231 100644 --- a/lib/widgets/pinned_events_drawer.dart +++ b/lib/widgets/pinned_events_drawer.dart @@ -1,5 +1,5 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:nexus/controllers/pinned_events.dart"; import "package:nexus/models/event.dart"; @@ -7,17 +7,12 @@ import "package:nexus/widgets/error_dialog.dart"; import "package:nexus/widgets/loading.dart"; import "package:nexus/widgets/renderers/event.dart"; -class PinnedEventsDrawer extends HookConsumerWidget { - final String roomId; - final IList Function(Event event) getEventOptions; - final Future Function(String eventId) jumpToId; - const PinnedEventsDrawer( - this.roomId, { - required this.getEventOptions, - required this.jumpToId, - super.key, - }); - +final class const PinnedEventsDrawer( + final String roomId, { + required final IList Function(Event event) getEventOptions, + required final Future Function(String eventId) jumpToId, + super.key, +}) extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final pinsProvider = ref.watch(PinnedEventsController.provider(roomId)); diff --git a/lib/widgets/players/audio.dart b/lib/widgets/players/audio.dart index 22a91f7..bd50a8b 100644 --- a/lib/widgets/players/audio.dart +++ b/lib/widgets/players/audio.dart @@ -1,18 +1,18 @@ import "dart:async"; -import "package:flutter/material.dart"; + +import "package:material_ui/material_ui.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:media_kit/media_kit.dart"; import "package:nexus/controllers/client.dart"; import "package:nexus/models/info/audio.dart"; -class AudioPlayer extends HookConsumerWidget { - final Uri uri; - final AudioInfo? info; - final bool encrypted; - - const AudioPlayer(this.uri, this.info, {this.encrypted = false, super.key}); - +class const AudioPlayer( + final Uri uri, + final AudioInfo? info, { + final bool encrypted = false, + super.key, +}) extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final player = useMemoized( diff --git a/lib/widgets/players/video.dart b/lib/widgets/players/video.dart index 457cdc4..024c30e 100644 --- a/lib/widgets/players/video.dart +++ b/lib/widgets/players/video.dart @@ -1,5 +1,6 @@ import "dart:async"; -import "package:flutter/material.dart"; + +import "package:material_ui/material_ui.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:nexus/controllers/client.dart"; import "package:nexus/models/info/video.dart"; @@ -7,12 +8,12 @@ import "package:flutter_hooks/flutter_hooks.dart"; import "package:media_kit/media_kit.dart"; import "package:media_kit_video/media_kit_video.dart"; -class VideoPlayer extends HookConsumerWidget { - final VideoInfo? info; - final Uri uri; - final bool encrypted; - const VideoPlayer(this.uri, this.info, {this.encrypted = false, super.key}); - +class const VideoPlayer( + final Uri uri, + final VideoInfo? info, { + final bool encrypted = false, + super.key, +}) extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final player = useMemoized( diff --git a/lib/widgets/reaction_row.dart b/lib/widgets/reaction_row.dart index b2fa5ca..56f2356 100644 --- a/lib/widgets/reaction_row.dart +++ b/lib/widgets/reaction_row.dart @@ -1,4 +1,4 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/controllers/client_state.dart"; @@ -10,10 +10,7 @@ import "package:nexus/widgets/error_dialog.dart"; import "package:nexus/main.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart"; -class ReactionRow extends ConsumerWidget { - final Event event; - const ReactionRow(this.event, {super.key}); - +class const ReactionRow(final Event event, {super.key}) extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final clientState = ref.watch(ClientStateController.provider); @@ -67,9 +64,8 @@ class ReactionRow extends ConsumerWidget { enabled.value = false; try { final controller = ref.watch( - RoomChatController.provider( - event.roomId, - ).notifier, + RoomChatController.provider(event.roomId) + .notifier, ); if (selected) { diff --git a/lib/widgets/renderers/event.dart b/lib/widgets/renderers/event.dart index a9c703a..7607c2a 100644 --- a/lib/widgets/renderers/event.dart +++ b/lib/widgets/renderers/event.dart @@ -1,5 +1,5 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:nexus/helpers/extensions/show_context_menu.dart"; @@ -25,23 +25,15 @@ import "package:nexus/widgets/reaction_row.dart"; import "package:nexus/widgets/renderers/membership.dart"; import "package:nexus/widgets/renderers/generic_event.dart"; -class EventRenderer extends HookConsumerWidget { - final Event event; - final bool textOnly; - final bool isGrouped; - final int? maxLines; - final VoidCallback? onTapReply; - final IList Function(Event event)? getEventOptions; - const EventRenderer( - this.event, { - this.onTapReply, - this.textOnly = false, - this.isGrouped = false, - this.maxLines, - this.getEventOptions, - super.key, - }); - +class const EventRenderer( + final Event event, { + final bool textOnly = false, + final bool isGrouped = false, + final int? maxLines, + final VoidCallback? onTapReply, + final IList Function(Event event)? getEventOptions, + super.key, +}) extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final theme = Theme.of(context); @@ -202,9 +194,8 @@ class EventRenderer extends HookConsumerWidget { onSecondaryTapUp: contextMenuCallback, onLongPressStart: contextMenuCallback, child: Padding( - padding: EdgeInsets.symmetric( - horizontal: 8, - ).copyWith(top: isGrouped ? 0 : 8), + padding: EdgeInsets.symmetric(horizontal: 8) + .copyWith(top: isGrouped ? 0 : 8), child: child, ), ), diff --git a/lib/widgets/renderers/generic_event.dart b/lib/widgets/renderers/generic_event.dart index 6dfae53..88d2db8 100644 --- a/lib/widgets/renderers/generic_event.dart +++ b/lib/widgets/renderers/generic_event.dart @@ -1,10 +1,10 @@ -import "package:flutter/material.dart"; - -class GenericEventRenderer extends StatelessWidget { - final IconData icon; - final List children; - const GenericEventRenderer(this.icon, this.children, {super.key}); +import "package:material_ui/material_ui.dart"; +class const GenericEventRenderer( + final IconData icon, + final List children, { + super.key, +}) extends StatelessWidget { @override Widget build(BuildContext context) => Padding( padding: .symmetric(vertical: 4), diff --git a/lib/widgets/renderers/membership.dart b/lib/widgets/renderers/membership.dart index b2835b4..5ce5d68 100644 --- a/lib/widgets/renderers/membership.dart +++ b/lib/widgets/renderers/membership.dart @@ -1,4 +1,4 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:nexus/helpers/extensions/get_localpart.dart"; import "package:nexus/helpers/extensions/show_user_popover.dart"; import "package:nexus/helpers/extensions/string_to_color.dart"; @@ -7,10 +7,8 @@ import "package:nexus/models/event.dart"; import "package:nexus/widgets/lazy_loading/message_displayname.dart"; import "package:nexus/widgets/renderers/generic_event.dart"; -class MembershipRenderer extends StatelessWidget { - final Event event; - const MembershipRenderer(this.event, {super.key}); - +class const MembershipRenderer(final Event event, {super.key}) + extends StatelessWidget { @override Widget build(BuildContext context) { assert( diff --git a/lib/widgets/renderers/message.dart b/lib/widgets/renderers/message.dart index c684085..8631fe2 100644 --- a/lib/widgets/renderers/message.dart +++ b/lib/widgets/renderers/message.dart @@ -1,5 +1,5 @@ import "package:collection/collection.dart"; -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:linkify/linkify.dart"; import "package:nexus/controllers/client_state.dart"; @@ -21,21 +21,14 @@ import "package:nexus/widgets/event_preview.dart"; import "package:nexus/widgets/players/video.dart"; import "package:nexus/widgets/players/audio.dart"; -class MessageRenderer extends ConsumerWidget { - final Event event; - final bool textOnly; - final bool isGrouped; - final int? maxLines; - final VoidCallback? onTapReply; - const MessageRenderer( - this.event, { - this.onTapReply, - this.textOnly = false, - this.isGrouped = false, - this.maxLines, - super.key, - }); - +class const MessageRenderer( + final Event event, { + final VoidCallback? onTapReply, + final bool textOnly = false, + final bool isGrouped = false, + final int? maxLines, + super.key, +}) extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final theme = Theme.of(context); diff --git a/lib/widgets/room_appbar.dart b/lib/widgets/room_appbar.dart index 69eafaa..305c490 100644 --- a/lib/widgets/room_appbar.dart +++ b/lib/widgets/room_appbar.dart @@ -1,4 +1,4 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:nexus/controllers/rooms.dart"; import "package:nexus/widgets/appbar.dart"; @@ -7,21 +7,14 @@ import "package:nexus/widgets/expandable_image.dart"; import "package:nexus/widgets/linkified_text.dart"; import "package:nexus/widgets/room_menu.dart"; -class RoomAppbar extends ConsumerWidget implements PreferredSizeWidget { - final bool isDesktop; - final void Function(BuildContext context)? onOpenMemberList; - final void Function()? onOpenPinnedMessagesList; - final void Function() onOpenDrawer; - final String? roomId; - const RoomAppbar({ - required this.roomId, - required this.isDesktop, - required this.onOpenDrawer, - this.onOpenMemberList, - this.onOpenPinnedMessagesList, - super.key, - }); - +final class const RoomAppbar({ + required final String? roomId, + required final bool isDesktop, + required final void Function() onOpenDrawer, + final void Function(BuildContext context)? onOpenMemberList, + final void Function()? onOpenPinnedMessagesList, + super.key, +}) extends ConsumerWidget implements PreferredSizeWidget { @override Size get preferredSize => AppBar().preferredSize; @@ -67,9 +60,9 @@ class RoomAppbar extends ConsumerWidget implements PreferredSizeWidget { room.metadata?.name ?? "Unnamed Room", overflow: .ellipsis, maxLines: 3, - style: Theme.of( - context, - ).textTheme.headlineSmall, + style: Theme.of(context) + .textTheme + .headlineSmall, ), ), ], @@ -79,9 +72,9 @@ class RoomAppbar extends ConsumerWidget implements PreferredSizeWidget { room.metadata!.topic!, style: Theme.of(context).textTheme.bodyLarge ?.copyWith( - color: Theme.of( - context, - ).colorScheme.onSurfaceVariant, + color: Theme.of(context) + .colorScheme + .onSurfaceVariant, ), ), ], diff --git a/lib/widgets/room_chat.dart b/lib/widgets/room_chat.dart index 01908a8..456109e 100644 --- a/lib/widgets/room_chat.dart +++ b/lib/widgets/room_chat.dart @@ -1,5 +1,5 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter/services.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; @@ -28,17 +28,12 @@ import "package:nexus/main.dart"; import "package:nexus/widgets/loading.dart"; import "package:super_sliver_list/super_sliver_list.dart"; -class RoomChat extends HookConsumerWidget { - final bool isDesktop; - final bool showMembersByDefault; - final String? roomId; - const RoomChat({ - required this.roomId, - required this.isDesktop, - required this.showMembersByDefault, - super.key, - }); - +final class const RoomChat({ + required final String? roomId, + required final bool isDesktop, + required final bool showMembersByDefault, + super.key, +}) extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final relatedEvent = useState(null); @@ -127,9 +122,8 @@ class RoomChat extends HookConsumerWidget { }, [scrollController.hasClients]); useEffect(() { - if (controllerData case AsyncData( - :final value?, - ) when scrollController.hasClients) { + if (controllerData case AsyncData(:final value?) + when scrollController.hasClients) { if (topEventBeforeLoad.value != null) { WidgetsBinding.instance.addPostFrameCallback((_) { if (scrollController.hasClients) { diff --git a/lib/widgets/room_menu.dart b/lib/widgets/room_menu.dart index e99991f..278e479 100644 --- a/lib/widgets/room_menu.dart +++ b/lib/widgets/room_menu.dart @@ -1,16 +1,16 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter/services.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/controllers/client.dart"; import "package:nexus/controllers/via.dart"; import "package:nexus/models/room.dart"; -class RoomMenu extends ConsumerWidget { - final Room? room; - final IList children; - const RoomMenu(this.room, {this.children = const IList.empty(), super.key}); - +final class const RoomMenu( + final Room? room, { + final IList children = const IList.empty(), + super.key, +}) extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final danger = Theme.of(context).colorScheme.error; diff --git a/lib/widgets/settings/dialog_list_tile.dart b/lib/widgets/settings/dialog_list_tile.dart index f0a236c..e66e335 100644 --- a/lib/widgets/settings/dialog_list_tile.dart +++ b/lib/widgets/settings/dialog_list_tile.dart @@ -1,28 +1,18 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/widgets/settings/radio_dialog.dart"; -class DialogListTile extends ConsumerWidget { - final T? initialValue; - final String title; - final Widget? subtitle; - final List options; - final bool required; - final Icon icon; - final void Function(T value)? onChanged; - final String Function(T option) getName; - const DialogListTile({ - super.key, - required this.icon, - required this.title, - required this.initialValue, - required this.options, - required this.onChanged, - required this.getName, - this.subtitle, - this.required = true, - }); - +final class const DialogListTile({ + required final T? initialValue, + required final Icon icon, + required final String title, + required final List options, + required final void Function(T value)? onChanged, + required final String Function(T option) getName, + final Widget? subtitle, + final bool required = true, + super.key, +}) extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) => FormField( validator: (value) => diff --git a/lib/widgets/settings/radio_dialog.dart b/lib/widgets/settings/radio_dialog.dart index 7695b9d..6696139 100644 --- a/lib/widgets/settings/radio_dialog.dart +++ b/lib/widgets/settings/radio_dialog.dart @@ -1,21 +1,14 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_hooks/flutter_hooks.dart"; -class RadioDialog extends HookWidget { - final T? value; - final String title; - final List options; - final void Function(T value)? onChanged; - final String Function(T option) getName; - const RadioDialog({ - super.key, - required this.title, - required this.value, - required this.options, - required this.onChanged, - required this.getName, - }); - +final class const RadioDialog({ + required final T? value, + required final String title, + required final List options, + required final void Function(T value)? onChanged, + required final String Function(T option) getName, + super.key, +}) extends HookWidget { @override Widget build(BuildContext context) { final mutValue = useState(null); diff --git a/lib/widgets/sidebar.dart b/lib/widgets/sidebar.dart index 1bd6cf5..04700f8 100644 --- a/lib/widgets/sidebar.dart +++ b/lib/widgets/sidebar.dart @@ -1,6 +1,6 @@ import "package:collection/collection.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart"; -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:navigation_rail_m3e/navigation_rail_m3e.dart"; import "package:nexus/controllers/key.dart"; @@ -12,10 +12,8 @@ import "package:nexus/widgets/divider_widget.dart"; import "package:nexus/widgets/join_dialog.dart"; import "package:nexus/widgets/room_menu.dart"; -class Sidebar extends HookConsumerWidget { - final bool isDesktop; - const Sidebar({required this.isDesktop, super.key}); - +class const Sidebar({required final bool isDesktop, super.key}) + extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final selectedSpaceProvider = KeyController.provider( diff --git a/lib/widgets/url_preview.dart b/lib/widgets/url_preview.dart index 3a20e19..37a2733 100644 --- a/lib/widgets/url_preview.dart +++ b/lib/widgets/url_preview.dart @@ -1,14 +1,11 @@ -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/controllers/url_preview.dart"; import "package:nexus/helpers/extensions/better_when.dart"; import "package:nexus/helpers/launch_helper.dart"; import "package:nexus/helpers/mxc_image.dart"; -class UrlPreview extends ConsumerWidget { - final Uri link; - const UrlPreview(this.link, {super.key}); - +class const UrlPreview(final Uri link, {super.key}) extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) => ConstrainedBox( constraints: .loose(.fromWidth(400)), @@ -21,9 +18,9 @@ class UrlPreview extends ConsumerWidget { onTap: () => ref.watch(LaunchHelper.provider).launchUrl(link), child: Card( margin: .symmetric(vertical: 4), - color: Theme.of( - context, - ).colorScheme.surfaceContainerHighest, + color: Theme.of(context) + .colorScheme + .surfaceContainerHighest, child: Padding( padding: .all(16), child: Column( diff --git a/lib/widgets/user_bottom_sheet.dart b/lib/widgets/user_bottom_sheet.dart index 15a24a0..a725613 100644 --- a/lib/widgets/user_bottom_sheet.dart +++ b/lib/widgets/user_bottom_sheet.dart @@ -1,5 +1,5 @@ import "package:collection/collection.dart"; -import "package:flutter/material.dart"; +import "package:material_ui/material_ui.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:intl/intl.dart"; @@ -16,12 +16,12 @@ import "package:nexus/widgets/avatar_or_hash.dart"; import "package:nexus/main.dart"; import "package:nexus/widgets/expandable_image.dart"; -class UserBottomSheet extends ConsumerWidget { - final MembershipContent member; - final String userId; - final String? roomId; - const UserBottomSheet(this.member, this.userId, {this.roomId, super.key}); - +final class const UserBottomSheet( + final MembershipContent member, + final String userId, { + final String? roomId, + super.key, +}) extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final theme = Theme.of(context); diff --git a/linux/nix/devshell.nix b/linux/nix/devshell.nix index 812082c..daddafd 100644 --- a/linux/nix/devshell.nix +++ b/linux/nix/devshell.nix @@ -2,7 +2,7 @@ let android = pkgs.androidenv.composeAndroidPackages { toolsVersion = "26.1.1"; - platformToolsVersion = "36.0.1"; + platformToolsVersion = "37.0.1"; buildToolsVersions = [ "35.0.0" "36.0.0" @@ -42,8 +42,7 @@ pkgs.mkShell { ANDROID_SDK_ROOT = ANDROID_HOME; JAVA_HOME = pkgs.jdk17; - TOOLS = "${ANDROID_HOME}/build-tools/${"36.0.0"}"; - GRADLE_OPTS = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${TOOLS}/aapt2"; + GRADLE_OPTS = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${ANDROID_HOME}/build-tools/36.0.0/aapt2"; } // lib.optionalAttrs pkgs.stdenv.isLinux { CPATH = lib.makeSearchPath "include" [ pkgs.glibc.dev ]; diff --git a/pubspec.lock b/pubspec.lock index 9be2c20..901a1ca 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,26 +5,26 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: a49d6cf99e8d8e7a8e93668d09ced0bbdb954d0b4fccc2f5f9241c6b87fad95c + sha256: "1b0e6a07425a3e460666e88bf1c949ccc7bb0116ad562ce94a1eca60fe820725" url: "https://pub.dev" source: hosted - version: "99.0.0" + version: "103.0.0" analysis_server_plugin: dependency: transitive description: name: analysis_server_plugin - sha256: "3960b28ee740004df39f85d5ebfc91785f7a90e51fd7c9a185e86a36b2f581b4" + sha256: c58b2a05b260a023eefd0848496ff6b113a318c6c95dad4215165a4bd54ae600 url: "https://pub.dev" source: hosted - version: "0.3.14" + version: "0.3.18" analyzer: dependency: transitive description: name: analyzer - sha256: "663efa951fb8a45e06f491223a604c93820598f20e6a99c25617a1576065e8b7" + sha256: "61c04d0c1bfed555c681ea079519933f071a5a026578ff73c4ff0df2d3462e5e" url: "https://pub.dev" source: hosted - version: "12.1.0" + version: "13.3.0" analyzer_buffer: dependency: transitive description: @@ -37,10 +37,10 @@ packages: dependency: transitive description: name: analyzer_plugin - sha256: "0057a98d64d7bb872b0c87dff6e73d2c2d80c77156e7a03f127a26f8aa240649" + sha256: c2a75baf1657171cc7872db96a12b07e385873cf7a73f2b4f7638e9d0701ee53 url: "https://pub.dev" source: hosted - version: "0.14.8" + version: "0.14.12" app_links: dependency: "direct main" description: @@ -77,10 +77,10 @@ packages: dependency: transitive description: name: archive - sha256: a96e8b390886ee8abb49b7bd3ac8df6f451c621619f52a26e815fdcf568959ff + sha256: be169cf6ac481e052c4538715d88841d567150dfe1df38aaec76461a4e7b39f2 url: "https://pub.dev" source: hosted - version: "4.0.9" + version: "4.1.0" args: dependency: transitive description: @@ -89,6 +89,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.7.0" + asn1lib: + dependency: transitive + description: + name: asn1lib + sha256: "9a8f69025044eb466b9b60ef3bc3ac99b4dc6c158ae9c56d25eeccf5bc56d024" + url: "https://pub.dev" + source: hosted + version: "1.6.5" async: dependency: transitive description: @@ -109,10 +117,10 @@ packages: dependency: transitive description: name: build - sha256: "45d14a0fb23e018d8287c32fc98d726ce466b231928ed9b9200f29bd3ccd39ae" + sha256: b94f5da9ed3d081fd4ecc426c260998b5f4f4eb2f6d89b7e5472edef0b2b2a1b url: "https://pub.dev" source: hosted - version: "4.0.7" + version: "4.0.10" build_config: dependency: transitive description: @@ -133,10 +141,10 @@ packages: dependency: "direct dev" description: name: build_runner - sha256: "5367e521935b102bdf1e735d2aab461e36b2edca6517662d088dd04cc39f8d16" + sha256: "90363d438bd9f84a4d5bbb83352251f57d2d9d771bc95a44e6a33fe25fa52774" url: "https://pub.dev" source: hosted - version: "2.15.1" + version: "2.16.0" built_collection: dependency: transitive description: @@ -169,14 +177,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.1" - charcode: - dependency: transitive - description: - name: charcode - sha256: fb0f1107cac15a5ea6ef0a6ef71a807b9e4267c713bb93e00e92d737cc8dbd8a - url: "https://pub.dev" - source: hosted - version: "1.4.0" checked_yaml: dependency: transitive description: @@ -273,38 +273,46 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.2" + cupertino_ui: + dependency: transitive + description: + name: cupertino_ui + sha256: "7ed8ce4159d342eec4c65f4ea6eec57adaf9365404378541f38efc1da20a5b3d" + url: "https://pub.dev" + source: hosted + version: "1.0.0" dart_style: dependency: transitive description: name: dart_style - sha256: a4c1ccfee44c7e75ed80484071a5c142a385345e658fd8bd7c4b5c97e7198f98 + sha256: "3f88fc9c96c568d631356507355a2d1e983ee000c9ac008bdcb39b5bf53ce777" url: "https://pub.dev" source: hosted - version: "3.1.8" + version: "3.1.12" dbus: dependency: transitive description: name: dbus - sha256: "792974a4007974fbc5c1b5433eb2330a9db3e368c3f906253af4c007d0f49a91" + sha256: a48d5da28e89bd02196e80d81ed8d7954923d00a0f4a68cc20b575038f023383 url: "https://pub.dev" source: hosted - version: "0.7.13" + version: "0.7.15" dynamic_color: dependency: "direct main" description: name: dynamic_color - sha256: "4aeb76de323e8eb660bab5557d826ad7ebbf1434a598f0c6aa8a11a9696a6757" + sha256: "869b3bce0100eb519768ecd71c0111f0b5ea679f5f62e1f59c49d80067e730c5" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "2.1.0" dynamic_polls: dependency: "direct main" description: name: dynamic_polls - sha256: "72ff19cdf041ad8dcfa76adaebb216d005f40b278d955e6e0c7bcb769215fabe" + sha256: "58cd1fafbbaba6b485a61692aa3bd33ded6f0f61734543b6c754511c362d8ae1" url: "https://pub.dev" source: hosted - version: "0.0.7" + version: "0.0.8" emoji_text_field: dependency: "direct main" description: @@ -314,6 +322,14 @@ packages: url: "https://github.com/Henry-Hiles/emoji_text_field" source: git version: "1.0.0" + encrypt: + dependency: transitive + description: + name: encrypt + sha256: "62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2" + url: "https://pub.dev" + source: hosted + version: "5.0.3" equatable: dependency: transitive description: @@ -512,10 +528,10 @@ packages: dependency: "direct main" description: name: flutter_riverpod - sha256: "9255e1e3ad6e38906a1b4f8287678f95f378744c5b46b1985588543f3f19046e" + sha256: "56e81e662e6e54e59b231da57e90ac0d06ac67d8e3f2273c129a37ae6282b40c" url: "https://pub.dev" source: hosted - version: "3.3.2" + version: "3.4.2" flutter_svg: dependency: "direct main" description: @@ -554,10 +570,10 @@ packages: dependency: "direct dev" description: name: freezed - sha256: "8599ba37236328ff6f97269ecce875d251a367eb2929c9bbf9b811b2ce56c74e" + sha256: "27585a6c2b9ac28ffb7b45d87fd1502332af1eb90e1c9f5eb1acb24c71d26e17" url: "https://pub.dev" source: hosted - version: "3.2.6-dev.1" + version: "4.0.0" freezed_annotation: dependency: "direct main" description: @@ -578,10 +594,10 @@ packages: dependency: transitive description: name: get_x_storage - sha256: "69e4412dd70e25a4991623c10bf72e3b12106f2cb4353a2d167353947597f3aa" + sha256: "597cd8f6ef8b01c747a6d95ff7b0310066f6c82ddf5565ca371f047f316fe43e" url: "https://pub.dev" source: hosted - version: "0.0.9" + version: "0.2.0" glob: dependency: transitive description: @@ -610,18 +626,18 @@ packages: dependency: "direct main" description: name: hooks - sha256: "9a62a50b50b769a737bc0a8ff381f333529df3ab746b2f6b02e83760231455ba" + sha256: eaac480a35ec0814146c2c48d96aaa829e0e44a7662c88ae84c9edf4bc35651f url: "https://pub.dev" source: hosted - version: "2.0.2" + version: "2.2.0" hooks_riverpod: dependency: "direct main" description: name: hooks_riverpod - sha256: dcaf59f0f41489ff08ce61438ada564d67f40cfa37cc7c8589da78fb600c2edc + sha256: fce693abc6289c8bb42348eae520b979f7edbaae0c1b77b946ef058d0693f6f6 url: "https://pub.dev" source: hosted - version: "3.3.2" + version: "3.4.2" html: dependency: transitive description: @@ -666,10 +682,10 @@ packages: dependency: transitive description: name: image - sha256: "6300175e00616bbc832e2fc91bfa4d776af5402c81c7151bee6905bb08473c52" + sha256: "1976370a4df3091bb0f72409c187ad1f9132a818bc6b95ca59c0bae1c75c688e" url: "https://pub.dev" source: hosted - version: "4.9.1" + version: "4.9.2" image_picker: dependency: "direct main" description: @@ -738,10 +754,10 @@ packages: dependency: "direct main" description: name: intl - sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" + sha256: "1ca20c894b1717686a2319b8548763d812bc0aabdac580420a44c5178c57a867" url: "https://pub.dev" source: hosted - version: "0.20.2" + version: "0.20.3" io: dependency: transitive description: @@ -750,6 +766,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.5" + js: + dependency: transitive + description: + name: js + sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc" + url: "https://pub.dev" + source: hosted + version: "0.7.2" json_annotation: dependency: "direct main" description: @@ -807,6 +831,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.1.0" + listen: + dependency: transitive + description: + name: listen + sha256: "47501a08016a43fcad79252439d723f50f14f88fa7bfd8a177e0a417e5c9e1f2" + url: "https://pub.dev" + source: hosted + version: "1.0.1" logging: dependency: transitive description: @@ -819,18 +851,18 @@ packages: dependency: "direct main" description: name: m3e_buttons - sha256: "20b29df165d4d866ffd0d4808090210740690707705f44fc61c9b275bec3af36" + sha256: "001031f1b72ef19643a8a6a531aafcfb31a06b53456b6f60014403c125e67056" url: "https://pub.dev" source: hosted - version: "0.0.5" + version: "1.0.0" m3e_card_list: dependency: "direct main" description: name: m3e_card_list - sha256: d4aba0123cccda40ac80789befa8d355e1dc16aa7dcee910157690b0546d78d6 + sha256: ed1cc150f051b8812ffd735915ae59fed23517ffeeed04c4b2b8ef6257cc18b7 url: "https://pub.dev" source: hosted - version: "0.1.0" + version: "1.0.0" m3e_design: dependency: transitive description: @@ -843,10 +875,10 @@ packages: dependency: transitive description: name: matcher - sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861 + sha256: "31bd099b47c10cd1aeb55146a2d46ce0277630ecef3f7dae54ad7873f36696cd" url: "https://pub.dev" source: hosted - version: "0.12.19" + version: "0.12.20" material_color_utilities: dependency: transitive description: @@ -855,6 +887,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.13.0" + material_ui: + dependency: "direct main" + description: + name: material_ui + sha256: "4f3f38b9953df0a87d6bf5f21880029f77c47048487d5339410c39936be4683b" + url: "https://pub.dev" + source: hosted + version: "1.0.1" measure_size: dependency: "direct main" description: @@ -931,10 +971,10 @@ packages: dependency: transitive description: name: meta - sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349" + sha256: "307249ce4ff29d58a18e97f6345f539382eb9c9c29ecda628900f31de0443dd9" url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.0" mime: dependency: transitive description: @@ -955,16 +995,16 @@ packages: dependency: transitive description: name: native_toolchain_c - sha256: f9c168717100ae6d9fee9ffb0be379bf1f8b26b0f6bcbd4fdddcd931993a6a72 + sha256: a1c26117c48cebe5677b0cf0e33a980a79a7c5577effc86f52e5a0d309cdcb60 url: "https://pub.dev" source: hosted - version: "0.19.2" + version: "0.19.3" navigation_rail_m3e: dependency: "direct main" description: path: "packages/navigation_rail_m3e" ref: HEAD - resolved-ref: "667b0bc8526fd53296778903b6ef3f22424f3aa4" + resolved-ref: c9edb0be7251e1a31e2336444f00557eb93ca09d url: "https://github.com/Henry-Hiles/material_3_expressive" source: git version: "0.3.5" @@ -1096,6 +1136,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" + pointycastle: + dependency: transitive + description: + name: pointycastle + sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe" + url: "https://pub.dev" + source: hosted + version: "3.9.1" pool: dependency: transitive description: @@ -1140,34 +1188,34 @@ packages: dependency: transitive description: name: record_use - sha256: "2551bd8eecfe95d14ae75f6021ad0248be5c27f138c2ec12fcb52b500b3ba1ed" + sha256: "1cb8564af8d43b464294411db9217f5ec04891c6f22ee2c32d73ae05e88a6bd2" url: "https://pub.dev" source: hosted - version: "0.6.0" + version: "1.1.1" riverpod: dependency: transitive description: name: riverpod - sha256: "17100416c51db7810c71a7bb2c34d1f881faa0074fd452afb0c4db6f8f126c76" + sha256: "84351b3472a447f7b89f961f95c73287009d58c59d8cc1267425d995f78e50f1" url: "https://pub.dev" source: hosted - version: "3.3.2" + version: "3.4.2" riverpod_analyzer_utils: dependency: transitive description: name: riverpod_analyzer_utils - sha256: "3e275138862ccc22ed61444a1f9a840f753094c367f28f4123f50289cd204d68" + sha256: "46a8dd0461080fde8f886f65f87580758dae8495e352f9ea6a09953abc3df7bd" url: "https://pub.dev" source: hosted - version: "1.0.0-dev.10" + version: "1.0.0-dev.11" riverpod_lint: dependency: "direct dev" description: name: riverpod_lint - sha256: "166f29492228dc471b6fe294092560ccd5545ed15c9fc155622455b58b2451a9" + sha256: "7d37414a82b0f52f3d8e440320830d9a8c59620663884b2bb5baaca26296c995" url: "https://pub.dev" source: hosted - version: "3.1.4" + version: "3.1.8" rxdart: dependency: transitive description: @@ -1345,10 +1393,10 @@ packages: dependency: transitive description: name: source_maps - sha256: "190222579a448b03896e0ca6eca5998fa810fda630c1d65e2f78b3f638f54812" + sha256: "14c2945847669b44089bb1222f66873d7ff7103c58911917f2a63c5a62327898" url: "https://pub.dev" source: hosted - version: "0.10.13" + version: "0.10.14" source_span: dependency: transitive description: @@ -1409,10 +1457,10 @@ packages: dependency: transitive description: name: synchronized - sha256: "61894a1956de6b4fc1aefd0892e109514a1a706cbece3ac59decd90ff5a7a423" + sha256: "3a7b5d17422dd0f8d5c6c14feaa5a1c65638b9455f871a96f08437562c046931" url: "https://pub.dev" source: hosted - version: "3.4.1+1" + version: "3.4.1+2" term_glyph: dependency: transitive description: @@ -1425,26 +1473,26 @@ packages: dependency: transitive description: name: test - sha256: "8d9ceddbab833f180fbefed08afa76d7c03513dfdba87ffcec2718b02bbcbf20" + sha256: ca578dc12bb8b2f40b67b7d3bd2fac4f31c01a6ff7130a14e2597b919934507f url: "https://pub.dev" source: hosted - version: "1.31.0" + version: "1.31.1" test_api: dependency: transitive description: name: test_api - sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e" + sha256: "2a122cbe059f8b610d3a5415f42e255b6c17b1f21eee1d960f31080237fb4f11" url: "https://pub.dev" source: hosted - version: "0.7.11" + version: "0.7.12" test_core: dependency: transitive description: name: test_core - sha256: "1991d4cfe85d5043241acac92962c3977c8d2f2add1ee73130c7b286417d1d34" + sha256: d2e98ec12998368dc59ddd47ab709f2cd55acd6b66dc7db764455a44082f4bc5 url: "https://pub.dev" source: hosted - version: "0.6.17" + version: "0.6.18" timeago: dependency: "direct main" description: @@ -1461,22 +1509,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" - universal_html: - dependency: transitive - description: - name: universal_html - sha256: c0bcae5c733c60f26c7dfc88b10b0fd27cbcc45cb7492311cdaa6067e21c9cd4 - url: "https://pub.dev" - source: hosted - version: "2.3.0" - universal_io: - dependency: transitive - description: - name: universal_io - sha256: f63cbc48103236abf48e345e07a03ce5757ea86285ed313a6a032596ed9301e2 - url: "https://pub.dev" - source: hosted - version: "2.3.1" universal_platform: dependency: transitive description: @@ -1593,18 +1625,18 @@ packages: dependency: transitive description: name: vector_math - sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + sha256: f36f9f3be64c6198714492bb455c11056e33e2f85d9a0b676a48301e44fdcf47 url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.4.2" vm_service: dependency: transitive description: name: vm_service - sha256: "0016aef94fc66495ac78af5859181e3f3bf2026bd8eecc72b9565601e19ab360" + sha256: "5f37239c4851efcef929cea7824e76df7f2f0970aef85d66bbc430afa40e72f0" url: "https://pub.dev" source: hosted - version: "15.2.0" + version: "15.3.0" wakelock_plus: dependency: transitive description: @@ -1710,5 +1742,5 @@ packages: source: hosted version: "2.2.4" sdks: - dart: ">=3.12.2 <4.0.0" - flutter: ">=3.44.0" + dart: "3.13.0" + flutter: ">=3.47.0" diff --git a/pubspec.yaml b/pubspec.yaml index e74d5d7..42e0426 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: nexus -description: "Yet another Matrix client" +description: "A simple and user-friendly Matrix client" version: 0.1.0 publish_to: none @@ -13,12 +13,12 @@ flutter: - asset: assets/fonts/Roboto.ttf assets: - assets/ - uses-material-design: true environment: - sdk: "^3.12.2" + sdk: 3.13.0 dependency_overrides: + dynamic_color: 2.1.0 path_provider_android: 2.2.23 # Pinned to avoid JNI linkify: git: @@ -30,16 +30,16 @@ dependencies: sdk: flutter flutter_localizations: sdk: flutter - flutter_riverpod: 3.3.2 - hooks_riverpod: 3.3.2 - intl: 0.20.2 + flutter_riverpod: 3.4.2 + hooks_riverpod: 3.4.2 + intl: 0.20.3 fast_immutable_collections: 11.2.0 path_provider: 2.1.6 url_launcher: 6.3.2 freezed_annotation: 3.1.0 - image_picker: ^1.2.3 + image_picker: 1.2.3 path: 1.9.1 - dynamic_color: 1.9.0 + dynamic_color: 2.1.0 collection: 1.19.1 window_manager: 0.5.2 color_hash: 1.0.1 @@ -48,10 +48,10 @@ dependencies: json_annotation: 4.12.0 shared_preferences: 2.5.5 fluttertagger: 2.3.2 - dynamic_polls: 0.0.7 + dynamic_polls: 0.0.8 flutter_hooks: 0.21.3+1 ffi: 2.2.0 - hooks: 2.0.2 + hooks: ^2.2.0 code_assets: 1.2.1 ffigen: 21.0.0 timeago: 3.7.1 @@ -67,22 +67,23 @@ dependencies: media_kit_video: 2.0.1 media_kit_libs_video: 1.0.7 measure_size: 5.0.2 - m3e_buttons: 0.0.5 + m3e_buttons: 1.0.0 navigation_rail_m3e: git: url: https://github.com/Henry-Hiles/material_3_expressive path: packages/navigation_rail_m3e - m3e_card_list: 0.1.0 + m3e_card_list: 1.0.0 xdg_directories: 1.1.0 package_info_plus: 10.2.1 app_links: 7.2.1 - file_selector: ^1.1.0 + file_selector: 1.1.0 + material_ui: 1.0.1 dev_dependencies: - build_runner: ^2.15.1 + build_runner: 2.16.0 flutter_lints: 6.0.0 - freezed: 3.2.6-dev.1 - riverpod_lint: 3.1.4 + freezed: 4.0.0 + riverpod_lint: 3.1.8 flutter_launcher_icons: 0.14.4 json_serializable: 6.14.1 From 2e72ecd5592ee3e1618b7dff36ee963908dbabce Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 22 Aug 2026 13:05:49 -0400 Subject: [PATCH 071/176] fix `navigation_rail_m3e` hash Fixes nix build --- linux/nix/pkg/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/nix/pkg/default.nix b/linux/nix/pkg/default.nix index c026606..68b7fce 100644 --- a/linux/nix/pkg/default.nix +++ b/linux/nix/pkg/default.nix @@ -31,7 +31,7 @@ flutter.buildFlutterApplication { gitHashes = { emoji_text_field = "sha256-3TOys09EP2GRo6pUBGPXaqBlE39O2Cmwt42Hs1cTDKo="; linkify = "sha256-TpMD6+0zyY6i9l+6d8ErnVufmepCv362rCtnbOht/z4="; - navigation_rail_m3e = "sha256-+2awDTQnK58gGRY1nuHckG/jjxarsYSRu9ovR4i4TEc="; + navigation_rail_m3e = "sha256-LbReuEG/fYjehmXsyimZ2JSf4fyuhDpmaywsxsXzToI="; }; postInstall = '' From 3baea40669cf563791b52aa73d88e86317d1c1fa Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 22 Aug 2026 13:24:26 -0400 Subject: [PATCH 072/176] skip broken android lints --- android/app/build.gradle.kts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 161d5a5..c0f7bec 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -19,6 +19,10 @@ android { compileSdk = 36 ndkVersion = flutter.ndkVersion + lint { + disable += setOf("EasterEgg", "StopShip") + } + compileOptions { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 From 56bb75866cf70a82831133046835bc3a237e4127 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 22 Aug 2026 13:50:00 -0400 Subject: [PATCH 073/176] bump JDK version --- android/app/build.gradle.kts | 10 +++------- linux/nix/devshell.nix | 4 ++-- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index c0f7bec..8a23bb6 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -19,13 +19,9 @@ android { compileSdk = 36 ndkVersion = flutter.ndkVersion - lint { - disable += setOf("EasterEgg", "StopShip") - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 } defaultConfig { @@ -69,7 +65,7 @@ android { kotlin { compilerOptions { - jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 + jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_21 } } diff --git a/linux/nix/devshell.nix b/linux/nix/devshell.nix index daddafd..dd3c78e 100644 --- a/linux/nix/devshell.nix +++ b/linux/nix/devshell.nix @@ -23,7 +23,7 @@ pkgs.mkShell { [ go git - jdk17 + libGL (flutter.override { extraPkgConfigPackages = [ @@ -40,7 +40,7 @@ pkgs.mkShell { ANDROID_HOME = "${android.androidsdk}/libexec/android-sdk"; ANDROID_SDK_ROOT = ANDROID_HOME; - JAVA_HOME = pkgs.jdk17; + JAVA_HOME = pkgs.jdk21; GRADLE_OPTS = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${ANDROID_HOME}/build-tools/36.0.0/aapt2"; } From b797b8de9c75879f3a15cdbfe359f1ae6dd76f3c Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 22 Aug 2026 13:51:44 -0400 Subject: [PATCH 074/176] fix icons not rendering --- pubspec.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/pubspec.yaml b/pubspec.yaml index 42e0426..974b720 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -13,6 +13,7 @@ flutter: - asset: assets/fonts/Roboto.ttf assets: - assets/ + uses-material-design: true environment: sdk: 3.13.0 From 9b79304edce34863ff27a83804620e1c58efe26f Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 22 Aug 2026 14:05:31 -0400 Subject: [PATCH 075/176] try to optimize APK size --- .github/workflows/android.yml | 4 ++-- assets/{ => bundled}/icon.svg | 0 lib/helpers/extensions/show_about_dialog.dart | 2 +- lib/pages/select_server.dart | 2 +- pubspec.yaml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) rename assets/{ => bundled}/icon.svg (100%) diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index dc1e9c7..7c96f78 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -8,7 +8,7 @@ on: jobs: build-apk: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04-arm steps: - name: Checkout repository @@ -27,7 +27,7 @@ jobs: KEYSTORE_CONTENT: ${{ secrets.KEYSTORE_CONTENT }} - name: Build app - run: nix develop --command bash -c "flutter pub get && dart scripts/generate.dart && flutter pub run build_runner build && flutter build apk --release" + run: nix develop --command bash -c "flutter pub get && dart scripts/generate.dart && flutter pub run build_runner build && flutter build apk --target-platform android-arm64" env: KEYSTORE_PATH: ../../keystore.jks KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }} diff --git a/assets/icon.svg b/assets/bundled/icon.svg similarity index 100% rename from assets/icon.svg rename to assets/bundled/icon.svg diff --git a/lib/helpers/extensions/show_about_dialog.dart b/lib/helpers/extensions/show_about_dialog.dart index 5bd2740..1d20315 100644 --- a/lib/helpers/extensions/show_about_dialog.dart +++ b/lib/helpers/extensions/show_about_dialog.dart @@ -20,7 +20,7 @@ extension ShowContextMenu on BuildContext { Row( spacing: 12, children: [ - SvgPicture.asset("assets/icon.svg", width: 64), + SvgPicture.asset("assets/bundled/icon.svg", width: 64), Expanded( child: Column( crossAxisAlignment: .start, diff --git a/lib/pages/select_server.dart b/lib/pages/select_server.dart index f894d13..85c84cb 100644 --- a/lib/pages/select_server.dart +++ b/lib/pages/select_server.dart @@ -132,7 +132,7 @@ class const SelectServerPage({super.key}) extends HookConsumerWidget { children: [ Row( children: [ - SvgPicture.asset("assets/icon.svg", width: 128), + SvgPicture.asset("assets/bundled/icon.svg", width: 128), SizedBox(width: 12), Expanded( child: Column( diff --git a/pubspec.yaml b/pubspec.yaml index 974b720..a9b2e01 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -12,7 +12,7 @@ flutter: fonts: - asset: assets/fonts/Roboto.ttf assets: - - assets/ + - assets/bundled/ uses-material-design: true environment: From 20f1c784f63c8382f88c65dbececaf6ec56e8be4 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 22 Aug 2026 14:16:35 -0400 Subject: [PATCH 076/176] optimize gomuks build size --- hook/build.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hook/build.dart b/hook/build.dart index a893544..9315e04 100644 --- a/hook/build.dart +++ b/hook/build.dart @@ -1,4 +1,5 @@ import "dart:io"; + import "package:collection/collection.dart"; import "package:hooks/hooks.dart"; import "package:code_assets/code_assets.dart"; @@ -134,6 +135,8 @@ Future main(List args) => build(args, (input, output) async { "go", [ "build", + "-trimpath", + "-ldflags=-s -w", "-tags", tags, "-o", From 4e1f1b64bcb8c5ae07d1fade3b577d753d91b51e Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 22 Aug 2026 14:18:12 -0400 Subject: [PATCH 077/176] run APK build on x86_64 --- .github/workflows/android.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 7c96f78..a3abae1 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -8,7 +8,7 @@ on: jobs: build-apk: - runs-on: ubuntu-24.04-arm + runs-on: ubuntu-latest steps: - name: Checkout repository From 32693fb3b5fa72db73d613dd4770e67c20f22e45 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 22 Aug 2026 14:26:28 -0400 Subject: [PATCH 078/176] fix path in nix build --- linux/nix/pkg/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/nix/pkg/default.nix b/linux/nix/pkg/default.nix index 68b7fce..49f0a00 100644 --- a/linux/nix/pkg/default.nix +++ b/linux/nix/pkg/default.nix @@ -35,7 +35,7 @@ flutter.buildFlutterApplication { }; postInstall = '' - install -D assets/icon.svg $out/share/icons/hicolor/scalable/apps/nexus.svg + install -D assets/bundled/icon.svg $out/share/icons/hicolor/scalable/apps/nexus.svg install -Dm755 linux/nexus.federated.nexus.desktop -t $out/share/applications wrapProgram $out/bin/nexus \ --suffix LD_LIBRARY_PATH : $out/app/nexus/lib From a090d88a2396f9f52a916042ecb5c6a79ce6b940 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 22 Aug 2026 15:12:35 -0400 Subject: [PATCH 079/176] add theming workaround for `navigation_rail_m3e` --- lib/widgets/sidebar.dart | 362 +++++++++++++++++++++------------------ pubspec.lock | 2 +- 2 files changed, 193 insertions(+), 171 deletions(-) diff --git a/lib/widgets/sidebar.dart b/lib/widgets/sidebar.dart index 04700f8..6473987 100644 --- a/lib/widgets/sidebar.dart +++ b/lib/widgets/sidebar.dart @@ -12,6 +12,9 @@ import "package:nexus/widgets/divider_widget.dart"; import "package:nexus/widgets/join_dialog.dart"; import "package:nexus/widgets/room_menu.dart"; +// Needed for navigation_rail_m3e (#65). +import "package:flutter/material.dart" as old_mat; + class const Sidebar({required final bool isDesktop, super.key}) extends HookConsumerWidget { @override @@ -72,126 +75,137 @@ class const Sidebar({required final bool isDesktop, super.key}) shape: Border(), child: Row( children: [ - Theme( - data: Theme.of(context).copyWith( - extensions: [ - NavigationRailM3ETheme( - itemCollapsedHeight: 48, - itemVerticalGap: 0, + MaterialUiCompatibilityBridge( + child: Builder( + builder: (context) => old_mat.Theme( + data: old_mat.Theme.of(context).copyWith( + extensions: [ + NavigationRailM3ETheme( + itemCollapsedHeight: 48, + itemVerticalGap: 0, + ), + ], ), - ], - ), - child: Container( - color: NavigationRailTokensAdapter(context).containerColor, - padding: EdgeInsets.only(top: 16), - child: NavigationRailM3E( - type: .alwaysCollapse, - labelBehavior: .alwaysHide, - scrollable: true, - onDestinationSelected: (value) { - selectedSpaceIdNotifier.set(spaces[value].id); - selectedRoomIdNotifier.set( - spaces[value].children.firstOrNull?.metadata?.id, - ); - }, - sections: [ - .new( - destinations: spaces - .map( - (space) => NavigationRailM3EDestination( - badgeCount: switch (space.children - .addAll( - space.subSpaces - .map((element) => element.children) - .flattened, - ) - .fold( - 0, - (previousValue, room) => - previousValue + - (room.metadata?.unreadNotifications ?? 0), - )) { - 0 => - space.children - .addAll( - space.subSpaces - .map( - (element) => element.children, - ) - .flattened, - ) - .any( - (room) => - room.metadata?.unreadMessages != - 0, - ) - ? 0 - : null, - int badgeCount => badgeCount, - }, - short: true, - icon: AvatarOrHash( - height: 28, - space.room?.metadata?.avatar, - fallback: space.icon == null - ? null - : Icon(space.icon), - space.title, - ), - label: space.title, - ), - ) - .toList(), - ), - ], - selectedIndex: selectedIndex, - trailingAtBottom: true, - trailing: Padding( - padding: .symmetric(vertical: 16), - child: Column( - spacing: 8, - children: [ - PopupMenuButton( - itemBuilder: (_) => [ - PopupMenuItem( - onTap: () => showDialog( - context: context, - builder: (_) => JoinDialog(ref), - ), - child: ListTile( - title: Text("Join an existing room (or space)"), - leading: Icon(Icons.numbers), - ), - ), - PopupMenuItem( - onTap: null, - child: ListTile( - title: Text("Create a new room"), - leading: Icon(Icons.add), - ), - ), - ], - icon: Icon(Icons.add), - ), - IconButton( - tooltip: "Explore other rooms", - onPressed: null, - icon: Icon(Icons.explore), - ), - IconButton( - tooltip: "Open settings", - onPressed: () => showDialog( - context: context, - builder: (_) => SettingsPage(), - ), - icon: Icon(Icons.settings), + child: Container( + color: NavigationRailTokensAdapter(context).containerColor, + padding: EdgeInsets.only(top: 16), + child: NavigationRailM3E( + type: .alwaysCollapse, + labelBehavior: .alwaysHide, + scrollable: true, + onDestinationSelected: (value) { + selectedSpaceIdNotifier.set(spaces[value].id); + selectedRoomIdNotifier.set( + spaces[value].children.firstOrNull?.metadata?.id, + ); + }, + sections: [ + .new( + destinations: spaces + .map( + (space) => NavigationRailM3EDestination( + badgeCount: switch (space.children + .addAll( + space.subSpaces + .map((element) => element.children) + .flattened, + ) + .fold( + 0, + (previousValue, room) => + previousValue + + (room.metadata?.unreadNotifications ?? + 0), + )) { + 0 => + space.children + .addAll( + space.subSpaces + .map( + (element) => + element.children, + ) + .flattened, + ) + .any( + (room) => + room + .metadata + ?.unreadMessages != + 0, + ) + ? 0 + : null, + int badgeCount => badgeCount, + }, + short: true, + icon: AvatarOrHash( + height: 28, + space.room?.metadata?.avatar, + fallback: space.icon == null + ? null + : Icon(space.icon), + space.title, + ), + label: space.title, + ), + ) + .toList(), ), ], + selectedIndex: selectedIndex, + trailingAtBottom: true, + trailing: Padding( + padding: .symmetric(vertical: 16), + child: Column( + spacing: 8, + children: [ + PopupMenuButton( + itemBuilder: (_) => [ + PopupMenuItem( + onTap: () => showDialog( + context: context, + builder: (_) => JoinDialog(ref), + ), + child: ListTile( + title: Text( + "Join an existing room (or space)", + ), + leading: Icon(Icons.numbers), + ), + ), + PopupMenuItem( + onTap: null, + child: ListTile( + title: Text("Create a new room"), + leading: Icon(Icons.add), + ), + ), + ], + icon: Icon(Icons.add), + ), + IconButton( + tooltip: "Explore other rooms", + onPressed: null, + icon: Icon(Icons.explore), + ), + IconButton( + tooltip: "Open settings", + onPressed: () => showDialog( + context: context, + builder: (_) => SettingsPage(), + ), + icon: Icon(Icons.settings), + ), + ], + ), + ), ), ), ), ), ), + Expanded( child: Scaffold( backgroundColor: Colors.transparent, @@ -217,67 +231,75 @@ class const Sidebar({required final bool isDesktop, super.key}) ), ], ), - body: Theme( - data: Theme.of(context).copyWith( - extensions: [ - NavigationRailM3ETheme( - itemExpandedHeight: 48, - iconLabelGap: 16, + body: MaterialUiCompatibilityBridge( + child: Builder( + builder: (context) => old_mat.Theme( + data: old_mat.Theme.of(context).copyWith( + extensions: [ + NavigationRailM3ETheme( + itemExpandedHeight: 48, + iconLabelGap: 16, + ), + ], ), - ], - ), - child: NavigationRailM3E( - expandedWidth: double.infinity, - scrollable: true, - background: Colors.transparent, - type: .alwaysExpand, - selectedIndex: selectedRoomIndex ?? 0, - sections: [ - .new( - header: selectedSpace.room == null - ? null - : DividerWidget(Text("Rooms")), - destinations: roomsToDestinations(selectedSpace.children), - ), - for (final subSpace in selectedSpace.subSpaces) - .new( - header: DividerWidget( - Row( - mainAxisSize: MainAxisSize.min, - spacing: 8, - children: [ - if (subSpace.room.metadata?.avatar != null) - AvatarOrHash( - subSpace.room.metadata?.avatar, - subSpace.room.metadata?.name ?? - "Unnamed Room", - height: 16, - ), - Flexible( - child: Text( - subSpace.room.metadata?.name ?? - "Unnamed Space", - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - ), - ], + child: NavigationRailM3E( + expandedWidth: double.infinity, + scrollable: true, + background: Colors.transparent, + type: .alwaysExpand, + selectedIndex: selectedRoomIndex ?? 0, + sections: [ + .new( + header: selectedSpace.room == null + ? null + : DividerWidget(Text("Rooms")), + destinations: roomsToDestinations( + selectedSpace.children, ), ), - destinations: roomsToDestinations(subSpace.children), - ), - ], - onDestinationSelected: (value) { - final children = selectedSpace.children.addAll( - selectedSpace.subSpaces - .map((element) => element.children) - .flattened, - ); - selectedRoomIdNotifier.set( - children[value].metadata?.id, // - ); - if (!isDesktop) Navigator.of(context).pop(); - }, + for (final subSpace in selectedSpace.subSpaces) + .new( + header: DividerWidget( + Row( + mainAxisSize: MainAxisSize.min, + spacing: 8, + children: [ + if (subSpace.room.metadata?.avatar != null) + AvatarOrHash( + subSpace.room.metadata?.avatar, + subSpace.room.metadata?.name ?? + "Unnamed Room", + height: 16, + ), + Flexible( + child: Text( + subSpace.room.metadata?.name ?? + "Unnamed Space", + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + ), + destinations: roomsToDestinations( + subSpace.children, + ), + ), + ], + onDestinationSelected: (value) { + final children = selectedSpace.children.addAll( + selectedSpace.subSpaces + .map((element) => element.children) + .flattened, + ); + selectedRoomIdNotifier.set( + children[value].metadata?.id, // + ); + if (!isDesktop) Navigator.of(context).pop(); + }, + ), + ), ), ), ), diff --git a/pubspec.lock b/pubspec.lock index 901a1ca..d45c4d4 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1004,7 +1004,7 @@ packages: description: path: "packages/navigation_rail_m3e" ref: HEAD - resolved-ref: c9edb0be7251e1a31e2336444f00557eb93ca09d + resolved-ref: da860a413d5cf78b9c9c967215250bcdbfe5191d url: "https://github.com/Henry-Hiles/material_3_expressive" source: git version: "0.3.5" From 0887421f3ebf6a09fbf29dd594f07b36f3f695d5 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 22 Aug 2026 15:14:41 -0400 Subject: [PATCH 080/176] put bridge for link colors --- lib/widgets/html/html.dart | 230 +++++++++++++++++++------------------ 1 file changed, 119 insertions(+), 111 deletions(-) diff --git a/lib/widgets/html/html.dart b/lib/widgets/html/html.dart index bdebf8f..0e95edd 100644 --- a/lib/widgets/html/html.dart +++ b/lib/widgets/html/html.dart @@ -18,123 +18,131 @@ class const Html( super.key, }) extends ConsumerWidget { @override - Widget build(BuildContext context, WidgetRef ref) => HtmlWidget( - html, - buildAsync: false, - textStyle: textStyle, - customWidgetBuilder: (element) { - if (element.attributes.keys.contains("data-mx-profile-fallback")) { - return SizedBox.shrink(); - } + Widget build(BuildContext context, WidgetRef ref) => + MaterialUiCompatibilityBridge( + child: HtmlWidget( + html, + buildAsync: false, + textStyle: textStyle, + customWidgetBuilder: (element) { + if (element.attributes.keys.contains("data-mx-profile-fallback")) { + return SizedBox.shrink(); + } - if (element.attributes.keys.contains("data-mx-spoiler")) { - return InlineCustomWidget(child: SpoilerText(element.text)); - } + if (element.attributes.keys.contains("data-mx-spoiler")) { + return InlineCustomWidget(child: SpoilerText(element.text)); + } - final height = - int.tryParse(element.attributes["height"] ?? "") ?? - (element.attributes.keys.contains("data-mx-emoticon") ? 32 : null) ?? - 300; - final width = int.tryParse(element.attributes["width"] ?? ""); - final src = Uri.tryParse(element.attributes["src"] ?? ""); + final height = + int.tryParse(element.attributes["height"] ?? "") ?? + (element.attributes.keys.contains("data-mx-emoticon") + ? 32 + : null) ?? + 300; + final width = int.tryParse(element.attributes["width"] ?? ""); + final src = Uri.tryParse(element.attributes["src"] ?? ""); - return switch (element.localName) { - "code" => - element.parent?.localName == "pre" - ? CodeBlock( - element.text, - lang: element.className.replaceAll("language-", ""), - ) - : null, + return switch (element.localName) { + "code" => + element.parent?.localName == "pre" + ? CodeBlock( + element.text, + lang: element.className.replaceAll("language-", ""), + ) + : null, - "blockquote" => Quoted( - Html(element.innerHtml, textStyle: textStyle, roomId: roomId), - ), + "blockquote" => Quoted( + Html(element.innerHtml, textStyle: textStyle, roomId: roomId), + ), - "a" => - element.attributes["href"]?.mention == null - ? null - : InlineCustomWidget( - child: MentionChip(element.attributes["href"]!, roomId), - ), - - "img" => - src == null - ? SizedBox.shrink() - : InlineCustomWidget( - alignment: PlaceholderAlignment.middle, - child: ExpandableImage( - .new(mxc: src), - child: Image( - image: MxcImage(ref, .new(mxc: src)), - errorBuilder: (_, error, _) => Text( - "Image Failed to Load", - style: .new(color: Theme.of(context).colorScheme.error), + "a" => + element.attributes["href"]?.mention == null + ? null + : InlineCustomWidget( + child: MentionChip(element.attributes["href"]!, roomId), ), - height: height.toDouble(), - width: width?.toDouble(), - loadingBuilder: (_, child, loadingProgress) => - loadingProgress == null - ? child - : CircularProgressIndicator(), - ), - ), - ), - // Allowed elements list - ("del" || - "h1" || - "h2" || - "h3" || - "h4" || - "h5" || - "h6" || - "p" || - "ul" || - "ol" || - "sup" || - "sub" || - "li" || - "b" || - "i" || - "u" || - "strong" || - "em" || - "s" || - "code" || - "hr" || - "br" || - "div" || - "table" || - "thead" || - "tbody" || - "tr" || - "th" || - "td" || - "caption" || - "pre" || - "span" || - "details" || - "summary") => - null, + "img" => + src == null + ? SizedBox.shrink() + : InlineCustomWidget( + alignment: PlaceholderAlignment.middle, + child: ExpandableImage( + .new(mxc: src), + child: Image( + image: MxcImage(ref, .new(mxc: src)), + errorBuilder: (_, error, _) => Text( + "Image Failed to Load", + style: .new( + color: Theme.of(context).colorScheme.error, + ), + ), + height: height.toDouble(), + width: width?.toDouble(), + loadingBuilder: (_, child, loadingProgress) => + loadingProgress == null + ? child + : CircularProgressIndicator(), + ), + ), + ), - _ => SizedBox.shrink(), - }; - }, - customStylesBuilder: (element) => { - "width": "auto", - ...Map.fromEntries( - element.attributes - .mapTo?>( - (key, value) => switch (key) { - "data-mx-color" => .new("color", value), - "data-mx-bg-color" => .new("background-color", value), - _ => null, - }, - ) - .nonNulls, - ), - }, - onTapUrl: (url) => ref.watch(LaunchHelper.provider).launchUrl(.parse(url)), - ); + // Allowed elements list + ("del" || + "h1" || + "h2" || + "h3" || + "h4" || + "h5" || + "h6" || + "p" || + "ul" || + "ol" || + "sup" || + "sub" || + "li" || + "b" || + "i" || + "u" || + "strong" || + "em" || + "s" || + "code" || + "hr" || + "br" || + "div" || + "table" || + "thead" || + "tbody" || + "tr" || + "th" || + "td" || + "caption" || + "pre" || + "span" || + "details" || + "summary") => + null, + + _ => SizedBox.shrink(), + }; + }, + customStylesBuilder: (element) => { + "width": "auto", + ...Map.fromEntries( + element.attributes + .mapTo?>( + (key, value) => switch (key) { + "data-mx-color" => .new("color", value), + "data-mx-bg-color" => .new("background-color", value), + _ => null, + }, + ) + .nonNulls, + ), + }, + onTapUrl: (url) => + ref.watch(LaunchHelper.provider).launchUrl(.parse(url)), + ), + ); } From a680c5cd0c4db2427d14577a8edad10ffaa73053 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 22 Aug 2026 15:15:39 -0400 Subject: [PATCH 081/176] update `navigation_rail_m3e` hash --- linux/nix/pkg/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/nix/pkg/default.nix b/linux/nix/pkg/default.nix index 49f0a00..1114d43 100644 --- a/linux/nix/pkg/default.nix +++ b/linux/nix/pkg/default.nix @@ -31,7 +31,7 @@ flutter.buildFlutterApplication { gitHashes = { emoji_text_field = "sha256-3TOys09EP2GRo6pUBGPXaqBlE39O2Cmwt42Hs1cTDKo="; linkify = "sha256-TpMD6+0zyY6i9l+6d8ErnVufmepCv362rCtnbOht/z4="; - navigation_rail_m3e = "sha256-LbReuEG/fYjehmXsyimZ2JSf4fyuhDpmaywsxsXzToI="; + navigation_rail_m3e = "sha256-+2awDTQnK58gGRY1nuHckG/jjxarsYSRu9ovR4i4TEc="; }; postInstall = '' From 47a3d9d92ffba51f9427c8d663b8f40ebf4c6d9c Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 22 Aug 2026 15:19:46 -0400 Subject: [PATCH 082/176] Add comment about why MaterialUiCompatibilityBridge is needed for HtmlWidget [skip ci] --- lib/widgets/html/html.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/widgets/html/html.dart b/lib/widgets/html/html.dart index 0e95edd..e4b8c01 100644 --- a/lib/widgets/html/html.dart +++ b/lib/widgets/html/html.dart @@ -19,6 +19,7 @@ class const Html( }) extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) => + // needed until https://github.com/daohoangson/flutter_widget_from_html/issues/1618 is resolved MaterialUiCompatibilityBridge( child: HtmlWidget( html, From e2f25749e02642e62d2f2cb723e8d367817319bd Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sun, 23 Aug 2026 14:00:11 -0400 Subject: [PATCH 083/176] fix fetching spec versions early --- lib/controllers/settings_sections.dart | 91 ++++++++++++++------------ lib/controllers/spec_versions.dart | 15 +++++ 2 files changed, 64 insertions(+), 42 deletions(-) create mode 100644 lib/controllers/spec_versions.dart diff --git a/lib/controllers/settings_sections.dart b/lib/controllers/settings_sections.dart index 149fe30..042b42b 100644 --- a/lib/controllers/settings_sections.dart +++ b/lib/controllers/settings_sections.dart @@ -1,4 +1,5 @@ import "dart:io"; + import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:material_ui/material_ui.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; @@ -8,6 +9,7 @@ import "package:nexus/controllers/account_data.dart"; import "package:nexus/controllers/client.dart"; import "package:nexus/controllers/client_state.dart"; import "package:nexus/controllers/settings.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"; @@ -18,9 +20,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([ @@ -49,8 +48,7 @@ class SettingsSectionsController .new( 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), @@ -76,8 +74,7 @@ class SettingsSectionsController settings: .new([ .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), @@ -104,40 +101,51 @@ class SettingsSectionsController settings: .new([ .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, ), @@ -156,9 +164,8 @@ class SettingsSectionsController final colorScheme = Theme.of(context).colorScheme; return M3EButton.icon( 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); +} From 88cdcf9863cba7d7c4a86262f43b90332b6eed60 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sun, 23 Aug 2026 14:02:25 -0400 Subject: [PATCH 084/176] use compat bridge for settings sidebar --- lib/pages/settings.dart | 52 ++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 24 deletions(-) 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( From 4314c88d5c60a49c48a5b76c6ee3b5aab7d92ca1 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 9 Sep 2026 15:19:10 -0400 Subject: [PATCH 085/176] fallback to empty profile if fetch fails --- gomuks | 2 +- lib/controllers/client.dart | 10 ++++++++-- lib/models/profile_response.dart | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/gomuks b/gomuks index 9444dd2..0e06c7b 160000 --- a/gomuks +++ b/gomuks @@ -1 +1 @@ -Subproject commit 9444dd293664c300c6e710bb6cddcd9c6cab365d +Subproject commit 0e06c7b74f96d3e29a8101893ca1921d13a90573 diff --git a/lib/controllers/client.dart b/lib/controllers/client.dart index b7d1eb4..af44d2f 100644 --- a/lib/controllers/client.dart +++ b/lib/controllers/client.dart @@ -2,6 +2,7 @@ import "dart:ffi"; import "dart:io"; import "dart:isolate"; import "dart:math"; + import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:ffi/ffi.dart"; import "package:flutter/foundation.dart"; @@ -261,8 +262,13 @@ class ClientController extends AsyncNotifier { Future paginate(PaginateRequest request) async => .fromJson(await _sendCommand("paginate", request.toJson())); - Future getProfile(String userId) async => - .fromJson(await _sendCommand("get_profile", {"user_id": userId})); + Future getProfile(String userId) async { + try { + return .fromJson(await _sendCommand("get_profile", {"user_id": userId})); + } catch (_) { + return ProfileResponse(profile: .new(id: userId)); + } + } Future reportEvent(ReportRequest request) => _sendCommand("report_event", request.toJson()); diff --git a/lib/models/profile_response.dart b/lib/models/profile_response.dart index 8984bcf..fcaaf2e 100644 --- a/lib/models/profile_response.dart +++ b/lib/models/profile_response.dart @@ -9,7 +9,7 @@ part "profile_response.g.dart"; @JsonSerializable() class const ProfileResponse({ @JsonKey(fromJson: Profile.fromJson) required final Profile profile, - required final Bio? bio, + final Bio? bio, }) with _$ProfileResponse { Map toJson() => _$ProfileResponseToJson(this); From 0201f71e5dcf9c5c1dbeca8a7a325f669a11f8ec Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 9 Sep 2026 15:26:04 -0400 Subject: [PATCH 086/176] allow banning left users --- lib/widgets/user_bottom_sheet.dart | 43 +++++++++++++++--------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/lib/widgets/user_bottom_sheet.dart b/lib/widgets/user_bottom_sheet.dart index a725613..feeb5a1 100644 --- a/lib/widgets/user_bottom_sheet.dart +++ b/lib/widgets/user_bottom_sheet.dart @@ -200,36 +200,35 @@ final class const UserBottomSheet( ), if (ref.watch( - PowerLevelController.provider( - .membershipAction( - action: .kick, - roomId: roomId!, - targetUser: userId, - ), - ), - ) && - member.status == .join || - member.status == .invite) + PowerLevelController.provider( + .membershipAction( + action: .kick, + roomId: roomId!, + targetUser: userId, + ), + ), + )) Padding( padding: .only(top: 4), child: Row( mainAxisSize: MainAxisSize.max, spacing: 8, children: [ - M3EButton.icon( - onPressed: () => showMembershipDialog(.kick), - shape: .square, - icon: Icon(Icons.sports_martial_arts), - label: Text("Kick"), - decoration: .new( - backgroundColor: WidgetStatePropertyAll( - theme.colorScheme.error, - ), - foregroundColor: WidgetStatePropertyAll( - theme.colorScheme.onError, + if (member.status == .join || member.status == .invite) + M3EButton.icon( + onPressed: () => showMembershipDialog(.kick), + shape: .square, + icon: Icon(Icons.sports_martial_arts), + label: Text("Kick"), + decoration: .new( + backgroundColor: WidgetStatePropertyAll( + theme.colorScheme.error, + ), + foregroundColor: WidgetStatePropertyAll( + theme.colorScheme.onError, + ), ), ), - ), M3EButton.icon( onPressed: () => showMembershipDialog(.ban), From da352cd035e0097ad6856f312fa4949467dccc11 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 9 Sep 2026 15:37:41 -0400 Subject: [PATCH 087/176] cap max length of embeds --- lib/widgets/url_preview.dart | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/widgets/url_preview.dart b/lib/widgets/url_preview.dart index 37a2733..5eda427 100644 --- a/lib/widgets/url_preview.dart +++ b/lib/widgets/url_preview.dart @@ -31,9 +31,15 @@ class const UrlPreview(final Uri link, {super.key}) extends ConsumerWidget { Text( preview.title!, style: Theme.of(context).textTheme.titleLarge, + maxLines: 3, + overflow: .ellipsis, ), if (preview.description != null) ...[ - Text(preview.description!), + Text( + preview.description!, + maxLines: 20, + overflow: .ellipsis, + ), SizedBox(height: 4), ], if (preview.imageUrl != null) From 0a667fda0bc99c8d725c4d4c0175caab6bcb6eee Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 9 Sep 2026 15:44:25 -0400 Subject: [PATCH 088/176] update gomuks vendorHash --- linux/nix/pkg/gomuks.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/nix/pkg/gomuks.nix b/linux/nix/pkg/gomuks.nix index ffa9d7c..0516f31 100644 --- a/linux/nix/pkg/gomuks.nix +++ b/linux/nix/pkg/gomuks.nix @@ -17,7 +17,7 @@ buildGoModule ( src = "${src}/gomuks"; - vendorHash = "sha256-C03ss88QAnmZu+XxoHhc1M/261xFl8hR/pzLbU37Qe8="; + vendorHash = "sha256-9CS/lAVT8gLWACLomwcEa8YNlAXvBOskPPx4zERg0wQ="; buildPhase = '' runHook preBuild From 1efb68ebe028e2863c7aff54af45e6999392f7ad Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Thu, 10 Sep 2026 15:09:47 -0400 Subject: [PATCH 089/176] bump deps, remove unwanted and now un-needed analyzer rule Fixes #69 --- analysis_options.yaml | 1 - pubspec.lock | 328 ++++++++++++++++-------------------------- pubspec.yaml | 22 +-- 3 files changed, 135 insertions(+), 216 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index 17adc10..00df0c4 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -2,7 +2,6 @@ analyzer: errors: invalid_annotation_target: ignore avoid_print: ignore - annotate_overrides: ignore exclude: - "build/**" - "**/*.g.dart" diff --git a/pubspec.lock b/pubspec.lock index d45c4d4..753373a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,42 +5,42 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "1b0e6a07425a3e460666e88bf1c949ccc7bb0116ad562ce94a1eca60fe820725" + sha256: fe18c7e37d5acb3b43224fa255281dec007970d6fd01f6d76fcd88ed3777a117 url: "https://pub.dev" source: hosted - version: "103.0.0" + version: "107.0.0" analysis_server_plugin: dependency: transitive description: name: analysis_server_plugin - sha256: c58b2a05b260a023eefd0848496ff6b113a318c6c95dad4215165a4bd54ae600 + sha256: fc372bb4778b901afe4dea2e7f71ec74e6cbe772999d9961a4d8e382bc4fa49c url: "https://pub.dev" source: hosted - version: "0.3.18" + version: "0.3.22" analyzer: dependency: transitive description: name: analyzer - sha256: "61c04d0c1bfed555c681ea079519933f071a5a026578ff73c4ff0df2d3462e5e" + sha256: f2dde9e50c23fc95b846b4ef334e98c3ae8c0effd5d2453b02fc9fb3f8939791 url: "https://pub.dev" source: hosted - version: "13.3.0" + version: "14.3.0" analyzer_buffer: dependency: transitive description: name: analyzer_buffer - sha256: "445b77e2054fa3e8c8a8ef1b5e9e6b23bb8028fffd34b5e60eaef315b7750674" + sha256: f890a2e708e38fbf4238ad2f9fd3d506538acdddb0cd8eb2c3e8c7bd17784b57 url: "https://pub.dev" source: hosted - version: "0.3.3" + version: "0.3.4" analyzer_plugin: dependency: transitive description: name: analyzer_plugin - sha256: c2a75baf1657171cc7872db96a12b07e385873cf7a73f2b4f7638e9d0701ee53 + sha256: "521fbb02dada7d99d0fc6d10e4b501a07ae1d39ff2a850afbd0ec2279fb81f5c" url: "https://pub.dev" source: hosted - version: "0.14.12" + version: "0.14.16" app_links: dependency: "direct main" description: @@ -77,10 +77,10 @@ packages: dependency: transitive description: name: archive - sha256: be169cf6ac481e052c4538715d88841d567150dfe1df38aaec76461a4e7b39f2 + sha256: ace891da0862b0e4cabbb064ee3fd87b2728b898949fdb366d83fe98342c9f19 url: "https://pub.dev" source: hosted - version: "4.1.0" + version: "4.2.0" args: dependency: transitive description: @@ -117,34 +117,34 @@ packages: dependency: transitive description: name: build - sha256: b94f5da9ed3d081fd4ecc426c260998b5f4f4eb2f6d89b7e5472edef0b2b2a1b + sha256: "8a5c5761af8e31748bba3c82f68925ace40f3225c3eea25be9beb57eca7cd7a8" url: "https://pub.dev" source: hosted - version: "4.0.10" + version: "4.0.11" build_config: dependency: transitive description: name: build_config - sha256: "94eaf6708fe64408c632ef2689ca3777b112f9421306ccf4f8c84d7c5c9f83f8" + sha256: d466ed2dc9c6cd1d169948879b84ee061eb5e22c64a7c6089879c6296d272a8d url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.3.3" build_daemon: dependency: transitive description: name: build_daemon - sha256: "79e05eaf15a48d7230b053a4363b8eaac0cc234bbd0134c3229455481f55cbc6" + sha256: e1d40ef3f7934986d5da2271b1ba07794921ce263e44d622fb6c406d76589e33 url: "https://pub.dev" source: hosted - version: "4.1.5" + version: "4.1.6" build_runner: dependency: "direct dev" description: name: build_runner - sha256: "90363d438bd9f84a4d5bbb83352251f57d2d9d771bc95a44e6a33fe25fa52774" + sha256: "894c243f6bc32015fec466ce30a6925bd537a77a426ee5bf481120477eb3de67" url: "https://pub.dev" source: hosted - version: "2.16.0" + version: "2.16.1" built_collection: dependency: transitive description: @@ -157,10 +157,10 @@ packages: dependency: transitive description: name: built_value - sha256: "31b24be6615ec7fcf70b3aa5a7469fe35826485e639a16dd7eb83ba30e4cc6a8" + sha256: f87ea98192116f7093cb214551ce1929caae0681fdba282b3d8b4462adee7bb7 url: "https://pub.dev" source: hosted - version: "8.12.7" + version: "8.13.0" button_m3e: dependency: transitive description: @@ -185,14 +185,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.4" - cli_config: - dependency: transitive - description: - name: cli_config - sha256: ac20a183a07002b700f0c25e61b7ee46b23c309d76ab7b7640a028f18e4d99ec - url: "https://pub.dev" - source: hosted - version: "0.2.0" cli_util: dependency: transitive description: @@ -205,18 +197,18 @@ packages: dependency: transitive description: name: clock - sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b + sha256: e51d50bca3217c9a9fa2b41a30e4a38971133f5f9ec7a3d57bae095007f1d28e url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.1.3" code_assets: dependency: "direct main" description: name: code_assets - sha256: bf394f466ba9205f1812a0433b392d6af280f155f56651eda7c18cc32ed493b8 + sha256: cfd4f5f575a49c5f10ca856e9846073f1e6c3ee94912377eea5f6cefc5272941 url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "2.0.0" collection: dependency: "direct main" description: @@ -241,22 +233,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.2" - coverage: - dependency: transitive - description: - name: coverage - sha256: "956a3de0725ca232ad353565a8290d3357592bf4250f6f298a185e2d949c5d3d" - url: "https://pub.dev" - source: hosted - version: "1.15.1" cross_file: dependency: transitive description: name: cross_file - sha256: "92c9c43c383bfa1c32079d3bc492d55d6d4318044b7b47edaff8971cbb555c51" + sha256: f141ea4f277af142a0356955707f6556f37b03947d39d55585981a06ca437bd6 url: "https://pub.dev" source: hosted - version: "0.3.5+4" + version: "0.3.5+5" crypto: dependency: transitive description: @@ -277,18 +261,18 @@ packages: dependency: transitive description: name: cupertino_ui - sha256: "7ed8ce4159d342eec4c65f4ea6eec57adaf9365404378541f38efc1da20a5b3d" + sha256: e9dfe7fac704028f8928cbe4028a0be5e8a709498e8daf8247de99e99a32aef3 url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.0.2" dart_style: dependency: transitive description: name: dart_style - sha256: "3f88fc9c96c568d631356507355a2d1e983ee000c9ac008bdcb39b5bf53ce777" + sha256: "82ade9fc4273f29ed673e33166944465225b4f7fc5d4aaef48605cc751c18fc1" url: "https://pub.dev" source: hosted - version: "3.1.12" + version: "3.1.13" dbus: dependency: transitive description: @@ -382,10 +366,10 @@ packages: dependency: "direct main" description: name: ffigen - sha256: "56fc0be88937409839a59c133dfdee4165e80da324c9e39f59013060249ffb44" + sha256: "31b2ca630cede89babbbf31688d20b735967c51bf60572b06ec16718e5a7f1ec" url: "https://pub.dev" source: hosted - version: "21.0.0" + version: "22.0.0" file: dependency: transitive description: @@ -406,34 +390,34 @@ packages: dependency: transitive description: name: file_selector_android - sha256: "1d45e9910f68c16eb0c74f0b10097ad81aed516ea28054c027137e8f7d75e840" + sha256: "7c76473740e33a11343c8fce88166049230850d2f19cd8a652ea935fcb8c9206" url: "https://pub.dev" source: hosted - version: "0.5.2+9" + version: "0.5.2+10" file_selector_ios: dependency: transitive description: name: file_selector_ios - sha256: e2ecf2885c121691ce13b60db3508f53c01f869fb6e8dc5c1cfa771e4c46aeca + sha256: "97269e5307a0ab813b1fa2430bada0a96e0afb74848417f8676f64ba5de0051c" url: "https://pub.dev" source: hosted - version: "0.5.3+5" + version: "0.5.3+6" file_selector_linux: dependency: transitive description: name: file_selector_linux - sha256: "2567f398e06ac72dcf2e98a0c95df2a9edd03c2c2e0cacd4780f20cdf56263a0" + sha256: da76400e7872ce7637ffdce12749ec24169c25f6195c28372208e65a24bcd2ab url: "https://pub.dev" source: hosted - version: "0.9.4" + version: "0.9.4+1" file_selector_macos: dependency: transitive description: name: file_selector_macos - sha256: "5e0bbe9c312416f1787a68259ea1505b52f258c587f12920422671807c4d618a" + sha256: d57c62362766b5e7ae739448650b66c6aab7a68ba7ecc65e04018652645ae0f4 url: "https://pub.dev" source: hosted - version: "0.9.5" + version: "0.9.5+1" file_selector_platform_interface: dependency: transitive description: @@ -454,10 +438,10 @@ packages: dependency: transitive description: name: file_selector_windows - sha256: "62197474ae75893a62df75939c777763d39c2bc5f73ce5b88497208bc269abfd" + sha256: fbefc5fb92c6d3cbe8d284a2cd971b593bb07d2cd6da8557b81a862250b4acec url: "https://pub.dev" source: hosted - version: "0.9.3+5" + version: "0.9.3+6" fixnum: dependency: transitive description: @@ -528,10 +512,10 @@ packages: dependency: "direct main" description: name: flutter_riverpod - sha256: "56e81e662e6e54e59b231da57e90ac0d06ac67d8e3f2273c129a37ae6282b40c" + sha256: "2b7f9d2a3c730ac1a98221b420cef966b990fca7ab546ede324642ca57a533e3" url: "https://pub.dev" source: hosted - version: "3.4.2" + version: "3.4.3" flutter_svg: dependency: "direct main" description: @@ -554,10 +538,10 @@ packages: dependency: "direct main" description: name: flutter_widget_from_html_core - sha256: "7ff010b116f6abc16429923e616fbc727f3f65ef4cee12ffdb280aeecbc21e7f" + sha256: "530f2e3cc57be1a00f8bfae1b0000064e8a6df0cf1fb4d48a80f85afde9b39b7" url: "https://pub.dev" source: hosted - version: "0.17.2" + version: "0.17.4" fluttertagger: dependency: "direct main" description: @@ -570,10 +554,10 @@ packages: dependency: "direct dev" description: name: freezed - sha256: "27585a6c2b9ac28ffb7b45d87fd1502332af1eb90e1c9f5eb1acb24c71d26e17" + sha256: "541a82723c84298f3ca46a6c2186935aa21ad529ad1f1423d67af18040494f51" url: "https://pub.dev" source: hosted - version: "4.0.0" + version: "4.0.1" freezed_annotation: dependency: "direct main" description: @@ -582,14 +566,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.0" - frontend_server_client: - dependency: transitive - description: - name: frontend_server_client - sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 - url: "https://pub.dev" - source: hosted - version: "4.0.0" get_x_storage: dependency: transitive description: @@ -602,10 +578,10 @@ packages: dependency: transitive description: name: glob - sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de + sha256: "218aeb56050c714f62a3182775320dfa04602b55074873e24e31bbd39bda96fb" url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.2.0" graphs: dependency: transitive description: @@ -634,18 +610,18 @@ packages: dependency: "direct main" description: name: hooks_riverpod - sha256: fce693abc6289c8bb42348eae520b979f7edbaae0c1b77b946ef058d0693f6f6 + sha256: d58e1e14aa112ca9c56d54effb7d0d717b2d3f96dad3cdd1fce16f8740450700 url: "https://pub.dev" source: hosted - version: "3.4.2" + version: "3.4.3" html: dependency: transitive description: name: html - sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602" + sha256: "43b67b8f43321ab066817dfac5619596c98bb1b61624e77203bb4351785f9699" url: "https://pub.dev" source: hosted - version: "0.15.6" + version: "0.15.7" http: dependency: "direct main" description: @@ -698,10 +674,10 @@ packages: dependency: transitive description: name: image_picker_android - sha256: "6f3a1995eafb000333174fae92202622033b0ee7fd917a6cd3730295264df84a" + sha256: "1c0c38790306fda4ed774095620444333e56a2b6bc8fc98f3a35c9398781cf54" url: "https://pub.dev" source: hosted - version: "0.8.13+19" + version: "0.8.13+22" image_picker_for_web: dependency: transitive description: @@ -714,10 +690,10 @@ packages: dependency: transitive description: name: image_picker_ios - sha256: b9c4a438a9ff4f60808c9cf0039b93a42bb6c2211ef6ebb647394b2b3fa84588 + sha256: ee3885b6fcd71958fbc79770dd194c63371439d536d69c47b279171a486482ae url: "https://pub.dev" source: hosted - version: "0.8.13+6" + version: "0.8.13+7" image_picker_linux: dependency: transitive description: @@ -762,10 +738,10 @@ packages: dependency: transitive description: name: io - sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b + sha256: "2635216ca6a737e60de577ffa1a48a0bec76ca8a62917cfc1bb88c14c570646f" url: "https://pub.dev" source: hosted - version: "1.0.5" + version: "1.1.0" js: dependency: transitive description: @@ -851,10 +827,10 @@ packages: dependency: "direct main" description: name: m3e_buttons - sha256: "001031f1b72ef19643a8a6a531aafcfb31a06b53456b6f60014403c125e67056" + sha256: "6bf60389eb7c838ac0402dba3657738ae1b015e312bc955ad8330ac17695a516" url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.0.2" m3e_card_list: dependency: "direct main" description: @@ -891,10 +867,10 @@ packages: dependency: "direct main" description: name: material_ui - sha256: "4f3f38b9953df0a87d6bf5f21880029f77c47048487d5339410c39936be4683b" + sha256: fbfb53cab6c4629438feeade5f3d305f72944bc9d9f25786b19106d32b80ec45 url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.2.0" measure_size: dependency: "direct main" description: @@ -979,10 +955,10 @@ packages: dependency: transitive description: name: mime - sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" + sha256: bd47de35f07e27267e69c8c8b22edf9473bfee170a60d60fcc93730c5144b7f6 url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "2.1.0" motor: dependency: transitive description: @@ -995,10 +971,10 @@ packages: dependency: transitive description: name: native_toolchain_c - sha256: a1c26117c48cebe5677b0cf0e33a980a79a7c5577effc86f52e5a0d309cdcb60 + sha256: "9d233b6f2d9c52e1a2b5fbe70451d2c10ac674d3bb419d0ec8de14989d437c26" url: "https://pub.dev" source: hosted - version: "0.19.3" + version: "0.19.4" navigation_rail_m3e: dependency: "direct main" description: @@ -1008,30 +984,22 @@ packages: url: "https://github.com/Henry-Hiles/material_3_expressive" source: git version: "0.3.5" - node_preamble: - dependency: transitive - description: - name: node_preamble - sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db" - url: "https://pub.dev" - source: hosted - version: "2.0.2" objective_c: dependency: transitive description: name: objective_c - sha256: b7fb95a6d9a4f009edd63dc5ac69f07420b23a16161c6dd8660290b59c602e8e + sha256: ad56fd53a78ff6b1472fa59ff2a4e8b8ccabafc586fc263a1dfad0b99b5553e3 url: "https://pub.dev" source: hosted - version: "9.5.0" + version: "9.6.0" package_config: dependency: transitive description: name: package_config - sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc + sha256: ffcf4cf3d6c0b74ac43708d9f56625506e8a68aa935abe9d267a7330f320eb5d url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "3.0.0" package_info_plus: dependency: "direct main" description: @@ -1124,10 +1092,10 @@ packages: dependency: transitive description: name: platform - sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" + sha256: a36d119c13416516a7b5913fbe8af8531e11633d784c550b2125f76c758524ec url: "https://pub.dev" source: hosted - version: "3.1.6" + version: "3.2.0" plugin_platform_interface: dependency: transitive description: @@ -1148,10 +1116,10 @@ packages: dependency: transitive description: name: pool - sha256: "978783255c543aa3586a1b3c21f6e9d720eb315376a915872c61ef8b5c20177d" + sha256: "4177f68c237ea2128d1bee66ac17b2ce05ba3dbaafcbdd54c5d40a39d0b6b11c" url: "https://pub.dev" source: hosted - version: "1.5.2" + version: "1.5.3" posix: dependency: transitive description: @@ -1160,22 +1128,30 @@ packages: url: "https://pub.dev" source: hosted version: "6.5.2" + process: + dependency: transitive + description: + name: process + sha256: "4242ba3508d37e01808bdf71ad1d5bb93a8d671bf2e7450e6b1b353fb0808891" + url: "https://pub.dev" + source: hosted + version: "5.0.6" pub_semver: dependency: transitive description: name: pub_semver - sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" + sha256: "261236774e8b1d69cfc6b9eabbc96c40f25e7a2d6b171f3385d4f65d5734fb24" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.2.1" pubspec_parse: dependency: transitive description: name: pubspec_parse - sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082" + sha256: c38b81cbf34450b67e0265d73433569d12e34782e30ed769c9cc99c9d5f2e796 url: "https://pub.dev" source: hosted - version: "1.5.0" + version: "1.6.0" quiver: dependency: transitive description: @@ -1196,26 +1172,26 @@ packages: dependency: transitive description: name: riverpod - sha256: "84351b3472a447f7b89f961f95c73287009d58c59d8cc1267425d995f78e50f1" + sha256: "484dfc873ea4c4f4240e5635444fa066f87b07862b7279ebd004a2b71fba4b7a" url: "https://pub.dev" source: hosted - version: "3.4.2" + version: "3.4.3" riverpod_analyzer_utils: dependency: transitive description: name: riverpod_analyzer_utils - sha256: "46a8dd0461080fde8f886f65f87580758dae8495e352f9ea6a09953abc3df7bd" + sha256: bb13cb3985815840cc103eda1027158358c5fdc00f308fc6f76574d0594107af url: "https://pub.dev" source: hosted - version: "1.0.0-dev.11" + version: "1.0.0-dev.12" riverpod_lint: dependency: "direct dev" description: name: riverpod_lint - sha256: "7d37414a82b0f52f3d8e440320830d9a8c59620663884b2bb5baaca26296c995" + sha256: "215cb3cd54a97e09bc3512535fa4e8bedd3bf2a06dc2ae015ac8e0050fc71bd1" url: "https://pub.dev" source: hosted - version: "3.1.8" + version: "3.1.9" rxdart: dependency: transitive description: @@ -1284,18 +1260,18 @@ packages: dependency: transitive description: name: shared_preferences_android - sha256: "0634e64bd719f89c012f392938e173521f535d3ecaf66558fa94a056d22b5cc7" + sha256: "1e12aafe408aa50da80edfd679a2a6bf63ba7ab37c7fa98286da459a757b3399" url: "https://pub.dev" source: hosted - version: "2.4.27" + version: "2.4.28" shared_preferences_foundation: dependency: transitive description: name: shared_preferences_foundation - sha256: "4e7eaffc2b17ba398759f1151415869a34771ba11ebbccd1b0145472a619a64f" + sha256: "2ec3934efa51e46117f23031cc141b8fc878e8525b94ec1ea4f7f586cf1b47ea" url: "https://pub.dev" source: hosted - version: "2.5.6" + version: "2.5.7" shared_preferences_linux: dependency: transitive description: @@ -1336,22 +1312,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.2" - shelf_packages_handler: - dependency: transitive - description: - name: shelf_packages_handler - sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e" - url: "https://pub.dev" - source: hosted - version: "3.0.2" - shelf_static: - dependency: transitive - description: - name: shelf_static - sha256: c87c3875f91262785dade62d135760c2c69cb217ac759485334c5857ad89f6e3 - url: "https://pub.dev" - source: hosted - version: "1.1.3" shelf_web_socket: dependency: transitive description: @@ -1369,10 +1329,10 @@ packages: dependency: transitive description: name: source_gen - sha256: a603f1fb984a7391ae5978d1b92bfaaa08b350dca5c825256f925818f7943bf5 + sha256: "11b6047da8e4eb6c643ccac3d0fda3f9c9e11651695f7da24a85ade8aff15a44" url: "https://pub.dev" source: hosted - version: "4.2.4" + version: "4.3.0" source_helper: dependency: transitive description: @@ -1381,22 +1341,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.13" - source_map_stack_trace: - dependency: transitive - description: - name: source_map_stack_trace - sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b - url: "https://pub.dev" - source: hosted - version: "2.1.2" - source_maps: - dependency: transitive - description: - name: source_maps - sha256: "14c2945847669b44089bb1222f66873d7ff7103c58911917f2a63c5a62327898" - url: "https://pub.dev" - source: hosted - version: "0.10.14" source_span: dependency: transitive description: @@ -1409,10 +1353,10 @@ packages: dependency: transitive description: name: stack_trace - sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" + sha256: "277654b3034d17ac6f9f1cb5595db011b1d5d41e8806866db28e0abaa101c490" url: "https://pub.dev" source: hosted - version: "1.12.1" + version: "1.12.2" state_notifier: dependency: transitive description: @@ -1433,10 +1377,10 @@ packages: dependency: transitive description: name: stream_transform - sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871 + sha256: a00e5f18bffc764f923e7dec1038527f7fe7a1791361a7117f0358193f13d53a url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" string_scanner: dependency: transitive description: @@ -1457,10 +1401,10 @@ packages: dependency: transitive description: name: synchronized - sha256: "3a7b5d17422dd0f8d5c6c14feaa5a1c65638b9455f871a96f08437562c046931" + sha256: "397b146f97613b83d84bdccb439bc8d0f3aebb6c1d14a9641e6f24201c490b2d" url: "https://pub.dev" source: hosted - version: "3.4.1+2" + version: "3.4.2" term_glyph: dependency: transitive description: @@ -1469,14 +1413,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.2" - test: - dependency: transitive - description: - name: test - sha256: ca578dc12bb8b2f40b67b7d3bd2fac4f31c01a6ff7130a14e2597b919934507f - url: "https://pub.dev" - source: hosted - version: "1.31.1" test_api: dependency: transitive description: @@ -1485,14 +1421,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.12" - test_core: - dependency: transitive - description: - name: test_core - sha256: d2e98ec12998368dc59ddd47ab709f2cd55acd6b66dc7db764455a44082f4bc5 - url: "https://pub.dev" - source: hosted - version: "0.6.18" timeago: dependency: "direct main" description: @@ -1537,34 +1465,34 @@ packages: dependency: transitive description: name: url_launcher_android - sha256: b413d49b73867ac08dd2f9890efd3cc11f2a0e577618d50843440a1fb3776c32 + sha256: "611e87fb320b70d1dd721dc46af89c98aceccea9b31fde49e084591414e0c610" url: "https://pub.dev" source: hosted - version: "6.3.32" + version: "6.3.33" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: "580fe5dfb51671ae38191d316e027f6b76272b026370708c2d898799750a02b0" + sha256: "8faa1aab294f1ab4040b43660c887b0418d5fa4f0cffef76a484e6aa1092eb4a" url: "https://pub.dev" source: hosted - version: "6.4.1" + version: "6.4.2" url_launcher_linux: dependency: transitive description: name: url_launcher_linux - sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a + sha256: "10f86fef4c2c43563fa6c211ff9cf757adf4d3ab762c56bd430664a947d70cd0" url: "https://pub.dev" source: hosted - version: "3.2.2" + version: "3.2.3" url_launcher_macos: dependency: transitive description: name: url_launcher_macos - sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18" + sha256: "5e835a3b869c2d70325349c81c5a45c28e20791265b67b2669da6b08c5cd5201" url: "https://pub.dev" source: hosted - version: "3.2.5" + version: "3.2.6" url_launcher_platform_interface: dependency: transitive description: @@ -1585,10 +1513,10 @@ packages: dependency: transitive description: name: url_launcher_windows - sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f" + sha256: "6c5ad3f22cd4c38e089b81963b3cd7bb83b111b2df5dce008bb066162f42e429" url: "https://pub.dev" source: hosted - version: "3.1.5" + version: "3.1.6" uuid: dependency: transitive description: @@ -1641,18 +1569,18 @@ packages: dependency: transitive description: name: wakelock_plus - sha256: "7253bca0fcf40d8413ddfcf4d2a1fa0a82475e79be25a4f2c564b695c9351486" + sha256: "22b3e7e937721de70e63c85e7139f4ac781dc22863b9262431a53ac030eb074b" url: "https://pub.dev" source: hosted - version: "1.7.0" + version: "1.8.0" wakelock_plus_platform_interface: dependency: transitive description: name: wakelock_plus_platform_interface - sha256: "0618d1799f0b28bcf98255b4ee8313e6fc4d38589dc4ee5fe5840d57d1aff6da" + sha256: "764c25504562abc8ac3406f5d175f126b276e6ba916c7c2675690b73368ca384" url: "https://pub.dev" source: hosted - version: "1.6.0" + version: "1.7.0" watcher: dependency: transitive description: @@ -1685,14 +1613,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.3" - webkit_inspection_protocol: - dependency: transitive - description: - name: webkit_inspection_protocol - sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572" - url: "https://pub.dev" - source: hosted - version: "1.2.1" win32: dependency: transitive description: @@ -1729,10 +1649,10 @@ packages: dependency: transitive description: name: yaml - sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce + sha256: f67cdd8e07d3c6329146aaef1ba043542b3134c12489f553ca9a7435d1068aea url: "https://pub.dev" source: hosted - version: "3.1.3" + version: "3.1.4" yaml_edit: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index a9b2e01..4b69b2c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -31,8 +31,8 @@ dependencies: sdk: flutter flutter_localizations: sdk: flutter - flutter_riverpod: 3.4.2 - hooks_riverpod: 3.4.2 + flutter_riverpod: 3.4.3 + hooks_riverpod: 3.4.3 intl: 0.20.3 fast_immutable_collections: 11.2.0 path_provider: 2.1.6 @@ -44,7 +44,7 @@ dependencies: collection: 1.19.1 window_manager: 0.5.2 color_hash: 1.0.1 - flutter_widget_from_html_core: 0.17.2 + flutter_widget_from_html_core: 0.17.4 flutter_svg: 2.3.0 json_annotation: 4.12.0 shared_preferences: 2.5.5 @@ -52,9 +52,9 @@ dependencies: dynamic_polls: 0.0.8 flutter_hooks: 0.21.3+1 ffi: 2.2.0 - hooks: ^2.2.0 - code_assets: 1.2.1 - ffigen: 21.0.0 + hooks: 2.2.0 + code_assets: 2.0.0 + ffigen: 22.0.0 timeago: 3.7.1 http: 1.6.0 flutter_linkify: 6.0.0 @@ -68,7 +68,7 @@ dependencies: media_kit_video: 2.0.1 media_kit_libs_video: 1.0.7 measure_size: 5.0.2 - m3e_buttons: 1.0.0 + m3e_buttons: 1.0.2 navigation_rail_m3e: git: url: https://github.com/Henry-Hiles/material_3_expressive @@ -78,13 +78,13 @@ dependencies: package_info_plus: 10.2.1 app_links: 7.2.1 file_selector: 1.1.0 - material_ui: 1.0.1 + material_ui: 1.2.0 dev_dependencies: - build_runner: 2.16.0 + build_runner: 2.16.1 flutter_lints: 6.0.0 - freezed: 4.0.0 - riverpod_lint: 3.1.8 + freezed: 4.0.1 + riverpod_lint: 3.1.9 flutter_launcher_icons: 0.14.4 json_serializable: 6.14.1 From 51ef66174a5cb3093d3e043c8aad73146aaeeed4 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Thu, 10 Sep 2026 15:15:12 -0400 Subject: [PATCH 090/176] fix generate script to work with new ffigen --- scripts/generate.dart | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/generate.dart b/scripts/generate.dart index 4dc7329..7109929 100644 --- a/scripts/generate.dart +++ b/scripts/generate.dart @@ -1,4 +1,5 @@ import "dart:io"; + import "package:ffigen/ffigen.dart"; import "package:path/path.dart"; import "package:nexus/helpers/extensions/get_xcode_sdk.dart"; @@ -11,16 +12,17 @@ void main(List args) async { final libclangPath = Platform.environment["LIBCLANG_PATH"]; FfiGenerator( output: Output( - dartFile: Platform.script.resolve("../lib/src/third_party/gomuks.g.dart"), + dart: .new( + path: Platform.script.resolve("../lib/src/third_party/gomuks.g.dart"), + ), ), - headers: Headers( + input: .new( entryPoints: [File(join(repoDir.path, "pkg", "ffi", "gomuksffi.h")).uri], compilerOptions: [ "--no-warnings", if (Platform.isMacOS) "-I${await getXCodeTool()}/usr/include", ], ), - functions: Functions.includeAll, ).generate( libclangDylib: libclangPath == null ? null From 3d7ef9b32f79a3d59d4baf3d98c968434873c4d6 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Thu, 10 Sep 2026 15:20:56 -0400 Subject: [PATCH 091/176] actually generate bindings Yes `ffigen`, I did actually want you to generate the bindings, not a file consisting only of comments. Crazy, right? --- scripts/generate.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/generate.dart b/scripts/generate.dart index 7109929..2966c9f 100644 --- a/scripts/generate.dart +++ b/scripts/generate.dart @@ -16,6 +16,7 @@ void main(List args) async { path: Platform.script.resolve("../lib/src/third_party/gomuks.g.dart"), ), ), + visitors: [Visitor(func: (node) => node.isIncluded = true)], input: .new( entryPoints: [File(join(repoDir.path, "pkg", "ffi", "gomuksffi.h")).uri], compilerOptions: [ From c105a6035cb810d7021562e21f0211dbb87e15cc Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Thu, 10 Sep 2026 15:21:53 -0400 Subject: [PATCH 092/176] use dot shorthands where possible in generate script --- scripts/generate.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/generate.dart b/scripts/generate.dart index 2966c9f..b9b8511 100644 --- a/scripts/generate.dart +++ b/scripts/generate.dart @@ -11,12 +11,12 @@ void main(List args) async { final libclangPath = Platform.environment["LIBCLANG_PATH"]; FfiGenerator( - output: Output( + output: .new( dart: .new( path: Platform.script.resolve("../lib/src/third_party/gomuks.g.dart"), ), ), - visitors: [Visitor(func: (node) => node.isIncluded = true)], + visitors: [.new(func: (node) => node.isIncluded = true)], input: .new( entryPoints: [File(join(repoDir.path, "pkg", "ffi", "gomuksffi.h")).uri], compilerOptions: [ From 6e42902322d208887f35b11ec75a5818c00ddcec Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Thu, 10 Sep 2026 15:32:30 -0400 Subject: [PATCH 093/176] run GomuksInit on an Isolate Fixes #70 --- lib/controllers/client.dart | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/controllers/client.dart b/lib/controllers/client.dart index af44d2f..27c0646 100644 --- a/lib/controllers/client.dart +++ b/lib/controllers/client.dart @@ -49,15 +49,17 @@ import "package:path_provider/path_provider.dart"; class ClientController extends AsyncNotifier { @override Future build() async { - final Pointer root; - if (Platform.isAndroid || Platform.isIOS) { - final dir = await getApplicationSupportDirectory(); - root = "${dir.path}/gomuks".toNativeUtf8().cast(); - } else { - root = nullptr.cast(); - } + final handle = await Isolate.run(() async { + final Pointer root; + if (Platform.isAndroid || Platform.isIOS) { + final dir = await getApplicationSupportDirectory(); + root = "${dir.path}/gomuks".toNativeUtf8().cast(); + } else { + root = nullptr.cast(); + } - final handle = GomuksInit(root); + return GomuksInit(root); + }); final callable = NativeCallable< From ff9bf3bec45494a6db86151ce66415404747e21d Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Thu, 10 Sep 2026 15:37:05 -0400 Subject: [PATCH 094/176] Push Notifications (#66) Fixes #35. Things to do: - [x] Register with local distributor - [x] Register with homeserver - [x] Recieve messages - [x] Show notifications - [ ] Notifications page (could come later) Reviewed-on: https://git.federated.nexus/Nexus/nexus/pulls/66 --- .vscode/settings.json | 4 +- README.md | 6 + android/app/build.gradle.kts | 14 +- ios/Runner/AppDelegate.swift | 3 +- lib/controllers/client.dart | 50 +++++- lib/controllers/key.dart | 1 + lib/controllers/notifications.dart | 120 +++++++++++++ lib/controllers/push_key.dart | 30 ++++ lib/controllers/settings_sections.dart | 92 +++++++++- lib/controllers/unified_push.dart | 164 ++++++++++++++++++ lib/controllers/unified_push_allowed.dart | 33 ++++ lib/main.dart | 37 ++-- lib/models/capabilities.dart | 25 +++ lib/models/client_state.dart | 1 + lib/models/join_rule.dart | 2 +- lib/models/membership_action.dart | 3 - lib/models/membership_status.dart | 3 - lib/models/requests/deregister_pusher.dart | 13 ++ lib/models/requests/register_pusher.dart | 56 ++++++ lib/pages/notifications.dart | 14 ++ lib/widgets/appbar.dart | 2 +- linux/flutter/generated_plugin_registrant.cc | 4 + linux/flutter/generated_plugins.cmake | 1 + linux/nix/devshell.nix | 1 - linux/runner/my_application.cc | 2 + macos/Flutter/GeneratedPluginRegistrant.swift | 4 + pubspec.lock | 112 ++++++++++++ pubspec.yaml | 6 + .../flutter/generated_plugin_registrant.cc | 3 + windows/flutter/generated_plugins.cmake | 2 + 30 files changed, 772 insertions(+), 36 deletions(-) create mode 100644 lib/controllers/notifications.dart create mode 100644 lib/controllers/push_key.dart create mode 100644 lib/controllers/unified_push.dart create mode 100644 lib/controllers/unified_push_allowed.dart create mode 100644 lib/models/capabilities.dart create mode 100644 lib/models/requests/deregister_pusher.dart create mode 100644 lib/models/requests/register_pusher.dart create mode 100644 lib/pages/notifications.dart diff --git a/.vscode/settings.json b/.vscode/settings.json index 2ff533e..fac2ed8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,6 +11,8 @@ "muks", "prefs", "unban", - "unredact" + "unifiedpush", + "unredact", + "webpush" ] } diff --git a/README.md b/README.md index 0c18acf..ee55903 100644 --- a/README.md +++ b/README.md @@ -190,6 +190,12 @@ dart scripts/generate.dart > export CPATH="$(clang -v 2>&1 | grep "Selected GCC installation" | rev | cut -d' ' -f1 | rev)/include" > ``` +Build webcrypto: + +```sh +flutter pub run webcrypto:setup +``` + Build generated files, and watch for new changes: ```sh diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 8a23bb6..9c0d96c 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -20,16 +20,21 @@ android { ndkVersion = flutter.ndkVersion compileOptions { - sourceCompatibility = JavaVersion.VERSION_21 + isCoreLibraryDesugaringEnabled = true + sourceCompatibility = JavaVersion.VERSION_21 targetCompatibility = JavaVersion.VERSION_21 } defaultConfig { applicationId = "nexus.federated.nexus" - minSdk = 29 + + minSdk = 29 targetSdk = flutter.targetSdkVersion + versionCode = flutter.versionCode versionName = flutter.versionName + + multiDexEnabled = true } signingConfigs { @@ -63,6 +68,11 @@ android { } } +dependencies { + implementation("org.unifiedpush.android:embedded-fcm-distributor:3.1.0") + coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4") +} + kotlin { compilerOptions { jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_21 diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index c30b367..c73d4ae 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -7,7 +7,8 @@ import UIKit _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { - return super.application(application, didFinishLaunchingWithOptions: launchOptions) + UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate + return super.application(application, didFinishLaunchingWithOptions: launchOptions) } func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) { diff --git a/lib/controllers/client.dart b/lib/controllers/client.dart index 27c0646..b8e060d 100644 --- a/lib/controllers/client.dart +++ b/lib/controllers/client.dart @@ -1,3 +1,4 @@ +import "dart:async"; import "dart:ffi"; import "dart:io"; import "dart:isolate"; @@ -15,11 +16,13 @@ import "package:nexus/controllers/sync_status.dart"; import "package:nexus/controllers/top_level_spaces.dart"; import "package:nexus/helpers/extensions/gomuks_buffer.dart"; import "package:nexus/main.dart"; +import "package:nexus/models/capabilities.dart"; import "package:nexus/models/content/message.dart"; import "package:nexus/models/event.dart"; import "package:nexus/models/oauth_auth_code_response.dart"; import "package:nexus/models/open_graph_data.dart"; import "package:nexus/models/paginate.dart"; +import "package:nexus/models/requests/deregister_pusher.dart"; import "package:nexus/models/requests/download_media.dart"; import "package:nexus/models/requests/get_event.dart"; import "package:nexus/models/requests/get_related_events.dart"; @@ -31,6 +34,7 @@ import "package:nexus/models/requests/oauth/get_auth_url.dart"; import "package:nexus/models/requests/oauth/register_client.dart"; import "package:nexus/models/requests/paginate.dart"; import "package:nexus/models/requests/redact_event.dart"; +import "package:nexus/models/requests/register_pusher.dart"; import "package:nexus/models/requests/report.dart"; import "package:nexus/models/requests/send_event.dart"; import "package:nexus/models/requests/send_message.dart"; @@ -156,18 +160,15 @@ class ClientController extends AsyncNotifier { throw Exception("GomuksStart returned error code $errorCode"); } - Future _sendCommand( - String command, [ - Map data = const {}, - ]) async { + Future callGomuksMethod( + Map data, + FutureOr Function(int handle, GomuksBorrowedBuffer data) + callback, + ) async { final bufferPointer = data.toGomuksBufferPtr(); final handle = await future; final response = await Isolate.run( - () => GomuksSubmitCommand( - handle, - command.toNativeUtf8().cast(), - bufferPointer.ref, - ), + () => callback(handle, bufferPointer.ref), ); calloc.free(bufferPointer); @@ -180,6 +181,24 @@ class ClientController extends AsyncNotifier { return json; } + Future handlePush(Map data) async { + final response = await callGomuksMethod( + data, + (handle, data) async => GomuksHandlePush(handle, data), + ); + + return response == null ? null : .fromJson(response); + } + + Future _sendCommand( + String command, [ + Map data = const {}, + ]) => callGomuksMethod( + data, + (handle, data) async => + GomuksSubmitCommand(handle, command.toNativeUtf8().cast(), data), + ); + Future redactEvent(RedactEventRequest report) => _sendCommand("redact_event", report.toJson()); @@ -281,6 +300,15 @@ class ClientController extends AsyncNotifier { Future setAccountData(SetAccountDataRequest request) => _sendCommand("set_account_data", request.toJson()); + Future registerPusher(RegisterPusherRequest request) => + _sendCommand("register_homeserver_push", request.toJson()); + + Future deregisterPusher(DeregisterPusherRequest request) => + _sendCommand("register_homeserver_push", { + ...request.toJson(), + "kind": null, + }); + Future uploadMedia(UploadMediaRequest request) async => .fromJson(await _sendCommand("upload_media", request.toJson())); @@ -318,6 +346,10 @@ class ClientController extends AsyncNotifier { Future getSpecVersions() async => .fromJson(await _sendCommand("get_versions")); + Future getCapabilities() async => Capabilities.fromJson( + (await _sendCommand("get_capabilities"))["capabilities"], + ); + Future discoverHomeserver(Uri homeserver) async { try { final response = await _sendCommand("discover_homeserver", { diff --git a/lib/controllers/key.dart b/lib/controllers/key.dart index b78acf8..0d02d17 100644 --- a/lib/controllers/key.dart +++ b/lib/controllers/key.dart @@ -4,6 +4,7 @@ import "package:nexus/controllers/shared_prefs.dart"; class KeyController(final String key) extends Notifier { static const String spaceKey = "space"; static const String roomKey = "room"; + static const String pushKeyKey = "pushKey"; @override String? build() => diff --git a/lib/controllers/notifications.dart b/lib/controllers/notifications.dart new file mode 100644 index 0000000..bd80467 --- /dev/null +++ b/lib/controllers/notifications.dart @@ -0,0 +1,120 @@ +import "dart:io"; + +import "package:material_ui/material_ui.dart"; +import "package:nexus/main.dart"; +import "package:flutter_local_notifications/flutter_local_notifications.dart"; +// ignore: implementation_imports +import "package:flutter_local_notifications_linux/src/model/hint.dart"; +import "package:flutter_riverpod/flutter_riverpod.dart"; +import "package:nexus/pages/notifications.dart"; + +class NotificationsController + extends AsyncNotifier { + @override + Future build() async { + final notifications = FlutterLocalNotificationsPlugin(); + + final darwin = DarwinInitializationSettings(); + + await notifications.initialize( + settings: .new( + windows: .new( + appName: "Nexus", + appUserModelId: "nexus.federated.nexus", + guid: "dde78daf-130f-4e46-a80a-e31deeab45d7", + ), + android: .new("ic_launcher_foreground"), + iOS: darwin, + macOS: darwin, + linux: .new(defaultActionName: "Open"), + ), + onDidReceiveNotificationResponse: (details) { + if (details.payload case final eventId?) { + if (navigatorKey.currentContext case final context?) { + Navigator.of(context).push( + MaterialPageRoute( + builder: (_) => NotificationsPage(eventId: eventId), + ), + ); + } + } + }, + ); + + return notifications; + } + + Future requestPermissions() async { + final controller = await future; + + if (Platform.isIOS) { + return await controller + .resolvePlatformSpecificImplementation< + IOSFlutterLocalNotificationsPlugin + >() + ?.requestPermissions(alert: true, badge: true, sound: true) ?? + true; + } else if (Platform.isMacOS) { + return await controller + .resolvePlatformSpecificImplementation< + MacOSFlutterLocalNotificationsPlugin + >() + ?.requestPermissions(alert: true, badge: true, sound: true) ?? + true; + } else if (Platform.isAndroid) { + return await controller + .resolvePlatformSpecificImplementation< + AndroidFlutterLocalNotificationsPlugin + >() + ?.requestNotificationsPermission() ?? + true; + } + + return true; + } + + Future send({ + required int id, + required String title, + String? body, + File? icon, + String? payload, + }) async { + final notificationDetails = NotificationDetails( + android: .new( + "messages", + "Messages", + largeIcon: icon == null ? null : FilePathAndroidBitmap(icon.path), + ), + linux: .new( + customHints: icon == null + ? null + : [ + .new( + name: "image-path", + value: LinuxHintStringValue(icon.path), + ), + ], + ), + // TODO: See if icons can be added to iOS, macOS, and Windows notifications (#68) + iOS: .new(), + macOS: .new(), + windows: .new(), + ); + + final controller = await future; + await controller.show( + id: id, + title: title, + body: body, + notificationDetails: notificationDetails, + payload: payload, + ); + } + + static final provider = + AsyncNotifierProvider< + NotificationsController, + FlutterLocalNotificationsPlugin + >(NotificationsController.new); +} diff --git a/lib/controllers/push_key.dart b/lib/controllers/push_key.dart new file mode 100644 index 0000000..7217886 --- /dev/null +++ b/lib/controllers/push_key.dart @@ -0,0 +1,30 @@ +import "dart:convert"; + +import "package:fast_immutable_collections/fast_immutable_collections.dart"; +import "package:flutter_riverpod/flutter_riverpod.dart"; +import "package:nexus/controllers/key.dart"; + +class PushKeyController(final String instance) extends Notifier { + @override + String? build() => json.decode( + ref.watch(KeyController.provider(KeyController.pushKeyKey)) ?? "{}", + )[instance]; + + Future set(String? value) async { + final provider = KeyController.provider(KeyController.pushKeyKey); + final notifier = ref.watch(provider.notifier); + final prefs = IMap(json.decode(ref.watch(provider) ?? "{}")); + + state = value; + notifier.set( + json.encode( + prefs.add(instance, value).where((_, value) => value != null).unlock, + ), + ); + } + + static final provider = + NotifierProvider.family( + PushKeyController.new, + ); +} diff --git a/lib/controllers/settings_sections.dart b/lib/controllers/settings_sections.dart index 042b42b..1e60263 100644 --- a/lib/controllers/settings_sections.dart +++ b/lib/controllers/settings_sections.dart @@ -1,15 +1,19 @@ import "dart:io"; import "package:fast_immutable_collections/fast_immutable_collections.dart"; +import "package:flutter_hooks/flutter_hooks.dart"; +import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:material_ui/material_ui.dart"; -import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:intl/intl.dart"; import "package:m3e_buttons/m3e_buttons.dart"; import "package:nexus/controllers/account_data.dart"; import "package:nexus/controllers/client.dart"; import "package:nexus/controllers/client_state.dart"; +import "package:nexus/controllers/notifications.dart"; import "package:nexus/controllers/settings.dart"; +import "package:nexus/controllers/unified_push.dart"; import "package:nexus/controllers/spec_versions.dart"; +import "package:nexus/controllers/unified_push_allowed.dart"; import "package:nexus/models/account_data.dart"; import "package:nexus/models/settings_category.dart"; import "package:nexus/main.dart"; @@ -95,6 +99,90 @@ class SettingsSectionsController if (ref.watch(ClientStateController.provider)?.isLoggedIn == true) "Account": .new([ .new(title: "Profile", icon: Icons.person, settings: .new([])), + .new( + title: "Notifications", + icon: Icons.notifications, + settings: .new([ + .new( + title: "Push notifications", + description: "Enable push notifications using Web Push", + builder: (title, description, icon) => HookConsumer( + builder: (context, ref, _) { + final loading = useState(false); + final pusherRegistered = ref.watch( + UnifiedPushController.provider, + ); + final unifiedPushAllowed = ref.watch( + UnifiedPushAllowedController.provider, + ); + + return SwitchListTile( + title: Text(title), + subtitle: Text( + unifiedPushAllowed.maybeWhen( + data: (data) => data, + orElse: () => null, + ) ?? + description, + ), + secondary: Icon(icon), + value: pusherRegistered.maybeWhen( + data: (value) => value, + orElse: () => false, + ), + onChanged: loading.value + ? null + : unifiedPushAllowed.maybeWhen( + data: (data) => data == null, + orElse: () => false, + ) + ? pusherRegistered.maybeWhen( + data: (_) => (value) async { + try { + loading.value = true; + if (value) { + if (await ref + .watch( + NotificationsController + .provider + .notifier, + ) + .requestPermissions()) { + await ref + .watch( + UnifiedPushController + .provider + .notifier, + ) + .register(); + } else { + // TODO: Handle not granted + } + } else { + await ref + .watch( + UnifiedPushController + .provider + .notifier, + ) + .deregister(); + } + } catch (error, stackTrace) { + showError(error, stackTrace); + } finally { + loading.value = false; + } + }, + orElse: () => null, + ) + : null, + ); + }, + ), + icon: Icons.notification_add, + ), + ]), + ), .new( title: "Safety", icon: Icons.gpp_good, @@ -166,6 +254,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/unified_push.dart b/lib/controllers/unified_push.dart new file mode 100644 index 0000000..1c1b41a --- /dev/null +++ b/lib/controllers/unified_push.dart @@ -0,0 +1,164 @@ +import "dart:convert"; +import "dart:io"; + +import "package:flutter/foundation.dart"; +import "package:flutter_riverpod/flutter_riverpod.dart"; +import "package:intl/intl.dart"; +import "package:nexus/controllers/key.dart"; +import "package:nexus/controllers/notifications.dart"; +import "package:nexus/controllers/push_key.dart"; +import "package:nexus/controllers/rooms.dart"; +import "package:nexus/main.dart"; +import "package:nexus/controllers/client.dart"; +import "package:nexus/controllers/client_state.dart"; +import "package:nexus/models/content/message.dart"; +import "package:nexus/models/content/sticker.dart"; +import "package:nexus/models/requests/register_pusher.dart"; +import "package:unifiedpush/unifiedpush.dart"; +import "package:unifiedpush_storage_shared_preferences/storage.dart"; +import "package:window_manager/window_manager.dart"; + +class UnifiedPushController extends AsyncNotifier { + @override + Future build() async { + final client = ref.watch(ClientController.provider.notifier); + final registered = await UnifiedPush.initialize( + linuxOptions: .new( + dbusName: "nexus.federated.nexus.UnifiedPush", + storage: UnifiedPushStorageSharedPreferences(), + background: isInBackground, + ), + onNewEndpoint: (endpoint, instance) async { + final pushKey = endpoint.pubKeySet!.pubKey; + await ref + .watch(PushKeyController.provider(instance).notifier) + .set(pushKey); + + await client.registerPusher( + .new( + appDisplayName: "Nexus", + appId: "nexus.federated.nexus", + data: PusherData.webPush( + url: Uri.parse(endpoint.url), + auth: endpoint.pubKeySet!.auth, + ), + deviceDisplayName: + "Nexus on ${toBeginningOfSentenceCase(Platform.operatingSystem)}", + kind: .webPush, + lang: "en", + pushKey: pushKey, + ), + ); + }, + onMessage: (message, instance) async { + if (message.decrypted == false) { + throw Exception( + "Failed to decrypt notification. Try toggling off and on UnifiedPush in settings.", + ); + } + final event = await client.handlePush( + json.decode(String.fromCharCodes(message.content)), + ); + + if (event == null || + event.unreadType?.shouldNotify != true || + (!isInBackground && + await windowManager.isFocused().onError((_, _) => false) && + ref.watch(KeyController.provider(KeyController.roomKey)) == + event.roomId)) { + return; + } + + final room = ref.read( + RoomsController.provider.select((rooms) => rooms[event.roomId]), + ); + + final avatar = room?.metadata?.avatar; + final icon = avatar == null + ? null + : await ref + .read(ClientController.provider.notifier) + .downloadMedia(.new(mxc: avatar, isAvatar: true)); + + await ref + .read(NotificationsController.provider.notifier) + .send( + id: event.eventId.hashCode & 0x7fffffff, + title: room?.metadata?.name ?? "New Event", + icon: icon, + payload: event.eventId, + body: switch (event.content) { + MessageContent(:final body?) || + StickerContent(:final body) => body, + _ => null, + }, + ); + + if (isInBackground) exit(0); + }, + onRegistrationFailed: (error, instance) => throw error, + onUnregistered: (instance) async { + await ref + .watch(PushKeyController.provider(instance).notifier) + .set(null); + ref.invalidateSelf(); + }, + ); + + if (registered) { + // Needs to be registered every startup + await register(true); + } + + return registered; + } + + Future register([bool alreadyRegistered = false]) async { + final clientState = ref.watch(ClientStateController.provider); + if (clientState?.deviceId == null) ref.invalidateSelf(); + + final capabilities = await ref + .watch(ClientController.provider.notifier) + .getCapabilities(); + + if (capabilities.webpush?.vapid == null) { + throw UnsupportedError( + "Your homeserver does not support MSC4174 (Web Push), and therefore cannot send notifications to Nexus.", + ); + } + + if (!alreadyRegistered && + !await UnifiedPush.tryUseCurrentOrDefaultDistributor()) { + throw Exception("No UnifiedPush distributors found"); + } + + await UnifiedPush.register( + instance: clientState!.deviceId!, + vapid: capabilities.webpush?.vapid, + ); + + if (!alreadyRegistered) ref.invalidateSelf(); + } + + Future deregister() async { + final clientState = ref.watch(ClientStateController.provider); + final key = ref.watch(PushKeyController.provider(clientState!.deviceId!)); + + if (key != null) { + await ref + .watch(ClientController.provider.notifier) + .deregisterPusher(.new(appId: "nexus.federated.nexus", pushKey: key)); + } else { + debugPrint( + "No matching pushKey found. Skipping deregistration from homeserver.", + ); + } + + await UnifiedPush.unregister(clientState.deviceId!); + ref.invalidateSelf(); + } + + static final provider = AsyncNotifierProvider( + UnifiedPushController.new, + ); +} diff --git a/lib/controllers/unified_push_allowed.dart b/lib/controllers/unified_push_allowed.dart new file mode 100644 index 0000000..af50d62 --- /dev/null +++ b/lib/controllers/unified_push_allowed.dart @@ -0,0 +1,33 @@ +import "dart:io"; + +import "package:flutter_riverpod/flutter_riverpod.dart"; +import "package:nexus/controllers/client.dart"; +import "package:unifiedpush/unifiedpush.dart"; + +class UnifiedPushAllowedController extends AsyncNotifier { + @override + Future build() async { + if (!await UnifiedPush.tryUseCurrentOrDefaultDistributor()) { + return "No valid distributors found. Try installing ${Platform.isLinux + ? "KUnifiedPush" + : Platform.isAndroid + ? "Google Play Services or NTFY" + : "NTFY"}."; + } + + final capabilities = await ref + .watch(ClientController.provider.notifier) + .getCapabilities(); + + if (capabilities.webpush?.vapid == null) { + return "Your homeserver does not support MSC4174 (Web Push), and therefore cannot send notifications to Nexus."; + } + + return null; + } + + static final provider = + AsyncNotifierProvider.autoDispose( + UnifiedPushAllowedController.new, + ); +} diff --git a/lib/main.dart b/lib/main.dart index a87d7f5..aaed5a0 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -8,8 +8,10 @@ import "package:media_kit/media_kit.dart"; import "package:nexus/controllers/client.dart"; import "package:nexus/controllers/client_state.dart"; import "package:nexus/controllers/multi_provider.dart"; +import "package:nexus/controllers/notifications.dart"; import "package:nexus/controllers/settings.dart"; import "package:nexus/controllers/shared_prefs.dart"; +import "package:nexus/controllers/unified_push.dart"; import "package:nexus/helpers/extensions/better_when.dart"; import "package:nexus/helpers/extensions/scheme_to_theme.dart"; import "package:nexus/helpers/font_licenses.dart"; @@ -22,6 +24,7 @@ import "package:window_manager/window_manager.dart"; import "package:material_ui/material_ui.dart"; final GlobalKey navigatorKey = GlobalKey(); +late final bool isInBackground; final class Logger extends ProviderObserver { @override @@ -45,6 +48,7 @@ void showError(Object error, [StackTrace? stackTrace]) { error.toString().contains("Invalid source") || error.toString().contains("UTF-16") || error.toString().contains("HTTP request failed") || + error.toString().contains("'_nextFrame != null': is not true.") || error.toString().contains("Invalid image data")) { return; } @@ -62,7 +66,7 @@ void showError(Object error, [StackTrace? stackTrace]) { } } -void main() async { +void main(List args) async { WidgetsFlutterBinding.ensureInitialized(); MediaKit.ensureInitialized(); @@ -77,25 +81,30 @@ void main() async { await windowManager.setMinimumSize(Size.square(500)); } + isInBackground = args.contains("--unifiedpush-bg"); + LicenseRegistry.addLicense(() => Stream.fromIterable(fontLicenses)); FlutterError.onError = (FlutterErrorDetails details) => showError(details.exception.toString(), details.stack); - runApp( - ProviderScope( - retry: (_, _) => null, - observers: [ - // Change false to true if you want debug information on provider reloads - // ignore: dead_code - if (false && kDebugMode) Logger(), - ], - child: const App(), - ), - ); + if (!isInBackground) { + runApp( + ProviderScope( + retry: (_, _) => null, + observers: [ + // Change false to true if you want debug information on provider reloads + // ignore: dead_code + if (false && kDebugMode) Logger(), + ], + child: App(isInBackground), + ), + ); + } } -class const App({super.key}) extends StatelessWidget { +class const App(final bool isInBackground, {super.key}) + extends StatelessWidget { @override Widget build(BuildContext context) => DynamicColorBuilder( builder: (lightDynamic, darkDynamic) => Consumer( @@ -138,6 +147,8 @@ class const App({super.key}) extends StatelessWidget { IListConst([ SharedPrefsController.provider, ClientController.provider, + NotificationsController.provider, + UnifiedPushController.provider, ]), ), ) diff --git a/lib/models/capabilities.dart b/lib/models/capabilities.dart new file mode 100644 index 0000000..6830170 --- /dev/null +++ b/lib/models/capabilities.dart @@ -0,0 +1,25 @@ +import "package:freezed_annotation/freezed_annotation.dart"; + +part "capabilities.freezed.dart"; +part "capabilities.g.dart"; + +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const Capabilities({ + @JsonKey(name: "org.matrix.msc4174.webpush") final WebPush? webpush, +}) with _$Capabilities { + Map toJson() => _$CapabilitiesToJson(this); + + factory Capabilities.fromJson(Map json) => + _$CapabilitiesFromJson(json); +} + +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const WebPush({required final bool enabled, final String? vapid}) + with _$WebPush { + Map toJson() => _$WebPushToJson(this); + + factory WebPush.fromJson(Map json) => + _$WebPushFromJson(json); +} diff --git a/lib/models/client_state.dart b/lib/models/client_state.dart index ff433ab..262203d 100644 --- a/lib/models/client_state.dart +++ b/lib/models/client_state.dart @@ -10,6 +10,7 @@ class const ClientState({ required final bool isLoggedIn, required final bool isVerified, required final String? userId, + required final String? deviceId, required final String? homeserverUrl, }) with _$ClientState { Map toJson() => _$ClientStateToJson(this); diff --git a/lib/models/join_rule.dart b/lib/models/join_rule.dart index 3fade23..44fb9bb 100644 --- a/lib/models/join_rule.dart +++ b/lib/models/join_rule.dart @@ -1,4 +1,4 @@ import "package:freezed_annotation/freezed_annotation.dart"; -@JsonEnum(fieldRename: FieldRename.snake) +@JsonEnum(fieldRename: .snake) enum JoinRule { public, knock, invite, private, restricted, knockRestricted } diff --git a/lib/models/membership_action.dart b/lib/models/membership_action.dart index d852164..f03ca99 100644 --- a/lib/models/membership_action.dart +++ b/lib/models/membership_action.dart @@ -1,4 +1 @@ -import "package:freezed_annotation/freezed_annotation.dart"; - -@JsonEnum() enum MembershipAction { ban, kick, unban, invite } diff --git a/lib/models/membership_status.dart b/lib/models/membership_status.dart index ba7a241..7eb5f72 100644 --- a/lib/models/membership_status.dart +++ b/lib/models/membership_status.dart @@ -1,4 +1 @@ -import "package:freezed_annotation/freezed_annotation.dart"; - -@JsonEnum() enum MembershipStatus { leave, invite, ban, join, knock } diff --git a/lib/models/requests/deregister_pusher.dart b/lib/models/requests/deregister_pusher.dart new file mode 100644 index 0000000..1416add --- /dev/null +++ b/lib/models/requests/deregister_pusher.dart @@ -0,0 +1,13 @@ +import "package:freezed_annotation/freezed_annotation.dart"; + +part "deregister_pusher.freezed.dart"; +part "deregister_pusher.g.dart"; + +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const DeregisterPusherRequest({ + required final String appId, + @JsonKey(name: "pushkey") required final String pushKey, +}) with _$DeregisterPusherRequest { + Map toJson() => _$DeregisterPusherRequestToJson(this); +} diff --git a/lib/models/requests/register_pusher.dart b/lib/models/requests/register_pusher.dart new file mode 100644 index 0000000..dd34e62 --- /dev/null +++ b/lib/models/requests/register_pusher.dart @@ -0,0 +1,56 @@ +import "package:freezed_annotation/freezed_annotation.dart"; + +part "register_pusher.freezed.dart"; +part "register_pusher.g.dart"; + +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const RegisterPusherRequest({ + required final String appDisplayName, + required final String appId, + final bool append = false, + required final PusherData data, + required final String deviceDisplayName, + required final PusherKind kind, + required final String lang, + + /// TODO: What does this do? + final String? profileTag, + + @JsonKey(name: "pushkey") required final String pushKey, +}) with _$RegisterPusherRequest { + Map toJson() => _$RegisterPusherRequestToJson(this); +} + +@freezed +sealed class PusherData with _$PusherData { + const factory PusherData.http({ + required Uri url, + @Default(PushFormat.eventIdOnly) PushFormat format, + }) = HttpPusherData; + + const factory PusherData.webPush({ + required Uri url, + @Default(PushFormat.eventIdOnly) PushFormat format, + + /// `data.auth`: RFC8291 authentication secret. + required String auth, + }) = WebPushPusherData; + + factory PusherData.fromJson(Map json) => + _$PusherDataFromJson(json); +} + +@JsonEnum(fieldRename: .snake) +enum PushFormat { + @JsonValue(null) + all, + eventIdOnly, +} + +enum PusherKind { + http, + email, + @JsonValue("org.matrix.msc4174.webpush") + webPush, +} diff --git a/lib/pages/notifications.dart b/lib/pages/notifications.dart new file mode 100644 index 0000000..ceca514 --- /dev/null +++ b/lib/pages/notifications.dart @@ -0,0 +1,14 @@ +import "package:material_ui/material_ui.dart"; +import "package:hooks_riverpod/hooks_riverpod.dart"; +import "package:nexus/widgets/appbar.dart"; + +class const NotificationsPage({final String? eventId, super.key}) + extends HookConsumerWidget { + @override + Widget build(BuildContext context, WidgetRef ref) { + return Scaffold( + appBar: Appbar(title: Text("Notifications")), + body: Placeholder(), + ); + } +} diff --git a/lib/widgets/appbar.dart b/lib/widgets/appbar.dart index a6058ea..33727ac 100644 --- a/lib/widgets/appbar.dart +++ b/lib/widgets/appbar.dart @@ -39,7 +39,7 @@ final class const Appbar({ : (_) => windowManager.startDragging(), ), child: AppBar( - leading: InkWell(onTap: onTap, child: leading), + leading: leading == null ? null : InkWell(onTap: onTap, child: leading), backgroundColor: backgroundColor, scrolledUnderElevation: scrolledUnderElevation, actionsPadding: const .symmetric(horizontal: 8), diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 603ea6a..70d9ba2 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -13,6 +13,7 @@ #include #include #include +#include #include void fl_register_plugins(FlPluginRegistry* registry) { @@ -37,6 +38,9 @@ void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); + g_autoptr(FlPluginRegistrar) webcrypto_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "WebcryptoPlugin"); + webcrypto_plugin_register_with_registrar(webcrypto_registrar); g_autoptr(FlPluginRegistrar) window_manager_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "WindowManagerPlugin"); window_manager_plugin_register_with_registrar(window_manager_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 7d8f046..1d53ad7 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -10,6 +10,7 @@ list(APPEND FLUTTER_PLUGIN_LIST media_kit_video screen_retriever_linux url_launcher_linux + webcrypto window_manager ) diff --git a/linux/nix/devshell.nix b/linux/nix/devshell.nix index dd3c78e..8bc8641 100644 --- a/linux/nix/devshell.nix +++ b/linux/nix/devshell.nix @@ -45,7 +45,6 @@ pkgs.mkShell { GRADLE_OPTS = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${ANDROID_HOME}/build-tools/36.0.0/aapt2"; } // lib.optionalAttrs pkgs.stdenv.isLinux { - CPATH = lib.makeSearchPath "include" [ pkgs.glibc.dev ]; LD_LIBRARY_PATH = "./build/native_assets/linux:${lib.makeLibraryPath [ pkgs.zlib ]}"; }; } diff --git a/linux/runner/my_application.cc b/linux/runner/my_application.cc index 62e5450..739e6df 100644 --- a/linux/runner/my_application.cc +++ b/linux/runner/my_application.cc @@ -1,5 +1,6 @@ #include "my_application.h" +#include #include #ifdef GDK_WINDOWING_X11 #include @@ -72,6 +73,7 @@ static void my_application_activate(GApplication* application) { gdk_rgba_parse(&background_color, "#000000"); fl_view_set_background_color(view, &background_color); gtk_widget_show(GTK_WIDGET(view)); + if (std::getenv("FLUTTER_HEADLESS")) gtk_widget_hide(GTK_WIDGET(window)); gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); // Show the window when Flutter renders. diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index f18d831..8b6bbb6 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -8,6 +8,7 @@ import Foundation import app_links import dynamic_color import file_selector_macos +import flutter_local_notifications import media_kit_libs_macos_video import media_kit_video import package_info_plus @@ -15,12 +16,14 @@ import screen_retriever_macos import shared_preferences_foundation import url_launcher_macos import wakelock_plus +import webcrypto import window_manager func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin")) DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin")) FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) + FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin")) MediaKitLibsMacosVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitLibsMacosVideoPlugin")) MediaKitVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitVideoPlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) @@ -28,5 +31,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin")) + WebcryptoPlugin.register(with: registry.registrar(forPlugin: "WebcryptoPlugin")) WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index 753373a..82e2d72 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -495,6 +495,46 @@ packages: url: "https://pub.dev" source: hosted version: "6.0.0" + flutter_local_notifications: + dependency: "direct main" + description: + name: flutter_local_notifications + sha256: "1447ba911c60f2ba3f25dae1af151ec187162566b0f57e37771bf0b400f013ad" + url: "https://pub.dev" + source: hosted + version: "22.3.0" + flutter_local_notifications_linux: + dependency: "direct main" + description: + name: flutter_local_notifications_linux + sha256: "9ca97e63776f29ab1b955725c09999fc2c150523269db150c39274f2a43c5a8b" + url: "https://pub.dev" + source: hosted + version: "8.0.1" + flutter_local_notifications_platform_interface: + dependency: transitive + description: + name: flutter_local_notifications_platform_interface + sha256: "43c3761d916c9bd3d5c7ebbc44d82f4990329840c0c5d62ad5260cc1b5d399bd" + url: "https://pub.dev" + source: hosted + version: "12.2.0" + flutter_local_notifications_web: + dependency: transitive + description: + name: flutter_local_notifications_web + sha256: "516afaf97a2d1e67a036c6617321b00d205d72f7a67b6eccf936cd565f985878" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + flutter_local_notifications_windows: + dependency: transitive + description: + name: flutter_local_notifications_windows + sha256: "6f43bdd03b171b7a90f22647506fea33e2bb12294b7c7c7a3d690e960a382945" + url: "https://pub.dev" + source: hosted + version: "3.1.1" flutter_localizations: dependency: "direct main" description: flutter @@ -1429,6 +1469,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.7.1" + timezone: + dependency: transitive + description: + name: timezone + sha256: "981d1020d6ef8fe1e7b3de5054e5b25579ae7c403d7734adc508ffc47668e9cb" + url: "https://pub.dev" + source: hosted + version: "0.11.1" typed_data: dependency: transitive description: @@ -1437,6 +1485,54 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" + unifiedpush: + dependency: "direct main" + description: + name: unifiedpush + sha256: "8ed9767f750a1dc6159a77e2171641d0cb825dc87682d1ce1b8618689b79f58e" + url: "https://pub.dev" + source: hosted + version: "6.2.0" + unifiedpush_android: + dependency: transitive + description: + name: unifiedpush_android + sha256: a902e505e91c8e28b54b379bb27f255f66df409274a97af24d6719f12f0d13dc + url: "https://pub.dev" + source: hosted + version: "3.5.0" + unifiedpush_linux: + dependency: transitive + description: + name: unifiedpush_linux + sha256: c062d5eedd1cec70bcd33270cc4e01ae0ff6501f33d471167c06b34a968adfeb + url: "https://pub.dev" + source: hosted + version: "1.0.0" + unifiedpush_platform_interface: + dependency: transitive + description: + name: unifiedpush_platform_interface + sha256: "83372bc8d794b8b12ef6993b518d7be907dcfc2191bdf6de0ece5c4445d89880" + url: "https://pub.dev" + source: hosted + version: "4.0.0" + unifiedpush_storage_interface: + dependency: transitive + description: + name: unifiedpush_storage_interface + sha256: b8d423a4695efc616aa21d8ab48fb5ef99d6288c68b56282b8faac1579ceabd9 + url: "https://pub.dev" + source: hosted + version: "1.0.0" + unifiedpush_storage_shared_preferences: + dependency: "direct main" + description: + name: unifiedpush_storage_shared_preferences + sha256: eda9c52bac0058f81e0d9c65e33eedc12c5901d2e68ad47fdf68175ddf00a3b4 + url: "https://pub.dev" + source: hosted + version: "1.0.0" universal_platform: dependency: transitive description: @@ -1613,6 +1709,22 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.3" + webcrypto: + dependency: "direct dev" + description: + name: webcrypto + sha256: "6b43001c4110856ff7fa5e5e65e7b2d44bec1d8b54a4d84d5fa2c7622267c5c1" + url: "https://pub.dev" + source: hosted + version: "0.6.0" + webpush_encryption: + dependency: transitive + description: + name: webpush_encryption + sha256: "5b83272b91acda6ae515fcd980c94f06bf413702282497c5a68f5dfc64fed27f" + url: "https://pub.dev" + source: hosted + version: "1.0.1" win32: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 4b69b2c..ab2f727 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -79,6 +79,10 @@ dependencies: app_links: 7.2.1 file_selector: 1.1.0 material_ui: 1.2.0 + unifiedpush: 6.2.0 + unifiedpush_storage_shared_preferences: 1.0.0 + flutter_local_notifications: 22.3.0 + flutter_local_notifications_linux: 8.0.1 dev_dependencies: build_runner: 2.16.1 @@ -87,6 +91,8 @@ dev_dependencies: riverpod_lint: 3.1.9 flutter_launcher_icons: 0.14.4 json_serializable: 6.14.1 + # Transitive dep but needed for commands + webcrypto: any flutter_launcher_icons: image_path: assets/icon.png diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 0694802..5d2b53e 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -13,6 +13,7 @@ #include #include #include +#include #include void RegisterPlugins(flutter::PluginRegistry* registry) { @@ -30,6 +31,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("ScreenRetrieverWindowsPluginCApi")); UrlLauncherWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("UrlLauncherWindows")); + WebcryptoPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("WebcryptoPlugin")); WindowManagerPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("WindowManagerPlugin")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 238ef93..c74b2f5 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -10,10 +10,12 @@ list(APPEND FLUTTER_PLUGIN_LIST media_kit_video screen_retriever_windows url_launcher_windows + webcrypto window_manager ) list(APPEND FLUTTER_FFI_PLUGIN_LIST + flutter_local_notifications_windows ) set(PLUGIN_BUNDLED_LIBRARIES) From b8882d6e486f6cf899fef254e7b77e4d23f5e834 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Thu, 10 Sep 2026 17:06:14 -0400 Subject: [PATCH 095/176] mark off notification support as added, add notifications page todo --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ee55903..cd7b9a3 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,8 @@ A simple and user-friendly Matrix client made with Flutter and a Gomuks backend. - [x] Member list - [x] Sort by power level - [ ] Colors based off of power level -- [ ] Notifications using UnifiedPush ([#35](https://git.federated.nexus/Nexus/nexus/issues/35)) +- [x] Notifications using UnifiedPush ([#35](https://git.federated.nexus/Nexus/nexus/issues/35)) +- [ ] Notifications page - [ ] Group calls using [MSC4195](https://github.com/matrix-org/matrix-spec-proposals/pull/4195) - [ ] Invites - [x] Settings From e925f9657cdf9922e5fd05a8a56df968add44c38 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Thu, 10 Sep 2026 17:14:41 -0400 Subject: [PATCH 096/176] add needed permissions for UnifiedPush to nexus flatpak --- flake.nix | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/flake.nix b/flake.nix index 2b13a08..c1502f0 100644 --- a/flake.nix +++ b/flake.nix @@ -62,6 +62,13 @@ "fallback-x11" "wayland" ]; + + talk-names = [ "org.unifiedpush.Distributor.*" ]; + own-names = [ + "nexus.federated.nexus" + "nexus.federated.nexus.*" + ]; + devices = [ "dri" ]; }; }; From 13d90df226f865e40bf4515b61a26bb0c6d77993 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Fri, 11 Sep 2026 19:28:10 -0400 Subject: [PATCH 097/176] remove un-needed overrides --- lib/models/event.dart | 6 +++--- lib/models/homeserver.dart | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/models/event.dart b/lib/models/event.dart index d06b41a..0c8fc84 100644 --- a/lib/models/event.dart +++ b/lib/models/event.dart @@ -17,7 +17,7 @@ class const Event({ required final String eventId, required final String sender, @JsonKey(readValue: Event.typeJsonFromJson) required final String type, - @EpochDateTimeConverter() @override required final DateTime timestamp, + @EpochDateTimeConverter() required final DateTime timestamp, final IMap unsigned = const IMap.empty(), final LocalContent? localContent, final String? transactionId, @@ -28,8 +28,8 @@ class const Event({ final String? decryptionError, final String? sendError, final IMap reactions = const IMap.empty(), - @JsonKey(name: "last_edit_rowid") @override final int lastEditRowId = 0, - @UnreadTypeConverter() @override final UnreadType? unreadType, + @JsonKey(name: "last_edit_rowid") final int lastEditRowId = 0, + @UnreadTypeConverter() final UnreadType? unreadType, final Profile? pmp, required final Content content, required final Content? previousContent, diff --git a/lib/models/homeserver.dart b/lib/models/homeserver.dart index 098dd12..5504941 100644 --- a/lib/models/homeserver.dart +++ b/lib/models/homeserver.dart @@ -4,8 +4,8 @@ part "homeserver.freezed.dart"; @freezed class const Homeserver({ - @override required final String name, - @override required final String description, - @override required final Uri url, - @override required final String iconUrl, + required final String name, + required final String description, + required final Uri url, + required final String iconUrl, }) with _$Homeserver; From 9507d694583237afa893e265c6ee7745e4e2e256 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Fri, 11 Sep 2026 19:29:47 -0400 Subject: [PATCH 098/176] move windows warning in readme --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cd7b9a3..22c2173 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,8 @@ A simple and user-friendly Matrix client made with Flutter and a Gomuks backend. - [x] Platform Support - [x] Linux - - [x] Windows - Currently has some bugs, due to us not having any developers on Windows. If you want to fix these, get in contact with us though the [Nexus Client Matrix room](https://matrix.to/#/#nexus:federated.nexus). + - [x] Windows + - Currently has some bugs, due to us not having any developers on Windows. If you want to fix these, get in contact with us though the [Nexus Client Matrix room](https://matrix.to/#/#nexus:federated.nexus). - [x] Android - [x] MacOS - Unsigned .dmg only - [x] iOS - Unsigned .ipa only From 9e7fcdbef7f77188954b33cface661cb928bf8d0 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Fri, 11 Sep 2026 19:46:04 -0400 Subject: [PATCH 099/176] sticky -> clientSticky to avoid conflicts with sticky events --- lib/controllers/room_chat.dart | 4 ++-- lib/controllers/rooms.dart | 9 +++++---- lib/models/room.dart | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/controllers/room_chat.dart b/lib/controllers/room_chat.dart index 0cd1011..2227225 100644 --- a/lib/controllers/room_chat.dart +++ b/lib/controllers/room_chat.dart @@ -43,7 +43,7 @@ class RoomChatController(final String roomId) .toEntryIList(compare: (a, b) => (a?.key ?? 0).compareTo(b?.key ?? 0)) .map((element) => element.value) .toIList() - .addAll(room.sticky) + .addAll(room.clientSticky) .map((entry) { final foundEvent = entry == null ? null : room.events[entry]; @@ -173,7 +173,7 @@ class RoomChatController(final String roomId) .new({ roomId: .new( events: .new({event.rowId: event}), - sticky: .new({event.rowId}), + clientSticky: .new({event.rowId}), ), }), .new(), diff --git a/lib/controllers/rooms.dart b/lib/controllers/rooms.dart index d0c6eb9..ff4d6a2 100644 --- a/lib/controllers/rooms.dart +++ b/lib/controllers/rooms.dart @@ -1,4 +1,5 @@ import "dart:isolate"; + import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/models/event.dart"; @@ -46,10 +47,10 @@ class RoomsController extends Notifier> { roomId, existing?.copyWith( hasMore: incoming.hasMore, - sticky: - (incoming.sticky.isEmpty == true - ? existing.sticky - : existing.sticky.addAll(incoming.sticky)) + clientSticky: + (incoming.clientSticky.isEmpty == true + ? existing.clientSticky + : existing.clientSticky.addAll(incoming.clientSticky)) .removeWhere( (rowId) => incoming.timeline.values.contains(rowId), ), diff --git a/lib/models/room.dart b/lib/models/room.dart index d030043..6d7553f 100644 --- a/lib/models/room.dart +++ b/lib/models/room.dart @@ -15,7 +15,7 @@ class const Room({ @JsonKey(fromJson: Room.timelineTupleJsonToIMap) final IMap timeline = const IMap.empty(), - final ISet sticky = const ISet.empty(), + final ISet clientSticky = const ISet.empty(), @JsonKey(fromJson: Room.eventsJsonToIMap) final IMap events = const IMap.empty(), @@ -34,7 +34,7 @@ class const Room({ }) with _$Room { /// [timeline] is an IMap of timelineRowId to eventRowId /// [events] is an IMap of eventRowId to event - /// [sticky] is an ISet of eventRowId + /// [clientSticky] is an ISet of eventRowId static IMap timelineTupleJsonToIMap(List json) => IMap.fromEntries( json.map( From 23e01c7a0d550047aefe3bfa4cdf35bbbe7878c0 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Fri, 11 Sep 2026 22:03:06 -0400 Subject: [PATCH 100/176] Notifications page Doesn't yet allow for jumping to events --- lib/controllers/client.dart | 7 ++ lib/controllers/notification.dart | 120 +++++++++++++++++++ lib/controllers/notifications.dart | 155 ++++++++----------------- lib/controllers/room_chat.dart | 2 +- lib/controllers/settings_sections.dart | 4 +- lib/controllers/unified_push.dart | 6 +- lib/main.dart | 4 +- lib/models/event.dart | 32 ++--- lib/models/requests/get_mentions.dart | 19 +++ lib/pages/notifications.dart | 74 +++++++++++- lib/widgets/room_chat.dart | 10 +- lib/widgets/sidebar.dart | 10 ++ 12 files changed, 300 insertions(+), 143 deletions(-) create mode 100644 lib/controllers/notification.dart create mode 100644 lib/models/requests/get_mentions.dart diff --git a/lib/controllers/client.dart b/lib/controllers/client.dart index b8e060d..931c023 100644 --- a/lib/controllers/client.dart +++ b/lib/controllers/client.dart @@ -25,6 +25,7 @@ import "package:nexus/models/paginate.dart"; import "package:nexus/models/requests/deregister_pusher.dart"; import "package:nexus/models/requests/download_media.dart"; import "package:nexus/models/requests/get_event.dart"; +import "package:nexus/models/requests/get_mentions.dart"; import "package:nexus/models/requests/get_related_events.dart"; import "package:nexus/models/requests/get_room_state.dart"; import "package:nexus/models/requests/join_room.dart"; @@ -272,6 +273,12 @@ class ClientController extends AsyncNotifier { return .new(response?.map((event) => .fromJson(event))); } + Future> getMentions(GetMentionsRequest request) async => .new( + ((await _sendCommand("get_mentions", request.toJson())) as List).map( + (event) => .fromJson(event), + ), + ); + Future getEvent(GetEventRequest request) async { final json = await _sendCommand("get_event", request.toJson()); return json == null ? null : .fromJson(json); diff --git a/lib/controllers/notification.dart b/lib/controllers/notification.dart new file mode 100644 index 0000000..a8b9e6c --- /dev/null +++ b/lib/controllers/notification.dart @@ -0,0 +1,120 @@ +import "dart:io"; + +import "package:material_ui/material_ui.dart"; +import "package:nexus/main.dart"; +import "package:flutter_local_notifications/flutter_local_notifications.dart"; +// ignore: implementation_imports +import "package:flutter_local_notifications_linux/src/model/hint.dart"; +import "package:flutter_riverpod/flutter_riverpod.dart"; +import "package:nexus/pages/notifications.dart"; + +class NotificationController + extends AsyncNotifier { + @override + Future build() async { + final notifications = FlutterLocalNotificationsPlugin(); + + final darwin = DarwinInitializationSettings(); + + await notifications.initialize( + settings: .new( + windows: .new( + appName: "Nexus", + appUserModelId: "nexus.federated.nexus", + guid: "dde78daf-130f-4e46-a80a-e31deeab45d7", + ), + android: .new("ic_launcher_foreground"), + iOS: darwin, + macOS: darwin, + linux: .new(defaultActionName: "Open"), + ), + onDidReceiveNotificationResponse: (details) { + if (details.payload case final eventId?) { + if (navigatorKey.currentContext case final context?) { + Navigator.of(context).push( + MaterialPageRoute( + builder: (_) => NotificationsPage(eventId: eventId), + ), + ); + } + } + }, + ); + + return notifications; + } + + Future requestPermissions() async { + final controller = await future; + + if (Platform.isIOS) { + return await controller + .resolvePlatformSpecificImplementation< + IOSFlutterLocalNotificationsPlugin + >() + ?.requestPermissions(alert: true, badge: true, sound: true) ?? + true; + } else if (Platform.isMacOS) { + return await controller + .resolvePlatformSpecificImplementation< + MacOSFlutterLocalNotificationsPlugin + >() + ?.requestPermissions(alert: true, badge: true, sound: true) ?? + true; + } else if (Platform.isAndroid) { + return await controller + .resolvePlatformSpecificImplementation< + AndroidFlutterLocalNotificationsPlugin + >() + ?.requestNotificationsPermission() ?? + true; + } + + return true; + } + + Future send({ + required int id, + required String title, + String? body, + File? icon, + String? payload, + }) async { + final notificationDetails = NotificationDetails( + android: .new( + "messages", + "Messages", + largeIcon: icon == null ? null : FilePathAndroidBitmap(icon.path), + ), + linux: .new( + customHints: icon == null + ? null + : [ + .new( + name: "image-path", + value: LinuxHintStringValue(icon.path), + ), + ], + ), + // TODO: See if icons can be added to iOS, macOS, and Windows notifications (#68) + iOS: .new(), + macOS: .new(), + windows: .new(), + ); + + final controller = await future; + await controller.show( + id: id, + title: title, + body: body, + notificationDetails: notificationDetails, + payload: payload, + ); + } + + static final provider = + AsyncNotifierProvider< + NotificationController, + FlutterLocalNotificationsPlugin + >(NotificationController.new); +} diff --git a/lib/controllers/notifications.dart b/lib/controllers/notifications.dart index bd80467..e57025e 100644 --- a/lib/controllers/notifications.dart +++ b/lib/controllers/notifications.dart @@ -1,120 +1,59 @@ -import "dart:io"; - -import "package:material_ui/material_ui.dart"; -import "package:nexus/main.dart"; -import "package:flutter_local_notifications/flutter_local_notifications.dart"; -// ignore: implementation_imports -import "package:flutter_local_notifications_linux/src/model/hint.dart"; +import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; -import "package:nexus/pages/notifications.dart"; +import "package:nexus/controllers/client.dart"; +import "package:nexus/models/event.dart"; + +typedef NotificationsRequest = (UnreadType? unreadType, String? roomId); + +class NotificationsController([final NotificationsRequest? request]) + extends AsyncNotifier> { + static const limit = 20; -class NotificationsController - extends AsyncNotifier { @override - Future build() async { - final notifications = FlutterLocalNotificationsPlugin(); + Future> build() async { + final client = ref.watch(ClientController.provider.notifier); - final darwin = DarwinInitializationSettings(); + final (unreadType, roomId) = request ?? (null, null); - await notifications.initialize( - settings: .new( - windows: .new( - appName: "Nexus", - appUserModelId: "nexus.federated.nexus", - guid: "dde78daf-130f-4e46-a80a-e31deeab45d7", + final mentions = await client.getMentions( + .new( + maxTimestamp: .now(), + unreadType: unreadType ?? .highlight, + limit: limit, + roomId: roomId, + ), + ); + + return mentions; + } + + Future loadOlder() async { + final currentNotifications = await future; + state = .loading(); + state = await .guard(() async { + final lastTs = currentNotifications.lastOrNull?.timestamp; + if (lastTs == null) return const .empty(); + + final client = ref.watch(ClientController.provider.notifier); + final (unreadType, roomId) = request ?? (null, null); + + final newNotifications = await client.getMentions( + .new( + maxTimestamp: lastTs, + unreadType: unreadType ?? .highlight, + limit: limit, + roomId: roomId, ), - android: .new("ic_launcher_foreground"), - iOS: darwin, - macOS: darwin, - linux: .new(defaultActionName: "Open"), - ), - onDidReceiveNotificationResponse: (details) { - if (details.payload case final eventId?) { - if (navigatorKey.currentContext case final context?) { - Navigator.of(context).push( - MaterialPageRoute( - builder: (_) => NotificationsPage(eventId: eventId), - ), - ); - } - } - }, - ); + ); - return notifications; + return currentNotifications.addAll(newNotifications); + }); } - Future requestPermissions() async { - final controller = await future; - - if (Platform.isIOS) { - return await controller - .resolvePlatformSpecificImplementation< - IOSFlutterLocalNotificationsPlugin - >() - ?.requestPermissions(alert: true, badge: true, sound: true) ?? - true; - } else if (Platform.isMacOS) { - return await controller - .resolvePlatformSpecificImplementation< - MacOSFlutterLocalNotificationsPlugin - >() - ?.requestPermissions(alert: true, badge: true, sound: true) ?? - true; - } else if (Platform.isAndroid) { - return await controller - .resolvePlatformSpecificImplementation< - AndroidFlutterLocalNotificationsPlugin - >() - ?.requestNotificationsPermission() ?? - true; - } - - return true; - } - - Future send({ - required int id, - required String title, - String? body, - File? icon, - String? payload, - }) async { - final notificationDetails = NotificationDetails( - android: .new( - "messages", - "Messages", - largeIcon: icon == null ? null : FilePathAndroidBitmap(icon.path), - ), - linux: .new( - customHints: icon == null - ? null - : [ - .new( - name: "image-path", - value: LinuxHintStringValue(icon.path), - ), - ], - ), - // TODO: See if icons can be added to iOS, macOS, and Windows notifications (#68) - iOS: .new(), - macOS: .new(), - windows: .new(), - ); - - final controller = await future; - await controller.show( - id: id, - title: title, - body: body, - notificationDetails: notificationDetails, - payload: payload, - ); - } - - static final provider = - AsyncNotifierProvider< + static final provider = AsyncNotifierProvider.family + .autoDispose< NotificationsController, - FlutterLocalNotificationsPlugin + IList, + NotificationsRequest? >(NotificationsController.new); } diff --git a/lib/controllers/room_chat.dart b/lib/controllers/room_chat.dart index 2227225..d761ecf 100644 --- a/lib/controllers/room_chat.dart +++ b/lib/controllers/room_chat.dart @@ -74,7 +74,7 @@ class RoomChatController(final String roomId) ); Future loadOlder() async { - state = AsyncLoading(); + state = .loading(); final timelineKeys = ref .read(RoomsController.provider.select((value) => value[roomId])) ?.timeline diff --git a/lib/controllers/settings_sections.dart b/lib/controllers/settings_sections.dart index 1e60263..7f25cb9 100644 --- a/lib/controllers/settings_sections.dart +++ b/lib/controllers/settings_sections.dart @@ -9,7 +9,7 @@ import "package:m3e_buttons/m3e_buttons.dart"; import "package:nexus/controllers/account_data.dart"; import "package:nexus/controllers/client.dart"; import "package:nexus/controllers/client_state.dart"; -import "package:nexus/controllers/notifications.dart"; +import "package:nexus/controllers/notification.dart"; import "package:nexus/controllers/settings.dart"; import "package:nexus/controllers/unified_push.dart"; import "package:nexus/controllers/spec_versions.dart"; @@ -143,7 +143,7 @@ class SettingsSectionsController if (value) { if (await ref .watch( - NotificationsController + NotificationController .provider .notifier, ) diff --git a/lib/controllers/unified_push.dart b/lib/controllers/unified_push.dart index 1c1b41a..0be46cb 100644 --- a/lib/controllers/unified_push.dart +++ b/lib/controllers/unified_push.dart @@ -5,7 +5,7 @@ import "package:flutter/foundation.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:intl/intl.dart"; import "package:nexus/controllers/key.dart"; -import "package:nexus/controllers/notifications.dart"; +import "package:nexus/controllers/notification.dart"; import "package:nexus/controllers/push_key.dart"; import "package:nexus/controllers/rooms.dart"; import "package:nexus/main.dart"; @@ -61,7 +61,7 @@ class UnifiedPushController extends AsyncNotifier { ); if (event == null || - event.unreadType?.shouldNotify != true || + event.unreadType?.shouldNotify() != true || (!isInBackground && await windowManager.isFocused().onError((_, _) => false) && ref.watch(KeyController.provider(KeyController.roomKey)) == @@ -81,7 +81,7 @@ class UnifiedPushController extends AsyncNotifier { .downloadMedia(.new(mxc: avatar, isAvatar: true)); await ref - .read(NotificationsController.provider.notifier) + .read(NotificationController.provider.notifier) .send( id: event.eventId.hashCode & 0x7fffffff, title: room?.metadata?.name ?? "New Event", diff --git a/lib/main.dart b/lib/main.dart index aaed5a0..80c2649 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -8,7 +8,7 @@ import "package:media_kit/media_kit.dart"; import "package:nexus/controllers/client.dart"; import "package:nexus/controllers/client_state.dart"; import "package:nexus/controllers/multi_provider.dart"; -import "package:nexus/controllers/notifications.dart"; +import "package:nexus/controllers/notification.dart"; import "package:nexus/controllers/settings.dart"; import "package:nexus/controllers/shared_prefs.dart"; import "package:nexus/controllers/unified_push.dart"; @@ -147,7 +147,7 @@ class const App(final bool isInBackground, {super.key}) IListConst([ SharedPrefsController.provider, ClientController.provider, - NotificationsController.provider, + NotificationController.provider, UnifiedPushController.provider, ]), ), diff --git a/lib/models/event.dart b/lib/models/event.dart index 0c8fc84..dc3dd46 100644 --- a/lib/models/event.dart +++ b/lib/models/event.dart @@ -29,7 +29,7 @@ class const Event({ final String? sendError, final IMap reactions = const IMap.empty(), @JsonKey(name: "last_edit_rowid") final int lastEditRowId = 0, - @UnreadTypeConverter() final UnreadType? unreadType, + final UnreadType? unreadType, final Profile? pmp, required final Content content, required final Content? previousContent, @@ -91,22 +91,10 @@ class const LocalContent({ _$LocalContentFromJson(json); } -class UnreadTypeConverter implements JsonConverter { - const UnreadTypeConverter(); - - @override - UnreadType? fromJson(int? json) => json == null ? null : UnreadType(json); - - @override - int? toJson(UnreadType? object) => object?.value; -} - -// I think this is correct but I'm not sure, its some type of bitmask. -@immutable -class UnreadType { - final int value; - - const UnreadType(this.value); +@Freezed(toJson: false, fromJson: false) +class const UnreadType(final int value) with _$UnreadType { + factory UnreadType.fromJson(int json) => UnreadType(json); + int toJson() => value; static const none = UnreadType(0); static const normal = UnreadType(1); @@ -114,9 +102,9 @@ class UnreadType { static const highlight = UnreadType(4); static const sound = UnreadType(8); - bool get isNone => value == 0; - bool get isNormal => (value & 1) != 0; - bool get shouldNotify => (value & 2) != 0; - bool get isHighlighted => (value & 4) != 0; - bool get playsSound => (value & 8) != 0; + bool isNone() => value == 0; + bool isNormal() => (value & 1) != 0; + bool shouldNotify() => (value & 2) != 0; + bool isHighlighted() => (value & 4) != 0; + bool playsSound() => (value & 8) != 0; } diff --git a/lib/models/requests/get_mentions.dart b/lib/models/requests/get_mentions.dart new file mode 100644 index 0000000..5df6870 --- /dev/null +++ b/lib/models/requests/get_mentions.dart @@ -0,0 +1,19 @@ +import "package:freezed_annotation/freezed_annotation.dart"; +import "package:nexus/models/epoch_date_time_converter.dart"; +import "package:nexus/models/event.dart"; +part "get_mentions.freezed.dart"; +part "get_mentions.g.dart"; + +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class GetMentionsRequest({ + @EpochDateTimeConverter() required final DateTime maxTimestamp, + @JsonKey(name: "type") required final UnreadType unreadType, + required final int limit, + final String? roomId, +}) with _$GetMentionsRequest { + Map toJson() => _$GetMentionsRequestToJson(this); + + factory GetMentionsRequest.fromJson(Map json) => + _$GetMentionsRequestFromJson(json); +} diff --git a/lib/pages/notifications.dart b/lib/pages/notifications.dart index ceca514..56afdad 100644 --- a/lib/pages/notifications.dart +++ b/lib/pages/notifications.dart @@ -1,14 +1,86 @@ import "package:material_ui/material_ui.dart"; +import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; +import "package:nexus/controllers/notifications.dart"; import "package:nexus/widgets/appbar.dart"; +import "package:nexus/widgets/error_dialog.dart"; +import "package:nexus/widgets/highlight_wrapper.dart"; +import "package:nexus/widgets/loading.dart"; +import "package:nexus/widgets/renderers/event.dart"; +import "package:super_sliver_list/super_sliver_list.dart"; class const NotificationsPage({final String? eventId, super.key}) extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { + final provider = NotificationsController.provider(null); + final notifications = ref.watch(provider); + final notifier = ref.watch(provider.notifier); + + final scrollController = useScrollController(); + + useEffect(() { + Future listener() async { + if (!scrollController.hasClients || notifications.isLoading) return; + + if (scrollController.position.pixels >= + scrollController.position.maxScrollExtent) { + await notifier.loadOlder(); + } + } + + scrollController.addListener(listener); + return () => scrollController.removeListener(listener); + }, [scrollController, notifications]); + return Scaffold( appBar: Appbar(title: Text("Notifications")), - body: Placeholder(), + body: Column( + children: [ + if (notifications is AsyncLoading && notifications.value != null) + const LinearProgressIndicator(minHeight: 2), + Expanded( + child: switch (notifications) { + AsyncData(:final value) || AsyncLoading(:final value?) => + value.isEmpty + ? Center( + child: Text( + "No notifications yet", + style: Theme.of(context).textTheme.headlineMedium, + ), + ) + : SuperListView.builder( + controller: scrollController, + itemCount: value.length, + padding: const EdgeInsets.symmetric( + horizontal: 8, + vertical: 12, + ), + reverse: true, + itemBuilder: (context, index) { + final event = value[index]; + final isHighlighted = event.eventId == eventId; + + return HighlightWrapper( + InkWell( + onTap: () { + //TODO + }, + child: EventRenderer(event), + ), + isHighlighted: isHighlighted, + ); + }, + ), + AsyncLoading() => const Loading(), + AsyncError(:final error, :final stackTrace) => ErrorDialog( + error, + stackTrace, + ), + }, + ), + ], + ), ); } } diff --git a/lib/widgets/room_chat.dart b/lib/widgets/room_chat.dart index 456109e..dd6ed25 100644 --- a/lib/widgets/room_chat.dart +++ b/lib/widgets/room_chat.dart @@ -78,10 +78,12 @@ final class const RoomChat({ final hasMore = useState(true); Future jumpToId(String eventId) async { - final index = controllerData.value?.indexWhere( - (element) => element.eventId == eventId, - ); - if (index == null) return; + final index = + controllerData.value?.indexWhere( + (element) => element.eventId == eventId, + ) ?? + -1; + if (index == -1) return; listController.value.animateToItem( index: index, diff --git a/lib/widgets/sidebar.dart b/lib/widgets/sidebar.dart index 6473987..c2a0170 100644 --- a/lib/widgets/sidebar.dart +++ b/lib/widgets/sidebar.dart @@ -6,6 +6,7 @@ import "package:navigation_rail_m3e/navigation_rail_m3e.dart"; import "package:nexus/controllers/key.dart"; import "package:nexus/controllers/spaces.dart"; import "package:nexus/models/room.dart"; +import "package:nexus/pages/notifications.dart"; import "package:nexus/pages/settings.dart"; import "package:nexus/widgets/avatar_or_hash.dart"; import "package:nexus/widgets/divider_widget.dart"; @@ -189,6 +190,15 @@ class const Sidebar({required final bool isDesktop, super.key}) onPressed: null, icon: Icon(Icons.explore), ), + IconButton( + tooltip: "Open notifications", + onPressed: () => Navigator.of(context).push( + MaterialPageRoute( + builder: (_) => NotificationsPage(), + ), + ), + icon: Icon(Icons.notifications), + ), IconButton( tooltip: "Open settings", onPressed: () => showDialog( From 6ca9b2a9487f3be7d013120f53884b66b9818406 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Fri, 11 Sep 2026 22:34:43 -0400 Subject: [PATCH 101/176] add notification page filter --- lib/controllers/notification.dart | 5 +- lib/pages/notifications.dart | 128 ++++++++++++++++++++---------- 2 files changed, 89 insertions(+), 44 deletions(-) diff --git a/lib/controllers/notification.dart b/lib/controllers/notification.dart index a8b9e6c..d3db8b7 100644 --- a/lib/controllers/notification.dart +++ b/lib/controllers/notification.dart @@ -33,7 +33,10 @@ class NotificationController if (navigatorKey.currentContext case final context?) { Navigator.of(context).push( MaterialPageRoute( - builder: (_) => NotificationsPage(eventId: eventId), + builder: (_) => NotificationsPage( + eventId: eventId, + defaultToAllNotifications: true, + ), ), ); } diff --git a/lib/pages/notifications.dart b/lib/pages/notifications.dart index 56afdad..0592acd 100644 --- a/lib/pages/notifications.dart +++ b/lib/pages/notifications.dart @@ -1,7 +1,9 @@ +import "package:m3e_buttons/m3e_buttons.dart"; import "package:material_ui/material_ui.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:nexus/controllers/notifications.dart"; +import "package:nexus/models/event.dart"; import "package:nexus/widgets/appbar.dart"; import "package:nexus/widgets/error_dialog.dart"; import "package:nexus/widgets/highlight_wrapper.dart"; @@ -9,11 +11,29 @@ import "package:nexus/widgets/loading.dart"; import "package:nexus/widgets/renderers/event.dart"; import "package:super_sliver_list/super_sliver_list.dart"; -class const NotificationsPage({final String? eventId, super.key}) - extends HookConsumerWidget { +class const NotificationsPage({ + final String? eventId, + final bool defaultToAllNotifications = false, + super.key, +}) extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final provider = NotificationsController.provider(null); + final options = { + M3EToggleButtonGroupAction( + label: Text("Mentions"), + icon: Icon(Icons.alternate_email), + ): .highlight, + M3EToggleButtonGroupAction( + label: Text("All Notifications"), + icon: Icon(Icons.notifications), + ): .notify, + }; + final unreadTypeIndex = useState(defaultToAllNotifications ? 1 : 0); + + final provider = NotificationsController.provider(( + options.values.toList()[unreadTypeIndex.value], + null, + )); final notifications = ref.watch(provider); final notifier = ref.watch(provider.notifier); @@ -35,49 +55,71 @@ class const NotificationsPage({final String? eventId, super.key}) return Scaffold( appBar: Appbar(title: Text("Notifications")), - body: Column( + body: Stack( children: [ - if (notifications is AsyncLoading && notifications.value != null) - const LinearProgressIndicator(minHeight: 2), - Expanded( - child: switch (notifications) { - AsyncData(:final value) || AsyncLoading(:final value?) => - value.isEmpty - ? Center( - child: Text( - "No notifications yet", - style: Theme.of(context).textTheme.headlineMedium, - ), - ) - : SuperListView.builder( - controller: scrollController, - itemCount: value.length, - padding: const EdgeInsets.symmetric( - horizontal: 8, - vertical: 12, - ), - reverse: true, - itemBuilder: (context, index) { - final event = value[index]; - final isHighlighted = event.eventId == eventId; - - return HighlightWrapper( - InkWell( - onTap: () { - //TODO - }, - child: EventRenderer(event), + Column( + children: [ + if (notifications is AsyncLoading && notifications.value != null) + const LinearProgressIndicator(minHeight: 2), + Expanded( + child: switch (notifications) { + AsyncData(:final value) || AsyncLoading(:final value?) => + value.isEmpty + ? Center( + child: Text( + "No notifications yet", + style: Theme.of(context).textTheme.headlineMedium, ), - isHighlighted: isHighlighted, - ); - }, - ), - AsyncLoading() => const Loading(), - AsyncError(:final error, :final stackTrace) => ErrorDialog( - error, - stackTrace, + ) + : SuperListView.builder( + controller: scrollController, + itemCount: value.length, + padding: const EdgeInsets.symmetric( + horizontal: 8, + vertical: 12, + ), + reverse: true, + itemBuilder: (context, index) { + final event = value[index]; + final isHighlighted = event.eventId == eventId; + + return Padding( + padding: .only(top: 8), + child: HighlightWrapper( + InkWell( + onTap: () { + //TODO + }, + child: EventRenderer(event), + ), + isHighlighted: isHighlighted, + ), + ); + }, + ), + AsyncLoading() => const Loading(), + AsyncError(:final error, :final stackTrace) => ErrorDialog( + error, + stackTrace, + ), + }, ), - }, + ], + ), + Align( + alignment: .topRight, + child: Card( + color: Theme.of(context).colorScheme.surfaceContainer, + child: Padding( + padding: .all(12), + child: M3EToggleButtonGroup( + selectedIndex: unreadTypeIndex.value, + onSelectedIndexChanged: (index) => + unreadTypeIndex.value = index ?? unreadTypeIndex.value, + actions: options.keys.toList(), + ), + ), + ), ), ], ), From 118e5a582632981a4c2b58e8dc38e3fd944820ab Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Fri, 11 Sep 2026 22:35:13 -0400 Subject: [PATCH 102/176] update readme for platform support to be more clear --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 22c2173..1c10866 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,12 @@ A simple and user-friendly Matrix client made with Flutter and a Gomuks backend. - [x] Windows - Currently has some bugs, due to us not having any developers on Windows. If you want to fix these, get in contact with us though the [Nexus Client Matrix room](https://matrix.to/#/#nexus:federated.nexus). - [x] Android - - [x] MacOS - Unsigned .dmg only - - [x] iOS - Unsigned .ipa only + - [x] MacOS + - [x] Unsigned .ipa + - [ ] App Store + - [x] iOS + - [x] Unsigned .ipa + - [ ] App Store - [ ] Web (may not be possible) - [x] Login (via OAuth) - [x] Rooms / Spaces From cd8d551e262b7652890f33695f1cb5024eb9c32e Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Fri, 11 Sep 2026 22:39:18 -0400 Subject: [PATCH 103/176] take notif filter out of card --- lib/pages/notifications.dart | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/lib/pages/notifications.dart b/lib/pages/notifications.dart index 0592acd..9b8c9b6 100644 --- a/lib/pages/notifications.dart +++ b/lib/pages/notifications.dart @@ -108,16 +108,13 @@ class const NotificationsPage({ ), Align( alignment: .topRight, - child: Card( - color: Theme.of(context).colorScheme.surfaceContainer, - child: Padding( - padding: .all(12), - child: M3EToggleButtonGroup( - selectedIndex: unreadTypeIndex.value, - onSelectedIndexChanged: (index) => - unreadTypeIndex.value = index ?? unreadTypeIndex.value, - actions: options.keys.toList(), - ), + child: Padding( + padding: .all(16), + child: M3EToggleButtonGroup( + selectedIndex: unreadTypeIndex.value, + onSelectedIndexChanged: (index) => + unreadTypeIndex.value = index ?? unreadTypeIndex.value, + actions: options.keys.toList(), ), ), ), From 8ebec15324cf146b3b206e259be7b370a46de543 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Fri, 11 Sep 2026 22:41:38 -0400 Subject: [PATCH 104/176] hide label whe not selected for filter --- lib/pages/notifications.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pages/notifications.dart b/lib/pages/notifications.dart index 9b8c9b6..a59c120 100644 --- a/lib/pages/notifications.dart +++ b/lib/pages/notifications.dart @@ -20,11 +20,11 @@ class const NotificationsPage({ Widget build(BuildContext context, WidgetRef ref) { final options = { M3EToggleButtonGroupAction( - label: Text("Mentions"), + checkedLabel: Text("Mentions"), icon: Icon(Icons.alternate_email), ): .highlight, M3EToggleButtonGroupAction( - label: Text("All Notifications"), + checkedLabel: Text("All Notifications"), icon: Icon(Icons.notifications), ): .notify, }; From 8c440447f2c36d644d5294553b195f912550c7ac Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Fri, 11 Sep 2026 22:42:17 -0400 Subject: [PATCH 105/176] check off Notifications page in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1c10866..b165d7a 100644 --- a/README.md +++ b/README.md @@ -111,7 +111,7 @@ A simple and user-friendly Matrix client made with Flutter and a Gomuks backend. - [x] Sort by power level - [ ] Colors based off of power level - [x] Notifications using UnifiedPush ([#35](https://git.federated.nexus/Nexus/nexus/issues/35)) -- [ ] Notifications page +- [x] Notifications page - [ ] Group calls using [MSC4195](https://github.com/matrix-org/matrix-spec-proposals/pull/4195) - [ ] Invites - [x] Settings From ea687471bc6247f243d11e6b0a95a28a9ee1eb3c Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Fri, 11 Sep 2026 22:42:43 -0400 Subject: [PATCH 106/176] Make TODO on notifications page more useful --- lib/pages/notifications.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pages/notifications.dart b/lib/pages/notifications.dart index a59c120..380e6af 100644 --- a/lib/pages/notifications.dart +++ b/lib/pages/notifications.dart @@ -88,7 +88,7 @@ class const NotificationsPage({ child: HighlightWrapper( InkWell( onTap: () { - //TODO + // TODO: Jump to event }, child: EventRenderer(event), ), From e21c9e8c2221d146fd4745f467017fbdcf2109ab Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 12 Sep 2026 09:52:01 -0400 Subject: [PATCH 107/176] make highlights work better for Notifications page --- lib/controllers/notification.dart | 2 +- lib/pages/notifications.dart | 45 ++++++++++++++++++++++++++++--- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/lib/controllers/notification.dart b/lib/controllers/notification.dart index d3db8b7..7996a47 100644 --- a/lib/controllers/notification.dart +++ b/lib/controllers/notification.dart @@ -34,7 +34,7 @@ class NotificationController Navigator.of(context).push( MaterialPageRoute( builder: (_) => NotificationsPage( - eventId: eventId, + highlightedEventId: eventId, defaultToAllNotifications: true, ), ), diff --git a/lib/pages/notifications.dart b/lib/pages/notifications.dart index 380e6af..3e70104 100644 --- a/lib/pages/notifications.dart +++ b/lib/pages/notifications.dart @@ -1,3 +1,5 @@ +import "dart:async"; + import "package:m3e_buttons/m3e_buttons.dart"; import "package:material_ui/material_ui.dart"; import "package:flutter_hooks/flutter_hooks.dart"; @@ -12,7 +14,7 @@ import "package:nexus/widgets/renderers/event.dart"; import "package:super_sliver_list/super_sliver_list.dart"; class const NotificationsPage({ - final String? eventId, + final String? highlightedEventId, final bool defaultToAllNotifications = false, super.key, }) extends HookConsumerWidget { @@ -30,6 +32,10 @@ class const NotificationsPage({ }; final unreadTypeIndex = useState(defaultToAllNotifications ? 1 : 0); + final highlightedId = useState(highlightedEventId); + final listController = useRef(ListController()); + final scrollController = useScrollController(); + final provider = NotificationsController.provider(( options.values.toList()[unreadTypeIndex.value], null, @@ -37,7 +43,38 @@ class const NotificationsPage({ final notifications = ref.watch(provider); final notifier = ref.watch(provider.notifier); - final scrollController = useScrollController(); + useEffect(() { + if (highlightedId.value == null) return null; + Timer? timer; + + void listener() => + WidgetsBinding.instance.addPostFrameCallback((_) async { + if (!listController.value.isAttached) return; + + final notifications = await ref.watch(provider.future); + + final index = notifications.indexWhere( + (element) => element.eventId == highlightedId.value!, + ); + + if (index == -1) return; + + listController.value.animateToItem( + index: index, + scrollController: scrollController, + alignment: 0.5, + duration: (_) => .new(milliseconds: 700), + curve: (_) => Curves.easeInOut, + ); + timer = Timer(.new(seconds: 1), () { + highlightedId.value = null; + }); + listController.value.removeListener(listener); + }); + + listController.value.addListener(listener); + return timer?.cancel; + }, []); useEffect(() { Future listener() async { @@ -72,6 +109,7 @@ class const NotificationsPage({ ), ) : SuperListView.builder( + listController: listController.value, controller: scrollController, itemCount: value.length, padding: const EdgeInsets.symmetric( @@ -81,7 +119,8 @@ class const NotificationsPage({ reverse: true, itemBuilder: (context, index) { final event = value[index]; - final isHighlighted = event.eventId == eventId; + final isHighlighted = + event.eventId == highlightedId.value; return Padding( padding: .only(top: 8), From 5acdbb5be0984977f86ffb9d67283ce3d00d1169 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 16 Sep 2026 14:47:46 -0400 Subject: [PATCH 108/176] Better emoji picker (#73) Adds a better, custom, emoji picker. Reviewed-on: https://git.federated.nexus/Nexus/nexus/pulls/73 --- lib/controllers/emoji.dart | 84 ---------------------------- lib/models/emoji.dart | 15 +++-- lib/models/emoji_category.dart | 12 ++++ lib/pages/chat.dart | 3 - lib/widgets/composer/composer.dart | 19 +++++-- lib/widgets/emoji_picker_button.dart | 46 --------------- lib/widgets/room_chat.dart | 27 +++++++-- pubspec.lock | 17 +++--- pubspec.yaml | 4 +- scripts/generate.dart | 4 +- 10 files changed, 69 insertions(+), 162 deletions(-) delete mode 100644 lib/controllers/emoji.dart create mode 100644 lib/models/emoji_category.dart delete mode 100644 lib/widgets/emoji_picker_button.dart diff --git a/lib/controllers/emoji.dart b/lib/controllers/emoji.dart deleted file mode 100644 index b0c1bd3..0000000 --- a/lib/controllers/emoji.dart +++ /dev/null @@ -1,84 +0,0 @@ -import "dart:convert"; -import "package:emoji_text_field/models/emoji_category.dart"; -import "package:fast_immutable_collections/fast_immutable_collections.dart"; -import "package:material_ui/material_ui.dart"; -import "package:flutter_riverpod/flutter_riverpod.dart"; -import "package:http/http.dart"; -import "package:nexus/models/emoji.dart"; - -typedef EmojiTuple = (IMap, IMap>); - -class EmojiController extends AsyncNotifier { - @override - Future build() async { - final response = await get( - .https("github.com", "github/gemoji/raw/refs/heads/master/db/emoji.json"), - ); - - if (response.statusCode != 200) { - throw Exception("Failed to load emoji data"); - } - - final data = json.decode(response.body); - - final entries = (data as List) - .cast>() - .map(Emoji.fromJson) - .toIList(); - - final categoryMap = entries.fold>>( - .new(), - (acc, entry) => acc.update( - entry.category, - (list) => list.add(entry.emoji), - ifAbsent: () => .new([entry.emoji]), - ), - ); - - final keywordMap = entries.fold>>( - .new(), - (acc, entry) => acc.add( - entry.emoji, - .new([...entry.tags, ...entry.aliases, entry.description]), - ), - ); - - final customCategories = IMap.fromEntries( - categoryMap.entries.map( - (entry) => MapEntry( - entry.key, - EmojiCategory( - name: entry.key, - icon: switch (entry.key) { - "Smileys & Emotion" => Icons.emoji_emotions, - "People & Body" => Icons.emoji_people, - "Animals & Nature" => Icons.emoji_nature, - "Food & Drink" => Icons.emoji_food_beverage, - "Travel & Places" => Icons.travel_explore, - "Activities" => Icons.sports_soccer, - "Objects" => Icons.emoji_objects, - "Symbols" => Icons.emoji_symbols, - "Flags" => Icons.emoji_flags, - _ => Icons.category, - }, - emojis: entry.value.toList(growable: false), - ), - ), - ), - ); - - final customKeywords = IMap( - .fromEntries( - keywordMap.entries.map( - (e) => .new(e.key, e.value.toList(growable: false)), - ), - ), - ); - - return (customCategories, customKeywords); - } - - static final provider = AsyncNotifierProvider( - EmojiController.new, - ); -} diff --git a/lib/models/emoji.dart b/lib/models/emoji.dart index 149ae18..75faf08 100644 --- a/lib/models/emoji.dart +++ b/lib/models/emoji.dart @@ -1,18 +1,25 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:freezed_annotation/freezed_annotation.dart"; +import "package:flutter/widgets.dart"; part "emoji.freezed.dart"; part "emoji.g.dart"; @Freezed(toJson: false, fromJson: false) -@JsonSerializable() +@JsonSerializable(createToJson: false) class Emoji({ - required final String emoji, - required final String category, + @JsonKey( + fromJson: Emoji.widgetFromJson, + readValue: Emoji.readWidgetValueFromJson, + ) + required final Widget widget, + @JsonKey(name: "emoji") required final String value, required final IList aliases, required final String description, required final IList tags, }) with _$Emoji { - Map toJson() => _$EmojiToJson(this); + static Widget widgetFromJson(String emoji) => Text(emoji); + static String readWidgetValueFromJson(Map json, _) => + json["emoji"]; factory Emoji.fromJson(Map json) => _$EmojiFromJson(json); } diff --git a/lib/models/emoji_category.dart b/lib/models/emoji_category.dart new file mode 100644 index 0000000..cc39bc3 --- /dev/null +++ b/lib/models/emoji_category.dart @@ -0,0 +1,12 @@ +import "package:fast_immutable_collections/fast_immutable_collections.dart"; +import "package:freezed_annotation/freezed_annotation.dart"; +import "package:nexus/models/emoji.dart"; +import "package:flutter/widgets.dart"; +part "emoji_category.freezed.dart"; + +@Freezed(toJson: false, fromJson: false) +class EmojiCategory({ + required final Widget icon, + required final String name, + required final IList emojis, +}) with _$EmojiCategory; diff --git a/lib/pages/chat.dart b/lib/pages/chat.dart index c58b7a7..9469c91 100644 --- a/lib/pages/chat.dart +++ b/lib/pages/chat.dart @@ -1,6 +1,5 @@ import "package:material_ui/material_ui.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:nexus/controllers/emoji.dart"; import "package:nexus/controllers/init_complete.dart"; import "package:nexus/controllers/key.dart"; import "package:nexus/widgets/appbar.dart"; @@ -17,8 +16,6 @@ class const ChatPage({super.key}) extends ConsumerWidget { final initComplete = ref.watch(InitCompleteController.provider); final roomId = ref.watch(KeyController.provider(KeyController.roomKey)); - ref.read(EmojiController.provider); - return SafeArea( child: Scaffold( appBar: initComplete ? null : Appbar(), diff --git a/lib/widgets/composer/composer.dart b/lib/widgets/composer/composer.dart index 9a597a4..eacfad8 100644 --- a/lib/widgets/composer/composer.dart +++ b/lib/widgets/composer/composer.dart @@ -2,6 +2,7 @@ import "dart:io"; import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:file_selector/file_selector.dart"; +import "package:material_emoji_picker/material_emoji_picker.dart"; import "package:material_ui/material_ui.dart"; import "package:flutter/services.dart"; import "package:flutter_hooks/flutter_hooks.dart"; @@ -15,7 +16,6 @@ import "package:nexus/models/event.dart"; import "package:nexus/models/relation_type.dart"; import "package:nexus/widgets/composer/mention_overlay.dart"; import "package:nexus/widgets/composer/relation_preview.dart"; -import "package:nexus/widgets/emoji_picker_button.dart"; import "package:nexus/main.dart"; class const Composer( @@ -119,10 +119,19 @@ class const Composer( ), ) ? [ - EmojiPickerButton( - context: context, - onSelection: (_) => node?.requestFocus(), - controller: controller.value, + IconButton( + onPressed: () => showModalBottomSheet( + isScrollControlled: true, + context: context, + builder: (context) => EmojiPicker( + onSelection: (value) { + Navigator.of(context).pop(); + controller.value.text += value; + node?.requestFocus(); + }, + ), + ), + icon: Icon(Icons.emoji_emotions), ), PopupMenuButton( tooltip: "Add media", diff --git a/lib/widgets/emoji_picker_button.dart b/lib/widgets/emoji_picker_button.dart deleted file mode 100644 index 1e20557..0000000 --- a/lib/widgets/emoji_picker_button.dart +++ /dev/null @@ -1,46 +0,0 @@ -import "package:emoji_text_field/emoji_text_field.dart"; -import "package:material_ui/material_ui.dart"; -import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:nexus/controllers/emoji.dart"; - -final class const EmojiPickerButton({ - required final BuildContext context, - final TextEditingController? controller, - final void Function(String emoji)? onSelection, - final VoidCallback? onPressed, - super.key, -}) extends HookConsumerWidget { - @override - Widget build(_, WidgetRef ref) => IconButton( - onPressed: () async { - onPressed?.call(); - final controller = this.controller ?? .new(); - - final emojis = await ref.watch(EmojiController.provider.future); - if (context.mounted) { - showModalBottomSheet( - context: context, - builder: (context) => EmojiKeyboardView( - config: .new( - showRecentTab: false, - customCategories: emojis.$1.unlock, - customKeywords: emojis.$2.unlock, - backgroundColor: Theme.of(context).colorScheme.surfaceContainer, - height: 600, - ), - textController: controller - ..addListener(() { - // Without this, there will sometimes be a debugLocked is not true error sometimes - // It might be preferable to use a microtask instead of a `Future.delayed`. - Future.delayed(.zero, () { - if (context.mounted) Navigator.of(context).pop(); - }); - onSelection?.call(controller.text); - }), - ), - ); - } - }, - icon: Icon(Icons.emoji_emotions), - ); -} diff --git a/lib/widgets/room_chat.dart b/lib/widgets/room_chat.dart index dd6ed25..121428b 100644 --- a/lib/widgets/room_chat.dart +++ b/lib/widgets/room_chat.dart @@ -17,7 +17,7 @@ import "package:nexus/models/content/message.dart"; import "package:nexus/models/event.dart"; import "package:nexus/models/relation_type.dart"; import "package:nexus/widgets/composer/composer.dart"; -import "package:nexus/widgets/emoji_picker_button.dart"; +import "package:material_emoji_picker/material_emoji_picker.dart"; import "package:nexus/widgets/pinned_events_drawer.dart"; import "package:nexus/widgets/renderers/event.dart"; import "package:nexus/widgets/member_list.dart"; @@ -234,11 +234,26 @@ final class const RoomChat({ icon: Text(emoji), ), ), - EmojiPickerButton( - context: context, - onPressed: Navigator.of(context).pop, - onSelection: (emoji) => - notifier.sendReaction(emoji, event).onError(showError), + IconButton( + icon: Icon(Icons.emoji_emotions), + + onPressed: () { + // TODO: More adaptive, e.g. dialog on desktop + Navigator.of(context).pop(); + showModalBottomSheet( + isScrollControlled: true, + context: context, + builder: (context) => EmojiPicker( + onSelection: (value) { + Navigator.of(context).pop(); + notifier + .sendReaction(value, event) + .onError(showError); + }, + allowFreeText: true, + ), + ); + }, ), ], ), diff --git a/pubspec.lock b/pubspec.lock index 82e2d72..b3102b9 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -297,15 +297,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.0.8" - emoji_text_field: - dependency: "direct main" - description: - path: "." - ref: HEAD - resolved-ref: "5f7baaf8a6f059ec3ab8ff0f5d02339b00bf6997" - url: "https://github.com/Henry-Hiles/emoji_text_field" - source: git - version: "1.0.0" encrypt: dependency: transitive description: @@ -903,6 +894,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.13.0" + material_emoji_picker: + dependency: "direct main" + description: + name: material_emoji_picker + sha256: "1547195a419134cf0b2396d119dc873589804f461424917b1b61a0966bfb7e5a" + url: "https://pub.dev" + source: hosted + version: "1.0.0+1" material_ui: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index ab2f727..9f3b2c5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -59,9 +59,6 @@ dependencies: http: 1.6.0 flutter_linkify: 6.0.0 linkify: 5.0.0 - emoji_text_field: - git: - url: https://github.com/Henry-Hiles/emoji_text_field flutter_blurhash: 0.9.1 super_sliver_list: 0.4.1 media_kit: 1.2.6 @@ -83,6 +80,7 @@ dependencies: unifiedpush_storage_shared_preferences: 1.0.0 flutter_local_notifications: 22.3.0 flutter_local_notifications_linux: 8.0.1 + material_emoji_picker: 1.0.0+1 dev_dependencies: build_runner: 2.16.1 diff --git a/scripts/generate.dart b/scripts/generate.dart index b9b8511..d8a8cb1 100644 --- a/scripts/generate.dart +++ b/scripts/generate.dart @@ -7,7 +7,7 @@ import "package:nexus/helpers/extensions/get_xcode_sdk.dart"; void main(List args) async { final repoDir = Directory.fromUri(Platform.script.resolve("../gomuks")); - print("Generating FFI Bindings..."); + print("Generating FFI bindings..."); final libclangPath = Platform.environment["LIBCLANG_PATH"]; FfiGenerator( @@ -40,5 +40,5 @@ void main(List args) async { ), ), ); - print("Done!"); + print("FFI bindings generated!"); } From ec1603b828a42247bc724245ea371e7b22eda334 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 16 Sep 2026 15:18:41 -0400 Subject: [PATCH 109/176] add support for showing recent emoji --- lib/widgets/composer/composer.dart | 2 +- lib/widgets/emoji_picker.dart | 53 ++++++++++++++++++++++++++++++ lib/widgets/room_chat.dart | 2 +- pubspec.lock | 4 +-- pubspec.yaml | 2 +- 5 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 lib/widgets/emoji_picker.dart diff --git a/lib/widgets/composer/composer.dart b/lib/widgets/composer/composer.dart index eacfad8..d8db045 100644 --- a/lib/widgets/composer/composer.dart +++ b/lib/widgets/composer/composer.dart @@ -2,7 +2,7 @@ import "dart:io"; import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:file_selector/file_selector.dart"; -import "package:material_emoji_picker/material_emoji_picker.dart"; +import "package:nexus/widgets/emoji_picker.dart"; import "package:material_ui/material_ui.dart"; import "package:flutter/services.dart"; import "package:flutter_hooks/flutter_hooks.dart"; diff --git a/lib/widgets/emoji_picker.dart b/lib/widgets/emoji_picker.dart new file mode 100644 index 0000000..144d9bc --- /dev/null +++ b/lib/widgets/emoji_picker.dart @@ -0,0 +1,53 @@ +import "dart:async"; + +import "package:collection/collection.dart"; +import "package:fast_immutable_collections/fast_immutable_collections.dart"; +import "package:hooks_riverpod/hooks_riverpod.dart"; +import "package:material_emoji_picker/material_emoji_picker.dart" as upstream; +import "package:material_ui/material_ui.dart"; +import "package:nexus/controllers/account_data.dart"; +import "package:nexus/helpers/extensions/better_when.dart"; + +class const EmojiPicker({ + required final FutureOr Function(String value) onSelection, + final bool allowFreeText = false, + super.key, +}) extends ConsumerWidget { + @override + Widget build(BuildContext context, WidgetRef ref) => ref + .watch(upstream.EmojiController.provider) + .betterWhen( + data: (categories) => upstream.EmojiPicker( + onSelection: (value) async { + // + await onSelection(value); + }, + allowFreeText: allowFreeText, + prependCategories: .new([ + .new( + icon: Icon(Icons.history), + name: "Recent", + emojis: .new( + ref + .watch( + AccountDataController.provider.select( + (value) => value.recentEmoji + .map((entry) => entry.emoji) + .toIList(), + ), + ) + .map( + (emoji) => categories + .map((element) => element.emojis) + .flattened + .firstWhereOrNull( + (element) => element.value == emoji, + ), + ) + .nonNulls, + ), + ), + ]), + ), + ); +} diff --git a/lib/widgets/room_chat.dart b/lib/widgets/room_chat.dart index 121428b..6161cde 100644 --- a/lib/widgets/room_chat.dart +++ b/lib/widgets/room_chat.dart @@ -17,7 +17,7 @@ import "package:nexus/models/content/message.dart"; import "package:nexus/models/event.dart"; import "package:nexus/models/relation_type.dart"; import "package:nexus/widgets/composer/composer.dart"; -import "package:material_emoji_picker/material_emoji_picker.dart"; +import "package:nexus/widgets/emoji_picker.dart"; import "package:nexus/widgets/pinned_events_drawer.dart"; import "package:nexus/widgets/renderers/event.dart"; import "package:nexus/widgets/member_list.dart"; diff --git a/pubspec.lock b/pubspec.lock index b3102b9..d081bdc 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -898,10 +898,10 @@ packages: dependency: "direct main" description: name: material_emoji_picker - sha256: "1547195a419134cf0b2396d119dc873589804f461424917b1b61a0966bfb7e5a" + sha256: bb1d5a467e2f83fd13dc83bd5a3c827bbfc525041921ed74a1d85b905fdc77e8 url: "https://pub.dev" source: hosted - version: "1.0.0+1" + version: "1.0.2" material_ui: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 9f3b2c5..a3e964a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -80,7 +80,7 @@ dependencies: unifiedpush_storage_shared_preferences: 1.0.0 flutter_local_notifications: 22.3.0 flutter_local_notifications_linux: 8.0.1 - material_emoji_picker: 1.0.0+1 + material_emoji_picker: 1.0.2 dev_dependencies: build_runner: 2.16.1 From 810a0b102b5ea091d85712acd442fedb08ada76e Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 16 Sep 2026 15:46:42 -0400 Subject: [PATCH 110/176] add support for setting recent emoji --- lib/controllers/recent_emoji.dart | 44 ++++++++++++++++++ lib/models/account_data.dart | 28 ++++++------ lib/widgets/emoji_picker.dart | 74 +++++++++++++++---------------- lib/widgets/room_chat.dart | 17 +++---- 4 files changed, 103 insertions(+), 60 deletions(-) create mode 100644 lib/controllers/recent_emoji.dart diff --git a/lib/controllers/recent_emoji.dart b/lib/controllers/recent_emoji.dart new file mode 100644 index 0000000..6cf57f7 --- /dev/null +++ b/lib/controllers/recent_emoji.dart @@ -0,0 +1,44 @@ +import "package:collection/collection.dart"; +import "package:fast_immutable_collections/fast_immutable_collections.dart"; +import "package:flutter_riverpod/flutter_riverpod.dart"; +import "package:nexus/controllers/account_data.dart"; +import "package:nexus/controllers/client.dart"; +import "package:nexus/models/account_data.dart"; + +class RecentEmojiController extends Notifier> { + @override + IList build() => ref.watch( + AccountDataController.provider.select( + (value) => value.recentEmoji.recentEmoji, + ), + ); + + Future add(String emoji) => ref + .watch(ClientController.provider.notifier) + .setAccountData( + .new( + type: AccountData.recentEmojiKey, + content: RecentEmojiData( + recentEmoji: .new([ + .new( + emoji: emoji, + total: + (state + .firstWhereOrNull( + (element) => element.emoji == emoji, + ) + ?.total ?? + 0) + + 1, + ), + ...state.whereNot((element) => element.emoji == emoji), + ]), + ), + ), + ); + + static final provider = + NotifierProvider.autoDispose>( + RecentEmojiController.new, + ); +} diff --git a/lib/models/account_data.dart b/lib/models/account_data.dart index 53b4ff2..955d8d1 100644 --- a/lib/models/account_data.dart +++ b/lib/models/account_data.dart @@ -14,22 +14,9 @@ class const AccountData({ @JsonKey(name: AccountData.directKey) final IMap> directMessages = const IMap.empty(), - @JsonKey( - name: AccountData.recentEmojiKey, - readValue: AccountData.readRecentEmojiValue, - toJson: AccountData.recentEmojiToJson, - ) - final IList recentEmoji = const IList.empty(), + @JsonKey(name: AccountData.recentEmojiKey) + final RecentEmojiData recentEmoji = const RecentEmojiData(), }) with _$AccountData { - static List? readRecentEmojiValue( - Map json, - String key, - ) => json[key]?["recent_emoji"]; - - static Map>? recentEmojiToJson( - IList recentEmoji, - ) => {"recent_emoji": recentEmoji.map((emoji) => emoji.toJson()).toList()}; - static const invitePermissionConfigKey = "m.invite_permission_config"; static const directKey = "m.direct"; static const recentEmojiKey = "m.recent_emoji"; @@ -40,6 +27,17 @@ class const AccountData({ _$AccountDataFromJson(json); } +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const RecentEmojiData({ + final IList recentEmoji = const IList.empty(), +}) with _$RecentEmojiData { + Map toJson() => _$RecentEmojiDataToJson(this); + + factory RecentEmojiData.fromJson(Map json) => + _$RecentEmojiDataFromJson(json); +} + @Freezed(toJson: false, fromJson: false) @JsonSerializable() class const InvitePermissionConfig({ diff --git a/lib/widgets/emoji_picker.dart b/lib/widgets/emoji_picker.dart index 144d9bc..a0c691a 100644 --- a/lib/widgets/emoji_picker.dart +++ b/lib/widgets/emoji_picker.dart @@ -1,12 +1,12 @@ import "dart:async"; import "package:collection/collection.dart"; -import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:material_emoji_picker/material_emoji_picker.dart" as upstream; import "package:material_ui/material_ui.dart"; -import "package:nexus/controllers/account_data.dart"; +import "package:nexus/controllers/recent_emoji.dart"; import "package:nexus/helpers/extensions/better_when.dart"; +import "package:nexus/main.dart"; class const EmojiPicker({ required final FutureOr Function(String value) onSelection, @@ -14,40 +14,40 @@ class const EmojiPicker({ super.key, }) extends ConsumerWidget { @override - Widget build(BuildContext context, WidgetRef ref) => ref - .watch(upstream.EmojiController.provider) - .betterWhen( - data: (categories) => upstream.EmojiPicker( - onSelection: (value) async { - // - await onSelection(value); - }, - allowFreeText: allowFreeText, - prependCategories: .new([ - .new( - icon: Icon(Icons.history), - name: "Recent", - emojis: .new( - ref - .watch( - AccountDataController.provider.select( - (value) => value.recentEmoji - .map((entry) => entry.emoji) - .toIList(), - ), - ) - .map( - (emoji) => categories - .map((element) => element.emojis) - .flattened - .firstWhereOrNull( - (element) => element.value == emoji, - ), - ) - .nonNulls, + Widget build(BuildContext context, WidgetRef ref) { + final recentEmoji = ref.watch(RecentEmojiController.provider); + + return ref + .watch(upstream.EmojiController.provider) + .betterWhen( + data: (categories) => upstream.EmojiPicker( + onSelection: (emoji) async { + await onSelection(emoji); + await ref + .watch(RecentEmojiController.provider.notifier) + .add(emoji) + .onError(showError); + }, + allowFreeText: allowFreeText, + prependCategories: .new([ + .new( + icon: Icon(Icons.history), + name: "Recent", + emojis: .new( + recentEmoji + .map( + (recent) => categories + .map((element) => element.emojis) + .flattened + .firstWhereOrNull( + (element) => element.value == recent.emoji, + ), + ) + .nonNulls, + ), ), - ), - ]), - ), - ); + ]), + ), + ); + } } diff --git a/lib/widgets/room_chat.dart b/lib/widgets/room_chat.dart index 6161cde..015bbc4 100644 --- a/lib/widgets/room_chat.dart +++ b/lib/widgets/room_chat.dart @@ -4,12 +4,12 @@ import "package:flutter/services.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:measure_size/measure_size.dart"; -import "package:nexus/controllers/account_data.dart"; import "package:nexus/controllers/client.dart"; import "package:nexus/controllers/client_state.dart"; import "package:nexus/controllers/member_list_opened.dart"; import "package:nexus/controllers/pinned_ids.dart"; import "package:nexus/controllers/power_level.dart"; +import "package:nexus/controllers/recent_emoji.dart"; import "package:nexus/controllers/rooms.dart"; import "package:nexus/controllers/room_chat.dart"; import "package:nexus/controllers/via.dart"; @@ -196,6 +196,8 @@ final class const RoomChat({ final danger = theme.colorScheme.error; final isSentByMe = event.sender == userId; + final recentEmoji = ref.watch(RecentEmojiController.provider); + return [ if (ref.watch( PowerLevelController.provider( @@ -209,13 +211,7 @@ final class const RoomChat({ child: Row( children: [ ...{ - ...ref.watch( - AccountDataController.provider.select( - (value) => value.recentEmoji - .map((entry) => entry.emoji) - .toIList(), - ), - ), + ...recentEmoji.map((entry) => entry.emoji), "👍", "🤣", "😭", @@ -230,6 +226,11 @@ final class const RoomChat({ await notifier .sendReaction(emoji, event) .onError(showError); + + ref + .watch(RecentEmojiController.provider.notifier) + .add(emoji) + .onError(showError); }, icon: Text(emoji), ), From e5dc270f8340ad6cd32a1e1f1171db058f03c850 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 16 Sep 2026 16:27:07 -0400 Subject: [PATCH 111/176] bump emoji picker --- pubspec.lock | 4 ++-- pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index d081bdc..1b0180e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -898,10 +898,10 @@ packages: dependency: "direct main" description: name: material_emoji_picker - sha256: bb1d5a467e2f83fd13dc83bd5a3c827bbfc525041921ed74a1d85b905fdc77e8 + sha256: d685f42595f3e2dfeb699d5da53f6576c44ae97da24f2a52f035c26b81d7645e url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "1.0.3" material_ui: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index a3e964a..6cb2f6e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -80,7 +80,7 @@ dependencies: unifiedpush_storage_shared_preferences: 1.0.0 flutter_local_notifications: 22.3.0 flutter_local_notifications_linux: 8.0.1 - material_emoji_picker: 1.0.2 + material_emoji_picker: 1.0.3 dev_dependencies: build_runner: 2.16.1 From dca0b7dd7db3ffdd4dbfd5e5225e6f54cf5a15c6 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 16 Sep 2026 16:27:10 -0400 Subject: [PATCH 112/176] refactor overlay system --- lib/widgets/composer/composer.dart | 5 +- lib/widgets/composer/mention_overlay.dart | 153 ------------------ .../composer/overlays/room_overlay.dart | 62 +++++++ .../composer/overlays/tagger_overlay.dart | 34 ++++ .../composer/overlays/user_overlay.dart | 67 ++++++++ 5 files changed, 166 insertions(+), 155 deletions(-) delete mode 100644 lib/widgets/composer/mention_overlay.dart create mode 100644 lib/widgets/composer/overlays/room_overlay.dart create mode 100644 lib/widgets/composer/overlays/tagger_overlay.dart create mode 100644 lib/widgets/composer/overlays/user_overlay.dart diff --git a/lib/widgets/composer/composer.dart b/lib/widgets/composer/composer.dart index d8db045..a120595 100644 --- a/lib/widgets/composer/composer.dart +++ b/lib/widgets/composer/composer.dart @@ -14,7 +14,7 @@ import "package:nexus/controllers/power_level.dart"; import "package:nexus/models/content/message.dart"; import "package:nexus/models/event.dart"; import "package:nexus/models/relation_type.dart"; -import "package:nexus/widgets/composer/mention_overlay.dart"; +import "package:nexus/widgets/composer/overlays/tagger_overlay.dart"; import "package:nexus/widgets/composer/relation_preview.dart"; import "package:nexus/main.dart"; @@ -195,7 +195,7 @@ class const Composer( Expanded( child: FlutterTagger( triggerStrategy: .eager, - overlay: MentionOverlay( + overlay: TaggerOverlay( roomId, query: query.value, triggerCharacter: triggerCharacter.value, @@ -212,6 +212,7 @@ class const Composer( triggerCharacterAndStyles: { "@": style, "#": style, + ":": style, }, builder: (context, key) => Focus( onKeyEvent: (_, event) { diff --git a/lib/widgets/composer/mention_overlay.dart b/lib/widgets/composer/mention_overlay.dart deleted file mode 100644 index 3dc0604..0000000 --- a/lib/widgets/composer/mention_overlay.dart +++ /dev/null @@ -1,153 +0,0 @@ -import "package:material_ui/material_ui.dart"; -import "package:hooks_riverpod/hooks_riverpod.dart"; -import "package:nexus/controllers/members_by_status.dart"; -import "package:nexus/controllers/rooms.dart"; -import "package:nexus/controllers/via.dart"; -import "package:nexus/helpers/extensions/better_when.dart"; -import "package:nexus/helpers/extensions/get_localpart.dart"; -import "package:nexus/models/content/membership.dart"; -import "package:nexus/widgets/avatar_or_hash.dart"; -import "package:nexus/widgets/loading.dart"; - -class const MentionOverlay( - final String roomId, { - required final String query, - required final void Function({required String id, required String name}) - addTag, - required final String? triggerCharacter, - super.key, -}) extends ConsumerWidget { - @override - Widget build(BuildContext context, WidgetRef ref) { - final rooms = ref.watch(RoomsController.provider); - - return Padding( - padding: .all(8), - child: ClipRRect( - borderRadius: .all(.circular(12)), - child: Container( - color: Theme.of(context).colorScheme.surfaceContainerHigh, - padding: .all(8), - child: switch (triggerCharacter) { - "@" => - ref - .watch( - MembersByStatusController.provider( - .new(roomId: roomId, status: .join), - ), - ) - .betterWhen( - data: (members) => ListView( - children: - (query.isEmpty - ? members - : members.where( - (member) => - member.stateKey - ?.toLowerCase() - .contains( - query.toLowerCase(), - ) == - true || - switch (member.content) { - MembershipContent( - :final displayName, - ) => - displayName - ?.toLowerCase() - .contains( - query.toLowerCase(), - ) == - true, - _ => false, - }, - )) - .map( - (member) => switch (member.content) { - MembershipContent( - :final displayName, - :final avatarUrl, - ) => - Material( - color: Colors.transparent, - child: ListTile( - leading: AvatarOrHash( - avatarUrl, - displayName ?? - member.stateKey!.localpart, - ), - title: Text( - displayName ?? - member.stateKey!.localpart, - ), - subtitle: Text(member.stateKey!), - onTap: () => addTag( - id: "[@$displayName](matrix:u/${member.stateKey!.substring(1)})", - name: member.stateKey!.localpart, - ), - ), - ), - _ => SizedBox.shrink(), - }, - ) - .toList(), - ), - ), - "#" => ListView( - children: - (query.isEmpty - ? rooms.values - : rooms.values.where( - (room) => - (room.metadata?.name ?? - room.metadata?.id ?? - "") - .toLowerCase() - .contains(query.toLowerCase()), - )) - .map((room) { - final name = - room.metadata?.name ?? - room.metadata?.canonicalAlias ?? - room.metadata?.id ?? - "Unknown Room"; - return Material( - color: Colors.transparent, - child: ListTile( - leading: AvatarOrHash( - room.metadata?.avatar, - name, - fallback: Icon(Icons.numbers), - ), - title: Text(name), - subtitle: room.metadata?.topic == null - ? null - : Text(room.metadata!.topic!, maxLines: 1), - onTap: () { - final vias = ref.watch( - ViaController.provider(room), - ); - addTag( - id: "[#$name](matrix:roomid/${room.metadata?.id.substring(1)}$vias)", - name: - (room.metadata?.canonicalAlias ?? - room.metadata?.id) - ?.substring(1) - .split(":") - .first ?? - "", - ); - }, - ), - ); - }) - .toList(), - ), - - _ => Loading(), - }, - ), - ), - ); - } -} diff --git a/lib/widgets/composer/overlays/room_overlay.dart b/lib/widgets/composer/overlays/room_overlay.dart new file mode 100644 index 0000000..5956608 --- /dev/null +++ b/lib/widgets/composer/overlays/room_overlay.dart @@ -0,0 +1,62 @@ +import "package:hooks_riverpod/hooks_riverpod.dart"; +import "package:material_ui/material_ui.dart"; +import "package:nexus/controllers/rooms.dart"; +import "package:nexus/controllers/via.dart"; +import "package:nexus/widgets/avatar_or_hash.dart"; + +class const RoomOverlay( + final String roomId, { + required final String query, + required final void Function({required String id, required String name}) + addTag, + super.key, +}) extends ConsumerWidget { + @override + Widget build(BuildContext context, WidgetRef ref) { + final rooms = ref.watch(RoomsController.provider); + return ListView( + children: + (query.isEmpty + ? rooms.values + : rooms.values.where( + (room) => (room.metadata?.name ?? room.metadata?.id ?? "") + .toLowerCase() + .contains(query.toLowerCase()), + )) + .map((room) { + final name = + room.metadata?.name ?? + room.metadata?.canonicalAlias ?? + room.metadata?.id ?? + "Unknown Room"; + return Material( + color: Colors.transparent, + child: ListTile( + leading: AvatarOrHash( + room.metadata?.avatar, + name, + fallback: Icon(Icons.numbers), + ), + title: Text(name), + subtitle: room.metadata?.topic == null + ? null + : Text(room.metadata!.topic!, maxLines: 1), + onTap: () { + final vias = ref.watch(ViaController.provider(room)); + addTag( + id: "[#$name](matrix:roomid/${room.metadata?.id.substring(1)}$vias)", + name: + (room.metadata?.canonicalAlias ?? room.metadata?.id) + ?.substring(1) + .split(":") + .first ?? + "", + ); + }, + ), + ); + }) + .toList(), + ); + } +} diff --git a/lib/widgets/composer/overlays/tagger_overlay.dart b/lib/widgets/composer/overlays/tagger_overlay.dart new file mode 100644 index 0000000..ef78636 --- /dev/null +++ b/lib/widgets/composer/overlays/tagger_overlay.dart @@ -0,0 +1,34 @@ +import "package:material_ui/material_ui.dart"; +import "package:hooks_riverpod/hooks_riverpod.dart"; +import "package:nexus/widgets/composer/overlays/room_overlay.dart"; +import "package:nexus/widgets/composer/overlays/user_overlay.dart"; +import "package:nexus/widgets/loading.dart"; + +class const TaggerOverlay( + final String roomId, { + required final String query, + required final void Function({required String id, required String name}) + addTag, + required final String? triggerCharacter, + super.key, +}) extends ConsumerWidget { + @override + Widget build(BuildContext context, WidgetRef ref) { + return Padding( + padding: .all(8), + child: ClipRRect( + borderRadius: .all(.circular(12)), + child: Container( + color: Theme.of(context).colorScheme.surfaceContainerHigh, + padding: .all(8), + child: switch (triggerCharacter) { + "@" => UserOverlay(roomId, query: query, addTag: addTag), + "#" => RoomOverlay(roomId, query: query, addTag: addTag), + + _ => Loading(), + }, + ), + ), + ); + } +} diff --git a/lib/widgets/composer/overlays/user_overlay.dart b/lib/widgets/composer/overlays/user_overlay.dart new file mode 100644 index 0000000..caf3d0f --- /dev/null +++ b/lib/widgets/composer/overlays/user_overlay.dart @@ -0,0 +1,67 @@ +import "package:hooks_riverpod/hooks_riverpod.dart"; +import "package:material_ui/material_ui.dart"; +import "package:nexus/controllers/members_by_status.dart"; +import "package:nexus/helpers/extensions/better_when.dart"; +import "package:nexus/helpers/extensions/get_localpart.dart"; +import "package:nexus/models/content/membership.dart"; +import "package:nexus/widgets/avatar_or_hash.dart"; + +class const UserOverlay( + final String roomId, { + required final String query, + required final void Function({required String id, required String name}) + addTag, + super.key, +}) extends ConsumerWidget { + @override + Widget build(BuildContext context, WidgetRef ref) => ref + .watch( + MembersByStatusController.provider(.new(roomId: roomId, status: .join)), + ) + .betterWhen( + data: (members) => ListView( + children: + (query.isEmpty + ? members + : members.where( + (member) => + member.stateKey?.toLowerCase().contains( + query.toLowerCase(), + ) == + true || + switch (member.content) { + MembershipContent(:final displayName) => + displayName?.toLowerCase().contains( + query.toLowerCase(), + ) == + true, + _ => false, + }, + )) + .map( + (member) => switch (member.content) { + MembershipContent(:final displayName, :final avatarUrl) => + Material( + color: Colors.transparent, + child: ListTile( + leading: AvatarOrHash( + avatarUrl, + displayName ?? member.stateKey!.localpart, + ), + title: Text( + displayName ?? member.stateKey!.localpart, + ), + subtitle: Text(member.stateKey!), + onTap: () => addTag( + id: "[@$displayName](matrix:u/${member.stateKey!.substring(1)})", + name: member.stateKey!.localpart, + ), + ), + ), + _ => SizedBox.shrink(), + }, + ) + .toList(), + ), + ); +} From 11457470a0480894a08a9a8aba8614766638996b Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 16 Sep 2026 16:30:15 -0400 Subject: [PATCH 113/176] move around args to overlays --- lib/widgets/composer/composer.dart | 4 ++-- lib/widgets/composer/overlays/room_overlay.dart | 3 +-- lib/widgets/composer/overlays/tagger_overlay.dart | 8 ++++---- lib/widgets/composer/overlays/user_overlay.dart | 4 ++-- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/lib/widgets/composer/composer.dart b/lib/widgets/composer/composer.dart index a120595..3d04a78 100644 --- a/lib/widgets/composer/composer.dart +++ b/lib/widgets/composer/composer.dart @@ -196,8 +196,8 @@ class const Composer( child: FlutterTagger( triggerStrategy: .eager, overlay: TaggerOverlay( - roomId, - query: query.value, + query.value, + roomId: roomId, triggerCharacter: triggerCharacter.value, addTag: ({required id, required name}) { controller.value.addTag(id: id, name: name); diff --git a/lib/widgets/composer/overlays/room_overlay.dart b/lib/widgets/composer/overlays/room_overlay.dart index 5956608..db74fc0 100644 --- a/lib/widgets/composer/overlays/room_overlay.dart +++ b/lib/widgets/composer/overlays/room_overlay.dart @@ -5,8 +5,7 @@ import "package:nexus/controllers/via.dart"; import "package:nexus/widgets/avatar_or_hash.dart"; class const RoomOverlay( - final String roomId, { - required final String query, + final String query, { required final void Function({required String id, required String name}) addTag, super.key, diff --git a/lib/widgets/composer/overlays/tagger_overlay.dart b/lib/widgets/composer/overlays/tagger_overlay.dart index ef78636..dda9043 100644 --- a/lib/widgets/composer/overlays/tagger_overlay.dart +++ b/lib/widgets/composer/overlays/tagger_overlay.dart @@ -5,8 +5,8 @@ import "package:nexus/widgets/composer/overlays/user_overlay.dart"; import "package:nexus/widgets/loading.dart"; class const TaggerOverlay( - final String roomId, { - required final String query, + final String query, { + required final String roomId, required final void Function({required String id, required String name}) addTag, required final String? triggerCharacter, @@ -22,8 +22,8 @@ class const TaggerOverlay( color: Theme.of(context).colorScheme.surfaceContainerHigh, padding: .all(8), child: switch (triggerCharacter) { - "@" => UserOverlay(roomId, query: query, addTag: addTag), - "#" => RoomOverlay(roomId, query: query, addTag: addTag), + "@" => UserOverlay(query, roomId: roomId, addTag: addTag), + "#" => RoomOverlay(query, addTag: addTag), _ => Loading(), }, diff --git a/lib/widgets/composer/overlays/user_overlay.dart b/lib/widgets/composer/overlays/user_overlay.dart index caf3d0f..ba23c1e 100644 --- a/lib/widgets/composer/overlays/user_overlay.dart +++ b/lib/widgets/composer/overlays/user_overlay.dart @@ -7,8 +7,8 @@ import "package:nexus/models/content/membership.dart"; import "package:nexus/widgets/avatar_or_hash.dart"; class const UserOverlay( - final String roomId, { - required final String query, + final String query, { + required final String roomId, required final void Function({required String id, required String name}) addTag, super.key, From 163947fc90d85fc09896815694768457c7336c8d Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 16 Sep 2026 16:52:58 -0400 Subject: [PATCH 114/176] add emoji overlay --- README.md | 4 +- .../composer/overlays/emoji_overlay.dart | 44 ++++++++++++++++++ .../composer/overlays/room_overlay.dart | 45 +++++++++---------- .../composer/overlays/tagger_overlay.dart | 15 ++++--- .../composer/overlays/user_overlay.dart | 27 +++++------ 5 files changed, 89 insertions(+), 46 deletions(-) create mode 100644 lib/widgets/composer/overlays/emoji_overlay.dart diff --git a/README.md b/README.md index b165d7a..dfe10f7 100644 --- a/README.md +++ b/README.md @@ -55,10 +55,10 @@ A simple and user-friendly Matrix client made with Flutter and a Gomuks backend. - [x] Per message profiles - [x] Attachments - [ ] Commands with [MSC4391](https://github.com/matrix-org/matrix-spec-proposals/pull/4391) - - [x] Mentions + - [x] Tags - [x] Users - [x] Rooms - - [ ] Inline emoji picker (Putting this here since it'll be implemented the same way as mentions) + - [x] Emojis - [ ] Custom emojis/stickers - [ ] GIFs using Gomuks' GIF proxies - [x] Receiving diff --git a/lib/widgets/composer/overlays/emoji_overlay.dart b/lib/widgets/composer/overlays/emoji_overlay.dart new file mode 100644 index 0000000..e537927 --- /dev/null +++ b/lib/widgets/composer/overlays/emoji_overlay.dart @@ -0,0 +1,44 @@ +import "package:collection/collection.dart"; +import "package:hooks_riverpod/hooks_riverpod.dart"; +import "package:material_emoji_picker/material_emoji_picker.dart"; +import "package:material_ui/material_ui.dart"; +import "package:nexus/helpers/extensions/better_when.dart"; + +class const EmojiOverlay( + final String query, { + required final String roomId, + required final void Function({required String id, required String name}) + addTag, + super.key, +}) extends ConsumerWidget { + @override + Widget build(BuildContext context, WidgetRef ref) => ref + .watch(EmojiController.provider) + .betterWhen( + data: (emojis) => ListView( + children: emojis + .map((element) => element.emojis) + .flattened + .where( + (emoji) => + emoji.aliases.join().contains(query) || + emoji.description.contains(query) || + emoji.tags.join().contains(query), + ) + .map( + (emoji) => ListTile( + leading: emoji.widget, + title: Text(emoji.aliases.first), + subtitle: Text(emoji.description), + onTap: () => addTag( + id: Uri.tryParse(emoji.value)?.scheme == "mxc" + ? "" // TODO: Handle custom emotes + : emoji.value, + name: emoji.aliases.first, + ), + ), + ) + .toList(), + ), + ); +} diff --git a/lib/widgets/composer/overlays/room_overlay.dart b/lib/widgets/composer/overlays/room_overlay.dart index db74fc0..b5af177 100644 --- a/lib/widgets/composer/overlays/room_overlay.dart +++ b/lib/widgets/composer/overlays/room_overlay.dart @@ -28,31 +28,28 @@ class const RoomOverlay( room.metadata?.canonicalAlias ?? room.metadata?.id ?? "Unknown Room"; - return Material( - color: Colors.transparent, - child: ListTile( - leading: AvatarOrHash( - room.metadata?.avatar, - name, - fallback: Icon(Icons.numbers), - ), - title: Text(name), - subtitle: room.metadata?.topic == null - ? null - : Text(room.metadata!.topic!, maxLines: 1), - onTap: () { - final vias = ref.watch(ViaController.provider(room)); - addTag( - id: "[#$name](matrix:roomid/${room.metadata?.id.substring(1)}$vias)", - name: - (room.metadata?.canonicalAlias ?? room.metadata?.id) - ?.substring(1) - .split(":") - .first ?? - "", - ); - }, + return ListTile( + leading: AvatarOrHash( + room.metadata?.avatar, + name, + fallback: Icon(Icons.numbers), ), + title: Text(name), + subtitle: room.metadata?.topic == null + ? null + : Text(room.metadata!.topic!, maxLines: 1), + onTap: () { + final vias = ref.watch(ViaController.provider(room)); + addTag( + id: "[#$name](matrix:roomid/${room.metadata?.id.substring(1)}$vias)", + name: + (room.metadata?.canonicalAlias ?? room.metadata?.id) + ?.substring(1) + .split(":") + .first ?? + "", + ); + }, ); }) .toList(), diff --git a/lib/widgets/composer/overlays/tagger_overlay.dart b/lib/widgets/composer/overlays/tagger_overlay.dart index dda9043..7d973dc 100644 --- a/lib/widgets/composer/overlays/tagger_overlay.dart +++ b/lib/widgets/composer/overlays/tagger_overlay.dart @@ -2,6 +2,7 @@ import "package:material_ui/material_ui.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:nexus/widgets/composer/overlays/room_overlay.dart"; import "package:nexus/widgets/composer/overlays/user_overlay.dart"; +import "package:nexus/widgets/composer/overlays/emoji_overlay.dart"; import "package:nexus/widgets/loading.dart"; class const TaggerOverlay( @@ -21,12 +22,16 @@ class const TaggerOverlay( child: Container( color: Theme.of(context).colorScheme.surfaceContainerHigh, padding: .all(8), - child: switch (triggerCharacter) { - "@" => UserOverlay(query, roomId: roomId, addTag: addTag), - "#" => RoomOverlay(query, addTag: addTag), + child: Material( + color: Colors.transparent, + child: switch (triggerCharacter) { + "@" => UserOverlay(query, roomId: roomId, addTag: addTag), + "#" => RoomOverlay(query, addTag: addTag), + ":" => EmojiOverlay(query, roomId: roomId, addTag: addTag), - _ => Loading(), - }, + _ => Loading(), + }, + ), ), ), ); diff --git a/lib/widgets/composer/overlays/user_overlay.dart b/lib/widgets/composer/overlays/user_overlay.dart index ba23c1e..fe4f70f 100644 --- a/lib/widgets/composer/overlays/user_overlay.dart +++ b/lib/widgets/composer/overlays/user_overlay.dart @@ -41,21 +41,18 @@ class const UserOverlay( .map( (member) => switch (member.content) { MembershipContent(:final displayName, :final avatarUrl) => - Material( - color: Colors.transparent, - child: ListTile( - leading: AvatarOrHash( - avatarUrl, - displayName ?? member.stateKey!.localpart, - ), - title: Text( - displayName ?? member.stateKey!.localpart, - ), - subtitle: Text(member.stateKey!), - onTap: () => addTag( - id: "[@$displayName](matrix:u/${member.stateKey!.substring(1)})", - name: member.stateKey!.localpart, - ), + ListTile( + leading: AvatarOrHash( + avatarUrl, + displayName ?? member.stateKey!.localpart, + ), + title: Text( + displayName ?? member.stateKey!.localpart, + ), + subtitle: Text(member.stateKey!), + onTap: () => addTag( + id: "[@$displayName](matrix:u/${member.stateKey!.substring(1)})", + name: member.stateKey!.localpart, ), ), _ => SizedBox.shrink(), From 63183e08247c23b17b98097d76cdf45c8f7e6f90 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 16 Sep 2026 21:59:55 -0400 Subject: [PATCH 115/176] don't init UP on platforms other than Linux or Android --- lib/controllers/unified_push.dart | 2 ++ lib/controllers/unified_push_allowed.dart | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/controllers/unified_push.dart b/lib/controllers/unified_push.dart index 0be46cb..ea8258b 100644 --- a/lib/controllers/unified_push.dart +++ b/lib/controllers/unified_push.dart @@ -21,6 +21,8 @@ import "package:window_manager/window_manager.dart"; class UnifiedPushController extends AsyncNotifier { @override Future build() async { + if (Platform.isLinux ^ Platform.isAndroid) return false; + final client = ref.watch(ClientController.provider.notifier); final registered = await UnifiedPush.initialize( linuxOptions: .new( diff --git a/lib/controllers/unified_push_allowed.dart b/lib/controllers/unified_push_allowed.dart index af50d62..8f7fd8e 100644 --- a/lib/controllers/unified_push_allowed.dart +++ b/lib/controllers/unified_push_allowed.dart @@ -8,11 +8,11 @@ class UnifiedPushAllowedController extends AsyncNotifier { @override Future build() async { if (!await UnifiedPush.tryUseCurrentOrDefaultDistributor()) { - return "No valid distributors found. Try installing ${Platform.isLinux - ? "KUnifiedPush" + return "No valid distributors found. ${Platform.isLinux + ? "Try installing KUnifiedPush" : Platform.isAndroid - ? "Google Play Services or NTFY" - : "NTFY"}."; + ? "Try installing Google Play Services or NTFY" + : "Your platform is not currently supported by UnifiedPush"}."; } final capabilities = await ref From 30b922d390dd31c14a9254fe88b5310d8b6e448c Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 16 Sep 2026 22:03:42 -0400 Subject: [PATCH 116/176] enlarge emojis on emoji overlay --- lib/widgets/composer/overlays/emoji_overlay.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/widgets/composer/overlays/emoji_overlay.dart b/lib/widgets/composer/overlays/emoji_overlay.dart index e537927..0e762c0 100644 --- a/lib/widgets/composer/overlays/emoji_overlay.dart +++ b/lib/widgets/composer/overlays/emoji_overlay.dart @@ -27,7 +27,10 @@ class const EmojiOverlay( ) .map( (emoji) => ListTile( - leading: emoji.widget, + leading: SizedBox.square( + dimension: 28, + child: FittedBox(child: emoji.widget), + ), title: Text(emoji.aliases.first), subtitle: Text(emoji.description), onTap: () => addTag( From 009ba504e30f22703e64c7fd21376403d8905267 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 16 Sep 2026 22:07:00 -0400 Subject: [PATCH 117/176] fixup logic for not init-ing UP An XOR was never the right choice for this --- lib/controllers/unified_push.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/controllers/unified_push.dart b/lib/controllers/unified_push.dart index ea8258b..f637156 100644 --- a/lib/controllers/unified_push.dart +++ b/lib/controllers/unified_push.dart @@ -21,7 +21,7 @@ import "package:window_manager/window_manager.dart"; class UnifiedPushController extends AsyncNotifier { @override Future build() async { - if (Platform.isLinux ^ Platform.isAndroid) return false; + if (!Platform.isLinux && !Platform.isAndroid) return false; final client = ref.watch(ClientController.provider.notifier); final registered = await UnifiedPush.initialize( From 5d62e66cd931d48b142ec50001745f655fdd86cd Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 16 Sep 2026 22:11:36 -0400 Subject: [PATCH 118/176] remove duplicate "Windows EXE" entry in "Try it out" section of README Thanks to @julian45 for spotting this! --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index dfe10f7..9960915 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,6 @@ A simple and user-friendly Matrix client made with Flutter and a Gomuks backend. If you want to try out Nexus, grab one of the following artifacts from CI: - [Android APK](https://nightly.link/Henry-Hiles/nexus/workflows/android/main/APK.zip) -- [Windows EXE](https://nightly.link/Henry-Hiles/nexus/workflows/windows/main/windows-installer.zip) - [Unsigned iOS IPA](https://nightly.link/Henry-Hiles/nexus/workflows/ios/main/Nexus.ipa.zip) - [Unsigned MacOS DMG](https://nightly.link/Henry-Hiles/nexus/workflows/macos/main/nexus.dmg.zip) - [Windows EXE](https://nightly.link/Henry-Hiles/nexus/workflows/windows/main/windows-installer.zip) From 7f7fb451e6f733341d0e4afb99dc5cd4df5e2400 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Thu, 17 Sep 2026 12:09:16 -0400 Subject: [PATCH 119/176] Bump emoji picker to 1.1.1 Better performance now. --- pubspec.lock | 4 ++-- pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 1b0180e..5b72591 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -898,10 +898,10 @@ packages: dependency: "direct main" description: name: material_emoji_picker - sha256: d685f42595f3e2dfeb699d5da53f6576c44ae97da24f2a52f035c26b81d7645e + sha256: feaaf38a4fa4010727dfdb0e05d32c3f49c1162bb7d6103ea808fc157d92a2e0 url: "https://pub.dev" source: hosted - version: "1.0.3" + version: "1.1.1" material_ui: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 6cb2f6e..635c506 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -80,7 +80,7 @@ dependencies: unifiedpush_storage_shared_preferences: 1.0.0 flutter_local_notifications: 22.3.0 flutter_local_notifications_linux: 8.0.1 - material_emoji_picker: 1.0.3 + material_emoji_picker: 1.1.1 dev_dependencies: build_runner: 2.16.1 From f23a35384d8b258bd7ef5f806dee7fbaada84aaf Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Thu, 17 Sep 2026 14:27:51 -0400 Subject: [PATCH 120/176] nicer / less intrusive mention style --- lib/widgets/html/mention_chip.dart | 35 +++++++++++++----------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/lib/widgets/html/mention_chip.dart b/lib/widgets/html/mention_chip.dart index eb10e4b..2387a49 100644 --- a/lib/widgets/html/mention_chip.dart +++ b/lib/widgets/html/mention_chip.dart @@ -40,26 +40,21 @@ class const MentionChip(final String content, final String? roomId, {super.key}) // TODO: Handle summary } }, - child: IgnorePointer( - child: Chip( - label: Text( - 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, - ), - ), - backgroundColor: Theme.of(context).colorScheme.primary, + child: Text( + 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.primary, ), ), ); From cfab803fa03f7ab7cea86264131705fdffddaacc Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Thu, 17 Sep 2026 23:21:33 -0400 Subject: [PATCH 121/176] show timestamps for state events --- lib/widgets/renderers/event.dart | 19 ++++++++++++++----- lib/widgets/renderers/generic_event.dart | 3 ++- lib/widgets/renderers/message.dart | 13 ++----------- lib/widgets/timestamp.dart | 17 +++++++++++++++++ 4 files changed, 35 insertions(+), 17 deletions(-) create mode 100644 lib/widgets/timestamp.dart diff --git a/lib/widgets/renderers/event.dart b/lib/widgets/renderers/event.dart index 7607c2a..46b68eb 100644 --- a/lib/widgets/renderers/event.dart +++ b/lib/widgets/renderers/event.dart @@ -24,6 +24,7 @@ import "package:nexus/widgets/renderers/message.dart"; import "package:nexus/widgets/reaction_row.dart"; import "package:nexus/widgets/renderers/membership.dart"; import "package:nexus/widgets/renderers/generic_event.dart"; +import "package:nexus/widgets/timestamp.dart"; class const EventRenderer( final Event event, { @@ -196,7 +197,18 @@ class const EventRenderer( child: Padding( padding: EdgeInsets.symmetric(horizontal: 8) .copyWith(top: isGrouped ? 0 : 8), - child: child, + child: Row( + mainAxisSize: .min, + spacing: 6, + children: [ + Flexible(child: child), + if (child is! MessageRenderer) + Flexible( + flex: 0, + child: Timestamp(event.timestamp), + ), + ], + ), ), ), ), @@ -204,10 +216,7 @@ class const EventRenderer( ), ...[ - if (event.content is! MessageContent && - event.content is! StickerContent && - event.content is! EncryptedContent) - ReactionRow(event), + if (child is! MessageRenderer) ReactionRow(event), if (event.sendError != null && event.sendError != "not sent") Padding( diff --git a/lib/widgets/renderers/generic_event.dart b/lib/widgets/renderers/generic_event.dart index 88d2db8..eb5b29b 100644 --- a/lib/widgets/renderers/generic_event.dart +++ b/lib/widgets/renderers/generic_event.dart @@ -10,9 +10,10 @@ class const GenericEventRenderer( padding: .symmetric(vertical: 4), child: Row( spacing: 8, + mainAxisSize: .min, children: [ Padding(padding: .symmetric(horizontal: 4), child: Icon(icon)), - Expanded(child: Wrap(spacing: 4, children: children)), + Flexible(child: Wrap(spacing: 4, children: children)), ], ), ); diff --git a/lib/widgets/renderers/message.dart b/lib/widgets/renderers/message.dart index 8631fe2..eff516c 100644 --- a/lib/widgets/renderers/message.dart +++ b/lib/widgets/renderers/message.dart @@ -15,6 +15,7 @@ import "package:nexus/widgets/lazy_loading/message_displayname.dart"; import "package:nexus/widgets/linkified_text.dart"; import "package:nexus/widgets/message_image.dart"; import "package:nexus/widgets/reaction_row.dart"; +import "package:nexus/widgets/timestamp.dart"; import "package:nexus/widgets/url_preview.dart"; import "package:timeago/timeago.dart"; import "package:nexus/widgets/event_preview.dart"; @@ -35,16 +36,6 @@ class const MessageRenderer( final colorScheme = theme.colorScheme; final errorStyle = TextStyle(color: colorScheme.error); - final timestamp = Tooltip( - message: event.timestamp.toString(), - child: Text( - format(event.timestamp), - maxLines: 1, - overflow: .ellipsis, - style: theme.textTheme.labelSmall?.copyWith(color: Colors.grey), - ), - ); - final textStyle = TextStyle( fontSize: event.localContent?.bigEmoji == true ? 32 : null, fontStyle: event.content is EmoteMessageContent ? .italic : null, @@ -70,7 +61,7 @@ class const MessageRenderer( spacing: 4, children: [ Flexible(child: MessageDisplayname(event)), - Flexible(flex: 0, child: timestamp), + Flexible(flex: 0, child: Timestamp(event.timestamp)), ], ), Card( diff --git a/lib/widgets/timestamp.dart b/lib/widgets/timestamp.dart new file mode 100644 index 0000000..bcdabd1 --- /dev/null +++ b/lib/widgets/timestamp.dart @@ -0,0 +1,17 @@ +import "package:flutter/material.dart"; +import "package:timeago/timeago.dart"; + +class const Timestamp(final DateTime timestamp, {super.key}) + extends StatelessWidget { + @override + Widget build(BuildContext context) => Tooltip( + message: timestamp.toString(), + child: Text( + format(timestamp), + maxLines: 1, + overflow: .ellipsis, + style: Theme.of(context).textTheme.labelSmall + ?.copyWith(color: Colors.grey), + ), + ); +} From 57f9498aa3b0bde5f76e13b97ba7b6e5bb67cb08 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Fri, 18 Sep 2026 09:58:49 -0400 Subject: [PATCH 122/176] better wrapping behavior for timestamps on state events --- lib/widgets/renderers/event.dart | 12 +++++------- lib/widgets/renderers/message.dart | 1 - 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/lib/widgets/renderers/event.dart b/lib/widgets/renderers/event.dart index 46b68eb..8e7373a 100644 --- a/lib/widgets/renderers/event.dart +++ b/lib/widgets/renderers/event.dart @@ -197,16 +197,14 @@ class const EventRenderer( child: Padding( padding: EdgeInsets.symmetric(horizontal: 8) .copyWith(top: isGrouped ? 0 : 8), - child: Row( - mainAxisSize: .min, + child: Wrap( + verticalDirection: .up, spacing: 6, + crossAxisAlignment: .center, children: [ - Flexible(child: child), + child, if (child is! MessageRenderer) - Flexible( - flex: 0, - child: Timestamp(event.timestamp), - ), + Timestamp(event.timestamp), ], ), ), diff --git a/lib/widgets/renderers/message.dart b/lib/widgets/renderers/message.dart index eff516c..99c3141 100644 --- a/lib/widgets/renderers/message.dart +++ b/lib/widgets/renderers/message.dart @@ -17,7 +17,6 @@ import "package:nexus/widgets/message_image.dart"; import "package:nexus/widgets/reaction_row.dart"; import "package:nexus/widgets/timestamp.dart"; import "package:nexus/widgets/url_preview.dart"; -import "package:timeago/timeago.dart"; import "package:nexus/widgets/event_preview.dart"; import "package:nexus/widgets/players/video.dart"; import "package:nexus/widgets/players/audio.dart"; From 73c4a7d07fdf112b800b86f154e537f8153e3c99 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Fri, 18 Sep 2026 10:57:16 -0400 Subject: [PATCH 123/176] don't invalidate UP controller --- lib/controllers/unified_push.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/controllers/unified_push.dart b/lib/controllers/unified_push.dart index f637156..47354ad 100644 --- a/lib/controllers/unified_push.dart +++ b/lib/controllers/unified_push.dart @@ -103,7 +103,7 @@ class UnifiedPushController extends AsyncNotifier { await ref .watch(PushKeyController.provider(instance).notifier) .set(null); - ref.invalidateSelf(); + state = .data(false); }, ); @@ -139,7 +139,7 @@ class UnifiedPushController extends AsyncNotifier { vapid: capabilities.webpush?.vapid, ); - if (!alreadyRegistered) ref.invalidateSelf(); + state = .data(true); } Future deregister() async { @@ -157,7 +157,7 @@ class UnifiedPushController extends AsyncNotifier { } await UnifiedPush.unregister(clientState.deviceId!); - ref.invalidateSelf(); + state = .data(false); } static final provider = AsyncNotifierProvider( From a9d2ccbcd19b5825802f06ccecfc6d8f2efb3894 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Fri, 18 Sep 2026 13:02:40 -0400 Subject: [PATCH 124/176] bump gradle --- android/gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 76d4386d..5fadfe8 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.0-all.zip From 85bb653980ba0b69da6b999f9bf31e661c3d913a Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Fri, 18 Sep 2026 15:39:45 -0400 Subject: [PATCH 125/176] fix gomuks init on android / ios --- lib/controllers/client.dart | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/lib/controllers/client.dart b/lib/controllers/client.dart index 931c023..a535b1e 100644 --- a/lib/controllers/client.dart +++ b/lib/controllers/client.dart @@ -54,17 +54,8 @@ import "package:path_provider/path_provider.dart"; class ClientController extends AsyncNotifier { @override Future build() async { - final handle = await Isolate.run(() async { - final Pointer root; - if (Platform.isAndroid || Platform.isIOS) { - final dir = await getApplicationSupportDirectory(); - root = "${dir.path}/gomuks".toNativeUtf8().cast(); - } else { - root = nullptr.cast(); - } - - return GomuksInit(root); - }); + final path = "${(await getApplicationSupportDirectory()).path}/gomuks"; + final handle = await init(path); final callable = NativeCallable< @@ -161,6 +152,13 @@ class ClientController extends AsyncNotifier { throw Exception("GomuksStart returned error code $errorCode"); } + Future init(String path) => Isolate.run( + () => GomuksInit( + ((Platform.isAndroid || Platform.isIOS) ? path.toNativeUtf8() : nullptr) + .cast(), + ), + ); + Future callGomuksMethod( Map data, FutureOr Function(int handle, GomuksBorrowedBuffer data) From 4f3b77f9f35cb4226fd0b4bbb9578ba4e1f4f7a8 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 19 Sep 2026 18:41:09 -0400 Subject: [PATCH 126/176] set env for gomuks Fixes #62 --- .gitmodules | 4 ++-- gomuks | 2 +- lib/controllers/client.dart | 22 +++++++++++++--------- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/.gitmodules b/.gitmodules index 145276a..0cecb0c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "gomuks"] path = gomuks - url = https://github.com/gomuks/gomuks - branch = main + url = https://github.com/Henry-Hiles/gomuks + branch = quad/chore/remove-root-set diff --git a/gomuks b/gomuks index 0e06c7b..9e45ee4 160000 --- a/gomuks +++ b/gomuks @@ -1 +1 @@ -Subproject commit 0e06c7b74f96d3e29a8101893ca1921d13a90573 +Subproject commit 9e45ee426cc8be0bfada269f4abc4957c30e994e diff --git a/lib/controllers/client.dart b/lib/controllers/client.dart index a535b1e..ee4e0a0 100644 --- a/lib/controllers/client.dart +++ b/lib/controllers/client.dart @@ -54,8 +54,19 @@ import "package:path_provider/path_provider.dart"; class ClientController extends AsyncNotifier { @override Future build() async { - final path = "${(await getApplicationSupportDirectory()).path}/gomuks"; - final handle = await init(path); + if (Platform.isAndroid || Platform.isIOS) { + final env = { + "GOMUKS_ROOT": (await getApplicationSupportDirectory()).path, + "GOMUKS_CACHE_HOME": (await getApplicationCacheDirectory()).path, + }; + for (final MapEntry(:key, :value) in env.entries) { + GomuksSetEnv( + key.toNativeUtf8().cast(), + value.toNativeUtf8().cast(), + ); + } + } + final handle = await Isolate.run(GomuksInit); final callable = NativeCallable< @@ -152,13 +163,6 @@ class ClientController extends AsyncNotifier { throw Exception("GomuksStart returned error code $errorCode"); } - Future init(String path) => Isolate.run( - () => GomuksInit( - ((Platform.isAndroid || Platform.isIOS) ? path.toNativeUtf8() : nullptr) - .cast(), - ), - ); - Future callGomuksMethod( Map data, FutureOr Function(int handle, GomuksBorrowedBuffer data) From 650c62fb99b238fbe402eaddfd5eefa7dc4c0241 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 19 Sep 2026 18:45:05 -0400 Subject: [PATCH 127/176] update gomuks hash --- linux/nix/pkg/gomuks.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/nix/pkg/gomuks.nix b/linux/nix/pkg/gomuks.nix index 0516f31..f2dd5ab 100644 --- a/linux/nix/pkg/gomuks.nix +++ b/linux/nix/pkg/gomuks.nix @@ -17,7 +17,7 @@ buildGoModule ( src = "${src}/gomuks"; - vendorHash = "sha256-9CS/lAVT8gLWACLomwcEa8YNlAXvBOskPPx4zERg0wQ="; + vendorHash = "sha256-bAjUVgN9eHilA/21OkIcMh1a4ywL+Oqrj1JloeDufu0="; buildPhase = '' runHook preBuild From 673c5bd894b666ef56f076219ebfd632ff3b4bbb Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 19 Sep 2026 21:13:03 -0400 Subject: [PATCH 128/176] fix memory leaks Oops! They were pretty slow, but still adds up. This might fix the bug that was stopping Nexus from working on GraphineOS. --- gomuks | 2 +- lib/controllers/client.dart | 25 +++++++++++++++---------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/gomuks b/gomuks index 9e45ee4..c200702 160000 --- a/gomuks +++ b/gomuks @@ -1 +1 @@ -Subproject commit 9e45ee426cc8be0bfada269f4abc4957c30e994e +Subproject commit c20070298d450cc02f465a503a5a52fea74af0d5 diff --git a/lib/controllers/client.dart b/lib/controllers/client.dart index ee4e0a0..cf49373 100644 --- a/lib/controllers/client.dart +++ b/lib/controllers/client.dart @@ -60,10 +60,12 @@ class ClientController extends AsyncNotifier { "GOMUKS_CACHE_HOME": (await getApplicationCacheDirectory()).path, }; for (final MapEntry(:key, :value) in env.entries) { - GomuksSetEnv( - key.toNativeUtf8().cast(), - value.toNativeUtf8().cast(), - ); + final keyPtr = key.toNativeUtf8().cast(); + final valuePtr = value.toNativeUtf8().cast(); + GomuksSetEnv(keyPtr, valuePtr); + calloc + ..free(keyPtr) + ..free(valuePtr); } } final handle = await Isolate.run(GomuksInit); @@ -193,14 +195,17 @@ class ClientController extends AsyncNotifier { return response == null ? null : .fromJson(response); } - Future _sendCommand( + dynamic _sendCommand( String command, [ Map data = const {}, - ]) => callGomuksMethod( - data, - (handle, data) async => - GomuksSubmitCommand(handle, command.toNativeUtf8().cast(), data), - ); + ]) => callGomuksMethod(data, (handle, data) { + final commandPointer = command.toNativeUtf8().cast(); + try { + return GomuksSubmitCommand(handle, commandPointer, data); + } finally { + calloc.free(commandPointer); + } + }); Future redactEvent(RedactEventRequest report) => _sendCommand("redact_event", report.toJson()); From 8b7e29ae334785cbd846369257033885887552a7 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sat, 19 Sep 2026 22:41:13 -0400 Subject: [PATCH 129/176] Set device name to "Nexus on $platform" Fixes #86. --- .gitmodules | 2 +- gomuks | 2 +- lib/controllers/client.dart | 13 ++++++++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 0cecb0c..627b6b0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "gomuks"] path = gomuks url = https://github.com/Henry-Hiles/gomuks - branch = quad/chore/remove-root-set + branch = quad/feat/customizable-device-name diff --git a/gomuks b/gomuks index c200702..ae11daa 160000 --- a/gomuks +++ b/gomuks @@ -1 +1 @@ -Subproject commit c20070298d450cc02f465a503a5a52fea74af0d5 +Subproject commit ae11daa1b14b103688e57accb9c65ad6401cb3ef diff --git a/lib/controllers/client.dart b/lib/controllers/client.dart index cf49373..cd1fa13 100644 --- a/lib/controllers/client.dart +++ b/lib/controllers/client.dart @@ -7,6 +7,7 @@ import "dart:math"; import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:ffi/ffi.dart"; import "package:flutter/foundation.dart"; +import "package:intl/intl.dart"; import "package:nexus/controllers/account_data.dart"; import "package:nexus/controllers/client_state.dart"; import "package:nexus/controllers/init_complete.dart"; @@ -68,7 +69,17 @@ class ClientController extends AsyncNotifier { ..free(valuePtr); } } - final handle = await Isolate.run(GomuksInit); + final handle = await Isolate.run(() { + final message = + "Nexus on ${toBeginningOfSentenceCase(Platform.operatingSystem)}" + .toNativeUtf8() + .cast(); + try { + return GomuksInit(message); + } finally { + calloc.free(message); + } + }); final callable = NativeCallable< From 87e7e093f7967cb70d64effeef00b9c0cba0242b Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sun, 20 Sep 2026 00:02:49 -0400 Subject: [PATCH 130/176] Revert "don't invalidate UP controller" This reverts commit 73c4a7d07fdf112b800b86f154e537f8153e3c99. --- lib/controllers/unified_push.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/controllers/unified_push.dart b/lib/controllers/unified_push.dart index 47354ad..f637156 100644 --- a/lib/controllers/unified_push.dart +++ b/lib/controllers/unified_push.dart @@ -103,7 +103,7 @@ class UnifiedPushController extends AsyncNotifier { await ref .watch(PushKeyController.provider(instance).notifier) .set(null); - state = .data(false); + ref.invalidateSelf(); }, ); @@ -139,7 +139,7 @@ class UnifiedPushController extends AsyncNotifier { vapid: capabilities.webpush?.vapid, ); - state = .data(true); + if (!alreadyRegistered) ref.invalidateSelf(); } Future deregister() async { @@ -157,7 +157,7 @@ class UnifiedPushController extends AsyncNotifier { } await UnifiedPush.unregister(clientState.deviceId!); - state = .data(false); + ref.invalidateSelf(); } static final provider = AsyncNotifierProvider( From d7c64fea808a21a098a45ba686c6b6e8368e4a2b Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sun, 20 Sep 2026 00:04:50 -0400 Subject: [PATCH 131/176] potentially fix notifs on flatpak --- flake.lock | 11 ++++++----- flake.nix | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/flake.lock b/flake.lock index 3544dd7..b3e4531 100644 --- a/flake.lock +++ b/flake.lock @@ -42,15 +42,16 @@ "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1774860670, - "narHash": "sha256-YjJkQrvxrErXtfDi3obUn6rNmkA+CIAZ3f5NgL5xuYE=", - "owner": "neobrain", + "lastModified": 1789876218, + "narHash": "sha256-/sUFGNLvcwf9MxGw+QS24o1bg217fQRY9NpinlmSjH4=", + "owner": "Henry-Hiles", "repo": "nix2flatpak", - "rev": "61d68e21e3fbc2d57590051f48736bea271f4aba", + "rev": "8264b886c1e64bffc172c49e9dfcb551cbd863f4", "type": "github" }, "original": { - "owner": "neobrain", + "owner": "Henry-Hiles", + "ref": "quad/fix/names", "repo": "nix2flatpak", "type": "github" } diff --git a/flake.nix b/flake.nix index c1502f0..2f55b83 100644 --- a/flake.nix +++ b/flake.nix @@ -5,7 +5,7 @@ self.submodules = true; nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; flake-parts.url = "github:hercules-ci/flake-parts"; - nix2flatpak.url = "github:neobrain/nix2flatpak"; + nix2flatpak.url = "github:Henry-Hiles/nix2flatpak/quad/fix/names"; }; outputs = From 3fee789c90b68a7daa1ab632c5ce1413e07cf2c2 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sun, 20 Sep 2026 00:07:47 -0400 Subject: [PATCH 132/176] fixup flatpak perms --- flake.nix | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/flake.nix b/flake.nix index 2f55b83..0eedbe2 100644 --- a/flake.nix +++ b/flake.nix @@ -63,12 +63,10 @@ "wayland" ]; - talk-names = [ "org.unifiedpush.Distributor.*" ]; - own-names = [ - "nexus.federated.nexus" - "nexus.federated.nexus.*" + talk-names = [ + "org.unifiedpush.Distributor.*" + "org.freedesktop.Notifications" ]; - devices = [ "dri" ]; }; }; From 3d690c26d8915a4ef7a4bf8977effe4eaf0d0465 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sun, 20 Sep 2026 13:27:47 -0400 Subject: [PATCH 133/176] hopefully fixup UP on linux when backgrounded --- lib/controllers/unified_push.dart | 1 + lib/main.dart | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/controllers/unified_push.dart b/lib/controllers/unified_push.dart index f637156..b9af5b2 100644 --- a/lib/controllers/unified_push.dart +++ b/lib/controllers/unified_push.dart @@ -68,6 +68,7 @@ class UnifiedPushController extends AsyncNotifier { await windowManager.isFocused().onError((_, _) => false) && ref.watch(KeyController.provider(KeyController.roomKey)) == event.roomId)) { + if (isInBackground) exit(0); return; } diff --git a/lib/main.dart b/lib/main.dart index 80c2649..58289f0 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -88,7 +88,13 @@ void main(List args) async { FlutterError.onError = (FlutterErrorDetails details) => showError(details.exception.toString(), details.stack); - if (!isInBackground) { + if (isInBackground) { + await ProviderContainer().read(UnifiedPushController.provider.future); + + // In case it didn't exit for some reason + await Future.delayed(Duration(seconds: 20)); + exit(0); + } else { runApp( ProviderScope( retry: (_, _) => null, From 0d1ace3fd051bc3cdd5429a194f7a7b41b06a2ae Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sun, 20 Sep 2026 13:41:22 -0400 Subject: [PATCH 134/176] add more logs for notifs --- lib/controllers/notification.dart | 1 + lib/controllers/unified_push.dart | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/controllers/notification.dart b/lib/controllers/notification.dart index 7996a47..abef40c 100644 --- a/lib/controllers/notification.dart +++ b/lib/controllers/notification.dart @@ -83,6 +83,7 @@ class NotificationController File? icon, String? payload, }) async { + debugPrint("Sending notification for $id"); final notificationDetails = NotificationDetails( android: .new( "messages", diff --git a/lib/controllers/unified_push.dart b/lib/controllers/unified_push.dart index b9af5b2..9575804 100644 --- a/lib/controllers/unified_push.dart +++ b/lib/controllers/unified_push.dart @@ -53,6 +53,7 @@ class UnifiedPushController extends AsyncNotifier { ); }, onMessage: (message, instance) async { + debugPrint("UP message received for $instance"); if (message.decrypted == false) { throw Exception( "Failed to decrypt notification. Try toggling off and on UnifiedPush in settings.", From e8fb3a85239bd336a6522dd5707264f9de6ee3ca Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sun, 20 Sep 2026 15:45:32 -0400 Subject: [PATCH 135/176] use SharedPreferencesAsync to avoid race condition in Sharedprefs This was so painful to debug... --- .vscode/launch.json | 17 +++++++++++++++++ lib/controllers/key.dart | 16 ++++++++-------- lib/controllers/member_list_opened.dart | 20 +++++++++----------- lib/controllers/push_key.dart | 13 +++++++------ lib/controllers/shared_prefs.dart | 6 +++--- lib/controllers/unified_push.dart | 13 ++++++++----- lib/main.dart | 16 +++++++++------- lib/pages/chat.dart | 4 +++- lib/widgets/room_chat.dart | 4 +++- lib/widgets/sidebar.dart | 4 ++-- 10 files changed, 69 insertions(+), 44 deletions(-) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..b83039c --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,17 @@ +{ + "configurations": [ + { + "name": "Flutter", + "type": "dart", + "request": "launch", + "program": "lib/main.dart" + }, + { + "name": "Flutter (Headless)", + "type": "dart", + "request": "launch", + "program": "lib/main.dart", + "env": { "FLUTTER_HEADLESS": "1" } + } + ] +} diff --git a/lib/controllers/key.dart b/lib/controllers/key.dart index 0d02d17..77b4883 100644 --- a/lib/controllers/key.dart +++ b/lib/controllers/key.dart @@ -1,28 +1,28 @@ import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/controllers/shared_prefs.dart"; -class KeyController(final String key) extends Notifier { +class KeyController(final String key) extends AsyncNotifier { static const String spaceKey = "space"; static const String roomKey = "room"; static const String pushKeyKey = "pushKey"; @override - String? build() => - ref.watch(SharedPrefsController.provider).requireValue.getString(key); + Future build() => + ref.watch(SharedPrefsController.provider).getString(key); Future set(String? value) async { - final prefs = ref.watch(SharedPrefsController.provider).requireValue; - state = value; + final prefs = ref.watch(SharedPrefsController.provider); + state = .data(value); if (value == null) { - prefs.remove(key); + await prefs.remove(key); } else { - prefs.setString(key, value); + await prefs.setString(key, value); } } static final provider = - NotifierProvider.family( + AsyncNotifierProvider.family( KeyController.new, ); } diff --git a/lib/controllers/member_list_opened.dart b/lib/controllers/member_list_opened.dart index e3509f0..f0295d8 100644 --- a/lib/controllers/member_list_opened.dart +++ b/lib/controllers/member_list_opened.dart @@ -1,22 +1,20 @@ import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/controllers/shared_prefs.dart"; -class MemberListOpenedController extends Notifier { +class MemberListOpenedController extends AsyncNotifier { static const String key = "memberListOpened"; @override - bool build() => - ref.watch(SharedPrefsController.provider).requireValue.getBool(key) ?? - true; + Future build() async => + await ref.watch(SharedPrefsController.provider).getBool(key) ?? true; Future set(bool value) async { - final prefs = ref.watch(SharedPrefsController.provider).requireValue; - state = value; - - prefs.setBool(key, value); + state = .data(value); + await ref.watch(SharedPrefsController.provider).setBool(key, value); } - static final provider = NotifierProvider( - MemberListOpenedController.new, - ); + static final provider = + AsyncNotifierProvider( + MemberListOpenedController.new, + ); } diff --git a/lib/controllers/push_key.dart b/lib/controllers/push_key.dart index 7217886..e3f6b82 100644 --- a/lib/controllers/push_key.dart +++ b/lib/controllers/push_key.dart @@ -4,18 +4,19 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/controllers/key.dart"; -class PushKeyController(final String instance) extends Notifier { +class PushKeyController(final String instance) extends AsyncNotifier { @override - String? build() => json.decode( - ref.watch(KeyController.provider(KeyController.pushKeyKey)) ?? "{}", + Future build() async => json.decode( + await ref.watch(KeyController.provider(KeyController.pushKeyKey).future) ?? + "{}", )[instance]; Future set(String? value) async { final provider = KeyController.provider(KeyController.pushKeyKey); final notifier = ref.watch(provider.notifier); - final prefs = IMap(json.decode(ref.watch(provider) ?? "{}")); + final prefs = IMap(json.decode(await ref.watch(provider.future) ?? "{}")); - state = value; + state = .data(value); notifier.set( json.encode( prefs.add(instance, value).where((_, value) => value != null).unlock, @@ -24,7 +25,7 @@ class PushKeyController(final String instance) extends Notifier { } static final provider = - NotifierProvider.family( + AsyncNotifierProvider.family( PushKeyController.new, ); } diff --git a/lib/controllers/shared_prefs.dart b/lib/controllers/shared_prefs.dart index 876fc47..9ecb34a 100644 --- a/lib/controllers/shared_prefs.dart +++ b/lib/controllers/shared_prefs.dart @@ -1,12 +1,12 @@ import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:shared_preferences/shared_preferences.dart"; -class SharedPrefsController extends AsyncNotifier { +class SharedPrefsController extends Notifier { @override - Future build() async => .getInstance(); + SharedPreferencesAsync build() => SharedPreferencesAsync(); static final provider = - AsyncNotifierProvider( + NotifierProvider( SharedPrefsController.new, ); } diff --git a/lib/controllers/unified_push.dart b/lib/controllers/unified_push.dart index 9575804..bc5f6e1 100644 --- a/lib/controllers/unified_push.dart +++ b/lib/controllers/unified_push.dart @@ -13,7 +13,6 @@ import "package:nexus/controllers/client.dart"; import "package:nexus/controllers/client_state.dart"; import "package:nexus/models/content/message.dart"; import "package:nexus/models/content/sticker.dart"; -import "package:nexus/models/requests/register_pusher.dart"; import "package:unifiedpush/unifiedpush.dart"; import "package:unifiedpush_storage_shared_preferences/storage.dart"; import "package:window_manager/window_manager.dart"; @@ -40,8 +39,8 @@ class UnifiedPushController extends AsyncNotifier { .new( appDisplayName: "Nexus", appId: "nexus.federated.nexus", - data: PusherData.webPush( - url: Uri.parse(endpoint.url), + data: .webPush( + url: .parse(endpoint.url), auth: endpoint.pubKeySet!.auth, ), deviceDisplayName: @@ -67,7 +66,9 @@ class UnifiedPushController extends AsyncNotifier { event.unreadType?.shouldNotify() != true || (!isInBackground && await windowManager.isFocused().onError((_, _) => false) && - ref.watch(KeyController.provider(KeyController.roomKey)) == + await ref.watch( + KeyController.provider(KeyController.roomKey).future, + ) == event.roomId)) { if (isInBackground) exit(0); return; @@ -146,7 +147,9 @@ class UnifiedPushController extends AsyncNotifier { Future deregister() async { final clientState = ref.watch(ClientStateController.provider); - final key = ref.watch(PushKeyController.provider(clientState!.deviceId!)); + final key = await ref.watch( + PushKeyController.provider(clientState!.deviceId!).future, + ); if (key != null) { await ref diff --git a/lib/main.dart b/lib/main.dart index 58289f0..05b840f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,10 +7,11 @@ import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:media_kit/media_kit.dart"; import "package:nexus/controllers/client.dart"; import "package:nexus/controllers/client_state.dart"; +import "package:nexus/controllers/key.dart"; +import "package:nexus/controllers/member_list_opened.dart"; import "package:nexus/controllers/multi_provider.dart"; import "package:nexus/controllers/notification.dart"; import "package:nexus/controllers/settings.dart"; -import "package:nexus/controllers/shared_prefs.dart"; import "package:nexus/controllers/unified_push.dart"; import "package:nexus/helpers/extensions/better_when.dart"; import "package:nexus/helpers/extensions/scheme_to_theme.dart"; @@ -81,9 +82,9 @@ void main(List args) async { await windowManager.setMinimumSize(Size.square(500)); } - isInBackground = args.contains("--unifiedpush-bg"); + isInBackground = Platform.environment["FLUTTER_HEADLESS"] != null; - LicenseRegistry.addLicense(() => Stream.fromIterable(fontLicenses)); + LicenseRegistry.addLicense(() => .fromIterable(fontLicenses)); FlutterError.onError = (FlutterErrorDetails details) => showError(details.exception.toString(), details.stack); @@ -103,14 +104,13 @@ void main(List args) async { // ignore: dead_code if (false && kDebugMode) Logger(), ], - child: App(isInBackground), + child: App(), ), ); } } -class const App(final bool isInBackground, {super.key}) - extends StatelessWidget { +class const App({super.key}) extends StatelessWidget { @override Widget build(BuildContext context) => DynamicColorBuilder( builder: (lightDynamic, darkDynamic) => Consumer( @@ -151,10 +151,12 @@ class const App(final bool isInBackground, {super.key}) .watch( MultiProviderController.provider( IListConst([ - SharedPrefsController.provider, ClientController.provider, NotificationController.provider, UnifiedPushController.provider, + MemberListOpenedController.provider, + KeyController.provider(KeyController.roomKey), + KeyController.provider(KeyController.spaceKey), ]), ), ) diff --git a/lib/pages/chat.dart b/lib/pages/chat.dart index 9469c91..fb165d3 100644 --- a/lib/pages/chat.dart +++ b/lib/pages/chat.dart @@ -14,7 +14,9 @@ class const ChatPage({super.key}) extends ConsumerWidget { final isDesktop = constraints.maxWidth > 650; final showMembersByDefault = constraints.maxWidth > 1000; final initComplete = ref.watch(InitCompleteController.provider); - final roomId = ref.watch(KeyController.provider(KeyController.roomKey)); + final roomId = ref + .watch(KeyController.provider(KeyController.roomKey)) + .requireValue; return SafeArea( child: Scaffold( diff --git a/lib/widgets/room_chat.dart b/lib/widgets/room_chat.dart index 015bbc4..d8424c9 100644 --- a/lib/widgets/room_chat.dart +++ b/lib/widgets/room_chat.dart @@ -43,7 +43,9 @@ final class const RoomChat({ final composerSize = useState(64); final userId = ref.watch(ClientStateController.provider)?.userId; - final memberListOpened = ref.watch(MemberListOpenedController.provider); + final memberListOpened = ref + .watch(MemberListOpenedController.provider) + .requireValue; final theme = Theme.of(context); final nothing = Center( diff --git a/lib/widgets/sidebar.dart b/lib/widgets/sidebar.dart index c2a0170..b2d8295 100644 --- a/lib/widgets/sidebar.dart +++ b/lib/widgets/sidebar.dart @@ -23,13 +23,13 @@ class const Sidebar({required final bool isDesktop, super.key}) final selectedSpaceProvider = KeyController.provider( KeyController.spaceKey, ); - final selectedSpaceId = ref.watch(selectedSpaceProvider); + final selectedSpaceId = ref.watch(selectedSpaceProvider).requireValue; final selectedSpaceIdNotifier = ref.watch(selectedSpaceProvider.notifier); final selectedRoomController = KeyController.provider( KeyController.roomKey, ); - final selectedRoomId = ref.watch(selectedRoomController); + final selectedRoomId = ref.watch(selectedRoomController).requireValue; final selectedRoomIdNotifier = ref.watch(selectedRoomController.notifier); final spaces = ref.watch(SpacesController.provider); From b3023d8147dba9cd62c0cd38951043c2fdd21c29 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sun, 20 Sep 2026 17:00:10 -0400 Subject: [PATCH 136/176] don't auto create dbus service --- lib/controllers/unified_push.dart | 1 + pubspec.lock | 24 +++++++++++++----------- pubspec.yaml | 10 ++++++++++ 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/lib/controllers/unified_push.dart b/lib/controllers/unified_push.dart index bc5f6e1..ae31cac 100644 --- a/lib/controllers/unified_push.dart +++ b/lib/controllers/unified_push.dart @@ -28,6 +28,7 @@ class UnifiedPushController extends AsyncNotifier { dbusName: "nexus.federated.nexus.UnifiedPush", storage: UnifiedPushStorageSharedPreferences(), background: isInBackground, + shouldWriteService: false, ), onNewEndpoint: (endpoint, instance) async { final pushKey = endpoint.pubKeySet!.pubKey; diff --git a/pubspec.lock b/pubspec.lock index 5b72591..a914165 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1501,20 +1501,22 @@ packages: source: hosted version: "3.5.0" unifiedpush_linux: - dependency: transitive + dependency: "direct overridden" description: - name: unifiedpush_linux - sha256: c062d5eedd1cec70bcd33270cc4e01ae0ff6501f33d471167c06b34a968adfeb - url: "https://pub.dev" - source: hosted - version: "1.0.0" + path: unifiedpush_linux + ref: "quad/feat/should-write-service-option" + resolved-ref: "7589b07ef4280820e4adea165d3d86b219f6022c" + url: "https://codeberg.org/Henry-Hiles/flutter-connector" + source: git + version: "1.0.1" unifiedpush_platform_interface: - dependency: transitive + dependency: "direct overridden" description: - name: unifiedpush_platform_interface - sha256: "83372bc8d794b8b12ef6993b518d7be907dcfc2191bdf6de0ece5c4445d89880" - url: "https://pub.dev" - source: hosted + path: unifiedpush_platform_interface + ref: "quad/feat/should-write-service-option" + resolved-ref: "7589b07ef4280820e4adea165d3d86b219f6022c" + url: "https://codeberg.org/Henry-Hiles/flutter-connector" + source: git version: "4.0.0" unifiedpush_storage_interface: dependency: transitive diff --git a/pubspec.yaml b/pubspec.yaml index 635c506..332efaf 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -20,6 +20,16 @@ environment: dependency_overrides: dynamic_color: 2.1.0 + unifiedpush_linux: + git: + url: https://codeberg.org/Henry-Hiles/flutter-connector + ref: quad/feat/should-write-service-option + path: unifiedpush_linux + unifiedpush_platform_interface: + git: + url: https://codeberg.org/Henry-Hiles/flutter-connector + ref: quad/feat/should-write-service-option + path: unifiedpush_platform_interface path_provider_android: 2.2.23 # Pinned to avoid JNI linkify: git: From 1cfea5a8196d65b8134b65c780a181a501714813 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sun, 20 Sep 2026 17:13:22 -0400 Subject: [PATCH 137/176] add nix module --- flake.nix | 57 +----------------- lib/controllers/unified_push.dart | 2 +- .../nexus.federated.nexus.UnifiedPush.service | 3 + linux/nix/default.nix | 59 +++++++++++++++++++ linux/nix/module.nix | 55 +++++++++++++++++ linux/nix/pkg/default.nix | 1 + 6 files changed, 120 insertions(+), 57 deletions(-) create mode 100644 linux/nexus.federated.nexus.UnifiedPush.service create mode 100644 linux/nix/default.nix create mode 100644 linux/nix/module.nix diff --git a/flake.nix b/flake.nix index 0eedbe2..91614b5 100644 --- a/flake.nix +++ b/flake.nix @@ -16,67 +16,12 @@ ... }@inputs: flake-parts.lib.mkFlake { inherit inputs; } { + imports = [ ./linux/nix ]; systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" "x86_64-darwin" ]; - - perSystem = - { - lib, - pkgs, - system, - ... - }: - - { - _module.args.pkgs = import nixpkgs { - inherit system; - config = { - android_sdk.accept_license = true; - allowUnfree = true; - }; - }; - - packages = - let - default = pkgs.callPackage ./linux/nix/pkg { - src = self; - }; - in - { - inherit default; - - flatpak = inputs.nix2flatpak.lib.${system}.mkFlatpak { - appName = "Nexus"; - developer = "QuadRadical"; - appId = "nexus.federated.nexus"; - package = default; - runtime = "org.gnome.Platform/49"; - permissions = { - share = [ "network" ]; - sockets = [ - "pulseaudio" - "fallback-x11" - "wayland" - ]; - - talk-names = [ - "org.unifiedpush.Distributor.*" - "org.freedesktop.Notifications" - ]; - devices = [ "dri" ]; - }; - }; - - gomuks = pkgs.callPackage ./linux/nix/pkg/gomuks.nix { - src = self; - }; - }; - - devShells.default = pkgs.callPackage ./linux/nix/devshell.nix { }; - }; }; } diff --git a/lib/controllers/unified_push.dart b/lib/controllers/unified_push.dart index ae31cac..1016053 100644 --- a/lib/controllers/unified_push.dart +++ b/lib/controllers/unified_push.dart @@ -28,7 +28,7 @@ class UnifiedPushController extends AsyncNotifier { dbusName: "nexus.federated.nexus.UnifiedPush", storage: UnifiedPushStorageSharedPreferences(), background: isInBackground, - shouldWriteService: false, + shouldWriteService: true, ), onNewEndpoint: (endpoint, instance) async { final pushKey = endpoint.pubKeySet!.pubKey; diff --git a/linux/nexus.federated.nexus.UnifiedPush.service b/linux/nexus.federated.nexus.UnifiedPush.service new file mode 100644 index 0000000..663ab9b --- /dev/null +++ b/linux/nexus.federated.nexus.UnifiedPush.service @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=nexus.federated.nexus.UnifiedPush +Exec=/usr/bin/env FLUTTER_HEADLESS=1 nexus diff --git a/linux/nix/default.nix b/linux/nix/default.nix new file mode 100644 index 0000000..756eb0b --- /dev/null +++ b/linux/nix/default.nix @@ -0,0 +1,59 @@ +{ self, inputs, ... }: { + + perSystem = + { + pkgs, + system, + lib, + ... + }: + { + _module.args.pkgs = import inputs.nixpkgs { + inherit system; + config = { + android_sdk.accept_license = true; + allowUnfree = true; + }; + }; + + packages = + let + default = pkgs.callPackage ./pkg { + src = self; + }; + in + { + inherit default; + + flatpak = inputs.nix2flatpak.lib.${system}.mkFlatpak { + appName = "Nexus"; + developer = "QuadRadical"; + appId = "nexus.federated.nexus"; + package = default; + runtime = "org.gnome.Platform/49"; + permissions = { + share = [ "network" ]; + sockets = [ + "pulseaudio" + "fallback-x11" + "wayland" + ]; + + talk-names = [ + "org.unifiedpush.Distributor.*" + "org.freedesktop.Notifications" + ]; + devices = [ "dri" ]; + }; + }; + + gomuks = pkgs.callPackage ./pkg/gomuks.nix { + src = self; + }; + }; + + devShells.default = pkgs.callPackage ./devshell.nix { }; + }; + + flake.nixosModules.default = import ./module.nix self; +} diff --git a/linux/nix/module.nix b/linux/nix/module.nix new file mode 100644 index 0000000..f901007 --- /dev/null +++ b/linux/nix/module.nix @@ -0,0 +1,55 @@ +self: +{ + pkgs, + lib, + config, + ... +}: + +let + inherit (lib) + mkIf + mkMerge + mkOption + mkEnableOption + mkPackageOption + types + ; + + cfg = config.programs.nexus; +in +{ + options.programs.nexus = { + enable = mkEnableOption "Nexus, a simple and user-friendly Matrix client"; + package = mkPackageOption self.packages.${pkgs.stdenv.hostPlatform.system} "nexus" { }; + + enableNotifications = mkOption { + description = '' + Whether to enable push notifications support via UnifiedPush, installing + {manpage}`kunifiedpush` and registering its systemd and D-Bus units. + ''; + type = types.bool; + default = false; + example = true; + }; + }; + + config = mkIf cfg.enable (mkMerge [ + { + environment.systemPackages = [ cfg.package ]; + } + (mkIf cfg.enableNotifications { + environment.systemPackages = [ + pkgs.kdePackages.kunifiedpush + ]; + + systemd.packages = [ + pkgs.kdePackages.kunifiedpush + ]; + + services.dbus.packages = [ + cfg.package + ]; + }) + ]); +} diff --git a/linux/nix/pkg/default.nix b/linux/nix/pkg/default.nix index 1114d43..cf1b107 100644 --- a/linux/nix/pkg/default.nix +++ b/linux/nix/pkg/default.nix @@ -37,6 +37,7 @@ flutter.buildFlutterApplication { postInstall = '' install -D assets/bundled/icon.svg $out/share/icons/hicolor/scalable/apps/nexus.svg install -Dm755 linux/nexus.federated.nexus.desktop -t $out/share/applications + install -Dm644 linux/*.service -t $out/share/dbus-1/services wrapProgram $out/bin/nexus \ --suffix LD_LIBRARY_PATH : $out/app/nexus/lib ''; From f40dd22277beb2679f2abb04d1137b4ef7a07819 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sun, 20 Sep 2026 17:14:56 -0400 Subject: [PATCH 138/176] use mkEnableOption for enableNotifications --- linux/nix/module.nix | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/linux/nix/module.nix b/linux/nix/module.nix index f901007..ac1b503 100644 --- a/linux/nix/module.nix +++ b/linux/nix/module.nix @@ -10,10 +10,8 @@ let inherit (lib) mkIf mkMerge - mkOption mkEnableOption mkPackageOption - types ; cfg = config.programs.nexus; @@ -23,15 +21,7 @@ in enable = mkEnableOption "Nexus, a simple and user-friendly Matrix client"; package = mkPackageOption self.packages.${pkgs.stdenv.hostPlatform.system} "nexus" { }; - enableNotifications = mkOption { - description = '' - Whether to enable push notifications support via UnifiedPush, installing - {manpage}`kunifiedpush` and registering its systemd and D-Bus units. - ''; - type = types.bool; - default = false; - example = true; - }; + enableNotifications = mkEnableOption "notifications support via UnifiedPush"; }; config = mkIf cfg.enable (mkMerge [ From 35ef82accd58a52e36e7436dc6421eb129b72af3 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sun, 20 Sep 2026 17:18:39 -0400 Subject: [PATCH 139/176] fixup module --- linux/nix/module.nix | 2 +- linux/nix/pkg/default.nix | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/linux/nix/module.nix b/linux/nix/module.nix index ac1b503..a8abd6c 100644 --- a/linux/nix/module.nix +++ b/linux/nix/module.nix @@ -19,7 +19,7 @@ in { options.programs.nexus = { enable = mkEnableOption "Nexus, a simple and user-friendly Matrix client"; - package = mkPackageOption self.packages.${pkgs.stdenv.hostPlatform.system} "nexus" { }; + package = mkPackageOption self.packages.${pkgs.stdenv.hostPlatform.system} "default" { }; enableNotifications = mkEnableOption "notifications support via UnifiedPush"; }; diff --git a/linux/nix/pkg/default.nix b/linux/nix/pkg/default.nix index cf1b107..36974ed 100644 --- a/linux/nix/pkg/default.nix +++ b/linux/nix/pkg/default.nix @@ -32,6 +32,8 @@ flutter.buildFlutterApplication { emoji_text_field = "sha256-3TOys09EP2GRo6pUBGPXaqBlE39O2Cmwt42Hs1cTDKo="; linkify = "sha256-TpMD6+0zyY6i9l+6d8ErnVufmepCv362rCtnbOht/z4="; navigation_rail_m3e = "sha256-+2awDTQnK58gGRY1nuHckG/jjxarsYSRu9ovR4i4TEc="; + unifiedpush_linux = "sha256-aIF/8oabSuuZo7K6qr4r7UBmf57qgoGAXyJ40fdntuQ="; + unifiedpush_platform_interface = "sha256-aIF/8oabSuuZo7K6qr4r7UBmf57qgoGAXyJ40fdntuQ="; }; postInstall = '' From 1a6a5c36ea6cbeb269f965b71444d8f362b12caa Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sun, 20 Sep 2026 17:21:26 -0400 Subject: [PATCH 140/176] link to module from readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9960915..b6adc87 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,7 @@ If you want to try out Nexus, grab one of the following artifacts from CI: - Flatpak - [AArch64/Arm64](https://nightly.link/Henry-Hiles/nexus/workflows/flatpak/main/flatpak-aarch64.zip) - [x86_64/AMD64](https://nightly.link/Henry-Hiles/nexus/workflows/flatpak/main/flatpak-x86_64.zip) +- [NixOS Module](linux/nix/module.nix) ## Build it yourself From c0d14ac30ee4eee44298771d00469b9df1edb5d9 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Sun, 20 Sep 2026 17:27:45 -0400 Subject: [PATCH 141/176] don't write service by default --- lib/controllers/unified_push.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/controllers/unified_push.dart b/lib/controllers/unified_push.dart index 1016053..ae31cac 100644 --- a/lib/controllers/unified_push.dart +++ b/lib/controllers/unified_push.dart @@ -28,7 +28,7 @@ class UnifiedPushController extends AsyncNotifier { dbusName: "nexus.federated.nexus.UnifiedPush", storage: UnifiedPushStorageSharedPreferences(), background: isInBackground, - shouldWriteService: true, + shouldWriteService: false, ), onNewEndpoint: (endpoint, instance) async { final pushKey = endpoint.pubKeySet!.pubKey; From deaf564c360477170fa2fada183559ce0d9b1de1 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Mon, 21 Sep 2026 14:16:29 -0400 Subject: [PATCH 142/176] use portals for linux notifs --- lib/controllers/notification.dart | 13 +++--------- linux/nexus.federated.nexus.desktop | 5 ++++- linux/nexus.federated.nexus.service | 3 +++ linux/nix/pkg/default.nix | 2 ++ pubspec.lock | 32 +++++++++++++++++++---------- pubspec.yaml | 10 +++++++++ 6 files changed, 43 insertions(+), 22 deletions(-) create mode 100644 linux/nexus.federated.nexus.service diff --git a/lib/controllers/notification.dart b/lib/controllers/notification.dart index abef40c..7c40d18 100644 --- a/lib/controllers/notification.dart +++ b/lib/controllers/notification.dart @@ -3,8 +3,6 @@ import "dart:io"; import "package:material_ui/material_ui.dart"; import "package:nexus/main.dart"; import "package:flutter_local_notifications/flutter_local_notifications.dart"; -// ignore: implementation_imports -import "package:flutter_local_notifications_linux/src/model/hint.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/pages/notifications.dart"; @@ -91,14 +89,9 @@ class NotificationController largeIcon: icon == null ? null : FilePathAndroidBitmap(icon.path), ), linux: .new( - customHints: icon == null - ? null - : [ - .new( - name: "image-path", - value: LinuxHintStringValue(icon.path), - ), - ], + category: LinuxNotificationCategory.imReceived, + defaultActionName: "app.event", + icon: icon == null ? null : FilePathLinuxIcon(icon.path), ), // TODO: See if icons can be added to iOS, macOS, and Windows notifications (#68) iOS: .new(), diff --git a/linux/nexus.federated.nexus.desktop b/linux/nexus.federated.nexus.desktop index d61734e..ac01719 100644 --- a/linux/nexus.federated.nexus.desktop +++ b/linux/nexus.federated.nexus.desktop @@ -7,4 +7,7 @@ Icon=nexus Terminal=false Type=Application Categories=Chat;Network;InstantMessaging; -MimeType=x-scheme-handler/nexus.federated.nexus; \ No newline at end of file +MimeType=x-scheme-handler/nexus.federated.nexus; +StartupNotify=true +DBusActivatable=true +X-GNOME-UsesNotifications=true \ No newline at end of file diff --git a/linux/nexus.federated.nexus.service b/linux/nexus.federated.nexus.service new file mode 100644 index 0000000..65e2e79 --- /dev/null +++ b/linux/nexus.federated.nexus.service @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=nexus.federated.nexus +Exec=/usr/bin/env FLUTTER_HEADLESS=1 nexus diff --git a/linux/nix/pkg/default.nix b/linux/nix/pkg/default.nix index 36974ed..f42d893 100644 --- a/linux/nix/pkg/default.nix +++ b/linux/nix/pkg/default.nix @@ -34,6 +34,8 @@ flutter.buildFlutterApplication { navigation_rail_m3e = "sha256-+2awDTQnK58gGRY1nuHckG/jjxarsYSRu9ovR4i4TEc="; unifiedpush_linux = "sha256-aIF/8oabSuuZo7K6qr4r7UBmf57qgoGAXyJ40fdntuQ="; unifiedpush_platform_interface = "sha256-aIF/8oabSuuZo7K6qr4r7UBmf57qgoGAXyJ40fdntuQ="; + flutter_local_notifications_linux = "sha256-I1X+Taw4+hxDHOUxCcqiWoJbZJqbrdVUXUC0vj1Adjc="; + flutter_local_notifications_platform_interface = "sha256-I1X+Taw4+hxDHOUxCcqiWoJbZJqbrdVUXUC0vj1Adjc="; }; postInstall = '' diff --git a/pubspec.lock b/pubspec.lock index a914165..278d3b4 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -497,19 +497,21 @@ packages: flutter_local_notifications_linux: dependency: "direct main" description: - name: flutter_local_notifications_linux - sha256: "9ca97e63776f29ab1b955725c09999fc2c150523269db150c39274f2a43c5a8b" - url: "https://pub.dev" - source: hosted - version: "8.0.1" + path: flutter_local_notifications_linux + ref: "quad/feat/xdg-portal-notifs" + resolved-ref: d853ff4997f6dd2b9ecdc53d37fb337cebe63863 + url: "https://github.com/Henry-Hiles/flutter_local_notifications" + source: git + version: "9.0.0-dev.1" flutter_local_notifications_platform_interface: - dependency: transitive + dependency: "direct overridden" description: - name: flutter_local_notifications_platform_interface - sha256: "43c3761d916c9bd3d5c7ebbc44d82f4990329840c0c5d62ad5260cc1b5d399bd" - url: "https://pub.dev" - source: hosted - version: "12.2.0" + path: flutter_local_notifications_platform_interface + ref: "quad/feat/xdg-portal-notifs" + resolved-ref: d853ff4997f6dd2b9ecdc53d37fb337cebe63863 + url: "https://github.com/Henry-Hiles/flutter_local_notifications" + source: git + version: "13.0.0-dev.1" flutter_local_notifications_web: dependency: transitive description: @@ -1742,6 +1744,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.5.2" + xdg_desktop_portal: + dependency: transitive + description: + name: xdg_desktop_portal + sha256: "4fae74b6ed63a449d4c796a74265cebdd912c390336dedc06d705142f3b939d7" + url: "https://pub.dev" + source: hosted + version: "0.1.14" xdg_directories: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 332efaf..2a2b2ff 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -35,6 +35,16 @@ dependency_overrides: git: url: https://github.com/appelladev/linkify ref: fix/consecutive-periods-loose-url + flutter_local_notifications_linux: + git: + url: https://github.com/Henry-Hiles/flutter_local_notifications + ref: quad/feat/xdg-portal-notifs + path: flutter_local_notifications_linux + flutter_local_notifications_platform_interface: + git: + url: https://github.com/Henry-Hiles/flutter_local_notifications + ref: quad/feat/xdg-portal-notifs + path: flutter_local_notifications_platform_interface dependencies: flutter: From fea39e4191a0d72d66835700c7b470cd861d1896 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Mon, 21 Sep 2026 15:43:01 -0400 Subject: [PATCH 143/176] use xdg_desktop_portal over flutter_local_notifications on linux --- lib/controllers/notification.dart | 134 +++++++++++++++++++--------- lib/controllers/portal.dart | 17 ++++ linux/nexus.federated.nexus.desktop | 4 +- linux/nexus.federated.nexus.service | 2 +- pubspec.lock | 37 ++++---- pubspec.yaml | 14 +-- 6 files changed, 132 insertions(+), 76 deletions(-) create mode 100644 lib/controllers/portal.dart diff --git a/lib/controllers/notification.dart b/lib/controllers/notification.dart index 7c40d18..67f2ed4 100644 --- a/lib/controllers/notification.dart +++ b/lib/controllers/notification.dart @@ -1,10 +1,13 @@ import "dart:io"; +import "package:flutter/foundation.dart"; import "package:material_ui/material_ui.dart"; +import "package:nexus/controllers/portal.dart"; import "package:nexus/main.dart"; import "package:flutter_local_notifications/flutter_local_notifications.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/pages/notifications.dart"; +import "package:xdg_desktop_portal/xdg_desktop_portal.dart"; class NotificationController extends AsyncNotifier { @@ -12,40 +15,77 @@ class NotificationController Future build() async { final notifications = FlutterLocalNotificationsPlugin(); - final darwin = DarwinInitializationSettings(); + if (!Platform.isLinux) { + final darwin = DarwinInitializationSettings(); - await notifications.initialize( - settings: .new( - windows: .new( - appName: "Nexus", - appUserModelId: "nexus.federated.nexus", - guid: "dde78daf-130f-4e46-a80a-e31deeab45d7", + await notifications.initialize( + settings: .new( + windows: .new( + appName: "Nexus", + appUserModelId: "nexus.federated.nexus", + guid: "dde78daf-130f-4e46-a80a-e31deeab45d7", + ), + android: .new("ic_launcher_foreground"), + iOS: darwin, + macOS: darwin, ), - android: .new("ic_launcher_foreground"), - iOS: darwin, - macOS: darwin, - linux: .new(defaultActionName: "Open"), - ), - onDidReceiveNotificationResponse: (details) { - if (details.payload case final eventId?) { - if (navigatorKey.currentContext case final context?) { + onDidReceiveNotificationResponse: (details) { + if (details.payload case final eventId?) { + if (navigatorKey.currentContext case final context?) { + Navigator.of(context).push( + MaterialPageRoute( + builder: (_) => NotificationsPage( + highlightedEventId: eventId, + defaultToAllNotifications: true, + ), + ), + ); + } + } + }, + ); + } + + if (Platform.isLinux) { + final portal = await ref.watch(PortalController.provider.future); + + portal.notification.actionInvoked.listen((event) { + if (event.action != "app.event") { + return; + } + + if (navigatorKey.currentContext case final context?) { + if (context.mounted) { Navigator.of(context).push( MaterialPageRoute( builder: (_) => NotificationsPage( - highlightedEventId: eventId, + highlightedEventId: event.id, defaultToAllNotifications: true, ), ), ); } } - }, - ); + }); + } + + ref.onDispose(() { + // The portal client owns its D-Bus connection. + if (Platform.isLinux) { + ref.read(PortalController.provider.future).then((portal) { + portal.close(); + }); + } + }); return notifications; } Future requestPermissions() async { + if (Platform.isLinux) { + return true; + } + final controller = await future; if (Platform.isIOS) { @@ -82,31 +122,41 @@ class NotificationController String? payload, }) async { debugPrint("Sending notification for $id"); - final notificationDetails = NotificationDetails( - android: .new( - "messages", - "Messages", - largeIcon: icon == null ? null : FilePathAndroidBitmap(icon.path), - ), - linux: .new( - category: LinuxNotificationCategory.imReceived, - defaultActionName: "app.event", - icon: icon == null ? null : FilePathLinuxIcon(icon.path), - ), - // TODO: See if icons can be added to iOS, macOS, and Windows notifications (#68) - iOS: .new(), - macOS: .new(), - windows: .new(), - ); - final controller = await future; - await controller.show( - id: id, - title: title, - body: body, - notificationDetails: notificationDetails, - payload: payload, - ); + if (Platform.isLinux) { + final portal = await ref.read(PortalController.provider.future); + + await portal.notification.addNotification( + id.toString(), + title: title, + body: body, + icon: icon == null ? null : XdgNotificationIconFile(icon.path), + defaultAction: "app.event", + ); + } else { + final notificationDetails = NotificationDetails( + android: .new( + "messages", + "Messages", + largeIcon: icon == null ? null : FilePathAndroidBitmap(icon.path), + ), + // TODO: See if icons can be added to iOS, macOS, and Windows + // notifications (#68) + iOS: .new(), + macOS: .new(), + windows: .new(), + ); + + final controller = await future; + + await controller.show( + id: id, + title: title, + body: body, + notificationDetails: notificationDetails, + payload: payload, + ); + } } static final provider = diff --git a/lib/controllers/portal.dart b/lib/controllers/portal.dart new file mode 100644 index 0000000..9fbc491 --- /dev/null +++ b/lib/controllers/portal.dart @@ -0,0 +1,17 @@ +import "package:flutter_riverpod/flutter_riverpod.dart"; +import "package:xdg_desktop_portal/xdg_desktop_portal.dart"; + +class PortalController extends AsyncNotifier { + @override + Future build() async { + final portal = XdgDesktopPortalClient(); + await portal.registerApplication("nexus.federated.nexus"); + + return portal; + } + + static final provider = + AsyncNotifierProvider( + PortalController.new, + ); +} diff --git a/linux/nexus.federated.nexus.desktop b/linux/nexus.federated.nexus.desktop index ac01719..a7a548a 100644 --- a/linux/nexus.federated.nexus.desktop +++ b/linux/nexus.federated.nexus.desktop @@ -8,6 +8,4 @@ Terminal=false Type=Application Categories=Chat;Network;InstantMessaging; MimeType=x-scheme-handler/nexus.federated.nexus; -StartupNotify=true -DBusActivatable=true -X-GNOME-UsesNotifications=true \ No newline at end of file +DBusActivatable=true \ No newline at end of file diff --git a/linux/nexus.federated.nexus.service b/linux/nexus.federated.nexus.service index 65e2e79..1757c2c 100644 --- a/linux/nexus.federated.nexus.service +++ b/linux/nexus.federated.nexus.service @@ -1,3 +1,3 @@ [D-BUS Service] Name=nexus.federated.nexus -Exec=/usr/bin/env FLUTTER_HEADLESS=1 nexus +Exec=/usr/bin/env nexus diff --git a/pubspec.lock b/pubspec.lock index 278d3b4..9a917a4 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -495,23 +495,21 @@ packages: source: hosted version: "22.3.0" flutter_local_notifications_linux: - dependency: "direct main" + dependency: transitive description: - path: flutter_local_notifications_linux - ref: "quad/feat/xdg-portal-notifs" - resolved-ref: d853ff4997f6dd2b9ecdc53d37fb337cebe63863 - url: "https://github.com/Henry-Hiles/flutter_local_notifications" - source: git - version: "9.0.0-dev.1" + name: flutter_local_notifications_linux + sha256: "9ca97e63776f29ab1b955725c09999fc2c150523269db150c39274f2a43c5a8b" + url: "https://pub.dev" + source: hosted + version: "8.0.1" flutter_local_notifications_platform_interface: - dependency: "direct overridden" + dependency: transitive description: - path: flutter_local_notifications_platform_interface - ref: "quad/feat/xdg-portal-notifs" - resolved-ref: d853ff4997f6dd2b9ecdc53d37fb337cebe63863 - url: "https://github.com/Henry-Hiles/flutter_local_notifications" - source: git - version: "13.0.0-dev.1" + name: flutter_local_notifications_platform_interface + sha256: "43c3761d916c9bd3d5c7ebbc44d82f4990329840c0c5d62ad5260cc1b5d399bd" + url: "https://pub.dev" + source: hosted + version: "12.2.0" flutter_local_notifications_web: dependency: transitive description: @@ -1745,12 +1743,13 @@ packages: source: hosted version: "0.5.2" xdg_desktop_portal: - dependency: transitive + dependency: "direct main" description: - name: xdg_desktop_portal - sha256: "4fae74b6ed63a449d4c796a74265cebdd912c390336dedc06d705142f3b939d7" - url: "https://pub.dev" - source: hosted + path: "." + ref: HEAD + resolved-ref: "6d070b677f908b01065b4dce79ddc9a208daadbf" + url: "https://github.com/Henry-Hiles/xdg_desktop_portal.dart" + source: git version: "0.1.14" xdg_directories: dependency: "direct main" diff --git a/pubspec.yaml b/pubspec.yaml index 2a2b2ff..403fe72 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -35,16 +35,6 @@ dependency_overrides: git: url: https://github.com/appelladev/linkify ref: fix/consecutive-periods-loose-url - flutter_local_notifications_linux: - git: - url: https://github.com/Henry-Hiles/flutter_local_notifications - ref: quad/feat/xdg-portal-notifs - path: flutter_local_notifications_linux - flutter_local_notifications_platform_interface: - git: - url: https://github.com/Henry-Hiles/flutter_local_notifications - ref: quad/feat/xdg-portal-notifs - path: flutter_local_notifications_platform_interface dependencies: flutter: @@ -99,8 +89,10 @@ dependencies: unifiedpush: 6.2.0 unifiedpush_storage_shared_preferences: 1.0.0 flutter_local_notifications: 22.3.0 - flutter_local_notifications_linux: 8.0.1 material_emoji_picker: 1.1.1 + xdg_desktop_portal: + git: + url: https://github.com/Henry-Hiles/xdg_desktop_portal.dart dev_dependencies: build_runner: 2.16.1 From 2a11bcb7e8c63c5be8eea6da168d72d1cbc68036 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Mon, 21 Sep 2026 15:44:10 -0400 Subject: [PATCH 144/176] update hashes --- linux/nix/pkg/default.nix | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/linux/nix/pkg/default.nix b/linux/nix/pkg/default.nix index f42d893..77c4067 100644 --- a/linux/nix/pkg/default.nix +++ b/linux/nix/pkg/default.nix @@ -34,8 +34,7 @@ flutter.buildFlutterApplication { navigation_rail_m3e = "sha256-+2awDTQnK58gGRY1nuHckG/jjxarsYSRu9ovR4i4TEc="; unifiedpush_linux = "sha256-aIF/8oabSuuZo7K6qr4r7UBmf57qgoGAXyJ40fdntuQ="; unifiedpush_platform_interface = "sha256-aIF/8oabSuuZo7K6qr4r7UBmf57qgoGAXyJ40fdntuQ="; - flutter_local_notifications_linux = "sha256-I1X+Taw4+hxDHOUxCcqiWoJbZJqbrdVUXUC0vj1Adjc="; - flutter_local_notifications_platform_interface = "sha256-I1X+Taw4+hxDHOUxCcqiWoJbZJqbrdVUXUC0vj1Adjc="; + xdg_desktop_portal = "sha256-S6AHWHg1TDT4RoBm6S5E9D1yWy7nYnuqzPTy735M6Xw="; }; postInstall = '' From 700b4e720f7f6f6f95054e321f4dbbc53be0a99a Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Mon, 21 Sep 2026 16:56:12 -0400 Subject: [PATCH 145/176] open notifications page on notif tap please please please let me never touch c++ again i hate it also the c++ got reformatted here but i dont really care --- lib/controllers/notification.dart | 39 ++- lib/controllers/portal.dart | 1 + linux/nix/pkg/default.nix | 2 +- linux/runner/my_application.cc | 415 +++++++++++++++++++++++------- pubspec.lock | 2 +- 5 files changed, 348 insertions(+), 111 deletions(-) diff --git a/lib/controllers/notification.dart b/lib/controllers/notification.dart index 67f2ed4..5d343cc 100644 --- a/lib/controllers/notification.dart +++ b/lib/controllers/notification.dart @@ -1,6 +1,7 @@ +import "dart:async"; import "dart:io"; -import "package:flutter/foundation.dart"; +import "package:flutter/services.dart"; import "package:material_ui/material_ui.dart"; import "package:nexus/controllers/portal.dart"; import "package:nexus/main.dart"; @@ -47,37 +48,28 @@ class NotificationController } if (Platform.isLinux) { - final portal = await ref.watch(PortalController.provider.future); + const notificationChannel = MethodChannel("nexus/notifications"); - portal.notification.actionInvoked.listen((event) { - if (event.action != "app.event") { + notificationChannel.setMethodCallHandler((call) async { + if (call.method != "notificationClicked") { return; } + final eventId = call.arguments as String; + if (navigatorKey.currentContext case final context?) { - if (context.mounted) { - Navigator.of(context).push( - MaterialPageRoute( - builder: (_) => NotificationsPage( - highlightedEventId: event.id, - defaultToAllNotifications: true, - ), + Navigator.of(context).push( + MaterialPageRoute( + builder: (_) => NotificationsPage( + highlightedEventId: eventId, + defaultToAllNotifications: true, ), - ); - } + ), + ); } }); } - ref.onDispose(() { - // The portal client owns its D-Bus connection. - if (Platform.isLinux) { - ref.read(PortalController.provider.future).then((portal) { - portal.close(); - }); - } - }); - return notifications; } @@ -124,7 +116,7 @@ class NotificationController debugPrint("Sending notification for $id"); if (Platform.isLinux) { - final portal = await ref.read(PortalController.provider.future); + final portal = await ref.watch(PortalController.provider.future); await portal.notification.addNotification( id.toString(), @@ -132,6 +124,7 @@ class NotificationController body: body, icon: icon == null ? null : XdgNotificationIconFile(icon.path), defaultAction: "app.event", + defaultActionTarget: payload, ); } else { final notificationDetails = NotificationDetails( diff --git a/lib/controllers/portal.dart b/lib/controllers/portal.dart index 9fbc491..006d39d 100644 --- a/lib/controllers/portal.dart +++ b/lib/controllers/portal.dart @@ -7,6 +7,7 @@ class PortalController extends AsyncNotifier { final portal = XdgDesktopPortalClient(); await portal.registerApplication("nexus.federated.nexus"); + ref.onDispose(portal.close); return portal; } diff --git a/linux/nix/pkg/default.nix b/linux/nix/pkg/default.nix index 77c4067..7914430 100644 --- a/linux/nix/pkg/default.nix +++ b/linux/nix/pkg/default.nix @@ -34,7 +34,7 @@ flutter.buildFlutterApplication { navigation_rail_m3e = "sha256-+2awDTQnK58gGRY1nuHckG/jjxarsYSRu9ovR4i4TEc="; unifiedpush_linux = "sha256-aIF/8oabSuuZo7K6qr4r7UBmf57qgoGAXyJ40fdntuQ="; unifiedpush_platform_interface = "sha256-aIF/8oabSuuZo7K6qr4r7UBmf57qgoGAXyJ40fdntuQ="; - xdg_desktop_portal = "sha256-S6AHWHg1TDT4RoBm6S5E9D1yWy7nYnuqzPTy735M6Xw="; + xdg_desktop_portal = "sha256-As1X1/IfCbSD5ful2kAxgBita95KxmInRN4/6QmVaTI="; }; postInstall = '' diff --git a/linux/runner/my_application.cc b/linux/runner/my_application.cc index 739e6df..910bf5b 100644 --- a/linux/runner/my_application.cc +++ b/linux/runner/my_application.cc @@ -1,7 +1,11 @@ #include "my_application.h" #include + #include +#include +#include + #ifdef GDK_WINDOWING_X11 #include #endif @@ -10,145 +14,384 @@ struct _MyApplication { GtkApplication parent_instance; + char** dart_entrypoint_arguments; + + FlEngine* flutter_engine; + FlMethodChannel* notification_channel; + + gchar* pending_notification_event_id; + gboolean flutter_ready; }; G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) -// Called when first Flutter frame received. -static void first_frame_cb(MyApplication* self, FlView *view) -{ - gtk_widget_show(gtk_widget_get_toplevel(GTK_WIDGET(view))); +static void my_application_activate(GApplication* application); + +static void send_notification_event_to_flutter( + MyApplication* self, + const gchar* event_id) { + if (self->notification_channel == nullptr || + !self->flutter_ready) { + g_free(self->pending_notification_event_id); + self->pending_notification_event_id = g_strdup(event_id); + return; + } + + g_autoptr(FlValue) args = + fl_value_new_string(event_id); + + fl_method_channel_invoke_method( + self->notification_channel, + "notificationClicked", + args, + nullptr, + nullptr, + nullptr); } -// Implements GApplication::activate. -static void my_application_activate(GApplication* application) { - MyApplication* self = MY_APPLICATION(application); +static void notification_event_action( + GSimpleAction* action, + GVariant* parameter, + gpointer user_data) { + MyApplication* self = + MY_APPLICATION(user_data); - GList* windows = gtk_application_get_windows(GTK_APPLICATION(application)); - if (windows) { - gtk_window_present(GTK_WINDOW(windows->data)); + if (parameter == nullptr) { + g_warning( + "Notification event action invoked without a target"); + return; + } + + if (!g_variant_is_of_type( + parameter, + G_VARIANT_TYPE_STRING)) { + g_warning( + "Notification event action received unexpected parameter type: %s", + g_variant_get_type_string(parameter)); + return; + } + + const gchar* event_id = + g_variant_get_string(parameter, nullptr); + + g_message( + "Notification event activated: %s", + event_id); + + send_notification_event_to_flutter( + self, + event_id); + + GList* windows = + gtk_application_get_windows( + GTK_APPLICATION(self)); + + if (windows != nullptr) { + gtk_window_present( + GTK_WINDOW(windows->data)); + } else { + my_application_activate( + G_APPLICATION(self)); + } +} + +static void first_frame_cb( + MyApplication* self, + FlView* view) { + self->flutter_ready = TRUE; + + gtk_widget_show( + gtk_widget_get_toplevel( + GTK_WIDGET(view))); + + if (self->pending_notification_event_id != nullptr) { + gchar* event_id = + self->pending_notification_event_id; + + self->pending_notification_event_id = nullptr; + + send_notification_event_to_flutter( + self, + event_id); + + g_free(event_id); + } +} + +static void my_application_activate( + GApplication* application) { + MyApplication* self = + MY_APPLICATION(application); + + GList* windows = + gtk_application_get_windows( + GTK_APPLICATION(application)); + + if (windows != nullptr) { + gtk_window_present( + GTK_WINDOW(windows->data)); return; } GtkWindow* window = - GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); + GTK_WINDOW( + gtk_application_window_new( + GTK_APPLICATION(application))); - // Use a header bar when running in GNOME as this is the common style used - // by applications and is the setup most users will be using (e.g. Ubuntu - // desktop). - // If running on X and not using GNOME then just use a traditional title bar - // in case the window manager does more exotic layout, e.g. tiling. - // If running on Wayland assume the header bar will work (may need changing - // if future cases occur). gboolean use_header_bar = TRUE; + #ifdef GDK_WINDOWING_X11 - GdkScreen* screen = gtk_window_get_screen(window); + GdkScreen* screen = + gtk_window_get_screen(window); + if (GDK_IS_X11_SCREEN(screen)) { - const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); + const gchar* wm_name = + gdk_x11_screen_get_window_manager_name(screen); + if (g_strcmp0(wm_name, "GNOME Shell") != 0) { use_header_bar = FALSE; } } #endif - gtk_widget_set_size_request(GTK_WIDGET(window), 250, -1); + + gtk_widget_set_size_request( + GTK_WIDGET(window), + 250, + -1); + if (use_header_bar) { - GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); - gtk_widget_show(GTK_WIDGET(header_bar)); - gtk_header_bar_set_title(header_bar, "nexus"); - gtk_header_bar_set_show_close_button(header_bar, TRUE); - gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); + GtkHeaderBar* header_bar = + GTK_HEADER_BAR( + gtk_header_bar_new()); + + gtk_widget_show( + GTK_WIDGET(header_bar)); + + gtk_header_bar_set_title( + header_bar, + "nexus"); + + gtk_header_bar_set_show_close_button( + header_bar, + TRUE); + + gtk_window_set_titlebar( + window, + GTK_WIDGET(header_bar)); } else { - gtk_window_set_title(window, "nexus"); + gtk_window_set_title( + window, + "nexus"); } - gtk_window_set_default_size(window, 1280, 720); + gtk_window_set_default_size( + window, + 1280, + 720); - g_autoptr(FlDartProject) project = fl_dart_project_new(); - fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); + g_autoptr(FlDartProject) project = + fl_dart_project_new(); + + fl_dart_project_set_dart_entrypoint_arguments( + project, + self->dart_entrypoint_arguments); + + FlView* view = + fl_view_new(project); + + self->flutter_engine = + fl_view_get_engine(view); + + g_autoptr(FlStandardMethodCodec) codec = + fl_standard_method_codec_new(); + + self->notification_channel = + fl_method_channel_new( + fl_engine_get_binary_messenger( + self->flutter_engine), + "nexus/notifications", + FL_METHOD_CODEC(codec)); - FlView* view = fl_view_new(project); GdkRGBA background_color; - // Background defaults to black, override it here if necessary, e.g. #00000000 for transparent. - gdk_rgba_parse(&background_color, "#000000"); - fl_view_set_background_color(view, &background_color); - gtk_widget_show(GTK_WIDGET(view)); - if (std::getenv("FLUTTER_HEADLESS")) gtk_widget_hide(GTK_WIDGET(window)); - gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); - // Show the window when Flutter renders. - // Requires the view to be realized so we can start rendering. - g_signal_connect_swapped(view, "first-frame", G_CALLBACK(first_frame_cb), self); - gtk_widget_realize(GTK_WIDGET(view)); + gdk_rgba_parse( + &background_color, + "#000000"); - fl_register_plugins(FL_PLUGIN_REGISTRY(view)); + fl_view_set_background_color( + view, + &background_color); - gtk_widget_grab_focus(GTK_WIDGET(view)); + gtk_widget_show( + GTK_WIDGET(view)); + + if (std::getenv("FLUTTER_HEADLESS")) { + gtk_widget_hide( + GTK_WIDGET(window)); + } + + gtk_container_add( + GTK_CONTAINER(window), + GTK_WIDGET(view)); + + g_signal_connect_swapped( + view, + "first-frame", + G_CALLBACK(first_frame_cb), + self); + + gtk_widget_realize( + GTK_WIDGET(view)); + + fl_register_plugins( + FL_PLUGIN_REGISTRY(view)); + + gtk_widget_grab_focus( + GTK_WIDGET(view)); } -// Implements GApplication::local_command_line. -static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) { - MyApplication* self = MY_APPLICATION(application); - // Strip out the first argument as it is the binary name. - self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); +static gboolean my_application_local_command_line( + GApplication* application, + gchar*** arguments, + int* exit_status) { + MyApplication* self = + MY_APPLICATION(application); + + self->dart_entrypoint_arguments = + g_strdupv(*arguments + 1); g_autoptr(GError) error = nullptr; - if (!g_application_register(application, nullptr, &error)) { - g_warning("Failed to register: %s", error->message); - *exit_status = 1; - return TRUE; + + if (!g_application_register( + application, + nullptr, + &error)) { + g_warning( + "Failed to register: %s", + error->message); + + *exit_status = 1; + return TRUE; } g_application_activate(application); + *exit_status = 0; - return FALSE; + return TRUE; } -// Implements GApplication::startup. -static void my_application_startup(GApplication* application) { - //MyApplication* self = MY_APPLICATION(object); +static void my_application_startup( + GApplication* application) { + g_message( + "GApplication application-id: %s", + g_application_get_application_id( + application)); - // Perform any actions required at application startup. + g_message( + "GApplication is remote: %d", + g_application_get_is_remote( + application)); - G_APPLICATION_CLASS(my_application_parent_class)->startup(application); + g_message( + "GApplication is registered: %d", + g_application_get_is_registered( + application)); + + g_message( + "prgname: %s", + g_get_prgname()); + + G_APPLICATION_CLASS( + my_application_parent_class) + ->startup(application); } -// Implements GApplication::shutdown. -static void my_application_shutdown(GApplication* application) { - //MyApplication* self = MY_APPLICATION(object); - - // Perform any actions required at application shutdown. - - G_APPLICATION_CLASS(my_application_parent_class)->shutdown(application); +static void my_application_shutdown( + GApplication* application) { + G_APPLICATION_CLASS( + my_application_parent_class) + ->shutdown(application); } -// Implements GObject::dispose. -static void my_application_dispose(GObject* object) { - MyApplication* self = MY_APPLICATION(object); - g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); - G_OBJECT_CLASS(my_application_parent_class)->dispose(object); +static void my_application_dispose( + GObject* object) { + MyApplication* self = + MY_APPLICATION(object); + + g_clear_pointer( + &self->dart_entrypoint_arguments, + g_strfreev); + + g_clear_pointer( + &self->pending_notification_event_id, + g_free); + + g_clear_object( + &self->notification_channel); + + self->flutter_engine = nullptr; + + G_OBJECT_CLASS( + my_application_parent_class) + ->dispose(object); } -static void my_application_class_init(MyApplicationClass* klass) { - G_APPLICATION_CLASS(klass)->activate = my_application_activate; - G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; - G_APPLICATION_CLASS(klass)->startup = my_application_startup; - G_APPLICATION_CLASS(klass)->shutdown = my_application_shutdown; - G_OBJECT_CLASS(klass)->dispose = my_application_dispose; +static void my_application_class_init( + MyApplicationClass* klass) { + G_APPLICATION_CLASS(klass)->activate = + my_application_activate; + + G_APPLICATION_CLASS(klass)->local_command_line = + my_application_local_command_line; + + G_APPLICATION_CLASS(klass)->startup = + my_application_startup; + + G_APPLICATION_CLASS(klass)->shutdown = + my_application_shutdown; + + G_OBJECT_CLASS(klass)->dispose = + my_application_dispose; } -static void my_application_init(MyApplication* self) {} +static void my_application_init( + MyApplication* self) { + self->dart_entrypoint_arguments = nullptr; + self->flutter_engine = nullptr; + self->notification_channel = nullptr; + self->pending_notification_event_id = nullptr; + self->flutter_ready = FALSE; + + GSimpleAction* action = + g_simple_action_new( + "event", + G_VARIANT_TYPE_STRING); + + g_signal_connect( + action, + "activate", + G_CALLBACK(notification_event_action), + self); + + g_action_map_add_action( + G_ACTION_MAP(self), + G_ACTION(action)); + + g_object_unref(action); +} MyApplication* my_application_new() { - // Set the program name to the application ID, which helps various systems - // like GTK and desktop environments map this running application to its - // corresponding .desktop file. This ensures better integration by allowing - // the application to be recognized beyond its binary name. g_set_prgname(APPLICATION_ID); - return MY_APPLICATION(g_object_new(my_application_get_type(), - "application-id", APPLICATION_ID, - "flags", G_APPLICATION_HANDLES_COMMAND_LINE | G_APPLICATION_HANDLES_OPEN, - nullptr)); -} + return MY_APPLICATION( + g_object_new( + my_application_get_type(), + "application-id", + APPLICATION_ID, + "flags", + G_APPLICATION_HANDLES_COMMAND_LINE | + G_APPLICATION_HANDLES_OPEN, + nullptr)); +} \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index 9a917a4..337cbae 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1747,7 +1747,7 @@ packages: description: path: "." ref: HEAD - resolved-ref: "6d070b677f908b01065b4dce79ddc9a208daadbf" + resolved-ref: "9ead341e908da2972293b2edc345f2b0a6423d78" url: "https://github.com/Henry-Hiles/xdg_desktop_portal.dart" source: git version: "0.1.14" From 00a42b5f1addda53e6e53509684060c7c30f4a4a Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Mon, 21 Sep 2026 17:20:43 -0400 Subject: [PATCH 146/176] fixup flatpak build --- flake.lock | 8 ++++---- flake.nix | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/flake.lock b/flake.lock index b3e4531..96ae5b8 100644 --- a/flake.lock +++ b/flake.lock @@ -42,16 +42,16 @@ "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1789876218, - "narHash": "sha256-/sUFGNLvcwf9MxGw+QS24o1bg217fQRY9NpinlmSjH4=", + "lastModified": 1790025133, + "narHash": "sha256-wxHdwhJ5SzJ8uI7hNrP0pDn+STDhzbeXRYOYPZQ1RVU=", "owner": "Henry-Hiles", "repo": "nix2flatpak", - "rev": "8264b886c1e64bffc172c49e9dfcb551cbd863f4", + "rev": "56025d55f17272493678e38fa1d219d19a447bf8", "type": "github" }, "original": { "owner": "Henry-Hiles", - "ref": "quad/fix/names", + "ref": "quad/nexus", "repo": "nix2flatpak", "type": "github" } diff --git a/flake.nix b/flake.nix index 91614b5..97d6068 100644 --- a/flake.nix +++ b/flake.nix @@ -5,7 +5,7 @@ self.submodules = true; nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; flake-parts.url = "github:hercules-ci/flake-parts"; - nix2flatpak.url = "github:Henry-Hiles/nix2flatpak/quad/fix/names"; + nix2flatpak.url = "github:Henry-Hiles/nix2flatpak/quad/nexus"; }; outputs = From 92b148f5b6564edb073215bc221e98a7abba81cb Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Mon, 21 Sep 2026 17:54:03 -0400 Subject: [PATCH 147/176] gate registration behind not flatpak --- lib/controllers/portal.dart | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/controllers/portal.dart b/lib/controllers/portal.dart index 006d39d..daae24a 100644 --- a/lib/controllers/portal.dart +++ b/lib/controllers/portal.dart @@ -1,3 +1,5 @@ +import "dart:io"; + import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:xdg_desktop_portal/xdg_desktop_portal.dart"; @@ -5,7 +7,9 @@ class PortalController extends AsyncNotifier { @override Future build() async { final portal = XdgDesktopPortalClient(); - await portal.registerApplication("nexus.federated.nexus"); + if (!await File("/.flatpak-info").exists()) { + await portal.registerApplication("nexus.federated.nexus"); + } ref.onDispose(portal.close); return portal; From 43f70f35a39578038fb6e332f07fbb5d27be416d Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Mon, 21 Sep 2026 18:00:42 -0400 Subject: [PATCH 148/176] bump nix2flatpak --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 96ae5b8..988e2bc 100644 --- a/flake.lock +++ b/flake.lock @@ -42,11 +42,11 @@ "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1790025133, - "narHash": "sha256-wxHdwhJ5SzJ8uI7hNrP0pDn+STDhzbeXRYOYPZQ1RVU=", + "lastModified": 1790028015, + "narHash": "sha256-eewOlFmEm5kgL50rAkaJrAY46t52jRLA3xw3kF52B3Q=", "owner": "Henry-Hiles", "repo": "nix2flatpak", - "rev": "56025d55f17272493678e38fa1d219d19a447bf8", + "rev": "2ac485c46cf34d27f029ad2c9a35bd622bec0d40", "type": "github" }, "original": { From 269d97be8f0ec6bfe6adda219fc6904468ca0286 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Mon, 21 Sep 2026 18:42:32 -0400 Subject: [PATCH 149/176] bump nix2flatpak --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 988e2bc..39eac15 100644 --- a/flake.lock +++ b/flake.lock @@ -42,11 +42,11 @@ "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1790028015, - "narHash": "sha256-eewOlFmEm5kgL50rAkaJrAY46t52jRLA3xw3kF52B3Q=", + "lastModified": 1790031199, + "narHash": "sha256-euXDUwHNlXubvZ5TXulw1rb8G59JK4Z88J8wQmsPCHU=", "owner": "Henry-Hiles", "repo": "nix2flatpak", - "rev": "2ac485c46cf34d27f029ad2c9a35bd622bec0d40", + "rev": "124e4b2327299bdc4afcf6c6c67a8a3673049eec", "type": "github" }, "original": { From 436b8642b3305f8d0222231532f9c49f66c239fa Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Mon, 21 Sep 2026 19:27:10 -0400 Subject: [PATCH 150/176] read not watch MultiProviderController providers Fixes random loading animations --- lib/controllers/multi_provider.dart | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/controllers/multi_provider.dart b/lib/controllers/multi_provider.dart index f1ae78c..98c01db 100644 --- a/lib/controllers/multi_provider.dart +++ b/lib/controllers/multi_provider.dart @@ -6,8 +6,10 @@ import "package:flutter_riverpod/flutter_riverpod.dart"; class MultiProviderController(final IList providers) extends AsyncNotifier { @override - Future build() => - .wait(providers.map((provider) => ref.watch(provider.future))); + Future build() => .wait( + providers.map((provider) => ref.read(provider.future)), + eagerError: true, + ); static final provider = AsyncNotifierProvider.family< From 11dca9bf143a89592d3ecad6614f11a67c0cda9c Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Mon, 21 Sep 2026 21:18:47 -0400 Subject: [PATCH 151/176] seperate URI handler desktop file --- linux/nexus.federated.nexus.desktop | 3 +-- linux/nexus.federated.nexus.uri.desktop | 8 ++++++++ linux/nix/pkg/default.nix | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 linux/nexus.federated.nexus.uri.desktop diff --git a/linux/nexus.federated.nexus.desktop b/linux/nexus.federated.nexus.desktop index a7a548a..64b4264 100644 --- a/linux/nexus.federated.nexus.desktop +++ b/linux/nexus.federated.nexus.desktop @@ -2,10 +2,9 @@ Name=Nexus GenericName=Matrix Client Comment=A simple and user-friendly Matrix client -Exec=nexus %u +Exec=nexus Icon=nexus Terminal=false Type=Application Categories=Chat;Network;InstantMessaging; -MimeType=x-scheme-handler/nexus.federated.nexus; DBusActivatable=true \ No newline at end of file diff --git a/linux/nexus.federated.nexus.uri.desktop b/linux/nexus.federated.nexus.uri.desktop new file mode 100644 index 0000000..10f495f --- /dev/null +++ b/linux/nexus.federated.nexus.uri.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Name=Nexus URI Handler +Exec=nexus %u +Icon=nexus +Terminal=false +Type=Application +NoDisplay=true +MimeType=x-scheme-handler/nexus.federated.nexus; \ No newline at end of file diff --git a/linux/nix/pkg/default.nix b/linux/nix/pkg/default.nix index 7914430..3e55dfe 100644 --- a/linux/nix/pkg/default.nix +++ b/linux/nix/pkg/default.nix @@ -39,7 +39,7 @@ flutter.buildFlutterApplication { postInstall = '' install -D assets/bundled/icon.svg $out/share/icons/hicolor/scalable/apps/nexus.svg - install -Dm755 linux/nexus.federated.nexus.desktop -t $out/share/applications + install -Dm755 linux/*.desktop -t $out/share/applications install -Dm644 linux/*.service -t $out/share/dbus-1/services wrapProgram $out/bin/nexus \ --suffix LD_LIBRARY_PATH : $out/app/nexus/lib From e4cf2a837c49231a8768ba5b9e1f6297747e4d2e Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Mon, 21 Sep 2026 21:41:18 -0400 Subject: [PATCH 152/176] fixup login --- linux/runner/my_application.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/runner/my_application.cc b/linux/runner/my_application.cc index 910bf5b..bf6e5ef 100644 --- a/linux/runner/my_application.cc +++ b/linux/runner/my_application.cc @@ -279,7 +279,7 @@ static gboolean my_application_local_command_line( *exit_status = 0; - return TRUE; + return FALSE; } static void my_application_startup( From 800ed0636d858c21f906911bf528c35c6da0b6ee Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Mon, 21 Sep 2026 22:18:24 -0400 Subject: [PATCH 153/176] bump nix2flatpak --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 39eac15..e8687c5 100644 --- a/flake.lock +++ b/flake.lock @@ -42,11 +42,11 @@ "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1790031199, - "narHash": "sha256-euXDUwHNlXubvZ5TXulw1rb8G59JK4Z88J8wQmsPCHU=", + "lastModified": 1790043059, + "narHash": "sha256-7ID4HL4IrrlalCsxMASkcAr+v0VHTNFp6+sZ+dpvOV8=", "owner": "Henry-Hiles", "repo": "nix2flatpak", - "rev": "124e4b2327299bdc4afcf6c6c67a8a3673049eec", + "rev": "290dd282e555cab988c021c2be5f2361e58c4d51", "type": "github" }, "original": { From 0cd815dc79f8d7c3911d02481e91d4afcced0938 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Mon, 21 Sep 2026 23:03:57 -0400 Subject: [PATCH 154/176] init ClientController before other providers --- lib/controllers/unified_push.dart | 2 +- lib/main.dart | 77 +++++++++++++++++++------------ 2 files changed, 49 insertions(+), 30 deletions(-) diff --git a/lib/controllers/unified_push.dart b/lib/controllers/unified_push.dart index ae31cac..7dbc386 100644 --- a/lib/controllers/unified_push.dart +++ b/lib/controllers/unified_push.dart @@ -121,7 +121,7 @@ class UnifiedPushController extends AsyncNotifier { Future register([bool alreadyRegistered = false]) async { final clientState = ref.watch(ClientStateController.provider); - if (clientState?.deviceId == null) ref.invalidateSelf(); + if (clientState?.deviceId == null) return ref.invalidateSelf(); final capabilities = await ref .watch(ClientController.provider.notifier) diff --git a/lib/main.dart b/lib/main.dart index 05b840f..903456e 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,7 +1,6 @@ import "dart:io"; import "package:dynamic_color/dynamic_color.dart"; -import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:flutter/foundation.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:media_kit/media_kit.dart"; @@ -18,7 +17,9 @@ import "package:nexus/helpers/extensions/scheme_to_theme.dart"; import "package:nexus/helpers/font_licenses.dart"; import "package:nexus/pages/chat.dart"; import "package:nexus/pages/select_server.dart"; +import "package:nexus/pages/settings.dart"; import "package:nexus/pages/verify.dart"; +import "package:nexus/widgets/appbar.dart"; import "package:nexus/widgets/error_dialog.dart"; import "package:nexus/widgets/loading.dart"; import "package:window_manager/window_manager.dart"; @@ -148,37 +149,55 @@ class const App({super.key}) extends StatelessWidget { child: Scaffold( body: Consumer( builder: (_, ref, _) => ref - .watch( - MultiProviderController.provider( - IListConst([ - ClientController.provider, - NotificationController.provider, - UnifiedPushController.provider, - MemberListOpenedController.provider, - KeyController.provider(KeyController.roomKey), - KeyController.provider(KeyController.spaceKey), - ]), - ), - ) + .watch(ClientController.provider) .betterWhen( - data: (_) => Consumer( - builder: (_, ref, _) { - final clientState = ref.watch( - ClientStateController.provider, - ); + data: (_) => ref + .watch( + MultiProviderController.provider( + .new([ + NotificationController.provider, + UnifiedPushController.provider, + MemberListOpenedController.provider, + KeyController.provider(KeyController.roomKey), + KeyController.provider(KeyController.spaceKey), + ]), + ), + ) + .betterWhen( + data: (_) => Consumer( + builder: (_, ref, _) { + final clientState = ref.watch( + ClientStateController.provider, + ); - if (clientState == null || !clientState.isInitialized) { - return Loading(); - } + if (clientState == null || + !clientState.isInitialized) { + return Loading(); + } - if (!clientState.isLoggedIn) { - return SelectServerPage(); - } else if (!clientState.isVerified) { - return VerifyPage(); - } else { - return ChatPage(); - } - }, + if (!clientState.isLoggedIn) { + return SelectServerPage(); + } else if (!clientState.isVerified) { + return VerifyPage(); + } else { + return ChatPage(); + } + }, + ), + ), + loading: () => Scaffold( + appBar: Appbar( + actions: .new([ + IconButton( + onPressed: () => showDialog( + context: context, + builder: (_) => SettingsPage(), + ), + icon: Icon(Icons.settings), + ), + ]), + ), + body: Loading(), ), ), ), From 09534a677561a1217ca81270e2d137c5778d2fa5 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 22 Sep 2026 09:53:00 -0400 Subject: [PATCH 155/176] use GomuksConfig --- .gitmodules | 3 +- gomuks | 2 +- lib/controllers/client.dart | 16 ++++++---- lib/models/gomuks_config.dart | 55 +++++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 9 deletions(-) create mode 100644 lib/models/gomuks_config.dart diff --git a/.gitmodules b/.gitmodules index 627b6b0..06dd51a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,3 @@ [submodule "gomuks"] path = gomuks - url = https://github.com/Henry-Hiles/gomuks - branch = quad/feat/customizable-device-name + url = https://github.com/gomuks/gomuks diff --git a/gomuks b/gomuks index ae11daa..b11eedc 160000 --- a/gomuks +++ b/gomuks @@ -1 +1 @@ -Subproject commit ae11daa1b14b103688e57accb9c65ad6401cb3ef +Subproject commit b11eedca121a7081d3ee48165ba363e722d18d87 diff --git a/lib/controllers/client.dart b/lib/controllers/client.dart index cd1fa13..8f6e774 100644 --- a/lib/controllers/client.dart +++ b/lib/controllers/client.dart @@ -20,6 +20,7 @@ import "package:nexus/main.dart"; import "package:nexus/models/capabilities.dart"; import "package:nexus/models/content/message.dart"; import "package:nexus/models/event.dart"; +import "package:nexus/models/gomuks_config.dart"; import "package:nexus/models/oauth_auth_code_response.dart"; import "package:nexus/models/open_graph_data.dart"; import "package:nexus/models/paginate.dart"; @@ -70,14 +71,17 @@ class ClientController extends AsyncNotifier { } } final handle = await Isolate.run(() { - final message = - "Nexus on ${toBeginningOfSentenceCase(Platform.operatingSystem)}" - .toNativeUtf8() - .cast(); + final bufferPointer = GomuksConfig( + matrix: .new( + initialDeviceDisplayName: + "Nexus on ${toBeginningOfSentenceCase(Platform.operatingSystem)}", + ), + ).toJson().toGomuksBufferPtr(); + try { - return GomuksInit(message); + return GomuksInit(bufferPointer.ref); } finally { - calloc.free(message); + calloc.free(bufferPointer); } }); diff --git a/lib/models/gomuks_config.dart b/lib/models/gomuks_config.dart new file mode 100644 index 0000000..e6a8ce7 --- /dev/null +++ b/lib/models/gomuks_config.dart @@ -0,0 +1,55 @@ +import "package:freezed_annotation/freezed_annotation.dart"; + +part "gomuks_config.freezed.dart"; +part "gomuks_config.g.dart"; + +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const GomuksConfig({ + final MatrixConfig? matrix, + final PushConfig? push, + final MediaConfig? media, +}) with _$GomuksConfig { + Map toJson() => _$GomuksConfigToJson(this); + + factory GomuksConfig.fromJson(Map json) => + _$GomuksConfigFromJson(json); +} + +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const MatrixConfig({ + @JsonKey(name: "disable_http2") final bool disableHttp2 = false, + @JsonKey(name: "set_presence") final String? setPresence, + @JsonKey(name: "initial_device_display_name") + required final String initialDeviceDisplayName, +}) with _$MatrixConfig { + Map toJson() => _$MatrixConfigToJson(this); + + factory MatrixConfig.fromJson(Map json) => + _$MatrixConfigFromJson(json); +} + +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const PushConfig({ + @JsonKey(name: "fcm_gateway") required final String fcmGateway, + @JsonKey(name: "vapid_private_key") required final String vapidPrivateKey, + @JsonKey(name: "vapid_public_key") required final String vapidPublicKey, +}) with _$PushConfig { + Map toJson() => _$PushConfigToJson(this); + + factory PushConfig.fromJson(Map json) => + _$PushConfigFromJson(json); +} + +@Freezed(toJson: false, fromJson: false) +@JsonSerializable() +class const MediaConfig({ + @JsonKey(name: "thumbnail_size") required final int thumbnailSize, +}) with _$MediaConfig { + Map toJson() => _$MediaConfigToJson(this); + + factory MediaConfig.fromJson(Map json) => + _$MediaConfigFromJson(json); +} From 0c660a98a79350fb7f64686a894a10aa10605f16 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 22 Sep 2026 09:57:10 -0400 Subject: [PATCH 156/176] just grab events out of get_mentions for now --- lib/controllers/client.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/controllers/client.dart b/lib/controllers/client.dart index 8f6e774..90f8896 100644 --- a/lib/controllers/client.dart +++ b/lib/controllers/client.dart @@ -296,9 +296,9 @@ class ClientController extends AsyncNotifier { } Future> getMentions(GetMentionsRequest request) async => .new( - ((await _sendCommand("get_mentions", request.toJson())) as List).map( - (event) => .fromJson(event), - ), + // TODO: Handle `related_events` + ((await _sendCommand("get_mentions", request.toJson()))["events"] as List) + .map((event) => .fromJson(event)), ); Future getEvent(GetEventRequest request) async { From 61f2aa7f2a2f96c559b4f6f8c448931766625786 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 22 Sep 2026 10:02:56 -0400 Subject: [PATCH 157/176] update gomuks vendorHash --- linux/nix/pkg/gomuks.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/nix/pkg/gomuks.nix b/linux/nix/pkg/gomuks.nix index f2dd5ab..ed6d8aa 100644 --- a/linux/nix/pkg/gomuks.nix +++ b/linux/nix/pkg/gomuks.nix @@ -17,7 +17,7 @@ buildGoModule ( src = "${src}/gomuks"; - vendorHash = "sha256-bAjUVgN9eHilA/21OkIcMh1a4ywL+Oqrj1JloeDufu0="; + vendorHash = "sha256-e3+bUe7IURUUaLy905a3xlRgKbkHpVfMuGlZCNSxOyU="; buildPhase = '' runHook preBuild From 386b3ad1cfe8b64ac0df22ce210f3397a449cdc7 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 22 Sep 2026 10:37:49 -0400 Subject: [PATCH 158/176] inline the mention fetch --- lib/controllers/notifications.dart | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/controllers/notifications.dart b/lib/controllers/notifications.dart index e57025e..bed3013 100644 --- a/lib/controllers/notifications.dart +++ b/lib/controllers/notifications.dart @@ -15,7 +15,7 @@ class NotificationsController([final NotificationsRequest? request]) final (unreadType, roomId) = request ?? (null, null); - final mentions = await client.getMentions( + return await client.getMentions( .new( maxTimestamp: .now(), unreadType: unreadType ?? .highlight, @@ -23,8 +23,6 @@ class NotificationsController([final NotificationsRequest? request]) roomId: roomId, ), ); - - return mentions; } Future loadOlder() async { From 6e47594a91af583dd3d8397564fda4b770b15601 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 22 Sep 2026 11:36:29 -0400 Subject: [PATCH 159/176] fix race condition on startup --- lib/controllers/multi_provider.dart | 2 +- lib/controllers/unified_push.dart | 46 +++++++------- lib/main.dart | 94 +++++++++++++++-------------- 3 files changed, 74 insertions(+), 68 deletions(-) diff --git a/lib/controllers/multi_provider.dart b/lib/controllers/multi_provider.dart index 98c01db..ab37d07 100644 --- a/lib/controllers/multi_provider.dart +++ b/lib/controllers/multi_provider.dart @@ -7,7 +7,7 @@ class MultiProviderController(final IList providers) extends AsyncNotifier { @override Future build() => .wait( - providers.map((provider) => ref.read(provider.future)), + providers.map((provider) => ref.watch(provider.future)), eagerError: true, ); diff --git a/lib/controllers/unified_push.dart b/lib/controllers/unified_push.dart index 7dbc386..719a096 100644 --- a/lib/controllers/unified_push.dart +++ b/lib/controllers/unified_push.dart @@ -22,7 +22,6 @@ class UnifiedPushController extends AsyncNotifier { Future build() async { if (!Platform.isLinux && !Platform.isAndroid) return false; - final client = ref.watch(ClientController.provider.notifier); final registered = await UnifiedPush.initialize( linuxOptions: .new( dbusName: "nexus.federated.nexus.UnifiedPush", @@ -36,21 +35,23 @@ class UnifiedPushController extends AsyncNotifier { .watch(PushKeyController.provider(instance).notifier) .set(pushKey); - await client.registerPusher( - .new( - appDisplayName: "Nexus", - appId: "nexus.federated.nexus", - data: .webPush( - url: .parse(endpoint.url), - auth: endpoint.pubKeySet!.auth, - ), - deviceDisplayName: - "Nexus on ${toBeginningOfSentenceCase(Platform.operatingSystem)}", - kind: .webPush, - lang: "en", - pushKey: pushKey, - ), - ); + await ref + .watch(ClientController.provider.notifier) + .registerPusher( + .new( + appDisplayName: "Nexus", + appId: "nexus.federated.nexus", + data: .webPush( + url: .parse(endpoint.url), + auth: endpoint.pubKeySet!.auth, + ), + deviceDisplayName: + "Nexus on ${toBeginningOfSentenceCase(Platform.operatingSystem)}", + kind: .webPush, + lang: "en", + pushKey: pushKey, + ), + ); }, onMessage: (message, instance) async { debugPrint("UP message received for $instance"); @@ -59,9 +60,9 @@ class UnifiedPushController extends AsyncNotifier { "Failed to decrypt notification. Try toggling off and on UnifiedPush in settings.", ); } - final event = await client.handlePush( - json.decode(String.fromCharCodes(message.content)), - ); + final event = await ref + .watch(ClientController.provider.notifier) + .handlePush(json.decode(String.fromCharCodes(message.content))); if (event == null || event.unreadType?.shouldNotify() != true || @@ -120,8 +121,11 @@ class UnifiedPushController extends AsyncNotifier { } Future register([bool alreadyRegistered = false]) async { - final clientState = ref.watch(ClientStateController.provider); - if (clientState?.deviceId == null) return ref.invalidateSelf(); + final clientStateProvider = ClientStateController.provider; + while (ref.watch(clientStateProvider)?.deviceId == null) { + await Future.delayed(.new(milliseconds: 250)); + } + final clientState = ref.watch(clientStateProvider); final capabilities = await ref .watch(ClientController.provider.notifier) diff --git a/lib/main.dart b/lib/main.dart index 903456e..f2794fe 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -151,54 +151,56 @@ class const App({super.key}) extends StatelessWidget { builder: (_, ref, _) => ref .watch(ClientController.provider) .betterWhen( - data: (_) => ref - .watch( - MultiProviderController.provider( - .new([ - NotificationController.provider, - UnifiedPushController.provider, - MemberListOpenedController.provider, - KeyController.provider(KeyController.roomKey), - KeyController.provider(KeyController.spaceKey), - ]), - ), - ) - .betterWhen( - data: (_) => Consumer( - builder: (_, ref, _) { - final clientState = ref.watch( - ClientStateController.provider, - ); - - if (clientState == null || - !clientState.isInitialized) { - return Loading(); - } - - if (!clientState.isLoggedIn) { - return SelectServerPage(); - } else if (!clientState.isVerified) { - return VerifyPage(); - } else { - return ChatPage(); - } - }, - ), - ), - loading: () => Scaffold( - appBar: Appbar( - actions: .new([ - IconButton( - onPressed: () => showDialog( - context: context, - builder: (_) => SettingsPage(), - ), - icon: Icon(Icons.settings), - ), + data: (_) => switch (ref.watch( + MultiProviderController.provider( + .new([ + NotificationController.provider, + UnifiedPushController.provider, + MemberListOpenedController.provider, + KeyController.provider(KeyController.roomKey), + KeyController.provider(KeyController.spaceKey), ]), ), - body: Loading(), - ), + )) { + AsyncData(value: _) || AsyncLoading(value: _?) => Consumer( + builder: (_, ref, _) { + final clientState = ref.watch( + ClientStateController.provider, + ); + + if (clientState == null || !clientState.isInitialized) { + return Loading(); + } + + if (!clientState.isLoggedIn) { + return SelectServerPage(); + } else if (!clientState.isVerified) { + return VerifyPage(); + } else { + return ChatPage(); + } + }, + ), + + AsyncLoading _ => Scaffold( + appBar: Appbar( + actions: .new([ + IconButton( + onPressed: () => showDialog( + context: context, + builder: (_) => SettingsPage(), + ), + icon: Icon(Icons.settings), + ), + ]), + ), + body: Loading(), + ), + AsyncError(:final error, :final stackTrace) => ErrorDialog( + error, + stackTrace, + ), + }, ), ), ), From 41806be9bf4e3e42836fedd134f2c63f138c465d Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 22 Sep 2026 14:34:08 -0400 Subject: [PATCH 160/176] More platform-independent approach to managing registered state --- lib/controllers/client.dart | 6 ++- lib/controllers/unified_push.dart | 85 ++++++++++++++++--------------- 2 files changed, 49 insertions(+), 42 deletions(-) diff --git a/lib/controllers/client.dart b/lib/controllers/client.dart index 90f8896..c855d0d 100644 --- a/lib/controllers/client.dart +++ b/lib/controllers/client.dart @@ -15,6 +15,7 @@ import "package:nexus/controllers/rooms.dart"; import "package:nexus/controllers/space_edges.dart"; import "package:nexus/controllers/sync_status.dart"; import "package:nexus/controllers/top_level_spaces.dart"; +import "package:nexus/controllers/unified_push.dart"; import "package:nexus/helpers/extensions/gomuks_buffer.dart"; import "package:nexus/main.dart"; import "package:nexus/models/capabilities.dart"; @@ -344,7 +345,10 @@ class ClientController extends AsyncNotifier { Future downloadMedia(DownloadMediaRequest request) async => .new((await _sendCommand("download_media", request.toJson()))["path"]); - Future logout() => _sendCommand("logout"); + Future logout() async { + await ref.watch(UnifiedPushController.provider.notifier).deregister(); + await _sendCommand("logout"); + } Future markRead(Room room) async { final eventRowId = room.timeline[room.timeline.keys.reduce(max)]; diff --git a/lib/controllers/unified_push.dart b/lib/controllers/unified_push.dart index 719a096..49a73ea 100644 --- a/lib/controllers/unified_push.dart +++ b/lib/controllers/unified_push.dart @@ -32,11 +32,11 @@ class UnifiedPushController extends AsyncNotifier { onNewEndpoint: (endpoint, instance) async { final pushKey = endpoint.pubKeySet!.pubKey; await ref - .watch(PushKeyController.provider(instance).notifier) + .read(PushKeyController.provider(instance).notifier) .set(pushKey); await ref - .watch(ClientController.provider.notifier) + .read(ClientController.provider.notifier) .registerPusher( .new( appDisplayName: "Nexus", @@ -52,6 +52,8 @@ class UnifiedPushController extends AsyncNotifier { pushKey: pushKey, ), ); + + state = .data(true); }, onMessage: (message, instance) async { debugPrint("UP message received for $instance"); @@ -61,14 +63,14 @@ class UnifiedPushController extends AsyncNotifier { ); } final event = await ref - .watch(ClientController.provider.notifier) + .read(ClientController.provider.notifier) .handlePush(json.decode(String.fromCharCodes(message.content))); if (event == null || event.unreadType?.shouldNotify() != true || (!isInBackground && await windowManager.isFocused().onError((_, _) => false) && - await ref.watch( + await ref.read( KeyController.provider(KeyController.roomKey).future, ) == event.roomId)) { @@ -103,13 +105,7 @@ class UnifiedPushController extends AsyncNotifier { if (isInBackground) exit(0); }, - onRegistrationFailed: (error, instance) => throw error, - onUnregistered: (instance) async { - await ref - .watch(PushKeyController.provider(instance).notifier) - .set(null); - ref.invalidateSelf(); - }, + onUnregistered: deregister, ); if (registered) { @@ -121,53 +117,60 @@ class UnifiedPushController extends AsyncNotifier { } Future register([bool alreadyRegistered = false]) async { - final clientStateProvider = ClientStateController.provider; - while (ref.watch(clientStateProvider)?.deviceId == null) { - await Future.delayed(.new(milliseconds: 250)); - } - final clientState = ref.watch(clientStateProvider); + state = .loading(); + try { + final clientStateProvider = ClientStateController.provider; + while (ref.read(clientStateProvider)?.deviceId == null) { + await Future.delayed(.new(milliseconds: 250)); + } + final clientState = ref.read(clientStateProvider); - final capabilities = await ref - .watch(ClientController.provider.notifier) - .getCapabilities(); + final capabilities = await ref + .read(ClientController.provider.notifier) + .getCapabilities(); - if (capabilities.webpush?.vapid == null) { - throw UnsupportedError( - "Your homeserver does not support MSC4174 (Web Push), and therefore cannot send notifications to Nexus.", + if (capabilities.webpush?.vapid == null) { + throw UnsupportedError( + "Your homeserver does not support MSC4174 (Web Push), and therefore cannot send notifications to Nexus.", + ); + } + + if (!alreadyRegistered && + !await UnifiedPush.tryUseCurrentOrDefaultDistributor()) { + throw Exception("No UnifiedPush distributors found"); + } + + await UnifiedPush.register( + instance: clientState!.deviceId!, + vapid: capabilities.webpush?.vapid, ); + } catch (_) { + state = .data(false); + rethrow; } - - if (!alreadyRegistered && - !await UnifiedPush.tryUseCurrentOrDefaultDistributor()) { - throw Exception("No UnifiedPush distributors found"); - } - - await UnifiedPush.register( - instance: clientState!.deviceId!, - vapid: capabilities.webpush?.vapid, - ); - - if (!alreadyRegistered) ref.invalidateSelf(); } - Future deregister() async { - final clientState = ref.watch(ClientStateController.provider); - final key = await ref.watch( - PushKeyController.provider(clientState!.deviceId!).future, + Future deregister([String? instance]) async { + final clientState = ref.read(ClientStateController.provider); + + final keyProvider = PushKeyController.provider( + instance ?? clientState!.deviceId!, ); + final key = await ref.read(keyProvider.future); if (key != null) { await ref - .watch(ClientController.provider.notifier) + .read(ClientController.provider.notifier) .deregisterPusher(.new(appId: "nexus.federated.nexus", pushKey: key)); + await ref.read(keyProvider.notifier).set(null); } else { debugPrint( "No matching pushKey found. Skipping deregistration from homeserver.", ); } - await UnifiedPush.unregister(clientState.deviceId!); - ref.invalidateSelf(); + await UnifiedPush.unregister(instance ?? clientState!.deviceId!); + state = .data(false); } static final provider = AsyncNotifierProvider( From 775c77194b7278040d25b48def2ccccb5c4bd0e7 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 22 Sep 2026 15:02:30 -0400 Subject: [PATCH 161/176] run in background properly on android --- lib/main.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/main.dart b/lib/main.dart index f2794fe..bdaab96 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -83,7 +83,9 @@ void main(List args) async { await windowManager.setMinimumSize(Size.square(500)); } - isInBackground = Platform.environment["FLUTTER_HEADLESS"] != null; + isInBackground = + Platform.environment["FLUTTER_HEADLESS"] != null || + args.contains("--unifiedpush-bg"); LicenseRegistry.addLicense(() => .fromIterable(fontLicenses)); From f4142859ba49531defd0a087fbcc69aa5f558fc2 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 22 Sep 2026 15:05:57 -0400 Subject: [PATCH 162/176] fallback isFocused to true --- lib/controllers/unified_push.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/controllers/unified_push.dart b/lib/controllers/unified_push.dart index 49a73ea..1a62477 100644 --- a/lib/controllers/unified_push.dart +++ b/lib/controllers/unified_push.dart @@ -69,7 +69,7 @@ class UnifiedPushController extends AsyncNotifier { if (event == null || event.unreadType?.shouldNotify() != true || (!isInBackground && - await windowManager.isFocused().onError((_, _) => false) && + await windowManager.isFocused().onError((_, _) => true) && await ref.read( KeyController.provider(KeyController.roomKey).future, ) == From f910d87a237cb67cabedf4b034d7be156a8ef062 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 22 Sep 2026 15:33:55 -0400 Subject: [PATCH 163/176] don't require login for UP controller to finish init --- lib/controllers/unified_push.dart | 7 +-- lib/main.dart | 92 +++++++++++++++---------------- 2 files changed, 45 insertions(+), 54 deletions(-) diff --git a/lib/controllers/unified_push.dart b/lib/controllers/unified_push.dart index 1a62477..59ef5d4 100644 --- a/lib/controllers/unified_push.dart +++ b/lib/controllers/unified_push.dart @@ -119,11 +119,8 @@ class UnifiedPushController extends AsyncNotifier { Future register([bool alreadyRegistered = false]) async { state = .loading(); try { - final clientStateProvider = ClientStateController.provider; - while (ref.read(clientStateProvider)?.deviceId == null) { - await Future.delayed(.new(milliseconds: 250)); - } - final clientState = ref.read(clientStateProvider); + final clientState = ref.watch(ClientStateController.provider); + if (clientState?.deviceId == null) return; final capabilities = await ref .read(ClientController.provider.notifier) diff --git a/lib/main.dart b/lib/main.dart index bdaab96..98d9a92 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -12,7 +12,6 @@ import "package:nexus/controllers/multi_provider.dart"; import "package:nexus/controllers/notification.dart"; import "package:nexus/controllers/settings.dart"; import "package:nexus/controllers/unified_push.dart"; -import "package:nexus/helpers/extensions/better_when.dart"; import "package:nexus/helpers/extensions/scheme_to_theme.dart"; import "package:nexus/helpers/font_licenses.dart"; import "package:nexus/pages/chat.dart"; @@ -150,60 +149,55 @@ class const App({super.key}) extends StatelessWidget { ), child: Scaffold( body: Consumer( - builder: (_, ref, _) => ref - .watch(ClientController.provider) - .betterWhen( - data: (_) => switch (ref.watch( - MultiProviderController.provider( - .new([ - NotificationController.provider, - UnifiedPushController.provider, - MemberListOpenedController.provider, - KeyController.provider(KeyController.roomKey), - KeyController.provider(KeyController.spaceKey), - ]), - ), - )) { - AsyncData(value: _) || AsyncLoading(value: _?) => Consumer( - builder: (_, ref, _) { - final clientState = ref.watch( - ClientStateController.provider, - ); + builder: (_, ref, _) => switch (ref.watch( + MultiProviderController.provider( + .new([ + ClientController.provider, + NotificationController.provider, + UnifiedPushController.provider, + MemberListOpenedController.provider, + KeyController.provider(KeyController.roomKey), + KeyController.provider(KeyController.spaceKey), + ]), + ), + )) { + AsyncData(value: _) || AsyncLoading(value: _?) => Consumer( + builder: (_, ref, _) { + final clientState = ref.watch(ClientStateController.provider); - if (clientState == null || !clientState.isInitialized) { - return Loading(); - } + if (clientState == null || !clientState.isInitialized) { + return Loading(); + } - if (!clientState.isLoggedIn) { - return SelectServerPage(); - } else if (!clientState.isVerified) { - return VerifyPage(); - } else { - return ChatPage(); - } - }, - ), + if (!clientState.isLoggedIn) { + return SelectServerPage(); + } else if (!clientState.isVerified) { + return VerifyPage(); + } else { + return ChatPage(); + } + }, + ), - AsyncLoading _ => Scaffold( - appBar: Appbar( - actions: .new([ - IconButton( - onPressed: () => showDialog( - context: context, - builder: (_) => SettingsPage(), - ), - icon: Icon(Icons.settings), - ), - ]), + AsyncLoading _ => Scaffold( + appBar: Appbar( + actions: .new([ + IconButton( + onPressed: () => showDialog( + context: context, + builder: (_) => SettingsPage(), ), - body: Loading(), + icon: Icon(Icons.settings), ), - AsyncError(:final error, :final stackTrace) => ErrorDialog( - error, - stackTrace, - ), - }, + ]), ), + body: Loading(), + ), + AsyncError(:final error, :final stackTrace) => ErrorDialog( + error, + stackTrace, + ), + }, ), ), ), From a2791a67173568fcd9c5bbb3bddf4641b0f3e6bd Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 22 Sep 2026 15:53:37 -0400 Subject: [PATCH 164/176] various small fixups --- lib/controllers/client.dart | 6 +----- lib/controllers/settings_sections.dart | 14 ++++++-------- lib/controllers/unified_push.dart | 5 ++--- lib/pages/select_server.dart | 11 +++++++---- 4 files changed, 16 insertions(+), 20 deletions(-) diff --git a/lib/controllers/client.dart b/lib/controllers/client.dart index c855d0d..90f8896 100644 --- a/lib/controllers/client.dart +++ b/lib/controllers/client.dart @@ -15,7 +15,6 @@ import "package:nexus/controllers/rooms.dart"; import "package:nexus/controllers/space_edges.dart"; import "package:nexus/controllers/sync_status.dart"; import "package:nexus/controllers/top_level_spaces.dart"; -import "package:nexus/controllers/unified_push.dart"; import "package:nexus/helpers/extensions/gomuks_buffer.dart"; import "package:nexus/main.dart"; import "package:nexus/models/capabilities.dart"; @@ -345,10 +344,7 @@ class ClientController extends AsyncNotifier { Future downloadMedia(DownloadMediaRequest request) async => .new((await _sendCommand("download_media", request.toJson()))["path"]); - Future logout() async { - await ref.watch(UnifiedPushController.provider.notifier).deregister(); - await _sendCommand("logout"); - } + Future logout() => _sendCommand("logout"); Future markRead(Room room) async { final eventRowId = room.timeline[room.timeline.keys.reduce(max)]; diff --git a/lib/controllers/settings_sections.dart b/lib/controllers/settings_sections.dart index 7f25cb9..7fc1b3f 100644 --- a/lib/controllers/settings_sections.dart +++ b/lib/controllers/settings_sections.dart @@ -252,16 +252,14 @@ class SettingsSectionsController final colorScheme = Theme.of(context).colorScheme; return M3EButton.icon( onPressed: () async { - Navigator.of(context) - .popUntil((route) => route.isFirst); - Navigator.of(context) - .popUntil((route) => route.isFirst); - - await WidgetsBinding.instance.endOfFrame; - + await ref + .watch(UnifiedPushController.provider.notifier) + .deregister() + .onError(showError); await ref .watch(ClientController.provider.notifier) - .logout(); + .logout() + .onError(showError); }, label: Text(title), icon: Icon(icon), diff --git a/lib/controllers/unified_push.dart b/lib/controllers/unified_push.dart index 59ef5d4..181a3d6 100644 --- a/lib/controllers/unified_push.dart +++ b/lib/controllers/unified_push.dart @@ -132,9 +132,8 @@ class UnifiedPushController extends AsyncNotifier { ); } - if (!alreadyRegistered && - !await UnifiedPush.tryUseCurrentOrDefaultDistributor()) { - throw Exception("No UnifiedPush distributors found"); + if (!await UnifiedPush.tryUseCurrentOrDefaultDistributor()) { + throw Exception("No UnifiedPush distributors found."); } await UnifiedPush.register( diff --git a/lib/pages/select_server.dart b/lib/pages/select_server.dart index 85c84cb..a903cf6 100644 --- a/lib/pages/select_server.dart +++ b/lib/pages/select_server.dart @@ -78,9 +78,11 @@ class const SelectServerPage({super.key}) extends HookConsumerWidget { ClientIdController.provider(url).future, ), ), - ) - .onError(showError); + ); } + } catch (error, stackTrace) { + showError(error, stackTrace); + rethrow; } finally { isLoading.value = false; } @@ -95,7 +97,7 @@ class const SelectServerPage({super.key}) extends HookConsumerWidget { style: .new(color: theme.colorScheme.onErrorContainer), ), action: SnackBarAction( - onPressed: () => tryLogin(newHomeserver!), + onPressed: () => tryLogin(newHomeserver!).onError(showError), label: "Attempt log in anyways", textColor: theme.colorScheme.onErrorContainer, ), @@ -103,11 +105,12 @@ class const SelectServerPage({super.key}) extends HookConsumerWidget { ), ); } else { - tryLogin(newUrl); + await tryLogin(newUrl); } } } catch (error, stackTrace) { showError(error, stackTrace); + rethrow; } finally { isLoading.value = false; } From 5738239da2075af6e6f95099f737d1ab3da95c8f Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 22 Sep 2026 18:31:38 -0400 Subject: [PATCH 165/176] fix name of ShowAboutDialog extension --- lib/helpers/extensions/show_about_dialog.dart | 2 +- lib/helpers/extensions/show_context_menu.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/helpers/extensions/show_about_dialog.dart b/lib/helpers/extensions/show_about_dialog.dart index 1d20315..38e99ba 100644 --- a/lib/helpers/extensions/show_about_dialog.dart +++ b/lib/helpers/extensions/show_about_dialog.dart @@ -5,7 +5,7 @@ import "package:m3e_card_list/m3e_card_list.dart"; import "package:nexus/helpers/launch_helper.dart"; import "package:package_info_plus/package_info_plus.dart"; -extension ShowContextMenu on BuildContext { +extension ShowAboutDialog on BuildContext { Future showAboutDialog(WidgetRef ref) async { final packageInfo = await PackageInfo.fromPlatform(); diff --git a/lib/helpers/extensions/show_context_menu.dart b/lib/helpers/extensions/show_context_menu.dart index 589942b..ccef3b5 100644 --- a/lib/helpers/extensions/show_context_menu.dart +++ b/lib/helpers/extensions/show_context_menu.dart @@ -9,7 +9,7 @@ extension ShowContextMenu on BuildContext { showMenu( context: this, - constraints: .loose(Size.infinite), + constraints: .loose(.infinite), position: .fromLTRB( globalPosition.dx, globalPosition.dy, From ece3d163181a045cbb6090499afeb94308c09b7d Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 22 Sep 2026 18:48:47 -0400 Subject: [PATCH 166/176] use dot shorthands in about dialog --- lib/helpers/extensions/show_about_dialog.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/helpers/extensions/show_about_dialog.dart b/lib/helpers/extensions/show_about_dialog.dart index 38e99ba..6ccba4c 100644 --- a/lib/helpers/extensions/show_about_dialog.dart +++ b/lib/helpers/extensions/show_about_dialog.dart @@ -50,8 +50,8 @@ extension ShowAboutDialog on BuildContext { M3ECardColumn( onTap: (index) => ref.watch(LaunchHelper.provider).launchUrl(switch (index) { - 0 => Uri.https("git.federated.nexus", "nexus/nexus"), - _ => Uri.https("liberapay.com", "QuadRadical"), + 0 => .https("git.federated.nexus", "nexus/nexus"), + _ => .https("liberapay.com", "QuadRadical"), }), children: [ ListTile( From 027033ad9e9df9adf334017d5e0584bb967b964e Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 22 Sep 2026 19:13:32 -0400 Subject: [PATCH 167/176] allow copying messages when on desktop without mobile mode on --- lib/widgets/html/html.dart | 255 ++++++++++++++++++++----------------- 1 file changed, 139 insertions(+), 116 deletions(-) diff --git a/lib/widgets/html/html.dart b/lib/widgets/html/html.dart index e4b8c01..fdb2140 100644 --- a/lib/widgets/html/html.dart +++ b/lib/widgets/html/html.dart @@ -1,7 +1,10 @@ +import "dart:io"; + import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:material_ui/material_ui.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart"; +import "package:nexus/controllers/settings.dart"; import "package:nexus/helpers/extensions/link_to_mention.dart"; import "package:nexus/helpers/launch_helper.dart"; import "package:nexus/helpers/mxc_image.dart"; @@ -18,132 +21,152 @@ class const Html( super.key, }) extends ConsumerWidget { @override - Widget build(BuildContext context, WidgetRef ref) => - // needed until https://github.com/daohoangson/flutter_widget_from_html/issues/1618 is resolved - MaterialUiCompatibilityBridge( - child: HtmlWidget( - html, - buildAsync: false, - textStyle: textStyle, - customWidgetBuilder: (element) { - if (element.attributes.keys.contains("data-mx-profile-fallback")) { - return SizedBox.shrink(); - } + Widget build(BuildContext context, WidgetRef ref) { + // needed until https://github.com/daohoangson/flutter_widget_from_html/issues/1618 is resolved + final htmlWidget = MaterialUiCompatibilityBridge( + child: HtmlWidget( + html, + buildAsync: false, + textStyle: textStyle, + customWidgetBuilder: (element) { + if (element.attributes.keys.contains("data-mx-profile-fallback")) { + return SizedBox.shrink(); + } - if (element.attributes.keys.contains("data-mx-spoiler")) { - return InlineCustomWidget(child: SpoilerText(element.text)); - } + if (element.attributes.keys.contains("data-mx-spoiler")) { + return InlineCustomWidget(child: SpoilerText(element.text)); + } - final height = - int.tryParse(element.attributes["height"] ?? "") ?? - (element.attributes.keys.contains("data-mx-emoticon") - ? 32 - : null) ?? - 300; - final width = int.tryParse(element.attributes["width"] ?? ""); - final src = Uri.tryParse(element.attributes["src"] ?? ""); + final height = + int.tryParse(element.attributes["height"] ?? "") ?? + (element.attributes.keys.contains("data-mx-emoticon") + ? 32 + : null) ?? + 300; + final width = int.tryParse(element.attributes["width"] ?? ""); + final src = Uri.tryParse(element.attributes["src"] ?? ""); - return switch (element.localName) { - "code" => - element.parent?.localName == "pre" - ? CodeBlock( - element.text, - lang: element.className.replaceAll("language-", ""), - ) - : null, + return switch (element.localName) { + "code" => + element.parent?.localName == "pre" + ? CodeBlock( + element.text, + lang: element.className.replaceAll("language-", ""), + ) + : null, - "blockquote" => Quoted( - Html(element.innerHtml, textStyle: textStyle, roomId: roomId), - ), + "blockquote" => Quoted( + Html(element.innerHtml, textStyle: textStyle, roomId: roomId), + ), - "a" => - element.attributes["href"]?.mention == null - ? null - : InlineCustomWidget( - child: MentionChip(element.attributes["href"]!, roomId), - ), + "a" => + element.attributes["href"]?.mention == null + ? null + : InlineCustomWidget( + child: MentionChip(element.attributes["href"]!, roomId), + ), - "img" => - src == null - ? SizedBox.shrink() - : InlineCustomWidget( - alignment: PlaceholderAlignment.middle, - child: ExpandableImage( - .new(mxc: src), - child: Image( - image: MxcImage(ref, .new(mxc: src)), - errorBuilder: (_, error, _) => Text( - "Image Failed to Load", - style: .new( - color: Theme.of(context).colorScheme.error, - ), + "img" => + src == null + ? SizedBox.shrink() + : InlineCustomWidget( + alignment: PlaceholderAlignment.middle, + child: ExpandableImage( + .new(mxc: src), + child: Image( + image: MxcImage(ref, .new(mxc: src)), + errorBuilder: (_, error, _) => Text( + "Image Failed to Load", + style: .new( + color: Theme.of(context).colorScheme.error, ), - height: height.toDouble(), - width: width?.toDouble(), - loadingBuilder: (_, child, loadingProgress) => - loadingProgress == null - ? child - : CircularProgressIndicator(), ), + height: height.toDouble(), + width: width?.toDouble(), + loadingBuilder: (_, child, loadingProgress) => + loadingProgress == null + ? child + : CircularProgressIndicator(), ), ), + ), - // Allowed elements list - ("del" || - "h1" || - "h2" || - "h3" || - "h4" || - "h5" || - "h6" || - "p" || - "ul" || - "ol" || - "sup" || - "sub" || - "li" || - "b" || - "i" || - "u" || - "strong" || - "em" || - "s" || - "code" || - "hr" || - "br" || - "div" || - "table" || - "thead" || - "tbody" || - "tr" || - "th" || - "td" || - "caption" || - "pre" || - "span" || - "details" || - "summary") => - null, + // Allowed elements list + ("del" || + "h1" || + "h2" || + "h3" || + "h4" || + "h5" || + "h6" || + "p" || + "ul" || + "ol" || + "sup" || + "sub" || + "li" || + "b" || + "i" || + "u" || + "strong" || + "em" || + "s" || + "code" || + "hr" || + "br" || + "div" || + "table" || + "thead" || + "tbody" || + "tr" || + "th" || + "td" || + "caption" || + "pre" || + "span" || + "details" || + "summary") => + null, - _ => SizedBox.shrink(), - }; - }, - customStylesBuilder: (element) => { - "width": "auto", - ...Map.fromEntries( - element.attributes - .mapTo?>( - (key, value) => switch (key) { - "data-mx-color" => .new("color", value), - "data-mx-bg-color" => .new("background-color", value), - _ => null, - }, - ) - .nonNulls, - ), - }, - onTapUrl: (url) => - ref.watch(LaunchHelper.provider).launchUrl(.parse(url)), - ), - ); + _ => SizedBox.shrink(), + }; + }, + customStylesBuilder: (element) => { + "width": "auto", + ...Map.fromEntries( + element.attributes + .mapTo?>( + (key, value) => switch (key) { + "data-mx-color" => .new("color", value), + "data-mx-bg-color" => .new("background-color", value), + _ => null, + }, + ) + .nonNulls, + ), + }, + onTapUrl: (url) => + ref.watch(LaunchHelper.provider).launchUrl(.parse(url)), + ), + ); + + final shouldBeSelectable = + ref + .watch(SettingsController.provider) + .when( + data: (data) => !data.linuxMobileMode, + error: (_, _) => false, + loading: () => false, + ) || + Platform.isIOS || + Platform.isAndroid; + return shouldBeSelectable + ? SelectableRegion( + contextMenuBuilder: (context, selectableRegionState) => + Text("data"), + selectionControls: materialTextSelectionControls, + child: htmlWidget, + ) + : htmlWidget; + } } From faa7292001ae1b03d7d090db2a881423454bc0b7 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 22 Sep 2026 19:19:21 -0400 Subject: [PATCH 168/176] add codeblock copy button --- lib/widgets/html/code_block.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/widgets/html/code_block.dart b/lib/widgets/html/code_block.dart index 974b74d..abd9be2 100644 --- a/lib/widgets/html/code_block.dart +++ b/lib/widgets/html/code_block.dart @@ -1,5 +1,6 @@ import "dart:math"; +import "package:flutter/services.dart"; import "package:material_ui/material_ui.dart"; class const CodeBlock( @@ -28,7 +29,7 @@ class const CodeBlock( ), ), TextButton.icon( - onPressed: () {}, + onPressed: () => Clipboard.setData(.new(text: code)), icon: Icon(Icons.copy), label: Text("Copy"), ), From 4d0a4605d6b56a6921bb06676331235a0e48acf3 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 22 Sep 2026 19:57:23 -0400 Subject: [PATCH 169/176] type contextMenuCallback --- lib/widgets/renderers/event.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/widgets/renderers/event.dart b/lib/widgets/renderers/event.dart index 8e7373a..697161f 100644 --- a/lib/widgets/renderers/event.dart +++ b/lib/widgets/renderers/event.dart @@ -1,4 +1,5 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; +import "package:flutter/gestures.dart"; import "package:material_ui/material_ui.dart"; import "package:flutter_hooks/flutter_hooks.dart"; import "package:hooks_riverpod/hooks_riverpod.dart"; @@ -152,7 +153,7 @@ class const EventRenderer( final contextMenuCallback = getEventOptions == null ? null - : (details) => context.showContextMenu( + : (PositionedGestureDetails details) => context.showContextMenu( globalPosition: details.globalPosition, children: getEventOptions!(event).toList(), ); From 023e75e0635ca30b0beca91c60e8859886f28e5f Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 22 Sep 2026 19:57:43 -0400 Subject: [PATCH 170/176] always make events selectable (on mobile the long press overrides it) --- lib/widgets/html/html.dart | 31 +++++-------------------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/lib/widgets/html/html.dart b/lib/widgets/html/html.dart index fdb2140..f10aad4 100644 --- a/lib/widgets/html/html.dart +++ b/lib/widgets/html/html.dart @@ -1,10 +1,7 @@ -import "dart:io"; - import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:material_ui/material_ui.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart"; -import "package:nexus/controllers/settings.dart"; import "package:nexus/helpers/extensions/link_to_mention.dart"; import "package:nexus/helpers/launch_helper.dart"; import "package:nexus/helpers/mxc_image.dart"; @@ -21,9 +18,10 @@ class const Html( super.key, }) extends ConsumerWidget { @override - Widget build(BuildContext context, WidgetRef ref) { + Widget build(BuildContext context, WidgetRef ref) => SelectableRegion( + selectionControls: materialTextSelectionControls, // needed until https://github.com/daohoangson/flutter_widget_from_html/issues/1618 is resolved - final htmlWidget = MaterialUiCompatibilityBridge( + child: MaterialUiCompatibilityBridge( child: HtmlWidget( html, buildAsync: false, @@ -148,25 +146,6 @@ class const Html( onTapUrl: (url) => ref.watch(LaunchHelper.provider).launchUrl(.parse(url)), ), - ); - - final shouldBeSelectable = - ref - .watch(SettingsController.provider) - .when( - data: (data) => !data.linuxMobileMode, - error: (_, _) => false, - loading: () => false, - ) || - Platform.isIOS || - Platform.isAndroid; - return shouldBeSelectable - ? SelectableRegion( - contextMenuBuilder: (context, selectableRegionState) => - Text("data"), - selectionControls: materialTextSelectionControls, - child: htmlWidget, - ) - : htmlWidget; - } + ), + ); } From 8f35ea2435f93a490626069abaf385e4c4fa6d60 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 22 Sep 2026 20:18:16 -0400 Subject: [PATCH 171/176] Add "Copy Text" context menu option --- lib/widgets/room_chat.dart | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/widgets/room_chat.dart b/lib/widgets/room_chat.dart index d8424c9..623e71f 100644 --- a/lib/widgets/room_chat.dart +++ b/lib/widgets/room_chat.dart @@ -331,6 +331,16 @@ final class const RoomChat({ }, child: ListTile(leading: Icon(Icons.link), title: Text("Copy Link")), ), + if (event.content case MessageContent(:final body?)) + PopupMenuItem( + onTap: () async { + await Clipboard.setData(ClipboardData(text: body)); + }, + child: ListTile( + leading: Icon(Icons.copy), + title: Text("Copy Text"), + ), + ), if (ref.watch( PowerLevelController.provider( .redaction(targetUser: event.sender, roomId: roomId), From ed761d6071273a3091dfcdb17e341dcccf99b74e Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 22 Sep 2026 20:40:55 -0400 Subject: [PATCH 172/176] gate selectable text behind mouse connected --- lib/widgets/html/html.dart | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/widgets/html/html.dart b/lib/widgets/html/html.dart index f10aad4..6cb60b2 100644 --- a/lib/widgets/html/html.dart +++ b/lib/widgets/html/html.dart @@ -1,4 +1,5 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; +import "package:flutter/rendering.dart"; import "package:material_ui/material_ui.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart"; @@ -18,10 +19,9 @@ class const Html( super.key, }) extends ConsumerWidget { @override - Widget build(BuildContext context, WidgetRef ref) => SelectableRegion( - selectionControls: materialTextSelectionControls, + Widget build(BuildContext context, WidgetRef ref) { // needed until https://github.com/daohoangson/flutter_widget_from_html/issues/1618 is resolved - child: MaterialUiCompatibilityBridge( + final htmlWidget = MaterialUiCompatibilityBridge( child: HtmlWidget( html, buildAsync: false, @@ -146,6 +146,13 @@ class const Html( onTapUrl: (url) => ref.watch(LaunchHelper.provider).launchUrl(.parse(url)), ), - ), - ); + ); + + return RendererBinding.instance.mouseTracker.mouseIsConnected + ? SelectableRegion( + selectionControls: materialTextSelectionControls, + child: htmlWidget, + ) + : htmlWidget; + } } From f2efbbeb9fd4c9529ffbd538536da9b17544a70c Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Tue, 22 Sep 2026 20:48:59 -0400 Subject: [PATCH 173/176] fixup select --- lib/widgets/html/html.dart | 242 ++++++++++++------------- lib/widgets/renderers/message.dart | 277 ++++++++++++----------------- 2 files changed, 229 insertions(+), 290 deletions(-) diff --git a/lib/widgets/html/html.dart b/lib/widgets/html/html.dart index 6cb60b2..85f8054 100644 --- a/lib/widgets/html/html.dart +++ b/lib/widgets/html/html.dart @@ -1,5 +1,4 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; -import "package:flutter/rendering.dart"; import "package:material_ui/material_ui.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart"; @@ -19,140 +18,133 @@ class const Html( super.key, }) extends ConsumerWidget { @override - Widget build(BuildContext context, WidgetRef ref) { - // needed until https://github.com/daohoangson/flutter_widget_from_html/issues/1618 is resolved - final htmlWidget = MaterialUiCompatibilityBridge( - child: HtmlWidget( - html, - buildAsync: false, - textStyle: textStyle, - customWidgetBuilder: (element) { - if (element.attributes.keys.contains("data-mx-profile-fallback")) { - return SizedBox.shrink(); - } + Widget + build(BuildContext context, WidgetRef ref) + // needed until https://github.com/daohoangson/flutter_widget_from_html/issues/1618 is resolved + => MaterialUiCompatibilityBridge( + child: HtmlWidget( + html, + buildAsync: false, + textStyle: textStyle, + customWidgetBuilder: (element) { + if (element.attributes.keys.contains("data-mx-profile-fallback")) { + return SizedBox.shrink(); + } - if (element.attributes.keys.contains("data-mx-spoiler")) { - return InlineCustomWidget(child: SpoilerText(element.text)); - } + if (element.attributes.keys.contains("data-mx-spoiler")) { + return InlineCustomWidget(child: SpoilerText(element.text)); + } - final height = - int.tryParse(element.attributes["height"] ?? "") ?? - (element.attributes.keys.contains("data-mx-emoticon") - ? 32 - : null) ?? - 300; - final width = int.tryParse(element.attributes["width"] ?? ""); - final src = Uri.tryParse(element.attributes["src"] ?? ""); + final height = + int.tryParse(element.attributes["height"] ?? "") ?? + (element.attributes.keys.contains("data-mx-emoticon") + ? 32 + : null) ?? + 300; + final width = int.tryParse(element.attributes["width"] ?? ""); + final src = Uri.tryParse(element.attributes["src"] ?? ""); - return switch (element.localName) { - "code" => - element.parent?.localName == "pre" - ? CodeBlock( - element.text, - lang: element.className.replaceAll("language-", ""), - ) - : null, + return switch (element.localName) { + "code" => + element.parent?.localName == "pre" + ? CodeBlock( + element.text, + lang: element.className.replaceAll("language-", ""), + ) + : null, - "blockquote" => Quoted( - Html(element.innerHtml, textStyle: textStyle, roomId: roomId), - ), + "blockquote" => Quoted( + Html(element.innerHtml, textStyle: textStyle, roomId: roomId), + ), - "a" => - element.attributes["href"]?.mention == null - ? null - : InlineCustomWidget( - child: MentionChip(element.attributes["href"]!, roomId), - ), + "a" => + element.attributes["href"]?.mention == null + ? null + : InlineCustomWidget( + child: MentionChip(element.attributes["href"]!, roomId), + ), - "img" => - src == null - ? SizedBox.shrink() - : InlineCustomWidget( - alignment: PlaceholderAlignment.middle, - child: ExpandableImage( - .new(mxc: src), - child: Image( - image: MxcImage(ref, .new(mxc: src)), - errorBuilder: (_, error, _) => Text( - "Image Failed to Load", - style: .new( - color: Theme.of(context).colorScheme.error, - ), + "img" => + src == null + ? SizedBox.shrink() + : InlineCustomWidget( + alignment: PlaceholderAlignment.middle, + child: ExpandableImage( + .new(mxc: src), + child: Image( + image: MxcImage(ref, .new(mxc: src)), + errorBuilder: (_, error, _) => Text( + "Image Failed to Load", + style: .new( + color: Theme.of(context).colorScheme.error, ), - height: height.toDouble(), - width: width?.toDouble(), - loadingBuilder: (_, child, loadingProgress) => - loadingProgress == null - ? child - : CircularProgressIndicator(), ), + height: height.toDouble(), + width: width?.toDouble(), + loadingBuilder: (_, child, loadingProgress) => + loadingProgress == null + ? child + : CircularProgressIndicator(), ), ), + ), - // Allowed elements list - ("del" || - "h1" || - "h2" || - "h3" || - "h4" || - "h5" || - "h6" || - "p" || - "ul" || - "ol" || - "sup" || - "sub" || - "li" || - "b" || - "i" || - "u" || - "strong" || - "em" || - "s" || - "code" || - "hr" || - "br" || - "div" || - "table" || - "thead" || - "tbody" || - "tr" || - "th" || - "td" || - "caption" || - "pre" || - "span" || - "details" || - "summary") => - null, + // Allowed elements list + ("del" || + "h1" || + "h2" || + "h3" || + "h4" || + "h5" || + "h6" || + "p" || + "ul" || + "ol" || + "sup" || + "sub" || + "li" || + "b" || + "i" || + "u" || + "strong" || + "em" || + "s" || + "code" || + "hr" || + "br" || + "div" || + "table" || + "thead" || + "tbody" || + "tr" || + "th" || + "td" || + "caption" || + "pre" || + "span" || + "details" || + "summary") => + null, - _ => SizedBox.shrink(), - }; - }, - customStylesBuilder: (element) => { - "width": "auto", - ...Map.fromEntries( - element.attributes - .mapTo?>( - (key, value) => switch (key) { - "data-mx-color" => .new("color", value), - "data-mx-bg-color" => .new("background-color", value), - _ => null, - }, - ) - .nonNulls, - ), - }, - onTapUrl: (url) => - ref.watch(LaunchHelper.provider).launchUrl(.parse(url)), - ), - ); - - return RendererBinding.instance.mouseTracker.mouseIsConnected - ? SelectableRegion( - selectionControls: materialTextSelectionControls, - child: htmlWidget, - ) - : htmlWidget; - } + _ => SizedBox.shrink(), + }; + }, + customStylesBuilder: (element) => { + "width": "auto", + ...Map.fromEntries( + element.attributes + .mapTo?>( + (key, value) => switch (key) { + "data-mx-color" => .new("color", value), + "data-mx-bg-color" => .new("background-color", value), + _ => null, + }, + ) + .nonNulls, + ), + }, + onTapUrl: (url) => + ref.watch(LaunchHelper.provider).launchUrl(.parse(url)), + ), + ); } diff --git a/lib/widgets/renderers/message.dart b/lib/widgets/renderers/message.dart index 99c3141..a0bbf99 100644 --- a/lib/widgets/renderers/message.dart +++ b/lib/widgets/renderers/message.dart @@ -1,4 +1,5 @@ import "package:collection/collection.dart"; +import "package:flutter/rendering.dart"; import "package:material_ui/material_ui.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:linkify/linkify.dart"; @@ -40,6 +41,111 @@ class const MessageRenderer( fontStyle: event.content is EmoteMessageContent ? .italic : null, ); + final rendered = switch (event.content) { + EncryptedContent() => Text("Unable to decrypt event", style: errorStyle), + StickerContent(:final body, :final url, :final info) => + textOnly + ? Text(body, maxLines: maxLines, overflow: .ellipsis) + : ConstrainedBox( + constraints: .loose(.square(200)), + child: MessageImage(url, info: info, encrypted: false), + ), + // TODO: Handle locations + // LocationMessageContent(:final body , :final geoUri) => + TextMessageContent(:final body, :final formattedBody, :final format) || + NoticeMessageContent(:final body, :final formattedBody, :final format) || + EmoteMessageContent(:final body, :final formattedBody, :final format) || + ImageMessageContent(:final body, :final formattedBody, :final format) || + VideoMessageContent(:final body, :final formattedBody, :final format) || + AudioMessageContent(:final body, :final formattedBody, :final format) || + FileMessageContent( + :final body, + :final formattedBody, + :final format, + ) => Column( + crossAxisAlignment: .start, + children: [ + format == .html && !textOnly + ? Html( + roomId: event.roomId, + textStyle: textStyle, + formattedBody!.replaceAllMapped( + RegExp( + r"(]*>.*?<\/a>)|(\bhttps?:\/\/[^\s<]+)", + caseSensitive: false, + dotAll: true, + ), + (m) { + // If it's already an tag, leave it unchanged + if (m.group(1) != null) { + return m.group(1)!; + } + + // Otherwise, wrap the bare URL + final url = m.group(2)!; + return "$url"; + }, + ), + ) + : LinkifiedText(body, style: textStyle, maxLines: maxLines), + + if (!textOnly) ...[ + if (event.content + case ImageMessageContent(:final url) || + FileMessageContent(:final url) || + VideoMessageContent(:final url) || + AudioMessageContent(:final url)) + ConstrainedBox( + constraints: .loose(.square(500)), + child: switch (event.content) { + VideoMessageContent(:final info, :final file) => VideoPlayer( + url, + info, + encrypted: file != null, + ), + AudioMessageContent(:final info, :final file) => AudioPlayer( + url, + info, + + encrypted: file != null, + ), + FileMessageContent(:final info, :final filename) => FileCard( + url, + info, + filename: filename, + ), + ImageMessageContent(:final info, :final file) => MessageImage( + url, + info: info, + encrypted: file != null, + ), + _ => SizedBox.shrink(), + }, + ), + + if (event.lastEditRowId != 0) + Text("(edited)", style: theme.textTheme.labelSmall), + + if (linkify(body) + .firstWhereOrNull((element) => element is UrlElement) + case final UrlElement link?) + if (Uri.tryParse(link.url) case final Uri url?) UrlPreview(url), + ], + ], + ), + MessageContent(:final body) => + body == null + ? Text("This message is redacted", style: errorStyle) + : Wrap( + spacing: 8, + children: [ + Text("Unknown message type:", style: errorStyle), + Text(body), + ], + ), + _ => throw Exception("This is impossible"), + }; + return Row( crossAxisAlignment: .start, mainAxisSize: .min, @@ -113,172 +219,13 @@ class const MessageRenderer( ), ), ), - switch (event.content) { - EncryptedContent() => Text( - "Unable to decrypt event", - style: errorStyle, - ), - StickerContent(:final body, :final url, :final info) => - textOnly - ? Text( - body, - maxLines: maxLines, - overflow: .ellipsis, - ) - : ConstrainedBox( - constraints: .loose(.square(200)), - child: MessageImage( - url, - info: info, - encrypted: false, - ), - ), - // TODO: Handle locations - // LocationMessageContent(:final body , :final geoUri) => - TextMessageContent( - :final body, - :final formattedBody, - :final format, - ) || - NoticeMessageContent( - :final body, - :final formattedBody, - :final format, - ) || - EmoteMessageContent( - :final body, - :final formattedBody, - :final format, - ) || - ImageMessageContent( - :final body, - :final formattedBody, - :final format, - ) || - VideoMessageContent( - :final body, - :final formattedBody, - :final format, - ) || - AudioMessageContent( - :final body, - :final formattedBody, - :final format, - ) || - FileMessageContent( - :final body, - :final formattedBody, - :final format, - ) => Column( - crossAxisAlignment: .start, - children: [ - format == .html && !textOnly - ? Html( - roomId: event.roomId, - textStyle: textStyle, - formattedBody!.replaceAllMapped( - RegExp( - r"(]*>.*?<\/a>)|(\bhttps?:\/\/[^\s<]+)", - caseSensitive: false, - dotAll: true, - ), - (m) { - // If it's already an tag, leave it unchanged - if (m.group(1) != null) { - return m.group(1)!; - } - // Otherwise, wrap the bare URL - final url = m.group(2)!; - return "$url"; - }, - ), - ) - : LinkifiedText( - body, - style: textStyle, - maxLines: maxLines, - ), - - if (!textOnly) ...[ - if (event.content - case ImageMessageContent(:final url) || - FileMessageContent(:final url) || - VideoMessageContent(:final url) || - AudioMessageContent(:final url)) - ConstrainedBox( - constraints: .loose(.square(500)), - child: switch (event.content) { - VideoMessageContent( - :final info, - :final file, - ) => - VideoPlayer( - url, - info, - encrypted: file != null, - ), - AudioMessageContent( - :final info, - :final file, - ) => - AudioPlayer( - url, - info, - - encrypted: file != null, - ), - FileMessageContent( - :final info, - :final filename, - ) => - FileCard(url, info, filename: filename), - ImageMessageContent( - :final info, - :final file, - ) => - MessageImage( - url, - info: info, - encrypted: file != null, - ), - _ => SizedBox.shrink(), - }, - ), - - if (event.lastEditRowId != 0) - Text( - "(edited)", - style: theme.textTheme.labelSmall, - ), - - if (linkify(body).firstWhereOrNull( - (element) => element is UrlElement, - ) - case final UrlElement link?) - if (Uri.tryParse(link.url) case final Uri url?) - UrlPreview(url), - ], - ], - ), - MessageContent(:final body) => - body == null - ? Text( - "This message is redacted", - style: errorStyle, - ) - : Wrap( - spacing: 8, - children: [ - Text( - "Unknown message type:", - style: errorStyle, - ), - Text(body), - ], - ), - _ => throw Exception("This is impossible"), - }, + RendererBinding.instance.mouseTracker.mouseIsConnected + ? SelectableRegion( + selectionControls: materialTextSelectionControls, + child: rendered, + ) + : rendered, if (!textOnly) ReactionRow(event), ], ), From a90bf00f18c450d39b763a1b7f11b8c4f621abe9 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 23 Sep 2026 10:30:12 -0400 Subject: [PATCH 174/176] dispose notif handler --- lib/controllers/notification.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/controllers/notification.dart b/lib/controllers/notification.dart index 5d343cc..681c625 100644 --- a/lib/controllers/notification.dart +++ b/lib/controllers/notification.dart @@ -68,6 +68,8 @@ class NotificationController ); } }); + + ref.onDispose(() => notificationChannel.setMethodCallHandler(null)); } return notifications; From 5d994bf2bb4cc3bc7f210047bba53d28cf988d91 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 23 Sep 2026 11:15:04 -0400 Subject: [PATCH 175/176] wait for metadata to come in on notif's rooms before sending them --- lib/controllers/unified_push.dart | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/lib/controllers/unified_push.dart b/lib/controllers/unified_push.dart index 181a3d6..72e29b2 100644 --- a/lib/controllers/unified_push.dart +++ b/lib/controllers/unified_push.dart @@ -1,3 +1,4 @@ +import "dart:async"; import "dart:convert"; import "dart:io"; @@ -78,10 +79,29 @@ class UnifiedPushController extends AsyncNotifier { return; } - final room = ref.read( - RoomsController.provider.select((rooms) => rooms[event.roomId]), + final provider = RoomsController.provider.select( + (rooms) => rooms[event.roomId], ); + if (ref.read(provider)?.metadata == null) { + final completer = Completer(); + + final subscription = ref.listen(provider, (previous, next) { + if (next?.metadata != null && !completer.isCompleted) { + completer.complete(); + } + }, fireImmediately: true); + + try { + await completer.future.timeout(.new(seconds: 10)); + } on TimeoutException { + // metadata didn't show up in time + } finally { + subscription.close(); + } + } + + final room = ref.read(provider); final avatar = room?.metadata?.avatar; final icon = avatar == null ? null From 721349ca2159ce50d764fe0df7cc86933867f395 Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 23 Sep 2026 11:22:47 -0400 Subject: [PATCH 176/176] explicit listener for ClientStateController in notifs --- lib/controllers/unified_push.dart | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/controllers/unified_push.dart b/lib/controllers/unified_push.dart index 72e29b2..1b52895 100644 --- a/lib/controllers/unified_push.dart +++ b/lib/controllers/unified_push.dart @@ -128,19 +128,26 @@ class UnifiedPushController extends AsyncNotifier { onUnregistered: deregister, ); + ref.listen( + ClientStateController.provider.select((value) => value?.deviceId), + (_, _) => register(), + ); + if (registered) { // Needs to be registered every startup - await register(true); + await register(); } return registered; } - Future register([bool alreadyRegistered = false]) async { + Future register() async { state = .loading(); try { - final clientState = ref.watch(ClientStateController.provider); - if (clientState?.deviceId == null) return; + final deviceId = ref.read( + ClientStateController.provider.select((value) => value?.deviceId), + ); + if (deviceId == null) return; final capabilities = await ref .read(ClientController.provider.notifier) @@ -157,7 +164,7 @@ class UnifiedPushController extends AsyncNotifier { } await UnifiedPush.register( - instance: clientState!.deviceId!, + instance: deviceId, vapid: capabilities.webpush?.vapid, ); } catch (_) {