Compare commits

..

256 Commits

Author SHA1 Message Date
LittleSheep
c9b71701c8 🚀 Launch 3.2.0+129 2025-08-26 01:33:57 +08:00
LittleSheep
28e98488f1 🌐 Localize new stuff 2025-08-26 01:24:58 +08:00
LittleSheep
b4d476613e 🐛 Optimzation and bug fixes 2025-08-26 01:18:54 +08:00
LittleSheep
b48a1aac44 Search messages!
♻️ Optimize messages loading, syncing
2025-08-26 01:05:30 +08:00
LittleSheep
596d212593 🐛 Fix account name localization 2025-08-26 00:17:34 +08:00
LittleSheep
54f290327e Copyable file ID 2025-08-26 00:08:50 +08:00
LittleSheep
16f248ceab 💄 Optimize file saving 2025-08-26 00:03:43 +08:00
LittleSheep
856d811187 🐛 Fix notification tap in system wide 2025-08-25 23:14:59 +08:00
LittleSheep
d07b194c04 🐛 Fixes 2025-08-25 20:44:35 +08:00
LittleSheep
2554b58be6 Show automated account in pfc 2025-08-25 20:31:43 +08:00
LittleSheep
a627b5838e 👔 Disable pin reply 2025-08-25 19:57:30 +08:00
LittleSheep
c479a9f381 Show social credits 2025-08-25 19:56:34 +08:00
LittleSheep
02057e663b Real previewing chat 2025-08-25 19:36:48 +08:00
LittleSheep
6501594100 Event dairy 2025-08-25 18:31:57 +08:00
LittleSheep
c6599edc3d 💄 Serval changes to optimize UX 2025-08-25 18:03:50 +08:00
LittleSheep
709a0620b6 Show pinned posts on realms, publishers 2025-08-25 17:09:24 +08:00
LittleSheep
f9b2a96c7c Pin post 2025-08-25 16:55:06 +08:00
LittleSheep
4dca6189cb 💄 Optimize post category subscribe loading state 2025-08-25 16:17:19 +08:00
LittleSheep
c7f5b63fe5 Subscribe to category and tags 2025-08-25 16:15:51 +08:00
LittleSheep
96c2f45c85 💄 Optimize articles page 2025-08-25 15:33:27 +08:00
LittleSheep
06f04eb3a5 🎉 Launch 3.2.0+128 2025-08-25 01:55:54 +08:00
LittleSheep
8af97e43b4 💄 Optimize articles view 2025-08-25 01:48:43 +08:00
LittleSheep
d1e8234b93 🐛 Fix bugs 2025-08-24 23:50:36 +08:00
LittleSheep
a03d6015a6 Manage secret 2025-08-24 23:46:14 +08:00
LittleSheep
246ac52d0a Custom app detail page 2025-08-24 22:33:41 +08:00
LittleSheep
abf395ff9a 🐛 Dozens of bug fixes 2025-08-24 21:49:40 +08:00
LittleSheep
4fdc8eb1d0 Feed discover and subscription 2025-08-24 13:55:06 +08:00
LittleSheep
d7dcde898c 🐛 Dozens of bug fixes 2025-08-24 02:33:02 +08:00
LittleSheep
f85484d3ed 💄 Optimize for large screen 2025-08-24 02:28:16 +08:00
LittleSheep
5060bd30c9 Rotate bot key 2025-08-24 01:49:56 +08:00
LittleSheep
3959f2260b Bot key management 2025-08-23 23:35:37 +08:00
LittleSheep
6f4f1216ad 🐛 Fix project detail 2025-08-23 17:45:08 +08:00
LittleSheep
f401ffbf81 🐛 Fix profile page 2025-08-23 17:34:01 +08:00
LittleSheep
0251697951 Show robot on profile page 2025-08-23 17:32:49 +08:00
LittleSheep
178c12b893 Bot basis 2025-08-23 17:07:42 +08:00
LittleSheep
4beda9200e Add developer projects 2025-08-23 02:56:28 +08:00
LittleSheep
7dfe411053 Add more developer pages (wip) 2025-08-23 02:19:07 +08:00
LittleSheep
1232318a5d Add feed subscription (wip) 2025-08-23 01:32:58 +08:00
LittleSheep
56f41b6c0e 🔀 Merge pull request #173 from Texas0295/v3
🐛 linux/userinfo.dart: guard Firebase calls if Firebase is uninitialized
2025-08-23 01:28:54 +08:00
Texas0295
3ea717d25a 🐛 linux/userinfo.dart: guard Firebase calls if Firebase is uninitialized 2025-08-23 00:34:56 +08:00
LittleSheep
1fe4889460 Search for stickers 2025-08-22 23:31:31 +08:00
LittleSheep
cdf2722268 Stickers order by usage 2025-08-22 22:59:41 +08:00
LittleSheep
a127b5bace Social credits 2025-08-22 19:55:26 +08:00
LittleSheep
b2097cf044 🐛 Fix chat summary failed when lastMessage is null 2025-08-22 19:00:06 +08:00
LittleSheep
701f29748d Debug set access token 2025-08-22 18:59:40 +08:00
LittleSheep
9e40ed4600 Show leveling BonusMultiplier 2025-08-22 17:58:28 +08:00
LittleSheep
c90e6fe661 Experience records & refine leveling page 2025-08-22 17:53:07 +08:00
LittleSheep
569483300d Card shuffle 2025-08-22 16:20:13 +08:00
LittleSheep
bab602d98b Shuffle post 2025-08-22 01:41:25 +08:00
LittleSheep
b4f2bb803a ⬆️ Upgrade deps 2025-08-22 00:22:06 +08:00
LittleSheep
03bfed6f46 💄 Optimize cloud file info 2025-08-22 00:17:13 +08:00
LittleSheep
f98e5a0aec Post browse by categories, tags 2025-08-21 23:21:30 +08:00
LittleSheep
3d473e2fec 🐛 Replace the push with go to view posts in creator centre in order to fix #172 2025-08-21 20:09:49 +08:00
LittleSheep
0b6efa373a 💄 Optimize realm list 2025-08-21 18:49:42 +08:00
LittleSheep
9b60e96cde 💄 Optimize post detail error page 2025-08-21 02:25:13 +08:00
LittleSheep
81cd9b2082 🐛 Fix issues when saving image to gallery without ext name 2025-08-21 02:22:21 +08:00
LittleSheep
923d5d7514 👽 Update stickers api call 2025-08-20 14:26:37 +08:00
LittleSheep
7169aff841 🚀 Launch 3.2.0+127 2025-08-18 13:28:05 +08:00
LittleSheep
fac3efb50c 💄 Add status code to userinfo alert 2025-08-18 13:19:50 +08:00
LittleSheep
e809aadaea Userinfo failed to load alert 2025-08-18 13:08:57 +08:00
LittleSheep
f33b569221 🐛 Fix realm detail 2025-08-18 11:51:44 +08:00
LittleSheep
e5f2e2d146 🐛 Fix notification page cannot return 2025-08-18 11:43:12 +08:00
LittleSheep
11368d064f 🐛 Fix explore page 2025-08-18 11:42:42 +08:00
LittleSheep
246b163aec 🍱 Update notification icon 2025-08-18 02:36:29 +08:00
LittleSheep
10e0d2fe5f 🚀 Launch 3.2.0+126 2025-08-18 02:21:39 +08:00
LittleSheep
99e10cb612 Chat, realm member list with status 2025-08-18 02:01:13 +08:00
LittleSheep
1db6941431 💄 Optimize message styling 2025-08-17 23:13:59 +08:00
LittleSheep
8370da4fe3 Realm page redesgiened 2025-08-17 19:44:43 +08:00
LittleSheep
2bdf7029e9 💄 Optimize chat list tile 2025-08-17 13:51:02 +08:00
LittleSheep
86682a3a9a 💄 Optimize realm discovery list 2025-08-17 13:48:02 +08:00
LittleSheep
c3925e81b5 :drunk: Media offline error builder 2025-08-17 13:40:35 +08:00
LittleSheep
6f1f488490 💄 Limit realm card max description line 2025-08-17 13:36:02 +08:00
LittleSheep
31b2de2e46 💄 Update styling of realm list 2025-08-17 13:35:03 +08:00
LittleSheep
412dcfa62a 💄 Move the publisher invite icon to the list 2025-08-17 13:26:17 +08:00
LittleSheep
ffdc7e81ae 🐛 Make video being contained to prevent some issue 2025-08-17 13:15:55 +08:00
LittleSheep
1d3357803d 🐛 Fix post slug 2025-08-17 13:11:13 +08:00
LittleSheep
6c48aa2356 💄 Optimize attachment preview 2025-08-17 13:08:08 +08:00
LittleSheep
466e354679 💄 Optimize attachment in article 2025-08-17 13:02:52 +08:00
LittleSheep
5d4b896f70 Post slug 2025-08-17 12:47:00 +08:00
LittleSheep
a04dffdfe8 🐛 Fix missing sharePositionOrigin in share 2025-08-17 11:56:34 +08:00
LittleSheep
ff871943cf Show realm post indicator 2025-08-17 02:56:12 +08:00
LittleSheep
1a892ab227 Realm post, and post publisher is org is rounded rect 2025-08-17 02:37:45 +08:00
LittleSheep
af1b303211 Prevent user from setting empty links 2025-08-17 00:55:22 +08:00
LittleSheep
6fd702eba8 🐛 Fix profile update 2025-08-17 00:47:10 +08:00
LittleSheep
d220d43cd2 💄 Optimize chat room 2025-08-17 00:11:28 +08:00
LittleSheep
6892afb974 🔊 Add more logging and optimzation 2025-08-16 23:39:41 +08:00
LittleSheep
007b46b080 ♻️ Refactored the message repository logic 2025-08-16 23:07:21 +08:00
LittleSheep
67d130dc34 🔨 Sync the CMakeLists in linux to update date with the v2 modified version 2025-08-16 18:09:45 +08:00
LittleSheep
7e923c77fe 💄 Change explore screen wide mode breakpoint 2025-08-16 18:03:23 +08:00
LittleSheep
a593b52812 ♻️ Adjust the firebase analytics observer guard 2025-08-16 17:20:03 +08:00
LittleSheep
520dc80303 🔀 Merge pull request #169 from Texas0295/v3
🐛 linux: guard FirebaseAnalyticsObserver when Firebase is not initialized
2025-08-16 17:18:20 +08:00
LittleSheep
001897bbcd Notification indicator 2025-08-16 17:14:26 +08:00
Texas0295
bab29c23e3 🐛 linux: guard FirebaseAnalyticsObserver when Firebase is not initialized 2025-08-16 16:58:12 +08:00
LittleSheep
76b39f2df3 Mark all as read 2025-08-16 11:47:29 +08:00
LittleSheep
509b3e145b 🐛 Fix category selection render error 2025-08-16 02:39:00 +08:00
LittleSheep
2b80ebc2d0 🐛 Fix markdown image in chat close #167 2025-08-16 02:14:44 +08:00
LittleSheep
0ab908dd2a Auto collapse featured post if read 2025-08-16 02:02:06 +08:00
LittleSheep
6007467e7a 🐛 Fixes due to changes in backend 2025-08-15 03:33:20 +08:00
LittleSheep
3745157c42 💄 Optimize snackbars 2025-08-15 00:09:05 +08:00
LittleSheep
94481ec7bd 💫 Chnaged tab page animations 2025-08-14 14:21:57 +08:00
LittleSheep
fbfe8cbdee 🚀 Launch 3.2.0+125 2025-08-14 02:34:05 +08:00
LittleSheep
fbbab0a981 Send delete session requset when logout 2025-08-14 02:29:32 +08:00
LittleSheep
ae2fb3b303 👽 Support new authorized device 2025-08-14 02:10:21 +08:00
LittleSheep
3d7a4666ed 👔 Skip the debug mode crashlytics setup 2025-08-13 15:32:34 +08:00
LittleSheep
5d3e0fb800 🐛 Fix gha artificats has same name 2025-08-13 15:26:00 +08:00
LittleSheep
85ff52a661 🔨 Update windows setup build script and use gha to do so 2025-08-13 13:55:11 +08:00
LittleSheep
da7fd64a43 Merge branch 'v3' of https://github.com/Solsynth/Solian into v3 2025-08-13 13:40:58 +08:00
LittleSheep
3902633217 🔨 Update windows setup builder script 2025-08-13 13:40:53 +08:00
LittleSheep
f478ea8b84 🐛 Serval bug fixes 2025-08-13 13:06:20 +08:00
LittleSheep
0f481aff5b ♻️ Extract the poll related words 2025-08-13 00:35:44 +08:00
LittleSheep
7a31663310 🍱 Update translation 2025-08-12 22:55:20 +08:00
LittleSheep
0239c53c04 💄 Optimize poll submitted view 2025-08-12 22:52:52 +08:00
LittleSheep
16987c758e 💄 Optimize poll 2025-08-12 22:52:05 +08:00
LittleSheep
3a36915140 Setup windows installer 2025-08-12 15:25:41 +08:00
LittleSheep
4bde708878 🐛 Fix windows 2025-08-12 13:04:15 +08:00
LittleSheep
2f0cf560f8 🐛 Hide share via screenshot on web 2025-08-11 22:23:21 +08:00
LittleSheep
cf355a95fd Post share card 2025-08-11 22:18:35 +08:00
LittleSheep
2f43073172 🐛 Hide actions on user himself's profile page 2025-08-11 22:02:50 +08:00
LittleSheep
8236d31ecc ♻️ Refactor the two types of post item 2025-08-11 21:33:10 +08:00
LittleSheep
459a7dade0 🚀 Launch 3.2.0+124 2025-08-11 18:56:32 +08:00
LittleSheep
e6000a660a 📈 Add firebase analytics 2025-08-11 17:59:05 +08:00
LittleSheep
75abaac205 📈 Setup firebase crash handler 2025-08-11 17:25:31 +08:00
LittleSheep
603d5c3f73 Remove keyboard nav 2025-08-11 16:46:43 +08:00
LittleSheep
4e4bd99598 🚀 Launch 3.1.0+123 2025-08-11 02:06:29 +08:00
LittleSheep
d1fbe5f15e 🐛 Dozens of bug fixes 2025-08-11 01:56:19 +08:00
LittleSheep
c061ef2132 🐛 Bug fixes 2025-08-11 01:44:18 +08:00
LittleSheep
c378309bdd 📝 Update localization 2025-08-11 01:44:12 +08:00
LittleSheep
b2c5d64fc5 Keyboard navigation basis 2025-08-10 16:57:11 +08:00
LittleSheep
5371637b16 🔀 Merge pull request #161 from Texas0295/v3
🐛 linux: guard FirebaseMessaging on unsupported platforms
2025-08-10 14:05:48 +08:00
LittleSheep
c5cbf0af37 ⬆️ Upgrade android native project 2025-08-10 13:51:19 +08:00
LittleSheep
1a31e22450 🐛 Fix stickers pack unable to create 2025-08-10 13:23:15 +08:00
Texas0295
49db54529d 🐛 linux: guard FirebaseMessaging on unsupported platforms 2025-08-10 13:17:48 +08:00
LittleSheep
8e0c0c6054 🚀 Launch 3.1.0+122 2025-08-10 04:16:58 +08:00
LittleSheep
f3d1183076 🐛 Fix android update 2025-08-10 04:16:53 +08:00
LittleSheep
a9f7f0cce0 🐛 Fix bugs, ah bugs ha ha, bugs 2025-08-10 04:04:31 +08:00
LittleSheep
f2943f8411 🐛 Fix iOS notify delegate wrong path 2025-08-10 03:30:57 +08:00
LittleSheep
808e7dcffa Option to boost github assets download 2025-08-10 03:25:57 +08:00
LittleSheep
9bed4fa6fb Android install update 2025-08-10 03:21:34 +08:00
LittleSheep
e6255a340b 🐛 Fix background image didn't apply in certain page 2025-08-10 02:59:28 +08:00
LittleSheep
78bf319fb7 💄 Adjust stickers styles 2025-08-10 02:59:11 +08:00
LittleSheep
36a966d582 🐛 Fix profile link parsing 2025-08-10 02:55:00 +08:00
LittleSheep
f72b268d36 💄 Optimize profile page 2025-08-10 02:29:46 +08:00
LittleSheep
44ef31034e 👽 Update the profile links 2025-08-10 02:17:06 +08:00
LittleSheep
229dc2186f 💄 Optimize markdown rendering 2025-08-10 01:53:14 +08:00
LittleSheep
a2f9a1efb4 Optimize post quick reply 2025-08-10 01:45:02 +08:00
LittleSheep
823e3c5de6 🔀 Merge pull request #160 from Texas0295/v3
[FIX] linux_firebase_guard: skip FirebaseMessaging calls on Linux
2025-08-10 01:11:29 +08:00
Texas0295
faac7bac35 🐛 linux: guard FirebaseMessaging calls when Firebase is not initialized 2025-08-10 00:40:49 +08:00
LittleSheep
1fac1bfe02 🐛 Fix post item and payment 2025-08-10 00:26:32 +08:00
LittleSheep
9394b1d9c8 🐛 Serval bug fixes 2025-08-09 23:24:21 +08:00
LittleSheep
43dd13bac4 🐛 Fix status update issue 2025-08-09 22:55:46 +08:00
LittleSheep
65bc372103 🐛 Fix iOS NSE wrong avatar path 2025-08-09 22:55:35 +08:00
LittleSheep
6558854a7a 🚀 Launch 3.1.0+120 2025-08-09 13:37:35 +08:00
LittleSheep
892035ab27 🐛 Somehow fix production video player issue 2025-08-09 13:35:54 +08:00
LittleSheep
87ae8d2ff4 🚀 Launch 3.1.0+119 2025-08-09 01:44:18 +08:00
LittleSheep
15c2dbaa0d 🐛 Fix developer 2025-08-09 01:41:51 +08:00
LittleSheep
6b3338b885 🚀 Launch 3.1.0+118 2025-08-09 00:48:50 +08:00
LittleSheep
bb00b1bc6a Debug options 2025-08-09 00:44:37 +08:00
LittleSheep
5e1a15ada2 Show profile links 2025-08-09 00:27:43 +08:00
LittleSheep
9bdf8ba346 🐛 Fix bugs 2025-08-09 00:21:27 +08:00
LittleSheep
204c087f29 Edit profile links 2025-08-09 00:15:35 +08:00
LittleSheep
1def3e1895 💄 Optimize profile page 2025-08-08 23:46:40 +08:00
LittleSheep
550c74e544 🐛 Fix unable to subscribe 2025-08-08 23:23:16 +08:00
LittleSheep
a39565f012 Post category details 2025-08-08 23:20:22 +08:00
LittleSheep
aa9755e6a7 💄 Optimized post category and tag 2025-08-08 22:19:17 +08:00
LittleSheep
b25e8d661a Show post tags and categories 2025-08-08 21:18:25 +08:00
LittleSheep
4b253ac3ec ⚗️ Testing out the firebase options on linux 2025-08-08 19:47:51 +08:00
LittleSheep
5d1b875d3c 🐛 Disable firebase on linux to prevent errors 2025-08-08 19:41:48 +08:00
LittleSheep
e2e103fa67 Post categories selection 2025-08-08 17:57:47 +08:00
LittleSheep
43c90da4e3 🐛 Fixes attachments 2025-08-08 15:04:50 +08:00
LittleSheep
fa210dd98f 💄 Post featured optimization 2025-08-08 14:44:59 +08:00
LittleSheep
43d9ca92bf Featured post 2025-08-08 03:28:16 +08:00
LittleSheep
5e592c143f ♻️ Rebuild the dupe device 2025-08-08 03:16:16 +08:00
LittleSheep
0c59816f26 👽 Update developer's path 2025-08-08 03:11:38 +08:00
LittleSheep
19c2457895 Network status, poll submit feedback 2025-08-08 02:56:44 +08:00
LittleSheep
af8d87857e Update service 2025-08-07 14:29:20 +08:00
LittleSheep
d05f63a36a 🐛 Bug fixes 2025-08-07 13:29:33 +08:00
LittleSheep
e2dc520012 Post item show more info 2025-08-07 12:17:37 +08:00
LittleSheep
cff9c15e31 🐛 Slicence post list disposed 2025-08-07 12:07:33 +08:00
LittleSheep
f00135c4bf 🐛 Fix room input 2025-08-07 12:04:47 +08:00
LittleSheep
30b8a6c30f 🐛 Fix status overflow 2025-08-07 11:56:37 +08:00
LittleSheep
b9c4ee31b1 Adjust picker size 2025-08-07 11:55:16 +08:00
LittleSheep
87870af866 Sticker picker basis 2025-08-07 03:22:56 +08:00
LittleSheep
b83cb0fb0b ♻️ Replace the snackbar usage 2025-08-07 03:03:15 +08:00
LittleSheep
7fd1fe34e5 Stickers marketplace 2025-08-07 03:00:29 +08:00
LittleSheep
1c18330891 🐛 Fixes poll feedback 2025-08-07 02:17:03 +08:00
LittleSheep
d320879ad0 Poll feedback 2025-08-07 02:01:15 +08:00
LittleSheep
950150e119 🐛 Fix large screen have no post category filter 2025-08-06 21:42:23 +08:00
LittleSheep
3c4a9767e1 ♻️ Move the title, description out of the settings sheet 2025-08-06 20:55:13 +08:00
LittleSheep
5df2445f3f 📝 Update user agreement 2025-08-06 20:30:59 +08:00
LittleSheep
56543d7b4c Publisher page category filter 2025-08-06 20:17:07 +08:00
LittleSheep
4c6fea1242 💄 Optimize cloud video 2025-08-06 18:49:04 +08:00
LittleSheep
fff43de9e3 🐛 Dozens of bug fixes 2025-08-06 18:15:13 +08:00
LittleSheep
b31a915544 🐛 Bug fixes 2025-08-06 14:57:42 +08:00
LittleSheep
8956723ac5 🚀 Launch 3.1.0+117 2025-08-06 03:30:33 +08:00
LittleSheep
ccc3ac415e 🐛 Poll bug fixes 2025-08-06 03:14:09 +08:00
LittleSheep
8c47a59b80 🐛 Bug fixes 2025-08-06 02:51:41 +08:00
LittleSheep
a6d869ebf6 Poll answer 2025-08-06 01:37:38 +08:00
LittleSheep
f3a8699389 🐛 Fixes poll editor 2025-08-05 18:09:34 +08:00
LittleSheep
d345c00e84 Poll editor basic 2025-08-05 17:40:47 +08:00
LittleSheep
a706f127b6 💄 Optimize hint 2025-08-05 02:59:08 +08:00
LittleSheep
680ece0b6a Sensitive marks hidden image 2025-08-05 02:57:27 +08:00
LittleSheep
b976c6ed37 File rename, sensitive 2025-08-05 00:53:00 +08:00
LittleSheep
6ae6b132de Use Solar Network drive hint 2025-08-04 22:37:20 +08:00
LittleSheep
95aec7c95b 💄 Change icon 2025-08-04 22:15:42 +08:00
LittleSheep
edd760fbcb Ability to crop image 2025-08-04 22:08:18 +08:00
LittleSheep
ba269dbbb8 💄 Optimization styles 2025-08-04 18:20:13 +08:00
LittleSheep
1aa45dd9f1 🐛 Fix bottom sheet didn't avoid keyboard 2025-08-04 17:36:04 +08:00
LittleSheep
92685d7410 💄 Optimize profile page 2025-08-04 17:24:17 +08:00
LittleSheep
c8e351514d 🐛 Dozens of bug fixes 2025-08-04 13:34:50 +08:00
LittleSheep
f3900825e3 🐛 Fix oidc 2025-08-03 12:34:12 +08:00
LittleSheep
2cc6652f75 Add audio from existing file 2025-08-02 15:35:18 +08:00
LittleSheep
4d4409de2e Show audio filename 2025-08-02 15:13:50 +08:00
LittleSheep
e1286c797f Audio player 2025-08-02 14:54:56 +08:00
LittleSheep
bec037622f Audio recorder 2025-08-02 14:06:58 +08:00
LittleSheep
a0d8c1a9b3 🐛 Fixes call 2025-08-02 01:53:02 +08:00
LittleSheep
26135d2116 🐛 Fix embed 2025-08-01 23:54:31 +08:00
LittleSheep
71b67fd22d 🐛 Fixes of videos and more 2025-08-01 23:21:43 +08:00
LittleSheep
855072dfea 🐛 Fix refresh failed after delete data 2025-08-01 21:46:43 +08:00
LittleSheep
b39e2e2d64 💄 Video player optimized 2025-08-01 20:36:39 +08:00
LittleSheep
84b1d6a346 💄 Optimization 2025-08-01 18:03:54 +08:00
LittleSheep
28335dd548 💄 Optimize profile page 2025-08-01 16:29:23 +08:00
LittleSheep
7253e2d3ef 🐛 Fix fast scroll explore cause error 2025-08-01 13:03:05 +08:00
LittleSheep
4d489425fa Comment threading
👽 Fix chat notify level
2025-08-01 13:01:38 +08:00
LittleSheep
890a8a44cf Adjustable zoom in image quaility 2025-08-01 11:37:56 +08:00
LittleSheep
8e3583f57a 💄 Optimize post 2025-08-01 11:30:38 +08:00
LittleSheep
d0ff14659f 🚀 Launch 3.1.0+116 2025-08-01 01:36:31 +08:00
LittleSheep
1f7caaeaac 💄 Optimize call 2025-08-01 01:03:01 +08:00
LittleSheep
9f9f42071a 💄 Fixes of call and optimizations 2025-08-01 00:12:18 +08:00
LittleSheep
6bd6e994cb Refreshed article post editor 2025-07-31 22:39:27 +08:00
LittleSheep
02e68d76ee 💄 Optimized creator mode post item 2025-07-31 22:31:22 +08:00
LittleSheep
d04b06089c 💄 Optimized reaction sheet 2025-07-31 22:27:25 +08:00
LittleSheep
9be6fea2e0 ⬆️ Upgrade deps in order to fix firebase breaking changes 2025-07-31 22:04:19 +08:00
LittleSheep
6b1214a06f 🐛 Fix the goddamn AI code 2025-07-31 21:44:14 +08:00
LittleSheep
4597373ac9 Message translate 2025-07-31 21:16:38 +08:00
LittleSheep
047c8d93aa Translate infra and post translate 2025-07-31 21:05:29 +08:00
LittleSheep
715f95ca22 🐛 Bug fixes 2025-07-31 16:48:50 +08:00
LittleSheep
ba709012d7 💄 Optimize article compose 2025-07-31 02:32:03 +08:00
LittleSheep
fd186f8391 💄 Optimize post compose and more 2025-07-31 02:01:18 +08:00
LittleSheep
262d36cd2d 🐛 Fix bugs 2025-07-31 01:20:11 +08:00
LittleSheep
f320855348 💄 Optimize explore page styles 2025-07-31 01:17:20 +08:00
LittleSheep
ed90152462 🐛 Fix message with link will not able to load 2025-07-30 23:04:59 +08:00
LittleSheep
6e5c5f1690 💄 Optimized post item 2025-07-30 22:36:27 +08:00
LittleSheep
7c92dee097 Edited the post item styles 2025-07-30 22:16:36 +08:00
LittleSheep
e4bb031138 💄 Optimize file viewer 2025-07-30 00:29:26 +08:00
LittleSheep
97226ae96b Websocket hearbeat 2025-07-29 18:13:26 +08:00
LittleSheep
d8cd33e79a Add file from ID
🐛 Fix explore unauthorized render error on large screen
2025-07-28 02:01:36 +08:00
LittleSheep
5ecd39b6a9 🚀 Launch 3.1.0+115 2025-07-25 01:59:08 +08:00
LittleSheep
8854305e99 💄 Update the stellar program colors 2025-07-24 02:32:52 +08:00
LittleSheep
903cade296 Stellar program in profile card 2025-07-23 21:50:59 +08:00
LittleSheep
e48410a528 🐛 Fixes of the stellar program 2025-07-23 20:25:14 +08:00
LittleSheep
170ea4f2c0 🐛 Dozens of bug fixes 2025-07-23 02:33:28 +08:00
LittleSheep
19f0e11384 🔨 Update the linux build workflow to fix missing libsecret 2025-07-22 22:36:42 +08:00
LittleSheep
80bf6c3bbe ⬆️ Upgrade flutter packages 2025-07-22 22:30:37 +08:00
LittleSheep
8352ce8b5b New explore screen on wide device 2025-07-21 20:03:06 +08:00
LittleSheep
c06abf6e42 Remove the two column in the explore 2025-07-21 19:35:52 +08:00
LittleSheep
37cc0a5291 📝 Update README.md to refernece Suki 2025-07-20 18:40:20 +08:00
274 changed files with 31701 additions and 7563 deletions

View File

@@ -41,6 +41,15 @@ jobs:
with:
name: build-output-windows
path: build/windows/x64/runner/Release
- name: Compile Installer
uses: Minionguyjpro/Inno-Setup-Action@v1.2.2
with:
path: setup.iss
- name: Archive installer artifacts
uses: actions/upload-artifact@v4
with:
name: build-output-windows-installer
path: Installer/windows-x86_64-setup.exe
build-linux:
runs-on: ubuntu-latest
steps:
@@ -59,7 +68,7 @@ jobs:
sudo apt-get install -y libnotify-dev
sudo apt-get install -y libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
sudo apt-get install -y gstreamer-1.0
sudo apt-get install -y libsecret-1-0
sudo apt-get install -y libsecret-1-dev
- run: flutter pub get
- run: flutter build linux
- name: Archive production artifacts

3
.gitignore vendored
View File

@@ -12,6 +12,9 @@
.swiftpm/
migrate_working_dir/
# Inno Setup
Installer/
# IntelliJ related
*.iml
*.ipr

View File

@@ -8,6 +8,9 @@
Hello there! Welcome to the main repository of the DysonNetwork (also known as the Solar Network). The code here is mainly about the front-end app (also known as Solian). But you can still post issues here to get help and request new features!
如果你看得懂这行字,你可以前往我们的文档来了解更多:
[Suki - Solar Network](https://kb.solsynth.dev/zh/solar-network)
## Server
The backend of the Solar Network project is located at [Solsynth/DysonNetwork](https://github.com/Solsynth/DysonNetwork)
@@ -25,8 +28,6 @@ The content below will lead you to the world of Solar Network.
### For Normal Users
**The v3 Release is not ready, yet.**
1. Go to the Github Releases page, and download the latest release / pre-release according to your platform.
- **What's the difference between stable and pre-release?** The pre-release is untested by the other users and includes the new cutting-edge features, usually the pre-release is the feature drop. At the same time, due to we're not doing the API versioning, some breaking changes may break the stable release, so use the pre-release one instead.
2. Create an account on the Solar Network

View File

@@ -5,6 +5,7 @@ plugins {
id("com.android.application")
// START: FlutterFire Configuration
id("com.google.gms.google-services")
id("com.google.firebase.crashlytics")
// END: FlutterFire Configuration
id("kotlin-android")
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
@@ -51,6 +52,12 @@ android {
buildTypes {
release {
signingConfig = signingConfigs.getByName("release")
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
}
@@ -58,8 +65,7 @@ android {
dependencies {
implementation("com.google.android.material:material:1.12.0")
implementation("com.github.bumptech.glide:glide:4.16.0")
implementation("com.squareup.okhttp3:okhttp:4.12.0")
implementation("com.google.firebase:firebase-messaging-ktx")
implementation("com.squareup.okhttp3:okhttp:5.1.0")
}
flutter {

View File

@@ -12,7 +12,12 @@
"package_name": "dev.solsynth.solian"
}
},
"oauth_client": [],
"oauth_client": [
{
"client_id": "961776991058-963m1qin2vtp8fv693b5fdrab5hmpl89.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyDvFNudXYs29uDtcCv6pFR8h5tXBs90FYk"
@@ -20,7 +25,20 @@
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
"other_platform_oauth_client": [
{
"client_id": "961776991058-963m1qin2vtp8fv693b5fdrab5hmpl89.apps.googleusercontent.com",
"client_type": 3
},
{
"client_id": "961776991058-stt7et4qvn3cpscl4r61gl1hnlatqkig.apps.googleusercontent.com",
"client_type": 2,
"ios_info": {
"bundle_id": "dev.solsynth.solian",
"app_store_id": "6499032345"
}
}
]
}
}
}

5
android/app/proguard-rules.pro vendored Normal file
View File

@@ -0,0 +1,5 @@
# JNI Zero initialization (required for WebRTC native method registration)
-keep class livekit.org.jni_zero.JniInit {
# Keep the init method un-obfuscated for native code callback
private static java.lang.Object[] init();
}

View File

@@ -4,6 +4,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
@@ -89,6 +90,13 @@
</intent-filter>
</activity>
<!-- Livekit Screenshare -->
<service
android:name="de.julianassmann.flutter_background.IsolateHolderService"
android:enabled="true"
android:exported="false"
android:foregroundServiceType="mediaProjection" />
<!-- Sign in with Apple -->
<activity
android:name="com.aboutyou.dart_packages.sign_in_with_apple.SignInWithAppleCallback"
@@ -109,14 +117,6 @@
android:enabled="true"
android:exported="true" />
<service
android:name=".service.MessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="dev.solsynth.solian.provider"

View File

@@ -1,102 +0,0 @@
package dev.solsynth.solian.service
import android.app.PendingIntent
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.app.RemoteInput
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import dev.solsynth.solian.MainActivity
import dev.solsynth.solian.receiver.ReplyReceiver
import org.json.JSONObject
class MessagingService: FirebaseMessagingService() {
override fun onMessageReceived(remoteMessage: RemoteMessage) {
val type = remoteMessage.data["type"]
if (type == "messages.new") {
handleMessageNotification(remoteMessage)
} else {
// Handle other notification types
}
}
private fun handleMessageNotification(remoteMessage: RemoteMessage) {
val data = remoteMessage.data
val metaString = data["meta"] ?: return
val meta = JSONObject(metaString)
val pfp = meta.optString("pfp", null)
val roomId = meta.optString("room_id", null)
val messageId = meta.optString("message_id", null)
val notificationId = System.currentTimeMillis().toInt()
val replyLabel = "Reply"
val remoteInput = RemoteInput.Builder("key_text_reply")
.setLabel(replyLabel)
.build()
val replyIntent = Intent(this, ReplyReceiver::class.java).apply {
putExtra("room_id", roomId)
putExtra("message_id", messageId)
putExtra("notification_id", notificationId)
}
val pendingIntentFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
} else {
PendingIntent.FLAG_UPDATE_CURRENT
}
val replyPendingIntent = PendingIntent.getBroadcast(
applicationContext,
notificationId,
replyIntent,
pendingIntentFlags
)
val action = NotificationCompat.Action.Builder(
android.R.drawable.ic_menu_send,
replyLabel,
replyPendingIntent
)
.addRemoteInput(remoteInput)
.build()
val intent = Intent(this, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
intent.putExtra("room_id", roomId)
val pendingIntent = PendingIntent.getActivity(this, 0, intent, pendingIntentFlags)
val notificationBuilder = NotificationCompat.Builder(this, "messages")
.setSmallIcon(android.R.drawable.ic_dialog_info)
.setContentTitle(remoteMessage.notification?.title)
.setContentText(remoteMessage.notification?.body)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentIntent(pendingIntent)
.addAction(action)
if (pfp != null) {
Glide.with(applicationContext)
.asBitmap()
.load(pfp)
.into(object : CustomTarget<Bitmap>() {
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
notificationBuilder.setLargeIcon(resource)
NotificationManagerCompat.from(applicationContext).notify(notificationId, notificationBuilder.build())
}
override fun onLoadCleared(placeholder: Drawable?) {}
})
} else {
NotificationManagerCompat.from(this).notify(notificationId, notificationBuilder.build())
}
}
}

View File

@@ -0,0 +1,41 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="192dp"
android:height="192dp"
android:viewportWidth="192"
android:viewportHeight="192">
<path
android:pathData="M54,147h86"
android:strokeLineJoin="round"
android:strokeWidth="12"
android:fillColor="#00000000"
android:strokeColor="#000"
android:strokeLineCap="round"/>
<path
android:pathData="M57,111s-2,-4.5 -2,-10m22,22s-4,7 -11,4m9,-22s-2,-4.5 -2,-10"
android:strokeLineJoin="round"
android:strokeWidth="10"
android:fillColor="#00000000"
android:strokeColor="#000"
android:strokeLineCap="round"/>
<path
android:pathData="M54,147a32,32 0,0 1,-12 -61.67A39,39 0,0 1,81 46m59,101a30,30 0,0 0,29.93 -28"
android:strokeLineJoin="round"
android:strokeWidth="12"
android:fillColor="#00000000"
android:strokeColor="#000"
android:strokeLineCap="round"/>
<path
android:pathData="M132,75m-4,0a4,4 0,1 1,8 0a4,4 0,1 1,-8 0"
android:strokeLineJoin="round"
android:strokeWidth="8"
android:fillColor="#00000000"
android:strokeColor="#000"
android:strokeLineCap="round"/>
<path
android:pathData="M112.5,41.22C100.84,47.96 93,60.56 93,75c0,6.38 1.53,12.39 4.24,17.71m69.51,-35.42A38.84,38.84 0,0 1,171 75c0,14.43 -7.84,27.03 -19.49,33.78m-0.79,-43.32A20.9,20.9 0,0 1,153 75c0,7.77 -4.22,14.56 -10.49,18.19m-21,-36.38C115.22,60.44 111,67.23 111,75a20.9,20.9 0,0 0,2.28 9.53"
android:strokeLineJoin="round"
android:strokeWidth="10"
android:fillColor="#00000000"
android:strokeColor="#000"
android:strokeLineCap="round"/>
</vector>

View File

@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-all.zip

View File

@@ -18,11 +18,12 @@ pluginManagement {
plugins {
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
id("com.android.application") version "8.10.1" apply false
id("com.android.application") version "8.12.0" apply false
// START: FlutterFire Configuration
id("com.google.gms.google-services") version("4.3.15") apply false
id("com.google.firebase.crashlytics") version("2.8.1") apply false
// END: FlutterFire Configuration
id("org.jetbrains.kotlin.android") version "1.8.22" apply false
id("org.jetbrains.kotlin.android") version("2.2.0") apply false
}
include(":app")

View File

@@ -144,9 +144,16 @@
"other": "{} attachments"
},
"edited": "Edited",
"editedAt": "Edited at {}",
"addVideo": "Add video",
"addPhoto": "Add photo",
"addAudio": "Add audio",
"addFile": "Add file",
"recordAudio": "Record Audio",
"linkAttachment": "Link Attachment",
"fileIdCannotBeEmpty": "File ID cannot be empty",
"fileIdLinkHint": "Haven't upload to the Solar Network? Tap here to open Solar Network Drive to customize your uploads.",
"failedToFetchFile": "Failed to fetch file: {}",
"createDirectMessage": "Send new DM",
"gotoDirectMessage": "Go to DM",
"react": "React",
@@ -327,6 +334,7 @@
"walletCreate": "Create a Wallet",
"settingsServerUrl": "Server URL",
"settingsApplied": "The settings has been applied.",
"settingsCustomFontsHelper": "Use comma to seprate.",
"notifications": "Notifications",
"posts": "Posts",
"settingsBackgroundImage": "Background Image",
@@ -352,6 +360,8 @@
"postTitle": "Title",
"postDescription": "Description",
"call": "Call",
"callLeave": "Leave",
"callEnd": "End this call",
"done": "Done",
"loginResetPasswordSent": "Password reset link sent, please check your email inbox.",
"accountDeletion": "Delete Account",
@@ -376,6 +386,7 @@
"postSettings": "Settings",
"postPublisherUnselected": "Publisher Unspecified",
"postType": "Post Type",
"postTypePost": "Post",
"articleAttachmentHint": "Attachments must be uploaded and inserted into the article body to be visible.",
"postVisibility": "Post Visibility",
"postVisibilityPublic": "Public",
@@ -564,6 +575,7 @@
"keyboardShortcuts": "Keyboard Shortcuts",
"share": "Share",
"sharePost": "Share Post",
"sharePostPhoto": "Share Post as Photo",
"quickActions": "Quick Actions",
"post": "Post",
"copy": "Copy",
@@ -622,8 +634,8 @@
"chatJoin": "Join the Chat",
"realmJoin": "Join the Realm",
"realmJoinSuccess": "Successfully joined the realm.",
"discoverRealms": "Discover Realms",
"discoverPublishers": "Discover Publishers",
"discoverRealms": "Discover realms",
"discoverPublishers": "Discover publishers",
"search": "Search",
"publisherMembers": "Collaborators",
"developerHub": "Developer Hub",
@@ -632,6 +644,18 @@
"enrollDeveloperHint": "Enroll one of your publishers to become a developer.",
"noPublishersToEnroll": "You don't have any publishers that can be enrolled as a developer.",
"totalCustomApps": "Total Custom Apps",
"projects": "Projects",
"noProjects": "No projects found.",
"deleteProject": "Delete Project",
"deleteProjectHint": "Are you sure you want to delete this project? This action cannot be undone.",
"createProject": "Create Project",
"editProject": "Edit Project",
"projectDetails": "Project Details",
"createBot": "Create Bot",
"bots": "Bots",
"noBots": "No bots yet.",
"deleteBotHint": "Are you sure you want to delete this bot? This action cannot be undone.",
"deleteBot": "Delete Bot",
"customApps": "Custom Apps",
"noCustomApps": "No custom apps yet.",
"createCustomApp": "Create Custom App",
@@ -697,10 +721,244 @@
"copyToClipboardTooltip": "Copy to clipboard",
"postForwardingTo": "Forwarding to",
"postReplyingTo": "Replying to",
"postReplyPlaceholder": "Post your reply",
"postEditing": "You are editing an existing post",
"postArticle": "Article",
"aboutDeviceName": "Device Name",
"aboutDeviceIdentifier": "Device Identifier",
"donate": "Donate",
"donateDescription": "Support us to continue developing the Solar Network and keep the server up and running."
"donateDescription": "Support us to continue developing the Solar Network and keep the server up and running.",
"fileId": "File ID",
"fileIdHint": "The file ID is the ID you get after upload the file via the Solar Network Drive.",
"translate": "Translate",
"translating": "Translating",
"translated": "Translated",
"reactionThumbUp": "Thumbs Up",
"reactionThumbDown": "Thumbs Down",
"reactionJustOkay": "Just Okay",
"reactionCry": "Cry",
"reactionConfuse": "Confused",
"reactionClap": "Clap",
"reactionLaugh": "Laugh",
"reactionAngry": "Angry",
"reactionParty": "Party",
"reactionPray": "Pray",
"reactionHeart": "Heart",
"selectMicrophone": "Select Microphone",
"selectCamera": "Select Camera",
"switchedTo": "Switched to {}",
"connecting": "Connecting",
"reconnecting": "Reconnecting",
"disconnected": "Disconnected",
"connected": "Connected",
"repliesLoadMore": "Load more replies",
"attachmentsRecentUploads": "Recent Uploads",
"attachmentsManualInput": "Manual Input",
"crop": "Crop",
"rename": "Rename",
"markAsSensitive": "Mark as Sensitive",
"fileName": "File name",
"sensitiveCategories.language": "Language",
"sensitiveCategories.sexualContent": "Sexual Content",
"sensitiveCategories.violence": "Violence",
"sensitiveCategories.profanity": "Profanity",
"sensitiveCategories.hateSpeech": "Hate Speech",
"sensitiveCategories.racism": "Racism",
"sensitiveCategories.adultContent": "Adult Content",
"sensitiveCategories.drugAbuse": "Drug Abuse",
"sensitiveCategories.alcoholAbuse": "Alcohol Abuse",
"sensitiveCategories.gambling": "Gambling",
"sensitiveCategories.selfHarm": "Self-harm",
"sensitiveCategories.childAbuse": "Child Abuse",
"sensitiveCategories.other": "Other",
"poll": "Poll",
"pollsRecent": "Recent Polls",
"pollCreateNew": "Create New",
"pollCreateNewHint": "Create a new poll for your post. Pick a publisher and continue.",
"pollQuestions": "Questions",
"publisher": "Publisher",
"publisherHint": "Enter the publisher name",
"publisherCannotBeEmpty": "Publisher cannot be empty",
"operationFailed": "Operation failed: {}",
"stickerMarketplace": "Sticker Marketplace",
"stickerPackAdded": "Sticker pack added to your collection",
"stickerPackRemoved": "Sticker pack removed from your collection",
"addPack": "Add Pack",
"removePack": "Remove Pack",
"browseAndAddStickers": "Browse and add sticker packs",
"stickerPack": "Sticker Pack",
"postCategoryTechnology": "Technology",
"postCategoryTravel": "Travel",
"postCategoryFood": "Food",
"postCategoryHealth": "Health",
"postCategoryScience": "Science",
"postCategorySports": "Sports",
"postCategoryFinance": "Finance",
"postCategoryLife": "Life",
"postCategoryArt": "Art",
"postCategoryStudy": "Study",
"postCategoryGaming": "Gaming",
"postCategoryProgramming": "Programming",
"postCategoryMusic": "Music",
"links": "Links",
"addLink": "Add link",
"linkKey": "Link Name",
"linkValue": "URL",
"debugOptions": "Debug Options",
"joinedAt": "Joined at {}",
"searchAccounts": "Search accounts...",
"webFeeds": "Web Feeds",
"polls": "Polls",
"sharePostSlogan": "Explore more on the Solar Network",
"filesListAdditional": {
"one": "+{} file remaining",
"other": "+{} files remaining"
},
"pollAnswerSubmitted": "Poll answer has been submitted.",
"modifyAnswers": "Modify Answers",
"back": "Back",
"submit": "Submit",
"pollOptionDefaultLabel": "Option 1",
"pollUpdated": "Poll updated.",
"pollCreated": "Poll created.",
"pollCreate": "Create Poll",
"pollEdit": "Edit Poll",
"pollPreviewJsonDebug": "Debug Preview",
"pollTitleRequired": "Title is required",
"pollEndDateOptional": "End date & time (optional)",
"notSet": "Not set",
"pick": "Pick",
"clear": "Clear",
"questions": "Questions",
"pollAddQuestion": "Add question",
"pollQuestionTypeSingleChoice": "Single choice",
"pollQuestionTypeMultipleChoice": "Multiple choice",
"pollQuestionTypeFreeText": "Free text",
"pollQuestionTypeYesNo": "Yes / No",
"pollQuestionTypeRating": "Rating",
"pollNoQuestionsYet": "No questions yet",
"pollNoQuestionsHint": "Use \"Add question\" to start building your poll.",
"pollDebugPreview": "Debug Preview",
"pollUntitledQuestion": "Untitled question",
"moveUp": "Move up",
"moveDown": "Move down",
"required": "Required",
"pollQuestionTitle": "Question title",
"pollQuestionTitleRequired": "Question title is required",
"pollQuestionDescriptionOptional": "Question description (optional)",
"options": "Options",
"pollAddOption": "Add option",
"pollOptionLabel": "Option label",
"pollLongTextAnswerPreview": "Long text answer (preview)",
"pollShortTextAnswerPreview": "Short text answer (preview)",
"messageJumpNotLoaded": "The referenced message was not loaded, unable to jump to it.",
"postUnlinkRealm": "No linked realm",
"postSlug": "Slug",
"postSlugHint": "The slug can be used to access your post via URL in the webpage, it should be publisher-wide unique.",
"attachmentOnDevice": "On-device",
"attachmentOnCloud": "On-cloud",
"attachments": "Attachments",
"publisherCollabInvitation": "Collabration invitations",
"publisherCollabInvitationCount": {
"zero": "No invitation",
"one": "{} available invitation",
"other": "{} available invitations"
},
"failedToLoadUserInfo": "Failed to load user info",
"failedToLoadUserInfoNetwork": "It seems be network issue, you can tap the button below to try again.",
"failedToLoadUserInfoUnauthorized": "It seems your session has been logged out or not available anymore, you can still try agian to fetch the user info if you want.",
"okay": "Okay",
"postDetail": "Post Detail",
"postCount": {
"zero": "No posts",
"one": "{} post",
"other": "{} posts"
},
"mimeType": "MIME Type",
"fileSize": "File Size",
"fileHash": "File Hash",
"exifData": "EXIF Data",
"postShuffle": "Shuffle Posts",
"leveling": "Leveling",
"levelingHistory": "Leveling History",
"stellarProgram": "Stellar Program",
"socialCredits": "Social Credits",
"credits": "Credits",
"creditsStatus": "Credits Status",
"socialCreditsDescription": "Social Credit is a way for Solar Network to evaluate users. It is calculated based on their behavior and interactions. With a base score of 100, higher scores indicate a user's credibility within the community. Scores change over time to reflect a user's recent behavior. Users with higher credit ratings enjoy more benefits, while users with lower credit ratings may have some functionality restricted.",
"socialCreditsLevelPoor": "Poor",
"socialCreditsLevelNormal": "Normal",
"socialCreditsLevelGood": "Good",
"socialCreditsLevelExcellent": "Excellent",
"orderByPopularity": "Sort by popularity",
"orderByReleaseDate": "Sort by release date",
"editBot": "Edit Bot",
"botAutomatedBy": "Automated by {}",
"botDetails": "Bot Details",
"overview": "Overview",
"keys": "Keys",
"botNotFound": "Bot not found.",
"newBotKey": "New Bot Key",
"newBotKeyHint": "Enter a name for your new key. The key will be shown only once.",
"revokeBotKey": "Revoke Bot Key",
"revokeBotKeyHint": "Are you sure you want to revoke this key? This action cannot be undone and any application using this key will stop working.",
"noBotKeys": "No bot keys yet.",
"revoke": "Revoke",
"keyName": "Key Name",
"newKeyGenerated": "New Key Generated",
"copyKeyHint": "Please copy this key and store it somewhere safe. You will not be able to see it again.",
"rotateKey": "Rotate Key",
"rotateBotKey": "Rotate Bot Key",
"rotateBotKeyHint": "Are you sure you want to rotate this key? The old key will become invalid immediately. This action cannot be undone.",
"webFeedArticleCount": {
"zero": "No articles",
"one": "{} article",
"other": "{} articles"
},
"webFeedSubscribed": "The feed has been subscribed",
"webFeedUnsubscribed": "The feed has been unsubscribed",
"appDetails": "App Details",
"secrets": "Secrets",
"appNotFound": "App not found.",
"secretCopied": "Secret copied to clipboard.",
"deleteSecret": "Delete Secret",
"deleteSecretHint": "Are you sure you want to delete this secret? This action cannot be undone.",
"generateSecret": "Generate New Secret",
"createdAt": "Created at {}",
"newSecretGenerated": "New Secret Generated",
"copySecretHint": "Please copy this secret and store it somewhere safe. You will not be able to see it again.",
"expiresIn": "Expires In (seconds)",
"isOidc": "OIDC Compliant",
"pinPost": "Pin Post",
"unpinPost": "Unpin Post",
"pinnedPost": "Pinned",
"publisherPage": "Publisher Page",
"realmPage": "Realm Page",
"replyPage": "Reply Page",
"pinPostPublisherHint": "Pin this post to your publisher page",
"pinPostRealmHint": "Pin this post to the realm page",
"pinPostRealmDisabledHint": "This post doesn't belong to any realm",
"pinPostReplyHint": "Pin this post to the reply page",
"pinPostReplyDisabledHint": "This post is not a reply",
"pin": "Pin",
"unpinPostHint": "Are you sure you want to unpin this post?",
"all": "All",
"statusPresent": "Present",
"accountAutomated": "Automated",
"chatBreakClearButton": "Clear",
"chatBreak5m": "5m",
"chatBreak10m": "10m",
"chatBreak15m": "15m",
"chatBreak30m": "30m",
"chatBreakCustomMinutes": "Custom (minutes)",
"chatBreakEnterMinutes": "Enter minutes",
"errorGeneric": "Error: {}",
"searchMessages": "Search Messages",
"messagesCount": "{} messages",
"dotSeparator": "·",
"roleValidationHint": "Role must be between 0 and 100",
"searchMessagesHint": "Search messages...",
"searchLinks": "Links",
"searchAttachments": "Attachments",
"noMessagesFound": "No messages found"
}

View File

@@ -46,7 +46,6 @@
"delete": "删除",
"deletePublisher": "删除发布者",
"deletePublisherHint": "确定要删除此发布者吗?这也会删除此发布者下的所有帖子和收藏。",
"somethingWentWrong": "发生了一些错误",
"deletePost": "删除帖子",
"deletePostHint": "确定要删除这篇帖子吗?",
"copyLink": "复制链接",
@@ -301,6 +300,7 @@
"walletCreate": "创建钱包",
"settingsServerUrl": "服务器 URL",
"settingsApplied": "设置已应用。",
"settingsCustomFontsHelper": "用逗号分隔。",
"notifications": "通知",
"posts": "帖子",
"settingsBackgroundImage": "背景图片",
@@ -349,7 +349,6 @@
"postContent": "内容",
"postSettings": "设置",
"postPublisherUnselected": "未指定发布者",
"postVisibility": "可见性",
"postVisibilityPublic": "公开",
"postVisibilityFriends": "仅好友可见",
"postVisibilityUnlisted": "不公开",
@@ -473,7 +472,7 @@
"description": "描述",
"pinCode": "PIN 码",
"biometric": "生物识别",
"enterPinToConfirm": "请输入您的 6 位数字 PIN 以确认付款",
"enterPinToConfirm": "请输入您的6位数字 PIN 以确认付款",
"clearPin": "清除 PIN 码",
"useBiometricToConfirm": "使用生物特征认证来确认付款",
"touchSensorToAuthenticate": "触摸传感器进行身份验证",
@@ -490,20 +489,26 @@
"paymentError": "付款失败: {error}",
"usePinInstead": "使用 PIN 码",
"levelProgress": "等级进度",
"unlockedFeatures": "已解锁的功能",
"unlockedFeaturesDescription": "在您当前级别上解锁的功能将显示在这里。",
"stellarMembership": "恒星计划",
"upgradeYourPlan": "升级您的计划",
"chooseYourPlan": "选择你的方案",
"currentMembership": "当前:{}",
"currentMembershipMember": "恒星计划「{}」级会员",
"membershipExpires": "过期于:{}",
"membershipTierStellar": "恒星",
"membershipTierNova": "新星",
"membershipTierSupernova": "超新星",
"membershipTierUnknown": "未知",
"membershipPriceStellar": "每月 1200 源点,至少需要 3 级",
"membershipPriceNova": "每月 2400 源点,至少需要 6 级",
"membershipPriceSupernova": "每月 3600 源点,至少需要 9 级",
"membershipFeatureBasic": "基础功能",
"membershipFeaturePrioritySupport": "优先支持",
"membershipFeatureAdFree": "无广告",
"membershipFeatureAllPrimary": "所有主要功能",
"membershipFeatureAdvancedCustomization": "高级自定义",
"membershipFeatureEarlyAccess": "抢先体验",
"membershipFeatureAllNova": "所有「新星」功能",
"membershipFeatureExclusiveContent": "限定内容",
"membershipFeatureVipSupport": "VIP 支持",
"membershipCurrentBadge": "当前",
"restorePurchase": "恢复购买",
"restorePurchaseDescription": "输入您付款的提供商和订单 ID 以恢复您的购买。",
@@ -513,11 +518,186 @@
"enterOrderId": "输入您的订单 ID",
"restore": "恢复",
"keyboardShortcuts": "键盘快捷键",
"safetyReport": "举报",
"safetyReportTitle": "举报",
"safetyReportDescription": "通过举报不合适的内容和行为来维护我们社区的稳定。",
"safetyReportType": "举报类型",
"safetyReportReason": "更多证据",
"safetyReportReasonHint": "请提供更多证据……",
"safetyReportSubmit": "提交举报",
"safetyReportSubmitting": "提交中……",
"safetyReportSuccess": "举报成功,感谢您参与维护社区健康发展。",
"safetyReportError": "举报失败,请稍后重试。",
"safetyReportReasonRequired": "请提供举报证据",
"safetyReportTypeSpam": "垃圾或导向错误",
"safetyReportTypeHarassment": "骚扰或暴力行为",
"safetyReportTypeHateSpeech": "歧视言论",
"safetyReportTypeViolence": "威胁或暴力内容",
"safetyReportTypeAdultContent": "成人内容",
"safetyReportTypeIntellectualProperty": "抄袭",
"safetyReportTypeOther": "其它",
"safetyReportTypeInappropriate": "不良内容",
"safetyReportTypeCopyright": "版权侵害",
"safetyReportSuccessTitle": "举报成功",
"safetyReportErrorTitle": "错误",
"discover": "发现",
"joinRealm": "加入领域",
"removePublisherMember": "移除发布者",
"removePublisherMemberHint": "你确定要将这个成员从发布者中移除?",
"drafts": "草稿箱",
"noDrafts": "无草稿",
"articleDrafts": "文章草稿",
"postDrafts": "帖子草稿",
"saveDraft": "保存草稿",
"draftSaved": "草稿已保存",
"draftSaveFailed": "保存草稿失败",
"clearAllDrafts": "清除全部草稿",
"clearAllDraftsConfirm": "你确定要清除全部草稿?这一操作无法撤销。",
"clearAll": "清除所有",
"untitled": "未命名",
"noContent": "内容为空",
"justNow": "刚刚",
"minutesAgo": "{} 分钟以前",
"hoursAgo": "{} 小时以前",
"daysAgo": "{} 天以前",
"public": "公开的",
"unlisted": "不列出",
"friends": "朋友",
"selected": "选择的",
"private": "私密的",
"postContentEmpty": "发布的内容不能为空",
"share": "分享",
"sharePost": "分享帖子",
"quickActions": "快捷操作",
"post": "发帖",
"copy": "复制",
"sendToChat": "发送到聊天",
"failedToShareToPost": "分享到帖子失败:{}",
"shareToChatComingSoon": "分享到聊天功能即将推出",
"failedToShareToChat": "分享到聊天失败:{}",
"shareToSpecificChatComingSoon": "分享到 {} 功能即将推出",
"directChat": "私信",
"systemShareComingSoon": "系统分享功能即将推出",
"failedToShareToSystem": "分享到系统失败:{}",
"failedToCopy": "复制失败:{}",
"noChatRoomsAvailable": "无可用聊天室",
"failedToLoadChats": "加载聊天失败",
"contentToShare": "分享内容:",
"unknownChat": "未知聊天",
"addAdditionalMessage": "添加附加消息……",
"uploadingFiles": "上传文件中……",
"sharedSuccessfully": "分享成功!",
"shareSuccess": "分享成功!",
"shareToSpecificChatSuccess": "成功分享至 {}",
"wouldYouLikeToGoToChat": "是否前往该聊天?",
"no": "否",
"yes": "是",
"navigateToChat": "前往聊天",
"abuseReport": "举报",
"abuseReportTitle": "举报内容",
"abuseReportDescription": "举报不当内容或行为,协助维护社区安全。",
"abuseReportType": "举报类型",
"abuseReportReason": "补充详情",
"abuseReportReasonHint": "请提供更多详情……",
"abuseReportSubmit": "提交举报",
"abuseReportSuccess": "举报提交成功,感谢你为社区维护作出贡献。",
"abuseReportError": "无法提交举报,请稍后再试。",
"abuseReportReasonRequired": "请提供关于此事件的细节",
"abuseReportSuccessTitle": "举报已提交",
"abuseReportErrorTitle": "错误",
"abuseReportTypeSpam": "垃圾或错误信息",
"abuseReportTypeHarassment": "骚扰或滥用",
"abuseReportTypeInappropriate": "不合适的内容",
"abuseReportTypeViolence": "暴力或人身威胁",
"abuseReportTypeCopyright": "版权侵犯",
"abuseReportTypeImpersonation": "冒充",
"abuseReportTypeOffensiveContent": "冒犯性内容",
"abuseReportTypePrivacyViolation": "隐私侵犯",
"abuseReportTypeIllegalContent": "违法内容",
"abuseReportTypeOther": "其他",
"tags": "标签",
"tagsHint": "输入标签,用英文逗号分隔",
"categories": "分类",
"categoriesHint": "输入分类,由逗号隔开",
"chatNotJoined": "你还没有加入这个聊天。",
"chatUnableJoin": "由于该聊天的访问设置使你无法加入。",
"chatJoin": "加入聊天",
"realmJoin": "加入领域",
"realmJoinSuccess": "成功加入领域。",
"search": "搜索",
"publisherMembers": "合作者",
"developerHub": "开发者中心",
"developerHubUnselectedHint": "选择一名开发者查看总结数据或成为一名。",
"enrollDeveloper": "成为一名开发者",
"enrollDeveloperHint": "让你的一个发布者成为开发者。",
"noPublishersToEnroll": "你没有可以成为开发者的发布者。",
"totalCustomApps": "所有应用套件",
"customApps": "应用套件",
"noCustomApps": "还没有应用套件。",
"createCustomApp": "创建应用套件",
"editCustomApp": "编辑应用套件",
"deleteCustomApp": "删除应用套件",
"deleteCustomAppHint": "你确定要删除这个应用套件吗?这一步无法撤销。",
"publicRealm": "公开领域",
"publicRealmDescription": "所有人都可以预览这个领域的内容。",
"communityRealm": "领域",
"communityRealmDescription": "所有人都可以加入该领域并参与讨论,并将在发现和反馈页面显示。",
"publicChat": "公开聊天",
"publicChatDescription": "任何人都可以预览此聊天的内容。包括未加入的机器人。",
"communityChat": "社区聊天",
"communityChatDescription": "所有人都可以加入该聊天并参与参与讨论。",
"appLinks": "应用链接",
"homePageUrl": "主页链接",
"privacyPolicyUrl": "隐私政策链接",
"termsOfServiceUrl": "用户协议链接",
"oauthConfig": "OAuth 配置",
"clientUri": "客户端 URI",
"redirectUris": "重定向 URIs",
"addRedirectUri": "添加重定向 URI",
"allowedScopes": "允许的范围",
"requirePkce": "需要 PKCE",
"allowOfflineAccess": "允许离线访问",
"redirectUri": "重定向 URI",
"redirectUriHint": "重定向 URI 用于 OAuth 认证,但您的项目状态转为线上时我们会验证请求中的重定向 URI 是否符合此配置。",
"uriRequired": "这个 URI 是必须填写的。",
"uriInvalid": "无效 URI。",
"add": "添加",
"addScope": "添加范围",
"scope": "范围",
"publisherFeatures": "功能",
"publisherFeatureDevelop": "开发者计划",
"publisherFeatureDevelopDescription": "为你的开发者解锁包括应用套件API 及更多开发功能。",
"publisherFeatureDevelopHint": "目前该功能还在开发中,你需要邀请才可解锁。",
"learnMore": "了解更多",
"discoverWebArticles": "来自站外的文章",
"webArticlesStand": "文章亭",
"about": "关于",
"somethingWentWrong": "发生了一些错误",
"editedAt": "编辑于 {}",
"addAudio": "添加音频",
"recordAudio": "录制音频",
"linkAttachment": "链接附件",
"fileIdCannotBeEmpty": "文件 ID 不能为空",
"fileIdLinkHint": "还没有上传到 Solar Network点击此处打开 Solar Network Drive自定义您的上传内容。",
"failedToFetchFile": "获取文件失败:{}",
"callLeave": "离开",
"callEnd": "挂断通话",
"postType": "帖子类型",
"articleAttachmentHint": "附件必须上传并插入到文章主体中才能显示出来。",
"postVisibility": "可见性",
"currentMembershipMember": "恒星计划成员 · {}",
"membershipPriceStellar": "需要用户等级 3+,每月价格 1200 NSP",
"membershipPriceNova": "需要用户等级 6+,每月价格 2400 NSP",
"membershipPriceSupernova": "需要用户等级 9+,每月价格 3600 NSP",
"sharePostPhoto": "通过图片分享帖子",
"wouldYouLikeToNavigateToChat": "你想要前往聊天页面吗?",
"abuseReports": "举报",
"discoverRealms": "发现领域",
"discoverPublishers": "发现发布者",
"membershipCancel": "取消会员订阅",
"membershipCancelConfirm": "确定要取消您的会员订阅?",
"membershipCancelHint": "确定要取消您的会员订阅吗?将不会再被收费。的会员资格将在当前计费周期结束前保持有效。并且您在当前订阅结束之前无法重新订阅。",
"membershipCancelSuccess": "的会员订阅已成功取消。",
"membershipCancelConfirm": "确定要取消会员订阅",
"membershipCancelHint": "确定要取消会员订阅吗?将不会再次被扣费。的会员资格将在当前计费周期结束前保持有效。并且你将无法重新订阅,直到当前订阅结束。",
"membershipCancelSuccess": "的会员订阅已成功取消。",
"aboutScreenTitle": "关于",
"aboutScreenVersionInfo": "版本 {} ({})",
"aboutScreenAppInfoSectionTitle": "应用信息",
@@ -527,18 +707,155 @@
"aboutScreenLinksSectionTitle": "链接",
"aboutScreenPrivacyPolicyTitle": "隐私政策",
"aboutScreenTermsOfServiceTitle": "服务条款",
"aboutScreenOpenSourceLicensesTitle": "开源许可",
"aboutScreenOpenSourceLicensesTitle": "开源许可",
"aboutScreenDeveloperSectionTitle": "开发者",
"aboutScreenContactUsTitle": "联系我们",
"aboutScreenLicenseTitle": "许可",
"aboutScreenLicenseContent": "GNU Affero General Public License v3.0",
"aboutScreenCopyright": "版权所有 © 索尔辛茨 {}",
"aboutScreenMadeWith": "由 Solar Network Team 用 ❤︎️ 制作",
"aboutScreenFailedToLoadPackageInfo": "加载包信息失败{error}",
"aboutScreenLicenseTitle": "许可",
"aboutScreenLicenseContent": "无法翻译",
"aboutScreenCopyright": "版权所有 © Solsynth {}",
"aboutScreenMadeWith": "由 Solar Network 团队用 ❤︎️ 制作",
"aboutScreenFailedToLoadPackageInfo": "无法加载包信息:{error}",
"copiedToClipboard": "已复制到剪贴板",
"copyToClipboardTooltip": "复制到剪贴板",
"postForwardingTo": "转发",
"postReplyingTo": "回复",
"postEditing": "您正在编辑现有帖子",
"postArticle": "文章"
"postForwardingTo": "正在转发",
"postReplyingTo": "正在回复",
"postReplyPlaceholder": "发表你的回复",
"postEditing": "你正在编辑一个现有的帖子",
"postArticle": "文章",
"aboutDeviceName": "设备名称",
"aboutDeviceIdentifier": "设备标识符",
"donate": "捐赠",
"donateDescription": "支持我们继续开发 Solar Network并维持服务器运行。",
"fileId": "文件 ID",
"fileIdHint": "文件 ID 是你通过 Solar Network Drive 上传文件后获得的 ID。",
"translate": "翻译",
"translating": "正在翻译",
"translated": "已翻译",
"reactionThumbUp": "赞",
"reactionThumbDown": "踩",
"reactionJustOkay": "还行",
"reactionCry": "哭",
"reactionConfuse": "困惑",
"reactionClap": "鼓掌",
"reactionLaugh": "笑",
"reactionAngry": "生气",
"reactionParty": "派对",
"reactionPray": "祈祷",
"reactionHeart": "爱心",
"selectMicrophone": "选择麦克风",
"selectCamera": "选择摄像头",
"switchedTo": "已切换到 {}",
"connecting": "正在连接",
"reconnecting": "正在重新连接",
"disconnected": "已断开连接",
"connected": "已连接",
"repliesLoadMore": "加载更多回复",
"attachmentsRecentUploads": "最近上传",
"attachmentsManualInput": "手动输入",
"crop": "裁剪",
"rename": "重命名",
"markAsSensitive": "标记为敏感",
"fileName": "文件名",
"sensitiveCategories": {
"language": "语言",
"sexualContent": "色情内容",
"violence": "暴力",
"profanity": "亵渎",
"hateSpeech": "仇恨言论",
"racism": "种族主义",
"adultContent": "成人内容",
"drugAbuse": "药物滥用",
"alcoholAbuse": "酗酒",
"gambling": "赌博",
"selfHarm": "自残",
"childAbuse": "虐待儿童",
"other": "其他"
},
"poll": "投票",
"pollsRecent": "最近投票",
"pollCreateNew": "创建新投票",
"pollCreateNewHint": "为你的帖子创建一个新投票。选择一个发布者然后继续。",
"publisher": "发布者",
"publisherHint": "输入发布者名称",
"publisherCannotBeEmpty": "发布者不能为空",
"operationFailed": "操作失败:{}",
"stickerMarketplace": "贴纸市场",
"stickerPackAdded": "贴纸包已添加到你的收藏",
"stickerPackRemoved": "贴纸包已从你的收藏中移除",
"addPack": "添加贴纸包",
"removePack": "移除贴纸包",
"browseAndAddStickers": "浏览并添加贴纸包",
"stickerPack": "贴纸包",
"postCategoryTechnology": "科技",
"postCategoryTravel": "旅行",
"postCategoryFood": "美食",
"postCategoryHealth": "健康",
"postCategoryScience": "科学",
"postCategorySports": "体育",
"postCategoryFinance": "金融",
"postCategoryLife": "生活",
"postCategoryArt": "艺术",
"postCategoryStudy": "学习",
"postCategoryGaming": "游戏",
"postCategoryProgramming": "编程",
"postCategoryMusic": "音乐",
"links": "链接",
"addLink": "添加链接",
"linkKey": "链接名称",
"linkValue": "链接",
"debugOptions": "调试选项",
"joinedAt": "加入于 {}",
"searchAccounts": "搜索帐号……",
"webFeeds": "订阅源",
"polls": "投票",
"sharePostSlogan": "加入 Solar Network 以便探索更多",
"filesListAdditional": {
"one": "+{} 个文件被折叠",
"other": "+{} 个文件被折叠"
},
"messageJumpNotLoaded": "引用的消息没有被加载,无法跳转。",
"postUnlinkRealm": "不关联领域",
"postSlug": "别名",
"postSlugHint": "这个别名可以用于在网页通过 URL 浏览到你的帖子,它应该在同一发布者中是唯一。",
"attachmentOnDevice": "离线",
"attachmentOnCloud": "在线",
"publisherCollabInvitation": "协作邀请",
"publisherCollabInvitationCount": {
"zero": "无邀请",
"one": "{} 个可用邀请",
"other": "{} 个可用邀请"
},
"failedToLoadUserInfo": "加载用户信息失败",
"failedToLoadUserInfoNetwork": "这看起来是个网络问题,你可以按下面的按钮来重试",
"failedToLoadUserInfoUnauthorized": "看来您的会话已被注销或不再可用,如果您愿意,您仍然可以再次尝试获取用户信息。",
"okay": "了解",
"postDetail": "帖子详情",
"mimeType": "类型",
"fileSize": "大小",
"fileHash": "哈希",
"exifData": "EXIF 数据",
"leveling": "等级",
"levelingHistory": "经验记录",
"stellarProgram": "恒星计划",
"socialCredits": "社会信用点",
"credits": "信用",
"socialCreditsDescription": "社会信用是 Solar Network 评价用户的一种方式。它基于用户的行为和互动来计算。以 100 分为基准,分数越高表示用户在社区中的信誉越好。分数会随着时间的推移而变化,反映用户的最新行为。信用等级高的用户可以享受到更多的福利,反之的用户部份功能可能受到限制。",
"socialCreditsLevelPoor": "糟糕",
"socialCreditsLevelNormal": "正常",
"socialCreditsLevelGood": "良好",
"socialCreditsLevelExcellent": "优秀",
"appDetails": "应用详情",
"secrets": "密钥",
"appNotFound": "应用未找到。",
"secretCopied": "密钥已复制到剪贴板。",
"deleteSecret": "删除密钥",
"deleteSecretHint": "您确定要删除此密钥吗?此操作无法撤销。",
"generateSecret": "生成新密钥",
"createdAt": "创建于 {}",
"newSecretGenerated": "已生成新密钥",
"copySecretHint": "请复制此密钥并将其存放在安全的地方。您将无法再次看到它。",
"expiresIn": "过期时间(秒)",
"isOidc": "OIDC 兼容",
"statusPresent": "至今",
"accountAutomated": "机器人"
}

File diff suppressed because it is too large Load Diff

BIN
assets/icons/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 KiB

View File

@@ -1 +1 @@
{"flutter":{"platforms":{"android":{"default":{"projectId":"solian-0x001","appId":"1:961776991058:android:a8d3f7995b0b8e86f4188b","fileOutput":"android/app/google-services.json"}},"ios":{"default":{"projectId":"solian-0x001","appId":"1:961776991058:ios:727229d368cc47e1f4188b","uploadDebugSymbols":false,"fileOutput":"ios/Runner/GoogleService-Info.plist"}},"macos":{"default":{"projectId":"solian-0x001","appId":"1:961776991058:ios:727229d368cc47e1f4188b","uploadDebugSymbols":false,"fileOutput":"macos/Runner/GoogleService-Info.plist"}},"dart":{"lib/firebase_options.dart":{"projectId":"solian-0x001","configurations":{"android":"1:961776991058:android:a8d3f7995b0b8e86f4188b","ios":"1:961776991058:ios:727229d368cc47e1f4188b","macos":"1:961776991058:ios:727229d368cc47e1f4188b","web":"1:961776991058:web:b91d12f2892a5609f4188b","windows":"1:961776991058:web:3a912c0eb14028e5f4188b"}}}}}}
{"flutter":{"platforms":{"android":{"default":{"projectId":"solian-0x001","appId":"1:961776991058:android:a8d3f7995b0b8e86f4188b","fileOutput":"android/app/google-services.json"}},"ios":{"default":{"projectId":"solian-0x001","appId":"1:961776991058:ios:727229d368cc47e1f4188b","uploadDebugSymbols":false,"fileOutput":"ios/Runner/GoogleService-Info.plist"}},"macos":{"default":{"projectId":"solian-0x001","appId":"1:961776991058:ios:727229d368cc47e1f4188b","uploadDebugSymbols":false,"fileOutput":"macos/Runner/GoogleService-Info.plist"}},"dart":{"lib/firebase_options.dart":{"projectId":"solian-0x001","configurations":{"android":"1:961776991058:android:a8d3f7995b0b8e86f4188b","ios":"1:961776991058:ios:727229d368cc47e1f4188b","macos":"1:961776991058:ios:727229d368cc47e1f4188b","web":"1:961776991058:web:3a912c0eb14028e5f4188b","windows":"1:961776991058:web:3a912c0eb14028e5f4188b"}}}}}}

View File

@@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
platform :ios, '13.0'
platform :ios, '15.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

View File

@@ -40,39 +40,93 @@ PODS:
- file_picker (0.0.1):
- DKImagePickerController/PhotoGallery
- Flutter
- Firebase/CoreOnly (11.15.0):
- FirebaseCore (~> 11.15.0)
- Firebase/Messaging (11.15.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 11.15.0)
- firebase_core (3.15.1):
- Firebase/CoreOnly (= 11.15.0)
- file_saver (0.0.1):
- Flutter
- firebase_messaging (15.2.9):
- Firebase/Messaging (= 11.15.0)
- Firebase/CoreOnly (12.0.0):
- FirebaseCore (~> 12.0.0)
- Firebase/Crashlytics (12.0.0):
- Firebase/CoreOnly
- FirebaseCrashlytics (~> 12.0.0)
- Firebase/Messaging (12.0.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 12.0.0)
- firebase_analytics (12.0.0):
- firebase_core
- FirebaseAnalytics (= 12.0.0)
- Flutter
- firebase_core (4.0.0):
- Firebase/CoreOnly (= 12.0.0)
- Flutter
- firebase_crashlytics (5.0.0):
- Firebase/Crashlytics (= 12.0.0)
- firebase_core
- Flutter
- FirebaseCore (11.15.0):
- FirebaseCoreInternal (~> 11.15.0)
- firebase_messaging (16.0.0):
- Firebase/Messaging (= 12.0.0)
- firebase_core
- Flutter
- FirebaseAnalytics (12.0.0):
- FirebaseAnalytics/Default (= 12.0.0)
- FirebaseCore (~> 12.0.0)
- FirebaseInstallations (~> 12.0.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.0.0):
- FirebaseCore (~> 12.0.0)
- FirebaseInstallations (~> 12.0.0)
- GoogleAppMeasurement/Default (= 12.0.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- FirebaseCore (12.0.0):
- FirebaseCoreInternal (~> 12.0.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/Logger (~> 8.1)
- FirebaseCoreInternal (11.15.0):
- FirebaseCoreExtension (12.0.0):
- FirebaseCore (~> 12.0.0)
- FirebaseCoreInternal (12.0.0):
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- FirebaseInstallations (11.15.0):
- FirebaseCore (~> 11.15.0)
- FirebaseCrashlytics (12.0.0):
- FirebaseCore (~> 12.0.0)
- FirebaseInstallations (~> 12.0.0)
- FirebaseRemoteConfigInterop (~> 12.0.0)
- FirebaseSessions (~> 12.0.0)
- GoogleDataTransport (~> 10.1)
- GoogleUtilities/Environment (~> 8.1)
- nanopb (~> 3.30910.0)
- PromisesObjC (~> 2.4)
- FirebaseInstallations (12.0.0):
- FirebaseCore (~> 12.0.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
- PromisesObjC (~> 2.4)
- FirebaseMessaging (11.15.0):
- FirebaseCore (~> 11.15.0)
- FirebaseInstallations (~> 11.0)
- GoogleDataTransport (~> 10.0)
- FirebaseMessaging (12.0.0):
- FirebaseCore (~> 12.0.0)
- FirebaseInstallations (~> 12.0.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.0.0)
- FirebaseSessions (12.0.0):
- FirebaseCore (~> 12.0.0)
- FirebaseCoreExtension (~> 12.0.0)
- FirebaseInstallations (~> 12.0.0)
- GoogleDataTransport (~> 10.1)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
- nanopb (~> 3.30910.0)
- PromisesSwift (~> 2.1)
- Flutter (1.0.0)
- flutter_app_update (0.0.1):
- Flutter
- flutter_inappwebview_ios (0.0.1):
- Flutter
- flutter_inappwebview_ios/Core (= 0.0.1)
@@ -93,12 +147,38 @@ PODS:
- flutter_udid (0.0.1):
- Flutter
- SAMKeychain
- flutter_webrtc (0.14.0):
- flutter_webrtc (1.0.0):
- Flutter
- WebRTC-SDK (= 125.6422.07)
- WebRTC-SDK (= 137.7151.02)
- gal (1.0.0):
- Flutter
- FlutterMacOS
- GoogleAdsOnDeviceConversion (2.1.0):
- GoogleUtilities/Logger (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- nanopb (~> 3.30910.0)
- GoogleAppMeasurement/Core (12.0.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.0.0):
- GoogleAdsOnDeviceConversion (= 2.1.0)
- GoogleAppMeasurement/Core (= 12.0.0)
- GoogleAppMeasurement/IdentitySupport (= 12.0.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.0.0):
- GoogleAppMeasurement/Core (= 12.0.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- GoogleDataTransport (10.1.0):
- nanopb (~> 3.30910.0)
- PromisesObjC (~> 2.4)
@@ -112,6 +192,9 @@ PODS:
- GoogleUtilities/Logger (8.1.0):
- GoogleUtilities/Environment
- GoogleUtilities/Privacy
- GoogleUtilities/MethodSwizzler (8.1.0):
- GoogleUtilities/Logger
- GoogleUtilities/Privacy
- GoogleUtilities/Network (8.1.0):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
@@ -130,11 +213,11 @@ PODS:
- Flutter
- irondash_engine_context (0.0.1):
- Flutter
- Kingfisher (8.4.0)
- livekit_client (2.4.9):
- Kingfisher (8.5.0)
- livekit_client (2.5.0):
- Flutter
- flutter_webrtc
- WebRTC-SDK (= 125.6422.07)
- WebRTC-SDK (= 137.7151.02)
- local_auth_darwin (0.0.1):
- Flutter
- FlutterMacOS
@@ -160,9 +243,11 @@ PODS:
- pointer_interceptor_ios (0.0.1):
- Flutter
- PromisesObjC (2.4.0)
- PromisesSwift (2.4.0):
- PromisesObjC (= 2.4.0)
- receive_sharing_intent (1.8.1):
- Flutter
- record_ios (1.0.0):
- record_ios (1.1.0):
- Flutter
- SAMKeychain (1.5.3)
- SDWebImage (5.21.1):
@@ -178,28 +263,31 @@ PODS:
- sqflite_darwin (0.0.4):
- Flutter
- FlutterMacOS
- sqlite3 (3.50.2):
- sqlite3/common (= 3.50.2)
- sqlite3/common (3.50.2)
- sqlite3/dbstatvtab (3.50.2):
- sqlite3 (3.50.4):
- sqlite3/common (= 3.50.4)
- sqlite3/common (3.50.4)
- sqlite3/dbstatvtab (3.50.4):
- sqlite3/common
- sqlite3/fts5 (3.50.2):
- sqlite3/fts5 (3.50.4):
- sqlite3/common
- sqlite3/math (3.50.2):
- sqlite3/math (3.50.4):
- sqlite3/common
- sqlite3/perf-threadsafe (3.50.2):
- sqlite3/perf-threadsafe (3.50.4):
- sqlite3/common
- sqlite3/rtree (3.50.2):
- sqlite3/rtree (3.50.4):
- sqlite3/common
- sqlite3/session (3.50.4):
- sqlite3/common
- sqlite3_flutter_libs (0.0.1):
- Flutter
- FlutterMacOS
- sqlite3 (~> 3.50.1)
- sqlite3 (~> 3.50.4)
- sqlite3/dbstatvtab
- sqlite3/fts5
- sqlite3/math
- sqlite3/perf-threadsafe
- sqlite3/rtree
- sqlite3/session
- super_native_extensions (0.0.1):
- Flutter
- SwiftyGif (5.4.5)
@@ -209,7 +297,7 @@ PODS:
- Flutter
- wakelock_plus (0.0.1):
- Flutter
- WebRTC-SDK (125.6422.07)
- WebRTC-SDK (137.7151.02)
DEPENDENCIES:
- Alamofire
@@ -217,9 +305,13 @@ DEPENDENCIES:
- croppy (from `.symlinks/plugins/croppy/ios`)
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- file_picker (from `.symlinks/plugins/file_picker/ios`)
- file_saver (from `.symlinks/plugins/file_saver/ios`)
- firebase_analytics (from `.symlinks/plugins/firebase_analytics/ios`)
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
- firebase_crashlytics (from `.symlinks/plugins/firebase_crashlytics/ios`)
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
- Flutter (from `Flutter`)
- flutter_app_update (from `.symlinks/plugins/flutter_app_update/ios`)
- flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`)
- flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`)
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
@@ -259,16 +351,24 @@ SPEC REPOS:
- DKImagePickerController
- DKPhotoGallery
- Firebase
- FirebaseAnalytics
- FirebaseCore
- FirebaseCoreExtension
- FirebaseCoreInternal
- FirebaseCrashlytics
- FirebaseInstallations
- FirebaseMessaging
- FirebaseRemoteConfigInterop
- FirebaseSessions
- GoogleAdsOnDeviceConversion
- GoogleAppMeasurement
- GoogleDataTransport
- GoogleUtilities
- Kingfisher
- nanopb
- OrderedSet
- PromisesObjC
- PromisesSwift
- SAMKeychain
- SDWebImage
- sqlite3
@@ -284,12 +384,20 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/device_info_plus/ios"
file_picker:
:path: ".symlinks/plugins/file_picker/ios"
file_saver:
:path: ".symlinks/plugins/file_saver/ios"
firebase_analytics:
:path: ".symlinks/plugins/firebase_analytics/ios"
firebase_core:
:path: ".symlinks/plugins/firebase_core/ios"
firebase_crashlytics:
:path: ".symlinks/plugins/firebase_crashlytics/ios"
firebase_messaging:
:path: ".symlinks/plugins/firebase_messaging/ios"
Flutter:
:path: Flutter
flutter_app_update:
:path: ".symlinks/plugins/flutter_app_update/ios"
flutter_inappwebview_ios:
:path: ".symlinks/plugins/flutter_inappwebview_ios/ios"
flutter_keyboard_visibility:
@@ -361,14 +469,23 @@ SPEC CHECKSUMS:
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be
Firebase: d99ac19b909cd2c548339c2241ecd0d1599ab02e
firebase_core: ece862f94b2bc72ee0edbeec7ab5c7cb09fe1ab5
firebase_messaging: e1a5fae495603115be1d0183bc849da748734e2b
FirebaseCore: efb3893e5b94f32b86e331e3bd6dadf18b66568e
FirebaseCoreInternal: 9afa45b1159304c963da48addb78275ef701c6b4
FirebaseInstallations: 317270fec08a5d418fdbc8429282238cab3ac843
FirebaseMessaging: 3b26e2cee503815e01c3701236b020aa9b576f09
file_saver: 6cdbcddd690cb02b0c1a0c225b37cd805c2bf8b6
Firebase: 800d487043c0557d9faed71477a38d9aafb08a41
firebase_analytics: cd56fc56f75c1df30a6ff5290cd56e230996a76d
firebase_core: 633e1851ffe1b9ab875f6467a4f574c79cef02e4
firebase_crashlytics: 2c6c1a17900a38081d938330e9f48e60ec5b255d
firebase_messaging: d17feef781edc84ebefe62624fb384358ad96361
FirebaseAnalytics: 6d790cd1b159b4eb61a99948df0934ce505a34f7
FirebaseCore: 055f4ab117d5964158c833f3d5e7ec6d91648d4a
FirebaseCoreExtension: 639afb3de6abd611952be78a794c54a47fa0f361
FirebaseCoreInternal: dedc28e569a4be85f38f3d6af1070a2e12018d55
FirebaseCrashlytics: db75aa0cab8d00f68406fa247c32fe17ade884d7
FirebaseInstallations: d4c7c958f99c8860d7fcece786314ae790e2f988
FirebaseMessaging: af49f8d7c0a3d2a017d9302c80946f45a7777dde
FirebaseRemoteConfigInterop: bfa0ea72ba3dc5af739777296424e46bd6f42613
FirebaseSessions: 4e784acda213108aafef536535cdfc03504acc42
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_app_update: 816fdb2e30e4832a7c45e3f108d391c42ef040a9
flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
flutter_keyboard_visibility: 4625131e43015dbbe759d9b20daaf77e0e3f6619
flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf
@@ -376,14 +493,16 @@ SPEC CHECKSUMS:
flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13
flutter_timezone: 7c838e17ffd4645d261e87037e5bebf6d38fe544
flutter_udid: f7c3884e6ec2951efe4f9de082257fc77c4d15e9
flutter_webrtc: fd0d3bdef8766a0736dbbe2e5b7e85f1f3c52117
flutter_webrtc: 6f7da106613d52ade777d5b4875a43f48c28b457
gal: baecd024ebfd13c441269ca7404792a7152fde89
GoogleAdsOnDeviceConversion: 2be6297a4f048459e0ae17fad9bfd2844e10cf64
GoogleAppMeasurement: 8f6ab04ad6ae493b53fcf56bd26323fb2f1384f3
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
irondash_engine_context: 8e58ca8e0212ee9d1c7dc6a42121849986c88486
Kingfisher: b14cc47bbfa7a3c150dd12962ee9c86338545629
livekit_client: 3f79d79233a5bd13d5b541732624ef959d7c538e
Kingfisher: ff0d31a1f07bdff6a1ebb3ba08b8e6e567b6500c
livekit_client: e3b79b99405428aac439b6b76a254cd9a11dbbfb
local_auth_darwin: d2e8c53ef0c4f43c646462e3415432c4dab3ae19
media_kit_libs_ios_video: 5a18affdb97d1f5d466dc79988b13eff6c5e2854
media_kit_video: 1746e198cb697d1ffb734b1d05ec429d1fcd1474
@@ -395,23 +514,24 @@ SPEC CHECKSUMS:
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
pointer_interceptor_ios: ec847ef8b0915778bed2b2cef636f4d177fa8eed
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851
receive_sharing_intent: 222384f00ffe7e952bbfabaa9e3967cb87e5fe00
record_ios: fee1c924aa4879b882ebca2b4bce6011bcfc3d8b
record_ios: f75fa1d57f840012775c0e93a38a7f3ceea1a374
SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c
SDWebImage: f29024626962457f3470184232766516dee8dfea
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
sign_in_with_apple: c5dcc141574c8c54d5ac99dd2163c0c72ad22418
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
sqlite3: 3e82a2daae39ba3b41ae6ee84a130494585460fc
sqlite3_flutter_libs: e7fc8c9ea2200ff3271f08f127842131746b70e2
sqlite3: 73513155ec6979715d3904ef53a8d68892d4032b
sqlite3_flutter_libs: 83f8e9f5b6554077f1d93119fe20ebaa5f3a9ef1
super_native_extensions: b763c02dc3a8fd078389f410bf15149179020cb4
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
volume_controller: 3657a1f65bedb98fa41ff7dc5793537919f31b12
wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556
WebRTC-SDK: dff00a3892bc570b6014e046297782084071657e
WebRTC-SDK: d20de357dcbf7c9696b124b39f3ff62125107e4b
PODFILE CHECKSUM: f6df17c2a0cbd7af89692fd3877231eaea40230f
PODFILE CHECKSUM: c818292390b02fa379036ea099713a332bd7193f
COCOAPODS: 1.16.2

View File

@@ -10,6 +10,8 @@
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
73ACDFAD2E3D0E6100B63535 /* ReplayKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73ACDFAC2E3D0E6100B63535 /* ReplayKit.framework */; };
73ACDFC32E3D0E6100B63535 /* SolianBroadcastExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 73ACDFAB2E3D0E6100B63535 /* SolianBroadcastExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
73C305D82E0BE878009035B9 /* SolianShareExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 73C305CE2E0BE878009035B9 /* SolianShareExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
73CDD6812DEC00480059D95D /* SolianNotificationService.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 73CDD67A2DEC00480059D95D /* SolianNotificationService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
73D4264B2DEB815D006C0AAE /* NotifyDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73D4264A2DEB815D006C0AAE /* NotifyDelegate.swift */; };
@@ -32,6 +34,13 @@
remoteGlobalIDString = 97C146ED1CF9000F007C117D;
remoteInfo = Runner;
};
73ACDFC12E3D0E6100B63535 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 97C146E61CF9000F007C117D /* Project object */;
proxyType = 1;
remoteGlobalIDString = 73ACDFAA2E3D0E6100B63535;
remoteInfo = SolianBroadcastExtension;
};
73C305D62E0BE878009035B9 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 97C146E61CF9000F007C117D /* Project object */;
@@ -55,6 +64,7 @@
dstPath = "";
dstSubfolderSpec = 13;
files = (
73ACDFC32E3D0E6100B63535 /* SolianBroadcastExtension.appex in Embed Foundation Extensions */,
73C305D82E0BE878009035B9 /* SolianShareExtension.appex in Embed Foundation Extensions */,
73CDD6812DEC00480059D95D /* SolianNotificationService.appex in Embed Foundation Extensions */,
);
@@ -91,6 +101,9 @@
3A1C47BD29CC6AC2587D4DBE /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
737E920B2DB6A9FF00BE9CDB /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
73ACDFAB2E3D0E6100B63535 /* SolianBroadcastExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = SolianBroadcastExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
73ACDFAC2E3D0E6100B63535 /* ReplayKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ReplayKit.framework; path = System/Library/Frameworks/ReplayKit.framework; sourceTree = SDKROOT; };
73ACDFB82E3D0E6100B63535 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
73C305CE2E0BE878009035B9 /* SolianShareExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = SolianShareExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
73CDD67A2DEC00480059D95D /* SolianNotificationService.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = SolianNotificationService.appex; sourceTree = BUILT_PRODUCTS_DIR; };
73D4264A2DEB815D006C0AAE /* NotifyDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotifyDelegate.swift; sourceTree = "<group>"; };
@@ -117,6 +130,13 @@
/* End PBXFileReference section */
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
73ACDFCA2E3D0E6100B63535 /* Exceptions for "SolianBroadcastExtension" folder in "SolianBroadcastExtension" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = (
Info.plist,
);
target = 73ACDFAA2E3D0E6100B63535 /* SolianBroadcastExtension */;
};
73C305DC2E0BE878009035B9 /* Exceptions for "SolianShareExtension" folder in "SolianShareExtension" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = (
@@ -150,6 +170,14 @@
path = Services;
sourceTree = "<group>";
};
73ACDFAE2E3D0E6100B63535 /* SolianBroadcastExtension */ = {
isa = PBXFileSystemSynchronizedRootGroup;
exceptions = (
73ACDFCA2E3D0E6100B63535 /* Exceptions for "SolianBroadcastExtension" folder in "SolianBroadcastExtension" target */,
);
path = SolianBroadcastExtension;
sourceTree = "<group>";
};
73C305CF2E0BE878009035B9 /* SolianShareExtension */ = {
isa = PBXFileSystemSynchronizedRootGroup;
exceptions = (
@@ -177,6 +205,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
73ACDFA82E3D0E6100B63535 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
73ACDFAD2E3D0E6100B63535 /* ReplayKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
73C305CB2E0BE878009035B9 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -220,6 +256,8 @@
AA0CA8A3E15DEE023BB27438 /* Pods_NotificationService.framework */,
39FE4CC6223F0D3C0E1FFD04 /* Pods_SolianNotificationService.framework */,
7B40764A2C4CC0E7DC70A0D3 /* Pods_SolianShareExtension.framework */,
73ACDFAC2E3D0E6100B63535 /* ReplayKit.framework */,
73ACDFB82E3D0E6100B63535 /* UIKit.framework */,
);
name = Frameworks;
sourceTree = "<group>";
@@ -264,6 +302,7 @@
97C146F01CF9000F007C117D /* Runner */,
73CDD67B2DEC00480059D95D /* SolianNotificationService */,
73C305CF2E0BE878009035B9 /* SolianShareExtension */,
73ACDFAE2E3D0E6100B63535 /* SolianBroadcastExtension */,
97C146EF1CF9000F007C117D /* Products */,
331C8082294A63A400263BE5 /* RunnerTests */,
91E124CE95BCB4DCD890160D /* Pods */,
@@ -279,6 +318,7 @@
331C8081294A63A400263BE5 /* RunnerTests.xctest */,
73CDD67A2DEC00480059D95D /* SolianNotificationService.appex */,
73C305CE2E0BE878009035B9 /* SolianShareExtension.appex */,
73ACDFAB2E3D0E6100B63535 /* SolianBroadcastExtension.appex */,
);
name = Products;
sourceTree = "<group>";
@@ -323,6 +363,26 @@
productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
73ACDFAA2E3D0E6100B63535 /* SolianBroadcastExtension */ = {
isa = PBXNativeTarget;
buildConfigurationList = 73ACDFCB2E3D0E6100B63535 /* Build configuration list for PBXNativeTarget "SolianBroadcastExtension" */;
buildPhases = (
73ACDFA72E3D0E6100B63535 /* Sources */,
73ACDFA82E3D0E6100B63535 /* Frameworks */,
73ACDFA92E3D0E6100B63535 /* Resources */,
);
buildRules = (
);
dependencies = (
);
fileSystemSynchronizedGroups = (
73ACDFAE2E3D0E6100B63535 /* SolianBroadcastExtension */,
);
name = SolianBroadcastExtension;
productName = SolianBroadcastExtension;
productReference = 73ACDFAB2E3D0E6100B63535 /* SolianBroadcastExtension.appex */;
productType = "com.apple.product-type.app-extension";
};
73C305CD2E0BE878009035B9 /* SolianShareExtension */ = {
isa = PBXNativeTarget;
buildConfigurationList = 73C305DD2E0BE878009035B9 /* Build configuration list for PBXNativeTarget "SolianShareExtension" */;
@@ -379,12 +439,14 @@
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
8C0351B03869BBF493808288 /* [CP] Embed Pods Frameworks */,
5E7D6EF29B671AC7EDBA5649 /* [CP] Copy Pods Resources */,
E86CDE9D6464F4F52B910856 /* FlutterFire: "flutterfire upload-crashlytics-symbols" */,
);
buildRules = (
);
dependencies = (
73CDD6802DEC00480059D95D /* PBXTargetDependency */,
73C305D72E0BE878009035B9 /* PBXTargetDependency */,
73ACDFC22E3D0E6100B63535 /* PBXTargetDependency */,
);
fileSystemSynchronizedGroups = (
73268D272DEB012A0076E970 /* Services */,
@@ -409,6 +471,9 @@
CreatedOnToolsVersion = 14.0;
TestTargetID = 97C146ED1CF9000F007C117D;
};
73ACDFAA2E3D0E6100B63535 = {
CreatedOnToolsVersion = 16.4;
};
73C305CD2E0BE878009035B9 = {
CreatedOnToolsVersion = 16.4;
};
@@ -438,6 +503,7 @@
331C8080294A63A400263BE5 /* RunnerTests */,
73CDD6792DEC00480059D95D /* SolianNotificationService */,
73C305CD2E0BE878009035B9 /* SolianShareExtension */,
73ACDFAA2E3D0E6100B63535 /* SolianBroadcastExtension */,
);
};
/* End PBXProject section */
@@ -450,6 +516,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
73ACDFA92E3D0E6100B63535 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
73C305CC2E0BE878009035B9 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@@ -610,6 +683,24 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
E86CDE9D6464F4F52B910856 /* FlutterFire: "flutterfire upload-crashlytics-symbols" */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = "FlutterFire: \"flutterfire upload-crashlytics-symbols\"";
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\n#!/bin/bash\nPATH=\"${PATH}:$FLUTTER_ROOT/bin:${PUB_CACHE}/bin:$HOME/.pub-cache/bin\"\n\nif [ -z \"$PODS_ROOT\" ] || [ ! -d \"$PODS_ROOT/FirebaseCrashlytics\" ]; then\n # Cannot use \"BUILD_DIR%/Build/*\" as per Firebase documentation, it points to \"flutter-project/build/ios/*\" path which doesn't have run script\n DERIVED_DATA_PATH=$(echo \"$BUILD_ROOT\" | sed -E 's|(.*DerivedData/[^/]+).*|\\1|')\n PATH_TO_CRASHLYTICS_UPLOAD_SCRIPT=\"${DERIVED_DATA_PATH}/SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/run\"\nelse\n PATH_TO_CRASHLYTICS_UPLOAD_SCRIPT=\"$PODS_ROOT/FirebaseCrashlytics/run\"\nfi\n\n# Command to upload symbols script used to upload symbols to Firebase server\nflutterfire upload-crashlytics-symbols --upload-symbols-script-path=\"$PATH_TO_CRASHLYTICS_UPLOAD_SCRIPT\" --platform=ios --apple-project-path=\"${SRCROOT}\" --env-platform-name=\"${PLATFORM_NAME}\" --env-configuration=\"${CONFIGURATION}\" --env-project-dir=\"${PROJECT_DIR}\" --env-built-products-dir=\"${BUILT_PRODUCTS_DIR}\" --env-dwarf-dsym-folder-path=\"${DWARF_DSYM_FOLDER_PATH}\" --env-dwarf-dsym-file-name=\"${DWARF_DSYM_FILE_NAME}\" --env-infoplist-path=\"${INFOPLIST_PATH}\" --default-config=default\n";
};
E947029FCA058878F9B63890 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -643,6 +734,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
73ACDFA72E3D0E6100B63535 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
73C305CA2E0BE878009035B9 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -675,6 +773,11 @@
target = 97C146ED1CF9000F007C117D /* Runner */;
targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */;
};
73ACDFC22E3D0E6100B63535 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 73ACDFAA2E3D0E6100B63535 /* SolianBroadcastExtension */;
targetProxy = 73ACDFC12E3D0E6100B63535 /* PBXContainerItemProxy */;
};
73C305D72E0BE878009035B9 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 73C305CD2E0BE878009035B9 /* SolianShareExtension */;
@@ -773,7 +876,7 @@
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Solian;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -836,6 +939,123 @@
};
name = Profile;
};
73ACDFC42E3D0E6100B63535 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = SolianBroadcastExtension/SolianBroadcastExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = W7HPZ53V6B;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = SolianBroadcastExtension/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = SolianBroadcastExtension;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MARKETING_VERSION = 1.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = dev.solsynth.solian.SolianBroadcastExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
73ACDFC52E3D0E6100B63535 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = SolianBroadcastExtension/SolianBroadcastExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = W7HPZ53V6B;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = SolianBroadcastExtension/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = SolianBroadcastExtension;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MARKETING_VERSION = 1.0;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = dev.solsynth.solian.SolianBroadcastExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
73ACDFC62E3D0E6100B63535 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = SolianBroadcastExtension/SolianBroadcastExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = W7HPZ53V6B;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = SolianBroadcastExtension/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = SolianBroadcastExtension;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MARKETING_VERSION = 1.0;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = dev.solsynth.solian.SolianBroadcastExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Profile;
};
73C305D92E0BE878009035B9 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 17FAB080A9C53193ABD9C15B /* Pods-SolianShareExtension.debug.xcconfig */;
@@ -1204,7 +1424,7 @@
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Solian;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -1232,7 +1452,7 @@
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Solian;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -1258,6 +1478,16 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
73ACDFCB2E3D0E6100B63535 /* Build configuration list for PBXNativeTarget "SolianBroadcastExtension" */ = {
isa = XCConfigurationList;
buildConfigurations = (
73ACDFC42E3D0E6100B63535 /* Debug */,
73ACDFC52E3D0E6100B63535 /* Release */,
73ACDFC62E3D0E6100B63535 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
73C305DD2E0BE878009035B9 /* Build configuration list for PBXNativeTarget "SolianShareExtension" */ = {
isa = XCConfigurationList;
buildConfigurations = (

View File

@@ -2,6 +2,12 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CLIENT_ID</key>
<string>961776991058-stt7et4qvn3cpscl4r61gl1hnlatqkig.apps.googleusercontent.com</string>
<key>REVERSED_CLIENT_ID</key>
<string>com.googleusercontent.apps.961776991058-stt7et4qvn3cpscl4r61gl1hnlatqkig</string>
<key>ANDROID_CLIENT_ID</key>
<string>961776991058-r4iv9qoio57ul7utbfpgfrda2etvtch8.apps.googleusercontent.com</string>
<key>API_KEY</key>
<string>AIzaSyCzQIyiYKoYHTpGXhN-IjgMML8z797WVD8</string>
<key>GCM_SENDER_ID</key>

View File

@@ -34,7 +34,7 @@ class NotifyDelegate: UIResponder, UNUserNotificationCenterDelegate {
}
let serverUrl = UserDefaults.standard.getServerUrl()
let url = "\(serverUrl)/chat/\(metadata["room_id"] ?? "")/messages"
let url = "\(serverUrl)/sphere/chat/\(metadata["room_id"] ?? "")/messages"
let parameters: [String: Any?] = [
"content": textResponse.userText,

View File

@@ -8,7 +8,7 @@
import Foundation
func getAttachmentUrl(for identifier: String) -> String {
let serverBaseUrl = "https://nt.solian.app"
let serverBaseUrl = "https://api.solian.app"
return identifier.starts(with: "http") ? identifier : "\(serverBaseUrl)/files/\(identifier)"
return identifier.starts(with: "http") ? identifier : "\(serverBaseUrl)/drive/files/\(identifier)"
}

View File

@@ -0,0 +1,37 @@
//
// Atomic.swift
// Broadcast Extension
//
// Created by Maksym Shcheglov.
// https://www.onswiftwings.com/posts/atomic-property-wrapper/
//
import Foundation
@propertyWrapper
struct Atomic<Value> {
private var value: Value
private let lock = NSLock()
init(wrappedValue value: Value) {
self.value = value
}
var wrappedValue: Value {
get { load() }
set { store(newValue: newValue) }
}
func load() -> Value {
lock.lock()
defer { lock.unlock() }
return value
}
mutating func store(newValue: Value) {
lock.lock()
defer { lock.unlock() }
value = newValue
}
}

View File

@@ -0,0 +1,29 @@
//
// DarwinNotificationCenter.swift
// Broadcast Extension
//
// Created by Alex-Dan Bumbu on 23/03/2021.
// Copyright © 2021 8x8, Inc. All rights reserved.
//
import Foundation
enum DarwinNotification: String {
case broadcastStarted = "iOS_BroadcastStarted"
case broadcastStopped = "iOS_BroadcastStopped"
}
class DarwinNotificationCenter {
static let shared = DarwinNotificationCenter()
private let notificationCenter: CFNotificationCenter
init() {
notificationCenter = CFNotificationCenterGetDarwinNotifyCenter()
}
func postNotification(_ name: DarwinNotification) {
CFNotificationCenterPostNotification(notificationCenter, CFNotificationName(rawValue: name.rawValue as CFString), nil, nil, true)
}
}

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.broadcast-services-upload</string>
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).SampleHandler</string>
<key>RPBroadcastProcessMode</key>
<string>RPBroadcastProcessModeSampleBuffer</string>
</dict>
</dict>
</plist>

View File

@@ -0,0 +1,103 @@
//
// SampleHandler.swift
// Broadcast Extension
//
// Created by Alex-Dan Bumbu on 04.06.2021.
//
import ReplayKit
import OSLog
let broadcastLogger = OSLog(subsystem: "dev.solsynth.solian", category: "Broadcast")
private enum Constants {
// the App Group ID value that the app and the broadcast extension targets are setup with. It differs for each app.
static let appGroupIdentifier = "group.solsynth.solian"
}
class SampleHandler: RPBroadcastSampleHandler {
private var clientConnection: SocketConnection?
private var uploader: SampleUploader?
private var frameCount: Int = 0
var socketFilePath: String {
let sharedContainer = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: Constants.appGroupIdentifier)
return sharedContainer?.appendingPathComponent("rtc_SSFD").path ?? ""
}
override init() {
super.init()
if let connection = SocketConnection(filePath: socketFilePath) {
clientConnection = connection
setupConnection()
uploader = SampleUploader(connection: connection)
}
os_log(.debug, log: broadcastLogger, "%{public}s", socketFilePath)
}
override func broadcastStarted(withSetupInfo setupInfo: [String: NSObject]?) {
// User has requested to start the broadcast. Setup info from the UI extension can be supplied but optional.
frameCount = 0
DarwinNotificationCenter.shared.postNotification(.broadcastStarted)
openConnection()
}
override func broadcastPaused() {
// User has requested to pause the broadcast. Samples will stop being delivered.
}
override func broadcastResumed() {
// User has requested to resume the broadcast. Samples delivery will resume.
}
override func broadcastFinished() {
// User has requested to finish the broadcast.
DarwinNotificationCenter.shared.postNotification(.broadcastStopped)
clientConnection?.close()
}
override func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) {
switch sampleBufferType {
case RPSampleBufferType.video:
uploader?.send(sample: sampleBuffer)
default:
break
}
}
}
private extension SampleHandler {
func setupConnection() {
clientConnection?.didClose = { [weak self] error in
os_log(.debug, log: broadcastLogger, "client connection did close \(String(describing: error))")
if let error = error {
self?.finishBroadcastWithError(error)
} else {
// the displayed failure message is more user friendly when using NSError instead of Error
let JMScreenSharingStopped = 10001
let customError = NSError(domain: RPRecordingErrorDomain, code: JMScreenSharingStopped, userInfo: [NSLocalizedDescriptionKey: "Screen sharing stopped"])
self?.finishBroadcastWithError(customError)
}
}
}
func openConnection() {
let queue = DispatchQueue(label: "broadcast.connectTimer")
let timer = DispatchSource.makeTimerSource(queue: queue)
timer.schedule(deadline: .now(), repeating: .milliseconds(100), leeway: .milliseconds(500))
timer.setEventHandler { [weak self] in
guard self?.clientConnection?.open() == true else {
return
}
timer.cancel()
}
timer.resume()
}
}

View File

@@ -0,0 +1,147 @@
//
// SampleUploader.swift
// Broadcast Extension
//
// Created by Alex-Dan Bumbu on 22/03/2021.
// Copyright © 2021 8x8, Inc. All rights reserved.
//
import Foundation
import ReplayKit
import OSLog
private enum Constants {
static let bufferMaxLength = 10240
}
class SampleUploader {
private static var imageContext = CIContext(options: nil)
@Atomic private var isReady = false
private var connection: SocketConnection
private var dataToSend: Data?
private var byteIndex = 0
private let serialQueue: DispatchQueue
init(connection: SocketConnection) {
self.connection = connection
self.serialQueue = DispatchQueue(label: "org.jitsi.meet.broadcast.sampleUploader")
setupConnection()
}
@discardableResult func send(sample buffer: CMSampleBuffer) -> Bool {
guard isReady else {
return false
}
isReady = false
dataToSend = prepare(sample: buffer)
byteIndex = 0
serialQueue.async { [weak self] in
self?.sendDataChunk()
}
return true
}
}
private extension SampleUploader {
func setupConnection() {
connection.didOpen = { [weak self] in
self?.isReady = true
}
connection.streamHasSpaceAvailable = { [weak self] in
self?.serialQueue.async {
if let success = self?.sendDataChunk() {
self?.isReady = !success
}
}
}
}
@discardableResult func sendDataChunk() -> Bool {
guard let dataToSend = dataToSend else {
return false
}
var bytesLeft = dataToSend.count - byteIndex
var length = bytesLeft > Constants.bufferMaxLength ? Constants.bufferMaxLength : bytesLeft
length = dataToSend[byteIndex..<(byteIndex + length)].withUnsafeBytes {
guard let ptr = $0.bindMemory(to: UInt8.self).baseAddress else {
return 0
}
return connection.writeToStream(buffer: ptr, maxLength: length)
}
if length > 0 {
byteIndex += length
bytesLeft -= length
if bytesLeft == 0 {
self.dataToSend = nil
byteIndex = 0
}
} else {
os_log(.debug, log: broadcastLogger, "writeBufferToStream failure")
}
return true
}
func prepare(sample buffer: CMSampleBuffer) -> Data? {
guard let imageBuffer = CMSampleBufferGetImageBuffer(buffer) else {
os_log(.debug, log: broadcastLogger, "image buffer not available")
return nil
}
CVPixelBufferLockBaseAddress(imageBuffer, .readOnly)
let scaleFactor = 1.0
let width = CVPixelBufferGetWidth(imageBuffer)/Int(scaleFactor)
let height = CVPixelBufferGetHeight(imageBuffer)/Int(scaleFactor)
let orientation = CMGetAttachment(buffer, key: RPVideoSampleOrientationKey as CFString, attachmentModeOut: nil)?.uintValue ?? 0
let scaleTransform = CGAffineTransform(scaleX: CGFloat(1.0/scaleFactor), y: CGFloat(1.0/scaleFactor))
let bufferData = self.jpegData(from: imageBuffer, scale: scaleTransform)
CVPixelBufferUnlockBaseAddress(imageBuffer, .readOnly)
guard let messageData = bufferData else {
os_log(.debug, log: broadcastLogger, "corrupted image buffer")
return nil
}
let httpResponse = CFHTTPMessageCreateResponse(nil, 200, nil, kCFHTTPVersion1_1).takeRetainedValue()
CFHTTPMessageSetHeaderFieldValue(httpResponse, "Content-Length" as CFString, String(messageData.count) as CFString)
CFHTTPMessageSetHeaderFieldValue(httpResponse, "Buffer-Width" as CFString, String(width) as CFString)
CFHTTPMessageSetHeaderFieldValue(httpResponse, "Buffer-Height" as CFString, String(height) as CFString)
CFHTTPMessageSetHeaderFieldValue(httpResponse, "Buffer-Orientation" as CFString, String(orientation) as CFString)
CFHTTPMessageSetBody(httpResponse, messageData as CFData)
let serializedMessage = CFHTTPMessageCopySerializedMessage(httpResponse)?.takeRetainedValue() as Data?
return serializedMessage
}
func jpegData(from buffer: CVPixelBuffer, scale scaleTransform: CGAffineTransform) -> Data? {
let image = CIImage(cvPixelBuffer: buffer).transformed(by: scaleTransform)
guard let colorSpace = image.colorSpace else {
return nil
}
let options: [CIImageRepresentationOption: Float] = [kCGImageDestinationLossyCompressionQuality as CIImageRepresentationOption: 1.0]
return SampleUploader.imageContext.jpegRepresentation(of: image, colorSpace: colorSpace, options: options)
}
}

View File

@@ -0,0 +1,199 @@
//
// SocketConnection.swift
// Broadcast Extension
//
// Created by Alex-Dan Bumbu on 22/03/2021.
// Copyright © 2021 Atlassian Inc. All rights reserved.
//
import Foundation
import OSLog
class SocketConnection: NSObject {
var didOpen: (() -> Void)?
var didClose: ((Error?) -> Void)?
var streamHasSpaceAvailable: (() -> Void)?
private let filePath: String
private var socketHandle: Int32 = -1
private var address: sockaddr_un?
private var inputStream: InputStream?
private var outputStream: OutputStream?
private var networkQueue: DispatchQueue?
private var shouldKeepRunning = false
init?(filePath path: String) {
filePath = path
socketHandle = Darwin.socket(AF_UNIX, SOCK_STREAM, 0)
guard socketHandle != -1 else {
os_log(.debug, log: broadcastLogger, "failure: create socket")
return nil
}
}
func open() -> Bool {
os_log(.debug, log: broadcastLogger, "open socket connection")
guard FileManager.default.fileExists(atPath: filePath) else {
os_log(.debug, log: broadcastLogger, "failure: socket file missing")
return false
}
guard setupAddress() == true else {
return false
}
guard connectSocket() == true else {
return false
}
setupStreams()
inputStream?.open()
outputStream?.open()
return true
}
func close() {
unscheduleStreams()
inputStream?.delegate = nil
outputStream?.delegate = nil
inputStream?.close()
outputStream?.close()
inputStream = nil
outputStream = nil
}
func writeToStream(buffer: UnsafePointer<UInt8>, maxLength length: Int) -> Int {
outputStream?.write(buffer, maxLength: length) ?? 0
}
}
extension SocketConnection: StreamDelegate {
func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
switch eventCode {
case .openCompleted:
os_log(.debug, log: broadcastLogger, "client stream open completed")
if aStream == outputStream {
didOpen?()
}
case .hasBytesAvailable:
if aStream == inputStream {
var buffer: UInt8 = 0
let numberOfBytesRead = inputStream?.read(&buffer, maxLength: 1)
if numberOfBytesRead == 0 && aStream.streamStatus == .atEnd {
os_log(.debug, log: broadcastLogger, "server socket closed")
close()
notifyDidClose(error: nil)
}
}
case .hasSpaceAvailable:
if aStream == outputStream {
streamHasSpaceAvailable?()
}
case .errorOccurred:
os_log(.debug, log: broadcastLogger, "client stream error occured: \(String(describing: aStream.streamError))")
close()
notifyDidClose(error: aStream.streamError)
default:
break
}
}
}
private extension SocketConnection {
func setupAddress() -> Bool {
var addr = sockaddr_un()
guard filePath.count < MemoryLayout.size(ofValue: addr.sun_path) else {
os_log(.debug, log: broadcastLogger, "failure: fd path is too long")
return false
}
_ = withUnsafeMutablePointer(to: &addr.sun_path.0) { ptr in
filePath.withCString {
strncpy(ptr, $0, filePath.count)
}
}
address = addr
return true
}
func connectSocket() -> Bool {
guard var addr = address else {
return false
}
let status = withUnsafePointer(to: &addr) { ptr in
ptr.withMemoryRebound(to: sockaddr.self, capacity: 1) {
Darwin.connect(socketHandle, $0, socklen_t(MemoryLayout<sockaddr_un>.size))
}
}
guard status == noErr else {
os_log(.debug, log: broadcastLogger, "failure: \(status)")
return false
}
return true
}
func setupStreams() {
var readStream: Unmanaged<CFReadStream>?
var writeStream: Unmanaged<CFWriteStream>?
CFStreamCreatePairWithSocket(kCFAllocatorDefault, socketHandle, &readStream, &writeStream)
inputStream = readStream?.takeRetainedValue()
inputStream?.delegate = self
inputStream?.setProperty(kCFBooleanTrue, forKey: Stream.PropertyKey(kCFStreamPropertyShouldCloseNativeSocket as String))
outputStream = writeStream?.takeRetainedValue()
outputStream?.delegate = self
outputStream?.setProperty(kCFBooleanTrue, forKey: Stream.PropertyKey(kCFStreamPropertyShouldCloseNativeSocket as String))
scheduleStreams()
}
func scheduleStreams() {
shouldKeepRunning = true
networkQueue = DispatchQueue.global(qos: .userInitiated)
networkQueue?.async { [weak self] in
self?.inputStream?.schedule(in: .current, forMode: .common)
self?.outputStream?.schedule(in: .current, forMode: .common)
RunLoop.current.run()
var isRunning = false
repeat {
isRunning = self?.shouldKeepRunning ?? false && RunLoop.current.run(mode: .default, before: .distantFuture)
} while (isRunning)
}
}
func unscheduleStreams() {
networkQueue?.sync { [weak self] in
self?.inputStream?.remove(from: .current, forMode: .common)
self?.outputStream?.remove(from: .current, forMode: .common)
}
shouldKeepRunning = false
}
func notifyDidClose(error: Error?) {
if didClose != nil {
didClose?(error)
}
}
}

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.application-groups</key>
<array>
<string>group.solsynth.solian</string>
</array>
</dict>
</plist>

View File

@@ -49,8 +49,7 @@ class AppDatabase extends _$AppDatabase {
}
Future<int> updateMessage(ChatMessagesCompanion message) {
return (update(chatMessages)
..where((m) => m.id.equals(message.id.value))).write(message);
return into(chatMessages).insert(message, mode: InsertMode.insertOrReplace);
}
Future<int> updateMessageStatus(String id, MessageStatus status) {
@@ -69,6 +68,34 @@ class AppDatabase extends _$AppDatabase {
return (delete(chatMessages)..where((m) => m.id.equals(id))).go();
}
Future<int> getTotalMessagesForRoom(String roomId) {
return (select(chatMessages)..where((m) => m.roomId.equals(roomId))).get().then((list) => list.length);
}
Future<List<LocalChatMessage>> searchMessages(
String roomId,
String query,
) async {
var selectStatement = select(chatMessages)
..where((m) => m.roomId.equals(roomId));
if (query.isNotEmpty) {
selectStatement =
selectStatement
..where((m) => m.content.like('%${query.toLowerCase()}%'));
}
final messages =
await (selectStatement
..orderBy([(m) => OrderingTerm.desc(m.createdAt)]))
.get();
return messages.map((msg) => companionToMessage(msg)).toList();
}
// Convert between Drift and model objects
ChatMessagesCompanion messageToCompanion(LocalChatMessage message) {
return ChatMessagesCompanion(

View File

@@ -1,484 +0,0 @@
import 'package:dio/dio.dart';
import 'package:island/database/drift_db.dart';
import 'package:island/database/message.dart';
import 'package:island/models/chat.dart';
import 'package:island/models/file.dart';
import 'package:island/services/file.dart';
import 'package:island/widgets/alert.dart';
import 'package:uuid/uuid.dart';
class MessageRepository {
final SnChatRoom room;
final SnChatMember identity;
final Dio _apiClient;
final AppDatabase _database;
final Map<String, LocalChatMessage> pendingMessages = {};
final Map<String, Map<int, double>> fileUploadProgress = {};
int? _totalCount;
MessageRepository(this.room, this.identity, this._apiClient, this._database);
Future<LocalChatMessage?> getLastMessages() async {
final dbMessages = await _database.getMessagesForRoom(
room.id,
offset: 0,
limit: 1,
);
if (dbMessages.isEmpty) {
return null;
}
return _database.companionToMessage(dbMessages.first);
}
Future<bool> syncMessages() async {
final lastMessage = await getLastMessages();
if (lastMessage == null) return false;
try {
final resp = await _apiClient.post(
'/sphere/chat/${room.id}/sync',
data: {
'last_sync_timestamp':
lastMessage.toRemoteMessage().updatedAt.millisecondsSinceEpoch,
},
);
final response = MessageSyncResponse.fromJson(resp.data);
for (final change in response.changes) {
switch (change.action) {
case MessageChangeAction.create:
await receiveMessage(change.message!);
break;
case MessageChangeAction.update:
await receiveMessageUpdate(change.message!);
break;
case MessageChangeAction.delete:
await receiveMessageDeletion(change.messageId.toString());
break;
}
}
} catch (err) {
showErrorAlert(err);
}
return true;
}
Future<List<LocalChatMessage>> listMessages({
int offset = 0,
int take = 20,
bool synced = false,
}) async {
try {
// For initial load, fetch latest messages in the background to sync.
if (offset == 0 && !synced) {
// Not awaiting this is intentional, for a quicker UI response.
// The UI should rely on a stream from the database to get updates.
_fetchAndCacheMessages(room.id, offset: 0, take: take).catchError((_) {
// Best effort, errors will be handled by later fetches.
return <LocalChatMessage>[];
});
}
final localMessages = await _getCachedMessages(
room.id,
offset: offset,
take: take,
);
// If local cache has messages, return them. This is the common case for scrolling up.
if (localMessages.isNotEmpty) {
return localMessages;
}
// If local cache is empty, we've probably reached the end of cached history.
// Fetch from remote. This will also be hit on first load if cache is empty.
return await _fetchAndCacheMessages(room.id, offset: offset, take: take);
} catch (e) {
// Final fallback to cache in case of network errors during fetch.
final localMessages = await _getCachedMessages(
room.id,
offset: offset,
take: take,
);
if (localMessages.isNotEmpty) {
return localMessages;
}
rethrow;
}
}
Future<List<LocalChatMessage>> _getCachedMessages(
String roomId, {
int offset = 0,
int take = 20,
}) async {
// Get messages from local database
final dbMessages = await _database.getMessagesForRoom(
roomId,
offset: offset,
limit: take,
);
final dbLocalMessages =
dbMessages.map(_database.companionToMessage).toList();
// Combine with pending messages for the first page
if (offset == 0) {
final pendingForRoom =
pendingMessages.values.where((msg) => msg.roomId == roomId).toList();
final allMessages = [...pendingForRoom, ...dbLocalMessages];
allMessages.sort((a, b) => b.createdAt.compareTo(a.createdAt));
// Remove duplicates by ID, preserving the order
final uniqueMessages = <LocalChatMessage>[];
final seenIds = <String>{};
for (final message in allMessages) {
if (seenIds.add(message.id)) {
uniqueMessages.add(message);
}
}
return uniqueMessages;
}
return dbLocalMessages;
}
Future<List<LocalChatMessage>> _fetchAndCacheMessages(
String roomId, {
int offset = 0,
int take = 20,
}) async {
// Use cached total count if available, otherwise fetch it
if (_totalCount == null) {
final response = await _apiClient.get(
'/sphere/chat/$roomId/messages',
queryParameters: {'offset': 0, 'take': 1},
);
_totalCount = int.parse(response.headers['x-total']?.firstOrNull ?? '0');
}
if (offset >= _totalCount!) {
return [];
}
final response = await _apiClient.get(
'/sphere/chat/$roomId/messages',
queryParameters: {'offset': offset, 'take': take},
);
final List<dynamic> data = response.data;
// Update total count from response headers
_totalCount = int.parse(response.headers['x-total']?.firstOrNull ?? '0');
final messages =
data.map((json) {
final remoteMessage = SnChatMessage.fromJson(json);
return LocalChatMessage.fromRemoteMessage(
remoteMessage,
MessageStatus.sent,
);
}).toList();
for (final message in messages) {
await _database.saveMessage(_database.messageToCompanion(message));
if (message.nonce != null) {
pendingMessages.removeWhere(
(_, pendingMsg) => pendingMsg.nonce == message.nonce,
);
}
}
return messages;
}
Future<LocalChatMessage> sendMessage(
String token,
String baseUrl,
String roomId,
String content,
String nonce, {
required List<UniversalFile> attachments,
Map<String, dynamic>? meta,
SnChatMessage? replyingTo,
SnChatMessage? forwardingTo,
SnChatMessage? editingTo,
Function(LocalChatMessage)? onPending,
Function(String, Map<int, double>)? onProgress,
}) async {
// Generate a unique nonce for this message
final nonce = const Uuid().v4();
// Create a local message with pending status
final mockMessage = SnChatMessage(
id: 'pending_$nonce',
chatRoomId: roomId,
senderId: identity.id,
content: content,
createdAt: DateTime.now(),
updatedAt: DateTime.now(),
nonce: nonce,
sender: identity,
);
final localMessage = LocalChatMessage.fromRemoteMessage(
mockMessage,
MessageStatus.pending,
);
// Store in memory and database
pendingMessages[localMessage.id] = localMessage;
fileUploadProgress[localMessage.id] = {};
await _database.saveMessage(_database.messageToCompanion(localMessage));
onPending?.call(localMessage);
try {
var cloudAttachments = List.empty(growable: true);
// Upload files
for (var idx = 0; idx < attachments.length; idx++) {
final cloudFile =
await putMediaToCloud(
fileData: attachments[idx],
atk: token,
baseUrl: baseUrl,
filename: attachments[idx].data.name ?? 'Post media',
mimetype:
attachments[idx].data.mimeType ??
switch (attachments[idx].type) {
UniversalFileType.image => 'image/unknown',
UniversalFileType.video => 'video/unknown',
UniversalFileType.audio => 'audio/unknown',
UniversalFileType.file => 'application/octet-stream',
},
onProgress: (progress, _) {
fileUploadProgress[localMessage.id]?[idx] = progress;
onProgress?.call(
localMessage.id,
fileUploadProgress[localMessage.id] ?? {},
);
},
).future;
if (cloudFile == null) {
throw ArgumentError('Failed to upload the file...');
}
cloudAttachments.add(cloudFile);
}
// Send to server
final response = await _apiClient.request(
editingTo == null
? '/sphere/chat/$roomId/messages'
: '/sphere/chat/$roomId/messages/${editingTo.id}',
data: {
'content': content,
'attachments_id': cloudAttachments.map((e) => e.id).toList(),
'replied_message_id': replyingTo?.id,
'forwarded_message_id': forwardingTo?.id,
'meta': meta,
'nonce': nonce,
},
options: Options(method: editingTo == null ? 'POST' : 'PATCH'),
);
// Update with server response
final remoteMessage = SnChatMessage.fromJson(response.data);
final updatedMessage = LocalChatMessage.fromRemoteMessage(
remoteMessage,
MessageStatus.sent,
);
// Remove from pending and update in database
pendingMessages.remove(localMessage.id);
await _database.deleteMessage(localMessage.id);
await _database.saveMessage(_database.messageToCompanion(updatedMessage));
return updatedMessage;
} catch (e) {
// Update status to failed
localMessage.status = MessageStatus.failed;
pendingMessages[localMessage.id] = localMessage;
await _database.updateMessageStatus(
localMessage.id,
MessageStatus.failed,
);
rethrow;
}
}
Future<LocalChatMessage> retryMessage(String pendingMessageId) async {
final message = await getMessageById(pendingMessageId);
if (message == null) {
throw Exception('Message not found');
}
// Update status back to pending
message.status = MessageStatus.pending;
pendingMessages[pendingMessageId] = message;
await _database.updateMessageStatus(
pendingMessageId,
MessageStatus.pending,
);
try {
// Send to server
var remoteMessage = message.toRemoteMessage();
final response = await _apiClient.post(
'/sphere/chat/${message.roomId}/messages',
data: {
'content': remoteMessage.content,
'attachments_id': remoteMessage.attachments,
'meta': remoteMessage.meta,
'nonce': message.nonce,
},
);
// Update with server response
remoteMessage = SnChatMessage.fromJson(response.data);
final updatedMessage = LocalChatMessage.fromRemoteMessage(
remoteMessage,
MessageStatus.sent,
);
// Remove from pending and update in database
pendingMessages.remove(pendingMessageId);
await _database.deleteMessage(pendingMessageId);
await _database.saveMessage(_database.messageToCompanion(updatedMessage));
return updatedMessage;
} catch (e) {
// Update status to failed
message.status = MessageStatus.failed;
pendingMessages[pendingMessageId] = message;
await _database.updateMessageStatus(
pendingMessageId,
MessageStatus.failed,
);
rethrow;
}
}
Future<LocalChatMessage> receiveMessage(SnChatMessage remoteMessage) async {
final localMessage = LocalChatMessage.fromRemoteMessage(
remoteMessage,
MessageStatus.sent,
);
if (remoteMessage.nonce != null) {
pendingMessages.removeWhere(
(_, pendingMsg) => pendingMsg.nonce == remoteMessage.nonce,
);
}
await _database.saveMessage(_database.messageToCompanion(localMessage));
return localMessage;
}
Future<LocalChatMessage> receiveMessageUpdate(
SnChatMessage remoteMessage,
) async {
final localMessage = LocalChatMessage.fromRemoteMessage(
remoteMessage,
MessageStatus.sent,
);
await _database.updateMessage(_database.messageToCompanion(localMessage));
return localMessage;
}
Future<void> receiveMessageDeletion(String messageId) async {
// Remove from pending messages if exists
pendingMessages.remove(messageId);
// Delete from local database
await _database.deleteMessage(messageId);
}
Future<LocalChatMessage> updateMessage(
String messageId,
String content, {
List<SnCloudFile>? attachments,
Map<String, dynamic>? meta,
}) async {
final message = pendingMessages[messageId];
if (message != null) {
// Update pending message
final rmMessage = message.toRemoteMessage();
final updatedRemoteMessage = rmMessage.copyWith(
content: content,
meta: meta ?? rmMessage.meta,
);
final updatedLocalMessage = LocalChatMessage.fromRemoteMessage(
updatedRemoteMessage,
MessageStatus.pending,
);
pendingMessages[messageId] = updatedLocalMessage;
await _database.updateMessage(
_database.messageToCompanion(updatedLocalMessage),
);
return message;
}
try {
// Update on server
final response = await _apiClient.put(
'/sphere/chat/${room.id}/messages/$messageId',
data: {'content': content, 'attachments': attachments, 'meta': meta},
);
// Update local copy
final remoteMessage = SnChatMessage.fromJson(response.data);
final updatedMessage = LocalChatMessage.fromRemoteMessage(
remoteMessage,
MessageStatus.sent,
);
await _database.updateMessage(
_database.messageToCompanion(updatedMessage),
);
return updatedMessage;
} catch (e) {
rethrow;
}
}
Future<void> deleteMessage(String messageId) async {
try {
await _apiClient.delete('/sphere/chat/${room.id}/messages/$messageId');
pendingMessages.remove(messageId);
await _database.deleteMessage(messageId);
} catch (e) {
rethrow;
}
}
Future<LocalChatMessage?> getMessageById(String messageId) async {
try {
// Attempt to get the message from the local database
final localMessage =
await (_database.select(_database.chatMessages)
..where((tbl) => tbl.id.equals(messageId))).getSingleOrNull();
if (localMessage != null) {
return _database.companionToMessage(localMessage);
}
// If not found locally, fetch from the server
final response = await _apiClient.get(
'/sphere/chat/${room.id}/messages/$messageId',
);
final remoteMessage = SnChatMessage.fromJson(response.data);
final message = LocalChatMessage.fromRemoteMessage(
remoteMessage,
MessageStatus.sent,
);
// Save the fetched message to the local database
await _database.saveMessage(_database.messageToCompanion(message));
return message;
} catch (e) {
if (e is DioException) return null;
// Handle errors
rethrow;
}
}
}

View File

@@ -29,10 +29,7 @@ class DefaultFirebaseOptions {
case TargetPlatform.windows:
return windows;
case TargetPlatform.linux:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for linux - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
return windows;
default:
throw UnsupportedError(
'DefaultFirebaseOptions are not supported for this platform.',
@@ -41,13 +38,13 @@ class DefaultFirebaseOptions {
}
static const FirebaseOptions web = FirebaseOptions(
apiKey: 'AIzaSyBKfIQpTouj5rXnlzkEieSlbAzepm4mgJE',
appId: '1:961776991058:web:b91d12f2892a5609f4188b',
apiKey: 'AIzaSyCfgOdlcr7h8x8j0WKx_S2wXnGkOopq320',
appId: '1:961776991058:web:3a912c0eb14028e5f4188b',
messagingSenderId: '961776991058',
projectId: 'solian-0x001',
authDomain: 'solian-0x001.firebaseapp.com',
storageBucket: 'solian-0x001.firebasestorage.app',
measurementId: 'G-XY3HHKG0PE',
measurementId: 'G-JD1YEG9D6F',
);
static const FirebaseOptions android = FirebaseOptions(
@@ -64,6 +61,8 @@ class DefaultFirebaseOptions {
messagingSenderId: '961776991058',
projectId: 'solian-0x001',
storageBucket: 'solian-0x001.firebasestorage.app',
androidClientId: '961776991058-r4iv9qoio57ul7utbfpgfrda2etvtch8.apps.googleusercontent.com',
iosClientId: '961776991058-stt7et4qvn3cpscl4r61gl1hnlatqkig.apps.googleusercontent.com',
iosBundleId: 'dev.solsynth.solian',
);
@@ -73,6 +72,8 @@ class DefaultFirebaseOptions {
messagingSenderId: '961776991058',
projectId: 'solian-0x001',
storageBucket: 'solian-0x001.firebasestorage.app',
androidClientId: '961776991058-r4iv9qoio57ul7utbfpgfrda2etvtch8.apps.googleusercontent.com',
iosClientId: '961776991058-stt7et4qvn3cpscl4r61gl1hnlatqkig.apps.googleusercontent.com',
iosBundleId: 'dev.solsynth.solian',
);

View File

@@ -4,10 +4,11 @@ import 'dart:io';
import 'package:croppy/croppy.dart';
import 'package:easy_localization/easy_localization.dart' hide TextDirection;
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
@@ -20,7 +21,6 @@ import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:island/pods/userinfo.dart';
import 'package:island/pods/websocket.dart';
import 'package:island/route.dart';
import 'package:island/services/notify.dart';
import 'package:island/services/timezone.dart';
import 'package:island/widgets/alert.dart';
@@ -30,6 +30,7 @@ import 'package:shared_preferences/shared_preferences.dart';
import 'package:image_picker_platform_interface/image_picker_platform_interface.dart';
import 'package:flutter_native_splash/flutter_native_splash.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'package:flutter_langdetect/flutter_langdetect.dart' as langdetect;
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
@@ -51,11 +52,29 @@ void main() async {
}
try {
await langdetect.initLangDetect();
await EasyLocalization.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
if (kIsWeb || !Platform.isLinux) {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
FirebaseMessaging.onBackgroundMessage(
_firebaseMessagingBackgroundHandler,
);
// Although previous if case checked this. Still check is web or not
// Otherwise the web platform will broke due to there is no Platform api on the web
// Skip crashlytics setup on debug mode to prevent unexpected report to firebase
if ((kIsWeb || !Platform.isWindows) && !kDebugMode) {
FlutterError.onError =
FirebaseCrashlytics.instance.recordFlutterFatalError;
PlatformDispatcher.instance.onError = (error, stack) {
FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
return true;
};
}
}
log("[SplashScreen] Firebase is ready!");
} catch (err) {
showErrorAlert(err);
@@ -150,12 +169,12 @@ class IslandApp extends HookConsumerWidget {
final theme = ref.watch(themeProvider);
void handleMessage(RemoteMessage notification) {
if (notification.data['action_uri'] != null) {
var uri = notification.data['action_uri'] as String;
if (notification.data['meta']?['action_uri'] != null) {
var uri = notification.data['meta']['action_uri'] as String;
if (uri.startsWith('/')) {
// In-app routes
final router = ref.read(routerProvider);
router.go(notification.data['action_uri']);
router.push(notification.data['meta']['action_uri']);
} else {
// External links
launchUrlString(uri);
@@ -164,28 +183,10 @@ class IslandApp extends HookConsumerWidget {
}
useEffect(() {
const channel = MethodChannel('dev.solsynth.solian/notifications');
Future<void> handleInitialLink() async {
final String? link = await channel.invokeMethod('initialLink');
if (link != null) {
final router = ref.read(routerProvider);
router.go(link);
}
if (!kIsWeb && Platform.isLinux) {
return null;
}
if (!kIsWeb && Platform.isAndroid) {
handleInitialLink();
}
channel.setMethodCallHandler((call) async {
if (call.method == 'newLink') {
final String link = call.arguments;
final router = ref.read(routerProvider);
router.go(link);
}
});
// When the app is opened from a terminated state.
FirebaseMessaging.instance.getInitialMessage().then((message) {
if (message != null) {

View File

@@ -1,9 +1,10 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:island/models/auth.dart';
import 'package:island/models/file.dart';
import 'package:island/models/wallet.dart';
part 'user.freezed.dart';
part 'user.g.dart';
part 'account.freezed.dart';
part 'account.g.dart';
@freezed
sealed class SnAccount with _$SnAccount {
@@ -13,7 +14,9 @@ sealed class SnAccount with _$SnAccount {
required String nick,
required String language,
required bool isSuperuser,
required String? automatedId,
required SnAccountProfile profile,
required SnWalletSubscriptionRef? perkSubscription,
@Default([]) List<SnAccountBadge> badges,
required DateTime createdAt,
required DateTime updatedAt,
@@ -24,6 +27,32 @@ sealed class SnAccount with _$SnAccount {
_$SnAccountFromJson(json);
}
@freezed
sealed class ProfileLink with _$ProfileLink {
const factory ProfileLink({required String name, required String url}) =
_ProfileLink;
factory ProfileLink.fromJson(Map<String, dynamic> json) =>
_$ProfileLinkFromJson(json);
}
class ProfileLinkConverter
implements JsonConverter<List<ProfileLink>, dynamic> {
const ProfileLinkConverter();
@override
List<ProfileLink> fromJson(dynamic json) {
return json is List<dynamic>
? json.map((e) => ProfileLink.fromJson(e)).cast<ProfileLink>().toList()
: <ProfileLink>[];
}
@override
List<dynamic> toJson(List<ProfileLink> object) {
return object.map((e) => e.toJson()).toList();
}
}
@freezed
sealed class SnAccountProfile with _$SnAccountProfile {
const factory SnAccountProfile({
@@ -37,15 +66,17 @@ sealed class SnAccountProfile with _$SnAccountProfile {
@Default('') String location,
@Default('') String timeZone,
DateTime? birthday,
@ProfileLinkConverter() @Default([]) List<ProfileLink> links,
DateTime? lastSeenAt,
SnAccountBadge? activeBadge,
required int experience,
required int level,
@Default(100) double socialCredits,
@Default(0) int socialCreditsLevel,
required double levelingProgress,
required SnCloudFile? picture,
required SnCloudFile? background,
required SnVerificationMark? verification,
required SnWalletSubscriptionRef? stellarMembership,
required DateTime createdAt,
required DateTime updatedAt,
required DateTime? deletedAt,
@@ -147,3 +178,70 @@ sealed class SnVerificationMark with _$SnVerificationMark {
factory SnVerificationMark.fromJson(Map<String, dynamic> json) =>
_$SnVerificationMarkFromJson(json);
}
@freezed
sealed class SnAuthDevice with _$SnAuthDevice {
const factory SnAuthDevice({
required String id,
required String deviceId,
required String deviceName,
required String? deviceLabel,
required String accountId,
required int platform,
@Default(false) bool isCurrent,
}) = _SnAuthDevice;
factory SnAuthDevice.fromJson(Map<String, dynamic> json) =>
_$SnAuthDeviceFromJson(json);
}
@freezed
sealed class SnAuthDeviceWithChallenge with _$SnAuthDeviceWithChallenge {
const factory SnAuthDeviceWithChallenge({
required String id,
required String deviceId,
required String deviceName,
required String? deviceLabel,
required String accountId,
required int platform,
required List<SnAuthChallenge> challenges,
@Default(false) bool isCurrent,
}) = _SnAuthDeviceWithChallengee;
factory SnAuthDeviceWithChallenge.fromJson(Map<String, dynamic> json) =>
_$SnAuthDeviceWithChallengeFromJson(json);
}
@freezed
sealed class SnExperienceRecord with _$SnExperienceRecord {
const factory SnExperienceRecord({
required String id,
required int delta,
required String reasonType,
required String reason,
@Default(1.0) double? bonusMultiplier,
required DateTime createdAt,
required DateTime updatedAt,
required DateTime? deletedAt,
}) = _SnExperienceRecord;
factory SnExperienceRecord.fromJson(Map<String, dynamic> json) =>
_$SnExperienceRecordFromJson(json);
}
@freezed
sealed class SnSocialCreditRecord with _$SnSocialCreditRecord {
const factory SnSocialCreditRecord({
required String id,
required double delta,
required String reasonType,
required String reason,
required DateTime? expiredAt,
required DateTime createdAt,
required DateTime updatedAt,
required DateTime? deletedAt,
}) = _SnSocialCreditRecord;
factory SnSocialCreditRecord.fromJson(Map<String, dynamic> json) =>
_$SnSocialCreditRecordFromJson(json);
}

View File

@@ -1,6 +1,6 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'user.dart';
part of 'account.dart';
// **************************************************************************
// JsonSerializableGenerator
@@ -12,7 +12,14 @@ _SnAccount _$SnAccountFromJson(Map<String, dynamic> json) => _SnAccount(
nick: json['nick'] as String,
language: json['language'] as String,
isSuperuser: json['is_superuser'] as bool,
automatedId: json['automated_id'] as String?,
profile: SnAccountProfile.fromJson(json['profile'] as Map<String, dynamic>),
perkSubscription:
json['perk_subscription'] == null
? null
: SnWalletSubscriptionRef.fromJson(
json['perk_subscription'] as Map<String, dynamic>,
),
badges:
(json['badges'] as List<dynamic>?)
?.map((e) => SnAccountBadge.fromJson(e as Map<String, dynamic>))
@@ -33,13 +40,21 @@ Map<String, dynamic> _$SnAccountToJson(_SnAccount instance) =>
'nick': instance.nick,
'language': instance.language,
'is_superuser': instance.isSuperuser,
'automated_id': instance.automatedId,
'profile': instance.profile.toJson(),
'perk_subscription': instance.perkSubscription?.toJson(),
'badges': instance.badges.map((e) => e.toJson()).toList(),
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
};
_ProfileLink _$ProfileLinkFromJson(Map<String, dynamic> json) =>
_ProfileLink(name: json['name'] as String, url: json['url'] as String);
Map<String, dynamic> _$ProfileLinkToJson(_ProfileLink instance) =>
<String, dynamic>{'name': instance.name, 'url': instance.url};
_SnAccountProfile _$SnAccountProfileFromJson(Map<String, dynamic> json) =>
_SnAccountProfile(
id: json['id'] as String,
@@ -55,6 +70,10 @@ _SnAccountProfile _$SnAccountProfileFromJson(Map<String, dynamic> json) =>
json['birthday'] == null
? null
: DateTime.parse(json['birthday'] as String),
links:
json['links'] == null
? const []
: const ProfileLinkConverter().fromJson(json['links']),
lastSeenAt:
json['last_seen_at'] == null
? null
@@ -67,6 +86,8 @@ _SnAccountProfile _$SnAccountProfileFromJson(Map<String, dynamic> json) =>
),
experience: (json['experience'] as num).toInt(),
level: (json['level'] as num).toInt(),
socialCredits: (json['social_credits'] as num?)?.toDouble() ?? 100,
socialCreditsLevel: (json['social_credits_level'] as num?)?.toInt() ?? 0,
levelingProgress: (json['leveling_progress'] as num).toDouble(),
picture:
json['picture'] == null
@@ -84,12 +105,6 @@ _SnAccountProfile _$SnAccountProfileFromJson(Map<String, dynamic> json) =>
: SnVerificationMark.fromJson(
json['verification'] as Map<String, dynamic>,
),
stellarMembership:
json['stellar_membership'] == null
? null
: SnWalletSubscriptionRef.fromJson(
json['stellar_membership'] as Map<String, dynamic>,
),
createdAt: DateTime.parse(json['created_at'] as String),
updatedAt: DateTime.parse(json['updated_at'] as String),
deletedAt:
@@ -110,15 +125,17 @@ Map<String, dynamic> _$SnAccountProfileToJson(_SnAccountProfile instance) =>
'location': instance.location,
'time_zone': instance.timeZone,
'birthday': instance.birthday?.toIso8601String(),
'links': const ProfileLinkConverter().toJson(instance.links),
'last_seen_at': instance.lastSeenAt?.toIso8601String(),
'active_badge': instance.activeBadge?.toJson(),
'experience': instance.experience,
'level': instance.level,
'social_credits': instance.socialCredits,
'social_credits_level': instance.socialCreditsLevel,
'leveling_progress': instance.levelingProgress,
'picture': instance.picture?.toJson(),
'background': instance.background?.toJson(),
'verification': instance.verification?.toJson(),
'stellar_membership': instance.stellarMembership?.toJson(),
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
@@ -286,3 +303,113 @@ Map<String, dynamic> _$SnVerificationMarkToJson(_SnVerificationMark instance) =>
'description': instance.description,
'verified_by': instance.verifiedBy,
};
_SnAuthDevice _$SnAuthDeviceFromJson(Map<String, dynamic> json) =>
_SnAuthDevice(
id: json['id'] as String,
deviceId: json['device_id'] as String,
deviceName: json['device_name'] as String,
deviceLabel: json['device_label'] as String?,
accountId: json['account_id'] as String,
platform: (json['platform'] as num).toInt(),
isCurrent: json['is_current'] as bool? ?? false,
);
Map<String, dynamic> _$SnAuthDeviceToJson(_SnAuthDevice instance) =>
<String, dynamic>{
'id': instance.id,
'device_id': instance.deviceId,
'device_name': instance.deviceName,
'device_label': instance.deviceLabel,
'account_id': instance.accountId,
'platform': instance.platform,
'is_current': instance.isCurrent,
};
_SnAuthDeviceWithChallengee _$SnAuthDeviceWithChallengeeFromJson(
Map<String, dynamic> json,
) => _SnAuthDeviceWithChallengee(
id: json['id'] as String,
deviceId: json['device_id'] as String,
deviceName: json['device_name'] as String,
deviceLabel: json['device_label'] as String?,
accountId: json['account_id'] as String,
platform: (json['platform'] as num).toInt(),
challenges:
(json['challenges'] as List<dynamic>)
.map((e) => SnAuthChallenge.fromJson(e as Map<String, dynamic>))
.toList(),
isCurrent: json['is_current'] as bool? ?? false,
);
Map<String, dynamic> _$SnAuthDeviceWithChallengeeToJson(
_SnAuthDeviceWithChallengee instance,
) => <String, dynamic>{
'id': instance.id,
'device_id': instance.deviceId,
'device_name': instance.deviceName,
'device_label': instance.deviceLabel,
'account_id': instance.accountId,
'platform': instance.platform,
'challenges': instance.challenges.map((e) => e.toJson()).toList(),
'is_current': instance.isCurrent,
};
_SnExperienceRecord _$SnExperienceRecordFromJson(Map<String, dynamic> json) =>
_SnExperienceRecord(
id: json['id'] as String,
delta: (json['delta'] as num).toInt(),
reasonType: json['reason_type'] as String,
reason: json['reason'] as String,
bonusMultiplier: (json['bonus_multiplier'] as num?)?.toDouble() ?? 1.0,
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> _$SnExperienceRecordToJson(_SnExperienceRecord instance) =>
<String, dynamic>{
'id': instance.id,
'delta': instance.delta,
'reason_type': instance.reasonType,
'reason': instance.reason,
'bonus_multiplier': instance.bonusMultiplier,
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
};
_SnSocialCreditRecord _$SnSocialCreditRecordFromJson(
Map<String, dynamic> json,
) => _SnSocialCreditRecord(
id: json['id'] as String,
delta: (json['delta'] as num).toDouble(),
reasonType: json['reason_type'] as String,
reason: json['reason'] as String,
expiredAt:
json['expired_at'] == null
? null
: DateTime.parse(json['expired_at'] 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> _$SnSocialCreditRecordToJson(
_SnSocialCreditRecord instance,
) => <String, dynamic>{
'id': instance.id,
'delta': instance.delta,
'reason_type': instance.reasonType,
'reason': instance.reason,
'expired_at': instance.expiredAt?.toIso8601String(),
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
};

View File

@@ -1,5 +1,5 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:island/models/user.dart';
import 'package:island/models/account.dart';
part 'activity.freezed.dart';
part 'activity.g.dart';
@@ -54,7 +54,7 @@ sealed class SnEventCalendarEntry with _$SnEventCalendarEntry {
const factory SnEventCalendarEntry({
required DateTime date,
required SnCheckInResult? checkInResult,
required List<dynamic> statuses,
required List<SnAccountStatus> statuses,
}) = _SnEventCalendarEntry;
factory SnEventCalendarEntry.fromJson(Map<String, dynamic> json) =>

View File

@@ -861,7 +861,7 @@ as String,
/// @nodoc
mixin _$SnEventCalendarEntry {
DateTime get date; SnCheckInResult? get checkInResult; List<dynamic> get statuses;
DateTime get date; SnCheckInResult? get checkInResult; List<SnAccountStatus> get statuses;
/// Create a copy of SnEventCalendarEntry
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -894,7 +894,7 @@ abstract mixin class $SnEventCalendarEntryCopyWith<$Res> {
factory $SnEventCalendarEntryCopyWith(SnEventCalendarEntry value, $Res Function(SnEventCalendarEntry) _then) = _$SnEventCalendarEntryCopyWithImpl;
@useResult
$Res call({
DateTime date, SnCheckInResult? checkInResult, List<dynamic> statuses
DateTime date, SnCheckInResult? checkInResult, List<SnAccountStatus> statuses
});
@@ -916,7 +916,7 @@ class _$SnEventCalendarEntryCopyWithImpl<$Res>
date: null == date ? _self.date : date // ignore: cast_nullable_to_non_nullable
as DateTime,checkInResult: freezed == checkInResult ? _self.checkInResult : checkInResult // ignore: cast_nullable_to_non_nullable
as SnCheckInResult?,statuses: null == statuses ? _self.statuses : statuses // ignore: cast_nullable_to_non_nullable
as List<dynamic>,
as List<SnAccountStatus>,
));
}
/// Create a copy of SnEventCalendarEntry
@@ -1010,7 +1010,7 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( DateTime date, SnCheckInResult? checkInResult, List<dynamic> statuses)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( DateTime date, SnCheckInResult? checkInResult, List<SnAccountStatus> statuses)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnEventCalendarEntry() when $default != null:
return $default(_that.date,_that.checkInResult,_that.statuses);case _:
@@ -1031,7 +1031,7 @@ return $default(_that.date,_that.checkInResult,_that.statuses);case _:
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( DateTime date, SnCheckInResult? checkInResult, List<dynamic> statuses) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( DateTime date, SnCheckInResult? checkInResult, List<SnAccountStatus> statuses) $default,) {final _that = this;
switch (_that) {
case _SnEventCalendarEntry():
return $default(_that.date,_that.checkInResult,_that.statuses);}
@@ -1048,7 +1048,7 @@ return $default(_that.date,_that.checkInResult,_that.statuses);}
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( DateTime date, SnCheckInResult? checkInResult, List<dynamic> statuses)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( DateTime date, SnCheckInResult? checkInResult, List<SnAccountStatus> statuses)? $default,) {final _that = this;
switch (_that) {
case _SnEventCalendarEntry() when $default != null:
return $default(_that.date,_that.checkInResult,_that.statuses);case _:
@@ -1063,13 +1063,13 @@ return $default(_that.date,_that.checkInResult,_that.statuses);case _:
@JsonSerializable()
class _SnEventCalendarEntry implements SnEventCalendarEntry {
const _SnEventCalendarEntry({required this.date, required this.checkInResult, required final List<dynamic> statuses}): _statuses = statuses;
const _SnEventCalendarEntry({required this.date, required this.checkInResult, required final List<SnAccountStatus> statuses}): _statuses = statuses;
factory _SnEventCalendarEntry.fromJson(Map<String, dynamic> json) => _$SnEventCalendarEntryFromJson(json);
@override final DateTime date;
@override final SnCheckInResult? checkInResult;
final List<dynamic> _statuses;
@override List<dynamic> get statuses {
final List<SnAccountStatus> _statuses;
@override List<SnAccountStatus> get statuses {
if (_statuses is EqualUnmodifiableListView) return _statuses;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_statuses);
@@ -1109,7 +1109,7 @@ abstract mixin class _$SnEventCalendarEntryCopyWith<$Res> implements $SnEventCal
factory _$SnEventCalendarEntryCopyWith(_SnEventCalendarEntry value, $Res Function(_SnEventCalendarEntry) _then) = __$SnEventCalendarEntryCopyWithImpl;
@override @useResult
$Res call({
DateTime date, SnCheckInResult? checkInResult, List<dynamic> statuses
DateTime date, SnCheckInResult? checkInResult, List<SnAccountStatus> statuses
});
@@ -1131,7 +1131,7 @@ class __$SnEventCalendarEntryCopyWithImpl<$Res>
date: null == date ? _self.date : date // ignore: cast_nullable_to_non_nullable
as DateTime,checkInResult: freezed == checkInResult ? _self.checkInResult : checkInResult // ignore: cast_nullable_to_non_nullable
as SnCheckInResult?,statuses: null == statuses ? _self._statuses : statuses // ignore: cast_nullable_to_non_nullable
as List<dynamic>,
as List<SnAccountStatus>,
));
}

View File

@@ -87,7 +87,10 @@ _SnEventCalendarEntry _$SnEventCalendarEntryFromJson(
: SnCheckInResult.fromJson(
json['check_in_result'] as Map<String, dynamic>,
),
statuses: json['statuses'] as List<dynamic>,
statuses:
(json['statuses'] as List<dynamic>)
.map((e) => SnAccountStatus.fromJson(e as Map<String, dynamic>))
.toList(),
);
Map<String, dynamic> _$SnEventCalendarEntryToJson(
@@ -95,5 +98,5 @@ Map<String, dynamic> _$SnEventCalendarEntryToJson(
) => <String, dynamic>{
'date': instance.date.toIso8601String(),
'check_in_result': instance.checkInResult?.toJson(),
'statuses': instance.statuses,
'statuses': instance.statuses.map((e) => e.toJson()).toList(),
};

View File

@@ -19,14 +19,12 @@ sealed class SnAuthChallenge with _$SnAuthChallenge {
required int stepRemain,
required int stepTotal,
required int failedAttempts,
required int platform,
required int type,
required List<String> blacklistFactors,
required List<dynamic> audiences,
required List<dynamic> scopes,
required String ipAddress,
required String userAgent,
required String deviceId,
required String? nonce,
required String? location,
required String accountId,
@@ -76,22 +74,6 @@ sealed class SnAuthFactor with _$SnAuthFactor {
_$SnAuthFactorFromJson(json);
}
@freezed
sealed class SnAuthDevice with _$SnAuthDevice {
const factory SnAuthDevice({
required dynamic label,
required String userAgent,
required String deviceId,
required int platform,
required List<SnAuthSession> sessions,
// Not from backend, used for UI
@Default(false) bool isCurrent,
}) = _SnAuthDevice;
factory SnAuthDevice.fromJson(Map<String, dynamic> json) =>
_$SnAuthDeviceFromJson(json);
}
@freezed
sealed class SnAccountConnection with _$SnAccountConnection {
const factory SnAccountConnection({

View File

@@ -272,7 +272,7 @@ as String,
/// @nodoc
mixin _$SnAuthChallenge {
String get id; DateTime get expiredAt; int get stepRemain; int get stepTotal; int get failedAttempts; int get platform; int get type; List<String> get blacklistFactors; List<dynamic> get audiences; List<dynamic> get scopes; String get ipAddress; String get userAgent; String get deviceId; String? get nonce; String? get location; String get accountId; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
String get id; DateTime get expiredAt; int get stepRemain; int get stepTotal; int get failedAttempts; int get type; List<String> get blacklistFactors; List<dynamic> get audiences; List<dynamic> get scopes; String get ipAddress; String get userAgent; String? get nonce; String? get location; String get accountId; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
/// Create a copy of SnAuthChallenge
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -285,16 +285,16 @@ $SnAuthChallengeCopyWith<SnAuthChallenge> get copyWith => _$SnAuthChallengeCopyW
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnAuthChallenge&&(identical(other.id, id) || other.id == id)&&(identical(other.expiredAt, expiredAt) || other.expiredAt == expiredAt)&&(identical(other.stepRemain, stepRemain) || other.stepRemain == stepRemain)&&(identical(other.stepTotal, stepTotal) || other.stepTotal == stepTotal)&&(identical(other.failedAttempts, failedAttempts) || other.failedAttempts == failedAttempts)&&(identical(other.platform, platform) || other.platform == platform)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other.blacklistFactors, blacklistFactors)&&const DeepCollectionEquality().equals(other.audiences, audiences)&&const DeepCollectionEquality().equals(other.scopes, scopes)&&(identical(other.ipAddress, ipAddress) || other.ipAddress == ipAddress)&&(identical(other.userAgent, userAgent) || other.userAgent == userAgent)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.nonce, nonce) || other.nonce == nonce)&&(identical(other.location, location) || other.location == location)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnAuthChallenge&&(identical(other.id, id) || other.id == id)&&(identical(other.expiredAt, expiredAt) || other.expiredAt == expiredAt)&&(identical(other.stepRemain, stepRemain) || other.stepRemain == stepRemain)&&(identical(other.stepTotal, stepTotal) || other.stepTotal == stepTotal)&&(identical(other.failedAttempts, failedAttempts) || other.failedAttempts == failedAttempts)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other.blacklistFactors, blacklistFactors)&&const DeepCollectionEquality().equals(other.audiences, audiences)&&const DeepCollectionEquality().equals(other.scopes, scopes)&&(identical(other.ipAddress, ipAddress) || other.ipAddress == ipAddress)&&(identical(other.userAgent, userAgent) || other.userAgent == userAgent)&&(identical(other.nonce, nonce) || other.nonce == nonce)&&(identical(other.location, location) || other.location == location)&&(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.hashAll([runtimeType,id,expiredAt,stepRemain,stepTotal,failedAttempts,platform,type,const DeepCollectionEquality().hash(blacklistFactors),const DeepCollectionEquality().hash(audiences),const DeepCollectionEquality().hash(scopes),ipAddress,userAgent,deviceId,nonce,location,accountId,createdAt,updatedAt,deletedAt]);
int get hashCode => Object.hash(runtimeType,id,expiredAt,stepRemain,stepTotal,failedAttempts,type,const DeepCollectionEquality().hash(blacklistFactors),const DeepCollectionEquality().hash(audiences),const DeepCollectionEquality().hash(scopes),ipAddress,userAgent,nonce,location,accountId,createdAt,updatedAt,deletedAt);
@override
String toString() {
return 'SnAuthChallenge(id: $id, expiredAt: $expiredAt, stepRemain: $stepRemain, stepTotal: $stepTotal, failedAttempts: $failedAttempts, platform: $platform, type: $type, blacklistFactors: $blacklistFactors, audiences: $audiences, scopes: $scopes, ipAddress: $ipAddress, userAgent: $userAgent, deviceId: $deviceId, nonce: $nonce, location: $location, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
return 'SnAuthChallenge(id: $id, expiredAt: $expiredAt, stepRemain: $stepRemain, stepTotal: $stepTotal, failedAttempts: $failedAttempts, type: $type, blacklistFactors: $blacklistFactors, audiences: $audiences, scopes: $scopes, ipAddress: $ipAddress, userAgent: $userAgent, nonce: $nonce, location: $location, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
@@ -305,7 +305,7 @@ abstract mixin class $SnAuthChallengeCopyWith<$Res> {
factory $SnAuthChallengeCopyWith(SnAuthChallenge value, $Res Function(SnAuthChallenge) _then) = _$SnAuthChallengeCopyWithImpl;
@useResult
$Res call({
String id, DateTime expiredAt, int stepRemain, int stepTotal, int failedAttempts, int platform, int type, List<String> blacklistFactors, List<dynamic> audiences, List<dynamic> scopes, String ipAddress, String userAgent, String deviceId, String? nonce, String? location, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
String id, DateTime expiredAt, int stepRemain, int stepTotal, int failedAttempts, int type, List<String> blacklistFactors, List<dynamic> audiences, List<dynamic> scopes, String ipAddress, String userAgent, String? nonce, String? location, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
@@ -322,21 +322,19 @@ class _$SnAuthChallengeCopyWithImpl<$Res>
/// Create a copy of SnAuthChallenge
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? expiredAt = null,Object? stepRemain = null,Object? stepTotal = null,Object? failedAttempts = null,Object? platform = null,Object? type = null,Object? blacklistFactors = null,Object? audiences = null,Object? scopes = null,Object? ipAddress = null,Object? userAgent = null,Object? deviceId = null,Object? nonce = freezed,Object? location = freezed,Object? accountId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? expiredAt = null,Object? stepRemain = null,Object? stepTotal = null,Object? failedAttempts = null,Object? type = null,Object? blacklistFactors = null,Object? audiences = null,Object? scopes = null,Object? ipAddress = null,Object? userAgent = null,Object? nonce = freezed,Object? location = 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,expiredAt: null == expiredAt ? _self.expiredAt : expiredAt // ignore: cast_nullable_to_non_nullable
as DateTime,stepRemain: null == stepRemain ? _self.stepRemain : stepRemain // ignore: cast_nullable_to_non_nullable
as int,stepTotal: null == stepTotal ? _self.stepTotal : stepTotal // ignore: cast_nullable_to_non_nullable
as int,failedAttempts: null == failedAttempts ? _self.failedAttempts : failedAttempts // ignore: cast_nullable_to_non_nullable
as int,platform: null == platform ? _self.platform : platform // ignore: cast_nullable_to_non_nullable
as int,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
as int,blacklistFactors: null == blacklistFactors ? _self.blacklistFactors : blacklistFactors // ignore: cast_nullable_to_non_nullable
as List<String>,audiences: null == audiences ? _self.audiences : audiences // ignore: cast_nullable_to_non_nullable
as List<dynamic>,scopes: null == scopes ? _self.scopes : scopes // ignore: cast_nullable_to_non_nullable
as List<dynamic>,ipAddress: null == ipAddress ? _self.ipAddress : ipAddress // ignore: cast_nullable_to_non_nullable
as String,userAgent: null == userAgent ? _self.userAgent : userAgent // ignore: cast_nullable_to_non_nullable
as String,deviceId: null == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
as String,nonce: freezed == nonce ? _self.nonce : nonce // ignore: cast_nullable_to_non_nullable
as String?,location: freezed == location ? _self.location : location // ignore: cast_nullable_to_non_nullable
as String?,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
@@ -425,10 +423,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, DateTime expiredAt, int stepRemain, int stepTotal, int failedAttempts, int platform, int type, List<String> blacklistFactors, List<dynamic> audiences, List<dynamic> scopes, String ipAddress, String userAgent, String deviceId, String? nonce, String? location, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, DateTime expiredAt, int stepRemain, int stepTotal, int failedAttempts, int type, List<String> blacklistFactors, List<dynamic> audiences, List<dynamic> scopes, String ipAddress, String userAgent, String? nonce, String? location, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnAuthChallenge() when $default != null:
return $default(_that.id,_that.expiredAt,_that.stepRemain,_that.stepTotal,_that.failedAttempts,_that.platform,_that.type,_that.blacklistFactors,_that.audiences,_that.scopes,_that.ipAddress,_that.userAgent,_that.deviceId,_that.nonce,_that.location,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return $default(_that.id,_that.expiredAt,_that.stepRemain,_that.stepTotal,_that.failedAttempts,_that.type,_that.blacklistFactors,_that.audiences,_that.scopes,_that.ipAddress,_that.userAgent,_that.nonce,_that.location,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return orElse();
}
@@ -446,10 +444,10 @@ return $default(_that.id,_that.expiredAt,_that.stepRemain,_that.stepTotal,_that.
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, DateTime expiredAt, int stepRemain, int stepTotal, int failedAttempts, int platform, int type, List<String> blacklistFactors, List<dynamic> audiences, List<dynamic> scopes, String ipAddress, String userAgent, String deviceId, String? nonce, String? location, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, DateTime expiredAt, int stepRemain, int stepTotal, int failedAttempts, int type, List<String> blacklistFactors, List<dynamic> audiences, List<dynamic> scopes, String ipAddress, String userAgent, String? nonce, String? location, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
switch (_that) {
case _SnAuthChallenge():
return $default(_that.id,_that.expiredAt,_that.stepRemain,_that.stepTotal,_that.failedAttempts,_that.platform,_that.type,_that.blacklistFactors,_that.audiences,_that.scopes,_that.ipAddress,_that.userAgent,_that.deviceId,_that.nonce,_that.location,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);}
return $default(_that.id,_that.expiredAt,_that.stepRemain,_that.stepTotal,_that.failedAttempts,_that.type,_that.blacklistFactors,_that.audiences,_that.scopes,_that.ipAddress,_that.userAgent,_that.nonce,_that.location,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);}
}
/// A variant of `when` that fallback to returning `null`
///
@@ -463,10 +461,10 @@ return $default(_that.id,_that.expiredAt,_that.stepRemain,_that.stepTotal,_that.
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, DateTime expiredAt, int stepRemain, int stepTotal, int failedAttempts, int platform, int type, List<String> blacklistFactors, List<dynamic> audiences, List<dynamic> scopes, String ipAddress, String userAgent, String deviceId, String? nonce, String? location, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, DateTime expiredAt, int stepRemain, int stepTotal, int failedAttempts, int type, List<String> blacklistFactors, List<dynamic> audiences, List<dynamic> scopes, String ipAddress, String userAgent, String? nonce, String? location, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
switch (_that) {
case _SnAuthChallenge() when $default != null:
return $default(_that.id,_that.expiredAt,_that.stepRemain,_that.stepTotal,_that.failedAttempts,_that.platform,_that.type,_that.blacklistFactors,_that.audiences,_that.scopes,_that.ipAddress,_that.userAgent,_that.deviceId,_that.nonce,_that.location,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return $default(_that.id,_that.expiredAt,_that.stepRemain,_that.stepTotal,_that.failedAttempts,_that.type,_that.blacklistFactors,_that.audiences,_that.scopes,_that.ipAddress,_that.userAgent,_that.nonce,_that.location,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return null;
}
@@ -478,7 +476,7 @@ return $default(_that.id,_that.expiredAt,_that.stepRemain,_that.stepTotal,_that.
@JsonSerializable()
class _SnAuthChallenge implements SnAuthChallenge {
const _SnAuthChallenge({required this.id, required this.expiredAt, required this.stepRemain, required this.stepTotal, required this.failedAttempts, required this.platform, required this.type, required final List<String> blacklistFactors, required final List<dynamic> audiences, required final List<dynamic> scopes, required this.ipAddress, required this.userAgent, required this.deviceId, required this.nonce, required this.location, required this.accountId, required this.createdAt, required this.updatedAt, required this.deletedAt}): _blacklistFactors = blacklistFactors,_audiences = audiences,_scopes = scopes;
const _SnAuthChallenge({required this.id, required this.expiredAt, required this.stepRemain, required this.stepTotal, required this.failedAttempts, required this.type, required final List<String> blacklistFactors, required final List<dynamic> audiences, required final List<dynamic> scopes, required this.ipAddress, required this.userAgent, required this.nonce, required this.location, required this.accountId, required this.createdAt, required this.updatedAt, required this.deletedAt}): _blacklistFactors = blacklistFactors,_audiences = audiences,_scopes = scopes;
factory _SnAuthChallenge.fromJson(Map<String, dynamic> json) => _$SnAuthChallengeFromJson(json);
@override final String id;
@@ -486,7 +484,6 @@ class _SnAuthChallenge implements SnAuthChallenge {
@override final int stepRemain;
@override final int stepTotal;
@override final int failedAttempts;
@override final int platform;
@override final int type;
final List<String> _blacklistFactors;
@override List<String> get blacklistFactors {
@@ -511,7 +508,6 @@ class _SnAuthChallenge implements SnAuthChallenge {
@override final String ipAddress;
@override final String userAgent;
@override final String deviceId;
@override final String? nonce;
@override final String? location;
@override final String accountId;
@@ -532,16 +528,16 @@ Map<String, dynamic> toJson() {
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnAuthChallenge&&(identical(other.id, id) || other.id == id)&&(identical(other.expiredAt, expiredAt) || other.expiredAt == expiredAt)&&(identical(other.stepRemain, stepRemain) || other.stepRemain == stepRemain)&&(identical(other.stepTotal, stepTotal) || other.stepTotal == stepTotal)&&(identical(other.failedAttempts, failedAttempts) || other.failedAttempts == failedAttempts)&&(identical(other.platform, platform) || other.platform == platform)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other._blacklistFactors, _blacklistFactors)&&const DeepCollectionEquality().equals(other._audiences, _audiences)&&const DeepCollectionEquality().equals(other._scopes, _scopes)&&(identical(other.ipAddress, ipAddress) || other.ipAddress == ipAddress)&&(identical(other.userAgent, userAgent) || other.userAgent == userAgent)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.nonce, nonce) || other.nonce == nonce)&&(identical(other.location, location) || other.location == location)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnAuthChallenge&&(identical(other.id, id) || other.id == id)&&(identical(other.expiredAt, expiredAt) || other.expiredAt == expiredAt)&&(identical(other.stepRemain, stepRemain) || other.stepRemain == stepRemain)&&(identical(other.stepTotal, stepTotal) || other.stepTotal == stepTotal)&&(identical(other.failedAttempts, failedAttempts) || other.failedAttempts == failedAttempts)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other._blacklistFactors, _blacklistFactors)&&const DeepCollectionEquality().equals(other._audiences, _audiences)&&const DeepCollectionEquality().equals(other._scopes, _scopes)&&(identical(other.ipAddress, ipAddress) || other.ipAddress == ipAddress)&&(identical(other.userAgent, userAgent) || other.userAgent == userAgent)&&(identical(other.nonce, nonce) || other.nonce == nonce)&&(identical(other.location, location) || other.location == location)&&(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.hashAll([runtimeType,id,expiredAt,stepRemain,stepTotal,failedAttempts,platform,type,const DeepCollectionEquality().hash(_blacklistFactors),const DeepCollectionEquality().hash(_audiences),const DeepCollectionEquality().hash(_scopes),ipAddress,userAgent,deviceId,nonce,location,accountId,createdAt,updatedAt,deletedAt]);
int get hashCode => Object.hash(runtimeType,id,expiredAt,stepRemain,stepTotal,failedAttempts,type,const DeepCollectionEquality().hash(_blacklistFactors),const DeepCollectionEquality().hash(_audiences),const DeepCollectionEquality().hash(_scopes),ipAddress,userAgent,nonce,location,accountId,createdAt,updatedAt,deletedAt);
@override
String toString() {
return 'SnAuthChallenge(id: $id, expiredAt: $expiredAt, stepRemain: $stepRemain, stepTotal: $stepTotal, failedAttempts: $failedAttempts, platform: $platform, type: $type, blacklistFactors: $blacklistFactors, audiences: $audiences, scopes: $scopes, ipAddress: $ipAddress, userAgent: $userAgent, deviceId: $deviceId, nonce: $nonce, location: $location, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
return 'SnAuthChallenge(id: $id, expiredAt: $expiredAt, stepRemain: $stepRemain, stepTotal: $stepTotal, failedAttempts: $failedAttempts, type: $type, blacklistFactors: $blacklistFactors, audiences: $audiences, scopes: $scopes, ipAddress: $ipAddress, userAgent: $userAgent, nonce: $nonce, location: $location, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
@@ -552,7 +548,7 @@ abstract mixin class _$SnAuthChallengeCopyWith<$Res> implements $SnAuthChallenge
factory _$SnAuthChallengeCopyWith(_SnAuthChallenge value, $Res Function(_SnAuthChallenge) _then) = __$SnAuthChallengeCopyWithImpl;
@override @useResult
$Res call({
String id, DateTime expiredAt, int stepRemain, int stepTotal, int failedAttempts, int platform, int type, List<String> blacklistFactors, List<dynamic> audiences, List<dynamic> scopes, String ipAddress, String userAgent, String deviceId, String? nonce, String? location, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
String id, DateTime expiredAt, int stepRemain, int stepTotal, int failedAttempts, int type, List<String> blacklistFactors, List<dynamic> audiences, List<dynamic> scopes, String ipAddress, String userAgent, String? nonce, String? location, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
@@ -569,21 +565,19 @@ class __$SnAuthChallengeCopyWithImpl<$Res>
/// Create a copy of SnAuthChallenge
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? expiredAt = null,Object? stepRemain = null,Object? stepTotal = null,Object? failedAttempts = null,Object? platform = null,Object? type = null,Object? blacklistFactors = null,Object? audiences = null,Object? scopes = null,Object? ipAddress = null,Object? userAgent = null,Object? deviceId = null,Object? nonce = freezed,Object? location = freezed,Object? accountId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? expiredAt = null,Object? stepRemain = null,Object? stepTotal = null,Object? failedAttempts = null,Object? type = null,Object? blacklistFactors = null,Object? audiences = null,Object? scopes = null,Object? ipAddress = null,Object? userAgent = null,Object? nonce = freezed,Object? location = freezed,Object? accountId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
return _then(_SnAuthChallenge(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,expiredAt: null == expiredAt ? _self.expiredAt : expiredAt // ignore: cast_nullable_to_non_nullable
as DateTime,stepRemain: null == stepRemain ? _self.stepRemain : stepRemain // ignore: cast_nullable_to_non_nullable
as int,stepTotal: null == stepTotal ? _self.stepTotal : stepTotal // ignore: cast_nullable_to_non_nullable
as int,failedAttempts: null == failedAttempts ? _self.failedAttempts : failedAttempts // ignore: cast_nullable_to_non_nullable
as int,platform: null == platform ? _self.platform : platform // ignore: cast_nullable_to_non_nullable
as int,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
as int,blacklistFactors: null == blacklistFactors ? _self._blacklistFactors : blacklistFactors // ignore: cast_nullable_to_non_nullable
as List<String>,audiences: null == audiences ? _self._audiences : audiences // ignore: cast_nullable_to_non_nullable
as List<dynamic>,scopes: null == scopes ? _self._scopes : scopes // ignore: cast_nullable_to_non_nullable
as List<dynamic>,ipAddress: null == ipAddress ? _self.ipAddress : ipAddress // ignore: cast_nullable_to_non_nullable
as String,userAgent: null == userAgent ? _self.userAgent : userAgent // ignore: cast_nullable_to_non_nullable
as String,deviceId: null == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
as String,nonce: freezed == nonce ? _self.nonce : nonce // ignore: cast_nullable_to_non_nullable
as String?,location: freezed == location ? _self.location : location // ignore: cast_nullable_to_non_nullable
as String?,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
@@ -1189,286 +1183,6 @@ as Map<String, dynamic>?,
}
/// @nodoc
mixin _$SnAuthDevice {
dynamic get label; String get userAgent; String get deviceId; int get platform; List<SnAuthSession> get sessions;// Not from backend, used for UI
bool get isCurrent;
/// Create a copy of SnAuthDevice
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$SnAuthDeviceCopyWith<SnAuthDevice> get copyWith => _$SnAuthDeviceCopyWithImpl<SnAuthDevice>(this as SnAuthDevice, _$identity);
/// Serializes this SnAuthDevice to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnAuthDevice&&const DeepCollectionEquality().equals(other.label, label)&&(identical(other.userAgent, userAgent) || other.userAgent == userAgent)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.platform, platform) || other.platform == platform)&&const DeepCollectionEquality().equals(other.sessions, sessions)&&(identical(other.isCurrent, isCurrent) || other.isCurrent == isCurrent));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(label),userAgent,deviceId,platform,const DeepCollectionEquality().hash(sessions),isCurrent);
@override
String toString() {
return 'SnAuthDevice(label: $label, userAgent: $userAgent, deviceId: $deviceId, platform: $platform, sessions: $sessions, isCurrent: $isCurrent)';
}
}
/// @nodoc
abstract mixin class $SnAuthDeviceCopyWith<$Res> {
factory $SnAuthDeviceCopyWith(SnAuthDevice value, $Res Function(SnAuthDevice) _then) = _$SnAuthDeviceCopyWithImpl;
@useResult
$Res call({
dynamic label, String userAgent, String deviceId, int platform, List<SnAuthSession> sessions, bool isCurrent
});
}
/// @nodoc
class _$SnAuthDeviceCopyWithImpl<$Res>
implements $SnAuthDeviceCopyWith<$Res> {
_$SnAuthDeviceCopyWithImpl(this._self, this._then);
final SnAuthDevice _self;
final $Res Function(SnAuthDevice) _then;
/// Create a copy of SnAuthDevice
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? label = freezed,Object? userAgent = null,Object? deviceId = null,Object? platform = null,Object? sessions = null,Object? isCurrent = null,}) {
return _then(_self.copyWith(
label: freezed == label ? _self.label : label // ignore: cast_nullable_to_non_nullable
as dynamic,userAgent: null == userAgent ? _self.userAgent : userAgent // ignore: cast_nullable_to_non_nullable
as String,deviceId: null == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
as String,platform: null == platform ? _self.platform : platform // ignore: cast_nullable_to_non_nullable
as int,sessions: null == sessions ? _self.sessions : sessions // ignore: cast_nullable_to_non_nullable
as List<SnAuthSession>,isCurrent: null == isCurrent ? _self.isCurrent : isCurrent // ignore: cast_nullable_to_non_nullable
as bool,
));
}
}
/// Adds pattern-matching-related methods to [SnAuthDevice].
extension SnAuthDevicePatterns on SnAuthDevice {
/// 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( _SnAuthDevice value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _SnAuthDevice() 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( _SnAuthDevice value) $default,){
final _that = this;
switch (_that) {
case _SnAuthDevice():
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( _SnAuthDevice value)? $default,){
final _that = this;
switch (_that) {
case _SnAuthDevice() 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( dynamic label, String userAgent, String deviceId, int platform, List<SnAuthSession> sessions, bool isCurrent)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnAuthDevice() when $default != null:
return $default(_that.label,_that.userAgent,_that.deviceId,_that.platform,_that.sessions,_that.isCurrent);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( dynamic label, String userAgent, String deviceId, int platform, List<SnAuthSession> sessions, bool isCurrent) $default,) {final _that = this;
switch (_that) {
case _SnAuthDevice():
return $default(_that.label,_that.userAgent,_that.deviceId,_that.platform,_that.sessions,_that.isCurrent);}
}
/// 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( dynamic label, String userAgent, String deviceId, int platform, List<SnAuthSession> sessions, bool isCurrent)? $default,) {final _that = this;
switch (_that) {
case _SnAuthDevice() when $default != null:
return $default(_that.label,_that.userAgent,_that.deviceId,_that.platform,_that.sessions,_that.isCurrent);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _SnAuthDevice implements SnAuthDevice {
const _SnAuthDevice({required this.label, required this.userAgent, required this.deviceId, required this.platform, required final List<SnAuthSession> sessions, this.isCurrent = false}): _sessions = sessions;
factory _SnAuthDevice.fromJson(Map<String, dynamic> json) => _$SnAuthDeviceFromJson(json);
@override final dynamic label;
@override final String userAgent;
@override final String deviceId;
@override final int platform;
final List<SnAuthSession> _sessions;
@override List<SnAuthSession> get sessions {
if (_sessions is EqualUnmodifiableListView) return _sessions;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_sessions);
}
// Not from backend, used for UI
@override@JsonKey() final bool isCurrent;
/// Create a copy of SnAuthDevice
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$SnAuthDeviceCopyWith<_SnAuthDevice> get copyWith => __$SnAuthDeviceCopyWithImpl<_SnAuthDevice>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$SnAuthDeviceToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnAuthDevice&&const DeepCollectionEquality().equals(other.label, label)&&(identical(other.userAgent, userAgent) || other.userAgent == userAgent)&&(identical(other.deviceId, deviceId) || other.deviceId == deviceId)&&(identical(other.platform, platform) || other.platform == platform)&&const DeepCollectionEquality().equals(other._sessions, _sessions)&&(identical(other.isCurrent, isCurrent) || other.isCurrent == isCurrent));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(label),userAgent,deviceId,platform,const DeepCollectionEquality().hash(_sessions),isCurrent);
@override
String toString() {
return 'SnAuthDevice(label: $label, userAgent: $userAgent, deviceId: $deviceId, platform: $platform, sessions: $sessions, isCurrent: $isCurrent)';
}
}
/// @nodoc
abstract mixin class _$SnAuthDeviceCopyWith<$Res> implements $SnAuthDeviceCopyWith<$Res> {
factory _$SnAuthDeviceCopyWith(_SnAuthDevice value, $Res Function(_SnAuthDevice) _then) = __$SnAuthDeviceCopyWithImpl;
@override @useResult
$Res call({
dynamic label, String userAgent, String deviceId, int platform, List<SnAuthSession> sessions, bool isCurrent
});
}
/// @nodoc
class __$SnAuthDeviceCopyWithImpl<$Res>
implements _$SnAuthDeviceCopyWith<$Res> {
__$SnAuthDeviceCopyWithImpl(this._self, this._then);
final _SnAuthDevice _self;
final $Res Function(_SnAuthDevice) _then;
/// Create a copy of SnAuthDevice
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? label = freezed,Object? userAgent = null,Object? deviceId = null,Object? platform = null,Object? sessions = null,Object? isCurrent = null,}) {
return _then(_SnAuthDevice(
label: freezed == label ? _self.label : label // ignore: cast_nullable_to_non_nullable
as dynamic,userAgent: null == userAgent ? _self.userAgent : userAgent // ignore: cast_nullable_to_non_nullable
as String,deviceId: null == deviceId ? _self.deviceId : deviceId // ignore: cast_nullable_to_non_nullable
as String,platform: null == platform ? _self.platform : platform // ignore: cast_nullable_to_non_nullable
as int,sessions: null == sessions ? _self._sessions : sessions // ignore: cast_nullable_to_non_nullable
as List<SnAuthSession>,isCurrent: null == isCurrent ? _self.isCurrent : isCurrent // ignore: cast_nullable_to_non_nullable
as bool,
));
}
}
/// @nodoc
mixin _$SnAccountConnection {

View File

@@ -20,7 +20,6 @@ _SnAuthChallenge _$SnAuthChallengeFromJson(Map<String, dynamic> json) =>
stepRemain: (json['step_remain'] as num).toInt(),
stepTotal: (json['step_total'] as num).toInt(),
failedAttempts: (json['failed_attempts'] as num).toInt(),
platform: (json['platform'] as num).toInt(),
type: (json['type'] as num).toInt(),
blacklistFactors:
(json['blacklist_factors'] as List<dynamic>)
@@ -30,7 +29,6 @@ _SnAuthChallenge _$SnAuthChallengeFromJson(Map<String, dynamic> json) =>
scopes: json['scopes'] as List<dynamic>,
ipAddress: json['ip_address'] as String,
userAgent: json['user_agent'] as String,
deviceId: json['device_id'] as String,
nonce: json['nonce'] as String?,
location: json['location'] as String?,
accountId: json['account_id'] as String,
@@ -49,14 +47,12 @@ Map<String, dynamic> _$SnAuthChallengeToJson(_SnAuthChallenge instance) =>
'step_remain': instance.stepRemain,
'step_total': instance.stepTotal,
'failed_attempts': instance.failedAttempts,
'platform': instance.platform,
'type': instance.type,
'blacklist_factors': instance.blacklistFactors,
'audiences': instance.audiences,
'scopes': instance.scopes,
'ip_address': instance.ipAddress,
'user_agent': instance.userAgent,
'device_id': instance.deviceId,
'nonce': instance.nonce,
'location': instance.location,
'account_id': instance.accountId,
@@ -133,29 +129,6 @@ Map<String, dynamic> _$SnAuthFactorToJson(_SnAuthFactor instance) =>
'created_response': instance.createdResponse,
};
_SnAuthDevice _$SnAuthDeviceFromJson(Map<String, dynamic> json) =>
_SnAuthDevice(
label: json['label'],
userAgent: json['user_agent'] as String,
deviceId: json['device_id'] as String,
platform: (json['platform'] as num).toInt(),
sessions:
(json['sessions'] as List<dynamic>)
.map((e) => SnAuthSession.fromJson(e as Map<String, dynamic>))
.toList(),
isCurrent: json['is_current'] as bool? ?? false,
);
Map<String, dynamic> _$SnAuthDeviceToJson(_SnAuthDevice instance) =>
<String, dynamic>{
'label': instance.label,
'user_agent': instance.userAgent,
'device_id': instance.deviceId,
'platform': instance.platform,
'sessions': instance.sessions.map((e) => e.toJson()).toList(),
'is_current': instance.isCurrent,
};
_SnAccountConnection _$SnAccountConnectionFromJson(Map<String, dynamic> json) =>
_SnAccountConnection(
id: json['id'] as String,

63
lib/models/bot.dart Normal file
View File

@@ -0,0 +1,63 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:island/models/account.dart';
import 'package:island/models/developer.dart';
part 'bot.freezed.dart';
part 'bot.g.dart';
@freezed
sealed class Bot with _$Bot {
const factory Bot({
required String id,
required String slug,
required bool isActive,
required String projectId,
required DateTime createdAt,
required DateTime updatedAt,
required SnAccount account,
SnDeveloper? developer,
}) = _Bot;
factory Bot.fromJson(Map<String, dynamic> json) => _$BotFromJson(json);
}
@freezed
sealed class BotConfig with _$BotConfig {
const factory BotConfig({
@Default(false) bool isPublic,
@Default(false) bool isInteractive,
@Default([]) List<String> allowedRealms,
@Default([]) List<String> allowedChatTypes,
@Default({}) Map<String, dynamic> metadata,
}) = _BotConfig;
factory BotConfig.fromJson(Map<String, dynamic> json) =>
_$BotConfigFromJson(json);
}
@freezed
sealed class BotLinks with _$BotLinks {
const factory BotLinks({
String? website,
String? documentation,
String? privacyPolicy,
String? termsOfService,
}) = _BotLinks;
factory BotLinks.fromJson(Map<String, dynamic> json) =>
_$BotLinksFromJson(json);
}
@freezed
sealed class BotSecret with _$BotSecret {
const factory BotSecret({
@Default('') String id,
@Default('') String secret,
String? description,
DateTime? expiredAt,
@Default('') String botId,
}) = _BotSecret;
factory BotSecret.fromJson(Map<String, dynamic> json) =>
_$BotSecretFromJson(json);
}

1156
lib/models/bot.freezed.dart Normal file

File diff suppressed because it is too large Load Diff

91
lib/models/bot.g.dart Normal file
View File

@@ -0,0 +1,91 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'bot.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_Bot _$BotFromJson(Map<String, dynamic> json) => _Bot(
id: json['id'] as String,
slug: json['slug'] as String,
isActive: json['is_active'] as bool,
projectId: json['project_id'] as String,
createdAt: DateTime.parse(json['created_at'] as String),
updatedAt: DateTime.parse(json['updated_at'] as String),
account: SnAccount.fromJson(json['account'] as Map<String, dynamic>),
developer:
json['developer'] == null
? null
: SnDeveloper.fromJson(json['developer'] as Map<String, dynamic>),
);
Map<String, dynamic> _$BotToJson(_Bot instance) => <String, dynamic>{
'id': instance.id,
'slug': instance.slug,
'is_active': instance.isActive,
'project_id': instance.projectId,
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'account': instance.account.toJson(),
'developer': instance.developer?.toJson(),
};
_BotConfig _$BotConfigFromJson(Map<String, dynamic> json) => _BotConfig(
isPublic: json['is_public'] as bool? ?? false,
isInteractive: json['is_interactive'] as bool? ?? false,
allowedRealms:
(json['allowed_realms'] as List<dynamic>?)
?.map((e) => e as String)
.toList() ??
const [],
allowedChatTypes:
(json['allowed_chat_types'] as List<dynamic>?)
?.map((e) => e as String)
.toList() ??
const [],
metadata: json['metadata'] as Map<String, dynamic>? ?? const {},
);
Map<String, dynamic> _$BotConfigToJson(_BotConfig instance) =>
<String, dynamic>{
'is_public': instance.isPublic,
'is_interactive': instance.isInteractive,
'allowed_realms': instance.allowedRealms,
'allowed_chat_types': instance.allowedChatTypes,
'metadata': instance.metadata,
};
_BotLinks _$BotLinksFromJson(Map<String, dynamic> json) => _BotLinks(
website: json['website'] as String?,
documentation: json['documentation'] as String?,
privacyPolicy: json['privacy_policy'] as String?,
termsOfService: json['terms_of_service'] as String?,
);
Map<String, dynamic> _$BotLinksToJson(_BotLinks instance) => <String, dynamic>{
'website': instance.website,
'documentation': instance.documentation,
'privacy_policy': instance.privacyPolicy,
'terms_of_service': instance.termsOfService,
};
_BotSecret _$BotSecretFromJson(Map<String, dynamic> json) => _BotSecret(
id: json['id'] as String? ?? '',
secret: json['secret'] as String? ?? '',
description: json['description'] as String?,
expiredAt:
json['expired_at'] == null
? null
: DateTime.parse(json['expired_at'] as String),
botId: json['bot_id'] as String? ?? '',
);
Map<String, dynamic> _$BotSecretToJson(_BotSecret instance) =>
<String, dynamic>{
'id': instance.id,
'secret': instance.secret,
'description': instance.description,
'expired_at': instance.expiredAt?.toIso8601String(),
'bot_id': instance.botId,
};

20
lib/models/bot_key.dart Normal file
View File

@@ -0,0 +1,20 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'bot_key.freezed.dart';
part 'bot_key.g.dart';
@freezed
sealed class SnAccountApiKey with _$SnAccountApiKey {
const factory SnAccountApiKey({
required String id,
required String label,
required String accountId,
required String sessionId,
required DateTime createdAt,
required DateTime updatedAt,
String? key,
}) = _SnAccountApiKey;
factory SnAccountApiKey.fromJson(Map<String, dynamic> json) =>
_$SnAccountApiKeyFromJson(json);
}

View File

@@ -0,0 +1,289 @@
// 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 'bot_key.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$SnAccountApiKey {
String get id; String get label; String get accountId; String get sessionId; DateTime get createdAt; DateTime get updatedAt; String? get key;
/// Create a copy of SnAccountApiKey
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$SnAccountApiKeyCopyWith<SnAccountApiKey> get copyWith => _$SnAccountApiKeyCopyWithImpl<SnAccountApiKey>(this as SnAccountApiKey, _$identity);
/// Serializes this SnAccountApiKey to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnAccountApiKey&&(identical(other.id, id) || other.id == id)&&(identical(other.label, label) || other.label == label)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.sessionId, sessionId) || other.sessionId == sessionId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.key, key) || other.key == key));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,label,accountId,sessionId,createdAt,updatedAt,key);
@override
String toString() {
return 'SnAccountApiKey(id: $id, label: $label, accountId: $accountId, sessionId: $sessionId, createdAt: $createdAt, updatedAt: $updatedAt, key: $key)';
}
}
/// @nodoc
abstract mixin class $SnAccountApiKeyCopyWith<$Res> {
factory $SnAccountApiKeyCopyWith(SnAccountApiKey value, $Res Function(SnAccountApiKey) _then) = _$SnAccountApiKeyCopyWithImpl;
@useResult
$Res call({
String id, String label, String accountId, String sessionId, DateTime createdAt, DateTime updatedAt, String? key
});
}
/// @nodoc
class _$SnAccountApiKeyCopyWithImpl<$Res>
implements $SnAccountApiKeyCopyWith<$Res> {
_$SnAccountApiKeyCopyWithImpl(this._self, this._then);
final SnAccountApiKey _self;
final $Res Function(SnAccountApiKey) _then;
/// Create a copy of SnAccountApiKey
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? label = null,Object? accountId = null,Object? sessionId = null,Object? createdAt = null,Object? updatedAt = null,Object? key = freezed,}) {
return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,label: null == label ? _self.label : label // ignore: cast_nullable_to_non_nullable
as String,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
as String,sessionId: null == sessionId ? _self.sessionId : sessionId // 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,key: freezed == key ? _self.key : key // ignore: cast_nullable_to_non_nullable
as String?,
));
}
}
/// Adds pattern-matching-related methods to [SnAccountApiKey].
extension SnAccountApiKeyPatterns on SnAccountApiKey {
/// 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( _SnAccountApiKey value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _SnAccountApiKey() 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( _SnAccountApiKey value) $default,){
final _that = this;
switch (_that) {
case _SnAccountApiKey():
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( _SnAccountApiKey value)? $default,){
final _that = this;
switch (_that) {
case _SnAccountApiKey() 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 label, String accountId, String sessionId, DateTime createdAt, DateTime updatedAt, String? key)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnAccountApiKey() when $default != null:
return $default(_that.id,_that.label,_that.accountId,_that.sessionId,_that.createdAt,_that.updatedAt,_that.key);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 label, String accountId, String sessionId, DateTime createdAt, DateTime updatedAt, String? key) $default,) {final _that = this;
switch (_that) {
case _SnAccountApiKey():
return $default(_that.id,_that.label,_that.accountId,_that.sessionId,_that.createdAt,_that.updatedAt,_that.key);}
}
/// 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 label, String accountId, String sessionId, DateTime createdAt, DateTime updatedAt, String? key)? $default,) {final _that = this;
switch (_that) {
case _SnAccountApiKey() when $default != null:
return $default(_that.id,_that.label,_that.accountId,_that.sessionId,_that.createdAt,_that.updatedAt,_that.key);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _SnAccountApiKey implements SnAccountApiKey {
const _SnAccountApiKey({required this.id, required this.label, required this.accountId, required this.sessionId, required this.createdAt, required this.updatedAt, this.key});
factory _SnAccountApiKey.fromJson(Map<String, dynamic> json) => _$SnAccountApiKeyFromJson(json);
@override final String id;
@override final String label;
@override final String accountId;
@override final String sessionId;
@override final DateTime createdAt;
@override final DateTime updatedAt;
@override final String? key;
/// Create a copy of SnAccountApiKey
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$SnAccountApiKeyCopyWith<_SnAccountApiKey> get copyWith => __$SnAccountApiKeyCopyWithImpl<_SnAccountApiKey>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$SnAccountApiKeyToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnAccountApiKey&&(identical(other.id, id) || other.id == id)&&(identical(other.label, label) || other.label == label)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.sessionId, sessionId) || other.sessionId == sessionId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.key, key) || other.key == key));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,label,accountId,sessionId,createdAt,updatedAt,key);
@override
String toString() {
return 'SnAccountApiKey(id: $id, label: $label, accountId: $accountId, sessionId: $sessionId, createdAt: $createdAt, updatedAt: $updatedAt, key: $key)';
}
}
/// @nodoc
abstract mixin class _$SnAccountApiKeyCopyWith<$Res> implements $SnAccountApiKeyCopyWith<$Res> {
factory _$SnAccountApiKeyCopyWith(_SnAccountApiKey value, $Res Function(_SnAccountApiKey) _then) = __$SnAccountApiKeyCopyWithImpl;
@override @useResult
$Res call({
String id, String label, String accountId, String sessionId, DateTime createdAt, DateTime updatedAt, String? key
});
}
/// @nodoc
class __$SnAccountApiKeyCopyWithImpl<$Res>
implements _$SnAccountApiKeyCopyWith<$Res> {
__$SnAccountApiKeyCopyWithImpl(this._self, this._then);
final _SnAccountApiKey _self;
final $Res Function(_SnAccountApiKey) _then;
/// Create a copy of SnAccountApiKey
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? label = null,Object? accountId = null,Object? sessionId = null,Object? createdAt = null,Object? updatedAt = null,Object? key = freezed,}) {
return _then(_SnAccountApiKey(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,label: null == label ? _self.label : label // ignore: cast_nullable_to_non_nullable
as String,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
as String,sessionId: null == sessionId ? _self.sessionId : sessionId // 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,key: freezed == key ? _self.key : key // ignore: cast_nullable_to_non_nullable
as String?,
));
}
}
// dart format on

29
lib/models/bot_key.g.dart Normal file
View File

@@ -0,0 +1,29 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'bot_key.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_SnAccountApiKey _$SnAccountApiKeyFromJson(Map<String, dynamic> json) =>
_SnAccountApiKey(
id: json['id'] as String,
label: json['label'] as String,
accountId: json['account_id'] as String,
sessionId: json['session_id'] as String,
createdAt: DateTime.parse(json['created_at'] as String),
updatedAt: DateTime.parse(json['updated_at'] as String),
key: json['key'] as String?,
);
Map<String, dynamic> _$SnAccountApiKeyToJson(_SnAccountApiKey instance) =>
<String, dynamic>{
'id': instance.id,
'label': instance.label,
'account_id': instance.accountId,
'session_id': instance.sessionId,
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'key': instance.key,
};

View File

@@ -1,7 +1,7 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:island/models/file.dart';
import 'package:island/models/realm.dart';
import 'package:island/models/user.dart';
import 'package:island/models/account.dart';
part 'chat.freezed.dart';
part 'chat.g.dart';
@@ -91,6 +91,7 @@ sealed class SnChatMember with _$SnChatMember {
required DateTime? breakUntil,
required DateTime? timeoutUntil,
required bool isBot,
required SnAccountStatus? status,
// Frontend data
DateTime? lastTyped,
}) = _SnChatMember;
@@ -103,7 +104,7 @@ sealed class SnChatMember with _$SnChatMember {
sealed class SnChatSummary with _$SnChatSummary {
const factory SnChatSummary({
required int unreadCount,
required SnChatMessage lastMessage,
required SnChatMessage? lastMessage,
}) = _SnChatSummary;
factory SnChatSummary.fromJson(Map<String, dynamic> json) =>
@@ -162,8 +163,6 @@ sealed class CallParticipant with _$CallParticipant {
required String identity,
required String name,
required DateTime joinedAt,
required String? accountId,
required SnChatMember? profile,
}) = _CallParticipant;
factory CallParticipant.fromJson(Map<String, dynamic> json) =>

View File

@@ -1037,7 +1037,7 @@ $SnChatMemberCopyWith<$Res> get sender {
/// @nodoc
mixin _$SnChatMember {
DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; String get id; String get chatRoomId; SnChatRoom? get chatRoom; String get accountId; SnAccount get account; String? get nick; int get role; int get notify; DateTime? get joinedAt; DateTime? get breakUntil; DateTime? get timeoutUntil; bool get isBot;// Frontend data
DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; String get id; String get chatRoomId; SnChatRoom? get chatRoom; String get accountId; SnAccount get account; String? get nick; int get role; int get notify; DateTime? get joinedAt; DateTime? get breakUntil; DateTime? get timeoutUntil; bool get isBot; SnAccountStatus? get status;// Frontend data
DateTime? get lastTyped;
/// Create a copy of SnChatMember
/// with the given fields replaced by the non-null parameter values.
@@ -1051,16 +1051,16 @@ $SnChatMemberCopyWith<SnChatMember> get copyWith => _$SnChatMemberCopyWithImpl<S
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnChatMember&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.id, id) || other.id == id)&&(identical(other.chatRoomId, chatRoomId) || other.chatRoomId == chatRoomId)&&(identical(other.chatRoom, chatRoom) || other.chatRoom == chatRoom)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.account, account) || other.account == account)&&(identical(other.nick, nick) || other.nick == nick)&&(identical(other.role, role) || other.role == role)&&(identical(other.notify, notify) || other.notify == notify)&&(identical(other.joinedAt, joinedAt) || other.joinedAt == joinedAt)&&(identical(other.breakUntil, breakUntil) || other.breakUntil == breakUntil)&&(identical(other.timeoutUntil, timeoutUntil) || other.timeoutUntil == timeoutUntil)&&(identical(other.isBot, isBot) || other.isBot == isBot)&&(identical(other.lastTyped, lastTyped) || other.lastTyped == lastTyped));
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnChatMember&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.id, id) || other.id == id)&&(identical(other.chatRoomId, chatRoomId) || other.chatRoomId == chatRoomId)&&(identical(other.chatRoom, chatRoom) || other.chatRoom == chatRoom)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.account, account) || other.account == account)&&(identical(other.nick, nick) || other.nick == nick)&&(identical(other.role, role) || other.role == role)&&(identical(other.notify, notify) || other.notify == notify)&&(identical(other.joinedAt, joinedAt) || other.joinedAt == joinedAt)&&(identical(other.breakUntil, breakUntil) || other.breakUntil == breakUntil)&&(identical(other.timeoutUntil, timeoutUntil) || other.timeoutUntil == timeoutUntil)&&(identical(other.isBot, isBot) || other.isBot == isBot)&&(identical(other.status, status) || other.status == status)&&(identical(other.lastTyped, lastTyped) || other.lastTyped == lastTyped));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,createdAt,updatedAt,deletedAt,id,chatRoomId,chatRoom,accountId,account,nick,role,notify,joinedAt,breakUntil,timeoutUntil,isBot,lastTyped);
int get hashCode => Object.hash(runtimeType,createdAt,updatedAt,deletedAt,id,chatRoomId,chatRoom,accountId,account,nick,role,notify,joinedAt,breakUntil,timeoutUntil,isBot,status,lastTyped);
@override
String toString() {
return 'SnChatMember(createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, id: $id, chatRoomId: $chatRoomId, chatRoom: $chatRoom, accountId: $accountId, account: $account, nick: $nick, role: $role, notify: $notify, joinedAt: $joinedAt, breakUntil: $breakUntil, timeoutUntil: $timeoutUntil, isBot: $isBot, lastTyped: $lastTyped)';
return 'SnChatMember(createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, id: $id, chatRoomId: $chatRoomId, chatRoom: $chatRoom, accountId: $accountId, account: $account, nick: $nick, role: $role, notify: $notify, joinedAt: $joinedAt, breakUntil: $breakUntil, timeoutUntil: $timeoutUntil, isBot: $isBot, status: $status, lastTyped: $lastTyped)';
}
@@ -1071,11 +1071,11 @@ abstract mixin class $SnChatMemberCopyWith<$Res> {
factory $SnChatMemberCopyWith(SnChatMember value, $Res Function(SnChatMember) _then) = _$SnChatMemberCopyWithImpl;
@useResult
$Res call({
DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String chatRoomId, SnChatRoom? chatRoom, String accountId, SnAccount account, String? nick, int role, int notify, DateTime? joinedAt, DateTime? breakUntil, DateTime? timeoutUntil, bool isBot, DateTime? lastTyped
DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String chatRoomId, SnChatRoom? chatRoom, String accountId, SnAccount account, String? nick, int role, int notify, DateTime? joinedAt, DateTime? breakUntil, DateTime? timeoutUntil, bool isBot, SnAccountStatus? status, DateTime? lastTyped
});
$SnChatRoomCopyWith<$Res>? get chatRoom;$SnAccountCopyWith<$Res> get account;
$SnChatRoomCopyWith<$Res>? get chatRoom;$SnAccountCopyWith<$Res> get account;$SnAccountStatusCopyWith<$Res>? get status;
}
/// @nodoc
@@ -1088,7 +1088,7 @@ class _$SnChatMemberCopyWithImpl<$Res>
/// Create a copy of SnChatMember
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? id = null,Object? chatRoomId = null,Object? chatRoom = freezed,Object? accountId = null,Object? account = null,Object? nick = freezed,Object? role = null,Object? notify = null,Object? joinedAt = freezed,Object? breakUntil = freezed,Object? timeoutUntil = freezed,Object? isBot = null,Object? lastTyped = freezed,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? id = null,Object? chatRoomId = null,Object? chatRoom = freezed,Object? accountId = null,Object? account = null,Object? nick = freezed,Object? role = null,Object? notify = null,Object? joinedAt = freezed,Object? breakUntil = freezed,Object? timeoutUntil = freezed,Object? isBot = null,Object? status = freezed,Object? lastTyped = freezed,}) {
return _then(_self.copyWith(
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
@@ -1105,7 +1105,8 @@ as int,joinedAt: freezed == joinedAt ? _self.joinedAt : joinedAt // ignore: cast
as DateTime?,breakUntil: freezed == breakUntil ? _self.breakUntil : breakUntil // ignore: cast_nullable_to_non_nullable
as DateTime?,timeoutUntil: freezed == timeoutUntil ? _self.timeoutUntil : timeoutUntil // ignore: cast_nullable_to_non_nullable
as DateTime?,isBot: null == isBot ? _self.isBot : isBot // ignore: cast_nullable_to_non_nullable
as bool,lastTyped: freezed == lastTyped ? _self.lastTyped : lastTyped // ignore: cast_nullable_to_non_nullable
as bool,status: freezed == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
as SnAccountStatus?,lastTyped: freezed == lastTyped ? _self.lastTyped : lastTyped // ignore: cast_nullable_to_non_nullable
as DateTime?,
));
}
@@ -1130,6 +1131,18 @@ $SnAccountCopyWith<$Res> get account {
return $SnAccountCopyWith<$Res>(_self.account, (value) {
return _then(_self.copyWith(account: value));
});
}/// Create a copy of SnChatMember
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnAccountStatusCopyWith<$Res>? get status {
if (_self.status == null) {
return null;
}
return $SnAccountStatusCopyWith<$Res>(_self.status!, (value) {
return _then(_self.copyWith(status: value));
});
}
}
@@ -1209,10 +1222,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String chatRoomId, SnChatRoom? chatRoom, String accountId, SnAccount account, String? nick, int role, int notify, DateTime? joinedAt, DateTime? breakUntil, DateTime? timeoutUntil, bool isBot, DateTime? lastTyped)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String chatRoomId, SnChatRoom? chatRoom, String accountId, SnAccount account, String? nick, int role, int notify, DateTime? joinedAt, DateTime? breakUntil, DateTime? timeoutUntil, bool isBot, SnAccountStatus? status, DateTime? lastTyped)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnChatMember() when $default != null:
return $default(_that.createdAt,_that.updatedAt,_that.deletedAt,_that.id,_that.chatRoomId,_that.chatRoom,_that.accountId,_that.account,_that.nick,_that.role,_that.notify,_that.joinedAt,_that.breakUntil,_that.timeoutUntil,_that.isBot,_that.lastTyped);case _:
return $default(_that.createdAt,_that.updatedAt,_that.deletedAt,_that.id,_that.chatRoomId,_that.chatRoom,_that.accountId,_that.account,_that.nick,_that.role,_that.notify,_that.joinedAt,_that.breakUntil,_that.timeoutUntil,_that.isBot,_that.status,_that.lastTyped);case _:
return orElse();
}
@@ -1230,10 +1243,10 @@ return $default(_that.createdAt,_that.updatedAt,_that.deletedAt,_that.id,_that.c
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String chatRoomId, SnChatRoom? chatRoom, String accountId, SnAccount account, String? nick, int role, int notify, DateTime? joinedAt, DateTime? breakUntil, DateTime? timeoutUntil, bool isBot, DateTime? lastTyped) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String chatRoomId, SnChatRoom? chatRoom, String accountId, SnAccount account, String? nick, int role, int notify, DateTime? joinedAt, DateTime? breakUntil, DateTime? timeoutUntil, bool isBot, SnAccountStatus? status, DateTime? lastTyped) $default,) {final _that = this;
switch (_that) {
case _SnChatMember():
return $default(_that.createdAt,_that.updatedAt,_that.deletedAt,_that.id,_that.chatRoomId,_that.chatRoom,_that.accountId,_that.account,_that.nick,_that.role,_that.notify,_that.joinedAt,_that.breakUntil,_that.timeoutUntil,_that.isBot,_that.lastTyped);}
return $default(_that.createdAt,_that.updatedAt,_that.deletedAt,_that.id,_that.chatRoomId,_that.chatRoom,_that.accountId,_that.account,_that.nick,_that.role,_that.notify,_that.joinedAt,_that.breakUntil,_that.timeoutUntil,_that.isBot,_that.status,_that.lastTyped);}
}
/// A variant of `when` that fallback to returning `null`
///
@@ -1247,10 +1260,10 @@ return $default(_that.createdAt,_that.updatedAt,_that.deletedAt,_that.id,_that.c
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String chatRoomId, SnChatRoom? chatRoom, String accountId, SnAccount account, String? nick, int role, int notify, DateTime? joinedAt, DateTime? breakUntil, DateTime? timeoutUntil, bool isBot, DateTime? lastTyped)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String chatRoomId, SnChatRoom? chatRoom, String accountId, SnAccount account, String? nick, int role, int notify, DateTime? joinedAt, DateTime? breakUntil, DateTime? timeoutUntil, bool isBot, SnAccountStatus? status, DateTime? lastTyped)? $default,) {final _that = this;
switch (_that) {
case _SnChatMember() when $default != null:
return $default(_that.createdAt,_that.updatedAt,_that.deletedAt,_that.id,_that.chatRoomId,_that.chatRoom,_that.accountId,_that.account,_that.nick,_that.role,_that.notify,_that.joinedAt,_that.breakUntil,_that.timeoutUntil,_that.isBot,_that.lastTyped);case _:
return $default(_that.createdAt,_that.updatedAt,_that.deletedAt,_that.id,_that.chatRoomId,_that.chatRoom,_that.accountId,_that.account,_that.nick,_that.role,_that.notify,_that.joinedAt,_that.breakUntil,_that.timeoutUntil,_that.isBot,_that.status,_that.lastTyped);case _:
return null;
}
@@ -1262,7 +1275,7 @@ return $default(_that.createdAt,_that.updatedAt,_that.deletedAt,_that.id,_that.c
@JsonSerializable()
class _SnChatMember implements SnChatMember {
const _SnChatMember({required this.createdAt, required this.updatedAt, required this.deletedAt, required this.id, required this.chatRoomId, required this.chatRoom, required this.accountId, required this.account, required this.nick, required this.role, required this.notify, required this.joinedAt, required this.breakUntil, required this.timeoutUntil, required this.isBot, this.lastTyped});
const _SnChatMember({required this.createdAt, required this.updatedAt, required this.deletedAt, required this.id, required this.chatRoomId, required this.chatRoom, required this.accountId, required this.account, required this.nick, required this.role, required this.notify, required this.joinedAt, required this.breakUntil, required this.timeoutUntil, required this.isBot, required this.status, this.lastTyped});
factory _SnChatMember.fromJson(Map<String, dynamic> json) => _$SnChatMemberFromJson(json);
@override final DateTime createdAt;
@@ -1280,6 +1293,7 @@ class _SnChatMember implements SnChatMember {
@override final DateTime? breakUntil;
@override final DateTime? timeoutUntil;
@override final bool isBot;
@override final SnAccountStatus? status;
// Frontend data
@override final DateTime? lastTyped;
@@ -1296,16 +1310,16 @@ Map<String, dynamic> toJson() {
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnChatMember&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.id, id) || other.id == id)&&(identical(other.chatRoomId, chatRoomId) || other.chatRoomId == chatRoomId)&&(identical(other.chatRoom, chatRoom) || other.chatRoom == chatRoom)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.account, account) || other.account == account)&&(identical(other.nick, nick) || other.nick == nick)&&(identical(other.role, role) || other.role == role)&&(identical(other.notify, notify) || other.notify == notify)&&(identical(other.joinedAt, joinedAt) || other.joinedAt == joinedAt)&&(identical(other.breakUntil, breakUntil) || other.breakUntil == breakUntil)&&(identical(other.timeoutUntil, timeoutUntil) || other.timeoutUntil == timeoutUntil)&&(identical(other.isBot, isBot) || other.isBot == isBot)&&(identical(other.lastTyped, lastTyped) || other.lastTyped == lastTyped));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnChatMember&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.id, id) || other.id == id)&&(identical(other.chatRoomId, chatRoomId) || other.chatRoomId == chatRoomId)&&(identical(other.chatRoom, chatRoom) || other.chatRoom == chatRoom)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.account, account) || other.account == account)&&(identical(other.nick, nick) || other.nick == nick)&&(identical(other.role, role) || other.role == role)&&(identical(other.notify, notify) || other.notify == notify)&&(identical(other.joinedAt, joinedAt) || other.joinedAt == joinedAt)&&(identical(other.breakUntil, breakUntil) || other.breakUntil == breakUntil)&&(identical(other.timeoutUntil, timeoutUntil) || other.timeoutUntil == timeoutUntil)&&(identical(other.isBot, isBot) || other.isBot == isBot)&&(identical(other.status, status) || other.status == status)&&(identical(other.lastTyped, lastTyped) || other.lastTyped == lastTyped));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,createdAt,updatedAt,deletedAt,id,chatRoomId,chatRoom,accountId,account,nick,role,notify,joinedAt,breakUntil,timeoutUntil,isBot,lastTyped);
int get hashCode => Object.hash(runtimeType,createdAt,updatedAt,deletedAt,id,chatRoomId,chatRoom,accountId,account,nick,role,notify,joinedAt,breakUntil,timeoutUntil,isBot,status,lastTyped);
@override
String toString() {
return 'SnChatMember(createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, id: $id, chatRoomId: $chatRoomId, chatRoom: $chatRoom, accountId: $accountId, account: $account, nick: $nick, role: $role, notify: $notify, joinedAt: $joinedAt, breakUntil: $breakUntil, timeoutUntil: $timeoutUntil, isBot: $isBot, lastTyped: $lastTyped)';
return 'SnChatMember(createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, id: $id, chatRoomId: $chatRoomId, chatRoom: $chatRoom, accountId: $accountId, account: $account, nick: $nick, role: $role, notify: $notify, joinedAt: $joinedAt, breakUntil: $breakUntil, timeoutUntil: $timeoutUntil, isBot: $isBot, status: $status, lastTyped: $lastTyped)';
}
@@ -1316,11 +1330,11 @@ abstract mixin class _$SnChatMemberCopyWith<$Res> implements $SnChatMemberCopyWi
factory _$SnChatMemberCopyWith(_SnChatMember value, $Res Function(_SnChatMember) _then) = __$SnChatMemberCopyWithImpl;
@override @useResult
$Res call({
DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String chatRoomId, SnChatRoom? chatRoom, String accountId, SnAccount account, String? nick, int role, int notify, DateTime? joinedAt, DateTime? breakUntil, DateTime? timeoutUntil, bool isBot, DateTime? lastTyped
DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String chatRoomId, SnChatRoom? chatRoom, String accountId, SnAccount account, String? nick, int role, int notify, DateTime? joinedAt, DateTime? breakUntil, DateTime? timeoutUntil, bool isBot, SnAccountStatus? status, DateTime? lastTyped
});
@override $SnChatRoomCopyWith<$Res>? get chatRoom;@override $SnAccountCopyWith<$Res> get account;
@override $SnChatRoomCopyWith<$Res>? get chatRoom;@override $SnAccountCopyWith<$Res> get account;@override $SnAccountStatusCopyWith<$Res>? get status;
}
/// @nodoc
@@ -1333,7 +1347,7 @@ class __$SnChatMemberCopyWithImpl<$Res>
/// Create a copy of SnChatMember
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? id = null,Object? chatRoomId = null,Object? chatRoom = freezed,Object? accountId = null,Object? account = null,Object? nick = freezed,Object? role = null,Object? notify = null,Object? joinedAt = freezed,Object? breakUntil = freezed,Object? timeoutUntil = freezed,Object? isBot = null,Object? lastTyped = freezed,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? id = null,Object? chatRoomId = null,Object? chatRoom = freezed,Object? accountId = null,Object? account = null,Object? nick = freezed,Object? role = null,Object? notify = null,Object? joinedAt = freezed,Object? breakUntil = freezed,Object? timeoutUntil = freezed,Object? isBot = null,Object? status = freezed,Object? lastTyped = freezed,}) {
return _then(_SnChatMember(
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
@@ -1350,7 +1364,8 @@ as int,joinedAt: freezed == joinedAt ? _self.joinedAt : joinedAt // ignore: cast
as DateTime?,breakUntil: freezed == breakUntil ? _self.breakUntil : breakUntil // ignore: cast_nullable_to_non_nullable
as DateTime?,timeoutUntil: freezed == timeoutUntil ? _self.timeoutUntil : timeoutUntil // ignore: cast_nullable_to_non_nullable
as DateTime?,isBot: null == isBot ? _self.isBot : isBot // ignore: cast_nullable_to_non_nullable
as bool,lastTyped: freezed == lastTyped ? _self.lastTyped : lastTyped // ignore: cast_nullable_to_non_nullable
as bool,status: freezed == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
as SnAccountStatus?,lastTyped: freezed == lastTyped ? _self.lastTyped : lastTyped // ignore: cast_nullable_to_non_nullable
as DateTime?,
));
}
@@ -1376,6 +1391,18 @@ $SnAccountCopyWith<$Res> get account {
return $SnAccountCopyWith<$Res>(_self.account, (value) {
return _then(_self.copyWith(account: value));
});
}/// Create a copy of SnChatMember
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnAccountStatusCopyWith<$Res>? get status {
if (_self.status == null) {
return null;
}
return $SnAccountStatusCopyWith<$Res>(_self.status!, (value) {
return _then(_self.copyWith(status: value));
});
}
}
@@ -1383,7 +1410,7 @@ $SnAccountCopyWith<$Res> get account {
/// @nodoc
mixin _$SnChatSummary {
int get unreadCount; SnChatMessage get lastMessage;
int get unreadCount; SnChatMessage? get lastMessage;
/// Create a copy of SnChatSummary
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -1416,11 +1443,11 @@ abstract mixin class $SnChatSummaryCopyWith<$Res> {
factory $SnChatSummaryCopyWith(SnChatSummary value, $Res Function(SnChatSummary) _then) = _$SnChatSummaryCopyWithImpl;
@useResult
$Res call({
int unreadCount, SnChatMessage lastMessage
int unreadCount, SnChatMessage? lastMessage
});
$SnChatMessageCopyWith<$Res> get lastMessage;
$SnChatMessageCopyWith<$Res>? get lastMessage;
}
/// @nodoc
@@ -1433,20 +1460,23 @@ class _$SnChatSummaryCopyWithImpl<$Res>
/// Create a copy of SnChatSummary
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? unreadCount = null,Object? lastMessage = null,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? unreadCount = null,Object? lastMessage = freezed,}) {
return _then(_self.copyWith(
unreadCount: null == unreadCount ? _self.unreadCount : unreadCount // ignore: cast_nullable_to_non_nullable
as int,lastMessage: null == lastMessage ? _self.lastMessage : lastMessage // ignore: cast_nullable_to_non_nullable
as SnChatMessage,
as int,lastMessage: freezed == lastMessage ? _self.lastMessage : lastMessage // ignore: cast_nullable_to_non_nullable
as SnChatMessage?,
));
}
/// Create a copy of SnChatSummary
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnChatMessageCopyWith<$Res> get lastMessage {
$SnChatMessageCopyWith<$Res>? get lastMessage {
if (_self.lastMessage == null) {
return null;
}
return $SnChatMessageCopyWith<$Res>(_self.lastMessage, (value) {
return $SnChatMessageCopyWith<$Res>(_self.lastMessage!, (value) {
return _then(_self.copyWith(lastMessage: value));
});
}
@@ -1528,7 +1558,7 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( int unreadCount, SnChatMessage lastMessage)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( int unreadCount, SnChatMessage? lastMessage)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnChatSummary() when $default != null:
return $default(_that.unreadCount,_that.lastMessage);case _:
@@ -1549,7 +1579,7 @@ return $default(_that.unreadCount,_that.lastMessage);case _:
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( int unreadCount, SnChatMessage lastMessage) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( int unreadCount, SnChatMessage? lastMessage) $default,) {final _that = this;
switch (_that) {
case _SnChatSummary():
return $default(_that.unreadCount,_that.lastMessage);}
@@ -1566,7 +1596,7 @@ return $default(_that.unreadCount,_that.lastMessage);}
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( int unreadCount, SnChatMessage lastMessage)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( int unreadCount, SnChatMessage? lastMessage)? $default,) {final _that = this;
switch (_that) {
case _SnChatSummary() when $default != null:
return $default(_that.unreadCount,_that.lastMessage);case _:
@@ -1585,7 +1615,7 @@ class _SnChatSummary implements SnChatSummary {
factory _SnChatSummary.fromJson(Map<String, dynamic> json) => _$SnChatSummaryFromJson(json);
@override final int unreadCount;
@override final SnChatMessage lastMessage;
@override final SnChatMessage? lastMessage;
/// Create a copy of SnChatSummary
/// with the given fields replaced by the non-null parameter values.
@@ -1620,11 +1650,11 @@ abstract mixin class _$SnChatSummaryCopyWith<$Res> implements $SnChatSummaryCopy
factory _$SnChatSummaryCopyWith(_SnChatSummary value, $Res Function(_SnChatSummary) _then) = __$SnChatSummaryCopyWithImpl;
@override @useResult
$Res call({
int unreadCount, SnChatMessage lastMessage
int unreadCount, SnChatMessage? lastMessage
});
@override $SnChatMessageCopyWith<$Res> get lastMessage;
@override $SnChatMessageCopyWith<$Res>? get lastMessage;
}
/// @nodoc
@@ -1637,11 +1667,11 @@ class __$SnChatSummaryCopyWithImpl<$Res>
/// Create a copy of SnChatSummary
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? unreadCount = null,Object? lastMessage = null,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? unreadCount = null,Object? lastMessage = freezed,}) {
return _then(_SnChatSummary(
unreadCount: null == unreadCount ? _self.unreadCount : unreadCount // ignore: cast_nullable_to_non_nullable
as int,lastMessage: null == lastMessage ? _self.lastMessage : lastMessage // ignore: cast_nullable_to_non_nullable
as SnChatMessage,
as int,lastMessage: freezed == lastMessage ? _self.lastMessage : lastMessage // ignore: cast_nullable_to_non_nullable
as SnChatMessage?,
));
}
@@ -1649,9 +1679,12 @@ as SnChatMessage,
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnChatMessageCopyWith<$Res> get lastMessage {
$SnChatMessageCopyWith<$Res>? get lastMessage {
if (_self.lastMessage == null) {
return null;
}
return $SnChatMessageCopyWith<$Res>(_self.lastMessage, (value) {
return $SnChatMessageCopyWith<$Res>(_self.lastMessage!, (value) {
return _then(_self.copyWith(lastMessage: value));
});
}
@@ -2498,7 +2531,7 @@ as List<CallParticipant>,
/// @nodoc
mixin _$CallParticipant {
String get identity; String get name; DateTime get joinedAt; String? get accountId; SnChatMember? get profile;
String get identity; String get name; DateTime get joinedAt;
/// Create a copy of CallParticipant
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -2511,16 +2544,16 @@ $CallParticipantCopyWith<CallParticipant> get copyWith => _$CallParticipantCopyW
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is CallParticipant&&(identical(other.identity, identity) || other.identity == identity)&&(identical(other.name, name) || other.name == name)&&(identical(other.joinedAt, joinedAt) || other.joinedAt == joinedAt)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.profile, profile) || other.profile == profile));
return identical(this, other) || (other.runtimeType == runtimeType&&other is CallParticipant&&(identical(other.identity, identity) || other.identity == identity)&&(identical(other.name, name) || other.name == name)&&(identical(other.joinedAt, joinedAt) || other.joinedAt == joinedAt));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,identity,name,joinedAt,accountId,profile);
int get hashCode => Object.hash(runtimeType,identity,name,joinedAt);
@override
String toString() {
return 'CallParticipant(identity: $identity, name: $name, joinedAt: $joinedAt, accountId: $accountId, profile: $profile)';
return 'CallParticipant(identity: $identity, name: $name, joinedAt: $joinedAt)';
}
@@ -2531,11 +2564,11 @@ abstract mixin class $CallParticipantCopyWith<$Res> {
factory $CallParticipantCopyWith(CallParticipant value, $Res Function(CallParticipant) _then) = _$CallParticipantCopyWithImpl;
@useResult
$Res call({
String identity, String name, DateTime joinedAt, String? accountId, SnChatMember? profile
String identity, String name, DateTime joinedAt
});
$SnChatMemberCopyWith<$Res>? get profile;
}
/// @nodoc
@@ -2548,29 +2581,15 @@ class _$CallParticipantCopyWithImpl<$Res>
/// Create a copy of CallParticipant
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? identity = null,Object? name = null,Object? joinedAt = null,Object? accountId = freezed,Object? profile = freezed,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? identity = null,Object? name = null,Object? joinedAt = null,}) {
return _then(_self.copyWith(
identity: null == identity ? _self.identity : identity // ignore: cast_nullable_to_non_nullable
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,joinedAt: null == joinedAt ? _self.joinedAt : joinedAt // ignore: cast_nullable_to_non_nullable
as DateTime,accountId: freezed == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
as String?,profile: freezed == profile ? _self.profile : profile // ignore: cast_nullable_to_non_nullable
as SnChatMember?,
as DateTime,
));
}
/// Create a copy of CallParticipant
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnChatMemberCopyWith<$Res>? get profile {
if (_self.profile == null) {
return null;
}
return $SnChatMemberCopyWith<$Res>(_self.profile!, (value) {
return _then(_self.copyWith(profile: value));
});
}
}
@@ -2649,10 +2668,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String identity, String name, DateTime joinedAt, String? accountId, SnChatMember? profile)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String identity, String name, DateTime joinedAt)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _CallParticipant() when $default != null:
return $default(_that.identity,_that.name,_that.joinedAt,_that.accountId,_that.profile);case _:
return $default(_that.identity,_that.name,_that.joinedAt);case _:
return orElse();
}
@@ -2670,10 +2689,10 @@ return $default(_that.identity,_that.name,_that.joinedAt,_that.accountId,_that.p
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String identity, String name, DateTime joinedAt, String? accountId, SnChatMember? profile) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String identity, String name, DateTime joinedAt) $default,) {final _that = this;
switch (_that) {
case _CallParticipant():
return $default(_that.identity,_that.name,_that.joinedAt,_that.accountId,_that.profile);}
return $default(_that.identity,_that.name,_that.joinedAt);}
}
/// A variant of `when` that fallback to returning `null`
///
@@ -2687,10 +2706,10 @@ return $default(_that.identity,_that.name,_that.joinedAt,_that.accountId,_that.p
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String identity, String name, DateTime joinedAt, String? accountId, SnChatMember? profile)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String identity, String name, DateTime joinedAt)? $default,) {final _that = this;
switch (_that) {
case _CallParticipant() when $default != null:
return $default(_that.identity,_that.name,_that.joinedAt,_that.accountId,_that.profile);case _:
return $default(_that.identity,_that.name,_that.joinedAt);case _:
return null;
}
@@ -2702,14 +2721,12 @@ return $default(_that.identity,_that.name,_that.joinedAt,_that.accountId,_that.p
@JsonSerializable()
class _CallParticipant implements CallParticipant {
const _CallParticipant({required this.identity, required this.name, required this.joinedAt, required this.accountId, required this.profile});
const _CallParticipant({required this.identity, required this.name, required this.joinedAt});
factory _CallParticipant.fromJson(Map<String, dynamic> json) => _$CallParticipantFromJson(json);
@override final String identity;
@override final String name;
@override final DateTime joinedAt;
@override final String? accountId;
@override final SnChatMember? profile;
/// Create a copy of CallParticipant
/// with the given fields replaced by the non-null parameter values.
@@ -2724,16 +2741,16 @@ Map<String, dynamic> toJson() {
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _CallParticipant&&(identical(other.identity, identity) || other.identity == identity)&&(identical(other.name, name) || other.name == name)&&(identical(other.joinedAt, joinedAt) || other.joinedAt == joinedAt)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.profile, profile) || other.profile == profile));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _CallParticipant&&(identical(other.identity, identity) || other.identity == identity)&&(identical(other.name, name) || other.name == name)&&(identical(other.joinedAt, joinedAt) || other.joinedAt == joinedAt));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,identity,name,joinedAt,accountId,profile);
int get hashCode => Object.hash(runtimeType,identity,name,joinedAt);
@override
String toString() {
return 'CallParticipant(identity: $identity, name: $name, joinedAt: $joinedAt, accountId: $accountId, profile: $profile)';
return 'CallParticipant(identity: $identity, name: $name, joinedAt: $joinedAt)';
}
@@ -2744,11 +2761,11 @@ abstract mixin class _$CallParticipantCopyWith<$Res> implements $CallParticipant
factory _$CallParticipantCopyWith(_CallParticipant value, $Res Function(_CallParticipant) _then) = __$CallParticipantCopyWithImpl;
@override @useResult
$Res call({
String identity, String name, DateTime joinedAt, String? accountId, SnChatMember? profile
String identity, String name, DateTime joinedAt
});
@override $SnChatMemberCopyWith<$Res>? get profile;
}
/// @nodoc
@@ -2761,30 +2778,16 @@ class __$CallParticipantCopyWithImpl<$Res>
/// Create a copy of CallParticipant
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? identity = null,Object? name = null,Object? joinedAt = null,Object? accountId = freezed,Object? profile = freezed,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? identity = null,Object? name = null,Object? joinedAt = null,}) {
return _then(_CallParticipant(
identity: null == identity ? _self.identity : identity // ignore: cast_nullable_to_non_nullable
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,joinedAt: null == joinedAt ? _self.joinedAt : joinedAt // ignore: cast_nullable_to_non_nullable
as DateTime,accountId: freezed == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
as String?,profile: freezed == profile ? _self.profile : profile // ignore: cast_nullable_to_non_nullable
as SnChatMember?,
as DateTime,
));
}
/// Create a copy of CallParticipant
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnChatMemberCopyWith<$Res>? get profile {
if (_self.profile == null) {
return null;
}
return $SnChatMemberCopyWith<$Res>(_self.profile!, (value) {
return _then(_self.copyWith(profile: value));
});
}
}

View File

@@ -177,6 +177,12 @@ _SnChatMember _$SnChatMemberFromJson(Map<String, dynamic> json) =>
? null
: DateTime.parse(json['timeout_until'] as String),
isBot: json['is_bot'] as bool,
status:
json['status'] == null
? null
: SnAccountStatus.fromJson(
json['status'] as Map<String, dynamic>,
),
lastTyped:
json['last_typed'] == null
? null
@@ -200,21 +206,25 @@ Map<String, dynamic> _$SnChatMemberToJson(_SnChatMember instance) =>
'break_until': instance.breakUntil?.toIso8601String(),
'timeout_until': instance.timeoutUntil?.toIso8601String(),
'is_bot': instance.isBot,
'status': instance.status?.toJson(),
'last_typed': instance.lastTyped?.toIso8601String(),
};
_SnChatSummary _$SnChatSummaryFromJson(Map<String, dynamic> json) =>
_SnChatSummary(
unreadCount: (json['unread_count'] as num).toInt(),
lastMessage: SnChatMessage.fromJson(
json['last_message'] as Map<String, dynamic>,
),
lastMessage:
json['last_message'] == null
? null
: SnChatMessage.fromJson(
json['last_message'] as Map<String, dynamic>,
),
);
Map<String, dynamic> _$SnChatSummaryToJson(_SnChatSummary instance) =>
<String, dynamic>{
'unread_count': instance.unreadCount,
'last_message': instance.lastMessage.toJson(),
'last_message': instance.lastMessage?.toJson(),
};
_MessageChange _$MessageChangeFromJson(Map<String, dynamic> json) =>
@@ -285,11 +295,6 @@ _CallParticipant _$CallParticipantFromJson(Map<String, dynamic> json) =>
identity: json['identity'] as String,
name: json['name'] as String,
joinedAt: DateTime.parse(json['joined_at'] as String),
accountId: json['account_id'] as String?,
profile:
json['profile'] == null
? null
: SnChatMember.fromJson(json['profile'] as Map<String, dynamic>),
);
Map<String, dynamic> _$CallParticipantToJson(_CallParticipant instance) =>
@@ -297,8 +302,6 @@ Map<String, dynamic> _$CallParticipantToJson(_CallParticipant instance) =>
'identity': instance.identity,
'name': instance.name,
'joined_at': instance.joinedAt.toIso8601String(),
'account_id': instance.accountId,
'profile': instance.profile?.toJson(),
};
_SnRealtimeCall _$SnRealtimeCallFromJson(Map<String, dynamic> json) =>

View File

@@ -1,6 +1,6 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:island/models/file.dart';
import 'package:island/models/user.dart';
import 'package:island/models/account.dart';
part 'custom_app.freezed.dart';
part 'custom_app.g.dart';

View File

@@ -0,0 +1,19 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'custom_app_secret.freezed.dart';
part 'custom_app_secret.g.dart';
@freezed
sealed class CustomAppSecret with _$CustomAppSecret {
const factory CustomAppSecret({
required String id,
required String? secret,
required DateTime createdAt,
String? description,
int? expiresIn,
bool? isOidc,
}) = _CustomAppSecret;
factory CustomAppSecret.fromJson(Map<String, dynamic> json) =>
_$CustomAppSecretFromJson(json);
}

View File

@@ -0,0 +1,286 @@
// 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 'custom_app_secret.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$CustomAppSecret {
String get id; String? get secret; DateTime get createdAt; String? get description; int? get expiresIn; bool? get isOidc;
/// Create a copy of CustomAppSecret
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$CustomAppSecretCopyWith<CustomAppSecret> get copyWith => _$CustomAppSecretCopyWithImpl<CustomAppSecret>(this as CustomAppSecret, _$identity);
/// Serializes this CustomAppSecret to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is CustomAppSecret&&(identical(other.id, id) || other.id == id)&&(identical(other.secret, secret) || other.secret == secret)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.description, description) || other.description == description)&&(identical(other.expiresIn, expiresIn) || other.expiresIn == expiresIn)&&(identical(other.isOidc, isOidc) || other.isOidc == isOidc));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,secret,createdAt,description,expiresIn,isOidc);
@override
String toString() {
return 'CustomAppSecret(id: $id, secret: $secret, createdAt: $createdAt, description: $description, expiresIn: $expiresIn, isOidc: $isOidc)';
}
}
/// @nodoc
abstract mixin class $CustomAppSecretCopyWith<$Res> {
factory $CustomAppSecretCopyWith(CustomAppSecret value, $Res Function(CustomAppSecret) _then) = _$CustomAppSecretCopyWithImpl;
@useResult
$Res call({
String id, String? secret, DateTime createdAt, String? description, int? expiresIn, bool? isOidc
});
}
/// @nodoc
class _$CustomAppSecretCopyWithImpl<$Res>
implements $CustomAppSecretCopyWith<$Res> {
_$CustomAppSecretCopyWithImpl(this._self, this._then);
final CustomAppSecret _self;
final $Res Function(CustomAppSecret) _then;
/// Create a copy of CustomAppSecret
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? secret = freezed,Object? createdAt = null,Object? description = freezed,Object? expiresIn = freezed,Object? isOidc = freezed,}) {
return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,secret: freezed == secret ? _self.secret : secret // ignore: cast_nullable_to_non_nullable
as String?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as DateTime,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
as String?,expiresIn: freezed == expiresIn ? _self.expiresIn : expiresIn // ignore: cast_nullable_to_non_nullable
as int?,isOidc: freezed == isOidc ? _self.isOidc : isOidc // ignore: cast_nullable_to_non_nullable
as bool?,
));
}
}
/// Adds pattern-matching-related methods to [CustomAppSecret].
extension CustomAppSecretPatterns on CustomAppSecret {
/// 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( _CustomAppSecret value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _CustomAppSecret() 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( _CustomAppSecret value) $default,){
final _that = this;
switch (_that) {
case _CustomAppSecret():
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( _CustomAppSecret value)? $default,){
final _that = this;
switch (_that) {
case _CustomAppSecret() 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? secret, DateTime createdAt, String? description, int? expiresIn, bool? isOidc)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _CustomAppSecret() when $default != null:
return $default(_that.id,_that.secret,_that.createdAt,_that.description,_that.expiresIn,_that.isOidc);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? secret, DateTime createdAt, String? description, int? expiresIn, bool? isOidc) $default,) {final _that = this;
switch (_that) {
case _CustomAppSecret():
return $default(_that.id,_that.secret,_that.createdAt,_that.description,_that.expiresIn,_that.isOidc);}
}
/// 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? secret, DateTime createdAt, String? description, int? expiresIn, bool? isOidc)? $default,) {final _that = this;
switch (_that) {
case _CustomAppSecret() when $default != null:
return $default(_that.id,_that.secret,_that.createdAt,_that.description,_that.expiresIn,_that.isOidc);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _CustomAppSecret implements CustomAppSecret {
const _CustomAppSecret({required this.id, required this.secret, required this.createdAt, this.description, this.expiresIn, this.isOidc});
factory _CustomAppSecret.fromJson(Map<String, dynamic> json) => _$CustomAppSecretFromJson(json);
@override final String id;
@override final String? secret;
@override final DateTime createdAt;
@override final String? description;
@override final int? expiresIn;
@override final bool? isOidc;
/// Create a copy of CustomAppSecret
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$CustomAppSecretCopyWith<_CustomAppSecret> get copyWith => __$CustomAppSecretCopyWithImpl<_CustomAppSecret>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$CustomAppSecretToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _CustomAppSecret&&(identical(other.id, id) || other.id == id)&&(identical(other.secret, secret) || other.secret == secret)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.description, description) || other.description == description)&&(identical(other.expiresIn, expiresIn) || other.expiresIn == expiresIn)&&(identical(other.isOidc, isOidc) || other.isOidc == isOidc));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,secret,createdAt,description,expiresIn,isOidc);
@override
String toString() {
return 'CustomAppSecret(id: $id, secret: $secret, createdAt: $createdAt, description: $description, expiresIn: $expiresIn, isOidc: $isOidc)';
}
}
/// @nodoc
abstract mixin class _$CustomAppSecretCopyWith<$Res> implements $CustomAppSecretCopyWith<$Res> {
factory _$CustomAppSecretCopyWith(_CustomAppSecret value, $Res Function(_CustomAppSecret) _then) = __$CustomAppSecretCopyWithImpl;
@override @useResult
$Res call({
String id, String? secret, DateTime createdAt, String? description, int? expiresIn, bool? isOidc
});
}
/// @nodoc
class __$CustomAppSecretCopyWithImpl<$Res>
implements _$CustomAppSecretCopyWith<$Res> {
__$CustomAppSecretCopyWithImpl(this._self, this._then);
final _CustomAppSecret _self;
final $Res Function(_CustomAppSecret) _then;
/// Create a copy of CustomAppSecret
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? secret = freezed,Object? createdAt = null,Object? description = freezed,Object? expiresIn = freezed,Object? isOidc = freezed,}) {
return _then(_CustomAppSecret(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,secret: freezed == secret ? _self.secret : secret // ignore: cast_nullable_to_non_nullable
as String?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as DateTime,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
as String?,expiresIn: freezed == expiresIn ? _self.expiresIn : expiresIn // ignore: cast_nullable_to_non_nullable
as int?,isOidc: freezed == isOidc ? _self.isOidc : isOidc // ignore: cast_nullable_to_non_nullable
as bool?,
));
}
}
// dart format on

View File

@@ -0,0 +1,27 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'custom_app_secret.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_CustomAppSecret _$CustomAppSecretFromJson(Map<String, dynamic> json) =>
_CustomAppSecret(
id: json['id'] as String,
secret: json['secret'] as String?,
createdAt: DateTime.parse(json['created_at'] as String),
description: json['description'] as String?,
expiresIn: (json['expires_in'] as num?)?.toInt(),
isOidc: json['is_oidc'] as bool?,
);
Map<String, dynamic> _$CustomAppSecretToJson(_CustomAppSecret instance) =>
<String, dynamic>{
'id': instance.id,
'secret': instance.secret,
'created_at': instance.createdAt.toIso8601String(),
'description': instance.description,
'expires_in': instance.expiresIn,
'is_oidc': instance.isOidc,
};

View File

@@ -0,0 +1,23 @@
class DevProject {
final String id;
final String slug;
final String name;
final String? description;
DevProject({
required this.id,
required this.slug,
required this.name,
this.description,
});
factory DevProject.fromJson(Map<String, dynamic> json) {
return DevProject(
id: json['id'],
slug: json['slug'],
name: json['name'],
description: json['description'],
);
}
}

View File

@@ -1,13 +1,25 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:island/models/publisher.dart';
part 'developer.freezed.dart';
part 'developer.g.dart';
@freezed
sealed class SnDeveloper with _$SnDeveloper {
const factory SnDeveloper({
required String id,
required String publisherId,
SnPublisher? publisher,
}) = _SnDeveloper;
factory SnDeveloper.fromJson(Map<String, dynamic> json) =>
_$SnDeveloperFromJson(json);
}
@freezed
sealed class DeveloperStats with _$DeveloperStats {
const factory DeveloperStats({
@Default(0) int totalCustomApps,
}) = _DeveloperStats;
const factory DeveloperStats({@Default(0) int totalCustomApps}) =
_DeveloperStats;
factory DeveloperStats.fromJson(Map<String, dynamic> json) =>
_$DeveloperStatsFromJson(json);

View File

@@ -12,6 +12,293 @@ part of 'developer.dart';
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$SnDeveloper {
String get id; String get publisherId; SnPublisher? get publisher;
/// Create a copy of SnDeveloper
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$SnDeveloperCopyWith<SnDeveloper> get copyWith => _$SnDeveloperCopyWithImpl<SnDeveloper>(this as SnDeveloper, _$identity);
/// Serializes this SnDeveloper to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnDeveloper&&(identical(other.id, id) || other.id == id)&&(identical(other.publisherId, publisherId) || other.publisherId == publisherId)&&(identical(other.publisher, publisher) || other.publisher == publisher));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,publisherId,publisher);
@override
String toString() {
return 'SnDeveloper(id: $id, publisherId: $publisherId, publisher: $publisher)';
}
}
/// @nodoc
abstract mixin class $SnDeveloperCopyWith<$Res> {
factory $SnDeveloperCopyWith(SnDeveloper value, $Res Function(SnDeveloper) _then) = _$SnDeveloperCopyWithImpl;
@useResult
$Res call({
String id, String publisherId, SnPublisher? publisher
});
$SnPublisherCopyWith<$Res>? get publisher;
}
/// @nodoc
class _$SnDeveloperCopyWithImpl<$Res>
implements $SnDeveloperCopyWith<$Res> {
_$SnDeveloperCopyWithImpl(this._self, this._then);
final SnDeveloper _self;
final $Res Function(SnDeveloper) _then;
/// Create a copy of SnDeveloper
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? publisherId = null,Object? publisher = freezed,}) {
return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,publisherId: null == publisherId ? _self.publisherId : publisherId // ignore: cast_nullable_to_non_nullable
as String,publisher: freezed == publisher ? _self.publisher : publisher // ignore: cast_nullable_to_non_nullable
as SnPublisher?,
));
}
/// Create a copy of SnDeveloper
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnPublisherCopyWith<$Res>? get publisher {
if (_self.publisher == null) {
return null;
}
return $SnPublisherCopyWith<$Res>(_self.publisher!, (value) {
return _then(_self.copyWith(publisher: value));
});
}
}
/// Adds pattern-matching-related methods to [SnDeveloper].
extension SnDeveloperPatterns on SnDeveloper {
/// 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( _SnDeveloper value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _SnDeveloper() 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( _SnDeveloper value) $default,){
final _that = this;
switch (_that) {
case _SnDeveloper():
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( _SnDeveloper value)? $default,){
final _that = this;
switch (_that) {
case _SnDeveloper() 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 publisherId, SnPublisher? publisher)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnDeveloper() when $default != null:
return $default(_that.id,_that.publisherId,_that.publisher);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 publisherId, SnPublisher? publisher) $default,) {final _that = this;
switch (_that) {
case _SnDeveloper():
return $default(_that.id,_that.publisherId,_that.publisher);}
}
/// 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 publisherId, SnPublisher? publisher)? $default,) {final _that = this;
switch (_that) {
case _SnDeveloper() when $default != null:
return $default(_that.id,_that.publisherId,_that.publisher);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _SnDeveloper implements SnDeveloper {
const _SnDeveloper({required this.id, required this.publisherId, this.publisher});
factory _SnDeveloper.fromJson(Map<String, dynamic> json) => _$SnDeveloperFromJson(json);
@override final String id;
@override final String publisherId;
@override final SnPublisher? publisher;
/// Create a copy of SnDeveloper
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$SnDeveloperCopyWith<_SnDeveloper> get copyWith => __$SnDeveloperCopyWithImpl<_SnDeveloper>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$SnDeveloperToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnDeveloper&&(identical(other.id, id) || other.id == id)&&(identical(other.publisherId, publisherId) || other.publisherId == publisherId)&&(identical(other.publisher, publisher) || other.publisher == publisher));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,publisherId,publisher);
@override
String toString() {
return 'SnDeveloper(id: $id, publisherId: $publisherId, publisher: $publisher)';
}
}
/// @nodoc
abstract mixin class _$SnDeveloperCopyWith<$Res> implements $SnDeveloperCopyWith<$Res> {
factory _$SnDeveloperCopyWith(_SnDeveloper value, $Res Function(_SnDeveloper) _then) = __$SnDeveloperCopyWithImpl;
@override @useResult
$Res call({
String id, String publisherId, SnPublisher? publisher
});
@override $SnPublisherCopyWith<$Res>? get publisher;
}
/// @nodoc
class __$SnDeveloperCopyWithImpl<$Res>
implements _$SnDeveloperCopyWith<$Res> {
__$SnDeveloperCopyWithImpl(this._self, this._then);
final _SnDeveloper _self;
final $Res Function(_SnDeveloper) _then;
/// Create a copy of SnDeveloper
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? publisherId = null,Object? publisher = freezed,}) {
return _then(_SnDeveloper(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,publisherId: null == publisherId ? _self.publisherId : publisherId // ignore: cast_nullable_to_non_nullable
as String,publisher: freezed == publisher ? _self.publisher : publisher // ignore: cast_nullable_to_non_nullable
as SnPublisher?,
));
}
/// Create a copy of SnDeveloper
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnPublisherCopyWith<$Res>? get publisher {
if (_self.publisher == null) {
return null;
}
return $SnPublisherCopyWith<$Res>(_self.publisher!, (value) {
return _then(_self.copyWith(publisher: value));
});
}
}
/// @nodoc
mixin _$DeveloperStats {

View File

@@ -6,6 +6,22 @@ part of 'developer.dart';
// JsonSerializableGenerator
// **************************************************************************
_SnDeveloper _$SnDeveloperFromJson(Map<String, dynamic> json) => _SnDeveloper(
id: json['id'] as String,
publisherId: json['publisher_id'] as String,
publisher:
json['publisher'] == null
? null
: SnPublisher.fromJson(json['publisher'] as Map<String, dynamic>),
);
Map<String, dynamic> _$SnDeveloperToJson(_SnDeveloper instance) =>
<String, dynamic>{
'id': instance.id,
'publisher_id': instance.publisherId,
'publisher': instance.publisher?.toJson(),
};
_DeveloperStats _$DeveloperStatsFromJson(Map<String, dynamic> json) =>
_DeveloperStats(
totalCustomApps: (json['total_custom_apps'] as num?)?.toInt() ?? 0,

View File

@@ -3,25 +3,6 @@ import 'package:freezed_annotation/freezed_annotation.dart';
part 'embed.freezed.dart';
part 'embed.g.dart';
@freezed
sealed class SnEmbedLink with _$SnEmbedLink {
const factory SnEmbedLink({
@JsonKey(name: 'Type') required String type,
@JsonKey(name: 'Url') required String url,
@JsonKey(name: 'Title') required String title,
@JsonKey(name: 'Description') required String? description,
@JsonKey(name: 'ImageUrl') required String? imageUrl,
@JsonKey(name: 'FaviconUrl') required String faviconUrl,
@JsonKey(name: 'SiteName') required String siteName,
@JsonKey(name: 'ContentType') required String? contentType,
@JsonKey(name: 'Author') required String? author,
@JsonKey(name: 'PublishedDate') required DateTime? publishedDate,
}) = _SnEmbedLink;
factory SnEmbedLink.fromJson(Map<String, dynamic> json) =>
_$SnEmbedLinkFromJson(json);
}
@freezed
sealed class SnScrappedLink with _$SnScrappedLink {
const factory SnScrappedLink({
@@ -30,8 +11,8 @@ sealed class SnScrappedLink with _$SnScrappedLink {
required String title,
required String? description,
required String? imageUrl,
required String faviconUrl,
required String siteName,
required String? faviconUrl,
required String? siteName,
required String? contentType,
required String? author,
required DateTime? publishedDate,

View File

@@ -12,294 +12,10 @@ part of 'embed.dart';
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$SnEmbedLink {
@JsonKey(name: 'Type') String get type;@JsonKey(name: 'Url') String get url;@JsonKey(name: 'Title') String get title;@JsonKey(name: 'Description') String? get description;@JsonKey(name: 'ImageUrl') String? get imageUrl;@JsonKey(name: 'FaviconUrl') String get faviconUrl;@JsonKey(name: 'SiteName') String get siteName;@JsonKey(name: 'ContentType') String? get contentType;@JsonKey(name: 'Author') String? get author;@JsonKey(name: 'PublishedDate') DateTime? get publishedDate;
/// Create a copy of SnEmbedLink
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$SnEmbedLinkCopyWith<SnEmbedLink> get copyWith => _$SnEmbedLinkCopyWithImpl<SnEmbedLink>(this as SnEmbedLink, _$identity);
/// Serializes this SnEmbedLink to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnEmbedLink&&(identical(other.type, type) || other.type == type)&&(identical(other.url, url) || other.url == url)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.imageUrl, imageUrl) || other.imageUrl == imageUrl)&&(identical(other.faviconUrl, faviconUrl) || other.faviconUrl == faviconUrl)&&(identical(other.siteName, siteName) || other.siteName == siteName)&&(identical(other.contentType, contentType) || other.contentType == contentType)&&(identical(other.author, author) || other.author == author)&&(identical(other.publishedDate, publishedDate) || other.publishedDate == publishedDate));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,type,url,title,description,imageUrl,faviconUrl,siteName,contentType,author,publishedDate);
@override
String toString() {
return 'SnEmbedLink(type: $type, url: $url, title: $title, description: $description, imageUrl: $imageUrl, faviconUrl: $faviconUrl, siteName: $siteName, contentType: $contentType, author: $author, publishedDate: $publishedDate)';
}
}
/// @nodoc
abstract mixin class $SnEmbedLinkCopyWith<$Res> {
factory $SnEmbedLinkCopyWith(SnEmbedLink value, $Res Function(SnEmbedLink) _then) = _$SnEmbedLinkCopyWithImpl;
@useResult
$Res call({
@JsonKey(name: 'Type') String type,@JsonKey(name: 'Url') String url,@JsonKey(name: 'Title') String title,@JsonKey(name: 'Description') String? description,@JsonKey(name: 'ImageUrl') String? imageUrl,@JsonKey(name: 'FaviconUrl') String faviconUrl,@JsonKey(name: 'SiteName') String siteName,@JsonKey(name: 'ContentType') String? contentType,@JsonKey(name: 'Author') String? author,@JsonKey(name: 'PublishedDate') DateTime? publishedDate
});
}
/// @nodoc
class _$SnEmbedLinkCopyWithImpl<$Res>
implements $SnEmbedLinkCopyWith<$Res> {
_$SnEmbedLinkCopyWithImpl(this._self, this._then);
final SnEmbedLink _self;
final $Res Function(SnEmbedLink) _then;
/// Create a copy of SnEmbedLink
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? type = null,Object? url = null,Object? title = null,Object? description = freezed,Object? imageUrl = freezed,Object? faviconUrl = null,Object? siteName = null,Object? contentType = freezed,Object? author = freezed,Object? publishedDate = freezed,}) {
return _then(_self.copyWith(
type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
as String,url: null == url ? _self.url : url // ignore: cast_nullable_to_non_nullable
as String,title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
as String?,imageUrl: freezed == imageUrl ? _self.imageUrl : imageUrl // ignore: cast_nullable_to_non_nullable
as String?,faviconUrl: null == faviconUrl ? _self.faviconUrl : faviconUrl // ignore: cast_nullable_to_non_nullable
as String,siteName: null == siteName ? _self.siteName : siteName // ignore: cast_nullable_to_non_nullable
as String,contentType: freezed == contentType ? _self.contentType : contentType // ignore: cast_nullable_to_non_nullable
as String?,author: freezed == author ? _self.author : author // ignore: cast_nullable_to_non_nullable
as String?,publishedDate: freezed == publishedDate ? _self.publishedDate : publishedDate // ignore: cast_nullable_to_non_nullable
as DateTime?,
));
}
}
/// Adds pattern-matching-related methods to [SnEmbedLink].
extension SnEmbedLinkPatterns on SnEmbedLink {
/// 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( _SnEmbedLink value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _SnEmbedLink() 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( _SnEmbedLink value) $default,){
final _that = this;
switch (_that) {
case _SnEmbedLink():
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( _SnEmbedLink value)? $default,){
final _that = this;
switch (_that) {
case _SnEmbedLink() 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(@JsonKey(name: 'Type') String type, @JsonKey(name: 'Url') String url, @JsonKey(name: 'Title') String title, @JsonKey(name: 'Description') String? description, @JsonKey(name: 'ImageUrl') String? imageUrl, @JsonKey(name: 'FaviconUrl') String faviconUrl, @JsonKey(name: 'SiteName') String siteName, @JsonKey(name: 'ContentType') String? contentType, @JsonKey(name: 'Author') String? author, @JsonKey(name: 'PublishedDate') DateTime? publishedDate)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnEmbedLink() when $default != null:
return $default(_that.type,_that.url,_that.title,_that.description,_that.imageUrl,_that.faviconUrl,_that.siteName,_that.contentType,_that.author,_that.publishedDate);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(@JsonKey(name: 'Type') String type, @JsonKey(name: 'Url') String url, @JsonKey(name: 'Title') String title, @JsonKey(name: 'Description') String? description, @JsonKey(name: 'ImageUrl') String? imageUrl, @JsonKey(name: 'FaviconUrl') String faviconUrl, @JsonKey(name: 'SiteName') String siteName, @JsonKey(name: 'ContentType') String? contentType, @JsonKey(name: 'Author') String? author, @JsonKey(name: 'PublishedDate') DateTime? publishedDate) $default,) {final _that = this;
switch (_that) {
case _SnEmbedLink():
return $default(_that.type,_that.url,_that.title,_that.description,_that.imageUrl,_that.faviconUrl,_that.siteName,_that.contentType,_that.author,_that.publishedDate);}
}
/// 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(@JsonKey(name: 'Type') String type, @JsonKey(name: 'Url') String url, @JsonKey(name: 'Title') String title, @JsonKey(name: 'Description') String? description, @JsonKey(name: 'ImageUrl') String? imageUrl, @JsonKey(name: 'FaviconUrl') String faviconUrl, @JsonKey(name: 'SiteName') String siteName, @JsonKey(name: 'ContentType') String? contentType, @JsonKey(name: 'Author') String? author, @JsonKey(name: 'PublishedDate') DateTime? publishedDate)? $default,) {final _that = this;
switch (_that) {
case _SnEmbedLink() when $default != null:
return $default(_that.type,_that.url,_that.title,_that.description,_that.imageUrl,_that.faviconUrl,_that.siteName,_that.contentType,_that.author,_that.publishedDate);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _SnEmbedLink implements SnEmbedLink {
const _SnEmbedLink({@JsonKey(name: 'Type') required this.type, @JsonKey(name: 'Url') required this.url, @JsonKey(name: 'Title') required this.title, @JsonKey(name: 'Description') required this.description, @JsonKey(name: 'ImageUrl') required this.imageUrl, @JsonKey(name: 'FaviconUrl') required this.faviconUrl, @JsonKey(name: 'SiteName') required this.siteName, @JsonKey(name: 'ContentType') required this.contentType, @JsonKey(name: 'Author') required this.author, @JsonKey(name: 'PublishedDate') required this.publishedDate});
factory _SnEmbedLink.fromJson(Map<String, dynamic> json) => _$SnEmbedLinkFromJson(json);
@override@JsonKey(name: 'Type') final String type;
@override@JsonKey(name: 'Url') final String url;
@override@JsonKey(name: 'Title') final String title;
@override@JsonKey(name: 'Description') final String? description;
@override@JsonKey(name: 'ImageUrl') final String? imageUrl;
@override@JsonKey(name: 'FaviconUrl') final String faviconUrl;
@override@JsonKey(name: 'SiteName') final String siteName;
@override@JsonKey(name: 'ContentType') final String? contentType;
@override@JsonKey(name: 'Author') final String? author;
@override@JsonKey(name: 'PublishedDate') final DateTime? publishedDate;
/// Create a copy of SnEmbedLink
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$SnEmbedLinkCopyWith<_SnEmbedLink> get copyWith => __$SnEmbedLinkCopyWithImpl<_SnEmbedLink>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$SnEmbedLinkToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnEmbedLink&&(identical(other.type, type) || other.type == type)&&(identical(other.url, url) || other.url == url)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.imageUrl, imageUrl) || other.imageUrl == imageUrl)&&(identical(other.faviconUrl, faviconUrl) || other.faviconUrl == faviconUrl)&&(identical(other.siteName, siteName) || other.siteName == siteName)&&(identical(other.contentType, contentType) || other.contentType == contentType)&&(identical(other.author, author) || other.author == author)&&(identical(other.publishedDate, publishedDate) || other.publishedDate == publishedDate));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,type,url,title,description,imageUrl,faviconUrl,siteName,contentType,author,publishedDate);
@override
String toString() {
return 'SnEmbedLink(type: $type, url: $url, title: $title, description: $description, imageUrl: $imageUrl, faviconUrl: $faviconUrl, siteName: $siteName, contentType: $contentType, author: $author, publishedDate: $publishedDate)';
}
}
/// @nodoc
abstract mixin class _$SnEmbedLinkCopyWith<$Res> implements $SnEmbedLinkCopyWith<$Res> {
factory _$SnEmbedLinkCopyWith(_SnEmbedLink value, $Res Function(_SnEmbedLink) _then) = __$SnEmbedLinkCopyWithImpl;
@override @useResult
$Res call({
@JsonKey(name: 'Type') String type,@JsonKey(name: 'Url') String url,@JsonKey(name: 'Title') String title,@JsonKey(name: 'Description') String? description,@JsonKey(name: 'ImageUrl') String? imageUrl,@JsonKey(name: 'FaviconUrl') String faviconUrl,@JsonKey(name: 'SiteName') String siteName,@JsonKey(name: 'ContentType') String? contentType,@JsonKey(name: 'Author') String? author,@JsonKey(name: 'PublishedDate') DateTime? publishedDate
});
}
/// @nodoc
class __$SnEmbedLinkCopyWithImpl<$Res>
implements _$SnEmbedLinkCopyWith<$Res> {
__$SnEmbedLinkCopyWithImpl(this._self, this._then);
final _SnEmbedLink _self;
final $Res Function(_SnEmbedLink) _then;
/// Create a copy of SnEmbedLink
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? type = null,Object? url = null,Object? title = null,Object? description = freezed,Object? imageUrl = freezed,Object? faviconUrl = null,Object? siteName = null,Object? contentType = freezed,Object? author = freezed,Object? publishedDate = freezed,}) {
return _then(_SnEmbedLink(
type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
as String,url: null == url ? _self.url : url // ignore: cast_nullable_to_non_nullable
as String,title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
as String?,imageUrl: freezed == imageUrl ? _self.imageUrl : imageUrl // ignore: cast_nullable_to_non_nullable
as String?,faviconUrl: null == faviconUrl ? _self.faviconUrl : faviconUrl // ignore: cast_nullable_to_non_nullable
as String,siteName: null == siteName ? _self.siteName : siteName // ignore: cast_nullable_to_non_nullable
as String,contentType: freezed == contentType ? _self.contentType : contentType // ignore: cast_nullable_to_non_nullable
as String?,author: freezed == author ? _self.author : author // ignore: cast_nullable_to_non_nullable
as String?,publishedDate: freezed == publishedDate ? _self.publishedDate : publishedDate // ignore: cast_nullable_to_non_nullable
as DateTime?,
));
}
}
/// @nodoc
mixin _$SnScrappedLink {
String get type; String get url; String get title; String? get description; String? get imageUrl; String get faviconUrl; String get siteName; String? get contentType; String? get author; DateTime? get publishedDate;
String get type; String get url; String get title; String? get description; String? get imageUrl; String? get faviconUrl; String? get siteName; String? get contentType; String? get author; DateTime? get publishedDate;
/// Create a copy of SnScrappedLink
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -332,7 +48,7 @@ abstract mixin class $SnScrappedLinkCopyWith<$Res> {
factory $SnScrappedLinkCopyWith(SnScrappedLink value, $Res Function(SnScrappedLink) _then) = _$SnScrappedLinkCopyWithImpl;
@useResult
$Res call({
String type, String url, String title, String? description, String? imageUrl, String faviconUrl, String siteName, String? contentType, String? author, DateTime? publishedDate
String type, String url, String title, String? description, String? imageUrl, String? faviconUrl, String? siteName, String? contentType, String? author, DateTime? publishedDate
});
@@ -349,16 +65,16 @@ class _$SnScrappedLinkCopyWithImpl<$Res>
/// Create a copy of SnScrappedLink
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? type = null,Object? url = null,Object? title = null,Object? description = freezed,Object? imageUrl = freezed,Object? faviconUrl = null,Object? siteName = null,Object? contentType = freezed,Object? author = freezed,Object? publishedDate = freezed,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? type = null,Object? url = null,Object? title = null,Object? description = freezed,Object? imageUrl = freezed,Object? faviconUrl = freezed,Object? siteName = freezed,Object? contentType = freezed,Object? author = freezed,Object? publishedDate = freezed,}) {
return _then(_self.copyWith(
type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
as String,url: null == url ? _self.url : url // ignore: cast_nullable_to_non_nullable
as String,title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
as String?,imageUrl: freezed == imageUrl ? _self.imageUrl : imageUrl // ignore: cast_nullable_to_non_nullable
as String?,faviconUrl: null == faviconUrl ? _self.faviconUrl : faviconUrl // ignore: cast_nullable_to_non_nullable
as String,siteName: null == siteName ? _self.siteName : siteName // ignore: cast_nullable_to_non_nullable
as String,contentType: freezed == contentType ? _self.contentType : contentType // ignore: cast_nullable_to_non_nullable
as String?,faviconUrl: freezed == faviconUrl ? _self.faviconUrl : faviconUrl // ignore: cast_nullable_to_non_nullable
as String?,siteName: freezed == siteName ? _self.siteName : siteName // ignore: cast_nullable_to_non_nullable
as String?,contentType: freezed == contentType ? _self.contentType : contentType // ignore: cast_nullable_to_non_nullable
as String?,author: freezed == author ? _self.author : author // ignore: cast_nullable_to_non_nullable
as String?,publishedDate: freezed == publishedDate ? _self.publishedDate : publishedDate // ignore: cast_nullable_to_non_nullable
as DateTime?,
@@ -443,7 +159,7 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String type, String url, String title, String? description, String? imageUrl, String faviconUrl, String siteName, String? contentType, String? author, DateTime? publishedDate)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String type, String url, String title, String? description, String? imageUrl, String? faviconUrl, String? siteName, String? contentType, String? author, DateTime? publishedDate)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnScrappedLink() when $default != null:
return $default(_that.type,_that.url,_that.title,_that.description,_that.imageUrl,_that.faviconUrl,_that.siteName,_that.contentType,_that.author,_that.publishedDate);case _:
@@ -464,7 +180,7 @@ return $default(_that.type,_that.url,_that.title,_that.description,_that.imageUr
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String type, String url, String title, String? description, String? imageUrl, String faviconUrl, String siteName, String? contentType, String? author, DateTime? publishedDate) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String type, String url, String title, String? description, String? imageUrl, String? faviconUrl, String? siteName, String? contentType, String? author, DateTime? publishedDate) $default,) {final _that = this;
switch (_that) {
case _SnScrappedLink():
return $default(_that.type,_that.url,_that.title,_that.description,_that.imageUrl,_that.faviconUrl,_that.siteName,_that.contentType,_that.author,_that.publishedDate);}
@@ -481,7 +197,7 @@ return $default(_that.type,_that.url,_that.title,_that.description,_that.imageUr
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String type, String url, String title, String? description, String? imageUrl, String faviconUrl, String siteName, String? contentType, String? author, DateTime? publishedDate)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String type, String url, String title, String? description, String? imageUrl, String? faviconUrl, String? siteName, String? contentType, String? author, DateTime? publishedDate)? $default,) {final _that = this;
switch (_that) {
case _SnScrappedLink() when $default != null:
return $default(_that.type,_that.url,_that.title,_that.description,_that.imageUrl,_that.faviconUrl,_that.siteName,_that.contentType,_that.author,_that.publishedDate);case _:
@@ -504,8 +220,8 @@ class _SnScrappedLink implements SnScrappedLink {
@override final String title;
@override final String? description;
@override final String? imageUrl;
@override final String faviconUrl;
@override final String siteName;
@override final String? faviconUrl;
@override final String? siteName;
@override final String? contentType;
@override final String? author;
@override final DateTime? publishedDate;
@@ -543,7 +259,7 @@ abstract mixin class _$SnScrappedLinkCopyWith<$Res> implements $SnScrappedLinkCo
factory _$SnScrappedLinkCopyWith(_SnScrappedLink value, $Res Function(_SnScrappedLink) _then) = __$SnScrappedLinkCopyWithImpl;
@override @useResult
$Res call({
String type, String url, String title, String? description, String? imageUrl, String faviconUrl, String siteName, String? contentType, String? author, DateTime? publishedDate
String type, String url, String title, String? description, String? imageUrl, String? faviconUrl, String? siteName, String? contentType, String? author, DateTime? publishedDate
});
@@ -560,16 +276,16 @@ class __$SnScrappedLinkCopyWithImpl<$Res>
/// Create a copy of SnScrappedLink
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? type = null,Object? url = null,Object? title = null,Object? description = freezed,Object? imageUrl = freezed,Object? faviconUrl = null,Object? siteName = null,Object? contentType = freezed,Object? author = freezed,Object? publishedDate = freezed,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? type = null,Object? url = null,Object? title = null,Object? description = freezed,Object? imageUrl = freezed,Object? faviconUrl = freezed,Object? siteName = freezed,Object? contentType = freezed,Object? author = freezed,Object? publishedDate = freezed,}) {
return _then(_SnScrappedLink(
type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
as String,url: null == url ? _self.url : url // ignore: cast_nullable_to_non_nullable
as String,title: null == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
as String?,imageUrl: freezed == imageUrl ? _self.imageUrl : imageUrl // ignore: cast_nullable_to_non_nullable
as String?,faviconUrl: null == faviconUrl ? _self.faviconUrl : faviconUrl // ignore: cast_nullable_to_non_nullable
as String,siteName: null == siteName ? _self.siteName : siteName // ignore: cast_nullable_to_non_nullable
as String,contentType: freezed == contentType ? _self.contentType : contentType // ignore: cast_nullable_to_non_nullable
as String?,faviconUrl: freezed == faviconUrl ? _self.faviconUrl : faviconUrl // ignore: cast_nullable_to_non_nullable
as String?,siteName: freezed == siteName ? _self.siteName : siteName // ignore: cast_nullable_to_non_nullable
as String?,contentType: freezed == contentType ? _self.contentType : contentType // ignore: cast_nullable_to_non_nullable
as String?,author: freezed == author ? _self.author : author // ignore: cast_nullable_to_non_nullable
as String?,publishedDate: freezed == publishedDate ? _self.publishedDate : publishedDate // ignore: cast_nullable_to_non_nullable
as DateTime?,

View File

@@ -6,36 +6,6 @@ part of 'embed.dart';
// JsonSerializableGenerator
// **************************************************************************
_SnEmbedLink _$SnEmbedLinkFromJson(Map<String, dynamic> json) => _SnEmbedLink(
type: json['Type'] as String,
url: json['Url'] as String,
title: json['Title'] as String,
description: json['Description'] as String?,
imageUrl: json['ImageUrl'] as String?,
faviconUrl: json['FaviconUrl'] as String,
siteName: json['SiteName'] as String,
contentType: json['ContentType'] as String?,
author: json['Author'] as String?,
publishedDate:
json['PublishedDate'] == null
? null
: DateTime.parse(json['PublishedDate'] as String),
);
Map<String, dynamic> _$SnEmbedLinkToJson(_SnEmbedLink instance) =>
<String, dynamic>{
'Type': instance.type,
'Url': instance.url,
'Title': instance.title,
'Description': instance.description,
'ImageUrl': instance.imageUrl,
'FaviconUrl': instance.faviconUrl,
'SiteName': instance.siteName,
'ContentType': instance.contentType,
'Author': instance.author,
'PublishedDate': instance.publishedDate?.toIso8601String(),
};
_SnScrappedLink _$SnScrappedLinkFromJson(Map<String, dynamic> json) =>
_SnScrappedLink(
type: json['type'] as String,
@@ -43,8 +13,8 @@ _SnScrappedLink _$SnScrappedLinkFromJson(Map<String, dynamic> json) =>
title: json['title'] as String,
description: json['description'] as String?,
imageUrl: json['image_url'] as String?,
faviconUrl: json['favicon_url'] as String,
siteName: json['site_name'] as String,
faviconUrl: json['favicon_url'] as String?,
siteName: json['site_name'] as String?,
contentType: json['content_type'] as String?,
author: json['author'] as String?,
publishedDate:

View File

@@ -12,6 +12,7 @@ sealed class UniversalFile with _$UniversalFile {
const factory UniversalFile({
required dynamic data,
required UniversalFileType type,
@Default(false) bool isLink,
}) = _UniversalFile;
factory UniversalFile.fromJson(Map<String, dynamic> json) =>
@@ -41,6 +42,7 @@ sealed class SnCloudFile with _$SnCloudFile {
required String? description,
required Map<String, dynamic>? fileMeta,
required Map<String, dynamic>? userMeta,
@Default([]) List<int> sensitiveMarks,
required String? mimeType,
required String? hash,
required int size,

View File

@@ -15,7 +15,7 @@ T _$identity<T>(T value) => value;
/// @nodoc
mixin _$UniversalFile {
dynamic get data; UniversalFileType get type;
dynamic get data; UniversalFileType get type; bool get isLink;
/// Create a copy of UniversalFile
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -28,16 +28,16 @@ $UniversalFileCopyWith<UniversalFile> get copyWith => _$UniversalFileCopyWithImp
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is UniversalFile&&const DeepCollectionEquality().equals(other.data, data)&&(identical(other.type, type) || other.type == type));
return identical(this, other) || (other.runtimeType == runtimeType&&other is UniversalFile&&const DeepCollectionEquality().equals(other.data, data)&&(identical(other.type, type) || other.type == type)&&(identical(other.isLink, isLink) || other.isLink == isLink));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(data),type);
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(data),type,isLink);
@override
String toString() {
return 'UniversalFile(data: $data, type: $type)';
return 'UniversalFile(data: $data, type: $type, isLink: $isLink)';
}
@@ -48,7 +48,7 @@ abstract mixin class $UniversalFileCopyWith<$Res> {
factory $UniversalFileCopyWith(UniversalFile value, $Res Function(UniversalFile) _then) = _$UniversalFileCopyWithImpl;
@useResult
$Res call({
dynamic data, UniversalFileType type
dynamic data, UniversalFileType type, bool isLink
});
@@ -65,11 +65,12 @@ class _$UniversalFileCopyWithImpl<$Res>
/// Create a copy of UniversalFile
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? data = freezed,Object? type = null,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? data = freezed,Object? type = null,Object? isLink = null,}) {
return _then(_self.copyWith(
data: freezed == data ? _self.data : data // ignore: cast_nullable_to_non_nullable
as dynamic,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
as UniversalFileType,
as UniversalFileType,isLink: null == isLink ? _self.isLink : isLink // ignore: cast_nullable_to_non_nullable
as bool,
));
}
@@ -151,10 +152,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( dynamic data, UniversalFileType type)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( dynamic data, UniversalFileType type, bool isLink)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _UniversalFile() when $default != null:
return $default(_that.data,_that.type);case _:
return $default(_that.data,_that.type,_that.isLink);case _:
return orElse();
}
@@ -172,10 +173,10 @@ return $default(_that.data,_that.type);case _:
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( dynamic data, UniversalFileType type) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( dynamic data, UniversalFileType type, bool isLink) $default,) {final _that = this;
switch (_that) {
case _UniversalFile():
return $default(_that.data,_that.type);}
return $default(_that.data,_that.type,_that.isLink);}
}
/// A variant of `when` that fallback to returning `null`
///
@@ -189,10 +190,10 @@ return $default(_that.data,_that.type);}
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( dynamic data, UniversalFileType type)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( dynamic data, UniversalFileType type, bool isLink)? $default,) {final _that = this;
switch (_that) {
case _UniversalFile() when $default != null:
return $default(_that.data,_that.type);case _:
return $default(_that.data,_that.type,_that.isLink);case _:
return null;
}
@@ -204,11 +205,12 @@ return $default(_that.data,_that.type);case _:
@JsonSerializable()
class _UniversalFile extends UniversalFile {
const _UniversalFile({required this.data, required this.type}): super._();
const _UniversalFile({required this.data, required this.type, this.isLink = false}): super._();
factory _UniversalFile.fromJson(Map<String, dynamic> json) => _$UniversalFileFromJson(json);
@override final dynamic data;
@override final UniversalFileType type;
@override@JsonKey() final bool isLink;
/// Create a copy of UniversalFile
/// with the given fields replaced by the non-null parameter values.
@@ -223,16 +225,16 @@ Map<String, dynamic> toJson() {
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _UniversalFile&&const DeepCollectionEquality().equals(other.data, data)&&(identical(other.type, type) || other.type == type));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _UniversalFile&&const DeepCollectionEquality().equals(other.data, data)&&(identical(other.type, type) || other.type == type)&&(identical(other.isLink, isLink) || other.isLink == isLink));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(data),type);
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(data),type,isLink);
@override
String toString() {
return 'UniversalFile(data: $data, type: $type)';
return 'UniversalFile(data: $data, type: $type, isLink: $isLink)';
}
@@ -243,7 +245,7 @@ abstract mixin class _$UniversalFileCopyWith<$Res> implements $UniversalFileCopy
factory _$UniversalFileCopyWith(_UniversalFile value, $Res Function(_UniversalFile) _then) = __$UniversalFileCopyWithImpl;
@override @useResult
$Res call({
dynamic data, UniversalFileType type
dynamic data, UniversalFileType type, bool isLink
});
@@ -260,11 +262,12 @@ class __$UniversalFileCopyWithImpl<$Res>
/// Create a copy of UniversalFile
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? data = freezed,Object? type = null,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? data = freezed,Object? type = null,Object? isLink = null,}) {
return _then(_UniversalFile(
data: freezed == data ? _self.data : data // ignore: cast_nullable_to_non_nullable
as dynamic,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
as UniversalFileType,
as UniversalFileType,isLink: null == isLink ? _self.isLink : isLink // ignore: cast_nullable_to_non_nullable
as bool,
));
}
@@ -275,7 +278,7 @@ as UniversalFileType,
/// @nodoc
mixin _$SnCloudFile {
String get id; String get name; String? get description; Map<String, dynamic>? get fileMeta; Map<String, dynamic>? get userMeta; String? get mimeType; String? get hash; int get size; DateTime? get uploadedAt; String? get uploadedTo; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
String get id; String get name; String? get description; Map<String, dynamic>? get fileMeta; Map<String, dynamic>? get userMeta; List<int> get sensitiveMarks; String? get mimeType; String? get hash; int get size; DateTime? get uploadedAt; String? get uploadedTo; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
/// Create a copy of SnCloudFile
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -288,16 +291,16 @@ $SnCloudFileCopyWith<SnCloudFile> get copyWith => _$SnCloudFileCopyWithImpl<SnCl
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnCloudFile&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&const DeepCollectionEquality().equals(other.fileMeta, fileMeta)&&const DeepCollectionEquality().equals(other.userMeta, userMeta)&&(identical(other.mimeType, mimeType) || other.mimeType == mimeType)&&(identical(other.hash, hash) || other.hash == hash)&&(identical(other.size, size) || other.size == size)&&(identical(other.uploadedAt, uploadedAt) || other.uploadedAt == uploadedAt)&&(identical(other.uploadedTo, uploadedTo) || other.uploadedTo == uploadedTo)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnCloudFile&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&const DeepCollectionEquality().equals(other.fileMeta, fileMeta)&&const DeepCollectionEquality().equals(other.userMeta, userMeta)&&const DeepCollectionEquality().equals(other.sensitiveMarks, sensitiveMarks)&&(identical(other.mimeType, mimeType) || other.mimeType == mimeType)&&(identical(other.hash, hash) || other.hash == hash)&&(identical(other.size, size) || other.size == size)&&(identical(other.uploadedAt, uploadedAt) || other.uploadedAt == uploadedAt)&&(identical(other.uploadedTo, uploadedTo) || other.uploadedTo == uploadedTo)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,name,description,const DeepCollectionEquality().hash(fileMeta),const DeepCollectionEquality().hash(userMeta),mimeType,hash,size,uploadedAt,uploadedTo,createdAt,updatedAt,deletedAt);
int get hashCode => Object.hash(runtimeType,id,name,description,const DeepCollectionEquality().hash(fileMeta),const DeepCollectionEquality().hash(userMeta),const DeepCollectionEquality().hash(sensitiveMarks),mimeType,hash,size,uploadedAt,uploadedTo,createdAt,updatedAt,deletedAt);
@override
String toString() {
return 'SnCloudFile(id: $id, name: $name, description: $description, fileMeta: $fileMeta, userMeta: $userMeta, mimeType: $mimeType, hash: $hash, size: $size, uploadedAt: $uploadedAt, uploadedTo: $uploadedTo, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
return 'SnCloudFile(id: $id, name: $name, description: $description, fileMeta: $fileMeta, userMeta: $userMeta, sensitiveMarks: $sensitiveMarks, mimeType: $mimeType, hash: $hash, size: $size, uploadedAt: $uploadedAt, uploadedTo: $uploadedTo, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
@@ -308,7 +311,7 @@ abstract mixin class $SnCloudFileCopyWith<$Res> {
factory $SnCloudFileCopyWith(SnCloudFile value, $Res Function(SnCloudFile) _then) = _$SnCloudFileCopyWithImpl;
@useResult
$Res call({
String id, String name, String? description, Map<String, dynamic>? fileMeta, Map<String, dynamic>? userMeta, String? mimeType, String? hash, int size, DateTime? uploadedAt, String? uploadedTo, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
String id, String name, String? description, Map<String, dynamic>? fileMeta, Map<String, dynamic>? userMeta, List<int> sensitiveMarks, String? mimeType, String? hash, int size, DateTime? uploadedAt, String? uploadedTo, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
@@ -325,14 +328,15 @@ class _$SnCloudFileCopyWithImpl<$Res>
/// Create a copy of SnCloudFile
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? fileMeta = freezed,Object? userMeta = freezed,Object? mimeType = freezed,Object? hash = freezed,Object? size = null,Object? uploadedAt = freezed,Object? uploadedTo = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? fileMeta = freezed,Object? userMeta = freezed,Object? sensitiveMarks = null,Object? mimeType = freezed,Object? hash = freezed,Object? size = null,Object? uploadedAt = freezed,Object? uploadedTo = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
as String?,fileMeta: freezed == fileMeta ? _self.fileMeta : fileMeta // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>?,userMeta: freezed == userMeta ? _self.userMeta : userMeta // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>?,mimeType: freezed == mimeType ? _self.mimeType : mimeType // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>?,sensitiveMarks: null == sensitiveMarks ? _self.sensitiveMarks : sensitiveMarks // ignore: cast_nullable_to_non_nullable
as List<int>,mimeType: freezed == mimeType ? _self.mimeType : mimeType // ignore: cast_nullable_to_non_nullable
as String?,hash: freezed == hash ? _self.hash : hash // ignore: cast_nullable_to_non_nullable
as String?,size: null == size ? _self.size : size // ignore: cast_nullable_to_non_nullable
as int,uploadedAt: freezed == uploadedAt ? _self.uploadedAt : uploadedAt // ignore: cast_nullable_to_non_nullable
@@ -422,10 +426,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String name, String? description, Map<String, dynamic>? fileMeta, Map<String, dynamic>? userMeta, String? mimeType, String? hash, int size, DateTime? uploadedAt, String? uploadedTo, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String name, String? description, Map<String, dynamic>? fileMeta, Map<String, dynamic>? userMeta, List<int> sensitiveMarks, String? mimeType, String? hash, int size, DateTime? uploadedAt, String? uploadedTo, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnCloudFile() when $default != null:
return $default(_that.id,_that.name,_that.description,_that.fileMeta,_that.userMeta,_that.mimeType,_that.hash,_that.size,_that.uploadedAt,_that.uploadedTo,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return $default(_that.id,_that.name,_that.description,_that.fileMeta,_that.userMeta,_that.sensitiveMarks,_that.mimeType,_that.hash,_that.size,_that.uploadedAt,_that.uploadedTo,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return orElse();
}
@@ -443,10 +447,10 @@ return $default(_that.id,_that.name,_that.description,_that.fileMeta,_that.userM
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String name, String? description, Map<String, dynamic>? fileMeta, Map<String, dynamic>? userMeta, String? mimeType, String? hash, int size, DateTime? uploadedAt, String? uploadedTo, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String name, String? description, Map<String, dynamic>? fileMeta, Map<String, dynamic>? userMeta, List<int> sensitiveMarks, String? mimeType, String? hash, int size, DateTime? uploadedAt, String? uploadedTo, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
switch (_that) {
case _SnCloudFile():
return $default(_that.id,_that.name,_that.description,_that.fileMeta,_that.userMeta,_that.mimeType,_that.hash,_that.size,_that.uploadedAt,_that.uploadedTo,_that.createdAt,_that.updatedAt,_that.deletedAt);}
return $default(_that.id,_that.name,_that.description,_that.fileMeta,_that.userMeta,_that.sensitiveMarks,_that.mimeType,_that.hash,_that.size,_that.uploadedAt,_that.uploadedTo,_that.createdAt,_that.updatedAt,_that.deletedAt);}
}
/// A variant of `when` that fallback to returning `null`
///
@@ -460,10 +464,10 @@ return $default(_that.id,_that.name,_that.description,_that.fileMeta,_that.userM
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String name, String? description, Map<String, dynamic>? fileMeta, Map<String, dynamic>? userMeta, String? mimeType, String? hash, int size, DateTime? uploadedAt, String? uploadedTo, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String name, String? description, Map<String, dynamic>? fileMeta, Map<String, dynamic>? userMeta, List<int> sensitiveMarks, String? mimeType, String? hash, int size, DateTime? uploadedAt, String? uploadedTo, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
switch (_that) {
case _SnCloudFile() when $default != null:
return $default(_that.id,_that.name,_that.description,_that.fileMeta,_that.userMeta,_that.mimeType,_that.hash,_that.size,_that.uploadedAt,_that.uploadedTo,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return $default(_that.id,_that.name,_that.description,_that.fileMeta,_that.userMeta,_that.sensitiveMarks,_that.mimeType,_that.hash,_that.size,_that.uploadedAt,_that.uploadedTo,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return null;
}
@@ -475,7 +479,7 @@ return $default(_that.id,_that.name,_that.description,_that.fileMeta,_that.userM
@JsonSerializable()
class _SnCloudFile implements SnCloudFile {
const _SnCloudFile({required this.id, required this.name, required this.description, required final Map<String, dynamic>? fileMeta, required final Map<String, dynamic>? userMeta, required this.mimeType, required this.hash, required this.size, required this.uploadedAt, required this.uploadedTo, required this.createdAt, required this.updatedAt, required this.deletedAt}): _fileMeta = fileMeta,_userMeta = userMeta;
const _SnCloudFile({required this.id, required this.name, required this.description, required final Map<String, dynamic>? fileMeta, required final Map<String, dynamic>? userMeta, final List<int> sensitiveMarks = const [], required this.mimeType, required this.hash, required this.size, required this.uploadedAt, required this.uploadedTo, required this.createdAt, required this.updatedAt, required this.deletedAt}): _fileMeta = fileMeta,_userMeta = userMeta,_sensitiveMarks = sensitiveMarks;
factory _SnCloudFile.fromJson(Map<String, dynamic> json) => _$SnCloudFileFromJson(json);
@override final String id;
@@ -499,6 +503,13 @@ class _SnCloudFile implements SnCloudFile {
return EqualUnmodifiableMapView(value);
}
final List<int> _sensitiveMarks;
@override@JsonKey() List<int> get sensitiveMarks {
if (_sensitiveMarks is EqualUnmodifiableListView) return _sensitiveMarks;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_sensitiveMarks);
}
@override final String? mimeType;
@override final String? hash;
@override final int size;
@@ -521,16 +532,16 @@ Map<String, dynamic> toJson() {
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnCloudFile&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&const DeepCollectionEquality().equals(other._fileMeta, _fileMeta)&&const DeepCollectionEquality().equals(other._userMeta, _userMeta)&&(identical(other.mimeType, mimeType) || other.mimeType == mimeType)&&(identical(other.hash, hash) || other.hash == hash)&&(identical(other.size, size) || other.size == size)&&(identical(other.uploadedAt, uploadedAt) || other.uploadedAt == uploadedAt)&&(identical(other.uploadedTo, uploadedTo) || other.uploadedTo == uploadedTo)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnCloudFile&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&const DeepCollectionEquality().equals(other._fileMeta, _fileMeta)&&const DeepCollectionEquality().equals(other._userMeta, _userMeta)&&const DeepCollectionEquality().equals(other._sensitiveMarks, _sensitiveMarks)&&(identical(other.mimeType, mimeType) || other.mimeType == mimeType)&&(identical(other.hash, hash) || other.hash == hash)&&(identical(other.size, size) || other.size == size)&&(identical(other.uploadedAt, uploadedAt) || other.uploadedAt == uploadedAt)&&(identical(other.uploadedTo, uploadedTo) || other.uploadedTo == uploadedTo)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,name,description,const DeepCollectionEquality().hash(_fileMeta),const DeepCollectionEquality().hash(_userMeta),mimeType,hash,size,uploadedAt,uploadedTo,createdAt,updatedAt,deletedAt);
int get hashCode => Object.hash(runtimeType,id,name,description,const DeepCollectionEquality().hash(_fileMeta),const DeepCollectionEquality().hash(_userMeta),const DeepCollectionEquality().hash(_sensitiveMarks),mimeType,hash,size,uploadedAt,uploadedTo,createdAt,updatedAt,deletedAt);
@override
String toString() {
return 'SnCloudFile(id: $id, name: $name, description: $description, fileMeta: $fileMeta, userMeta: $userMeta, mimeType: $mimeType, hash: $hash, size: $size, uploadedAt: $uploadedAt, uploadedTo: $uploadedTo, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
return 'SnCloudFile(id: $id, name: $name, description: $description, fileMeta: $fileMeta, userMeta: $userMeta, sensitiveMarks: $sensitiveMarks, mimeType: $mimeType, hash: $hash, size: $size, uploadedAt: $uploadedAt, uploadedTo: $uploadedTo, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
@@ -541,7 +552,7 @@ abstract mixin class _$SnCloudFileCopyWith<$Res> implements $SnCloudFileCopyWith
factory _$SnCloudFileCopyWith(_SnCloudFile value, $Res Function(_SnCloudFile) _then) = __$SnCloudFileCopyWithImpl;
@override @useResult
$Res call({
String id, String name, String? description, Map<String, dynamic>? fileMeta, Map<String, dynamic>? userMeta, String? mimeType, String? hash, int size, DateTime? uploadedAt, String? uploadedTo, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
String id, String name, String? description, Map<String, dynamic>? fileMeta, Map<String, dynamic>? userMeta, List<int> sensitiveMarks, String? mimeType, String? hash, int size, DateTime? uploadedAt, String? uploadedTo, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
@@ -558,14 +569,15 @@ class __$SnCloudFileCopyWithImpl<$Res>
/// Create a copy of SnCloudFile
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? fileMeta = freezed,Object? userMeta = freezed,Object? mimeType = freezed,Object? hash = freezed,Object? size = null,Object? uploadedAt = freezed,Object? uploadedTo = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? fileMeta = freezed,Object? userMeta = freezed,Object? sensitiveMarks = null,Object? mimeType = freezed,Object? hash = freezed,Object? size = null,Object? uploadedAt = freezed,Object? uploadedTo = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
return _then(_SnCloudFile(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
as String?,fileMeta: freezed == fileMeta ? _self._fileMeta : fileMeta // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>?,userMeta: freezed == userMeta ? _self._userMeta : userMeta // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>?,mimeType: freezed == mimeType ? _self.mimeType : mimeType // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>?,sensitiveMarks: null == sensitiveMarks ? _self._sensitiveMarks : sensitiveMarks // ignore: cast_nullable_to_non_nullable
as List<int>,mimeType: freezed == mimeType ? _self.mimeType : mimeType // ignore: cast_nullable_to_non_nullable
as String?,hash: freezed == hash ? _self.hash : hash // ignore: cast_nullable_to_non_nullable
as String?,size: null == size ? _self.size : size // ignore: cast_nullable_to_non_nullable
as int,uploadedAt: freezed == uploadedAt ? _self.uploadedAt : uploadedAt // ignore: cast_nullable_to_non_nullable

View File

@@ -10,12 +10,14 @@ _UniversalFile _$UniversalFileFromJson(Map<String, dynamic> json) =>
_UniversalFile(
data: json['data'],
type: $enumDecode(_$UniversalFileTypeEnumMap, json['type']),
isLink: json['is_link'] as bool? ?? false,
);
Map<String, dynamic> _$UniversalFileToJson(_UniversalFile instance) =>
<String, dynamic>{
'data': instance.data,
'type': _$UniversalFileTypeEnumMap[instance.type]!,
'is_link': instance.isLink,
};
const _$UniversalFileTypeEnumMap = {
@@ -31,6 +33,11 @@ _SnCloudFile _$SnCloudFileFromJson(Map<String, dynamic> json) => _SnCloudFile(
description: json['description'] as String?,
fileMeta: json['file_meta'] as Map<String, dynamic>?,
userMeta: json['user_meta'] as Map<String, dynamic>?,
sensitiveMarks:
(json['sensitive_marks'] as List<dynamic>?)
?.map((e) => (e as num).toInt())
.toList() ??
const [],
mimeType: json['mime_type'] as String?,
hash: json['hash'] as String?,
size: (json['size'] as num).toInt(),
@@ -54,6 +61,7 @@ Map<String, dynamic> _$SnCloudFileToJson(_SnCloudFile instance) =>
'description': instance.description,
'file_meta': instance.fileMeta,
'user_meta': instance.userMeta,
'sensitive_marks': instance.sensitiveMarks,
'mime_type': instance.mimeType,
'hash': instance.hash,
'size': instance.size,

108
lib/models/poll.dart Normal file
View File

@@ -0,0 +1,108 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:island/models/publisher.dart';
part 'poll.freezed.dart';
part 'poll.g.dart';
@freezed
sealed class SnPollWithStats with _$SnPollWithStats {
const factory SnPollWithStats({
required Map<String, dynamic>? userAnswer,
@Default({}) Map<String, dynamic> stats,
required String id,
required List<SnPollQuestion> questions,
String? title,
String? description,
DateTime? endedAt,
required String publisherId,
required DateTime createdAt,
required DateTime updatedAt,
DateTime? deletedAt,
}) = _SnPollWithStats;
factory SnPollWithStats.fromJson(Map<String, dynamic> json) =>
_$SnPollWithStatsFromJson(json);
}
@freezed
sealed class SnPoll with _$SnPoll {
const factory SnPoll({
required String id,
required List<SnPollQuestion> questions,
String? title,
String? description,
DateTime? endedAt,
required String publisherId,
SnPublisher? publisher,
// ModelBase fields
required DateTime createdAt,
required DateTime updatedAt,
DateTime? deletedAt,
}) = _SnPoll;
factory SnPoll.fromJson(Map<String, dynamic> json) => _$SnPollFromJson(json);
}
@freezed
sealed class SnPollQuestion with _$SnPollQuestion {
const factory SnPollQuestion({
required String id,
required SnPollQuestionType type,
List<SnPollOption>? options,
required String title,
String? description,
required int order,
required bool isRequired,
}) = _SnPollQuestion;
factory SnPollQuestion.fromJson(Map<String, dynamic> json) =>
_$SnPollQuestionFromJson(json);
}
@freezed
sealed class SnPollOption with _$SnPollOption {
const factory SnPollOption({
required String id,
required String label,
String? description,
required int order,
}) = _SnPollOption;
factory SnPollOption.fromJson(Map<String, dynamic> json) =>
_$SnPollOptionFromJson(json);
}
enum SnPollQuestionType {
@JsonValue(0)
singleChoice,
@JsonValue(1)
multipleChoice,
@JsonValue(2)
yesNo,
@JsonValue(3)
rating,
@JsonValue(4)
freeText,
}
@freezed
sealed class SnPollAnswer with _$SnPollAnswer {
const factory SnPollAnswer({
required String id,
required Map<String, dynamic> answer,
required String accountId,
required String pollId,
required DateTime createdAt,
required DateTime updatedAt,
required DateTime? deletedAt,
}) = _SnPollAnswer;
factory SnPollAnswer.fromJson(Map<String, dynamic> json) =>
_$SnPollAnswerFromJson(json);
}

1467
lib/models/poll.freezed.dart Normal file

File diff suppressed because it is too large Load Diff

158
lib/models/poll.g.dart Normal file
View File

@@ -0,0 +1,158 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'poll.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_SnPollWithStats _$SnPollWithStatsFromJson(Map<String, dynamic> json) =>
_SnPollWithStats(
userAnswer: json['user_answer'] as Map<String, dynamic>?,
stats: json['stats'] as Map<String, dynamic>? ?? const {},
id: json['id'] as String,
questions:
(json['questions'] as List<dynamic>)
.map((e) => SnPollQuestion.fromJson(e as Map<String, dynamic>))
.toList(),
title: json['title'] as String?,
description: json['description'] as String?,
endedAt:
json['ended_at'] == null
? null
: DateTime.parse(json['ended_at'] as String),
publisherId: json['publisher_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> _$SnPollWithStatsToJson(_SnPollWithStats instance) =>
<String, dynamic>{
'user_answer': instance.userAnswer,
'stats': instance.stats,
'id': instance.id,
'questions': instance.questions.map((e) => e.toJson()).toList(),
'title': instance.title,
'description': instance.description,
'ended_at': instance.endedAt?.toIso8601String(),
'publisher_id': instance.publisherId,
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
};
_SnPoll _$SnPollFromJson(Map<String, dynamic> json) => _SnPoll(
id: json['id'] as String,
questions:
(json['questions'] as List<dynamic>)
.map((e) => SnPollQuestion.fromJson(e as Map<String, dynamic>))
.toList(),
title: json['title'] as String?,
description: json['description'] as String?,
endedAt:
json['ended_at'] == null
? null
: DateTime.parse(json['ended_at'] as String),
publisherId: json['publisher_id'] as String,
publisher:
json['publisher'] == null
? null
: SnPublisher.fromJson(json['publisher'] 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> _$SnPollToJson(_SnPoll instance) => <String, dynamic>{
'id': instance.id,
'questions': instance.questions.map((e) => e.toJson()).toList(),
'title': instance.title,
'description': instance.description,
'ended_at': instance.endedAt?.toIso8601String(),
'publisher_id': instance.publisherId,
'publisher': instance.publisher?.toJson(),
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
};
_SnPollQuestion _$SnPollQuestionFromJson(Map<String, dynamic> json) =>
_SnPollQuestion(
id: json['id'] as String,
type: $enumDecode(_$SnPollQuestionTypeEnumMap, json['type']),
options:
(json['options'] as List<dynamic>?)
?.map((e) => SnPollOption.fromJson(e as Map<String, dynamic>))
.toList(),
title: json['title'] as String,
description: json['description'] as String?,
order: (json['order'] as num).toInt(),
isRequired: json['is_required'] as bool,
);
Map<String, dynamic> _$SnPollQuestionToJson(_SnPollQuestion instance) =>
<String, dynamic>{
'id': instance.id,
'type': _$SnPollQuestionTypeEnumMap[instance.type]!,
'options': instance.options?.map((e) => e.toJson()).toList(),
'title': instance.title,
'description': instance.description,
'order': instance.order,
'is_required': instance.isRequired,
};
const _$SnPollQuestionTypeEnumMap = {
SnPollQuestionType.singleChoice: 0,
SnPollQuestionType.multipleChoice: 1,
SnPollQuestionType.yesNo: 2,
SnPollQuestionType.rating: 3,
SnPollQuestionType.freeText: 4,
};
_SnPollOption _$SnPollOptionFromJson(Map<String, dynamic> json) =>
_SnPollOption(
id: json['id'] as String,
label: json['label'] as String,
description: json['description'] as String?,
order: (json['order'] as num).toInt(),
);
Map<String, dynamic> _$SnPollOptionToJson(_SnPollOption instance) =>
<String, dynamic>{
'id': instance.id,
'label': instance.label,
'description': instance.description,
'order': instance.order,
};
_SnPollAnswer _$SnPollAnswerFromJson(Map<String, dynamic> json) =>
_SnPollAnswer(
id: json['id'] as String,
answer: json['answer'] as Map<String, dynamic>,
accountId: json['account_id'] as String,
pollId: json['poll_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> _$SnPollAnswerToJson(_SnPollAnswer instance) =>
<String, dynamic>{
'id': instance.id,
'answer': instance.answer,
'account_id': instance.accountId,
'poll_id': instance.pollId,
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
};

View File

@@ -3,6 +3,7 @@ import 'package:island/models/file.dart';
import 'package:island/models/post_category.dart';
import 'package:island/models/post_tag.dart';
import 'package:island/models/publisher.dart';
import 'package:island/models/realm.dart';
part 'post.freezed.dart';
part 'post.g.dart';
@@ -18,6 +19,7 @@ sealed class SnPost with _$SnPost {
@Default(null) DateTime? publishedAt,
@Default(0) int visibility,
String? content,
String? slug,
@Default(0) int type,
Map<String, dynamic>? meta,
@Default(0) int viewsUnique,
@@ -25,18 +27,22 @@ sealed class SnPost with _$SnPost {
@Default(0) int upvotes,
@Default(0) int downvotes,
@Default(0) int repliesCount,
int? pinMode,
String? threadedPostId,
SnPost? threadedPost,
String? repliedPostId,
SnPost? repliedPost,
String? forwardedPostId,
SnPost? forwardedPost,
String? realmId,
SnRealm? realm,
@Default([]) List<SnCloudFile> attachments,
required SnPublisher publisher,
@Default({}) Map<String, int> reactionsCount,
@Default({}) Map<String, bool> reactionsMade,
@Default([]) List<dynamic> reactions,
@Default([]) List<PostTag> tags,
@Default([]) List<PostCategory> categories,
@Default([]) List<SnPostTag> tags,
@Default([]) List<SnPostCategory> categories,
@Default([]) List<dynamic> collections,
@Default(null) DateTime? createdAt,
@Default(null) DateTime? updatedAt,
@@ -77,6 +83,13 @@ sealed class SnSubscriptionStatus with _$SnSubscriptionStatus {
sealed class ReactInfo with _$ReactInfo {
const factory ReactInfo({required String icon, required int attitude}) =
_ReactInfo;
static String getTranslationKey(String templateKey) {
final parts = templateKey.split('_');
final camelCase =
parts.map((p) => p[0].toUpperCase() + p.substring(1)).join();
return 'reaction$camelCase';
}
}
const Map<String, ReactInfo> kReactionTemplates = {

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; int get type; Map<String, dynamic>? get meta; int get viewsUnique; int get viewsTotal; int get upvotes; int get downvotes; int get repliesCount; String? get threadedPostId; SnPost? get threadedPost; String? get repliedPostId; SnPost? get repliedPost; String? get forwardedPostId; SnPost? get forwardedPost; List<SnCloudFile> get attachments; SnPublisher get publisher; Map<String, int> get reactionsCount; List<dynamic> get reactions; List<PostTag> get tags; List<PostCategory> 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; int get viewsUnique; int get viewsTotal; int get upvotes; int get downvotes; int get repliesCount; 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;
/// 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.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other.meta, meta)&&(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.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)&&const DeepCollectionEquality().equals(other.attachments, attachments)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&const DeepCollectionEquality().equals(other.reactionsCount, reactionsCount)&&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.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.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));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hashAll([runtimeType,id,title,description,language,editedAt,publishedAt,visibility,content,type,const DeepCollectionEquality().hash(meta),viewsUnique,viewsTotal,upvotes,downvotes,repliesCount,threadedPostId,threadedPost,repliedPostId,repliedPost,forwardedPostId,forwardedPost,const DeepCollectionEquality().hash(attachments),publisher,const DeepCollectionEquality().hash(reactionsCount),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),viewsUnique,viewsTotal,upvotes,downvotes,repliesCount,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]);
@override
String toString() {
return 'SnPost(id: $id, title: $title, description: $description, language: $language, editedAt: $editedAt, publishedAt: $publishedAt, visibility: $visibility, content: $content, type: $type, meta: $meta, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, repliesCount: $repliesCount, threadedPostId: $threadedPostId, threadedPost: $threadedPost, repliedPostId: $repliedPostId, repliedPost: $repliedPost, forwardedPostId: $forwardedPostId, forwardedPost: $forwardedPost, attachments: $attachments, publisher: $publisher, reactionsCount: $reactionsCount, 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, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, repliesCount: $repliesCount, 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)';
}
@@ -48,11 +48,11 @@ 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, int type, Map<String, dynamic>? meta, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, List<dynamic> reactions, List<PostTag> tags, List<PostCategory> 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, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, 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
});
$SnPostCopyWith<$Res>? get threadedPost;$SnPostCopyWith<$Res>? get repliedPost;$SnPostCopyWith<$Res>? get forwardedPost;$SnPublisherCopyWith<$Res> get publisher;
$SnPostCopyWith<$Res>? get threadedPost;$SnPostCopyWith<$Res>? get repliedPost;$SnPostCopyWith<$Res>? get forwardedPost;$SnRealmCopyWith<$Res>? get realm;$SnPublisherCopyWith<$Res> get publisher;
}
/// @nodoc
@@ -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? type = null,Object? meta = freezed,Object? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? repliesCount = null,Object? threadedPostId = freezed,Object? threadedPost = freezed,Object? repliedPostId = freezed,Object? repliedPost = freezed,Object? forwardedPostId = freezed,Object? forwardedPost = freezed,Object? attachments = null,Object? publisher = null,Object? reactionsCount = 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? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? repliesCount = 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,}) {
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
@@ -75,6 +75,7 @@ as String?,editedAt: freezed == editedAt ? _self.editedAt : editedAt // ignore:
as DateTime?,publishedAt: freezed == publishedAt ? _self.publishedAt : publishedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,visibility: null == visibility ? _self.visibility : visibility // ignore: cast_nullable_to_non_nullable
as int,content: freezed == content ? _self.content : content // ignore: cast_nullable_to_non_nullable
as String?,slug: freezed == slug ? _self.slug : slug // ignore: cast_nullable_to_non_nullable
as String?,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
as int,meta: freezed == meta ? _self.meta : meta // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>?,viewsUnique: null == viewsUnique ? _self.viewsUnique : viewsUnique // ignore: cast_nullable_to_non_nullable
@@ -82,19 +83,23 @@ as int,viewsTotal: null == viewsTotal ? _self.viewsTotal : viewsTotal // ignore:
as int,upvotes: null == upvotes ? _self.upvotes : upvotes // ignore: cast_nullable_to_non_nullable
as int,downvotes: null == downvotes ? _self.downvotes : downvotes // ignore: cast_nullable_to_non_nullable
as int,repliesCount: null == repliesCount ? _self.repliesCount : repliesCount // ignore: cast_nullable_to_non_nullable
as int,threadedPostId: freezed == threadedPostId ? _self.threadedPostId : threadedPostId // ignore: cast_nullable_to_non_nullable
as int,pinMode: freezed == pinMode ? _self.pinMode : pinMode // ignore: cast_nullable_to_non_nullable
as int?,threadedPostId: freezed == threadedPostId ? _self.threadedPostId : threadedPostId // ignore: cast_nullable_to_non_nullable
as String?,threadedPost: freezed == threadedPost ? _self.threadedPost : threadedPost // ignore: cast_nullable_to_non_nullable
as SnPost?,repliedPostId: freezed == repliedPostId ? _self.repliedPostId : repliedPostId // ignore: cast_nullable_to_non_nullable
as String?,repliedPost: freezed == repliedPost ? _self.repliedPost : repliedPost // ignore: cast_nullable_to_non_nullable
as SnPost?,forwardedPostId: freezed == forwardedPostId ? _self.forwardedPostId : forwardedPostId // ignore: cast_nullable_to_non_nullable
as String?,forwardedPost: freezed == forwardedPost ? _self.forwardedPost : forwardedPost // ignore: cast_nullable_to_non_nullable
as SnPost?,attachments: null == attachments ? _self.attachments : attachments // ignore: cast_nullable_to_non_nullable
as SnPost?,realmId: freezed == realmId ? _self.realmId : realmId // ignore: cast_nullable_to_non_nullable
as String?,realm: freezed == realm ? _self.realm : realm // ignore: cast_nullable_to_non_nullable
as SnRealm?,attachments: null == attachments ? _self.attachments : attachments // ignore: cast_nullable_to_non_nullable
as List<SnCloudFile>,publisher: null == publisher ? _self.publisher : publisher // ignore: cast_nullable_to_non_nullable
as SnPublisher,reactionsCount: null == reactionsCount ? _self.reactionsCount : reactionsCount // ignore: cast_nullable_to_non_nullable
as Map<String, int>,reactions: null == reactions ? _self.reactions : reactions // ignore: cast_nullable_to_non_nullable
as Map<String, int>,reactionsMade: null == reactionsMade ? _self.reactionsMade : reactionsMade // ignore: cast_nullable_to_non_nullable
as Map<String, bool>,reactions: null == reactions ? _self.reactions : reactions // ignore: cast_nullable_to_non_nullable
as List<dynamic>,tags: null == tags ? _self.tags : tags // ignore: cast_nullable_to_non_nullable
as List<PostTag>,categories: null == categories ? _self.categories : categories // ignore: cast_nullable_to_non_nullable
as List<PostCategory>,collections: null == collections ? _self.collections : collections // 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 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
@@ -142,6 +147,18 @@ $SnPostCopyWith<$Res>? get forwardedPost {
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnRealmCopyWith<$Res>? get realm {
if (_self.realm == null) {
return null;
}
return $SnRealmCopyWith<$Res>(_self.realm!, (value) {
return _then(_self.copyWith(realm: value));
});
}/// Create a copy of SnPost
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnPublisherCopyWith<$Res> get publisher {
return $SnPublisherCopyWith<$Res>(_self.publisher, (value) {
@@ -226,10 +243,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, int type, Map<String, dynamic>? meta, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, List<dynamic> reactions, List<PostTag> tags, List<PostCategory> 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, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, 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;
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.type,_that.meta,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.attachments,_that.publisher,_that.reactionsCount,_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.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_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 orElse();
}
@@ -247,10 +264,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, int type, Map<String, dynamic>? meta, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, List<dynamic> reactions, List<PostTag> tags, List<PostCategory> 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, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, 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;
switch (_that) {
case _SnPost():
return $default(_that.id,_that.title,_that.description,_that.language,_that.editedAt,_that.publishedAt,_that.visibility,_that.content,_that.type,_that.meta,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.attachments,_that.publisher,_that.reactionsCount,_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.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_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);}
}
/// A variant of `when` that fallback to returning `null`
///
@@ -264,10 +281,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, int type, Map<String, dynamic>? meta, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, List<dynamic> reactions, List<PostTag> tags, List<PostCategory> 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, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, 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;
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.type,_that.meta,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.attachments,_that.publisher,_that.reactionsCount,_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.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_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 null;
}
@@ -279,7 +296,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.type = 0, final Map<String, dynamic>? meta, this.viewsUnique = 0, this.viewsTotal = 0, this.upvotes = 0, this.downvotes = 0, this.repliesCount = 0, this.threadedPostId, this.threadedPost, this.repliedPostId, this.repliedPost, this.forwardedPostId, this.forwardedPost, final List<SnCloudFile> attachments = const [], required this.publisher, final Map<String, int> reactionsCount = const {}, final List<dynamic> reactions = const [], final List<PostTag> tags = const [], final List<PostCategory> categories = const [], final List<dynamic> collections = const [], this.createdAt = null, this.updatedAt = null, this.deletedAt, this.isTruncated = false}): _meta = meta,_attachments = attachments,_reactionsCount = reactionsCount,_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.viewsUnique = 0, this.viewsTotal = 0, this.upvotes = 0, this.downvotes = 0, this.repliesCount = 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;
factory _SnPost.fromJson(Map<String, dynamic> json) => _$SnPostFromJson(json);
@override final String id;
@@ -290,6 +307,7 @@ class _SnPost implements SnPost {
@override@JsonKey() final DateTime? publishedAt;
@override@JsonKey() final int visibility;
@override final String? content;
@override final String? slug;
@override@JsonKey() final int type;
final Map<String, dynamic>? _meta;
@override Map<String, dynamic>? get meta {
@@ -305,12 +323,15 @@ class _SnPost implements SnPost {
@override@JsonKey() final int upvotes;
@override@JsonKey() final int downvotes;
@override@JsonKey() final int repliesCount;
@override final int? pinMode;
@override final String? threadedPostId;
@override final SnPost? threadedPost;
@override final String? repliedPostId;
@override final SnPost? repliedPost;
@override final String? forwardedPostId;
@override final SnPost? forwardedPost;
@override final String? realmId;
@override final SnRealm? realm;
final List<SnCloudFile> _attachments;
@override@JsonKey() List<SnCloudFile> get attachments {
if (_attachments is EqualUnmodifiableListView) return _attachments;
@@ -326,6 +347,13 @@ class _SnPost implements SnPost {
return EqualUnmodifiableMapView(_reactionsCount);
}
final Map<String, bool> _reactionsMade;
@override@JsonKey() Map<String, bool> get reactionsMade {
if (_reactionsMade is EqualUnmodifiableMapView) return _reactionsMade;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(_reactionsMade);
}
final List<dynamic> _reactions;
@override@JsonKey() List<dynamic> get reactions {
if (_reactions is EqualUnmodifiableListView) return _reactions;
@@ -333,15 +361,15 @@ class _SnPost implements SnPost {
return EqualUnmodifiableListView(_reactions);
}
final List<PostTag> _tags;
@override@JsonKey() List<PostTag> get tags {
final List<SnPostTag> _tags;
@override@JsonKey() List<SnPostTag> get tags {
if (_tags is EqualUnmodifiableListView) return _tags;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_tags);
}
final List<PostCategory> _categories;
@override@JsonKey() List<PostCategory> get categories {
final List<SnPostCategory> _categories;
@override@JsonKey() List<SnPostCategory> get categories {
if (_categories is EqualUnmodifiableListView) return _categories;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_categories);
@@ -372,16 +400,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.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other._meta, _meta)&&(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.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)&&const DeepCollectionEquality().equals(other._attachments, _attachments)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&const DeepCollectionEquality().equals(other._reactionsCount, _reactionsCount)&&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.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.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));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hashAll([runtimeType,id,title,description,language,editedAt,publishedAt,visibility,content,type,const DeepCollectionEquality().hash(_meta),viewsUnique,viewsTotal,upvotes,downvotes,repliesCount,threadedPostId,threadedPost,repliedPostId,repliedPost,forwardedPostId,forwardedPost,const DeepCollectionEquality().hash(_attachments),publisher,const DeepCollectionEquality().hash(_reactionsCount),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),viewsUnique,viewsTotal,upvotes,downvotes,repliesCount,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]);
@override
String toString() {
return 'SnPost(id: $id, title: $title, description: $description, language: $language, editedAt: $editedAt, publishedAt: $publishedAt, visibility: $visibility, content: $content, type: $type, meta: $meta, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, repliesCount: $repliesCount, threadedPostId: $threadedPostId, threadedPost: $threadedPost, repliedPostId: $repliedPostId, repliedPost: $repliedPost, forwardedPostId: $forwardedPostId, forwardedPost: $forwardedPost, attachments: $attachments, publisher: $publisher, reactionsCount: $reactionsCount, 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, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, repliesCount: $repliesCount, 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)';
}
@@ -392,11 +420,11 @@ 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, int type, Map<String, dynamic>? meta, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, List<dynamic> reactions, List<PostTag> tags, List<PostCategory> 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, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, 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
});
@override $SnPostCopyWith<$Res>? get threadedPost;@override $SnPostCopyWith<$Res>? get repliedPost;@override $SnPostCopyWith<$Res>? get forwardedPost;@override $SnPublisherCopyWith<$Res> get publisher;
@override $SnPostCopyWith<$Res>? get threadedPost;@override $SnPostCopyWith<$Res>? get repliedPost;@override $SnPostCopyWith<$Res>? get forwardedPost;@override $SnRealmCopyWith<$Res>? get realm;@override $SnPublisherCopyWith<$Res> get publisher;
}
/// @nodoc
@@ -409,7 +437,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? type = null,Object? meta = freezed,Object? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? repliesCount = null,Object? threadedPostId = freezed,Object? threadedPost = freezed,Object? repliedPostId = freezed,Object? repliedPost = freezed,Object? forwardedPostId = freezed,Object? forwardedPost = freezed,Object? attachments = null,Object? publisher = null,Object? reactionsCount = 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? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? repliesCount = 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,}) {
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
@@ -419,6 +447,7 @@ as String?,editedAt: freezed == editedAt ? _self.editedAt : editedAt // ignore:
as DateTime?,publishedAt: freezed == publishedAt ? _self.publishedAt : publishedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,visibility: null == visibility ? _self.visibility : visibility // ignore: cast_nullable_to_non_nullable
as int,content: freezed == content ? _self.content : content // ignore: cast_nullable_to_non_nullable
as String?,slug: freezed == slug ? _self.slug : slug // ignore: cast_nullable_to_non_nullable
as String?,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
as int,meta: freezed == meta ? _self._meta : meta // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>?,viewsUnique: null == viewsUnique ? _self.viewsUnique : viewsUnique // ignore: cast_nullable_to_non_nullable
@@ -426,19 +455,23 @@ as int,viewsTotal: null == viewsTotal ? _self.viewsTotal : viewsTotal // ignore:
as int,upvotes: null == upvotes ? _self.upvotes : upvotes // ignore: cast_nullable_to_non_nullable
as int,downvotes: null == downvotes ? _self.downvotes : downvotes // ignore: cast_nullable_to_non_nullable
as int,repliesCount: null == repliesCount ? _self.repliesCount : repliesCount // ignore: cast_nullable_to_non_nullable
as int,threadedPostId: freezed == threadedPostId ? _self.threadedPostId : threadedPostId // ignore: cast_nullable_to_non_nullable
as int,pinMode: freezed == pinMode ? _self.pinMode : pinMode // ignore: cast_nullable_to_non_nullable
as int?,threadedPostId: freezed == threadedPostId ? _self.threadedPostId : threadedPostId // ignore: cast_nullable_to_non_nullable
as String?,threadedPost: freezed == threadedPost ? _self.threadedPost : threadedPost // ignore: cast_nullable_to_non_nullable
as SnPost?,repliedPostId: freezed == repliedPostId ? _self.repliedPostId : repliedPostId // ignore: cast_nullable_to_non_nullable
as String?,repliedPost: freezed == repliedPost ? _self.repliedPost : repliedPost // ignore: cast_nullable_to_non_nullable
as SnPost?,forwardedPostId: freezed == forwardedPostId ? _self.forwardedPostId : forwardedPostId // ignore: cast_nullable_to_non_nullable
as String?,forwardedPost: freezed == forwardedPost ? _self.forwardedPost : forwardedPost // ignore: cast_nullable_to_non_nullable
as SnPost?,attachments: null == attachments ? _self._attachments : attachments // ignore: cast_nullable_to_non_nullable
as SnPost?,realmId: freezed == realmId ? _self.realmId : realmId // ignore: cast_nullable_to_non_nullable
as String?,realm: freezed == realm ? _self.realm : realm // ignore: cast_nullable_to_non_nullable
as SnRealm?,attachments: null == attachments ? _self._attachments : attachments // ignore: cast_nullable_to_non_nullable
as List<SnCloudFile>,publisher: null == publisher ? _self.publisher : publisher // ignore: cast_nullable_to_non_nullable
as SnPublisher,reactionsCount: null == reactionsCount ? _self._reactionsCount : reactionsCount // ignore: cast_nullable_to_non_nullable
as Map<String, int>,reactions: null == reactions ? _self._reactions : reactions // ignore: cast_nullable_to_non_nullable
as Map<String, int>,reactionsMade: null == reactionsMade ? _self._reactionsMade : reactionsMade // ignore: cast_nullable_to_non_nullable
as Map<String, bool>,reactions: null == reactions ? _self._reactions : reactions // ignore: cast_nullable_to_non_nullable
as List<dynamic>,tags: null == tags ? _self._tags : tags // ignore: cast_nullable_to_non_nullable
as List<PostTag>,categories: null == categories ? _self._categories : categories // ignore: cast_nullable_to_non_nullable
as List<PostCategory>,collections: null == collections ? _self._collections : collections // 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 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
@@ -487,6 +520,18 @@ $SnPostCopyWith<$Res>? get forwardedPost {
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnRealmCopyWith<$Res>? get realm {
if (_self.realm == null) {
return null;
}
return $SnRealmCopyWith<$Res>(_self.realm!, (value) {
return _then(_self.copyWith(realm: value));
});
}/// Create a copy of SnPost
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnPublisherCopyWith<$Res> get publisher {
return $SnPublisherCopyWith<$Res>(_self.publisher, (value) {

View File

@@ -21,6 +21,7 @@ _SnPost _$SnPostFromJson(Map<String, dynamic> json) => _SnPost(
: DateTime.parse(json['published_at'] as String),
visibility: (json['visibility'] as num?)?.toInt() ?? 0,
content: json['content'] as String?,
slug: json['slug'] as String?,
type: (json['type'] as num?)?.toInt() ?? 0,
meta: json['meta'] as Map<String, dynamic>?,
viewsUnique: (json['views_unique'] as num?)?.toInt() ?? 0,
@@ -28,6 +29,7 @@ _SnPost _$SnPostFromJson(Map<String, dynamic> json) => _SnPost(
upvotes: (json['upvotes'] as num?)?.toInt() ?? 0,
downvotes: (json['downvotes'] as num?)?.toInt() ?? 0,
repliesCount: (json['replies_count'] as num?)?.toInt() ?? 0,
pinMode: (json['pin_mode'] as num?)?.toInt(),
threadedPostId: json['threaded_post_id'] as String?,
threadedPost:
json['threaded_post'] == null
@@ -43,6 +45,11 @@ _SnPost _$SnPostFromJson(Map<String, dynamic> json) => _SnPost(
json['forwarded_post'] == null
? null
: SnPost.fromJson(json['forwarded_post'] as Map<String, dynamic>),
realmId: json['realm_id'] as String?,
realm:
json['realm'] == null
? null
: SnRealm.fromJson(json['realm'] as Map<String, dynamic>),
attachments:
(json['attachments'] as List<dynamic>?)
?.map((e) => SnCloudFile.fromJson(e as Map<String, dynamic>))
@@ -54,15 +61,20 @@ _SnPost _$SnPostFromJson(Map<String, dynamic> json) => _SnPost(
(k, e) => MapEntry(k, (e as num).toInt()),
) ??
const {},
reactionsMade:
(json['reactions_made'] as Map<String, dynamic>?)?.map(
(k, e) => MapEntry(k, e as bool),
) ??
const {},
reactions: json['reactions'] as List<dynamic>? ?? const [],
tags:
(json['tags'] as List<dynamic>?)
?.map((e) => PostTag.fromJson(e as Map<String, dynamic>))
?.map((e) => SnPostTag.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
categories:
(json['categories'] as List<dynamic>?)
?.map((e) => PostCategory.fromJson(e as Map<String, dynamic>))
?.map((e) => SnPostCategory.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
collections: json['collections'] as List<dynamic>? ?? const [],
@@ -90,6 +102,7 @@ Map<String, dynamic> _$SnPostToJson(_SnPost instance) => <String, dynamic>{
'published_at': instance.publishedAt?.toIso8601String(),
'visibility': instance.visibility,
'content': instance.content,
'slug': instance.slug,
'type': instance.type,
'meta': instance.meta,
'views_unique': instance.viewsUnique,
@@ -97,15 +110,19 @@ Map<String, dynamic> _$SnPostToJson(_SnPost instance) => <String, dynamic>{
'upvotes': instance.upvotes,
'downvotes': instance.downvotes,
'replies_count': instance.repliesCount,
'pin_mode': instance.pinMode,
'threaded_post_id': instance.threadedPostId,
'threaded_post': instance.threadedPost?.toJson(),
'replied_post_id': instance.repliedPostId,
'replied_post': instance.repliedPost?.toJson(),
'forwarded_post_id': instance.forwardedPostId,
'forwarded_post': instance.forwardedPost?.toJson(),
'realm_id': instance.realmId,
'realm': instance.realm?.toJson(),
'attachments': instance.attachments.map((e) => e.toJson()).toList(),
'publisher': instance.publisher.toJson(),
'reactions_count': instance.reactionsCount,
'reactions_made': instance.reactionsMade,
'reactions': instance.reactions,
'tags': instance.tags.map((e) => e.toJson()).toList(),
'categories': instance.categories.map((e) => e.toJson()).toList(),

View File

@@ -1,19 +1,31 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:island/models/post.dart';
import 'package:island/services/text.dart';
part 'post_category.freezed.dart';
part 'post_category.g.dart';
@freezed
sealed class PostCategory with _$PostCategory {
const factory PostCategory({
sealed class SnPostCategory with _$SnPostCategory {
const SnPostCategory._();
const factory SnPostCategory({
required String id,
required String slug,
String? name,
@Default([]) List<SnPost> posts,
}) = _PostCategory;
@Default(0) int usage,
}) = _SnPostCategory;
factory PostCategory.fromJson(Map<String, dynamic> json) =>
_$PostCategoryFromJson(json);
factory SnPostCategory.fromJson(Map<String, dynamic> json) =>
_$SnPostCategoryFromJson(json);
String get categoryDisplayTitle {
final capitalizedSlug = slug.capitalizeEachWord();
if ('postCategory$capitalizedSlug'.trExists()) {
return 'postCategory$capitalizedSlug'.tr();
}
return name ?? slug;
}
}

View File

@@ -13,42 +13,42 @@ part of 'post_category.dart';
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$PostCategory {
mixin _$SnPostCategory {
String get id; String get slug; String? get name; List<SnPost> get posts;
/// Create a copy of PostCategory
String get id; String get slug; String? get name; List<SnPost> get posts; int get usage;
/// Create a copy of SnPostCategory
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$PostCategoryCopyWith<PostCategory> get copyWith => _$PostCategoryCopyWithImpl<PostCategory>(this as PostCategory, _$identity);
$SnPostCategoryCopyWith<SnPostCategory> get copyWith => _$SnPostCategoryCopyWithImpl<SnPostCategory>(this as SnPostCategory, _$identity);
/// Serializes this PostCategory to a JSON map.
/// Serializes this SnPostCategory to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is PostCategory&&(identical(other.id, id) || other.id == id)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.name, name) || other.name == name)&&const DeepCollectionEquality().equals(other.posts, posts));
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPostCategory&&(identical(other.id, id) || other.id == id)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.name, name) || other.name == name)&&const DeepCollectionEquality().equals(other.posts, posts)&&(identical(other.usage, usage) || other.usage == usage));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,slug,name,const DeepCollectionEquality().hash(posts));
int get hashCode => Object.hash(runtimeType,id,slug,name,const DeepCollectionEquality().hash(posts),usage);
@override
String toString() {
return 'PostCategory(id: $id, slug: $slug, name: $name, posts: $posts)';
return 'SnPostCategory(id: $id, slug: $slug, name: $name, posts: $posts, usage: $usage)';
}
}
/// @nodoc
abstract mixin class $PostCategoryCopyWith<$Res> {
factory $PostCategoryCopyWith(PostCategory value, $Res Function(PostCategory) _then) = _$PostCategoryCopyWithImpl;
abstract mixin class $SnPostCategoryCopyWith<$Res> {
factory $SnPostCategoryCopyWith(SnPostCategory value, $Res Function(SnPostCategory) _then) = _$SnPostCategoryCopyWithImpl;
@useResult
$Res call({
String id, String slug, String? name, List<SnPost> posts
String id, String slug, String? name, List<SnPost> posts, int usage
});
@@ -56,30 +56,31 @@ $Res call({
}
/// @nodoc
class _$PostCategoryCopyWithImpl<$Res>
implements $PostCategoryCopyWith<$Res> {
_$PostCategoryCopyWithImpl(this._self, this._then);
class _$SnPostCategoryCopyWithImpl<$Res>
implements $SnPostCategoryCopyWith<$Res> {
_$SnPostCategoryCopyWithImpl(this._self, this._then);
final PostCategory _self;
final $Res Function(PostCategory) _then;
final SnPostCategory _self;
final $Res Function(SnPostCategory) _then;
/// Create a copy of PostCategory
/// Create a copy of SnPostCategory
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? slug = null,Object? name = freezed,Object? posts = null,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? slug = null,Object? name = freezed,Object? posts = null,Object? usage = null,}) {
return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,slug: null == slug ? _self.slug : slug // ignore: cast_nullable_to_non_nullable
as String,name: freezed == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String?,posts: null == posts ? _self.posts : posts // ignore: cast_nullable_to_non_nullable
as List<SnPost>,
as List<SnPost>,usage: null == usage ? _self.usage : usage // ignore: cast_nullable_to_non_nullable
as int,
));
}
}
/// Adds pattern-matching-related methods to [PostCategory].
extension PostCategoryPatterns on PostCategory {
/// Adds pattern-matching-related methods to [SnPostCategory].
extension SnPostCategoryPatterns on SnPostCategory {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
@@ -92,10 +93,10 @@ extension PostCategoryPatterns on PostCategory {
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _PostCategory value)? $default,{required TResult orElse(),}){
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _SnPostCategory value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _PostCategory() when $default != null:
case _SnPostCategory() when $default != null:
return $default(_that);case _:
return orElse();
@@ -114,10 +115,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _PostCategory value) $default,){
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _SnPostCategory value) $default,){
final _that = this;
switch (_that) {
case _PostCategory():
case _SnPostCategory():
return $default(_that);}
}
/// A variant of `map` that fallback to returning `null`.
@@ -132,10 +133,10 @@ return $default(_that);}
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _PostCategory value)? $default,){
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _SnPostCategory value)? $default,){
final _that = this;
switch (_that) {
case _PostCategory() when $default != null:
case _SnPostCategory() when $default != null:
return $default(_that);case _:
return null;
@@ -153,10 +154,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String slug, String? name, List<SnPost> posts)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String slug, String? name, List<SnPost> posts, int usage)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _PostCategory() when $default != null:
return $default(_that.id,_that.slug,_that.name,_that.posts);case _:
case _SnPostCategory() when $default != null:
return $default(_that.id,_that.slug,_that.name,_that.posts,_that.usage);case _:
return orElse();
}
@@ -174,10 +175,10 @@ return $default(_that.id,_that.slug,_that.name,_that.posts);case _:
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String slug, String? name, List<SnPost> posts) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String slug, String? name, List<SnPost> posts, int usage) $default,) {final _that = this;
switch (_that) {
case _PostCategory():
return $default(_that.id,_that.slug,_that.name,_that.posts);}
case _SnPostCategory():
return $default(_that.id,_that.slug,_that.name,_that.posts,_that.usage);}
}
/// A variant of `when` that fallback to returning `null`
///
@@ -191,10 +192,10 @@ return $default(_that.id,_that.slug,_that.name,_that.posts);}
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String slug, String? name, List<SnPost> posts)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String slug, String? name, List<SnPost> posts, int usage)? $default,) {final _that = this;
switch (_that) {
case _PostCategory() when $default != null:
return $default(_that.id,_that.slug,_that.name,_that.posts);case _:
case _SnPostCategory() when $default != null:
return $default(_that.id,_that.slug,_that.name,_that.posts,_that.usage);case _:
return null;
}
@@ -205,9 +206,9 @@ return $default(_that.id,_that.slug,_that.name,_that.posts);case _:
/// @nodoc
@JsonSerializable()
class _PostCategory implements PostCategory {
const _PostCategory({required this.id, required this.slug, this.name, final List<SnPost> posts = const []}): _posts = posts;
factory _PostCategory.fromJson(Map<String, dynamic> json) => _$PostCategoryFromJson(json);
class _SnPostCategory extends SnPostCategory {
const _SnPostCategory({required this.id, required this.slug, this.name, final List<SnPost> posts = const [], this.usage = 0}): _posts = posts,super._();
factory _SnPostCategory.fromJson(Map<String, dynamic> json) => _$SnPostCategoryFromJson(json);
@override final String id;
@override final String slug;
@@ -219,41 +220,42 @@ class _PostCategory implements PostCategory {
return EqualUnmodifiableListView(_posts);
}
@override@JsonKey() final int usage;
/// Create a copy of PostCategory
/// Create a copy of SnPostCategory
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$PostCategoryCopyWith<_PostCategory> get copyWith => __$PostCategoryCopyWithImpl<_PostCategory>(this, _$identity);
_$SnPostCategoryCopyWith<_SnPostCategory> get copyWith => __$SnPostCategoryCopyWithImpl<_SnPostCategory>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$PostCategoryToJson(this, );
return _$SnPostCategoryToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _PostCategory&&(identical(other.id, id) || other.id == id)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.name, name) || other.name == name)&&const DeepCollectionEquality().equals(other._posts, _posts));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPostCategory&&(identical(other.id, id) || other.id == id)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.name, name) || other.name == name)&&const DeepCollectionEquality().equals(other._posts, _posts)&&(identical(other.usage, usage) || other.usage == usage));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,slug,name,const DeepCollectionEquality().hash(_posts));
int get hashCode => Object.hash(runtimeType,id,slug,name,const DeepCollectionEquality().hash(_posts),usage);
@override
String toString() {
return 'PostCategory(id: $id, slug: $slug, name: $name, posts: $posts)';
return 'SnPostCategory(id: $id, slug: $slug, name: $name, posts: $posts, usage: $usage)';
}
}
/// @nodoc
abstract mixin class _$PostCategoryCopyWith<$Res> implements $PostCategoryCopyWith<$Res> {
factory _$PostCategoryCopyWith(_PostCategory value, $Res Function(_PostCategory) _then) = __$PostCategoryCopyWithImpl;
abstract mixin class _$SnPostCategoryCopyWith<$Res> implements $SnPostCategoryCopyWith<$Res> {
factory _$SnPostCategoryCopyWith(_SnPostCategory value, $Res Function(_SnPostCategory) _then) = __$SnPostCategoryCopyWithImpl;
@override @useResult
$Res call({
String id, String slug, String? name, List<SnPost> posts
String id, String slug, String? name, List<SnPost> posts, int usage
});
@@ -261,22 +263,23 @@ $Res call({
}
/// @nodoc
class __$PostCategoryCopyWithImpl<$Res>
implements _$PostCategoryCopyWith<$Res> {
__$PostCategoryCopyWithImpl(this._self, this._then);
class __$SnPostCategoryCopyWithImpl<$Res>
implements _$SnPostCategoryCopyWith<$Res> {
__$SnPostCategoryCopyWithImpl(this._self, this._then);
final _PostCategory _self;
final $Res Function(_PostCategory) _then;
final _SnPostCategory _self;
final $Res Function(_SnPostCategory) _then;
/// Create a copy of PostCategory
/// Create a copy of SnPostCategory
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? slug = null,Object? name = freezed,Object? posts = null,}) {
return _then(_PostCategory(
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? slug = null,Object? name = freezed,Object? posts = null,Object? usage = null,}) {
return _then(_SnPostCategory(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,slug: null == slug ? _self.slug : slug // ignore: cast_nullable_to_non_nullable
as String,name: freezed == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String?,posts: null == posts ? _self._posts : posts // ignore: cast_nullable_to_non_nullable
as List<SnPost>,
as List<SnPost>,usage: null == usage ? _self.usage : usage // ignore: cast_nullable_to_non_nullable
as int,
));
}

View File

@@ -6,8 +6,8 @@ part of 'post_category.dart';
// JsonSerializableGenerator
// **************************************************************************
_PostCategory _$PostCategoryFromJson(Map<String, dynamic> json) =>
_PostCategory(
_SnPostCategory _$SnPostCategoryFromJson(Map<String, dynamic> json) =>
_SnPostCategory(
id: json['id'] as String,
slug: json['slug'] as String,
name: json['name'] as String?,
@@ -16,12 +16,14 @@ _PostCategory _$PostCategoryFromJson(Map<String, dynamic> json) =>
?.map((e) => SnPost.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
usage: (json['usage'] as num?)?.toInt() ?? 0,
);
Map<String, dynamic> _$PostCategoryToJson(_PostCategory instance) =>
Map<String, dynamic> _$SnPostCategoryToJson(_SnPostCategory instance) =>
<String, dynamic>{
'id': instance.id,
'slug': instance.slug,
'name': instance.name,
'posts': instance.posts.map((e) => e.toJson()).toList(),
'usage': instance.usage,
};

View File

@@ -1,4 +1,3 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:island/models/post.dart';
@@ -6,14 +5,15 @@ part 'post_tag.freezed.dart';
part 'post_tag.g.dart';
@freezed
sealed class PostTag with _$PostTag {
const factory PostTag({
sealed class SnPostTag with _$SnPostTag {
const factory SnPostTag({
required String id,
required String slug,
String? name,
@Default([]) List<SnPost> posts,
}) = _PostTag;
@Default(0) int usage,
}) = _SnPostTag;
factory PostTag.fromJson(Map<String, dynamic> json) =>
_$PostTagFromJson(json);
factory SnPostTag.fromJson(Map<String, dynamic> json) =>
_$SnPostTagFromJson(json);
}

View File

@@ -13,42 +13,42 @@ part of 'post_tag.dart';
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$PostTag {
mixin _$SnPostTag {
String get id; String get slug; String? get name; List<SnPost> get posts;
/// Create a copy of PostTag
String get id; String get slug; String? get name; List<SnPost> get posts; int get usage;
/// Create a copy of SnPostTag
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$PostTagCopyWith<PostTag> get copyWith => _$PostTagCopyWithImpl<PostTag>(this as PostTag, _$identity);
$SnPostTagCopyWith<SnPostTag> get copyWith => _$SnPostTagCopyWithImpl<SnPostTag>(this as SnPostTag, _$identity);
/// Serializes this PostTag to a JSON map.
/// Serializes this SnPostTag to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is PostTag&&(identical(other.id, id) || other.id == id)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.name, name) || other.name == name)&&const DeepCollectionEquality().equals(other.posts, posts));
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPostTag&&(identical(other.id, id) || other.id == id)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.name, name) || other.name == name)&&const DeepCollectionEquality().equals(other.posts, posts)&&(identical(other.usage, usage) || other.usage == usage));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,slug,name,const DeepCollectionEquality().hash(posts));
int get hashCode => Object.hash(runtimeType,id,slug,name,const DeepCollectionEquality().hash(posts),usage);
@override
String toString() {
return 'PostTag(id: $id, slug: $slug, name: $name, posts: $posts)';
return 'SnPostTag(id: $id, slug: $slug, name: $name, posts: $posts, usage: $usage)';
}
}
/// @nodoc
abstract mixin class $PostTagCopyWith<$Res> {
factory $PostTagCopyWith(PostTag value, $Res Function(PostTag) _then) = _$PostTagCopyWithImpl;
abstract mixin class $SnPostTagCopyWith<$Res> {
factory $SnPostTagCopyWith(SnPostTag value, $Res Function(SnPostTag) _then) = _$SnPostTagCopyWithImpl;
@useResult
$Res call({
String id, String slug, String? name, List<SnPost> posts
String id, String slug, String? name, List<SnPost> posts, int usage
});
@@ -56,30 +56,31 @@ $Res call({
}
/// @nodoc
class _$PostTagCopyWithImpl<$Res>
implements $PostTagCopyWith<$Res> {
_$PostTagCopyWithImpl(this._self, this._then);
class _$SnPostTagCopyWithImpl<$Res>
implements $SnPostTagCopyWith<$Res> {
_$SnPostTagCopyWithImpl(this._self, this._then);
final PostTag _self;
final $Res Function(PostTag) _then;
final SnPostTag _self;
final $Res Function(SnPostTag) _then;
/// Create a copy of PostTag
/// Create a copy of SnPostTag
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? slug = null,Object? name = freezed,Object? posts = null,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? slug = null,Object? name = freezed,Object? posts = null,Object? usage = null,}) {
return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,slug: null == slug ? _self.slug : slug // ignore: cast_nullable_to_non_nullable
as String,name: freezed == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String?,posts: null == posts ? _self.posts : posts // ignore: cast_nullable_to_non_nullable
as List<SnPost>,
as List<SnPost>,usage: null == usage ? _self.usage : usage // ignore: cast_nullable_to_non_nullable
as int,
));
}
}
/// Adds pattern-matching-related methods to [PostTag].
extension PostTagPatterns on PostTag {
/// Adds pattern-matching-related methods to [SnPostTag].
extension SnPostTagPatterns on SnPostTag {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
@@ -92,10 +93,10 @@ extension PostTagPatterns on PostTag {
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _PostTag value)? $default,{required TResult orElse(),}){
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _SnPostTag value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _PostTag() when $default != null:
case _SnPostTag() when $default != null:
return $default(_that);case _:
return orElse();
@@ -114,10 +115,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _PostTag value) $default,){
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _SnPostTag value) $default,){
final _that = this;
switch (_that) {
case _PostTag():
case _SnPostTag():
return $default(_that);}
}
/// A variant of `map` that fallback to returning `null`.
@@ -132,10 +133,10 @@ return $default(_that);}
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _PostTag value)? $default,){
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _SnPostTag value)? $default,){
final _that = this;
switch (_that) {
case _PostTag() when $default != null:
case _SnPostTag() when $default != null:
return $default(_that);case _:
return null;
@@ -153,10 +154,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String slug, String? name, List<SnPost> posts)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String slug, String? name, List<SnPost> posts, int usage)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _PostTag() when $default != null:
return $default(_that.id,_that.slug,_that.name,_that.posts);case _:
case _SnPostTag() when $default != null:
return $default(_that.id,_that.slug,_that.name,_that.posts,_that.usage);case _:
return orElse();
}
@@ -174,10 +175,10 @@ return $default(_that.id,_that.slug,_that.name,_that.posts);case _:
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String slug, String? name, List<SnPost> posts) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String slug, String? name, List<SnPost> posts, int usage) $default,) {final _that = this;
switch (_that) {
case _PostTag():
return $default(_that.id,_that.slug,_that.name,_that.posts);}
case _SnPostTag():
return $default(_that.id,_that.slug,_that.name,_that.posts,_that.usage);}
}
/// A variant of `when` that fallback to returning `null`
///
@@ -191,10 +192,10 @@ return $default(_that.id,_that.slug,_that.name,_that.posts);}
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String slug, String? name, List<SnPost> posts)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String slug, String? name, List<SnPost> posts, int usage)? $default,) {final _that = this;
switch (_that) {
case _PostTag() when $default != null:
return $default(_that.id,_that.slug,_that.name,_that.posts);case _:
case _SnPostTag() when $default != null:
return $default(_that.id,_that.slug,_that.name,_that.posts,_that.usage);case _:
return null;
}
@@ -205,9 +206,9 @@ return $default(_that.id,_that.slug,_that.name,_that.posts);case _:
/// @nodoc
@JsonSerializable()
class _PostTag implements PostTag {
const _PostTag({required this.id, required this.slug, this.name, final List<SnPost> posts = const []}): _posts = posts;
factory _PostTag.fromJson(Map<String, dynamic> json) => _$PostTagFromJson(json);
class _SnPostTag implements SnPostTag {
const _SnPostTag({required this.id, required this.slug, this.name, final List<SnPost> posts = const [], this.usage = 0}): _posts = posts;
factory _SnPostTag.fromJson(Map<String, dynamic> json) => _$SnPostTagFromJson(json);
@override final String id;
@override final String slug;
@@ -219,41 +220,42 @@ class _PostTag implements PostTag {
return EqualUnmodifiableListView(_posts);
}
@override@JsonKey() final int usage;
/// Create a copy of PostTag
/// Create a copy of SnPostTag
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$PostTagCopyWith<_PostTag> get copyWith => __$PostTagCopyWithImpl<_PostTag>(this, _$identity);
_$SnPostTagCopyWith<_SnPostTag> get copyWith => __$SnPostTagCopyWithImpl<_SnPostTag>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$PostTagToJson(this, );
return _$SnPostTagToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _PostTag&&(identical(other.id, id) || other.id == id)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.name, name) || other.name == name)&&const DeepCollectionEquality().equals(other._posts, _posts));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPostTag&&(identical(other.id, id) || other.id == id)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.name, name) || other.name == name)&&const DeepCollectionEquality().equals(other._posts, _posts)&&(identical(other.usage, usage) || other.usage == usage));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,slug,name,const DeepCollectionEquality().hash(_posts));
int get hashCode => Object.hash(runtimeType,id,slug,name,const DeepCollectionEquality().hash(_posts),usage);
@override
String toString() {
return 'PostTag(id: $id, slug: $slug, name: $name, posts: $posts)';
return 'SnPostTag(id: $id, slug: $slug, name: $name, posts: $posts, usage: $usage)';
}
}
/// @nodoc
abstract mixin class _$PostTagCopyWith<$Res> implements $PostTagCopyWith<$Res> {
factory _$PostTagCopyWith(_PostTag value, $Res Function(_PostTag) _then) = __$PostTagCopyWithImpl;
abstract mixin class _$SnPostTagCopyWith<$Res> implements $SnPostTagCopyWith<$Res> {
factory _$SnPostTagCopyWith(_SnPostTag value, $Res Function(_SnPostTag) _then) = __$SnPostTagCopyWithImpl;
@override @useResult
$Res call({
String id, String slug, String? name, List<SnPost> posts
String id, String slug, String? name, List<SnPost> posts, int usage
});
@@ -261,22 +263,23 @@ $Res call({
}
/// @nodoc
class __$PostTagCopyWithImpl<$Res>
implements _$PostTagCopyWith<$Res> {
__$PostTagCopyWithImpl(this._self, this._then);
class __$SnPostTagCopyWithImpl<$Res>
implements _$SnPostTagCopyWith<$Res> {
__$SnPostTagCopyWithImpl(this._self, this._then);
final _PostTag _self;
final $Res Function(_PostTag) _then;
final _SnPostTag _self;
final $Res Function(_SnPostTag) _then;
/// Create a copy of PostTag
/// Create a copy of SnPostTag
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? slug = null,Object? name = freezed,Object? posts = null,}) {
return _then(_PostTag(
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? slug = null,Object? name = freezed,Object? posts = null,Object? usage = null,}) {
return _then(_SnPostTag(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,slug: null == slug ? _self.slug : slug // ignore: cast_nullable_to_non_nullable
as String,name: freezed == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String?,posts: null == posts ? _self._posts : posts // ignore: cast_nullable_to_non_nullable
as List<SnPost>,
as List<SnPost>,usage: null == usage ? _self.usage : usage // ignore: cast_nullable_to_non_nullable
as int,
));
}

View File

@@ -6,7 +6,7 @@ part of 'post_tag.dart';
// JsonSerializableGenerator
// **************************************************************************
_PostTag _$PostTagFromJson(Map<String, dynamic> json) => _PostTag(
_SnPostTag _$SnPostTagFromJson(Map<String, dynamic> json) => _SnPostTag(
id: json['id'] as String,
slug: json['slug'] as String,
name: json['name'] as String?,
@@ -15,11 +15,14 @@ _PostTag _$PostTagFromJson(Map<String, dynamic> json) => _PostTag(
?.map((e) => SnPost.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
usage: (json['usage'] as num?)?.toInt() ?? 0,
);
Map<String, dynamic> _$PostTagToJson(_PostTag instance) => <String, dynamic>{
'id': instance.id,
'slug': instance.slug,
'name': instance.name,
'posts': instance.posts.map((e) => e.toJson()).toList(),
};
Map<String, dynamic> _$SnPostTagToJson(_SnPostTag instance) =>
<String, dynamic>{
'id': instance.id,
'slug': instance.slug,
'name': instance.name,
'posts': instance.posts.map((e) => e.toJson()).toList(),
'usage': instance.usage,
};

View File

@@ -1,6 +1,6 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:island/models/file.dart';
import 'package:island/models/user.dart';
import 'package:island/models/account.dart';
part 'publisher.freezed.dart';
part 'publisher.g.dart';

View File

@@ -1,6 +1,6 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:island/models/file.dart';
import 'package:island/models/user.dart';
import 'package:island/models/account.dart';
part 'realm.freezed.dart';
part 'realm.g.dart';
@@ -40,6 +40,7 @@ sealed class SnRealmMember with _$SnRealmMember {
required DateTime createdAt,
required DateTime updatedAt,
required DateTime? deletedAt,
required SnAccountStatus? status,
}) = _SnRealmMember;
factory SnRealmMember.fromJson(Map<String, dynamic> json) =>

View File

@@ -359,7 +359,7 @@ $SnCloudFileCopyWith<$Res>? get background {
/// @nodoc
mixin _$SnRealmMember {
String get realmId; SnRealm? get realm; String get accountId; SnAccount? get account; int get role; DateTime? get joinedAt; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
String get realmId; SnRealm? get realm; String get accountId; SnAccount? get account; int get role; DateTime? get joinedAt; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; SnAccountStatus? get status;
/// Create a copy of SnRealmMember
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -372,16 +372,16 @@ $SnRealmMemberCopyWith<SnRealmMember> get copyWith => _$SnRealmMemberCopyWithImp
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnRealmMember&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.account, account) || other.account == account)&&(identical(other.role, role) || other.role == role)&&(identical(other.joinedAt, joinedAt) || other.joinedAt == joinedAt)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnRealmMember&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.account, account) || other.account == account)&&(identical(other.role, role) || other.role == role)&&(identical(other.joinedAt, joinedAt) || other.joinedAt == joinedAt)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.status, status) || other.status == status));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,realmId,realm,accountId,account,role,joinedAt,createdAt,updatedAt,deletedAt);
int get hashCode => Object.hash(runtimeType,realmId,realm,accountId,account,role,joinedAt,createdAt,updatedAt,deletedAt,status);
@override
String toString() {
return 'SnRealmMember(realmId: $realmId, realm: $realm, accountId: $accountId, account: $account, role: $role, joinedAt: $joinedAt, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
return 'SnRealmMember(realmId: $realmId, realm: $realm, accountId: $accountId, account: $account, role: $role, joinedAt: $joinedAt, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, status: $status)';
}
@@ -392,11 +392,11 @@ abstract mixin class $SnRealmMemberCopyWith<$Res> {
factory $SnRealmMemberCopyWith(SnRealmMember value, $Res Function(SnRealmMember) _then) = _$SnRealmMemberCopyWithImpl;
@useResult
$Res call({
String realmId, SnRealm? realm, String accountId, SnAccount? account, int role, DateTime? joinedAt, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
String realmId, SnRealm? realm, String accountId, SnAccount? account, int role, DateTime? joinedAt, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, SnAccountStatus? status
});
$SnRealmCopyWith<$Res>? get realm;$SnAccountCopyWith<$Res>? get account;
$SnRealmCopyWith<$Res>? get realm;$SnAccountCopyWith<$Res>? get account;$SnAccountStatusCopyWith<$Res>? get status;
}
/// @nodoc
@@ -409,7 +409,7 @@ class _$SnRealmMemberCopyWithImpl<$Res>
/// Create a copy of SnRealmMember
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? realmId = null,Object? realm = freezed,Object? accountId = null,Object? account = freezed,Object? role = null,Object? joinedAt = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? realmId = null,Object? realm = freezed,Object? accountId = null,Object? account = freezed,Object? role = null,Object? joinedAt = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? status = freezed,}) {
return _then(_self.copyWith(
realmId: null == realmId ? _self.realmId : realmId // ignore: cast_nullable_to_non_nullable
as String,realm: freezed == realm ? _self.realm : realm // ignore: cast_nullable_to_non_nullable
@@ -420,7 +420,8 @@ as int,joinedAt: freezed == joinedAt ? _self.joinedAt : joinedAt // ignore: cast
as DateTime?,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?,
as DateTime?,status: freezed == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
as SnAccountStatus?,
));
}
/// Create a copy of SnRealmMember
@@ -447,6 +448,18 @@ $SnAccountCopyWith<$Res>? get account {
return $SnAccountCopyWith<$Res>(_self.account!, (value) {
return _then(_self.copyWith(account: value));
});
}/// Create a copy of SnRealmMember
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnAccountStatusCopyWith<$Res>? get status {
if (_self.status == null) {
return null;
}
return $SnAccountStatusCopyWith<$Res>(_self.status!, (value) {
return _then(_self.copyWith(status: value));
});
}
}
@@ -526,10 +539,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String realmId, SnRealm? realm, String accountId, SnAccount? account, int role, DateTime? joinedAt, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String realmId, SnRealm? realm, String accountId, SnAccount? account, int role, DateTime? joinedAt, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, SnAccountStatus? status)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnRealmMember() when $default != null:
return $default(_that.realmId,_that.realm,_that.accountId,_that.account,_that.role,_that.joinedAt,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return $default(_that.realmId,_that.realm,_that.accountId,_that.account,_that.role,_that.joinedAt,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.status);case _:
return orElse();
}
@@ -547,10 +560,10 @@ return $default(_that.realmId,_that.realm,_that.accountId,_that.account,_that.ro
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String realmId, SnRealm? realm, String accountId, SnAccount? account, int role, DateTime? joinedAt, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String realmId, SnRealm? realm, String accountId, SnAccount? account, int role, DateTime? joinedAt, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, SnAccountStatus? status) $default,) {final _that = this;
switch (_that) {
case _SnRealmMember():
return $default(_that.realmId,_that.realm,_that.accountId,_that.account,_that.role,_that.joinedAt,_that.createdAt,_that.updatedAt,_that.deletedAt);}
return $default(_that.realmId,_that.realm,_that.accountId,_that.account,_that.role,_that.joinedAt,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.status);}
}
/// A variant of `when` that fallback to returning `null`
///
@@ -564,10 +577,10 @@ return $default(_that.realmId,_that.realm,_that.accountId,_that.account,_that.ro
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String realmId, SnRealm? realm, String accountId, SnAccount? account, int role, DateTime? joinedAt, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String realmId, SnRealm? realm, String accountId, SnAccount? account, int role, DateTime? joinedAt, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, SnAccountStatus? status)? $default,) {final _that = this;
switch (_that) {
case _SnRealmMember() when $default != null:
return $default(_that.realmId,_that.realm,_that.accountId,_that.account,_that.role,_that.joinedAt,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return $default(_that.realmId,_that.realm,_that.accountId,_that.account,_that.role,_that.joinedAt,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.status);case _:
return null;
}
@@ -579,7 +592,7 @@ return $default(_that.realmId,_that.realm,_that.accountId,_that.account,_that.ro
@JsonSerializable()
class _SnRealmMember implements SnRealmMember {
const _SnRealmMember({required this.realmId, required this.realm, required this.accountId, required this.account, required this.role, required this.joinedAt, required this.createdAt, required this.updatedAt, required this.deletedAt});
const _SnRealmMember({required this.realmId, required this.realm, required this.accountId, required this.account, required this.role, required this.joinedAt, required this.createdAt, required this.updatedAt, required this.deletedAt, required this.status});
factory _SnRealmMember.fromJson(Map<String, dynamic> json) => _$SnRealmMemberFromJson(json);
@override final String realmId;
@@ -591,6 +604,7 @@ class _SnRealmMember implements SnRealmMember {
@override final DateTime createdAt;
@override final DateTime updatedAt;
@override final DateTime? deletedAt;
@override final SnAccountStatus? status;
/// Create a copy of SnRealmMember
/// with the given fields replaced by the non-null parameter values.
@@ -605,16 +619,16 @@ Map<String, dynamic> toJson() {
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnRealmMember&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.account, account) || other.account == account)&&(identical(other.role, role) || other.role == role)&&(identical(other.joinedAt, joinedAt) || other.joinedAt == joinedAt)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnRealmMember&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.account, account) || other.account == account)&&(identical(other.role, role) || other.role == role)&&(identical(other.joinedAt, joinedAt) || other.joinedAt == joinedAt)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.status, status) || other.status == status));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,realmId,realm,accountId,account,role,joinedAt,createdAt,updatedAt,deletedAt);
int get hashCode => Object.hash(runtimeType,realmId,realm,accountId,account,role,joinedAt,createdAt,updatedAt,deletedAt,status);
@override
String toString() {
return 'SnRealmMember(realmId: $realmId, realm: $realm, accountId: $accountId, account: $account, role: $role, joinedAt: $joinedAt, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
return 'SnRealmMember(realmId: $realmId, realm: $realm, accountId: $accountId, account: $account, role: $role, joinedAt: $joinedAt, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, status: $status)';
}
@@ -625,11 +639,11 @@ abstract mixin class _$SnRealmMemberCopyWith<$Res> implements $SnRealmMemberCopy
factory _$SnRealmMemberCopyWith(_SnRealmMember value, $Res Function(_SnRealmMember) _then) = __$SnRealmMemberCopyWithImpl;
@override @useResult
$Res call({
String realmId, SnRealm? realm, String accountId, SnAccount? account, int role, DateTime? joinedAt, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
String realmId, SnRealm? realm, String accountId, SnAccount? account, int role, DateTime? joinedAt, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, SnAccountStatus? status
});
@override $SnRealmCopyWith<$Res>? get realm;@override $SnAccountCopyWith<$Res>? get account;
@override $SnRealmCopyWith<$Res>? get realm;@override $SnAccountCopyWith<$Res>? get account;@override $SnAccountStatusCopyWith<$Res>? get status;
}
/// @nodoc
@@ -642,7 +656,7 @@ class __$SnRealmMemberCopyWithImpl<$Res>
/// Create a copy of SnRealmMember
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? realmId = null,Object? realm = freezed,Object? accountId = null,Object? account = freezed,Object? role = null,Object? joinedAt = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? realmId = null,Object? realm = freezed,Object? accountId = null,Object? account = freezed,Object? role = null,Object? joinedAt = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? status = freezed,}) {
return _then(_SnRealmMember(
realmId: null == realmId ? _self.realmId : realmId // ignore: cast_nullable_to_non_nullable
as String,realm: freezed == realm ? _self.realm : realm // ignore: cast_nullable_to_non_nullable
@@ -653,7 +667,8 @@ as int,joinedAt: freezed == joinedAt ? _self.joinedAt : joinedAt // ignore: cast
as DateTime?,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?,
as DateTime?,status: freezed == status ? _self.status : status // ignore: cast_nullable_to_non_nullable
as SnAccountStatus?,
));
}
@@ -681,6 +696,18 @@ $SnAccountCopyWith<$Res>? get account {
return $SnAccountCopyWith<$Res>(_self.account!, (value) {
return _then(_self.copyWith(account: value));
});
}/// Create a copy of SnRealmMember
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnAccountStatusCopyWith<$Res>? get status {
if (_self.status == null) {
return null;
}
return $SnAccountStatusCopyWith<$Res>(_self.status!, (value) {
return _then(_self.copyWith(status: value));
});
}
}

View File

@@ -75,6 +75,12 @@ _SnRealmMember _$SnRealmMemberFromJson(Map<String, dynamic> json) =>
json['deleted_at'] == null
? null
: DateTime.parse(json['deleted_at'] as String),
status:
json['status'] == null
? null
: SnAccountStatus.fromJson(
json['status'] as Map<String, dynamic>,
),
);
Map<String, dynamic> _$SnRealmMemberToJson(_SnRealmMember instance) =>
@@ -88,4 +94,5 @@ Map<String, dynamic> _$SnRealmMemberToJson(_SnRealmMember instance) =>
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
'status': instance.status?.toJson(),
};

View File

@@ -1,6 +1,6 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:island/models/user.dart';
import 'package:island/models/account.dart';
part 'relationship.freezed.dart';
part 'relationship.g.dart';

View File

@@ -35,6 +35,7 @@ sealed class SnStickerPack with _$SnStickerPack {
required DateTime createdAt,
required DateTime updatedAt,
required DateTime? deletedAt,
@Default([]) List<SnSticker> stickers,
}) = _SnStickerPack;
factory SnStickerPack.fromJson(Map<String, dynamic> json) =>

View File

@@ -338,7 +338,7 @@ $SnStickerPackCopyWith<$Res>? get pack {
/// @nodoc
mixin _$SnStickerPack {
String get id; String get name; String get description; String get prefix; String get publisherId; SnPublisher? get publisher; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
String get id; String get name; String get description; String get prefix; String get publisherId; SnPublisher? get publisher; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; List<SnSticker> get stickers;
/// Create a copy of SnStickerPack
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -351,16 +351,16 @@ $SnStickerPackCopyWith<SnStickerPack> get copyWith => _$SnStickerPackCopyWithImp
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnStickerPack&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&(identical(other.prefix, prefix) || other.prefix == prefix)&&(identical(other.publisherId, publisherId) || other.publisherId == publisherId)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnStickerPack&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&(identical(other.prefix, prefix) || other.prefix == prefix)&&(identical(other.publisherId, publisherId) || other.publisherId == publisherId)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&const DeepCollectionEquality().equals(other.stickers, stickers));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,name,description,prefix,publisherId,publisher,createdAt,updatedAt,deletedAt);
int get hashCode => Object.hash(runtimeType,id,name,description,prefix,publisherId,publisher,createdAt,updatedAt,deletedAt,const DeepCollectionEquality().hash(stickers));
@override
String toString() {
return 'SnStickerPack(id: $id, name: $name, description: $description, prefix: $prefix, publisherId: $publisherId, publisher: $publisher, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
return 'SnStickerPack(id: $id, name: $name, description: $description, prefix: $prefix, publisherId: $publisherId, publisher: $publisher, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, stickers: $stickers)';
}
@@ -371,7 +371,7 @@ abstract mixin class $SnStickerPackCopyWith<$Res> {
factory $SnStickerPackCopyWith(SnStickerPack value, $Res Function(SnStickerPack) _then) = _$SnStickerPackCopyWithImpl;
@useResult
$Res call({
String id, String name, String description, String prefix, String publisherId, SnPublisher? publisher, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
String id, String name, String description, String prefix, String publisherId, SnPublisher? publisher, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, List<SnSticker> stickers
});
@@ -388,7 +388,7 @@ class _$SnStickerPackCopyWithImpl<$Res>
/// Create a copy of SnStickerPack
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? description = null,Object? prefix = null,Object? publisherId = null,Object? publisher = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? description = null,Object? prefix = null,Object? publisherId = null,Object? publisher = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? stickers = null,}) {
return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
@@ -399,7 +399,8 @@ as String,publisher: freezed == publisher ? _self.publisher : publisher // ignor
as SnPublisher?,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?,
as DateTime?,stickers: null == stickers ? _self.stickers : stickers // ignore: cast_nullable_to_non_nullable
as List<SnSticker>,
));
}
/// Create a copy of SnStickerPack
@@ -493,10 +494,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String name, String description, String prefix, String publisherId, SnPublisher? publisher, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String name, String description, String prefix, String publisherId, SnPublisher? publisher, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, List<SnSticker> stickers)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnStickerPack() when $default != null:
return $default(_that.id,_that.name,_that.description,_that.prefix,_that.publisherId,_that.publisher,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return $default(_that.id,_that.name,_that.description,_that.prefix,_that.publisherId,_that.publisher,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.stickers);case _:
return orElse();
}
@@ -514,10 +515,10 @@ return $default(_that.id,_that.name,_that.description,_that.prefix,_that.publish
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String name, String description, String prefix, String publisherId, SnPublisher? publisher, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String name, String description, String prefix, String publisherId, SnPublisher? publisher, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, List<SnSticker> stickers) $default,) {final _that = this;
switch (_that) {
case _SnStickerPack():
return $default(_that.id,_that.name,_that.description,_that.prefix,_that.publisherId,_that.publisher,_that.createdAt,_that.updatedAt,_that.deletedAt);}
return $default(_that.id,_that.name,_that.description,_that.prefix,_that.publisherId,_that.publisher,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.stickers);}
}
/// A variant of `when` that fallback to returning `null`
///
@@ -531,10 +532,10 @@ return $default(_that.id,_that.name,_that.description,_that.prefix,_that.publish
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String name, String description, String prefix, String publisherId, SnPublisher? publisher, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String name, String description, String prefix, String publisherId, SnPublisher? publisher, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, List<SnSticker> stickers)? $default,) {final _that = this;
switch (_that) {
case _SnStickerPack() when $default != null:
return $default(_that.id,_that.name,_that.description,_that.prefix,_that.publisherId,_that.publisher,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return $default(_that.id,_that.name,_that.description,_that.prefix,_that.publisherId,_that.publisher,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.stickers);case _:
return null;
}
@@ -546,7 +547,7 @@ return $default(_that.id,_that.name,_that.description,_that.prefix,_that.publish
@JsonSerializable()
class _SnStickerPack implements SnStickerPack {
const _SnStickerPack({required this.id, required this.name, required this.description, required this.prefix, required this.publisherId, required this.publisher, required this.createdAt, required this.updatedAt, required this.deletedAt});
const _SnStickerPack({required this.id, required this.name, required this.description, required this.prefix, required this.publisherId, required this.publisher, required this.createdAt, required this.updatedAt, required this.deletedAt, final List<SnSticker> stickers = const []}): _stickers = stickers;
factory _SnStickerPack.fromJson(Map<String, dynamic> json) => _$SnStickerPackFromJson(json);
@override final String id;
@@ -558,6 +559,13 @@ class _SnStickerPack implements SnStickerPack {
@override final DateTime createdAt;
@override final DateTime updatedAt;
@override final DateTime? deletedAt;
final List<SnSticker> _stickers;
@override@JsonKey() List<SnSticker> get stickers {
if (_stickers is EqualUnmodifiableListView) return _stickers;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_stickers);
}
/// Create a copy of SnStickerPack
/// with the given fields replaced by the non-null parameter values.
@@ -572,16 +580,16 @@ Map<String, dynamic> toJson() {
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnStickerPack&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&(identical(other.prefix, prefix) || other.prefix == prefix)&&(identical(other.publisherId, publisherId) || other.publisherId == publisherId)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnStickerPack&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&(identical(other.prefix, prefix) || other.prefix == prefix)&&(identical(other.publisherId, publisherId) || other.publisherId == publisherId)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&const DeepCollectionEquality().equals(other._stickers, _stickers));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,name,description,prefix,publisherId,publisher,createdAt,updatedAt,deletedAt);
int get hashCode => Object.hash(runtimeType,id,name,description,prefix,publisherId,publisher,createdAt,updatedAt,deletedAt,const DeepCollectionEquality().hash(_stickers));
@override
String toString() {
return 'SnStickerPack(id: $id, name: $name, description: $description, prefix: $prefix, publisherId: $publisherId, publisher: $publisher, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
return 'SnStickerPack(id: $id, name: $name, description: $description, prefix: $prefix, publisherId: $publisherId, publisher: $publisher, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, stickers: $stickers)';
}
@@ -592,7 +600,7 @@ abstract mixin class _$SnStickerPackCopyWith<$Res> implements $SnStickerPackCopy
factory _$SnStickerPackCopyWith(_SnStickerPack value, $Res Function(_SnStickerPack) _then) = __$SnStickerPackCopyWithImpl;
@override @useResult
$Res call({
String id, String name, String description, String prefix, String publisherId, SnPublisher? publisher, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
String id, String name, String description, String prefix, String publisherId, SnPublisher? publisher, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, List<SnSticker> stickers
});
@@ -609,7 +617,7 @@ class __$SnStickerPackCopyWithImpl<$Res>
/// Create a copy of SnStickerPack
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? description = null,Object? prefix = null,Object? publisherId = null,Object? publisher = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? description = null,Object? prefix = null,Object? publisherId = null,Object? publisher = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? stickers = null,}) {
return _then(_SnStickerPack(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
@@ -620,7 +628,8 @@ as String,publisher: freezed == publisher ? _self.publisher : publisher // ignor
as SnPublisher?,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?,
as DateTime?,stickers: null == stickers ? _self._stickers : stickers // ignore: cast_nullable_to_non_nullable
as List<SnSticker>,
));
}

View File

@@ -54,6 +54,11 @@ _SnStickerPack _$SnStickerPackFromJson(Map<String, dynamic> json) =>
json['deleted_at'] == null
? null
: DateTime.parse(json['deleted_at'] as String),
stickers:
(json['stickers'] as List<dynamic>?)
?.map((e) => SnSticker.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
);
Map<String, dynamic> _$SnStickerPackToJson(_SnStickerPack instance) =>
@@ -67,4 +72,5 @@ Map<String, dynamic> _$SnStickerPackToJson(_SnStickerPack instance) =>
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
'stickers': instance.stickers.map((e) => e.toJson()).toList(),
};

View File

@@ -1,5 +1,5 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:island/models/user.dart';
import 'package:island/models/account.dart';
part 'wallet.freezed.dart';
part 'wallet.g.dart';

View File

@@ -4,28 +4,27 @@ import 'package:island/models/webfeed.dart';
import 'package:island/pods/network.dart';
/// Provider that fetches a single article by its ID
final articleDetailProvider = FutureProvider.autoDispose.family<SnWebArticle, String>(
(ref, articleId) async {
final dio = ref.watch(apiClientProvider);
final articleDetailProvider = FutureProvider.autoDispose
.family<SnWebArticle, String>((ref, articleId) async {
final dio = ref.watch(apiClientProvider);
try {
final response = await dio.get<Map<String, dynamic>>(
'/feeds/articles/$articleId',
);
try {
final response = await dio.get<Map<String, dynamic>>(
'/sphere/feeds/articles/$articleId',
);
if (response.statusCode == 200 && response.data != null) {
return SnWebArticle.fromJson(response.data!);
} else {
throw Exception('Failed to load article');
if (response.statusCode == 200 && response.data != null) {
return SnWebArticle.fromJson(response.data!);
} else {
throw Exception('Failed to load article');
}
} on DioException catch (e) {
if (e.response?.statusCode == 404) {
throw Exception('Article not found');
} else {
throw Exception('Failed to load article: ${e.message}');
}
} catch (e) {
throw Exception('Failed to load article: $e');
}
} on DioException catch (e) {
if (e.response?.statusCode == 404) {
throw Exception('Article not found');
} else {
throw Exception('Failed to load article: ${e.message}');
}
} catch (e) {
throw Exception('Failed to load article: $e');
}
},
);
});

View File

@@ -1,13 +1,14 @@
import 'package:island/pods/userinfo.dart';
import 'package:island/screens/chat/chat.dart';
import 'dart:async';
import 'dart:developer';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:island/widgets/chat/call_button.dart';
import 'package:livekit_client/livekit_client.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'dart:async';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:island/pods/network.dart';
import 'package:island/models/chat.dart';
import 'package:island/pods/websocket.dart';
part 'call.g.dart';
part 'call.freezed.dart';
@@ -27,6 +28,7 @@ sealed class CallState with _$CallState {
required bool isMicrophoneEnabled,
required bool isCameraEnabled,
required bool isScreenSharing,
required bool isSpeakerphone,
@Default(Duration(seconds: 0)) Duration duration,
String? error,
}) = _CallState;
@@ -42,7 +44,8 @@ sealed class CallParticipantLive with _$CallParticipantLive {
}) = _CallParticipantLive;
bool get isSpeaking => remoteParticipant.isSpeaking;
bool get isMuted => remoteParticipant.isMuted;
bool get isMuted =>
remoteParticipant.isMuted || !remoteParticipant.isMicrophoneEnabled();
bool get isScreenSharing => remoteParticipant.isScreenShareEnabled();
bool get isScreenSharingWithAudio =>
remoteParticipant.isScreenShareAudioEnabled();
@@ -57,13 +60,14 @@ class CallNotifier extends _$CallNotifier {
LocalParticipant? _localParticipant;
List<CallParticipantLive> _participants = [];
final Map<String, CallParticipant> _participantInfoByIdentity = {};
StreamSubscription? _wsSubscription;
EventsListener? _roomListener;
List<CallParticipantLive> get participants =>
List.unmodifiable(_participants);
LocalParticipant? get localParticipant => _localParticipant;
Map<String, double> participantsVolumes = {};
Timer? _durationTimer;
Room? get room => _room;
@@ -71,36 +75,15 @@ class CallNotifier extends _$CallNotifier {
@override
CallState build() {
// Subscribe to websocket updates
_subscribeToParticipantsUpdate();
return const CallState(
isConnected: false,
isMicrophoneEnabled: true,
isCameraEnabled: false,
isScreenSharing: false,
isSpeakerphone: true,
);
}
void _subscribeToParticipantsUpdate() {
// Only subscribe once
if (_wsSubscription != null) return;
final ws = ref.read(websocketProvider);
_wsSubscription = ws.dataStream.listen((packet) {
if (packet.type == 'call.participants.update' && packet.data != null) {
final participantsData = packet.data!["participants"];
if (participantsData is List) {
final parsed =
participantsData
.map(
(e) =>
CallParticipant.fromJson(Map<String, dynamic>.from(e)),
)
.toList();
_updateLiveParticipants(parsed);
}
}
});
}
void _initRoomListeners() {
if (_room == null) return;
_roomListener?.dispose();
@@ -143,8 +126,6 @@ class CallNotifier extends _$CallNotifier {
identity: remote.identity,
name: remote.identity,
joinedAt: DateTime.now(),
accountId: null,
profile: null,
);
return CallParticipantLive(
participant: match,
@@ -169,16 +150,12 @@ class CallNotifier extends _$CallNotifier {
if (idx != -1) return participants[idx];
}
final userInfo = ref.read(userInfoProvider);
final roomIdentity = ref.read(chatroomIdentityProvider(_roomId));
// Otherwise, use info from the identity map or fallback to minimal
return _participantInfoByIdentity[_localParticipant!.identity] ??
CallParticipant(
identity: _localParticipant!.identity,
name: _localParticipant!.identity,
joinedAt: DateTime.now(),
accountId: userInfo.value?.id,
profile: roomIdentity.value,
);
}
@@ -205,6 +182,7 @@ class CallNotifier extends _$CallNotifier {
remoteParticipant: _localParticipant!,
),
);
state = state.copyWith();
}
// Add remote participants
_participants.addAll(
@@ -233,7 +211,13 @@ class CallNotifier extends _$CallNotifier {
Future<void> joinRoom(String roomId) async {
if (_roomId == roomId && _room != null) {
log('[Call] Call skipped. Already has data');
return;
} else if (_room != null) {
if (!_room!.isDisposed &&
_room!.connectionState != ConnectionState.disconnected) {
throw Exception('Call already connected');
}
}
_roomId = roomId;
if (_room != null) {
@@ -264,7 +248,8 @@ class CallNotifier extends _$CallNotifier {
duration: Duration(
milliseconds:
(DateTime.now().millisecondsSinceEpoch -
(ongoingCall?.createdAt.millisecondsSinceEpoch ?? 0)),
(ongoingCall?.createdAt.millisecondsSinceEpoch ??
DateTime.now().millisecondsSinceEpoch)),
),
);
});
@@ -286,6 +271,10 @@ class CallNotifier extends _$CallNotifier {
_initRoomListeners();
_updateLiveParticipants(participants);
if (!kIsWeb && (Platform.isIOS || Platform.isAndroid)) {
Hardware.instance.setSpeakerphoneOn(true);
}
// Listen for connection updates
_room!.addListener(() {
state = state.copyWith(
@@ -318,6 +307,7 @@ class CallNotifier extends _$CallNotifier {
stopOnMute: autostop,
);
}
state = state.copyWith();
}
}
@@ -326,6 +316,7 @@ class CallNotifier extends _$CallNotifier {
final target = !_localParticipant!.isCameraEnabled();
state = state.copyWith(isCameraEnabled: target);
await _localParticipant!.setCameraEnabled(target);
state = state.copyWith();
}
}
@@ -334,9 +325,16 @@ class CallNotifier extends _$CallNotifier {
final target = !_localParticipant!.isScreenShareEnabled();
state = state.copyWith(isScreenSharing: target);
await _localParticipant!.setScreenShareEnabled(target);
state = state.copyWith();
}
}
Future<void> toggleSpeakerphone() async {
state = state.copyWith(isSpeakerphone: !state.isSpeakerphone);
await Hardware.instance.setSpeakerphoneOn(state.isSpeakerphone);
state = state.copyWith();
}
Future<void> disconnect() async {
if (_room != null) {
await _room!.disconnect();
@@ -349,11 +347,39 @@ class CallNotifier extends _$CallNotifier {
}
}
void setParticipantVolume(CallParticipantLive live, double volume) {
if (participantsVolumes[live.remoteParticipant.sid] == null) {
participantsVolumes[live.remoteParticipant.sid] = 1;
}
Helper.setVolume(
volume,
live
.remoteParticipant
.audioTrackPublications
.first
.track!
.mediaStreamTrack,
);
participantsVolumes[live.remoteParticipant.sid] = volume;
}
double getParticipantVolume(CallParticipantLive live) {
return participantsVolumes[live.remoteParticipant.sid] ?? 1;
}
void dispose() {
_wsSubscription?.cancel();
state = state.copyWith(
error: null,
isConnected: false,
isMicrophoneEnabled: false,
isCameraEnabled: false,
isScreenSharing: false,
);
_roomListener?.dispose();
_room?.removeListener(_onRoomChange);
_room?.dispose();
_durationTimer?.cancel();
_roomId = null;
participantsVolumes = {};
}
}

View File

@@ -12,9 +12,9 @@ part of 'call.dart';
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$CallState {
mixin _$CallState implements DiagnosticableTreeMixin {
bool get isConnected; bool get isMicrophoneEnabled; bool get isCameraEnabled; bool get isScreenSharing; Duration get duration; String? get error;
bool get isConnected; bool get isMicrophoneEnabled; bool get isCameraEnabled; bool get isScreenSharing; bool get isSpeakerphone; Duration get duration; String? get error;
/// Create a copy of CallState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -22,19 +22,25 @@ mixin _$CallState {
$CallStateCopyWith<CallState> get copyWith => _$CallStateCopyWithImpl<CallState>(this as CallState, _$identity);
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
properties
..add(DiagnosticsProperty('type', 'CallState'))
..add(DiagnosticsProperty('isConnected', isConnected))..add(DiagnosticsProperty('isMicrophoneEnabled', isMicrophoneEnabled))..add(DiagnosticsProperty('isCameraEnabled', isCameraEnabled))..add(DiagnosticsProperty('isScreenSharing', isScreenSharing))..add(DiagnosticsProperty('isSpeakerphone', isSpeakerphone))..add(DiagnosticsProperty('duration', duration))..add(DiagnosticsProperty('error', error));
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is CallState&&(identical(other.isConnected, isConnected) || other.isConnected == isConnected)&&(identical(other.isMicrophoneEnabled, isMicrophoneEnabled) || other.isMicrophoneEnabled == isMicrophoneEnabled)&&(identical(other.isCameraEnabled, isCameraEnabled) || other.isCameraEnabled == isCameraEnabled)&&(identical(other.isScreenSharing, isScreenSharing) || other.isScreenSharing == isScreenSharing)&&(identical(other.duration, duration) || other.duration == duration)&&(identical(other.error, error) || other.error == error));
return identical(this, other) || (other.runtimeType == runtimeType&&other is CallState&&(identical(other.isConnected, isConnected) || other.isConnected == isConnected)&&(identical(other.isMicrophoneEnabled, isMicrophoneEnabled) || other.isMicrophoneEnabled == isMicrophoneEnabled)&&(identical(other.isCameraEnabled, isCameraEnabled) || other.isCameraEnabled == isCameraEnabled)&&(identical(other.isScreenSharing, isScreenSharing) || other.isScreenSharing == isScreenSharing)&&(identical(other.isSpeakerphone, isSpeakerphone) || other.isSpeakerphone == isSpeakerphone)&&(identical(other.duration, duration) || other.duration == duration)&&(identical(other.error, error) || other.error == error));
}
@override
int get hashCode => Object.hash(runtimeType,isConnected,isMicrophoneEnabled,isCameraEnabled,isScreenSharing,duration,error);
int get hashCode => Object.hash(runtimeType,isConnected,isMicrophoneEnabled,isCameraEnabled,isScreenSharing,isSpeakerphone,duration,error);
@override
String toString() {
return 'CallState(isConnected: $isConnected, isMicrophoneEnabled: $isMicrophoneEnabled, isCameraEnabled: $isCameraEnabled, isScreenSharing: $isScreenSharing, duration: $duration, error: $error)';
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
return 'CallState(isConnected: $isConnected, isMicrophoneEnabled: $isMicrophoneEnabled, isCameraEnabled: $isCameraEnabled, isScreenSharing: $isScreenSharing, isSpeakerphone: $isSpeakerphone, duration: $duration, error: $error)';
}
@@ -45,7 +51,7 @@ abstract mixin class $CallStateCopyWith<$Res> {
factory $CallStateCopyWith(CallState value, $Res Function(CallState) _then) = _$CallStateCopyWithImpl;
@useResult
$Res call({
bool isConnected, bool isMicrophoneEnabled, bool isCameraEnabled, bool isScreenSharing, Duration duration, String? error
bool isConnected, bool isMicrophoneEnabled, bool isCameraEnabled, bool isScreenSharing, bool isSpeakerphone, Duration duration, String? error
});
@@ -62,12 +68,13 @@ class _$CallStateCopyWithImpl<$Res>
/// Create a copy of CallState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? isConnected = null,Object? isMicrophoneEnabled = null,Object? isCameraEnabled = null,Object? isScreenSharing = null,Object? duration = null,Object? error = freezed,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? isConnected = null,Object? isMicrophoneEnabled = null,Object? isCameraEnabled = null,Object? isScreenSharing = null,Object? isSpeakerphone = null,Object? duration = null,Object? error = freezed,}) {
return _then(_self.copyWith(
isConnected: null == isConnected ? _self.isConnected : isConnected // ignore: cast_nullable_to_non_nullable
as bool,isMicrophoneEnabled: null == isMicrophoneEnabled ? _self.isMicrophoneEnabled : isMicrophoneEnabled // ignore: cast_nullable_to_non_nullable
as bool,isCameraEnabled: null == isCameraEnabled ? _self.isCameraEnabled : isCameraEnabled // ignore: cast_nullable_to_non_nullable
as bool,isScreenSharing: null == isScreenSharing ? _self.isScreenSharing : isScreenSharing // ignore: cast_nullable_to_non_nullable
as bool,isSpeakerphone: null == isSpeakerphone ? _self.isSpeakerphone : isSpeakerphone // ignore: cast_nullable_to_non_nullable
as bool,duration: null == duration ? _self.duration : duration // ignore: cast_nullable_to_non_nullable
as Duration,error: freezed == error ? _self.error : error // ignore: cast_nullable_to_non_nullable
as String?,
@@ -152,10 +159,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool isConnected, bool isMicrophoneEnabled, bool isCameraEnabled, bool isScreenSharing, Duration duration, String? error)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool isConnected, bool isMicrophoneEnabled, bool isCameraEnabled, bool isScreenSharing, bool isSpeakerphone, Duration duration, String? error)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _CallState() when $default != null:
return $default(_that.isConnected,_that.isMicrophoneEnabled,_that.isCameraEnabled,_that.isScreenSharing,_that.duration,_that.error);case _:
return $default(_that.isConnected,_that.isMicrophoneEnabled,_that.isCameraEnabled,_that.isScreenSharing,_that.isSpeakerphone,_that.duration,_that.error);case _:
return orElse();
}
@@ -173,10 +180,10 @@ return $default(_that.isConnected,_that.isMicrophoneEnabled,_that.isCameraEnable
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool isConnected, bool isMicrophoneEnabled, bool isCameraEnabled, bool isScreenSharing, Duration duration, String? error) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool isConnected, bool isMicrophoneEnabled, bool isCameraEnabled, bool isScreenSharing, bool isSpeakerphone, Duration duration, String? error) $default,) {final _that = this;
switch (_that) {
case _CallState():
return $default(_that.isConnected,_that.isMicrophoneEnabled,_that.isCameraEnabled,_that.isScreenSharing,_that.duration,_that.error);}
return $default(_that.isConnected,_that.isMicrophoneEnabled,_that.isCameraEnabled,_that.isScreenSharing,_that.isSpeakerphone,_that.duration,_that.error);}
}
/// A variant of `when` that fallback to returning `null`
///
@@ -190,10 +197,10 @@ return $default(_that.isConnected,_that.isMicrophoneEnabled,_that.isCameraEnable
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool isConnected, bool isMicrophoneEnabled, bool isCameraEnabled, bool isScreenSharing, Duration duration, String? error)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool isConnected, bool isMicrophoneEnabled, bool isCameraEnabled, bool isScreenSharing, bool isSpeakerphone, Duration duration, String? error)? $default,) {final _that = this;
switch (_that) {
case _CallState() when $default != null:
return $default(_that.isConnected,_that.isMicrophoneEnabled,_that.isCameraEnabled,_that.isScreenSharing,_that.duration,_that.error);case _:
return $default(_that.isConnected,_that.isMicrophoneEnabled,_that.isCameraEnabled,_that.isScreenSharing,_that.isSpeakerphone,_that.duration,_that.error);case _:
return null;
}
@@ -204,14 +211,15 @@ return $default(_that.isConnected,_that.isMicrophoneEnabled,_that.isCameraEnable
/// @nodoc
class _CallState implements CallState {
const _CallState({required this.isConnected, required this.isMicrophoneEnabled, required this.isCameraEnabled, required this.isScreenSharing, this.duration = const Duration(seconds: 0), this.error});
class _CallState with DiagnosticableTreeMixin implements CallState {
const _CallState({required this.isConnected, required this.isMicrophoneEnabled, required this.isCameraEnabled, required this.isScreenSharing, required this.isSpeakerphone, this.duration = const Duration(seconds: 0), this.error});
@override final bool isConnected;
@override final bool isMicrophoneEnabled;
@override final bool isCameraEnabled;
@override final bool isScreenSharing;
@override final bool isSpeakerphone;
@override@JsonKey() final Duration duration;
@override final String? error;
@@ -222,19 +230,25 @@ class _CallState implements CallState {
_$CallStateCopyWith<_CallState> get copyWith => __$CallStateCopyWithImpl<_CallState>(this, _$identity);
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
properties
..add(DiagnosticsProperty('type', 'CallState'))
..add(DiagnosticsProperty('isConnected', isConnected))..add(DiagnosticsProperty('isMicrophoneEnabled', isMicrophoneEnabled))..add(DiagnosticsProperty('isCameraEnabled', isCameraEnabled))..add(DiagnosticsProperty('isScreenSharing', isScreenSharing))..add(DiagnosticsProperty('isSpeakerphone', isSpeakerphone))..add(DiagnosticsProperty('duration', duration))..add(DiagnosticsProperty('error', error));
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _CallState&&(identical(other.isConnected, isConnected) || other.isConnected == isConnected)&&(identical(other.isMicrophoneEnabled, isMicrophoneEnabled) || other.isMicrophoneEnabled == isMicrophoneEnabled)&&(identical(other.isCameraEnabled, isCameraEnabled) || other.isCameraEnabled == isCameraEnabled)&&(identical(other.isScreenSharing, isScreenSharing) || other.isScreenSharing == isScreenSharing)&&(identical(other.duration, duration) || other.duration == duration)&&(identical(other.error, error) || other.error == error));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _CallState&&(identical(other.isConnected, isConnected) || other.isConnected == isConnected)&&(identical(other.isMicrophoneEnabled, isMicrophoneEnabled) || other.isMicrophoneEnabled == isMicrophoneEnabled)&&(identical(other.isCameraEnabled, isCameraEnabled) || other.isCameraEnabled == isCameraEnabled)&&(identical(other.isScreenSharing, isScreenSharing) || other.isScreenSharing == isScreenSharing)&&(identical(other.isSpeakerphone, isSpeakerphone) || other.isSpeakerphone == isSpeakerphone)&&(identical(other.duration, duration) || other.duration == duration)&&(identical(other.error, error) || other.error == error));
}
@override
int get hashCode => Object.hash(runtimeType,isConnected,isMicrophoneEnabled,isCameraEnabled,isScreenSharing,duration,error);
int get hashCode => Object.hash(runtimeType,isConnected,isMicrophoneEnabled,isCameraEnabled,isScreenSharing,isSpeakerphone,duration,error);
@override
String toString() {
return 'CallState(isConnected: $isConnected, isMicrophoneEnabled: $isMicrophoneEnabled, isCameraEnabled: $isCameraEnabled, isScreenSharing: $isScreenSharing, duration: $duration, error: $error)';
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
return 'CallState(isConnected: $isConnected, isMicrophoneEnabled: $isMicrophoneEnabled, isCameraEnabled: $isCameraEnabled, isScreenSharing: $isScreenSharing, isSpeakerphone: $isSpeakerphone, duration: $duration, error: $error)';
}
@@ -245,7 +259,7 @@ abstract mixin class _$CallStateCopyWith<$Res> implements $CallStateCopyWith<$Re
factory _$CallStateCopyWith(_CallState value, $Res Function(_CallState) _then) = __$CallStateCopyWithImpl;
@override @useResult
$Res call({
bool isConnected, bool isMicrophoneEnabled, bool isCameraEnabled, bool isScreenSharing, Duration duration, String? error
bool isConnected, bool isMicrophoneEnabled, bool isCameraEnabled, bool isScreenSharing, bool isSpeakerphone, Duration duration, String? error
});
@@ -262,12 +276,13 @@ class __$CallStateCopyWithImpl<$Res>
/// Create a copy of CallState
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? isConnected = null,Object? isMicrophoneEnabled = null,Object? isCameraEnabled = null,Object? isScreenSharing = null,Object? duration = null,Object? error = freezed,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? isConnected = null,Object? isMicrophoneEnabled = null,Object? isCameraEnabled = null,Object? isScreenSharing = null,Object? isSpeakerphone = null,Object? duration = null,Object? error = freezed,}) {
return _then(_CallState(
isConnected: null == isConnected ? _self.isConnected : isConnected // ignore: cast_nullable_to_non_nullable
as bool,isMicrophoneEnabled: null == isMicrophoneEnabled ? _self.isMicrophoneEnabled : isMicrophoneEnabled // ignore: cast_nullable_to_non_nullable
as bool,isCameraEnabled: null == isCameraEnabled ? _self.isCameraEnabled : isCameraEnabled // ignore: cast_nullable_to_non_nullable
as bool,isScreenSharing: null == isScreenSharing ? _self.isScreenSharing : isScreenSharing // ignore: cast_nullable_to_non_nullable
as bool,isSpeakerphone: null == isSpeakerphone ? _self.isSpeakerphone : isSpeakerphone // ignore: cast_nullable_to_non_nullable
as bool,duration: null == duration ? _self.duration : duration // ignore: cast_nullable_to_non_nullable
as Duration,error: freezed == error ? _self.error : error // ignore: cast_nullable_to_non_nullable
as String?,
@@ -278,7 +293,7 @@ as String?,
}
/// @nodoc
mixin _$CallParticipantLive {
mixin _$CallParticipantLive implements DiagnosticableTreeMixin {
CallParticipant get participant; Participant get remoteParticipant;
/// Create a copy of CallParticipantLive
@@ -288,6 +303,12 @@ mixin _$CallParticipantLive {
$CallParticipantLiveCopyWith<CallParticipantLive> get copyWith => _$CallParticipantLiveCopyWithImpl<CallParticipantLive>(this as CallParticipantLive, _$identity);
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
properties
..add(DiagnosticsProperty('type', 'CallParticipantLive'))
..add(DiagnosticsProperty('participant', participant))..add(DiagnosticsProperty('remoteParticipant', remoteParticipant));
}
@override
bool operator ==(Object other) {
@@ -299,7 +320,7 @@ bool operator ==(Object other) {
int get hashCode => Object.hash(runtimeType,participant,remoteParticipant);
@override
String toString() {
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
return 'CallParticipantLive(participant: $participant, remoteParticipant: $remoteParticipant)';
}
@@ -475,7 +496,7 @@ return $default(_that.participant,_that.remoteParticipant);case _:
/// @nodoc
class _CallParticipantLive extends CallParticipantLive {
class _CallParticipantLive extends CallParticipantLive with DiagnosticableTreeMixin {
const _CallParticipantLive({required this.participant, required this.remoteParticipant}): super._();
@@ -489,6 +510,12 @@ class _CallParticipantLive extends CallParticipantLive {
_$CallParticipantLiveCopyWith<_CallParticipantLive> get copyWith => __$CallParticipantLiveCopyWithImpl<_CallParticipantLive>(this, _$identity);
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
properties
..add(DiagnosticsProperty('type', 'CallParticipantLive'))
..add(DiagnosticsProperty('participant', participant))..add(DiagnosticsProperty('remoteParticipant', remoteParticipant));
}
@override
bool operator ==(Object other) {
@@ -500,7 +527,7 @@ bool operator ==(Object other) {
int get hashCode => Object.hash(runtimeType,participant,remoteParticipant);
@override
String toString() {
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
return 'CallParticipantLive(participant: $participant, remoteParticipant: $remoteParticipant)';
}

View File

@@ -6,7 +6,7 @@ part of 'call.dart';
// RiverpodGenerator
// **************************************************************************
String _$callNotifierHash() => r'107174cd6cfab6bfafe44f8c4a72a67bcb93217b';
String _$callNotifierHash() => r'18fb807f067eecd3ea42631c1426c3e5f1fb4280';
/// See also [CallNotifier].
@ProviderFor(CallNotifier)

View File

@@ -23,6 +23,8 @@ const kAppSoundEffects = 'app_sound_effects';
const kAppAprilFoolFeatures = 'app_april_fool_features';
const kAppWindowSize = 'app_window_size';
const kAppEnterToSend = 'app_enter_to_send';
const kFeaturedPostsCollapsedId =
'featured_posts_collapsed_id'; // Key for storing the ID of the collapsed featured post
const Map<String, FilterQuality> kImageQualityLevel = {
'settingsImageQualityLowest': FilterQuality.none,

38
lib/pods/translate.dart Normal file
View File

@@ -0,0 +1,38 @@
import 'dart:convert';
import 'dart:developer';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/pods/network.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:flutter_langdetect/flutter_langdetect.dart' as langdetect;
part 'translate.freezed.dart';
part 'translate.g.dart';
@freezed
sealed class TranslateQuery with _$TranslateQuery {
const factory TranslateQuery({required String text, required String lang}) =
_TranslateQuery;
}
@riverpod
Future<String> translateString(Ref ref, TranslateQuery query) async {
final client = ref.watch(apiClientProvider);
final response = await client.post(
'/sphere/translate',
queryParameters: {'to': query.lang},
data: jsonEncode(query.text),
);
return response.data as String;
}
@riverpod
String? detectStringLanguage(Ref ref, String text) {
try {
return langdetect.detectLangs(text).firstOrNull?.lang;
} catch (err) {
log('[Language] Unable to detect text\'s language: $text');
return null;
}
}

View File

@@ -0,0 +1,268 @@
// 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 'translate.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$TranslateQuery {
String get text; String get lang;
/// Create a copy of TranslateQuery
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$TranslateQueryCopyWith<TranslateQuery> get copyWith => _$TranslateQueryCopyWithImpl<TranslateQuery>(this as TranslateQuery, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is TranslateQuery&&(identical(other.text, text) || other.text == text)&&(identical(other.lang, lang) || other.lang == lang));
}
@override
int get hashCode => Object.hash(runtimeType,text,lang);
@override
String toString() {
return 'TranslateQuery(text: $text, lang: $lang)';
}
}
/// @nodoc
abstract mixin class $TranslateQueryCopyWith<$Res> {
factory $TranslateQueryCopyWith(TranslateQuery value, $Res Function(TranslateQuery) _then) = _$TranslateQueryCopyWithImpl;
@useResult
$Res call({
String text, String lang
});
}
/// @nodoc
class _$TranslateQueryCopyWithImpl<$Res>
implements $TranslateQueryCopyWith<$Res> {
_$TranslateQueryCopyWithImpl(this._self, this._then);
final TranslateQuery _self;
final $Res Function(TranslateQuery) _then;
/// Create a copy of TranslateQuery
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? text = null,Object? lang = null,}) {
return _then(_self.copyWith(
text: null == text ? _self.text : text // ignore: cast_nullable_to_non_nullable
as String,lang: null == lang ? _self.lang : lang // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// Adds pattern-matching-related methods to [TranslateQuery].
extension TranslateQueryPatterns on TranslateQuery {
/// 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( _TranslateQuery value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _TranslateQuery() 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( _TranslateQuery value) $default,){
final _that = this;
switch (_that) {
case _TranslateQuery():
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( _TranslateQuery value)? $default,){
final _that = this;
switch (_that) {
case _TranslateQuery() 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 text, String lang)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _TranslateQuery() when $default != null:
return $default(_that.text,_that.lang);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 text, String lang) $default,) {final _that = this;
switch (_that) {
case _TranslateQuery():
return $default(_that.text,_that.lang);}
}
/// 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 text, String lang)? $default,) {final _that = this;
switch (_that) {
case _TranslateQuery() when $default != null:
return $default(_that.text,_that.lang);case _:
return null;
}
}
}
/// @nodoc
class _TranslateQuery implements TranslateQuery {
const _TranslateQuery({required this.text, required this.lang});
@override final String text;
@override final String lang;
/// Create a copy of TranslateQuery
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$TranslateQueryCopyWith<_TranslateQuery> get copyWith => __$TranslateQueryCopyWithImpl<_TranslateQuery>(this, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _TranslateQuery&&(identical(other.text, text) || other.text == text)&&(identical(other.lang, lang) || other.lang == lang));
}
@override
int get hashCode => Object.hash(runtimeType,text,lang);
@override
String toString() {
return 'TranslateQuery(text: $text, lang: $lang)';
}
}
/// @nodoc
abstract mixin class _$TranslateQueryCopyWith<$Res> implements $TranslateQueryCopyWith<$Res> {
factory _$TranslateQueryCopyWith(_TranslateQuery value, $Res Function(_TranslateQuery) _then) = __$TranslateQueryCopyWithImpl;
@override @useResult
$Res call({
String text, String lang
});
}
/// @nodoc
class __$TranslateQueryCopyWithImpl<$Res>
implements _$TranslateQueryCopyWith<$Res> {
__$TranslateQueryCopyWithImpl(this._self, this._then);
final _TranslateQuery _self;
final $Res Function(_TranslateQuery) _then;
/// Create a copy of TranslateQuery
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? text = null,Object? lang = null,}) {
return _then(_TranslateQuery(
text: null == text ? _self.text : text // ignore: cast_nullable_to_non_nullable
as String,lang: null == lang ? _self.lang : lang // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
// dart format on

274
lib/pods/translate.g.dart Normal file
View File

@@ -0,0 +1,274 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'translate.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
String _$translateStringHash() => r'51d638cf07cbf3ffa9469298f5bd9c667bc0ccb7';
/// 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 [translateString].
@ProviderFor(translateString)
const translateStringProvider = TranslateStringFamily();
/// See also [translateString].
class TranslateStringFamily extends Family<AsyncValue<String>> {
/// See also [translateString].
const TranslateStringFamily();
/// See also [translateString].
TranslateStringProvider call(TranslateQuery query) {
return TranslateStringProvider(query);
}
@override
TranslateStringProvider getProviderOverride(
covariant TranslateStringProvider provider,
) {
return call(provider.query);
}
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'translateStringProvider';
}
/// See also [translateString].
class TranslateStringProvider extends AutoDisposeFutureProvider<String> {
/// See also [translateString].
TranslateStringProvider(TranslateQuery query)
: this._internal(
(ref) => translateString(ref as TranslateStringRef, query),
from: translateStringProvider,
name: r'translateStringProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product')
? null
: _$translateStringHash,
dependencies: TranslateStringFamily._dependencies,
allTransitiveDependencies:
TranslateStringFamily._allTransitiveDependencies,
query: query,
);
TranslateStringProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.query,
}) : super.internal();
final TranslateQuery query;
@override
Override overrideWith(
FutureOr<String> Function(TranslateStringRef provider) create,
) {
return ProviderOverride(
origin: this,
override: TranslateStringProvider._internal(
(ref) => create(ref as TranslateStringRef),
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
query: query,
),
);
}
@override
AutoDisposeFutureProviderElement<String> createElement() {
return _TranslateStringProviderElement(this);
}
@override
bool operator ==(Object other) {
return other is TranslateStringProvider && other.query == query;
}
@override
int get hashCode {
var hash = _SystemHash.combine(0, runtimeType.hashCode);
hash = _SystemHash.combine(hash, query.hashCode);
return _SystemHash.finish(hash);
}
}
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
mixin TranslateStringRef on AutoDisposeFutureProviderRef<String> {
/// The parameter `query` of this provider.
TranslateQuery get query;
}
class _TranslateStringProviderElement
extends AutoDisposeFutureProviderElement<String>
with TranslateStringRef {
_TranslateStringProviderElement(super.provider);
@override
TranslateQuery get query => (origin as TranslateStringProvider).query;
}
String _$detectStringLanguageHash() =>
r'697b68464b3d00927cc43ccc1ba8ba93f2a470ed';
/// See also [detectStringLanguage].
@ProviderFor(detectStringLanguage)
const detectStringLanguageProvider = DetectStringLanguageFamily();
/// See also [detectStringLanguage].
class DetectStringLanguageFamily extends Family<String?> {
/// See also [detectStringLanguage].
const DetectStringLanguageFamily();
/// See also [detectStringLanguage].
DetectStringLanguageProvider call(String text) {
return DetectStringLanguageProvider(text);
}
@override
DetectStringLanguageProvider getProviderOverride(
covariant DetectStringLanguageProvider provider,
) {
return call(provider.text);
}
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'detectStringLanguageProvider';
}
/// See also [detectStringLanguage].
class DetectStringLanguageProvider extends AutoDisposeProvider<String?> {
/// See also [detectStringLanguage].
DetectStringLanguageProvider(String text)
: this._internal(
(ref) => detectStringLanguage(ref as DetectStringLanguageRef, text),
from: detectStringLanguageProvider,
name: r'detectStringLanguageProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product')
? null
: _$detectStringLanguageHash,
dependencies: DetectStringLanguageFamily._dependencies,
allTransitiveDependencies:
DetectStringLanguageFamily._allTransitiveDependencies,
text: text,
);
DetectStringLanguageProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.text,
}) : super.internal();
final String text;
@override
Override overrideWith(
String? Function(DetectStringLanguageRef provider) create,
) {
return ProviderOverride(
origin: this,
override: DetectStringLanguageProvider._internal(
(ref) => create(ref as DetectStringLanguageRef),
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
text: text,
),
);
}
@override
AutoDisposeProviderElement<String?> createElement() {
return _DetectStringLanguageProviderElement(this);
}
@override
bool operator ==(Object other) {
return other is DetectStringLanguageProvider && other.text == text;
}
@override
int get hashCode {
var hash = _SystemHash.combine(0, runtimeType.hashCode);
hash = _SystemHash.combine(hash, text.hashCode);
return _SystemHash.finish(hash);
}
}
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
mixin DetectStringLanguageRef on AutoDisposeProviderRef<String?> {
/// The parameter `text` of this provider.
String get text;
}
class _DetectStringLanguageProviderElement
extends AutoDisposeProviderElement<String?>
with DetectStringLanguageRef {
_DetectStringLanguageProviderElement(super.provider);
@override
String get text => (origin as DetectStringLanguageProvider).text;
}
// 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

@@ -1,8 +1,15 @@
import 'dart:convert';
import 'dart:developer';
import 'dart:io' show Platform;
import 'package:dio/dio.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_platform_alert/flutter_platform_alert.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/user.dart';
import 'package:island/models/account.dart';
import 'package:island/pods/config.dart';
import 'package:island/pods/network.dart';
@@ -12,12 +19,59 @@ class UserInfoNotifier extends StateNotifier<AsyncValue<SnAccount?>> {
UserInfoNotifier(this._ref) : super(const AsyncValue.data(null));
Future<void> fetchUser() async {
final token = _ref.watch(tokenProvider);
if (token == null) {
log('[UserInfo] No token found, not going to fetch...');
return;
}
try {
final client = _ref.read(apiClientProvider);
final response = await client.get('/id/accounts/me');
final user = SnAccount.fromJson(response.data);
state = AsyncValue.data(user);
if (kIsWeb || !Platform.isLinux) {
FirebaseAnalytics.instance.setUserId(id: user.id);
}
} catch (error, stackTrace) {
if (!kIsWeb) {
if (error is DioException) {
FlutterPlatformAlert.showCustomAlert(
windowTitle: 'failedToLoadUserInfo'.tr(),
text: [
(error.response?.statusCode == 401
? 'failedToLoadUserInfoUnauthorized'
: 'failedToLoadUserInfoNetwork')
.tr()
.trim(),
'${error.response!.statusCode}\n${error.response?.headers}',
jsonEncode(error.response?.data),
].join('\n\n'),
iconStyle: IconStyle.error,
neutralButtonTitle: 'retry'.tr(),
negativeButtonTitle: 'okay'.tr(),
).then((value) {
if (value == CustomButton.neutralButton) {
fetchUser();
}
});
}
FlutterPlatformAlert.showCustomAlert(
windowTitle: 'failedToLoadUserInfo'.tr(),
text:
[
'failedToLoadUserInfoNetwork'.tr(),
error.toString(),
].join('\n\n').trim(),
iconStyle: IconStyle.error,
neutralButtonTitle: 'retry'.tr(),
negativeButtonTitle: 'okay'.tr(),
).then((value) {
if (value == CustomButton.neutralButton) {
fetchUser();
}
});
}
log(
"[UserInfo] Failed to fetch user info...",
name: 'UserInfoNotifier',
@@ -33,6 +87,9 @@ class UserInfoNotifier extends StateNotifier<AsyncValue<SnAccount?>> {
final prefs = _ref.read(sharedPreferencesProvider);
await prefs.remove(kTokenPairStoreKey);
_ref.invalidate(tokenProvider);
if (kIsWeb || !Platform.isLinux) {
FirebaseAnalytics.instance.setUserId(id: null);
}
}
}

View File

@@ -1,7 +1,6 @@
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'package:flutter/foundation.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
@@ -18,6 +17,8 @@ sealed class WebSocketState with _$WebSocketState {
const factory WebSocketState.connected() = _Connected;
const factory WebSocketState.connecting() = _Connecting;
const factory WebSocketState.disconnected() = _Disconnected;
const factory WebSocketState.serverDown() = _ServerDown;
const factory WebSocketState.duplicateDevice() = _DuplicateDevice;
const factory WebSocketState.error(String message) = _Error;
}
@@ -46,6 +47,10 @@ class WebSocketService {
final StreamController<WebSocketState> _statusStreamController =
StreamController<WebSocketState>.broadcast();
Timer? _reconnectTimer;
Timer? _heartbeatTimer;
DateTime? _heartbeatAt;
Duration? heartbeatDelay;
Stream<WebSocketPacket> get dataStream => _streamController.stream;
Stream<WebSocketState> get statusStream => _statusStreamController.stream;
@@ -71,15 +76,28 @@ class WebSocketService {
}
await _channel!.ready;
_statusStreamController.sink.add(WebSocketState.connected());
_scheduleHeartbeat();
_channel!.stream.listen(
(data) {
final dataStr =
data is Uint8List ? utf8.decode(data) : data.toString();
final packet = WebSocketPacket.fromJson(jsonDecode(dataStr));
if (packet.type == 'error.dupe') {
_statusStreamController.sink.add(WebSocketState.duplicateDevice());
_channel!.sink.close();
return;
}
_streamController.sink.add(packet);
log(
"[WebSocket] Received packet: ${packet.type} ${packet.errorMessage}",
);
if (packet.type == 'pong' && _heartbeatAt != null) {
var now = DateTime.now();
heartbeatDelay = now.difference(_heartbeatAt!);
log(
"[WebSocket] Server respond last heartbeat for ${heartbeatDelay!.inMilliseconds} ms",
);
}
},
onDone: () {
log('[WebSocket] Connection closed, attempting to reconnect...');
@@ -108,6 +126,19 @@ class WebSocketService {
});
}
void _scheduleHeartbeat() {
_heartbeatTimer?.cancel();
_heartbeatTimer = Timer.periodic(const Duration(seconds: 60), (_) {
_beatTheHeart();
});
}
void _beatTheHeart() {
_heartbeatAt = DateTime.now();
log('[WebSocket] We\'re beating the heart! $_heartbeatAt');
sendMessage(jsonEncode(WebSocketPacket(type: 'ping', data: null)));
}
WebSocketChannel? get ws => _channel;
void sendMessage(String message) {

View File

@@ -61,13 +61,15 @@ extension WebSocketStatePatterns on WebSocketState {
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( _Connected value)? connected,TResult Function( _Connecting value)? connecting,TResult Function( _Disconnected value)? disconnected,TResult Function( _Error value)? error,required TResult orElse(),}){
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( _Connected value)? connected,TResult Function( _Connecting value)? connecting,TResult Function( _Disconnected value)? disconnected,TResult Function( _ServerDown value)? serverDown,TResult Function( _DuplicateDevice value)? duplicateDevice,TResult Function( _Error value)? error,required TResult orElse(),}){
final _that = this;
switch (_that) {
case _Connected() when connected != null:
return connected(_that);case _Connecting() when connecting != null:
return connecting(_that);case _Disconnected() when disconnected != null:
return disconnected(_that);case _Error() when error != null:
return disconnected(_that);case _ServerDown() when serverDown != null:
return serverDown(_that);case _DuplicateDevice() when duplicateDevice != null:
return duplicateDevice(_that);case _Error() when error != null:
return error(_that);case _:
return orElse();
@@ -86,13 +88,15 @@ return error(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( _Connected value) connected,required TResult Function( _Connecting value) connecting,required TResult Function( _Disconnected value) disconnected,required TResult Function( _Error value) error,}){
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( _Connected value) connected,required TResult Function( _Connecting value) connecting,required TResult Function( _Disconnected value) disconnected,required TResult Function( _ServerDown value) serverDown,required TResult Function( _DuplicateDevice value) duplicateDevice,required TResult Function( _Error value) error,}){
final _that = this;
switch (_that) {
case _Connected():
return connected(_that);case _Connecting():
return connecting(_that);case _Disconnected():
return disconnected(_that);case _Error():
return disconnected(_that);case _ServerDown():
return serverDown(_that);case _DuplicateDevice():
return duplicateDevice(_that);case _Error():
return error(_that);}
}
/// A variant of `map` that fallback to returning `null`.
@@ -107,13 +111,15 @@ return error(_that);}
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( _Connected value)? connected,TResult? Function( _Connecting value)? connecting,TResult? Function( _Disconnected value)? disconnected,TResult? Function( _Error value)? error,}){
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( _Connected value)? connected,TResult? Function( _Connecting value)? connecting,TResult? Function( _Disconnected value)? disconnected,TResult? Function( _ServerDown value)? serverDown,TResult? Function( _DuplicateDevice value)? duplicateDevice,TResult? Function( _Error value)? error,}){
final _that = this;
switch (_that) {
case _Connected() when connected != null:
return connected(_that);case _Connecting() when connecting != null:
return connecting(_that);case _Disconnected() when disconnected != null:
return disconnected(_that);case _Error() when error != null:
return disconnected(_that);case _ServerDown() when serverDown != null:
return serverDown(_that);case _DuplicateDevice() when duplicateDevice != null:
return duplicateDevice(_that);case _Error() when error != null:
return error(_that);case _:
return null;
@@ -131,12 +137,14 @@ return error(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function()? connected,TResult Function()? connecting,TResult Function()? disconnected,TResult Function( String message)? error,required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function()? connected,TResult Function()? connecting,TResult Function()? disconnected,TResult Function()? serverDown,TResult Function()? duplicateDevice,TResult Function( String message)? error,required TResult orElse(),}) {final _that = this;
switch (_that) {
case _Connected() when connected != null:
return connected();case _Connecting() when connecting != null:
return connecting();case _Disconnected() when disconnected != null:
return disconnected();case _Error() when error != null:
return disconnected();case _ServerDown() when serverDown != null:
return serverDown();case _DuplicateDevice() when duplicateDevice != null:
return duplicateDevice();case _Error() when error != null:
return error(_that.message);case _:
return orElse();
@@ -155,12 +163,14 @@ return error(_that.message);case _:
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function() connected,required TResult Function() connecting,required TResult Function() disconnected,required TResult Function( String message) error,}) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function() connected,required TResult Function() connecting,required TResult Function() disconnected,required TResult Function() serverDown,required TResult Function() duplicateDevice,required TResult Function( String message) error,}) {final _that = this;
switch (_that) {
case _Connected():
return connected();case _Connecting():
return connecting();case _Disconnected():
return disconnected();case _Error():
return disconnected();case _ServerDown():
return serverDown();case _DuplicateDevice():
return duplicateDevice();case _Error():
return error(_that.message);}
}
/// A variant of `when` that fallback to returning `null`
@@ -175,12 +185,14 @@ return error(_that.message);}
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function()? connected,TResult? Function()? connecting,TResult? Function()? disconnected,TResult? Function( String message)? error,}) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function()? connected,TResult? Function()? connecting,TResult? Function()? disconnected,TResult? Function()? serverDown,TResult? Function()? duplicateDevice,TResult? Function( String message)? error,}) {final _that = this;
switch (_that) {
case _Connected() when connected != null:
return connected();case _Connecting() when connecting != null:
return connecting();case _Disconnected() when disconnected != null:
return disconnected();case _Error() when error != null:
return disconnected();case _ServerDown() when serverDown != null:
return serverDown();case _DuplicateDevice() when duplicateDevice != null:
return duplicateDevice();case _Error() when error != null:
return error(_that.message);case _:
return null;
@@ -303,6 +315,82 @@ String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
/// @nodoc
class _ServerDown with DiagnosticableTreeMixin implements WebSocketState {
const _ServerDown();
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
properties
..add(DiagnosticsProperty('type', 'WebSocketState.serverDown'))
;
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _ServerDown);
}
@override
int get hashCode => runtimeType.hashCode;
@override
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
return 'WebSocketState.serverDown()';
}
}
/// @nodoc
class _DuplicateDevice with DiagnosticableTreeMixin implements WebSocketState {
const _DuplicateDevice();
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
properties
..add(DiagnosticsProperty('type', 'WebSocketState.duplicateDevice'))
;
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _DuplicateDevice);
}
@override
int get hashCode => runtimeType.hashCode;
@override
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
return 'WebSocketState.duplicateDevice()';
}
}
/// @nodoc

View File

@@ -1,12 +1,26 @@
import 'dart:io' show Platform;
import 'package:animations/animations.dart';
import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/screens/about.dart';
import 'package:island/screens/developers/apps.dart';
import 'package:island/screens/account/credits.dart';
import 'package:island/screens/developers/app_detail.dart';
import 'package:island/screens/developers/bot_detail.dart';
import 'package:island/screens/developers/edit_app.dart';
import 'package:island/screens/developers/edit_bot.dart';
import 'package:island/screens/developers/new_app.dart';
import 'package:island/screens/developers/hub.dart';
import 'package:island/screens/developers/new_bot.dart';
import 'package:island/screens/developers/projects.dart';
import 'package:island/screens/developers/edit_project.dart';
import 'package:island/screens/developers/new_project.dart';
import 'package:island/screens/developers/project_detail.dart';
import 'package:island/screens/discovery/articles.dart';
import 'package:island/screens/posts/post_categories_list.dart';
import 'package:island/screens/posts/post_category_detail.dart';
import 'package:island/screens/posts/post_search.dart';
import 'package:island/widgets/app_wrapper.dart';
import 'package:island/screens/tabs.dart';
@@ -17,20 +31,27 @@ 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';
import 'package:island/screens/account/me/update.dart';
import 'package:island/screens/account/me/profile_update.dart';
import 'package:island/screens/account/leveling.dart';
import 'package:island/screens/account/me/settings.dart';
import 'package:island/screens/account/me/account_settings.dart';
import 'package:island/screens/chat/chat.dart';
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_screen.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';
import 'package:island/screens/creators/stickers/pack_detail.dart';
import 'package:island/screens/stickers/sticker_marketplace.dart';
import 'package:island/screens/stickers/pack_detail.dart';
import 'package:island/screens/discovery/feeds/feed_marketplace.dart';
import 'package:island/screens/discovery/feeds/feed_detail.dart';
import 'package:island/screens/creators/poll/poll_list.dart';
import 'package:island/screens/creators/publishers.dart';
import 'package:island/screens/creators/webfeed/webfeed_list.dart';
import 'package:island/screens/creators/webfeed/webfeed_edit.dart';
import 'package:island/screens/poll/poll_editor.dart';
import 'package:island/screens/posts/compose.dart';
import 'package:island/screens/posts/post_detail.dart';
import 'package:island/screens/posts/pub_profile.dart';
@@ -43,17 +64,43 @@ import 'package:island/screens/account/event_calendar.dart';
import 'package:island/screens/discovery/realms.dart';
import 'package:island/screens/reports/report_detail.dart';
import 'package:island/screens/reports/report_list.dart';
import 'package:island/widgets/post/post_shuffle.dart';
// Shell route keys for nested navigation
final rootNavigatorKey = GlobalKey<NavigatorState>();
final _shellNavigatorKey = GlobalKey<NavigatorState>();
final _tabsShellKey = GlobalKey<NavigatorState>();
Widget _tabPagesTransitionBuilder(
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) {
return FadeThroughTransition(
animation: animation,
secondaryAnimation: secondaryAnimation,
fillColor: Theme.of(context).colorScheme.surface,
child: child,
);
}
bool get _supportsAnalytics =>
kIsWeb ||
Platform.isAndroid ||
Platform.isIOS ||
Platform.isMacOS ||
Platform.isWindows;
// Provider for the router
final routerProvider = Provider<GoRouter>((ref) {
return GoRouter(
navigatorKey: rootNavigatorKey,
initialLocation: '/',
observers: [
if (_supportsAnalytics)
FirebaseAnalyticsObserver(analytics: FirebaseAnalytics.instance),
],
routes: [
ShellRoute(
navigatorKey: _shellNavigatorKey,
@@ -144,6 +191,37 @@ final routerProvider = Provider<GoRouter>((ref) {
return CreatorPostListScreen(pubName: name);
},
),
// Poll list route
GoRoute(
name: 'creatorPolls',
path: '/creators/:name/polls',
builder: (context, state) {
final name = state.pathParameters['name']!;
return CreatorPollListScreen(pubName: name);
},
),
// Poll routes
GoRoute(
name: 'creatorPollNew',
path: '/creators/:name/polls/new',
builder: (context, state) {
final name = state.pathParameters['name']!;
// initialPollId left null for create; initialPublisher prefilled
return PollEditorScreen(initialPublisher: name);
},
),
GoRoute(
name: 'creatorPollEdit',
path: '/creators/:name/polls/:id/edit',
builder: (context, state) {
final name = state.pathParameters['name']!;
final id = state.pathParameters['id']!;
return PollEditorScreen(
initialPollId: id,
initialPublisher: name,
);
},
),
GoRoute(
name: 'creatorStickers',
path: '/creators/:name/stickers',
@@ -221,30 +299,99 @@ final routerProvider = Provider<GoRouter>((ref) {
builder: (context, state) => const DeveloperHubScreen(),
),
GoRoute(
name: 'developerApps',
path: '/developers/:name/apps',
name: 'developerProjects',
path: '/developers/:name/projects',
builder:
(context, state) => CustomAppsScreen(
(context, state) => DevProjectsScreen(
publisherName: state.pathParameters['name']!,
),
),
GoRoute(
name: 'developerAppNew',
path: '/developers/:name/apps/new',
name: 'developerProjectNew',
path: '/developers/:name/projects/new',
builder:
(context, state) => NewCustomAppScreen(
(context, state) => NewProjectScreen(
publisherName: state.pathParameters['name']!,
),
),
GoRoute(
name: 'developerAppEdit',
path: '/developers/:name/apps/:id',
name: 'developerProjectEdit',
path: '/developers/:name/projects/:id/edit',
builder:
(context, state) => EditAppScreen(
(context, state) => EditProjectScreen(
publisherName: state.pathParameters['name']!,
id: state.pathParameters['id']!,
),
),
GoRoute(
name: 'developerProjectDetail',
path: '/developers/:name/projects/:projectId',
builder:
(context, state) => ProjectDetailScreen(
publisherName: state.pathParameters['name']!,
projectId: state.pathParameters['projectId']!,
),
routes: [
GoRoute(
name: 'developerAppNew',
path: 'apps/new',
builder:
(context, state) => NewCustomAppScreen(
publisherName: state.pathParameters['name']!,
projectId: state.pathParameters['projectId']!,
),
),
GoRoute(
name: 'developerAppEdit',
path: 'apps/:id/edit',
builder:
(context, state) => EditAppScreen(
publisherName: state.pathParameters['name']!,
projectId: state.pathParameters['projectId']!,
id: state.pathParameters['id']!,
),
),
GoRoute(
name: 'developerAppDetail',
path: 'apps/:appId',
builder:
(context, state) => AppDetailScreen(
publisherName: state.pathParameters['name']!,
projectId: state.pathParameters['projectId']!,
appId: state.pathParameters['appId']!,
),
),
GoRoute(
name: 'developerBotDetail',
path: 'bots/:botId',
builder:
(context, state) => BotDetailScreen(
publisherName: state.pathParameters['name']!,
projectId: state.pathParameters['projectId']!,
botId: state.pathParameters['botId']!,
),
),
GoRoute(
name: 'developerBotNew',
path: 'bots/new',
builder:
(context, state) => NewBotScreen(
publisherName: state.pathParameters['name']!,
projectId: state.pathParameters['projectId']!,
),
),
GoRoute(
name: 'developerBotEdit',
path: 'bots/:id/edit',
builder:
(context, state) => EditBotScreen(
publisherName: state.pathParameters['name']!,
projectId: state.pathParameters['projectId']!,
id: state.pathParameters['id']!,
),
),
],
),
],
),
@@ -287,21 +434,6 @@ final routerProvider = Provider<GoRouter>((ref) {
builder: (context, state) => const AboutScreen(),
),
GoRoute(
name: 'reportList',
path: '/safety/reports/me',
builder: (context, state) => const AbuseReportListScreen(),
),
GoRoute(
name: 'reportDetail',
path: '/safety/reports/me/:id',
builder: (context, state) {
final id = state.pathParameters['id']!;
return AbuseReportDetailScreen(reportId: id);
},
),
// Main tabs with TabsScreen shell
ShellRoute(
navigatorKey: _tabsShellKey,
@@ -310,48 +442,85 @@ final routerProvider = Provider<GoRouter>((ref) {
},
routes: [
// Explore tab
ShellRoute(
builder:
(context, state, child) => ExploreShellScreen(child: child),
routes: [
GoRoute(
name: 'explore',
path: '/',
builder: (context, state) => const ExploreScreen(),
),
GoRoute(
name: 'postSearch',
path: '/posts/search',
builder: (context, state) => const PostSearchScreen(),
),
GoRoute(
name: 'postDetail',
path: '/posts/:id',
builder: (context, state) {
final id = state.pathParameters['id']!;
return PostDetailScreen(id: id);
},
),
GoRoute(
name: 'publisherProfile',
path: '/publishers/:name',
builder: (context, state) {
final name = state.pathParameters['name']!;
return PublisherProfileScreen(name: name);
},
),
GoRoute(
name: 'discoveryRealms',
path: '/discovery/realms',
builder: (context, state) => const DiscoveryRealmsScreen(),
),
],
GoRoute(
name: 'explore',
path: '/',
pageBuilder:
(context, state) => CustomTransitionPage(
key: const ValueKey('explore'),
child: const ExploreScreen(),
transitionsBuilder: _tabPagesTransitionBuilder,
),
),
GoRoute(
name: 'postSearch',
path: '/posts/search',
builder: (context, state) => const PostSearchScreen(),
),
GoRoute(
name: 'postShuffle',
path: '/posts/shuffle',
builder: (context, state) => const PostShuffleScreen(),
),
GoRoute(
name: 'postCategories',
path: '/posts/categories',
builder: (context, state) => const PostCategoriesListScreen(),
),
GoRoute(
name: 'postCategoryDetail',
path: '/posts/categories/:slug',
builder: (context, state) {
final slug = state.pathParameters['slug']!;
return PostCategoryDetailScreen(slug: slug, isCategory: true);
},
),
GoRoute(
name: 'postTags',
path: '/posts/tags',
builder: (context, state) => const PostTagsListScreen(),
),
GoRoute(
name: 'postTagDetail',
path: '/posts/tags/:slug',
builder: (context, state) {
final slug = state.pathParameters['slug']!;
return PostCategoryDetailScreen(
slug: slug,
isCategory: false,
);
},
),
GoRoute(
name: 'postDetail',
path: '/posts/:id',
builder: (context, state) {
final id = state.pathParameters['id']!;
return PostDetailScreen(id: id);
},
),
GoRoute(
name: 'publisherProfile',
path: '/publishers/:name',
builder: (context, state) {
final name = state.pathParameters['name']!;
return PublisherProfileScreen(name: name);
},
),
GoRoute(
name: 'discoveryRealms',
path: '/discovery/realms',
builder: (context, state) => const DiscoveryRealmsScreen(),
),
// Chat tab
ShellRoute(
builder:
(context, state, child) => ChatShellScreen(child: child),
pageBuilder:
(context, state, child) => CustomTransitionPage(
key: const ValueKey('chat'),
child: ChatShellScreen(child: child),
transitionsBuilder: _tabPagesTransitionBuilder,
),
routes: [
GoRoute(
name: 'chatList',
@@ -387,6 +556,14 @@ final routerProvider = Provider<GoRouter>((ref) {
return ChatDetailScreen(id: id);
},
),
GoRoute(
name: 'searchMessages',
path: '/chat/:id/search',
builder: (context, state) {
final id = state.pathParameters['id']!;
return SearchMessagesScreen(roomId: id);
},
),
],
),
@@ -394,7 +571,12 @@ final routerProvider = Provider<GoRouter>((ref) {
GoRoute(
name: 'realmList',
path: '/realms',
builder: (context, state) => const RealmListScreen(),
pageBuilder:
(context, state) => CustomTransitionPage(
key: const ValueKey('realms'),
child: const RealmListScreen(),
transitionsBuilder: _tabPagesTransitionBuilder,
),
routes: [
GoRoute(
name: 'realmNew',
@@ -422,14 +604,51 @@ final routerProvider = Provider<GoRouter>((ref) {
// Account tab
ShellRoute(
builder:
(context, state, child) => AccountShellScreen(child: child),
pageBuilder:
(context, state, child) => CustomTransitionPage(
key: const ValueKey('account'),
child: AccountShellScreen(child: child),
transitionsBuilder: _tabPagesTransitionBuilder,
),
routes: [
GoRoute(
name: 'account',
path: '/account',
builder: (context, state) => const AccountScreen(),
),
// Sticker marketplace (user-facing, no publisher)
GoRoute(
name: 'stickerMarketplace',
path: '/stickers',
builder:
(context, state) => const MarketplaceStickersScreen(),
routes: [
GoRoute(
name: 'stickerPackDetail',
path: ':packId',
builder: (context, state) {
final packId = state.pathParameters['packId']!;
return MarketplaceStickerPackDetailScreen(id: packId);
},
),
],
),
GoRoute(
name: 'webFeedMarketplace',
path: '/feeds',
builder:
(context, state) => const MarketplaceWebFeedsScreen(),
routes: [
GoRoute(
name: 'webFeedDetail',
path: ':feedId',
builder: (context, state) {
final feedId = state.pathParameters['feedId']!;
return MarketplaceWebFeedDetailScreen(id: feedId);
},
),
],
),
GoRoute(
name: 'notifications',
path: '/account/notifications',
@@ -440,19 +659,16 @@ final routerProvider = Provider<GoRouter>((ref) {
path: '/account/wallet',
builder: (context, state) => const WalletScreen(),
),
GoRoute(
name: 'socialCredits',
path: '/account/credits',
builder: (context, state) => const SocialCreditsScreen(),
),
GoRoute(
name: 'relationships',
path: '/account/relationships',
builder: (context, state) => const RelationshipScreen(),
),
GoRoute(
name: 'accountProfile',
path: '/account/:name',
builder: (context, state) {
final name = state.pathParameters['name']!;
return AccountProfileScreen(name: name);
},
),
GoRoute(
name: 'profileUpdate',
path: '/account/me/update',
@@ -468,8 +684,30 @@ final routerProvider = Provider<GoRouter>((ref) {
path: '/account/me/settings',
builder: (context, state) => const AccountSettingsScreen(),
),
GoRoute(
name: 'reportList',
path: '/safety/reports/me',
builder: (context, state) => const AbuseReportListScreen(),
),
GoRoute(
name: 'reportDetail',
path: '/safety/reports/me/:id',
builder: (context, state) {
final id = state.pathParameters['id']!;
return AbuseReportDetailScreen(reportId: id);
},
),
],
),
GoRoute(
name: 'accountProfile',
path: '/account/:name',
builder: (context, state) {
final name = state.pathParameters['name']!;
return AccountProfileScreen(name: name);
},
),
],
),
],

View File

@@ -7,10 +7,12 @@ import 'package:flutter/services.dart';
import 'package:gap/gap.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/services/udid.native.dart';
import 'package:island/widgets/alert.dart';
import 'package:island/widgets/app_scaffold.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:styled_widget/styled_widget.dart';
import 'package:island/services/update_service.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:url_launcher/url_launcher_string.dart';
@@ -93,202 +95,234 @@ class _AboutScreenState extends ConsumerState<AboutScreen> {
final theme = Theme.of(context);
return AppScaffold(
isNoBackground: false,
appBar: AppBar(title: Text('about'.tr()), elevation: 0),
body:
_isLoading
? const Center(child: CircularProgressIndicator())
: _errorMessage != null
? Center(child: Text(_errorMessage!))
: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(height: 24),
// App Icon and Name
CircleAvatar(
radius: 50,
backgroundColor: theme.colorScheme.primary.withOpacity(
0.1,
),
child: Image.asset(
'assets/icons/icon.png',
width: 56,
height: 56,
),
),
const SizedBox(height: 16),
Text(
_packageInfo.appName,
style: theme.textTheme.headlineSmall?.copyWith(
fontWeight: FontWeight.bold,
),
),
Text(
'aboutScreenVersionInfo'.tr(
args: [_packageInfo.version, _packageInfo.buildNumber],
),
style: theme.textTheme.bodyMedium?.copyWith(
color: theme.textTheme.bodySmall?.color,
),
),
const SizedBox(height: 32),
// App Info Card
_buildSection(
context,
title: 'aboutScreenAppInfoSectionTitle'.tr(),
: Center(
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 540),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
_buildInfoItem(
context,
icon: Symbols.info,
label: 'aboutScreenPackageNameLabel'.tr(),
value: _packageInfo.packageName,
),
_buildInfoItem(
context,
icon: Symbols.update,
label: 'aboutScreenVersionLabel'.tr(),
value: _packageInfo.version,
),
_buildInfoItem(
context,
icon: Symbols.build,
label: 'aboutScreenBuildNumberLabel'.tr(),
value: _packageInfo.buildNumber,
),
],
),
if (_deviceInfo != null) const SizedBox(height: 16),
if (_deviceInfo != null)
_buildSection(
context,
title: 'Device Information',
children: [
_buildInfoItem(
context,
icon: Symbols.label,
label: 'aboutDeviceName'.tr(),
value: _deviceInfo?.data['name'],
const SizedBox(height: 24),
// App Icon and Name
CircleAvatar(
radius: 50,
backgroundColor: theme.colorScheme.primary
.withOpacity(0.1),
child: Image.asset(
'assets/icons/icon.png',
width: 56,
height: 56,
),
_buildInfoItem(
context,
icon: Symbols.fingerprint,
label: 'aboutDeviceIdentifier'.tr(),
value: _deviceUdid ?? 'N/A',
copyable: true,
),
const SizedBox(height: 16),
Text(
_packageInfo.appName,
style: theme.textTheme.headlineSmall?.copyWith(
fontWeight: FontWeight.bold,
),
],
),
const SizedBox(height: 16),
// Links Card
_buildSection(
context,
title: 'aboutScreenLinksSectionTitle'.tr(),
children: [
_buildListTile(
context,
icon: Symbols.privacy_tip,
title: 'aboutScreenPrivacyPolicyTitle'.tr(),
onTap:
() => _launchURL(
'https://solsynth.dev/terms/privacy-policy',
),
),
_buildListTile(
context,
icon: Symbols.description,
title: 'aboutScreenTermsOfServiceTitle'.tr(),
onTap:
() => _launchURL(
'https://solsynth.dev/terms/basic-law',
),
),
_buildListTile(
context,
icon: Symbols.code,
title: 'aboutScreenOpenSourceLicensesTitle'.tr(),
onTap: () {
showLicensePage(
context: context,
applicationName: _packageInfo.appName,
applicationVersion:
'Version ${_packageInfo.version}',
);
},
),
],
),
const SizedBox(height: 16),
// Developer Info
_buildSection(
context,
title: 'aboutScreenDeveloperSectionTitle'.tr(),
children: [
_buildListTile(
context,
icon: Symbols.email,
title: 'aboutScreenContactUsTitle'.tr(),
subtitle: 'lily@solsynth.dev',
onTap: () => _launchURL('mailto:lily@solsynth.dev'),
),
_buildListTile(
context,
icon: Symbols.copyright,
title: 'aboutScreenLicenseTitle'.tr(),
subtitle: 'aboutScreenLicenseContent'.tr(
args: [DateTime.now().year.toString()],
Text(
'aboutScreenVersionInfo'.tr(
args: [
_packageInfo.version,
_packageInfo.buildNumber,
],
),
onTap:
() => _launchURL(
'https://github.com/Solsynth/Solian/blob/v3/LICENSE.txt',
),
),
if (kIsWeb || !(Platform.isMacOS || Platform.isIOS))
_buildListTile(
context,
icon: Symbols.favorite,
title: 'donate'.tr(),
subtitle: 'donateDescription'.tr(),
onTap: () {
launchUrlString(
'https://afdian.com/@littlesheep',
);
},
style: theme.textTheme.bodyMedium?.copyWith(
color: theme.textTheme.bodySmall?.color,
),
],
),
),
const SizedBox(height: 32),
const SizedBox(height: 32),
// Copyright
Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Text(
'aboutScreenCopyright'.tr(
args: [DateTime.now().year.toString()],
// App Info Card
_buildSection(
context,
title: 'aboutScreenAppInfoSectionTitle'.tr(),
children: [
_buildInfoItem(
context,
icon: Symbols.info,
label: 'aboutScreenPackageNameLabel'.tr(),
value: _packageInfo.packageName,
),
style: theme.textTheme.bodySmall,
textAlign: TextAlign.center,
),
const Gap(1),
Text(
'aboutScreenMadeWith'.tr(),
textAlign: TextAlign.center,
).fontSize(10).opacity(0.8),
],
),
),
_buildInfoItem(
context,
icon: Symbols.update,
label: 'aboutScreenVersionLabel'.tr(),
value: _packageInfo.version,
),
_buildInfoItem(
context,
icon: Symbols.build,
label: 'aboutScreenBuildNumberLabel'.tr(),
value: _packageInfo.buildNumber,
),
],
),
Gap(MediaQuery.of(context).padding.bottom + 16),
],
if (_deviceInfo != null) const SizedBox(height: 16),
if (_deviceInfo != null)
_buildSection(
context,
title: 'Device Information',
children: [
_buildInfoItem(
context,
icon: Symbols.label,
label: 'aboutDeviceName'.tr(),
value:
_deviceInfo?.data['name'] ?? 'unknown'.tr(),
),
_buildInfoItem(
context,
icon: Symbols.fingerprint,
label: 'aboutDeviceIdentifier'.tr(),
value: _deviceUdid ?? 'N/A',
copyable: true,
),
],
),
const SizedBox(height: 16),
// Links Card
_buildSection(
context,
title: 'aboutScreenLinksSectionTitle'.tr(),
children: [
_buildListTile(
context,
icon: Symbols.system_update,
title: 'Check for updates',
onTap: () async {
// Fetch latest release and show the unified sheet
final svc = UpdateService();
// Reuse service fetch + compare to decide content
showLoadingModal(context);
final release = await svc.fetchLatestRelease();
if (!context.mounted) return;
hideLoadingModal(context);
if (release != null) {
await svc.showUpdateSheet(context, release);
} else {
showInfoAlert(
'Currently cannot get update from the GitHub.',
'Unable to check for updates',
);
}
},
),
_buildListTile(
context,
icon: Symbols.privacy_tip,
title: 'aboutScreenPrivacyPolicyTitle'.tr(),
onTap:
() => _launchURL(
'https://solsynth.dev/terms/privacy-policy',
),
),
_buildListTile(
context,
icon: Symbols.description,
title: 'aboutScreenTermsOfServiceTitle'.tr(),
onTap:
() => _launchURL(
'https://solsynth.dev/terms/user-agreement',
),
),
_buildListTile(
context,
icon: Symbols.code,
title: 'aboutScreenOpenSourceLicensesTitle'.tr(),
onTap: () {
showLicensePage(
context: context,
applicationName: _packageInfo.appName,
applicationVersion:
'Version ${_packageInfo.version}',
);
},
),
],
),
const SizedBox(height: 16),
// Developer Info
_buildSection(
context,
title: 'aboutScreenDeveloperSectionTitle'.tr(),
children: [
_buildListTile(
context,
icon: Symbols.email,
title: 'aboutScreenContactUsTitle'.tr(),
subtitle: 'lily@solsynth.dev',
onTap:
() => _launchURL('mailto:lily@solsynth.dev'),
),
_buildListTile(
context,
icon: Symbols.copyright,
title: 'aboutScreenLicenseTitle'.tr(),
subtitle: 'aboutScreenLicenseContent'.tr(
args: [DateTime.now().year.toString()],
),
onTap:
() => _launchURL(
'https://github.com/Solsynth/Solian/blob/v3/LICENSE.txt',
),
),
if (kIsWeb || !(Platform.isMacOS || Platform.isIOS))
_buildListTile(
context,
icon: Symbols.favorite,
title: 'donate'.tr(),
subtitle: 'donateDescription'.tr(),
onTap: () {
launchUrlString(
'https://afdian.com/@littlesheep',
);
},
),
],
),
const SizedBox(height: 32),
// Copyright
Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Text(
'aboutScreenCopyright'.tr(
args: [DateTime.now().year.toString()],
),
style: theme.textTheme.bodySmall,
textAlign: TextAlign.center,
),
const Gap(1),
Text(
'aboutScreenMadeWith'.tr(),
textAlign: TextAlign.center,
).fontSize(10).opacity(0.8),
],
),
),
Gap(MediaQuery.of(context).padding.bottom + 16),
],
),
),
),
),
);

Some files were not shown because too many files have changed in this diff Show More