Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
088cb4d5a2 | |||
33e84805d7 | |||
9aca6eb674 | |||
e431a54a89 | |||
c00987dfdc | |||
4187ceb248 | |||
152e076d44 | |||
7f36c86c55 | |||
311420e1f7 | |||
afe1c700eb | |||
b0c1981c9a | |||
d943275ed5 | |||
010a49251c | |||
bdc13978c3 | |||
5d8c73e468 |
83
.github/workflows/build.yml
vendored
Normal file
83
.github/workflows/build.yml
vendored
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
name: Build Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- '*'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-web:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Clone repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Set up Flutter
|
||||||
|
uses: subosito/flutter-action@v2
|
||||||
|
with:
|
||||||
|
channel: stable
|
||||||
|
cache: true
|
||||||
|
- run: flutter pub get
|
||||||
|
- run: flutter build web --release
|
||||||
|
- name: Archive production artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: build-output-web
|
||||||
|
path: build/web
|
||||||
|
build-exe:
|
||||||
|
runs-on: windows-latest
|
||||||
|
steps:
|
||||||
|
- name: Clone repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Set up Flutter
|
||||||
|
uses: subosito/flutter-action@v2
|
||||||
|
with:
|
||||||
|
channel: stable
|
||||||
|
cache: true
|
||||||
|
- run: flutter pub get
|
||||||
|
- run: flutter build windows
|
||||||
|
- name: Archive production artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: build-output-windows
|
||||||
|
path: build/windows/x64/runner/Release
|
||||||
|
build-linux:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Clone repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Set up Flutter
|
||||||
|
uses: subosito/flutter-action@v2
|
||||||
|
with:
|
||||||
|
channel: stable
|
||||||
|
- run: |
|
||||||
|
sudo apt-get update -y
|
||||||
|
sudo apt-get install -y ninja-build libgtk-3-dev
|
||||||
|
sudo apt-get install -y libmpv-dev mpv
|
||||||
|
sudo apt-get install -y libayatana-appindicator3-dev
|
||||||
|
sudo apt-get install -y keybinder-3.0
|
||||||
|
sudo apt-get install -y libnotify-dev
|
||||||
|
sudo apt-get install -y libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
|
||||||
|
sudo apt-get install -y gstreamer-1.0
|
||||||
|
- run: flutter pub get
|
||||||
|
- run: flutter build linux
|
||||||
|
- name: Archive production artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: build-output-linux
|
||||||
|
path: build/linux/x64/release/bundle
|
||||||
|
- name: Build AppImage
|
||||||
|
run: |
|
||||||
|
rm -r Solian.AppDir | true
|
||||||
|
mkdir Solian.AppDir
|
||||||
|
cp -r build/linux/x64/release/bundle/* Solian.AppDir
|
||||||
|
cp -r buildtools/appimage_config/* Solian.AppDir
|
||||||
|
cp assets/icon/icon-light-radius.png Solian.AppDir
|
||||||
|
sudo chmod +x buildtools/appimagetool-x86_64.AppImage
|
||||||
|
sudo chmod +x Solian.AppDir/AppRun
|
||||||
|
./buildtools/appimagetool-x86_64.AppImage Solian.AppDir
|
||||||
|
- name: Archive production artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: build-output-linux-appimage
|
||||||
|
path: './*.AppImage*'
|
1
.vscode/settings.json
vendored
Normal file
1
.vscode/settings.json
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
{}
|
@ -11,7 +11,7 @@ plugins {
|
|||||||
android {
|
android {
|
||||||
namespace = "dev.solsynth.solian"
|
namespace = "dev.solsynth.solian"
|
||||||
compileSdk = flutter.compileSdkVersion
|
compileSdk = flutter.compileSdkVersion
|
||||||
ndkVersion = "27.0.12077973"
|
ndkVersion = "29.0.13113456"
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility = JavaVersion.VERSION_17
|
sourceCompatibility = JavaVersion.VERSION_17
|
||||||
|
@ -34,19 +34,22 @@
|
|||||||
while the Flutter UI initializes. After that, this theme continues
|
while the Flutter UI initializes. After that, this theme continues
|
||||||
to determine the Window background behind the Flutter UI. -->
|
to determine the Window background behind the Flutter UI. -->
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="io.flutter.embedding.android.NormalTheme"
|
android:name="io.flutter.embedding.android.NormalTheme"
|
||||||
android:resource="@style/NormalTheme"
|
android:resource="@style/NormalTheme"
|
||||||
/>
|
/>
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER"/>
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<provider
|
<provider
|
||||||
android:name="com.superlist.super_native_extensions.DataProvider"
|
android:name="androidx.core.content.FileProvider"
|
||||||
android:authorities="dev.solsynth.solian.SuperClipboardDataProvider"
|
android:authorities="dev.solsynth.solian.provider"
|
||||||
android:exported="true"
|
android:exported="false"
|
||||||
android:grantUriPermissions="true" >
|
android:grantUriPermissions="true">
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||||
|
android:resource="@xml/provider_paths" />
|
||||||
</provider>
|
</provider>
|
||||||
<!-- Don't delete the meta-data below.
|
<!-- Don't delete the meta-data below.
|
||||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||||
@ -61,8 +64,8 @@
|
|||||||
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
|
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
|
||||||
<queries>
|
<queries>
|
||||||
<intent>
|
<intent>
|
||||||
<action android:name="android.intent.action.PROCESS_TEXT"/>
|
<action android:name="android.intent.action.PROCESS_TEXT" />
|
||||||
<data android:mimeType="text/plain"/>
|
<data android:mimeType="text/plain" />
|
||||||
</intent>
|
</intent>
|
||||||
</queries>
|
</queries>
|
||||||
</manifest>
|
</manifest>
|
@ -1,5 +0,0 @@
|
|||||||
package dev.solsynth.solian
|
|
||||||
|
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
|
||||||
|
|
||||||
class MainActivity : FlutterActivity()
|
|
@ -0,0 +1,14 @@
|
|||||||
|
package dev.solsynth.solian
|
||||||
|
|
||||||
|
import io.flutter.embedding.android.FlutterActivity
|
||||||
|
import io.flutter.embedding.engine.FlutterEngine
|
||||||
|
import io.flutter.plugins.sharedpreferences.LegacySharedPreferencesPlugin
|
||||||
|
|
||||||
|
class MainActivity : FlutterActivity()
|
||||||
|
{
|
||||||
|
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
||||||
|
super.configureFlutterEngine(flutterEngine)
|
||||||
|
// https://github.com/flutter/flutter/issues/153075#issuecomment-2693189362
|
||||||
|
flutterEngine.plugins.add(LegacySharedPreferencesPlugin())
|
||||||
|
}
|
||||||
|
}
|
6
android/app/src/main/res/xml/provider_paths.xml
Normal file
6
android/app/src/main/res/xml/provider_paths.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<external-path
|
||||||
|
name="external_files"
|
||||||
|
path="." />
|
||||||
|
</paths>
|
663
android/build/reports/problems/problems-report.html
Normal file
663
android/build/reports/problems/problems-report.html
Normal file
File diff suppressed because one or more lines are too long
@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
|
|||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-all.zip
|
||||||
|
@ -18,7 +18,7 @@ pluginManagement {
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
|
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
|
||||||
id("com.android.application") version "8.7.0" apply false
|
id("com.android.application") version "8.10.1" apply false
|
||||||
// START: FlutterFire Configuration
|
// START: FlutterFire Configuration
|
||||||
id("com.google.gms.google-services") version("4.3.15") apply false
|
id("com.google.gms.google-services") version("4.3.15") apply false
|
||||||
// END: FlutterFire Configuration
|
// END: FlutterFire Configuration
|
||||||
|
@ -99,6 +99,16 @@
|
|||||||
"permissionMember": "Member",
|
"permissionMember": "Member",
|
||||||
"reply": "Reply",
|
"reply": "Reply",
|
||||||
"forward": "Forward",
|
"forward": "Forward",
|
||||||
|
"repliedTo": "Replied to",
|
||||||
|
"forwarded": "Forwarded",
|
||||||
|
"hasAttachments": {
|
||||||
|
"one": "{} attachment",
|
||||||
|
"other": "{} attachments"
|
||||||
|
},
|
||||||
|
"postHasAttachments": {
|
||||||
|
"one": "{} attachment",
|
||||||
|
"other": "{} attachments"
|
||||||
|
},
|
||||||
"edited": "Edited",
|
"edited": "Edited",
|
||||||
"addVideo": "Add video",
|
"addVideo": "Add video",
|
||||||
"addPhoto": "Add photo",
|
"addPhoto": "Add photo",
|
||||||
@ -279,6 +289,10 @@
|
|||||||
"settingsSoundEffects": "Sound Effects",
|
"settingsSoundEffects": "Sound Effects",
|
||||||
"settingsAprilFoolFeatures": "April Fool Features",
|
"settingsAprilFoolFeatures": "April Fool Features",
|
||||||
"settingsEnterToSend": "Enter to Send",
|
"settingsEnterToSend": "Enter to Send",
|
||||||
|
"settingsTransparentAppBar": "Transparent App Bar",
|
||||||
|
"settingsCustomFonts": "Custom Fonts",
|
||||||
|
"settingsCustomFontsHint": "Custom fonts will be used for all text in the app. Make sure it is installed on your device.",
|
||||||
|
"settingsColorScheme": "Color Scheme",
|
||||||
"postTitle": "Title",
|
"postTitle": "Title",
|
||||||
"postDescription": "Description",
|
"postDescription": "Description",
|
||||||
"call": "Call",
|
"call": "Call",
|
||||||
@ -308,5 +322,13 @@
|
|||||||
"accountDataExportRequested": "Data export requested. You'll receive an email when it's ready.",
|
"accountDataExportRequested": "Data export requested. You'll receive an email when it's ready.",
|
||||||
"accountDeletionDescription": "Permanently delete your account and all your data",
|
"accountDeletionDescription": "Permanently delete your account and all your data",
|
||||||
"accountSettingsHelp": "Account Settings Help",
|
"accountSettingsHelp": "Account Settings Help",
|
||||||
"accountSettingsHelpContent": "This page allows you to manage your account security, privacy, and other settings. If you need assistance, please contact support."
|
"accountSettingsHelpContent": "This page allows you to manage your account security, privacy, and other settings. If you need assistance, please contact support.",
|
||||||
|
"unauthorized": "Unauthorized",
|
||||||
|
"unauthorizedHint": "You're not signed in or session expired, please sign in again.",
|
||||||
|
"publisherVisitAccountPage": "Visit the profile of {}",
|
||||||
|
"postVisibility": "Visibility",
|
||||||
|
"postVisibilityPublic": "Public",
|
||||||
|
"postVisibilityFriends": "Friends Only",
|
||||||
|
"postVisibilityUnlisted": "Unlisted",
|
||||||
|
"postVisibilityPrivate": "Private"
|
||||||
}
|
}
|
||||||
|
@ -99,6 +99,14 @@
|
|||||||
"permissionMember": "成员",
|
"permissionMember": "成员",
|
||||||
"reply": "回复",
|
"reply": "回复",
|
||||||
"forward": "转发",
|
"forward": "转发",
|
||||||
|
"repliedTo": "回复了",
|
||||||
|
"forwarded": "转发了",
|
||||||
|
"hasAttachments": {
|
||||||
|
"other": "{}个附件"
|
||||||
|
},
|
||||||
|
"postHasAttachments": {
|
||||||
|
"other": "{}个附件"
|
||||||
|
},
|
||||||
"edited": "已编辑",
|
"edited": "已编辑",
|
||||||
"addVideo": "添加视频",
|
"addVideo": "添加视频",
|
||||||
"addPhoto": "添加照片",
|
"addPhoto": "添加照片",
|
||||||
@ -278,5 +286,10 @@
|
|||||||
"settingsHideBottomNav": "隐藏底部导航",
|
"settingsHideBottomNav": "隐藏底部导航",
|
||||||
"settingsSoundEffects": "音效",
|
"settingsSoundEffects": "音效",
|
||||||
"settingsAprilFoolFeatures": "愚人节功能",
|
"settingsAprilFoolFeatures": "愚人节功能",
|
||||||
"settingsEnterToSend": "按下 Enter 发送"
|
"settingsEnterToSend": "按下 Enter 发送",
|
||||||
|
"postVisibility": "可见性",
|
||||||
|
"postVisibilityPublic": "公开",
|
||||||
|
"postVisibilityFriends": "仅好友可见",
|
||||||
|
"postVisibilityUnlisted": "不公开",
|
||||||
|
"postVisibilityPrivate": "私密"
|
||||||
}
|
}
|
@ -99,6 +99,14 @@
|
|||||||
"permissionMember": "成員",
|
"permissionMember": "成員",
|
||||||
"reply": "回覆",
|
"reply": "回覆",
|
||||||
"forward": "轉發",
|
"forward": "轉發",
|
||||||
|
"repliedTo": "回覆了",
|
||||||
|
"forwarded": "轉發了",
|
||||||
|
"hasAttachments": {
|
||||||
|
"other": "{}個附件"
|
||||||
|
},
|
||||||
|
"postHasAttachments": {
|
||||||
|
"other": "{}個附件"
|
||||||
|
},
|
||||||
"edited": "已編輯",
|
"edited": "已編輯",
|
||||||
"addVideo": "新增影片",
|
"addVideo": "新增影片",
|
||||||
"addPhoto": "新增照片",
|
"addPhoto": "新增照片",
|
||||||
@ -278,5 +286,10 @@
|
|||||||
"settingsHideBottomNav": "隱藏底部導航",
|
"settingsHideBottomNav": "隱藏底部導航",
|
||||||
"settingsSoundEffects": "音效",
|
"settingsSoundEffects": "音效",
|
||||||
"settingsAprilFoolFeatures": "愚人節功能",
|
"settingsAprilFoolFeatures": "愚人節功能",
|
||||||
"settingsEnterToSend": "按下 Enter 傳送"
|
"settingsEnterToSend": "按下 Enter 傳送",
|
||||||
|
"postVisibility": "可見性",
|
||||||
|
"postVisibilityPublic": "公開",
|
||||||
|
"postVisibilityFriends": "僅好友可見",
|
||||||
|
"postVisibilityUnlisted": "不公開",
|
||||||
|
"postVisibilityPrivate": "私密"
|
||||||
}
|
}
|
10
ios/Podfile
10
ios/Podfile
@ -29,13 +29,21 @@ flutter_ios_podfile_setup
|
|||||||
|
|
||||||
target 'Runner' do
|
target 'Runner' do
|
||||||
use_frameworks!
|
use_frameworks!
|
||||||
|
use_modular_headers!
|
||||||
|
|
||||||
pod 'Kingfisher', '~> 8.0'
|
pod 'Alamofire'
|
||||||
|
|
||||||
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
|
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
|
||||||
|
|
||||||
target 'RunnerTests' do
|
target 'RunnerTests' do
|
||||||
inherit! :search_paths
|
inherit! :search_paths
|
||||||
end
|
end
|
||||||
|
|
||||||
|
target 'SolianNotificationService' do
|
||||||
|
inherit! :search_paths
|
||||||
|
pod 'Kingfisher', '~> 8.0'
|
||||||
|
pod 'Alamofire'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
post_install do |installer|
|
post_install do |installer|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
PODS:
|
PODS:
|
||||||
|
- Alamofire (5.10.2)
|
||||||
- connectivity_plus (0.0.1):
|
- connectivity_plus (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- croppy (0.0.1):
|
- croppy (0.0.1):
|
||||||
@ -137,6 +138,8 @@ PODS:
|
|||||||
- OrderedSet (6.0.3)
|
- OrderedSet (6.0.3)
|
||||||
- package_info_plus (0.4.5):
|
- package_info_plus (0.4.5):
|
||||||
- Flutter
|
- Flutter
|
||||||
|
- pasteboard (0.0.1):
|
||||||
|
- Flutter
|
||||||
- path_provider_foundation (0.0.1):
|
- path_provider_foundation (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
@ -185,6 +188,7 @@ PODS:
|
|||||||
- WebRTC-SDK (125.6422.07)
|
- WebRTC-SDK (125.6422.07)
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
|
- Alamofire
|
||||||
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
|
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
|
||||||
- croppy (from `.symlinks/plugins/croppy/ios`)
|
- croppy (from `.symlinks/plugins/croppy/ios`)
|
||||||
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
||||||
@ -204,6 +208,7 @@ DEPENDENCIES:
|
|||||||
- media_kit_libs_ios_video (from `.symlinks/plugins/media_kit_libs_ios_video/ios`)
|
- media_kit_libs_ios_video (from `.symlinks/plugins/media_kit_libs_ios_video/ios`)
|
||||||
- media_kit_video (from `.symlinks/plugins/media_kit_video/ios`)
|
- media_kit_video (from `.symlinks/plugins/media_kit_video/ios`)
|
||||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||||
|
- pasteboard (from `.symlinks/plugins/pasteboard/ios`)
|
||||||
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
||||||
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||||
- sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
|
- sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
|
||||||
@ -215,6 +220,7 @@ DEPENDENCIES:
|
|||||||
|
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
|
- Alamofire
|
||||||
- DKImagePickerController
|
- DKImagePickerController
|
||||||
- DKPhotoGallery
|
- DKPhotoGallery
|
||||||
- Firebase
|
- Firebase
|
||||||
@ -271,6 +277,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: ".symlinks/plugins/media_kit_video/ios"
|
:path: ".symlinks/plugins/media_kit_video/ios"
|
||||||
package_info_plus:
|
package_info_plus:
|
||||||
:path: ".symlinks/plugins/package_info_plus/ios"
|
:path: ".symlinks/plugins/package_info_plus/ios"
|
||||||
|
pasteboard:
|
||||||
|
:path: ".symlinks/plugins/pasteboard/ios"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
:path: ".symlinks/plugins/path_provider_foundation/darwin"
|
:path: ".symlinks/plugins/path_provider_foundation/darwin"
|
||||||
shared_preferences_foundation:
|
shared_preferences_foundation:
|
||||||
@ -289,6 +297,7 @@ EXTERNAL SOURCES:
|
|||||||
:path: ".symlinks/plugins/wakelock_plus/ios"
|
:path: ".symlinks/plugins/wakelock_plus/ios"
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
|
Alamofire: 7193b3b92c74a07f85569e1a6c4f4237291e7496
|
||||||
connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd
|
connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd
|
||||||
croppy: 979e8ddc254f4642bffe7d52dc7193354b27ba30
|
croppy: 979e8ddc254f4642bffe7d52dc7193354b27ba30
|
||||||
device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe
|
device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe
|
||||||
@ -319,6 +328,7 @@ SPEC CHECKSUMS:
|
|||||||
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
|
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
|
||||||
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
|
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
|
||||||
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
|
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
|
||||||
|
pasteboard: 49088aeb6119d51f976a421db60d8e1ab079b63c
|
||||||
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
|
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
|
||||||
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
|
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
|
||||||
SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c
|
SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c
|
||||||
@ -334,6 +344,6 @@ SPEC CHECKSUMS:
|
|||||||
wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556
|
wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556
|
||||||
WebRTC-SDK: dff00a3892bc570b6014e046297782084071657e
|
WebRTC-SDK: dff00a3892bc570b6014e046297782084071657e
|
||||||
|
|
||||||
PODFILE CHECKSUM: 2608312fddeea6d787ca3aa478c756da8f4ca66d
|
PODFILE CHECKSUM: 0c13198c20d0416ef589aeb2e1dac5c50262254f
|
||||||
|
|
||||||
COCOAPODS: 1.16.2
|
COCOAPODS: 1.16.2
|
||||||
|
@ -10,12 +10,15 @@
|
|||||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
||||||
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
|
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
|
||||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||||
|
73CDD6812DEC00480059D95D /* SolianNotificationService.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 73CDD67A2DEC00480059D95D /* SolianNotificationService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||||
|
73D4264B2DEB815D006C0AAE /* NotifyDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73D4264A2DEB815D006C0AAE /* NotifyDelegate.swift */; };
|
||||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
||||||
755557017FD1B99AFC4F9127 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 29812C17FFBE7DBBC7203981 /* Pods_RunnerTests.framework */; };
|
755557017FD1B99AFC4F9127 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 29812C17FFBE7DBBC7203981 /* Pods_RunnerTests.framework */; };
|
||||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
||||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
||||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
||||||
B87C0E607033790E71B54D73 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6D834CA86410B09796B312B /* Pods_Runner.framework */; };
|
B87C0E607033790E71B54D73 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6D834CA86410B09796B312B /* Pods_Runner.framework */; };
|
||||||
|
D1772CE196985AE8E8C9F2E5 /* Pods_SolianNotificationService.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 39FE4CC6223F0D3C0E1FFD04 /* Pods_SolianNotificationService.framework */; };
|
||||||
E7A0B456EF7AAA71D1397081 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9AE244813FCDFAA941430393 /* GoogleService-Info.plist */; };
|
E7A0B456EF7AAA71D1397081 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9AE244813FCDFAA941430393 /* GoogleService-Info.plist */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
@ -27,9 +30,27 @@
|
|||||||
remoteGlobalIDString = 97C146ED1CF9000F007C117D;
|
remoteGlobalIDString = 97C146ED1CF9000F007C117D;
|
||||||
remoteInfo = Runner;
|
remoteInfo = Runner;
|
||||||
};
|
};
|
||||||
|
73CDD67F2DEC00480059D95D /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 97C146E61CF9000F007C117D /* Project object */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = 73CDD6792DEC00480059D95D;
|
||||||
|
remoteInfo = SolianNotificationService;
|
||||||
|
};
|
||||||
/* End PBXContainerItemProxy section */
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
/* Begin PBXCopyFilesBuildPhase section */
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
|
73268D1D2DEAFD670076E970 /* Embed Foundation Extensions */ = {
|
||||||
|
isa = PBXCopyFilesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
dstPath = "";
|
||||||
|
dstSubfolderSpec = 13;
|
||||||
|
files = (
|
||||||
|
73CDD6812DEC00480059D95D /* SolianNotificationService.appex in Embed Foundation Extensions */,
|
||||||
|
);
|
||||||
|
name = "Embed Foundation Extensions";
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
|
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
|
||||||
isa = PBXCopyFilesBuildPhase;
|
isa = PBXCopyFilesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
@ -47,16 +68,23 @@
|
|||||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
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>"; };
|
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||||
14DFD79BE7C26E51B117583C /* 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>"; };
|
14DFD79BE7C26E51B117583C /* 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>"; };
|
||||||
|
192FDACE67D7CB6AED15C634 /* Pods-NotificationService.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotificationService.debug.xcconfig"; path = "Target Support Files/Pods-NotificationService/Pods-NotificationService.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
1C14F71D23E4371602065522 /* 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>"; };
|
1C14F71D23E4371602065522 /* 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>"; };
|
||||||
|
252A83CE6862573BB856ED8E /* Pods-NotificationService.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotificationService.release.xcconfig"; path = "Target Support Files/Pods-NotificationService/Pods-NotificationService.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
29812C17FFBE7DBBC7203981 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
29812C17FFBE7DBBC7203981 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
2D2457F8B2E6EF9C0F935035 /* Pods-NotificationService.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotificationService.profile.xcconfig"; path = "Target Support Files/Pods-NotificationService/Pods-NotificationService.profile.xcconfig"; sourceTree = "<group>"; };
|
||||||
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; 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; };
|
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
39FE4CC6223F0D3C0E1FFD04 /* Pods_SolianNotificationService.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SolianNotificationService.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
3A1C47BD29CC6AC2587D4DBE /* 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>"; };
|
3A1C47BD29CC6AC2587D4DBE /* 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>"; };
|
||||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||||
737E920B2DB6A9FF00BE9CDB /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
|
737E920B2DB6A9FF00BE9CDB /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
|
||||||
|
73CDD67A2DEC00480059D95D /* SolianNotificationService.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = SolianNotificationService.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
73D4264A2DEB815D006C0AAE /* NotifyDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotifyDelegate.swift; sourceTree = "<group>"; };
|
||||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; 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>"; };
|
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
||||||
|
8B40620B1EEBB09456406A3C /* Pods-SolianNotificationService.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SolianNotificationService.profile.xcconfig"; path = "Target Support Files/Pods-SolianNotificationService/Pods-SolianNotificationService.profile.xcconfig"; sourceTree = "<group>"; };
|
||||||
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
|
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>"; };
|
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; };
|
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
@ -66,10 +94,50 @@
|
|||||||
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
9AE244813FCDFAA941430393 /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = "<group>"; };
|
9AE244813FCDFAA941430393 /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = "<group>"; };
|
||||||
A499FDB2082EB000933AA8C5 /* 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>"; };
|
A499FDB2082EB000933AA8C5 /* 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>"; };
|
||||||
|
AA0CA8A3E15DEE023BB27438 /* Pods_NotificationService.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_NotificationService.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
B93771F2A63E4148DC6142F7 /* Pods-SolianNotificationService.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SolianNotificationService.release.xcconfig"; path = "Target Support Files/Pods-SolianNotificationService/Pods-SolianNotificationService.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
E6B10A9A85BECA2E576C91FF /* 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>"; };
|
E6B10A9A85BECA2E576C91FF /* 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>"; };
|
||||||
F6D834CA86410B09796B312B /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
F6D834CA86410B09796B312B /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
F830F535CB92E3F2E1653A11 /* Pods-SolianNotificationService.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SolianNotificationService.debug.xcconfig"; path = "Target Support Files/Pods-SolianNotificationService/Pods-SolianNotificationService.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
||||||
|
73CDD6822DEC00480059D95D /* Exceptions for "SolianNotificationService" folder in "SolianNotificationService" target */ = {
|
||||||
|
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
|
||||||
|
membershipExceptions = (
|
||||||
|
Info.plist,
|
||||||
|
);
|
||||||
|
target = 73CDD6792DEC00480059D95D /* SolianNotificationService */;
|
||||||
|
};
|
||||||
|
73CDD68E2DEC00BE0059D95D /* Exceptions for "Services" folder in "SolianNotificationService" target */ = {
|
||||||
|
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
|
||||||
|
membershipExceptions = (
|
||||||
|
CloudFile.swift,
|
||||||
|
DataExchange.swift,
|
||||||
|
);
|
||||||
|
target = 73CDD6792DEC00480059D95D /* SolianNotificationService */;
|
||||||
|
};
|
||||||
|
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
||||||
|
|
||||||
|
/* Begin PBXFileSystemSynchronizedRootGroup section */
|
||||||
|
73268D272DEB012A0076E970 /* Services */ = {
|
||||||
|
isa = PBXFileSystemSynchronizedRootGroup;
|
||||||
|
exceptions = (
|
||||||
|
73CDD68E2DEC00BE0059D95D /* Exceptions for "Services" folder in "SolianNotificationService" target */,
|
||||||
|
);
|
||||||
|
path = Services;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
73CDD67B2DEC00480059D95D /* SolianNotificationService */ = {
|
||||||
|
isa = PBXFileSystemSynchronizedRootGroup;
|
||||||
|
exceptions = (
|
||||||
|
73CDD6822DEC00480059D95D /* Exceptions for "SolianNotificationService" folder in "SolianNotificationService" target */,
|
||||||
|
);
|
||||||
|
path = SolianNotificationService;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXFileSystemSynchronizedRootGroup section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
1DFF8FEBBD0CF5A990600776 /* Frameworks */ = {
|
1DFF8FEBBD0CF5A990600776 /* Frameworks */ = {
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
@ -79,6 +147,14 @@
|
|||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
73CDD6772DEC00480059D95D /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
D1772CE196985AE8E8C9F2E5 /* Pods_SolianNotificationService.framework in Frameworks */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
97C146EB1CF9000F007C117D /* Frameworks */ = {
|
97C146EB1CF9000F007C117D /* Frameworks */ = {
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
@ -103,6 +179,8 @@
|
|||||||
children = (
|
children = (
|
||||||
F6D834CA86410B09796B312B /* Pods_Runner.framework */,
|
F6D834CA86410B09796B312B /* Pods_Runner.framework */,
|
||||||
29812C17FFBE7DBBC7203981 /* Pods_RunnerTests.framework */,
|
29812C17FFBE7DBBC7203981 /* Pods_RunnerTests.framework */,
|
||||||
|
AA0CA8A3E15DEE023BB27438 /* Pods_NotificationService.framework */,
|
||||||
|
39FE4CC6223F0D3C0E1FFD04 /* Pods_SolianNotificationService.framework */,
|
||||||
);
|
);
|
||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -116,6 +194,12 @@
|
|||||||
14DFD79BE7C26E51B117583C /* Pods-RunnerTests.debug.xcconfig */,
|
14DFD79BE7C26E51B117583C /* Pods-RunnerTests.debug.xcconfig */,
|
||||||
14118AC858B441AB16B7309E /* Pods-RunnerTests.release.xcconfig */,
|
14118AC858B441AB16B7309E /* Pods-RunnerTests.release.xcconfig */,
|
||||||
E6B10A9A85BECA2E576C91FF /* Pods-RunnerTests.profile.xcconfig */,
|
E6B10A9A85BECA2E576C91FF /* Pods-RunnerTests.profile.xcconfig */,
|
||||||
|
192FDACE67D7CB6AED15C634 /* Pods-NotificationService.debug.xcconfig */,
|
||||||
|
252A83CE6862573BB856ED8E /* Pods-NotificationService.release.xcconfig */,
|
||||||
|
2D2457F8B2E6EF9C0F935035 /* Pods-NotificationService.profile.xcconfig */,
|
||||||
|
F830F535CB92E3F2E1653A11 /* Pods-SolianNotificationService.debug.xcconfig */,
|
||||||
|
B93771F2A63E4148DC6142F7 /* Pods-SolianNotificationService.release.xcconfig */,
|
||||||
|
8B40620B1EEBB09456406A3C /* Pods-SolianNotificationService.profile.xcconfig */,
|
||||||
);
|
);
|
||||||
path = Pods;
|
path = Pods;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -136,6 +220,7 @@
|
|||||||
children = (
|
children = (
|
||||||
9740EEB11CF90186004384FC /* Flutter */,
|
9740EEB11CF90186004384FC /* Flutter */,
|
||||||
97C146F01CF9000F007C117D /* Runner */,
|
97C146F01CF9000F007C117D /* Runner */,
|
||||||
|
73CDD67B2DEC00480059D95D /* SolianNotificationService */,
|
||||||
97C146EF1CF9000F007C117D /* Products */,
|
97C146EF1CF9000F007C117D /* Products */,
|
||||||
331C8082294A63A400263BE5 /* RunnerTests */,
|
331C8082294A63A400263BE5 /* RunnerTests */,
|
||||||
91E124CE95BCB4DCD890160D /* Pods */,
|
91E124CE95BCB4DCD890160D /* Pods */,
|
||||||
@ -149,6 +234,7 @@
|
|||||||
children = (
|
children = (
|
||||||
97C146EE1CF9000F007C117D /* Runner.app */,
|
97C146EE1CF9000F007C117D /* Runner.app */,
|
||||||
331C8081294A63A400263BE5 /* RunnerTests.xctest */,
|
331C8081294A63A400263BE5 /* RunnerTests.xctest */,
|
||||||
|
73CDD67A2DEC00480059D95D /* SolianNotificationService.appex */,
|
||||||
);
|
);
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -156,6 +242,7 @@
|
|||||||
97C146F01CF9000F007C117D /* Runner */ = {
|
97C146F01CF9000F007C117D /* Runner */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
73268D272DEB012A0076E970 /* Services */,
|
||||||
737E920B2DB6A9FF00BE9CDB /* Runner.entitlements */,
|
737E920B2DB6A9FF00BE9CDB /* Runner.entitlements */,
|
||||||
97C146FA1CF9000F007C117D /* Main.storyboard */,
|
97C146FA1CF9000F007C117D /* Main.storyboard */,
|
||||||
97C146FD1CF9000F007C117D /* Assets.xcassets */,
|
97C146FD1CF9000F007C117D /* Assets.xcassets */,
|
||||||
@ -165,6 +252,7 @@
|
|||||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
|
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
|
||||||
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
|
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
|
||||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
|
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
|
||||||
|
73D4264A2DEB815D006C0AAE /* NotifyDelegate.swift */,
|
||||||
);
|
);
|
||||||
path = Runner;
|
path = Runner;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -191,6 +279,27 @@
|
|||||||
productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */;
|
productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */;
|
||||||
productType = "com.apple.product-type.bundle.unit-test";
|
productType = "com.apple.product-type.bundle.unit-test";
|
||||||
};
|
};
|
||||||
|
73CDD6792DEC00480059D95D /* SolianNotificationService */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 73CDD6832DEC00480059D95D /* Build configuration list for PBXNativeTarget "SolianNotificationService" */;
|
||||||
|
buildPhases = (
|
||||||
|
5FC5C1EF9F17B7166B432FF2 /* [CP] Check Pods Manifest.lock */,
|
||||||
|
73CDD6762DEC00480059D95D /* Sources */,
|
||||||
|
73CDD6772DEC00480059D95D /* Frameworks */,
|
||||||
|
73CDD6782DEC00480059D95D /* Resources */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
fileSystemSynchronizedGroups = (
|
||||||
|
73CDD67B2DEC00480059D95D /* SolianNotificationService */,
|
||||||
|
);
|
||||||
|
name = SolianNotificationService;
|
||||||
|
productName = SolianNotificationService;
|
||||||
|
productReference = 73CDD67A2DEC00480059D95D /* SolianNotificationService.appex */;
|
||||||
|
productType = "com.apple.product-type.app-extension";
|
||||||
|
};
|
||||||
97C146ED1CF9000F007C117D /* Runner */ = {
|
97C146ED1CF9000F007C117D /* Runner */ = {
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||||
@ -199,6 +308,7 @@
|
|||||||
9740EEB61CF901F6004384FC /* Run Script */,
|
9740EEB61CF901F6004384FC /* Run Script */,
|
||||||
97C146EA1CF9000F007C117D /* Sources */,
|
97C146EA1CF9000F007C117D /* Sources */,
|
||||||
97C146EB1CF9000F007C117D /* Frameworks */,
|
97C146EB1CF9000F007C117D /* Frameworks */,
|
||||||
|
73268D1D2DEAFD670076E970 /* Embed Foundation Extensions */,
|
||||||
97C146EC1CF9000F007C117D /* Resources */,
|
97C146EC1CF9000F007C117D /* Resources */,
|
||||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||||
@ -208,6 +318,10 @@
|
|||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
|
73CDD6802DEC00480059D95D /* PBXTargetDependency */,
|
||||||
|
);
|
||||||
|
fileSystemSynchronizedGroups = (
|
||||||
|
73268D272DEB012A0076E970 /* Services */,
|
||||||
);
|
);
|
||||||
name = Runner;
|
name = Runner;
|
||||||
productName = Runner;
|
productName = Runner;
|
||||||
@ -221,6 +335,7 @@
|
|||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
BuildIndependentTargetsInParallel = YES;
|
BuildIndependentTargetsInParallel = YES;
|
||||||
|
LastSwiftUpdateCheck = 1640;
|
||||||
LastUpgradeCheck = 1510;
|
LastUpgradeCheck = 1510;
|
||||||
ORGANIZATIONNAME = "";
|
ORGANIZATIONNAME = "";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
@ -228,6 +343,9 @@
|
|||||||
CreatedOnToolsVersion = 14.0;
|
CreatedOnToolsVersion = 14.0;
|
||||||
TestTargetID = 97C146ED1CF9000F007C117D;
|
TestTargetID = 97C146ED1CF9000F007C117D;
|
||||||
};
|
};
|
||||||
|
73CDD6792DEC00480059D95D = {
|
||||||
|
CreatedOnToolsVersion = 16.4;
|
||||||
|
};
|
||||||
97C146ED1CF9000F007C117D = {
|
97C146ED1CF9000F007C117D = {
|
||||||
CreatedOnToolsVersion = 7.3.1;
|
CreatedOnToolsVersion = 7.3.1;
|
||||||
LastSwiftMigration = 1100;
|
LastSwiftMigration = 1100;
|
||||||
@ -235,7 +353,6 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
|
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
|
||||||
compatibilityVersion = "Xcode 9.3";
|
|
||||||
developmentRegion = en;
|
developmentRegion = en;
|
||||||
hasScannedForEncodings = 0;
|
hasScannedForEncodings = 0;
|
||||||
knownRegions = (
|
knownRegions = (
|
||||||
@ -243,12 +360,14 @@
|
|||||||
Base,
|
Base,
|
||||||
);
|
);
|
||||||
mainGroup = 97C146E51CF9000F007C117D;
|
mainGroup = 97C146E51CF9000F007C117D;
|
||||||
|
preferredProjectObjectVersion = 77;
|
||||||
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
|
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
targets = (
|
targets = (
|
||||||
97C146ED1CF9000F007C117D /* Runner */,
|
97C146ED1CF9000F007C117D /* Runner */,
|
||||||
331C8080294A63A400263BE5 /* RunnerTests */,
|
331C8080294A63A400263BE5 /* RunnerTests */,
|
||||||
|
73CDD6792DEC00480059D95D /* SolianNotificationService */,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
/* End PBXProject section */
|
/* End PBXProject section */
|
||||||
@ -261,6 +380,13 @@
|
|||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
73CDD6782DEC00480059D95D /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
97C146EC1CF9000F007C117D /* Resources */ = {
|
97C146EC1CF9000F007C117D /* Resources */ = {
|
||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
@ -331,6 +457,28 @@
|
|||||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
|
||||||
showEnvVarsInLog = 0;
|
showEnvVarsInLog = 0;
|
||||||
};
|
};
|
||||||
|
5FC5C1EF9F17B7166B432FF2 /* [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-SolianNotificationService-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;
|
||||||
|
};
|
||||||
8C0351B03869BBF493808288 /* [CP] Embed Pods Frameworks */ = {
|
8C0351B03869BBF493808288 /* [CP] Embed Pods Frameworks */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
@ -396,12 +544,20 @@
|
|||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
73CDD6762DEC00480059D95D /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
97C146EA1CF9000F007C117D /* Sources */ = {
|
97C146EA1CF9000F007C117D /* Sources */ = {
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
|
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
|
||||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
|
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
|
||||||
|
73D4264B2DEB815D006C0AAE /* NotifyDelegate.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -413,6 +569,11 @@
|
|||||||
target = 97C146ED1CF9000F007C117D /* Runner */;
|
target = 97C146ED1CF9000F007C117D /* Runner */;
|
||||||
targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */;
|
targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */;
|
||||||
};
|
};
|
||||||
|
73CDD6802DEC00480059D95D /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
target = 73CDD6792DEC00480059D95D /* SolianNotificationService */;
|
||||||
|
targetProxy = 73CDD67F2DEC00480059D95D /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
/* End PBXTargetDependency section */
|
/* End PBXTargetDependency section */
|
||||||
|
|
||||||
/* Begin PBXVariantGroup section */
|
/* Begin PBXVariantGroup section */
|
||||||
@ -562,6 +723,123 @@
|
|||||||
};
|
};
|
||||||
name = Profile;
|
name = Profile;
|
||||||
};
|
};
|
||||||
|
73CDD6842DEC00480059D95D /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = F830F535CB92E3F2E1653A11 /* Pods-SolianNotificationService.debug.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = W7HPZ53V6B;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = SolianNotificationService/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = SolianNotificationService;
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 18.5;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
"@executable_path/../../Frameworks",
|
||||||
|
);
|
||||||
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
|
MTL_FAST_MATH = YES;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = dev.solsynth.solian.SolianNotificationService;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
73CDD6852DEC00480059D95D /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = B93771F2A63E4148DC6142F7 /* Pods-SolianNotificationService.release.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = W7HPZ53V6B;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = SolianNotificationService/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = SolianNotificationService;
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 18.5;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
"@executable_path/../../Frameworks",
|
||||||
|
);
|
||||||
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
MTL_FAST_MATH = YES;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = dev.solsynth.solian.SolianNotificationService;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
73CDD6862DEC00480059D95D /* Profile */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 8B40620B1EEBB09456406A3C /* Pods-SolianNotificationService.profile.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = W7HPZ53V6B;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = SolianNotificationService/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = SolianNotificationService;
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 18.5;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
"@executable_path/../../Frameworks",
|
||||||
|
);
|
||||||
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
MTL_FAST_MATH = YES;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = dev.solsynth.solian.SolianNotificationService;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
};
|
||||||
|
name = Profile;
|
||||||
|
};
|
||||||
97C147031CF9000F007C117D /* Debug */ = {
|
97C147031CF9000F007C117D /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
@ -737,6 +1015,16 @@
|
|||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
|
73CDD6832DEC00480059D95D /* Build configuration list for PBXNativeTarget "SolianNotificationService" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
73CDD6842DEC00480059D95D /* Debug */,
|
||||||
|
73CDD6852DEC00480059D95D /* Release */,
|
||||||
|
73CDD6862DEC00480059D95D /* Profile */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
|
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
|
@ -3,11 +3,15 @@ import UIKit
|
|||||||
|
|
||||||
@main
|
@main
|
||||||
@objc class AppDelegate: FlutterAppDelegate {
|
@objc class AppDelegate: FlutterAppDelegate {
|
||||||
|
let notifyDelegate = NotifyDelegate()
|
||||||
|
|
||||||
override func application(
|
override func application(
|
||||||
_ application: UIApplication,
|
_ application: UIApplication,
|
||||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
||||||
) -> Bool {
|
) -> Bool {
|
||||||
GeneratedPluginRegistrant.register(with: self)
|
UNUserNotificationCenter.current().delegate = notifyDelegate
|
||||||
|
|
||||||
|
GeneratedPluginRegistrant.register(with: self)
|
||||||
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>ITSAppUsesNonExemptEncryption</key>
|
||||||
|
<false/>
|
||||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
@ -64,5 +66,10 @@
|
|||||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
</array>
|
</array>
|
||||||
|
<key>NSUserActivityTypes</key>
|
||||||
|
<array>
|
||||||
|
<string>INStartCallIntent</string>
|
||||||
|
<string>INSendMessageIntent</string>
|
||||||
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
@ -1,153 +0,0 @@
|
|||||||
//
|
|
||||||
// BlurHashDecoder.swift
|
|
||||||
// Runner
|
|
||||||
//
|
|
||||||
// Created by LittleSheep on 2025/4/21.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
extension UIImage {
|
|
||||||
public convenience init?(blurHash: String, size: CGSize, punch: Float = 1) {
|
|
||||||
guard blurHash.count >= 6 else { return nil }
|
|
||||||
|
|
||||||
let sizeFlag = String(blurHash[0]).decode83()
|
|
||||||
let numY = (sizeFlag / 9) + 1
|
|
||||||
let numX = (sizeFlag % 9) + 1
|
|
||||||
|
|
||||||
let quantisedMaximumValue = String(blurHash[1]).decode83()
|
|
||||||
let maximumValue = Float(quantisedMaximumValue + 1) / 166
|
|
||||||
|
|
||||||
guard blurHash.count == 4 + 2 * numX * numY else { return nil }
|
|
||||||
|
|
||||||
let colours: [(Float, Float, Float)] = (0 ..< numX * numY).map { i in
|
|
||||||
if i == 0 {
|
|
||||||
let value = String(blurHash[2 ..< 6]).decode83()
|
|
||||||
return decodeDC(value)
|
|
||||||
} else {
|
|
||||||
let value = String(blurHash[4 + i * 2 ..< 4 + i * 2 + 2]).decode83()
|
|
||||||
return decodeAC(value, maximumValue: maximumValue * punch)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let width = Int(size.width)
|
|
||||||
let height = Int(size.height)
|
|
||||||
let bytesPerRow = width * 3
|
|
||||||
guard let data = CFDataCreateMutable(kCFAllocatorDefault, bytesPerRow * height) else { return nil }
|
|
||||||
CFDataSetLength(data, bytesPerRow * height)
|
|
||||||
guard let pixels = CFDataGetMutableBytePtr(data) else { return nil }
|
|
||||||
|
|
||||||
for y in 0 ..< height {
|
|
||||||
for x in 0 ..< width {
|
|
||||||
var r: Float = 0
|
|
||||||
var g: Float = 0
|
|
||||||
var b: Float = 0
|
|
||||||
|
|
||||||
for j in 0 ..< numY {
|
|
||||||
for i in 0 ..< numX {
|
|
||||||
let basis = cos(Float.pi * Float(x) * Float(i) / Float(width)) * cos(Float.pi * Float(y) * Float(j) / Float(height))
|
|
||||||
let colour = colours[i + j * numX]
|
|
||||||
r += colour.0 * basis
|
|
||||||
g += colour.1 * basis
|
|
||||||
b += colour.2 * basis
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let intR = UInt8(linearTosRGB(r))
|
|
||||||
let intG = UInt8(linearTosRGB(g))
|
|
||||||
let intB = UInt8(linearTosRGB(b))
|
|
||||||
|
|
||||||
pixels[3 * x + 0 + y * bytesPerRow] = intR
|
|
||||||
pixels[3 * x + 1 + y * bytesPerRow] = intG
|
|
||||||
pixels[3 * x + 2 + y * bytesPerRow] = intB
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue)
|
|
||||||
|
|
||||||
guard let provider = CGDataProvider(data: data) else { return nil }
|
|
||||||
guard let cgImage = CGImage(width: width, height: height, bitsPerComponent: 8, bitsPerPixel: 24, bytesPerRow: bytesPerRow,
|
|
||||||
space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: bitmapInfo, provider: provider, decode: nil, shouldInterpolate: true, intent: .defaultIntent) else { return nil }
|
|
||||||
|
|
||||||
self.init(cgImage: cgImage)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func decodeDC(_ value: Int) -> (Float, Float, Float) {
|
|
||||||
let intR = value >> 16
|
|
||||||
let intG = (value >> 8) & 255
|
|
||||||
let intB = value & 255
|
|
||||||
return (sRGBToLinear(intR), sRGBToLinear(intG), sRGBToLinear(intB))
|
|
||||||
}
|
|
||||||
|
|
||||||
private func decodeAC(_ value: Int, maximumValue: Float) -> (Float, Float, Float) {
|
|
||||||
let quantR = value / (19 * 19)
|
|
||||||
let quantG = (value / 19) % 19
|
|
||||||
let quantB = value % 19
|
|
||||||
|
|
||||||
let rgb = (
|
|
||||||
signPow((Float(quantR) - 9) / 9, 2) * maximumValue,
|
|
||||||
signPow((Float(quantG) - 9) / 9, 2) * maximumValue,
|
|
||||||
signPow((Float(quantB) - 9) / 9, 2) * maximumValue
|
|
||||||
)
|
|
||||||
|
|
||||||
return rgb
|
|
||||||
}
|
|
||||||
|
|
||||||
private func signPow(_ value: Float, _ exp: Float) -> Float {
|
|
||||||
return copysign(pow(abs(value), exp), value)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func linearTosRGB(_ value: Float) -> Int {
|
|
||||||
let v = max(0, min(1, value))
|
|
||||||
if v <= 0.0031308 { return Int(v * 12.92 * 255 + 0.5) }
|
|
||||||
else { return Int((1.055 * pow(v, 1 / 2.4) - 0.055) * 255 + 0.5) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private func sRGBToLinear<Type: BinaryInteger>(_ value: Type) -> Float {
|
|
||||||
let v = Float(Int64(value)) / 255
|
|
||||||
if v <= 0.04045 { return v / 12.92 }
|
|
||||||
else { return pow((v + 0.055) / 1.055, 2.4) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private let encodeCharacters: [String] = {
|
|
||||||
return "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~".map { String($0) }
|
|
||||||
}()
|
|
||||||
|
|
||||||
private let decodeCharacters: [String: Int] = {
|
|
||||||
var dict: [String: Int] = [:]
|
|
||||||
for (index, character) in encodeCharacters.enumerated() {
|
|
||||||
dict[character] = index
|
|
||||||
}
|
|
||||||
return dict
|
|
||||||
}()
|
|
||||||
|
|
||||||
extension String {
|
|
||||||
func decode83() -> Int {
|
|
||||||
var value: Int = 0
|
|
||||||
for character in self {
|
|
||||||
if let digit = decodeCharacters[String(character)] {
|
|
||||||
value = value * 83 + digit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private extension String {
|
|
||||||
subscript (offset: Int) -> Character {
|
|
||||||
return self[index(startIndex, offsetBy: offset)]
|
|
||||||
}
|
|
||||||
|
|
||||||
subscript (bounds: CountableClosedRange<Int>) -> Substring {
|
|
||||||
let start = index(startIndex, offsetBy: bounds.lowerBound)
|
|
||||||
let end = index(startIndex, offsetBy: bounds.upperBound)
|
|
||||||
return self[start...end]
|
|
||||||
}
|
|
||||||
|
|
||||||
subscript (bounds: CountableRange<Int>) -> Substring {
|
|
||||||
let start = index(startIndex, offsetBy: bounds.lowerBound)
|
|
||||||
let end = index(startIndex, offsetBy: bounds.upperBound)
|
|
||||||
return self[start..<end]
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
//
|
|
||||||
// ImageView.swift
|
|
||||||
// Runner
|
|
||||||
//
|
|
||||||
// Created by LittleSheep on 2025/4/21.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
import Kingfisher
|
|
||||||
|
|
||||||
class ImageView: UIImageView {
|
|
||||||
private var _size: CGSize = CGSize(width: 0, height: 0)
|
|
||||||
|
|
||||||
// Initialize the image view
|
|
||||||
override init(frame: CGRect) {
|
|
||||||
super.init(frame: frame)
|
|
||||||
contentMode = .scaleAspectFill
|
|
||||||
clipsToBounds = true
|
|
||||||
}
|
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
|
||||||
super.init(coder: coder)
|
|
||||||
contentMode = .scaleAspectFill
|
|
||||||
clipsToBounds = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method to set the image from a URL using Kingfisher
|
|
||||||
func setImage(from url: URL, blurHash: String?) {
|
|
||||||
let placeholderImage = blurHash != nil ? UIImage.init(blurHash: blurHash!, size: _size) : nil
|
|
||||||
let processor = DownsamplingImageProcessor(size: _size) |> RoundCornerImageProcessor(cornerRadius: 20)
|
|
||||||
|
|
||||||
self.kf.indicatorType = .activity
|
|
||||||
self.kf.setImage(
|
|
||||||
with: url,
|
|
||||||
placeholder: placeholderImage,
|
|
||||||
options: [
|
|
||||||
.processor(processor),
|
|
||||||
.transition(.fade(0.3))
|
|
||||||
]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
//
|
|
||||||
// NativeImage.swift
|
|
||||||
// Runner
|
|
||||||
//
|
|
||||||
// Created by LittleSheep on 2025/4/21.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Flutter
|
|
||||||
import UIKit
|
|
||||||
import Kingfisher
|
|
||||||
|
|
||||||
class FLNativeImageFactory : NSObject, FlutterPlatformViewFactory {
|
|
||||||
private var messenger: FlutterBinaryMessenger
|
|
||||||
|
|
||||||
init(messenger: FlutterBinaryMessenger) {
|
|
||||||
self.messenger = messenger
|
|
||||||
super.init()
|
|
||||||
}
|
|
||||||
|
|
||||||
func create(
|
|
||||||
withFrame frame: CGRect,
|
|
||||||
viewIdentifier viewId: Int64,
|
|
||||||
arguments args: Any?
|
|
||||||
) -> FlutterPlatformView {
|
|
||||||
return FLNativeImage(
|
|
||||||
frame: frame,
|
|
||||||
viewIdentifier: viewId,
|
|
||||||
arguments: args,
|
|
||||||
binaryMessenger: messenger)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implementing this method is only necessary when the `arguments` in `createWithFrame` is not `nil`.
|
|
||||||
public func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol {
|
|
||||||
return FlutterStandardMessageCodec.sharedInstance()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class FLNativeImage : NSObject, FlutterPlatformView {
|
|
||||||
private var _view: ImageView
|
|
||||||
|
|
||||||
init(
|
|
||||||
frame: CGRect,
|
|
||||||
viewIdentifier viewId: Int64,
|
|
||||||
arguments args: Any?,
|
|
||||||
binaryMessenger messenger: FlutterBinaryMessenger?
|
|
||||||
) {
|
|
||||||
_view = ImageView(frame: frame)
|
|
||||||
super.init()
|
|
||||||
|
|
||||||
let argsMap = args as! [AnyHashable: Any]
|
|
||||||
let source = argsMap["src"] as! String
|
|
||||||
let blurHash = argsMap["blur"] as? String
|
|
||||||
|
|
||||||
if let url = URL(string: source) {
|
|
||||||
_view.setImage(from: url, blurHash: blurHash)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func view() -> UIView {
|
|
||||||
return _view
|
|
||||||
}
|
|
||||||
}
|
|
49
ios/Runner/NotifyDelegate.swift
Normal file
49
ios/Runner/NotifyDelegate.swift
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
//
|
||||||
|
// NotifyDelegate.swift
|
||||||
|
// Runner
|
||||||
|
//
|
||||||
|
// Created by LittleSheep on 2025/6/1.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Alamofire
|
||||||
|
|
||||||
|
class NotifyDelegate: UIResponder, UNUserNotificationCenterDelegate {
|
||||||
|
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
|
||||||
|
if let textResponse = response as? UNTextInputNotificationResponse {
|
||||||
|
let content = response.notification.request.content
|
||||||
|
guard let metadata = content.userInfo["meta"] as? [AnyHashable: Any] else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var token: String? = UserDefaults.standard.getFlutterToken()
|
||||||
|
if token == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let serverUrl = UserDefaults.standard.getServerUrl()
|
||||||
|
let url = "\(serverUrl)/chat/\(metadata["room_id"] ?? "")/messages"
|
||||||
|
|
||||||
|
let parameters: [String: Any?] = [
|
||||||
|
"content": textResponse.userText,
|
||||||
|
"replied_message_id": metadata["message_id"]
|
||||||
|
]
|
||||||
|
|
||||||
|
AF.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: HTTPHeaders(
|
||||||
|
[HTTPHeader(name: "Authorization", value: "AtField \(token!)")]
|
||||||
|
))
|
||||||
|
.validate()
|
||||||
|
.responseString { response in
|
||||||
|
switch response.result {
|
||||||
|
case .success(_):
|
||||||
|
break
|
||||||
|
case .failure(let error):
|
||||||
|
print("Failed to send chat reply message: \(error)")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
completionHandler()
|
||||||
|
}
|
||||||
|
}
|
@ -4,5 +4,7 @@
|
|||||||
<dict>
|
<dict>
|
||||||
<key>aps-environment</key>
|
<key>aps-environment</key>
|
||||||
<string>development</string>
|
<string>development</string>
|
||||||
|
<key>com.apple.developer.usernotifications.communication</key>
|
||||||
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
14
ios/Runner/Services/CloudFile.swift
Normal file
14
ios/Runner/Services/CloudFile.swift
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
//
|
||||||
|
// CloudFile.swift
|
||||||
|
// Runner
|
||||||
|
//
|
||||||
|
// Created by LittleSheep on 2025/5/31.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
func getAttachmentUrl(for identifier: String) -> String {
|
||||||
|
let serverBaseUrl = "https://nt.solian.app"
|
||||||
|
|
||||||
|
return identifier.starts(with: "http") ? identifier : "\(serverBaseUrl)/files/\(identifier)"
|
||||||
|
}
|
31
ios/Runner/Services/DataExchange.swift
Normal file
31
ios/Runner/Services/DataExchange.swift
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
//
|
||||||
|
// DataExchange.swift
|
||||||
|
// Runner
|
||||||
|
//
|
||||||
|
// Created by LittleSheep on 2025/6/2.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension UserDefaults {
|
||||||
|
func getFlutterValue<T>(forKey key: String) -> T? {
|
||||||
|
let prefixedKey = "flutter.\(key)"
|
||||||
|
return self.object(forKey: prefixedKey) as? T
|
||||||
|
}
|
||||||
|
|
||||||
|
func getFlutterToken(forKey key: String = "dyn_user_tk") -> String? {
|
||||||
|
let prefixedKey = "flutter.\(key)"
|
||||||
|
guard let jsonString = self.string(forKey: prefixedKey),
|
||||||
|
let data = jsonString.data(using: .utf8),
|
||||||
|
let jsonObject = try? JSONSerialization.jsonObject(with: data),
|
||||||
|
let jsonDict = jsonObject as? [String: Any],
|
||||||
|
let token = jsonDict["token"] as? String else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return token
|
||||||
|
}
|
||||||
|
|
||||||
|
func getServerUrl(forKey key: String = "app_server_url") -> String {
|
||||||
|
return self.getFlutterValue(forKey: key) ?? "https://nt.solian.app"
|
||||||
|
}
|
||||||
|
}
|
18
ios/SolianNotificationService/Info.plist
Normal file
18
ios/SolianNotificationService/Info.plist
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?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>NSUserActivityTypes</key>
|
||||||
|
<array>
|
||||||
|
<string>INStartCallIntent</string>
|
||||||
|
<string>INSendMessageIntent</string>
|
||||||
|
</array>
|
||||||
|
<key>NSExtension</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSExtensionPointIdentifier</key>
|
||||||
|
<string>com.apple.usernotifications.service</string>
|
||||||
|
<key>NSExtensionPrincipalClass</key>
|
||||||
|
<string>$(PRODUCT_MODULE_NAME).NotificationService</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
221
ios/SolianNotificationService/NotificationService.swift
Normal file
221
ios/SolianNotificationService/NotificationService.swift
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
//
|
||||||
|
// NotificationService.swift
|
||||||
|
// NotificationService
|
||||||
|
//
|
||||||
|
// Created by LittleSheep on 2025/5/31.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UserNotifications
|
||||||
|
import Intents
|
||||||
|
import Kingfisher
|
||||||
|
import UniformTypeIdentifiers
|
||||||
|
|
||||||
|
enum ParseNotificationPayloadError: Error {
|
||||||
|
case missingMetadata(String)
|
||||||
|
case missingAvatarUrl(String)
|
||||||
|
}
|
||||||
|
|
||||||
|
class NotificationService: UNNotificationServiceExtension {
|
||||||
|
|
||||||
|
private var contentHandler: ((UNNotificationContent) -> Void)?
|
||||||
|
private var bestAttemptContent: UNMutableNotificationContent?
|
||||||
|
|
||||||
|
override func didReceive(
|
||||||
|
_ request: UNNotificationRequest,
|
||||||
|
withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void
|
||||||
|
) {
|
||||||
|
self.contentHandler = contentHandler
|
||||||
|
guard let bestAttemptContent = request.content.mutableCopy() as? UNMutableNotificationContent else {
|
||||||
|
contentHandler(request.content)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.bestAttemptContent = bestAttemptContent
|
||||||
|
|
||||||
|
do {
|
||||||
|
try processNotification(request: request, content: bestAttemptContent)
|
||||||
|
} catch {
|
||||||
|
contentHandler(bestAttemptContent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override func serviceExtensionTimeWillExpire() {
|
||||||
|
if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
|
||||||
|
contentHandler(bestAttemptContent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func processNotification(request: UNNotificationRequest, content: UNMutableNotificationContent) throws {
|
||||||
|
switch content.userInfo["type"] as? String {
|
||||||
|
case "messages.new":
|
||||||
|
try handleMessagingNotification(request: request, content: content)
|
||||||
|
default:
|
||||||
|
try handleDefaultNotification(content: content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func handleMessagingNotification(request: UNNotificationRequest, content: UNMutableNotificationContent) throws {
|
||||||
|
guard let meta = content.userInfo["meta"] as? [AnyHashable: Any] else {
|
||||||
|
throw ParseNotificationPayloadError.missingMetadata("The notification has no meta.")
|
||||||
|
}
|
||||||
|
|
||||||
|
let pfpIdentifier = meta["pfp"] as? String
|
||||||
|
|
||||||
|
let replyableMessageCategory = UNNotificationCategory(
|
||||||
|
identifier: content.categoryIdentifier,
|
||||||
|
actions: [
|
||||||
|
UNTextInputNotificationAction(
|
||||||
|
identifier: "reply_action",
|
||||||
|
title: "Reply",
|
||||||
|
options: []
|
||||||
|
),
|
||||||
|
],
|
||||||
|
intentIdentifiers: [],
|
||||||
|
options: []
|
||||||
|
)
|
||||||
|
|
||||||
|
UNUserNotificationCenter.current().setNotificationCategories([replyableMessageCategory])
|
||||||
|
content.categoryIdentifier = replyableMessageCategory.identifier
|
||||||
|
|
||||||
|
let metaCopy = meta as? [String: Any] ?? [:]
|
||||||
|
let pfpUrl = pfpIdentifier != nil ? getAttachmentUrl(for: pfpIdentifier!) : nil
|
||||||
|
|
||||||
|
let targetSize = 512
|
||||||
|
let scaleProcessor = ResizingImageProcessor(referenceSize: CGSize(width: targetSize, height: targetSize), mode: .aspectFit)
|
||||||
|
|
||||||
|
KingfisherManager.shared.retrieveImage(with: URL(string: pfpUrl!)!, options: [.processor(scaleProcessor)], completionHandler: { result in
|
||||||
|
var image: Data?
|
||||||
|
switch result {
|
||||||
|
case .success(let value):
|
||||||
|
image = value.image.pngData()
|
||||||
|
case .failure(let error):
|
||||||
|
print("Unable to get pfp url: \(error)")
|
||||||
|
}
|
||||||
|
|
||||||
|
let handle = INPersonHandle(value: "\(metaCopy["user_id"] ?? "")", type: .unknown)
|
||||||
|
let sender = INPerson(
|
||||||
|
personHandle: handle,
|
||||||
|
nameComponents: PersonNameComponents(nickname: "\(metaCopy["sender_name"] ?? "")"),
|
||||||
|
displayName: content.title,
|
||||||
|
image: image == nil ? nil : INImage(imageData: image!),
|
||||||
|
contactIdentifier: nil,
|
||||||
|
customIdentifier: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
let intent = self.createMessageIntent(with: sender, meta: metaCopy, body: content.body)
|
||||||
|
self.donateInteraction(for: intent)
|
||||||
|
let updatedContent = try? request.content.updating(from: intent)
|
||||||
|
self.contentHandler?(updatedContent ?? content)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private func handleDefaultNotification(content: UNMutableNotificationContent) throws {
|
||||||
|
guard let meta = content.userInfo["meta"] as? [AnyHashable: Any] else {
|
||||||
|
throw ParseNotificationPayloadError.missingMetadata("The notification has no meta.")
|
||||||
|
}
|
||||||
|
|
||||||
|
if let imageIdentifier = meta["image"] as? String {
|
||||||
|
attachMedia(to: content, withIdentifier: [imageIdentifier], fileType: UTType.webP, doScaleDown: true)
|
||||||
|
} else if let pfpIdentifier = meta["pfp"] as? String {
|
||||||
|
attachMedia(to: content, withIdentifier: [pfpIdentifier], fileType: UTType.webP, doScaleDown: true)
|
||||||
|
} else if let imagesIdentifier = meta["images"] as? Array<String> {
|
||||||
|
attachMedia(to: content, withIdentifier: imagesIdentifier, fileType: UTType.webP, doScaleDown: true)
|
||||||
|
} else {
|
||||||
|
contentHandler?(content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func attachMedia(to content: UNMutableNotificationContent, withIdentifier identifier: Array<String>, fileType type: UTType?, doScaleDown scaleDown: Bool = false) {
|
||||||
|
let attachmentUrls = identifier.compactMap { element in
|
||||||
|
return getAttachmentUrl(for: element)
|
||||||
|
}
|
||||||
|
|
||||||
|
guard !attachmentUrls.isEmpty else {
|
||||||
|
print("Invalid URLs for attachments: \(attachmentUrls)")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let targetSize = 512
|
||||||
|
let scaleProcessor = ResizingImageProcessor(referenceSize: CGSize(width: targetSize, height: targetSize), mode: .aspectFit)
|
||||||
|
|
||||||
|
for attachmentUrl in attachmentUrls {
|
||||||
|
guard let remoteUrl = URL(string: attachmentUrl) else {
|
||||||
|
print("Invalid URL for attachment: \(attachmentUrl)")
|
||||||
|
continue // Skip this URL and move to the next one
|
||||||
|
}
|
||||||
|
|
||||||
|
KingfisherManager.shared.retrieveImage(with: remoteUrl, options: scaleDown ? [
|
||||||
|
.processor(scaleProcessor)
|
||||||
|
] : nil) { [weak self] result in
|
||||||
|
guard let self = self else { return }
|
||||||
|
|
||||||
|
switch result {
|
||||||
|
case .success(let retrievalResult):
|
||||||
|
// The image is either retrieved from cache or downloaded
|
||||||
|
let tempDirectory = FileManager.default.temporaryDirectory
|
||||||
|
let cachedFileUrl = tempDirectory.appendingPathComponent(UUID().uuidString) // Unique identifier for each file
|
||||||
|
|
||||||
|
do {
|
||||||
|
// Write the image data to a temporary file for UNNotificationAttachment
|
||||||
|
try retrievalResult.image.pngData()?.write(to: cachedFileUrl)
|
||||||
|
self.attachLocalMedia(to: content, fileType: type?.identifier, from: cachedFileUrl, withIdentifier: attachmentUrl)
|
||||||
|
} catch {
|
||||||
|
print("Failed to write media to temporary file: \(error.localizedDescription)")
|
||||||
|
self.contentHandler?(content)
|
||||||
|
}
|
||||||
|
|
||||||
|
case .failure(let error):
|
||||||
|
print("Failed to retrieve image: \(error.localizedDescription)")
|
||||||
|
self.contentHandler?(content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func attachLocalMedia(to content: UNMutableNotificationContent, fileType type: String?, from localUrl: URL, withIdentifier identifier: String) {
|
||||||
|
do {
|
||||||
|
let attachment = try UNNotificationAttachment(identifier: identifier, url: localUrl, options: [
|
||||||
|
UNNotificationAttachmentOptionsTypeHintKey: type as Any,
|
||||||
|
UNNotificationAttachmentOptionsThumbnailHiddenKey: 0,
|
||||||
|
])
|
||||||
|
content.attachments = [attachment]
|
||||||
|
} catch let error as NSError {
|
||||||
|
// Log detailed error information
|
||||||
|
print("Failed to create attachment from file at \(localUrl.path)")
|
||||||
|
print("Error: \(error.localizedDescription)")
|
||||||
|
|
||||||
|
// Check specific error codes if needed
|
||||||
|
if error.domain == NSCocoaErrorDomain {
|
||||||
|
switch error.code {
|
||||||
|
case NSFileReadNoSuchFileError:
|
||||||
|
print("File does not exist at \(localUrl.path)")
|
||||||
|
case NSFileReadNoPermissionError:
|
||||||
|
print("No permission to read file at \(localUrl.path)")
|
||||||
|
default:
|
||||||
|
print("Unhandled file error: \(error.code)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call content handler regardless of success or failure
|
||||||
|
self.contentHandler?(content)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func createMessageIntent(with sender: INPerson, meta: [AnyHashable: Any], body: String) -> INSendMessageIntent {
|
||||||
|
INSendMessageIntent(
|
||||||
|
recipients: nil,
|
||||||
|
outgoingMessageType: .outgoingMessageText,
|
||||||
|
content: body,
|
||||||
|
speakableGroupName: meta["room_name"] != nil ? INSpeakableString(spokenPhrase: meta["room_name"] as! String) : nil,
|
||||||
|
conversationIdentifier: "\(meta["room_id"] ?? "")",
|
||||||
|
serviceName: nil,
|
||||||
|
sender: sender,
|
||||||
|
attachments: nil
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func donateInteraction(for intent: INIntent) {
|
||||||
|
let interaction = INInteraction(intent: intent, response: nil)
|
||||||
|
interaction.direction = .incoming
|
||||||
|
interaction.donate(completion: nil)
|
||||||
|
}
|
||||||
|
}
|
@ -186,7 +186,7 @@ class MessageRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<LocalChatMessage> sendMessage(
|
Future<LocalChatMessage> sendMessage(
|
||||||
String atk,
|
String token,
|
||||||
String baseUrl,
|
String baseUrl,
|
||||||
String roomId,
|
String roomId,
|
||||||
String content,
|
String content,
|
||||||
@ -232,7 +232,7 @@ class MessageRepository {
|
|||||||
final cloudFile =
|
final cloudFile =
|
||||||
await putMediaToCloud(
|
await putMediaToCloud(
|
||||||
fileData: attachments[idx].data,
|
fileData: attachments[idx].data,
|
||||||
atk: atk,
|
atk: token,
|
||||||
baseUrl: baseUrl,
|
baseUrl: baseUrl,
|
||||||
filename: attachments[idx].data.name ?? 'Post media',
|
filename: attachments[idx].data.name ?? 'Post media',
|
||||||
mimetype:
|
mimetype:
|
||||||
|
@ -4,14 +4,11 @@ part 'auth.freezed.dart';
|
|||||||
part 'auth.g.dart';
|
part 'auth.g.dart';
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
sealed class AppTokenPair with _$AppTokenPair {
|
sealed class AppToken with _$AppToken {
|
||||||
const factory AppTokenPair({
|
const factory AppToken({required String token}) = _AppToken;
|
||||||
required String accessToken,
|
|
||||||
required String refreshToken,
|
|
||||||
}) = _AppTokenPair;
|
|
||||||
|
|
||||||
factory AppTokenPair.fromJson(Map<String, dynamic> json) =>
|
factory AppToken.fromJson(Map<String, dynamic> json) =>
|
||||||
_$AppTokenPairFromJson(json);
|
_$AppTokenFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
|
@ -14,42 +14,42 @@ part of 'auth.dart';
|
|||||||
T _$identity<T>(T value) => value;
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$AppTokenPair {
|
mixin _$AppToken {
|
||||||
|
|
||||||
String get accessToken; String get refreshToken;
|
String get token;
|
||||||
/// Create a copy of AppTokenPair
|
/// Create a copy of AppToken
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
$AppTokenPairCopyWith<AppTokenPair> get copyWith => _$AppTokenPairCopyWithImpl<AppTokenPair>(this as AppTokenPair, _$identity);
|
$AppTokenCopyWith<AppToken> get copyWith => _$AppTokenCopyWithImpl<AppToken>(this as AppToken, _$identity);
|
||||||
|
|
||||||
/// Serializes this AppTokenPair to a JSON map.
|
/// Serializes this AppToken to a JSON map.
|
||||||
Map<String, dynamic> toJson();
|
Map<String, dynamic> toJson();
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is AppTokenPair&&(identical(other.accessToken, accessToken) || other.accessToken == accessToken)&&(identical(other.refreshToken, refreshToken) || other.refreshToken == refreshToken));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is AppToken&&(identical(other.token, token) || other.token == token));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,accessToken,refreshToken);
|
int get hashCode => Object.hash(runtimeType,token);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'AppTokenPair(accessToken: $accessToken, refreshToken: $refreshToken)';
|
return 'AppToken(token: $token)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
abstract mixin class $AppTokenPairCopyWith<$Res> {
|
abstract mixin class $AppTokenCopyWith<$Res> {
|
||||||
factory $AppTokenPairCopyWith(AppTokenPair value, $Res Function(AppTokenPair) _then) = _$AppTokenPairCopyWithImpl;
|
factory $AppTokenCopyWith(AppToken value, $Res Function(AppToken) _then) = _$AppTokenCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String accessToken, String refreshToken
|
String token
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -57,19 +57,18 @@ $Res call({
|
|||||||
|
|
||||||
}
|
}
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class _$AppTokenPairCopyWithImpl<$Res>
|
class _$AppTokenCopyWithImpl<$Res>
|
||||||
implements $AppTokenPairCopyWith<$Res> {
|
implements $AppTokenCopyWith<$Res> {
|
||||||
_$AppTokenPairCopyWithImpl(this._self, this._then);
|
_$AppTokenCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
final AppTokenPair _self;
|
final AppToken _self;
|
||||||
final $Res Function(AppTokenPair) _then;
|
final $Res Function(AppToken) _then;
|
||||||
|
|
||||||
/// Create a copy of AppTokenPair
|
/// Create a copy of AppToken
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? accessToken = null,Object? refreshToken = null,}) {
|
@pragma('vm:prefer-inline') @override $Res call({Object? token = null,}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
accessToken: null == accessToken ? _self.accessToken : accessToken // ignore: cast_nullable_to_non_nullable
|
token: null == token ? _self.token : token // ignore: cast_nullable_to_non_nullable
|
||||||
as String,refreshToken: null == refreshToken ? _self.refreshToken : refreshToken // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String,
|
as String,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -80,47 +79,46 @@ as String,
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _AppTokenPair implements AppTokenPair {
|
class _AppToken implements AppToken {
|
||||||
const _AppTokenPair({required this.accessToken, required this.refreshToken});
|
const _AppToken({required this.token});
|
||||||
factory _AppTokenPair.fromJson(Map<String, dynamic> json) => _$AppTokenPairFromJson(json);
|
factory _AppToken.fromJson(Map<String, dynamic> json) => _$AppTokenFromJson(json);
|
||||||
|
|
||||||
@override final String accessToken;
|
@override final String token;
|
||||||
@override final String refreshToken;
|
|
||||||
|
|
||||||
/// Create a copy of AppTokenPair
|
/// Create a copy of AppToken
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
_$AppTokenPairCopyWith<_AppTokenPair> get copyWith => __$AppTokenPairCopyWithImpl<_AppTokenPair>(this, _$identity);
|
_$AppTokenCopyWith<_AppToken> get copyWith => __$AppTokenCopyWithImpl<_AppToken>(this, _$identity);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return _$AppTokenPairToJson(this, );
|
return _$AppTokenToJson(this, );
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _AppTokenPair&&(identical(other.accessToken, accessToken) || other.accessToken == accessToken)&&(identical(other.refreshToken, refreshToken) || other.refreshToken == refreshToken));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _AppToken&&(identical(other.token, token) || other.token == token));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,accessToken,refreshToken);
|
int get hashCode => Object.hash(runtimeType,token);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'AppTokenPair(accessToken: $accessToken, refreshToken: $refreshToken)';
|
return 'AppToken(token: $token)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
abstract mixin class _$AppTokenPairCopyWith<$Res> implements $AppTokenPairCopyWith<$Res> {
|
abstract mixin class _$AppTokenCopyWith<$Res> implements $AppTokenCopyWith<$Res> {
|
||||||
factory _$AppTokenPairCopyWith(_AppTokenPair value, $Res Function(_AppTokenPair) _then) = __$AppTokenPairCopyWithImpl;
|
factory _$AppTokenCopyWith(_AppToken value, $Res Function(_AppToken) _then) = __$AppTokenCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String accessToken, String refreshToken
|
String token
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -128,19 +126,18 @@ $Res call({
|
|||||||
|
|
||||||
}
|
}
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class __$AppTokenPairCopyWithImpl<$Res>
|
class __$AppTokenCopyWithImpl<$Res>
|
||||||
implements _$AppTokenPairCopyWith<$Res> {
|
implements _$AppTokenCopyWith<$Res> {
|
||||||
__$AppTokenPairCopyWithImpl(this._self, this._then);
|
__$AppTokenCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
final _AppTokenPair _self;
|
final _AppToken _self;
|
||||||
final $Res Function(_AppTokenPair) _then;
|
final $Res Function(_AppToken) _then;
|
||||||
|
|
||||||
/// Create a copy of AppTokenPair
|
/// Create a copy of AppToken
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? accessToken = null,Object? refreshToken = null,}) {
|
@override @pragma('vm:prefer-inline') $Res call({Object? token = null,}) {
|
||||||
return _then(_AppTokenPair(
|
return _then(_AppToken(
|
||||||
accessToken: null == accessToken ? _self.accessToken : accessToken // ignore: cast_nullable_to_non_nullable
|
token: null == token ? _self.token : token // ignore: cast_nullable_to_non_nullable
|
||||||
as String,refreshToken: null == refreshToken ? _self.refreshToken : refreshToken // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String,
|
as String,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -6,17 +6,12 @@ part of 'auth.dart';
|
|||||||
// JsonSerializableGenerator
|
// JsonSerializableGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
_AppTokenPair _$AppTokenPairFromJson(Map<String, dynamic> json) =>
|
_AppToken _$AppTokenFromJson(Map<String, dynamic> json) =>
|
||||||
_AppTokenPair(
|
_AppToken(token: json['token'] as String);
|
||||||
accessToken: json['access_token'] as String,
|
|
||||||
refreshToken: json['refresh_token'] as String,
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> _$AppTokenPairToJson(_AppTokenPair instance) =>
|
Map<String, dynamic> _$AppTokenToJson(_AppToken instance) => <String, dynamic>{
|
||||||
<String, dynamic>{
|
'token': instance.token,
|
||||||
'access_token': instance.accessToken,
|
};
|
||||||
'refresh_token': instance.refreshToken,
|
|
||||||
};
|
|
||||||
|
|
||||||
_SnAuthChallenge _$SnAuthChallengeFromJson(Map<String, dynamic> json) =>
|
_SnAuthChallenge _$SnAuthChallengeFromJson(Map<String, dynamic> json) =>
|
||||||
_SnAuthChallenge(
|
_SnAuthChallenge(
|
||||||
|
@ -14,9 +14,7 @@ sealed class SnChatRoom with _$SnChatRoom {
|
|||||||
required String? description,
|
required String? description,
|
||||||
required int type,
|
required int type,
|
||||||
required bool isPublic,
|
required bool isPublic,
|
||||||
required String? pictureId,
|
|
||||||
required SnCloudFile? picture,
|
required SnCloudFile? picture,
|
||||||
required String? backgroundId,
|
|
||||||
required SnCloudFile? background,
|
required SnCloudFile? background,
|
||||||
required String? realmId,
|
required String? realmId,
|
||||||
required SnRealm? realm,
|
required SnRealm? realm,
|
||||||
|
@ -16,7 +16,7 @@ T _$identity<T>(T value) => value;
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$SnChatRoom {
|
mixin _$SnChatRoom {
|
||||||
|
|
||||||
String get id; String? get name; String? get description; int get type; bool get isPublic; String? get pictureId; SnCloudFile? get picture; String? get backgroundId; SnCloudFile? get background; String? get realmId; SnRealm? get realm; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; List<SnChatMember>? get members;
|
String get id; String? get name; String? get description; int get type; bool get isPublic; SnCloudFile? get picture; SnCloudFile? get background; String? get realmId; SnRealm? get realm; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; List<SnChatMember>? get members;
|
||||||
/// Create a copy of SnChatRoom
|
/// Create a copy of SnChatRoom
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@ -29,16 +29,16 @@ $SnChatRoomCopyWith<SnChatRoom> get copyWith => _$SnChatRoomCopyWithImpl<SnChatR
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnChatRoom&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&(identical(other.type, type) || other.type == type)&&(identical(other.isPublic, isPublic) || other.isPublic == isPublic)&&(identical(other.pictureId, pictureId) || other.pictureId == pictureId)&&(identical(other.picture, picture) || other.picture == picture)&&(identical(other.backgroundId, backgroundId) || other.backgroundId == backgroundId)&&(identical(other.background, background) || other.background == background)&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&const DeepCollectionEquality().equals(other.members, members));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnChatRoom&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&(identical(other.type, type) || other.type == type)&&(identical(other.isPublic, isPublic) || other.isPublic == isPublic)&&(identical(other.picture, picture) || other.picture == picture)&&(identical(other.background, background) || other.background == background)&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&const DeepCollectionEquality().equals(other.members, members));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,id,name,description,type,isPublic,pictureId,picture,backgroundId,background,realmId,realm,createdAt,updatedAt,deletedAt,const DeepCollectionEquality().hash(members));
|
int get hashCode => Object.hash(runtimeType,id,name,description,type,isPublic,picture,background,realmId,realm,createdAt,updatedAt,deletedAt,const DeepCollectionEquality().hash(members));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnChatRoom(id: $id, name: $name, description: $description, type: $type, isPublic: $isPublic, pictureId: $pictureId, picture: $picture, backgroundId: $backgroundId, background: $background, realmId: $realmId, realm: $realm, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, members: $members)';
|
return 'SnChatRoom(id: $id, name: $name, description: $description, type: $type, isPublic: $isPublic, picture: $picture, background: $background, realmId: $realmId, realm: $realm, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, members: $members)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ abstract mixin class $SnChatRoomCopyWith<$Res> {
|
|||||||
factory $SnChatRoomCopyWith(SnChatRoom value, $Res Function(SnChatRoom) _then) = _$SnChatRoomCopyWithImpl;
|
factory $SnChatRoomCopyWith(SnChatRoom value, $Res Function(SnChatRoom) _then) = _$SnChatRoomCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, String? name, String? description, int type, bool isPublic, String? pictureId, SnCloudFile? picture, String? backgroundId, SnCloudFile? background, String? realmId, SnRealm? realm, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, List<SnChatMember>? members
|
String id, String? name, String? description, int type, bool isPublic, SnCloudFile? picture, SnCloudFile? background, String? realmId, SnRealm? realm, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, List<SnChatMember>? members
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -66,17 +66,15 @@ class _$SnChatRoomCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnChatRoom
|
/// Create a copy of SnChatRoom
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = freezed,Object? description = freezed,Object? type = null,Object? isPublic = null,Object? pictureId = freezed,Object? picture = freezed,Object? backgroundId = freezed,Object? background = freezed,Object? realmId = freezed,Object? realm = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? members = freezed,}) {
|
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = freezed,Object? description = freezed,Object? type = null,Object? isPublic = null,Object? picture = freezed,Object? background = freezed,Object? realmId = freezed,Object? realm = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? members = freezed,}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,name: freezed == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
as String,name: freezed == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
as String?,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
as String?,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
||||||
as int,isPublic: null == isPublic ? _self.isPublic : isPublic // ignore: cast_nullable_to_non_nullable
|
as int,isPublic: null == isPublic ? _self.isPublic : isPublic // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,pictureId: freezed == pictureId ? _self.pictureId : pictureId // ignore: cast_nullable_to_non_nullable
|
as bool,picture: freezed == picture ? _self.picture : picture // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,picture: freezed == picture ? _self.picture : picture // ignore: cast_nullable_to_non_nullable
|
as SnCloudFile?,background: freezed == background ? _self.background : background // ignore: cast_nullable_to_non_nullable
|
||||||
as SnCloudFile?,backgroundId: freezed == backgroundId ? _self.backgroundId : backgroundId // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,background: freezed == background ? _self.background : background // ignore: cast_nullable_to_non_nullable
|
|
||||||
as SnCloudFile?,realmId: freezed == realmId ? _self.realmId : realmId // ignore: cast_nullable_to_non_nullable
|
as SnCloudFile?,realmId: freezed == realmId ? _self.realmId : realmId // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,realm: freezed == realm ? _self.realm : realm // ignore: cast_nullable_to_non_nullable
|
as String?,realm: freezed == realm ? _self.realm : realm // ignore: cast_nullable_to_non_nullable
|
||||||
as SnRealm?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
as SnRealm?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
@ -130,7 +128,7 @@ $SnRealmCopyWith<$Res>? get realm {
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _SnChatRoom implements SnChatRoom {
|
class _SnChatRoom implements SnChatRoom {
|
||||||
const _SnChatRoom({required this.id, required this.name, required this.description, required this.type, required this.isPublic, required this.pictureId, required this.picture, required this.backgroundId, required this.background, required this.realmId, required this.realm, required this.createdAt, required this.updatedAt, required this.deletedAt, required final List<SnChatMember>? members}): _members = members;
|
const _SnChatRoom({required this.id, required this.name, required this.description, required this.type, required this.isPublic, required this.picture, required this.background, required this.realmId, required this.realm, required this.createdAt, required this.updatedAt, required this.deletedAt, required final List<SnChatMember>? members}): _members = members;
|
||||||
factory _SnChatRoom.fromJson(Map<String, dynamic> json) => _$SnChatRoomFromJson(json);
|
factory _SnChatRoom.fromJson(Map<String, dynamic> json) => _$SnChatRoomFromJson(json);
|
||||||
|
|
||||||
@override final String id;
|
@override final String id;
|
||||||
@ -138,9 +136,7 @@ class _SnChatRoom implements SnChatRoom {
|
|||||||
@override final String? description;
|
@override final String? description;
|
||||||
@override final int type;
|
@override final int type;
|
||||||
@override final bool isPublic;
|
@override final bool isPublic;
|
||||||
@override final String? pictureId;
|
|
||||||
@override final SnCloudFile? picture;
|
@override final SnCloudFile? picture;
|
||||||
@override final String? backgroundId;
|
|
||||||
@override final SnCloudFile? background;
|
@override final SnCloudFile? background;
|
||||||
@override final String? realmId;
|
@override final String? realmId;
|
||||||
@override final SnRealm? realm;
|
@override final SnRealm? realm;
|
||||||
@ -170,16 +166,16 @@ Map<String, dynamic> toJson() {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnChatRoom&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&(identical(other.type, type) || other.type == type)&&(identical(other.isPublic, isPublic) || other.isPublic == isPublic)&&(identical(other.pictureId, pictureId) || other.pictureId == pictureId)&&(identical(other.picture, picture) || other.picture == picture)&&(identical(other.backgroundId, backgroundId) || other.backgroundId == backgroundId)&&(identical(other.background, background) || other.background == background)&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&const DeepCollectionEquality().equals(other._members, _members));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnChatRoom&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&(identical(other.type, type) || other.type == type)&&(identical(other.isPublic, isPublic) || other.isPublic == isPublic)&&(identical(other.picture, picture) || other.picture == picture)&&(identical(other.background, background) || other.background == background)&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&const DeepCollectionEquality().equals(other._members, _members));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,id,name,description,type,isPublic,pictureId,picture,backgroundId,background,realmId,realm,createdAt,updatedAt,deletedAt,const DeepCollectionEquality().hash(_members));
|
int get hashCode => Object.hash(runtimeType,id,name,description,type,isPublic,picture,background,realmId,realm,createdAt,updatedAt,deletedAt,const DeepCollectionEquality().hash(_members));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnChatRoom(id: $id, name: $name, description: $description, type: $type, isPublic: $isPublic, pictureId: $pictureId, picture: $picture, backgroundId: $backgroundId, background: $background, realmId: $realmId, realm: $realm, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, members: $members)';
|
return 'SnChatRoom(id: $id, name: $name, description: $description, type: $type, isPublic: $isPublic, picture: $picture, background: $background, realmId: $realmId, realm: $realm, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, members: $members)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -190,7 +186,7 @@ abstract mixin class _$SnChatRoomCopyWith<$Res> implements $SnChatRoomCopyWith<$
|
|||||||
factory _$SnChatRoomCopyWith(_SnChatRoom value, $Res Function(_SnChatRoom) _then) = __$SnChatRoomCopyWithImpl;
|
factory _$SnChatRoomCopyWith(_SnChatRoom value, $Res Function(_SnChatRoom) _then) = __$SnChatRoomCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, String? name, String? description, int type, bool isPublic, String? pictureId, SnCloudFile? picture, String? backgroundId, SnCloudFile? background, String? realmId, SnRealm? realm, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, List<SnChatMember>? members
|
String id, String? name, String? description, int type, bool isPublic, SnCloudFile? picture, SnCloudFile? background, String? realmId, SnRealm? realm, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, List<SnChatMember>? members
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -207,17 +203,15 @@ class __$SnChatRoomCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnChatRoom
|
/// Create a copy of SnChatRoom
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = freezed,Object? description = freezed,Object? type = null,Object? isPublic = null,Object? pictureId = freezed,Object? picture = freezed,Object? backgroundId = freezed,Object? background = freezed,Object? realmId = freezed,Object? realm = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? members = freezed,}) {
|
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = freezed,Object? description = freezed,Object? type = null,Object? isPublic = null,Object? picture = freezed,Object? background = freezed,Object? realmId = freezed,Object? realm = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? members = freezed,}) {
|
||||||
return _then(_SnChatRoom(
|
return _then(_SnChatRoom(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,name: freezed == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
as String,name: freezed == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
as String?,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
as String?,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
||||||
as int,isPublic: null == isPublic ? _self.isPublic : isPublic // ignore: cast_nullable_to_non_nullable
|
as int,isPublic: null == isPublic ? _self.isPublic : isPublic // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,pictureId: freezed == pictureId ? _self.pictureId : pictureId // ignore: cast_nullable_to_non_nullable
|
as bool,picture: freezed == picture ? _self.picture : picture // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,picture: freezed == picture ? _self.picture : picture // ignore: cast_nullable_to_non_nullable
|
as SnCloudFile?,background: freezed == background ? _self.background : background // ignore: cast_nullable_to_non_nullable
|
||||||
as SnCloudFile?,backgroundId: freezed == backgroundId ? _self.backgroundId : backgroundId // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,background: freezed == background ? _self.background : background // ignore: cast_nullable_to_non_nullable
|
|
||||||
as SnCloudFile?,realmId: freezed == realmId ? _self.realmId : realmId // ignore: cast_nullable_to_non_nullable
|
as SnCloudFile?,realmId: freezed == realmId ? _self.realmId : realmId // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,realm: freezed == realm ? _self.realm : realm // ignore: cast_nullable_to_non_nullable
|
as String?,realm: freezed == realm ? _self.realm : realm // ignore: cast_nullable_to_non_nullable
|
||||||
as SnRealm?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
as SnRealm?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
@ -12,12 +12,10 @@ _SnChatRoom _$SnChatRoomFromJson(Map<String, dynamic> json) => _SnChatRoom(
|
|||||||
description: json['description'] as String?,
|
description: json['description'] as String?,
|
||||||
type: (json['type'] as num).toInt(),
|
type: (json['type'] as num).toInt(),
|
||||||
isPublic: json['is_public'] as bool,
|
isPublic: json['is_public'] as bool,
|
||||||
pictureId: json['picture_id'] as String?,
|
|
||||||
picture:
|
picture:
|
||||||
json['picture'] == null
|
json['picture'] == null
|
||||||
? null
|
? null
|
||||||
: SnCloudFile.fromJson(json['picture'] as Map<String, dynamic>),
|
: SnCloudFile.fromJson(json['picture'] as Map<String, dynamic>),
|
||||||
backgroundId: json['background_id'] as String?,
|
|
||||||
background:
|
background:
|
||||||
json['background'] == null
|
json['background'] == null
|
||||||
? null
|
? null
|
||||||
@ -46,9 +44,7 @@ Map<String, dynamic> _$SnChatRoomToJson(_SnChatRoom instance) =>
|
|||||||
'description': instance.description,
|
'description': instance.description,
|
||||||
'type': instance.type,
|
'type': instance.type,
|
||||||
'is_public': instance.isPublic,
|
'is_public': instance.isPublic,
|
||||||
'picture_id': instance.pictureId,
|
|
||||||
'picture': instance.picture?.toJson(),
|
'picture': instance.picture?.toJson(),
|
||||||
'background_id': instance.backgroundId,
|
|
||||||
'background': instance.background?.toJson(),
|
'background': instance.background?.toJson(),
|
||||||
'realm_id': instance.realmId,
|
'realm_id': instance.realmId,
|
||||||
'realm': instance.realm?.toJson(),
|
'realm': instance.realm?.toJson(),
|
||||||
|
@ -43,7 +43,6 @@ sealed class SnCloudFile with _$SnCloudFile {
|
|||||||
required int size,
|
required int size,
|
||||||
required DateTime? uploadedAt,
|
required DateTime? uploadedAt,
|
||||||
required String? uploadedTo,
|
required String? uploadedTo,
|
||||||
required int usedCount,
|
|
||||||
required DateTime createdAt,
|
required DateTime createdAt,
|
||||||
required DateTime updatedAt,
|
required DateTime updatedAt,
|
||||||
required DateTime? deletedAt,
|
required DateTime? deletedAt,
|
||||||
|
@ -146,7 +146,7 @@ as UniversalFileType,
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$SnCloudFile {
|
mixin _$SnCloudFile {
|
||||||
|
|
||||||
String get id; String get name; String? get description; Map<String, dynamic>? get fileMeta; Map<String, dynamic>? get userMeta; String? get mimeType; String? get hash; int get size; DateTime? get uploadedAt; String? get uploadedTo; int get usedCount; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
|
String get id; String get name; String? get description; Map<String, dynamic>? get fileMeta; Map<String, dynamic>? get userMeta; String? get mimeType; String? get hash; int get size; DateTime? get uploadedAt; String? get uploadedTo; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
|
||||||
/// Create a copy of SnCloudFile
|
/// Create a copy of SnCloudFile
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@ -159,16 +159,16 @@ $SnCloudFileCopyWith<SnCloudFile> get copyWith => _$SnCloudFileCopyWithImpl<SnCl
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnCloudFile&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&const DeepCollectionEquality().equals(other.fileMeta, fileMeta)&&const DeepCollectionEquality().equals(other.userMeta, userMeta)&&(identical(other.mimeType, mimeType) || other.mimeType == mimeType)&&(identical(other.hash, hash) || other.hash == hash)&&(identical(other.size, size) || other.size == size)&&(identical(other.uploadedAt, uploadedAt) || other.uploadedAt == uploadedAt)&&(identical(other.uploadedTo, uploadedTo) || other.uploadedTo == uploadedTo)&&(identical(other.usedCount, usedCount) || other.usedCount == usedCount)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnCloudFile&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&const DeepCollectionEquality().equals(other.fileMeta, fileMeta)&&const DeepCollectionEquality().equals(other.userMeta, userMeta)&&(identical(other.mimeType, mimeType) || other.mimeType == mimeType)&&(identical(other.hash, hash) || other.hash == hash)&&(identical(other.size, size) || other.size == size)&&(identical(other.uploadedAt, uploadedAt) || other.uploadedAt == uploadedAt)&&(identical(other.uploadedTo, uploadedTo) || other.uploadedTo == uploadedTo)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,id,name,description,const DeepCollectionEquality().hash(fileMeta),const DeepCollectionEquality().hash(userMeta),mimeType,hash,size,uploadedAt,uploadedTo,usedCount,createdAt,updatedAt,deletedAt);
|
int get hashCode => Object.hash(runtimeType,id,name,description,const DeepCollectionEquality().hash(fileMeta),const DeepCollectionEquality().hash(userMeta),mimeType,hash,size,uploadedAt,uploadedTo,createdAt,updatedAt,deletedAt);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnCloudFile(id: $id, name: $name, description: $description, fileMeta: $fileMeta, userMeta: $userMeta, mimeType: $mimeType, hash: $hash, size: $size, uploadedAt: $uploadedAt, uploadedTo: $uploadedTo, usedCount: $usedCount, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
return 'SnCloudFile(id: $id, name: $name, description: $description, fileMeta: $fileMeta, userMeta: $userMeta, mimeType: $mimeType, hash: $hash, size: $size, uploadedAt: $uploadedAt, uploadedTo: $uploadedTo, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -179,7 +179,7 @@ abstract mixin class $SnCloudFileCopyWith<$Res> {
|
|||||||
factory $SnCloudFileCopyWith(SnCloudFile value, $Res Function(SnCloudFile) _then) = _$SnCloudFileCopyWithImpl;
|
factory $SnCloudFileCopyWith(SnCloudFile value, $Res Function(SnCloudFile) _then) = _$SnCloudFileCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, String name, String? description, Map<String, dynamic>? fileMeta, Map<String, dynamic>? userMeta, String? mimeType, String? hash, int size, DateTime? uploadedAt, String? uploadedTo, int usedCount, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
String id, String name, String? description, Map<String, dynamic>? fileMeta, Map<String, dynamic>? userMeta, String? mimeType, String? hash, int size, DateTime? uploadedAt, String? uploadedTo, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -196,7 +196,7 @@ class _$SnCloudFileCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnCloudFile
|
/// Create a copy of SnCloudFile
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? fileMeta = freezed,Object? userMeta = freezed,Object? mimeType = freezed,Object? hash = freezed,Object? size = null,Object? uploadedAt = freezed,Object? uploadedTo = freezed,Object? usedCount = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? fileMeta = freezed,Object? userMeta = freezed,Object? mimeType = freezed,Object? hash = freezed,Object? size = null,Object? uploadedAt = freezed,Object? uploadedTo = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||||
@ -208,8 +208,7 @@ as String?,hash: freezed == hash ? _self.hash : hash // ignore: cast_nullable_to
|
|||||||
as String?,size: null == size ? _self.size : size // ignore: cast_nullable_to_non_nullable
|
as String?,size: null == size ? _self.size : size // ignore: cast_nullable_to_non_nullable
|
||||||
as int,uploadedAt: freezed == uploadedAt ? _self.uploadedAt : uploadedAt // ignore: cast_nullable_to_non_nullable
|
as int,uploadedAt: freezed == uploadedAt ? _self.uploadedAt : uploadedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,uploadedTo: freezed == uploadedTo ? _self.uploadedTo : uploadedTo // ignore: cast_nullable_to_non_nullable
|
as DateTime?,uploadedTo: freezed == uploadedTo ? _self.uploadedTo : uploadedTo // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,usedCount: null == usedCount ? _self.usedCount : usedCount // ignore: cast_nullable_to_non_nullable
|
as String?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
as int,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
|
||||||
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,
|
as DateTime?,
|
||||||
@ -223,7 +222,7 @@ as DateTime?,
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _SnCloudFile implements SnCloudFile {
|
class _SnCloudFile implements SnCloudFile {
|
||||||
const _SnCloudFile({required this.id, required this.name, required this.description, required final Map<String, dynamic>? fileMeta, required final Map<String, dynamic>? userMeta, required this.mimeType, required this.hash, required this.size, required this.uploadedAt, required this.uploadedTo, required this.usedCount, required this.createdAt, required this.updatedAt, required this.deletedAt}): _fileMeta = fileMeta,_userMeta = userMeta;
|
const _SnCloudFile({required this.id, required this.name, required this.description, required final Map<String, dynamic>? fileMeta, required final Map<String, dynamic>? userMeta, required this.mimeType, required this.hash, required this.size, required this.uploadedAt, required this.uploadedTo, required this.createdAt, required this.updatedAt, required this.deletedAt}): _fileMeta = fileMeta,_userMeta = userMeta;
|
||||||
factory _SnCloudFile.fromJson(Map<String, dynamic> json) => _$SnCloudFileFromJson(json);
|
factory _SnCloudFile.fromJson(Map<String, dynamic> json) => _$SnCloudFileFromJson(json);
|
||||||
|
|
||||||
@override final String id;
|
@override final String id;
|
||||||
@ -252,7 +251,6 @@ class _SnCloudFile implements SnCloudFile {
|
|||||||
@override final int size;
|
@override final int size;
|
||||||
@override final DateTime? uploadedAt;
|
@override final DateTime? uploadedAt;
|
||||||
@override final String? uploadedTo;
|
@override final String? uploadedTo;
|
||||||
@override final int usedCount;
|
|
||||||
@override final DateTime createdAt;
|
@override final DateTime createdAt;
|
||||||
@override final DateTime updatedAt;
|
@override final DateTime updatedAt;
|
||||||
@override final DateTime? deletedAt;
|
@override final DateTime? deletedAt;
|
||||||
@ -270,16 +268,16 @@ Map<String, dynamic> toJson() {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnCloudFile&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&const DeepCollectionEquality().equals(other._fileMeta, _fileMeta)&&const DeepCollectionEquality().equals(other._userMeta, _userMeta)&&(identical(other.mimeType, mimeType) || other.mimeType == mimeType)&&(identical(other.hash, hash) || other.hash == hash)&&(identical(other.size, size) || other.size == size)&&(identical(other.uploadedAt, uploadedAt) || other.uploadedAt == uploadedAt)&&(identical(other.uploadedTo, uploadedTo) || other.uploadedTo == uploadedTo)&&(identical(other.usedCount, usedCount) || other.usedCount == usedCount)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnCloudFile&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&const DeepCollectionEquality().equals(other._fileMeta, _fileMeta)&&const DeepCollectionEquality().equals(other._userMeta, _userMeta)&&(identical(other.mimeType, mimeType) || other.mimeType == mimeType)&&(identical(other.hash, hash) || other.hash == hash)&&(identical(other.size, size) || other.size == size)&&(identical(other.uploadedAt, uploadedAt) || other.uploadedAt == uploadedAt)&&(identical(other.uploadedTo, uploadedTo) || other.uploadedTo == uploadedTo)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,id,name,description,const DeepCollectionEquality().hash(_fileMeta),const DeepCollectionEquality().hash(_userMeta),mimeType,hash,size,uploadedAt,uploadedTo,usedCount,createdAt,updatedAt,deletedAt);
|
int get hashCode => Object.hash(runtimeType,id,name,description,const DeepCollectionEquality().hash(_fileMeta),const DeepCollectionEquality().hash(_userMeta),mimeType,hash,size,uploadedAt,uploadedTo,createdAt,updatedAt,deletedAt);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnCloudFile(id: $id, name: $name, description: $description, fileMeta: $fileMeta, userMeta: $userMeta, mimeType: $mimeType, hash: $hash, size: $size, uploadedAt: $uploadedAt, uploadedTo: $uploadedTo, usedCount: $usedCount, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
return 'SnCloudFile(id: $id, name: $name, description: $description, fileMeta: $fileMeta, userMeta: $userMeta, mimeType: $mimeType, hash: $hash, size: $size, uploadedAt: $uploadedAt, uploadedTo: $uploadedTo, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -290,7 +288,7 @@ abstract mixin class _$SnCloudFileCopyWith<$Res> implements $SnCloudFileCopyWith
|
|||||||
factory _$SnCloudFileCopyWith(_SnCloudFile value, $Res Function(_SnCloudFile) _then) = __$SnCloudFileCopyWithImpl;
|
factory _$SnCloudFileCopyWith(_SnCloudFile value, $Res Function(_SnCloudFile) _then) = __$SnCloudFileCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, String name, String? description, Map<String, dynamic>? fileMeta, Map<String, dynamic>? userMeta, String? mimeType, String? hash, int size, DateTime? uploadedAt, String? uploadedTo, int usedCount, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
String id, String name, String? description, Map<String, dynamic>? fileMeta, Map<String, dynamic>? userMeta, String? mimeType, String? hash, int size, DateTime? uploadedAt, String? uploadedTo, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -307,7 +305,7 @@ class __$SnCloudFileCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnCloudFile
|
/// Create a copy of SnCloudFile
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? fileMeta = freezed,Object? userMeta = freezed,Object? mimeType = freezed,Object? hash = freezed,Object? size = null,Object? uploadedAt = freezed,Object? uploadedTo = freezed,Object? usedCount = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? fileMeta = freezed,Object? userMeta = freezed,Object? mimeType = freezed,Object? hash = freezed,Object? size = null,Object? uploadedAt = freezed,Object? uploadedTo = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
||||||
return _then(_SnCloudFile(
|
return _then(_SnCloudFile(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||||
@ -319,8 +317,7 @@ as String?,hash: freezed == hash ? _self.hash : hash // ignore: cast_nullable_to
|
|||||||
as String?,size: null == size ? _self.size : size // ignore: cast_nullable_to_non_nullable
|
as String?,size: null == size ? _self.size : size // ignore: cast_nullable_to_non_nullable
|
||||||
as int,uploadedAt: freezed == uploadedAt ? _self.uploadedAt : uploadedAt // ignore: cast_nullable_to_non_nullable
|
as int,uploadedAt: freezed == uploadedAt ? _self.uploadedAt : uploadedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,uploadedTo: freezed == uploadedTo ? _self.uploadedTo : uploadedTo // ignore: cast_nullable_to_non_nullable
|
as DateTime?,uploadedTo: freezed == uploadedTo ? _self.uploadedTo : uploadedTo // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,usedCount: null == usedCount ? _self.usedCount : usedCount // ignore: cast_nullable_to_non_nullable
|
as String?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
as int,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
|
||||||
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,
|
as DateTime?,
|
||||||
|
@ -20,7 +20,6 @@ _SnCloudFile _$SnCloudFileFromJson(Map<String, dynamic> json) => _SnCloudFile(
|
|||||||
? null
|
? null
|
||||||
: DateTime.parse(json['uploaded_at'] as String),
|
: DateTime.parse(json['uploaded_at'] as String),
|
||||||
uploadedTo: json['uploaded_to'] as String?,
|
uploadedTo: json['uploaded_to'] as String?,
|
||||||
usedCount: (json['used_count'] as num).toInt(),
|
|
||||||
createdAt: DateTime.parse(json['created_at'] as String),
|
createdAt: DateTime.parse(json['created_at'] as String),
|
||||||
updatedAt: DateTime.parse(json['updated_at'] as String),
|
updatedAt: DateTime.parse(json['updated_at'] as String),
|
||||||
deletedAt:
|
deletedAt:
|
||||||
@ -41,7 +40,6 @@ Map<String, dynamic> _$SnCloudFileToJson(_SnCloudFile instance) =>
|
|||||||
'size': instance.size,
|
'size': instance.size,
|
||||||
'uploaded_at': instance.uploadedAt?.toIso8601String(),
|
'uploaded_at': instance.uploadedAt?.toIso8601String(),
|
||||||
'uploaded_to': instance.uploadedTo,
|
'uploaded_to': instance.uploadedTo,
|
||||||
'used_count': instance.usedCount,
|
|
||||||
'created_at': instance.createdAt.toIso8601String(),
|
'created_at': instance.createdAt.toIso8601String(),
|
||||||
'updated_at': instance.updatedAt.toIso8601String(),
|
'updated_at': instance.updatedAt.toIso8601String(),
|
||||||
'deleted_at': instance.deletedAt?.toIso8601String(),
|
'deleted_at': instance.deletedAt?.toIso8601String(),
|
||||||
|
@ -51,9 +51,7 @@ sealed class SnPublisher with _$SnPublisher {
|
|||||||
required String name,
|
required String name,
|
||||||
required String nick,
|
required String nick,
|
||||||
@Default('') String bio,
|
@Default('') String bio,
|
||||||
required String? pictureId,
|
|
||||||
required SnCloudFile? picture,
|
required SnCloudFile? picture,
|
||||||
required String? backgroundId,
|
|
||||||
required SnCloudFile? background,
|
required SnCloudFile? background,
|
||||||
required SnAccount? account,
|
required SnAccount? account,
|
||||||
required String? accountId,
|
required String? accountId,
|
||||||
|
@ -370,7 +370,7 @@ $SnPublisherCopyWith<$Res> get publisher {
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$SnPublisher {
|
mixin _$SnPublisher {
|
||||||
|
|
||||||
String get id; int get type; String get name; String get nick; String get bio; String? get pictureId; SnCloudFile? get picture; String? get backgroundId; SnCloudFile? get background; SnAccount? get account; String? get accountId; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; String? get realmId;
|
String get id; int get type; String get name; String get nick; String get bio; SnCloudFile? get picture; SnCloudFile? get background; SnAccount? get account; String? get accountId; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; String? get realmId;
|
||||||
/// Create a copy of SnPublisher
|
/// Create a copy of SnPublisher
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@ -383,16 +383,16 @@ $SnPublisherCopyWith<SnPublisher> get copyWith => _$SnPublisherCopyWithImpl<SnPu
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPublisher&&(identical(other.id, id) || other.id == id)&&(identical(other.type, type) || other.type == type)&&(identical(other.name, name) || other.name == name)&&(identical(other.nick, nick) || other.nick == nick)&&(identical(other.bio, bio) || other.bio == bio)&&(identical(other.pictureId, pictureId) || other.pictureId == pictureId)&&(identical(other.picture, picture) || other.picture == picture)&&(identical(other.backgroundId, backgroundId) || other.backgroundId == backgroundId)&&(identical(other.background, background) || other.background == background)&&(identical(other.account, account) || other.account == account)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.realmId, realmId) || other.realmId == realmId));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPublisher&&(identical(other.id, id) || other.id == id)&&(identical(other.type, type) || other.type == type)&&(identical(other.name, name) || other.name == name)&&(identical(other.nick, nick) || other.nick == nick)&&(identical(other.bio, bio) || other.bio == bio)&&(identical(other.picture, picture) || other.picture == picture)&&(identical(other.background, background) || other.background == background)&&(identical(other.account, account) || other.account == account)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.realmId, realmId) || other.realmId == realmId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,id,type,name,nick,bio,pictureId,picture,backgroundId,background,account,accountId,createdAt,updatedAt,deletedAt,realmId);
|
int get hashCode => Object.hash(runtimeType,id,type,name,nick,bio,picture,background,account,accountId,createdAt,updatedAt,deletedAt,realmId);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnPublisher(id: $id, type: $type, name: $name, nick: $nick, bio: $bio, pictureId: $pictureId, picture: $picture, backgroundId: $backgroundId, background: $background, account: $account, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, realmId: $realmId)';
|
return 'SnPublisher(id: $id, type: $type, name: $name, nick: $nick, bio: $bio, picture: $picture, background: $background, account: $account, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, realmId: $realmId)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -403,7 +403,7 @@ abstract mixin class $SnPublisherCopyWith<$Res> {
|
|||||||
factory $SnPublisherCopyWith(SnPublisher value, $Res Function(SnPublisher) _then) = _$SnPublisherCopyWithImpl;
|
factory $SnPublisherCopyWith(SnPublisher value, $Res Function(SnPublisher) _then) = _$SnPublisherCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, int type, String name, String nick, String bio, String? pictureId, SnCloudFile? picture, String? backgroundId, SnCloudFile? background, SnAccount? account, String? accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String? realmId
|
String id, int type, String name, String nick, String bio, SnCloudFile? picture, SnCloudFile? background, SnAccount? account, String? accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String? realmId
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -420,17 +420,15 @@ class _$SnPublisherCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnPublisher
|
/// Create a copy of SnPublisher
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? type = null,Object? name = null,Object? nick = null,Object? bio = null,Object? pictureId = freezed,Object? picture = freezed,Object? backgroundId = freezed,Object? background = freezed,Object? account = freezed,Object? accountId = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? realmId = freezed,}) {
|
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? type = null,Object? name = null,Object? nick = null,Object? bio = null,Object? picture = freezed,Object? background = freezed,Object? account = freezed,Object? accountId = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? realmId = freezed,}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
as String,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
||||||
as int,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
as int,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||||
as String,nick: null == nick ? _self.nick : nick // ignore: cast_nullable_to_non_nullable
|
as String,nick: null == nick ? _self.nick : nick // ignore: cast_nullable_to_non_nullable
|
||||||
as String,bio: null == bio ? _self.bio : bio // ignore: cast_nullable_to_non_nullable
|
as String,bio: null == bio ? _self.bio : bio // ignore: cast_nullable_to_non_nullable
|
||||||
as String,pictureId: freezed == pictureId ? _self.pictureId : pictureId // ignore: cast_nullable_to_non_nullable
|
as String,picture: freezed == picture ? _self.picture : picture // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,picture: freezed == picture ? _self.picture : picture // ignore: cast_nullable_to_non_nullable
|
as SnCloudFile?,background: freezed == background ? _self.background : background // ignore: cast_nullable_to_non_nullable
|
||||||
as SnCloudFile?,backgroundId: freezed == backgroundId ? _self.backgroundId : backgroundId // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,background: freezed == background ? _self.background : background // ignore: cast_nullable_to_non_nullable
|
|
||||||
as SnCloudFile?,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
|
as SnCloudFile?,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
|
||||||
as SnAccount?,accountId: freezed == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
as SnAccount?,accountId: freezed == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
as String?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
@ -484,7 +482,7 @@ $SnAccountCopyWith<$Res>? get account {
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _SnPublisher implements SnPublisher {
|
class _SnPublisher implements SnPublisher {
|
||||||
const _SnPublisher({required this.id, required this.type, required this.name, required this.nick, this.bio = '', required this.pictureId, required this.picture, required this.backgroundId, required this.background, required this.account, required this.accountId, required this.createdAt, required this.updatedAt, required this.deletedAt, required this.realmId});
|
const _SnPublisher({required this.id, required this.type, required this.name, required this.nick, this.bio = '', required this.picture, required this.background, required this.account, required this.accountId, required this.createdAt, required this.updatedAt, required this.deletedAt, required this.realmId});
|
||||||
factory _SnPublisher.fromJson(Map<String, dynamic> json) => _$SnPublisherFromJson(json);
|
factory _SnPublisher.fromJson(Map<String, dynamic> json) => _$SnPublisherFromJson(json);
|
||||||
|
|
||||||
@override final String id;
|
@override final String id;
|
||||||
@ -492,9 +490,7 @@ class _SnPublisher implements SnPublisher {
|
|||||||
@override final String name;
|
@override final String name;
|
||||||
@override final String nick;
|
@override final String nick;
|
||||||
@override@JsonKey() final String bio;
|
@override@JsonKey() final String bio;
|
||||||
@override final String? pictureId;
|
|
||||||
@override final SnCloudFile? picture;
|
@override final SnCloudFile? picture;
|
||||||
@override final String? backgroundId;
|
|
||||||
@override final SnCloudFile? background;
|
@override final SnCloudFile? background;
|
||||||
@override final SnAccount? account;
|
@override final SnAccount? account;
|
||||||
@override final String? accountId;
|
@override final String? accountId;
|
||||||
@ -516,16 +512,16 @@ Map<String, dynamic> toJson() {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPublisher&&(identical(other.id, id) || other.id == id)&&(identical(other.type, type) || other.type == type)&&(identical(other.name, name) || other.name == name)&&(identical(other.nick, nick) || other.nick == nick)&&(identical(other.bio, bio) || other.bio == bio)&&(identical(other.pictureId, pictureId) || other.pictureId == pictureId)&&(identical(other.picture, picture) || other.picture == picture)&&(identical(other.backgroundId, backgroundId) || other.backgroundId == backgroundId)&&(identical(other.background, background) || other.background == background)&&(identical(other.account, account) || other.account == account)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.realmId, realmId) || other.realmId == realmId));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPublisher&&(identical(other.id, id) || other.id == id)&&(identical(other.type, type) || other.type == type)&&(identical(other.name, name) || other.name == name)&&(identical(other.nick, nick) || other.nick == nick)&&(identical(other.bio, bio) || other.bio == bio)&&(identical(other.picture, picture) || other.picture == picture)&&(identical(other.background, background) || other.background == background)&&(identical(other.account, account) || other.account == account)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.realmId, realmId) || other.realmId == realmId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,id,type,name,nick,bio,pictureId,picture,backgroundId,background,account,accountId,createdAt,updatedAt,deletedAt,realmId);
|
int get hashCode => Object.hash(runtimeType,id,type,name,nick,bio,picture,background,account,accountId,createdAt,updatedAt,deletedAt,realmId);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnPublisher(id: $id, type: $type, name: $name, nick: $nick, bio: $bio, pictureId: $pictureId, picture: $picture, backgroundId: $backgroundId, background: $background, account: $account, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, realmId: $realmId)';
|
return 'SnPublisher(id: $id, type: $type, name: $name, nick: $nick, bio: $bio, picture: $picture, background: $background, account: $account, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, realmId: $realmId)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -536,7 +532,7 @@ abstract mixin class _$SnPublisherCopyWith<$Res> implements $SnPublisherCopyWith
|
|||||||
factory _$SnPublisherCopyWith(_SnPublisher value, $Res Function(_SnPublisher) _then) = __$SnPublisherCopyWithImpl;
|
factory _$SnPublisherCopyWith(_SnPublisher value, $Res Function(_SnPublisher) _then) = __$SnPublisherCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, int type, String name, String nick, String bio, String? pictureId, SnCloudFile? picture, String? backgroundId, SnCloudFile? background, SnAccount? account, String? accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String? realmId
|
String id, int type, String name, String nick, String bio, SnCloudFile? picture, SnCloudFile? background, SnAccount? account, String? accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String? realmId
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -553,17 +549,15 @@ class __$SnPublisherCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnPublisher
|
/// Create a copy of SnPublisher
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? type = null,Object? name = null,Object? nick = null,Object? bio = null,Object? pictureId = freezed,Object? picture = freezed,Object? backgroundId = freezed,Object? background = freezed,Object? account = freezed,Object? accountId = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? realmId = freezed,}) {
|
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? type = null,Object? name = null,Object? nick = null,Object? bio = null,Object? picture = freezed,Object? background = freezed,Object? account = freezed,Object? accountId = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? realmId = freezed,}) {
|
||||||
return _then(_SnPublisher(
|
return _then(_SnPublisher(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
as String,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
||||||
as int,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
as int,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||||
as String,nick: null == nick ? _self.nick : nick // ignore: cast_nullable_to_non_nullable
|
as String,nick: null == nick ? _self.nick : nick // ignore: cast_nullable_to_non_nullable
|
||||||
as String,bio: null == bio ? _self.bio : bio // ignore: cast_nullable_to_non_nullable
|
as String,bio: null == bio ? _self.bio : bio // ignore: cast_nullable_to_non_nullable
|
||||||
as String,pictureId: freezed == pictureId ? _self.pictureId : pictureId // ignore: cast_nullable_to_non_nullable
|
as String,picture: freezed == picture ? _self.picture : picture // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,picture: freezed == picture ? _self.picture : picture // ignore: cast_nullable_to_non_nullable
|
as SnCloudFile?,background: freezed == background ? _self.background : background // ignore: cast_nullable_to_non_nullable
|
||||||
as SnCloudFile?,backgroundId: freezed == backgroundId ? _self.backgroundId : backgroundId // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,background: freezed == background ? _self.background : background // ignore: cast_nullable_to_non_nullable
|
|
||||||
as SnCloudFile?,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
|
as SnCloudFile?,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
|
||||||
as SnAccount?,accountId: freezed == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
as SnAccount?,accountId: freezed == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
as String?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
@ -100,12 +100,10 @@ _SnPublisher _$SnPublisherFromJson(Map<String, dynamic> json) => _SnPublisher(
|
|||||||
name: json['name'] as String,
|
name: json['name'] as String,
|
||||||
nick: json['nick'] as String,
|
nick: json['nick'] as String,
|
||||||
bio: json['bio'] as String? ?? '',
|
bio: json['bio'] as String? ?? '',
|
||||||
pictureId: json['picture_id'] as String?,
|
|
||||||
picture:
|
picture:
|
||||||
json['picture'] == null
|
json['picture'] == null
|
||||||
? null
|
? null
|
||||||
: SnCloudFile.fromJson(json['picture'] as Map<String, dynamic>),
|
: SnCloudFile.fromJson(json['picture'] as Map<String, dynamic>),
|
||||||
backgroundId: json['background_id'] as String?,
|
|
||||||
background:
|
background:
|
||||||
json['background'] == null
|
json['background'] == null
|
||||||
? null
|
? null
|
||||||
@ -131,9 +129,7 @@ Map<String, dynamic> _$SnPublisherToJson(_SnPublisher instance) =>
|
|||||||
'name': instance.name,
|
'name': instance.name,
|
||||||
'nick': instance.nick,
|
'nick': instance.nick,
|
||||||
'bio': instance.bio,
|
'bio': instance.bio,
|
||||||
'picture_id': instance.pictureId,
|
|
||||||
'picture': instance.picture?.toJson(),
|
'picture': instance.picture?.toJson(),
|
||||||
'background_id': instance.backgroundId,
|
|
||||||
'background': instance.background?.toJson(),
|
'background': instance.background?.toJson(),
|
||||||
'account': instance.account?.toJson(),
|
'account': instance.account?.toJson(),
|
||||||
'account_id': instance.accountId,
|
'account_id': instance.accountId,
|
||||||
|
@ -16,9 +16,7 @@ sealed class SnRealm with _$SnRealm {
|
|||||||
required DateTime? verifiedAt,
|
required DateTime? verifiedAt,
|
||||||
required bool isCommunity,
|
required bool isCommunity,
|
||||||
required bool isPublic,
|
required bool isPublic,
|
||||||
required String? pictureId,
|
|
||||||
required SnCloudFile? picture,
|
required SnCloudFile? picture,
|
||||||
required String? backgroundId,
|
|
||||||
required SnCloudFile? background,
|
required SnCloudFile? background,
|
||||||
required String accountId,
|
required String accountId,
|
||||||
required DateTime createdAt,
|
required DateTime createdAt,
|
||||||
|
@ -16,7 +16,7 @@ T _$identity<T>(T value) => value;
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$SnRealm {
|
mixin _$SnRealm {
|
||||||
|
|
||||||
String get id; String get slug; String get name; String get description; String? get verifiedAs; DateTime? get verifiedAt; bool get isCommunity; bool get isPublic; String? get pictureId; SnCloudFile? get picture; String? get backgroundId; SnCloudFile? get background; String get accountId; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
|
String get id; String get slug; String get name; String get description; String? get verifiedAs; DateTime? get verifiedAt; bool get isCommunity; bool get isPublic; SnCloudFile? get picture; SnCloudFile? get background; String get accountId; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
|
||||||
/// Create a copy of SnRealm
|
/// Create a copy of SnRealm
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@ -29,16 +29,16 @@ $SnRealmCopyWith<SnRealm> get copyWith => _$SnRealmCopyWithImpl<SnRealm>(this as
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnRealm&&(identical(other.id, id) || other.id == id)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&(identical(other.verifiedAs, verifiedAs) || other.verifiedAs == verifiedAs)&&(identical(other.verifiedAt, verifiedAt) || other.verifiedAt == verifiedAt)&&(identical(other.isCommunity, isCommunity) || other.isCommunity == isCommunity)&&(identical(other.isPublic, isPublic) || other.isPublic == isPublic)&&(identical(other.pictureId, pictureId) || other.pictureId == pictureId)&&(identical(other.picture, picture) || other.picture == picture)&&(identical(other.backgroundId, backgroundId) || other.backgroundId == backgroundId)&&(identical(other.background, background) || other.background == background)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnRealm&&(identical(other.id, id) || other.id == id)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&(identical(other.verifiedAs, verifiedAs) || other.verifiedAs == verifiedAs)&&(identical(other.verifiedAt, verifiedAt) || other.verifiedAt == verifiedAt)&&(identical(other.isCommunity, isCommunity) || other.isCommunity == isCommunity)&&(identical(other.isPublic, isPublic) || other.isPublic == isPublic)&&(identical(other.picture, picture) || other.picture == picture)&&(identical(other.background, background) || other.background == background)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,id,slug,name,description,verifiedAs,verifiedAt,isCommunity,isPublic,pictureId,picture,backgroundId,background,accountId,createdAt,updatedAt,deletedAt);
|
int get hashCode => Object.hash(runtimeType,id,slug,name,description,verifiedAs,verifiedAt,isCommunity,isPublic,picture,background,accountId,createdAt,updatedAt,deletedAt);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnRealm(id: $id, slug: $slug, name: $name, description: $description, verifiedAs: $verifiedAs, verifiedAt: $verifiedAt, isCommunity: $isCommunity, isPublic: $isPublic, pictureId: $pictureId, picture: $picture, backgroundId: $backgroundId, background: $background, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
return 'SnRealm(id: $id, slug: $slug, name: $name, description: $description, verifiedAs: $verifiedAs, verifiedAt: $verifiedAt, isCommunity: $isCommunity, isPublic: $isPublic, picture: $picture, background: $background, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ abstract mixin class $SnRealmCopyWith<$Res> {
|
|||||||
factory $SnRealmCopyWith(SnRealm value, $Res Function(SnRealm) _then) = _$SnRealmCopyWithImpl;
|
factory $SnRealmCopyWith(SnRealm value, $Res Function(SnRealm) _then) = _$SnRealmCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, String slug, String name, String description, String? verifiedAs, DateTime? verifiedAt, bool isCommunity, bool isPublic, String? pictureId, SnCloudFile? picture, String? backgroundId, SnCloudFile? background, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
String id, String slug, String name, String description, String? verifiedAs, DateTime? verifiedAt, bool isCommunity, bool isPublic, SnCloudFile? picture, SnCloudFile? background, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ class _$SnRealmCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnRealm
|
/// Create a copy of SnRealm
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? slug = null,Object? name = null,Object? description = null,Object? verifiedAs = freezed,Object? verifiedAt = freezed,Object? isCommunity = null,Object? isPublic = null,Object? pictureId = freezed,Object? picture = freezed,Object? backgroundId = freezed,Object? background = freezed,Object? accountId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? slug = null,Object? name = null,Object? description = null,Object? verifiedAs = freezed,Object? verifiedAt = freezed,Object? isCommunity = null,Object? isPublic = null,Object? picture = freezed,Object? background = freezed,Object? accountId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,slug: null == slug ? _self.slug : slug // ignore: cast_nullable_to_non_nullable
|
as String,slug: null == slug ? _self.slug : slug // ignore: cast_nullable_to_non_nullable
|
||||||
@ -76,10 +76,8 @@ as String,verifiedAs: freezed == verifiedAs ? _self.verifiedAs : verifiedAs // i
|
|||||||
as String?,verifiedAt: freezed == verifiedAt ? _self.verifiedAt : verifiedAt // ignore: cast_nullable_to_non_nullable
|
as String?,verifiedAt: freezed == verifiedAt ? _self.verifiedAt : verifiedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,isCommunity: null == isCommunity ? _self.isCommunity : isCommunity // ignore: cast_nullable_to_non_nullable
|
as DateTime?,isCommunity: null == isCommunity ? _self.isCommunity : isCommunity // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,isPublic: null == isPublic ? _self.isPublic : isPublic // ignore: cast_nullable_to_non_nullable
|
as bool,isPublic: null == isPublic ? _self.isPublic : isPublic // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,pictureId: freezed == pictureId ? _self.pictureId : pictureId // ignore: cast_nullable_to_non_nullable
|
as bool,picture: freezed == picture ? _self.picture : picture // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,picture: freezed == picture ? _self.picture : picture // ignore: cast_nullable_to_non_nullable
|
as SnCloudFile?,background: freezed == background ? _self.background : background // ignore: cast_nullable_to_non_nullable
|
||||||
as SnCloudFile?,backgroundId: freezed == backgroundId ? _self.backgroundId : backgroundId // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,background: freezed == background ? _self.background : background // ignore: cast_nullable_to_non_nullable
|
|
||||||
as SnCloudFile?,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
as SnCloudFile?,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
||||||
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
@ -119,7 +117,7 @@ $SnCloudFileCopyWith<$Res>? get background {
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _SnRealm implements SnRealm {
|
class _SnRealm implements SnRealm {
|
||||||
const _SnRealm({required this.id, required this.slug, required this.name, required this.description, required this.verifiedAs, required this.verifiedAt, required this.isCommunity, required this.isPublic, required this.pictureId, required this.picture, required this.backgroundId, required this.background, required this.accountId, required this.createdAt, required this.updatedAt, required this.deletedAt});
|
const _SnRealm({required this.id, required this.slug, required this.name, required this.description, required this.verifiedAs, required this.verifiedAt, required this.isCommunity, required this.isPublic, required this.picture, required this.background, required this.accountId, required this.createdAt, required this.updatedAt, required this.deletedAt});
|
||||||
factory _SnRealm.fromJson(Map<String, dynamic> json) => _$SnRealmFromJson(json);
|
factory _SnRealm.fromJson(Map<String, dynamic> json) => _$SnRealmFromJson(json);
|
||||||
|
|
||||||
@override final String id;
|
@override final String id;
|
||||||
@ -130,9 +128,7 @@ class _SnRealm implements SnRealm {
|
|||||||
@override final DateTime? verifiedAt;
|
@override final DateTime? verifiedAt;
|
||||||
@override final bool isCommunity;
|
@override final bool isCommunity;
|
||||||
@override final bool isPublic;
|
@override final bool isPublic;
|
||||||
@override final String? pictureId;
|
|
||||||
@override final SnCloudFile? picture;
|
@override final SnCloudFile? picture;
|
||||||
@override final String? backgroundId;
|
|
||||||
@override final SnCloudFile? background;
|
@override final SnCloudFile? background;
|
||||||
@override final String accountId;
|
@override final String accountId;
|
||||||
@override final DateTime createdAt;
|
@override final DateTime createdAt;
|
||||||
@ -152,16 +148,16 @@ Map<String, dynamic> toJson() {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnRealm&&(identical(other.id, id) || other.id == id)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&(identical(other.verifiedAs, verifiedAs) || other.verifiedAs == verifiedAs)&&(identical(other.verifiedAt, verifiedAt) || other.verifiedAt == verifiedAt)&&(identical(other.isCommunity, isCommunity) || other.isCommunity == isCommunity)&&(identical(other.isPublic, isPublic) || other.isPublic == isPublic)&&(identical(other.pictureId, pictureId) || other.pictureId == pictureId)&&(identical(other.picture, picture) || other.picture == picture)&&(identical(other.backgroundId, backgroundId) || other.backgroundId == backgroundId)&&(identical(other.background, background) || other.background == background)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnRealm&&(identical(other.id, id) || other.id == id)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&(identical(other.verifiedAs, verifiedAs) || other.verifiedAs == verifiedAs)&&(identical(other.verifiedAt, verifiedAt) || other.verifiedAt == verifiedAt)&&(identical(other.isCommunity, isCommunity) || other.isCommunity == isCommunity)&&(identical(other.isPublic, isPublic) || other.isPublic == isPublic)&&(identical(other.picture, picture) || other.picture == picture)&&(identical(other.background, background) || other.background == background)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,id,slug,name,description,verifiedAs,verifiedAt,isCommunity,isPublic,pictureId,picture,backgroundId,background,accountId,createdAt,updatedAt,deletedAt);
|
int get hashCode => Object.hash(runtimeType,id,slug,name,description,verifiedAs,verifiedAt,isCommunity,isPublic,picture,background,accountId,createdAt,updatedAt,deletedAt);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnRealm(id: $id, slug: $slug, name: $name, description: $description, verifiedAs: $verifiedAs, verifiedAt: $verifiedAt, isCommunity: $isCommunity, isPublic: $isPublic, pictureId: $pictureId, picture: $picture, backgroundId: $backgroundId, background: $background, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
return 'SnRealm(id: $id, slug: $slug, name: $name, description: $description, verifiedAs: $verifiedAs, verifiedAt: $verifiedAt, isCommunity: $isCommunity, isPublic: $isPublic, picture: $picture, background: $background, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -172,7 +168,7 @@ abstract mixin class _$SnRealmCopyWith<$Res> implements $SnRealmCopyWith<$Res> {
|
|||||||
factory _$SnRealmCopyWith(_SnRealm value, $Res Function(_SnRealm) _then) = __$SnRealmCopyWithImpl;
|
factory _$SnRealmCopyWith(_SnRealm value, $Res Function(_SnRealm) _then) = __$SnRealmCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, String slug, String name, String description, String? verifiedAs, DateTime? verifiedAt, bool isCommunity, bool isPublic, String? pictureId, SnCloudFile? picture, String? backgroundId, SnCloudFile? background, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
String id, String slug, String name, String description, String? verifiedAs, DateTime? verifiedAt, bool isCommunity, bool isPublic, SnCloudFile? picture, SnCloudFile? background, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -189,7 +185,7 @@ class __$SnRealmCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnRealm
|
/// Create a copy of SnRealm
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? slug = null,Object? name = null,Object? description = null,Object? verifiedAs = freezed,Object? verifiedAt = freezed,Object? isCommunity = null,Object? isPublic = null,Object? pictureId = freezed,Object? picture = freezed,Object? backgroundId = freezed,Object? background = freezed,Object? accountId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? slug = null,Object? name = null,Object? description = null,Object? verifiedAs = freezed,Object? verifiedAt = freezed,Object? isCommunity = null,Object? isPublic = null,Object? picture = freezed,Object? background = freezed,Object? accountId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
||||||
return _then(_SnRealm(
|
return _then(_SnRealm(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,slug: null == slug ? _self.slug : slug // ignore: cast_nullable_to_non_nullable
|
as String,slug: null == slug ? _self.slug : slug // ignore: cast_nullable_to_non_nullable
|
||||||
@ -199,10 +195,8 @@ as String,verifiedAs: freezed == verifiedAs ? _self.verifiedAs : verifiedAs // i
|
|||||||
as String?,verifiedAt: freezed == verifiedAt ? _self.verifiedAt : verifiedAt // ignore: cast_nullable_to_non_nullable
|
as String?,verifiedAt: freezed == verifiedAt ? _self.verifiedAt : verifiedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,isCommunity: null == isCommunity ? _self.isCommunity : isCommunity // ignore: cast_nullable_to_non_nullable
|
as DateTime?,isCommunity: null == isCommunity ? _self.isCommunity : isCommunity // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,isPublic: null == isPublic ? _self.isPublic : isPublic // ignore: cast_nullable_to_non_nullable
|
as bool,isPublic: null == isPublic ? _self.isPublic : isPublic // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,pictureId: freezed == pictureId ? _self.pictureId : pictureId // ignore: cast_nullable_to_non_nullable
|
as bool,picture: freezed == picture ? _self.picture : picture // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,picture: freezed == picture ? _self.picture : picture // ignore: cast_nullable_to_non_nullable
|
as SnCloudFile?,background: freezed == background ? _self.background : background // ignore: cast_nullable_to_non_nullable
|
||||||
as SnCloudFile?,backgroundId: freezed == backgroundId ? _self.backgroundId : backgroundId // ignore: cast_nullable_to_non_nullable
|
|
||||||
as String?,background: freezed == background ? _self.background : background // ignore: cast_nullable_to_non_nullable
|
|
||||||
as SnCloudFile?,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
as SnCloudFile?,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
||||||
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
@ -18,12 +18,10 @@ _SnRealm _$SnRealmFromJson(Map<String, dynamic> json) => _SnRealm(
|
|||||||
: DateTime.parse(json['verified_at'] as String),
|
: DateTime.parse(json['verified_at'] as String),
|
||||||
isCommunity: json['is_community'] as bool,
|
isCommunity: json['is_community'] as bool,
|
||||||
isPublic: json['is_public'] as bool,
|
isPublic: json['is_public'] as bool,
|
||||||
pictureId: json['picture_id'] as String?,
|
|
||||||
picture:
|
picture:
|
||||||
json['picture'] == null
|
json['picture'] == null
|
||||||
? null
|
? null
|
||||||
: SnCloudFile.fromJson(json['picture'] as Map<String, dynamic>),
|
: SnCloudFile.fromJson(json['picture'] as Map<String, dynamic>),
|
||||||
backgroundId: json['background_id'] as String?,
|
|
||||||
background:
|
background:
|
||||||
json['background'] == null
|
json['background'] == null
|
||||||
? null
|
? null
|
||||||
@ -46,9 +44,7 @@ Map<String, dynamic> _$SnRealmToJson(_SnRealm instance) => <String, dynamic>{
|
|||||||
'verified_at': instance.verifiedAt?.toIso8601String(),
|
'verified_at': instance.verifiedAt?.toIso8601String(),
|
||||||
'is_community': instance.isCommunity,
|
'is_community': instance.isCommunity,
|
||||||
'is_public': instance.isPublic,
|
'is_public': instance.isPublic,
|
||||||
'picture_id': instance.pictureId,
|
|
||||||
'picture': instance.picture?.toJson(),
|
'picture': instance.picture?.toJson(),
|
||||||
'background_id': instance.backgroundId,
|
|
||||||
'background': instance.background?.toJson(),
|
'background': instance.background?.toJson(),
|
||||||
'account_id': instance.accountId,
|
'account_id': instance.accountId,
|
||||||
'created_at': instance.createdAt.toIso8601String(),
|
'created_at': instance.createdAt.toIso8601String(),
|
||||||
|
@ -31,12 +31,10 @@ sealed class SnAccountProfile with _$SnAccountProfile {
|
|||||||
required String? middleName,
|
required String? middleName,
|
||||||
required String? lastName,
|
required String? lastName,
|
||||||
@Default('') String bio,
|
@Default('') String bio,
|
||||||
required String? pictureId,
|
|
||||||
required int experience,
|
required int experience,
|
||||||
required int level,
|
required int level,
|
||||||
required double levelingProgress,
|
required double levelingProgress,
|
||||||
required SnCloudFile? picture,
|
required SnCloudFile? picture,
|
||||||
required String? backgroundId,
|
|
||||||
required SnCloudFile? background,
|
required SnCloudFile? background,
|
||||||
required DateTime createdAt,
|
required DateTime createdAt,
|
||||||
required DateTime updatedAt,
|
required DateTime updatedAt,
|
||||||
|
@ -200,7 +200,7 @@ $SnAccountProfileCopyWith<$Res> get profile {
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$SnAccountProfile {
|
mixin _$SnAccountProfile {
|
||||||
|
|
||||||
String get id; String? get firstName; String? get middleName; String? get lastName; String get bio; String? get pictureId; int get experience; int get level; double get levelingProgress; SnCloudFile? get picture; String? get backgroundId; SnCloudFile? get background; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
|
String get id; String? get firstName; String? get middleName; String? get lastName; String get bio; int get experience; int get level; double get levelingProgress; SnCloudFile? get picture; SnCloudFile? get background; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
|
||||||
/// Create a copy of SnAccountProfile
|
/// Create a copy of SnAccountProfile
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@ -213,16 +213,16 @@ $SnAccountProfileCopyWith<SnAccountProfile> get copyWith => _$SnAccountProfileCo
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnAccountProfile&&(identical(other.id, id) || other.id == id)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.middleName, middleName) || other.middleName == middleName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.bio, bio) || other.bio == bio)&&(identical(other.pictureId, pictureId) || other.pictureId == pictureId)&&(identical(other.experience, experience) || other.experience == experience)&&(identical(other.level, level) || other.level == level)&&(identical(other.levelingProgress, levelingProgress) || other.levelingProgress == levelingProgress)&&(identical(other.picture, picture) || other.picture == picture)&&(identical(other.backgroundId, backgroundId) || other.backgroundId == backgroundId)&&(identical(other.background, background) || other.background == background)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnAccountProfile&&(identical(other.id, id) || other.id == id)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.middleName, middleName) || other.middleName == middleName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.bio, bio) || other.bio == bio)&&(identical(other.experience, experience) || other.experience == experience)&&(identical(other.level, level) || other.level == level)&&(identical(other.levelingProgress, levelingProgress) || other.levelingProgress == levelingProgress)&&(identical(other.picture, picture) || other.picture == picture)&&(identical(other.background, background) || other.background == background)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,id,firstName,middleName,lastName,bio,pictureId,experience,level,levelingProgress,picture,backgroundId,background,createdAt,updatedAt,deletedAt);
|
int get hashCode => Object.hash(runtimeType,id,firstName,middleName,lastName,bio,experience,level,levelingProgress,picture,background,createdAt,updatedAt,deletedAt);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnAccountProfile(id: $id, firstName: $firstName, middleName: $middleName, lastName: $lastName, bio: $bio, pictureId: $pictureId, experience: $experience, level: $level, levelingProgress: $levelingProgress, picture: $picture, backgroundId: $backgroundId, background: $background, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
return 'SnAccountProfile(id: $id, firstName: $firstName, middleName: $middleName, lastName: $lastName, bio: $bio, experience: $experience, level: $level, levelingProgress: $levelingProgress, picture: $picture, background: $background, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -233,7 +233,7 @@ abstract mixin class $SnAccountProfileCopyWith<$Res> {
|
|||||||
factory $SnAccountProfileCopyWith(SnAccountProfile value, $Res Function(SnAccountProfile) _then) = _$SnAccountProfileCopyWithImpl;
|
factory $SnAccountProfileCopyWith(SnAccountProfile value, $Res Function(SnAccountProfile) _then) = _$SnAccountProfileCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, String? firstName, String? middleName, String? lastName, String bio, String? pictureId, int experience, int level, double levelingProgress, SnCloudFile? picture, String? backgroundId, SnCloudFile? background, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
String id, String? firstName, String? middleName, String? lastName, String bio, int experience, int level, double levelingProgress, SnCloudFile? picture, SnCloudFile? background, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -250,20 +250,18 @@ class _$SnAccountProfileCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnAccountProfile
|
/// Create a copy of SnAccountProfile
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? firstName = freezed,Object? middleName = freezed,Object? lastName = freezed,Object? bio = null,Object? pictureId = freezed,Object? experience = null,Object? level = null,Object? levelingProgress = null,Object? picture = freezed,Object? backgroundId = freezed,Object? background = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? firstName = freezed,Object? middleName = freezed,Object? lastName = freezed,Object? bio = null,Object? experience = null,Object? level = null,Object? levelingProgress = null,Object? picture = freezed,Object? background = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,firstName: freezed == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable
|
as String,firstName: freezed == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,middleName: freezed == middleName ? _self.middleName : middleName // ignore: cast_nullable_to_non_nullable
|
as String?,middleName: freezed == middleName ? _self.middleName : middleName // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,lastName: freezed == lastName ? _self.lastName : lastName // ignore: cast_nullable_to_non_nullable
|
as String?,lastName: freezed == lastName ? _self.lastName : lastName // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,bio: null == bio ? _self.bio : bio // ignore: cast_nullable_to_non_nullable
|
as String?,bio: null == bio ? _self.bio : bio // ignore: cast_nullable_to_non_nullable
|
||||||
as String,pictureId: freezed == pictureId ? _self.pictureId : pictureId // ignore: cast_nullable_to_non_nullable
|
as String,experience: null == experience ? _self.experience : experience // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,experience: null == experience ? _self.experience : experience // ignore: cast_nullable_to_non_nullable
|
|
||||||
as int,level: null == level ? _self.level : level // ignore: cast_nullable_to_non_nullable
|
as int,level: null == level ? _self.level : level // ignore: cast_nullable_to_non_nullable
|
||||||
as int,levelingProgress: null == levelingProgress ? _self.levelingProgress : levelingProgress // ignore: cast_nullable_to_non_nullable
|
as int,levelingProgress: null == levelingProgress ? _self.levelingProgress : levelingProgress // ignore: cast_nullable_to_non_nullable
|
||||||
as double,picture: freezed == picture ? _self.picture : picture // ignore: cast_nullable_to_non_nullable
|
as double,picture: freezed == picture ? _self.picture : picture // ignore: cast_nullable_to_non_nullable
|
||||||
as SnCloudFile?,backgroundId: freezed == backgroundId ? _self.backgroundId : backgroundId // ignore: cast_nullable_to_non_nullable
|
as SnCloudFile?,background: freezed == background ? _self.background : background // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,background: freezed == background ? _self.background : background // ignore: cast_nullable_to_non_nullable
|
|
||||||
as SnCloudFile?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
as SnCloudFile?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
@ -302,7 +300,7 @@ $SnCloudFileCopyWith<$Res>? get background {
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _SnAccountProfile implements SnAccountProfile {
|
class _SnAccountProfile implements SnAccountProfile {
|
||||||
const _SnAccountProfile({required this.id, required this.firstName, required this.middleName, required this.lastName, this.bio = '', required this.pictureId, required this.experience, required this.level, required this.levelingProgress, required this.picture, required this.backgroundId, required this.background, required this.createdAt, required this.updatedAt, required this.deletedAt});
|
const _SnAccountProfile({required this.id, required this.firstName, required this.middleName, required this.lastName, this.bio = '', required this.experience, required this.level, required this.levelingProgress, required this.picture, required this.background, required this.createdAt, required this.updatedAt, required this.deletedAt});
|
||||||
factory _SnAccountProfile.fromJson(Map<String, dynamic> json) => _$SnAccountProfileFromJson(json);
|
factory _SnAccountProfile.fromJson(Map<String, dynamic> json) => _$SnAccountProfileFromJson(json);
|
||||||
|
|
||||||
@override final String id;
|
@override final String id;
|
||||||
@ -310,12 +308,10 @@ class _SnAccountProfile implements SnAccountProfile {
|
|||||||
@override final String? middleName;
|
@override final String? middleName;
|
||||||
@override final String? lastName;
|
@override final String? lastName;
|
||||||
@override@JsonKey() final String bio;
|
@override@JsonKey() final String bio;
|
||||||
@override final String? pictureId;
|
|
||||||
@override final int experience;
|
@override final int experience;
|
||||||
@override final int level;
|
@override final int level;
|
||||||
@override final double levelingProgress;
|
@override final double levelingProgress;
|
||||||
@override final SnCloudFile? picture;
|
@override final SnCloudFile? picture;
|
||||||
@override final String? backgroundId;
|
|
||||||
@override final SnCloudFile? background;
|
@override final SnCloudFile? background;
|
||||||
@override final DateTime createdAt;
|
@override final DateTime createdAt;
|
||||||
@override final DateTime updatedAt;
|
@override final DateTime updatedAt;
|
||||||
@ -334,16 +330,16 @@ Map<String, dynamic> toJson() {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnAccountProfile&&(identical(other.id, id) || other.id == id)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.middleName, middleName) || other.middleName == middleName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.bio, bio) || other.bio == bio)&&(identical(other.pictureId, pictureId) || other.pictureId == pictureId)&&(identical(other.experience, experience) || other.experience == experience)&&(identical(other.level, level) || other.level == level)&&(identical(other.levelingProgress, levelingProgress) || other.levelingProgress == levelingProgress)&&(identical(other.picture, picture) || other.picture == picture)&&(identical(other.backgroundId, backgroundId) || other.backgroundId == backgroundId)&&(identical(other.background, background) || other.background == background)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnAccountProfile&&(identical(other.id, id) || other.id == id)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.middleName, middleName) || other.middleName == middleName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.bio, bio) || other.bio == bio)&&(identical(other.experience, experience) || other.experience == experience)&&(identical(other.level, level) || other.level == level)&&(identical(other.levelingProgress, levelingProgress) || other.levelingProgress == levelingProgress)&&(identical(other.picture, picture) || other.picture == picture)&&(identical(other.background, background) || other.background == background)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,id,firstName,middleName,lastName,bio,pictureId,experience,level,levelingProgress,picture,backgroundId,background,createdAt,updatedAt,deletedAt);
|
int get hashCode => Object.hash(runtimeType,id,firstName,middleName,lastName,bio,experience,level,levelingProgress,picture,background,createdAt,updatedAt,deletedAt);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnAccountProfile(id: $id, firstName: $firstName, middleName: $middleName, lastName: $lastName, bio: $bio, pictureId: $pictureId, experience: $experience, level: $level, levelingProgress: $levelingProgress, picture: $picture, backgroundId: $backgroundId, background: $background, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
return 'SnAccountProfile(id: $id, firstName: $firstName, middleName: $middleName, lastName: $lastName, bio: $bio, experience: $experience, level: $level, levelingProgress: $levelingProgress, picture: $picture, background: $background, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -354,7 +350,7 @@ abstract mixin class _$SnAccountProfileCopyWith<$Res> implements $SnAccountProfi
|
|||||||
factory _$SnAccountProfileCopyWith(_SnAccountProfile value, $Res Function(_SnAccountProfile) _then) = __$SnAccountProfileCopyWithImpl;
|
factory _$SnAccountProfileCopyWith(_SnAccountProfile value, $Res Function(_SnAccountProfile) _then) = __$SnAccountProfileCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, String? firstName, String? middleName, String? lastName, String bio, String? pictureId, int experience, int level, double levelingProgress, SnCloudFile? picture, String? backgroundId, SnCloudFile? background, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
String id, String? firstName, String? middleName, String? lastName, String bio, int experience, int level, double levelingProgress, SnCloudFile? picture, SnCloudFile? background, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -371,20 +367,18 @@ class __$SnAccountProfileCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnAccountProfile
|
/// Create a copy of SnAccountProfile
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? firstName = freezed,Object? middleName = freezed,Object? lastName = freezed,Object? bio = null,Object? pictureId = freezed,Object? experience = null,Object? level = null,Object? levelingProgress = null,Object? picture = freezed,Object? backgroundId = freezed,Object? background = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? firstName = freezed,Object? middleName = freezed,Object? lastName = freezed,Object? bio = null,Object? experience = null,Object? level = null,Object? levelingProgress = null,Object? picture = freezed,Object? background = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
||||||
return _then(_SnAccountProfile(
|
return _then(_SnAccountProfile(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,firstName: freezed == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable
|
as String,firstName: freezed == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,middleName: freezed == middleName ? _self.middleName : middleName // ignore: cast_nullable_to_non_nullable
|
as String?,middleName: freezed == middleName ? _self.middleName : middleName // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,lastName: freezed == lastName ? _self.lastName : lastName // ignore: cast_nullable_to_non_nullable
|
as String?,lastName: freezed == lastName ? _self.lastName : lastName // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,bio: null == bio ? _self.bio : bio // ignore: cast_nullable_to_non_nullable
|
as String?,bio: null == bio ? _self.bio : bio // ignore: cast_nullable_to_non_nullable
|
||||||
as String,pictureId: freezed == pictureId ? _self.pictureId : pictureId // ignore: cast_nullable_to_non_nullable
|
as String,experience: null == experience ? _self.experience : experience // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,experience: null == experience ? _self.experience : experience // ignore: cast_nullable_to_non_nullable
|
|
||||||
as int,level: null == level ? _self.level : level // ignore: cast_nullable_to_non_nullable
|
as int,level: null == level ? _self.level : level // ignore: cast_nullable_to_non_nullable
|
||||||
as int,levelingProgress: null == levelingProgress ? _self.levelingProgress : levelingProgress // ignore: cast_nullable_to_non_nullable
|
as int,levelingProgress: null == levelingProgress ? _self.levelingProgress : levelingProgress // ignore: cast_nullable_to_non_nullable
|
||||||
as double,picture: freezed == picture ? _self.picture : picture // ignore: cast_nullable_to_non_nullable
|
as double,picture: freezed == picture ? _self.picture : picture // ignore: cast_nullable_to_non_nullable
|
||||||
as SnCloudFile?,backgroundId: freezed == backgroundId ? _self.backgroundId : backgroundId // ignore: cast_nullable_to_non_nullable
|
as SnCloudFile?,background: freezed == background ? _self.background : background // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,background: freezed == background ? _self.background : background // ignore: cast_nullable_to_non_nullable
|
|
||||||
as SnCloudFile?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
as SnCloudFile?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
@ -47,7 +47,6 @@ _SnAccountProfile _$SnAccountProfileFromJson(Map<String, dynamic> json) =>
|
|||||||
middleName: json['middle_name'] as String?,
|
middleName: json['middle_name'] as String?,
|
||||||
lastName: json['last_name'] as String?,
|
lastName: json['last_name'] as String?,
|
||||||
bio: json['bio'] as String? ?? '',
|
bio: json['bio'] as String? ?? '',
|
||||||
pictureId: json['picture_id'] as String?,
|
|
||||||
experience: (json['experience'] as num).toInt(),
|
experience: (json['experience'] as num).toInt(),
|
||||||
level: (json['level'] as num).toInt(),
|
level: (json['level'] as num).toInt(),
|
||||||
levelingProgress: (json['leveling_progress'] as num).toDouble(),
|
levelingProgress: (json['leveling_progress'] as num).toDouble(),
|
||||||
@ -55,7 +54,6 @@ _SnAccountProfile _$SnAccountProfileFromJson(Map<String, dynamic> json) =>
|
|||||||
json['picture'] == null
|
json['picture'] == null
|
||||||
? null
|
? null
|
||||||
: SnCloudFile.fromJson(json['picture'] as Map<String, dynamic>),
|
: SnCloudFile.fromJson(json['picture'] as Map<String, dynamic>),
|
||||||
backgroundId: json['background_id'] as String?,
|
|
||||||
background:
|
background:
|
||||||
json['background'] == null
|
json['background'] == null
|
||||||
? null
|
? null
|
||||||
@ -77,12 +75,10 @@ Map<String, dynamic> _$SnAccountProfileToJson(_SnAccountProfile instance) =>
|
|||||||
'middle_name': instance.middleName,
|
'middle_name': instance.middleName,
|
||||||
'last_name': instance.lastName,
|
'last_name': instance.lastName,
|
||||||
'bio': instance.bio,
|
'bio': instance.bio,
|
||||||
'picture_id': instance.pictureId,
|
|
||||||
'experience': instance.experience,
|
'experience': instance.experience,
|
||||||
'level': instance.level,
|
'level': instance.level,
|
||||||
'leveling_progress': instance.levelingProgress,
|
'leveling_progress': instance.levelingProgress,
|
||||||
'picture': instance.picture?.toJson(),
|
'picture': instance.picture?.toJson(),
|
||||||
'background_id': instance.backgroundId,
|
|
||||||
'background': instance.background?.toJson(),
|
'background': instance.background?.toJson(),
|
||||||
'created_at': instance.createdAt.toIso8601String(),
|
'created_at': instance.createdAt.toIso8601String(),
|
||||||
'updated_at': instance.updatedAt.toIso8601String(),
|
'updated_at': instance.updatedAt.toIso8601String(),
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'package:island/pods/theme.dart';
|
||||||
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
part 'config.freezed.dart';
|
part 'config.freezed.dart';
|
||||||
|
part 'config.g.dart';
|
||||||
|
|
||||||
const kTokenPairStoreKey = 'dyn_user_tk';
|
const kTokenPairStoreKey = 'dyn_user_tk';
|
||||||
|
|
||||||
@ -14,13 +17,8 @@ const kAppbarTransparentStoreKey = 'app_bar_transparent';
|
|||||||
const kAppBackgroundStoreKey = 'app_has_background';
|
const kAppBackgroundStoreKey = 'app_has_background';
|
||||||
const kAppColorSchemeStoreKey = 'app_color_scheme';
|
const kAppColorSchemeStoreKey = 'app_color_scheme';
|
||||||
const kAppNotifyWithHaptic = 'app_notify_with_haptic';
|
const kAppNotifyWithHaptic = 'app_notify_with_haptic';
|
||||||
const kAppExpandPostLink = 'app_expand_post_link';
|
|
||||||
const kAppExpandChatLink = 'app_expand_chat_link';
|
|
||||||
const kAppRealmCompactView = 'app_realm_compact_view';
|
|
||||||
const kAppCustomFonts = 'app_custom_fonts';
|
const kAppCustomFonts = 'app_custom_fonts';
|
||||||
const kAppMixedFeed = 'app_mixed_feed';
|
|
||||||
const kAppAutoTranslate = 'app_auto_translate';
|
const kAppAutoTranslate = 'app_auto_translate';
|
||||||
const kAppHideBottomNav = 'app_hide_bottom_nav';
|
|
||||||
const kAppSoundEffects = 'app_sound_effects';
|
const kAppSoundEffects = 'app_sound_effects';
|
||||||
const kAppAprilFoolFeatures = 'app_april_fool_features';
|
const kAppAprilFoolFeatures = 'app_april_fool_features';
|
||||||
const kAppWindowSize = 'app_window_size';
|
const kAppWindowSize = 'app_window_size';
|
||||||
@ -57,48 +55,73 @@ sealed class AppSettings with _$AppSettings {
|
|||||||
required bool soundEffects,
|
required bool soundEffects,
|
||||||
required bool aprilFoolFeatures,
|
required bool aprilFoolFeatures,
|
||||||
required bool enterToSend,
|
required bool enterToSend,
|
||||||
|
required bool appBarTransparent,
|
||||||
|
required String? customFonts,
|
||||||
|
required int? appColorScheme, // The color stored via the int type
|
||||||
}) = _AppSettings;
|
}) = _AppSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
class AppSettingsNotifier extends StateNotifier<AppSettings> {
|
@riverpod
|
||||||
final SharedPreferences prefs;
|
class AppSettingsNotifier extends _$AppSettingsNotifier {
|
||||||
|
@override
|
||||||
AppSettingsNotifier(this.prefs)
|
AppSettings build() {
|
||||||
: super(
|
final prefs = ref.watch(sharedPreferencesProvider);
|
||||||
AppSettings(
|
return AppSettings(
|
||||||
autoTranslate: prefs.getBool(kAppAutoTranslate) ?? false,
|
autoTranslate: prefs.getBool(kAppAutoTranslate) ?? false,
|
||||||
soundEffects: prefs.getBool(kAppSoundEffects) ?? true,
|
soundEffects: prefs.getBool(kAppSoundEffects) ?? true,
|
||||||
aprilFoolFeatures: prefs.getBool(kAppAprilFoolFeatures) ?? true,
|
aprilFoolFeatures: prefs.getBool(kAppAprilFoolFeatures) ?? true,
|
||||||
enterToSend: prefs.getBool(kAppEnterToSend) ?? true,
|
enterToSend: prefs.getBool(kAppEnterToSend) ?? true,
|
||||||
),
|
appBarTransparent: prefs.getBool(kAppbarTransparentStoreKey) ?? false,
|
||||||
);
|
customFonts: prefs.getString(kAppCustomFonts),
|
||||||
|
appColorScheme: prefs.getInt(kAppColorSchemeStoreKey),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void setAutoTranslate(bool value) {
|
void setAutoTranslate(bool value) {
|
||||||
|
final prefs = ref.read(sharedPreferencesProvider);
|
||||||
prefs.setBool(kAppAutoTranslate, value);
|
prefs.setBool(kAppAutoTranslate, value);
|
||||||
state = state.copyWith(autoTranslate: value);
|
state = state.copyWith(autoTranslate: value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSoundEffects(bool value) {
|
void setSoundEffects(bool value) {
|
||||||
|
final prefs = ref.read(sharedPreferencesProvider);
|
||||||
prefs.setBool(kAppSoundEffects, value);
|
prefs.setBool(kAppSoundEffects, value);
|
||||||
state = state.copyWith(soundEffects: value);
|
state = state.copyWith(soundEffects: value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setAprilFoolFeatures(bool value) {
|
void setAprilFoolFeatures(bool value) {
|
||||||
|
final prefs = ref.read(sharedPreferencesProvider);
|
||||||
prefs.setBool(kAppAprilFoolFeatures, value);
|
prefs.setBool(kAppAprilFoolFeatures, value);
|
||||||
state = state.copyWith(aprilFoolFeatures: value);
|
state = state.copyWith(aprilFoolFeatures: value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setEnterToSend(bool value) {
|
void setEnterToSend(bool value) {
|
||||||
|
final prefs = ref.read(sharedPreferencesProvider);
|
||||||
prefs.setBool(kAppEnterToSend, value);
|
prefs.setBool(kAppEnterToSend, value);
|
||||||
state = state.copyWith(enterToSend: value);
|
state = state.copyWith(enterToSend: value);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
final appSettingsProvider =
|
void setAppBarTransparent(bool value) {
|
||||||
StateNotifierProvider<AppSettingsNotifier, AppSettings>((ref) {
|
final prefs = ref.read(sharedPreferencesProvider);
|
||||||
final prefs = ref.watch(sharedPreferencesProvider);
|
prefs.setBool(kAppbarTransparentStoreKey, value);
|
||||||
return AppSettingsNotifier(prefs);
|
state = state.copyWith(appBarTransparent: value);
|
||||||
});
|
ref.read(themeProvider.notifier).reloadTheme();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setCustomFonts(String? value) {
|
||||||
|
final prefs = ref.read(sharedPreferencesProvider);
|
||||||
|
prefs.setString(kAppCustomFonts, value ?? '');
|
||||||
|
state = state.copyWith(customFonts: value);
|
||||||
|
ref.read(themeProvider.notifier).reloadTheme();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAppColorScheme(int? value) {
|
||||||
|
final prefs = ref.read(sharedPreferencesProvider);
|
||||||
|
prefs.setInt(kAppColorSchemeStoreKey, value ?? 0);
|
||||||
|
state = state.copyWith(appColorScheme: value);
|
||||||
|
ref.read(themeProvider.notifier).reloadTheme();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final updateInfoProvider =
|
final updateInfoProvider =
|
||||||
StateNotifierProvider<UpdateInfoNotifier, (String?, String?)>((ref) {
|
StateNotifierProvider<UpdateInfoNotifier, (String?, String?)>((ref) {
|
||||||
|
@ -15,7 +15,7 @@ T _$identity<T>(T value) => value;
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$AppSettings {
|
mixin _$AppSettings {
|
||||||
|
|
||||||
bool get autoTranslate; bool get soundEffects; bool get aprilFoolFeatures; bool get enterToSend;
|
bool get autoTranslate; bool get soundEffects; bool get aprilFoolFeatures; bool get enterToSend; bool get appBarTransparent; String? get customFonts; int? get appColorScheme;
|
||||||
/// Create a copy of AppSettings
|
/// Create a copy of AppSettings
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@ -26,16 +26,16 @@ $AppSettingsCopyWith<AppSettings> get copyWith => _$AppSettingsCopyWithImpl<AppS
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is AppSettings&&(identical(other.autoTranslate, autoTranslate) || other.autoTranslate == autoTranslate)&&(identical(other.soundEffects, soundEffects) || other.soundEffects == soundEffects)&&(identical(other.aprilFoolFeatures, aprilFoolFeatures) || other.aprilFoolFeatures == aprilFoolFeatures)&&(identical(other.enterToSend, enterToSend) || other.enterToSend == enterToSend));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is AppSettings&&(identical(other.autoTranslate, autoTranslate) || other.autoTranslate == autoTranslate)&&(identical(other.soundEffects, soundEffects) || other.soundEffects == soundEffects)&&(identical(other.aprilFoolFeatures, aprilFoolFeatures) || other.aprilFoolFeatures == aprilFoolFeatures)&&(identical(other.enterToSend, enterToSend) || other.enterToSend == enterToSend)&&(identical(other.appBarTransparent, appBarTransparent) || other.appBarTransparent == appBarTransparent)&&(identical(other.customFonts, customFonts) || other.customFonts == customFonts)&&(identical(other.appColorScheme, appColorScheme) || other.appColorScheme == appColorScheme));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,autoTranslate,soundEffects,aprilFoolFeatures,enterToSend);
|
int get hashCode => Object.hash(runtimeType,autoTranslate,soundEffects,aprilFoolFeatures,enterToSend,appBarTransparent,customFonts,appColorScheme);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'AppSettings(autoTranslate: $autoTranslate, soundEffects: $soundEffects, aprilFoolFeatures: $aprilFoolFeatures, enterToSend: $enterToSend)';
|
return 'AppSettings(autoTranslate: $autoTranslate, soundEffects: $soundEffects, aprilFoolFeatures: $aprilFoolFeatures, enterToSend: $enterToSend, appBarTransparent: $appBarTransparent, customFonts: $customFonts, appColorScheme: $appColorScheme)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ abstract mixin class $AppSettingsCopyWith<$Res> {
|
|||||||
factory $AppSettingsCopyWith(AppSettings value, $Res Function(AppSettings) _then) = _$AppSettingsCopyWithImpl;
|
factory $AppSettingsCopyWith(AppSettings value, $Res Function(AppSettings) _then) = _$AppSettingsCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
bool autoTranslate, bool soundEffects, bool aprilFoolFeatures, bool enterToSend
|
bool autoTranslate, bool soundEffects, bool aprilFoolFeatures, bool enterToSend, bool appBarTransparent, String? customFonts, int? appColorScheme
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -63,13 +63,16 @@ class _$AppSettingsCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of AppSettings
|
/// Create a copy of AppSettings
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? autoTranslate = null,Object? soundEffects = null,Object? aprilFoolFeatures = null,Object? enterToSend = null,}) {
|
@pragma('vm:prefer-inline') @override $Res call({Object? autoTranslate = null,Object? soundEffects = null,Object? aprilFoolFeatures = null,Object? enterToSend = null,Object? appBarTransparent = null,Object? customFonts = freezed,Object? appColorScheme = freezed,}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
autoTranslate: null == autoTranslate ? _self.autoTranslate : autoTranslate // ignore: cast_nullable_to_non_nullable
|
autoTranslate: null == autoTranslate ? _self.autoTranslate : autoTranslate // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,soundEffects: null == soundEffects ? _self.soundEffects : soundEffects // ignore: cast_nullable_to_non_nullable
|
as bool,soundEffects: null == soundEffects ? _self.soundEffects : soundEffects // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,aprilFoolFeatures: null == aprilFoolFeatures ? _self.aprilFoolFeatures : aprilFoolFeatures // ignore: cast_nullable_to_non_nullable
|
as bool,aprilFoolFeatures: null == aprilFoolFeatures ? _self.aprilFoolFeatures : aprilFoolFeatures // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,enterToSend: null == enterToSend ? _self.enterToSend : enterToSend // ignore: cast_nullable_to_non_nullable
|
as bool,enterToSend: null == enterToSend ? _self.enterToSend : enterToSend // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,
|
as bool,appBarTransparent: null == appBarTransparent ? _self.appBarTransparent : appBarTransparent // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,customFonts: freezed == customFonts ? _self.customFonts : customFonts // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,appColorScheme: freezed == appColorScheme ? _self.appColorScheme : appColorScheme // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int?,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,13 +83,16 @@ as bool,
|
|||||||
|
|
||||||
|
|
||||||
class _AppSettings implements AppSettings {
|
class _AppSettings implements AppSettings {
|
||||||
const _AppSettings({required this.autoTranslate, required this.soundEffects, required this.aprilFoolFeatures, required this.enterToSend});
|
const _AppSettings({required this.autoTranslate, required this.soundEffects, required this.aprilFoolFeatures, required this.enterToSend, required this.appBarTransparent, required this.customFonts, required this.appColorScheme});
|
||||||
|
|
||||||
|
|
||||||
@override final bool autoTranslate;
|
@override final bool autoTranslate;
|
||||||
@override final bool soundEffects;
|
@override final bool soundEffects;
|
||||||
@override final bool aprilFoolFeatures;
|
@override final bool aprilFoolFeatures;
|
||||||
@override final bool enterToSend;
|
@override final bool enterToSend;
|
||||||
|
@override final bool appBarTransparent;
|
||||||
|
@override final String? customFonts;
|
||||||
|
@override final int? appColorScheme;
|
||||||
|
|
||||||
/// Create a copy of AppSettings
|
/// Create a copy of AppSettings
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@ -98,16 +104,16 @@ _$AppSettingsCopyWith<_AppSettings> get copyWith => __$AppSettingsCopyWithImpl<_
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _AppSettings&&(identical(other.autoTranslate, autoTranslate) || other.autoTranslate == autoTranslate)&&(identical(other.soundEffects, soundEffects) || other.soundEffects == soundEffects)&&(identical(other.aprilFoolFeatures, aprilFoolFeatures) || other.aprilFoolFeatures == aprilFoolFeatures)&&(identical(other.enterToSend, enterToSend) || other.enterToSend == enterToSend));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _AppSettings&&(identical(other.autoTranslate, autoTranslate) || other.autoTranslate == autoTranslate)&&(identical(other.soundEffects, soundEffects) || other.soundEffects == soundEffects)&&(identical(other.aprilFoolFeatures, aprilFoolFeatures) || other.aprilFoolFeatures == aprilFoolFeatures)&&(identical(other.enterToSend, enterToSend) || other.enterToSend == enterToSend)&&(identical(other.appBarTransparent, appBarTransparent) || other.appBarTransparent == appBarTransparent)&&(identical(other.customFonts, customFonts) || other.customFonts == customFonts)&&(identical(other.appColorScheme, appColorScheme) || other.appColorScheme == appColorScheme));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,autoTranslate,soundEffects,aprilFoolFeatures,enterToSend);
|
int get hashCode => Object.hash(runtimeType,autoTranslate,soundEffects,aprilFoolFeatures,enterToSend,appBarTransparent,customFonts,appColorScheme);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'AppSettings(autoTranslate: $autoTranslate, soundEffects: $soundEffects, aprilFoolFeatures: $aprilFoolFeatures, enterToSend: $enterToSend)';
|
return 'AppSettings(autoTranslate: $autoTranslate, soundEffects: $soundEffects, aprilFoolFeatures: $aprilFoolFeatures, enterToSend: $enterToSend, appBarTransparent: $appBarTransparent, customFonts: $customFonts, appColorScheme: $appColorScheme)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -118,7 +124,7 @@ abstract mixin class _$AppSettingsCopyWith<$Res> implements $AppSettingsCopyWith
|
|||||||
factory _$AppSettingsCopyWith(_AppSettings value, $Res Function(_AppSettings) _then) = __$AppSettingsCopyWithImpl;
|
factory _$AppSettingsCopyWith(_AppSettings value, $Res Function(_AppSettings) _then) = __$AppSettingsCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
bool autoTranslate, bool soundEffects, bool aprilFoolFeatures, bool enterToSend
|
bool autoTranslate, bool soundEffects, bool aprilFoolFeatures, bool enterToSend, bool appBarTransparent, String? customFonts, int? appColorScheme
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -135,13 +141,16 @@ class __$AppSettingsCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of AppSettings
|
/// Create a copy of AppSettings
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? autoTranslate = null,Object? soundEffects = null,Object? aprilFoolFeatures = null,Object? enterToSend = null,}) {
|
@override @pragma('vm:prefer-inline') $Res call({Object? autoTranslate = null,Object? soundEffects = null,Object? aprilFoolFeatures = null,Object? enterToSend = null,Object? appBarTransparent = null,Object? customFonts = freezed,Object? appColorScheme = freezed,}) {
|
||||||
return _then(_AppSettings(
|
return _then(_AppSettings(
|
||||||
autoTranslate: null == autoTranslate ? _self.autoTranslate : autoTranslate // ignore: cast_nullable_to_non_nullable
|
autoTranslate: null == autoTranslate ? _self.autoTranslate : autoTranslate // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,soundEffects: null == soundEffects ? _self.soundEffects : soundEffects // ignore: cast_nullable_to_non_nullable
|
as bool,soundEffects: null == soundEffects ? _self.soundEffects : soundEffects // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,aprilFoolFeatures: null == aprilFoolFeatures ? _self.aprilFoolFeatures : aprilFoolFeatures // ignore: cast_nullable_to_non_nullable
|
as bool,aprilFoolFeatures: null == aprilFoolFeatures ? _self.aprilFoolFeatures : aprilFoolFeatures // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,enterToSend: null == enterToSend ? _self.enterToSend : enterToSend // ignore: cast_nullable_to_non_nullable
|
as bool,enterToSend: null == enterToSend ? _self.enterToSend : enterToSend // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,
|
as bool,appBarTransparent: null == appBarTransparent ? _self.appBarTransparent : appBarTransparent // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,customFonts: freezed == customFonts ? _self.customFonts : customFonts // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,appColorScheme: freezed == appColorScheme ? _self.appColorScheme : appColorScheme // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int?,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
28
lib/pods/config.g.dart
Normal file
28
lib/pods/config.g.dart
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'config.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// RiverpodGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
String _$appSettingsNotifierHash() =>
|
||||||
|
r'4f727d448ee17a87b5698b8e36ef67521655406c';
|
||||||
|
|
||||||
|
/// See also [AppSettingsNotifier].
|
||||||
|
@ProviderFor(AppSettingsNotifier)
|
||||||
|
final appSettingsNotifierProvider =
|
||||||
|
AutoDisposeNotifierProvider<AppSettingsNotifier, AppSettings>.internal(
|
||||||
|
AppSettingsNotifier.new,
|
||||||
|
name: r'appSettingsNotifierProvider',
|
||||||
|
debugGetCreateSourceHash:
|
||||||
|
const bool.fromEnvironment('dart.vm.product')
|
||||||
|
? null
|
||||||
|
: _$appSettingsNotifierHash,
|
||||||
|
dependencies: null,
|
||||||
|
allTransitiveDependencies: null,
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef _$AppSettingsNotifier = AutoDisposeNotifier<AppSettings>;
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
@ -1,6 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:developer';
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
@ -68,16 +67,9 @@ final apiClientProvider = Provider<Dio>((ref) {
|
|||||||
RequestInterceptorHandler handler,
|
RequestInterceptorHandler handler,
|
||||||
) async {
|
) async {
|
||||||
try {
|
try {
|
||||||
final atk = await getFreshAtk(
|
final token = await getToken(ref.watch(tokenProvider));
|
||||||
ref.watch(tokenPairProvider),
|
if (token != null) {
|
||||||
ref.watch(serverUrlProvider),
|
options.headers['Authorization'] = 'AtField $token';
|
||||||
onRefreshed: (atk, rtk) {
|
|
||||||
setTokenPair(ref.watch(sharedPreferencesProvider), atk, rtk);
|
|
||||||
ref.invalidate(tokenPairProvider);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
if (atk != null) {
|
|
||||||
options.headers['Authorization'] = 'Bearer $atk';
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// ignore
|
// ignore
|
||||||
@ -95,105 +87,21 @@ final apiClientProvider = Provider<Dio>((ref) {
|
|||||||
return dio;
|
return dio;
|
||||||
});
|
});
|
||||||
|
|
||||||
final tokenPairProvider = Provider<AppTokenPair?>((ref) {
|
final tokenProvider = Provider<AppToken?>((ref) {
|
||||||
final prefs = ref.watch(sharedPreferencesProvider);
|
final prefs = ref.watch(sharedPreferencesProvider);
|
||||||
final tkPairString = prefs.getString(kTokenPairStoreKey);
|
final tokenString = prefs.getString(kTokenPairStoreKey);
|
||||||
if (tkPairString == null) return null;
|
if (tokenString == null) return null;
|
||||||
return AppTokenPair.fromJson(jsonDecode(tkPairString));
|
return AppToken.fromJson(jsonDecode(tokenString));
|
||||||
});
|
});
|
||||||
|
|
||||||
Future<(String, String)?> refreshToken(String baseUrl, String? rtk) async {
|
// Token refresh functionality removed as per backend changes
|
||||||
if (rtk == null) return null;
|
|
||||||
|
|
||||||
final dio = Dio();
|
Future<String?> getToken(AppToken? token) async {
|
||||||
dio.options.baseUrl = baseUrl;
|
return token?.token;
|
||||||
|
|
||||||
final resp = await dio.post(
|
|
||||||
'/auth/token',
|
|
||||||
data: {'grant_type': 'refresh_token', 'refresh_token': rtk},
|
|
||||||
);
|
|
||||||
|
|
||||||
final String atk = resp.data['access_token'];
|
|
||||||
final String nRtk = resp.data['refresh_token'];
|
|
||||||
|
|
||||||
return (atk, nRtk);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Completer<String?>? _refreshCompleter;
|
Future<void> setToken(SharedPreferences prefs, String token) async {
|
||||||
|
final appToken = AppToken(token: token);
|
||||||
Future<String?> getFreshAtk(
|
final tokenString = jsonEncode(appToken);
|
||||||
AppTokenPair? tkPair,
|
prefs.setString(kTokenPairStoreKey, tokenString);
|
||||||
String baseUrl, {
|
|
||||||
Function(String, String)? onRefreshed,
|
|
||||||
}) async {
|
|
||||||
var atk = tkPair?.accessToken;
|
|
||||||
var rtk = tkPair?.refreshToken;
|
|
||||||
|
|
||||||
if (_refreshCompleter != null) {
|
|
||||||
return await _refreshCompleter!.future;
|
|
||||||
} else {
|
|
||||||
_refreshCompleter = Completer<String?>();
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (atk != null) {
|
|
||||||
final atkParts = atk.split('.');
|
|
||||||
if (atkParts.length != 3) {
|
|
||||||
throw Exception('invalid format of access token');
|
|
||||||
}
|
|
||||||
|
|
||||||
var rawPayload = atkParts[1].replaceAll('-', '+').replaceAll('_', '/');
|
|
||||||
switch (rawPayload.length % 4) {
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
rawPayload += '==';
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
rawPayload += '=';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw Exception('illegal format of access token payload');
|
|
||||||
}
|
|
||||||
|
|
||||||
final b64 = utf8.fuse(base64Url);
|
|
||||||
final payload = b64.decode(rawPayload);
|
|
||||||
final exp = jsonDecode(payload)['exp'];
|
|
||||||
if (exp <= DateTime.now().millisecondsSinceEpoch ~/ 1000) {
|
|
||||||
log('[Auth] Access token need refresh, doing it at ${DateTime.now()}');
|
|
||||||
final result = await refreshToken(baseUrl, rtk);
|
|
||||||
if (result == null) {
|
|
||||||
atk = null;
|
|
||||||
} else {
|
|
||||||
onRefreshed?.call(result.$1, result.$2);
|
|
||||||
atk = result.$1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (atk != null) {
|
|
||||||
_refreshCompleter!.complete(atk);
|
|
||||||
return atk;
|
|
||||||
} else {
|
|
||||||
log('[Auth] Access token refresh failed...');
|
|
||||||
_refreshCompleter!.complete(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
log('[Auth] Failed to authenticate user... $err');
|
|
||||||
_refreshCompleter!.completeError(err);
|
|
||||||
} finally {
|
|
||||||
_refreshCompleter = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> setTokenPair(
|
|
||||||
SharedPreferences prefs,
|
|
||||||
String atk,
|
|
||||||
String rtk,
|
|
||||||
) async {
|
|
||||||
final tkPair = AppTokenPair(accessToken: atk, refreshToken: rtk);
|
|
||||||
final tkPairString = jsonEncode(tkPair);
|
|
||||||
prefs.setString(kTokenPairStoreKey, tkPairString);
|
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ class UserInfoNotifier extends StateNotifier<AsyncValue<SnAccount?>> {
|
|||||||
|
|
||||||
Future<String?> getAccessToken() async {
|
Future<String?> getAccessToken() async {
|
||||||
final prefs = _ref.read(sharedPreferencesProvider);
|
final prefs = _ref.read(sharedPreferencesProvider);
|
||||||
return prefs.getString('dyn_user_atk');
|
return prefs.getString(kTokenPairStoreKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> fetchUser() async {
|
Future<void> fetchUser() async {
|
||||||
|
@ -54,25 +54,18 @@ class WebSocketService {
|
|||||||
_statusStreamController.sink.add(WebSocketState.connecting());
|
_statusStreamController.sink.add(WebSocketState.connecting());
|
||||||
|
|
||||||
final baseUrl = ref.watch(serverUrlProvider);
|
final baseUrl = ref.watch(serverUrlProvider);
|
||||||
final atk = await getFreshAtk(
|
final token = await getToken(ref.watch(tokenProvider));
|
||||||
ref.watch(tokenPairProvider),
|
|
||||||
baseUrl,
|
|
||||||
onRefreshed: (atk, rtk) {
|
|
||||||
setTokenPair(ref.watch(sharedPreferencesProvider), atk, rtk);
|
|
||||||
ref.invalidate(tokenPairProvider);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
final url = '$baseUrl/ws'.replaceFirst('http', 'ws');
|
final url = '$baseUrl/ws'.replaceFirst('http', 'ws');
|
||||||
|
|
||||||
log('[WebSocket] Trying connecting to $url');
|
log('[WebSocket] Trying connecting to $url');
|
||||||
try {
|
try {
|
||||||
if (kIsWeb) {
|
if (kIsWeb) {
|
||||||
_channel = WebSocketChannel.connect(Uri.parse('$url?tk=$atk'));
|
_channel = WebSocketChannel.connect(Uri.parse('$url?tk=$token'));
|
||||||
} else {
|
} else {
|
||||||
_channel = IOWebSocketChannel.connect(
|
_channel = IOWebSocketChannel.connect(
|
||||||
Uri.parse(url),
|
Uri.parse(url),
|
||||||
headers: {'Authorization': 'Bearer $atk'},
|
headers: {'Authorization': 'Bearer $token'},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
await _channel!.ready;
|
await _channel!.ready;
|
||||||
|
@ -1071,10 +1071,17 @@ class PostComposeRoute extends _i27.PageRouteInfo<PostComposeRouteArgs> {
|
|||||||
PostComposeRoute({
|
PostComposeRoute({
|
||||||
_i28.Key? key,
|
_i28.Key? key,
|
||||||
_i30.SnPost? originalPost,
|
_i30.SnPost? originalPost,
|
||||||
|
_i30.SnPost? repliedPost,
|
||||||
|
_i30.SnPost? forwardedPost,
|
||||||
List<_i27.PageRouteInfo>? children,
|
List<_i27.PageRouteInfo>? children,
|
||||||
}) : super(
|
}) : super(
|
||||||
PostComposeRoute.name,
|
PostComposeRoute.name,
|
||||||
args: PostComposeRouteArgs(key: key, originalPost: originalPost),
|
args: PostComposeRouteArgs(
|
||||||
|
key: key,
|
||||||
|
originalPost: originalPost,
|
||||||
|
repliedPost: repliedPost,
|
||||||
|
forwardedPost: forwardedPost,
|
||||||
|
),
|
||||||
initialChildren: children,
|
initialChildren: children,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1089,32 +1096,50 @@ class PostComposeRoute extends _i27.PageRouteInfo<PostComposeRouteArgs> {
|
|||||||
return _i18.PostComposeScreen(
|
return _i18.PostComposeScreen(
|
||||||
key: args.key,
|
key: args.key,
|
||||||
originalPost: args.originalPost,
|
originalPost: args.originalPost,
|
||||||
|
repliedPost: args.repliedPost,
|
||||||
|
forwardedPost: args.forwardedPost,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class PostComposeRouteArgs {
|
class PostComposeRouteArgs {
|
||||||
const PostComposeRouteArgs({this.key, this.originalPost});
|
const PostComposeRouteArgs({
|
||||||
|
this.key,
|
||||||
|
this.originalPost,
|
||||||
|
this.repliedPost,
|
||||||
|
this.forwardedPost,
|
||||||
|
});
|
||||||
|
|
||||||
final _i28.Key? key;
|
final _i28.Key? key;
|
||||||
|
|
||||||
final _i30.SnPost? originalPost;
|
final _i30.SnPost? originalPost;
|
||||||
|
|
||||||
|
final _i30.SnPost? repliedPost;
|
||||||
|
|
||||||
|
final _i30.SnPost? forwardedPost;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'PostComposeRouteArgs{key: $key, originalPost: $originalPost}';
|
return 'PostComposeRouteArgs{key: $key, originalPost: $originalPost, repliedPost: $repliedPost, forwardedPost: $forwardedPost}';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
if (identical(this, other)) return true;
|
if (identical(this, other)) return true;
|
||||||
if (other is! PostComposeRouteArgs) return false;
|
if (other is! PostComposeRouteArgs) return false;
|
||||||
return key == other.key && originalPost == other.originalPost;
|
return key == other.key &&
|
||||||
|
originalPost == other.originalPost &&
|
||||||
|
repliedPost == other.repliedPost &&
|
||||||
|
forwardedPost == other.forwardedPost;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => key.hashCode ^ originalPost.hashCode;
|
int get hashCode =>
|
||||||
|
key.hashCode ^
|
||||||
|
originalPost.hashCode ^
|
||||||
|
repliedPost.hashCode ^
|
||||||
|
forwardedPost.hashCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
|
@ -74,7 +74,7 @@ class AccountScreen extends HookConsumerWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
if (user.value?.profile.backgroundId != null)
|
if (user.value?.profile.background?.id != null)
|
||||||
ClipRRect(
|
ClipRRect(
|
||||||
borderRadius: BorderRadius.only(
|
borderRadius: BorderRadius.only(
|
||||||
topLeft: Radius.circular(8),
|
topLeft: Radius.circular(8),
|
||||||
@ -83,7 +83,7 @@ class AccountScreen extends HookConsumerWidget {
|
|||||||
child: AspectRatio(
|
child: AspectRatio(
|
||||||
aspectRatio: 16 / 7,
|
aspectRatio: 16 / 7,
|
||||||
child: CloudImageWidget(
|
child: CloudImageWidget(
|
||||||
fileId: user.value!.profile.backgroundId!,
|
fileId: user.value!.profile.background!.id,
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -94,7 +94,7 @@ class AccountScreen extends HookConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
child: ProfilePictureWidget(
|
child: ProfilePictureWidget(
|
||||||
fileId: user.value?.profile.pictureId,
|
fileId: user.value?.profile.picture?.id,
|
||||||
radius: 24,
|
radius: 24,
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
@ -254,8 +254,8 @@ class AccountScreen extends HookConsumerWidget {
|
|||||||
contentPadding: EdgeInsets.symmetric(horizontal: 24),
|
contentPadding: EdgeInsets.symmetric(horizontal: 24),
|
||||||
title: Text('Copy access token'),
|
title: Text('Copy access token'),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final tk = ref.watch(tokenPairProvider);
|
final tk = ref.watch(tokenProvider);
|
||||||
Clipboard.setData(ClipboardData(text: tk!.accessToken));
|
Clipboard.setData(ClipboardData(text: tk!.token));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
if (kDebugMode)
|
if (kDebugMode)
|
||||||
|
@ -202,7 +202,7 @@ class EventCalanderScreen extends HookConsumerWidget {
|
|||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
leading: ProfilePictureWidget(
|
leading: ProfilePictureWidget(
|
||||||
fileId: user.value!.profile.pictureId,
|
fileId: user.value!.profile.picture?.id,
|
||||||
),
|
),
|
||||||
title: Text(user.value!.nick).bold(),
|
title: Text(user.value!.nick).bold(),
|
||||||
subtitle: Text('@${user.value!.name}'),
|
subtitle: Text('@${user.value!.name}'),
|
||||||
|
@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
|
import 'package:island/models/file.dart';
|
||||||
import 'package:island/pods/config.dart';
|
import 'package:island/pods/config.dart';
|
||||||
import 'package:island/pods/network.dart';
|
import 'package:island/pods/network.dart';
|
||||||
import 'package:island/pods/userinfo.dart';
|
import 'package:island/pods/userinfo.dart';
|
||||||
@ -59,19 +60,15 @@ class UpdateProfileScreen extends HookConsumerWidget {
|
|||||||
submitting.value = true;
|
submitting.value = true;
|
||||||
try {
|
try {
|
||||||
final baseUrl = ref.watch(serverUrlProvider);
|
final baseUrl = ref.watch(serverUrlProvider);
|
||||||
final atk = await getFreshAtk(
|
final token = await getToken(ref.watch(tokenProvider));
|
||||||
ref.watch(tokenPairProvider),
|
if (token == null) throw ArgumentError('Token is null');
|
||||||
baseUrl,
|
|
||||||
onRefreshed: (atk, rtk) {
|
|
||||||
setTokenPair(ref.watch(sharedPreferencesProvider), atk, rtk);
|
|
||||||
ref.invalidate(tokenPairProvider);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
if (atk == null) throw ArgumentError('Access token is null');
|
|
||||||
final cloudFile =
|
final cloudFile =
|
||||||
await putMediaToCloud(
|
await putMediaToCloud(
|
||||||
fileData: result,
|
fileData: UniversalFile(
|
||||||
atk: atk,
|
data: result,
|
||||||
|
type: UniversalFileType.image,
|
||||||
|
),
|
||||||
|
atk: token,
|
||||||
baseUrl: baseUrl,
|
baseUrl: baseUrl,
|
||||||
filename: result.name,
|
filename: result.name,
|
||||||
mimetype: result.mimeType ?? 'image/jpeg',
|
mimetype: result.mimeType ?? 'image/jpeg',
|
||||||
@ -166,9 +163,9 @@ class UpdateProfileScreen extends HookConsumerWidget {
|
|||||||
child: Container(
|
child: Container(
|
||||||
color: Theme.of(context).colorScheme.surfaceContainerHigh,
|
color: Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||||
child:
|
child:
|
||||||
user.value!.profile.backgroundId != null
|
user.value!.profile.background?.id != null
|
||||||
? CloudImageWidget(
|
? CloudImageWidget(
|
||||||
fileId: user.value!.profile.backgroundId!,
|
fileId: user.value!.profile.background!.id,
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
)
|
)
|
||||||
: const SizedBox.shrink(),
|
: const SizedBox.shrink(),
|
||||||
@ -182,7 +179,7 @@ class UpdateProfileScreen extends HookConsumerWidget {
|
|||||||
bottom: -32,
|
bottom: -32,
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
child: ProfilePictureWidget(
|
child: ProfilePictureWidget(
|
||||||
fileId: user.value!.profile.pictureId,
|
fileId: user.value!.profile.picture?.id,
|
||||||
radius: 40,
|
radius: 40,
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
@ -67,9 +67,9 @@ class AccountProfileScreen extends HookConsumerWidget {
|
|||||||
leading: PageBackButton(shadows: [iconShadow]),
|
leading: PageBackButton(shadows: [iconShadow]),
|
||||||
flexibleSpace: FlexibleSpaceBar(
|
flexibleSpace: FlexibleSpaceBar(
|
||||||
background:
|
background:
|
||||||
data.profile.backgroundId != null
|
data.profile.background?.id != null
|
||||||
? CloudImageWidget(
|
? CloudImageWidget(
|
||||||
fileId: data.profile.backgroundId!,
|
fileId: data.profile.background!.id,
|
||||||
)
|
)
|
||||||
: Container(
|
: Container(
|
||||||
color:
|
color:
|
||||||
@ -91,7 +91,7 @@ class AccountProfileScreen extends HookConsumerWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
ProfilePictureWidget(
|
ProfilePictureWidget(
|
||||||
fileId: data.profile.pictureId,
|
fileId: data.profile.picture?.id,
|
||||||
radius: 32,
|
radius: 32,
|
||||||
),
|
),
|
||||||
const Gap(20),
|
const Gap(20),
|
||||||
|
@ -100,7 +100,7 @@ class RelationshipListTile extends StatelessWidget {
|
|||||||
|
|
||||||
return ListTile(
|
return ListTile(
|
||||||
contentPadding: const EdgeInsets.only(left: 16, right: 12),
|
contentPadding: const EdgeInsets.only(left: 16, right: 12),
|
||||||
leading: ProfilePictureWidget(fileId: account.profile.pictureId),
|
leading: ProfilePictureWidget(fileId: account.profile.picture?.id),
|
||||||
title: Row(
|
title: Row(
|
||||||
spacing: 6,
|
spacing: 6,
|
||||||
children: [
|
children: [
|
||||||
|
@ -142,10 +142,9 @@ class _LoginCheckScreen extends HookConsumerWidget {
|
|||||||
'/auth/token',
|
'/auth/token',
|
||||||
data: {'grant_type': 'authorization_code', 'code': result.id},
|
data: {'grant_type': 'authorization_code', 'code': result.id},
|
||||||
);
|
);
|
||||||
final atk = tokenResp.data['access_token'];
|
final token = tokenResp.data['token'];
|
||||||
final rtk = tokenResp.data['refresh_token'];
|
setToken(ref.watch(sharedPreferencesProvider), token);
|
||||||
setTokenPair(ref.watch(sharedPreferencesProvider), atk, rtk);
|
ref.invalidate(tokenProvider);
|
||||||
ref.invalidate(tokenPairProvider);
|
|
||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
final userNotifier = ref.read(userInfoProvider.notifier);
|
final userNotifier = ref.read(userInfoProvider.notifier);
|
||||||
userNotifier.fetchUser().then((_) {
|
userNotifier.fetchUser().then((_) {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -17,6 +19,7 @@ class TabNavigationObserver extends AutoRouterObserver {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void didPush(Route route, Route? previousRoute) {
|
void didPush(Route route, Route? previousRoute) {
|
||||||
|
log('pushed ${previousRoute?.settings.name} -> ${route.settings.name}');
|
||||||
if (route is DialogRoute) return;
|
if (route is DialogRoute) return;
|
||||||
Future(() {
|
Future(() {
|
||||||
onChange(route.settings.name);
|
onChange(route.settings.name);
|
||||||
@ -25,6 +28,7 @@ class TabNavigationObserver extends AutoRouterObserver {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void didPop(Route route, Route? previousRoute) {
|
void didPop(Route route, Route? previousRoute) {
|
||||||
|
log('popped ${route.settings.name} -> ${previousRoute?.settings.name}');
|
||||||
if (route is DialogRoute) return;
|
if (route is DialogRoute) return;
|
||||||
Future(() {
|
Future(() {
|
||||||
onChange(previousRoute?.settings.name);
|
onChange(previousRoute?.settings.name);
|
||||||
@ -45,7 +49,6 @@ class TabsNavigationWidget extends HookConsumerWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final useHorizontalLayout = isWideScreen(context);
|
final useHorizontalLayout = isWideScreen(context);
|
||||||
final useExpandableLayout = isWidestScreen(context);
|
|
||||||
final currentRoute = ref.watch(currentRouteProvider);
|
final currentRoute = ref.watch(currentRouteProvider);
|
||||||
|
|
||||||
final notificationUnreadCount = ref.watch(
|
final notificationUnreadCount = ref.watch(
|
||||||
@ -82,6 +85,7 @@ class TabsNavigationWidget extends HookConsumerWidget {
|
|||||||
];
|
];
|
||||||
final routeNames = [
|
final routeNames = [
|
||||||
ExploreRoute.name,
|
ExploreRoute.name,
|
||||||
|
ExploreShellRoute.name,
|
||||||
ChatListRoute.name,
|
ChatListRoute.name,
|
||||||
RealmListRoute.name,
|
RealmListRoute.name,
|
||||||
AccountRoute.name,
|
AccountRoute.name,
|
||||||
@ -112,8 +116,6 @@ class TabsNavigationWidget extends HookConsumerWidget {
|
|||||||
Gap(MediaQuery.of(context).padding.top + 8),
|
Gap(MediaQuery.of(context).padding.top + 8),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: NavigationRail(
|
child: NavigationRail(
|
||||||
minExtendedWidth: 200,
|
|
||||||
extended: useExpandableLayout,
|
|
||||||
selectedIndex: activeIndex,
|
selectedIndex: activeIndex,
|
||||||
onDestinationSelected: (index) {
|
onDestinationSelected: (index) {
|
||||||
router.replace(routes[index]);
|
router.replace(routes[index]);
|
||||||
|
@ -166,7 +166,8 @@ class CallScreen extends HookConsumerWidget {
|
|||||||
.profile
|
.profile
|
||||||
?.account
|
?.account
|
||||||
.profile
|
.profile
|
||||||
.pictureId,
|
.picture
|
||||||
|
?.id,
|
||||||
size: 72,
|
size: 72,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -109,7 +109,7 @@ class ChatRoomListTile extends HookConsumerWidget {
|
|||||||
},
|
},
|
||||||
loading: () => const SizedBox.shrink(),
|
loading: () => const SizedBox.shrink(),
|
||||||
error:
|
error:
|
||||||
(_, __) =>
|
(_, _) =>
|
||||||
isDirect && room.description == null
|
isDirect && room.description == null
|
||||||
? Text(
|
? Text(
|
||||||
room.members!.map((e) => '@${e.account.name}').join(', '),
|
room.members!.map((e) => '@${e.account.name}').join(', '),
|
||||||
@ -127,19 +127,19 @@ class ChatRoomListTile extends HookConsumerWidget {
|
|||||||
isLabelVisible: summary.when(
|
isLabelVisible: summary.when(
|
||||||
data: (data) => (data?.unreadCount ?? 0) > 0,
|
data: (data) => (data?.unreadCount ?? 0) > 0,
|
||||||
loading: () => false,
|
loading: () => false,
|
||||||
error: (_, __) => false,
|
error: (_, _) => false,
|
||||||
),
|
),
|
||||||
child:
|
child:
|
||||||
(isDirect && room.pictureId == null)
|
(isDirect && room.picture?.id == null)
|
||||||
? SplitAvatarWidget(
|
? SplitAvatarWidget(
|
||||||
filesId:
|
filesId:
|
||||||
room.members!
|
room.members!
|
||||||
.map((e) => e.account.profile.pictureId)
|
.map((e) => e.account.profile.picture?.id)
|
||||||
.toList(),
|
.toList(),
|
||||||
)
|
)
|
||||||
: room.pictureId == null
|
: room.picture?.id == null
|
||||||
? CircleAvatar(child: Text(room.name![0].toUpperCase()))
|
? CircleAvatar(child: Text(room.name![0].toUpperCase()))
|
||||||
: ProfilePictureWidget(fileId: room.pictureId),
|
: ProfilePictureWidget(fileId: room.picture?.id),
|
||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
(isDirect && room.name == null)
|
(isDirect && room.name == null)
|
||||||
@ -147,6 +147,7 @@ class ChatRoomListTile extends HookConsumerWidget {
|
|||||||
: room.name ?? '',
|
: room.name ?? '',
|
||||||
),
|
),
|
||||||
subtitle: buildSubtitle(),
|
subtitle: buildSubtitle(),
|
||||||
|
trailing: trailing, // Add this line
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
// Clear unread count if there are unread messages
|
// Clear unread count if there are unread messages
|
||||||
ref.read(chatSummaryProvider.future).then((summary) {
|
ref.read(chatSummaryProvider.future).then((summary) {
|
||||||
@ -279,13 +280,13 @@ class ChatListScreen extends HookConsumerWidget {
|
|||||||
label: Text(
|
label: Text(
|
||||||
chatInvites.when(
|
chatInvites.when(
|
||||||
data: (invites) => invites.length.toString(),
|
data: (invites) => invites.length.toString(),
|
||||||
error: (_, __) => '0',
|
error: (_, _) => '0',
|
||||||
loading: () => '0',
|
loading: () => '0',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
isLabelVisible: chatInvites.when(
|
isLabelVisible: chatInvites.when(
|
||||||
data: (invites) => invites.isNotEmpty,
|
data: (invites) => invites.isNotEmpty,
|
||||||
error: (_, __) => false,
|
error: (_, _) => false,
|
||||||
loading: () => false,
|
loading: () => false,
|
||||||
),
|
),
|
||||||
child: const Icon(Symbols.email),
|
child: const Icon(Symbols.email),
|
||||||
@ -522,19 +523,15 @@ class EditChatScreen extends HookConsumerWidget {
|
|||||||
submitting.value = true;
|
submitting.value = true;
|
||||||
try {
|
try {
|
||||||
final baseUrl = ref.watch(serverUrlProvider);
|
final baseUrl = ref.watch(serverUrlProvider);
|
||||||
final atk = await getFreshAtk(
|
final token = await getToken(ref.watch(tokenProvider));
|
||||||
ref.watch(tokenPairProvider),
|
if (token == null) throw ArgumentError('Token is null');
|
||||||
baseUrl,
|
|
||||||
onRefreshed: (atk, rtk) {
|
|
||||||
setTokenPair(ref.watch(sharedPreferencesProvider), atk, rtk);
|
|
||||||
ref.invalidate(tokenPairProvider);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
if (atk == null) throw ArgumentError('Access token is null');
|
|
||||||
final cloudFile =
|
final cloudFile =
|
||||||
await putMediaToCloud(
|
await putMediaToCloud(
|
||||||
fileData: result,
|
fileData: UniversalFile(
|
||||||
atk: atk,
|
data: result,
|
||||||
|
type: UniversalFileType.image,
|
||||||
|
),
|
||||||
|
atk: token,
|
||||||
baseUrl: baseUrl,
|
baseUrl: baseUrl,
|
||||||
filename: result.name,
|
filename: result.name,
|
||||||
mimetype: result.mimeType ?? 'image/jpeg',
|
mimetype: result.mimeType ?? 'image/jpeg',
|
||||||
@ -595,7 +592,7 @@ class EditChatScreen extends HookConsumerWidget {
|
|||||||
realms: joinedRealms.when(
|
realms: joinedRealms.when(
|
||||||
data: (realms) => realms,
|
data: (realms) => realms,
|
||||||
loading: () => [],
|
loading: () => [],
|
||||||
error: (_, __) => [],
|
error: (_, _) => [],
|
||||||
),
|
),
|
||||||
onChanged: (SnRealm? value) {
|
onChanged: (SnRealm? value) {
|
||||||
currentRealm.value = value;
|
currentRealm.value = value;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
|
||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -18,21 +17,21 @@ import 'package:island/pods/database.dart';
|
|||||||
import 'package:island/pods/network.dart';
|
import 'package:island/pods/network.dart';
|
||||||
import 'package:island/pods/websocket.dart';
|
import 'package:island/pods/websocket.dart';
|
||||||
import 'package:island/route.gr.dart';
|
import 'package:island/route.gr.dart';
|
||||||
import 'package:island/screens/posts/compose.dart';
|
|
||||||
import 'package:island/services/responsive.dart';
|
import 'package:island/services/responsive.dart';
|
||||||
import 'package:island/widgets/alert.dart';
|
import 'package:island/widgets/alert.dart';
|
||||||
import 'package:island/widgets/app_scaffold.dart';
|
import 'package:island/widgets/app_scaffold.dart';
|
||||||
import 'package:island/widgets/chat/call_overlay.dart';
|
import 'package:island/widgets/chat/call_overlay.dart';
|
||||||
import 'package:island/widgets/chat/message_item.dart';
|
import 'package:island/widgets/chat/message_item.dart';
|
||||||
|
import 'package:island/widgets/content/attachment_preview.dart';
|
||||||
import 'package:island/widgets/content/cloud_files.dart';
|
import 'package:island/widgets/content/cloud_files.dart';
|
||||||
import 'package:island/widgets/response.dart';
|
import 'package:island/widgets/response.dart';
|
||||||
import 'package:material_symbols_icons/material_symbols_icons.dart';
|
import 'package:material_symbols_icons/material_symbols_icons.dart';
|
||||||
|
import 'package:pasteboard/pasteboard.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
import 'package:super_sliver_list/super_sliver_list.dart';
|
import 'package:super_sliver_list/super_sliver_list.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
import 'package:super_clipboard/super_clipboard.dart';
|
|
||||||
import 'chat.dart';
|
import 'chat.dart';
|
||||||
import 'package:island/widgets/chat/call_button.dart';
|
import 'package:island/widgets/chat/call_button.dart';
|
||||||
|
|
||||||
@ -117,19 +116,12 @@ class MessagesNotifier extends _$MessagesNotifier {
|
|||||||
messageRepositoryProvider(_roomId).future,
|
messageRepositoryProvider(_roomId).future,
|
||||||
);
|
);
|
||||||
final baseUrl = ref.read(serverUrlProvider);
|
final baseUrl = ref.read(serverUrlProvider);
|
||||||
final atk = await getFreshAtk(
|
final token = await getToken(ref.watch(tokenProvider));
|
||||||
ref.watch(tokenPairProvider),
|
if (token == null) throw ArgumentError('Access token is null');
|
||||||
baseUrl,
|
|
||||||
onRefreshed: (atk, rtk) {
|
|
||||||
setTokenPair(ref.watch(sharedPreferencesProvider), atk, rtk);
|
|
||||||
ref.invalidate(tokenPairProvider);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
if (atk == null) throw ArgumentError('Access token is null');
|
|
||||||
|
|
||||||
final currentMessages = state.value ?? [];
|
final currentMessages = state.value ?? [];
|
||||||
await repository.sendMessage(
|
await repository.sendMessage(
|
||||||
atk,
|
token,
|
||||||
baseUrl,
|
baseUrl,
|
||||||
_roomId,
|
_roomId,
|
||||||
content,
|
content,
|
||||||
@ -441,19 +433,23 @@ class ChatRoomScreen extends HookConsumerWidget {
|
|||||||
height: 26,
|
height: 26,
|
||||||
width: 26,
|
width: 26,
|
||||||
child:
|
child:
|
||||||
(room!.type == 1 && room.pictureId == null)
|
(room!.type == 1 && room.picture?.id == null)
|
||||||
? SplitAvatarWidget(
|
? SplitAvatarWidget(
|
||||||
filesId:
|
filesId:
|
||||||
room.members!
|
room.members!
|
||||||
.map(
|
.map(
|
||||||
(e) =>
|
(e) =>
|
||||||
e.account.profile.pictureId,
|
e
|
||||||
|
.account
|
||||||
|
.profile
|
||||||
|
.picture
|
||||||
|
?.id,
|
||||||
)
|
)
|
||||||
.toList(),
|
.toList(),
|
||||||
)
|
)
|
||||||
: room.pictureId != null
|
: room.picture?.id != null
|
||||||
? ProfilePictureWidget(
|
? ProfilePictureWidget(
|
||||||
fileId: room.pictureId,
|
fileId: room.picture?.id,
|
||||||
fallbackIcon: Symbols.chat,
|
fallbackIcon: Symbols.chat,
|
||||||
)
|
)
|
||||||
: CircleAvatar(
|
: CircleAvatar(
|
||||||
@ -481,19 +477,23 @@ class ChatRoomScreen extends HookConsumerWidget {
|
|||||||
height: 26,
|
height: 26,
|
||||||
width: 26,
|
width: 26,
|
||||||
child:
|
child:
|
||||||
(room!.type == 1 && room.pictureId == null)
|
(room!.type == 1 && room.picture?.id == null)
|
||||||
? SplitAvatarWidget(
|
? SplitAvatarWidget(
|
||||||
filesId:
|
filesId:
|
||||||
room.members!
|
room.members!
|
||||||
.map(
|
.map(
|
||||||
(e) =>
|
(e) =>
|
||||||
e.account.profile.pictureId,
|
e
|
||||||
|
.account
|
||||||
|
.profile
|
||||||
|
.picture
|
||||||
|
?.id,
|
||||||
)
|
)
|
||||||
.toList(),
|
.toList(),
|
||||||
)
|
)
|
||||||
: room.pictureId != null
|
: room.picture?.id != null
|
||||||
? ProfilePictureWidget(
|
? ProfilePictureWidget(
|
||||||
fileId: room.pictureId,
|
fileId: room.picture?.id,
|
||||||
fallbackIcon: Symbols.chat,
|
fallbackIcon: Symbols.chat,
|
||||||
)
|
)
|
||||||
: CircleAvatar(
|
: CircleAvatar(
|
||||||
@ -514,7 +514,7 @@ class ChatRoomScreen extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
loading: () => const Text('Loading...'),
|
loading: () => const Text('Loading...'),
|
||||||
error:
|
error:
|
||||||
(err, __) => ResponseErrorWidget(
|
(err, _) => ResponseErrorWidget(
|
||||||
error: err,
|
error: err,
|
||||||
onRetry: () => messagesNotifier.loadInitial(),
|
onRetry: () => messagesNotifier.loadInitial(),
|
||||||
),
|
),
|
||||||
@ -615,7 +615,7 @@ class ChatRoomScreen extends HookConsumerWidget {
|
|||||||
progress: null,
|
progress: null,
|
||||||
showAvatar: false,
|
showAvatar: false,
|
||||||
),
|
),
|
||||||
error: (_, __) => const SizedBox.shrink(),
|
error: (_, _) => const SizedBox.shrink(),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -680,7 +680,7 @@ class ChatRoomScreen extends HookConsumerWidget {
|
|||||||
attachments.value = newAttachments;
|
attachments.value = newAttachments;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
error: (_, __) => const SizedBox.shrink(),
|
error: (_, _) => const SizedBox.shrink(),
|
||||||
loading: () => const SizedBox.shrink(),
|
loading: () => const SizedBox.shrink(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -739,7 +739,7 @@ class _ChatInput extends ConsumerWidget {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final enterToSend = ref.read(appSettingsProvider).enterToSend;
|
final enterToSend = ref.read(appSettingsNotifierProvider).enterToSend;
|
||||||
final isEnter = event.logicalKey == LogicalKeyboardKey.enter;
|
final isEnter = event.logicalKey == LogicalKeyboardKey.enter;
|
||||||
|
|
||||||
if (isEnter) {
|
if (isEnter) {
|
||||||
@ -752,38 +752,21 @@ class _ChatInput extends ConsumerWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _handlePaste() async {
|
Future<void> _handlePaste() async {
|
||||||
final clipboard = SystemClipboard.instance;
|
final clipboard = await Pasteboard.image;
|
||||||
if (clipboard == null) return;
|
if (clipboard == null) return;
|
||||||
|
|
||||||
final reader = await clipboard.read();
|
onAttachmentsChanged([
|
||||||
if (reader.canProvide(Formats.png)) {
|
...attachments,
|
||||||
reader.getFile(Formats.png, (file) async {
|
UniversalFile(
|
||||||
final stream = file.getStream();
|
data: XFile.fromData(clipboard, mimeType: "image/jpeg"),
|
||||||
final bytes = await stream.toList();
|
type: UniversalFileType.image,
|
||||||
final imageBytes = bytes.expand((e) => e).toList();
|
),
|
||||||
|
]);
|
||||||
// Create a temporary file to store the image
|
|
||||||
final tempDir = Directory.systemTemp;
|
|
||||||
final tempFile = File(
|
|
||||||
'${tempDir.path}/pasted_image_${DateTime.now().millisecondsSinceEpoch}.png',
|
|
||||||
);
|
|
||||||
await tempFile.writeAsBytes(imageBytes);
|
|
||||||
|
|
||||||
// Add the file to attachments
|
|
||||||
onAttachmentsChanged([
|
|
||||||
...attachments,
|
|
||||||
UniversalFile(
|
|
||||||
data: XFile(tempFile.path),
|
|
||||||
type: UniversalFileType.image,
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final enterToSend = ref.watch(appSettingsProvider).enterToSend;
|
final enterToSend = ref.watch(appSettingsNotifierProvider).enterToSend;
|
||||||
|
|
||||||
return Material(
|
return Material(
|
||||||
elevation: 8,
|
elevation: 8,
|
||||||
@ -805,7 +788,7 @@ class _ChatInput extends ConsumerWidget {
|
|||||||
onMove: (delta) => onMoveAttachment(idx, delta),
|
onMove: (delta) => onMoveAttachment(idx, delta),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
separatorBuilder: (_, __) => const Gap(8),
|
separatorBuilder: (_, _) => const Gap(8),
|
||||||
),
|
),
|
||||||
).padding(top: 12),
|
).padding(top: 12),
|
||||||
if (messageReplyingTo != null ||
|
if (messageReplyingTo != null ||
|
||||||
|
@ -6,7 +6,7 @@ part of 'room.dart';
|
|||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$messagesNotifierHash() => r'71a9fc1c6d024f6203f06225384c19335b9b6f2c';
|
String _$messagesNotifierHash() => r'afc4d43f4948ec571118cef0321838a6cefc89c0';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
|
@ -48,9 +48,9 @@ class ChatDetailScreen extends HookConsumerWidget {
|
|||||||
flexibleSpace: FlexibleSpaceBar(
|
flexibleSpace: FlexibleSpaceBar(
|
||||||
background:
|
background:
|
||||||
(currentRoom!.type == 1 &&
|
(currentRoom!.type == 1 &&
|
||||||
currentRoom.backgroundId != null)
|
currentRoom.background?.id != null)
|
||||||
? CloudImageWidget(
|
? CloudImageWidget(
|
||||||
fileId: currentRoom.backgroundId!,
|
fileId: currentRoom.background!.id,
|
||||||
)
|
)
|
||||||
: (currentRoom.type == 1 &&
|
: (currentRoom.type == 1 &&
|
||||||
currentRoom.members!.length == 1 &&
|
currentRoom.members!.length == 1 &&
|
||||||
@ -59,7 +59,8 @@ class ChatDetailScreen extends HookConsumerWidget {
|
|||||||
.first
|
.first
|
||||||
.account
|
.account
|
||||||
.profile
|
.profile
|
||||||
.backgroundId !=
|
.background
|
||||||
|
?.id !=
|
||||||
null)
|
null)
|
||||||
? CloudImageWidget(
|
? CloudImageWidget(
|
||||||
fileId:
|
fileId:
|
||||||
@ -68,11 +69,12 @@ class ChatDetailScreen extends HookConsumerWidget {
|
|||||||
.first
|
.first
|
||||||
.account
|
.account
|
||||||
.profile
|
.profile
|
||||||
.backgroundId!,
|
.background!
|
||||||
|
.id,
|
||||||
)
|
)
|
||||||
: currentRoom.backgroundId != null
|
: currentRoom.background?.id != null
|
||||||
? CloudImageWidget(
|
? CloudImageWidget(
|
||||||
fileId: currentRoom.backgroundId!,
|
fileId: currentRoom.background!.id,
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
)
|
)
|
||||||
: Container(
|
: Container(
|
||||||
@ -390,7 +392,7 @@ class _ChatMemberListSheet extends HookConsumerWidget {
|
|||||||
return ListTile(
|
return ListTile(
|
||||||
contentPadding: EdgeInsets.only(left: 16, right: 12),
|
contentPadding: EdgeInsets.only(left: 16, right: 12),
|
||||||
leading: ProfilePictureWidget(
|
leading: ProfilePictureWidget(
|
||||||
fileId: member.account.profile.pictureId,
|
fileId: member.account.profile.picture?.id,
|
||||||
),
|
),
|
||||||
title: Row(
|
title: Row(
|
||||||
spacing: 6,
|
spacing: 6,
|
||||||
|
@ -101,7 +101,7 @@ class CreatorHubScreen extends HookConsumerWidget {
|
|||||||
minTileHeight: 48,
|
minTileHeight: 48,
|
||||||
leading: ProfilePictureWidget(
|
leading: ProfilePictureWidget(
|
||||||
radius: 16,
|
radius: 16,
|
||||||
fileId: item.pictureId,
|
fileId: item.picture?.id,
|
||||||
),
|
),
|
||||||
title: Text(item.nick),
|
title: Text(item.nick),
|
||||||
subtitle: Text('@${item.name}'),
|
subtitle: Text('@${item.name}'),
|
||||||
@ -115,7 +115,7 @@ class CreatorHubScreen extends HookConsumerWidget {
|
|||||||
)
|
)
|
||||||
.toList(),
|
.toList(),
|
||||||
loading: () => [],
|
loading: () => [],
|
||||||
error: (_, __) => [],
|
error: (_, _) => [],
|
||||||
);
|
);
|
||||||
|
|
||||||
final publisherStats = ref.watch(
|
final publisherStats = ref.watch(
|
||||||
@ -150,7 +150,7 @@ class CreatorHubScreen extends HookConsumerWidget {
|
|||||||
...publishersMenu.map(
|
...publishersMenu.map(
|
||||||
(e) => ProfilePictureWidget(
|
(e) => ProfilePictureWidget(
|
||||||
radius: 16,
|
radius: 16,
|
||||||
fileId: e.value?.pictureId,
|
fileId: e.value?.picture?.id,
|
||||||
).center().padding(right: 8),
|
).center().padding(right: 8),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
@ -204,7 +204,7 @@ class CreatorHubScreen extends HookConsumerWidget {
|
|||||||
...(publishers.value?.map(
|
...(publishers.value?.map(
|
||||||
(publisher) => ListTile(
|
(publisher) => ListTile(
|
||||||
leading: ProfilePictureWidget(
|
leading: ProfilePictureWidget(
|
||||||
fileId: publisher.pictureId,
|
fileId: publisher.picture?.id,
|
||||||
),
|
),
|
||||||
title: Text(publisher.nick),
|
title: Text(publisher.nick),
|
||||||
subtitle: Text('@${publisher.name}'),
|
subtitle: Text('@${publisher.name}'),
|
||||||
@ -293,7 +293,7 @@ class CreatorHubScreen extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
loading: () => const Center(child: CircularProgressIndicator()),
|
loading: () => const Center(child: CircularProgressIndicator()),
|
||||||
error: (_, __) => const SizedBox.shrink(),
|
error: (_, _) => const SizedBox.shrink(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
|
import 'package:island/models/file.dart';
|
||||||
import 'package:island/models/post.dart';
|
import 'package:island/models/post.dart';
|
||||||
import 'package:island/models/realm.dart';
|
import 'package:island/models/realm.dart';
|
||||||
import 'package:island/pods/config.dart';
|
import 'package:island/pods/config.dart';
|
||||||
@ -95,19 +96,15 @@ class EditPublisherScreen extends HookConsumerWidget {
|
|||||||
submitting.value = true;
|
submitting.value = true;
|
||||||
try {
|
try {
|
||||||
final baseUrl = ref.watch(serverUrlProvider);
|
final baseUrl = ref.watch(serverUrlProvider);
|
||||||
final atk = await getFreshAtk(
|
final token = await getToken(ref.watch(tokenProvider));
|
||||||
ref.watch(tokenPairProvider),
|
if (token == null) throw ArgumentError('Token is null');
|
||||||
baseUrl,
|
|
||||||
onRefreshed: (atk, rtk) {
|
|
||||||
setTokenPair(ref.watch(sharedPreferencesProvider), atk, rtk);
|
|
||||||
ref.invalidate(tokenPairProvider);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
if (atk == null) throw ArgumentError('Access token is null');
|
|
||||||
final cloudFile =
|
final cloudFile =
|
||||||
await putMediaToCloud(
|
await putMediaToCloud(
|
||||||
fileData: result,
|
fileData: UniversalFile(
|
||||||
atk: atk,
|
data: result,
|
||||||
|
type: UniversalFileType.image,
|
||||||
|
),
|
||||||
|
atk: token,
|
||||||
baseUrl: baseUrl,
|
baseUrl: baseUrl,
|
||||||
filename: result.name,
|
filename: result.name,
|
||||||
mimetype: result.mimeType ?? 'image/jpeg',
|
mimetype: result.mimeType ?? 'image/jpeg',
|
||||||
@ -145,8 +142,8 @@ class EditPublisherScreen extends HookConsumerWidget {
|
|||||||
|
|
||||||
useEffect(() {
|
useEffect(() {
|
||||||
if (publisher.value != null) {
|
if (publisher.value != null) {
|
||||||
picture.value = publisher.value!.pictureId;
|
picture.value = publisher.value!.picture?.id;
|
||||||
background.value = publisher.value!.backgroundId;
|
background.value = publisher.value!.background?.id;
|
||||||
nameController.text = publisher.value!.name;
|
nameController.text = publisher.value!.name;
|
||||||
nickController.text = publisher.value!.nick;
|
nickController.text = publisher.value!.nick;
|
||||||
bioController.text = publisher.value!.bio;
|
bioController.text = publisher.value!.bio;
|
||||||
@ -200,7 +197,7 @@ class EditPublisherScreen extends HookConsumerWidget {
|
|||||||
realms: joinedRealms.when(
|
realms: joinedRealms.when(
|
||||||
data: (realms) => realms,
|
data: (realms) => realms,
|
||||||
loading: () => [],
|
loading: () => [],
|
||||||
error: (_, __) => [],
|
error: (_, _) => [],
|
||||||
),
|
),
|
||||||
onChanged: (SnRealm? value) {
|
onChanged: (SnRealm? value) {
|
||||||
currentRealm.value = value;
|
currentRealm.value = value;
|
||||||
@ -286,14 +283,14 @@ class EditPublisherScreen extends HookConsumerWidget {
|
|||||||
nameController.text = user.value!.name;
|
nameController.text = user.value!.name;
|
||||||
nickController.text = user.value!.nick;
|
nickController.text = user.value!.nick;
|
||||||
bioController.text = user.value!.profile.bio;
|
bioController.text = user.value!.profile.bio;
|
||||||
picture.value = user.value!.profile.pictureId;
|
picture.value = user.value!.profile.picture?.id;
|
||||||
background.value = user.value!.profile.backgroundId;
|
background.value = user.value!.profile.background?.id;
|
||||||
} else {
|
} else {
|
||||||
nameController.text = currentRealm.value!.slug;
|
nameController.text = currentRealm.value!.slug;
|
||||||
nickController.text = currentRealm.value!.name;
|
nickController.text = currentRealm.value!.name;
|
||||||
bioController.text = currentRealm.value!.description;
|
bioController.text = currentRealm.value!.description;
|
||||||
picture.value = currentRealm.value!.pictureId;
|
picture.value = currentRealm.value!.picture?.id;
|
||||||
background.value = currentRealm.value!.backgroundId;
|
background.value = currentRealm.value!.background?.id;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
label:
|
label:
|
||||||
|
@ -17,6 +17,7 @@ import 'package:material_symbols_icons/symbols.dart';
|
|||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';
|
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';
|
||||||
import 'package:island/pods/network.dart';
|
import 'package:island/pods/network.dart';
|
||||||
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
|
||||||
part 'explore.g.dart';
|
part 'explore.g.dart';
|
||||||
|
|
||||||
@ -131,10 +132,16 @@ class _ActivityListView extends HookConsumerWidget {
|
|||||||
|
|
||||||
switch (item.type) {
|
switch (item.type) {
|
||||||
case 'posts.new':
|
case 'posts.new':
|
||||||
|
case 'posts.new.replies':
|
||||||
|
final isReply = item.type == 'posts.new.replies';
|
||||||
itemWidget = PostItem(
|
itemWidget = PostItem(
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
isWideScreen(context) ? Colors.transparent : null,
|
isWideScreen(context) ? Colors.transparent : null,
|
||||||
item: SnPost.fromJson(item.data),
|
item: SnPost.fromJson(item.data),
|
||||||
|
padding:
|
||||||
|
isReply
|
||||||
|
? EdgeInsets.only(left: 16, right: 16, bottom: 16)
|
||||||
|
: null,
|
||||||
onRefresh: (_) {
|
onRefresh: (_) {
|
||||||
activitiesNotifier.forceRefresh();
|
activitiesNotifier.forceRefresh();
|
||||||
},
|
},
|
||||||
@ -145,6 +152,21 @@ class _ActivityListView extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
if (isReply) {
|
||||||
|
itemWidget = Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
const Icon(Symbols.reply),
|
||||||
|
const Gap(8),
|
||||||
|
Text('Replying your post'),
|
||||||
|
],
|
||||||
|
).padding(horizontal: 20, vertical: 8),
|
||||||
|
itemWidget,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'accounts.check-in':
|
case 'accounts.check-in':
|
||||||
itemWidget = CheckInActivityWidget(item: item);
|
itemWidget = CheckInActivityWidget(item: item);
|
||||||
|
@ -7,7 +7,7 @@ part of 'notification.dart';
|
|||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$notificationUnreadCountNotifierHash() =>
|
String _$notificationUnreadCountNotifierHash() =>
|
||||||
r'074143cf208a3afe1495be405198532a23ef77c8';
|
r'372a2cc259d7d838cd4f33a9129f7396ef31dbb9';
|
||||||
|
|
||||||
/// See also [NotificationUnreadCountNotifier].
|
/// See also [NotificationUnreadCountNotifier].
|
||||||
@ProviderFor(NotificationUnreadCountNotifier)
|
@ProviderFor(NotificationUnreadCountNotifier)
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
@ -21,10 +19,11 @@ import 'package:island/services/responsive.dart';
|
|||||||
import 'package:island/widgets/alert.dart';
|
import 'package:island/widgets/alert.dart';
|
||||||
import 'package:island/widgets/app_scaffold.dart';
|
import 'package:island/widgets/app_scaffold.dart';
|
||||||
import 'package:island/widgets/content/cloud_files.dart';
|
import 'package:island/widgets/content/cloud_files.dart';
|
||||||
|
import 'package:island/widgets/content/attachment_preview.dart';
|
||||||
import 'package:island/widgets/post/publishers_modal.dart';
|
import 'package:island/widgets/post/publishers_modal.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
|
import 'package:pasteboard/pasteboard.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
import 'package:super_clipboard/super_clipboard.dart';
|
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
class PostEditScreen extends HookConsumerWidget {
|
class PostEditScreen extends HookConsumerWidget {
|
||||||
@ -53,7 +52,14 @@ class PostEditScreen extends HookConsumerWidget {
|
|||||||
@RoutePage()
|
@RoutePage()
|
||||||
class PostComposeScreen extends HookConsumerWidget {
|
class PostComposeScreen extends HookConsumerWidget {
|
||||||
final SnPost? originalPost;
|
final SnPost? originalPost;
|
||||||
const PostComposeScreen({super.key, this.originalPost});
|
final SnPost? repliedPost;
|
||||||
|
final SnPost? forwardedPost;
|
||||||
|
const PostComposeScreen({
|
||||||
|
super.key,
|
||||||
|
this.originalPost,
|
||||||
|
this.repliedPost,
|
||||||
|
this.forwardedPost,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
@ -90,9 +96,14 @@ class PostComposeScreen extends HookConsumerWidget {
|
|||||||
text: originalPost?.description,
|
text: originalPost?.description,
|
||||||
);
|
);
|
||||||
final contentController = useTextEditingController(
|
final contentController = useTextEditingController(
|
||||||
text: originalPost?.content,
|
text:
|
||||||
|
originalPost?.content ??
|
||||||
|
(forwardedPost != null ? '> ${forwardedPost!.content}\n\n' : null),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Add visibility state with default value from original post or 0 (public)
|
||||||
|
final visibility = useState<int>(originalPost?.visibility ?? 0);
|
||||||
|
|
||||||
final submitting = useState(false);
|
final submitting = useState(false);
|
||||||
|
|
||||||
Future<void> pickPhotoMedia() async {
|
Future<void> pickPhotoMedia() async {
|
||||||
@ -125,21 +136,14 @@ class PostComposeScreen extends HookConsumerWidget {
|
|||||||
final attachment = attachments.value[index];
|
final attachment = attachments.value[index];
|
||||||
if (attachment is SnCloudFile) return;
|
if (attachment is SnCloudFile) return;
|
||||||
final baseUrl = ref.watch(serverUrlProvider);
|
final baseUrl = ref.watch(serverUrlProvider);
|
||||||
final atk = await getFreshAtk(
|
final token = await getToken(ref.watch(tokenProvider));
|
||||||
ref.watch(tokenPairProvider),
|
if (token == null) throw ArgumentError('Token is null');
|
||||||
baseUrl,
|
|
||||||
onRefreshed: (atk, rtk) {
|
|
||||||
setTokenPair(ref.watch(sharedPreferencesProvider), atk, rtk);
|
|
||||||
ref.invalidate(tokenPairProvider);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
if (atk == null) throw ArgumentError('Access token is null');
|
|
||||||
try {
|
try {
|
||||||
attachmentProgress.value = {...attachmentProgress.value, index: 0};
|
attachmentProgress.value = {...attachmentProgress.value, index: 0};
|
||||||
final cloudFile =
|
final cloudFile =
|
||||||
await putMediaToCloud(
|
await putMediaToCloud(
|
||||||
fileData: attachment.data,
|
fileData: attachment.data,
|
||||||
atk: atk,
|
atk: token,
|
||||||
baseUrl: baseUrl,
|
baseUrl: baseUrl,
|
||||||
filename: attachment.data.name ?? 'Post media',
|
filename: attachment.data.name ?? 'Post media',
|
||||||
mimetype:
|
mimetype:
|
||||||
@ -195,12 +199,18 @@ class PostComposeScreen extends HookConsumerWidget {
|
|||||||
await client.request(
|
await client.request(
|
||||||
originalPost == null ? '/posts' : '/posts/${originalPost!.id}',
|
originalPost == null ? '/posts' : '/posts/${originalPost!.id}',
|
||||||
data: {
|
data: {
|
||||||
|
'title': titleController.text,
|
||||||
|
'description': descriptionController.text,
|
||||||
'content': contentController.text,
|
'content': contentController.text,
|
||||||
|
'visibility':
|
||||||
|
visibility.value, // Add visibility field to API request
|
||||||
'attachments':
|
'attachments':
|
||||||
attachments.value
|
attachments.value
|
||||||
.where((e) => e.isOnCloud)
|
.where((e) => e.isOnCloud)
|
||||||
.map((e) => e.data.id)
|
.map((e) => e.data.id)
|
||||||
.toList(),
|
.toList(),
|
||||||
|
if (repliedPost != null) 'replied_post_id': repliedPost!.id,
|
||||||
|
if (forwardedPost != null) 'forwarded_post_id': forwardedPost!.id,
|
||||||
},
|
},
|
||||||
options: Options(
|
options: Options(
|
||||||
headers: {'X-Pub': currentPublisher.value?.name},
|
headers: {'X-Pub': currentPublisher.value?.name},
|
||||||
@ -217,44 +227,106 @@ class PostComposeScreen extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _handlePaste() async {
|
Future<void> handlePaste() async {
|
||||||
final clipboard = SystemClipboard.instance;
|
final clipboard = await Pasteboard.image;
|
||||||
if (clipboard == null) return;
|
if (clipboard == null) return;
|
||||||
|
|
||||||
final reader = await clipboard.read();
|
attachments.value = [
|
||||||
if (reader.canProvide(Formats.png)) {
|
...attachments.value,
|
||||||
reader.getFile(Formats.png, (file) async {
|
UniversalFile(
|
||||||
final stream = file.getStream();
|
data: XFile.fromData(clipboard, mimeType: "image/jpeg"),
|
||||||
final bytes = await stream.toList();
|
type: UniversalFileType.image,
|
||||||
final imageBytes = bytes.expand((e) => e).toList();
|
),
|
||||||
|
];
|
||||||
// Create a temporary file to store the image
|
|
||||||
final tempDir = Directory.systemTemp;
|
|
||||||
final tempFile = File(
|
|
||||||
'${tempDir.path}/pasted_image_${DateTime.now().millisecondsSinceEpoch}.png',
|
|
||||||
);
|
|
||||||
await tempFile.writeAsBytes(imageBytes);
|
|
||||||
|
|
||||||
// Add the file to attachments
|
|
||||||
attachments.value = [
|
|
||||||
...attachments.value,
|
|
||||||
UniversalFile(
|
|
||||||
data: XFile(tempFile.path),
|
|
||||||
type: UniversalFileType.image,
|
|
||||||
),
|
|
||||||
];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleKeyPress(RawKeyEvent event) {
|
void handleKeyPress(RawKeyEvent event) {
|
||||||
if (event is! RawKeyDownEvent) return;
|
if (event is! RawKeyDownEvent) return;
|
||||||
|
|
||||||
final isPaste = event.logicalKey == LogicalKeyboardKey.keyV;
|
final isPaste = event.logicalKey == LogicalKeyboardKey.keyV;
|
||||||
final isModifierPressed = event.isMetaPressed || event.isControlPressed;
|
final isModifierPressed = event.isMetaPressed || event.isControlPressed;
|
||||||
|
|
||||||
if (isPaste && isModifierPressed) {
|
if (isPaste && isModifierPressed) {
|
||||||
_handlePaste();
|
handlePaste();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void showVisibilityModal() {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder:
|
||||||
|
(context) => AlertDialog(
|
||||||
|
title: Text('postVisibility'.tr()),
|
||||||
|
content: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
ListTile(
|
||||||
|
leading: Icon(Symbols.public),
|
||||||
|
title: Text('postVisibilityPublic'.tr()),
|
||||||
|
onTap: () {
|
||||||
|
visibility.value = 0;
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
selected: visibility.value == 0,
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
leading: Icon(Symbols.group),
|
||||||
|
title: Text('postVisibilityFriends'.tr()),
|
||||||
|
onTap: () {
|
||||||
|
visibility.value = 1;
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
selected: visibility.value == 1,
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
leading: Icon(Symbols.link_off),
|
||||||
|
title: Text('postVisibilityUnlisted'.tr()),
|
||||||
|
onTap: () {
|
||||||
|
visibility.value = 2;
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
selected: visibility.value == 2,
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
leading: Icon(Symbols.lock),
|
||||||
|
title: Text('postVisibilityPrivate'.tr()),
|
||||||
|
onTap: () {
|
||||||
|
visibility.value = 3;
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
selected: visibility.value == 3,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper method to get the appropriate icon for each visibility status
|
||||||
|
IconData getVisibilityIcon(int visibilityValue) {
|
||||||
|
switch (visibilityValue) {
|
||||||
|
case 1: // Friends
|
||||||
|
return Symbols.group;
|
||||||
|
case 2: // Unlisted
|
||||||
|
return Symbols.link_off;
|
||||||
|
case 3: // Private
|
||||||
|
return Symbols.lock;
|
||||||
|
default: // Public (0) or unknown
|
||||||
|
return Symbols.public;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper method to get the translation key for each visibility status
|
||||||
|
String getVisibilityText(int visibilityValue) {
|
||||||
|
switch (visibilityValue) {
|
||||||
|
case 1: // Friends
|
||||||
|
return 'postVisibilityFriends';
|
||||||
|
case 2: // Unlisted
|
||||||
|
return 'postVisibilityUnlisted';
|
||||||
|
case 3: // Private
|
||||||
|
return 'postVisibilityPrivate';
|
||||||
|
default: // Public (0) or unknown
|
||||||
|
return 'postVisibilityPublic';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,6 +392,48 @@ class PostComposeScreen extends HookConsumerWidget {
|
|||||||
body: Column(
|
body: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
if (repliedPost != null)
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||||
|
color: Theme.of(
|
||||||
|
context,
|
||||||
|
).colorScheme.surfaceVariant.withOpacity(0.5),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
const Icon(Symbols.reply, size: 16),
|
||||||
|
const Gap(8),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
'${'reply'.tr()}: ${repliedPost!.publisher.nick}',
|
||||||
|
style: Theme.of(context).textTheme.bodySmall,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (forwardedPost != null)
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||||
|
color: Theme.of(
|
||||||
|
context,
|
||||||
|
).colorScheme.surfaceVariant.withOpacity(0.5),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
const Icon(Symbols.forward, size: 16),
|
||||||
|
const Gap(8),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
'${'forward'.tr()}: ${forwardedPost!.publisher.nick}',
|
||||||
|
style: Theme.of(context).textTheme.bodySmall,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Row(
|
child: Row(
|
||||||
spacing: 12,
|
spacing: 12,
|
||||||
@ -327,7 +441,7 @@ class PostComposeScreen extends HookConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
child: ProfilePictureWidget(
|
child: ProfilePictureWidget(
|
||||||
fileId: currentPublisher.value?.pictureId,
|
fileId: currentPublisher.value?.picture?.id,
|
||||||
radius: 20,
|
radius: 20,
|
||||||
fallbackIcon:
|
fallbackIcon:
|
||||||
currentPublisher.value == null
|
currentPublisher.value == null
|
||||||
@ -348,7 +462,52 @@ class PostComposeScreen extends HookConsumerWidget {
|
|||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
padding: EdgeInsets.symmetric(vertical: 16),
|
padding: EdgeInsets.symmetric(vertical: 16),
|
||||||
child: Column(
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
OutlinedButton(
|
||||||
|
onPressed: () {
|
||||||
|
showVisibilityModal();
|
||||||
|
},
|
||||||
|
style: OutlinedButton.styleFrom(
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
),
|
||||||
|
side: BorderSide(
|
||||||
|
color: Theme.of(
|
||||||
|
context,
|
||||||
|
).colorScheme.primary.withOpacity(0.5),
|
||||||
|
),
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 16),
|
||||||
|
visualDensity: const VisualDensity(
|
||||||
|
vertical: -2,
|
||||||
|
horizontal: -4,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
getVisibilityIcon(visibility.value),
|
||||||
|
size: 16,
|
||||||
|
color:
|
||||||
|
Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 6),
|
||||||
|
Text(
|
||||||
|
getVisibilityText(visibility.value).tr(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color:
|
||||||
|
Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).padding(bottom: 6),
|
||||||
TextField(
|
TextField(
|
||||||
controller: titleController,
|
controller: titleController,
|
||||||
decoration: InputDecoration.collapsed(
|
decoration: InputDecoration.collapsed(
|
||||||
@ -372,7 +531,7 @@ class PostComposeScreen extends HookConsumerWidget {
|
|||||||
const Gap(8),
|
const Gap(8),
|
||||||
RawKeyboardListener(
|
RawKeyboardListener(
|
||||||
focusNode: FocusNode(),
|
focusNode: FocusNode(),
|
||||||
onKey: _handleKeyPress,
|
onKey: handleKeyPress,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
controller: contentController,
|
controller: contentController,
|
||||||
style: TextStyle(fontSize: 14),
|
style: TextStyle(fontSize: 14),
|
||||||
@ -394,49 +553,32 @@ class PostComposeScreen extends HookConsumerWidget {
|
|||||||
final isWide = isWideScreen(context);
|
final isWide = isWideScreen(context);
|
||||||
return isWide
|
return isWide
|
||||||
? Wrap(
|
? Wrap(
|
||||||
spacing: 8,
|
spacing: 8,
|
||||||
runSpacing: 8,
|
runSpacing: 8,
|
||||||
children: [
|
children: [
|
||||||
for (var idx = 0; idx < attachments.value.length; idx++)
|
for (
|
||||||
SizedBox(
|
var idx = 0;
|
||||||
width: constraints.maxWidth / 2 - 4,
|
idx < attachments.value.length;
|
||||||
child: AttachmentPreview(
|
idx++
|
||||||
item: attachments.value[idx],
|
)
|
||||||
progress: attachmentProgress.value[idx],
|
SizedBox(
|
||||||
onRequestUpload: () => uploadAttachment(idx),
|
width: constraints.maxWidth / 2 - 4,
|
||||||
onDelete: () => deleteAttachment(idx),
|
child: AttachmentPreview(
|
||||||
onMove: (delta) {
|
|
||||||
if (idx + delta < 0 ||
|
|
||||||
idx + delta >= attachments.value.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final clone = List.of(attachments.value);
|
|
||||||
clone.insert(
|
|
||||||
idx + delta,
|
|
||||||
clone.removeAt(idx),
|
|
||||||
);
|
|
||||||
attachments.value = clone;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
spacing: 8,
|
|
||||||
children: [
|
|
||||||
for (var idx = 0; idx < attachments.value.length; idx++)
|
|
||||||
AttachmentPreview(
|
|
||||||
item: attachments.value[idx],
|
item: attachments.value[idx],
|
||||||
progress: attachmentProgress.value[idx],
|
progress:
|
||||||
onRequestUpload: () => uploadAttachment(idx),
|
attachmentProgress.value[idx],
|
||||||
|
onRequestUpload:
|
||||||
|
() => uploadAttachment(idx),
|
||||||
onDelete: () => deleteAttachment(idx),
|
onDelete: () => deleteAttachment(idx),
|
||||||
onMove: (delta) {
|
onMove: (delta) {
|
||||||
if (idx + delta < 0 ||
|
if (idx + delta < 0 ||
|
||||||
idx + delta >= attachments.value.length) {
|
idx + delta >=
|
||||||
|
attachments.value.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final clone = List.of(attachments.value);
|
final clone = List.of(
|
||||||
|
attachments.value,
|
||||||
|
);
|
||||||
clone.insert(
|
clone.insert(
|
||||||
idx + delta,
|
idx + delta,
|
||||||
clone.removeAt(idx),
|
clone.removeAt(idx),
|
||||||
@ -444,8 +586,42 @@ class PostComposeScreen extends HookConsumerWidget {
|
|||||||
attachments.value = clone;
|
attachments.value = clone;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
);
|
],
|
||||||
|
)
|
||||||
|
: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
spacing: 8,
|
||||||
|
children: [
|
||||||
|
for (
|
||||||
|
var idx = 0;
|
||||||
|
idx < attachments.value.length;
|
||||||
|
idx++
|
||||||
|
)
|
||||||
|
AttachmentPreview(
|
||||||
|
item: attachments.value[idx],
|
||||||
|
progress: attachmentProgress.value[idx],
|
||||||
|
onRequestUpload:
|
||||||
|
() => uploadAttachment(idx),
|
||||||
|
onDelete: () => deleteAttachment(idx),
|
||||||
|
onMove: (delta) {
|
||||||
|
if (idx + delta < 0 ||
|
||||||
|
idx + delta >=
|
||||||
|
attachments.value.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final clone = List.of(
|
||||||
|
attachments.value,
|
||||||
|
);
|
||||||
|
clone.insert(
|
||||||
|
idx + delta,
|
||||||
|
clone.removeAt(idx),
|
||||||
|
);
|
||||||
|
attachments.value = clone;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -481,204 +657,3 @@ class PostComposeScreen extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AttachmentPreview extends StatelessWidget {
|
|
||||||
final UniversalFile item;
|
|
||||||
final double? progress;
|
|
||||||
final Function(int)? onMove;
|
|
||||||
final Function? onDelete;
|
|
||||||
final Function? onRequestUpload;
|
|
||||||
const AttachmentPreview({
|
|
||||||
super.key,
|
|
||||||
required this.item,
|
|
||||||
this.progress,
|
|
||||||
this.onRequestUpload,
|
|
||||||
this.onMove,
|
|
||||||
this.onDelete,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return AspectRatio(
|
|
||||||
aspectRatio:
|
|
||||||
(item.isOnCloud ? (item.data.fileMeta?['ratio'] ?? 1) : 1).toDouble(),
|
|
||||||
child: ClipRRect(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
child: Stack(
|
|
||||||
fit: StackFit.expand,
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
color: Theme.of(context).colorScheme.surfaceContainerHigh,
|
|
||||||
child: Builder(
|
|
||||||
builder: (context) {
|
|
||||||
if (item.isOnCloud) {
|
|
||||||
return CloudFileWidget(item: item.data);
|
|
||||||
} else if (item.data is XFile) {
|
|
||||||
if (item.type == UniversalFileType.image) {
|
|
||||||
return Image.file(File(item.data.path));
|
|
||||||
} else {
|
|
||||||
return Center(
|
|
||||||
child: Text(
|
|
||||||
'Preview is not supported for ${item.type}',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else if (item is List<int> || item is Uint8List) {
|
|
||||||
if (item.type == UniversalFileType.image) {
|
|
||||||
return Image.memory(item.data);
|
|
||||||
} else {
|
|
||||||
return Center(
|
|
||||||
child: Text(
|
|
||||||
'Preview is not supported for ${item.type}',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Placeholder();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (progress != null)
|
|
||||||
Positioned.fill(
|
|
||||||
child: Container(
|
|
||||||
color: Colors.black.withOpacity(0.3),
|
|
||||||
padding: EdgeInsets.symmetric(horizontal: 40, vertical: 16),
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
if (progress != null)
|
|
||||||
Text(
|
|
||||||
'${progress!.toStringAsFixed(2)}%',
|
|
||||||
style: TextStyle(color: Colors.white),
|
|
||||||
)
|
|
||||||
else
|
|
||||||
Text(
|
|
||||||
'uploading'.tr(),
|
|
||||||
style: TextStyle(color: Colors.white),
|
|
||||||
),
|
|
||||||
Gap(6),
|
|
||||||
Center(child: LinearProgressIndicator(value: progress)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Positioned(
|
|
||||||
left: 8,
|
|
||||||
top: 8,
|
|
||||||
child: ClipRRect(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
child: Container(
|
|
||||||
color: Colors.black.withOpacity(0.5),
|
|
||||||
child: Material(
|
|
||||||
color: Colors.transparent,
|
|
||||||
child: Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
if (onDelete != null)
|
|
||||||
InkWell(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
child: const Icon(
|
|
||||||
Symbols.delete,
|
|
||||||
size: 14,
|
|
||||||
color: Colors.white,
|
|
||||||
).padding(horizontal: 8, vertical: 6),
|
|
||||||
onTap: () {
|
|
||||||
onDelete?.call();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
if (onDelete != null && onMove != null)
|
|
||||||
SizedBox(
|
|
||||||
height: 26,
|
|
||||||
child: const VerticalDivider(
|
|
||||||
width: 0.3,
|
|
||||||
color: Colors.white,
|
|
||||||
thickness: 0.3,
|
|
||||||
),
|
|
||||||
).padding(horizontal: 2),
|
|
||||||
if (onMove != null)
|
|
||||||
InkWell(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
child: const Icon(
|
|
||||||
Symbols.keyboard_arrow_up,
|
|
||||||
size: 14,
|
|
||||||
color: Colors.white,
|
|
||||||
).padding(horizontal: 8, vertical: 6),
|
|
||||||
onTap: () {
|
|
||||||
onMove?.call(-1);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
if (onMove != null)
|
|
||||||
InkWell(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
child: const Icon(
|
|
||||||
Symbols.keyboard_arrow_down,
|
|
||||||
size: 14,
|
|
||||||
color: Colors.white,
|
|
||||||
).padding(horizontal: 8, vertical: 6),
|
|
||||||
onTap: () {
|
|
||||||
onMove?.call(1);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (onRequestUpload != null)
|
|
||||||
Positioned(
|
|
||||||
top: 8,
|
|
||||||
right: 8,
|
|
||||||
child: InkWell(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
onTap: () => onRequestUpload?.call(),
|
|
||||||
child: ClipRRect(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
child: Container(
|
|
||||||
color: Colors.black.withOpacity(0.5),
|
|
||||||
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
|
||||||
child:
|
|
||||||
(item.isOnCloud)
|
|
||||||
? Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
Symbols.cloud,
|
|
||||||
size: 16,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
const Gap(8),
|
|
||||||
Text(
|
|
||||||
'On-cloud',
|
|
||||||
style: TextStyle(color: Colors.white),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
: Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
Symbols.cloud_off,
|
|
||||||
size: 16,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
const Gap(8),
|
|
||||||
Text(
|
|
||||||
'On-device',
|
|
||||||
style: TextStyle(color: Colors.white),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:auto_route/annotations.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
@ -108,8 +108,8 @@ class PublisherProfileScreen extends HookConsumerWidget {
|
|||||||
leading: PageBackButton(shadows: [iconShadow]),
|
leading: PageBackButton(shadows: [iconShadow]),
|
||||||
flexibleSpace: FlexibleSpaceBar(
|
flexibleSpace: FlexibleSpaceBar(
|
||||||
background:
|
background:
|
||||||
data.backgroundId != null
|
data.background?.id != null
|
||||||
? CloudImageWidget(fileId: data.backgroundId!)
|
? CloudImageWidget(fileId: data.background!.id)
|
||||||
: Container(
|
: Container(
|
||||||
color:
|
color:
|
||||||
Theme.of(context).appBarTheme.backgroundColor,
|
Theme.of(context).appBarTheme.backgroundColor,
|
||||||
@ -139,7 +139,7 @@ class PublisherProfileScreen extends HookConsumerWidget {
|
|||||||
shadows: [iconShadow],
|
shadows: [iconShadow],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
error: (_, __) => const SizedBox(),
|
error: (_, _) => const SizedBox(),
|
||||||
loading:
|
loading:
|
||||||
() => const SizedBox(
|
() => const SizedBox(
|
||||||
width: 48,
|
width: 48,
|
||||||
@ -163,7 +163,10 @@ class PublisherProfileScreen extends HookConsumerWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
spacing: 20,
|
spacing: 20,
|
||||||
children: [
|
children: [
|
||||||
ProfilePictureWidget(fileId: data.pictureId!, radius: 32),
|
ProfilePictureWidget(
|
||||||
|
fileId: data.picture!.id,
|
||||||
|
radius: 32,
|
||||||
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
@ -177,6 +180,26 @@ class PublisherProfileScreen extends HookConsumerWidget {
|
|||||||
).fontSize(14).opacity(0.85),
|
).fontSize(14).opacity(0.85),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
if (data.type == 0 && data.account != null)
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
context.router.pushPath(
|
||||||
|
'/account/${data.account!.name}',
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
spacing: 4,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'publisherVisitAccountPage'.tr(
|
||||||
|
args: ['@${data.account!.name}'],
|
||||||
|
),
|
||||||
|
).fontSize(14),
|
||||||
|
Icon(Icons.launch, size: 14),
|
||||||
|
],
|
||||||
|
).opacity(0.85),
|
||||||
|
).padding(bottom: 6),
|
||||||
if (data.type == 0 && data.account != null)
|
if (data.type == 0 && data.account != null)
|
||||||
AccountStatusWidget(
|
AccountStatusWidget(
|
||||||
uname: data.account!.name,
|
uname: data.account!.name,
|
||||||
|
@ -145,7 +145,7 @@ class _PublisherProviderElement
|
|||||||
String get uname => (origin as PublisherProvider).uname;
|
String get uname => (origin as PublisherProvider).uname;
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$publisherBadgesHash() => r'b26d8804ddc9734c453bdf76af0a9336f166542c';
|
String _$publisherBadgesHash() => r'a5781deded7e682a781ccd7854418f050438e3f4';
|
||||||
|
|
||||||
/// See also [publisherBadges].
|
/// See also [publisherBadges].
|
||||||
@ProviderFor(publisherBadges)
|
@ProviderFor(publisherBadges)
|
||||||
|
@ -54,8 +54,8 @@ class RealmDetailScreen extends HookConsumerWidget {
|
|||||||
leading: PageBackButton(shadows: [iconShadow]),
|
leading: PageBackButton(shadows: [iconShadow]),
|
||||||
flexibleSpace: FlexibleSpaceBar(
|
flexibleSpace: FlexibleSpaceBar(
|
||||||
background:
|
background:
|
||||||
realm!.backgroundId != null
|
realm!.background?.id != null
|
||||||
? CloudImageWidget(fileId: realm.backgroundId!)
|
? CloudImageWidget(fileId: realm.background!.id)
|
||||||
: Container(
|
: Container(
|
||||||
color:
|
color:
|
||||||
Theme.of(context).appBarTheme.backgroundColor,
|
Theme.of(context).appBarTheme.backgroundColor,
|
||||||
@ -118,7 +118,7 @@ class _RealmActionMenu extends HookConsumerWidget {
|
|||||||
final isModerator = realmIdentityAsync.when(
|
final isModerator = realmIdentityAsync.when(
|
||||||
data: (identity) => (identity?.role ?? 0) >= 50,
|
data: (identity) => (identity?.role ?? 0) >= 50,
|
||||||
loading: () => false,
|
loading: () => false,
|
||||||
error: (_, __) => false,
|
error: (_, _) => false,
|
||||||
);
|
);
|
||||||
|
|
||||||
return PopupMenuButton(
|
return PopupMenuButton(
|
||||||
@ -212,7 +212,7 @@ class _RealmActionMenu extends HookConsumerWidget {
|
|||||||
child: Center(child: CircularProgressIndicator()),
|
child: Center(child: CircularProgressIndicator()),
|
||||||
),
|
),
|
||||||
error:
|
error:
|
||||||
(_, __) => PopupMenuItem(
|
(_, _) => PopupMenuItem(
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Icon(
|
Icon(
|
||||||
@ -403,7 +403,7 @@ class _RealmMemberListSheet extends HookConsumerWidget {
|
|||||||
return ListTile(
|
return ListTile(
|
||||||
contentPadding: EdgeInsets.only(left: 16, right: 12),
|
contentPadding: EdgeInsets.only(left: 16, right: 12),
|
||||||
leading: ProfilePictureWidget(
|
leading: ProfilePictureWidget(
|
||||||
fileId: member.account!.profile.pictureId,
|
fileId: member.account!.profile.picture?.id,
|
||||||
),
|
),
|
||||||
title: Row(
|
title: Row(
|
||||||
spacing: 6,
|
spacing: 6,
|
||||||
|
@ -49,13 +49,13 @@ class RealmListScreen extends HookConsumerWidget {
|
|||||||
label: Text(
|
label: Text(
|
||||||
realmInvites.when(
|
realmInvites.when(
|
||||||
data: (invites) => invites.length.toString(),
|
data: (invites) => invites.length.toString(),
|
||||||
error: (_, __) => '0',
|
error: (_, _) => '0',
|
||||||
loading: () => '0',
|
loading: () => '0',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
isLabelVisible: realmInvites.when(
|
isLabelVisible: realmInvites.when(
|
||||||
data: (invites) => invites.isNotEmpty,
|
data: (invites) => invites.isNotEmpty,
|
||||||
error: (_, __) => false,
|
error: (_, _) => false,
|
||||||
loading: () => false,
|
loading: () => false,
|
||||||
),
|
),
|
||||||
child: const Icon(Symbols.email),
|
child: const Icon(Symbols.email),
|
||||||
@ -97,7 +97,7 @@ class RealmListScreen extends HookConsumerWidget {
|
|||||||
return ListTile(
|
return ListTile(
|
||||||
isThreeLine: true,
|
isThreeLine: true,
|
||||||
leading: ProfilePictureWidget(
|
leading: ProfilePictureWidget(
|
||||||
fileId: value[item].pictureId,
|
fileId: value[item].picture?.id,
|
||||||
fallbackIcon: Symbols.group,
|
fallbackIcon: Symbols.group,
|
||||||
),
|
),
|
||||||
title: Text(value[item].name),
|
title: Text(value[item].name),
|
||||||
@ -211,19 +211,15 @@ class EditRealmScreen extends HookConsumerWidget {
|
|||||||
submitting.value = true;
|
submitting.value = true;
|
||||||
try {
|
try {
|
||||||
final baseUrl = ref.watch(serverUrlProvider);
|
final baseUrl = ref.watch(serverUrlProvider);
|
||||||
final atk = await getFreshAtk(
|
final token = await getToken(ref.watch(tokenProvider));
|
||||||
ref.watch(tokenPairProvider),
|
if (token == null) throw ArgumentError('Access token is null');
|
||||||
baseUrl,
|
|
||||||
onRefreshed: (atk, rtk) {
|
|
||||||
setTokenPair(ref.watch(sharedPreferencesProvider), atk, rtk);
|
|
||||||
ref.invalidate(tokenPairProvider);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
if (atk == null) throw ArgumentError('Access token is null');
|
|
||||||
final cloudFile =
|
final cloudFile =
|
||||||
await putMediaToCloud(
|
await putMediaToCloud(
|
||||||
fileData: result,
|
fileData: UniversalFile(
|
||||||
atk: atk,
|
data: result,
|
||||||
|
type: UniversalFileType.image,
|
||||||
|
),
|
||||||
|
atk: token,
|
||||||
baseUrl: baseUrl,
|
baseUrl: baseUrl,
|
||||||
filename: result.name,
|
filename: result.name,
|
||||||
mimetype: result.mimeType ?? 'image/jpeg',
|
mimetype: result.mimeType ?? 'image/jpeg',
|
||||||
@ -455,7 +451,7 @@ class _RealmInviteSheet extends HookConsumerWidget {
|
|||||||
final invite = items[index];
|
final invite = items[index];
|
||||||
return ListTile(
|
return ListTile(
|
||||||
leading: ProfilePictureWidget(
|
leading: ProfilePictureWidget(
|
||||||
fileId: invite.realm!.pictureId,
|
fileId: invite.realm!.picture?.id,
|
||||||
fallbackIcon: Symbols.group,
|
fallbackIcon: Symbols.group,
|
||||||
),
|
),
|
||||||
title: Text(invite.realm!.name),
|
title: Text(invite.realm!.name),
|
||||||
|
@ -7,6 +7,7 @@ import 'package:easy_localization/easy_localization.dart';
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
@ -28,7 +29,7 @@ class SettingsScreen extends HookConsumerWidget {
|
|||||||
final serverUrl = ref.watch(serverUrlProvider);
|
final serverUrl = ref.watch(serverUrlProvider);
|
||||||
final prefs = ref.watch(sharedPreferencesProvider);
|
final prefs = ref.watch(sharedPreferencesProvider);
|
||||||
final controller = TextEditingController(text: serverUrl);
|
final controller = TextEditingController(text: serverUrl);
|
||||||
final settings = ref.watch(appSettingsProvider);
|
final settings = ref.watch(appSettingsNotifierProvider);
|
||||||
final isDesktop =
|
final isDesktop =
|
||||||
!kIsWeb && (Platform.isWindows || Platform.isMacOS || Platform.isLinux);
|
!kIsWeb && (Platform.isWindows || Platform.isMacOS || Platform.isLinux);
|
||||||
final isWide = isWideScreen(context);
|
final isWide = isWideScreen(context);
|
||||||
@ -88,6 +89,108 @@ class SettingsScreen extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// Custom fonts settings
|
||||||
|
ListTile(
|
||||||
|
isThreeLine: true,
|
||||||
|
minLeadingWidth: 48,
|
||||||
|
title: Text('settingsCustomFonts').tr(),
|
||||||
|
contentPadding: const EdgeInsets.only(left: 24, right: 17),
|
||||||
|
leading: const Icon(Symbols.font_download),
|
||||||
|
subtitle: Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 6),
|
||||||
|
child: TextField(
|
||||||
|
controller: TextEditingController(text: settings.customFonts),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: 'Nunito, Arial, sans-serif',
|
||||||
|
helperText: 'settingsCustomFontsHelper'.tr(),
|
||||||
|
suffixIcon: IconButton(
|
||||||
|
icon: const Icon(Symbols.restart_alt),
|
||||||
|
onPressed: () {
|
||||||
|
ref
|
||||||
|
.read(appSettingsNotifierProvider.notifier)
|
||||||
|
.setCustomFonts(null);
|
||||||
|
showSnackBar(context, 'settingsApplied'.tr());
|
||||||
|
},
|
||||||
|
),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
isDense: true,
|
||||||
|
),
|
||||||
|
onSubmitted: (value) {
|
||||||
|
ref
|
||||||
|
.read(appSettingsNotifierProvider.notifier)
|
||||||
|
.setCustomFonts(value.isEmpty ? null : value);
|
||||||
|
showSnackBar(context, 'settingsApplied'.tr());
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Color scheme settings
|
||||||
|
ListTile(
|
||||||
|
minLeadingWidth: 48,
|
||||||
|
title: Text('settingsColorScheme').tr(),
|
||||||
|
contentPadding: const EdgeInsets.only(left: 24, right: 17),
|
||||||
|
leading: const Icon(Symbols.palette),
|
||||||
|
trailing: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
Color selectedColor =
|
||||||
|
settings.appColorScheme != null
|
||||||
|
? Color(settings.appColorScheme!)
|
||||||
|
: Colors.indigo;
|
||||||
|
|
||||||
|
return AlertDialog(
|
||||||
|
title: Text('settingsColorScheme').tr(),
|
||||||
|
content: SingleChildScrollView(
|
||||||
|
child: ColorPicker(
|
||||||
|
enableAlpha: false,
|
||||||
|
pickerColor: selectedColor,
|
||||||
|
onColorChanged: (color) {
|
||||||
|
selectedColor = color;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
child: Text('Cancel').tr(),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
ref
|
||||||
|
.read(appSettingsNotifierProvider.notifier)
|
||||||
|
.setAppColorScheme(selectedColor.value);
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: Text('Confirm').tr(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color:
|
||||||
|
settings.appColorScheme != null
|
||||||
|
? Color(settings.appColorScheme!)
|
||||||
|
: Colors.indigo,
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
border: Border.all(
|
||||||
|
color: Theme.of(context).colorScheme.outline.withOpacity(0.5),
|
||||||
|
width: 2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
// Background image settings (only for non-web platforms)
|
// Background image settings (only for non-web platforms)
|
||||||
if (!kIsWeb && docBasepath.value != null)
|
if (!kIsWeb && docBasepath.value != null)
|
||||||
ListTile(
|
ListTile(
|
||||||
@ -128,13 +231,15 @@ class SettingsScreen extends HookConsumerWidget {
|
|||||||
// Clear background image option
|
// Clear background image option
|
||||||
if (!kIsWeb && docBasepath.value != null)
|
if (!kIsWeb && docBasepath.value != null)
|
||||||
FutureBuilder<bool>(
|
FutureBuilder<bool>(
|
||||||
future: File('${docBasepath.value}/app_background_image').exists(),
|
future:
|
||||||
|
File('${docBasepath.value}/$kAppBackgroundImagePath').exists(),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (!snapshot.hasData || !snapshot.data!) {
|
if (!snapshot.hasData || !snapshot.data!) {
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ListTile(
|
return ListTile(
|
||||||
|
minLeadingWidth: 48,
|
||||||
title: Text('settingsBackgroundImageClear').tr(),
|
title: Text('settingsBackgroundImageClear').tr(),
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
||||||
leading: const Icon(Symbols.texture),
|
leading: const Icon(Symbols.texture),
|
||||||
@ -207,7 +312,9 @@ class SettingsScreen extends HookConsumerWidget {
|
|||||||
trailing: Switch(
|
trailing: Switch(
|
||||||
value: settings.autoTranslate,
|
value: settings.autoTranslate,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
ref.read(appSettingsProvider.notifier).setAutoTranslate(value);
|
ref
|
||||||
|
.read(appSettingsNotifierProvider.notifier)
|
||||||
|
.setAutoTranslate(value);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -221,7 +328,9 @@ class SettingsScreen extends HookConsumerWidget {
|
|||||||
trailing: Switch(
|
trailing: Switch(
|
||||||
value: settings.soundEffects,
|
value: settings.soundEffects,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
ref.read(appSettingsProvider.notifier).setSoundEffects(value);
|
ref
|
||||||
|
.read(appSettingsNotifierProvider.notifier)
|
||||||
|
.setSoundEffects(value);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -235,7 +344,9 @@ class SettingsScreen extends HookConsumerWidget {
|
|||||||
trailing: Switch(
|
trailing: Switch(
|
||||||
value: settings.aprilFoolFeatures,
|
value: settings.aprilFoolFeatures,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
ref.read(appSettingsProvider.notifier).setAprilFoolFeatures(value);
|
ref
|
||||||
|
.read(appSettingsNotifierProvider.notifier)
|
||||||
|
.setAprilFoolFeatures(value);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -253,7 +364,25 @@ class SettingsScreen extends HookConsumerWidget {
|
|||||||
trailing: Switch(
|
trailing: Switch(
|
||||||
value: settings.enterToSend,
|
value: settings.enterToSend,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
ref.read(appSettingsProvider.notifier).setEnterToSend(value);
|
ref
|
||||||
|
.read(appSettingsNotifierProvider.notifier)
|
||||||
|
.setEnterToSend(value);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Transparent app bar settings
|
||||||
|
ListTile(
|
||||||
|
minLeadingWidth: 48,
|
||||||
|
title: Text('settingsTransparentAppBar').tr(),
|
||||||
|
contentPadding: const EdgeInsets.only(left: 24, right: 17),
|
||||||
|
leading: const Icon(Symbols.blur_on),
|
||||||
|
trailing: Switch(
|
||||||
|
value: settings.appBarTransparent,
|
||||||
|
onChanged: (value) {
|
||||||
|
ref
|
||||||
|
.read(appSettingsNotifierProvider.notifier)
|
||||||
|
.setAppBarTransparent(value);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -39,7 +39,7 @@ Future<XFile?> cropImage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Completer<SnCloudFile?> putMediaToCloud({
|
Completer<SnCloudFile?> putMediaToCloud({
|
||||||
required dynamic fileData, // Can be XFile or List<int> (Uint8List)
|
required UniversalFile fileData,
|
||||||
required String atk,
|
required String atk,
|
||||||
required String baseUrl,
|
required String baseUrl,
|
||||||
String? filename,
|
String? filename,
|
||||||
@ -51,21 +51,27 @@ Completer<SnCloudFile?> putMediaToCloud({
|
|||||||
String actualMimetype = mimetype ?? '';
|
String actualMimetype = mimetype ?? '';
|
||||||
Uint8List? byteData;
|
Uint8List? byteData;
|
||||||
|
|
||||||
if (fileData is XFile) {
|
// Handle the data based on what's in the UniversalFile
|
||||||
file = fileData;
|
final data = fileData.data;
|
||||||
actualFilename = filename ?? fileData.name;
|
|
||||||
actualMimetype = mimetype ?? fileData.mimeType ?? '';
|
if (data is XFile) {
|
||||||
} else if (fileData is List<int> || fileData is Uint8List) {
|
file = data;
|
||||||
byteData = fileData is List<int> ? Uint8List.fromList(fileData) : fileData;
|
actualFilename = filename ?? data.name;
|
||||||
|
actualMimetype = mimetype ?? data.mimeType ?? '';
|
||||||
|
} else if (data is List<int> || data is Uint8List) {
|
||||||
|
byteData = data is List<int> ? Uint8List.fromList(data) : data;
|
||||||
actualFilename = filename ?? 'uploaded_file';
|
actualFilename = filename ?? 'uploaded_file';
|
||||||
actualMimetype = mimetype ?? 'application/octet-stream';
|
actualMimetype = mimetype ?? 'application/octet-stream';
|
||||||
if (mimetype == null) {
|
if (mimetype == null) {
|
||||||
throw ArgumentError('Mimetype is required when providing raw bytes.');
|
throw ArgumentError('Mimetype is required when providing raw bytes.');
|
||||||
}
|
}
|
||||||
file = XFile.fromData(byteData!, mimeType: actualMimetype);
|
file = XFile.fromData(byteData!, mimeType: actualMimetype);
|
||||||
|
} else if (data is SnCloudFile) {
|
||||||
|
// If the file is already on the cloud, just return it
|
||||||
|
return Completer<SnCloudFile?>()..complete(data);
|
||||||
} else {
|
} else {
|
||||||
throw ArgumentError(
|
throw ArgumentError(
|
||||||
'Invalid fileData type. Expected XFile or List<int> (Uint8List).',
|
'Invalid fileData type. Expected data to be XFile, List<int>, Uint8List, or SnCloudFile.',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ class AccountPickerSheet extends HookConsumerWidget {
|
|||||||
final account = accounts[index];
|
final account = accounts[index];
|
||||||
return ListTile(
|
return ListTile(
|
||||||
leading: ProfilePictureWidget(
|
leading: ProfilePictureWidget(
|
||||||
fileId: account.profile.pictureId,
|
fileId: account.profile.picture?.id,
|
||||||
),
|
),
|
||||||
title: Text(account.nick),
|
title: Text(account.nick),
|
||||||
subtitle: Text('@${account.name}'),
|
subtitle: Text('@${account.name}'),
|
||||||
|
@ -146,7 +146,7 @@ class StatusActivityWidget extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
ProfilePictureWidget(
|
ProfilePictureWidget(
|
||||||
fileId: item.account.profile.pictureId,
|
fileId: item.account.profile.picture?.id,
|
||||||
radius: 12,
|
radius: 12,
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
|
@ -235,7 +235,7 @@ class AppBackground extends ConsumerWidget {
|
|||||||
},
|
},
|
||||||
loading: () => const SizedBox(),
|
loading: () => const SizedBox(),
|
||||||
error:
|
error:
|
||||||
(_, __) => Material(
|
(_, _) => Material(
|
||||||
color: Theme.of(context).colorScheme.surface,
|
color: Theme.of(context).colorScheme.surface,
|
||||||
child: child,
|
child: child,
|
||||||
),
|
),
|
||||||
|
@ -14,6 +14,7 @@ part 'call_button.g.dart';
|
|||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
Future<SnRealtimeCall?> ongoingCall(Ref ref, String roomId) async {
|
Future<SnRealtimeCall?> ongoingCall(Ref ref, String roomId) async {
|
||||||
|
if (roomId.isEmpty) return null;
|
||||||
try {
|
try {
|
||||||
final apiClient = ref.watch(apiClientProvider);
|
final apiClient = ref.watch(apiClientProvider);
|
||||||
final resp = await apiClient.get('/chat/realtime/$roomId');
|
final resp = await apiClient.get('/chat/realtime/$roomId');
|
||||||
|
@ -6,7 +6,7 @@ part of 'call_button.dart';
|
|||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$ongoingCallHash() => r'd8a942e6695a7da702daeaa452464c16761ef6e7';
|
String _$ongoingCallHash() => r'ab7337bcd4d766897bd6d6a38f418c6bdd15eb94';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
|
@ -45,7 +45,7 @@ class CallControlsBar extends HookConsumerWidget {
|
|||||||
callNotifier.localParticipant!.isSpeaking,
|
callNotifier.localParticipant!.isSpeaking,
|
||||||
audioLevel:
|
audioLevel:
|
||||||
callNotifier.localParticipant!.audioLevel,
|
callNotifier.localParticipant!.audioLevel,
|
||||||
pictureId: userInfo.value?.profile.pictureId,
|
pictureId: userInfo.value?.profile.picture?.id,
|
||||||
size: 36,
|
size: 36,
|
||||||
).center(),
|
).center(),
|
||||||
);
|
);
|
||||||
@ -158,7 +158,8 @@ class CallOverlayBar extends HookConsumerWidget {
|
|||||||
.profile
|
.profile
|
||||||
?.account
|
?.account
|
||||||
.profile
|
.profile
|
||||||
.pictureId,
|
.picture
|
||||||
|
?.id,
|
||||||
size: 36,
|
size: 36,
|
||||||
).center(),
|
).center(),
|
||||||
);
|
);
|
||||||
|
@ -106,7 +106,7 @@ class CallParticipantTile extends StatelessWidget {
|
|||||||
return SpeakingRippleAvatar(
|
return SpeakingRippleAvatar(
|
||||||
isSpeaking: live.isSpeaking,
|
isSpeaking: live.isSpeaking,
|
||||||
audioLevel: audioLevel,
|
audioLevel: audioLevel,
|
||||||
pictureId: live.participant.profile?.account.profile.pictureId,
|
pictureId: live.participant.profile?.account.profile.picture?.id,
|
||||||
size: 84,
|
size: 84,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ class MessageItem extends HookConsumerWidget {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
ProfilePictureWidget(
|
ProfilePictureWidget(
|
||||||
fileId: sender.account.profile.pictureId,
|
fileId: sender.account.profile.picture?.id,
|
||||||
radius: 16,
|
radius: 16,
|
||||||
),
|
),
|
||||||
Column(
|
Column(
|
||||||
@ -414,7 +414,7 @@ class _MessageItemContent extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
case 'text':
|
case 'text':
|
||||||
default:
|
default:
|
||||||
return MarkdownTextContent(content: item.content!);
|
return MarkdownTextContent(content: item.content!, isSelectable: true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ class CheckInWidget extends HookConsumerWidget {
|
|||||||
key: ValueKey(result != null),
|
key: ValueKey(result != null),
|
||||||
),
|
),
|
||||||
loading: () => const Icon(Symbols.refresh),
|
loading: () => const Icon(Symbols.refresh),
|
||||||
error: (_, __) => const Icon(Symbols.error),
|
error: (_, _) => const Icon(Symbols.error),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -188,7 +188,7 @@ class CheckInActivityWidget extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
ProfilePictureWidget(
|
ProfilePictureWidget(
|
||||||
fileId: result.account!.profile.pictureId,
|
fileId: result.account!.profile.picture?.id,
|
||||||
radius: 12,
|
radius: 12,
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
|
212
lib/widgets/content/attachment_preview.dart
Normal file
212
lib/widgets/content/attachment_preview.dart
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:cross_file/cross_file.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:gap/gap.dart';
|
||||||
|
import 'package:island/models/file.dart';
|
||||||
|
import 'package:island/widgets/content/cloud_files.dart';
|
||||||
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
|
||||||
|
class AttachmentPreview extends StatelessWidget {
|
||||||
|
final UniversalFile item;
|
||||||
|
final double? progress;
|
||||||
|
final Function(int)? onMove;
|
||||||
|
final Function? onDelete;
|
||||||
|
final Function? onRequestUpload;
|
||||||
|
const AttachmentPreview({
|
||||||
|
super.key,
|
||||||
|
required this.item,
|
||||||
|
this.progress,
|
||||||
|
this.onRequestUpload,
|
||||||
|
this.onMove,
|
||||||
|
this.onDelete,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AspectRatio(
|
||||||
|
aspectRatio:
|
||||||
|
(item.isOnCloud ? (item.data.fileMeta?['ratio'] ?? 1) : 1).toDouble(),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
child: Stack(
|
||||||
|
fit: StackFit.expand,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
color: Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||||
|
child: Builder(
|
||||||
|
builder: (context) {
|
||||||
|
if (item.isOnCloud) {
|
||||||
|
return CloudFileWidget(item: item.data);
|
||||||
|
} else if (item.data is XFile) {
|
||||||
|
if (item.type == UniversalFileType.image) {
|
||||||
|
return Image.file(File(item.data.path));
|
||||||
|
} else {
|
||||||
|
return Center(
|
||||||
|
child: Text(
|
||||||
|
'Preview is not supported for ${item.type}',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (item is List<int> || item is Uint8List) {
|
||||||
|
if (item.type == UniversalFileType.image) {
|
||||||
|
return Image.memory(item.data);
|
||||||
|
} else {
|
||||||
|
return Center(
|
||||||
|
child: Text(
|
||||||
|
'Preview is not supported for ${item.type}',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Placeholder();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (progress != null)
|
||||||
|
Positioned.fill(
|
||||||
|
child: Container(
|
||||||
|
color: Colors.black.withOpacity(0.3),
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 40, vertical: 16),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
if (progress != null)
|
||||||
|
Text(
|
||||||
|
'${progress!.toStringAsFixed(2)}%',
|
||||||
|
style: TextStyle(color: Colors.white),
|
||||||
|
)
|
||||||
|
else
|
||||||
|
Text(
|
||||||
|
'uploading'.tr(),
|
||||||
|
style: TextStyle(color: Colors.white),
|
||||||
|
),
|
||||||
|
Gap(6),
|
||||||
|
Center(child: LinearProgressIndicator(value: progress)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
left: 8,
|
||||||
|
top: 8,
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
child: Container(
|
||||||
|
color: Colors.black.withOpacity(0.5),
|
||||||
|
child: Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
if (onDelete != null)
|
||||||
|
InkWell(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
child: const Icon(
|
||||||
|
Symbols.delete,
|
||||||
|
size: 14,
|
||||||
|
color: Colors.white,
|
||||||
|
).padding(horizontal: 8, vertical: 6),
|
||||||
|
onTap: () {
|
||||||
|
onDelete?.call();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
if (onDelete != null && onMove != null)
|
||||||
|
SizedBox(
|
||||||
|
height: 26,
|
||||||
|
child: const VerticalDivider(
|
||||||
|
width: 0.3,
|
||||||
|
color: Colors.white,
|
||||||
|
thickness: 0.3,
|
||||||
|
),
|
||||||
|
).padding(horizontal: 2),
|
||||||
|
if (onMove != null)
|
||||||
|
InkWell(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
child: const Icon(
|
||||||
|
Symbols.keyboard_arrow_up,
|
||||||
|
size: 14,
|
||||||
|
color: Colors.white,
|
||||||
|
).padding(horizontal: 8, vertical: 6),
|
||||||
|
onTap: () {
|
||||||
|
onMove?.call(-1);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
if (onMove != null)
|
||||||
|
InkWell(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
child: const Icon(
|
||||||
|
Symbols.keyboard_arrow_down,
|
||||||
|
size: 14,
|
||||||
|
color: Colors.white,
|
||||||
|
).padding(horizontal: 8, vertical: 6),
|
||||||
|
onTap: () {
|
||||||
|
onMove?.call(1);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (onRequestUpload != null)
|
||||||
|
Positioned(
|
||||||
|
top: 8,
|
||||||
|
right: 8,
|
||||||
|
child: InkWell(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
onTap: () => onRequestUpload?.call(),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
child: Container(
|
||||||
|
color: Colors.black.withOpacity(0.5),
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||||
|
child:
|
||||||
|
(item.isOnCloud)
|
||||||
|
? Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Symbols.cloud,
|
||||||
|
size: 16,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
const Gap(8),
|
||||||
|
Text(
|
||||||
|
'On-cloud',
|
||||||
|
style: TextStyle(color: Colors.white),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Symbols.cloud_off,
|
||||||
|
size: 16,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
const Gap(8),
|
||||||
|
Text(
|
||||||
|
'On-device',
|
||||||
|
style: TextStyle(color: Colors.white),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -159,7 +159,7 @@ class CloudFileList extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
separatorBuilder: (_, __) => const Gap(8),
|
separatorBuilder: (_, _) => const Gap(8),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -8,9 +8,9 @@ import 'package:image_picker/image_picker.dart';
|
|||||||
import 'package:island/models/file.dart';
|
import 'package:island/models/file.dart';
|
||||||
import 'package:island/pods/config.dart';
|
import 'package:island/pods/config.dart';
|
||||||
import 'package:island/pods/network.dart';
|
import 'package:island/pods/network.dart';
|
||||||
import 'package:island/screens/posts/compose.dart';
|
|
||||||
import 'package:island/services/file.dart';
|
import 'package:island/services/file.dart';
|
||||||
import 'package:island/widgets/alert.dart';
|
import 'package:island/widgets/alert.dart';
|
||||||
|
import 'package:island/widgets/content/attachment_preview.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
|
||||||
@ -43,15 +43,8 @@ class CloudFilePicker extends HookConsumerWidget {
|
|||||||
if (files.value.isEmpty) return;
|
if (files.value.isEmpty) return;
|
||||||
|
|
||||||
final baseUrl = ref.read(serverUrlProvider);
|
final baseUrl = ref.read(serverUrlProvider);
|
||||||
final atk = await getFreshAtk(
|
final token = await getToken(ref.watch(tokenProvider));
|
||||||
ref.watch(tokenPairProvider),
|
if (token == null) throw Exception("Unauthorized");
|
||||||
baseUrl,
|
|
||||||
onRefreshed: (atk, rtk) {
|
|
||||||
setTokenPair(ref.watch(sharedPreferencesProvider), atk, rtk);
|
|
||||||
ref.invalidate(tokenPairProvider);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
if (atk == null) throw Exception("Unauthorized");
|
|
||||||
|
|
||||||
List<SnCloudFile> result = List.empty(growable: true);
|
List<SnCloudFile> result = List.empty(growable: true);
|
||||||
|
|
||||||
@ -64,7 +57,7 @@ class CloudFilePicker extends HookConsumerWidget {
|
|||||||
final cloudFile =
|
final cloudFile =
|
||||||
await putMediaToCloud(
|
await putMediaToCloud(
|
||||||
fileData: file.data,
|
fileData: file.data,
|
||||||
atk: atk,
|
atk: token,
|
||||||
baseUrl: baseUrl,
|
baseUrl: baseUrl,
|
||||||
filename: file.data.name ?? 'Post media',
|
filename: file.data.name ?? 'Post media',
|
||||||
mimetype:
|
mimetype:
|
||||||
@ -266,7 +259,7 @@ class CloudFilePicker extends HookConsumerWidget {
|
|||||||
progress: null,
|
progress: null,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
separatorBuilder: (_, __) => const Gap(8),
|
separatorBuilder: (_, _) => const Gap(8),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Card(
|
Card(
|
||||||
|
@ -1 +1,53 @@
|
|||||||
export 'image.native.dart' if (dart.library.html) 'image.web.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_blurhash/flutter_blurhash.dart';
|
||||||
|
|
||||||
|
class UniversalImage extends StatelessWidget {
|
||||||
|
final String uri;
|
||||||
|
final String? blurHash;
|
||||||
|
final BoxFit fit;
|
||||||
|
final double? width;
|
||||||
|
final double? height;
|
||||||
|
final bool noCacheOptimization;
|
||||||
|
|
||||||
|
const UniversalImage({
|
||||||
|
super.key,
|
||||||
|
required this.uri,
|
||||||
|
this.blurHash,
|
||||||
|
this.fit = BoxFit.cover,
|
||||||
|
this.width,
|
||||||
|
this.height,
|
||||||
|
this.noCacheOptimization = false,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
int? cacheWidth;
|
||||||
|
int? cacheHeight;
|
||||||
|
if (width != null && height != null && !noCacheOptimization) {
|
||||||
|
final devicePixelRatio = MediaQuery.of(context).devicePixelRatio;
|
||||||
|
cacheWidth = width != null ? (width! * devicePixelRatio).round() : null;
|
||||||
|
cacheHeight =
|
||||||
|
height != null ? (height! * devicePixelRatio).round() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SizedBox(
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
child: Stack(
|
||||||
|
fit: StackFit.expand,
|
||||||
|
children: [
|
||||||
|
if (blurHash != null) BlurHash(hash: blurHash!),
|
||||||
|
CachedNetworkImage(
|
||||||
|
imageUrl: uri,
|
||||||
|
fit: fit,
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
memCacheHeight: cacheHeight,
|
||||||
|
memCacheWidth: cacheWidth,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,53 +0,0 @@
|
|||||||
import 'package:cached_network_image/cached_network_image.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_blurhash/flutter_blurhash.dart';
|
|
||||||
|
|
||||||
class UniversalImage extends StatelessWidget {
|
|
||||||
final String uri;
|
|
||||||
final String? blurHash;
|
|
||||||
final BoxFit fit;
|
|
||||||
final double? width;
|
|
||||||
final double? height;
|
|
||||||
final bool noCacheOptimization;
|
|
||||||
|
|
||||||
const UniversalImage({
|
|
||||||
super.key,
|
|
||||||
required this.uri,
|
|
||||||
this.blurHash,
|
|
||||||
this.fit = BoxFit.cover,
|
|
||||||
this.width,
|
|
||||||
this.height,
|
|
||||||
this.noCacheOptimization = false,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
int? cacheWidth;
|
|
||||||
int? cacheHeight;
|
|
||||||
if (width != null && height != null && !noCacheOptimization) {
|
|
||||||
final devicePixelRatio = MediaQuery.of(context).devicePixelRatio;
|
|
||||||
cacheWidth = width != null ? (width! * devicePixelRatio).round() : null;
|
|
||||||
cacheHeight =
|
|
||||||
height != null ? (height! * devicePixelRatio).round() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return SizedBox(
|
|
||||||
width: width,
|
|
||||||
height: height,
|
|
||||||
child: Stack(
|
|
||||||
fit: StackFit.expand,
|
|
||||||
children: [
|
|
||||||
if (blurHash != null) BlurHash(hash: blurHash!),
|
|
||||||
CachedNetworkImage(
|
|
||||||
imageUrl: uri,
|
|
||||||
fit: fit,
|
|
||||||
width: width,
|
|
||||||
height: height,
|
|
||||||
memCacheHeight: cacheHeight,
|
|
||||||
memCacheWidth: cacheWidth,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
import 'package:web/web.dart' as web;
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class UniversalImage extends StatelessWidget {
|
|
||||||
final String uri;
|
|
||||||
final String? blurHash;
|
|
||||||
final BoxFit fit;
|
|
||||||
final double? width;
|
|
||||||
final double? height;
|
|
||||||
// No cache optimization for web
|
|
||||||
final bool noCacheOptimization;
|
|
||||||
|
|
||||||
const UniversalImage({
|
|
||||||
super.key,
|
|
||||||
required this.uri,
|
|
||||||
this.blurHash,
|
|
||||||
this.fit = BoxFit.cover,
|
|
||||||
this.width,
|
|
||||||
this.height,
|
|
||||||
this.noCacheOptimization = false,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return HtmlElementView.fromTagName(
|
|
||||||
tagName: 'img',
|
|
||||||
onElementCreated: (element) {
|
|
||||||
element as web.HTMLImageElement;
|
|
||||||
element.src = uri;
|
|
||||||
element.style.width = width?.toString() ?? '100%';
|
|
||||||
element.style.height = height?.toString() ?? '100%';
|
|
||||||
element.style.objectFit = switch (fit) {
|
|
||||||
BoxFit.cover || BoxFit.fitWidth || BoxFit.fitHeight => 'cover',
|
|
||||||
BoxFit.fill => 'fill',
|
|
||||||
BoxFit.contain => 'contain',
|
|
||||||
BoxFit.none => 'none',
|
|
||||||
_ => 'cover',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,7 +4,6 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:island/pods/config.dart';
|
|
||||||
import 'package:island/pods/network.dart';
|
import 'package:island/pods/network.dart';
|
||||||
import 'package:island/widgets/alert.dart';
|
import 'package:island/widgets/alert.dart';
|
||||||
import 'package:media_kit/media_kit.dart';
|
import 'package:media_kit/media_kit.dart';
|
||||||
@ -38,18 +37,10 @@ class _UniversalVideoState extends ConsumerState<UniversalVideo> {
|
|||||||
final inCacheInfo = await DefaultCacheManager().getFileFromCache(url);
|
final inCacheInfo = await DefaultCacheManager().getFileFromCache(url);
|
||||||
if (inCacheInfo == null) {
|
if (inCacheInfo == null) {
|
||||||
log('[MediaPlayer] Miss cache: $url');
|
log('[MediaPlayer] Miss cache: $url');
|
||||||
final baseUrl = ref.watch(serverUrlProvider);
|
final token = await getToken(ref.watch(tokenProvider));
|
||||||
final atk = await getFreshAtk(
|
|
||||||
ref.watch(tokenPairProvider),
|
|
||||||
baseUrl,
|
|
||||||
onRefreshed: (atk, rtk) {
|
|
||||||
setTokenPair(ref.watch(sharedPreferencesProvider), atk, rtk);
|
|
||||||
ref.invalidate(tokenPairProvider);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
final fileStream = DefaultCacheManager().getFileStream(
|
final fileStream = DefaultCacheManager().getFileStream(
|
||||||
url,
|
url,
|
||||||
headers: {'Authorization': 'Bearer $atk'},
|
headers: {'Authorization': 'Bearer $token'},
|
||||||
withProgress: true,
|
withProgress: true,
|
||||||
);
|
);
|
||||||
await for (var fileInfo in fileStream) {
|
await for (var fileInfo in fileStream) {
|
||||||
|
@ -25,6 +25,7 @@ class PostItem extends HookConsumerWidget {
|
|||||||
final SnPost item;
|
final SnPost item;
|
||||||
final EdgeInsets? padding;
|
final EdgeInsets? padding;
|
||||||
final bool isOpenable;
|
final bool isOpenable;
|
||||||
|
final bool showReferencePost;
|
||||||
final Function? onRefresh;
|
final Function? onRefresh;
|
||||||
final Function(SnPost)? onUpdate;
|
final Function(SnPost)? onUpdate;
|
||||||
const PostItem({
|
const PostItem({
|
||||||
@ -33,6 +34,7 @@ class PostItem extends HookConsumerWidget {
|
|||||||
this.backgroundColor,
|
this.backgroundColor,
|
||||||
this.padding,
|
this.padding,
|
||||||
this.isOpenable = true,
|
this.isOpenable = true,
|
||||||
|
this.showReferencePost = true,
|
||||||
this.onRefresh,
|
this.onRefresh,
|
||||||
this.onUpdate,
|
this.onUpdate,
|
||||||
});
|
});
|
||||||
@ -101,6 +103,20 @@ class PostItem extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
MenuAction(
|
||||||
|
title: 'reply'.tr(),
|
||||||
|
image: MenuImage.icon(Symbols.reply),
|
||||||
|
callback: () {
|
||||||
|
context.router.push(PostComposeRoute(repliedPost: item));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
MenuAction(
|
||||||
|
title: 'forward'.tr(),
|
||||||
|
image: MenuImage.icon(Symbols.forward),
|
||||||
|
callback: () {
|
||||||
|
context.router.push(PostComposeRoute(forwardedPost: item));
|
||||||
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -118,7 +134,7 @@ class PostItem extends HookConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
child: ProfilePictureWidget(
|
child: ProfilePictureWidget(
|
||||||
fileId: item.publisher.pictureId,
|
fileId: item.publisher.picture?.id,
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.router.push(
|
context.router.push(
|
||||||
@ -132,8 +148,52 @@ class PostItem extends HookConsumerWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(item.publisher.nick).bold(),
|
Text(item.publisher.nick).bold(),
|
||||||
|
// Add visibility indicator if not public (visibility != 0)
|
||||||
|
if (item.visibility != 0)
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
_getVisibilityIcon(item.visibility),
|
||||||
|
size: 14,
|
||||||
|
color:
|
||||||
|
Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
Text(
|
||||||
|
_getVisibilityText(item.visibility).tr(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color:
|
||||||
|
Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).padding(top: 2, bottom: 2),
|
||||||
|
if (item.title?.isNotEmpty ?? false)
|
||||||
|
Text(
|
||||||
|
item.title!,
|
||||||
|
style: Theme.of(context).textTheme.titleMedium
|
||||||
|
?.copyWith(fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
if (item.description?.isNotEmpty ?? false)
|
||||||
|
Text(
|
||||||
|
item.description!,
|
||||||
|
style: Theme.of(
|
||||||
|
context,
|
||||||
|
).textTheme.bodyMedium?.copyWith(
|
||||||
|
color:
|
||||||
|
Theme.of(
|
||||||
|
context,
|
||||||
|
).colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
).padding(bottom: 8),
|
||||||
if (item.content?.isNotEmpty ?? false)
|
if (item.content?.isNotEmpty ?? false)
|
||||||
MarkdownTextContent(content: item.content!),
|
MarkdownTextContent(content: item.content!),
|
||||||
|
if ((item.repliedPost != null ||
|
||||||
|
item.forwardedPost != null) &&
|
||||||
|
showReferencePost)
|
||||||
|
_buildReferencePost(context, item),
|
||||||
if (item.attachments.isNotEmpty)
|
if (item.attachments.isNotEmpty)
|
||||||
CloudFileList(
|
CloudFileList(
|
||||||
files: item.attachments,
|
files: item.attachments,
|
||||||
@ -178,6 +238,141 @@ class PostItem extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildReferencePost(BuildContext context, SnPost item) {
|
||||||
|
final referencePost = item.repliedPost ?? item.forwardedPost;
|
||||||
|
if (referencePost == null) return const SizedBox.shrink();
|
||||||
|
|
||||||
|
final isReply = item.repliedPost != null;
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
margin: const EdgeInsets.only(top: 8, bottom: 8),
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.surfaceVariant.withOpacity(0.5),
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
border: Border.all(
|
||||||
|
color: Theme.of(context).colorScheme.outline.withOpacity(0.3),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
isReply ? Symbols.reply : Symbols.forward,
|
||||||
|
size: 16,
|
||||||
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 6),
|
||||||
|
Text(
|
||||||
|
isReply ? 'repliedTo'.tr() : 'forwarded'.tr(),
|
||||||
|
style: TextStyle(
|
||||||
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
fontSize: 12,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
ProfilePictureWidget(
|
||||||
|
fileId: referencePost.publisher.picture?.id,
|
||||||
|
radius: 16,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
referencePost.publisher.nick,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 14,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Add visibility indicator for referenced post if not public
|
||||||
|
if (referencePost.visibility != 0)
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
_getVisibilityIcon(referencePost.visibility),
|
||||||
|
size: 12,
|
||||||
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
Text(
|
||||||
|
_getVisibilityText(referencePost.visibility).tr(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10,
|
||||||
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).padding(top: 2, bottom: 2),
|
||||||
|
if (referencePost.title?.isNotEmpty ?? false)
|
||||||
|
Text(
|
||||||
|
referencePost.title!,
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 13,
|
||||||
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
|
),
|
||||||
|
).padding(top: 2, bottom: 2),
|
||||||
|
if (referencePost.description?.isNotEmpty ?? false)
|
||||||
|
Text(
|
||||||
|
referencePost.description!,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
).padding(bottom: 2),
|
||||||
|
if (referencePost.content?.isNotEmpty ?? false)
|
||||||
|
MarkdownTextContent(
|
||||||
|
content: referencePost.content!,
|
||||||
|
textStyle: const TextStyle(fontSize: 14),
|
||||||
|
isSelectable: false,
|
||||||
|
).padding(bottom: 4),
|
||||||
|
if (referencePost.attachments.isNotEmpty)
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Symbols.attach_file,
|
||||||
|
size: 12,
|
||||||
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
Text(
|
||||||
|
'postHasAttachments'.plural(
|
||||||
|
referencePost.attachments.length,
|
||||||
|
),
|
||||||
|
style: TextStyle(
|
||||||
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
|
fontSize: 12,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).padding(vertical: 2),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
).gestures(
|
||||||
|
onTap: () => context.router.push(PostDetailRoute(id: referencePost.id)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
class PostReactionList extends HookConsumerWidget {
|
class PostReactionList extends HookConsumerWidget {
|
||||||
final String parentId;
|
final String parentId;
|
||||||
final Map<String, int> reactions;
|
final Map<String, int> reactions;
|
||||||
@ -388,3 +583,31 @@ class _PostReactionSheet extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper method to get the appropriate icon for each visibility status
|
||||||
|
IconData _getVisibilityIcon(int visibility) {
|
||||||
|
switch (visibility) {
|
||||||
|
case 1: // Friends
|
||||||
|
return Symbols.group;
|
||||||
|
case 2: // Unlisted
|
||||||
|
return Symbols.link_off;
|
||||||
|
case 3: // Private
|
||||||
|
return Symbols.lock;
|
||||||
|
default: // Public (0) or unknown
|
||||||
|
return Symbols.public;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper method to get the translation key for each visibility status
|
||||||
|
String _getVisibilityText(int visibility) {
|
||||||
|
switch (visibility) {
|
||||||
|
case 1: // Friends
|
||||||
|
return 'postVisibilityFriends';
|
||||||
|
case 2: // Unlisted
|
||||||
|
return 'postVisibilityUnlisted';
|
||||||
|
case 3: // Private
|
||||||
|
return 'postVisibilityPrivate';
|
||||||
|
default: // Public (0) or unknown
|
||||||
|
return 'postVisibilityPublic';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -14,8 +14,6 @@ class PostListNotifier extends _$PostListNotifier
|
|||||||
with CursorPagingNotifierMixin<SnPost> {
|
with CursorPagingNotifierMixin<SnPost> {
|
||||||
static const int _pageSize = 20;
|
static const int _pageSize = 20;
|
||||||
|
|
||||||
String? pubName;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<CursorPagingData<SnPost>> build(String? pubName) {
|
Future<CursorPagingData<SnPost>> build(String? pubName) {
|
||||||
this.pubName = pubName;
|
this.pubName = pubName;
|
||||||
|
@ -6,7 +6,7 @@ part of 'post_list.dart';
|
|||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$postListNotifierHash() => r'6568b7a5afad71551009d9bc7af26afb4b07c9e5';
|
String _$postListNotifierHash() => r'58a2d5d9a8f742f0a3a3e224a51a811d43903e0d';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
|
@ -65,7 +65,7 @@ class PostQuickReply extends HookConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
child: ProfilePictureWidget(
|
child: ProfilePictureWidget(
|
||||||
fileId: currentPublisher.value?.pictureId,
|
fileId: currentPublisher.value?.picture?.id,
|
||||||
radius: 16,
|
radius: 16,
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
@ -94,6 +94,7 @@ class PostRepliesList extends HookConsumerWidget {
|
|||||||
PostItem(
|
PostItem(
|
||||||
item: data.items[index],
|
item: data.items[index],
|
||||||
backgroundColor: isWide ? Colors.transparent : null,
|
backgroundColor: isWide ? Colors.transparent : null,
|
||||||
|
showReferencePost: false,
|
||||||
),
|
),
|
||||||
const Divider(height: 1),
|
const Divider(height: 1),
|
||||||
],
|
],
|
||||||
|
@ -49,7 +49,7 @@ class RealmSelectionDropdown extends StatelessWidget {
|
|||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
ProfilePictureWidget(
|
ProfilePictureWidget(
|
||||||
fileId: realm.pictureId,
|
fileId: realm.picture?.id,
|
||||||
fallbackIcon: Symbols.workspaces,
|
fallbackIcon: Symbols.workspaces,
|
||||||
radius: 16,
|
radius: 16,
|
||||||
),
|
),
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:dio/dio.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
@ -7,11 +8,8 @@ import 'package:styled_widget/styled_widget.dart';
|
|||||||
class ResponseErrorWidget extends StatelessWidget {
|
class ResponseErrorWidget extends StatelessWidget {
|
||||||
final dynamic error;
|
final dynamic error;
|
||||||
final VoidCallback onRetry;
|
final VoidCallback onRetry;
|
||||||
const ResponseErrorWidget({
|
|
||||||
super.key,
|
const ResponseErrorWidget({super.key, required this.error, required this.onRetry});
|
||||||
required this.error,
|
|
||||||
required this.onRetry,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -20,14 +18,33 @@ class ResponseErrorWidget extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
const Icon(Symbols.error_outline, size: 48),
|
const Icon(Symbols.error_outline, size: 48),
|
||||||
const Gap(4),
|
const Gap(4),
|
||||||
ConstrainedBox(
|
if (error is DioException && error.response?.statusCode == 401)
|
||||||
constraints: const BoxConstraints(maxWidth: 320),
|
ConstrainedBox(
|
||||||
child: Text(
|
constraints: const BoxConstraints(maxWidth: 320),
|
||||||
error.toString(),
|
child: Column(
|
||||||
textAlign: TextAlign.center,
|
children: [
|
||||||
style: const TextStyle(color: Color(0xFF757575)),
|
Text(
|
||||||
),
|
'unauthorized'.tr(),
|
||||||
).center(),
|
textAlign: TextAlign.center,
|
||||||
|
style: const TextStyle(color: Color(0xFF757575)),
|
||||||
|
).bold(),
|
||||||
|
Text(
|
||||||
|
'unauthorizedHint'.tr(),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: const TextStyle(color: Color(0xFF757575)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
).center()
|
||||||
|
else
|
||||||
|
ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints(maxWidth: 320),
|
||||||
|
child: Text(
|
||||||
|
error.toString(),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: const TextStyle(color: Color(0xFF757575)),
|
||||||
|
),
|
||||||
|
).center(),
|
||||||
const Gap(8),
|
const Gap(8),
|
||||||
TextButton(onPressed: onRetry, child: const Text('retry').tr()),
|
TextButton(onPressed: onRetry, child: const Text('retry').tr()),
|
||||||
],
|
],
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
#include <irondash_engine_context/irondash_engine_context_plugin.h>
|
#include <irondash_engine_context/irondash_engine_context_plugin.h>
|
||||||
#include <media_kit_libs_linux/media_kit_libs_linux_plugin.h>
|
#include <media_kit_libs_linux/media_kit_libs_linux_plugin.h>
|
||||||
#include <media_kit_video/media_kit_video_plugin.h>
|
#include <media_kit_video/media_kit_video_plugin.h>
|
||||||
|
#include <pasteboard/pasteboard_plugin.h>
|
||||||
|
#include <record_linux/record_linux_plugin.h>
|
||||||
#include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h>
|
#include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h>
|
||||||
#include <super_native_extensions/super_native_extensions_plugin.h>
|
#include <super_native_extensions/super_native_extensions_plugin.h>
|
||||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||||
@ -44,6 +46,12 @@ void fl_register_plugins(FlPluginRegistry* registry) {
|
|||||||
g_autoptr(FlPluginRegistrar) media_kit_video_registrar =
|
g_autoptr(FlPluginRegistrar) media_kit_video_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "MediaKitVideoPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "MediaKitVideoPlugin");
|
||||||
media_kit_video_plugin_register_with_registrar(media_kit_video_registrar);
|
media_kit_video_plugin_register_with_registrar(media_kit_video_registrar);
|
||||||
|
g_autoptr(FlPluginRegistrar) pasteboard_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "PasteboardPlugin");
|
||||||
|
pasteboard_plugin_register_with_registrar(pasteboard_registrar);
|
||||||
|
g_autoptr(FlPluginRegistrar) record_linux_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "RecordLinuxPlugin");
|
||||||
|
record_linux_plugin_register_with_registrar(record_linux_registrar);
|
||||||
g_autoptr(FlPluginRegistrar) sqlite3_flutter_libs_registrar =
|
g_autoptr(FlPluginRegistrar) sqlite3_flutter_libs_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "Sqlite3FlutterLibsPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "Sqlite3FlutterLibsPlugin");
|
||||||
sqlite3_flutter_libs_plugin_register_with_registrar(sqlite3_flutter_libs_registrar);
|
sqlite3_flutter_libs_plugin_register_with_registrar(sqlite3_flutter_libs_registrar);
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user