diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml index 5f16f9f..08e9093 100644 --- a/.github/workflows/ios.yml +++ b/.github/workflows/ios.yml @@ -1,48 +1,50 @@ -name: "Build iOS App" +name: "Build IPA" 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: Set up Flutter - uses: subosito/flutter-action@v2 - with: - flutter-version: 3.44.4 + - 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: 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 - - name: Build app - run: | - flutter pub get - dart scripts/generate.dart - flutter pub run build_runner build - flutter build ios --release --no-codesign + FLUTTER_ROOT="$(dirname "$(dirname "$(readlink -f "$(command -v flutter)")")")" + sudo find -L "$FLUTTER_ROOT" -type d -iname "*.framework" -exec chmod -R u+w {} + - # 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 build ios --release --no-codesign + ' - - name: Upload IPA artifact - uses: actions/upload-artifact@v6 - with: - name: Nexus.ipa - path: Nexus.ipa + # 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 1476116..df7a47a 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -1,47 +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: Set up Flutter - uses: subosito/flutter-action@v2 - with: - flutter-version: 3.44.4 + - 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: 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 - - name: Build App - run: | - flutter pub get - dart scripts/generate.dart - flutter pub run build_runner build - flutter build macos --release + FLUTTER_ROOT="$(dirname "$(dirname "$(readlink -f "$(command -v flutter)")")")" + sudo find -L "$FLUTTER_ROOT" -type d -iname "*.framework" -exec chmod -R u+w {} + - - name: Create DMG - id: create-dmg - uses: L-Super/create-dmg-actions@28511e988b13ca34096d439159a66d468b8e724f - with: - dmg_name: nexus - src_dir: build/macos/Build/Products/Release/Nexus.app + flutter build macos --release + ' - - name: Upload DMG - uses: actions/upload-artifact@v6 - with: - name: nexus.dmg - path: ${{ steps.create-dmg.outputs.dmg_path }} + - name: Upload installer artifact + uses: actions/upload-artifact@v6 + with: + name: App + path: build/macos/Build/Products/Release/Nexus.app diff --git a/.gitignore b/.gitignore index 2bec583..935a117 100644 --- a/.gitignore +++ b/.gitignore @@ -41,4 +41,7 @@ key.properties password.txt # Nix -/result \ No newline at end of file +/result + +# Local IPA builds +*.ipa \ No newline at end of file diff --git a/README.md b/README.md index 0c18acf..57b42d8 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 -- [x] Platform Support +- [ ] 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 - [x] Android - - [x] MacOS - Unsigned .dmg only - - [x] iOS - Unsigned .ipa only + - [ ] MacOS ([#50](https://git.federated.nexus/Nexus/nexus/issues/50)) + - [ ] iOS - [ ] Web (may not be possible) - [x] Login (via OAuth) - [x] Rooms / Spaces @@ -116,9 +116,6 @@ 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) - 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) @@ -129,8 +126,8 @@ If you want to try out Nexus, grab one of the following artifacts from CI: #### Linux -- 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. +- 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. #### Windows diff --git a/flake.lock b/flake.lock index b743efe..41cfb9d 100644 --- a/flake.lock +++ b/flake.lock @@ -5,11 +5,11 @@ "nixpkgs-lib": "nixpkgs-lib" }, "locked": { - "lastModified": 1785627969, - "narHash": "sha256-4dtXQk/NMePegK/nWp5NSeuZKLATItOq61lpEvmXqGw=", + "lastModified": 1782949081, + "narHash": "sha256-vp6Y/Grm98ESt6ceOkWiHWyZRDV3J1RID4w+6NWK9yA=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "427bf4bd9435fdf21321c8cc628c24efc14c0f7a", + "rev": "17c9d6cdfc60c64f4ee8d306f9bc0b4ccb51481e", "type": "github" }, "original": { @@ -73,11 +73,11 @@ }, "nixpkgs-lib": { "locked": { - "lastModified": 1785031560, - "narHash": "sha256-OmshNvn2vupOFpYinLUu+1Dnpu4n7Q5N3ggGVNHpkUI=", + "lastModified": 1782614948, + "narHash": "sha256-ePjCwr1sNm9NYUqywL7QfK3JnlS015msC+eBu2zKlp8=", "owner": "nix-community", "repo": "nixpkgs.lib", - "rev": "0e79af5e3d4dcfcd676ab5ba3f95d2e3352e078c", + "rev": "db3f255737b94216eb71cce308e2912cf6bc2d7c", "type": "github" }, "original": { @@ -88,11 +88,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1785967620, - "narHash": "sha256-IItrdb7Puk05RqOBWZYFC5X6Wl1sJmCfh5MWVHw5iMM=", + "lastModified": 1784497964, + "narHash": "sha256-vlHUuqAcbcH2RKmHbPiuQzbv1pnzzavXnI62RD0bqCU=", "owner": "nixos", "repo": "nixpkgs", - "rev": "b7c2ada94fe99c15b0dbcf4d11fd7850b957a436", + "rev": "241313f4e8e508cb9b13278c2b0fa25b9ca27163", "type": "github" }, "original": { diff --git a/hook/build.dart b/hook/build.dart index a893544..4c89389 100644 --- a/hook/build.dart +++ b/hook/build.dart @@ -29,7 +29,6 @@ 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", @@ -37,7 +36,6 @@ 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"; @@ -50,10 +48,7 @@ Future main(List args) => build(args, (input, output) async { break; case OS.macOS: libFileName = "libgomuks.dylib"; - extraEnv = { - "SDKROOT": await getXCodeTool(), - "MACOSX_DEPLOYMENT_TARGET": codeConfig.macOS.targetVersion.toString(), - }; + extraEnv = {"SDKROOT": await getXCodeTool()}; break; case OS.windows: libFileName = "libgomuks.dll"; 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 1682af0..0d531c4 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png index 51f4a9b..da4acee 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ 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 index 97b3b3f..a3cfb1d 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ 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 17d971e..adbdcd5 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ 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 ca74554..fee4302 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ 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 index 6129702..4d21624 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ 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 16c3d1e..3e7a859 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ 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 index 97b3b3f..a3cfb1d 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ 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 f515ebd..518d397 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ 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 2e49a13..25f2b47 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ 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 66b9ef2..8f79bb9 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png differ 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 53af9ff..c48dec6 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png differ 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 455803d..99d44e8 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png differ 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 7a2fd0f..6f987f0 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png differ 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 2e49a13..25f2b47 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ 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 c34ad9e..fcf969a 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ 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 5e21545..16dea29 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png differ 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 2140e17..3366fb5 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png differ 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 a27d854..81c9cb8 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ 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 8b4eb75..efda04b 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png index 21c424b..3774574 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/lib/controllers/client.dart b/lib/controllers/client.dart index b7d1eb4..e31e4f3 100644 --- a/lib/controllers/client.dart +++ b/lib/controllers/client.dart @@ -38,7 +38,6 @@ 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"; @@ -214,11 +213,10 @@ class ClientController extends AsyncNotifier { } } - 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 joinRoom(JoinRoomRequest request) async { + final response = await _sendCommand("join_room", request.toJson()); + return response["room_id"]; + } Future leaveRoom(Room room) async { if (room.metadata == null) return; @@ -313,7 +311,7 @@ class ClientController extends AsyncNotifier { Future discoverHomeserver(Uri homeserver) async { try { final response = await _sendCommand("discover_homeserver", { - "user_id": "@fake-user:${homeserver.authority}", + "user_id": "@fake-user:${homeserver.host}", }); return Uri.parse(response["m.homeserver"]?["base_url"]); } catch (error) { diff --git a/lib/controllers/room_chat.dart b/lib/controllers/room_chat.dart index 35038a0..3e531bb 100644 --- a/lib/controllers/room_chat.dart +++ b/lib/controllers/room_chat.dart @@ -75,13 +75,12 @@ 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 - .read(ClientController.provider.notifier) + .watch(ClientController.provider.notifier) .paginate( .new( roomId: roomId, @@ -91,30 +90,26 @@ class RoomChatController extends AsyncNotifier?> { ), ); - 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, - ), + ref + .watch(RoomsController.provider.notifier) + .update( + IMap({ + roomId: Room( + events: IMap.fromIterable( + response.events.addAll(response.relatedEvents), + keyMapper: (event) => event.rowId, + valueMapper: (event) => event, ), - }), - .new(), - ); - } + hasMore: response.hasMore, + timeline: IMap.fromIterable( + response.events, + keyMapper: (event) => event.timelineRowId, + valueMapper: (event) => event.rowId, + ), + ), + }), + .new(), + ); return response.hasMore; } diff --git a/lib/controllers/room_summary.dart b/lib/controllers/room_summary.dart deleted file mode 100644 index d47d8ef..0000000 --- a/lib/controllers/room_summary.dart +++ /dev/null @@ -1,18 +0,0 @@ -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 8c107e3..572d2e9 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 .fromJson(json.decode(await file.readAsString())); + return Settings.fromJson(json.decode(await file.readAsString())); } catch (_) { - return .new(); + return Settings(); } } Future set(Settings settings) async { - state = .data(settings); + state = AsyncData(settings); final file = await ref.watch(SettingsFileController.provider.future); await file.writeAsString(json.encode(settings.toJson())); } diff --git a/lib/helpers/extensions/link_to_mention.dart b/lib/helpers/extensions/link_to_mention.dart index 8595669..f4868d3 100644 --- a/lib/helpers/extensions/link_to_mention.dart +++ b/lib/helpers/extensions/link_to_mention.dart @@ -9,7 +9,6 @@ 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(); diff --git a/lib/main.dart b/lib/main.dart index aabfe47..53cc57b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -112,7 +112,7 @@ class App extends StatelessWidget { data: (settings) => settings.useDynamicTheming ? lightDynamic : null, ) ?? - ThemeData.light().colorScheme) + ColorScheme.fromSeed(seedColor: Colors.indigo)) .theme, darkTheme: (ref @@ -122,7 +122,10 @@ class App extends StatelessWidget { data: (settings) => settings.useDynamicTheming ? darkDynamic : null, ) ?? - ThemeData.dark().colorScheme) + ColorScheme.fromSeed( + seedColor: Colors.indigo, + brightness: Brightness.dark, + )) .theme, themeMode: ref .watch(SettingsController.provider) diff --git a/lib/models/requests/join_room.dart b/lib/models/requests/join_room.dart index 72cce7f..8487298 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, - @Default(IList.empty()) IList via, + required IList via, }) = _JoinRoomRequest; factory JoinRoomRequest.fromJson(Map json) => diff --git a/lib/models/room_summary.dart b/lib/models/room_summary.dart deleted file mode 100644 index d0ee96b..0000000 --- a/lib/models/room_summary.dart +++ /dev/null @@ -1,23 +0,0 @@ -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/pages/select_server.dart b/lib/pages/select_server.dart index e8e689b..853e5fc 100644 --- a/lib/pages/select_server.dart +++ b/lib/pages/select_server.dart @@ -26,17 +26,6 @@ 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 { @@ -44,14 +33,26 @@ class SelectServerPage extends HookConsumerWidget { newHomeserver = Uri.https(newHomeserver!.path); } - final newUrl = await ref - .read(ClientController.provider.notifier) - .discoverHomeserver(newHomeserver!); + final newUrl = newHomeserver == null + ? null + : await ref + .read(ClientController.provider.notifier) + .discoverHomeserver(newHomeserver); if (context.mounted) { - Future tryLogin(Uri url) async { + 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 { final codeResponse = await ref.watch( - AuthUrlController.provider(url).future, + AuthUrlController.provider(newUrl).future, ); await ref.watch(LaunchHelper.provider).launchUrl(codeResponse.url); @@ -69,7 +70,7 @@ class SelectServerPage extends HookConsumerWidget { .watch(ClientController.provider.notifier) .exchangeToken( .new( - homeserverUrl: url, + homeserverUrl: newUrl, codeVerifier: codeResponse.codeVerifier, redirectUri: .new( scheme: "nexus.federated.nexus", @@ -77,7 +78,7 @@ class SelectServerPage extends HookConsumerWidget { ), code: code, clientId: await ref.watch( - ClientIdController.provider(url).future, + ClientIdController.provider(newUrl).future, ), ), ) @@ -88,25 +89,6 @@ 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); diff --git a/lib/widgets/composer/composer.dart b/lib/widgets/composer/composer.dart index 8b7fec4..5eb7db3 100644 --- a/lib/widgets/composer/composer.dart +++ b/lib/widgets/composer/composer.dart @@ -235,11 +235,9 @@ class Composer extends HookConsumerWidget { maxLines: 12, minLines: 1, autofocus: - (Platform.isLinux || - Platform.isMacOS || - Platform.isWindows) - ? true - : false, + Platform.isLinux || + Platform.isMacOS || + Platform.isWindows, decoration: .new( hintText: "Your message here...", border: .none, diff --git a/lib/widgets/html/mention_chip.dart b/lib/widgets/html/mention_chip.dart index 57e23b4..f6105e3 100644 --- a/lib/widgets/html/mention_chip.dart +++ b/lib/widgets/html/mention_chip.dart @@ -1,11 +1,8 @@ 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; @@ -15,48 +12,29 @@ class MentionChip extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final mention = content.mention; - 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, - }; + final membership = mention?.startsWith("@") == true + ? ref + .watch( + UserController.provider(.new(roomId: roomId, userId: mention!)), + ) + .whenOrNull(data: (data) => data) + : null; return mention == null ? SizedBox.shrink() : InkWell( onTap: () { - if (data case MembershipContent membership) { + if (membership != null) { context.showUserPopover(membership, mention, roomId: roomId); - } else if (data case RoomSummary summary) { - // 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, - }, + (membership?.displayName == null + ? null + : "@${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 01908a8..e867008 100644 --- a/lib/widgets/room_chat.dart +++ b/lib/widgets/room_chat.dart @@ -80,7 +80,6 @@ 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( @@ -106,7 +105,7 @@ class RoomChat extends HookConsumerWidget { Future loadOlder() async { if (controllerData case AsyncData(:final value?)) { topEventBeforeLoad.value = value.firstOrNull?.eventId; - hasMore.value = await notifier.loadOlder(); + await notifier.loadOlder(); } } @@ -311,7 +310,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)", ), ); }, @@ -467,24 +466,23 @@ class RoomChat extends HookConsumerWidget { child: switch (controllerData) { AsyncData(:final value?) || AsyncLoading(:final value?) => CustomScrollView( + controller: scrollController, keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag, - controller: scrollController, slivers: [ - if (hasMore.value) - SliverToBoxAdapter( - child: Padding( - padding: .symmetric(vertical: 36), - child: Center( - child: ElevatedButton( - onPressed: controllerData is AsyncData - ? loadOlder - : null, - child: Text("Load More"), - ), + 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, diff --git a/lib/widgets/room_menu.dart b/lib/widgets/room_menu.dart index e99991f..95936df 100644 --- a/lib/widgets/room_menu.dart +++ b/lib/widgets/room_menu.dart @@ -35,7 +35,8 @@ 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)", ), ); }, diff --git a/macos/Podfile b/macos/Podfile index 65543e2..ff5ddb3 100644 --- a/macos/Podfile +++ b/macos/Podfile @@ -1,4 +1,4 @@ -platform :osx, '13.0' +platform :osx, '10.15' # 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 fa18d44..67876ad 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 = 13.0; + MACOSX_DEPLOYMENT_TARGET = 10.15; 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 = 13.0; + MACOSX_DEPLOYMENT_TARGET = 10.15; 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 = 13.0; + MACOSX_DEPLOYMENT_TARGET = 10.15; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json index 96d3fee..a2ec33f 100644 --- a/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,68 +1,68 @@ { - "info": { - "version": 1, - "author": "xcode" + "images" : [ + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_16.png", + "scale" : "1x" }, - "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 + { + "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" + } +} 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 1682af0..82b6f9d 100644 Binary files a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ 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 c2e488b..13b35eb 100644 Binary files a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png index e2bf256..0a3f5fa 100644 Binary files a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ 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 983d7fa..bdb5722 100644 Binary files a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ 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 c8f0676..f083318 100644 Binary files a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ 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 468be1f..326c0e7 100644 Binary files a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png index a77207d..2f1632c 100644 Binary files a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/pubspec.lock b/pubspec.lock index 9be2c20..c204b95 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -293,10 +293,10 @@ packages: dependency: "direct main" description: name: dynamic_color - sha256: "4aeb76de323e8eb660bab5557d826ad7ebbf1434a598f0c6aa8a11a9696a6757" + sha256: "43a5a6679649a7731ab860334a5812f2067c2d9ce6452cf069c5e0c25336c17c" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.8.1" dynamic_polls: dependency: "direct main" description: @@ -366,10 +366,10 @@ packages: dependency: "direct main" description: name: ffigen - sha256: "56fc0be88937409839a59c133dfdee4165e80da324c9e39f59013060249ffb44" + sha256: b7803707faeec4ce3c1b0c2274906504b796e3b70ad573577e72333bd1c9b3ba url: "https://pub.dev" source: hosted - version: "21.0.0" + version: "20.1.1" file: dependency: transitive description: @@ -762,10 +762,10 @@ packages: dependency: "direct dev" description: name: json_serializable - sha256: e45aefa0324f08c683caafbb94b72837aa6193c61822799c916e45f4a263113d + sha256: ffcd10cde35a93b2abbbcc26bd9971f4ca93763e8abe78d855e3c4177797e501 url: "https://pub.dev" source: hosted - version: "6.14.1" + version: "6.14.0" leak_tracker: dependency: transitive description: @@ -819,10 +819,10 @@ packages: dependency: "direct main" description: name: m3e_buttons - sha256: "20b29df165d4d866ffd0d4808090210740690707705f44fc61c9b275bec3af36" + sha256: af1b19bd5ec7327d20b5a57c6c91e1ed30ee15a4dbade781c0cdbc72e6b04b5e url: "https://pub.dev" source: hosted - version: "0.0.5" + version: "0.0.4" m3e_card_list: dependency: "direct main" description: @@ -951,14 +951,6 @@ 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 e74d5d7..72748b1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,98 +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.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 - + 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 + 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.1 + 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 flutter_launcher_icons: - 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 - windows: - generate: true - macos: - generate: true - image_path: assets/mobile.png + 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