Compare commits

...

42 Commits

Author SHA1 Message Date
c003f27b9a ⬆️ Upgrade cocoapods 2025-10-26 02:28:46 +08:00
19db8309c4 🌐 Localize the new feature: thinking 2025-10-26 01:46:49 +08:00
aa72ce08e8 🐛 Fix think sticky issue 2025-10-26 00:24:03 +08:00
4639b00b86 🐛 Fix AI topic won't be set 2025-10-26 00:15:21 +08:00
cc5460ea55 🐛 Fix thought seq id didn't update 2025-10-25 23:40:54 +08:00
eafac811e6 💄 Optimize thought sequence list 2025-10-25 23:37:17 +08:00
e3be691596 💄 Optimize the AI thought 2025-10-25 23:20:10 +08:00
aa180a1358 Ai thought basis 2025-10-25 23:01:32 +08:00
c2707b8af1 ♻️ Re-designed bottom nav 2025-10-25 21:50:43 +08:00
62fd0500f3 💄 Fix card transparency 2025-10-25 01:09:34 +08:00
eeae865cc8 💄 Optimize lotteries 2025-10-25 00:29:36 +08:00
cdf1413fe0 Lotteries 2025-10-25 00:18:08 +08:00
327b4c04f1 Message detail (action sheet) shows full sent at date 2025-10-24 00:50:51 +08:00
bd903ce29c 💄 Change realm bottom nav icon 2025-10-24 00:46:30 +08:00
1b8ecb15ce Post featured history 2025-10-24 00:45:34 +08:00
d4e380a97a ♻️ Moved the pinned to the metadata 2025-10-23 01:32:38 +08:00
126048b4fa 💄 Optimize post metadata 2025-10-23 01:27:40 +08:00
8bec18813d 💄 Optimize publisher name display 2025-10-23 00:38:37 +08:00
1ae81794b1 💥 Updated API routes 2025-10-22 22:51:51 +08:00
2a7d12de48 🐛 Fix bugs 2025-10-20 23:48:24 +08:00
64c60ead48 ⬆️ Upgrade deps 2025-10-20 23:40:30 +08:00
001549b190 💄 Fix notification bottom sheet covered with sheet 2025-10-15 22:55:37 +08:00
4595865ad3 🐛 Bug fixes on windows 2025-10-15 22:49:43 +08:00
LittleSheep
1834643167 🔀 Merge pull request #184 from Texas0295/v3
[FIX] linux: restrict setAsFrameless to Wayland only
2025-10-15 20:05:40 +08:00
Texas0295
0e816eaa3e [FIX] wayland: restrict setAsFrameless to Wayland only
Prevent unconditional frameless calls on non-Wayland platforms.

Signed-off-by: Texas0295 <kimura@texas0295.top>
2025-10-15 02:24:40 +08:00
LittleSheep
7c1f24b824 🔀 Merge pull request #183 from Texas0295/v3
[FIX] linux: correct Wayland window buffer mismatch by setAsFreameless()
2025-10-15 00:47:58 +08:00
c6594ea2ce 🚀 Launch 3.3.0+136 2025-10-15 00:46:34 +08:00
3bec6e683e 🐛 Fix chat input not enter to send 2025-10-15 00:42:26 +08:00
83e92e2eed Show heatmap on pub profile 2025-10-15 00:27:32 +08:00
Texas0295
b7d44d96ba [FIX] linux: correct Wayland window buffer mismatch by setAsFreameless()
Wayland (Hyprland, Sway, etc.) compositors misreport window buffer geometry
when using transparent + hidden titlebar settings.

This causes Flutter to render outside the actual visible region
and the debug banner to be cropped offscreen.

Calling windowManager.setAsFrameless() once after window creation
forces compositor to reconfigure the surface and align buffer size
with the visible client area.

No effect on X11, Windows, or macOS.

Signed-off-by: Texas0295 <kimura@texas0295.top>
2025-10-15 00:06:03 +08:00
a83b929d42 ♻️ Convert the notification to sheet 2025-10-14 23:44:07 +08:00
9423affa75 🐛 Fix bugs 2025-10-14 23:01:40 +08:00
cda23db609 🐛 Make the background image not responsive for virtual keyboard to provide better visual experience on iOS 26 2025-10-14 22:53:59 +08:00
61074bc5a3 🐛 Fix compose dialog 2025-10-14 22:53:38 +08:00
5feafa9255 💄 Optimize quick reply input again... 2025-10-14 22:48:34 +08:00
e604577c1f 💄 Optimize quick reply input 2025-10-14 22:27:51 +08:00
af0ddd1273 💄 Optimize and bug fixes in auto complete 2025-10-14 22:26:06 +08:00
8a6bb34808 🔨 Fix android build 2025-10-14 01:39:59 +08:00
4ef8445c77 ⬆️ Upgrade the dependcenies 2025-10-14 01:38:16 +08:00
ec39ad6ca3 💄 Optimizations 2025-10-14 01:37:54 +08:00
eabb3154f1 💄 Optimize card colors 2025-10-14 01:16:02 +08:00
910bf20eef 🐛 Fix mobile haven't enter to submit 2025-10-13 01:48:30 +08:00
100 changed files with 5102 additions and 898 deletions

View File

@@ -25,8 +25,13 @@ android {
compileOptions {
isCoreLibraryDesugaringEnabled = true
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions { jvmTarget = JavaVersion.VERSION_17.toString() }
defaultConfig {
applicationId = "dev.solsynth.solian"
// You can update the following values to match your application needs.
@@ -71,16 +76,3 @@ flutter {
source = "../.."
}
kotlin {
compilerOptions {
jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_21)
}
jvmToolchain(21)
}
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(21))
}
}

View File

@@ -871,6 +871,7 @@
"pollShortTextAnswerPreview": "Short text answer (preview)",
"award": "Award",
"awardPost": "Award Post",
"awardPoints": "Awarded {} points",
"awardMessage": "Message",
"awardMessageHint": "Enter your award message...",
"awardAttitude": "Attitude",
@@ -1252,5 +1253,51 @@
"availableWithYourPlan": "Available with your plan",
"upgradeRequired": "Upgrade required",
"settingsDisableAnimation": "Disable Animation",
"addTag": "Add Tag"
"addTag": "Add Tag",
"postFeaturedIn": "Post featured on {}",
"messageSentAt": "Sent at {}",
"myTickets": "My Tickets",
"drawHistory": "Draw History",
"lottery": "Lottery",
"noLotteryTickets": "No lottery tickets yet",
"buyYourFirstTicket": "Buy your first lottery ticket to get started!",
"buyTicket": "Buy Ticket",
"ticketNumbers": "Numbers: {}, Special: {}",
"cost": "Cost",
"multiplier": "Multiplier",
"prizeWon": "Prize Won",
"pending": "Pending",
"drawn": "Drawn",
"won": "Won",
"lost": "Lost",
"noDrawHistory": "No draw history yet",
"buyLotteryTicket": "Buy Lottery Ticket",
"selectNumbers": "Select Numbers",
"select5UniqueNumbers": "Select 5 unique numbers",
"selectSpecialNumber": "Select Special Number",
"selectMultiplier": "Select Multiplier",
"baseCost": "Base Cost",
"totalCost": "Total Cost",
"prizeStructure": "Prize Structure",
"enterPinToConfirmPurchase": "Enter your PIN to confirm purchase",
"ticketPurchasedSuccessfully": "Ticket purchased successfully!",
"winningNumbers": "Winning Numbers",
"specialNumber": "Special Number",
"totalTickets": "Total Tickets",
"totalWinners": "Total Winners",
"prizePool": "Prize Pool",
"enterPinToConfirmPayment": "Enter your PIN code to confirm payment",
"purchase": "Purchase",
"multiplierLabel": "Multiplier",
"specialOnly": "Special Only",
"matches": "Matches",
"thoughtDefaultTopic": "Reflection",
"thoughtAiName": "SN-chan",
"thoughtUserName": "You",
"thoughtStreamingHint": "Sn-chan is thinking...",
"thoughtInputHint": "Ask sn-chan anything...",
"thoughtNewConversation": "Start New Conversation",
"thoughtParseError": "Failed to parse AI response",
"aiThought": "AI Thought",
"aiThoughtTitle": "Let sn-chan think"
}

View File

@@ -1081,5 +1081,14 @@
"postPublish": "发布帖子",
"restoreDraftTitle": "恢复草稿",
"restoreDraftMessage": "发现了一个草稿。你想要恢复它吗?",
"draft": "草稿"
"draft": "草稿",
"thoughtDefaultTopic": "寻思",
"thoughtAiName": "SN 酱",
"thoughtUserName": "您",
"thoughtStreamingHint": "Sn-chan 正在思考...",
"thoughtInputHint": "问 sn-chan 任何问题...",
"thoughtNewConversation": "开始新对话",
"thoughtParseError": "解析 AI 响应失败",
"aiThought": "寻思",
"aiThoughtTitle": "让 SN 酱寻思寻思"
}

View File

