Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
e300f4efc9 |
|||
|
bab699658f |
|||
|
1c1f585362 |
|||
|
c90a1c41b0 |
|||
|
9f070fcdba |
|||
|
d712bb3193 |
|||
|
3217c17ea0 |
|||
|
031fbe326c |
|||
|
0149aa2f84 |
|||
|
a1efdb0f46 |
|||
| 389b65ae61 | |||
|
3429a3ed98 |
|||
|
7ab92f76bf |
|||
|
aecfac9533 |
|||
|
c7b89b8e56 |
|||
|
721727d48c |
|||
|
004c3bcd0d |
|||
|
943cd85e22 |
|||
|
09904536e7 |
|||
|
856072e0b0 |
|||
|
110caff170 |
|||
|
eeb2e2f54b |
|||
|
529a2e35c4 |
|||
|
6ad4657d76 |
|||
|
38fd19ad1a |
|||
|
0636366359 |
|||
|
efe9262a97 |
|||
|
2763a0fdf5 |
|||
|
a5da44fdea |
|||
|
ccca02a0bc |
|||
|
721349ca21 |
|||
|
5d994bf2bb |
|||
|
a90bf00f18 |
|||
|
f2efbbeb9f |
|||
|
ed761d6071 |
|||
|
8f35ea2435 |
|||
|
023e75e063 |
|||
|
4d0a4605d6 |
|||
|
faa7292001 |
|||
|
027033ad9e |
|||
|
ece3d16318 |
|||
|
5738239da2 |
|||
|
a2791a6717 |
|||
|
f910d87a23 |
|||
|
f4142859ba |
|||
|
775c77194b |
|||
|
41806be9bf |
|||
|
6e47594a91 |
|||
|
386b3ad1cf |
|||
|
61f2aa7f2a |
|||
|
0c660a98a7 |
|||
|
09534a6775 |
|||
|
0cd815dc79 |
|||
|
800ed0636d |
|||
|
e4cf2a837c |
|||
|
11dca9bf14 |
|||
|
436b8642b3 |
|||
|
269d97be8f |
|||
|
43f70f35a3 |
|||
|
92b148f5b6 |
|||
|
00a42b5f1a |
|||
|
700b4e720f |
|||
|
2a11bcb7e8 |
|||
|
fea39e4191 |
|||
|
deaf564c36 |
|||
|
c0d14ac30e |
|||
|
1a6a5c36ea |
|||
|
35ef82accd |
|||
|
f40dd22277 |
|||
|
1cfea5a819 |
|||
|
b3023d8147 |
|||
|
e8fb3a8523 |
|||
|
0d1ace3fd0 |
|||
|
3d690c26d8 |
|||
|
3fee789c90 |
|||
|
d7c64fea80 |
|||
|
87e7e093f7 |
|||
|
8b7e29ae33 |
|||
|
673c5bd894 |
|||
|
650c62fb99 |
|||
|
4f3b77f9f3 |
|||
|
85bb653980 |
|||
|
a9d2ccbcd1 |
|||
|
73c4a7d07f |
|||
|
57f9498aa3 |
|||
|
cfab803fa0 |
|||
|
f23a35384d |
|||
|
7f7fb451e6 |
|||
|
5d62e66cd9 |
|||
|
009ba504e3 |
|||
|
30b922d390 |
|||
|
63183e0824 |
|||
|
163947fc90 |
|||
|
11457470a0 |
|||
|
dca0b7dd7d |
|||
|
e5dc270f83 |
|||
|
810a0b102b |
|||
|
ec1603b828 |
|||
| 5acdbb5be0 | |||
|
e21c9e8c22 |
|||
|
ea687471bc |
|||
|
8c440447f2 |
|||
|
8ebec15324 |
|||
|
cd8d551e26 |
|||
|
118e5a5826 |
|||
|
6ca9b2a948 |
|||
|
23e01c7a0d |
|||
|
9e7fcdbef7 |
|||
|
9507d69458 |
|||
|
13d90df226 |
|||
|
e925f9657c |
|||
|
b8882d6e48 |
|||
| ff9bf3bec4 | |||
|
6e42902322 |
|||
|
c105a6035c |
|||
|
3d7ef9b32f |
|||
|
51ef66174a |
|||
|
1efb68ebe0 |
|||
|
0a667fda0b |
|||
|
da352cd035 |
|||
|
0201f71e5d |
|||
|
4314c88d5c |
|||
|
88cdcf9863 |
|||
|
e2f25749e0 |
|||
|
47a3d9d92f |
|||
|
a680c5cd0c |
|||
|
0887421f3e |
|||
|
a090d88a23 |
|||
|
32693fb3b5 |
|||
|
4e1f1b64bc |
|||
|
20f1c784f6 |
|||
|
9b79304edc |
|||
|
b797b8de9c |
|||
|
56bb75866c |
|||
|
3baea40669 |
|||
|
2e72ecd559 |
|||
| 077044ec19 | |||
|
01b13b4764 |
|||
|
050e42cc6f |
|||
|
67cee201b6 |
|||
|
2d7b067c93 |
|||
|
a9993013f5 |
|||
|
9c488e8981 |
|||
|
5c16f42d20 |
|||
|
092fc616e6 |
|||
|
6cbf78be6b |
|||
|
68f4bb0c03 |
|||
|
9e24f4cb31 |
|||
|
43d2e94d62 |
|||
|
62fe37c6ae |
|||
|
b9dfbd3ca2 |
|||
|
620440e2a1 |
|||
|
724171384c |
|||
|
1bd677eb23 |
|||
|
41658c3a9d |
|||
|
b011cc2166 |
|||
|
75ad6cbd02 |
|||
|
6c1d3d8894 |
|||
|
842ab0a82c |
|||
|
a0e5d2fb9e |
|||
|
a2cdc3df68 |
|||
|
07f8a35b74 |
|||
|
85b9007c47 |
|||
|
5bbd51c4bc |
|||
|
21a0e0db70 |
|||
|
a5f42fe56e |
|||
|
185c1d2714 |
|||
|
7eab09585b |
|||
|
c84f0e7e93 |
|||
|
f7847d587c |
|||
|
56dbd91c96 |
|||
| 7bb4d87638 | |||
|
bf31f5510a |
|||
|
bd185824f9 |
|||
|
2afd5ae258 |
|||
|
76f9175857 |
|||
|
e32941f062 |
|||
|
cf89604ff5 |
2
.github/workflows/android.yml
vendored
|
|
@ -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 }}
|
||||
|
|
|
|||
48
.github/workflows/ios.yml
vendored
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
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: Set up Flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
flutter-version: 3.47.4
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version-file: gomuks/go.mod
|
||||
|
||||
- name: Build app
|
||||
run: |
|
||||
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
|
||||
39
.github/workflows/macos.yml
vendored
|
|
@ -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:
|
||||
|
|
@ -17,16 +16,32 @@ 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.47.4
|
||||
|
||||
- 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: Set up Go
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version-file: gomuks/go.mod
|
||||
|
||||
- name: Upload installer artifact
|
||||
- name: Build App
|
||||
run: |
|
||||
flutter pub get
|
||||
dart scripts/generate.dart
|
||||
flutter pub run build_runner build
|
||||
flutter build macos --release
|
||||
|
||||
- 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
|
||||
|
||||
- name: Upload DMG
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: App
|
||||
path: build/macos/Build/Products/Release/Nexus.app
|
||||
name: nexus.dmg
|
||||
path: ${{ steps.create-dmg.outputs.dmg_path }}
|
||||
|
|
|
|||
3
.github/workflows/windows.yml
vendored
|
|
@ -19,8 +19,7 @@ jobs:
|
|||
- name: Set up Flutter
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
flutter-version: 3.44.4
|
||||
|
||||
flutter-version: 3.47.4
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
|
|
|
|||
1
.gitmodules
vendored
|
|
@ -1,4 +1,3 @@
|
|||
[submodule "gomuks"]
|
||||
path = gomuks
|
||||
url = https://github.com/gomuks/gomuks
|
||||
branch = main
|
||||
|
|
|
|||
12
.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
|
||||
|
||||
|
|
|
|||
17
.vscode/launch.json
vendored
Normal file
|
|
@ -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" }
|
||||
}
|
||||
]
|
||||
}
|
||||
4
.vscode/settings.json
vendored
|
|
@ -11,6 +11,8 @@
|
|||
"muks",
|
||||
"prefs",
|
||||
"unban",
|
||||
"unredact"
|
||||
"unifiedpush",
|
||||
"unredact",
|
||||
"webpush"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ See [Effective Dart: Style](https://dart.dev/effective-dart/style) for general r
|
|||
Controllers live in `lib/controllers/` and provide a source that exposes data and logic via Riverpod providers, allowing other parts of the code to watch state changes with ref.watch (`ref.watch(MyController.provider)`), access the current value with ref.read (`ref.read(MyController.provider)`), and run helper methods on those classes using the notifier:
|
||||
|
||||
```dart
|
||||
ref.watch(MyController.provider.notifier).helperMethod()
|
||||
ref.read(MyController.provider.notifier).helperMethod()
|
||||
```
|
||||
|
||||
We use an object oriented style for controllers, where `provider` is a static member on the controller class. E.g.
|
||||
|
|
|
|||
35
README.md
|
|
@ -15,12 +15,17 @@ A simple and user-friendly Matrix client made with Flutter and a Gomuks backend.
|
|||
|
||||
## Progress
|
||||
|
||||
- [ ] Platform Support
|
||||
- [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] Android
|
||||
- [ ] MacOS ([#50](https://git.federated.nexus/Nexus/nexus/issues/50))
|
||||
- [ ] iOS
|
||||
- [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
|
||||
|
|
@ -50,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
|
||||
|
|
@ -63,9 +68,7 @@ A simple and user-friendly Matrix client made with Flutter and a Gomuks backend.
|
|||
- [x] URL Previews
|
||||
- [x] Replies
|
||||
- [x] Viewing
|
||||
- [ ] Jump to original message
|
||||
- [x] In loaded timeline
|
||||
- [ ] Out of loaded timeline
|
||||
- [x] Jump to original message
|
||||
- [x] Edits
|
||||
- [x] Attachments
|
||||
- [x] Unencrypted
|
||||
|
|
@ -105,7 +108,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))
|
||||
- [x] Notifications page
|
||||
- [ ] Group calls using [MSC4195](https://github.com/matrix-org/matrix-spec-proposals/pull/4195)
|
||||
- [ ] Invites
|
||||
- [x] Settings
|
||||
|
|
@ -115,10 +119,13 @@ 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)
|
||||
- [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)
|
||||
- [NixOS Module](linux/nix/module.nix)
|
||||
|
||||
## Build it yourself
|
||||
|
||||
|
|
@ -126,8 +133,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
|
||||
|
||||
|
|
@ -187,6 +194,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
|
||||
|
|
|
|||
22
altstore-source.json
Normal file
|
|
@ -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": []
|
||||
}
|
||||
|
|
@ -6,6 +6,12 @@ analyzer:
|
|||
- "build/**"
|
||||
- "**/*.g.dart"
|
||||
- "**/*.freezed.dart"
|
||||
- android/**
|
||||
- ios/**
|
||||
- web/**
|
||||
- windows/**
|
||||
- macos/**
|
||||
- linux/**
|
||||
include: package:flutter_lints/flutter.yaml
|
||||
linter:
|
||||
rules:
|
||||
|
|
|
|||
|
|
@ -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 = "../.."
|
||||
}
|
||||
84
android/app/build.gradle.kts
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
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 {
|
||||
isCoreLibraryDesugaringEnabled = true
|
||||
sourceCompatibility = JavaVersion.VERSION_21
|
||||
targetCompatibility = JavaVersion.VERSION_21
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "nexus.federated.nexus"
|
||||
|
||||
minSdk = 29
|
||||
targetSdk = flutter.targetSdkVersion
|
||||
|
||||
versionCode = flutter.versionCode
|
||||
versionName = flutter.versionName
|
||||
|
||||
multiDexEnabled = true
|
||||
}
|
||||
|
||||
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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
flutter {
|
||||
source = "../.."
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
25
android/build.gradle.kts
Normal file
|
|
@ -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<Delete>("clean") {
|
||||
delete(rootProject.layout.buildDirectory)
|
||||
}
|
||||
|
|
@ -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.6.0-all.zip
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
26
android/settings.gradle.kts
Normal file
|
|
@ -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")
|
||||
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 9.2 KiB |
BIN
assets/twim/notif.webp
Normal file
|
After Width: | Height: | Size: 15 MiB |
|
Before Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 130 KiB |
29
flake.lock
generated
|
|
@ -5,11 +5,11 @@
|
|||
"nixpkgs-lib": "nixpkgs-lib"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1782949081,
|
||||
"narHash": "sha256-vp6Y/Grm98ESt6ceOkWiHWyZRDV3J1RID4w+6NWK9yA=",
|
||||
"lastModified": 1788450739,
|
||||
"narHash": "sha256-glZLQlzIn1fXH6PazR2iUmTo7kzzyYSshrWhLS9TqCU=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "17c9d6cdfc60c64f4ee8d306f9bc0b4ccb51481e",
|
||||
"rev": "31729ca8cbdb4fa927b34e5f4353e6a83f39e993",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -42,15 +42,16 @@
|
|||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1774860670,
|
||||
"narHash": "sha256-YjJkQrvxrErXtfDi3obUn6rNmkA+CIAZ3f5NgL5xuYE=",
|
||||
"owner": "neobrain",
|
||||
"lastModified": 1790043059,
|
||||
"narHash": "sha256-7ID4HL4IrrlalCsxMASkcAr+v0VHTNFp6+sZ+dpvOV8=",
|
||||
"owner": "Henry-Hiles",
|
||||
"repo": "nix2flatpak",
|
||||
"rev": "61d68e21e3fbc2d57590051f48736bea271f4aba",
|
||||
"rev": "290dd282e555cab988c021c2be5f2361e58c4d51",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "neobrain",
|
||||
"owner": "Henry-Hiles",
|
||||
"ref": "quad/nexus",
|
||||
"repo": "nix2flatpak",
|
||||
"type": "github"
|
||||
}
|
||||
|
|
@ -73,11 +74,11 @@
|
|||
},
|
||||
"nixpkgs-lib": {
|
||||
"locked": {
|
||||
"lastModified": 1782614948,
|
||||
"narHash": "sha256-ePjCwr1sNm9NYUqywL7QfK3JnlS015msC+eBu2zKlp8=",
|
||||
"lastModified": 1788057806,
|
||||
"narHash": "sha256-DTQSMxzDWmT0zhguthvegnVkn7CFqGCv4IHCzk5ZUpM=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"rev": "db3f255737b94216eb71cce308e2912cf6bc2d7c",
|
||||
"rev": "596e2e3940e09b2abbeb03f75fa1828c57fcd72c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -88,11 +89,11 @@
|
|||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1784497964,
|
||||
"narHash": "sha256-vlHUuqAcbcH2RKmHbPiuQzbv1pnzzavXnI62RD0bqCU=",
|
||||
"lastModified": 1790185690,
|
||||
"narHash": "sha256-xJ+X4hBtOcAFGBOe5nAMyMUeF9foJBmIOu3NjBqBycU=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "241313f4e8e508cb9b13278c2b0fa25b9ca27163",
|
||||
"rev": "4975466d324710c576dc11ad614684e6bd8cad8e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
|||
54
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/nexus";
|
||||
};
|
||||
|
||||
outputs =
|
||||
|
|
@ -16,62 +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"
|
||||
];
|
||||
devices = [ "dri" ];
|
||||
};
|
||||
};
|
||||
|
||||
gomuks = pkgs.callPackage ./linux/nix/pkg/gomuks.nix {
|
||||
src = self;
|
||||
};
|
||||
};
|
||||
|
||||
devShells.default = pkgs.callPackage ./linux/nix/devshell.nix { };
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
2
gomuks
|
|
@ -1 +1 @@
|
|||
Subproject commit 2d566a2b585e2dba882714f7ca741a52afb36237
|
||||
Subproject commit 480938f9e01e7eae2cf249657efae03df76599d6
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
import "dart:io";
|
||||
|
||||
import "package:collection/collection.dart";
|
||||
import "package:hooks/hooks.dart";
|
||||
import "package:code_assets/code_assets.dart";
|
||||
|
|
@ -13,22 +14,46 @@ Future<void> main(List<String> args) => build(args, (input, output) async {
|
|||
|
||||
String libFileName;
|
||||
Map<String, String> 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(),
|
||||
"CGO_ENABLED": "1",
|
||||
"GOARCH": switch (targetArch) {
|
||||
Architecture.arm64 => "arm64",
|
||||
Architecture.x64 => "amd64",
|
||||
_ => throw UnsupportedError(
|
||||
"Unsupported macOS architecture: $targetArch",
|
||||
),
|
||||
},
|
||||
"SDKROOT": await getXCodeTool(),
|
||||
"MACOSX_DEPLOYMENT_TARGET": codeConfig.macOS.targetVersion.toString(),
|
||||
};
|
||||
break;
|
||||
case OS.windows:
|
||||
|
|
@ -96,15 +121,28 @@ Future<void> main(List<String> 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",
|
||||
"-trimpath",
|
||||
"-ldflags=-s -w",
|
||||
"-tags",
|
||||
tags,
|
||||
"-o",
|
||||
archiveFile.path,
|
||||
"-buildmode=${targetOS == OS.iOS ? "c-archive" : "c-shared"}",
|
||||
],
|
||||
workingDirectory: gomuksBuildDir.resolve("pkg/ffi/").toFilePath(),
|
||||
environment: {
|
||||
"CGO_ENABLED": "1",
|
||||
|
|
@ -124,6 +162,35 @@ Future<void> main(List<String> 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";
|
||||
|
|
|
|||
34
ios/.gitignore
vendored
Normal file
|
|
@ -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
|
||||
24
ios/Flutter/AppFrameworkInfo.plist
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>App</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>io.flutter.flutter.app</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>App</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
</dict>
|
||||
</plist>
|
||||
2
ios/Flutter/Debug.xcconfig
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||
#include "Generated.xcconfig"
|
||||
2
ios/Flutter/Release.xcconfig
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||
#include "Generated.xcconfig"
|
||||
43
ios/Podfile
Normal file
|
|
@ -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
|
||||
28
ios/Podfile.lock
Normal file
|
|
@ -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
|
||||
759
ios/Runner.xcodeproj/project.pbxproj
Normal file
|
|
@ -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 = "<group>"; };
|
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
|
||||
78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = "<group>"; };
|
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
/* 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 = "<group>";
|
||||
};
|
||||
331C8082294A63A400263BE5 /* RunnerTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
331C807B294A618700263BE5 /* RunnerTests.swift */,
|
||||
);
|
||||
path = RunnerTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
594EB1F65336CF9C7958F6FA /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
82F9A3759658343C81A0EA4C /* Pods_Runner.framework */,
|
||||
8156A45F510382D558AED93A /* Pods_RunnerTests.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9740EEB11CF90186004384FC /* Flutter */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */,
|
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
|
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */,
|
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
|
||||
9740EEB31CF90195004384FC /* Generated.xcconfig */,
|
||||
);
|
||||
name = Flutter;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146E51CF9000F007C117D = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9740EEB11CF90186004384FC /* Flutter */,
|
||||
97C146F01CF9000F007C117D /* Runner */,
|
||||
97C146EF1CF9000F007C117D /* Products */,
|
||||
331C8082294A63A400263BE5 /* RunnerTests */,
|
||||
1CFFAE23B502BCCEB2B191A3 /* Pods */,
|
||||
594EB1F65336CF9C7958F6FA /* Frameworks */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146EF1CF9000F007C117D /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
97C146EE1CF9000F007C117D /* Runner.app */,
|
||||
331C8081294A63A400263BE5 /* RunnerTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
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 = "<group>";
|
||||
};
|
||||
/* 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 = "/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 = "/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 = "<group>";
|
||||
};
|
||||
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
97C147001CF9000F007C117D /* Base */,
|
||||
);
|
||||
name = LaunchScreen.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* 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 */;
|
||||
}
|
||||
7
ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>PreviewsEnabled</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
119
ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1510"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<PreActions>
|
||||
<ExecutionAction
|
||||
ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction">
|
||||
<ActionContent
|
||||
title = "Run Prepare Flutter Framework Script"
|
||||
scriptText = "/bin/sh "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" prepare ">
|
||||
<EnvironmentBuildable>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</EnvironmentBuildable>
|
||||
</ActionContent>
|
||||
</ExecutionAction>
|
||||
</PreActions>
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO"
|
||||
parallelizable = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "331C8080294A63A400263BE5"
|
||||
BuildableName = "RunnerTests.xctest"
|
||||
BlueprintName = "RunnerTests"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
enableGPUValidationMode = "1"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Profile"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
10
ios/Runner.xcworkspace/contents.xcworkspacedata
generated
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>PreviewsEnabled</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
17
ios/Runner/AppDelegate.swift
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import Flutter
|
||||
import UIKit
|
||||
|
||||
@main
|
||||
@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate {
|
||||
override func application(
|
||||
_ application: UIApplication,
|
||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
||||
) -> Bool {
|
||||
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
|
||||
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||
}
|
||||
|
||||
func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) {
|
||||
GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry)
|
||||
}
|
||||
}
|
||||
|
|
@ -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"}}
|
||||
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 846 B |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 4 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 5 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 8.3 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
23
ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
vendored
Normal file
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
BIN
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
vendored
Normal file
|
After Width: | Height: | Size: 68 B |
BIN
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 68 B |
BIN
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 68 B |
5
ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
vendored
Normal file
|
|
@ -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.
|
||||
37
ios/Runner/Base.lproj/LaunchScreen.storyboard
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="EHf-IW-A2E">
|
||||
<objects>
|
||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
|
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="53" y="375"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="LaunchImage" width="168" height="185"/>
|
||||
</resources>
|
||||
</document>
|
||||
26
ios/Runner/Base.lproj/Main.storyboard
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Flutter View Controller-->
|
||||
<scene sceneID="tne-QT-ifu">
|
||||
<objects>
|
||||
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
79
ios/Runner/Info.plist
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<false/>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Nexus</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>nexus</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(FLUTTER_BUILD_NAME)</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>nexus.federated.nexus</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UIApplicationSceneManifest</key>
|
||||
<dict>
|
||||
<key>UIApplicationSupportsMultipleScenes</key>
|
||||
<false/>
|
||||
<key>UISceneConfigurations</key>
|
||||
<dict>
|
||||
<key>UIWindowSceneSessionRoleApplication</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UISceneClassName</key>
|
||||
<string>UIWindowScene</string>
|
||||
<key>UISceneConfigurationName</key>
|
||||
<string>flutter</string>
|
||||
<key>UISceneDelegateClassName</key>
|
||||
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
|
||||
<key>UISceneStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
1
ios/Runner/Runner-Bridging-Header.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
#import "GeneratedPluginRegistrant.h"
|
||||
6
ios/Runner/SceneDelegate.swift
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import Flutter
|
||||
import UIKit
|
||||
|
||||
class SceneDelegate: FlutterSceneDelegate {
|
||||
|
||||
}
|
||||
12
ios/RunnerTests/RunnerTests.swift
Normal file
|
|
@ -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.
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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<OAuthAuthCodeResponse> {
|
||||
final Uri homeserver;
|
||||
AuthUrlController(this.homeserver);
|
||||
|
||||
class AuthUrlController(final Uri homeserver)
|
||||
extends AsyncNotifier<OAuthAuthCodeResponse> {
|
||||
@override
|
||||
Future<OAuthAuthCodeResponse> build() async => ref
|
||||
.watch(ClientController.provider.notifier)
|
||||
|
|
|
|||
|
|
@ -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<MembershipContent> {
|
||||
final Event event;
|
||||
AuthorController(this.event);
|
||||
|
||||
class AuthorController(final Event event)
|
||||
extends AsyncNotifier<MembershipContent> {
|
||||
@override
|
||||
Future<MembershipContent> 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(
|
||||
|
|
|
|||
|
|
@ -1,26 +1,28 @@
|
|||
import "dart:async";
|
||||
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";
|
||||
import "package:nexus/controllers/account_data.dart";
|
||||
import "package:nexus/controllers/client_state.dart";
|
||||
import "package:nexus/controllers/init_complete.dart";
|
||||
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:flutter/cupertino.dart";
|
||||
import "package:intl/intl.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/event_context.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";
|
||||
import "package:nexus/models/paginate_manual.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_event_context.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";
|
||||
|
|
@ -29,7 +31,9 @@ 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";
|
||||
import "package:nexus/models/requests/paginate.dart";
|
||||
import "package:nexus/models/requests/paginate_manual.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";
|
||||
|
|
@ -38,8 +42,9 @@ 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_metadata.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";
|
||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||
import "package:path_provider/path_provider.dart";
|
||||
|
|
@ -47,134 +52,99 @@ import "package:path_provider/path_provider.dart";
|
|||
class ClientController extends AsyncNotifier<int> {
|
||||
@override
|
||||
Future<int> build() async {
|
||||
final Pointer<Char> root;
|
||||
if (Platform.isAndroid) {
|
||||
final dir = await getApplicationSupportDirectory();
|
||||
root = "${dir.path}/gomuks".toNativeUtf8().cast();
|
||||
} else {
|
||||
root = nullptr.cast();
|
||||
}
|
||||
|
||||
final handle = GomuksInit(root);
|
||||
|
||||
final callable =
|
||||
NativeCallable<
|
||||
Void Function(Pointer<Char>, Int64, GomuksOwnedBuffer)
|
||||
>.listener((
|
||||
Pointer<Char> command,
|
||||
int requestId,
|
||||
GomuksOwnedBuffer data,
|
||||
) {
|
||||
debugPrint("Setting Gomuks env...");
|
||||
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) {
|
||||
final keyPtr = key.toNativeUtf8().cast<Char>();
|
||||
final valuePtr = value.toNativeUtf8().cast<Char>();
|
||||
try {
|
||||
final muksEventType = command.cast<Utf8>().toDartString();
|
||||
debugPrint("Handling $muksEventType...");
|
||||
final decodedMuksEvent = data.toJson();
|
||||
|
||||
switch (muksEventType) {
|
||||
case "client_state":
|
||||
ref
|
||||
.watch(ClientStateController.provider.notifier)
|
||||
.set(.fromJson(decodedMuksEvent));
|
||||
break;
|
||||
case "sync_status":
|
||||
ref
|
||||
.watch(SyncStatusController.provider.notifier)
|
||||
.set(.fromJson(decodedMuksEvent));
|
||||
break;
|
||||
case "init_complete":
|
||||
ref.watch(InitCompleteController.provider.notifier).complete();
|
||||
break;
|
||||
case "send_complete":
|
||||
final event = Event.fromJson(decodedMuksEvent["event"]);
|
||||
ref
|
||||
.watch(RoomsController.provider.notifier)
|
||||
.update(
|
||||
.new({
|
||||
event.roomId: .new(events: .new({event.rowId: event})),
|
||||
}),
|
||||
.new(),
|
||||
);
|
||||
|
||||
break;
|
||||
case "sync_complete":
|
||||
final syncData = SyncData.fromJson(decodedMuksEvent);
|
||||
final roomProvider = RoomsController.provider;
|
||||
final accountDataProvider = AccountDataController.provider;
|
||||
|
||||
if (syncData.clearState) {
|
||||
ref.invalidate(roomProvider);
|
||||
ref.invalidate(accountDataProvider);
|
||||
GomuksSetEnv(keyPtr, valuePtr);
|
||||
} finally {
|
||||
calloc
|
||||
..free(keyPtr)
|
||||
..free(valuePtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ref
|
||||
.watch(roomProvider.notifier)
|
||||
.update(syncData.rooms, syncData.leftRooms);
|
||||
ref
|
||||
.watch(accountDataProvider.notifier)
|
||||
.update(syncData.accountData);
|
||||
debugPrint("Initializing Gomuks...");
|
||||
final handle = await Isolate.run(() {
|
||||
final bufferPointer = GomuksConfig(
|
||||
matrix: .new(
|
||||
initialDeviceDisplayName:
|
||||
"Nexus on ${toBeginningOfSentenceCase(Platform.operatingSystem)}",
|
||||
),
|
||||
).toJson().toGomuksBufferPtr();
|
||||
|
||||
if (syncData.topLevelSpaces != null) {
|
||||
ref
|
||||
.watch(TopLevelSpacesController.provider.notifier)
|
||||
.set(syncData.topLevelSpaces!);
|
||||
}
|
||||
|
||||
if (syncData.spaceEdges != null) {
|
||||
ref
|
||||
.watch(SpaceEdgesController.provider.notifier)
|
||||
.set(syncData.spaceEdges!);
|
||||
}
|
||||
|
||||
// ref
|
||||
// .watch(SyncStatusController.provider.notifier)
|
||||
// .set(SyncStatus.fromJson(decodedMuksEvent));
|
||||
break;
|
||||
default:
|
||||
debugPrint("Unhandled event: $muksEventType");
|
||||
}
|
||||
debugPrint("Finished handling $muksEventType...");
|
||||
} catch (error, stackTrace) {
|
||||
if (kDebugMode) {
|
||||
debugPrintStack(stackTrace: stackTrace, label: error.toString());
|
||||
rethrow;
|
||||
} else {
|
||||
showError(error, stackTrace);
|
||||
}
|
||||
try {
|
||||
return GomuksInit(bufferPointer.ref);
|
||||
} finally {
|
||||
calloc
|
||||
..free(bufferPointer.ref.base)
|
||||
..free(bufferPointer);
|
||||
}
|
||||
});
|
||||
|
||||
ref.onDispose(() => GomuksDestroy(handle));
|
||||
ref.onDispose(callable.close);
|
||||
|
||||
final errorCode = GomuksStart(handle, callable.nativeFunction);
|
||||
|
||||
if (errorCode == 0) return handle;
|
||||
throw Exception("GomuksStart returned error code $errorCode");
|
||||
return handle;
|
||||
}
|
||||
|
||||
Future<dynamic> _sendCommand(
|
||||
String command, [
|
||||
Map<String, dynamic> data = const {},
|
||||
]) async {
|
||||
Future<dynamic> callGomuksMethod(
|
||||
Map<String, dynamic> data,
|
||||
FutureOr<GomuksResponse> Function(int handle, GomuksBorrowedBuffer data)
|
||||
callback,
|
||||
) async {
|
||||
final bufferPointer = data.toGomuksBufferPtr();
|
||||
|
||||
try {
|
||||
final handle = await future;
|
||||
|
||||
final response = await Isolate.run(
|
||||
() => GomuksSubmitCommand(
|
||||
handle,
|
||||
command.toNativeUtf8().cast<Char>(),
|
||||
bufferPointer.ref,
|
||||
),
|
||||
() => callback(handle, bufferPointer.ref),
|
||||
);
|
||||
|
||||
calloc.free(bufferPointer);
|
||||
|
||||
final json = response.buf.toJson();
|
||||
|
||||
if (response.command.cast<Utf8>().toDartString() == "error") {
|
||||
throw json;
|
||||
}
|
||||
|
||||
return json;
|
||||
} finally {
|
||||
calloc
|
||||
..free(bufferPointer.ref.base)
|
||||
..free(bufferPointer);
|
||||
}
|
||||
}
|
||||
|
||||
Future<(Event, RoomMetadata)> handlePush(Map<String, dynamic> data) async {
|
||||
final response = await callGomuksMethod(
|
||||
data,
|
||||
(handle, data) async => GomuksHandlePush(handle, data),
|
||||
);
|
||||
|
||||
return (
|
||||
Event.fromJson(response["event"]),
|
||||
RoomMetadata.fromJson(response["room"]),
|
||||
);
|
||||
}
|
||||
|
||||
dynamic _sendCommand(
|
||||
String command, [
|
||||
Map<String, dynamic> data = const {},
|
||||
]) => callGomuksMethod(data, (handle, data) {
|
||||
final commandPointer = command.toNativeUtf8().cast<Char>();
|
||||
try {
|
||||
return GomuksSubmitCommand(handle, commandPointer, data);
|
||||
} finally {
|
||||
calloc.free(commandPointer);
|
||||
}
|
||||
});
|
||||
|
||||
Future<void> redactEvent(RedactEventRequest report) =>
|
||||
_sendCommand("redact_event", report.toJson());
|
||||
|
|
@ -213,21 +183,17 @@ class ClientController extends AsyncNotifier<int> {
|
|||
}
|
||||
}
|
||||
|
||||
Future<String> joinRoom(JoinRoomRequest request) async {
|
||||
final response = await _sendCommand("join_room", request.toJson());
|
||||
return response["room_id"];
|
||||
}
|
||||
Future<String> joinRoom(JoinRoomRequest request) async =>
|
||||
(await _sendCommand("join_room", request.toJson()))["room_id"];
|
||||
|
||||
Future<RoomSummary> getRoomSummary(JoinRoomRequest request) async =>
|
||||
.fromJson(await _sendCommand("get_room_summary", request.toJson()));
|
||||
|
||||
Future<void> leaveRoom(Room room) async {
|
||||
if (room.metadata == null) return;
|
||||
await _sendCommand("leave_room", {"room_id": room.metadata!.id});
|
||||
}
|
||||
|
||||
// (await _sendCommand("get_event_context", {
|
||||
// "room_id": request.roomId,
|
||||
// "event_id": r"$OqZT4NuTj0J1-771IOEEWRI4XdumRNu6ighlvO3K3gc",
|
||||
// }));
|
||||
|
||||
Future<IList<Event>> getRoomState(GetRoomStateRequest request) async {
|
||||
Future<List?> getState(GetRoomStateRequest request) async =>
|
||||
(await _sendCommand("get_room_state", request.toJson())) as List?;
|
||||
|
|
@ -248,6 +214,12 @@ class ClientController extends AsyncNotifier<int> {
|
|||
return .new(response?.map((event) => .fromJson(event)));
|
||||
}
|
||||
|
||||
Future<IList<Event>> getMentions(GetMentionsRequest request) async => .new(
|
||||
// TODO: Handle `related_events`
|
||||
((await _sendCommand("get_mentions", request.toJson()))["events"] as List)
|
||||
.map((event) => .fromJson(event)),
|
||||
);
|
||||
|
||||
Future<Event?> getEvent(GetEventRequest request) async {
|
||||
final json = await _sendCommand("get_event", request.toJson());
|
||||
return json == null ? null : .fromJson(json);
|
||||
|
|
@ -259,8 +231,19 @@ class ClientController extends AsyncNotifier<int> {
|
|||
Future<Paginate> paginate(PaginateRequest request) async =>
|
||||
.fromJson(await _sendCommand("paginate", request.toJson()));
|
||||
|
||||
Future<ProfileResponse> getProfile(String userId) async =>
|
||||
.fromJson(await _sendCommand("get_profile", {"user_id": userId}));
|
||||
Future<PaginateManual> paginateManual(PaginateManualRequest request) async =>
|
||||
.fromJson(await _sendCommand("paginate_manual", request.toJson()));
|
||||
|
||||
Future<EventContext> getEventContext(GetEventContextRequest request) async =>
|
||||
.fromJson(await _sendCommand("get_event_context", request.toJson()));
|
||||
|
||||
Future<ProfileResponse> getProfile(String userId) async {
|
||||
try {
|
||||
return .fromJson(await _sendCommand("get_profile", {"user_id": userId}));
|
||||
} catch (_) {
|
||||
return ProfileResponse(profile: .new(id: userId));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> reportEvent(ReportRequest request) =>
|
||||
_sendCommand("report_event", request.toJson());
|
||||
|
|
@ -271,6 +254,15 @@ class ClientController extends AsyncNotifier<int> {
|
|||
Future<void> setAccountData(SetAccountDataRequest request) =>
|
||||
_sendCommand("set_account_data", request.toJson());
|
||||
|
||||
Future<void> registerPusher(RegisterPusherRequest request) =>
|
||||
_sendCommand("register_homeserver_push", request.toJson());
|
||||
|
||||
Future<void> deregisterPusher(DeregisterPusherRequest request) =>
|
||||
_sendCommand("register_homeserver_push", {
|
||||
...request.toJson(),
|
||||
"kind": null,
|
||||
});
|
||||
|
||||
Future<MessageContent> uploadMedia(UploadMediaRequest request) async =>
|
||||
.fromJson(await _sendCommand("upload_media", request.toJson()));
|
||||
|
||||
|
|
@ -280,9 +272,11 @@ class ClientController extends AsyncNotifier<int> {
|
|||
Future<void> logout() => _sendCommand("logout");
|
||||
|
||||
Future<void> markRead(Room room) async {
|
||||
if (room.timeline.isEmpty || room.metadata == null) return;
|
||||
final eventRowId = room.timeline[room.timeline.keys.reduce(max)];
|
||||
final event = eventRowId == null ? null : room.events[eventRowId];
|
||||
if (event == null || room.metadata == null) return;
|
||||
|
||||
if (event == null) return;
|
||||
|
||||
await _sendCommand("mark_read", {
|
||||
"room_id": room.metadata!.id,
|
||||
|
|
@ -308,10 +302,14 @@ class ClientController extends AsyncNotifier<int> {
|
|||
Future<SpecVersionsResponse> getSpecVersions() async =>
|
||||
.fromJson(await _sendCommand("get_versions"));
|
||||
|
||||
Future<Capabilities> getCapabilities() async => Capabilities.fromJson(
|
||||
(await _sendCommand("get_capabilities"))["capabilities"],
|
||||
);
|
||||
|
||||
Future<Uri?> 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) {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||
import "package:nexus/controllers/client.dart";
|
||||
|
||||
class ClientIdController extends AsyncNotifier<String> {
|
||||
final Uri homeserver;
|
||||
ClientIdController(this.homeserver);
|
||||
|
||||
class ClientIdController(final Uri homeserver) extends AsyncNotifier<String> {
|
||||
@override
|
||||
Future<String> build() => ref
|
||||
.watch(ClientController.provider.notifier)
|
||||
|
|
|
|||
|
|
@ -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:flutter/material.dart";
|
||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||
import "package:http/http.dart";
|
||||
import "package:nexus/models/emoji.dart";
|
||||
|
||||
typedef EmojiTuple = (IMap<String, EmojiCategory>, IMap<String, List<String>>);
|
||||
|
||||
class EmojiController extends AsyncNotifier<EmojiTuple> {
|
||||
@override
|
||||
Future<EmojiTuple> 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<String, dynamic>>()
|
||||
.map(Emoji.fromJson)
|
||||
.toIList();
|
||||
|
||||
final categoryMap = entries.fold<IMap<String, IList<String>>>(
|
||||
.new(),
|
||||
(acc, entry) => acc.update(
|
||||
entry.category,
|
||||
(list) => list.add(entry.emoji),
|
||||
ifAbsent: () => .new([entry.emoji]),
|
||||
),
|
||||
);
|
||||
|
||||
final keywordMap = entries.fold<IMap<String, IList<String>>>(
|
||||
.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, EmojiTuple>(
|
||||
EmojiController.new,
|
||||
);
|
||||
}
|
||||
|
|
@ -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<Event?> {
|
||||
final GetEventRequest request;
|
||||
EventController(this.request);
|
||||
|
||||
class EventController(final GetEventRequest request)
|
||||
extends AsyncNotifier<Event?> {
|
||||
@override
|
||||
Future<Event?> build() async {
|
||||
final room = ref.watch(
|
||||
|
|
|
|||
124
lib/controllers/gomuks_listener.dart
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
import "dart:async";
|
||||
import "dart:ffi";
|
||||
|
||||
import "package:flutter/foundation.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/init_complete.dart";
|
||||
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/helpers/extensions/gomuks_buffer.dart";
|
||||
import "package:nexus/main.dart";
|
||||
import "package:ffi/ffi.dart";
|
||||
import "package:nexus/models/event.dart";
|
||||
import "package:nexus/models/sync_data.dart";
|
||||
import "package:nexus/src/third_party/gomuks.g.dart";
|
||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||
|
||||
class GomuksListenerController extends AsyncNotifier<void> {
|
||||
@override
|
||||
Future<void> build() async {
|
||||
debugPrint("Starting gomuks...");
|
||||
final handle = await ref.watch(ClientController.provider.future);
|
||||
|
||||
final callable =
|
||||
NativeCallable<
|
||||
Void Function(Pointer<Char>, Int64, GomuksOwnedBuffer)
|
||||
>.listener((
|
||||
Pointer<Char> command,
|
||||
int requestId,
|
||||
GomuksOwnedBuffer data,
|
||||
) {
|
||||
try {
|
||||
final muksEventType = command.cast<Utf8>().toDartString();
|
||||
debugPrint("Handling $muksEventType...");
|
||||
final decodedMuksEvent = data.toJson();
|
||||
|
||||
switch (muksEventType) {
|
||||
case "client_state":
|
||||
ref
|
||||
.watch(ClientStateController.provider.notifier)
|
||||
.set(.fromJson(decodedMuksEvent));
|
||||
break;
|
||||
case "sync_status":
|
||||
ref
|
||||
.watch(SyncStatusController.provider.notifier)
|
||||
.set(.fromJson(decodedMuksEvent));
|
||||
break;
|
||||
case "init_complete":
|
||||
ref.watch(InitCompleteController.provider.notifier).complete();
|
||||
break;
|
||||
case "send_complete":
|
||||
final event = Event.fromJson(decodedMuksEvent["event"]);
|
||||
ref
|
||||
.watch(RoomsController.provider.notifier)
|
||||
.update(
|
||||
.new({
|
||||
event.roomId: .new(events: .new({event.rowId: event})),
|
||||
}),
|
||||
.new(),
|
||||
);
|
||||
|
||||
break;
|
||||
case "sync_complete":
|
||||
final syncData = SyncData.fromJson(decodedMuksEvent);
|
||||
final roomProvider = RoomsController.provider;
|
||||
final accountDataProvider = AccountDataController.provider;
|
||||
|
||||
if (syncData.clearState) {
|
||||
ref.invalidate(roomProvider);
|
||||
ref.invalidate(accountDataProvider);
|
||||
}
|
||||
|
||||
ref
|
||||
.watch(roomProvider.notifier)
|
||||
.update(syncData.rooms, syncData.leftRooms);
|
||||
ref
|
||||
.watch(accountDataProvider.notifier)
|
||||
.update(syncData.accountData);
|
||||
|
||||
if (syncData.topLevelSpaces != null) {
|
||||
ref
|
||||
.watch(TopLevelSpacesController.provider.notifier)
|
||||
.set(syncData.topLevelSpaces!);
|
||||
}
|
||||
|
||||
if (syncData.spaceEdges != null) {
|
||||
ref
|
||||
.watch(SpaceEdgesController.provider.notifier)
|
||||
.set(syncData.spaceEdges!);
|
||||
}
|
||||
|
||||
// ref
|
||||
// .watch(SyncStatusController.provider.notifier)
|
||||
// .set(SyncStatus.fromJson(decodedMuksEvent));
|
||||
break;
|
||||
default:
|
||||
debugPrint("Unhandled event: $muksEventType");
|
||||
}
|
||||
debugPrint("Finished handling $muksEventType...");
|
||||
} catch (error, stackTrace) {
|
||||
if (kDebugMode) {
|
||||
debugPrintStack(stackTrace: stackTrace, label: error.toString());
|
||||
rethrow;
|
||||
} else {
|
||||
showError(error, stackTrace);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ref.onDispose(callable.close);
|
||||
|
||||
final errorCode = GomuksStart(handle, callable.nativeFunction);
|
||||
if (errorCode != 0) {
|
||||
throw Exception("GomuksStart returned error code $errorCode");
|
||||
}
|
||||
}
|
||||
|
||||
static final provider = AsyncNotifierProvider<GomuksListenerController, void>(
|
||||
GomuksListenerController.new,
|
||||
);
|
||||
}
|
||||
16
lib/controllers/jump_to_event.dart
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||
|
||||
class JumpToEventController(String? _) extends Notifier<String?> {
|
||||
@override
|
||||
String? build() => null;
|
||||
|
||||
void set(String? eventId) => state = eventId;
|
||||
|
||||
@override
|
||||
bool updateShouldNotify(_, _) => true;
|
||||
|
||||
static final provider = NotifierProvider.family
|
||||
.autoDispose<JumpToEventController, String?, String?>(
|
||||
JumpToEventController.new,
|
||||
);
|
||||
}
|
||||
|
|
@ -1,30 +1,28 @@
|
|||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||
import "package:nexus/controllers/shared_prefs.dart";
|
||||
|
||||
class KeyController extends Notifier<String?> {
|
||||
final String key;
|
||||
KeyController(this.key);
|
||||
|
||||
class KeyController(final String key) extends AsyncNotifier<String?> {
|
||||
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<String?> build() =>
|
||||
ref.watch(SharedPrefsController.provider).getString(key);
|
||||
|
||||
Future<void> 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<KeyController, String?, String>(
|
||||
AsyncNotifierProvider.family<KeyController, String?, String>(
|
||||
KeyController.new,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,20 @@
|
|||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||
import "package:nexus/controllers/shared_prefs.dart";
|
||||
|
||||
class MemberListOpenedController extends Notifier<bool> {
|
||||
class MemberListOpenedController extends AsyncNotifier<bool> {
|
||||
static const String key = "memberListOpened";
|
||||
|
||||
@override
|
||||
bool build() =>
|
||||
ref.watch(SharedPrefsController.provider).requireValue.getBool(key) ??
|
||||
true;
|
||||
Future<bool> build() async =>
|
||||
await ref.watch(SharedPrefsController.provider).getBool(key) ?? true;
|
||||
|
||||
Future<void> 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, bool>(
|
||||
static final provider =
|
||||
AsyncNotifierProvider<MemberListOpenedController, bool>(
|
||||
MemberListOpenedController.new,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<ISet<Event>> {
|
||||
final String roomId;
|
||||
MembersController(this.roomId);
|
||||
|
||||
class MembersController(final String roomId)
|
||||
extends AsyncNotifier<ISet<Event>> {
|
||||
@override
|
||||
Future<ISet<Event>> build() async {
|
||||
final room = ref.watch(
|
||||
|
|
|
|||
|
|
@ -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<ISet<Event>> {
|
||||
final MembersByStatusConfig config;
|
||||
MembersByStatusController(this.config);
|
||||
|
||||
class MembersByStatusController(final MembersByStatusConfig config)
|
||||
extends AsyncNotifier<ISet<Event>> {
|
||||
@override
|
||||
Future<ISet<Event>> build() => ref.watch(
|
||||
MembersController.provider(config.roomId).selectAsync(
|
||||
|
|
|
|||
|
|
@ -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<IList<MapEntry<int?, ISet<Event>>>> {
|
||||
final MembersByStatusConfig config;
|
||||
MembersGroupedController(this.config);
|
||||
|
||||
@override
|
||||
Future<IList<MapEntry<int?, ISet<Event>>>> build() async {
|
||||
final room = ref.watch(
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
import "dart:async";
|
||||
|
||||
import "package:fast_immutable_collections/fast_immutable_collections.dart";
|
||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||
|
||||
class MultiProviderController extends AsyncNotifier<void> {
|
||||
MultiProviderController(this.providers);
|
||||
final IList<AsyncNotifierProvider> providers;
|
||||
|
||||
class MultiProviderController(final IList<AsyncNotifierProvider> providers)
|
||||
extends AsyncNotifier<void> {
|
||||
@override
|
||||
Future<void> build() =>
|
||||
.wait(providers.map((provider) => ref.watch(provider.future)));
|
||||
Future<void> build() => .wait(
|
||||
providers.map((provider) => ref.watch(provider.future)),
|
||||
eagerError: true,
|
||||
);
|
||||
|
||||
static final provider =
|
||||
AsyncNotifierProvider.family<
|
||||
|
|
|
|||
162
lib/controllers/notification.dart
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
import "dart:async";
|
||||
import "dart:io";
|
||||
|
||||
import "package:flutter/services.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/widgets/pages/notifications.dart";
|
||||
import "package:xdg_desktop_portal/xdg_desktop_portal.dart";
|
||||
|
||||
class NotificationController
|
||||
extends AsyncNotifier<FlutterLocalNotificationsPlugin> {
|
||||
@override
|
||||
Future<FlutterLocalNotificationsPlugin> build() async {
|
||||
final notifications = FlutterLocalNotificationsPlugin();
|
||||
|
||||
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",
|
||||
),
|
||||
android: .new("ic_launcher_foreground"),
|
||||
iOS: darwin,
|
||||
macOS: darwin,
|
||||
),
|
||||
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) {
|
||||
const notificationChannel = MethodChannel("nexus/notifications");
|
||||
|
||||
notificationChannel.setMethodCallHandler((call) async {
|
||||
if (call.method != "notificationClicked") {
|
||||
return;
|
||||
}
|
||||
|
||||
final eventId = call.arguments as String;
|
||||
|
||||
if (navigatorKey.currentContext case final context?) {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (_) => NotificationsPage(
|
||||
highlightedEventId: eventId,
|
||||
defaultToAllNotifications: true,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
ref.onDispose(() => notificationChannel.setMethodCallHandler(null));
|
||||
}
|
||||
|
||||
return notifications;
|
||||
}
|
||||
|
||||
Future<bool> requestPermissions() async {
|
||||
if (Platform.isLinux) {
|
||||
return true;
|
||||
}
|
||||
|
||||
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<void> send({
|
||||
required int id,
|
||||
required String title,
|
||||
String? body,
|
||||
File? icon,
|
||||
String? payload,
|
||||
}) async {
|
||||
debugPrint("Sending notification for $id");
|
||||
|
||||
if (Platform.isLinux) {
|
||||
final portal = await ref.watch(PortalController.provider.future);
|
||||
|
||||
await portal.notification.addNotification(
|
||||
id.toString(),
|
||||
title: title,
|
||||
body: body,
|
||||
icon: icon == null ? null : XdgNotificationIconFile(icon.path),
|
||||
defaultAction: "app.event",
|
||||
defaultActionTarget: payload,
|
||||
);
|
||||
} 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 =
|
||||
AsyncNotifierProvider<
|
||||
NotificationController,
|
||||
FlutterLocalNotificationsPlugin
|
||||
>(NotificationController.new);
|
||||
}
|
||||
53
lib/controllers/notifications.dart
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import "package:fast_immutable_collections/fast_immutable_collections.dart";
|
||||
import "package:flutter_riverpod/flutter_riverpod.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<IList<Event>> {
|
||||
@override
|
||||
Future<IList<Event>> build() async {
|
||||
final client = ref.read(ClientController.provider.notifier);
|
||||
|
||||
final (unreadType, roomId) = request ?? (null, null);
|
||||
|
||||
return await client.getMentions(
|
||||
.new(
|
||||
maxTimestamp: .now(),
|
||||
unreadType: unreadType ?? .highlight,
|
||||
roomId: roomId,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> 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.read(ClientController.provider.notifier);
|
||||
final (unreadType, roomId) = request ?? (null, null);
|
||||
|
||||
final newNotifications = await client.getMentions(
|
||||
.new(
|
||||
maxTimestamp: lastTs,
|
||||
unreadType: unreadType ?? .highlight,
|
||||
roomId: roomId,
|
||||
),
|
||||
);
|
||||
|
||||
return currentNotifications.addAll(newNotifications);
|
||||
});
|
||||
}
|
||||
|
||||
static final provider = AsyncNotifierProvider.family
|
||||
.autoDispose<
|
||||
NotificationsController,
|
||||
IList<Event>,
|
||||
NotificationsRequest?
|
||||
>(NotificationsController.new);
|
||||
}
|
||||
|
|
@ -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<IList<Event>> {
|
||||
final String roomId;
|
||||
PinnedEventsController(this.roomId);
|
||||
|
||||
class PinnedEventsController(final String roomId)
|
||||
extends AsyncNotifier<IList<Event>> {
|
||||
@override
|
||||
Future<IList<Event>> build() async {
|
||||
final pinIds = ref.watch(PinnedIdsController.provider(roomId));
|
||||
|
|
@ -15,9 +13,8 @@ class PinnedEventsController extends AsyncNotifier<IList<Event>> {
|
|||
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();
|
||||
|
|
|
|||
|
|
@ -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<IList<String>> {
|
||||
final String roomId;
|
||||
PinnedIdsController(this.roomId);
|
||||
|
||||
class PinnedIdsController(final String roomId) extends Notifier<IList<String>> {
|
||||
@override
|
||||
IList<String> build() {
|
||||
final room = ref.watch(
|
||||
|
|
|
|||
22
lib/controllers/portal.dart
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import "dart:io";
|
||||
|
||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||
import "package:xdg_desktop_portal/xdg_desktop_portal.dart";
|
||||
|
||||
class PortalController extends AsyncNotifier<XdgDesktopPortalClient> {
|
||||
@override
|
||||
Future<XdgDesktopPortalClient> build() async {
|
||||
final portal = XdgDesktopPortalClient();
|
||||
if (!await File("/.flatpak-info").exists()) {
|
||||
await portal.registerApplication("nexus.federated.nexus");
|
||||
}
|
||||
|
||||
ref.onDispose(portal.close);
|
||||
return portal;
|
||||
}
|
||||
|
||||
static final provider =
|
||||
AsyncNotifierProvider<PortalController, XdgDesktopPortalClient>(
|
||||
PortalController.new,
|
||||
);
|
||||
}
|
||||
|
|
@ -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<bool> {
|
||||
final PowerLevelConfig config;
|
||||
PowerLevelController(this.config);
|
||||
|
||||
class PowerLevelController(final PowerLevelConfig config)
|
||||
extends Notifier<bool> {
|
||||
@override
|
||||
bool build() {
|
||||
if (config case EventPowerLevelConfig(:final eventType)) {
|
||||
|
|
|
|||
|
|
@ -2,13 +2,11 @@ import "package:flutter_riverpod/flutter_riverpod.dart";
|
|||
import "package:nexus/controllers/client.dart";
|
||||
import "package:nexus/models/profile_response.dart";
|
||||
|
||||
class ProfileController extends AsyncNotifier<ProfileResponse> {
|
||||
final String userId;
|
||||
ProfileController(this.userId);
|
||||
|
||||
class ProfileController(final String userId)
|
||||
extends AsyncNotifier<ProfileResponse> {
|
||||
@override
|
||||
Future<ProfileResponse> build() {
|
||||
final client = ref.watch(ClientController.provider.notifier);
|
||||
final client = ref.read(ClientController.provider.notifier);
|
||||
return client.getProfile(userId);
|
||||
}
|
||||
|
||||
|
|
|
|||
31
lib/controllers/push_key.dart
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
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 AsyncNotifier<String?> {
|
||||
@override
|
||||
Future<String?> build() async => json.decode(
|
||||
await ref.watch(KeyController.provider(KeyController.pushKeyKey).future) ??
|
||||
"{}",
|
||||
)[instance];
|
||||
|
||||
Future<void> set(String? value) async {
|
||||
final provider = KeyController.provider(KeyController.pushKeyKey);
|
||||
final notifier = ref.watch(provider.notifier);
|
||||
final prefs = IMap(json.decode(await ref.watch(provider.future) ?? "{}"));
|
||||
|
||||
state = .data(value);
|
||||
notifier.set(
|
||||
json.encode(
|
||||
prefs.add(instance, value).where((_, value) => value != null).unlock,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
static final provider =
|
||||
AsyncNotifierProvider.family<PushKeyController, String?, String>(
|
||||
PushKeyController.new,
|
||||
);
|
||||
}
|
||||
|
|
@ -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<IMap<String, IList<String>>> {
|
||||
final ReactionsConfig config;
|
||||
ReactionsController(this.config);
|
||||
|
||||
class ReactionsController(final ReactionsConfig config)
|
||||
extends AsyncNotifier<IMap<String, IList<String>>> {
|
||||
@override
|
||||
Future<IMap<String, IList<String>>> build() async {
|
||||
final eventInfo = ref.watch(
|
||||
|
|
|
|||
44
lib/controllers/recent_emoji.dart
Normal file
|
|
@ -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<IList<RecentEmoji>> {
|
||||
@override
|
||||
IList<RecentEmoji> build() => ref.watch(
|
||||
AccountDataController.provider.select(
|
||||
(value) => value.recentEmoji.recentEmoji,
|
||||
),
|
||||
);
|
||||
|
||||
Future<void> 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, IList<RecentEmoji>>(
|
||||
RecentEmojiController.new,
|
||||
);
|
||||
}
|
||||