@@ -44,83 +44,83 @@ PODS:
- Flutter
- file_saver (0.0.1):
- Flutter
- Firebase/CoreOnly (12.2.0):
- FirebaseCore (~> 12.2.0)
- Firebase/Crashlytics (12.2.0):
- Firebase/CoreOnly (12.4.0):
- FirebaseCore (~> 12.4.0)
- Firebase/Crashlytics (12.4.0):
- Firebase/CoreOnly
- FirebaseCrashlytics (~> 12.2.0)
- Firebase/Messaging (12.2.0):
- FirebaseCrashlytics (~> 12.4.0)
- Firebase/Messaging (12.4.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 12.2.0)
- firebase_analytics (12.0.2):
- FirebaseMessaging (~> 12.4.0)
- firebase_analytics (12.0.3):
- firebase_core
- FirebaseAnalytics (= 12.2.0)
- FirebaseAnalytics (= 12.4.0)
- Flutter
- firebase_core (4.1.1):
- Firebase/CoreOnly (= 12.2.0)
- firebase_core (4.2.0):
- Firebase/CoreOnly (= 12.4.0)
- Flutter
- firebase_crashlytics (5.0.2):
- Firebase/Crashlytics (= 12.2.0)
- firebase_crashlytics (5.0.3):
- Firebase/Crashlytics (= 12.4.0)
- firebase_core
- Flutter
- firebase_messaging (16.0.2):
- Firebase/Messaging (= 12.2.0)
- firebase_messaging (16.0.3):
- Firebase/Messaging (= 12.4.0)
- firebase_core
- Flutter
- FirebaseAnalytics (12.2.0):
- FirebaseAnalytics/Default (= 12.2.0)
- FirebaseCore (~> 12.2.0)
- FirebaseInstallations (~> 12.2.0)
- FirebaseAnalytics (12.4.0):
- FirebaseAnalytics/Default (= 12.4.0)
- FirebaseCore (~> 12.4.0)
- FirebaseInstallations (~> 12.4.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- FirebaseAnalytics/Default (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseInstallations (~> 12.2.0)
- GoogleAppMeasurement/Default (= 12.2.0)
- FirebaseAnalytics/Default (12.4.0):
- FirebaseCore (~> 12.4.0)
- FirebaseInstallations (~> 12.4.0)
- GoogleAppMeasurement/Default (= 12.4.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- FirebaseCore (12.2.0):
- FirebaseCoreInternal (~> 12.2.0)
- FirebaseCore (12.4.0):
- FirebaseCoreInternal (~> 12.4.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/Logger (~> 8.1)
- FirebaseCoreExtension (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseCoreInternal (12.2.0):
- FirebaseCoreExtension (12.4.0):
- FirebaseCore (~> 12.4.0)
- FirebaseCoreInternal (12.4.0):
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- FirebaseCrashlytics (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseInstallations (~> 12.2.0)
- FirebaseRemoteConfigInterop (~> 12.2.0)
- FirebaseSessions (~> 12.2.0)
- FirebaseCrashlytics (12.4.0):
- FirebaseCore (~> 12.4.0)
- FirebaseInstallations (~> 12.4.0)
- FirebaseRemoteConfigInterop (~> 12.4.0)
- FirebaseSessions (~> 12.4.0)
- GoogleDataTransport (~> 10.1)
- GoogleUtilities/Environment (~> 8.1)
- nanopb (~> 3.30910.0)
- PromisesObjC (~> 2.4)
- FirebaseInstallations (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseInstallations (12.4.0):
- FirebaseCore (~> 12.4.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
- PromisesObjC (~> 2.4)
- FirebaseMessaging (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseInstallations (~> 12.2.0)
- FirebaseMessaging (12.4.0):
- FirebaseCore (~> 12.4.0)
- FirebaseInstallations (~> 12.4.0)
- GoogleDataTransport (~> 10.1)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/Reachability (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
- nanopb (~> 3.30910.0)
- FirebaseRemoteConfigInterop (12.2.0)
- FirebaseSessions (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseCoreExtension (~> 12.2.0)
- FirebaseInstallations (~> 12.2.0)
- FirebaseRemoteConfigInterop (12.4.0)
- FirebaseSessions (12.4.0):
- FirebaseCore (~> 12.4.0)
- FirebaseCoreExtension (~> 12.4.0)
- FirebaseInstallations (~> 12.4.0)
- GoogleDataTransport (~> 10.1)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
@@ -157,27 +157,28 @@ PODS:
- gal (1.0.0):
- Flutter
- FlutterMacOS
- GoogleAdsOnDeviceConversion (2.3.0):
- GoogleAdsOnDeviceConversion (3.1.0):
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/Logger (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- nanopb (~> 3.30910.0)
- GoogleAppMeasurement/Core (12.2.0):
- GoogleAppMeasurement/Core (12.4.0):
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- GoogleAppMeasurement/Default (12.2.0):
- GoogleAdsOnDeviceConversion (= 2.3.0)
- GoogleAppMeasurement/Core (= 12.2.0)
- GoogleAppMeasurement/IdentitySupport (= 12.2.0)
- GoogleAppMeasurement/Default (12.4.0):
- GoogleAdsOnDeviceConversion (~> 3.1.0)
- GoogleAppMeasurement/Core (= 12.4.0)
- GoogleAppMeasurement/IdentitySupport (= 12.4.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- GoogleAppMeasurement/IdentitySupport (12.2.0):
- GoogleAppMeasurement/Core (= 12.2.0)
- GoogleAppMeasurement/IdentitySupport (12.4.0):
- GoogleAppMeasurement/Core (= 12.4.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
@@ -218,7 +219,7 @@ PODS:
- irondash_engine_context (0.0.1):
- Flutter
- Kingfisher (8.6.0)
- livekit_client (2.5.0):
- livekit_client (2.5.3):
- Flutter
- flutter_webrtc
- WebRTC-SDK (= 137.7151.04)
@@ -486,20 +487,20 @@ SPEC CHECKSUMS:
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be
file_saver: 6cdbcddd690cb02b0c1a0c225b37cd805c2bf8b6
Firebase: 26f6f8d460603af3df970ad505b16b15f5e2e9a1
firebase_analytics: 8c78ce6224e0623152379d6cc7ef3d9098477b7e
firebase_core: dfc4bd142bee4bc53a5d482397ca322c2dd3165d
firebase_crashlytics: e55dcf895eed0dd87c447dd5aff8db7f1bb8bbdb
firebase_messaging: 38c66c1184695b0c87abe51d40fc590718abed1a
FirebaseAnalytics: e04e23bc070e3014aa5cf4980f9df7ce5cd79ec8
FirebaseCore: 311c48a147ad4a0ab7febbaed89e8025c67510cd
FirebaseCoreExtension: 73af080c22a2f7b44cefa391dc08f7e4ee162cb5
FirebaseCoreInternal: 56ea29f3dad2894f81b060f706f9d53509b6ed3b
FirebaseCrashlytics: f83cbf176d5c637ade108c0aacf1ccbd5ec499bf
FirebaseInstallations: 3e884b01feabdf67582a80f3250425a00979b4ed
FirebaseMessaging: 43ec73bbfedd0c385a849bb91593ab4ad4b9e48e
FirebaseRemoteConfigInterop: 0896fd52ab72586a355c8f389ff85aaa9e5375e1
FirebaseSessions: f4692789e770bec66ce17d772c0e9561c4f11737
Firebase: f07b15ae5a6ec0f93713e30b923d9970d144af3e
firebase_analytics: 1d024068b1d4707d5ba7a42a12976ddf3316d835
firebase_core: 744984dbbed8b3036abf34f0b98d80f130a7e464
firebase_crashlytics: f3a9a4338ab99b67042f64e9e22e1bf349cb44ed
firebase_messaging: 82c70650c426a0a14873e1acdb9ec2b443c4e8b4
FirebaseAnalytics: 0fc2b20091f0ddd21bf73397cf8f0eb5346dc24f
FirebaseCore: bb595f3114953664e3c1dc032f008a244147cfd3
FirebaseCoreExtension: 7e1f7118ee970e001a8013719fb90950ee5e0018
FirebaseCoreInternal: d7f5a043c2cd01a08103ab586587c1468047bca6
FirebaseCrashlytics: a6ece278a837c7e88de2d9b5da0a3542f2342395
FirebaseInstallations: ae9f4902cb5bf1d0c5eaa31ec1f4e5495a0714e2
FirebaseMessaging: d33971b7bb252745ea6cd31ab190d1a1df4b8ed5
FirebaseRemoteConfigInterop: 1e31ec72b89c9924367c59bfb5ec9ab60d1d6766
FirebaseSessions: ba7c7a7ca8696a8d540eb3fe3800fbe98c79786d
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
flutter_app_update: 816fdb2e30e4832a7c45e3f108d391c42ef040a9
flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
@@ -512,14 +513,14 @@ SPEC CHECKSUMS:
flutter_udid: f7c3884e6ec2951efe4f9de082257fc77c4d15e9
flutter_webrtc: c3e21fc0dcd9d8eb246ae4d5256fcbeb2f5ecd22
gal: baecd024ebfd13c441269ca7404792a7152fde89
GoogleAdsOnDeviceConversion: 9090c435cde08903e8dd1ba2c77fbec9e46d9afe
GoogleAppMeasurement: 09f341dfa8527d1612a09cbfe809a242c0b737af
GoogleAdsOnDeviceConversion: e03a386840803ea7eef3fd22a061930142c039c1
GoogleAppMeasurement: 1e718274b7e015cefd846ac1fcf7820c70dc017d
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
image_picker_ios: e0ece4aa2a75771a7de3fa735d26d90817041326
irondash_engine_context: 8e58ca8e0212ee9d1c7dc6a42121849986c88486
Kingfisher: 64278f126a815d0e2d391cdf71311b85882c4de0
livekit_client: a6f5fa86ac28ccd7ded53626a5379961db311ab4
livekit_client: 86c8af579274e4b7a215185a8080db2d4e176f40
local_auth_darwin: c3ee6cce0a8d56be34c8ccb66ba31f7f180aaebb
media_kit_libs_ios_video: 5a18affdb97d1f5d466dc79988b13eff6c5e2854
media_kit_video: 1746e198cb697d1ffb734b1d05ec429d1fcd1474
@@ -528,8 +529,8 @@ SPEC CHECKSUMS:
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
pasteboard: 49088aeb6119d51f976a421db60d8e1ab079b63c
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
pointer_interceptor_ios: ec847ef8b0915778bed2b2cef636f4d177fa8eed
path_provider_foundation: bb55f6dbba17d0dccd6737fe6f7f34fbd0376880
pointer_interceptor_ios: da06a662d5bfd329602b45b2ab41bc0fb5fdb0f0
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851
receive_sharing_intent: 222384f00ffe7e952bbfabaa9e3967cb87e5fe00
@@ -537,7 +538,7 @@ SPEC CHECKSUMS:
SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c
SDWebImage: 16309af6d214ba3f77a7c6f6fdda888cb313a50a
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb
sign_in_with_apple: c5dcc141574c8c54d5ac99dd2163c0c72ad22418
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
sqlite3: 73513155ec6979715d3904ef53a8d68892d4032b
@@ -545,7 +546,7 @@ SPEC CHECKSUMS:
super_native_extensions: b763c02dc3a8fd078389f410bf15149179020cb4
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
syncfusion_flutter_pdfviewer: 90dc48305d2e33d4aa20681d1e98ddeda891bc14
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b
volume_controller: 3657a1f65bedb98fa41ff7dc5793537919f31b12
wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556
WebRTC-SDK: 40d4f5ba05cadff14e4db5614aec402a633f007e

View File

@@ -120,13 +120,24 @@ void main() async {
windowButtonVisibility: true,
);
windowManager.waitUntilReadyToShow(windowOptions, () async {
final env = Platform.environment;
final isWayland = env.containsKey('WAYLAND_DISPLAY');
if (isWayland) {
try {
await windowManager.setAsFrameless();
} catch (e) {
debugPrint('[Wayland] setAsFrameless failed: $e');
}
}
await windowManager.setMinimumSize(defaultSize);
await windowManager.show();
await windowManager.focus();
final opacity = prefs.getDouble(kAppWindowOpacity) ?? 1.0;
await windowManager.setOpacity(opacity);
talker.info(
"[SplashScreen] Desktop window is ready with size: ${initialSize.width}x${initialSize.height}",
"[SplashScreen] Desktop window is ready with size: ${initialSize.width}x${initialSize.height}"
"${isWayland ? " (Wayland frameless fix applied)" : ""}",
);
});
}

View File

@@ -47,6 +47,7 @@ sealed class SnPost with _$SnPost {
@Default([]) List<SnPostTag> tags,
@Default([]) List<SnPostCategory> categories,
@Default([]) List<dynamic> collections,
@Default([]) List<SnPostFeaturedRecord> featuredRecords,
@Default(null) DateTime? createdAt,
@Default(null) DateTime? updatedAt,
DateTime? deletedAt,
@@ -161,3 +162,19 @@ sealed class SnPostReaction with _$SnPostReaction {
factory SnPostReaction.fromJson(Map<String, dynamic> json) =>
_$SnPostReactionFromJson(json);
}
@freezed
sealed class SnPostFeaturedRecord with _$SnPostFeaturedRecord {
const factory SnPostFeaturedRecord({
required String id,
required String postId,
required DateTime? featuredAt,
required int socialCredits,
required DateTime createdAt,
required DateTime updatedAt,
required DateTime? deletedAt,
}) = _SnPostFeaturedRecord;
factory SnPostFeaturedRecord.fromJson(Map<String, dynamic> json) =>
_$SnPostFeaturedRecordFromJson(json);
}

View File

@@ -15,7 +15,7 @@ T _$identity<T>(T value) => value;
/// @nodoc
mixin _$SnPost {
String get id; String? get title; String? get description; String? get language; DateTime? get editedAt; DateTime? get publishedAt; int get visibility; String? get content; String? get slug; int get type; Map<String, dynamic>? get meta; SnPostEmbedView? get embedView; int get viewsUnique; int get viewsTotal; int get upvotes; int get downvotes; int get repliesCount; int get awardedScore; int? get pinMode; String? get threadedPostId; SnPost? get threadedPost; String? get repliedPostId; SnPost? get repliedPost; String? get forwardedPostId; SnPost? get forwardedPost; String? get realmId; SnRealm? get realm; List<SnCloudFile> get attachments; SnPublisher get publisher; Map<String, int> get reactionsCount; Map<String, bool> get reactionsMade; List<dynamic> get reactions; List<SnPostTag> get tags; List<SnPostCategory> get categories; List<dynamic> get collections; DateTime? get createdAt; DateTime? get updatedAt; DateTime? get deletedAt; bool get isTruncated;
String get id; String? get title; String? get description; String? get language; DateTime? get editedAt; DateTime? get publishedAt; int get visibility; String? get content; String? get slug; int get type; Map<String, dynamic>? get meta; SnPostEmbedView? get embedView; int get viewsUnique; int get viewsTotal; int get upvotes; int get downvotes; int get repliesCount; int get awardedScore; int? get pinMode; String? get threadedPostId; SnPost? get threadedPost; String? get repliedPostId; SnPost? get repliedPost; String? get forwardedPostId; SnPost? get forwardedPost; String? get realmId; SnRealm? get realm; List<SnCloudFile> get attachments; SnPublisher get publisher; Map<String, int> get reactionsCount; Map<String, bool> get reactionsMade; List<dynamic> get reactions; List<SnPostTag> get tags; List<SnPostCategory> get categories; List<dynamic> get collections; List<SnPostFeaturedRecord> get featuredRecords; DateTime? get createdAt; DateTime? get updatedAt; DateTime? get deletedAt; bool get isTruncated;
/// Create a copy of SnPost
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -28,16 +28,16 @@ $SnPostCopyWith<SnPost> get copyWith => _$SnPostCopyWithImpl<SnPost>(this as SnP
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPost&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.language, language) || other.language == language)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.visibility, visibility) || other.visibility == visibility)&&(identical(other.content, content) || other.content == content)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other.meta, meta)&&(identical(other.embedView, embedView) || other.embedView == embedView)&&(identical(other.viewsUnique, viewsUnique) || other.viewsUnique == viewsUnique)&&(identical(other.viewsTotal, viewsTotal) || other.viewsTotal == viewsTotal)&&(identical(other.upvotes, upvotes) || other.upvotes == upvotes)&&(identical(other.downvotes, downvotes) || other.downvotes == downvotes)&&(identical(other.repliesCount, repliesCount) || other.repliesCount == repliesCount)&&(identical(other.awardedScore, awardedScore) || other.awardedScore == awardedScore)&&(identical(other.pinMode, pinMode) || other.pinMode == pinMode)&&(identical(other.threadedPostId, threadedPostId) || other.threadedPostId == threadedPostId)&&(identical(other.threadedPost, threadedPost) || other.threadedPost == threadedPost)&&(identical(other.repliedPostId, repliedPostId) || other.repliedPostId == repliedPostId)&&(identical(other.repliedPost, repliedPost) || other.repliedPost == repliedPost)&&(identical(other.forwardedPostId, forwardedPostId) || other.forwardedPostId == forwardedPostId)&&(identical(other.forwardedPost, forwardedPost) || other.forwardedPost == forwardedPost)&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&const DeepCollectionEquality().equals(other.attachments, attachments)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&const DeepCollectionEquality().equals(other.reactionsCount, reactionsCount)&&const DeepCollectionEquality().equals(other.reactionsMade, reactionsMade)&&const DeepCollectionEquality().equals(other.reactions, reactions)&&const DeepCollectionEquality().equals(other.tags, tags)&&const DeepCollectionEquality().equals(other.categories, categories)&&const DeepCollectionEquality().equals(other.collections, collections)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.isTruncated, isTruncated) || other.isTruncated == isTruncated));
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPost&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.language, language) || other.language == language)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.visibility, visibility) || other.visibility == visibility)&&(identical(other.content, content) || other.content == content)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other.meta, meta)&&(identical(other.embedView, embedView) || other.embedView == embedView)&&(identical(other.viewsUnique, viewsUnique) || other.viewsUnique == viewsUnique)&&(identical(other.viewsTotal, viewsTotal) || other.viewsTotal == viewsTotal)&&(identical(other.upvotes, upvotes) || other.upvotes == upvotes)&&(identical(other.downvotes, downvotes) || other.downvotes == downvotes)&&(identical(other.repliesCount, repliesCount) || other.repliesCount == repliesCount)&&(identical(other.awardedScore, awardedScore) || other.awardedScore == awardedScore)&&(identical(other.pinMode, pinMode) || other.pinMode == pinMode)&&(identical(other.threadedPostId, threadedPostId) || other.threadedPostId == threadedPostId)&&(identical(other.threadedPost, threadedPost) || other.threadedPost == threadedPost)&&(identical(other.repliedPostId, repliedPostId) || other.repliedPostId == repliedPostId)&&(identical(other.repliedPost, repliedPost) || other.repliedPost == repliedPost)&&(identical(other.forwardedPostId, forwardedPostId) || other.forwardedPostId == forwardedPostId)&&(identical(other.forwardedPost, forwardedPost) || other.forwardedPost == forwardedPost)&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&const DeepCollectionEquality().equals(other.attachments, attachments)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&const DeepCollectionEquality().equals(other.reactionsCount, reactionsCount)&&const DeepCollectionEquality().equals(other.reactionsMade, reactionsMade)&&const DeepCollectionEquality().equals(other.reactions, reactions)&&const DeepCollectionEquality().equals(other.tags, tags)&&const DeepCollectionEquality().equals(other.categories, categories)&&const DeepCollectionEquality().equals(other.collections, collections)&&const DeepCollectionEquality().equals(other.featuredRecords, featuredRecords)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.isTruncated, isTruncated) || other.isTruncated == isTruncated));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hashAll([runtimeType,id,title,description,language,editedAt,publishedAt,visibility,content,slug,type,const DeepCollectionEquality().hash(meta),embedView,viewsUnique,viewsTotal,upvotes,downvotes,repliesCount,awardedScore,pinMode,threadedPostId,threadedPost,repliedPostId,repliedPost,forwardedPostId,forwardedPost,realmId,realm,const DeepCollectionEquality().hash(attachments),publisher,const DeepCollectionEquality().hash(reactionsCount),const DeepCollectionEquality().hash(reactionsMade),const DeepCollectionEquality().hash(reactions),const DeepCollectionEquality().hash(tags),const DeepCollectionEquality().hash(categories),const DeepCollectionEquality().hash(collections),createdAt,updatedAt,deletedAt,isTruncated]);
int get hashCode => Object.hashAll([runtimeType,id,title,description,language,editedAt,publishedAt,visibility,content,slug,type,const DeepCollectionEquality().hash(meta),embedView,viewsUnique,viewsTotal,upvotes,downvotes,repliesCount,awardedScore,pinMode,threadedPostId,threadedPost,repliedPostId,repliedPost,forwardedPostId,forwardedPost,realmId,realm,const DeepCollectionEquality().hash(attachments),publisher,const DeepCollectionEquality().hash(reactionsCount),const DeepCollectionEquality().hash(reactionsMade),const DeepCollectionEquality().hash(reactions),const DeepCollectionEquality().hash(tags),const DeepCollectionEquality().hash(categories),const DeepCollectionEquality().hash(collections),const DeepCollectionEquality().hash(featuredRecords),createdAt,updatedAt,deletedAt,isTruncated]);
@override
String toString() {
return 'SnPost(id: $id, title: $title, description: $description, language: $language, editedAt: $editedAt, publishedAt: $publishedAt, visibility: $visibility, content: $content, slug: $slug, type: $type, meta: $meta, embedView: $embedView, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, repliesCount: $repliesCount, awardedScore: $awardedScore, pinMode: $pinMode, threadedPostId: $threadedPostId, threadedPost: $threadedPost, repliedPostId: $repliedPostId, repliedPost: $repliedPost, forwardedPostId: $forwardedPostId, forwardedPost: $forwardedPost, realmId: $realmId, realm: $realm, attachments: $attachments, publisher: $publisher, reactionsCount: $reactionsCount, reactionsMade: $reactionsMade, reactions: $reactions, tags: $tags, categories: $categories, collections: $collections, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, isTruncated: $isTruncated)';
return 'SnPost(id: $id, title: $title, description: $description, language: $language, editedAt: $editedAt, publishedAt: $publishedAt, visibility: $visibility, content: $content, slug: $slug, type: $type, meta: $meta, embedView: $embedView, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, repliesCount: $repliesCount, awardedScore: $awardedScore, pinMode: $pinMode, threadedPostId: $threadedPostId, threadedPost: $threadedPost, repliedPostId: $repliedPostId, repliedPost: $repliedPost, forwardedPostId: $forwardedPostId, forwardedPost: $forwardedPost, realmId: $realmId, realm: $realm, attachments: $attachments, publisher: $publisher, reactionsCount: $reactionsCount, reactionsMade: $reactionsMade, reactions: $reactions, tags: $tags, categories: $categories, collections: $collections, featuredRecords: $featuredRecords, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, isTruncated: $isTruncated)';
}
@@ -48,7 +48,7 @@ abstract mixin class $SnPostCopyWith<$Res> {
factory $SnPostCopyWith(SnPost value, $Res Function(SnPost) _then) = _$SnPostCopyWithImpl;
@useResult
$Res call({
String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated
String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, List<SnPostFeaturedRecord> featuredRecords, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated
});
@@ -65,7 +65,7 @@ class _$SnPostCopyWithImpl<$Res>
/// Create a copy of SnPost
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? title = freezed,Object? description = freezed,Object? language = freezed,Object? editedAt = freezed,Object? publishedAt = freezed,Object? visibility = null,Object? content = freezed,Object? slug = freezed,Object? type = null,Object? meta = freezed,Object? embedView = freezed,Object? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? repliesCount = null,Object? awardedScore = null,Object? pinMode = freezed,Object? threadedPostId = freezed,Object? threadedPost = freezed,Object? repliedPostId = freezed,Object? repliedPost = freezed,Object? forwardedPostId = freezed,Object? forwardedPost = freezed,Object? realmId = freezed,Object? realm = freezed,Object? attachments = null,Object? publisher = null,Object? reactionsCount = null,Object? reactionsMade = null,Object? reactions = null,Object? tags = null,Object? categories = null,Object? collections = null,Object? createdAt = freezed,Object? updatedAt = freezed,Object? deletedAt = freezed,Object? isTruncated = null,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? title = freezed,Object? description = freezed,Object? language = freezed,Object? editedAt = freezed,Object? publishedAt = freezed,Object? visibility = null,Object? content = freezed,Object? slug = freezed,Object? type = null,Object? meta = freezed,Object? embedView = freezed,Object? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? repliesCount = null,Object? awardedScore = null,Object? pinMode = freezed,Object? threadedPostId = freezed,Object? threadedPost = freezed,Object? repliedPostId = freezed,Object? repliedPost = freezed,Object? forwardedPostId = freezed,Object? forwardedPost = freezed,Object? realmId = freezed,Object? realm = freezed,Object? attachments = null,Object? publisher = null,Object? reactionsCount = null,Object? reactionsMade = null,Object? reactions = null,Object? tags = null,Object? categories = null,Object? collections = null,Object? featuredRecords = null,Object? createdAt = freezed,Object? updatedAt = freezed,Object? deletedAt = freezed,Object? isTruncated = null,}) {
return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,title: freezed == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
@@ -102,7 +102,8 @@ as Map<String, bool>,reactions: null == reactions ? _self.reactions : reactions
as List<dynamic>,tags: null == tags ? _self.tags : tags // ignore: cast_nullable_to_non_nullable
as List<SnPostTag>,categories: null == categories ? _self.categories : categories // ignore: cast_nullable_to_non_nullable
as List<SnPostCategory>,collections: null == collections ? _self.collections : collections // ignore: cast_nullable_to_non_nullable
as List<dynamic>,createdAt: freezed == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as List<dynamic>,featuredRecords: null == featuredRecords ? _self.featuredRecords : featuredRecords // ignore: cast_nullable_to_non_nullable
as List<SnPostFeaturedRecord>,createdAt: freezed == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as DateTime?,updatedAt: freezed == 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?,isTruncated: null == isTruncated ? _self.isTruncated : isTruncated // ignore: cast_nullable_to_non_nullable
@@ -257,10 +258,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, List<SnPostFeaturedRecord> featuredRecords, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnPost() when $default != null:
return $default(_that.id,_that.title,_that.description,_that.language,_that.editedAt,_that.publishedAt,_that.visibility,_that.content,_that.slug,_that.type,_that.meta,_that.embedView,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.awardedScore,_that.pinMode,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.realmId,_that.realm,_that.attachments,_that.publisher,_that.reactionsCount,_that.reactionsMade,_that.reactions,_that.tags,_that.categories,_that.collections,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.isTruncated);case _:
return $default(_that.id,_that.title,_that.description,_that.language,_that.editedAt,_that.publishedAt,_that.visibility,_that.content,_that.slug,_that.type,_that.meta,_that.embedView,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.awardedScore,_that.pinMode,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.realmId,_that.realm,_that.attachments,_that.publisher,_that.reactionsCount,_that.reactionsMade,_that.reactions,_that.tags,_that.categories,_that.collections,_that.featuredRecords,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.isTruncated);case _:
return orElse();
}
@@ -278,10 +279,10 @@ return $default(_that.id,_that.title,_that.description,_that.language,_that.edit
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, List<SnPostFeaturedRecord> featuredRecords, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated) $default,) {final _that = this;
switch (_that) {
case _SnPost():
return $default(_that.id,_that.title,_that.description,_that.language,_that.editedAt,_that.publishedAt,_that.visibility,_that.content,_that.slug,_that.type,_that.meta,_that.embedView,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.awardedScore,_that.pinMode,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.realmId,_that.realm,_that.attachments,_that.publisher,_that.reactionsCount,_that.reactionsMade,_that.reactions,_that.tags,_that.categories,_that.collections,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.isTruncated);}
return $default(_that.id,_that.title,_that.description,_that.language,_that.editedAt,_that.publishedAt,_that.visibility,_that.content,_that.slug,_that.type,_that.meta,_that.embedView,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.awardedScore,_that.pinMode,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.realmId,_that.realm,_that.attachments,_that.publisher,_that.reactionsCount,_that.reactionsMade,_that.reactions,_that.tags,_that.categories,_that.collections,_that.featuredRecords,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.isTruncated);}
}
/// A variant of `when` that fallback to returning `null`
///
@@ -295,10 +296,10 @@ return $default(_that.id,_that.title,_that.description,_that.language,_that.edit
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, List<SnPostFeaturedRecord> featuredRecords, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated)? $default,) {final _that = this;
switch (_that) {
case _SnPost() when $default != null:
return $default(_that.id,_that.title,_that.description,_that.language,_that.editedAt,_that.publishedAt,_that.visibility,_that.content,_that.slug,_that.type,_that.meta,_that.embedView,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.awardedScore,_that.pinMode,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.realmId,_that.realm,_that.attachments,_that.publisher,_that.reactionsCount,_that.reactionsMade,_that.reactions,_that.tags,_that.categories,_that.collections,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.isTruncated);case _:
return $default(_that.id,_that.title,_that.description,_that.language,_that.editedAt,_that.publishedAt,_that.visibility,_that.content,_that.slug,_that.type,_that.meta,_that.embedView,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.awardedScore,_that.pinMode,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.realmId,_that.realm,_that.attachments,_that.publisher,_that.reactionsCount,_that.reactionsMade,_that.reactions,_that.tags,_that.categories,_that.collections,_that.featuredRecords,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.isTruncated);case _:
return null;
}
@@ -310,7 +311,7 @@ return $default(_that.id,_that.title,_that.description,_that.language,_that.edit
@JsonSerializable()
class _SnPost implements SnPost {
const _SnPost({required this.id, this.title, this.description, this.language, this.editedAt, this.publishedAt = null, this.visibility = 0, this.content, this.slug, this.type = 0, final Map<String, dynamic>? meta, this.embedView, this.viewsUnique = 0, this.viewsTotal = 0, this.upvotes = 0, this.downvotes = 0, this.repliesCount = 0, this.awardedScore = 0, this.pinMode, this.threadedPostId, this.threadedPost, this.repliedPostId, this.repliedPost, this.forwardedPostId, this.forwardedPost, this.realmId, this.realm, final List<SnCloudFile> attachments = const [], required this.publisher, final Map<String, int> reactionsCount = const {}, final Map<String, bool> reactionsMade = const {}, final List<dynamic> reactions = const [], final List<SnPostTag> tags = const [], final List<SnPostCategory> categories = const [], final List<dynamic> collections = const [], this.createdAt = null, this.updatedAt = null, this.deletedAt, this.isTruncated = false}): _meta = meta,_attachments = attachments,_reactionsCount = reactionsCount,_reactionsMade = reactionsMade,_reactions = reactions,_tags = tags,_categories = categories,_collections = collections;
const _SnPost({required this.id, this.title, this.description, this.language, this.editedAt, this.publishedAt = null, this.visibility = 0, this.content, this.slug, this.type = 0, final Map<String, dynamic>? meta, this.embedView, this.viewsUnique = 0, this.viewsTotal = 0, this.upvotes = 0, this.downvotes = 0, this.repliesCount = 0, this.awardedScore = 0, this.pinMode, this.threadedPostId, this.threadedPost, this.repliedPostId, this.repliedPost, this.forwardedPostId, this.forwardedPost, this.realmId, this.realm, final List<SnCloudFile> attachments = const [], required this.publisher, final Map<String, int> reactionsCount = const {}, final Map<String, bool> reactionsMade = const {}, final List<dynamic> reactions = const [], final List<SnPostTag> tags = const [], final List<SnPostCategory> categories = const [], final List<dynamic> collections = const [], final List<SnPostFeaturedRecord> featuredRecords = const [], this.createdAt = null, this.updatedAt = null, this.deletedAt, this.isTruncated = false}): _meta = meta,_attachments = attachments,_reactionsCount = reactionsCount,_reactionsMade = reactionsMade,_reactions = reactions,_tags = tags,_categories = categories,_collections = collections,_featuredRecords = featuredRecords;
factory _SnPost.fromJson(Map<String, dynamic> json) => _$SnPostFromJson(json);
@override final String id;
@@ -398,6 +399,13 @@ class _SnPost implements SnPost {
return EqualUnmodifiableListView(_collections);
}
final List<SnPostFeaturedRecord> _featuredRecords;
@override@JsonKey() List<SnPostFeaturedRecord> get featuredRecords {
if (_featuredRecords is EqualUnmodifiableListView) return _featuredRecords;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_featuredRecords);
}
@override@JsonKey() final DateTime? createdAt;
@override@JsonKey() final DateTime? updatedAt;
@override final DateTime? deletedAt;
@@ -416,16 +424,16 @@ Map<String, dynamic> toJson() {
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPost&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.language, language) || other.language == language)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.visibility, visibility) || other.visibility == visibility)&&(identical(other.content, content) || other.content == content)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other._meta, _meta)&&(identical(other.embedView, embedView) || other.embedView == embedView)&&(identical(other.viewsUnique, viewsUnique) || other.viewsUnique == viewsUnique)&&(identical(other.viewsTotal, viewsTotal) || other.viewsTotal == viewsTotal)&&(identical(other.upvotes, upvotes) || other.upvotes == upvotes)&&(identical(other.downvotes, downvotes) || other.downvotes == downvotes)&&(identical(other.repliesCount, repliesCount) || other.repliesCount == repliesCount)&&(identical(other.awardedScore, awardedScore) || other.awardedScore == awardedScore)&&(identical(other.pinMode, pinMode) || other.pinMode == pinMode)&&(identical(other.threadedPostId, threadedPostId) || other.threadedPostId == threadedPostId)&&(identical(other.threadedPost, threadedPost) || other.threadedPost == threadedPost)&&(identical(other.repliedPostId, repliedPostId) || other.repliedPostId == repliedPostId)&&(identical(other.repliedPost, repliedPost) || other.repliedPost == repliedPost)&&(identical(other.forwardedPostId, forwardedPostId) || other.forwardedPostId == forwardedPostId)&&(identical(other.forwardedPost, forwardedPost) || other.forwardedPost == forwardedPost)&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&const DeepCollectionEquality().equals(other._attachments, _attachments)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&const DeepCollectionEquality().equals(other._reactionsCount, _reactionsCount)&&const DeepCollectionEquality().equals(other._reactionsMade, _reactionsMade)&&const DeepCollectionEquality().equals(other._reactions, _reactions)&&const DeepCollectionEquality().equals(other._tags, _tags)&&const DeepCollectionEquality().equals(other._categories, _categories)&&const DeepCollectionEquality().equals(other._collections, _collections)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.isTruncated, isTruncated) || other.isTruncated == isTruncated));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPost&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.language, language) || other.language == language)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.visibility, visibility) || other.visibility == visibility)&&(identical(other.content, content) || other.content == content)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other._meta, _meta)&&(identical(other.embedView, embedView) || other.embedView == embedView)&&(identical(other.viewsUnique, viewsUnique) || other.viewsUnique == viewsUnique)&&(identical(other.viewsTotal, viewsTotal) || other.viewsTotal == viewsTotal)&&(identical(other.upvotes, upvotes) || other.upvotes == upvotes)&&(identical(other.downvotes, downvotes) || other.downvotes == downvotes)&&(identical(other.repliesCount, repliesCount) || other.repliesCount == repliesCount)&&(identical(other.awardedScore, awardedScore) || other.awardedScore == awardedScore)&&(identical(other.pinMode, pinMode) || other.pinMode == pinMode)&&(identical(other.threadedPostId, threadedPostId) || other.threadedPostId == threadedPostId)&&(identical(other.threadedPost, threadedPost) || other.threadedPost == threadedPost)&&(identical(other.repliedPostId, repliedPostId) || other.repliedPostId == repliedPostId)&&(identical(other.repliedPost, repliedPost) || other.repliedPost == repliedPost)&&(identical(other.forwardedPostId, forwardedPostId) || other.forwardedPostId == forwardedPostId)&&(identical(other.forwardedPost, forwardedPost) || other.forwardedPost == forwardedPost)&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&const DeepCollectionEquality().equals(other._attachments, _attachments)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&const DeepCollectionEquality().equals(other._reactionsCount, _reactionsCount)&&const DeepCollectionEquality().equals(other._reactionsMade, _reactionsMade)&&const DeepCollectionEquality().equals(other._reactions, _reactions)&&const DeepCollectionEquality().equals(other._tags, _tags)&&const DeepCollectionEquality().equals(other._categories, _categories)&&const DeepCollectionEquality().equals(other._collections, _collections)&&const DeepCollectionEquality().equals(other._featuredRecords, _featuredRecords)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.isTruncated, isTruncated) || other.isTruncated == isTruncated));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hashAll([runtimeType,id,title,description,language,editedAt,publishedAt,visibility,content,slug,type,const DeepCollectionEquality().hash(_meta),embedView,viewsUnique,viewsTotal,upvotes,downvotes,repliesCount,awardedScore,pinMode,threadedPostId,threadedPost,repliedPostId,repliedPost,forwardedPostId,forwardedPost,realmId,realm,const DeepCollectionEquality().hash(_attachments),publisher,const DeepCollectionEquality().hash(_reactionsCount),const DeepCollectionEquality().hash(_reactionsMade),const DeepCollectionEquality().hash(_reactions),const DeepCollectionEquality().hash(_tags),const DeepCollectionEquality().hash(_categories),const DeepCollectionEquality().hash(_collections),createdAt,updatedAt,deletedAt,isTruncated]);
int get hashCode => Object.hashAll([runtimeType,id,title,description,language,editedAt,publishedAt,visibility,content,slug,type,const DeepCollectionEquality().hash(_meta),embedView,viewsUnique,viewsTotal,upvotes,downvotes,repliesCount,awardedScore,pinMode,threadedPostId,threadedPost,repliedPostId,repliedPost,forwardedPostId,forwardedPost,realmId,realm,const DeepCollectionEquality().hash(_attachments),publisher,const DeepCollectionEquality().hash(_reactionsCount),const DeepCollectionEquality().hash(_reactionsMade),const DeepCollectionEquality().hash(_reactions),const DeepCollectionEquality().hash(_tags),const DeepCollectionEquality().hash(_categories),const DeepCollectionEquality().hash(_collections),const DeepCollectionEquality().hash(_featuredRecords),createdAt,updatedAt,deletedAt,isTruncated]);
@override
String toString() {
return 'SnPost(id: $id, title: $title, description: $description, language: $language, editedAt: $editedAt, publishedAt: $publishedAt, visibility: $visibility, content: $content, slug: $slug, type: $type, meta: $meta, embedView: $embedView, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, repliesCount: $repliesCount, awardedScore: $awardedScore, pinMode: $pinMode, threadedPostId: $threadedPostId, threadedPost: $threadedPost, repliedPostId: $repliedPostId, repliedPost: $repliedPost, forwardedPostId: $forwardedPostId, forwardedPost: $forwardedPost, realmId: $realmId, realm: $realm, attachments: $attachments, publisher: $publisher, reactionsCount: $reactionsCount, reactionsMade: $reactionsMade, reactions: $reactions, tags: $tags, categories: $categories, collections: $collections, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, isTruncated: $isTruncated)';
return 'SnPost(id: $id, title: $title, description: $description, language: $language, editedAt: $editedAt, publishedAt: $publishedAt, visibility: $visibility, content: $content, slug: $slug, type: $type, meta: $meta, embedView: $embedView, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, repliesCount: $repliesCount, awardedScore: $awardedScore, pinMode: $pinMode, threadedPostId: $threadedPostId, threadedPost: $threadedPost, repliedPostId: $repliedPostId, repliedPost: $repliedPost, forwardedPostId: $forwardedPostId, forwardedPost: $forwardedPost, realmId: $realmId, realm: $realm, attachments: $attachments, publisher: $publisher, reactionsCount: $reactionsCount, reactionsMade: $reactionsMade, reactions: $reactions, tags: $tags, categories: $categories, collections: $collections, featuredRecords: $featuredRecords, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, isTruncated: $isTruncated)';
}
@@ -436,7 +444,7 @@ abstract mixin class _$SnPostCopyWith<$Res> implements $SnPostCopyWith<$Res> {
factory _$SnPostCopyWith(_SnPost value, $Res Function(_SnPost) _then) = __$SnPostCopyWithImpl;
@override @useResult
$Res call({
String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated
String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, List<SnPostFeaturedRecord> featuredRecords, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated
});
@@ -453,7 +461,7 @@ class __$SnPostCopyWithImpl<$Res>
/// Create a copy of SnPost
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? title = freezed,Object? description = freezed,Object? language = freezed,Object? editedAt = freezed,Object? publishedAt = freezed,Object? visibility = null,Object? content = freezed,Object? slug = freezed,Object? type = null,Object? meta = freezed,Object? embedView = freezed,Object? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? repliesCount = null,Object? awardedScore = null,Object? pinMode = freezed,Object? threadedPostId = freezed,Object? threadedPost = freezed,Object? repliedPostId = freezed,Object? repliedPost = freezed,Object? forwardedPostId = freezed,Object? forwardedPost = freezed,Object? realmId = freezed,Object? realm = freezed,Object? attachments = null,Object? publisher = null,Object? reactionsCount = null,Object? reactionsMade = null,Object? reactions = null,Object? tags = null,Object? categories = null,Object? collections = null,Object? createdAt = freezed,Object? updatedAt = freezed,Object? deletedAt = freezed,Object? isTruncated = null,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? title = freezed,Object? description = freezed,Object? language = freezed,Object? editedAt = freezed,Object? publishedAt = freezed,Object? visibility = null,Object? content = freezed,Object? slug = freezed,Object? type = null,Object? meta = freezed,Object? embedView = freezed,Object? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? repliesCount = null,Object? awardedScore = null,Object? pinMode = freezed,Object? threadedPostId = freezed,Object? threadedPost = freezed,Object? repliedPostId = freezed,Object? repliedPost = freezed,Object? forwardedPostId = freezed,Object? forwardedPost = freezed,Object? realmId = freezed,Object? realm = freezed,Object? attachments = null,Object? publisher = null,Object? reactionsCount = null,Object? reactionsMade = null,Object? reactions = null,Object? tags = null,Object? categories = null,Object? collections = null,Object? featuredRecords = null,Object? createdAt = freezed,Object? updatedAt = freezed,Object? deletedAt = freezed,Object? isTruncated = null,}) {
return _then(_SnPost(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,title: freezed == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
@@ -490,7 +498,8 @@ as Map<String, bool>,reactions: null == reactions ? _self._reactions : reactions
as List<dynamic>,tags: null == tags ? _self._tags : tags // ignore: cast_nullable_to_non_nullable
as List<SnPostTag>,categories: null == categories ? _self._categories : categories // ignore: cast_nullable_to_non_nullable
as List<SnPostCategory>,collections: null == collections ? _self._collections : collections // ignore: cast_nullable_to_non_nullable
as List<dynamic>,createdAt: freezed == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as List<dynamic>,featuredRecords: null == featuredRecords ? _self._featuredRecords : featuredRecords // ignore: cast_nullable_to_non_nullable
as List<SnPostFeaturedRecord>,createdAt: freezed == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as DateTime?,updatedAt: freezed == 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?,isTruncated: null == isTruncated ? _self.isTruncated : isTruncated // ignore: cast_nullable_to_non_nullable
@@ -2205,4 +2214,279 @@ $SnAccountCopyWith<$Res>? get account {
}
}
/// @nodoc
mixin _$SnPostFeaturedRecord {
String get id; String get postId; DateTime? get featuredAt; int get socialCredits; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
/// Create a copy of SnPostFeaturedRecord
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$SnPostFeaturedRecordCopyWith<SnPostFeaturedRecord> get copyWith => _$SnPostFeaturedRecordCopyWithImpl<SnPostFeaturedRecord>(this as SnPostFeaturedRecord, _$identity);
/// Serializes this SnPostFeaturedRecord to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPostFeaturedRecord&&(identical(other.id, id) || other.id == id)&&(identical(other.postId, postId) || other.postId == postId)&&(identical(other.featuredAt, featuredAt) || other.featuredAt == featuredAt)&&(identical(other.socialCredits, socialCredits) || other.socialCredits == socialCredits)&&(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)
@override
int get hashCode => Object.hash(runtimeType,id,postId,featuredAt,socialCredits,createdAt,updatedAt,deletedAt);
@override
String toString() {
return 'SnPostFeaturedRecord(id: $id, postId: $postId, featuredAt: $featuredAt, socialCredits: $socialCredits, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
}
/// @nodoc
abstract mixin class $SnPostFeaturedRecordCopyWith<$Res> {
factory $SnPostFeaturedRecordCopyWith(SnPostFeaturedRecord value, $Res Function(SnPostFeaturedRecord) _then) = _$SnPostFeaturedRecordCopyWithImpl;
@useResult
$Res call({
String id, String postId, DateTime? featuredAt, int socialCredits, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
}
/// @nodoc
class _$SnPostFeaturedRecordCopyWithImpl<$Res>
implements $SnPostFeaturedRecordCopyWith<$Res> {
_$SnPostFeaturedRecordCopyWithImpl(this._self, this._then);
final SnPostFeaturedRecord _self;
final $Res Function(SnPostFeaturedRecord) _then;
/// Create a copy of SnPostFeaturedRecord
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? postId = null,Object? featuredAt = freezed,Object? socialCredits = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,postId: null == postId ? _self.postId : postId // ignore: cast_nullable_to_non_nullable
as String,featuredAt: freezed == featuredAt ? _self.featuredAt : featuredAt // ignore: cast_nullable_to_non_nullable
as DateTime?,socialCredits: null == socialCredits ? _self.socialCredits : socialCredits // 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,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,
));
}
}
/// Adds pattern-matching-related methods to [SnPostFeaturedRecord].
extension SnPostFeaturedRecordPatterns on SnPostFeaturedRecord {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _SnPostFeaturedRecord value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _SnPostFeaturedRecord() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _SnPostFeaturedRecord value) $default,){
final _that = this;
switch (_that) {
case _SnPostFeaturedRecord():
return $default(_that);}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _SnPostFeaturedRecord value)? $default,){
final _that = this;
switch (_that) {
case _SnPostFeaturedRecord() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String postId, DateTime? featuredAt, int socialCredits, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnPostFeaturedRecord() when $default != null:
return $default(_that.id,_that.postId,_that.featuredAt,_that.socialCredits,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String postId, DateTime? featuredAt, int socialCredits, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
switch (_that) {
case _SnPostFeaturedRecord():
return $default(_that.id,_that.postId,_that.featuredAt,_that.socialCredits,_that.createdAt,_that.updatedAt,_that.deletedAt);}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String postId, DateTime? featuredAt, int socialCredits, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
switch (_that) {
case _SnPostFeaturedRecord() when $default != null:
return $default(_that.id,_that.postId,_that.featuredAt,_that.socialCredits,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _SnPostFeaturedRecord implements SnPostFeaturedRecord {
const _SnPostFeaturedRecord({required this.id, required this.postId, required this.featuredAt, required this.socialCredits, required this.createdAt, required this.updatedAt, required this.deletedAt});
factory _SnPostFeaturedRecord.fromJson(Map<String, dynamic> json) => _$SnPostFeaturedRecordFromJson(json);
@override final String id;
@override final String postId;
@override final DateTime? featuredAt;
@override final int socialCredits;
@override final DateTime createdAt;
@override final DateTime updatedAt;
@override final DateTime? deletedAt;
/// Create a copy of SnPostFeaturedRecord
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$SnPostFeaturedRecordCopyWith<_SnPostFeaturedRecord> get copyWith => __$SnPostFeaturedRecordCopyWithImpl<_SnPostFeaturedRecord>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$SnPostFeaturedRecordToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPostFeaturedRecord&&(identical(other.id, id) || other.id == id)&&(identical(other.postId, postId) || other.postId == postId)&&(identical(other.featuredAt, featuredAt) || other.featuredAt == featuredAt)&&(identical(other.socialCredits, socialCredits) || other.socialCredits == socialCredits)&&(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)
@override
int get hashCode => Object.hash(runtimeType,id,postId,featuredAt,socialCredits,createdAt,updatedAt,deletedAt);
@override
String toString() {
return 'SnPostFeaturedRecord(id: $id, postId: $postId, featuredAt: $featuredAt, socialCredits: $socialCredits, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
}
/// @nodoc
abstract mixin class _$SnPostFeaturedRecordCopyWith<$Res> implements $SnPostFeaturedRecordCopyWith<$Res> {
factory _$SnPostFeaturedRecordCopyWith(_SnPostFeaturedRecord value, $Res Function(_SnPostFeaturedRecord) _then) = __$SnPostFeaturedRecordCopyWithImpl;
@override @useResult
$Res call({
String id, String postId, DateTime? featuredAt, int socialCredits, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
}
/// @nodoc
class __$SnPostFeaturedRecordCopyWithImpl<$Res>
implements _$SnPostFeaturedRecordCopyWith<$Res> {
__$SnPostFeaturedRecordCopyWithImpl(this._self, this._then);
final _SnPostFeaturedRecord _self;
final $Res Function(_SnPostFeaturedRecord) _then;
/// Create a copy of SnPostFeaturedRecord
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? postId = null,Object? featuredAt = freezed,Object? socialCredits = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
return _then(_SnPostFeaturedRecord(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,postId: null == postId ? _self.postId : postId // ignore: cast_nullable_to_non_nullable
as String,featuredAt: freezed == featuredAt ? _self.featuredAt : featuredAt // ignore: cast_nullable_to_non_nullable
as DateTime?,socialCredits: null == socialCredits ? _self.socialCredits : socialCredits // 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,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,
));
}
}
// dart format on

View File

@@ -85,6 +85,11 @@ _SnPost _$SnPostFromJson(Map<String, dynamic> json) => _SnPost(
.toList() ??
const [],
collections: json['collections'] as List<dynamic>? ?? const [],
featuredRecords:
(json['featured_records'] as List<dynamic>?)
?.map((e) => SnPostFeaturedRecord.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
createdAt:
json['created_at'] == null
? null
@@ -136,6 +141,7 @@ Map<String, dynamic> _$SnPostToJson(_SnPost instance) => <String, dynamic>{
'tags': instance.tags.map((e) => e.toJson()).toList(),
'categories': instance.categories.map((e) => e.toJson()).toList(),
'collections': instance.collections,
'featured_records': instance.featuredRecords.map((e) => e.toJson()).toList(),
'created_at': instance.createdAt?.toIso8601String(),
'updated_at': instance.updatedAt?.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
@@ -262,3 +268,33 @@ Map<String, dynamic> _$SnPostReactionToJson(_SnPostReaction instance) =>
'account': instance.account?.toJson(),
'deleted_at': instance.deletedAt?.toIso8601String(),
};
_SnPostFeaturedRecord _$SnPostFeaturedRecordFromJson(
Map<String, dynamic> json,
) => _SnPostFeaturedRecord(
id: json['id'] as String,
postId: json['post_id'] as String,
featuredAt:
json['featured_at'] == null
? null
: DateTime.parse(json['featured_at'] as String),
socialCredits: (json['social_credits'] as num).toInt(),
createdAt: DateTime.parse(json['created_at'] as String),
updatedAt: DateTime.parse(json['updated_at'] as String),
deletedAt:
json['deleted_at'] == null
? null
: DateTime.parse(json['deleted_at'] as String),
);
Map<String, dynamic> _$SnPostFeaturedRecordToJson(
_SnPostFeaturedRecord instance,
) => <String, dynamic>{
'id': instance.id,
'post_id': instance.postId,
'featured_at': instance.featuredAt?.toIso8601String(),
'social_credits': instance.socialCredits,
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
};

72
lib/models/thought.dart Normal file
View File

@@ -0,0 +1,72 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:island/models/file.dart';
part 'thought.freezed.dart';
part 'thought.g.dart';
enum ThinkingThoughtRole {
assistant(0),
user(1);
const ThinkingThoughtRole(this.value);
final int value;
static ThinkingThoughtRole fromValue(int value) {
return values.firstWhere((e) => e.value == value);
}
}
class ThinkingThoughtRoleConverter
implements JsonConverter<ThinkingThoughtRole, int> {
const ThinkingThoughtRoleConverter();
@override
ThinkingThoughtRole fromJson(int json) => ThinkingThoughtRole.fromValue(json);
@override
int toJson(ThinkingThoughtRole object) => object.value;
}
@freezed
sealed class StreamThinkingRequest with _$StreamThinkingRequest {
const factory StreamThinkingRequest({
required String userMessage,
String? sequenceId,
}) = _StreamThinkingRequest;
factory StreamThinkingRequest.fromJson(Map<String, dynamic> json) =>
_$StreamThinkingRequestFromJson(json);
}
@freezed
sealed class SnThinkingSequence with _$SnThinkingSequence {
const factory SnThinkingSequence({
required String id,
String? topic,
required String accountId,
required DateTime createdAt,
required DateTime updatedAt,
DateTime? deletedAt,
}) = _SnThinkingSequence;
factory SnThinkingSequence.fromJson(Map<String, dynamic> json) =>
_$SnThinkingSequenceFromJson(json);
}
@freezed
sealed class SnThinkingThought with _$SnThinkingThought {
const factory SnThinkingThought({
required String id,
String? content,
@Default([]) List<SnCloudFile> files,
@ThinkingThoughtRoleConverter() required ThinkingThoughtRole role,
required String sequenceId,
SnThinkingSequence? sequence,
required DateTime createdAt,
required DateTime updatedAt,
DateTime? deletedAt,
}) = _SnThinkingThought;
factory SnThinkingThought.fromJson(Map<String, dynamic> json) =>
_$SnThinkingThoughtFromJson(json);
}

View File

@@ -0,0 +1,857 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// coverage:ignore-file
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'thought.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$StreamThinkingRequest {
String get userMessage; String? get sequenceId;
/// Create a copy of StreamThinkingRequest
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$StreamThinkingRequestCopyWith<StreamThinkingRequest> get copyWith => _$StreamThinkingRequestCopyWithImpl<StreamThinkingRequest>(this as StreamThinkingRequest, _$identity);
/// Serializes this StreamThinkingRequest to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is StreamThinkingRequest&&(identical(other.userMessage, userMessage) || other.userMessage == userMessage)&&(identical(other.sequenceId, sequenceId) || other.sequenceId == sequenceId));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,userMessage,sequenceId);
@override
String toString() {
return 'StreamThinkingRequest(userMessage: $userMessage, sequenceId: $sequenceId)';
}
}
/// @nodoc
abstract mixin class $StreamThinkingRequestCopyWith<$Res> {
factory $StreamThinkingRequestCopyWith(StreamThinkingRequest value, $Res Function(StreamThinkingRequest) _then) = _$StreamThinkingRequestCopyWithImpl;
@useResult
$Res call({
String userMessage, String? sequenceId
});
}
/// @nodoc
class _$StreamThinkingRequestCopyWithImpl<$Res>
implements $StreamThinkingRequestCopyWith<$Res> {
_$StreamThinkingRequestCopyWithImpl(this._self, this._then);
final StreamThinkingRequest _self;
final $Res Function(StreamThinkingRequest) _then;
/// Create a copy of StreamThinkingRequest
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? userMessage = null,Object? sequenceId = freezed,}) {
return _then(_self.copyWith(
userMessage: null == userMessage ? _self.userMessage : userMessage // ignore: cast_nullable_to_non_nullable
as String,sequenceId: freezed == sequenceId ? _self.sequenceId : sequenceId // ignore: cast_nullable_to_non_nullable
as String?,
));
}
}
/// Adds pattern-matching-related methods to [StreamThinkingRequest].
extension StreamThinkingRequestPatterns on StreamThinkingRequest {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _StreamThinkingRequest value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _StreamThinkingRequest() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _StreamThinkingRequest value) $default,){
final _that = this;
switch (_that) {
case _StreamThinkingRequest():
return $default(_that);}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _StreamThinkingRequest value)? $default,){
final _that = this;
switch (_that) {
case _StreamThinkingRequest() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String userMessage, String? sequenceId)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _StreamThinkingRequest() when $default != null:
return $default(_that.userMessage,_that.sequenceId);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String userMessage, String? sequenceId) $default,) {final _that = this;
switch (_that) {
case _StreamThinkingRequest():
return $default(_that.userMessage,_that.sequenceId);}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String userMessage, String? sequenceId)? $default,) {final _that = this;
switch (_that) {
case _StreamThinkingRequest() when $default != null:
return $default(_that.userMessage,_that.sequenceId);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _StreamThinkingRequest implements StreamThinkingRequest {
const _StreamThinkingRequest({required this.userMessage, this.sequenceId});
factory _StreamThinkingRequest.fromJson(Map<String, dynamic> json) => _$StreamThinkingRequestFromJson(json);
@override final String userMessage;
@override final String? sequenceId;
/// Create a copy of StreamThinkingRequest
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$StreamThinkingRequestCopyWith<_StreamThinkingRequest> get copyWith => __$StreamThinkingRequestCopyWithImpl<_StreamThinkingRequest>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$StreamThinkingRequestToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _StreamThinkingRequest&&(identical(other.userMessage, userMessage) || other.userMessage == userMessage)&&(identical(other.sequenceId, sequenceId) || other.sequenceId == sequenceId));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,userMessage,sequenceId);
@override
String toString() {
return 'StreamThinkingRequest(userMessage: $userMessage, sequenceId: $sequenceId)';
}
}
/// @nodoc
abstract mixin class _$StreamThinkingRequestCopyWith<$Res> implements $StreamThinkingRequestCopyWith<$Res> {
factory _$StreamThinkingRequestCopyWith(_StreamThinkingRequest value, $Res Function(_StreamThinkingRequest) _then) = __$StreamThinkingRequestCopyWithImpl;
@override @useResult
$Res call({
String userMessage, String? sequenceId
});
}
/// @nodoc
class __$StreamThinkingRequestCopyWithImpl<$Res>
implements _$StreamThinkingRequestCopyWith<$Res> {
__$StreamThinkingRequestCopyWithImpl(this._self, this._then);
final _StreamThinkingRequest _self;
final $Res Function(_StreamThinkingRequest) _then;
/// Create a copy of StreamThinkingRequest
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? userMessage = null,Object? sequenceId = freezed,}) {
return _then(_StreamThinkingRequest(
userMessage: null == userMessage ? _self.userMessage : userMessage // ignore: cast_nullable_to_non_nullable
as String,sequenceId: freezed == sequenceId ? _self.sequenceId : sequenceId // ignore: cast_nullable_to_non_nullable
as String?,
));
}
}
/// @nodoc
mixin _$SnThinkingSequence {
String get id; String? get topic; String get accountId; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
/// Create a copy of SnThinkingSequence
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$SnThinkingSequenceCopyWith<SnThinkingSequence> get copyWith => _$SnThinkingSequenceCopyWithImpl<SnThinkingSequence>(this as SnThinkingSequence, _$identity);
/// Serializes this SnThinkingSequence to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnThinkingSequence&&(identical(other.id, id) || other.id == id)&&(identical(other.topic, topic) || other.topic == topic)&&(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)
@override
int get hashCode => Object.hash(runtimeType,id,topic,accountId,createdAt,updatedAt,deletedAt);
@override
String toString() {
return 'SnThinkingSequence(id: $id, topic: $topic, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
}
/// @nodoc
abstract mixin class $SnThinkingSequenceCopyWith<$Res> {
factory $SnThinkingSequenceCopyWith(SnThinkingSequence value, $Res Function(SnThinkingSequence) _then) = _$SnThinkingSequenceCopyWithImpl;
@useResult
$Res call({
String id, String? topic, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
}
/// @nodoc
class _$SnThinkingSequenceCopyWithImpl<$Res>
implements $SnThinkingSequenceCopyWith<$Res> {
_$SnThinkingSequenceCopyWithImpl(this._self, this._then);
final SnThinkingSequence _self;
final $Res Function(SnThinkingSequence) _then;
/// Create a copy of SnThinkingSequence
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? topic = freezed,Object? accountId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,topic: freezed == topic ? _self.topic : topic // ignore: cast_nullable_to_non_nullable
as String?,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 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?,
));
}
}
/// Adds pattern-matching-related methods to [SnThinkingSequence].
extension SnThinkingSequencePatterns on SnThinkingSequence {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _SnThinkingSequence value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _SnThinkingSequence() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _SnThinkingSequence value) $default,){
final _that = this;
switch (_that) {
case _SnThinkingSequence():
return $default(_that);}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _SnThinkingSequence value)? $default,){
final _that = this;
switch (_that) {
case _SnThinkingSequence() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String? topic, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnThinkingSequence() when $default != null:
return $default(_that.id,_that.topic,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String? topic, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
switch (_that) {
case _SnThinkingSequence():
return $default(_that.id,_that.topic,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String? topic, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
switch (_that) {
case _SnThinkingSequence() when $default != null:
return $default(_that.id,_that.topic,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _SnThinkingSequence implements SnThinkingSequence {
const _SnThinkingSequence({required this.id, this.topic, required this.accountId, required this.createdAt, required this.updatedAt, this.deletedAt});
factory _SnThinkingSequence.fromJson(Map<String, dynamic> json) => _$SnThinkingSequenceFromJson(json);
@override final String id;
@override final String? topic;
@override final String accountId;
@override final DateTime createdAt;
@override final DateTime updatedAt;
@override final DateTime? deletedAt;
/// Create a copy of SnThinkingSequence
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$SnThinkingSequenceCopyWith<_SnThinkingSequence> get copyWith => __$SnThinkingSequenceCopyWithImpl<_SnThinkingSequence>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$SnThinkingSequenceToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnThinkingSequence&&(identical(other.id, id) || other.id == id)&&(identical(other.topic, topic) || other.topic == topic)&&(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)
@override
int get hashCode => Object.hash(runtimeType,id,topic,accountId,createdAt,updatedAt,deletedAt);
@override
String toString() {
return 'SnThinkingSequence(id: $id, topic: $topic, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
}
/// @nodoc
abstract mixin class _$SnThinkingSequenceCopyWith<$Res> implements $SnThinkingSequenceCopyWith<$Res> {
factory _$SnThinkingSequenceCopyWith(_SnThinkingSequence value, $Res Function(_SnThinkingSequence) _then) = __$SnThinkingSequenceCopyWithImpl;
@override @useResult
$Res call({
String id, String? topic, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
}
/// @nodoc
class __$SnThinkingSequenceCopyWithImpl<$Res>
implements _$SnThinkingSequenceCopyWith<$Res> {
__$SnThinkingSequenceCopyWithImpl(this._self, this._then);
final _SnThinkingSequence _self;
final $Res Function(_SnThinkingSequence) _then;
/// Create a copy of SnThinkingSequence
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? topic = freezed,Object? accountId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
return _then(_SnThinkingSequence(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,topic: freezed == topic ? _self.topic : topic // ignore: cast_nullable_to_non_nullable
as String?,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 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?,
));
}
}
/// @nodoc
mixin _$SnThinkingThought {
String get id; String? get content; List<SnCloudFile> get files;@ThinkingThoughtRoleConverter() ThinkingThoughtRole get role; String get sequenceId; SnThinkingSequence? get sequence; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
/// Create a copy of SnThinkingThought
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$SnThinkingThoughtCopyWith<SnThinkingThought> get copyWith => _$SnThinkingThoughtCopyWithImpl<SnThinkingThought>(this as SnThinkingThought, _$identity);
/// Serializes this SnThinkingThought to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnThinkingThought&&(identical(other.id, id) || other.id == id)&&(identical(other.content, content) || other.content == content)&&const DeepCollectionEquality().equals(other.files, files)&&(identical(other.role, role) || other.role == role)&&(identical(other.sequenceId, sequenceId) || other.sequenceId == sequenceId)&&(identical(other.sequence, sequence) || other.sequence == sequence)&&(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)
@override
int get hashCode => Object.hash(runtimeType,id,content,const DeepCollectionEquality().hash(files),role,sequenceId,sequence,createdAt,updatedAt,deletedAt);
@override
String toString() {
return 'SnThinkingThought(id: $id, content: $content, files: $files, role: $role, sequenceId: $sequenceId, sequence: $sequence, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
}
/// @nodoc
abstract mixin class $SnThinkingThoughtCopyWith<$Res> {
factory $SnThinkingThoughtCopyWith(SnThinkingThought value, $Res Function(SnThinkingThought) _then) = _$SnThinkingThoughtCopyWithImpl;
@useResult
$Res call({
String id, String? content, List<SnCloudFile> files,@ThinkingThoughtRoleConverter() ThinkingThoughtRole role, String sequenceId, SnThinkingSequence? sequence, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
$SnThinkingSequenceCopyWith<$Res>? get sequence;
}
/// @nodoc
class _$SnThinkingThoughtCopyWithImpl<$Res>
implements $SnThinkingThoughtCopyWith<$Res> {
_$SnThinkingThoughtCopyWithImpl(this._self, this._then);
final SnThinkingThought _self;
final $Res Function(SnThinkingThought) _then;
/// Create a copy of SnThinkingThought
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? content = freezed,Object? files = null,Object? role = null,Object? sequenceId = null,Object? sequence = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,content: freezed == content ? _self.content : content // ignore: cast_nullable_to_non_nullable
as String?,files: null == files ? _self.files : files // ignore: cast_nullable_to_non_nullable
as List<SnCloudFile>,role: null == role ? _self.role : role // ignore: cast_nullable_to_non_nullable
as ThinkingThoughtRole,sequenceId: null == sequenceId ? _self.sequenceId : sequenceId // ignore: cast_nullable_to_non_nullable
as String,sequence: freezed == sequence ? _self.sequence : sequence // ignore: cast_nullable_to_non_nullable
as SnThinkingSequence?,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,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,
));
}
/// Create a copy of SnThinkingThought
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnThinkingSequenceCopyWith<$Res>? get sequence {
if (_self.sequence == null) {
return null;
}
return $SnThinkingSequenceCopyWith<$Res>(_self.sequence!, (value) {
return _then(_self.copyWith(sequence: value));
});
}
}
/// Adds pattern-matching-related methods to [SnThinkingThought].
extension SnThinkingThoughtPatterns on SnThinkingThought {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _SnThinkingThought value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _SnThinkingThought() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _SnThinkingThought value) $default,){
final _that = this;
switch (_that) {
case _SnThinkingThought():
return $default(_that);}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _SnThinkingThought value)? $default,){
final _that = this;
switch (_that) {
case _SnThinkingThought() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String? content, List<SnCloudFile> files, @ThinkingThoughtRoleConverter() ThinkingThoughtRole role, String sequenceId, SnThinkingSequence? sequence, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnThinkingThought() when $default != null:
return $default(_that.id,_that.content,_that.files,_that.role,_that.sequenceId,_that.sequence,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String? content, List<SnCloudFile> files, @ThinkingThoughtRoleConverter() ThinkingThoughtRole role, String sequenceId, SnThinkingSequence? sequence, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
switch (_that) {
case _SnThinkingThought():
return $default(_that.id,_that.content,_that.files,_that.role,_that.sequenceId,_that.sequence,_that.createdAt,_that.updatedAt,_that.deletedAt);}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String? content, List<SnCloudFile> files, @ThinkingThoughtRoleConverter() ThinkingThoughtRole role, String sequenceId, SnThinkingSequence? sequence, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
switch (_that) {
case _SnThinkingThought() when $default != null:
return $default(_that.id,_that.content,_that.files,_that.role,_that.sequenceId,_that.sequence,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _SnThinkingThought implements SnThinkingThought {
const _SnThinkingThought({required this.id, this.content, final List<SnCloudFile> files = const [], @ThinkingThoughtRoleConverter() required this.role, required this.sequenceId, this.sequence, required this.createdAt, required this.updatedAt, this.deletedAt}): _files = files;
factory _SnThinkingThought.fromJson(Map<String, dynamic> json) => _$SnThinkingThoughtFromJson(json);
@override final String id;
@override final String? content;
final List<SnCloudFile> _files;
@override@JsonKey() List<SnCloudFile> get files {
if (_files is EqualUnmodifiableListView) return _files;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_files);
}
@override@ThinkingThoughtRoleConverter() final ThinkingThoughtRole role;
@override final String sequenceId;
@override final SnThinkingSequence? sequence;
@override final DateTime createdAt;
@override final DateTime updatedAt;
@override final DateTime? deletedAt;
/// Create a copy of SnThinkingThought
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$SnThinkingThoughtCopyWith<_SnThinkingThought> get copyWith => __$SnThinkingThoughtCopyWithImpl<_SnThinkingThought>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$SnThinkingThoughtToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnThinkingThought&&(identical(other.id, id) || other.id == id)&&(identical(other.content, content) || other.content == content)&&const DeepCollectionEquality().equals(other._files, _files)&&(identical(other.role, role) || other.role == role)&&(identical(other.sequenceId, sequenceId) || other.sequenceId == sequenceId)&&(identical(other.sequence, sequence) || other.sequence == sequence)&&(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)
@override
int get hashCode => Object.hash(runtimeType,id,content,const DeepCollectionEquality().hash(_files),role,sequenceId,sequence,createdAt,updatedAt,deletedAt);
@override
String toString() {
return 'SnThinkingThought(id: $id, content: $content, files: $files, role: $role, sequenceId: $sequenceId, sequence: $sequence, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
}
/// @nodoc
abstract mixin class _$SnThinkingThoughtCopyWith<$Res> implements $SnThinkingThoughtCopyWith<$Res> {
factory _$SnThinkingThoughtCopyWith(_SnThinkingThought value, $Res Function(_SnThinkingThought) _then) = __$SnThinkingThoughtCopyWithImpl;
@override @useResult
$Res call({
String id, String? content, List<SnCloudFile> files,@ThinkingThoughtRoleConverter() ThinkingThoughtRole role, String sequenceId, SnThinkingSequence? sequence, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
@override $SnThinkingSequenceCopyWith<$Res>? get sequence;
}
/// @nodoc
class __$SnThinkingThoughtCopyWithImpl<$Res>
implements _$SnThinkingThoughtCopyWith<$Res> {
__$SnThinkingThoughtCopyWithImpl(this._self, this._then);
final _SnThinkingThought _self;
final $Res Function(_SnThinkingThought) _then;
/// Create a copy of SnThinkingThought
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? content = freezed,Object? files = null,Object? role = null,Object? sequenceId = null,Object? sequence = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
return _then(_SnThinkingThought(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,content: freezed == content ? _self.content : content // ignore: cast_nullable_to_non_nullable
as String?,files: null == files ? _self._files : files // ignore: cast_nullable_to_non_nullable
as List<SnCloudFile>,role: null == role ? _self.role : role // ignore: cast_nullable_to_non_nullable
as ThinkingThoughtRole,sequenceId: null == sequenceId ? _self.sequenceId : sequenceId // ignore: cast_nullable_to_non_nullable
as String,sequence: freezed == sequence ? _self.sequence : sequence // ignore: cast_nullable_to_non_nullable
as SnThinkingSequence?,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,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,
));
}
/// Create a copy of SnThinkingThought
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnThinkingSequenceCopyWith<$Res>? get sequence {
if (_self.sequence == null) {
return null;
}
return $SnThinkingSequenceCopyWith<$Res>(_self.sequence!, (value) {
return _then(_self.copyWith(sequence: value));
});
}
}
// dart format on

84
lib/models/thought.g.dart Normal file
View File

@@ -0,0 +1,84 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'thought.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_StreamThinkingRequest _$StreamThinkingRequestFromJson(
Map<String, dynamic> json,
) => _StreamThinkingRequest(
userMessage: json['user_message'] as String,
sequenceId: json['sequence_id'] as String?,
);
Map<String, dynamic> _$StreamThinkingRequestToJson(
_StreamThinkingRequest instance,
) => <String, dynamic>{
'user_message': instance.userMessage,
'sequence_id': instance.sequenceId,
};
_SnThinkingSequence _$SnThinkingSequenceFromJson(Map<String, dynamic> json) =>
_SnThinkingSequence(
id: json['id'] as String,
topic: json['topic'] as String?,
accountId: json['account_id'] as String,
createdAt: DateTime.parse(json['created_at'] as String),
updatedAt: DateTime.parse(json['updated_at'] as String),
deletedAt:
json['deleted_at'] == null
? null
: DateTime.parse(json['deleted_at'] as String),
);
Map<String, dynamic> _$SnThinkingSequenceToJson(_SnThinkingSequence instance) =>
<String, dynamic>{
'id': instance.id,
'topic': instance.topic,
'account_id': instance.accountId,
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
};
_SnThinkingThought _$SnThinkingThoughtFromJson(Map<String, dynamic> json) =>
_SnThinkingThought(
id: json['id'] as String,
content: json['content'] as String?,
files:
(json['files'] as List<dynamic>?)
?.map((e) => SnCloudFile.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
role: const ThinkingThoughtRoleConverter().fromJson(
(json['role'] as num).toInt(),
),
sequenceId: json['sequence_id'] as String,
sequence:
json['sequence'] == null
? null
: SnThinkingSequence.fromJson(
json['sequence'] as Map<String, dynamic>,
),
createdAt: DateTime.parse(json['created_at'] as String),
updatedAt: DateTime.parse(json['updated_at'] as String),
deletedAt:
json['deleted_at'] == null
? null
: DateTime.parse(json['deleted_at'] as String),
);
Map<String, dynamic> _$SnThinkingThoughtToJson(_SnThinkingThought instance) =>
<String, dynamic>{
'id': instance.id,
'content': instance.content,
'files': instance.files.map((e) => e.toJson()).toList(),
'role': const ThinkingThoughtRoleConverter().toJson(instance.role),
'sequence_id': instance.sequenceId,
'sequence': instance.sequence?.toJson(),
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
};

View File

@@ -211,3 +211,44 @@ sealed class SnWalletFundRecipient with _$SnWalletFundRecipient {
factory SnWalletFundRecipient.fromJson(Map<String, dynamic> json) =>
_$SnWalletFundRecipientFromJson(json);
}
@freezed
sealed class SnLotteryTicket with _$SnLotteryTicket {
const factory SnLotteryTicket({
required String id,
required String accountId,
required SnAccount? account,
required List<int> regionOneNumbers,
required int regionTwoNumber,
required int multiplier,
required int drawStatus,
required DateTime? drawDate,
required List<int>? matchedRegionOneNumbers,
required int? matchedRegionTwoNumber,
required DateTime createdAt,
required DateTime updatedAt,
required DateTime? deletedAt,
}) = _SnLotteryTicket;
factory SnLotteryTicket.fromJson(Map<String, dynamic> json) =>
_$SnLotteryTicketFromJson(json);
}
@freezed
sealed class SnLotteryRecord with _$SnLotteryRecord {
const factory SnLotteryRecord({
required String id,
required DateTime drawDate,
required List<int> winningRegionOneNumbers,
required int winningRegionTwoNumber,
required int totalTickets,
required int totalPrizesAwarded,
required double totalPrizeAmount,
required DateTime createdAt,
required DateTime updatedAt,
required DateTime? deletedAt,
}) = _SnLotteryRecord;
factory SnLotteryRecord.fromJson(Map<String, dynamic> json) =>
_$SnLotteryRecordFromJson(json);
}

View File

@@ -3184,4 +3184,625 @@ $SnAccountCopyWith<$Res>? get recipientAccount {
}
}
/// @nodoc
mixin _$SnLotteryTicket {
String get id; String get accountId; SnAccount? get account; List<int> get regionOneNumbers; int get regionTwoNumber; int get multiplier; int get drawStatus; DateTime? get drawDate; List<int>? get matchedRegionOneNumbers; int? get matchedRegionTwoNumber; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
/// Create a copy of SnLotteryTicket
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$SnLotteryTicketCopyWith<SnLotteryTicket> get copyWith => _$SnLotteryTicketCopyWithImpl<SnLotteryTicket>(this as SnLotteryTicket, _$identity);
/// Serializes this SnLotteryTicket to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnLotteryTicket&&(identical(other.id, id) || other.id == id)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.account, account) || other.account == account)&&const DeepCollectionEquality().equals(other.regionOneNumbers, regionOneNumbers)&&(identical(other.regionTwoNumber, regionTwoNumber) || other.regionTwoNumber == regionTwoNumber)&&(identical(other.multiplier, multiplier) || other.multiplier == multiplier)&&(identical(other.drawStatus, drawStatus) || other.drawStatus == drawStatus)&&(identical(other.drawDate, drawDate) || other.drawDate == drawDate)&&const DeepCollectionEquality().equals(other.matchedRegionOneNumbers, matchedRegionOneNumbers)&&(identical(other.matchedRegionTwoNumber, matchedRegionTwoNumber) || other.matchedRegionTwoNumber == matchedRegionTwoNumber)&&(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)
@override
int get hashCode => Object.hash(runtimeType,id,accountId,account,const DeepCollectionEquality().hash(regionOneNumbers),regionTwoNumber,multiplier,drawStatus,drawDate,const DeepCollectionEquality().hash(matchedRegionOneNumbers),matchedRegionTwoNumber,createdAt,updatedAt,deletedAt);
@override
String toString() {
return 'SnLotteryTicket(id: $id, accountId: $accountId, account: $account, regionOneNumbers: $regionOneNumbers, regionTwoNumber: $regionTwoNumber, multiplier: $multiplier, drawStatus: $drawStatus, drawDate: $drawDate, matchedRegionOneNumbers: $matchedRegionOneNumbers, matchedRegionTwoNumber: $matchedRegionTwoNumber, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
}
/// @nodoc
abstract mixin class $SnLotteryTicketCopyWith<$Res> {
factory $SnLotteryTicketCopyWith(SnLotteryTicket value, $Res Function(SnLotteryTicket) _then) = _$SnLotteryTicketCopyWithImpl;
@useResult
$Res call({
String id, String accountId, SnAccount? account, List<int> regionOneNumbers, int regionTwoNumber, int multiplier, int drawStatus, DateTime? drawDate, List<int>? matchedRegionOneNumbers, int? matchedRegionTwoNumber, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
$SnAccountCopyWith<$Res>? get account;
}
/// @nodoc
class _$SnLotteryTicketCopyWithImpl<$Res>
implements $SnLotteryTicketCopyWith<$Res> {
_$SnLotteryTicketCopyWithImpl(this._self, this._then);
final SnLotteryTicket _self;
final $Res Function(SnLotteryTicket) _then;
/// Create a copy of SnLotteryTicket
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? accountId = null,Object? account = freezed,Object? regionOneNumbers = null,Object? regionTwoNumber = null,Object? multiplier = null,Object? drawStatus = null,Object? drawDate = freezed,Object? matchedRegionOneNumbers = freezed,Object? matchedRegionTwoNumber = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
as String,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
as SnAccount?,regionOneNumbers: null == regionOneNumbers ? _self.regionOneNumbers : regionOneNumbers // ignore: cast_nullable_to_non_nullable
as List<int>,regionTwoNumber: null == regionTwoNumber ? _self.regionTwoNumber : regionTwoNumber // ignore: cast_nullable_to_non_nullable
as int,multiplier: null == multiplier ? _self.multiplier : multiplier // ignore: cast_nullable_to_non_nullable
as int,drawStatus: null == drawStatus ? _self.drawStatus : drawStatus // ignore: cast_nullable_to_non_nullable
as int,drawDate: freezed == drawDate ? _self.drawDate : drawDate // ignore: cast_nullable_to_non_nullable
as DateTime?,matchedRegionOneNumbers: freezed == matchedRegionOneNumbers ? _self.matchedRegionOneNumbers : matchedRegionOneNumbers // ignore: cast_nullable_to_non_nullable
as List<int>?,matchedRegionTwoNumber: freezed == matchedRegionTwoNumber ? _self.matchedRegionTwoNumber : matchedRegionTwoNumber // 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,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,
));
}
/// Create a copy of SnLotteryTicket
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnAccountCopyWith<$Res>? get account {
if (_self.account == null) {
return null;
}
return $SnAccountCopyWith<$Res>(_self.account!, (value) {
return _then(_self.copyWith(account: value));
});
}
}
/// Adds pattern-matching-related methods to [SnLotteryTicket].
extension SnLotteryTicketPatterns on SnLotteryTicket {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _SnLotteryTicket value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _SnLotteryTicket() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _SnLotteryTicket value) $default,){
final _that = this;
switch (_that) {
case _SnLotteryTicket():
return $default(_that);}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _SnLotteryTicket value)? $default,){
final _that = this;
switch (_that) {
case _SnLotteryTicket() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String accountId, SnAccount? account, List<int> regionOneNumbers, int regionTwoNumber, int multiplier, int drawStatus, DateTime? drawDate, List<int>? matchedRegionOneNumbers, int? matchedRegionTwoNumber, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnLotteryTicket() when $default != null:
return $default(_that.id,_that.accountId,_that.account,_that.regionOneNumbers,_that.regionTwoNumber,_that.multiplier,_that.drawStatus,_that.drawDate,_that.matchedRegionOneNumbers,_that.matchedRegionTwoNumber,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String accountId, SnAccount? account, List<int> regionOneNumbers, int regionTwoNumber, int multiplier, int drawStatus, DateTime? drawDate, List<int>? matchedRegionOneNumbers, int? matchedRegionTwoNumber, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
switch (_that) {
case _SnLotteryTicket():
return $default(_that.id,_that.accountId,_that.account,_that.regionOneNumbers,_that.regionTwoNumber,_that.multiplier,_that.drawStatus,_that.drawDate,_that.matchedRegionOneNumbers,_that.matchedRegionTwoNumber,_that.createdAt,_that.updatedAt,_that.deletedAt);}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String accountId, SnAccount? account, List<int> regionOneNumbers, int regionTwoNumber, int multiplier, int drawStatus, DateTime? drawDate, List<int>? matchedRegionOneNumbers, int? matchedRegionTwoNumber, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
switch (_that) {
case _SnLotteryTicket() when $default != null:
return $default(_that.id,_that.accountId,_that.account,_that.regionOneNumbers,_that.regionTwoNumber,_that.multiplier,_that.drawStatus,_that.drawDate,_that.matchedRegionOneNumbers,_that.matchedRegionTwoNumber,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _SnLotteryTicket implements SnLotteryTicket {
const _SnLotteryTicket({required this.id, required this.accountId, required this.account, required final List<int> regionOneNumbers, required this.regionTwoNumber, required this.multiplier, required this.drawStatus, required this.drawDate, required final List<int>? matchedRegionOneNumbers, required this.matchedRegionTwoNumber, required this.createdAt, required this.updatedAt, required this.deletedAt}): _regionOneNumbers = regionOneNumbers,_matchedRegionOneNumbers = matchedRegionOneNumbers;
factory _SnLotteryTicket.fromJson(Map<String, dynamic> json) => _$SnLotteryTicketFromJson(json);
@override final String id;
@override final String accountId;
@override final SnAccount? account;
final List<int> _regionOneNumbers;
@override List<int> get regionOneNumbers {
if (_regionOneNumbers is EqualUnmodifiableListView) return _regionOneNumbers;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_regionOneNumbers);
}
@override final int regionTwoNumber;
@override final int multiplier;
@override final int drawStatus;
@override final DateTime? drawDate;
final List<int>? _matchedRegionOneNumbers;
@override List<int>? get matchedRegionOneNumbers {
final value = _matchedRegionOneNumbers;
if (value == null) return null;
if (_matchedRegionOneNumbers is EqualUnmodifiableListView) return _matchedRegionOneNumbers;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(value);
}
@override final int? matchedRegionTwoNumber;
@override final DateTime createdAt;
@override final DateTime updatedAt;
@override final DateTime? deletedAt;
/// Create a copy of SnLotteryTicket
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$SnLotteryTicketCopyWith<_SnLotteryTicket> get copyWith => __$SnLotteryTicketCopyWithImpl<_SnLotteryTicket>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$SnLotteryTicketToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnLotteryTicket&&(identical(other.id, id) || other.id == id)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.account, account) || other.account == account)&&const DeepCollectionEquality().equals(other._regionOneNumbers, _regionOneNumbers)&&(identical(other.regionTwoNumber, regionTwoNumber) || other.regionTwoNumber == regionTwoNumber)&&(identical(other.multiplier, multiplier) || other.multiplier == multiplier)&&(identical(other.drawStatus, drawStatus) || other.drawStatus == drawStatus)&&(identical(other.drawDate, drawDate) || other.drawDate == drawDate)&&const DeepCollectionEquality().equals(other._matchedRegionOneNumbers, _matchedRegionOneNumbers)&&(identical(other.matchedRegionTwoNumber, matchedRegionTwoNumber) || other.matchedRegionTwoNumber == matchedRegionTwoNumber)&&(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)
@override
int get hashCode => Object.hash(runtimeType,id,accountId,account,const DeepCollectionEquality().hash(_regionOneNumbers),regionTwoNumber,multiplier,drawStatus,drawDate,const DeepCollectionEquality().hash(_matchedRegionOneNumbers),matchedRegionTwoNumber,createdAt,updatedAt,deletedAt);
@override
String toString() {
return 'SnLotteryTicket(id: $id, accountId: $accountId, account: $account, regionOneNumbers: $regionOneNumbers, regionTwoNumber: $regionTwoNumber, multiplier: $multiplier, drawStatus: $drawStatus, drawDate: $drawDate, matchedRegionOneNumbers: $matchedRegionOneNumbers, matchedRegionTwoNumber: $matchedRegionTwoNumber, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
}
/// @nodoc
abstract mixin class _$SnLotteryTicketCopyWith<$Res> implements $SnLotteryTicketCopyWith<$Res> {
factory _$SnLotteryTicketCopyWith(_SnLotteryTicket value, $Res Function(_SnLotteryTicket) _then) = __$SnLotteryTicketCopyWithImpl;
@override @useResult
$Res call({
String id, String accountId, SnAccount? account, List<int> regionOneNumbers, int regionTwoNumber, int multiplier, int drawStatus, DateTime? drawDate, List<int>? matchedRegionOneNumbers, int? matchedRegionTwoNumber, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
@override $SnAccountCopyWith<$Res>? get account;
}
/// @nodoc
class __$SnLotteryTicketCopyWithImpl<$Res>
implements _$SnLotteryTicketCopyWith<$Res> {
__$SnLotteryTicketCopyWithImpl(this._self, this._then);
final _SnLotteryTicket _self;
final $Res Function(_SnLotteryTicket) _then;
/// Create a copy of SnLotteryTicket
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? accountId = null,Object? account = freezed,Object? regionOneNumbers = null,Object? regionTwoNumber = null,Object? multiplier = null,Object? drawStatus = null,Object? drawDate = freezed,Object? matchedRegionOneNumbers = freezed,Object? matchedRegionTwoNumber = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
return _then(_SnLotteryTicket(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
as String,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
as SnAccount?,regionOneNumbers: null == regionOneNumbers ? _self._regionOneNumbers : regionOneNumbers // ignore: cast_nullable_to_non_nullable
as List<int>,regionTwoNumber: null == regionTwoNumber ? _self.regionTwoNumber : regionTwoNumber // ignore: cast_nullable_to_non_nullable
as int,multiplier: null == multiplier ? _self.multiplier : multiplier // ignore: cast_nullable_to_non_nullable
as int,drawStatus: null == drawStatus ? _self.drawStatus : drawStatus // ignore: cast_nullable_to_non_nullable
as int,drawDate: freezed == drawDate ? _self.drawDate : drawDate // ignore: cast_nullable_to_non_nullable
as DateTime?,matchedRegionOneNumbers: freezed == matchedRegionOneNumbers ? _self._matchedRegionOneNumbers : matchedRegionOneNumbers // ignore: cast_nullable_to_non_nullable
as List<int>?,matchedRegionTwoNumber: freezed == matchedRegionTwoNumber ? _self.matchedRegionTwoNumber : matchedRegionTwoNumber // 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,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,
));
}
/// Create a copy of SnLotteryTicket
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnAccountCopyWith<$Res>? get account {
if (_self.account == null) {
return null;
}
return $SnAccountCopyWith<$Res>(_self.account!, (value) {
return _then(_self.copyWith(account: value));
});
}
}
/// @nodoc
mixin _$SnLotteryRecord {
String get id; DateTime get drawDate; List<int> get winningRegionOneNumbers; int get winningRegionTwoNumber; int get totalTickets; int get totalPrizesAwarded; double get totalPrizeAmount; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
/// Create a copy of SnLotteryRecord
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$SnLotteryRecordCopyWith<SnLotteryRecord> get copyWith => _$SnLotteryRecordCopyWithImpl<SnLotteryRecord>(this as SnLotteryRecord, _$identity);
/// Serializes this SnLotteryRecord to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnLotteryRecord&&(identical(other.id, id) || other.id == id)&&(identical(other.drawDate, drawDate) || other.drawDate == drawDate)&&const DeepCollectionEquality().equals(other.winningRegionOneNumbers, winningRegionOneNumbers)&&(identical(other.winningRegionTwoNumber, winningRegionTwoNumber) || other.winningRegionTwoNumber == winningRegionTwoNumber)&&(identical(other.totalTickets, totalTickets) || other.totalTickets == totalTickets)&&(identical(other.totalPrizesAwarded, totalPrizesAwarded) || other.totalPrizesAwarded == totalPrizesAwarded)&&(identical(other.totalPrizeAmount, totalPrizeAmount) || other.totalPrizeAmount == totalPrizeAmount)&&(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)
@override
int get hashCode => Object.hash(runtimeType,id,drawDate,const DeepCollectionEquality().hash(winningRegionOneNumbers),winningRegionTwoNumber,totalTickets,totalPrizesAwarded,totalPrizeAmount,createdAt,updatedAt,deletedAt);
@override
String toString() {
return 'SnLotteryRecord(id: $id, drawDate: $drawDate, winningRegionOneNumbers: $winningRegionOneNumbers, winningRegionTwoNumber: $winningRegionTwoNumber, totalTickets: $totalTickets, totalPrizesAwarded: $totalPrizesAwarded, totalPrizeAmount: $totalPrizeAmount, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
}
/// @nodoc
abstract mixin class $SnLotteryRecordCopyWith<$Res> {
factory $SnLotteryRecordCopyWith(SnLotteryRecord value, $Res Function(SnLotteryRecord) _then) = _$SnLotteryRecordCopyWithImpl;
@useResult
$Res call({
String id, DateTime drawDate, List<int> winningRegionOneNumbers, int winningRegionTwoNumber, int totalTickets, int totalPrizesAwarded, double totalPrizeAmount, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
}
/// @nodoc
class _$SnLotteryRecordCopyWithImpl<$Res>
implements $SnLotteryRecordCopyWith<$Res> {
_$SnLotteryRecordCopyWithImpl(this._self, this._then);
final SnLotteryRecord _self;
final $Res Function(SnLotteryRecord) _then;
/// Create a copy of SnLotteryRecord
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? drawDate = null,Object? winningRegionOneNumbers = null,Object? winningRegionTwoNumber = null,Object? totalTickets = null,Object? totalPrizesAwarded = null,Object? totalPrizeAmount = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,drawDate: null == drawDate ? _self.drawDate : drawDate // ignore: cast_nullable_to_non_nullable
as DateTime,winningRegionOneNumbers: null == winningRegionOneNumbers ? _self.winningRegionOneNumbers : winningRegionOneNumbers // ignore: cast_nullable_to_non_nullable
as List<int>,winningRegionTwoNumber: null == winningRegionTwoNumber ? _self.winningRegionTwoNumber : winningRegionTwoNumber // ignore: cast_nullable_to_non_nullable
as int,totalTickets: null == totalTickets ? _self.totalTickets : totalTickets // ignore: cast_nullable_to_non_nullable
as int,totalPrizesAwarded: null == totalPrizesAwarded ? _self.totalPrizesAwarded : totalPrizesAwarded // ignore: cast_nullable_to_non_nullable
as int,totalPrizeAmount: null == totalPrizeAmount ? _self.totalPrizeAmount : totalPrizeAmount // ignore: cast_nullable_to_non_nullable
as double,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,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,
));
}
}
/// Adds pattern-matching-related methods to [SnLotteryRecord].
extension SnLotteryRecordPatterns on SnLotteryRecord {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _SnLotteryRecord value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _SnLotteryRecord() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _SnLotteryRecord value) $default,){
final _that = this;
switch (_that) {
case _SnLotteryRecord():
return $default(_that);}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _SnLotteryRecord value)? $default,){
final _that = this;
switch (_that) {
case _SnLotteryRecord() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, DateTime drawDate, List<int> winningRegionOneNumbers, int winningRegionTwoNumber, int totalTickets, int totalPrizesAwarded, double totalPrizeAmount, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnLotteryRecord() when $default != null:
return $default(_that.id,_that.drawDate,_that.winningRegionOneNumbers,_that.winningRegionTwoNumber,_that.totalTickets,_that.totalPrizesAwarded,_that.totalPrizeAmount,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, DateTime drawDate, List<int> winningRegionOneNumbers, int winningRegionTwoNumber, int totalTickets, int totalPrizesAwarded, double totalPrizeAmount, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
switch (_that) {
case _SnLotteryRecord():
return $default(_that.id,_that.drawDate,_that.winningRegionOneNumbers,_that.winningRegionTwoNumber,_that.totalTickets,_that.totalPrizesAwarded,_that.totalPrizeAmount,_that.createdAt,_that.updatedAt,_that.deletedAt);}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, DateTime drawDate, List<int> winningRegionOneNumbers, int winningRegionTwoNumber, int totalTickets, int totalPrizesAwarded, double totalPrizeAmount, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
switch (_that) {
case _SnLotteryRecord() when $default != null:
return $default(_that.id,_that.drawDate,_that.winningRegionOneNumbers,_that.winningRegionTwoNumber,_that.totalTickets,_that.totalPrizesAwarded,_that.totalPrizeAmount,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _SnLotteryRecord implements SnLotteryRecord {
const _SnLotteryRecord({required this.id, required this.drawDate, required final List<int> winningRegionOneNumbers, required this.winningRegionTwoNumber, required this.totalTickets, required this.totalPrizesAwarded, required this.totalPrizeAmount, required this.createdAt, required this.updatedAt, required this.deletedAt}): _winningRegionOneNumbers = winningRegionOneNumbers;
factory _SnLotteryRecord.fromJson(Map<String, dynamic> json) => _$SnLotteryRecordFromJson(json);
@override final String id;
@override final DateTime drawDate;
final List<int> _winningRegionOneNumbers;
@override List<int> get winningRegionOneNumbers {
if (_winningRegionOneNumbers is EqualUnmodifiableListView) return _winningRegionOneNumbers;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_winningRegionOneNumbers);
}
@override final int winningRegionTwoNumber;
@override final int totalTickets;
@override final int totalPrizesAwarded;
@override final double totalPrizeAmount;
@override final DateTime createdAt;
@override final DateTime updatedAt;
@override final DateTime? deletedAt;
/// Create a copy of SnLotteryRecord
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$SnLotteryRecordCopyWith<_SnLotteryRecord> get copyWith => __$SnLotteryRecordCopyWithImpl<_SnLotteryRecord>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$SnLotteryRecordToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnLotteryRecord&&(identical(other.id, id) || other.id == id)&&(identical(other.drawDate, drawDate) || other.drawDate == drawDate)&&const DeepCollectionEquality().equals(other._winningRegionOneNumbers, _winningRegionOneNumbers)&&(identical(other.winningRegionTwoNumber, winningRegionTwoNumber) || other.winningRegionTwoNumber == winningRegionTwoNumber)&&(identical(other.totalTickets, totalTickets) || other.totalTickets == totalTickets)&&(identical(other.totalPrizesAwarded, totalPrizesAwarded) || other.totalPrizesAwarded == totalPrizesAwarded)&&(identical(other.totalPrizeAmount, totalPrizeAmount) || other.totalPrizeAmount == totalPrizeAmount)&&(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)
@override
int get hashCode => Object.hash(runtimeType,id,drawDate,const DeepCollectionEquality().hash(_winningRegionOneNumbers),winningRegionTwoNumber,totalTickets,totalPrizesAwarded,totalPrizeAmount,createdAt,updatedAt,deletedAt);
@override
String toString() {
return 'SnLotteryRecord(id: $id, drawDate: $drawDate, winningRegionOneNumbers: $winningRegionOneNumbers, winningRegionTwoNumber: $winningRegionTwoNumber, totalTickets: $totalTickets, totalPrizesAwarded: $totalPrizesAwarded, totalPrizeAmount: $totalPrizeAmount, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
}
/// @nodoc
abstract mixin class _$SnLotteryRecordCopyWith<$Res> implements $SnLotteryRecordCopyWith<$Res> {
factory _$SnLotteryRecordCopyWith(_SnLotteryRecord value, $Res Function(_SnLotteryRecord) _then) = __$SnLotteryRecordCopyWithImpl;
@override @useResult
$Res call({
String id, DateTime drawDate, List<int> winningRegionOneNumbers, int winningRegionTwoNumber, int totalTickets, int totalPrizesAwarded, double totalPrizeAmount, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
}
/// @nodoc
class __$SnLotteryRecordCopyWithImpl<$Res>
implements _$SnLotteryRecordCopyWith<$Res> {
__$SnLotteryRecordCopyWithImpl(this._self, this._then);
final _SnLotteryRecord _self;
final $Res Function(_SnLotteryRecord) _then;
/// Create a copy of SnLotteryRecord
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? drawDate = null,Object? winningRegionOneNumbers = null,Object? winningRegionTwoNumber = null,Object? totalTickets = null,Object? totalPrizesAwarded = null,Object? totalPrizeAmount = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
return _then(_SnLotteryRecord(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,drawDate: null == drawDate ? _self.drawDate : drawDate // ignore: cast_nullable_to_non_nullable
as DateTime,winningRegionOneNumbers: null == winningRegionOneNumbers ? _self._winningRegionOneNumbers : winningRegionOneNumbers // ignore: cast_nullable_to_non_nullable
as List<int>,winningRegionTwoNumber: null == winningRegionTwoNumber ? _self.winningRegionTwoNumber : winningRegionTwoNumber // ignore: cast_nullable_to_non_nullable
as int,totalTickets: null == totalTickets ? _self.totalTickets : totalTickets // ignore: cast_nullable_to_non_nullable
as int,totalPrizesAwarded: null == totalPrizesAwarded ? _self.totalPrizesAwarded : totalPrizesAwarded // ignore: cast_nullable_to_non_nullable
as int,totalPrizeAmount: null == totalPrizeAmount ? _self.totalPrizeAmount : totalPrizeAmount // ignore: cast_nullable_to_non_nullable
as double,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,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,
));
}
}
// dart format on

View File

@@ -414,3 +414,88 @@ Map<String, dynamic> _$SnWalletFundRecipientToJson(
'updated_at': instance.updatedAt.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
};
_SnLotteryTicket _$SnLotteryTicketFromJson(Map<String, dynamic> json) =>
_SnLotteryTicket(
id: json['id'] as String,
accountId: json['account_id'] as String,
account:
json['account'] == null
? null
: SnAccount.fromJson(json['account'] as Map<String, dynamic>),
regionOneNumbers:
(json['region_one_numbers'] as List<dynamic>)
.map((e) => (e as num).toInt())
.toList(),
regionTwoNumber: (json['region_two_number'] as num).toInt(),
multiplier: (json['multiplier'] as num).toInt(),
drawStatus: (json['draw_status'] as num).toInt(),
drawDate:
json['draw_date'] == null
? null
: DateTime.parse(json['draw_date'] as String),
matchedRegionOneNumbers:
(json['matched_region_one_numbers'] as List<dynamic>?)
?.map((e) => (e as num).toInt())
.toList(),
matchedRegionTwoNumber:
(json['matched_region_two_number'] as num?)?.toInt(),
createdAt: DateTime.parse(json['created_at'] as String),
updatedAt: DateTime.parse(json['updated_at'] as String),
deletedAt:
json['deleted_at'] == null
? null
: DateTime.parse(json['deleted_at'] as String),
);
Map<String, dynamic> _$SnLotteryTicketToJson(_SnLotteryTicket instance) =>
<String, dynamic>{
'id': instance.id,
'account_id': instance.accountId,
'account': instance.account?.toJson(),
'region_one_numbers': instance.regionOneNumbers,
'region_two_number': instance.regionTwoNumber,
'multiplier': instance.multiplier,
'draw_status': instance.drawStatus,
'draw_date': instance.drawDate?.toIso8601String(),
'matched_region_one_numbers': instance.matchedRegionOneNumbers,
'matched_region_two_number': instance.matchedRegionTwoNumber,
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
};
_SnLotteryRecord _$SnLotteryRecordFromJson(Map<String, dynamic> json) =>
_SnLotteryRecord(
id: json['id'] as String,
drawDate: DateTime.parse(json['draw_date'] as String),
winningRegionOneNumbers:
(json['winning_region_one_numbers'] as List<dynamic>)
.map((e) => (e as num).toInt())
.toList(),
winningRegionTwoNumber:
(json['winning_region_two_number'] as num).toInt(),
totalTickets: (json['total_tickets'] as num).toInt(),
totalPrizesAwarded: (json['total_prizes_awarded'] as num).toInt(),
totalPrizeAmount: (json['total_prize_amount'] as num).toDouble(),
createdAt: DateTime.parse(json['created_at'] as String),
updatedAt: DateTime.parse(json['updated_at'] as String),
deletedAt:
json['deleted_at'] == null
? null
: DateTime.parse(json['deleted_at'] as String),
);
Map<String, dynamic> _$SnLotteryRecordToJson(_SnLotteryRecord instance) =>
<String, dynamic>{
'id': instance.id,
'draw_date': instance.drawDate.toIso8601String(),
'winning_region_one_numbers': instance.winningRegionOneNumbers,
'winning_region_two_number': instance.winningRegionTwoNumber,
'total_tickets': instance.totalTickets,
'total_prizes_awarded': instance.totalPrizesAwarded,
'total_prize_amount': instance.totalPrizeAmount,
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
};

View File

@@ -433,7 +433,7 @@ Future<void> setRemoteActivityStatus(
) async {
final apiClient = ref.read(apiClientProvider);
await apiClient.post(
'/id/accounts/me/statuses',
'/pass/accounts/me/statuses',
data: {
'is_invisible': false,
'is_not_disturb': false,
@@ -448,7 +448,7 @@ Future<void> setRemoteActivityStatus(
Future<void> unsetRemoteActivityStatus(Ref ref, String appId) async {
final apiClient = ref.read(apiClientProvider);
await apiClient.delete(
'/id/accounts/me/statuses',
'/pass/accounts/me/statuses',
queryParameters: {'app': appId},
);
}

View File

@@ -44,7 +44,7 @@ Future<List<SnEventCalendarEntry>> eventCalendar(
) async {
final client = ref.watch(apiClientProvider);
final resp = await client.get(
'/id/accounts/${query.uname ?? 'me'}/calendar',
'/pass/accounts/${query.uname ?? 'me'}/calendar',
queryParameters: {'year': query.year, 'month': query.month},
);
return resp.data

View File

@@ -6,7 +6,7 @@ part of 'event_calendar.dart';
// RiverpodGenerator
// **************************************************************************
String _$eventCalendarHash() => r'72232fc044ac3c99b855dca37ff2f06a64be0afb';
String _$eventCalendarHash() => r'3a33581c28bcd44bc5eb3abdb770171b4d275a5d';
/// Copied from Dart SDK
class _SystemHash {

View File

@@ -114,9 +114,9 @@ final apiClientProvider = Provider<Dio>((ref) {
dio: dio,
retries: 3,
retryDelays: const [
Duration(seconds: 1),
Duration(seconds: 2),
Duration(seconds: 3),
Duration(milliseconds: 300),
Duration(milliseconds: 500),
Duration(milliseconds: 1000),
],
retryEvaluator: (err, _) => err.requestOptions.method == 'GET',
),

View File

@@ -88,6 +88,7 @@ ThemeData createAppTheme(Brightness brightness, AppSettings settings) {
color: colorScheme.surfaceContainer.withOpacity(
settings.cardTransparency,
),
elevation: settings.cardTransparency < 1 ? 0 : null,
),
pageTransitionsTheme: PageTransitionsTheme(
builders: {

View File

@@ -26,7 +26,7 @@ class UserInfoNotifier extends StateNotifier<AsyncValue<SnAccount?>> {
}
try {
final client = _ref.read(apiClientProvider);
final response = await client.get('/id/accounts/me');
final response = await client.get('/pass/accounts/me');
final user = SnAccount.fromJson(response.data);
state = AsyncValue.data(user);

View File

@@ -25,7 +25,6 @@ import 'package:island/screens/tabs.dart';
import 'package:island/screens/explore.dart';
import 'package:island/screens/discovery/article_detail.dart';
import 'package:island/screens/account.dart';
import 'package:island/screens/notification.dart';
import 'package:island/screens/wallet.dart';
import 'package:island/screens/account/relationship.dart';
import 'package:island/screens/account/profile.dart';
@@ -38,6 +37,7 @@ import 'package:island/screens/chat/room.dart';
import 'package:island/screens/chat/room_detail.dart';
import 'package:island/screens/chat/call.dart';
import 'package:island/screens/chat/search_messages.dart';
import 'package:island/screens/thought/think.dart';
import 'package:island/screens/creators/hub.dart';
import 'package:island/screens/creators/posts/post_manage_list.dart';
import 'package:island/screens/creators/stickers/stickers.dart';
@@ -132,6 +132,11 @@ final routerProvider = Provider<GoRouter>((ref) {
return CallScreen(roomId: id);
},
),
GoRoute(
name: 'thought',
path: '/thought',
builder: (context, state) => const ThoughtScreen(),
),
GoRoute(
name: 'logs',
path: '/logs',
@@ -392,11 +397,6 @@ final routerProvider = Provider<GoRouter>((ref) {
),
],
),
GoRoute(
name: 'notifications',
path: '/account/notifications',
builder: (context, state) => const NotificationScreen(),
),
GoRoute(
name: 'wallet',
path: '/account/wallet',

View File

@@ -203,7 +203,7 @@ class AccountScreen extends HookConsumerWidget {
],
).padding(horizontal: 16, vertical: 12),
onTap: () {
context.pushNamed('developerHub');
context.goNamed('developerHub');
},
),
).height(140),
@@ -282,7 +282,12 @@ class AccountScreen extends HookConsumerWidget {
],
),
onTap: () {
context.pushNamed('notifications');
showModalBottomSheet(
context: context,
isScrollControlled: true,
useRootNavigator: true,
builder: (context) => const NotificationSheet(),
);
},
),
ListTile(
@@ -378,7 +383,7 @@ class AccountScreen extends HookConsumerWidget {
onTap: () async {
final apiClient = ref.watch(apiClientProvider);
showLoadingModal(context);
await apiClient.delete('/id/accounts/me/sessions/current');
await apiClient.delete('/pass/accounts/me/sessions/current');
if (!context.mounted) return;
hideLoadingModal(context);
final userNotifier = ref.read(userInfoProvider.notifier);

View File

@@ -14,7 +14,7 @@ part 'credits.g.dart';
@riverpod
Future<double> socialCredits(Ref ref) async {
final client = ref.watch(apiClientProvider);
final response = await client.get('/id/accounts/me/credits');
final response = await client.get('/pass/accounts/me/credits');
if (response.statusCode != 200) {
throw Exception('Failed to load social credits');
}
@@ -39,7 +39,7 @@ class SocialCreditHistoryNotifier extends _$SocialCreditHistoryNotifier
final queryParams = {'offset': offset, 'take': _pageSize};
final response = await client.get(
'/id/accounts/me/credits/history',
'/pass/accounts/me/credits/history',
queryParameters: queryParams,
);
final total = int.parse(response.headers.value('X-Total') ?? '0');

View File

@@ -6,7 +6,7 @@ part of 'credits.dart';
// RiverpodGenerator
// **************************************************************************
String _$socialCreditsHash() => r'2599844e892127ee4d315caced5c10e4dbaea142';
String _$socialCreditsHash() => r'a0284583e94bc97285c689ac2bc018536932da69';
/// See also [socialCredits].
@ProviderFor(socialCredits)
@@ -25,7 +25,7 @@ final socialCreditsProvider = AutoDisposeFutureProvider<double>.internal(
// ignore: unused_element
typedef SocialCreditsRef = AutoDisposeFutureProviderRef<double>;
String _$socialCreditHistoryNotifierHash() =>
r'950db020754160f835c64cedf3fa2175e61e4d64';
r'3e87af246cc5dc72a1f3a87b81d1c87169bdfb5b';
/// See also [SocialCreditHistoryNotifier].
@ProviderFor(SocialCreditHistoryNotifier)

View File

@@ -34,7 +34,7 @@ class LevelingHistoryNotifier extends _$LevelingHistoryNotifier
final queryParams = {'offset': offset, 'take': _pageSize};
final response = await client.get(
'/id/accounts/me/leveling',
'/pass/accounts/me/leveling',
queryParameters: queryParams,
);
final total = int.parse(response.headers.value('X-Total') ?? '0');

View File

@@ -7,7 +7,7 @@ part of 'leveling.dart';
// **************************************************************************
String _$levelingHistoryNotifierHash() =>
r'e795f9b7911c9e50f15c095ea237cb0e87bf1e89';
r'de51012e1590ac46388b6f3f2050b21cb96698d1';
/// See also [LevelingHistoryNotifier].
@ProviderFor(LevelingHistoryNotifier)

View File

@@ -28,14 +28,14 @@ part 'account_settings.g.dart';
@riverpod
Future<List<SnAuthFactor>> authFactors(Ref ref) async {
final client = ref.read(apiClientProvider);
final res = await client.get('/id/accounts/me/factors');
final res = await client.get('/pass/accounts/me/factors');
return res.data.map<SnAuthFactor>((e) => SnAuthFactor.fromJson(e)).toList();
}
@riverpod
Future<List<SnContactMethod>> contactMethods(Ref ref) async {
final client = ref.read(apiClientProvider);
final resp = await client.get('/id/accounts/me/contacts');
final resp = await client.get('/pass/accounts/me/contacts');
return resp.data
.map<SnContactMethod>((e) => SnContactMethod.fromJson(e))
.toList();
@@ -44,7 +44,7 @@ Future<List<SnContactMethod>> contactMethods(Ref ref) async {
@riverpod
Future<List<SnAccountConnection>> accountConnections(Ref ref) async {
final client = ref.read(apiClientProvider);
final resp = await client.get('/id/accounts/me/connections');
final resp = await client.get('/pass/accounts/me/connections');
return resp.data
.map<SnAccountConnection>((e) => SnAccountConnection.fromJson(e))
.toList();
@@ -67,7 +67,7 @@ class AccountSettingsScreen extends HookConsumerWidget {
try {
showLoadingModal(context);
final client = ref.read(apiClientProvider);
await client.delete('/id/accounts/me');
await client.delete('/pass/accounts/me');
if (context.mounted) {
showSnackBar('accountDeletionSent'.tr());
}
@@ -93,7 +93,7 @@ class AccountSettingsScreen extends HookConsumerWidget {
final userInfo = ref.read(userInfoProvider);
final client = ref.read(apiClientProvider);
await client.post(
'/id/accounts/recovery/password',
'/pass/accounts/recovery/password',
data: {'account': userInfo.value!.name, 'captcha_token': captchaTk},
);
if (context.mounted) {

View File

@@ -6,7 +6,7 @@ part of 'account_settings.dart';
// RiverpodGenerator
// **************************************************************************
String _$authFactorsHash() => r'24fe2f7b375b019d87fc3b85cbedbe857f399c0f';
String _$authFactorsHash() => r'ed87d7dbd421fef0a5620416727c3dc598c97ef5';
/// See also [authFactors].
@ProviderFor(authFactors)
@@ -25,7 +25,7 @@ final authFactorsProvider =
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef AuthFactorsRef = AutoDisposeFutureProviderRef<List<SnAuthFactor>>;
String _$contactMethodsHash() => r'76a1a93f61c51c44b32b4821f5112d58406155f0';
String _$contactMethodsHash() => r'1d3d03e9ffbf36126236558ead22cb7d88bb9cb2';
/// See also [contactMethods].
@ProviderFor(contactMethods)
@@ -45,7 +45,7 @@ final contactMethodsProvider =
// ignore: unused_element
typedef ContactMethodsRef = AutoDisposeFutureProviderRef<List<SnContactMethod>>;
String _$accountConnectionsHash() =>
r'9f69e7f23e3e53c528d38b93d76f0c9efc9a83db';
r'33c10b98962ede6c428d4028c0d5f2f12ff0eb22';
/// See also [accountConnections].
@ProviderFor(accountConnections)

View File

@@ -87,7 +87,7 @@ class UpdateProfileScreen extends HookConsumerWidget {
}
final client = ref.watch(apiClientProvider);
await client.patch(
'/id/accounts/me/profile',
'/pass/accounts/me/profile',
data: {'${position}_id': cloudFile.id},
);
final userNotifier = ref.read(userInfoProvider.notifier);
@@ -114,7 +114,7 @@ class UpdateProfileScreen extends HookConsumerWidget {
try {
final client = ref.watch(apiClientProvider);
await client.patch(
'/id/accounts/me',
'/pass/accounts/me',
data: {
'name': usernameController.text,
'nick': nicknameController.text,
@@ -194,7 +194,7 @@ class UpdateProfileScreen extends HookConsumerWidget {
};
await client.patch(
'/id/accounts/me/profile',
'/pass/accounts/me/profile',
data: {
'bio': bioController.text,
'first_name': firstNameController.text,

View File

@@ -31,7 +31,7 @@ class AuthFactorSheet extends HookConsumerWidget {
try {
showLoadingModal(context);
final client = ref.read(apiClientProvider);
await client.delete('/id/accounts/me/factors/${factor.id}');
await client.delete('/pass/accounts/me/factors/${factor.id}');
if (context.mounted) Navigator.pop(context, true);
} catch (err) {
showErrorAlert(err);
@@ -49,7 +49,7 @@ class AuthFactorSheet extends HookConsumerWidget {
try {
showLoadingModal(context);
final client = ref.read(apiClientProvider);
await client.post('/id/accounts/me/factors/${factor.id}/disable');
await client.post('/pass/accounts/me/factors/${factor.id}/disable');
if (context.mounted) Navigator.pop(context, true);
} catch (err) {
showErrorAlert(err);
@@ -106,7 +106,7 @@ class AuthFactorSheet extends HookConsumerWidget {
showLoadingModal(context);
final client = ref.read(apiClientProvider);
await client.post(
'/id/accounts/me/factors/${factor.id}/enable',
'/pass/accounts/me/factors/${factor.id}/enable',
data: jsonEncode(password),
);
if (context.mounted) Navigator.pop(context, true);
@@ -193,7 +193,7 @@ class AuthFactorNewSheet extends HookConsumerWidget {
showLoadingModal(context);
final apiClient = ref.read(apiClientProvider);
final resp = await apiClient.post(
'/id/accounts/me/factors',
'/pass/accounts/me/factors',
data: {'type': factorType.value, 'secret': secretController.text},
);
final factor = SnAuthFactor.fromJson(resp.data);

View File

@@ -77,7 +77,7 @@ class AccountConnectionSheet extends HookConsumerWidget {
try {
showLoadingModal(context);
final client = ref.read(apiClientProvider);
await client.delete('/id/accounts/me/connections/${connection.id}');
await client.delete('/pass/accounts/me/connections/${connection.id}');
if (context.mounted) Navigator.pop(context, true);
} catch (err) {
showErrorAlert(err);
@@ -175,7 +175,7 @@ class AccountConnectionNewSheet extends HookConsumerWidget {
if (context.mounted) showLoadingModal(context);
await client.post(
'/id/auth/connect/apple/mobile',
'/pass/auth/connect/apple/mobile',
data: {
'identity_token': credential.identityToken!,
'authorization_code': credential.authorizationCode,
@@ -200,7 +200,7 @@ class AccountConnectionNewSheet extends HookConsumerWidget {
final serverUrl = ref.watch(serverUrlProvider);
final accessToken = ref.watch(tokenProvider);
launchUrlString(
'$serverUrl/id/auth/login/${selectedProvider.value}?tk=${accessToken!.token}',
'$serverUrl/pass/auth/login/${selectedProvider.value}?tk=${accessToken!.token}',
);
} else {
await Navigator.of(context, rootNavigator: true).push(
@@ -345,7 +345,7 @@ class AccountConnectionsSheet extends HookConsumerWidget {
try {
final client = ref.read(apiClientProvider);
await client.delete(
'/id/accounts/me/connections/${connection.id}',
'/pass/accounts/me/connections/${connection.id}',
);
ref.invalidate(accountConnectionsProvider);
return true;

View File

@@ -25,7 +25,7 @@ class ContactMethodSheet extends HookConsumerWidget {
try {
showLoadingModal(context);
final client = ref.read(apiClientProvider);
await client.delete('/id/accounts/me/contacts/${contact.id}');
await client.delete('/pass/accounts/me/contacts/${contact.id}');
if (context.mounted) Navigator.pop(context, true);
} catch (err) {
showErrorAlert(err);
@@ -38,7 +38,7 @@ class ContactMethodSheet extends HookConsumerWidget {
try {
showLoadingModal(context);
final client = ref.read(apiClientProvider);
await client.post('/id/accounts/me/contacts/${contact.id}/verify');
await client.post('/pass/accounts/me/contacts/${contact.id}/verify');
if (context.mounted) {
showSnackBar('contactMethodVerificationSent'.tr());
}
@@ -53,7 +53,7 @@ class ContactMethodSheet extends HookConsumerWidget {
try {
showLoadingModal(context);
final client = ref.read(apiClientProvider);
await client.post('/id/accounts/me/contacts/${contact.id}/primary');
await client.post('/pass/accounts/me/contacts/${contact.id}/primary');
if (context.mounted) Navigator.pop(context, true);
} catch (err) {
showErrorAlert(err);
@@ -66,7 +66,7 @@ class ContactMethodSheet extends HookConsumerWidget {
try {
showLoadingModal(context);
final client = ref.read(apiClientProvider);
await client.post('/id/accounts/me/contacts/${contact.id}/public');
await client.post('/pass/accounts/me/contacts/${contact.id}/public');
if (context.mounted) Navigator.pop(context, true);
} catch (err) {
showErrorAlert(err);
@@ -79,7 +79,7 @@ class ContactMethodSheet extends HookConsumerWidget {
try {
showLoadingModal(context);
final client = ref.read(apiClientProvider);
await client.delete('/id/accounts/me/contacts/${contact.id}/public');
await client.delete('/pass/accounts/me/contacts/${contact.id}/public');
if (context.mounted) Navigator.pop(context, true);
} catch (err) {
showErrorAlert(err);
@@ -221,7 +221,7 @@ class ContactMethodNewSheet extends HookConsumerWidget {
showLoadingModal(context);
final apiClient = ref.read(apiClientProvider);
await apiClient.post(
'/id/accounts/me/contacts',
'/pass/accounts/me/contacts',
data: {'type': contactType.value, 'content': contentController.text},
);
if (context.mounted) {

View File

@@ -561,14 +561,14 @@ Future<SnAccount> account(Ref ref, String uname) async {
}
}
final apiClient = ref.watch(apiClientProvider);
final resp = await apiClient.get("/id/accounts/$uname");
final resp = await apiClient.get("/pass/accounts/$uname");
return SnAccount.fromJson(resp.data);
}
@riverpod
Future<List<SnAccountBadge>> accountBadges(Ref ref, String uname) async {
final apiClient = ref.watch(apiClientProvider);
final resp = await apiClient.get("/id/accounts/$uname/badges");
final resp = await apiClient.get("/pass/accounts/$uname/badges");
return List<SnAccountBadge>.from(
resp.data.map((x) => SnAccountBadge.fromJson(x)),
);
@@ -617,7 +617,7 @@ Future<SnRelationship?> accountRelationship(Ref ref, String uname) async {
final account = await ref.watch(accountProvider(uname).future);
final apiClient = ref.watch(apiClientProvider);
try {
final resp = await apiClient.get("/id/relationships/${account.id}");
final resp = await apiClient.get("/pass/relationships/${account.id}");
return SnRelationship.fromJson(resp.data);
} catch (err) {
if (err is DioException && err.response?.statusCode == 404) {
@@ -690,7 +690,7 @@ class AccountProfileScreen extends HookConsumerWidget {
showLoadingModal(context);
try {
final client = ref.watch(apiClientProvider);
await client.post('/id/relationships/${account.value!.id}/friends');
await client.post('/pass/relationships/${account.value!.id}/friends');
ref.invalidate(accountRelationshipProvider(name));
} catch (err) {
showErrorAlert(err);
@@ -704,9 +704,9 @@ class AccountProfileScreen extends HookConsumerWidget {
try {
final client = ref.watch(apiClientProvider);
if (accountRelationship.value == null) {
await client.post('/id/relationships/${account.value!.id}/block');
await client.post('/pass/relationships/${account.value!.id}/block');
} else {
await client.delete('/id/relationships/${account.value!.id}/block');
await client.delete('/pass/relationships/${account.value!.id}/block');
}
ref.invalidate(accountRelationshipProvider(name));
} catch (err) {

View File

@@ -6,7 +6,7 @@ part of 'profile.dart';
// RiverpodGenerator
// **************************************************************************
String _$accountHash() => r'ce7264a04f69e32a5cb07bc10ca5fa47ae1fddaa';
String _$accountHash() => r'5e2b7bd59151b4638a5561f495537c259f767123';
/// Copied from Dart SDK
class _SystemHash {
@@ -145,7 +145,7 @@ class _AccountProviderElement
String get uname => (origin as AccountProvider).uname;
}
String _$accountBadgesHash() => r'1de05e122c23ff2c6ac6d318977165761e2ad177';
String _$accountBadgesHash() => r'68db63f49827020beecbdbf20529520d0cd14a7d';
/// See also [accountBadges].
@ProviderFor(accountBadges)
@@ -517,7 +517,7 @@ class _AccountDirectChatProviderElement
}
String _$accountRelationshipHash() =>
r'9a3a4e8c6c6706f73df95feccb86736fcad33f30';
r'319f743261b113a1d3c6a397d48d13c858312669';
/// See also [accountRelationship].
@ProviderFor(accountRelationship)

View File

@@ -21,7 +21,7 @@ part 'relationship.g.dart';
@riverpod
Future<List<SnRelationship>> sentFriendRequest(Ref ref) async {
final client = ref.read(apiClientProvider);
final resp = await client.get('/id/relationships/requests');
final resp = await client.get('/pass/relationships/requests');
return resp.data
.map((e) => SnRelationship.fromJson(e))
.cast<SnRelationship>()
@@ -43,7 +43,7 @@ class RelationshipListNotifier extends _$RelationshipListNotifier
final take = 20;
final response = await client.get(
'/id/relationships',
'/pass/relationships',
queryParameters: {'offset': offset, 'take': take},
);
@@ -226,7 +226,7 @@ class RelationshipScreen extends HookConsumerWidget {
if (result == null) return;
final client = ref.read(apiClientProvider);
await client.post('/id/relationships/${result.id}/friends');
await client.post('/pass/relationships/${result.id}/friends');
ref.invalidate(sentFriendRequestProvider);
}
@@ -240,7 +240,7 @@ class RelationshipScreen extends HookConsumerWidget {
submitting.value = true;
final client = ref.read(apiClientProvider);
await client.post(
'/id/relationships/${relationship.accountId}/friends/${isAccept ? 'accept' : 'decline'}',
'/pass/relationships/${relationship.accountId}/friends/${isAccept ? 'accept' : 'decline'}',
);
relationshipNotifier.forceRefresh();
if (!context.mounted) return;
@@ -267,7 +267,7 @@ class RelationshipScreen extends HookConsumerWidget {
) async {
final client = ref.read(apiClientProvider);
await client.patch(
'/id/relationships/${relationship.accountId}',
'/pass/relationships/${relationship.accountId}',
data: {'status': newStatus},
);
relationshipNotifier.forceRefresh();
@@ -350,7 +350,7 @@ class _SentFriendRequestsSheet extends HookConsumerWidget {
Future<void> cancelRequest(SnRelationship request) async {
try {
final client = ref.read(apiClientProvider);
await client.delete('/id/relationships/${request.relatedId}/friends');
await client.delete('/pass/relationships/${request.relatedId}/friends');
ref.invalidate(sentFriendRequestProvider);
} catch (err) {
showErrorAlert(err);

View File

@@ -6,7 +6,7 @@ part of 'relationship.dart';
// RiverpodGenerator
// **************************************************************************
String _$sentFriendRequestHash() => r'dc02ace6cb755a01ab862c9fcff3b26de7f946cb';
String _$sentFriendRequestHash() => r'0c52813eb6f86c05f6e0b1e4e840d0d9c350aa9e';
/// See also [sentFriendRequest].
@ProviderFor(sentFriendRequest)
@@ -27,7 +27,7 @@ final sentFriendRequestProvider =
typedef SentFriendRequestRef =
AutoDisposeFutureProviderRef<List<SnRelationship>>;
String _$relationshipListNotifierHash() =>
r'0a134ce69489a4f2002d2223853855b6f22e4e9f';
r'fc46920256f7c48445c00652165e879890f2c9a3';
/// See also [RelationshipListNotifier].
@ProviderFor(RelationshipListNotifier)

View File

@@ -49,7 +49,7 @@ class CreateAccountScreen extends HookConsumerWidget {
showLoadingModal(context);
final client = ref.watch(apiClientProvider);
await client.post(
'/id/accounts',
'/pass/accounts',
data: {
'name': usernameController.text,
'nick': nicknameController.text,

View File

@@ -175,7 +175,7 @@ class _LoginCheckScreen extends HookConsumerWidget {
// Get token if challenge is completed
final client = ref.watch(apiClientProvider);
final tokenResp = await client.post(
'/id/auth/token',
'/pass/auth/token',
data: {
'grant_type': 'authorization_code',
'code': code ?? challenge!.id,
@@ -241,7 +241,7 @@ class _LoginCheckScreen extends HookConsumerWidget {
// Pass challenge
final client = ref.watch(apiClientProvider);
final resp = await client.patch(
'/id/auth/challenge/${challenge!.id}',
'/pass/auth/challenge/${challenge!.id}',
data: {'factor_id': factor!.id, 'password': pwd},
);
final result = SnAuthChallenge.fromJson(resp.data);
@@ -388,7 +388,7 @@ class _LoginPickerScreen extends HookConsumerWidget {
try {
await client.post(
'/id/auth/challenge/${challenge!.id}/factors/${factorPicked.value!.id}',
'/pass/auth/challenge/${challenge!.id}/factors/${factorPicked.value!.id}',
data:
hintController.text.isNotEmpty
? jsonEncode(hintController.text)
@@ -531,7 +531,7 @@ class _LoginLookupScreen extends HookConsumerWidget {
try {
final client = ref.watch(apiClientProvider);
await client.post(
'/id/accounts/recovery/password',
'/pass/accounts/recovery/password',
data: {'account': uname, 'captcha_token': captchaTk},
);
showInfoAlert('loginResetPasswordSent'.tr(), 'done'.tr());
@@ -549,7 +549,7 @@ class _LoginLookupScreen extends HookConsumerWidget {
try {
final client = ref.watch(apiClientProvider);
final resp = await client.post(
'/id/auth/challenge',
'/pass/auth/challenge',
data: {
'account': uname,
'device_id': await getUdid(),
@@ -570,7 +570,7 @@ class _LoginLookupScreen extends HookConsumerWidget {
final result = SnAuthChallenge.fromJson(resp.data);
onChallenge(result);
final factorResp = await client.get(
'/id/auth/challenge/${result.id}/factors',
'/pass/auth/challenge/${result.id}/factors',
);
onFactor(
List<SnAuthFactor>.from(
@@ -599,7 +599,7 @@ class _LoginLookupScreen extends HookConsumerWidget {
if (context.mounted) showLoadingModal(context);
final resp = await client.post(
'/id/auth/login/apple/mobile',
'/pass/auth/login/apple/mobile',
data: {
'identity_token': credential.identityToken!,
'authorization_code': credential.authorizationCode,
@@ -611,7 +611,7 @@ class _LoginLookupScreen extends HookConsumerWidget {
final challenge = SnAuthChallenge.fromJson(resp.data);
onChallenge(challenge);
final factorResp = await client.get(
'/id/auth/challenge/${challenge.id}/factors',
'/pass/auth/challenge/${challenge.id}/factors',
);
onFactor(
List<SnAuthFactor>.from(
@@ -636,11 +636,11 @@ class _LoginLookupScreen extends HookConsumerWidget {
final client = ref.watch(apiClientProvider);
try {
final resp = await client.get('/id/auth/challenge/$challengeId');
final resp = await client.get('/pass/auth/challenge/$challengeId');
final challenge = SnAuthChallenge.fromJson(resp.data);
onChallenge(challenge);
final factorResp = await client.get(
'/id/auth/challenge/${challenge.id}/factors',
'/pass/auth/challenge/${challenge.id}/factors',
);
onFactor(
List<SnAuthFactor>.from(

View File

@@ -80,7 +80,9 @@ class _OidcScreenState extends ConsumerState<OidcScreen> {
: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36',
),
initialUrlRequest: URLRequest(
url: WebUri('$serverUrl/id/auth/login/${widget.provider}'),
url: WebUri(
'$serverUrl/pass/auth/login/${widget.provider}',
),
headers: {
if (token?.token.isNotEmpty ?? false)
'Authorization': 'AtField ${token!.token}',

View File

@@ -522,7 +522,7 @@ class CreatorHubScreen extends HookConsumerWidget {
return AppScaffold(
isNoBackground: false,
appBar: AppBar(
leading: const PageBackButton(),
leading: const PageBackButton(backTo: '/account'),
title: Text('creatorHub').tr(),
actions: [
if (!isWideScreen(context))

View File

@@ -181,7 +181,7 @@ class _ConsoleAppBar extends StatelessWidget implements PreferredSizeWidget {
@override
Widget build(BuildContext context) {
return AppBar(
leading: const PageBackButton(),
leading: const PageBackButton(backTo: '/account'),
title: Text('developerHub').tr(),
actions: [
if (currentProject != null)

View File

@@ -20,6 +20,7 @@ class ArticleDetailScreen extends ConsumerWidget {
final articleAsync = ref.watch(articleDetailProvider(articleId));
return AppScaffold(
isNoBackground: false,
body: articleAsync.when(
data:
(article) => AppScaffold(

View File

@@ -19,7 +19,6 @@ import 'package:island/widgets/check_in.dart';
import 'package:island/widgets/post/post_featured.dart';
import 'package:island/widgets/post/post_item.dart';
import 'package:island/widgets/post/compose_card.dart';
import 'package:island/widgets/post/compose_dialog.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';
@@ -54,7 +53,12 @@ Widget notificationIndicatorWidget(
trailing: const Icon(Symbols.chevron_right),
contentPadding: EdgeInsets.only(left: 16, right: 15),
onTap: () {
GoRouter.of(context).pushNamed('notifications');
showModalBottomSheet(
context: context,
isScrollControlled: true,
useRootNavigator: true,
builder: (context) => const NotificationSheet(),
);
},
),
);
@@ -86,10 +90,6 @@ class ExploreScreen extends HookConsumerWidget {
return () => tabController.removeListener(listener);
}, [tabController]);
final activitiesNotifier = ref.watch(
activityListNotifierProvider(currentFilter.value).notifier,
);
final now = DateTime.now();
final query = useState(
@@ -208,27 +208,6 @@ class ExploreScreen extends HookConsumerWidget {
return AppScaffold(
isNoBackground: false,
floatingActionButton:
isWide
? null
: InkWell(
onLongPress: () async {
final result = await PostComposeDialog.show(context);
if (result != null) {
activitiesNotifier.forceRefresh();
}
},
child: FloatingActionButton(
heroTag: Key("explore-page-fab"),
onPressed: () async {
final result = await PostComposeDialog.show(context);
if (result != null) {
activitiesNotifier.forceRefresh();
}
},
child: const Icon(Symbols.edit),
),
),
body:
isWide
? _buildWideBody(
@@ -329,11 +308,7 @@ class ExploreScreen extends HookConsumerWidget {
margin: EdgeInsets.zero,
),
PostFeaturedList(),
PostComposeCard(
onSubmit: (post) {
activitiesNotifier.forceRefresh();
},
),
const PostComposeCard(),
],
),
),

829
lib/screens/lottery.dart Normal file
View File

@@ -0,0 +1,829 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/wallet.dart';
import 'package:island/pods/network.dart';
import 'package:island/screens/wallet.dart';
import 'package:island/services/time.dart';
import 'package:island/widgets/alert.dart';
import 'package:island/widgets/content/sheet.dart';
import 'package:island/widgets/payment/payment_overlay.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:styled_widget/styled_widget.dart';
part 'lottery.g.dart';
@riverpod
Future<List<SnLotteryTicket>> lotteryTickets(
Ref ref, {
int offset = 0,
int take = 20,
}) async {
final client = ref.watch(apiClientProvider);
final resp = await client.get('/pass/lotteries?offset=$offset&take=$take');
return (resp.data as List).map((e) => SnLotteryTicket.fromJson(e)).toList();
}
@riverpod
Future<List<SnLotteryRecord>> lotteryRecords(
Ref ref, {
int offset = 0,
int take = 20,
}) async {
final client = ref.watch(apiClientProvider);
final resp = await client.get(
'/pass/lotteries/records?offset=$offset&take=$take',
);
return (resp.data as List).map((e) => SnLotteryRecord.fromJson(e)).toList();
}
class LotteryTab extends StatelessWidget {
const LotteryTab({super.key});
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Column(
children: [
TabBar(
tabs: [Tab(text: 'myTickets'.tr()), Tab(text: 'drawHistory'.tr())],
),
Expanded(
child: TabBarView(
children: [LotteryTicketsList(), LotteryRecordsList()],
),
),
],
),
);
}
}
class LotteryTicketsList extends HookConsumerWidget {
const LotteryTicketsList({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final tickets = ref.watch(lotteryTicketsProvider());
return tickets.when(
data: (ticketsList) {
if (ticketsList.isEmpty) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Symbols.casino,
size: 48,
color: Theme.of(context).colorScheme.outline,
),
const Gap(16),
Text(
'noLotteryTickets'.tr(),
style: Theme.of(context).textTheme.titleMedium,
),
const Gap(8),
Text(
'buyYourFirstTicket'.tr(),
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
textAlign: TextAlign.center,
),
const Gap(16),
FilledButton.icon(
onPressed: () => _showLotteryPurchaseSheet(context, ref),
icon: const Icon(Symbols.add),
label: Text('buyTicket'.tr()),
),
],
),
);
}
return Column(
children: [
Expanded(
child: ListView.builder(
padding: const EdgeInsets.all(16),
itemCount: ticketsList.length,
itemBuilder: (context, index) {
final ticket = ticketsList[index];
return Card(
margin: const EdgeInsets.only(bottom: 8),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(
Symbols.confirmation_number,
color: Theme.of(context).colorScheme.primary,
),
const Gap(8),
Expanded(
child: Text(ticket.createdAt.formatSystem()),
),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 8,
vertical: 4,
),
decoration: BoxDecoration(
color: _getLotteryStatusColor(
context,
ticket.drawStatus,
).withOpacity(0.1),
borderRadius: BorderRadius.circular(12),
),
child: Text(
_getLotteryStatusText(ticket.drawStatus),
style: TextStyle(
color: _getLotteryStatusColor(
context,
ticket.drawStatus,
),
fontSize: 12,
fontWeight: FontWeight.w600,
),
),
),
],
),
const Gap(8),
_buildTicketNumbersDisplay(context, ticket),
const Gap(8),
Row(
spacing: 6,
children: [
const Icon(Symbols.asterisk, size: 18),
Text('multiplier').tr().fontSize(13),
Text(
'·',
).fontWeight(FontWeight.w900).fontSize(13),
Text(
'${ticket.multiplier}x',
style: Theme.of(context).textTheme.bodyMedium,
).fontSize(13),
],
).opacity(0.75),
],
),
),
);
},
),
),
Padding(
padding: const EdgeInsets.all(16),
child: FilledButton.icon(
onPressed: () => _showLotteryPurchaseSheet(context, ref),
icon: const Icon(Symbols.add),
label: Text('buyTicket'.tr()),
style: FilledButton.styleFrom(
minimumSize: const Size(double.infinity, 48),
),
),
),
],
);
},
loading: () => const Center(child: CircularProgressIndicator()),
error: (error, stack) => Center(child: Text('Error: $error')),
);
}
Future<void> _showLotteryPurchaseSheet(
BuildContext context,
WidgetRef ref,
) async {
final result = await showModalBottomSheet<Map<String, dynamic>>(
context: context,
useRootNavigator: true,
isScrollControlled: true,
builder: (context) => const LotteryPurchaseSheet(),
);
if (result != null && context.mounted) {
await _handleLotteryPurchase(context, ref, result);
}
}
Future<void> _handleLotteryPurchase(
BuildContext context,
WidgetRef ref,
Map<String, dynamic> purchaseData,
) async {
final client = ref.read(apiClientProvider);
try {
showLoadingModal(context);
// The lottery API creates the order for us
final orderResponse = await client.post(
'/pass/lotteries',
data: purchaseData,
);
if (context.mounted) hideLoadingModal(context);
final order = SnWalletOrder.fromJson(orderResponse.data);
// Show payment overlay
if (context.mounted) {
final completedOrder = await PaymentOverlay.show(
context: context,
order: order,
);
if (completedOrder != null) {
// Payment successful, refresh data
ref.invalidate(lotteryTicketsProvider);
ref.invalidate(walletCurrentProvider);
if (context.mounted) {
showSnackBar('ticketPurchasedSuccessfully'.tr());
}
}
}
} catch (err) {
if (context.mounted) hideLoadingModal(context);
showErrorAlert(err);
}
}
String _getLotteryStatusText(int status) {
switch (status) {
case 0:
return 'pending'.tr();
case 1:
return 'drawn'.tr();
case 2:
return 'won'.tr();
case 3:
return 'lost'.tr();
default:
return 'unknown'.tr();
}
}
Color _getLotteryStatusColor(BuildContext context, int status) {
switch (status) {
case 0:
return Colors.blue;
case 1:
return Colors.orange;
case 2:
return Colors.green;
case 3:
return Colors.red;
default:
return Theme.of(context).colorScheme.primary;
}
}
Widget _buildTicketNumbersDisplay(
BuildContext context,
SnLotteryTicket ticket,
) {
final numbers = <Widget>[];
// Check if any numbers matched
bool hasAnyMatch =
ticket.matchedRegionOneNumbers != null &&
ticket.matchedRegionOneNumbers!.isNotEmpty;
// Add region one numbers
for (final number in ticket.regionOneNumbers) {
final isMatched =
ticket.matchedRegionOneNumbers?.contains(number) ?? false;
if (isMatched) hasAnyMatch = true;
numbers.add(
_buildNumberWidget(
context,
number,
isMatched: isMatched,
allUnmatched: !hasAnyMatch && ticket.drawStatus >= 1,
),
);
}
// Add region two number
final isSpecialMatched =
ticket.matchedRegionTwoNumber == ticket.regionTwoNumber;
if (isSpecialMatched) hasAnyMatch = true;
numbers.add(
_buildNumberWidget(
context,
ticket.regionTwoNumber,
isMatched: isSpecialMatched,
isSpecial: true,
allUnmatched: !hasAnyMatch && ticket.drawStatus >= 1,
),
);
return Wrap(
spacing: 6,
crossAxisAlignment: WrapCrossAlignment.center,
children: numbers,
);
}
Widget _buildNumberWidget(
BuildContext context,
int number, {
bool isMatched = false,
bool isSpecial = false,
bool allUnmatched = false,
}) {
Color backgroundColor;
Color textColor;
Color borderColor;
if (isMatched) {
backgroundColor = Colors.green;
textColor = Colors.white;
borderColor = Colors.green;
} else {
backgroundColor =
isSpecial
? Theme.of(context).colorScheme.secondary
: Theme.of(context).colorScheme.surface;
textColor =
isSpecial
? Theme.of(context).colorScheme.onSecondary
: Theme.of(context).colorScheme.onSurface;
borderColor =
isSpecial
? Theme.of(context).colorScheme.secondary
: Theme.of(context).colorScheme.outline.withOpacity(0.3);
// Blend with red if all numbers are unmatched
if (allUnmatched) {
backgroundColor = Color.alphaBlend(
Colors.red.withOpacity(0.3),
backgroundColor,
);
if (!isSpecial) {
textColor = Color.alphaBlend(Colors.red.withOpacity(0.5), textColor);
}
}
}
return Container(
width: 32,
height: 32,
decoration: BoxDecoration(
color: backgroundColor,
border: Border.all(color: borderColor),
borderRadius: BorderRadius.circular(8),
),
child: Center(
child: Text(
number.toString().padLeft(2, '0'),
style: TextStyle(
color: textColor,
fontWeight: FontWeight.w600,
fontSize: 12,
),
),
),
);
}
}
class LotteryRecordsList extends HookConsumerWidget {
const LotteryRecordsList({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final records = ref.watch(lotteryRecordsProvider());
return records.when(
data: (recordsList) {
if (recordsList.isEmpty) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Symbols.history,
size: 48,
color: Theme.of(context).colorScheme.outline,
),
const Gap(16),
Text(
'noDrawHistory'.tr(),
style: Theme.of(context).textTheme.titleMedium,
),
],
),
);
}
return ListView.builder(
padding: const EdgeInsets.all(16),
itemCount: recordsList.length,
itemBuilder: (context, index) {
final record = recordsList[index];
return Card(
margin: const EdgeInsets.only(bottom: 8),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(
Symbols.celebration,
color: Theme.of(context).colorScheme.primary,
),
const Gap(8),
Text(
DateFormat.yMd().format(record.drawDate),
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
],
),
const Gap(8),
Text(
'${'winningNumbers'.tr()}: ${record.winningRegionOneNumbers.join(', ')}',
style: Theme.of(context).textTheme.bodyMedium,
),
const Gap(4),
Text(
'${'specialNumber'.tr()}: ${record.winningRegionTwoNumber}',
style: Theme.of(context).textTheme.bodyMedium,
),
const Gap(8),
Text(
'${'totalTickets'.tr()}: ${record.totalTickets}',
style: Theme.of(context).textTheme.bodySmall,
),
const Gap(4),
Text(
'${'totalWinners'.tr()}: ${record.totalPrizesAwarded}',
style: Theme.of(context).textTheme.bodySmall,
),
const Gap(4),
Text(
'${'prizePool'.tr()}: ${record.totalPrizeAmount.toStringAsFixed(2)} ${'walletCurrencyShortPoints'.tr()}',
style: Theme.of(context).textTheme.bodySmall,
),
],
),
),
);
},
);
},
loading: () => const Center(child: CircularProgressIndicator()),
error: (error, stack) => Center(child: Text('Error: $error')),
);
}
}
class LotteryPurchaseSheet extends StatefulWidget {
const LotteryPurchaseSheet({super.key});
@override
State<LotteryPurchaseSheet> createState() => _LotteryPurchaseSheetState();
}
class _LotteryPurchaseSheetState extends State<LotteryPurchaseSheet> {
final List<int> selectedNumbers = [];
int multiplier = 1;
@override
Widget build(BuildContext context) {
final totalCost = 10.0 * multiplier; // Base cost of 10 ISP per ticket
return SheetScaffold(
titleText: 'buyLotteryTicket'.tr(),
child: Column(
children: [
Expanded(
child: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Number Selection Section
Text(
'selectNumbers'.tr(),
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: Theme.of(context).colorScheme.primary,
),
),
const Gap(8),
Text(
'select5UniqueNumbers'.tr(),
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
const Gap(4),
Text(
'The last selected number will be your special number.',
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: Theme.of(context).colorScheme.secondary,
fontWeight: FontWeight.w500,
),
),
const Gap(16),
// Number Grid
_buildNumberGrid(),
const Gap(16),
// Multiplier Section
Text(
'selectMultiplier'.tr(),
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: Theme.of(context).colorScheme.primary,
),
),
const Gap(16),
_buildMultiplierSelector(),
const Gap(16),
// Cost Summary
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('baseCost'.tr()),
Text('10.00 ${'walletCurrencyShortPoints'.tr()}'),
],
),
if (multiplier > 1) ...[
const Gap(8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'multiplier'.tr(
args: [multiplier.toString()],
),
),
Text(
'+ ${(10.0 * (multiplier - 1)).toStringAsFixed(2)} ${'walletCurrencyShortPoints'.tr()}',
),
],
),
],
const Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'totalCost'.tr(),
style: const TextStyle(
fontWeight: FontWeight.bold,
),
),
Text(
'${totalCost.toStringAsFixed(2)} ${'walletCurrencyShortPoints'.tr()}',
style: const TextStyle(
fontWeight: FontWeight.bold,
),
),
],
),
],
),
),
),
const Gap(16),
// Prize Structure
Text(
'prizeStructure'.tr(),
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: Theme.of(context).colorScheme.primary,
),
),
const Gap(8),
_buildPrizeStructure(),
],
),
),
),
// Action Buttons
Padding(
padding: const EdgeInsets.all(16),
child: Row(
children: [
Expanded(
child: OutlinedButton(
onPressed: () => Navigator.of(context).pop(),
child: Text('cancel'.tr()),
),
),
const Gap(8),
Expanded(
child: FilledButton(
onPressed: _canPurchase ? _purchaseTicket : null,
child: Text('purchase'.tr()),
),
),
],
),
),
],
),
);
}
Widget _buildNumberGrid() {
return GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 10,
crossAxisSpacing: 8,
mainAxisSpacing: 8,
),
itemCount: 100,
itemBuilder: (context, index) {
final number = index;
final isSelected = selectedNumbers.contains(number);
final isSpecialNumber =
selectedNumbers.isNotEmpty &&
selectedNumbers.last == number &&
selectedNumbers.length == 6;
return GestureDetector(
onTap: () => _toggleNumber(number),
child: Container(
decoration: BoxDecoration(
color:
isSpecialNumber
? Theme.of(context).colorScheme.secondary
: isSelected
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.surface,
border: Border.all(
color:
isSpecialNumber
? Theme.of(context).colorScheme.secondary
: isSelected
? Theme.of(context).colorScheme.primary
: Theme.of(
context,
).colorScheme.outline.withOpacity(0.3),
),
borderRadius: BorderRadius.circular(8),
),
child: Center(
child: Text(
number.toString().padLeft(2, '0'),
style: TextStyle(
color:
isSpecialNumber
? Theme.of(context).colorScheme.onSecondary
: isSelected
? Theme.of(context).colorScheme.onPrimary
: Theme.of(context).colorScheme.onSurface,
fontWeight: FontWeight.w600,
),
),
),
),
);
},
);
}
Widget _buildMultiplierSelector() {
return TextFormField(
initialValue: multiplier.toString(),
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'multiplierLabel'.tr(),
prefixText: 'x',
border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)),
contentPadding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 12,
),
),
onChanged: (value) {
final parsed = int.tryParse(value);
if (parsed != null && parsed >= 1) {
setState(() => multiplier = parsed);
}
},
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter a multiplier';
}
final parsed = int.tryParse(value);
if (parsed == null || parsed < 1 || parsed > 10) {
return 'Multiplier must be between 1 and 10';
}
return null;
},
);
}
Widget _buildPrizeStructure() {
// Base rewards for matched numbers (0-5)
final baseRewards = [0, 10, 100, 500, 1000, 10000];
final prizeStructure = <String, String>{};
// Generate prize structure for 0-5 matches with and without special
for (int matches = 5; matches >= 0; matches--) {
final baseReward = baseRewards[matches];
// With special number match (x10 multiplier)
final specialReward = baseReward * 10;
prizeStructure['$matches+Special'] = specialReward.toStringAsFixed(2);
// Without special number match
if (matches > 0) {
prizeStructure[matches.toString()] = baseReward.toStringAsFixed(2);
}
}
return Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children:
prizeStructure.entries.map((entry) {
return Padding(
padding: const EdgeInsets.only(bottom: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
entry.key == '0+Special'
? 'specialOnly'.tr()
: entry.key.tr(),
),
Text(
'${entry.value} ${'walletCurrencyShortPoints'.tr()}',
),
],
),
);
}).toList(),
),
),
);
}
void _toggleNumber(int number) {
setState(() {
if (selectedNumbers.contains(number)) {
selectedNumbers.remove(number);
} else if (selectedNumbers.length < 6) {
selectedNumbers.add(number);
}
});
}
bool get _canPurchase {
return selectedNumbers.length == 6;
}
Future<void> _purchaseTicket() async {
if (!_canPurchase) return;
// Sort all numbers except the last one (special number)
final regularNumbers = selectedNumbers.sublist(0, 5)..sort();
final specialNumber = selectedNumbers.last;
final purchaseData = {
'region_one_numbers': regularNumbers,
'region_two_number': specialNumber,
'multiplier': multiplier,
};
if (mounted) Navigator.of(context).pop(purchaseData);
}
}

307
lib/screens/lottery.g.dart Normal file
View File

@@ -0,0 +1,307 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'lottery.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
String _$lotteryTicketsHash() => r'dd17cd721fc3b176ffa0ee0a85d0d850740e5e80';
/// Copied from Dart SDK
class _SystemHash {
_SystemHash._();
static int combine(int hash, int value) {
// ignore: parameter_assignments
hash = 0x1fffffff & (hash + value);
// ignore: parameter_assignments
hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
return hash ^ (hash >> 6);
}
static int finish(int hash) {
// ignore: parameter_assignments
hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
// ignore: parameter_assignments
hash = hash ^ (hash >> 11);
return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
}
}
/// See also [lotteryTickets].
@ProviderFor(lotteryTickets)
const lotteryTicketsProvider = LotteryTicketsFamily();
/// See also [lotteryTickets].
class LotteryTicketsFamily extends Family<AsyncValue<List<SnLotteryTicket>>> {
/// See also [lotteryTickets].
const LotteryTicketsFamily();
/// See also [lotteryTickets].
LotteryTicketsProvider call({int offset = 0, int take = 20}) {
return LotteryTicketsProvider(offset: offset, take: take);
}
@override
LotteryTicketsProvider getProviderOverride(
covariant LotteryTicketsProvider provider,
) {
return call(offset: provider.offset, take: provider.take);
}
static const Iterable<ProviderOrFamily>? _dependencies = null;
@override
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
@override
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
_allTransitiveDependencies;
@override
String? get name => r'lotteryTicketsProvider';
}
/// See also [lotteryTickets].
class LotteryTicketsProvider
extends AutoDisposeFutureProvider<List<SnLotteryTicket>> {
/// See also [lotteryTickets].
LotteryTicketsProvider({int offset = 0, int take = 20})
: this._internal(
(ref) => lotteryTickets(
ref as LotteryTicketsRef,
offset: offset,
take: take,
),
from: lotteryTicketsProvider,
name: r'lotteryTicketsProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product')
? null
: _$lotteryTicketsHash,
dependencies: LotteryTicketsFamily._dependencies,
allTransitiveDependencies:
LotteryTicketsFamily._allTransitiveDependencies,
offset: offset,
take: take,
);
LotteryTicketsProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.offset,
required this.take,
}) : super.internal();
final int offset;
final int take;
@override
Override overrideWith(
FutureOr<List<SnLotteryTicket>> Function(LotteryTicketsRef provider) create,
) {
return ProviderOverride(
origin: this,
override: LotteryTicketsProvider._internal(
(ref) => create(ref as LotteryTicketsRef),
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
offset: offset,
take: take,
),
);
}
@override
AutoDisposeFutureProviderElement<List<SnLotteryTicket>> createElement() {
return _LotteryTicketsProviderElement(this);
}
@override
bool operator ==(Object other) {
return other is LotteryTicketsProvider &&
other.offset == offset &&
other.take == take;
}
@override
int get hashCode {
var hash = _SystemHash.combine(0, runtimeType.hashCode);
hash = _SystemHash.combine(hash, offset.hashCode);
hash = _SystemHash.combine(hash, take.hashCode);
return _SystemHash.finish(hash);
}
}
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
mixin LotteryTicketsRef on AutoDisposeFutureProviderRef<List<SnLotteryTicket>> {
/// The parameter `offset` of this provider.
int get offset;
/// The parameter `take` of this provider.
int get take;
}
class _LotteryTicketsProviderElement
extends AutoDisposeFutureProviderElement<List<SnLotteryTicket>>
with LotteryTicketsRef {
_LotteryTicketsProviderElement(super.provider);
@override
int get offset => (origin as LotteryTicketsProvider).offset;
@override
int get take => (origin as LotteryTicketsProvider).take;
}
String _$lotteryRecordsHash() => r'55c657460f18d9777741d09013b445ca036863f3';
/// See also [lotteryRecords].
@ProviderFor(lotteryRecords)
const lotteryRecordsProvider = LotteryRecordsFamily();
/// See also [lotteryRecords].
class LotteryRecordsFamily extends Family<AsyncValue<List<SnLotteryRecord>>> {
/// See also [lotteryRecords].
const LotteryRecordsFamily();
/// See also [lotteryRecords].
LotteryRecordsProvider call({int offset = 0, int take = 20}) {
return LotteryRecordsProvider(offset: offset, take: take);
}
@override
LotteryRecordsProvider getProviderOverride(
covariant LotteryRecordsProvider provider,
) {
return call(offset: provider.offset, take: provider.take);
}
static const Iterable<ProviderOrFamily>? _dependencies = null;
@override
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
@override
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
_allTransitiveDependencies;
@override
String? get name => r'lotteryRecordsProvider';
}
/// See also [lotteryRecords].
class LotteryRecordsProvider
extends AutoDisposeFutureProvider<List<SnLotteryRecord>> {
/// See also [lotteryRecords].
LotteryRecordsProvider({int offset = 0, int take = 20})
: this._internal(
(ref) => lotteryRecords(
ref as LotteryRecordsRef,
offset: offset,
take: take,
),
from: lotteryRecordsProvider,
name: r'lotteryRecordsProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product')
? null
: _$lotteryRecordsHash,
dependencies: LotteryRecordsFamily._dependencies,
allTransitiveDependencies:
LotteryRecordsFamily._allTransitiveDependencies,
offset: offset,
take: take,
);
LotteryRecordsProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.offset,
required this.take,
}) : super.internal();
final int offset;
final int take;
@override
Override overrideWith(
FutureOr<List<SnLotteryRecord>> Function(LotteryRecordsRef provider) create,
) {
return ProviderOverride(
origin: this,
override: LotteryRecordsProvider._internal(
(ref) => create(ref as LotteryRecordsRef),
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
offset: offset,
take: take,
),
);
}
@override
AutoDisposeFutureProviderElement<List<SnLotteryRecord>> createElement() {
return _LotteryRecordsProviderElement(this);
}
@override
bool operator ==(Object other) {
return other is LotteryRecordsProvider &&
other.offset == offset &&
other.take == take;
}
@override
int get hashCode {
var hash = _SystemHash.combine(0, runtimeType.hashCode);
hash = _SystemHash.combine(hash, offset.hashCode);
hash = _SystemHash.combine(hash, take.hashCode);
return _SystemHash.finish(hash);
}
}
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
mixin LotteryRecordsRef on AutoDisposeFutureProviderRef<List<SnLotteryRecord>> {
/// The parameter `offset` of this provider.
int get offset;
/// The parameter `take` of this provider.
int get take;
}
class _LotteryRecordsProviderElement
extends AutoDisposeFutureProviderElement<List<SnLotteryRecord>>
with LotteryRecordsRef {
_LotteryRecordsProviderElement(super.provider);
@override
int get offset => (origin as LotteryRecordsProvider).offset;
@override
int get take => (origin as LotteryRecordsProvider).take;
}
// 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

View File

@@ -3,7 +3,6 @@ import 'dart:math' as math;
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/account.dart';
@@ -11,8 +10,8 @@ import 'package:island/pods/network.dart';
import 'package:island/pods/websocket.dart';
import 'package:island/route.dart';
import 'package:island/widgets/alert.dart';
import 'package:island/widgets/app_scaffold.dart';
import 'package:island/widgets/content/markdown.dart';
import 'package:island/widgets/content/sheet.dart';
import 'package:material_symbols_icons/material_symbols_icons.dart';
import 'package:relative_time/relative_time.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
@@ -113,8 +112,8 @@ class NotificationListNotifier extends _$NotificationListNotifier
}
}
class NotificationScreen extends HookConsumerWidget {
const NotificationScreen({super.key});
class NotificationSheet extends HookConsumerWidget {
const NotificationSheet({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
@@ -128,19 +127,15 @@ class NotificationScreen extends HookConsumerWidget {
ref.watch(notificationUnreadCountNotifierProvider.notifier).clear();
}
return AppScaffold(
appBar: AppBar(
leading: const PageBackButton(),
title: const Text('notifications').tr(),
actions: [
IconButton(
onPressed: markAllRead,
icon: const Icon(Symbols.mark_as_unread),
),
const Gap(8),
],
),
body: PagingHelperView(
return SheetScaffold(
titleText: 'notifications'.tr(),
actions: [
IconButton(
onPressed: markAllRead,
icon: const Icon(Symbols.mark_as_unread),
),
],
child: PagingHelperView(
provider: notificationListNotifierProvider,
futureRefreshable: notificationListNotifierProvider.future,
notifierRefreshable: notificationListNotifierProvider.notifier,

View File

@@ -237,7 +237,7 @@ class PostCategoryDetailScreen extends HookConsumerWidget {
loading: () => ResponseLoadingWidget(),
),
),
),
).padding(horizontal: 8),
),
),
const SliverGap(4),

View File

@@ -289,7 +289,7 @@ class PostActionButtons extends HookConsumerWidget {
builder: (context) => PostAwardHistorySheet(postId: post.id),
);
},
icon: const Icon(Symbols.star),
icon: const Icon(Symbols.emoji_events),
label:
post.awardedScore > 0
? Text('${formatScore(post.awardedScore)} pts')

View File

@@ -8,6 +8,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/post.dart';
import 'package:island/models/publisher.dart';
import 'package:island/models/account.dart';
import 'package:island/models/heatmap.dart';
import 'package:island/pods/config.dart';
import 'package:island/pods/network.dart';
import 'package:island/services/color.dart';
@@ -20,6 +21,7 @@ import 'package:island/widgets/app_scaffold.dart';
import 'package:island/widgets/content/cloud_files.dart';
import 'package:island/widgets/content/markdown.dart';
import 'package:island/widgets/post/post_list.dart';
import 'package:island/widgets/activity_heatmap.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'package:island/services/color_extraction.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
@@ -222,6 +224,32 @@ class _PublisherBioWidget extends StatelessWidget {
}
}
class _PublisherHeatmapWidget extends StatelessWidget {
final AsyncValue<SnHeatmap?> heatmap;
final bool forceDense;
const _PublisherHeatmapWidget({
required this.heatmap,
this.forceDense = false,
});
@override
Widget build(BuildContext context) {
return heatmap.when(
data:
(data) =>
data != null
? ActivityHeatmapWidget(
heatmap: data,
forceDense: forceDense,
).padding(horizontal: 8)
: const SizedBox.shrink(),
loading: () => const SizedBox.shrink(),
error: (_, _) => const SizedBox.shrink(),
);
}
}
class _PublisherCategoryTabWidget extends StatelessWidget {
final TabController categoryTabController;
@@ -257,7 +285,9 @@ Future<List<SnAccountBadge>> publisherBadges(Ref ref, String pubName) async {
final pub = await ref.watch(publisherProvider(pubName).future);
if (pub.type != 0 || pub.account == null) return [];
final apiClient = ref.watch(apiClientProvider);
final resp = await apiClient.get("/id/accounts/${pub.account!.name}/badges");
final resp = await apiClient.get(
"/pass/accounts/${pub.account!.name}/badges",
);
return List<SnAccountBadge>.from(
resp.data.map((x) => SnAccountBadge.fromJson(x)),
);
@@ -292,6 +322,13 @@ Future<Color?> publisherAppbarForcegroundColor(Ref ref, String pubName) async {
}
}
@riverpod
Future<SnHeatmap?> publisherHeatmap(Ref ref, String uname) async {
final apiClient = ref.watch(apiClientProvider);
final resp = await apiClient.get('/sphere/publishers/$uname/heatmap');
return SnHeatmap.fromJson(resp.data);
}
class PublisherProfileScreen extends HookConsumerWidget {
final String name;
const PublisherProfileScreen({super.key, required this.name});
@@ -301,6 +338,7 @@ class PublisherProfileScreen extends HookConsumerWidget {
final publisher = ref.watch(publisherProvider(name));
final badges = ref.watch(publisherBadgesProvider(name));
final subStatus = ref.watch(publisherSubscriptionStatusProvider(name));
final heatmap = ref.watch(publisherHeatmapProvider(name));
final appbarColor = ref.watch(
publisherAppbarForcegroundColorProvider(name),
);
@@ -446,6 +484,10 @@ class PublisherProfileScreen extends HookConsumerWidget {
),
_PublisherVerificationWidget(data: data),
_PublisherBioWidget(data: data),
_PublisherHeatmapWidget(
heatmap: heatmap,
forceDense: true,
),
],
),
),
@@ -517,6 +559,9 @@ class PublisherProfileScreen extends HookConsumerWidget {
SliverToBoxAdapter(
child: _PublisherBioWidget(data: data),
),
SliverToBoxAdapter(
child: _PublisherHeatmapWidget(heatmap: heatmap),
),
SliverPostList(pubName: name, pinned: true),
SliverToBoxAdapter(
child: _PublisherCategoryTabWidget(

View File

@@ -145,7 +145,7 @@ class _PublisherProviderElement
String get uname => (origin as PublisherProvider).uname;
}
String _$publisherBadgesHash() => r'527efad74225fbacf558ac5db160ecce53a60c62';
String _$publisherBadgesHash() => r'26776fd6cb611953f52bdb6a7dfa004c34d5cd8e';
/// See also [publisherBadges].
@ProviderFor(publisherBadges)
@@ -530,5 +530,126 @@ class _PublisherAppbarForcegroundColorProviderElement
(origin as PublisherAppbarForcegroundColorProvider).pubName;
}
String _$publisherHeatmapHash() => r'86db275ce3861a2855b5ec35fbfef85fc47b23a6';
/// See also [publisherHeatmap].
@ProviderFor(publisherHeatmap)
const publisherHeatmapProvider = PublisherHeatmapFamily();
/// See also [publisherHeatmap].
class PublisherHeatmapFamily extends Family<AsyncValue<SnHeatmap?>> {
/// See also [publisherHeatmap].
const PublisherHeatmapFamily();
/// See also [publisherHeatmap].
PublisherHeatmapProvider call(String uname) {
return PublisherHeatmapProvider(uname);
}
@override
PublisherHeatmapProvider getProviderOverride(
covariant PublisherHeatmapProvider provider,
) {
return call(provider.uname);
}
static const Iterable<ProviderOrFamily>? _dependencies = null;
@override
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
@override
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
_allTransitiveDependencies;
@override
String? get name => r'publisherHeatmapProvider';
}
/// See also [publisherHeatmap].
class PublisherHeatmapProvider extends AutoDisposeFutureProvider<SnHeatmap?> {
/// See also [publisherHeatmap].
PublisherHeatmapProvider(String uname)
: this._internal(
(ref) => publisherHeatmap(ref as PublisherHeatmapRef, uname),
from: publisherHeatmapProvider,
name: r'publisherHeatmapProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product')
? null
: _$publisherHeatmapHash,
dependencies: PublisherHeatmapFamily._dependencies,
allTransitiveDependencies:
PublisherHeatmapFamily._allTransitiveDependencies,
uname: uname,
);
PublisherHeatmapProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.uname,
}) : super.internal();
final String uname;
@override
Override overrideWith(
FutureOr<SnHeatmap?> Function(PublisherHeatmapRef provider) create,
) {
return ProviderOverride(
origin: this,
override: PublisherHeatmapProvider._internal(
(ref) => create(ref as PublisherHeatmapRef),
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
uname: uname,
),
);
}
@override
AutoDisposeFutureProviderElement<SnHeatmap?> createElement() {
return _PublisherHeatmapProviderElement(this);
}
@override
bool operator ==(Object other) {
return other is PublisherHeatmapProvider && other.uname == uname;
}
@override
int get hashCode {
var hash = _SystemHash.combine(0, runtimeType.hashCode);
hash = _SystemHash.combine(hash, uname.hashCode);
return _SystemHash.finish(hash);
}
}
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
mixin PublisherHeatmapRef on AutoDisposeFutureProviderRef<SnHeatmap?> {
/// The parameter `uname` of this provider.
String get uname;
}
class _PublisherHeatmapProviderElement
extends AutoDisposeFutureProviderElement<SnHeatmap?>
with PublisherHeatmapRef {
_PublisherHeatmapProviderElement(super.provider);
@override
String get uname => (origin as PublisherHeatmapProvider).uname;
}
// 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

View File

@@ -47,9 +47,7 @@ Future<Color?> realmAppbarForegroundColor(Ref ref, String realmSlug) async {
Future<SnRealmMember?> realmIdentity(Ref ref, String realmSlug) async {
try {
final apiClient = ref.watch(apiClientProvider);
final response = await apiClient.get(
'/sphere/realms/$realmSlug/members/me',
);
final response = await apiClient.get('/pass/realms/$realmSlug/members/me');
return SnRealmMember.fromJson(response.data);
} catch (err) {
if (err is DioException && err.response?.statusCode == 404) {
@@ -117,7 +115,7 @@ class RealmDetailScreen extends HookConsumerWidget {
onPressed: () async {
try {
final apiClient = ref.read(apiClientProvider);
await apiClient.post('/sphere/realms/$slug/members/me');
await apiClient.post('/pass/realms/$slug/members/me');
ref.invalidate(realmIdentityProvider(slug));
ref.invalidate(realmsJoinedProvider);
showSnackBar('realmJoinSuccess'.tr());
@@ -432,7 +430,7 @@ class _RealmActionMenu extends HookConsumerWidget {
).then((confirm) {
if (confirm) {
final client = ref.watch(apiClientProvider);
client.delete('/sphere/realms/$realmSlug');
client.delete('/pass/realms/$realmSlug');
ref.invalidate(realmsJoinedProvider);
if (context.mounted) {
context.pop(true);
@@ -465,7 +463,7 @@ class _RealmActionMenu extends HookConsumerWidget {
if (confirm) {
final client = ref.watch(apiClientProvider);
await client.delete(
'/sphere/realms/$realmSlug/members/me',
'/pass/realms/$realmSlug/members/me',
);
ref.invalidate(realmsJoinedProvider);
if (context.mounted) {
@@ -505,7 +503,7 @@ class _RealmActionMenu extends HookConsumerWidget {
if (confirm) {
final client = ref.watch(apiClientProvider);
await client.delete(
'/sphere/realms/$realmSlug/members/me',
'/pass/realms/$realmSlug/members/me',
);
ref.invalidate(realmsJoinedProvider);
if (context.mounted) {
@@ -539,7 +537,7 @@ class RealmMemberListNotifier extends _$RealmMemberListNotifier
final offset = cursor != null ? int.parse(cursor) : 0;
final response = await apiClient.get(
'/sphere/realms/$realmSlug/members',
'/pass/realms/$realmSlug/members',
queryParameters: {
'offset': offset,
'take': _pageSize,
@@ -592,7 +590,7 @@ class _RealmMemberListSheet extends HookConsumerWidget {
try {
final apiClient = ref.watch(apiClientProvider);
await apiClient.post(
'/sphere/realms/invites/$realmSlug',
'/pass/realms/invites/$realmSlug',
data: {'related_user_id': result.id, 'role': 0},
);
// Refresh the provider
@@ -729,7 +727,7 @@ class _RealmMemberListSheet extends HookConsumerWidget {
try {
final apiClient = ref.watch(apiClientProvider);
await apiClient.delete(
'/sphere/realms/$realmSlug/members/${member.accountId}',
'/pass/realms/$realmSlug/members/${member.accountId}',
);
// Refresh the provider
ref.invalidate(memberListProvider);
@@ -860,7 +858,7 @@ class _RealmMemberRoleSheet extends HookConsumerWidget {
final apiClient = ref.read(apiClientProvider);
await apiClient.patch(
'/sphere/realms/$realmSlug/members/${member.accountId}/role',
'/pass/realms/$realmSlug/members/${member.accountId}/role',
data: newRole,
);

View File

@@ -155,7 +155,7 @@ class _RealmAppbarForegroundColorProviderElement
(origin as RealmAppbarForegroundColorProvider).realmSlug;
}
String _$realmIdentityHash() => r'c5e2977d243260947b919bc27146c134e34f0db1';
String _$realmIdentityHash() => r'd5a3ecc6eeec291cebbfc9a45d8aac7195366381';
/// See also [realmIdentity].
@ProviderFor(realmIdentity)
@@ -399,7 +399,7 @@ class _RealmChatRoomsProviderElement
}
String _$realmMemberListNotifierHash() =>
r'db1fd8a6741dfb3d5bb921d5d965f0cfdc0e7bcc';
r'ab38c550c43cbf93d4c3e92e6658d76f40252c1f';
abstract class _$RealmMemberListNotifier
extends BuildlessAutoDisposeAsyncNotifier<CursorPagingData<SnRealmMember>> {

View File

@@ -122,7 +122,7 @@ class EditRealmScreen extends HookConsumerWidget {
try {
final client = ref.watch(apiClientProvider);
final resp = await client.request(
'/sphere${slug == null ? '/realms' : '/realms/$slug'}',
'/pass${slug == null ? '/realms' : '/realms/$slug'}',
data: {
'slug': slugController.text,
'name': nameController.text,

View File

@@ -21,7 +21,7 @@ part 'realms.g.dart';
@riverpod
Future<List<SnRealm>> realmsJoined(Ref ref) async {
final client = ref.watch(apiClientProvider);
final resp = await client.get('/sphere/realms');
final resp = await client.get('/pass/realms');
return resp.data.map((e) => SnRealm.fromJson(e)).cast<SnRealm>().toList();
}
@@ -29,7 +29,7 @@ Future<List<SnRealm>> realmsJoined(Ref ref) async {
Future<SnRealm?> realm(Ref ref, String? identifier) async {
if (identifier == null) return null;
final client = ref.watch(apiClientProvider);
final resp = await client.get('/sphere/realms/$identifier');
final resp = await client.get('/pass/realms/$identifier');
return SnRealm.fromJson(resp.data);
}
@@ -128,7 +128,7 @@ class RealmListScreen extends HookConsumerWidget {
@riverpod
Future<List<SnRealmMember>> realmInvites(Ref ref) async {
final client = ref.watch(apiClientProvider);
final resp = await client.get('/sphere/realms/invites');
final resp = await client.get('/pass/realms/invites');
return resp.data
.map((e) => SnRealmMember.fromJson(e))
.cast<SnRealmMember>()
@@ -145,9 +145,7 @@ class _RealmInviteSheet extends HookConsumerWidget {
Future<void> acceptInvite(SnRealmMember invite) async {
try {
final client = ref.read(apiClientProvider);
await client.post(
'/sphere/realms/invites/${invite.realm!.slug}/accept',
);
await client.post('/pass/realms/invites/${invite.realm!.slug}/accept');
ref.invalidate(realmInvitesProvider);
ref.invalidate(realmsJoinedProvider);
} catch (err) {
@@ -158,9 +156,7 @@ class _RealmInviteSheet extends HookConsumerWidget {
Future<void> declineInvite(SnRealmMember invite) async {
try {
final client = ref.read(apiClientProvider);
await client.post(
'/sphere/realms/invites/${invite.realm!.slug}/decline',
);
await client.post('/pass/realms/invites/${invite.realm!.slug}/decline');
ref.invalidate(realmInvitesProvider);
} catch (err) {
showErrorAlert(err);

View File

@@ -6,7 +6,7 @@ part of 'realms.dart';
// RiverpodGenerator
// **************************************************************************
String _$realmsJoinedHash() => r'e8083f02ffae450bba2470c31757675b4df32cd0';
String _$realmsJoinedHash() => r'b15029acd38f03bbbb8708adb78f25ac357a0421';
/// See also [realmsJoined].
@ProviderFor(realmsJoined)
@@ -22,7 +22,7 @@ final realmsJoinedProvider = AutoDisposeFutureProvider<List<SnRealm>>.internal(
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef RealmsJoinedRef = AutoDisposeFutureProviderRef<List<SnRealm>>;
String _$realmHash() => r'4650b17608a9ee14170ef20295eb14d295e909c9';
String _$realmHash() => r'71a126ab2810566646e1629290c1ce9ffa0839e3';
/// Copied from Dart SDK
class _SystemHash {
@@ -156,7 +156,7 @@ class _RealmProviderElement extends AutoDisposeFutureProviderElement<SnRealm?>
String? get identifier => (origin as RealmProvider).identifier;
}
String _$realmInvitesHash() => r'ed73443c6423b92ed72982be2a93b7dcc7ce3945';
String _$realmInvitesHash() => r'92cce0978c7ca8813e27ae42fc6f3a93a09a8962';
/// See also [realmInvites].
@ProviderFor(realmInvites)

View File

@@ -3,11 +3,13 @@ import 'dart:ui';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:gap/gap.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:island/screens/notification.dart';
import 'package:island/services/responsive.dart';
import 'package:island/widgets/navigation/conditional_bottom_nav.dart';
import 'package:island/widgets/post/compose_dialog.dart';
import 'package:material_symbols_icons/symbols.dart';
final currentRouteProvider = StateProvider<String?>((ref) => null);
@@ -50,10 +52,13 @@ class TabsScreen extends HookConsumerWidget {
label: 'explore'.tr(),
icon: const Icon(Symbols.explore),
),
NavigationDestination(label: 'chat'.tr(), icon: const Icon(Symbols.chat)),
NavigationDestination(
label: 'chat'.tr(),
icon: const Icon(Symbols.chat_rounded),
),
NavigationDestination(
label: 'realms'.tr(),
icon: const Icon(Symbols.workspaces),
icon: const Icon(Symbols.group),
),
NavigationDestination(
label: 'account'.tr(),
@@ -66,12 +71,12 @@ class TabsScreen extends HookConsumerWidget {
if (wideScreen)
NavigationDestination(
label: 'creatorHub'.tr(),
icon: const Icon(Symbols.draw),
icon: const Icon(Symbols.ink_pen),
),
if (wideScreen)
NavigationDestination(
label: 'developerHub'.tr(),
icon: const Icon(Symbols.code),
icon: const Icon(Symbols.data_object),
),
];
@@ -91,6 +96,12 @@ class TabsScreen extends HookConsumerWidget {
final currentIndex = getCurrentIndex();
final routes = kTabRoutes.sublist(
0,
isWideScreen(context) ? null : kWideScreenRouteStart,
);
final shouldShowFab = routes.contains(currentLocation) && !wideScreen;
if (isWideScreen(context)) {
return Container(
color: Theme.of(context).colorScheme.surfaceContainer,
@@ -126,6 +137,7 @@ class TabsScreen extends HookConsumerWidget {
return Scaffold(
backgroundColor: Colors.transparent,
extendBody: true,
resizeToAvoidBottomInset: false,
body: ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(16),
@@ -133,29 +145,120 @@ class TabsScreen extends HookConsumerWidget {
),
child: child ?? const SizedBox.shrink(),
),
floatingActionButton:
shouldShowFab
? FloatingActionButton(
child: const Icon(Symbols.menu),
onPressed: () {
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
const Gap(24),
ListTile(
contentPadding: const EdgeInsets.symmetric(
horizontal: 24,
),
leading: const Icon(Symbols.post_add_rounded),
title: Text('postCompose'.tr()),
onTap: () async {
Navigator.of(context).pop();
await PostComposeDialog.show(context);
},
),
ListTile(
contentPadding: const EdgeInsets.symmetric(
horizontal: 24,
),
leading: const Icon(Symbols.bubble_chart),
title: Text('aiThoughtTitle'.tr()),
onTap: () async {
Navigator.of(context).pop();
context.pushNamed('thought');
},
),
Consumer(
builder: (context, ref, _) {
final notificationCount = ref.watch(
notificationUnreadCountNotifierProvider,
);
return ListTile(
contentPadding: const EdgeInsets.symmetric(
horizontal: 24,
),
leading: const Icon(Symbols.notifications),
trailing: Badge(
label: Text(notificationCount.toString()),
isLabelVisible: notificationCount.value! > 0,
),
title: Text('notifications'.tr()),
onTap: () async {
Navigator.of(context).pop();
showModalBottomSheet(
context: context,
isScrollControlled: true,
useRootNavigator: true,
builder:
(context) => const NotificationSheet(),
);
},
);
},
),
Gap(MediaQuery.of(context).padding.bottom + 16),
],
);
},
);
},
)
: null,
floatingActionButtonLocation:
shouldShowFab ? TabbedFabLocation(context) : null,
bottomNavigationBar: ConditionalBottomNav(
child: ClipRRect(
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 1, sigmaY: 1),
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface.withOpacity(0.8),
),
child: MediaQuery.removePadding(
context: context,
removeTop: true,
child: NavigationBar(
backgroundColor: Colors.transparent,
shadowColor: Colors.transparent,
overlayColor: const WidgetStatePropertyAll(
Colors.transparent,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
),
child: MediaQuery.removePadding(
context: context,
removeTop: true,
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5),
child: BottomAppBar(
height: 56,
padding: EdgeInsets.symmetric(horizontal: 24),
shape: AutomaticNotchedShape(
RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(16)),
),
surfaceTintColor: Colors.transparent,
height: 56,
labelBehavior: NavigationDestinationLabelBehavior.alwaysHide,
selectedIndex: currentIndex,
onDestinationSelected: onDestinationSelected,
destinations: destinations,
),
color: Theme.of(context).colorScheme.surface.withOpacity(0.8),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: () {
final navItems =
destinations.asMap().entries.map<Widget>((entry) {
int index = entry.key;
NavigationDestination dest = entry.value;
return IconButton(
icon: dest.icon,
onPressed: () => onDestinationSelected(index),
color:
index == currentIndex
? Theme.of(context).colorScheme.primary
: null,
);
}).toList();
// Add mock item in the center to leave space for FAB
int centerIndex = navItems.length ~/ 2;
navItems.insert(centerIndex, const SizedBox(width: 72));
return navItems;
}(),
),
),
),
@@ -176,14 +279,13 @@ class TabbedFabLocation extends FloatingActionButtonLocation {
final mediaQuery = MediaQuery.of(context);
final safeAreaPadding = mediaQuery.padding;
// Calculate position with proper safe area considerations
// Center horizontally
final double fabX =
scaffoldGeometry.scaffoldSize.width -
scaffoldGeometry.floatingActionButtonSize.width -
16 -
safeAreaPadding.right;
(scaffoldGeometry.scaffoldSize.width -
scaffoldGeometry.floatingActionButtonSize.width) /
2;
// Use safe area bottom padding + navigation bar height (typically 80px)
// Position closer to bottom with reduced padding
final double fabY =
scaffoldGeometry.scaffoldSize.height -
scaffoldGeometry.floatingActionButtonSize.height -

View File

@@ -0,0 +1,461 @@
import "dart:async";
import "dart:convert";
import "package:dio/dio.dart";
import "package:easy_localization/easy_localization.dart";
import "package:flutter/material.dart";
import "package:flutter_hooks/flutter_hooks.dart";
import "package:gap/gap.dart";
import "package:hooks_riverpod/hooks_riverpod.dart";
import "package:island/models/thought.dart";
import "package:island/pods/network.dart";
import "package:island/pods/userinfo.dart";
import "package:island/services/time.dart";
import "package:island/widgets/alert.dart";
import "package:island/widgets/app_scaffold.dart";
import "package:island/widgets/content/markdown.dart";
import "package:island/widgets/response.dart";
import "package:island/widgets/thought/thought_sequence_list.dart";
import "package:material_symbols_icons/material_symbols_icons.dart";
import "package:super_sliver_list/super_sliver_list.dart";
final thoughtSequenceProvider =
FutureProvider.family<List<SnThinkingThought>, String>((
ref,
sequenceId,
) async {
final apiClient = ref.watch(apiClientProvider);
final response = await apiClient.get(
'/insight/thought/sequences/$sequenceId',
);
return (response.data as List)
.map((e) => SnThinkingThought.fromJson(e))
.toList();
});
class ThoughtScreen extends HookConsumerWidget {
const ThoughtScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final selectedSequenceId = useState<String?>(null);
final thoughts =
selectedSequenceId.value != null
? ref.watch(thoughtSequenceProvider(selectedSequenceId.value!))
: const AsyncValue<List<SnThinkingThought>>.data([]);
final localThoughts = useState<List<SnThinkingThought>>([]);
final currentTopic = useState<String?>('aiThought'.tr());
final messageController = useTextEditingController();
final scrollController = useScrollController();
final isStreaming = useState(false);
final streamingText = useState<String>('');
final listController = useMemoized(() => ListController(), []);
// Update local thoughts when provider data changes
useEffect(() {
thoughts.whenData((data) {
// Server returns messages in DESC order (newest first), keep as-is for UI
localThoughts.value = data;
// Update topic from the first thought's sequence
if (data.isNotEmpty && data.first.sequence?.topic != null) {
currentTopic.value = data.first.sequence!.topic;
} else {
currentTopic.value = 'aiThought'.tr();
}
});
return null;
}, [thoughts]);
// Scroll to bottom when thoughts change or streaming state changes
useEffect(() {
if (localThoughts.value.isNotEmpty || isStreaming.value) {
WidgetsBinding.instance.addPostFrameCallback((_) {
scrollController.animateTo(
0,
duration: const Duration(milliseconds: 300),
curve: Curves.easeOut,
);
});
}
return null;
}, [localThoughts.value.length, isStreaming.value]);
void sendMessage() async {
if (messageController.text.trim().isEmpty) return;
final userMessage = messageController.text.trim();
// Add user message to local thoughts
final userInfo = ref.read(userInfoProvider);
final now = DateTime.now();
final userThought = SnThinkingThought(
id: 'user-${DateTime.now().millisecondsSinceEpoch}',
content: userMessage,
files: [],
role: ThinkingThoughtRole.user,
sequenceId: selectedSequenceId.value ?? '',
createdAt: now,
updatedAt: now,
sequence:
selectedSequenceId.value != null
? thoughts.value?.firstOrNull?.sequence ??
SnThinkingSequence(
id: selectedSequenceId.value!,
accountId: '',
createdAt: now,
updatedAt: now,
)
: SnThinkingSequence(
id: '',
accountId: userInfo.value!.id,
createdAt: now,
updatedAt: now,
),
);
localThoughts.value = [userThought, ...localThoughts.value];
final request = StreamThinkingRequest(
userMessage: userMessage,
sequenceId: selectedSequenceId.value,
);
try {
isStreaming.value = true;
streamingText.value = '';
final apiClient = ref.read(apiClientProvider);
final response = await apiClient.post(
'/insight/thought',
data: request.toJson(),
options: Options(
responseType: ResponseType.stream,
sendTimeout: Duration(minutes: 1),
receiveTimeout: Duration(minutes: 1),
),
);
final stream = response.data.stream;
final completer = Completer<String>();
final buffer = StringBuffer();
stream.listen(
(data) {
final chunk = utf8.decode(data);
buffer.write(chunk);
streamingText.value = buffer.toString();
},
onDone: () {
completer.complete(buffer.toString());
isStreaming.value = false;
// Parse the response and add AI thought
try {
final lines =
buffer
.toString()
.split('\n')
.where((line) => line.trim().isNotEmpty)
.toList();
final lastLine = lines.last;
final responseJson = jsonDecode(lastLine);
final aiThought = SnThinkingThought.fromJson(responseJson);
// Check for topic in second last line
String? topic;
if (lines.length >= 2) {
final secondLastLine = lines[lines.length - 2];
final topicMatch = RegExp(
r'<topic>(.*)</topic>',
).firstMatch(secondLastLine);
if (topicMatch != null) {
topic = topicMatch.group(1);
}
}
// Add AI thought to conversation
localThoughts.value = [aiThought, ...localThoughts.value];
// Update selected sequence ID if it was null (new conversation)
if (selectedSequenceId.value == null &&
aiThought.sequenceId.isNotEmpty) {
selectedSequenceId.value = aiThought.sequenceId;
}
// Update current topic if found (AI responses don't include sequence to prevent backend loops)
if (topic != null) {
currentTopic.value = topic;
}
} catch (e) {
showErrorAlert('thoughtParseError'.tr());
}
},
onError: (error) {
completer.completeError(error);
isStreaming.value = false;
// Handle streaming response errors differently
if (error is DioException && error.response?.data is ResponseBody) {
// For streaming responses, show a generic error message
showErrorAlert('toughtParseError'.tr());
} else {
showErrorAlert(error);
}
},
);
messageController.clear();
FocusManager.instance.primaryFocus?.unfocus();
} catch (error) {
isStreaming.value = false;
showErrorAlert(error);
}
}
Widget thoughtItem(SnThinkingThought thought, int index) {
final key = Key('thought-${thought.id}');
final thoughtWidget = Container(
margin: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color:
thought.role == ThinkingThoughtRole.assistant
? Theme.of(context).colorScheme.surfaceContainerHighest
: Theme.of(context).colorScheme.primaryContainer,
borderRadius: BorderRadius.circular(12),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(
thought.role == ThinkingThoughtRole.assistant
? Symbols.smart_toy
: Symbols.person,
size: 20,
),
const Gap(8),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.ideographic,
spacing: 8,
children: [
Text(
thought.role == ThinkingThoughtRole.assistant
? 'toughtAiName'.tr()
: 'thoughtUserName'.tr(),
style: Theme.of(context).textTheme.titleSmall,
),
Tooltip(
message: thought.createdAt.formatSystem(),
child: Text(
thought.createdAt.formatRelative(context),
style: Theme.of(
context,
).textTheme.bodySmall?.copyWith(
color:
Theme.of(context).colorScheme.onSurfaceVariant,
),
),
),
],
),
),
],
),
const Gap(8),
if (thought.content != null)
MarkdownTextContent(
isSelectable: true,
content: thought.content!,
textStyle: Theme.of(context).textTheme.bodyMedium,
),
],
),
);
return TweenAnimationBuilder<double>(
key: key,
tween: Tween<double>(begin: 0.0, end: 1.0),
duration: Duration(
milliseconds: 400 + (index % 5) * 50,
), // Staggered delay
curve: Curves.easeOutCubic,
builder: (context, animationValue, child) {
return Transform.translate(
offset: Offset(
0,
20 * (1 - animationValue),
), // Slide up from bottom
child: Opacity(opacity: animationValue, child: child),
);
},
child: thoughtWidget,
);
}
Widget streamingThoughtItem() => Container(
margin: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surfaceContainerHighest,
borderRadius: BorderRadius.circular(12),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(Symbols.smart_toy, size: 20),
const Gap(8),
Text(
'thoughtAiName'.tr(),
style: Theme.of(context).textTheme.titleSmall,
),
const Spacer(),
SizedBox(
width: 16,
height: 16,
child: CircularProgressIndicator(strokeWidth: 2),
),
],
),
const Gap(8),
MarkdownTextContent(
content: streamingText.value,
textStyle: Theme.of(context).textTheme.bodyMedium,
),
],
),
);
return AppScaffold(
appBar: AppBar(
title: Text(currentTopic.value ?? 'aiThought'.tr()),
actions: [
IconButton(
icon: const Icon(Symbols.history),
onPressed: () {
// Show sequence selector
showModalBottomSheet(
context: context,
builder:
(context) => ThoughtSequenceSelector(
onSequenceSelected: (sequenceId) {
selectedSequenceId.value = sequenceId;
},
),
);
},
),
if (localThoughts.value.isNotEmpty &&
!isStreaming.value &&
localThoughts.value.last.role == ThinkingThoughtRole.assistant)
IconButton(
icon: const Icon(Symbols.add),
tooltip: 'thoughtNewConversation'.tr(),
onPressed: () {
// Clear current conversation and start new one
selectedSequenceId.value = null;
localThoughts.value = [];
currentTopic.value = 'aiThought'.tr();
messageController.clear();
},
),
const Gap(8),
],
),
body: Column(
children: [
Expanded(
child: thoughts.when(
data:
(thoughtList) => SuperListView.builder(
listController: listController,
controller: scrollController,
padding: const EdgeInsets.only(top: 16, bottom: 16),
reverse: true,
itemCount:
localThoughts.value.length +
(isStreaming.value ? 1 : 0),
itemBuilder: (context, index) {
if (isStreaming.value && index == 0) {
return streamingThoughtItem();
}
final thoughtIndex =
isStreaming.value ? index - 1 : index;
final thought = localThoughts.value[thoughtIndex];
return thoughtItem(thought, thoughtIndex);
},
),
loading: () => const Center(child: CircularProgressIndicator()),
error:
(error, _) => ResponseErrorWidget(
error: error,
onRetry:
() =>
selectedSequenceId.value != null
? ref.invalidate(
thoughtSequenceProvider(
selectedSequenceId.value!,
),
)
: null,
),
),
),
Container(
margin: EdgeInsets.only(
left: 16,
right: 16,
bottom: 16 + MediaQuery.of(context).padding.bottom,
),
child: Material(
elevation: 2,
color: Theme.of(context).colorScheme.surfaceContainerHighest,
borderRadius: BorderRadius.circular(32),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 8),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: TextField(
controller: messageController,
keyboardType: TextInputType.multiline,
enabled: !isStreaming.value,
decoration: InputDecoration(
hintText:
isStreaming.value
? 'thoughtStreamingHint'.tr()
: 'thoughtInputHint'.tr(),
border: InputBorder.none,
isDense: true,
contentPadding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 12,
),
),
maxLines: 5,
minLines: 1,
textInputAction: TextInputAction.send,
onSubmitted: (_) => sendMessage(),
),
),
IconButton(
icon: Icon(isStreaming.value ? Symbols.stop : Icons.send),
color: Theme.of(context).colorScheme.primary,
onPressed: sendMessage,
),
],
),
),
),
),
],
),
);
}
}

View File

@@ -8,6 +8,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/account.dart';
import 'package:island/models/wallet.dart';
import 'package:island/pods/network.dart';
import 'package:island/screens/lottery.dart';
import 'package:island/widgets/account/account_pfc.dart';
import 'package:island/widgets/account/account_picker.dart';
import 'package:island/widgets/app_scaffold.dart';
@@ -28,7 +29,7 @@ part 'wallet.g.dart';
Future<SnWallet?> walletCurrent(Ref ref) async {
try {
final apiClient = ref.watch(apiClientProvider);
final resp = await apiClient.get('/id/wallets');
final resp = await apiClient.get('/pass/wallets');
return SnWallet.fromJson(resp.data);
} catch (err) {
if (err is DioException && err.response?.statusCode == 404) {
@@ -41,7 +42,7 @@ Future<SnWallet?> walletCurrent(Ref ref) async {
@riverpod
Future<SnWalletStats> walletStats(Ref ref) async {
final client = ref.watch(apiClientProvider);
final resp = await client.get('/id/wallets/stats');
final resp = await client.get('/pass/wallets/stats');
return SnWalletStats.fromJson(resp.data);
}
@@ -998,11 +999,6 @@ class _CreateTransferSheetState extends State<CreateTransferSheet> {
}
}
const Map<String, IconData> kCurrencyIconData = {
'points': Symbols.toll,
'golds': Symbols.attach_money,
};
@riverpod
class TransactionListNotifier extends _$TransactionListNotifier
with CursorPagingNotifierMixin<SnTransaction> {
@@ -1021,7 +1017,7 @@ class TransactionListNotifier extends _$TransactionListNotifier
final queryParams = {'offset': offset, 'take': _pageSize};
final response = await client.get(
'/id/wallets/transactions',
'/pass/wallets/transactions',
queryParameters: queryParams,
);
final total = int.parse(response.headers.value('X-Total') ?? '0');
@@ -1048,7 +1044,9 @@ Future<List<SnWalletFund>> walletFunds(
int take = 20,
}) async {
final client = ref.watch(apiClientProvider);
final resp = await client.get('/id/wallets/funds?offset=$offset&take=$take');
final resp = await client.get(
'/pass/wallets/funds?offset=$offset&take=$take',
);
return (resp.data as List).map((e) => SnWalletFund.fromJson(e)).toList();
}
@@ -1060,7 +1058,7 @@ Future<List<SnWalletFundRecipient>> walletFundRecipients(
}) async {
final client = ref.watch(apiClientProvider);
final resp = await client.get(
'/id/wallets/funds/recipients?offset=$offset&take=$take',
'/pass/wallets/funds/recipients?offset=$offset&take=$take',
);
return (resp.data as List)
.map((e) => SnWalletFundRecipient.fromJson(e))
@@ -1070,7 +1068,7 @@ Future<List<SnWalletFundRecipient>> walletFundRecipients(
@riverpod
Future<SnWalletFund> walletFund(Ref ref, String fundId) async {
final client = ref.watch(apiClientProvider);
final resp = await client.get('/id/wallets/funds/$fundId');
final resp = await client.get('/pass/wallets/funds/$fundId');
return SnWalletFund.fromJson(resp.data);
}
@@ -1247,7 +1245,7 @@ class WalletScreen extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final wallet = ref.watch(walletCurrentProvider);
final tabController = useTabController(initialLength: 2);
final tabController = useTabController(initialLength: 3);
final currentTabIndex = useState(0);
useEffect(() {
@@ -1262,7 +1260,7 @@ class WalletScreen extends HookConsumerWidget {
Future<void> createWallet() async {
final client = ref.read(apiClientProvider);
try {
await client.post('/id/wallets');
await client.post('/pass/wallets');
ref.invalidate(walletCurrentProvider);
} catch (err) {
showErrorAlert(err);
@@ -1326,18 +1324,20 @@ class WalletScreen extends HookConsumerWidget {
appBar: AppBar(
title: Text('wallet').tr(),
actions: [
IconButton(
icon: Icon(
currentTabIndex.value == 1
? Symbols.money_bag
: Symbols.swap_horiz,
),
onPressed: currentTabIndex.value == 1 ? createFund : createTransfer,
tooltip:
if (currentTabIndex.value != 2) // Hide for lottery tab
IconButton(
icon: Icon(
currentTabIndex.value == 1
? 'createFund'.tr()
: 'createTransfer'.tr(),
),
? Symbols.money_bag
: Symbols.swap_horiz,
),
onPressed:
currentTabIndex.value == 1 ? createFund : createTransfer,
tooltip:
currentTabIndex.value == 1
? 'createFund'.tr()
: 'createTransfer'.tr(),
),
const Gap(8),
],
),
@@ -1408,6 +1408,7 @@ class WalletScreen extends HookConsumerWidget {
tabs: [
Tab(text: 'transactions'.tr()),
Tab(text: 'myFunds'.tr()),
Tab(text: 'lottery'.tr()),
],
),
),
@@ -1485,6 +1486,9 @@ class WalletScreen extends HookConsumerWidget {
// My Funds Tab
_buildFundsList(context, ref),
// Lottery Tab
const LotteryTab(),
],
),
);
@@ -1762,14 +1766,16 @@ class WalletScreen extends HookConsumerWidget {
try {
showLoadingModal(context);
final resp = await client.post(
'/id/wallets/funds',
'/pass/wallets/funds',
data: fundData,
options: Options(headers: {'X-Noop': true}),
);
final fund = SnWalletFund.fromJson(resp.data);
if (fund.status == 0) return; // Already created
final orderResp = await client.post('/id/wallets/funds/${fund.id}/order');
final orderResp = await client.post(
'/pass/wallets/funds/${fund.id}/order',
);
final order = SnWalletOrder.fromJson(orderResp.data);
if (context.mounted) hideLoadingModal(context);
@@ -1808,7 +1814,7 @@ class WalletScreen extends HookConsumerWidget {
final client = ref.read(apiClientProvider);
try {
showLoadingModal(context);
await client.post('/id/wallets/transfer', data: transferData);
await client.post('/pass/wallets/transfer', data: transferData);
if (context.mounted) hideLoadingModal(context);
@@ -1855,3 +1861,8 @@ class WalletScreen extends HookConsumerWidget {
}
}
}
const Map<String, IconData> kCurrencyIconData = {
'points': Symbols.toll,
'golds': Symbols.attach_money,
};

View File

@@ -26,7 +26,7 @@ part 'wallet.g.dart';
Future<SnWallet?> walletCurrent(Ref ref) async {
try {
final apiClient = ref.watch(apiClientProvider);
final resp = await apiClient.get('/id/wallets');
final resp = await apiClient.get('/pass/wallets');
return SnWallet.fromJson(resp.data);
} catch (err) {
if (err is DioException && err.response?.statusCode == 404) {
@@ -491,7 +491,7 @@ class TransactionListNotifier extends _$TransactionListNotifier
final queryParams = {'offset': offset, 'take': _pageSize};
final response = await client.get(
'/id/wallets/transactions',
'/pass/wallets/transactions',
queryParameters: queryParams,
);
final total = int.parse(response.headers.value('X-Total') ?? '0');
@@ -518,7 +518,7 @@ Future<List<SnWalletFund>> walletFunds(
int take = 20,
}) async {
final client = ref.watch(apiClientProvider);
final resp = await client.get('/id/wallets/funds?offset=$offset&take=$take');
final resp = await client.get('/pass/wallets/funds?offset=$offset&take=$take');
return (resp.data as List).map((e) => SnWalletFund.fromJson(e)).toList();
}
@@ -530,7 +530,7 @@ Future<List<SnWalletFundRecipient>> walletFundRecipients(
}) async {
final client = ref.watch(apiClientProvider);
final resp = await client.get(
'/id/wallets/funds/recipients?offset=$offset&take=$take',
'/pass/wallets/funds/recipients?offset=$offset&take=$take',
);
return (resp.data as List)
.map((e) => SnWalletFundRecipient.fromJson(e))
@@ -540,14 +540,14 @@ Future<List<SnWalletFundRecipient>> walletFundRecipients(
@riverpod
Future<SnWalletFund> walletFund(Ref ref, String fundId) async {
final client = ref.watch(apiClientProvider);
final resp = await client.get('/id/wallets/funds/$fundId');
final resp = await client.get('/pass/wallets/funds/$fundId');
return SnWalletFund.fromJson(resp.data);
}
@riverpod
Future<Map<String, dynamic>> walletFundStats(Ref ref) async {
final client = ref.watch(apiClientProvider);
final resp = await client.get('/id/wallets/funds/stats');
final resp = await client.get('/pass/wallets/funds/stats');
return resp.data as Map<String, dynamic>;
}
@@ -563,7 +563,7 @@ class WalletScreen extends HookConsumerWidget {
Future<void> createWallet() async {
final client = ref.read(apiClientProvider);
try {
await client.post('/id/wallets');
await client.post('/pass/wallets');
ref.invalidate(walletCurrentProvider);
} catch (err) {
showErrorAlert(err);
@@ -941,14 +941,14 @@ class WalletScreen extends HookConsumerWidget {
try {
showLoadingModal(context);
final resp = await client.post(
'/id/wallets/funds',
'/pass/wallets/funds',
data: fundData,
options: Options(headers: {'X-Noop': true}),
);
final fund = SnWalletFund.fromJson(resp.data);
if (fund.status == 0) return; // Already created
final orderResp = await client.post('/id/wallets/funds/${fund.id}/order');
final orderResp = await client.post('/pass/wallets/funds/${fund.id}/order');
final order = SnWalletOrder.fromJson(orderResp.data);
if (context.mounted) hideLoadingModal(context);

View File

@@ -6,7 +6,7 @@ part of 'wallet.dart';
// RiverpodGenerator
// **************************************************************************
String _$walletCurrentHash() => r'088505ce1a78901016a3bda05217f813ed3b44c6';
String _$walletCurrentHash() => r'bdc7cb27ce2286b561a03522085cc4efc884faad';
/// See also [walletCurrent].
@ProviderFor(walletCurrent)
@@ -24,7 +24,7 @@ final walletCurrentProvider = AutoDisposeFutureProvider<SnWallet?>.internal(
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef WalletCurrentRef = AutoDisposeFutureProviderRef<SnWallet?>;
String _$walletStatsHash() => r'23d692a922c2388135be6a46afa73c018762eb57';
String _$walletStatsHash() => r'2243011937b377a66cdf44cae144021cee69e82f';
/// See also [walletStats].
@ProviderFor(walletStats)
@@ -40,7 +40,7 @@ final walletStatsProvider = AutoDisposeFutureProvider<SnWalletStats>.internal(
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef WalletStatsRef = AutoDisposeFutureProviderRef<SnWalletStats>;
String _$walletFundsHash() => r'7ceb415f64fcadab2b10461e27b95bf92352c707';
String _$walletFundsHash() => r'f60718c01ca5b7618a02682a0417669f750644a3';
/// Copied from Dart SDK
class _SystemHash {
@@ -195,7 +195,7 @@ class _WalletFundsProviderElement
}
String _$walletFundRecipientsHash() =>
r'18eb815eb709449dd5c545d81fc0ee43ca667578';
r'3a5e32b2d20700edd5944885693aff127b58adb1';
/// See also [walletFundRecipients].
@ProviderFor(walletFundRecipients)
@@ -339,7 +339,7 @@ class _WalletFundRecipientsProviderElement
int get take => (origin as WalletFundRecipientsProvider).take;
}
String _$walletFundHash() => r'a690b0def8f4293b4a8f244e44f8bb735687e5dd';
String _$walletFundHash() => r'459efdee5e2775eedaa4312e0d317c218fa7e1fa';
/// See also [walletFund].
@ProviderFor(walletFund)
@@ -460,7 +460,7 @@ class _WalletFundProviderElement
}
String _$transactionListNotifierHash() =>
r'7b777cd44f3351f68f7bd1dd76bfe8b388381bdb';
r'74d3c15f45a6e55b36150ab38e98475a508fc932';
/// See also [TransactionListNotifier].
@ProviderFor(TransactionListNotifier)

View File

@@ -13,14 +13,14 @@ class AbuseReportService {
Future<SnAbuseReport> getReport(String id) async {
final response = await ref
.read(apiClientProvider)
.get('/id/safety/reports/me/$id');
.get('/pass/safety/reports/me/$id');
return SnAbuseReport.fromJson(response.data);
}
Future<List<SnAbuseReport>> getReports() async {
final response = await ref
.read(apiClientProvider)
.get('/id/safety/reports/me');
.get('/pass/safety/reports/me');
return (response.data as List)
.map((json) => SnAbuseReport.fromJson(json))
.toList();

View File

@@ -0,0 +1,13 @@
import 'package:event_bus/event_bus.dart';
/// Global event bus instance for the application
final eventBus = EventBus();
/// Event fired when a post is successfully created
class PostCreatedEvent {
final String? postId;
final String? title;
final String? content;
const PostCreatedEvent({this.postId, this.title, this.content});
}

View File

@@ -22,7 +22,7 @@ part 'account_devices.g.dart';
Future<List<SnAuthDeviceWithChallenge>> authDevices(Ref ref) async {
final resp = await ref
.watch(apiClientProvider)
.get('/id/accounts/me/devices');
.get('/pass/accounts/me/devices');
final currentId = await getUdid();
final data =
resp.data.map<SnAuthDeviceWithChallenge>((e) {
@@ -154,7 +154,7 @@ class AccountSessionSheet extends HookConsumerWidget {
if (!confirm || !context.mounted) return;
try {
final apiClient = ref.watch(apiClientProvider);
await apiClient.delete('/id/accounts/me/devices/$sessionId');
await apiClient.delete('/pass/accounts/me/devices/$sessionId');
ref.invalidate(authDevicesProvider);
} catch (err) {
showErrorAlert(err);
@@ -193,7 +193,7 @@ class AccountSessionSheet extends HookConsumerWidget {
try {
final apiClient = ref.watch(apiClientProvider);
await apiClient.patch(
'/id/accounts/me/devices/$sessionId/label',
'/pass/accounts/me/devices/$sessionId/label',
data: jsonEncode(label),
);
ref.invalidate(authDevicesProvider);
@@ -284,7 +284,7 @@ class AccountSessionSheet extends HookConsumerWidget {
apiClientProvider,
);
await apiClient.delete(
'/id/accounts/me/devices/${device.deviceId}',
'/pass/accounts/me/devices/${device.deviceId}',
);
ref.invalidate(authDevicesProvider);
} catch (err) {

View File

@@ -6,7 +6,7 @@ part of 'account_devices.dart';
// RiverpodGenerator
// **************************************************************************
String _$authDevicesHash() => r'feb19238f759921e51c888f8b443a3d7761e68da';
String _$authDevicesHash() => r'35735af4ed75b73fe80c8942e53b3bc26a569c01';
/// See also [authDevices].
@ProviderFor(authDevices)

View File

@@ -36,11 +36,13 @@ const kVerificationMarkColors = [
class AccountName extends StatelessWidget {
final SnAccount account;
final TextStyle? style;
final String? textOverride;
final bool ignorePermissions;
const AccountName({
super.key,
required this.account,
this.style,
this.textOverride,
this.ignorePermissions = false,
});
@@ -177,7 +179,7 @@ class AccountName extends StatelessWidget {
child: ShaderMask(
shaderCallback: (bounds) => gradient.createShader(bounds),
child: Text(
account.nick,
textOverride ?? account.nick,
style: nameStyle.copyWith(color: Colors.white),
maxLines: 1,
overflow: TextOverflow.ellipsis,

View File

@@ -19,7 +19,7 @@ Future<List<SnAccount>> searchAccounts(Ref ref, {required String query}) async {
final apiClient = ref.watch(apiClientProvider);
final response = await apiClient.get(
'/id/accounts/search',
'/pass/accounts/search',
queryParameters: {'query': query},
);

View File

@@ -6,7 +6,7 @@ part of 'account_picker.dart';
// RiverpodGenerator
// **************************************************************************
String _$searchAccountsHash() => r'fa3b8b7d51e14cf40d4116ba0ff0b6955fa0ff54';
String _$searchAccountsHash() => r'3b4aa4d7970a1e406c1a0a1dfac2c686e05bc533';
/// Copied from Dart SDK
class _SystemHash {

View File

@@ -99,7 +99,7 @@ class EventDetailsWidget extends StatelessWidget {
],
),
if (event?.checkInResult == null && (event?.statuses.isEmpty ?? true))
Text('eventCalandarEmpty').tr(),
Text('eventCalendarEmpty').tr(),
],
).padding(vertical: 24, horizontal: 24);
}

View File

@@ -31,7 +31,7 @@ class RestorePurchaseSheet extends HookConsumerWidget {
try {
final client = ref.read(apiClientProvider);
await client.post(
'/id/subscriptions/order/restore/${selectedProvider.value!}',
'/pass/subscriptions/order/restore/${selectedProvider.value!}',
data: {'order_id': orderIdController.text.trim()},
);

View File

@@ -27,14 +27,18 @@ class CurrentAccountStatusNotifier extends StateNotifier<SnAccountStatus?> {
}
}
final currentAccountStatusProvider = StateNotifierProvider<CurrentAccountStatusNotifier, SnAccountStatus?>((ref) {
return CurrentAccountStatusNotifier();
});
final currentAccountStatusProvider =
StateNotifierProvider<CurrentAccountStatusNotifier, SnAccountStatus?>((
ref,
) {
return CurrentAccountStatusNotifier();
});
@riverpod
Future<SnAccountStatus?> accountStatus(Ref ref, String uname) async {
final userInfo = ref.watch(userInfoProvider);
if (uname == 'me' || (userInfo.value != null && uname == userInfo.value!.name)) {
if (uname == 'me' ||
(userInfo.value != null && uname == userInfo.value!.name)) {
final local = ref.watch(currentAccountStatusProvider);
if (local != null) {
return local;
@@ -42,7 +46,7 @@ Future<SnAccountStatus?> accountStatus(Ref ref, String uname) async {
}
final apiClient = ref.watch(apiClientProvider);
try {
final resp = await apiClient.get('/id/accounts/$uname/statuses');
final resp = await apiClient.get('/pass/accounts/$uname/statuses');
return SnAccountStatus.fromJson(resp.data);
} catch (err) {
if (err is DioException) {
@@ -137,9 +141,13 @@ class AccountStatusWidget extends HookConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final userInfo = ref.watch(userInfoProvider);
final localStatus = ref.watch(currentAccountStatusProvider);
final status = (uname == 'me' || (userInfo.value != null && uname == userInfo.value!.name && localStatus != null))
? AsyncValue.data(localStatus)
: ref.watch(accountStatusProvider(uname));
final status =
(uname == 'me' ||
(userInfo.value != null &&
uname == userInfo.value!.name &&
localStatus != null))
? AsyncValue.data(localStatus)
: ref.watch(accountStatusProvider(uname));
final account = ref.watch(accountProvider(uname));
return Padding(
@@ -166,16 +174,17 @@ class AccountStatusWidget extends HookConsumerWidget {
onLongPress: () {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Activity Details'),
content: buildActivityDetails(status.value),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text('Close'),
builder:
(context) => AlertDialog(
title: Text('Activity Details'),
content: buildActivityDetails(status.value),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text('Close'),
),
],
),
],
),
);
},
child: Tooltip(

View File

@@ -6,7 +6,7 @@ part of 'status.dart';
// RiverpodGenerator
// **************************************************************************
String _$accountStatusHash() => r'abc2f11f0fbaf637efc182cf85ab838936c4d875';
String _$accountStatusHash() => r'4cac809808e6f1345dab06dc32d759cfcea13315';
/// Copied from Dart SDK
class _SystemHash {

View File

@@ -33,7 +33,7 @@ class AccountStatusCreationSheet extends HookConsumerWidget {
submitting.value = true;
final user = ref.watch(userInfoProvider);
final apiClient = ref.read(apiClientProvider);
await apiClient.delete('/id/accounts/me/statuses');
await apiClient.delete('/pass/accounts/me/statuses');
if (!context.mounted) return;
ref.invalidate(accountStatusProvider(user.value!.name));
Navigator.pop(context);
@@ -50,7 +50,7 @@ class AccountStatusCreationSheet extends HookConsumerWidget {
final user = ref.watch(userInfoProvider);
final apiClient = ref.read(apiClientProvider);
await apiClient.request(
'/id/accounts/me/statuses',
'/pass/accounts/me/statuses',
data: {
'attitude': attitude.value,
'is_invisible': isInvisible.value,

View File

@@ -30,7 +30,7 @@ part 'stellar_program_tab.g.dart';
Future<SnWalletSubscription?> accountStellarSubscription(Ref ref) async {
try {
final client = ref.watch(apiClientProvider);
final resp = await client.get('/id/subscriptions/fuzzy/solian.stellar');
final resp = await client.get('/pass/subscriptions/fuzzy/solian.stellar');
return SnWalletSubscription.fromJson(resp.data);
} catch (err) {
if (err is DioException && err.response?.statusCode == 404) return null;
@@ -46,7 +46,7 @@ Future<List<SnWalletGift>> accountSentGifts(
}) async {
final client = ref.watch(apiClientProvider);
final resp = await client.get(
'/id/subscriptions/gifts/sent?offset=$offset&take=$take',
'/pass/subscriptions/gifts/sent?offset=$offset&take=$take',
);
return (resp.data as List).map((e) => SnWalletGift.fromJson(e)).toList();
}
@@ -59,7 +59,7 @@ Future<List<SnWalletGift>> accountReceivedGifts(
}) async {
final client = ref.watch(apiClientProvider);
final resp = await client.get(
'/id/subscriptions/gifts/received?offset=$offset&take=$take',
'/pass/subscriptions/gifts/received?offset=$offset&take=$take',
);
return (resp.data as List).map((e) => SnWalletGift.fromJson(e)).toList();
}
@@ -67,7 +67,7 @@ Future<List<SnWalletGift>> accountReceivedGifts(
@riverpod
Future<SnWalletGift> accountGift(Ref ref, String giftId) async {
final client = ref.watch(apiClientProvider);
final resp = await client.get('/id/subscriptions/gifts/$giftId');
final resp = await client.get('/pass/subscriptions/gifts/$giftId');
return SnWalletGift.fromJson(resp.data);
}
@@ -388,7 +388,9 @@ class StellarProgramTab extends HookConsumerWidget {
try {
showLoadingModal(context);
final client = ref.watch(apiClientProvider);
await client.post('/id/subscriptions/${membership.identifier}/cancel');
await client.post(
'/pass/subscriptions/${membership.identifier}/cancel',
);
ref.invalidate(accountStellarSubscriptionProvider);
ref.read(userInfoProvider.notifier).fetchUser();
if (context.mounted) {
@@ -698,7 +700,7 @@ class StellarProgramTab extends HookConsumerWidget {
try {
showLoadingModal(context);
final resp = await client.post(
'/id/subscriptions',
'/pass/subscriptions',
data: {
'identifier': tierId,
'payment_method': 'solian.wallet',
@@ -710,7 +712,7 @@ class StellarProgramTab extends HookConsumerWidget {
final subscription = SnWalletSubscription.fromJson(resp.data);
if (subscription.status == 1) return;
final orderResp = await client.post(
'/id/subscriptions/${subscription.identifier}/order',
'/pass/subscriptions/${subscription.identifier}/order',
);
final order = SnWalletOrder.fromJson(orderResp.data);
@@ -1221,7 +1223,7 @@ class StellarProgramTab extends HookConsumerWidget {
try {
showLoadingModal(context);
final resp = await client.post(
'/id/subscriptions/gifts/purchase',
'/pass/subscriptions/gifts/purchase',
data: {
'subscription_identifier': subscriptionId,
if (recipientId != null) 'recipient_id': recipientId,
@@ -1237,7 +1239,7 @@ class StellarProgramTab extends HookConsumerWidget {
if (gift.status == 1) return; // Already paid
final orderResp = await client.post(
'/id/subscriptions/gifts/${gift.id}/order',
'/pass/subscriptions/gifts/${gift.id}/order',
);
final order = SnWalletOrder.fromJson(orderResp.data);
@@ -1258,7 +1260,9 @@ class StellarProgramTab extends HookConsumerWidget {
await Future.delayed(const Duration(seconds: 1));
// Get the updated gift
final giftResp = await client.get('/id/subscriptions/gifts/${gift.id}');
final giftResp = await client.get(
'/pass/subscriptions/gifts/${gift.id}',
);
final updatedGift = SnWalletGift.fromJson(giftResp.data);
if (context.mounted) hideLoadingModal(context);
@@ -1367,7 +1371,7 @@ class StellarProgramTab extends HookConsumerWidget {
// First check if gift can be redeemed
final checkResp = await client.get(
'/id/subscriptions/gifts/check/$giftCode',
'/pass/subscriptions/gifts/check/$giftCode',
);
final checkData = checkResp.data as Map<String, dynamic>;
@@ -1379,7 +1383,7 @@ class StellarProgramTab extends HookConsumerWidget {
// Redeem the gift
await client.post(
'/id/subscriptions/gifts/redeem',
'/pass/subscriptions/gifts/redeem',
data: {'gift_code': giftCode},
);
@@ -1424,7 +1428,7 @@ class StellarProgramTab extends HookConsumerWidget {
final client = ref.watch(apiClientProvider);
try {
showLoadingModal(context);
await client.post('/id/subscriptions/gifts/${gift.id}/cancel');
await client.post('/pass/subscriptions/gifts/${gift.id}/cancel');
ref.invalidate(accountSentGiftsProvider);
if (context.mounted) {
hideLoadingModal(context);

View File

@@ -7,7 +7,7 @@ part of 'stellar_program_tab.dart';
// **************************************************************************
String _$accountStellarSubscriptionHash() =>
r'80abcdefb3868775fd8fe3c980215713efff5948';
r'7cdfc7ca29aac240fc8704f4493498d87f307400';
/// See also [accountStellarSubscription].
@ProviderFor(accountStellarSubscription)
@@ -27,7 +27,7 @@ final accountStellarSubscriptionProvider =
// ignore: unused_element
typedef AccountStellarSubscriptionRef =
AutoDisposeFutureProviderRef<SnWalletSubscription?>;
String _$accountSentGiftsHash() => r'36fdf4e2be3805e8501cca1657d8be27aa891ef4';
String _$accountSentGiftsHash() => r'460af8d22e16dc402848cb94e9b8a8a26d023c41';
/// Copied from Dart SDK
class _SystemHash {
@@ -187,7 +187,7 @@ class _AccountSentGiftsProviderElement
}
String _$accountReceivedGiftsHash() =>
r'15f6f7e27aa0277b67b02dd72875ba3efd147dfd';
r'1208c27cca49e154af073071a197b37a2703f56d';
/// See also [accountReceivedGifts].
@ProviderFor(accountReceivedGifts)
@@ -328,7 +328,7 @@ class _AccountReceivedGiftsProviderElement
int get take => (origin as AccountReceivedGiftsProvider).take;
}
String _$accountGiftHash() => r'598c5071fff3cc1dd7eb867df48d69fef04543db';
String _$accountGiftHash() => r'70ca553e0b84cba9dfbee428f9bf44207138713a';
/// See also [accountGift].
@ProviderFor(accountGift)

View File

@@ -11,8 +11,13 @@ import '../services/responsive.dart';
/// Shows exactly 365 days (wide screen) or 90 days (non-wide screen) of data ending at the current date.
class ActivityHeatmapWidget extends HookConsumerWidget {
final SnHeatmap heatmap;
final bool forceDense;
const ActivityHeatmapWidget({super.key, required this.heatmap});
const ActivityHeatmapWidget({
super.key,
required this.heatmap,
this.forceDense = false,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
@@ -21,7 +26,7 @@ class ActivityHeatmapWidget extends HookConsumerWidget {
final now = DateTime.now();
final isWide = isWideScreen(context);
final days = isWide ? 365 : 90;
final days = (isWide && !forceDense) ? 365 : 90;
// Start from exactly the selected days ago
final startDate = now.subtract(Duration(days: days));

View File

@@ -12,7 +12,6 @@ import 'package:island/pods/config.dart';
import 'package:island/route.dart';
import 'package:island/pods/userinfo.dart';
import 'package:island/pods/websocket.dart';
import 'package:island/screens/tabs.dart';
import 'package:island/services/responsive.dart';
import 'package:material_symbols_icons/material_symbols_icons.dart';
import 'package:path_provider/path_provider.dart';
@@ -314,28 +313,22 @@ class AppScaffold extends HookConsumerWidget {
final noBackground = isNoBackground ?? isWideScreen(context);
final content = Column(
children: [
IgnorePointer(
child: SizedBox(height: appBar != null ? appBarHeight + safeTop : 0),
),
if (body != null) Expanded(child: body!),
],
);
return Focus(
final builtWidget = Focus(
focusNode: focusNode,
child: Scaffold(
extendBody: extendBody ?? true,
extendBodyBehindAppBar: true,
backgroundColor:
noBackground
? Colors.transparent
: Theme.of(context).scaffoldBackgroundColor,
body:
noBackground
? content
: AppBackground(isRoot: true, child: content),
backgroundColor: Colors.transparent,
body: Column(
children: [
IgnorePointer(
child: SizedBox(
height: appBar != null ? appBarHeight + safeTop : 0,
),
),
if (body != null) Expanded(child: body!),
],
),
appBar: appBar,
bottomNavigationBar: bottomNavigationBar,
bottomSheet: bottomSheet,
@@ -343,11 +336,14 @@ class AppScaffold extends HookConsumerWidget {
endDrawer: endDrawer,
floatingActionButton: floatingActionButton,
floatingActionButtonAnimator: floatingActionButtonAnimator,
floatingActionButtonLocation: TabbedFabLocation(context),
onDrawerChanged: onDrawerChanged,
onEndDrawerChanged: onEndDrawerChanged,
),
);
return noBackground
? builtWidget
: AppBackground(isRoot: true, child: builtWidget);
}
}
@@ -372,14 +368,20 @@ class PageBackButton extends StatelessWidget {
final Color? color;
final List<Shadow>? shadows;
final VoidCallback? onWillPop;
const PageBackButton({super.key, this.shadows, this.onWillPop, this.color});
final String? backTo;
const PageBackButton({
super.key,
this.shadows,
this.onWillPop,
this.color,
this.backTo,
});
@override
Widget build(BuildContext context) {
final isDesktop =
!kIsWeb && (Platform.isMacOS || Platform.isLinux || Platform.isWindows);
final hasPageAction = !kIsWeb && Platform.isMacOS;
if (isDesktop && isWideScreen(context)) return const SizedBox.shrink();
if (hasPageAction && isWideScreen(context)) return const SizedBox.shrink();
return IconButton(
onPressed: () {
@@ -387,7 +389,7 @@ class PageBackButton extends StatelessWidget {
if (context.canPop()) {
context.pop();
} else {
context.go('/');
context.go(backTo ?? '/');
}
},
icon: Icon(

View File

@@ -73,10 +73,8 @@ class ChatInput extends HookConsumerWidget {
final chatSubscribe = ref.watch(chatSubscribeNotifierProvider(chatRoom.id));
void send() {
inputFocusNode.requestFocus();
onSend.call();
WidgetsBinding.instance.addPostFrameCallback((_) {
inputFocusNode.requestFocus();
});
}
void insertNewLine() {
@@ -120,6 +118,8 @@ class ChatInput extends HookConsumerWidget {
}
}
final settings = ref.watch(appSettingsNotifierProvider);
inputFocusNode.onKeyEvent = (node, event) {
if (event is! KeyDownEvent) return KeyEventResult.ignored;
@@ -133,7 +133,7 @@ class ChatInput extends HookConsumerWidget {
return KeyEventResult.handled;
}
final enterToSend = ref.read(appSettingsNotifierProvider).enterToSend;
final enterToSend = settings.enterToSend;
final isEnter = event.logicalKey == LogicalKeyboardKey.enter;
if (isEnter) {
@@ -467,24 +467,28 @@ class ChatInput extends HookConsumerWidget {
),
UploadMenu(
items: [
MenuItemData(
UploadMenuItemData(
Symbols.add_a_photo,
'addPhoto',
() => onPickFile(true),
),
MenuItemData(
UploadMenuItemData(
Symbols.videocam,
'addVideo',
() => onPickFile(false),
),
MenuItemData(Symbols.mic, 'addAudio', onPickAudio),
MenuItemData(
UploadMenuItemData(
Symbols.mic,
'addAudio',
onPickAudio,
),
UploadMenuItemData(
Symbols.file_upload,
'uploadFile',
onPickGeneralFile,
),
if (onLinkAttachment != null)
MenuItemData(
UploadMenuItemData(
Symbols.attach_file,
'linkAttachment',
onLinkAttachment!,
@@ -528,11 +532,17 @@ class ChatInput extends HookConsumerWidget {
? '${messageController.text.length}/4096'
: null,
),
maxLines: 3,
maxLines: 5,
minLines: 1,
onTapOutside:
(_) =>
FocusManager.instance.primaryFocus?.unfocus(),
textInputAction:
settings.enterToSend
? TextInputAction.send
: null,
onSubmitted:
settings.enterToSend ? (_) => send() : null,
);
},
suggestionsCallback: (pattern) async {
@@ -542,11 +552,13 @@ class ChatInput extends HookConsumerWidget {
final triggerIndex =
atIndex > colonIndex ? atIndex : colonIndex;
if (triggerIndex == -1) return [];
final chopped = pattern.substring(triggerIndex);
if (chopped.contains(' ')) return [];
final service = ref.read(autocompleteServiceProvider);
try {
return await service.getSuggestions(
chatRoom.id,
pattern,
chopped,
);
} catch (e) {
return [];
@@ -637,7 +649,7 @@ class ChatInput extends HookConsumerWidget {
direction: VerticalDirection.up,
hideOnEmpty: true,
hideOnLoading: true,
debounceDuration: const Duration(milliseconds: 500),
debounceDuration: const Duration(milliseconds: 1000),
),
),
IconButton(

View File

@@ -13,8 +13,8 @@ import 'package:island/pods/chat/chat_rooms.dart';
import 'package:island/pods/chat/messages_notifier.dart';
import 'package:island/pods/translate.dart';
import 'package:island/pods/config.dart';
import 'package:island/services/time.dart';
import 'package:island/widgets/account/account_pfc.dart';
import 'package:island/widgets/app_scaffold.dart';
import 'package:island/widgets/chat/message_content.dart';
import 'package:island/widgets/chat/message_indicators.dart';
import 'package:island/widgets/chat/message_sender_info.dart';
@@ -161,6 +161,7 @@ class MessageItem extends HookConsumerWidget {
clipBehavior: Clip.none,
children: [
SwipeTo(
swipeSensitivity: 15,
rightSwipeWidget: Transform.flip(
flipX: true,
child: Icon(Symbols.menu_open),
@@ -398,7 +399,19 @@ class _MessageActionSheetState extends State<MessageActionSheet> {
const Gap(4),
],
const Gap(8),
Row(
spacing: 6,
children: [
Icon(Symbols.send, size: 16),
Text(
'messageSentAt'.tr(
args: [widget.message.createdAt.formatSystem()],
),
).fontSize(13),
],
).opacity(0.75).padding(horizontal: 20, top: 8, bottom: 6),
const Divider(),
// Action buttons
if (widget.isCurrentUser)
@@ -477,6 +490,8 @@ class _MessageActionSheetState extends State<MessageActionSheet> {
Navigator.pop(context);
},
),
Gap(MediaQuery.of(context).padding.bottom + 32),
],
),
),
@@ -663,17 +678,11 @@ class MessageItemDisplayBubble extends HookConsumerWidget {
? Theme.of(context).colorScheme.primaryContainer.withOpacity(0.5)
: Theme.of(context).colorScheme.surfaceContainer;
final hasBackground =
ref.watch(backgroundImageFileProvider).valueOrNull != null;
final remoteMessage = message.toRemoteMessage();
final sender = remoteMessage.sender;
return Material(
color:
hasBackground
? Colors.transparent
: Theme.of(context).colorScheme.surface,
color: Colors.transparent,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
child: Column(

View File

@@ -26,7 +26,7 @@ part 'check_in.g.dart';
Future<SnCheckInResult?> checkInResultToday(Ref ref) async {
final client = ref.watch(apiClientProvider);
try {
final resp = await client.get('/id/accounts/me/check-in');
final resp = await client.get('/pass/accounts/me/check-in');
return SnCheckInResult.fromJson(resp.data);
} catch (err) {
if (err is DioException) {
@@ -42,7 +42,7 @@ Future<SnCheckInResult?> checkInResultToday(Ref ref) async {
Future<SnNotableDay?> nextNotableDay(Ref ref) async {
final client = ref.watch(apiClientProvider);
try {
final resp = await client.get('/id/notable/me/next');
final resp = await client.get('/pass/notable/me/next');
return SnNotableDay.fromJson(resp.data);
} catch (err) {
return null;
@@ -94,7 +94,7 @@ class CheckInWidget extends HookConsumerWidget {
final client = ref.read(apiClientProvider);
try {
await client.post(
'/id/accounts/me/check-in',
'/pass/accounts/me/check-in',
data: captchatTk == null ? null : jsonEncode(captchatTk),
);
ref.invalidate(checkInResultTodayProvider);

View File

@@ -7,7 +7,7 @@ part of 'check_in.dart';
// **************************************************************************
String _$checkInResultTodayHash() =>
r'402e3a3be0d441ae12b2370d19d09bf81326933f';
r'b4dc97b2243f542b36c295dc5cce3fe6097cb308';
/// See also [checkInResultToday].
@ProviderFor(checkInResultToday)
@@ -26,7 +26,7 @@ final checkInResultTodayProvider =
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef CheckInResultTodayRef = AutoDisposeFutureProviderRef<SnCheckInResult?>;
String _$nextNotableDayHash() => r'698370bec4be28774d332412c5a701f914064c90';
String _$nextNotableDayHash() => r'c8404308f6b0f581cc7df251bce8f3c5ac130245';
/// See also [nextNotableDay].
@ProviderFor(nextNotableDay)

View File

@@ -193,10 +193,7 @@ class _PaymentContentState extends ConsumerState<_PaymentContent> {
// Perform biometric authentication
final bool didAuthenticate = await _localAuth.authenticate(
localizedReason: 'biometricPrompt'.tr(),
options: const AuthenticationOptions(
biometricOnly: true,
stickyAuth: true,
),
biometricOnly: true,
);
if (didAuthenticate) {
@@ -244,7 +241,7 @@ class _PaymentContentState extends ConsumerState<_PaymentContent> {
try {
final client = ref.read(apiClientProvider);
final response = await client.post(
'/id/orders/${widget.order.id}/pay',
'/pass/orders/${widget.order.id}/pay',
data: {'pin_code': pin},
);

View File

@@ -34,9 +34,9 @@ class PostComposeCard extends HookConsumerWidget {
final SnPost? originalPost;
final PostComposeInitialState? initialState;
final VoidCallback? onCancel;
final Function(SnPost)? onSubmit;
final Function()? onSubmit;
final Function(ComposeState)? onStateChanged;
final bool isInDialog;
final bool isDialog;
const PostComposeCard({
super.key,
@@ -45,7 +45,7 @@ class PostComposeCard extends HookConsumerWidget {
this.onCancel,
this.onSubmit,
this.onStateChanged,
this.isInDialog = false,
this.isDialog = false,
});
@override
@@ -164,20 +164,19 @@ class PostComposeCard extends HookConsumerWidget {
// Reset the form for new composition
ComposeStateUtils.resetForm(state);
// Call the widget's onSubmit callback to trigger activity list refresh
// Note: onSubmit still receives the post from the return value
onSubmit?.call();
},
);
}
final maxHeight = math.min(
640.0,
MediaQuery.of(context).size.height * (isInDialog ? 0.8 : 0.72),
MediaQuery.of(context).size.height * (isDialog ? 0.8 : 0.72),
);
return Card(
margin: EdgeInsets.zero,
color: Theme.of(context).colorScheme.surfaceContainer,
color: isDialog ? Theme.of(context).colorScheme.surfaceContainer : null,
child: Container(
constraints: BoxConstraints(maxHeight: maxHeight),
child: Column(
@@ -311,7 +310,7 @@ class PostComposeCard extends HookConsumerWidget {
onTap: () {
if (state.currentPublisher.value == null) {
// No publisher loaded, guide user to create one
if (isInDialog) {
if (isDialog) {
Navigator.of(context).pop();
}
context.pushNamed('creatorNew').then((value) {
@@ -348,7 +347,7 @@ class PostComposeCard extends HookConsumerWidget {
onPublisherTap: () {
if (state.currentPublisher.value == null) {
// No publisher loaded, guide user to create one
if (isInDialog) {
if (isDialog) {
Navigator.of(context).pop();
}
context.pushNamed('creatorNew').then((

View File

@@ -6,6 +6,7 @@ import 'package:island/models/file.dart';
import 'package:island/models/post.dart';
import 'package:island/screens/posts/compose.dart';
import 'package:island/services/compose_storage_db.dart';
import 'package:island/services/event_bus.dart';
import 'package:island/services/responsive.dart';
import 'package:island/widgets/post/compose_card.dart';
@@ -23,12 +24,12 @@ class PostComposeDialog extends HookConsumerWidget {
this.isBottomSheet = false,
});
static Future<SnPost?> show(
static Future<bool?> show(
BuildContext context, {
SnPost? originalPost,
PostComposeInitialState? initialState,
}) {
return showDialog<SnPost>(
return showDialog<bool>(
context: context,
useRootNavigator: true,
builder:
@@ -74,8 +75,12 @@ class PostComposeDialog extends HookConsumerWidget {
originalPost: originalPost,
initialState: restoredInitialState.value ?? initialState,
onCancel: () => Navigator.of(context).pop(),
onSubmit: (post) => Navigator.of(context).pop(post),
isInDialog: true,
onSubmit: () {
// Fire event to notify listeners that a post was created
eventBus.fire(PostCreatedEvent());
Navigator.of(context).pop(true);
},
isDialog: true,
),
),
);

View File

@@ -149,9 +149,11 @@ class ComposeFormFields extends HookConsumerWidget {
final triggerIndex =
atIndex > colonIndex ? atIndex : colonIndex;
if (triggerIndex == -1) return [];
final chopped = pattern.substring(triggerIndex);
if (chopped.contains(' ')) return [];
final service = ref.read(autocompleteServiceProvider);
try {
return await service.getGeneralSuggestions(pattern);
return await service.getGeneralSuggestions(chopped);
} catch (e) {
return [];
}
@@ -235,7 +237,7 @@ class ComposeFormFields extends HookConsumerWidget {
direction: VerticalDirection.down,
hideOnEmpty: true,
hideOnLoading: true,
debounceDuration: const Duration(milliseconds: 500),
debounceDuration: const Duration(milliseconds: 1000),
),
],
),

View File

@@ -16,7 +16,6 @@ import 'package:island/widgets/post/compose_shared.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:styled_widget/styled_widget.dart';
import 'package:textfield_tags/textfield_tags.dart';
part 'compose_settings_sheet.g.dart';
@@ -37,98 +36,6 @@ Future<List<SnPostCategory>> postCategories(Ref ref) async {
return uniqueCategories.values.toList();
}
/// A reusable widget for tag input fields with chip display
class ChipTagInputField extends StatelessWidget {
final InputFieldValues inputFieldValues;
final String labelText;
final String hintText;
const ChipTagInputField({
super.key,
required this.inputFieldValues,
required this.labelText,
required this.hintText,
});
@override
Widget build(BuildContext context) {
return TextField(
controller: inputFieldValues.textEditingController,
focusNode: inputFieldValues.focusNode,
decoration: InputDecoration(
label: Text(labelText).tr(),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
contentPadding: const EdgeInsets.all(16),
hintText: inputFieldValues.tags.isNotEmpty ? '' : hintText.tr(),
errorText: inputFieldValues.error,
prefixIconConstraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width * 0.8,
),
prefixIcon:
inputFieldValues.tags.isNotEmpty
? SingleChildScrollView(
controller: inputFieldValues.tagScrollController,
scrollDirection: Axis.vertical,
child: Padding(
padding: const EdgeInsets.only(top: 8, bottom: 8, left: 8),
child: Wrap(
runSpacing: 4.0,
spacing: 4.0,
children:
inputFieldValues.tags.map<Widget>((dynamic tag) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(20.0),
),
color: Theme.of(context).colorScheme.primary,
),
margin: const EdgeInsets.only(left: 5),
padding: const EdgeInsets.symmetric(
horizontal: 10.0,
vertical: 5.0,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
InkWell(
child: Text(
'#$tag',
style: TextStyle(
color:
Theme.of(
context,
).colorScheme.onPrimary,
),
),
),
const Gap(4),
InkWell(
child: const Icon(
Icons.cancel,
size: 14.0,
color: Color.fromARGB(255, 233, 233, 233),
),
onTap: () {
inputFieldValues.onTagRemoved(tag);
},
),
],
),
);
}).toList(),
),
),
)
: null,
),
onChanged: inputFieldValues.onTagChanged,
onSubmitted: inputFieldValues.onTagSubmitted,
);
}
}
class ComposeSettingsSheet extends HookConsumerWidget {
final ComposeState state;

View File

@@ -82,10 +82,10 @@ class ComposeToolbar extends HookConsumerWidget {
}
final uploadMenuItems = [
MenuItemData(Symbols.add_a_photo, 'addPhoto', pickPhotoMedia),
MenuItemData(Symbols.videocam, 'addVideo', pickVideoMedia),
MenuItemData(Symbols.mic, 'addAudio', addAudio),
MenuItemData(Symbols.file_upload, 'uploadFile', pickGeneralFile),
UploadMenuItemData(Symbols.add_a_photo, 'addPhoto', pickPhotoMedia),
UploadMenuItemData(Symbols.videocam, 'addVideo', pickVideoMedia),
UploadMenuItemData(Symbols.mic, 'addAudio', addAudio),
UploadMenuItemData(Symbols.file_upload, 'uploadFile', pickGeneralFile),
];
final colorScheme = Theme.of(context).colorScheme;

View File

@@ -259,7 +259,7 @@ class PostAwardSheet extends HookConsumerWidget {
final orderId = awardResponse.data['order_id'] as String;
// Fetch order details
final orderResponse = await client.get('/id/orders/$orderId');
final orderResponse = await client.get('/pass/orders/$orderId');
final order = SnWalletOrder.fromJson(orderResponse.data);
if (context.mounted) {

View File

@@ -334,7 +334,7 @@ class PostActionableItem extends HookConsumerWidget {
);
},
child: Material(
color: Theme.of(context).colorScheme.surfaceContainerLow,
color: Theme.of(context).cardTheme.color,
borderRadius:
borderRadius != null
? BorderRadius.all(Radius.circular(borderRadius!))
@@ -488,7 +488,9 @@ class PostItem extends HookConsumerWidget {
child: TextButton.icon(
onPressed: translating.value ? null : translate,
style: ButtonStyle(
padding: const WidgetStatePropertyAll(EdgeInsets.zero),
padding: const WidgetStatePropertyAll(
EdgeInsets.symmetric(horizontal: 2),
),
visualDensity: const VisualDensity(
horizontal: 0,
vertical: -4,

View File

@@ -23,6 +23,7 @@ class PostListNotifier extends _$PostListNotifier
List<String>? tags,
bool? pinned,
bool shuffle = false,
bool? includeReplies,
}) {
return fetch(cursor: null);
}
@@ -42,6 +43,7 @@ class PostListNotifier extends _$PostListNotifier
if (categories != null) 'categories': categories,
if (shuffle) 'shuffle': true,
if (pinned != null) 'pinned': pinned,
if (includeReplies != null) 'includeReplies': includeReplies,
};
final response = await client.get(

View File

@@ -6,7 +6,7 @@ part of 'post_list.dart';
// RiverpodGenerator
// **************************************************************************
String _$postListNotifierHash() => r'3c0a8154ded4bcd8f5456f7a4ea2e542f57efa85';
String _$postListNotifierHash() => r'fc139ad4df0deb67bcbb949560319f2f7fbfb503';
/// Copied from Dart SDK
class _SystemHash {
@@ -38,6 +38,7 @@ abstract class _$PostListNotifier
late final List<String>? tags;
late final bool? pinned;
late final bool shuffle;
late final bool? includeReplies;
FutureOr<CursorPagingData<SnPost>> build({
String? pubName,
@@ -47,6 +48,7 @@ abstract class _$PostListNotifier
List<String>? tags,
bool? pinned,
bool shuffle = false,
bool? includeReplies,
});
}
@@ -69,6 +71,7 @@ class PostListNotifierFamily
List<String>? tags,
bool? pinned,
bool shuffle = false,
bool? includeReplies,
}) {
return PostListNotifierProvider(
pubName: pubName,
@@ -78,6 +81,7 @@ class PostListNotifierFamily
tags: tags,
pinned: pinned,
shuffle: shuffle,
includeReplies: includeReplies,
);
}
@@ -93,6 +97,7 @@ class PostListNotifierFamily
tags: provider.tags,
pinned: provider.pinned,
shuffle: provider.shuffle,
includeReplies: provider.includeReplies,
);
}
@@ -127,6 +132,7 @@ class PostListNotifierProvider
List<String>? tags,
bool? pinned,
bool shuffle = false,
bool? includeReplies,
}) : this._internal(
() =>
PostListNotifier()
@@ -136,7 +142,8 @@ class PostListNotifierProvider
..categories = categories
..tags = tags
..pinned = pinned
..shuffle = shuffle,
..shuffle = shuffle
..includeReplies = includeReplies,
from: postListNotifierProvider,
name: r'postListNotifierProvider',
debugGetCreateSourceHash:
@@ -153,6 +160,7 @@ class PostListNotifierProvider
tags: tags,
pinned: pinned,
shuffle: shuffle,
includeReplies: includeReplies,
);
PostListNotifierProvider._internal(
@@ -169,6 +177,7 @@ class PostListNotifierProvider
required this.tags,
required this.pinned,
required this.shuffle,
required this.includeReplies,
}) : super.internal();
final String? pubName;
@@ -178,6 +187,7 @@ class PostListNotifierProvider
final List<String>? tags;
final bool? pinned;
final bool shuffle;
final bool? includeReplies;
@override
FutureOr<CursorPagingData<SnPost>> runNotifierBuild(
@@ -191,6 +201,7 @@ class PostListNotifierProvider
tags: tags,
pinned: pinned,
shuffle: shuffle,
includeReplies: includeReplies,
);
}
@@ -207,7 +218,8 @@ class PostListNotifierProvider
..categories = categories
..tags = tags
..pinned = pinned
..shuffle = shuffle,
..shuffle = shuffle
..includeReplies = includeReplies,
from: from,
name: null,
dependencies: null,
@@ -220,6 +232,7 @@ class PostListNotifierProvider
tags: tags,
pinned: pinned,
shuffle: shuffle,
includeReplies: includeReplies,
),
);
}
@@ -242,7 +255,8 @@ class PostListNotifierProvider
other.categories == categories &&
other.tags == tags &&
other.pinned == pinned &&
other.shuffle == shuffle;
other.shuffle == shuffle &&
other.includeReplies == includeReplies;
}
@override
@@ -255,6 +269,7 @@ class PostListNotifierProvider
hash = _SystemHash.combine(hash, tags.hashCode);
hash = _SystemHash.combine(hash, pinned.hashCode);
hash = _SystemHash.combine(hash, shuffle.hashCode);
hash = _SystemHash.combine(hash, includeReplies.hashCode);
return _SystemHash.finish(hash);
}
@@ -284,6 +299,9 @@ mixin PostListNotifierRef
/// The parameter `shuffle` of this provider.
bool get shuffle;
/// The parameter `includeReplies` of this provider.
bool? get includeReplies;
}
class _PostListNotifierProviderElement
@@ -310,6 +328,9 @@ class _PostListNotifierProviderElement
bool? get pinned => (origin as PostListNotifierProvider).pinned;
@override
bool get shuffle => (origin as PostListNotifierProvider).shuffle;
@override
bool? get includeReplies =>
(origin as PostListNotifierProvider).includeReplies;
}
// ignore_for_file: type=lint

View File

@@ -68,21 +68,24 @@ class PostQuickReply extends HookConsumerWidget {
}
}
const kInputChipHeight = 54.0;
return publishers.when(
data:
(data) => Material(
elevation: 2,
color: Theme.of(context).colorScheme.surfaceContainerHighest,
borderRadius: BorderRadius.circular(20),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 8),
borderRadius: BorderRadius.circular(28),
child: Container(
constraints: BoxConstraints(minHeight: kInputChipHeight),
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
GestureDetector(
child: ProfilePictureWidget(
fileId: currentPublisher.value?.picture?.id,
radius: 16,
radius: (kInputChipHeight * 0.5) - 6,
),
onTap: () {
showModalBottomSheet(
@@ -106,11 +109,13 @@ class PostQuickReply extends HookConsumerWidget {
isCollapsed: true,
contentPadding: EdgeInsets.symmetric(
horizontal: 12,
vertical: 9,
vertical: 14,
),
visualDensity: VisualDensity.compact,
),
style: TextStyle(fontSize: 14),
maxLines: null,
minLines: 1,
maxLines: 5,
onTapOutside:
(_) => FocusManager.instance.primaryFocus?.unfocus(),
),
@@ -130,6 +135,10 @@ class PostQuickReply extends HookConsumerWidget {
},
icon: const Icon(Symbols.launch, size: 20),
visualDensity: VisualDensity.compact,
constraints: BoxConstraints(
maxHeight: kInputChipHeight - 6,
minHeight: kInputChipHeight - 6,
),
),
IconButton(
icon:
@@ -143,6 +152,10 @@ class PostQuickReply extends HookConsumerWidget {
color: Theme.of(context).colorScheme.primary,
onPressed: submitting.value ? null : performAction,
visualDensity: VisualDensity.compact,
constraints: BoxConstraints(
maxHeight: kInputChipHeight - 6,
minHeight: kInputChipHeight - 6,
),
),
],
),

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/post.dart';
import 'package:island/pods/userinfo.dart';
@@ -19,35 +20,37 @@ class PostRepliesSheet extends HookConsumerWidget {
return SheetScaffold(
titleText: 'repliesCount'.plural(post.repliesCount),
child: Column(
child: Stack(
children: [
// Replies list
Expanded(
child: CustomScrollView(
slivers: [
PostRepliesList(
postId: post.id.toString(),
onOpen: () {
Navigator.pop(context);
},
),
],
),
CustomScrollView(
slivers: [
PostRepliesList(
postId: post.id.toString(),
onOpen: () {
Navigator.pop(context);
},
),
SliverGap(80),
],
),
// Quick reply section
if (user.value != null)
PostQuickReply(
parent: post,
onPosted: () {
ref.invalidate(postRepliesNotifierProvider(post.id));
},
onLaunch: () {
Navigator.of(context).pop();
},
).padding(
bottom: MediaQuery.of(context).padding.bottom + 16,
top: 8,
horizontal: 16,
Positioned(
bottom: 0,
left: 0,
right: 0,
child: PostQuickReply(
parent: post,
onPosted: () {
ref.invalidate(postRepliesNotifierProvider(post.id));
},
onLaunch: () {
Navigator.of(context).pop();
},
).padding(
bottom: MediaQuery.of(context).padding.bottom + 16,
top: 8,
horizontal: 16,
),
),
],
),

View File

@@ -547,14 +547,6 @@ class PostHeader extends StatelessWidget {
Widget build(BuildContext context) {
return Column(
children: [
if (item.pinMode != null)
Row(
spacing: 4,
children: [
const Icon(Symbols.keep, size: 15, fill: 1),
Text('pinnedPost').tr().fontSize(13),
],
).opacity(0.8).padding(horizontal: 8, bottom: 4),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
spacing: 12,
@@ -570,7 +562,9 @@ class PostHeader extends StatelessWidget {
}
: null,
child: ProfilePictureWidget(
file: item.publisher.picture,
file:
item.publisher.picture ??
item.publisher.account?.profile.picture,
radius: 16,
borderRadius: item.publisher.type == 0 ? null : 6,
),
@@ -586,11 +580,17 @@ class PostHeader extends StatelessWidget {
children: [
Flexible(
child:
Text(
item.publisher.nick,
maxLines: 1,
overflow: TextOverflow.ellipsis,
).bold(),
item.publisher.account != null
? AccountName(
account: item.publisher.account!,
textOverride: item.publisher.nick,
style: TextStyle(fontWeight: FontWeight.bold),
)
: Text(
item.publisher.nick,
maxLines: 1,
overflow: TextOverflow.ellipsis,
).bold(),
),
if (item.publisher.verification != null)
VerificationMark(mark: item.publisher.verification!),
@@ -639,35 +639,13 @@ class PostHeader extends StatelessWidget {
]),
],
),
Row(
spacing: 6,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
!isFullPost && isRelativeTime
? (item.publishedAt ?? item.createdAt)!
.formatRelative(context)
: (item.publishedAt ?? item.createdAt)!
.formatSystem(),
).fontSize(10),
if (item.editedAt != null)
Text(
'editedAt'.tr(
args: [
!isFullPost && isRelativeTime
? item.editedAt!.formatRelative(context)
: item.editedAt!.formatSystem(),
],
),
).fontSize(10),
if (item.visibility != 0)
Text(
PostVisibilityHelpers.getVisibilityText(
item.visibility,
).tr(),
).fontSize(10),
],
),
Text(
!isFullPost && isRelativeTime
? (item.publishedAt ?? item.createdAt)!.formatRelative(
context,
)
: (item.publishedAt ?? item.createdAt)!.formatSystem(),
).fontSize(10),
],
),
),
@@ -686,6 +664,7 @@ class PostBody extends ConsumerWidget {
final Widget? translationSection;
final bool isInteractive;
final EdgeInsets renderingPadding;
final bool isRelativeTime;
const PostBody({
super.key,
@@ -695,10 +674,144 @@ class PostBody extends ConsumerWidget {
this.translationSection,
this.isInteractive = true,
this.renderingPadding = EdgeInsets.zero,
this.isRelativeTime = true,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final metadataChildren = <Widget>[];
if (item.pinMode != null) {
metadataChildren.add(
Row(
spacing: 8,
children: [
const Icon(Symbols.push_pin, size: 16),
Text('pinnedPost'.tr()).fontSize(13),
],
),
);
}
if (item.tags.isNotEmpty) {
metadataChildren.add(
Wrap(
runAlignment: WrapAlignment.center,
spacing: 8,
children: [
const Icon(Symbols.label, size: 16).padding(top: 2),
for (final tag in isFullPost ? item.tags : item.tags.take(3))
InkWell(
onTap:
isInteractive
? () {
GoRouter.of(context).pushNamed(
'postTagDetail',
pathParameters: {'slug': tag.slug},
);
}
: null,
child: Text('#${tag.name ?? tag.slug}'),
),
if (!isFullPost && item.tags.length > 3)
Text('+${item.tags.length - 3}').opacity(0.6),
],
),
);
}
if (item.categories.isNotEmpty) {
metadataChildren.add(
Wrap(
runAlignment: WrapAlignment.center,
spacing: 8,
children: [
const Icon(Symbols.category, size: 16).padding(top: 2),
for (final category
in isFullPost ? item.categories : item.categories.take(2))
InkWell(
onTap:
isInteractive
? () {
GoRouter.of(context).pushNamed(
'postCategoryDetail',
pathParameters: {'slug': category.slug},
);
}
: null,
child: Text(category.categoryDisplayTitle),
),
if (!isFullPost && item.categories.length > 2)
Text('+${item.categories.length - 2}').opacity(0.6),
],
),
);
}
if (item.editedAt != null) {
metadataChildren.add(
Row(
spacing: 8,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Icon(Symbols.edit, size: 16),
Text(
'editedAt'.tr(
args: [
!isFullPost && isRelativeTime
? item.editedAt!.formatRelative(context)
: item.editedAt!.formatSystem(),
],
),
).fontSize(13),
],
),
);
}
if (item.visibility != 0) {
metadataChildren.add(
Row(
spacing: 8,
children: [
const Icon(Symbols.visibility_lock, size: 16),
Text(
PostVisibilityHelpers.getVisibilityText(item.visibility).tr(),
).fontSize(13),
],
),
);
}
if (item.awardedScore != 0) {
metadataChildren.add(
Row(
spacing: 8,
children: [
const Icon(Symbols.emoji_events, size: 16),
Text(
'awardPoints'.tr(args: [item.awardedScore.toString()]),
).fontSize(13),
],
),
);
}
if (item.featuredRecords.isNotEmpty) {
metadataChildren.add(
Row(
spacing: 8,
children: [
const Icon(Symbols.highlight, size: 16),
Text(
'postFeaturedOn'.tr(
args: [
item.featuredRecords
.map((e) => e.featuredAt ?? e.createdAt)
.map((e) => e.formatCustom("yyyy/MM/dd"))
.join(','),
],
),
).fontSize(13),
],
),
);
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@@ -811,63 +924,12 @@ class PostBody extends ConsumerWidget {
vertical: 4,
),
),
if (item.tags.isNotEmpty || item.categories.isNotEmpty)
if (metadataChildren.isNotEmpty)
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
spacing: 2,
children: [
if (item.tags.isNotEmpty)
Wrap(
runAlignment: WrapAlignment.center,
spacing: 8,
children: [
const Icon(Symbols.label, size: 16).padding(top: 2),
for (final tag
in isFullPost ? item.tags : item.tags.take(3))
InkWell(
onTap:
isInteractive
? () {
GoRouter.of(context).pushNamed(
'postTagDetail',
pathParameters: {'slug': tag.slug},
);
}
: null,
child: Text('#${tag.name ?? tag.slug}'),
),
if (!isFullPost && item.tags.length > 3)
Text('+${item.tags.length - 3}').opacity(0.6),
],
),
if (item.categories.isNotEmpty)
Wrap(
runAlignment: WrapAlignment.center,
spacing: 8,
children: [
const Icon(Symbols.category, size: 16).padding(top: 2),
for (final category
in isFullPost
? item.categories
: item.categories.take(2))
InkWell(
onTap:
isInteractive
? () {
GoRouter.of(context).pushNamed(
'postCategoryDetail',
pathParameters: {'slug': category.slug},
);
}
: null,
child: Text(category.categoryDisplayTitle),
),
if (!isFullPost && item.categories.length > 2)
Text('+${item.categories.length - 2}').opacity(0.6),
],
),
],
children: metadataChildren,
).padding(horizontal: renderingPadding.horizontal + 4, top: 4),
if (item.meta?['embeds'] != null)
EmbedListWidget(

View File

@@ -43,7 +43,7 @@ class AbuseReportSheet extends HookConsumerWidget {
try {
final client = ref.read(apiClientProvider);
await client.post(
'/id/safety/reports',
'/pass/safety/reports',
data: {
'resource_identifier': resourceIdentifier,
'type': selectedType.value,

View File

@@ -2,16 +2,16 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:material_symbols_icons/symbols.dart';
class MenuItemData {
class UploadMenuItemData {
final IconData icon;
final String textKey;
final VoidCallback onPressed;
const MenuItemData(this.icon, this.textKey, this.onPressed);
const UploadMenuItemData(this.icon, this.textKey, this.onPressed);
}
class UploadMenu extends StatelessWidget {
final List<MenuItemData> items;
final List<UploadMenuItemData> items;
final bool isCompact;
final Color? iconColor;
@@ -51,6 +51,7 @@ class UploadMenu extends StatelessWidget {
onPressed: item.onPressed,
leadingIcon: Icon(item.icon),
style: ButtonStyle(
visualDensity: VisualDensity.compact,
padding: WidgetStatePropertyAll(
EdgeInsets.only(left: 12, right: 16, top: 20, bottom: 20),
),

View File

@@ -0,0 +1,87 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/thought.dart';
import 'package:island/pods/network.dart';
import 'package:island/services/time.dart';
import 'package:island/widgets/content/sheet.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';
part 'thought_sequence_list.g.dart';
@riverpod
class ThoughtSequenceListNotifier extends _$ThoughtSequenceListNotifier
with CursorPagingNotifierMixin<SnThinkingSequence> {
static const int _pageSize = 20;
@override
Future<CursorPagingData<SnThinkingSequence>> build() {
return fetch(cursor: null);
}
@override
Future<CursorPagingData<SnThinkingSequence>> fetch({
required String? cursor,
}) async {
final client = ref.read(apiClientProvider);
final offset = cursor == null ? 0 : int.parse(cursor);
final queryParams = {'offset': offset, 'take': _pageSize};
final response = await client.get(
'/insight/thought/sequences',
queryParameters: queryParams,
);
final total = int.parse(response.headers.value('X-Total') ?? '0');
final List<dynamic> data = response.data;
final sequences =
data.map((json) => SnThinkingSequence.fromJson(json)).toList();
final hasMore = offset + sequences.length < total;
final nextCursor = hasMore ? (offset + sequences.length).toString() : null;
return CursorPagingData(
items: sequences,
hasMore: hasMore,
nextCursor: nextCursor,
);
}
}
class ThoughtSequenceSelector extends HookConsumerWidget {
final Function(String) onSequenceSelected;
const ThoughtSequenceSelector({super.key, required this.onSequenceSelected});
@override
Widget build(BuildContext context, WidgetRef ref) {
final provider = thoughtSequenceListNotifierProvider;
return SheetScaffold(
titleText: 'Select Conversation',
child: PagingHelperView(
provider: provider,
futureRefreshable: provider.future,
notifierRefreshable: provider.notifier,
contentBuilder:
(data, widgetCount, endItemView) => ListView.builder(
itemCount: widgetCount,
itemBuilder: (context, index) {
if (index == widgetCount - 1) {
return endItemView;
}
final sequence = data.items[index];
return ListTile(
title: Text(sequence.topic ?? 'Untitled Conversation'),
subtitle: Text(sequence.createdAt.formatSystem()),
onTap: () {
onSequenceSelected(sequence.id);
Navigator.of(context).pop();
},
);
},
),
),
);
}
}

View File

@@ -0,0 +1,31 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'thought_sequence_list.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
String _$thoughtSequenceListNotifierHash() =>
r'fc619402d8691d523d19d3c7633adfada4956db4';
/// See also [ThoughtSequenceListNotifier].
@ProviderFor(ThoughtSequenceListNotifier)
final thoughtSequenceListNotifierProvider = AutoDisposeAsyncNotifierProvider<
ThoughtSequenceListNotifier,
CursorPagingData<SnThinkingSequence>
>.internal(
ThoughtSequenceListNotifier.new,
name: r'thoughtSequenceListNotifierProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product')
? null
: _$thoughtSequenceListNotifierHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$ThoughtSequenceListNotifier =
AutoDisposeAsyncNotifier<CursorPagingData<SnThinkingSequence>>;
// 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

View File

@@ -13,85 +13,85 @@ PODS:
- FlutterMacOS
- file_selector_macos (0.0.1):
- FlutterMacOS
- Firebase/CoreOnly (12.2.0):
- FirebaseCore (~> 12.2.0)
- Firebase/Crashlytics (12.2.0):
- Firebase/CoreOnly (12.4.0):
- FirebaseCore (~> 12.4.0)
- Firebase/Crashlytics (12.4.0):
- Firebase/CoreOnly
- FirebaseCrashlytics (~> 12.2.0)
- Firebase/Messaging (12.2.0):
- FirebaseCrashlytics (~> 12.4.0)
- Firebase/Messaging (12.4.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 12.2.0)
- firebase_analytics (12.0.2):
- FirebaseMessaging (~> 12.4.0)
- firebase_analytics (12.0.3):
- firebase_core
- FirebaseAnalytics (= 12.2.0)
- FirebaseAnalytics (= 12.4.0)
- FlutterMacOS
- firebase_core (4.1.1):
- Firebase/CoreOnly (~> 12.2.0)
- firebase_core (4.2.0):
- Firebase/CoreOnly (~> 12.4.0)
- FlutterMacOS
- firebase_crashlytics (5.0.2):
- Firebase/CoreOnly (~> 12.2.0)
- Firebase/Crashlytics (~> 12.2.0)
- firebase_crashlytics (5.0.3):
- Firebase/CoreOnly (~> 12.4.0)
- Firebase/Crashlytics (~> 12.4.0)
- firebase_core
- FlutterMacOS
- firebase_messaging (16.0.2):
- Firebase/CoreOnly (~> 12.2.0)
- Firebase/Messaging (~> 12.2.0)
- firebase_messaging (16.0.3):
- Firebase/CoreOnly (~> 12.4.0)
- Firebase/Messaging (~> 12.4.0)
- firebase_core
- FlutterMacOS
- FirebaseAnalytics (12.2.0):
- FirebaseAnalytics/Default (= 12.2.0)
- FirebaseCore (~> 12.2.0)
- FirebaseInstallations (~> 12.2.0)
- FirebaseAnalytics (12.4.0):
- FirebaseAnalytics/Default (= 12.4.0)
- FirebaseCore (~> 12.4.0)
- FirebaseInstallations (~> 12.4.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- FirebaseAnalytics/Default (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseInstallations (~> 12.2.0)
- GoogleAppMeasurement/Default (= 12.2.0)
- FirebaseAnalytics/Default (12.4.0):
- FirebaseCore (~> 12.4.0)
- FirebaseInstallations (~> 12.4.0)
- GoogleAppMeasurement/Default (= 12.4.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- FirebaseCore (12.2.0):
- FirebaseCoreInternal (~> 12.2.0)
- FirebaseCore (12.4.0):
- FirebaseCoreInternal (~> 12.4.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/Logger (~> 8.1)
- FirebaseCoreExtension (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseCoreInternal (12.2.0):
- FirebaseCoreExtension (12.4.0):
- FirebaseCore (~> 12.4.0)
- FirebaseCoreInternal (12.4.0):
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- FirebaseCrashlytics (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseInstallations (~> 12.2.0)
- FirebaseRemoteConfigInterop (~> 12.2.0)
- FirebaseSessions (~> 12.2.0)
- FirebaseCrashlytics (12.4.0):
- FirebaseCore (~> 12.4.0)
- FirebaseInstallations (~> 12.4.0)
- FirebaseRemoteConfigInterop (~> 12.4.0)
- FirebaseSessions (~> 12.4.0)
- GoogleDataTransport (~> 10.1)
- GoogleUtilities/Environment (~> 8.1)
- nanopb (~> 3.30910.0)
- PromisesObjC (~> 2.4)
- FirebaseInstallations (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseInstallations (12.4.0):
- FirebaseCore (~> 12.4.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
- PromisesObjC (~> 2.4)
- FirebaseMessaging (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseInstallations (~> 12.2.0)
- FirebaseMessaging (12.4.0):
- FirebaseCore (~> 12.4.0)
- FirebaseInstallations (~> 12.4.0)
- GoogleDataTransport (~> 10.1)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/Reachability (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
- nanopb (~> 3.30910.0)
- FirebaseRemoteConfigInterop (12.2.0)
- FirebaseSessions (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseCoreExtension (~> 12.2.0)
- FirebaseInstallations (~> 12.2.0)
- FirebaseRemoteConfigInterop (12.4.0)
- FirebaseSessions (12.4.0):
- FirebaseCore (~> 12.4.0)
- FirebaseCoreExtension (~> 12.4.0)
- FirebaseInstallations (~> 12.4.0)
- GoogleDataTransport (~> 10.1)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
@@ -118,23 +118,23 @@ PODS:
- gal (1.0.0):
- Flutter
- FlutterMacOS
- GoogleAppMeasurement/Core (12.2.0):
- GoogleAppMeasurement/Core (12.4.0):
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- GoogleAppMeasurement/Default (12.2.0):
- GoogleAdsOnDeviceConversion (= 2.3.0)
- GoogleAppMeasurement/Core (= 12.2.0)
- GoogleAppMeasurement/IdentitySupport (= 12.2.0)
- GoogleAppMeasurement/Default (12.4.0):
- GoogleAdsOnDeviceConversion (~> 3.1.0)
- GoogleAppMeasurement/Core (= 12.4.0)
- GoogleAppMeasurement/IdentitySupport (= 12.4.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- GoogleAppMeasurement/IdentitySupport (12.2.0):
- GoogleAppMeasurement/Core (= 12.2.0)
- GoogleAppMeasurement/IdentitySupport (12.4.0):
- GoogleAppMeasurement/Core (= 12.4.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
@@ -172,7 +172,7 @@ PODS:
- GoogleUtilities/Privacy
- irondash_engine_context (0.0.1):
- FlutterMacOS
- livekit_client (2.5.0):
- livekit_client (2.5.3):
- flutter_webrtc
- FlutterMacOS
- WebRTC-SDK (= 137.7151.04)
@@ -415,21 +415,21 @@ SPEC CHECKSUMS:
device_info_plus: 4fb280989f669696856f8b129e4a5e3cd6c48f76
file_picker: 7584aae6fa07a041af2b36a2655122d42f578c1a
file_saver: e35bd97de451dde55ff8c38862ed7ad0f3418d0f
file_selector_macos: 6280b52b459ae6c590af5d78fc35c7267a3c4b31
Firebase: 26f6f8d460603af3df970ad505b16b15f5e2e9a1
firebase_analytics: 26346c2ccb9ba410c2f33d5d34c62e6369cbbf29
firebase_core: 54fd706197e1779d510b297548eee74d3b39577c
firebase_crashlytics: 3694b4aca0849f6919244d7bbbb40615f989f46b
firebase_messaging: 658f1a6906d80faec2fb20e3aadb81af6b09e441
FirebaseAnalytics: e04e23bc070e3014aa5cf4980f9df7ce5cd79ec8
FirebaseCore: 311c48a147ad4a0ab7febbaed89e8025c67510cd
FirebaseCoreExtension: 73af080c22a2f7b44cefa391dc08f7e4ee162cb5
FirebaseCoreInternal: 56ea29f3dad2894f81b060f706f9d53509b6ed3b
FirebaseCrashlytics: f83cbf176d5c637ade108c0aacf1ccbd5ec499bf
FirebaseInstallations: 3e884b01feabdf67582a80f3250425a00979b4ed
FirebaseMessaging: 43ec73bbfedd0c385a849bb91593ab4ad4b9e48e
FirebaseRemoteConfigInterop: 0896fd52ab72586a355c8f389ff85aaa9e5375e1
FirebaseSessions: f4692789e770bec66ce17d772c0e9561c4f11737
file_selector_macos: 9e9e068e90ebee155097d00e89ae91edb2374db7
Firebase: f07b15ae5a6ec0f93713e30b923d9970d144af3e
firebase_analytics: d876586269c1d8d2b3dcac085bc2d97c62abc9df
firebase_core: d81d1a44df95699ce074ae63d8cb43e9df21e142
firebase_crashlytics: 723622cc39a9fa7320585424f5864c5699893ce1
firebase_messaging: 31f412ae5a54e02d1c46d467969f7ad92c4b81ec
FirebaseAnalytics: 0fc2b20091f0ddd21bf73397cf8f0eb5346dc24f
FirebaseCore: bb595f3114953664e3c1dc032f008a244147cfd3
FirebaseCoreExtension: 7e1f7118ee970e001a8013719fb90950ee5e0018
FirebaseCoreInternal: d7f5a043c2cd01a08103ab586587c1468047bca6
FirebaseCrashlytics: a6ece278a837c7e88de2d9b5da0a3542f2342395
FirebaseInstallations: ae9f4902cb5bf1d0c5eaa31ec1f4e5495a0714e2
FirebaseMessaging: d33971b7bb252745ea6cd31ab190d1a1df4b8ed5
FirebaseRemoteConfigInterop: 1e31ec72b89c9924367c59bfb5ec9ab60d1d6766
FirebaseSessions: ba7c7a7ca8696a8d540eb3fe3800fbe98c79786d
flutter_inappwebview_macos: c2d68649f9f8f1831bfcd98d73fd6256366d9d1d
flutter_local_notifications: 4bf37a31afde695b56091b4ae3e4d9c7a7e6cda0
flutter_platform_alert: 8fa7a7c21f95b26d08b4a3891936ca27e375f284
@@ -439,11 +439,11 @@ SPEC CHECKSUMS:
flutter_webrtc: 718eae22a371cd94e5d56aa4f301443ebc5bb737
FlutterMacOS: d0db08ddef1a9af05a5ec4b724367152bb0500b1
gal: baecd024ebfd13c441269ca7404792a7152fde89
GoogleAppMeasurement: 09f341dfa8527d1612a09cbfe809a242c0b737af
GoogleAppMeasurement: 1e718274b7e015cefd846ac1fcf7820c70dc017d
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
irondash_engine_context: 893c7d96d20ce361d7e996f39d360c4c2f9869ba
livekit_client: 95b4a47f51f98a8be3a181c3fa251be7823dddd4
livekit_client: a6d5ae8aaeebf3e52235da866fea00f43156c72b
local_auth_darwin: c3ee6cce0a8d56be34c8ccb66ba31f7f180aaebb
media_kit_libs_macos_video: 85a23e549b5f480e72cae3e5634b5514bc692f65
media_kit_video: fa6564e3799a0a28bff39442334817088b7ca758
@@ -451,14 +451,14 @@ SPEC CHECKSUMS:
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
package_info_plus: f0052d280d17aa382b932f399edf32507174e870
pasteboard: 278d8100149f940fb795d6b3a74f0720c890ecb7
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
path_provider_foundation: bb55f6dbba17d0dccd6737fe6f7f34fbd0376880
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851
record_macos: 43194b6c06ca6f8fa132e2acea72b202b92a0f5b
SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c
screen_retriever_macos: 452e51764a9e1cdb74b3c541238795849f21557f
share_plus: 510bf0af1a42cd602274b4629920c9649c52f4cc
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb
sign_in_with_apple: 6673c03c9e3643f6c8d33601943fbfa9ae99f94e
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
sqlite3: 73513155ec6979715d3904ef53a8d68892d4032b
@@ -466,7 +466,7 @@ SPEC CHECKSUMS:
super_native_extensions: c2795d6d9aedf4a79fae25cb6160b71b50549189
syncfusion_pdfviewer_macos: b3b110c68039178ca4105dd03ef38761eca3b36b
tray_manager: a104b5c81b578d83f3c3d0f40a997c8b10810166
url_launcher_macos: 0fba8ddabfc33ce0a9afe7c5fef5aab3d8d2d673
url_launcher_macos: f87a979182d112f911de6820aefddaf56ee9fbfd
volume_controller: 5c068e6d085c80dadd33fc2c918d2114b775b3dd
wakelock_plus: 917609be14d812ddd9e9528876538b2263aaa03b
WebRTC-SDK: 40d4f5ba05cadff14e4db5614aec402a633f007e

View File

@@ -13,10 +13,10 @@ packages:
dependency: transitive
description:
name: _flutterfire_internals
sha256: "23d16f00a2da8ffa997c782453c73867b0609bd90435195671a54de38a3566df"
sha256: f871a7d1b686bea1f13722aa51ab31554d05c81f47054d6de48cc8c45153508b
url: "https://pub.dev"
source: hosted
version: "1.3.62"
version: "1.3.63"
analyzer:
dependency: transitive
description:
@@ -141,10 +141,10 @@ packages:
dependency: transitive
description:
name: build_daemon
sha256: "8e928697a82be082206edb0b9c99c5a4ad6bc31c9e9b8b2f291ae65cd4a25daa"
sha256: "409002f1adeea601018715d613115cfaf0e31f512cb80ae4534c79867ae2363d"
url: "https://pub.dev"
source: hosted
version: "4.0.4"
version: "4.1.0"
build_resolvers:
dependency: transitive
description:
@@ -325,10 +325,10 @@ packages:
dependency: "direct main"
description:
name: croppy
sha256: ca70a77cd5a981172d69382a7b43629d15d6c868475b2bbb45efce32cfc58b86
sha256: ceea4ea0bc36354ea2b3d2cc515a29d6bccf75196c8080148f4174902d185a53
url: "https://pub.dev"
source: hosted
version: "1.4.0"
version: "1.4.1"
cross_file:
dependency: "direct main"
description:
@@ -545,6 +545,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.7"
event_bus:
dependency: "direct main"
description:
name: event_bus
sha256: "1a55e97923769c286d295240048fc180e7b0768902c3c2e869fe059aafa15304"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
expandable:
dependency: transitive
description:
@@ -605,10 +613,10 @@ packages:
dependency: transitive
description:
name: file_selector_macos
sha256: "19124ff4a3d8864fdc62072b6a2ef6c222d55a3404fe14893a3c02744907b60c"
sha256: "88707a3bec4b988aaed3b4df5d7441ee4e987f20b286cddca5d6a8270cab23f2"
url: "https://pub.dev"
source: hosted
version: "0.9.4+4"
version: "0.9.4+5"
file_selector_platform_interface:
dependency: transitive
description:
@@ -629,90 +637,90 @@ packages:
dependency: "direct main"
description:
name: firebase_analytics
sha256: fce78440ab7b95563054039aac5e342088efed9dc009ac6f81d5cac07155d509
sha256: "3cfc4089e61e810ffb531af63cfde2c8cfd36f12dc14fdba359e623992311015"
url: "https://pub.dev"
source: hosted
version: "12.0.2"
version: "12.0.3"
firebase_analytics_platform_interface:
dependency: transitive
description:
name: firebase_analytics_platform_interface
sha256: "75bdcd2d2635c4cdcd7ec13727527751ddf2f9933e5bf1264a2387920246f3c5"
sha256: "775fc18d9b00a014362510a33f76f1f34deb30f69a64edcb41a7dfd0ebd9cf98"
url: "https://pub.dev"
source: hosted
version: "5.0.2"
version: "5.0.3"
firebase_analytics_web:
dependency: transitive
description:
name: firebase_analytics_web
sha256: ed5767695b131cdd425ee6d49934dca80689d9df40609c0d0aa8907ee6f0f785
sha256: "6eafa8fef5fdca6c922ac3e353c9a093c12344a3ba996e65fd40f8db0a00d26f"
url: "https://pub.dev"
source: hosted
version: "0.6.0+2"
version: "0.6.0+3"
firebase_core:
dependency: "direct main"
description:
name: firebase_core
sha256: "4dd96f05015c0dcceaa47711394c32971aee70169625d5e2477e7676c01ce0ee"
sha256: "132e1c311bc41e7d387b575df0aacdf24efbf4930365eb61042be5bde3978f03"
url: "https://pub.dev"
source: hosted
version: "4.1.1"
version: "4.2.0"
firebase_core_platform_interface:
dependency: transitive
description:
name: firebase_core_platform_interface
sha256: "5873a370f0d232918e23a5a6137dbe4c2c47cf017301f4ea02d9d636e52f60f0"
sha256: cccb4f572325dc14904c02fcc7db6323ad62ba02536833dddb5c02cac7341c64
url: "https://pub.dev"
source: hosted
version: "6.0.1"
version: "6.0.2"
firebase_core_web:
dependency: transitive
description:
name: firebase_core_web
sha256: "61a51037312dac781f713308903bb7a1762a7f92f7bc286a3a0947fb2a713b82"
sha256: ecde2def458292404a4fcd3731ee4992fd631a0ec359d2d67c33baa8da5ec8ae
url: "https://pub.dev"
source: hosted
version: "3.1.1"
version: "3.2.0"
firebase_crashlytics:
dependency: "direct main"
description:
name: firebase_crashlytics
sha256: a636096df0d2a4bc72397bfc669a4fffc8896016a58de1a6f45a49d9ba064f94
sha256: "2f53d0d3c0875105b166f09bdf026026bb74f26930c6ffcd5d65b311ca5a9f58"
url: "https://pub.dev"
source: hosted
version: "5.0.2"
version: "5.0.3"
firebase_crashlytics_platform_interface:
dependency: transitive
description:
name: firebase_crashlytics_platform_interface
sha256: "1ccad077a6fc7bace97d8eace263f42e66dc23a23a839de864a4f10ac4a7c264"
sha256: de5c857525fc9576cd3fc30fc72422bc2371179ecae110246c0135ae896c6de3
url: "https://pub.dev"
source: hosted
version: "3.8.13"
version: "3.8.14"
firebase_messaging:
dependency: "direct main"
description:
name: firebase_messaging
sha256: ba12ad0b600e0c939fbb9391e1cd3320a5b5dad5284276b9182fc21eb1e72c2b
sha256: "5021279acd1cb5ccaceaa388e616e82cc4a2e4d862f02637df0e8ab766e6900a"
url: "https://pub.dev"
source: hosted
version: "16.0.2"
version: "16.0.3"
firebase_messaging_platform_interface:
dependency: transitive
description:
name: firebase_messaging_platform_interface
sha256: b4bade67bfc09fcc56eb012b3fc72b59ca9e2259a34cdfb81b368169770ff536
sha256: f3a16c51f02055ace2a7c16ccb341c1f1b36b67c13270a48bcef68c1d970bbe8
url: "https://pub.dev"
source: hosted
version: "4.7.2"
version: "4.7.3"
firebase_messaging_web:
dependency: transitive
description:
name: firebase_messaging_web
sha256: "8ae4a00d178993feb79603cad324b53696375cbb78805e8eb603fe331866629d"
sha256: "3eb9a1382caeb95b370f21e36d4a460496af777c9c2ef5df9b90d4803982c069"
url: "https://pub.dev"
source: hosted
version: "4.0.2"
version: "4.0.3"
fixnum:
dependency: transitive
description:
@@ -770,10 +778,10 @@ packages:
dependency: "direct main"
description:
name: flutter_card_swiper
sha256: "1eacbfab31b572223042e03409726553aec431abe48af48c8d591d376d070d3d"
sha256: "9fbe75c913c0a01f34f9f98068ad198e396695fcf8abfa433cc53652fceb5617"
url: "https://pub.dev"
source: hosted
version: "7.0.2"
version: "7.1.0"
flutter_colorpicker:
dependency: "direct main"
description:
@@ -782,6 +790,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.1.0"
flutter_expandable_fab:
dependency: "direct main"
description:
name: flutter_expandable_fab
sha256: "2a488600924fd2a041679ad889807ee5670414a7a518cf11d4854b9898b3504f"
url: "https://pub.dev"
source: hosted
version: "2.5.2"
flutter_highlight:
dependency: "direct main"
description:
@@ -930,10 +946,10 @@ packages:
dependency: "direct main"
description:
name: flutter_local_notifications
sha256: "7ed76be64e8a7d01dfdf250b8434618e2a028c9dfa2a3c41dc9b531d4b3fc8a5"
sha256: "19ffb0a8bb7407875555e5e98d7343a633bb73707bae6c6a5f37c90014077875"
url: "https://pub.dev"
source: hosted
version: "19.4.2"
version: "19.5.0"
flutter_local_notifications_linux:
dependency: transitive
description:
@@ -991,10 +1007,10 @@ packages:
dependency: "direct main"
description:
name: flutter_native_splash
sha256: "8321a6d11a8d13977fa780c89de8d257cce3d841eecfb7a4cadffcc4f12d82dc"
sha256: "4fb9f4113350d3a80841ce05ebf1976a36de622af7d19aca0ca9a9911c7ff002"
url: "https://pub.dev"
source: hosted
version: "2.4.6"
version: "2.4.7"
flutter_otp_text_field:
dependency: "direct main"
description:
@@ -1015,10 +1031,10 @@ packages:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: c2fe1001710127dfa7da89977a08d591398370d099aacdaa6d44da7eb14b8476
sha256: "306f0596590e077338312f38837f595c04f28d6cdeeac392d3d74df2f0003687"
url: "https://pub.dev"
source: hosted
version: "2.0.31"
version: "2.0.32"
flutter_popup_card:
dependency: "direct main"
description:
@@ -1137,10 +1153,10 @@ packages:
dependency: transitive
description:
name: font_awesome_flutter
sha256: "27af5982e6c510dec1ba038eff634fa284676ee84e3fd807225c80c4ad869177"
sha256: b9011df3a1fa02993630b8fb83526368cf2206a711259830325bab2f1d2a4eb0
url: "https://pub.dev"
source: hosted
version: "10.10.0"
version: "10.12.0"
freezed:
dependency: "direct dev"
description:
@@ -1201,10 +1217,10 @@ packages:
dependency: "direct main"
description:
name: go_router
sha256: c752e2d08d088bf83742cb05bf83003f3e9d276ff1519b5c92f9d5e60e5ddd23
sha256: d8f590a69729f719177ea68eb1e598295e8dbc41bbc247fed78b2c8a25660d7c
url: "https://pub.dev"
source: hosted
version: "16.2.4"
version: "16.3.0"
google_fonts:
dependency: "direct main"
description:
@@ -1321,10 +1337,10 @@ packages:
dependency: "direct main"
description:
name: image_picker_android
sha256: dd7a61daaa5896cc34b7bc95f66c60225ae6bee0d167dde0e21a9d9016cac0dc
sha256: "58a85e6f09fe9c4484d53d18a0bd6271b72c53fce1d05e6f745ae36d8c18efca"
url: "https://pub.dev"
source: hosted
version: "0.8.13+4"
version: "0.8.13+5"
image_picker_for_web:
dependency: transitive
description:
@@ -1337,10 +1353,10 @@ packages:
dependency: transitive
description:
name: image_picker_ios
sha256: eb06fe30bab4c4497bad449b66448f50edcc695f1c59408e78aa3a8059eb8f0e
sha256: e675c22790bcc24e9abd455deead2b7a88de4b79f7327a281812f14de1a56f58
url: "https://pub.dev"
source: hosted
version: "0.8.13"
version: "0.8.13+1"
image_picker_linux:
dependency: transitive
description:
@@ -1353,18 +1369,18 @@ packages:
dependency: transitive
description:
name: image_picker_macos
sha256: d58cd9d67793d52beefd6585b12050af0a7663c0c2a6ece0fb110a35d6955e04
sha256: "86f0f15a309de7e1a552c12df9ce5b59fe927e71385329355aec4776c6a8ec91"
url: "https://pub.dev"
source: hosted
version: "0.2.2"
version: "0.2.2+1"
image_picker_platform_interface:
dependency: "direct main"
description:
name: image_picker_platform_interface
sha256: "9f143b0dba3e459553209e20cc425c9801af48e6dfa4f01a0fcf927be3f41665"
sha256: "567e056716333a1647c64bb6bd873cff7622233a5c3f694be28a583d4715690c"
url: "https://pub.dev"
source: hosted
version: "2.11.0"
version: "2.11.1"
image_picker_windows:
dependency: transitive
description:
@@ -1473,34 +1489,34 @@ packages:
dependency: "direct main"
description:
name: livekit_client
sha256: "4c1663c1e6ac20a743d9a46c7bc71f17e1949db99d245750c68661d554e30cd2"
sha256: ddb4467d306be472898b2459c87768121aba030173b3664ef367f7f7f4c96897
url: "https://pub.dev"
source: hosted
version: "2.5.1"
version: "2.5.3"
local_auth:
dependency: "direct main"
description:
name: local_auth
sha256: "434d854cf478f17f12ab29a76a02b3067f86a63a6d6c4eb8fbfdcfe4879c1b7b"
sha256: a4f1bf57f0236a4aeb5e8f0ec180e197f4b112a3456baa6c1e73b546630b0422
url: "https://pub.dev"
source: hosted
version: "2.3.0"
version: "3.0.0"
local_auth_android:
dependency: transitive
description:
name: local_auth_android
sha256: b2446c74fab1db37f828d4c54adaa3f003df80a29f5cbd710bbb8883d302e991
sha256: d836715ed95b16b2de3a8c47a88ba5e607976bb1e27c9446d193152ea1429fae
url: "https://pub.dev"
source: hosted
version: "1.0.55"
version: "2.0.0"
local_auth_darwin:
dependency: transitive
description:
name: local_auth_darwin
sha256: "699873970067a40ef2f2c09b4c72eb1cfef64224ef041b3df9fdc5c4c1f91f49"
sha256: "15d9db4ad4d58a11d7269e55d46ff8d49ed5e856226c8a5a91280f0d7c37b3a6"
url: "https://pub.dev"
source: hosted
version: "1.6.1"
version: "2.0.0"
local_auth_platform_interface:
dependency: transitive
description:
@@ -1513,10 +1529,10 @@ packages:
dependency: transitive
description:
name: local_auth_windows
sha256: bc4e66a29b0fdf751aafbec923b5bed7ad6ed3614875d8151afe2578520b2ab5
sha256: d95535a73eddf57ce5930d5e78a0fa4f294c31981fdeeee83325b797302be454
url: "https://pub.dev"
source: hosted
version: "1.0.11"
version: "2.0.0"
logger:
dependency: transitive
description:
@@ -1785,18 +1801,18 @@ packages:
dependency: transitive
description:
name: path_provider_android
sha256: "3b4c1fc3aa55ddc9cd4aa6759984330d5c8e66aa7702a6223c61540dc6380c37"
sha256: e122c5ea805bb6773bb12ce667611265980940145be920cd09a4b0ec0285cb16
url: "https://pub.dev"
source: hosted
version: "2.2.19"
version: "2.2.20"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: "16eef174aacb07e09c351502740fa6254c165757638eba1e9116b0a781201bbd"
sha256: efaec349ddfc181528345c56f8eda9d6cccd71c177511b132c6a0ddaefaa2738
url: "https://pub.dev"
source: hosted
version: "2.4.2"
version: "2.4.3"
path_provider_linux:
dependency: transitive
description:
@@ -1881,10 +1897,10 @@ packages:
dependency: transitive
description:
name: pointer_interceptor_ios
sha256: a6906772b3205b42c44614fcea28f818b1e5fdad73a4ca742a7bd49818d9c917
sha256: "03c5fa5896080963ab4917eeffda8d28c90f22863a496fb5ba13bc10943e40e4"
url: "https://pub.dev"
source: hosted
version: "0.10.1"
version: "0.10.1+1"
pointer_interceptor_platform_interface:
dependency: transitive
description:
@@ -1992,10 +2008,11 @@ packages:
receive_sharing_intent:
dependency: "direct main"
description:
name: receive_sharing_intent
sha256: ec76056e4d258ad708e76d85591d933678625318e411564dcb9059048ca3a593
url: "https://pub.dev"
source: hosted
path: "."
ref: master
resolved-ref: "2cea396843cd3ab1b5ec4334be4233864637874e"
url: "https://github.com/KasemJaffer/receive_sharing_intent"
source: git
version: "1.8.1"
record:
dependency: "direct main"
@@ -2009,10 +2026,10 @@ packages:
dependency: transitive
description:
name: record_android
sha256: f05677eeed074898327f890f232f9eb49cd99d1c20d0daaf22b5612f4b2301bb
sha256: fb54ee4e28f6829b8c580252a9ef49d9c549cfd263b0660ad7eeac0908658e9f
url: "https://pub.dev"
source: hosted
version: "1.4.3"
version: "1.4.4"
record_ios:
dependency: transitive
description:
@@ -2049,10 +2066,10 @@ packages:
dependency: transitive
description:
name: record_web
sha256: "4f0adf20c9ccafcc02d71111fd91fba1ca7b17a7453902593e5a9b25b74a5c56"
sha256: "20ac10d56514cb9f8cecc8f3579383084fdfb43b0d04e05a95244d0d76091d90"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
version: "1.2.1"
record_windows:
dependency: transitive
description:
@@ -2217,10 +2234,10 @@ packages:
dependency: "direct main"
description:
name: share_plus
sha256: "3424e9d5c22fd7f7590254ba09465febd6f8827c8b19a44350de4ac31d92d3a6"
sha256: "14c8860d4de93d3a7e53af51bff479598c4e999605290756bbbe45cf65b37840"
url: "https://pub.dev"
source: hosted
version: "12.0.0"
version: "12.0.1"
share_plus_platform_interface:
dependency: transitive
description:
@@ -2249,10 +2266,10 @@ packages:
dependency: transitive
description:
name: shared_preferences_foundation
sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03"
sha256: "1c33a907142607c40a7542768ec9badfd16293bac51da3a4482623d15845f88b"
url: "https://pub.dev"
source: hosted
version: "2.5.4"
version: "2.5.5"
shared_preferences_linux:
dependency: transitive
description:
@@ -2430,10 +2447,10 @@ packages:
dependency: transitive
description:
name: sqlite3
sha256: "809bc27297bd0633ef360a7e27e056e93a2ef598079616db97b0c93e275f6d31"
sha256: f18fd9a72d7a1ad2920db61368f2a69368f1cc9b56b8233e9d83b47b0a8435aa
url: "https://pub.dev"
source: hosted
version: "2.9.2"
version: "2.9.3"
sqlite3_flutter_libs:
dependency: transitive
description:
@@ -2534,18 +2551,18 @@ packages:
dependency: transitive
description:
name: syncfusion_flutter_core
sha256: "3135dc6b427686cdda1546bdeab3a4a45372f5bb3d95369e007776b605f863ac"
sha256: d03c43f577cdbe020d1632bece00cbf8bec4a7d0ab123923b69141b5fec35420
url: "https://pub.dev"
source: hosted
version: "31.1.23"
version: "31.2.3"
syncfusion_flutter_pdf:
dependency: transitive
description:
name: syncfusion_flutter_pdf
sha256: "222874bf28765671a5a57dac56b6c9d6fc6cfed4ce49ef0cfb38e3558bf31070"
sha256: cb16c8631ab390fdd547c0661f3c8ab7a417ce0f4d7f47a6b8a0811b9bd23b2d
url: "https://pub.dev"
source: hosted
version: "31.1.23"
version: "31.2.3"
syncfusion_flutter_pdfviewer:
dependency: "direct main"
description:
@@ -2558,50 +2575,50 @@ packages:
dependency: transitive
description:
name: syncfusion_flutter_signaturepad
sha256: "0491efc4b0bba057fbb83cb3864b7718132608950d8b7ebb1f0ff61c066111ae"
sha256: "73c73ad0779f772084493bed59124b069e30ae295f4d35ae81dc5a7513198d97"
url: "https://pub.dev"
source: hosted
version: "31.1.23"
version: "31.2.3"
syncfusion_pdfviewer_linux:
dependency: transitive
description:
name: syncfusion_pdfviewer_linux
sha256: "9b448ce3d11ebd879418a2eefdb78d83daa9240729b5d9eed986ef30b97f666c"
sha256: a69242b0ced822e190a5cba8791cb203999da372f6c67f038d14dda799ecfb80
url: "https://pub.dev"
source: hosted
version: "31.1.23"
version: "31.2.3"
syncfusion_pdfviewer_macos:
dependency: transitive
description:
name: syncfusion_pdfviewer_macos
sha256: c4fad8e6e8d31d98fc4e5766b6f282da42b06d527b0a734751080191a03e7c73
sha256: "0253828d6c07e4a5ade5afe528045bd047fbccf907823ae57811b6bbf09a5b2f"
url: "https://pub.dev"
source: hosted
version: "31.1.23"
version: "31.2.3"
syncfusion_pdfviewer_platform_interface:
dependency: transitive
description:
name: syncfusion_pdfviewer_platform_interface
sha256: "52278505016e61b871d740014379854adc07e5e29c97f9362f8d130ec5747bb3"
sha256: "00aef95383dd457e868ec00a0babc25a669f3ee3c30a49b230f561257349b965"
url: "https://pub.dev"
source: hosted
version: "31.1.23"
version: "31.2.3"
syncfusion_pdfviewer_web:
dependency: transitive
description:
name: syncfusion_pdfviewer_web
sha256: c3ea7aac63ea3a1b73ada80fc60de07855e22d6817d44e8f1424ac6428228640
sha256: "87fbbec373cd80f231bb5c48dcb69808ba55acb9fb81a7423b959ec8a7cddf77"
url: "https://pub.dev"
source: hosted
version: "31.1.23"
version: "31.2.3"
syncfusion_pdfviewer_windows:
dependency: transitive
description:
name: syncfusion_pdfviewer_windows
sha256: b7c5988cd797e1e2432377131910d09e4bc4f54bb2b5a56953da2d553fdfd853
sha256: "3b9ec92595e75c65be0a9514f61c566c8fc1b1601ab97927b958276de395ca9f"
url: "https://pub.dev"
source: hosted
version: "31.1.23"
version: "31.2.3"
synchronized:
dependency: transitive
description:
@@ -2674,15 +2691,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.7.6"
textfield_tags:
dependency: "direct main"
description:
path: "."
ref: "fixes/allow-controller-re-registration"
resolved-ref: "7574e79649e34df1c3cc0c49b2f0cc2b92de6a7b"
url: "https://github.com/lionelmennig/textfield_tags.git"
source: git
version: "3.0.1"
timezone:
dependency: "direct main"
description:
@@ -2784,10 +2792,10 @@ packages:
dependency: transitive
description:
name: url_launcher_ios
sha256: d80b3f567a617cb923546034cc94bfe44eb15f989fe670b37f26abdb9d939cb7
sha256: "6b63f1441e4f653ae799166a72b50b1767321ecc263a57aadf825a7a2a5477d9"
url: "https://pub.dev"
source: hosted
version: "6.3.4"
version: "6.3.5"
url_launcher_linux:
dependency: transitive
description:
@@ -2800,10 +2808,10 @@ packages:
dependency: transitive
description:
name: url_launcher_macos
sha256: c043a77d6600ac9c38300567f33ef12b0ef4f4783a2c1f00231d2b1941fea13f
sha256: "8262208506252a3ed4ff5c0dc1e973d2c0e0ef337d0a074d35634da5d44397c9"
url: "https://pub.dev"
source: hosted
version: "3.2.3"
version: "3.2.4"
url_launcher_platform_interface:
dependency: transitive
description:

View File

@@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 3.3.0+135
version: 3.3.0+136
environment:
sdk: ^3.7.2
@@ -38,7 +38,7 @@ dependencies:
cupertino_icons: ^1.0.8
flutter_hooks: ^0.21.3+1
hooks_riverpod: ^2.6.1
go_router: ^16.2.4
go_router: ^16.3.0
styled_widget: ^0.4.1
shared_preferences: ^2.5.3
flutter_riverpod: ^2.6.1
@@ -74,13 +74,13 @@ dependencies:
image_picker: ^1.2.0
file_picker: ^10.3.3
riverpod_annotation: ^2.6.1
image_picker_platform_interface: ^2.11.0
image_picker_android: ^0.8.13+4
image_picker_platform_interface: ^2.11.1
image_picker_android: ^0.8.13+5
super_context_menu: ^0.9.1
modal_bottom_sheet: ^3.0.0
firebase_messaging: ^16.0.2
firebase_messaging: ^16.0.3
flutter_udid: ^4.0.0
firebase_core: ^4.1.1
firebase_core: ^4.2.0
web_socket_channel: ^3.0.3
material_symbols_icons: ^4.2874.0
drift: ^2.28.2
@@ -88,7 +88,7 @@ dependencies:
path: ^1.9.1
collection: ^1.19.1
markdown_editor_plus: ^0.2.15
croppy: ^1.4.0
croppy: ^1.4.1
table_calendar: ^3.2.0
relative_time: ^5.0.0
dropdown_button2: ^2.3.9
@@ -97,12 +97,12 @@ dependencies:
avatar_stack: ^3.0.0
markdown_widget: ^2.3.2+8
visibility_detector: ^0.4.0+2
flutter_native_splash: ^2.4.6
flutter_native_splash: ^2.4.7
photo_view: ^0.15.0
gal: ^2.3.2
dismissible_page: ^1.0.2
super_sliver_list: ^0.4.1
livekit_client: ^2.5.1
livekit_client: ^2.5.3
pasteboard: ^0.4.0
flutter_colorpicker: ^1.1.0
image: ^4.5.4
@@ -117,16 +117,16 @@ dependencies:
sign_in_with_apple: ^7.0.1
flutter_svg: ^2.2.1
native_exif: ^0.6.2
local_auth: ^2.3.0
local_auth: ^3.0.0
flutter_secure_storage: ^9.2.4
flutter_math_fork: ^0.7.4
share_plus: ^12.0.0
receive_sharing_intent: ^1.8.1
top_snackbar_flutter: ^3.3.0
textfield_tags:
share_plus: ^12.0.1
# https://github.com/KasemJaffer/receive_sharing_intent/pull/333
receive_sharing_intent:
git:
url: https://github.com/lionelmennig/textfield_tags.git
ref: fixes/allow-controller-re-registration
url: https://github.com/KasemJaffer/receive_sharing_intent
ref: master
top_snackbar_flutter: ^3.3.0
mime: ^2.0.0
html2md: ^1.3.2
flutter_typeahead: ^5.2.0
@@ -134,15 +134,15 @@ dependencies:
flutter_app_update: ^3.2.2
archive: ^4.0.7
process_run: ^1.2.4
firebase_crashlytics: ^5.0.2
firebase_analytics: ^12.0.2
firebase_crashlytics: ^5.0.3
firebase_analytics: ^12.0.3
material_color_utilities: ^0.11.1
screenshot: ^3.0.0
flutter_card_swiper: ^7.0.2
flutter_card_swiper: ^7.1.0
file_saver: ^0.3.1
tray_manager: ^0.5.1
flutter_webrtc: ^1.2.0
flutter_local_notifications: ^19.4.2
flutter_local_notifications: ^19.5.0
wakelock_plus: ^1.4.0
slide_countdown: ^2.0.2
shelf: ^1.4.2
@@ -163,6 +163,8 @@ dependencies:
swipe_to: ^1.0.6
fl_heatmap: ^0.4.5
dio_smart_retry: ^7.0.1
flutter_expandable_fab: ^2.5.2
event_bus: ^2.0.1
dev_dependencies:
flutter_test: