Compare commits

...

306 Commits

Author SHA1 Message Date
5efa9b2ae8 🚀 Launch 3.3.0+135 2025-10-13 01:25:37 +08:00
dd3e39e891 💄 Smart retry GET requests 2025-10-13 00:58:51 +08:00
b6896ded23 🐛 Fix compose settings bugs 2025-10-13 00:55:45 +08:00
f28a73ff9c ♻️ Refactor post tags 2025-10-13 00:53:45 +08:00
a014b64235 🐛 Fix performance issue and recycle logic issue 2025-10-13 00:36:40 +08:00
7e0e7c20d7 ♻️ Convert the activity calandar screen to sheet 2025-10-13 00:34:16 +08:00
389fa515ba Able to turn off animation (for message only for now) 2025-10-13 00:22:30 +08:00
681ead02eb 🐛 Fix markdown rendering 2025-10-13 00:16:57 +08:00
8d1c145b0b 💫 Message list fully animated 2025-10-13 00:16:50 +08:00
51b4754182 💄 Optimize chat room, chat input
💫 More animations in chat input
2025-10-13 00:05:22 +08:00
8a2b321701 Custom color name 2025-10-12 23:53:28 +08:00
f685a7a249 🐛 Bug fixes in developer hub 2025-10-12 23:27:49 +08:00
76009147e9 🐛 Fix message notifier 2025-10-12 23:23:13 +08:00
ce12f28e56 Custom reaction via sticker 2025-10-12 23:18:58 +08:00
3604373a1e 🐛 Fix update message 2025-10-12 22:43:25 +08:00
9704a4c2c7 ♻️ Use the dialog when launch from quick reply to post 2025-10-12 22:32:43 +08:00
67def56ad1 💄 Better post quick reply 2025-10-12 22:26:37 +08:00
1be33916af 💄 Optimize post reaction sheet 2025-10-12 22:21:15 +08:00
e8ff1bfd22 🐛 Bug fixes and optimization 2025-10-12 22:08:33 +08:00
3ae56f3d89 Post reaction detail popover 2025-10-12 22:05:47 +08:00
707143e998 ♻️ Extract post reaction sheet from post item 2025-10-12 21:38:24 +08:00
1fd34eb2a3 💄 Merge the creator hub and developer hub to the tabs 2025-10-12 21:32:34 +08:00
d7ca41e946 ♻️ Refactored heatmap 2025-10-12 20:58:41 +08:00
ad9fb0719a 🐛 Bug fixes and optimization 2025-10-12 20:45:10 +08:00
e2d315afd4 Auto complete in post as well 2025-10-12 19:49:16 +08:00
6124dbfd79 Heatmap 2025-10-12 18:47:01 +08:00
5327f04ec0 ♻️ Gloablize pop intent 2025-10-12 18:26:28 +08:00
41c56a2319 Markdown++ 2025-10-12 18:22:16 +08:00
f9d033542e Mention tag in markdown 2025-10-12 17:56:31 +08:00
91784e65e6 Message item swipe to 2025-10-12 17:29:03 +08:00
9d39c6a825 Auto complete, better metion parser, sticker placeholder v2 2025-10-12 17:10:18 +08:00
537e49f1a4 Add typing ahead 2025-10-12 16:15:04 +08:00
75bbd4df71 Desktop page actions on title bar 2025-10-12 16:14:54 +08:00
6ef4580d93 💄 Optimize developer hub 2025-10-12 16:14:44 +08:00
6ffd498761 ♻️ Refactored developer hub 2025-10-12 14:28:18 +08:00
27157e7cc1 ♻️ Refactored web feed, poll 2025-10-12 12:19:50 +08:00
bbb07d574a ♻️ Refactored cloud file picker, stickers 2025-10-12 02:21:39 +08:00
c660a419e2 ♻️ Optimize the creator hub 2025-10-12 00:06:48 +08:00
c3f61467c8 👔 Ignore language, message always translatable 2025-10-11 22:59:34 +08:00
9bc47df452 ⬆️ Upgrade flutter 2025-10-11 22:18:08 +08:00
9ef8ca4d45 🐛 Fix wrong import lead to failed compile on web 2025-10-11 00:52:52 +08:00
b55cbd08d1 ♻️ Optimized the experience of cloud files 2025-10-11 00:49:14 +08:00
8c6bd0feaa 💄 Optimize cloud file text file 2025-10-10 23:58:33 +08:00
7dd4b20628 🐛 Fix some bugs 2025-10-10 23:00:13 +08:00
fec0cb7640 ⬆️ Upgrade dependecies 2025-10-10 22:44:51 +08:00
75deb04a2b ♻️ Better resend message 2025-10-10 22:34:34 +08:00
7c7ed21a96 💄 Optimize message delete when failed to send 2025-10-10 21:50:52 +08:00
a201f20793 💄 Optimize message indicator 2025-10-10 21:38:53 +08:00
598c51bc1a Chat input full featured upload 2025-10-10 20:54:37 +08:00
e1ea61c5f1 🐛 Fix the compose 2025-10-10 01:04:21 +08:00
ac424bde36 💄 Optimize the ability to search 2025-10-10 00:50:17 +08:00
b43b70df3f 💄 Optimize the search message a step further 2025-10-10 00:43:49 +08:00
4321aa621a 💄 Optimize search message design 2025-10-10 00:38:43 +08:00
d5d275fb43 🐛 Fix the message search need tap twice 2025-10-10 00:23:11 +08:00
6bb3307144 🐛 Fix message jumps in search 2025-10-10 00:19:22 +08:00
391604d4a2 🐛 Fix bugs 2025-10-09 01:15:27 +08:00
1d9361c12f 💄 Bug fixes search messages and optimization 2025-10-09 01:11:14 +08:00
a129b9cdd0 💄 Optimize search message tile 2025-10-09 00:41:17 +08:00
3bf815ac61 💄 Optimize message actions 2025-10-09 00:38:45 +08:00
77bae4d6fd 💄 Optimize message action area 2025-10-09 00:00:25 +08:00
0a301c4c9b 💄 Confirm when deleting message 2025-10-08 23:54:59 +08:00
27b390a51c 💄 Hovering actions 2025-10-08 23:48:06 +08:00
018386d14e 💄 Optimize chat message cursor 2025-10-08 22:42:43 +08:00
3825d7c6c7 💄 Optimize display of certain type of message item 2025-10-08 22:33:56 +08:00
bf930291e4 ♻️ Update the embed rendering 2025-10-08 21:58:24 +08:00
a8c4988790 🐛 Fix bugs 2025-10-07 03:05:53 +08:00
28dd204b1a 🐛 Fix bugs 2025-10-06 22:41:23 +08:00
3cbc1a59a7 🐛 Fix some post related bugs 2025-10-06 12:51:28 +08:00
277e9ae3d1 💄 Optimize compose design 2025-10-06 12:28:17 +08:00
27b3ca25b7 💄 Optimize compose 2025-10-06 12:24:09 +08:00
f871cd3b62 ♻️ Refactor post 2025-10-06 11:55:53 +08:00
a8a59ee30c 💄 Optimize compose card 2025-10-05 18:34:54 +08:00
2cd1416a13 Capture screen audio 2025-10-05 12:34:43 +08:00
6be7dfbc61 🐛 Bug fixes 2025-10-05 00:14:08 +08:00
1abbd85614 Fully customizable color scheme 2025-10-04 22:12:39 +08:00
31ac5ad07c 🐛 FIx color extraction 2025-10-04 21:48:56 +08:00
ae2ba495e9 Card opacity and refactored theme 2025-10-04 21:46:32 +08:00
637aa44548 Transfer 2025-10-04 21:22:37 +08:00
44dbfc36d9 💄 Optimized wallet screen 2025-10-04 20:38:42 +08:00
5dbe7371cb Transaction details 2025-10-04 20:33:34 +08:00
6c91093198 💄 Optimized wallet 2025-10-04 15:48:16 +08:00
3f640b7898 Wallet funds 2025-10-04 01:17:09 +08:00
7db164fda6 🐛 Tries to fix 2025-10-03 22:06:05 +08:00
6df1d96cc9 🌐 More localized stellar program 2025-10-03 21:17:47 +08:00
122a796f8c 🌐 Localized gift subscription 2025-10-03 21:11:11 +08:00
fbc7812a16 💄 Optimize gift subscription 2025-10-03 20:45:08 +08:00
0b1a23e81a 💄 Optimize publisher first time UX
♻️ Split up the forms and list screens
💄 Use dropdown forms fields instead of selection
2025-10-03 15:42:56 +08:00
c87e6cfe07 ♻️ Refactored the stellar program tab 2025-10-02 13:03:18 +08:00
53d51b8a0e Plain text rendering 2025-10-02 02:15:48 +08:00
337ae39e08 PDF rendering 2025-10-02 02:10:45 +08:00
8fe3a664a6 ♻️ Better file upload 2025-10-02 01:13:41 +08:00
3bfc0b8181 ♻️ Refactor the bottom nav display 2025-10-01 16:35:41 +08:00
ac2951479b App links 2025-10-01 14:55:04 +08:00
2bfd13d843 🐛 Fixes bugs and optimization
 Add app links
2025-10-01 12:41:48 +08:00
28db6f9f01 Better windows notification 2025-10-01 12:28:23 +08:00
a4f7b8415d 💄 Optimize the draft manager clear hint 2025-09-30 00:14:23 +08:00
2255d3d591 ♻️ Better draft, post saving and auto restore hint 2025-09-30 00:04:51 +08:00
97792ae734 💄 Localized language picker 2025-09-29 23:10:21 +08:00
a5d13250cc 🍱 Update translations 2025-09-29 23:10:10 +08:00
de9e235d0c ♻️ Dialog based editor for normal post 2025-09-29 01:16:32 +08:00
56fb5451cd 💄 Optimize explore compose region 2025-09-29 00:34:30 +08:00
870de961f5 💄 Optimize border radius 2025-09-28 23:09:59 +08:00
22bf6d1c33 💄 Redesign explore 2025-09-28 23:07:22 +08:00
5b62f89531 🐛 Fix web file upload 2025-09-28 01:53:55 +08:00
b1326d8f04 🐛 Dozens of bug fixes 2025-09-28 01:39:07 +08:00
fffca4a78c ♻️ Refactor logger system 2025-09-28 00:39:17 +08:00
42bd7f97cb Add talker and upgrade deps 2025-09-27 23:40:08 +08:00
6377856ae0 💄 Optimize online indicator 2025-09-27 23:01:42 +08:00
0f1c52b9e3 🐛 Fix subscribe 2025-09-27 23:00:04 +08:00
6ed6f60fbc 💄 New chat UI 2025-09-27 22:59:16 +08:00
e65a414065 🐛 Fixes and improvements in syncing 2025-09-27 22:47:31 +08:00
214d5c4a53 Online indicator in chat 2025-09-27 22:17:29 +08:00
fe33931304 Split force update and check for update 2025-09-27 21:49:13 +08:00
113309257e Proper windows update 2025-09-27 21:33:12 +08:00
b95a8b2ed2 Merge branch 'v3' of https://git.solsynth.dev/SolarNetwork/App into v3 2025-09-27 21:25:10 +08:00
LittleSheep
e922971a5e 🔀 Merge pull request #180 from liang-work/appchangetest
[Feature] Able to change theme mode not following System Theme
2025-09-27 21:17:39 +08:00
9d5b71bead 💄 Optimize chat indicator style 2025-09-27 21:17:14 +08:00
890efa2efb upload i18n update file. 2025-09-27 20:55:04 +08:00
674097e425 git commit
Upload code that can run
2025-09-27 20:26:37 +08:00
3379dcb7f3 Dynamic chat online counter basis 2025-09-27 19:25:24 +08:00
eb5a849e1f 💄 Optimize title bar for windows and linux 2025-09-27 18:45:58 +08:00
4981a23e8e Chat summary realtime updates 2025-09-27 17:07:19 +08:00
c64d4bacb6 📝 Update CODE_OF_CONDUCT 2025-09-27 17:05:21 +08:00
838d18013b 🐛 Fix message deletion 2025-09-27 16:54:23 +08:00
3f7902e463 🐛 Fix post detail award button 2025-09-27 16:34:50 +08:00
54560ad5d8 🐛 Fix some bugs in attachment upload sheet 2025-09-27 15:51:26 +08:00
0c729db639 🐛 Fix native window 2025-09-27 15:33:42 +08:00
1fbaac8d88 💄 Optimize chat input a step further 2025-09-27 15:31:57 +08:00
b9dc724f0b 🐛 Fix chat newline on desktop 2025-09-27 00:22:43 +08:00
a2cc55696f Transparent window on desktop 2025-09-27 00:04:04 +08:00
e79f857feb ♻️ Replace bitsdojo_window with window_manager 2025-09-26 23:26:40 +08:00
affba29c04 🐛 Fix IRC style display the message time wrong 2025-09-26 22:30:46 +08:00
756746b144 🍱 Update translation keys 2025-09-24 23:31:47 +08:00
28b6eade48 🚀 Launch 3.2.0+134 2025-09-24 22:37:16 +08:00
1de7ef8c96 🐛 Fix bugs 2025-09-24 22:34:05 +08:00
67eac5dcf5 Optimized rpc 2025-09-24 22:14:40 +08:00
7a44bfa075 ⬆️ Upgrade packages 2025-09-24 21:29:21 +08:00
1c2f25a152 💄 Optimize leveling page 2025-09-24 21:21:51 +08:00
be26ea280e 🌐 Make file info localizable 2025-09-24 21:20:00 +08:00
b4996d069f 🐛 Fix bugs 2025-09-24 21:03:53 +08:00
bf4892b34d 🐛 Fix bugs 2025-09-24 20:52:56 +08:00
5f84751fd5 🐛 Fix file upload 2025-09-24 20:29:30 +08:00
457d1bac60 🚀 Launch 3.2.0+133 2025-09-24 19:30:36 +08:00
02ec11845b Seprate uploading action in chat 2025-09-24 16:53:32 +08:00
612f1bf004 File uploader 2025-09-24 16:45:24 +08:00
fd80b713ad 🐛 Fix something 2025-09-24 16:16:21 +08:00
508805368c File manage filter 2025-09-24 16:09:40 +08:00
98eb28a4ec File manage list 2025-09-24 15:56:56 +08:00
d1a2f59dd1 💄 Optimize account page 2025-09-24 14:49:06 +08:00
bb9adb963a 💄 Redesign leveling card 2025-09-24 14:29:50 +08:00
83e40cd860 ♻️ Merge the social credits to the leveling page 2025-09-24 13:59:01 +08:00
c06fb12f6a 🐛 Fix styling issue 2025-09-24 12:41:09 +08:00
6600cf4df8 🍱 Update reactions images 2025-09-24 00:33:28 +08:00
4293daaa2f Introduce cuite reaction 2025-09-23 23:39:58 +08:00
866674ddde 🐛 Fix something 2025-09-23 22:55:53 +08:00
27d478ba4f 💄 Optimize the embed view experience 2025-09-23 21:02:14 +08:00
cccade763f 💄 Rename IRC chat UI 2025-09-23 20:28:46 +08:00
f760b85186 💄 Optimize message flashing 2025-09-23 20:27:18 +08:00
e68c5f4f92 💄 Optimize irc styles 2025-09-23 20:12:39 +08:00
b0f3b6b5c3 Configure message style 2025-09-23 19:39:27 +08:00
cb2af379fa Provide three styles of message 2025-09-23 19:05:44 +08:00
38f8103265 Search and jump to message 2025-09-23 16:56:02 +08:00
06bb18bdaa 💄 Flashing message background when jumped 2025-09-23 16:19:54 +08:00
84c38500d0 Edited message diff 2025-09-23 15:20:45 +08:00
9529bbf08b 💄 Save historic sync changes message 2025-09-23 14:58:07 +08:00
8baf77bcf7 ♻️ Refactor room message sorting 2025-09-23 14:21:45 +08:00
b2ac5fbef2 ♻️ Optimize message data structure 2025-09-23 14:00:43 +08:00
c79b1d7aab 🐛 Fix file upload 2025-09-21 23:20:36 +08:00
LittleSheep
4f55a8209c 🔀 Merge pull request #179 from Texas0295/v3
[Feature] add pool-aware file upload with default pool selection
2025-09-21 23:19:30 +08:00
Texas0295
ace302111a [REF] unify file upload logic and pool utils
- merge putMediaToCloud and putFileToPool into putFileToCloud
  with FileUploadMode for media-safe vs generic uploads

Signed-off-by: Texas0295 <kimura@texas0295.top>
2025-09-21 22:38:49 +08:00
Texas0295
1391fa0dde [REF] unify pool handling with extension methods
- Move pool filtering and parsing logic into SnFilePool extension
- Replace PoolService and pool_utils with unified extension
- Update settings screen to use pools.filterValid() + resolveDefaultPoolId
- Cleanup references in compose_shared.dart
- Remove obsolete files: pool_service.dart, pool_utils.dart

Signed-off-by: Texas0295 <kimura@texas0295.top>
2025-09-21 22:10:25 +08:00
Texas0295
cbdc7acdcd [REF] refactor file pool model and imports
- Refactor SnFilePool using freezed + sealed for consistency with other Sn models
- Add extension method listFromResponse for PoolService compatibility
- Update PoolService and utils to use SnFilePool
- Replace relative imports (../) with package imports for clarity and maintainability

Signed-off-by: Texas0295 <kimura@texas0295.top>
2025-09-21 21:37:07 +08:00
Texas0295
b80d91825a migrate file upload from tus to FileUploader API
The tus-based upload flow (/drive/tus) has been removed upstream in favor
of a new multipart upload protocol. This commit replaces all TusClient
usage with the new FileUploader service that follows the official
/drive/files/upload/{create,chunk,complete} endpoints.

Changes include:
- remove tus_client_dart dependency and related code
- add putFileToPool() backed by FileUploader.uploadFile()
- update uploadAttachment() to call the new putFileToPool
- preserve poolId support, filename, and mimetype handling
- ensure progress callbacks fire at start and completion

This aligns the client with the new upload protocol while keeping the
same Compose UI and settings logic introduced in earlier patches.

Signed-off-by: Texas0295 <kimura@texas0295.top>
2025-09-21 20:33:17 +08:00
Texas0295
1a703b7eba add default pool selection with validation and fallback
- extend AppSettings with defaultPoolId
- add pool filtering utility to exclude media-only pools
- add resolveDefaultPoolId with fallback to safe pool
- update SettingsScreen with default pool dropdown
- integrate uploadAttachment with default pool resolution

Signed-off-by: Texas0295 <kimura@texas0295.top>
2025-09-21 20:33:12 +08:00
Texas0295
3621ea7744 support default file pool selection
- add defaultPoolId to AppSettings + persistence
- extend SettingsScreen with pool dropdown
- update uploadAttachment to use defaultPoolId with fallback

Signed-off-by: Texas0295 <kimura@texas0295.top>
2025-09-21 20:33:12 +08:00
Texas0295
b638343f02 add pool fetching service and provider
- define FilePool model
- implement PoolService with /drive/pools endpoint
- add Riverpod providers (poolServiceProvider, poolsProvider)

Signed-off-by: Texas0295 <kimura@texas0295.top>
2025-09-21 20:33:12 +08:00
Texas0295
269a64cabb add general file upload support with pool-aware tus client
- add "uploadFile" i18n key (en, zh-CN, zh-TW)
- introduce putFileToPool for tus upload with X-FilePool header
- add ComposeLogic.pickGeneralFile for arbitrary files
- extend uploadAttachment to support poolId override
- add toolbar button for general file upload

Signed-off-by: Texas0295 <kimura@texas0295.top>
2025-09-21 20:33:11 +08:00
406e5187a8 🐛 Fix captcha 2025-09-21 19:42:13 +08:00
9bdd08d8dd New protocol to upload file 2025-09-21 18:46:48 +08:00
d737232dcf 💄 Optimize auth devices 2025-09-21 15:33:09 +08:00
c9d751479e 🐛 Fix iOS build 2025-09-21 15:32:52 +08:00
a2c2bfe585 ♻️ Replace the pattle_generator 2025-09-21 14:50:30 +08:00
c7f9da0dee ⬆️ Upgrade deps and flutter 2025-09-21 02:06:34 +08:00
LittleSheep
a243cda1df 🔀 Merge pull request #178 from Texas0295/v3
[FIX] chat: fix message pagination logic
2025-09-17 22:17:47 +08:00
Texas0295
7b238f32fd [FIX] chat: fix message pagination logic
`loadInitial()` fetched 100 messages while `_page_size` was 20,
so `_has_more` turned false too early and history stopped around
10h back. `loadMore()` also used `_currentPage * _page_size`
for offset, causing duplicates.

Use `_page_size` for initial load and rely on current message
count as offset. This removes `_currentPage` entirely and lets
older messages load correctly.

Signed-off-by: Texas0295 <kimura@texas0295.top>
2025-09-17 19:36:51 +08:00
313af28d7f 👽 Update service usage 2025-09-17 00:48:01 +08:00
c64e1e208c Desktop device name, close #7 2025-09-14 19:38:01 +08:00
c9b07a9a2a 🐛 Fix errors 2025-09-14 17:38:11 +08:00
55c0e355f1 ♻️ Refactor ICP server to make it available across platform 2025-09-13 20:32:39 +08:00
be414891ec 🐛 Fix pipe path 2025-09-13 17:59:33 +08:00
787876ab6a 🗑️ Removed unused method 2025-09-13 15:57:45 +08:00
8578cde620 🐛 Fix expired at must non null 2025-09-13 15:46:07 +08:00
14d55d45a8 🐛 Fix ipc server on web 2025-09-13 15:31:05 +08:00
724391584e 🐛 Fix and optimize alert 2025-09-13 15:31:05 +08:00
3a5e45808a 🐛 Fix firebase analytics not available on windows 2025-09-13 15:29:38 +08:00
488055955c ♻️ Splitting up ipc servers in unix and windows 2025-09-13 12:59:54 +08:00
LittleSheep
313ebc64cc 🔀 Merge pull request #177 from Texas0295/v3
[FIX] tray: ensure Show Window works reliably on Linux/Wayland
2025-09-12 21:07:56 +08:00
Texas0295
1ed8b1d0c1 [FIX] tray: ensure Show Window works reliably on Linux/Wayland
Avoid relying on appWindow.isVisible, which is not trustworthy under

bitsdojo on Linux/Wayland. Instead, always run show → restore → show

sequence to guarantee window is re-mapped and raised.


Signed-off-by: Texas0295<kimura@texas0295.top>
2025-09-12 13:26:15 +08:00
4af816d931 🐛 Fix windows rpc 2025-09-11 01:15:52 +08:00
1c058a4323 ♻️ Better windows support 2025-09-11 01:06:58 +08:00
461ed1fcda ♻️ FFI windows rpc ipc implmentation 2025-09-11 00:56:26 +08:00
5363afa558 🐛 Trying to fix windows rpc ipc 2025-09-11 00:33:44 +08:00
f0d2737da8 Windows RPC IPC 2025-09-11 00:23:14 +08:00
1f2f80aa3e 🐛 Trying to fix windows notification issue 2025-09-10 23:40:19 +08:00
240a872e65 Rollback windows gha changes 2025-09-10 23:12:57 +08:00
c1ec6f0849 Merge branch 'v3' of https://github.com/Solsynth/Solian into v3 2025-09-10 22:48:54 +08:00
ab42686d4d 🔨 Trying to fix windows build issue 2025-09-10 22:48:50 +08:00
c9727e92b8 🚀 Launch 3.2.0+132 2025-09-10 01:32:38 +08:00
9b8768061d Award history 2025-09-10 01:23:50 +08:00
0949f0da54 ⬆️ Upgrade flutter and deps 2025-09-09 23:34:31 +08:00
215ca705ac Delete the poll 2025-09-09 01:03:42 +08:00
03457af04a 💄 Optimize poll editor 2025-09-09 01:01:28 +08:00
73c6a1febf Show account on poll feedback
💄 Optimize poll feedback
2025-09-09 01:00:21 +08:00
ba8d30bcde 🐛 Fix order didn't paid successfully 2025-09-09 00:45:31 +08:00
8449658b47 RPC now set remote status 2025-09-09 00:27:26 +08:00
c7f417234e Show awarded score 2025-09-08 23:55:50 +08:00
6c847ee1e1 👽 Remove order handle in stellar program purchase 2025-09-08 22:50:32 +08:00
18ad4d376e 💄 The payment now no longer auto procced 2025-09-08 22:48:46 +08:00
c4d5ba5c9d 🐛 Fix inline attachment didn't render properly 2025-09-08 22:43:41 +08:00
1069669049 🐛 Post visibility not readable 2025-09-08 22:26:44 +08:00
aa648fec62 Reworked post draft 2025-09-08 22:25:54 +08:00
541900673a 🐛 Disable unix socks completely on macOS 2025-09-08 21:49:23 +08:00
265502ffd0 🐛 Disable ipc rpc server on macos 2025-09-08 21:34:03 +08:00
3bd79350d1 🧱 Activity RPC server 2025-09-08 20:57:27 +08:00
5294d1fb23 💄 Make sure cloud file background fill entire space 2025-09-08 19:29:01 +08:00
ec1269dcf1 💄 Optimize check in widget and add today's countdown 2025-09-08 19:27:30 +08:00
edb0a25f34 💄 Optimize embed view renderer loading logic 2025-09-08 15:48:10 +08:00
7cd10118cc Post award 2025-09-08 15:47:57 +08:00
fcddc8f345 💄 Optimize embed webview 2025-09-08 02:45:20 +08:00
1cc34240da Post embed view rendering 2025-09-08 02:42:49 +08:00
013f7f02bc Post embed view 2025-09-08 02:15:22 +08:00
4e79e4100f Public contact method 2025-09-08 00:40:32 +08:00
feda1f067f 🐛 Post detail initial expand poll 2025-09-07 23:57:14 +08:00
fe0e192a43 💄 Optimize error alert 2025-09-07 23:56:58 +08:00
93df294142 Poll collapse 2025-09-07 23:00:29 +08:00
78d65c39f3 🐛 Fix poll yes or no stats 2025-09-07 22:48:22 +08:00
18b0dbd797 🐛 Fix post submit 2025-09-07 22:20:49 +08:00
80cc8cbb40 🐛 Fix android build 2025-09-07 18:30:35 +08:00
646e95a9fc 💄 Optimize check in 2025-09-07 18:30:28 +08:00
6f9d51673b 🚀 Launch 3.2.0+131 2025-09-07 16:33:04 +08:00
f8c6887769 Notable day countdown 2025-09-07 16:30:36 +08:00
cd2a507b7f Account region settings 2025-09-07 16:00:30 +08:00
3cafce00a2 Windows auto update 2025-09-07 15:44:51 +08:00
837f3fbe98 👽 Update the update service to use Solsynth download source 2025-09-07 15:31:36 +08:00
ca7cc5d7ee 👽 Update auth challenge model for remote changes 2025-09-07 15:24:56 +08:00
ef2c14daa2 🐛 Fix image rendering 2025-09-07 14:20:00 +08:00
3a17837cc6 💄 Optimize cloud file rendering 2025-09-07 14:12:51 +08:00
2617a64acf 💄 Optimize post actions 2025-09-07 13:11:18 +08:00
afe1e12a3b 🐛 Some fixes 2025-09-07 13:00:59 +08:00
be80f5ff85 💄 Shadow on reblur button 2025-09-07 02:35:36 +08:00
3281d69eba Apply texas's pathc to reblur content 2025-09-07 02:34:51 +08:00
77b6ce9937 Post actions on post detail page 2025-09-07 02:31:57 +08:00
39275f61b5 🐛 Fix trackpack no longer able to scroll 2025-09-07 02:11:28 +08:00
72193ba8f3 Allow use mosue drag to scroll vertical lists 2025-09-07 02:09:07 +08:00
98dd9b6617 💄 Some changes to improve UX 2025-09-07 01:31:41 +08:00
a22b94a263 Call pod keep alive 2025-09-07 01:20:22 +08:00
9c75eafdb3 Call wakelock 2025-09-07 01:11:40 +08:00
28fda3d0c7 Publisher list on account 2025-09-07 01:05:49 +08:00
187c2ea43e ♻️ Refactor the profile and pub profile 2025-09-07 01:05:49 +08:00
ae7d967461 🐛 Fix some errors 2025-09-07 01:05:49 +08:00
1ce71f1fa1 🐛 Fix post shuffle 2025-09-07 01:05:48 +08:00
9b68808c77 🐛 Fix iOS NSE 2025-09-07 01:05:48 +08:00
Texas0295
99b7bf8199 fixup! data-saving: implement gate with bypass 2025-09-07 00:21:20 +08:00
Texas0295
eb9bb73c31 fixup! data-saving: implement gate with bypass 2025-09-06 19:55:35 +08:00
Texas0295
a8c3830d67 data-saving: implement gate with bypass
- Implement DataSavingGate util (previous commit was only the shell)
- Update ProfilePictureWidget to always load avatars via UniversalImage
  using fileId, bypassing CloudFileWidget and its data-saving check
- Keep larger media under data-saving control
- Add i18n strings for data-saving mode

Signed-off-by: Texas0295 <kimura@texas0295.top>
2025-09-06 14:14:00 +08:00
Texas0295
07a5a19141 settings: add Data Saving Mode toggle (UI & i18n only)
Signed-off-by: Texas0295 <kimura@texas0295.top>
2025-09-06 14:13:59 +08:00
ecc100ac45 Extended refresh indicator (keyboard based) 2025-09-06 13:52:20 +08:00
573b76d3ff 🍱 Update media offline placeholder
🐛 Fix image picker
2025-09-06 13:23:09 +08:00
f7dad5e419 Cache udid 2025-09-06 13:09:27 +08:00
9f2f1c0848 System notification for desktop and android 2025-09-06 12:59:23 +08:00
580d9fd979 🐛 Trying to make the macOS app do not quit after all windows closed 2025-09-06 11:53:22 +08:00
3b375abc09 Tray 2025-09-04 22:10:00 +08:00
c527b5e67c 🐛 Fix explore pagination 2025-09-04 00:55:37 +08:00
e9f09bbe54 Explore shuffle post 2025-09-04 00:52:02 +08:00
3aece9316c Able to temporary disable background image 2025-09-04 00:25:44 +08:00
a61c889c6c ⬆️ Upgrade flutter deps 2025-09-03 00:31:47 +08:00
0dd3221a56 🐛 Fix oidc on web close #175 2025-09-02 00:36:06 +08:00
66918521f8 More search filter 2025-09-02 00:01:36 +08:00
bb1846e462 🐛 Fix post creator style broke 2025-09-01 23:17:54 +08:00
a976a6eaf4 💄 Optimize the post item reaction made effect 2025-09-01 23:10:24 +08:00
4252f66fd3 💄 Optimize some designs 2025-09-01 23:05:11 +08:00
f2d780b48f 💄 Optimize of account profile card 2025-09-01 21:37:59 +08:00
300541f9bb ♻️ Replaced picker 2025-09-01 01:00:52 +08:00
43787bb813 💄 Optimize attachment previewer in editing 2025-09-01 00:45:35 +08:00
3417c51a3b Preview for SND files 2025-09-01 00:34:55 +08:00
f98e603e82 🐛 Dozens of bug fixes 2025-09-01 00:07:19 +08:00
c9b71701c8 🚀 Launch 3.2.0+129 2025-08-26 01:33:57 +08:00
28e98488f1 🌐 Localize new stuff 2025-08-26 01:24:58 +08:00
b4d476613e 🐛 Optimzation and bug fixes 2025-08-26 01:18:54 +08:00
b48a1aac44 Search messages!
♻️ Optimize messages loading, syncing
2025-08-26 01:05:30 +08:00
596d212593 🐛 Fix account name localization 2025-08-26 00:17:34 +08:00
54f290327e Copyable file ID 2025-08-26 00:08:50 +08:00
16f248ceab 💄 Optimize file saving 2025-08-26 00:03:43 +08:00
856d811187 🐛 Fix notification tap in system wide 2025-08-25 23:14:59 +08:00
d07b194c04 🐛 Fixes 2025-08-25 20:44:35 +08:00
2554b58be6 Show automated account in pfc 2025-08-25 20:31:43 +08:00
a627b5838e 👔 Disable pin reply 2025-08-25 19:57:30 +08:00
c479a9f381 Show social credits 2025-08-25 19:56:34 +08:00
02057e663b Real previewing chat 2025-08-25 19:36:48 +08:00
6501594100 Event dairy 2025-08-25 18:31:57 +08:00
c6599edc3d 💄 Serval changes to optimize UX 2025-08-25 18:03:50 +08:00
709a0620b6 Show pinned posts on realms, publishers 2025-08-25 17:09:24 +08:00
f9b2a96c7c Pin post 2025-08-25 16:55:06 +08:00
4dca6189cb 💄 Optimize post category subscribe loading state 2025-08-25 16:17:19 +08:00
c7f5b63fe5 Subscribe to category and tags 2025-08-25 16:15:51 +08:00
96c2f45c85 💄 Optimize articles page 2025-08-25 15:33:27 +08:00
300 changed files with 47024 additions and 13226 deletions

View File

@@ -14,13 +14,13 @@ The backend of the Solar Network is written in Go and is a microservices app. Th
## Commit Messages
We're using the gitmoji to clarify the reason and changes of the commit. To learn more about gitmoji, visit https://gitmoji.dev
We're using the gitmoji to clarify the reason and changes of the commit. To learn more about gitmoji, visit <https://gitmoji.dev>
All the commit message should follow `:[gitmoji]: <commit message>` syntax
## Translations & Localization
We're not accepting translation and localization improvements, or fixes on the GitHub or Solsynth Git Repository. If you want to contribute to those, please head to our Crowdin project: https://crowdin.com/project/solian
We're not accepting translation and localization improvements, or fixes on the GitHub or Solsynth Git Repository. If you want to contribute to those, please head to our Crowdin project: <https://crowdin.com/project/solian>
## New Features
@@ -28,9 +28,14 @@ To contribute new features, please create an issue or mention the feature you wa
## Bug Reports / Ask for help
Read the error message, check for the update (including pre-releases), and wiki before creating an issue. At the same time, be respectful and don't argue with our developers and contributors in the development chat or GitHub issue. Otherwise your issue may got deleted and your Solar Network Account may got a strike.
Read the error message, check for the update (including pre-releases), and wiki before creating an issue. At the same time, be respectful and don't argue with our developers and contributors in the development chat or GitHub issue. Otherwise your issue may got deleted and your Solar Network Account may got a strike.
## Styles of Code
Before you create a Pull Request, make sure your code has pass the `flutter analyze` check, if there is any notes, fix as much as possible, if there is no way to fix, do ignore.
When the code contains comments, use English. We do not any other language of comments existing in the codebase. It might confuse future contributors, cause the code hard to understand and maintaiance.
-----------
We appreciate every single commit you contributed. Let's work together and create a better Solar Network!

View File

@@ -62,4 +62,3 @@ If you want to build the release version, use the flutter build command. Learn m
```bash
flutter build <platform>
```

View File

@@ -24,12 +24,9 @@ android {
ndkVersion = "29.0.13113456"
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
isCoreLibraryDesugaringEnabled = true
}
kotlinOptions { jvmTarget = JavaVersion.VERSION_17.toString() }
defaultConfig {
applicationId = "dev.solsynth.solian"
// You can update the following values to match your application needs.
@@ -63,6 +60,8 @@ android {
}
dependencies {
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4")
implementation("com.google.android.material:material:1.12.0")
implementation("com.github.bumptech.glide:glide:4.16.0")
implementation("com.squareup.okhttp3:okhttp:5.1.0")
@@ -71,3 +70,17 @@ dependencies {
flutter {
source = "../.."
}
kotlin {
compilerOptions {
jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_21)
}
jvmToolchain(21)
}
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(21))
}
}

View File

@@ -51,6 +51,12 @@
<data android:scheme="http" android:host="solian.app" />
<data android:scheme="https" />
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="solian" />
</intent-filter>
<!-- Share Intent Filters -->
<intent-filter>

File diff suppressed because it is too large Load Diff

1079
assets/i18n/es-ES.json Normal file

File diff suppressed because it is too large Load Diff

1079
assets/i18n/ja-JP.json Normal file

File diff suppressed because it is too large Load Diff

1079
assets/i18n/ko-KR.json Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1079
assets/i18n/zh-OG.json Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -116,7 +116,7 @@
},
"postHasAttachments": {
"one": "{} 個附件",
"other": "{}個附件"
"other": "{} 個附件"
},
"edited": "已編輯",
"addVideo": "添加視頻",
@@ -668,7 +668,6 @@
"publisherFeatureDevelopDescription": "為你的開發者解鎖包括應用套件API 及更多開發功能。",
"publisherFeatureDevelopHint": "目前該功能還在開發中,你需要邀請才可解鎖。",
"learnMore": "瞭解更多",
"discoverWebArticles": "來自站外的文章",
"webArticlesStand": "文章亭",
"about": "關於",
"somethingWentWrong": "發生了一些錯誤",
@@ -691,8 +690,6 @@
"sharePostPhoto": "通過圖片分享帖子",
"wouldYouLikeToNavigateToChat": "你想要前往聊天頁面嗎?",
"abuseReports": "舉報",
"discoverRealms": "發現領域",
"discoverPublishers": "發現發佈者",
"membershipCancel": "取消會員訂閱",
"membershipCancelConfirm": "你確定要取消會員訂閱嗎?",
"membershipCancelHint": "你確定要取消會員訂閱嗎?你將不會再次被扣費。你的會員資格將在當前計費週期結束前保持有效。並且你將無法重新訂閱,直到當前訂閱結束。",
@@ -812,6 +809,159 @@
"one": "+{} 個文件被摺疊",
"other": "+{} 個文件被摺疊"
},
"pollQuestions": "問題",
"pollAnswerSubmitted": "投票答案已提交。",
"modifyAnswers": "修改答案",
"back": "返回",
"submit": "提交",
"pollOptionDefaultLabel": "選項1",
"pollUpdated": "投票已更新。",
"pollCreated": "投票已創建。",
"pollCreate": "創建投票",
"pollEdit": "編輯投票",
"pollPreviewJsonDebug": "調試預覽",
"pollTitleRequired": "標題不可為空",
"pollEndDateOptional": "結束日期和時間 (可選)",
"notSet": "未設定",
"pick": "選擇",
"clear": "清除",
"questions": "問題",
"pollAddQuestion": "添加問題",
"pollQuestionTypeSingleChoice": "單選框",
"pollQuestionTypeMultipleChoice": "多選框",
"pollQuestionTypeFreeText": "自由文本",
"pollQuestionTypeYesNo": "是 / 不是",
"pollQuestionTypeRating": "評分",
"pollNoQuestionsYet": "尚未有問題",
"pollNoQuestionsHint": "使用「添加問題」開始建立您的投票。",
"pollDebugPreview": "調試預覽",
"pollUntitledQuestion": "無標題問題",
"moveUp": "往上移動",
"moveDown": "往下移動",
"required": "必需的",
"pollQuestionTitle": "問題標題",
"pollQuestionTitleRequired": "問題標題是必需的",
"pollQuestionDescriptionOptional": "問題描述(選填)",
"options": "選項",
"pollAddOption": "添加選項",
"pollOptionLabel": "選項標籤",
"pollLongTextAnswerPreview": "長文本答案 (預覽)",
"pollShortTextAnswerPreview": "短文本答案 (預覽)",
"award": "讚賞",
"awardPost": "讚賞帖子",
"awardMessage": "消息",
"awardMessageHint": "輸入您的讚賞消息...",
"awardAttitude": "態度",
"awardAttitudePositive": "積極",
"awardAttitudeNegative": "消极",
"awardAmount": "金額",
"awardAmountHint": "輸入金額……",
"awardAmountRequired": "「金額」為必填字段",
"awardAmountInvalid": "請輸入有效金額",
"awardMessageTooLong": "消息太長最多4096個字符",
"awardSuccess": "獎勵已成功發送!",
"awardSubmit": "讚賞",
"awardPostPreview": "帖子預覽",
"awardNoContent": "暫無內容",
"awardByPublisher": "由 {} 發表",
"awardBenefits": "讚賞福利",
"awardBenefitsDescription": "為該帖子授予獎勵可以提升其價值和曝光度。價值更高的帖子更有可能在社區中被推薦和突出顯示。",
"checkInResultLevel5": "生日快樂 🥳",
"region": "區域",
"accountRegionHint": "這個區域將用於內容傳遞和本地化。",
"settingsCustomFontsHelper": "使用逗號分隔。",
"settingsBackgroundImageEnable": "顯示背景圖片",
"settingsDataSavingMode": "低數據模式",
"dataSavingHint": "低數據模式",
"postTypePost": "帖子",
"searchDrafts": "搜尋草稿……",
"noSearchResults": "無搜尋結果",
"contactMethodMakePublic": "設為公開",
"contactMethodMakePrivate": "設定為僅自己可見",
"contactMethodPublic": "公開",
"contactMethodPrivate": "私密",
"discoverRealms": "發現領域",
"discoverPublishers": "發現發佈者",
"discoverShuffledPost": "隨機帖子",
"projects": "項目",
"noProjects": "未找到項目。",
"deleteProject": "刪除項目",
"deleteProjectHint": "確定要刪除此項目嗎?此操作無法撤銷。",
"createProject": "新建專案",
"editProject": "編輯項目",
"projectDetails": "專案描述",
"createBot": "創建機器人",
"bots": "機器人",
"noBots": "還沒有機器人。",
"deleteBotHint": "您確定要刪除這個機器人嗎?此操作無法撤銷。",
"deleteBot": "刪除機器人",
"discoverWebArticles": "來自站外的文章",
"messageJumpNotLoaded": "引用的訊息未加載,無法跳轉到該訊息。",
"postUnlinkRealm": "未連結到領域",
"postSlug": "別名",
"postSlugHint": "這個別名可以用於在網頁通過 URL 瀏覽到你的帖子,它應該在同一發布者中是唯一。",
"attachmentOnDevice": "離線",
"attachmentOnCloud": "在線",
"attachments": "附件",
"publisherCollabInvitation": "協作邀請",
"publisherCollabInvitationCount": {
"zero": "無邀請",
"one": "{} 個可用邀請",
"other": "{} 個可用邀請"
},
"failedToLoadUserInfo": "無法加載用戶資訊",
"failedToLoadUserInfoNetwork": "看起來是網絡問題,您可以點擊下面的按鈕再試一次。",
"failedToLoadUserInfoUnauthorized": "看起來您的會話已經登出或不再可用,如果您想的話,您仍然可以嘗試再次獲取用戶資訊。",
"okay": "好的",
"postDetail": "帖子詳情",
"postCount": {
"zero": "沒有帖子",
"one": "{} 帖子",
"other": "{} 帖子"
},
"mimeType": "類型",
"fileSize": "文件大小",
"fileHash": "文件哈希",
"exifData": "EXIF 數據",
"postShuffle": "隨機帖子",
"leveling": "等級",
"levelingHistory": "經驗記錄",
"stellarProgram": "恆星計畫",
"socialCredits": "社會信用點",
"credits": "信用",
"creditsStatus": "積分狀態",
"socialCreditsDescription": "社會信用是 Solar Network 評價用戶的一種方式。它基於用戶的行為和互動來計算。以 100 分為基準,分數越高表示用戶在社區中的信譽越好。分數會隨著時間的推移而變化,反映用戶的最新行為。信用等級高的用戶可以享受到更多的福利,反之的用戶部分功能可能受到限制。",
"socialCreditsLevelPoor": "糟糕",
"socialCreditsLevelNormal": "正常",
"socialCreditsLevelGood": "良好",
"socialCreditsLevelExcellent": "優秀",
"orderByPopularity": "按熱度排序",
"orderByReleaseDate": "按發佈日期排序",
"editBot": "編輯機器人",
"botAutomatedBy": "由 {} 自動化",
"botDetails": "機器人描述",
"overview": "概述",
"keys": "密鑰",
"botNotFound": "機器人未找到。",
"newBotKey": "新建密鑰",
"newBotKeyHint": "輸入新密鑰的名稱,密鑰只會顯示一次。",
"revokeBotKey": "撤銷密鑰",
"revokeBotKeyHint": "你確定要撤銷這個密鑰?這個操作無法撤回,所有使用該密鑰的應用程式會停止工作。",
"noBotKeys": "機器人未找到。",
"revoke": "撤銷",
"keyName": "密鑰名稱",
"newKeyGenerated": "新密鑰已生成",
"copyKeyHint": "請安全地保存該密鑰,你不會再次看到它。",
"rotateKey": "旋轉密鑰",
"rotateBotKey": "旋轉密鑰",
"rotateBotKeyHint": "你確認要旋轉這個密鑰?久的密鑰會立即失效,該操作無法撤銷。",
"webFeedArticleCount": {
"zero": "無文章",
"one": "{} 文章",
"other": "{} 文章"
},
"webFeedSubscribed": "你已經訂閱了這個來源",
"webFeedUnsubscribed": "你已經取消訂閱這個來源",
"appDetails": "應用程式詳情",
"secrets": "密鑰",
"appNotFound": "找不到應用程式。",
@@ -823,5 +973,109 @@
"newSecretGenerated": "已產生新密鑰",
"copySecretHint": "請複製此密鑰並將其存放在安全的地方。您將無法再次看到它。",
"expiresIn": "過期時間(秒)",
"isOidc": "OIDC 相容"
}
"isOidc": "OIDC 相容",
"pinPost": "置頂帖子",
"unpinPost": "取消置頂",
"pinnedPost": "已置顶",
"publisherPage": "發布者頁面",
"realmPage": "領域頁面",
"replyPage": "回覆頁面",
"pinPostPublisherHint": "將這篇文章置顶到您的發佈者頁面",
"pinPostRealmHint": "將這篇文章置顶到領域頁面",
"pinPostRealmDisabledHint": "這個帖子不屬於任何領域",
"pinPostReplyHint": "將這篇文章置顶到回覆頁面",
"pinPostReplyDisabledHint": "這篇帖子不是回覆",
"pin": "置顶",
"unpinPostHint": "你確定要取消置顶這篇帖子嗎?",
"all": "所有",
"statusPresent": "至今",
"accountAutomated": "機器人",
"chatBreakClearButton": "清除",
"chatBreak5m": "5 分鐘",
"chatBreak10m": "10 分鐘",
"chatBreak15m": "15 分鐘",
"chatBreak30m": "30 分鐘",
"chatBreakCustomMinutes": "自訂(分鐘)",
"errorGeneric": "錯誤:{}",
"searchMessages": "搜尋消息",
"messagesCount": "{} 消息",
"dotSeparator": ".",
"roleValidationHint": "成員角色必須設置在0到100之間",
"searchMessagesHint": "搜尋消息…",
"searchLinks": "連結",
"searchAttachments": "附件",
"noMessagesFound": "未找到消息",
"openInBrowser": "在瀏覽器打開",
"highlightPost": "精選帖子",
"filters": "過濾器",
"apply": "應用",
"pubName": "題目名稱",
"realm": "領域",
"shuffle": "隨機",
"pinned": "已置顶",
"noResultsFound": "未找到結果",
"toggleFilters": "切換篩檢器",
"notableDayNext": "距離 {} 還有",
"expandPoll": "展開投票",
"collapsePoll": "摺叠投票",
"embedView": "嵌入視圖",
"embedUri": "嵌入URL",
"aspectRatio": "縱橫比",
"renderer": "渲染器",
"addEmbed": "添加嵌入",
"editEmbed": "編輯嵌入",
"deleteEmbed": "刪除嵌入",
"deleteEmbedConfirm": "您確定要刪除這個嵌入嗎?",
"currentEmbed": "當前嵌入",
"noEmbed": "尚未嵌入",
"save": "保存",
"webView": "網頁視圖",
"settingsDefaultPool": "預設檔案池",
"settingsDefaultPoolHelper": "選擇文件上傳的默認儲存池",
"uploadFile": "上傳檔案",
"authDeviceChallenges": "設備活動",
"authDeviceHint": "向左滑動以編輯標籤,向右滑動以登出設備。",
"settingsMessageDisplayStyle": "訊息顯示樣式",
"auto": "自動",
"manual": "手動",
"iframeCode": "Iframe 代碼",
"iframeCodeHint": "<iframe src=\"...\" width=\"...\" height=\"...\">",
"parseIframe": "解析 Iframe",
"messageActions": "消息選項",
"viewEmbedLoadHint": "點擊以載入",
"levelingStage1": "新手",
"levelingStage2": "學徒",
"levelingStage3": "學徒工",
"levelingStage4": "熟練",
"levelingStage5": "專家",
"levelingStage6": "大師",
"levelingStage7": "宗師",
"levelingStage8": "傳說",
"levelingStage9": "神話",
"levelingStage10": "不朽",
"levelingStage11": "神聖",
"levelingStage12": "超凡",
"uploadAttachment": "上傳附件",
"attachmentPreview": "附件預覽",
"selectPool": "選擇檔案池",
"choosePool": "選擇一個檔案池",
"errorLoadingPools": "加載池時出錯",
"quotaCostInfo": "這次上傳將消耗 {} 配額點",
"uploadConstraints": "上傳限制",
"fileSizeExceeded": "檔案大小超過了 {} 的最大限制",
"fileTypeNotAccepted": "該文件類型不被此池接受",
"files": "附件",
"confirmDeleteFile": "你確定要刪除這個文件嗎?",
"deleteFile": "刪除文件",
"failedToDeleteFile": "刪除文件失敗",
"drive": "雲盤",
"allPools": "全部的池",
"includeRecycled": "包含已回收文件",
"confirmDeleteRecycledFiles": "您確定要刪除所有回收的檔案嗎?",
"deleteRecycledFiles": "刪除已回收檔案",
"recycledFilesDeleted": "已回收檔案刪除成功",
"failedToDeleteRecycledFiles": "已回收檔案刪除失敗",
"upload": "上傳",
"postCompose": "撰寫帖子",
"postPublish": "發佈帖子"
}

View File

@@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" width="192" height="192" fill="none">
<path stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="12"
d="M54 147h86" />
<path stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="10"
d="M57 111s-2-4.5-2-10m22 22s-4 7-11 4m9-22s-2-4.5-2-10" />
<path stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="12"
d="M54 147a32 32 0 0 1-11.999-61.665A39 39 0 0 1 81 46m59 101a30 30 0 0 0 29.933-28" />
<circle cx="132" cy="75" r="4" stroke="#fff" stroke-linecap="round" stroke-linejoin="round"
stroke-width="8" />
<path stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="10"
d="M112.5 41.217C100.843 47.961 93 60.564 93 75c0 6.375 1.53 12.393 4.242 17.707m69.513-35.419A38.84 38.84 0 0 1 171 75c0 14.433-7.84 27.034-19.493 33.779m-.793-43.317A20.9 20.9 0 0 1 153 75c0 7.77-4.221 14.556-10.495 18.188m-21.003-36.38C115.224 60.44 111 67.226 111 75a20.9 20.9 0 0 0 2.284 9.533" />
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 461 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 307 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 668 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 666 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 623 KiB

View File

@@ -5,3 +5,7 @@ targets:
options:
explicit_to_json: true
field_rename: snake
drift_dev:
options:
databases:
app_database: lib/database/drift_db.dart

File diff suppressed because one or more lines are too long

View File

@@ -21,6 +21,6 @@
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>12.0</string>
<string>13.0</string>
</dict>
</plist>

View File

@@ -1,5 +1,7 @@
PODS:
- Alamofire (5.10.2)
- app_links (6.4.1):
- Flutter
- connectivity_plus (0.0.1):
- Flutter
- croppy (0.0.1):
@@ -40,83 +42,85 @@ PODS:
- file_picker (0.0.1):
- DKImagePickerController/PhotoGallery
- Flutter
- Firebase/CoreOnly (12.0.0):
- FirebaseCore (~> 12.0.0)
- Firebase/Crashlytics (12.0.0):
- file_saver (0.0.1):
- Flutter
- Firebase/CoreOnly (12.2.0):
- FirebaseCore (~> 12.2.0)
- Firebase/Crashlytics (12.2.0):
- Firebase/CoreOnly
- FirebaseCrashlytics (~> 12.0.0)
- Firebase/Messaging (12.0.0):
- FirebaseCrashlytics (~> 12.2.0)
- Firebase/Messaging (12.2.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 12.0.0)
- firebase_analytics (12.0.0):
- FirebaseMessaging (~> 12.2.0)
- firebase_analytics (12.0.2):
- firebase_core
- FirebaseAnalytics (= 12.0.0)
- FirebaseAnalytics (= 12.2.0)
- Flutter
- firebase_core (4.0.0):
- Firebase/CoreOnly (= 12.0.0)
- firebase_core (4.1.1):
- Firebase/CoreOnly (= 12.2.0)
- Flutter
- firebase_crashlytics (5.0.0):
- Firebase/Crashlytics (= 12.0.0)
- firebase_crashlytics (5.0.2):
- Firebase/Crashlytics (= 12.2.0)
- firebase_core
- Flutter
- firebase_messaging (16.0.0):
- Firebase/Messaging (= 12.0.0)
- firebase_messaging (16.0.2):
- Firebase/Messaging (= 12.2.0)
- firebase_core
- Flutter
- FirebaseAnalytics (12.0.0):
- FirebaseAnalytics/Default (= 12.0.0)
- FirebaseCore (~> 12.0.0)
- FirebaseInstallations (~> 12.0.0)
- FirebaseAnalytics (12.2.0):
- FirebaseAnalytics/Default (= 12.2.0)
- FirebaseCore (~> 12.2.0)
- FirebaseInstallations (~> 12.2.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)
- FirebaseAnalytics/Default (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseInstallations (~> 12.2.0)
- GoogleAppMeasurement/Default (= 12.2.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)
- FirebaseCore (12.2.0):
- FirebaseCoreInternal (~> 12.2.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/Logger (~> 8.1)
- FirebaseCoreExtension (12.0.0):
- FirebaseCore (~> 12.0.0)
- FirebaseCoreInternal (12.0.0):
- FirebaseCoreExtension (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseCoreInternal (12.2.0):
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- FirebaseCrashlytics (12.0.0):
- FirebaseCore (~> 12.0.0)
- FirebaseInstallations (~> 12.0.0)
- FirebaseRemoteConfigInterop (~> 12.0.0)
- FirebaseSessions (~> 12.0.0)
- FirebaseCrashlytics (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseInstallations (~> 12.2.0)
- FirebaseRemoteConfigInterop (~> 12.2.0)
- FirebaseSessions (~> 12.2.0)
- GoogleDataTransport (~> 10.1)
- GoogleUtilities/Environment (~> 8.1)
- nanopb (~> 3.30910.0)
- PromisesObjC (~> 2.4)
- FirebaseInstallations (12.0.0):
- FirebaseCore (~> 12.0.0)
- FirebaseInstallations (12.2.0):
- FirebaseCore (~> 12.2.0)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
- PromisesObjC (~> 2.4)
- FirebaseMessaging (12.0.0):
- FirebaseCore (~> 12.0.0)
- FirebaseInstallations (~> 12.0.0)
- FirebaseMessaging (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseInstallations (~> 12.2.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)
- FirebaseRemoteConfigInterop (12.2.0)
- FirebaseSessions (12.2.0):
- FirebaseCore (~> 12.2.0)
- FirebaseCoreExtension (~> 12.2.0)
- FirebaseInstallations (~> 12.2.0)
- GoogleDataTransport (~> 10.1)
- GoogleUtilities/Environment (~> 8.1)
- GoogleUtilities/UserDefaults (~> 8.1)
@@ -134,6 +138,8 @@ PODS:
- OrderedSet (~> 6.0.3)
- flutter_keyboard_visibility (0.0.1):
- Flutter
- flutter_local_notifications (0.0.1):
- Flutter
- flutter_native_splash (2.4.3):
- Flutter
- flutter_platform_alert (0.0.1):
@@ -145,33 +151,33 @@ PODS:
- flutter_udid (0.0.1):
- Flutter
- SAMKeychain
- flutter_webrtc (1.0.0):
- flutter_webrtc (1.2.0):
- Flutter
- WebRTC-SDK (= 137.7151.02)
- WebRTC-SDK (= 137.7151.04)
- gal (1.0.0):
- Flutter
- FlutterMacOS
- GoogleAdsOnDeviceConversion (2.1.0):
- GoogleAdsOnDeviceConversion (2.3.0):
- GoogleUtilities/Logger (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- nanopb (~> 3.30910.0)
- GoogleAppMeasurement/Core (12.0.0):
- GoogleAppMeasurement/Core (12.2.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)
- GoogleAppMeasurement/Default (12.2.0):
- GoogleAdsOnDeviceConversion (= 2.3.0)
- GoogleAppMeasurement/Core (= 12.2.0)
- GoogleAppMeasurement/IdentitySupport (= 12.2.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)
- GoogleAppMeasurement/IdentitySupport (12.2.0):
- GoogleAppMeasurement/Core (= 12.2.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
@@ -211,11 +217,11 @@ PODS:
- Flutter
- irondash_engine_context (0.0.1):
- Flutter
- Kingfisher (8.5.0)
- Kingfisher (8.6.0)
- livekit_client (2.5.0):
- Flutter
- flutter_webrtc
- WebRTC-SDK (= 137.7151.02)
- WebRTC-SDK (= 137.7151.04)
- local_auth_darwin (0.0.1):
- Flutter
- FlutterMacOS
@@ -248,9 +254,9 @@ PODS:
- record_ios (1.1.0):
- Flutter
- SAMKeychain (1.5.3)
- SDWebImage (5.21.1):
- SDWebImage/Core (= 5.21.1)
- SDWebImage/Core (5.21.1)
- SDWebImage (5.21.3):
- SDWebImage/Core (= 5.21.3)
- SDWebImage/Core (5.21.3)
- share_plus (0.0.1):
- Flutter
- shared_preferences_foundation (0.0.1):
@@ -289,20 +295,24 @@ PODS:
- super_native_extensions (0.0.1):
- Flutter
- SwiftyGif (5.4.5)
- syncfusion_flutter_pdfviewer (0.0.1):
- Flutter
- url_launcher_ios (0.0.1):
- Flutter
- volume_controller (0.0.1):
- Flutter
- wakelock_plus (0.0.1):
- Flutter
- WebRTC-SDK (137.7151.02)
- WebRTC-SDK (137.7151.04)
DEPENDENCIES:
- Alamofire
- app_links (from `.symlinks/plugins/app_links/ios`)
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
- 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`)
@@ -311,6 +321,7 @@ DEPENDENCIES:
- 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_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
- flutter_platform_alert (from `.symlinks/plugins/flutter_platform_alert/ios`)
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
@@ -338,6 +349,7 @@ DEPENDENCIES:
- sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
- sqlite3_flutter_libs (from `.symlinks/plugins/sqlite3_flutter_libs/darwin`)
- super_native_extensions (from `.symlinks/plugins/super_native_extensions/ios`)
- syncfusion_flutter_pdfviewer (from `.symlinks/plugins/syncfusion_flutter_pdfviewer/ios`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
- volume_controller (from `.symlinks/plugins/volume_controller/ios`)
- wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
@@ -373,6 +385,8 @@ SPEC REPOS:
- WebRTC-SDK
EXTERNAL SOURCES:
app_links:
:path: ".symlinks/plugins/app_links/ios"
connectivity_plus:
:path: ".symlinks/plugins/connectivity_plus/ios"
croppy:
@@ -381,6 +395,8 @@ 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:
@@ -397,6 +413,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/flutter_inappwebview_ios/ios"
flutter_keyboard_visibility:
:path: ".symlinks/plugins/flutter_keyboard_visibility/ios"
flutter_local_notifications:
:path: ".symlinks/plugins/flutter_local_notifications/ios"
flutter_native_splash:
:path: ".symlinks/plugins/flutter_native_splash/ios"
flutter_platform_alert:
@@ -449,6 +467,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/sqlite3_flutter_libs/darwin"
super_native_extensions:
:path: ".symlinks/plugins/super_native_extensions/ios"
syncfusion_flutter_pdfviewer:
:path: ".symlinks/plugins/syncfusion_flutter_pdfviewer/ios"
url_launcher_ios:
:path: ".symlinks/plugins/url_launcher_ios/ios"
volume_controller:
@@ -458,46 +478,49 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
Alamofire: 7193b3b92c74a07f85569e1a6c4f4237291e7496
app_links: 3dbc685f76b1693c66a6d9dd1e9ab6f73d97dc0a
connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd
croppy: 979e8ddc254f4642bffe7d52dc7193354b27ba30
device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be
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
file_saver: 6cdbcddd690cb02b0c1a0c225b37cd805c2bf8b6
Firebase: 26f6f8d460603af3df970ad505b16b15f5e2e9a1
firebase_analytics: 8c78ce6224e0623152379d6cc7ef3d9098477b7e
firebase_core: dfc4bd142bee4bc53a5d482397ca322c2dd3165d
firebase_crashlytics: e55dcf895eed0dd87c447dd5aff8db7f1bb8bbdb
firebase_messaging: 38c66c1184695b0c87abe51d40fc590718abed1a
FirebaseAnalytics: e04e23bc070e3014aa5cf4980f9df7ce5cd79ec8
FirebaseCore: 311c48a147ad4a0ab7febbaed89e8025c67510cd
FirebaseCoreExtension: 73af080c22a2f7b44cefa391dc08f7e4ee162cb5
FirebaseCoreInternal: 56ea29f3dad2894f81b060f706f9d53509b6ed3b
FirebaseCrashlytics: f83cbf176d5c637ade108c0aacf1ccbd5ec499bf
FirebaseInstallations: 3e884b01feabdf67582a80f3250425a00979b4ed
FirebaseMessaging: 43ec73bbfedd0c385a849bb91593ab4ad4b9e48e
FirebaseRemoteConfigInterop: 0896fd52ab72586a355c8f389ff85aaa9e5375e1
FirebaseSessions: f4692789e770bec66ce17d772c0e9561c4f11737
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
flutter_app_update: 816fdb2e30e4832a7c45e3f108d391c42ef040a9
flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
flutter_keyboard_visibility: 4625131e43015dbbe759d9b20daaf77e0e3f6619
flutter_local_notifications: a5a732f069baa862e728d839dd2ebb904737effb
flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf
flutter_platform_alert: bf3b5fcd4ac14bd637e20527e9c471633071afd3
flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13
flutter_timezone: 7c838e17ffd4645d261e87037e5bebf6d38fe544
flutter_udid: f7c3884e6ec2951efe4f9de082257fc77c4d15e9
flutter_webrtc: 6f7da106613d52ade777d5b4875a43f48c28b457
flutter_webrtc: c3e21fc0dcd9d8eb246ae4d5256fcbeb2f5ecd22
gal: baecd024ebfd13c441269ca7404792a7152fde89
GoogleAdsOnDeviceConversion: 2be6297a4f048459e0ae17fad9bfd2844e10cf64
GoogleAppMeasurement: 8f6ab04ad6ae493b53fcf56bd26323fb2f1384f3
GoogleAdsOnDeviceConversion: 9090c435cde08903e8dd1ba2c77fbec9e46d9afe
GoogleAppMeasurement: 09f341dfa8527d1612a09cbfe809a242c0b737af
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
irondash_engine_context: 8e58ca8e0212ee9d1c7dc6a42121849986c88486
Kingfisher: ff0d31a1f07bdff6a1ebb3ba08b8e6e567b6500c
livekit_client: e3b79b99405428aac439b6b76a254cd9a11dbbfb
local_auth_darwin: d2e8c53ef0c4f43c646462e3415432c4dab3ae19
Kingfisher: 64278f126a815d0e2d391cdf71311b85882c4de0
livekit_client: a6f5fa86ac28ccd7ded53626a5379961db311ab4
local_auth_darwin: c3ee6cce0a8d56be34c8ccb66ba31f7f180aaebb
media_kit_libs_ios_video: 5a18affdb97d1f5d466dc79988b13eff6c5e2854
media_kit_video: 1746e198cb697d1ffb734b1d05ec429d1fcd1474
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
@@ -512,7 +535,7 @@ SPEC CHECKSUMS:
receive_sharing_intent: 222384f00ffe7e952bbfabaa9e3967cb87e5fe00
record_ios: f75fa1d57f840012775c0e93a38a7f3ceea1a374
SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c
SDWebImage: f29024626962457f3470184232766516dee8dfea
SDWebImage: 16309af6d214ba3f77a7c6f6fdda888cb313a50a
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
sign_in_with_apple: c5dcc141574c8c54d5ac99dd2163c0c72ad22418
@@ -521,10 +544,11 @@ SPEC CHECKSUMS:
sqlite3_flutter_libs: 83f8e9f5b6554077f1d93119fe20ebaa5f3a9ef1
super_native_extensions: b763c02dc3a8fd078389f410bf15149179020cb4
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
syncfusion_flutter_pdfviewer: 90dc48305d2e33d4aa20681d1e98ddeda891bc14
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
volume_controller: 3657a1f65bedb98fa41ff7dc5793537919f31b12
wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556
WebRTC-SDK: d20de357dcbf7c9696b124b39f3ff62125107e4b
WebRTC-SDK: 40d4f5ba05cadff14e4db5614aec402a633f007e
PODFILE CHECKSUM: c818292390b02fa379036ea099713a332bd7193f

View File

@@ -566,7 +566,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n";
};
4815E0A19398E51078F4160D /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
@@ -853,7 +853,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
@@ -883,6 +883,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = dev.solsynth.solian;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ENABLE_EXPLICIT_MODULES = "$(SWIFT_USE_INTEGRATED_DRIVER)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
@@ -897,6 +898,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = dev.solsynth.solian.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -915,6 +917,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = dev.solsynth.solian.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -931,6 +934,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = dev.solsynth.solian.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -1078,7 +1082,7 @@
INFOPLIST_FILE = SolianShareExtension/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = SolianShareExtension;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -1093,6 +1097,7 @@
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_ENABLE_EXPLICIT_MODULES = NO;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -1121,7 +1126,7 @@
INFOPLIST_FILE = SolianShareExtension/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = SolianShareExtension;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -1134,6 +1139,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_ENABLE_EXPLICIT_MODULES = NO;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
@@ -1161,7 +1167,7 @@
INFOPLIST_FILE = SolianShareExtension/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = SolianShareExtension;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -1174,6 +1180,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_ENABLE_EXPLICIT_MODULES = NO;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
@@ -1348,7 +1355,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -1399,7 +1406,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
@@ -1431,6 +1438,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = dev.solsynth.solian;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ENABLE_EXPLICIT_MODULES = "$(SWIFT_USE_INTEGRATED_DRIVER)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
@@ -1459,6 +1467,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = dev.solsynth.solian;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ENABLE_EXPLICIT_MODULES = "$(SWIFT_USE_INTEGRATED_DRIVER)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";

View File

@@ -12,7 +12,7 @@ import UIKit
UNUserNotificationCenter.current().delegate = notifyDelegate
let replyableMessageCategory = UNNotificationCategory(
identifier: "REPLYABLE_MESSAGE",
identifier: "CHAT_MESSAGE",
actions: [
UNTextInputNotificationAction(
identifier: "reply_action",

View File

@@ -36,6 +36,14 @@
<string>ShareMedia-$(PRODUCT_BUNDLE_IDENTIFIER)</string>
</array>
</dict>
<dict>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>CFBundleURLSchemes</key>
<array>
<string>solian</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>

View File

@@ -60,8 +60,6 @@ class NotificationService: UNNotificationServiceExtension {
let pfpIdentifier = meta["pfp"] as? String
content.categoryIdentifier = "REPLYABLE_MESSAGE"
let metaCopy = meta as? [String: Any] ?? [:]
let pfpUrl = pfpIdentifier != nil ? getAttachmentUrl(for: pfpIdentifier!) : nil
@@ -90,7 +88,12 @@ class NotificationService: UNNotificationServiceExtension {
let intent = self.createMessageIntent(with: sender, meta: metaCopy, body: content.body)
self.donateInteraction(for: intent)
let updatedContent = try? request.content.updating(from: intent)
self.contentHandler?(updatedContent ?? content)
content.categoryIdentifier = "CHAT_MESSAGE"
if let updatedContent = updatedContent {
self.contentHandler?(updatedContent)
} else {
self.contentHandler?(content)
}
})
}

View File

@@ -1,6 +1,7 @@
import 'package:drift/drift.dart';
import 'package:drift/wasm.dart';
import 'package:island/database/drift_db.dart';
import 'package:island/talker.dart';
AppDatabase constructDb() {
return AppDatabase(connectOnWeb());
@@ -9,12 +10,17 @@ AppDatabase constructDb() {
DatabaseConnection connectOnWeb() {
return DatabaseConnection.delayed(
Future(() async {
final result = await WasmDatabase.open(
databaseName: 'solar_network_data',
sqlite3Uri: Uri.parse('sqlite3.wasm'),
driftWorkerUri: Uri.parse('drift_worker.dart.js'),
);
return result.resolvedExecutor;
try {
final result = await WasmDatabase.open(
databaseName: 'solar_network_data',
sqlite3Uri: Uri.parse('sqlite3.wasm'),
driftWorkerUri: Uri.parse('drift_worker.dart.js'),
);
return result.resolvedExecutor;
} catch (e, stackTrace) {
talker.error('Failed to open WASM database...', e, stackTrace);
rethrow;
}
}),
);
}

View File

@@ -2,8 +2,15 @@ import 'package:drift/drift.dart';
class PostDrafts extends Table {
TextColumn get id => text()();
TextColumn get post => text()(); // Store SnPost model as JSON string
// Searchable fields stored separately for performance
TextColumn get title => text().nullable()();
TextColumn get description => text().nullable()();
TextColumn get content => text().nullable()();
IntColumn get visibility => integer().withDefault(const Constant(0))();
IntColumn get type => integer().withDefault(const Constant(0))();
DateTimeColumn get lastModified => dateTime()();
// Full post data stored as JSON for complete restoration
TextColumn get postData => text()();
@override
Set<Column> get primaryKey => {id};

View File

@@ -12,7 +12,7 @@ class AppDatabase extends _$AppDatabase {
AppDatabase(super.e);
@override
int get schemaVersion => 4;
int get schemaVersion => 7;
@override
MigrationStrategy get migration => MigrationStrategy(
@@ -21,16 +21,97 @@ class AppDatabase extends _$AppDatabase {
},
onUpgrade: (Migrator m, int from, int to) async {
if (from < 2) {
// Add isRead column with default value false
await m.addColumn(chatMessages, chatMessages.isRead);
// Add isDeleted column with default value false
await m.addColumn(chatMessages, chatMessages.isDeleted);
}
if (from < 4) {
// Drop old draft tables if they exist
await m.createTable(postDrafts);
}
if (from < 6) {
// Migrate from old schema to new schema with separate searchable fields
await _migrateToVersion6(m);
}
if (from < 7) {
// Add new columns from SnChatMessage, ignore if they already exist
final columnsToAdd = [
chatMessages.updatedAt,
chatMessages.deletedAt,
chatMessages.type,
chatMessages.meta,
chatMessages.membersMentioned,
chatMessages.editedAt,
chatMessages.attachments,
chatMessages.reactions,
chatMessages.repliedMessageId,
chatMessages.forwardedMessageId,
];
for (final column in columnsToAdd) {
try {
await m.addColumn(chatMessages, column);
} catch (e) {
// Column already exists, skip
}
}
}
},
);
Future<void> _migrateToVersion6(Migrator m) async {
// Rename existing table to old if it exists
try {
await customStatement(
'ALTER TABLE post_drafts RENAME TO post_drafts_old',
);
} catch (e) {
// Table might not exist
}
// Drop the table
await customStatement('DROP TABLE IF EXISTS post_drafts');
// Create new table
await m.createTable(postDrafts);
// Migrate existing data if any
try {
final oldDrafts =
await customSelect(
'SELECT id, post, lastModified FROM post_drafts_old',
readsFrom: {postDrafts},
).get();
for (final row in oldDrafts) {
final postJson = row.read<String>('post');
final id = row.read<String>('id');
final lastModified = row.read<DateTime>('lastModified');
if (postJson.isNotEmpty) {
final post = SnPost.fromJson(jsonDecode(postJson));
await into(postDrafts).insert(
PostDraftsCompanion(
id: Value(id),
title: Value(post.title),
description: Value(post.description),
content: Value(post.content),
visibility: Value(post.visibility),
type: Value(post.type),
lastModified: Value(lastModified),
postData: Value(postJson),
),
);
}
}
// Drop old table
await customStatement('DROP TABLE IF EXISTS post_drafts_old');
} catch (e) {
// If migration fails, just recreate the table
await m.createTable(postDrafts);
}
}
// Methods for chat messages
Future<List<ChatMessage>> getMessagesForRoom(
String roomId, {
@@ -58,28 +139,70 @@ class AppDatabase extends _$AppDatabase {
)).write(ChatMessagesCompanion(status: Value(status)));
}
Future<int> markMessageAsRead(String id) {
return (update(chatMessages)..where(
(m) => m.id.equals(id),
)).write(ChatMessagesCompanion(isRead: const Value(true)));
}
Future<int> deleteMessage(String id) {
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, {
bool? withAttachments,
}) async {
var selectStatement = select(chatMessages)
..where((m) => m.roomId.equals(roomId));
if (query.isNotEmpty) {
final searchTerm = '%$query%';
selectStatement =
selectStatement..where(
(m) =>
m.content.like(searchTerm) |
m.meta.like(searchTerm) |
m.attachments.like(searchTerm) |
m.type.like(searchTerm),
);
}
if (withAttachments == true) {
selectStatement =
selectStatement..where((m) => m.attachments.equals('[]').not());
}
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) {
final remote = message.toRemoteMessage();
return ChatMessagesCompanion(
id: Value(message.id),
roomId: Value(message.roomId),
senderId: Value(message.senderId),
content: Value(message.toRemoteMessage().content),
content: Value(remote.content),
nonce: Value(message.nonce),
data: Value(jsonEncode(message.data)),
createdAt: Value(message.createdAt),
status: Value(message.status),
isRead: Value(message.isRead),
updatedAt: Value(remote.updatedAt),
deletedAt: Value(remote.deletedAt),
type: Value(remote.type),
meta: Value(remote.meta),
membersMentioned: Value(remote.membersMentioned),
editedAt: Value(remote.editedAt),
attachments: Value(remote.attachments.map((e) => e.toJson()).toList()),
reactions: Value(remote.reactions.map((e) => e.toJson()).toList()),
repliedMessageId: Value(remote.repliedMessageId),
forwardedMessageId: Value(remote.forwardedMessageId),
);
}
@@ -93,7 +216,18 @@ class AppDatabase extends _$AppDatabase {
createdAt: dbMessage.createdAt,
status: dbMessage.status,
nonce: dbMessage.nonce,
isRead: dbMessage.isRead,
content: dbMessage.content,
isDeleted: dbMessage.isDeleted,
updatedAt: dbMessage.updatedAt,
deletedAt: dbMessage.deletedAt,
type: dbMessage.type,
meta: dbMessage.meta,
membersMentioned: dbMessage.membersMentioned,
editedAt: dbMessage.editedAt,
attachments: dbMessage.attachments,
reactions: dbMessage.reactions,
repliedMessageId: dbMessage.repliedMessageId,
forwardedMessageId: dbMessage.forwardedMessageId,
);
}
@@ -101,10 +235,31 @@ class AppDatabase extends _$AppDatabase {
Future<List<SnPost>> getAllPostDrafts() async {
final drafts = await select(postDrafts).get();
return drafts
.map((draft) => SnPost.fromJson(jsonDecode(draft.post)))
.map((draft) => SnPost.fromJson(jsonDecode(draft.postData)))
.toList();
}
Future<List<PostDraft>> getAllPostDraftRecords() async {
return await select(postDrafts).get();
}
Future<List<PostDraft>> searchPostDrafts(String query) async {
if (query.isEmpty) {
return await select(postDrafts).get();
}
final searchTerm = '%${query.toLowerCase()}%';
return await (select(postDrafts)
..where(
(draft) =>
draft.title.like(searchTerm) |
draft.description.like(searchTerm) |
draft.content.like(searchTerm),
)
..orderBy([(draft) => OrderingTerm.desc(draft.lastModified)]))
.get();
}
Future<void> addPostDraft(PostDraftsCompanion entry) async {
await into(postDrafts).insert(entry, mode: InsertMode.replace);
}
@@ -116,4 +271,9 @@ class AppDatabase extends _$AppDatabase {
Future<void> clearAllPostDrafts() async {
await delete(postDrafts).go();
}
Future<PostDraft?> getPostDraftById(String id) async {
return await (select(postDrafts)
..where((tbl) => tbl.id.equals(id))).getSingleOrNull();
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,41 @@
import 'dart:convert';
import 'package:drift/drift.dart';
import 'package:island/models/chat.dart';
import 'package:island/models/file.dart';
class MapConverter extends TypeConverter<Map<String, dynamic>, String> {
const MapConverter();
@override
Map<String, dynamic> fromSql(String fromDb) => json.decode(fromDb);
@override
String toSql(Map<String, dynamic> value) => json.encode(value);
}
class ListStringConverter extends TypeConverter<List<String>, String> {
const ListStringConverter();
@override
List<String> fromSql(String fromDb) => List<String>.from(json.decode(fromDb));
@override
String toSql(List<String> value) => json.encode(value);
}
class ListMapConverter
extends TypeConverter<List<Map<String, dynamic>>, String> {
const ListMapConverter();
@override
List<Map<String, dynamic>> fromSql(String fromDb) =>
List<Map<String, dynamic>>.from(json.decode(fromDb));
@override
String toSql(List<Map<String, dynamic>> value) => json.encode(value);
}
class ChatMessages extends Table {
TextColumn get id => text()();
TextColumn get roomId => text()();
@@ -11,7 +45,24 @@ class ChatMessages extends Table {
TextColumn get data => text()();
DateTimeColumn get createdAt => dateTime()();
IntColumn get status => intEnum<MessageStatus>()();
BoolColumn get isRead => boolean().withDefault(const Constant(false))();
BoolColumn get isDeleted =>
boolean().nullable().withDefault(const Constant(false))();
DateTimeColumn get updatedAt => dateTime().nullable()();
DateTimeColumn get deletedAt => dateTime().nullable()();
TextColumn get type => text().withDefault(const Constant('text'))();
TextColumn get meta =>
text().map(const MapConverter()).withDefault(const Constant('{}'))();
TextColumn get membersMentioned =>
text()
.map(const ListStringConverter())
.withDefault(const Constant('[]'))();
DateTimeColumn get editedAt => dateTime().nullable()();
TextColumn get attachments =>
text().map(const ListMapConverter()).withDefault(const Constant('[]'))();
TextColumn get reactions =>
text().map(const ListMapConverter()).withDefault(const Constant('[]'))();
TextColumn get repliedMessageId => text().nullable()();
TextColumn get forwardedMessageId => text().nullable()();
@override
Set<Column> get primaryKey => {id};
@@ -25,8 +76,19 @@ class LocalChatMessage {
final DateTime createdAt;
MessageStatus status;
final String? nonce;
final String? content;
final bool? isDeleted;
final DateTime? updatedAt;
final DateTime? deletedAt;
final String type;
final Map<String, dynamic> meta;
final List<String> membersMentioned;
final DateTime? editedAt;
final List<Map<String, dynamic>> attachments;
final List<Map<String, dynamic>> reactions;
final String? repliedMessageId;
final String? forwardedMessageId;
List<UniversalFile>? localAttachments;
bool isRead;
LocalChatMessage({
required this.id,
@@ -36,8 +98,19 @@ class LocalChatMessage {
required this.createdAt,
required this.nonce,
required this.status,
this.content,
this.isDeleted,
this.updatedAt,
this.deletedAt,
required this.type,
required this.meta,
required this.membersMentioned,
this.editedAt,
required this.attachments,
required this.reactions,
this.repliedMessageId,
this.forwardedMessageId,
this.localAttachments,
this.isRead = false,
});
SnChatMessage toRemoteMessage() {
@@ -48,7 +121,6 @@ class LocalChatMessage {
SnChatMessage message,
MessageStatus status, {
String? nonce,
bool isRead = false,
}) {
return LocalChatMessage(
id: message.id,
@@ -58,7 +130,18 @@ class LocalChatMessage {
createdAt: message.createdAt,
status: status,
nonce: nonce ?? message.nonce,
isRead: isRead,
content: message.content,
isDeleted: false,
updatedAt: message.updatedAt,
deletedAt: null,
type: message.type,
meta: message.meta,
membersMentioned: message.membersMentioned,
editedAt: message.editedAt,
attachments: message.attachments.map((e) => e.toJson()).toList(),
reactions: message.reactions.map((e) => e.toJson()).toList(),
repliedMessageId: message.repliedMessageId,
forwardedMessageId: message.forwardedMessageId,
);
}
}

View File

@@ -1,6 +1,4 @@
import 'dart:developer';
import 'dart:io';
import 'package:croppy/croppy.dart';
import 'package:easy_localization/easy_localization.dart' hide TextDirection;
import 'package:firebase_core/firebase_core.dart';
@@ -8,16 +6,15 @@ 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';
import 'package:image_picker_android/image_picker_android.dart';
import 'package:island/talker.dart';
import 'package:island/firebase_options.dart';
import 'package:island/pods/config.dart';
import 'package:island/pods/network.dart';
import 'package:island/pods/theme.dart';
import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:island/pods/userinfo.dart';
import 'package:island/pods/websocket.dart';
import 'package:island/route.dart';
@@ -29,19 +26,21 @@ import 'package:relative_time/relative_time.dart';
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:talker_flutter/talker_flutter.dart';
import 'package:talker_riverpod_logger/talker_riverpod_logger.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'package:flutter_langdetect/flutter_langdetect.dart' as langdetect;
import 'package:window_manager/window_manager.dart';
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
log('Handling a background message: ${message.messageId}');
talker.info('Handling a background message: ${message.messageId}');
}
void main() async {
final widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) {
log(
talker.info(
"[SplashScreen] Keeping the flash screen to loading other resources...",
);
FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
@@ -52,7 +51,6 @@ void main() async {
}
try {
await langdetect.initLangDetect();
await EasyLocalization.ensureInitialized();
if (kIsWeb || !Platform.isLinux) {
@@ -75,48 +73,59 @@ void main() async {
}
}
log("[SplashScreen] Firebase is ready!");
talker.info("[SplashScreen] Firebase is ready!");
} catch (err) {
showErrorAlert(err);
}
try {
log("[SplashScreen] Loading timezone database...");
talker.info("[SplashScreen] Loading timezone database...");
await initializeTzdb();
log("[SplashScreen] Time zone database was loaded!");
talker.info("[SplashScreen] Time zone database was loaded!");
} catch (err) {
log("[SplashScreen] Failed to load timezone database... $err");
talker.error("[SplashScreen] Failed to load timezone database... $err");
}
final prefs = await SharedPreferences.getInstance();
if (!kIsWeb && (Platform.isMacOS || Platform.isLinux || Platform.isWindows)) {
doWhenWindowReady(() {
const defaultSize = Size(360, 640);
await windowManager.ensureInitialized();
// Get saved window size from preferences
final savedSizeString = prefs.getString(kAppWindowSize);
Size initialSize = defaultSize;
const defaultSize = Size(360, 640);
if (savedSizeString != null) {
try {
final parts = savedSizeString.split(',');
if (parts.length == 2) {
final width = double.parse(parts[0]);
final height = double.parse(parts[1]);
initialSize = Size(width, height);
}
} catch (e) {
log("[SplashScreen] Failed to parse saved window size: $e");
initialSize = defaultSize;
// Get saved window size from preferences
final savedSizeString = prefs.getString(kAppWindowSize);
Size initialSize = defaultSize;
if (savedSizeString != null) {
try {
final parts = savedSizeString.split(',');
if (parts.length == 2) {
final width = double.parse(parts[0]);
final height = double.parse(parts[1]);
initialSize = Size(width, height);
}
} catch (e) {
talker.error("[SplashScreen] Failed to parse saved window size: $e");
initialSize = defaultSize;
}
}
appWindow.minSize = defaultSize;
appWindow.size = initialSize;
appWindow.alignment = Alignment.center;
appWindow.show();
log(
WindowOptions windowOptions = WindowOptions(
size: initialSize,
center: true,
backgroundColor: Colors.transparent,
skipTaskbar: false,
titleBarStyle: TitleBarStyle.hidden,
windowButtonVisibility: true,
);
windowManager.waitUntilReadyToShow(windowOptions, () async {
await windowManager.setMinimumSize(defaultSize);
await windowManager.show();
await windowManager.focus();
final opacity = prefs.getDouble(kAppWindowOpacity) ?? 1.0;
await windowManager.setOpacity(opacity);
talker.info(
"[SplashScreen] Desktop window is ready with size: ${initialSize.width}x${initialSize.height}",
);
});
@@ -128,16 +137,27 @@ void main() async {
if (imagePickerImplementation is ImagePickerAndroid) {
imagePickerImplementation.useAndroidPhotoPicker = true;
}
log("[SplashScreen] Android image picker is ready!");
talker.info("[SplashScreen] Android image picker is ready!");
}
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) {
FlutterNativeSplash.remove();
log("[SplashScreen] Now hiding the splash screen...");
talker.info("[SplashScreen] Now hiding the splash screen...");
}
runApp(
ProviderScope(
observers: [
TalkerRiverpodObserver(
talker: talker,
settings: TalkerRiverpodLoggerSettings(
printProviderAdded: false,
printProviderDisposed: false,
printProviderUpdated: false,
printStateFullData: false,
),
),
],
overrides: [sharedPreferencesProvider.overrideWithValue(prefs)],
child: Directionality(
textDirection: TextDirection.ltr,
@@ -146,6 +166,10 @@ void main() async {
Locale('en', 'US'),
Locale('zh', 'CN'),
Locale('zh', 'TW'),
Locale('zh', 'OG'),
Locale('ja', 'JP'),
Locale('ko', 'KR'),
Locale('es', 'ES'),
],
path: 'assets/i18n',
fallbackLocale: Locale('en', 'US'),
@@ -167,14 +191,29 @@ class IslandApp extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final theme = ref.watch(themeProvider);
final settings = ref.watch(appSettingsNotifierProvider);
// Convert string theme mode to ThemeMode enum
ThemeMode getThemeMode() {
final themeMode = settings.themeMode ?? 'system';
switch (themeMode) {
case 'light':
return ThemeMode.light;
case 'dark':
return ThemeMode.dark;
case 'system':
default:
return ThemeMode.system;
}
}
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);
@@ -183,30 +222,9 @@ class IslandApp extends HookConsumerWidget {
}
useEffect(() {
if (!kIsWeb && Platform.isLinux) {
if (!kIsWeb && (Platform.isLinux || Platform.isWindows)) {
return null;
}
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.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) {
@@ -224,7 +242,9 @@ class IslandApp extends HookConsumerWidget {
final onMessageSubscription = FirebaseMessaging.onMessage.listen((
message,
) {
log('Foreground message received: ${message.messageId}');
talker.info(
'[Notification] foreground message received: ${message.messageId}',
);
handleMessage(message);
});
@@ -238,7 +258,7 @@ class IslandApp extends HookConsumerWidget {
// Load userinfo
final userNotifier = ref.read(userInfoProvider.notifier);
ref.listen(websocketStateProvider, (_, state) {
log('[WebSocket] $state');
talker.info('[WebSocket] $state');
});
Future(() {
userNotifier.fetchUser().then((_) {
@@ -246,6 +266,7 @@ class IslandApp extends HookConsumerWidget {
if (user.value != null) {
final apiClient = ref.read(apiClientProvider);
subscribePushNotification(apiClient);
initializeLocalNotifications();
final wsNotifier = ref.read(websocketStateProvider.notifier);
wsNotifier.connect();
}
@@ -257,11 +278,13 @@ class IslandApp extends HookConsumerWidget {
final router = ref.watch(routerProvider);
return MaterialApp.router(
theme: theme?.light,
darkTheme: theme?.dark,
themeMode: ThemeMode.system,
color: Colors.transparent,
theme: theme.light,
darkTheme: theme.dark,
themeMode: getThemeMode(),
routerConfig: router,
supportedLocales: context.supportedLocales,
scrollBehavior: AppScrollBehavior(),
localizationsDelegates: [
...context.localizationDelegates,
CroppyLocalizations.delegate,
@@ -273,9 +296,15 @@ class IslandApp extends HookConsumerWidget {
key: globalOverlay,
initialEntries: [
OverlayEntry(
builder:
(_) =>
WindowScaffold(child: child ?? const SizedBox.shrink()),
builder: (_) {
return TalkerWrapper(
talker: talker,
options: const TalkerWrapperOptions(enableErrorAlerts: true),
child: WindowScaffold(
child: child ?? const SizedBox.shrink(),
),
);
},
),
],
);

View File

@@ -13,11 +13,13 @@ sealed class SnAccount with _$SnAccount {
required String name,
required String nick,
required String language,
@Default("") String region,
required bool isSuperuser,
required String? automatedId,
required SnAccountProfile profile,
required SnWalletSubscriptionRef? perkSubscription,
@Default([]) List<SnAccountBadge> badges,
@Default([]) List<SnContactMethod> contacts,
required DateTime createdAt,
required DateTime updatedAt,
required DateTime? deletedAt,
@@ -53,6 +55,19 @@ class ProfileLinkConverter
}
}
@freezed
sealed class UsernameColor with _$UsernameColor {
const factory UsernameColor({
@Default('plain') String type,
String? value,
String? direction,
List<String>? colors,
}) = _UsernameColor;
factory UsernameColor.fromJson(Map<String, dynamic> json) =>
_$UsernameColorFromJson(json);
}
@freezed
sealed class SnAccountProfile with _$SnAccountProfile {
const factory SnAccountProfile({
@@ -71,10 +86,13 @@ sealed class SnAccountProfile with _$SnAccountProfile {
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,
UsernameColor? usernameColor,
required DateTime createdAt,
required DateTime updatedAt,
required DateTime? deletedAt,
@@ -94,6 +112,7 @@ sealed class SnAccountStatus with _$SnAccountStatus {
required bool isNotDisturb,
required bool isCustomized,
@Default("") String label,
required Map<String, dynamic>? meta,
required DateTime? clearedAt,
required String accountId,
required DateTime createdAt,
@@ -132,6 +151,7 @@ sealed class SnContactMethod with _$SnContactMethod {
required int type,
required DateTime? verifiedAt,
required bool isPrimary,
required bool isPublic,
required String content,
required String accountId,
required DateTime createdAt,

View File

@@ -15,7 +15,7 @@ T _$identity<T>(T value) => value;
/// @nodoc
mixin _$SnAccount {
String get id; String get name; String get nick; String get language; bool get isSuperuser; String? get automatedId; SnAccountProfile get profile; SnWalletSubscriptionRef? get perkSubscription; List<SnAccountBadge> get badges; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
String get id; String get name; String get nick; String get language; String get region; bool get isSuperuser; String? get automatedId; SnAccountProfile get profile; SnWalletSubscriptionRef? get perkSubscription; List<SnAccountBadge> get badges; List<SnContactMethod> get contacts; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
/// Create a copy of SnAccount
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -28,16 +28,16 @@ $SnAccountCopyWith<SnAccount> get copyWith => _$SnAccountCopyWithImpl<SnAccount>
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnAccount&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.nick, nick) || other.nick == nick)&&(identical(other.language, language) || other.language == language)&&(identical(other.isSuperuser, isSuperuser) || other.isSuperuser == isSuperuser)&&(identical(other.automatedId, automatedId) || other.automatedId == automatedId)&&(identical(other.profile, profile) || other.profile == profile)&&(identical(other.perkSubscription, perkSubscription) || other.perkSubscription == perkSubscription)&&const DeepCollectionEquality().equals(other.badges, badges)&&(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 SnAccount&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.nick, nick) || other.nick == nick)&&(identical(other.language, language) || other.language == language)&&(identical(other.region, region) || other.region == region)&&(identical(other.isSuperuser, isSuperuser) || other.isSuperuser == isSuperuser)&&(identical(other.automatedId, automatedId) || other.automatedId == automatedId)&&(identical(other.profile, profile) || other.profile == profile)&&(identical(other.perkSubscription, perkSubscription) || other.perkSubscription == perkSubscription)&&const DeepCollectionEquality().equals(other.badges, badges)&&const DeepCollectionEquality().equals(other.contacts, contacts)&&(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,nick,language,isSuperuser,automatedId,profile,perkSubscription,const DeepCollectionEquality().hash(badges),createdAt,updatedAt,deletedAt);
int get hashCode => Object.hash(runtimeType,id,name,nick,language,region,isSuperuser,automatedId,profile,perkSubscription,const DeepCollectionEquality().hash(badges),const DeepCollectionEquality().hash(contacts),createdAt,updatedAt,deletedAt);
@override
String toString() {
return 'SnAccount(id: $id, name: $name, nick: $nick, language: $language, isSuperuser: $isSuperuser, automatedId: $automatedId, profile: $profile, perkSubscription: $perkSubscription, badges: $badges, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
return 'SnAccount(id: $id, name: $name, nick: $nick, language: $language, region: $region, isSuperuser: $isSuperuser, automatedId: $automatedId, profile: $profile, perkSubscription: $perkSubscription, badges: $badges, contacts: $contacts, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
@@ -48,7 +48,7 @@ abstract mixin class $SnAccountCopyWith<$Res> {
factory $SnAccountCopyWith(SnAccount value, $Res Function(SnAccount) _then) = _$SnAccountCopyWithImpl;
@useResult
$Res call({
String id, String name, String nick, String language, bool isSuperuser, String? automatedId, SnAccountProfile profile, SnWalletSubscriptionRef? perkSubscription, List<SnAccountBadge> badges, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
String id, String name, String nick, String language, String region, bool isSuperuser, String? automatedId, SnAccountProfile profile, SnWalletSubscriptionRef? perkSubscription, List<SnAccountBadge> badges, List<SnContactMethod> contacts, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
@@ -65,18 +65,20 @@ class _$SnAccountCopyWithImpl<$Res>
/// Create a copy of SnAccount
/// 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? nick = null,Object? language = null,Object? isSuperuser = null,Object? automatedId = freezed,Object? profile = null,Object? perkSubscription = freezed,Object? badges = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? nick = null,Object? language = null,Object? region = null,Object? isSuperuser = null,Object? automatedId = freezed,Object? profile = null,Object? perkSubscription = freezed,Object? badges = null,Object? contacts = 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,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
as String,nick: null == nick ? _self.nick : nick // ignore: cast_nullable_to_non_nullable
as String,language: null == language ? _self.language : language // ignore: cast_nullable_to_non_nullable
as String,region: null == region ? _self.region : region // ignore: cast_nullable_to_non_nullable
as String,isSuperuser: null == isSuperuser ? _self.isSuperuser : isSuperuser // ignore: cast_nullable_to_non_nullable
as bool,automatedId: freezed == automatedId ? _self.automatedId : automatedId // ignore: cast_nullable_to_non_nullable
as String?,profile: null == profile ? _self.profile : profile // ignore: cast_nullable_to_non_nullable
as SnAccountProfile,perkSubscription: freezed == perkSubscription ? _self.perkSubscription : perkSubscription // ignore: cast_nullable_to_non_nullable
as SnWalletSubscriptionRef?,badges: null == badges ? _self.badges : badges // ignore: cast_nullable_to_non_nullable
as List<SnAccountBadge>,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as List<SnAccountBadge>,contacts: null == contacts ? _self.contacts : contacts // ignore: cast_nullable_to_non_nullable
as List<SnContactMethod>,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?,
@@ -182,10 +184,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String name, String nick, String language, bool isSuperuser, String? automatedId, SnAccountProfile profile, SnWalletSubscriptionRef? perkSubscription, List<SnAccountBadge> badges, 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 nick, String language, String region, bool isSuperuser, String? automatedId, SnAccountProfile profile, SnWalletSubscriptionRef? perkSubscription, List<SnAccountBadge> badges, List<SnContactMethod> contacts, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnAccount() when $default != null:
return $default(_that.id,_that.name,_that.nick,_that.language,_that.isSuperuser,_that.automatedId,_that.profile,_that.perkSubscription,_that.badges,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return $default(_that.id,_that.name,_that.nick,_that.language,_that.region,_that.isSuperuser,_that.automatedId,_that.profile,_that.perkSubscription,_that.badges,_that.contacts,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return orElse();
}
@@ -203,10 +205,10 @@ return $default(_that.id,_that.name,_that.nick,_that.language,_that.isSuperuser,
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String name, String nick, String language, bool isSuperuser, String? automatedId, SnAccountProfile profile, SnWalletSubscriptionRef? perkSubscription, List<SnAccountBadge> badges, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String name, String nick, String language, String region, bool isSuperuser, String? automatedId, SnAccountProfile profile, SnWalletSubscriptionRef? perkSubscription, List<SnAccountBadge> badges, List<SnContactMethod> contacts, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
switch (_that) {
case _SnAccount():
return $default(_that.id,_that.name,_that.nick,_that.language,_that.isSuperuser,_that.automatedId,_that.profile,_that.perkSubscription,_that.badges,_that.createdAt,_that.updatedAt,_that.deletedAt);}
return $default(_that.id,_that.name,_that.nick,_that.language,_that.region,_that.isSuperuser,_that.automatedId,_that.profile,_that.perkSubscription,_that.badges,_that.contacts,_that.createdAt,_that.updatedAt,_that.deletedAt);}
}
/// A variant of `when` that fallback to returning `null`
///
@@ -220,10 +222,10 @@ return $default(_that.id,_that.name,_that.nick,_that.language,_that.isSuperuser,
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String name, String nick, String language, bool isSuperuser, String? automatedId, SnAccountProfile profile, SnWalletSubscriptionRef? perkSubscription, List<SnAccountBadge> badges, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String name, String nick, String language, String region, bool isSuperuser, String? automatedId, SnAccountProfile profile, SnWalletSubscriptionRef? perkSubscription, List<SnAccountBadge> badges, List<SnContactMethod> contacts, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
switch (_that) {
case _SnAccount() when $default != null:
return $default(_that.id,_that.name,_that.nick,_that.language,_that.isSuperuser,_that.automatedId,_that.profile,_that.perkSubscription,_that.badges,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return $default(_that.id,_that.name,_that.nick,_that.language,_that.region,_that.isSuperuser,_that.automatedId,_that.profile,_that.perkSubscription,_that.badges,_that.contacts,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return null;
}
@@ -235,13 +237,14 @@ return $default(_that.id,_that.name,_that.nick,_that.language,_that.isSuperuser,
@JsonSerializable()
class _SnAccount implements SnAccount {
const _SnAccount({required this.id, required this.name, required this.nick, required this.language, required this.isSuperuser, required this.automatedId, required this.profile, required this.perkSubscription, final List<SnAccountBadge> badges = const [], required this.createdAt, required this.updatedAt, required this.deletedAt}): _badges = badges;
const _SnAccount({required this.id, required this.name, required this.nick, required this.language, this.region = "", required this.isSuperuser, required this.automatedId, required this.profile, required this.perkSubscription, final List<SnAccountBadge> badges = const [], final List<SnContactMethod> contacts = const [], required this.createdAt, required this.updatedAt, required this.deletedAt}): _badges = badges,_contacts = contacts;
factory _SnAccount.fromJson(Map<String, dynamic> json) => _$SnAccountFromJson(json);
@override final String id;
@override final String name;
@override final String nick;
@override final String language;
@override@JsonKey() final String region;
@override final bool isSuperuser;
@override final String? automatedId;
@override final SnAccountProfile profile;
@@ -253,6 +256,13 @@ class _SnAccount implements SnAccount {
return EqualUnmodifiableListView(_badges);
}
final List<SnContactMethod> _contacts;
@override@JsonKey() List<SnContactMethod> get contacts {
if (_contacts is EqualUnmodifiableListView) return _contacts;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_contacts);
}
@override final DateTime createdAt;
@override final DateTime updatedAt;
@override final DateTime? deletedAt;
@@ -270,16 +280,16 @@ Map<String, dynamic> toJson() {
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnAccount&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.nick, nick) || other.nick == nick)&&(identical(other.language, language) || other.language == language)&&(identical(other.isSuperuser, isSuperuser) || other.isSuperuser == isSuperuser)&&(identical(other.automatedId, automatedId) || other.automatedId == automatedId)&&(identical(other.profile, profile) || other.profile == profile)&&(identical(other.perkSubscription, perkSubscription) || other.perkSubscription == perkSubscription)&&const DeepCollectionEquality().equals(other._badges, _badges)&&(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 _SnAccount&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.nick, nick) || other.nick == nick)&&(identical(other.language, language) || other.language == language)&&(identical(other.region, region) || other.region == region)&&(identical(other.isSuperuser, isSuperuser) || other.isSuperuser == isSuperuser)&&(identical(other.automatedId, automatedId) || other.automatedId == automatedId)&&(identical(other.profile, profile) || other.profile == profile)&&(identical(other.perkSubscription, perkSubscription) || other.perkSubscription == perkSubscription)&&const DeepCollectionEquality().equals(other._badges, _badges)&&const DeepCollectionEquality().equals(other._contacts, _contacts)&&(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,nick,language,isSuperuser,automatedId,profile,perkSubscription,const DeepCollectionEquality().hash(_badges),createdAt,updatedAt,deletedAt);
int get hashCode => Object.hash(runtimeType,id,name,nick,language,region,isSuperuser,automatedId,profile,perkSubscription,const DeepCollectionEquality().hash(_badges),const DeepCollectionEquality().hash(_contacts),createdAt,updatedAt,deletedAt);
@override
String toString() {
return 'SnAccount(id: $id, name: $name, nick: $nick, language: $language, isSuperuser: $isSuperuser, automatedId: $automatedId, profile: $profile, perkSubscription: $perkSubscription, badges: $badges, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
return 'SnAccount(id: $id, name: $name, nick: $nick, language: $language, region: $region, isSuperuser: $isSuperuser, automatedId: $automatedId, profile: $profile, perkSubscription: $perkSubscription, badges: $badges, contacts: $contacts, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
@@ -290,7 +300,7 @@ abstract mixin class _$SnAccountCopyWith<$Res> implements $SnAccountCopyWith<$Re
factory _$SnAccountCopyWith(_SnAccount value, $Res Function(_SnAccount) _then) = __$SnAccountCopyWithImpl;
@override @useResult
$Res call({
String id, String name, String nick, String language, bool isSuperuser, String? automatedId, SnAccountProfile profile, SnWalletSubscriptionRef? perkSubscription, List<SnAccountBadge> badges, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
String id, String name, String nick, String language, String region, bool isSuperuser, String? automatedId, SnAccountProfile profile, SnWalletSubscriptionRef? perkSubscription, List<SnAccountBadge> badges, List<SnContactMethod> contacts, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
@@ -307,18 +317,20 @@ class __$SnAccountCopyWithImpl<$Res>
/// Create a copy of SnAccount
/// 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? nick = null,Object? language = null,Object? isSuperuser = null,Object? automatedId = freezed,Object? profile = null,Object? perkSubscription = freezed,Object? badges = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? nick = null,Object? language = null,Object? region = null,Object? isSuperuser = null,Object? automatedId = freezed,Object? profile = null,Object? perkSubscription = freezed,Object? badges = null,Object? contacts = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
return _then(_SnAccount(
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,nick: null == nick ? _self.nick : nick // ignore: cast_nullable_to_non_nullable
as String,language: null == language ? _self.language : language // ignore: cast_nullable_to_non_nullable
as String,region: null == region ? _self.region : region // ignore: cast_nullable_to_non_nullable
as String,isSuperuser: null == isSuperuser ? _self.isSuperuser : isSuperuser // ignore: cast_nullable_to_non_nullable
as bool,automatedId: freezed == automatedId ? _self.automatedId : automatedId // ignore: cast_nullable_to_non_nullable
as String?,profile: null == profile ? _self.profile : profile // ignore: cast_nullable_to_non_nullable
as SnAccountProfile,perkSubscription: freezed == perkSubscription ? _self.perkSubscription : perkSubscription // ignore: cast_nullable_to_non_nullable
as SnWalletSubscriptionRef?,badges: null == badges ? _self._badges : badges // ignore: cast_nullable_to_non_nullable
as List<SnAccountBadge>,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as List<SnAccountBadge>,contacts: null == contacts ? _self._contacts : contacts // ignore: cast_nullable_to_non_nullable
as List<SnContactMethod>,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?,
@@ -610,10 +622,284 @@ as String,
}
/// @nodoc
mixin _$UsernameColor {
String get type; String? get value; String? get direction; List<String>? get colors;
/// Create a copy of UsernameColor
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$UsernameColorCopyWith<UsernameColor> get copyWith => _$UsernameColorCopyWithImpl<UsernameColor>(this as UsernameColor, _$identity);
/// Serializes this UsernameColor to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is UsernameColor&&(identical(other.type, type) || other.type == type)&&(identical(other.value, value) || other.value == value)&&(identical(other.direction, direction) || other.direction == direction)&&const DeepCollectionEquality().equals(other.colors, colors));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,type,value,direction,const DeepCollectionEquality().hash(colors));
@override
String toString() {
return 'UsernameColor(type: $type, value: $value, direction: $direction, colors: $colors)';
}
}
/// @nodoc
abstract mixin class $UsernameColorCopyWith<$Res> {
factory $UsernameColorCopyWith(UsernameColor value, $Res Function(UsernameColor) _then) = _$UsernameColorCopyWithImpl;
@useResult
$Res call({
String type, String? value, String? direction, List<String>? colors
});
}
/// @nodoc
class _$UsernameColorCopyWithImpl<$Res>
implements $UsernameColorCopyWith<$Res> {
_$UsernameColorCopyWithImpl(this._self, this._then);
final UsernameColor _self;
final $Res Function(UsernameColor) _then;
/// Create a copy of UsernameColor
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? type = null,Object? value = freezed,Object? direction = freezed,Object? colors = freezed,}) {
return _then(_self.copyWith(
type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
as String,value: freezed == value ? _self.value : value // ignore: cast_nullable_to_non_nullable
as String?,direction: freezed == direction ? _self.direction : direction // ignore: cast_nullable_to_non_nullable
as String?,colors: freezed == colors ? _self.colors : colors // ignore: cast_nullable_to_non_nullable
as List<String>?,
));
}
}
/// Adds pattern-matching-related methods to [UsernameColor].
extension UsernameColorPatterns on UsernameColor {
/// 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( _UsernameColor value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _UsernameColor() 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( _UsernameColor value) $default,){
final _that = this;
switch (_that) {
case _UsernameColor():
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( _UsernameColor value)? $default,){
final _that = this;
switch (_that) {
case _UsernameColor() 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 type, String? value, String? direction, List<String>? colors)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _UsernameColor() when $default != null:
return $default(_that.type,_that.value,_that.direction,_that.colors);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 type, String? value, String? direction, List<String>? colors) $default,) {final _that = this;
switch (_that) {
case _UsernameColor():
return $default(_that.type,_that.value,_that.direction,_that.colors);}
}
/// 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 type, String? value, String? direction, List<String>? colors)? $default,) {final _that = this;
switch (_that) {
case _UsernameColor() when $default != null:
return $default(_that.type,_that.value,_that.direction,_that.colors);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _UsernameColor implements UsernameColor {
const _UsernameColor({this.type = 'plain', this.value, this.direction, final List<String>? colors}): _colors = colors;
factory _UsernameColor.fromJson(Map<String, dynamic> json) => _$UsernameColorFromJson(json);
@override@JsonKey() final String type;
@override final String? value;
@override final String? direction;
final List<String>? _colors;
@override List<String>? get colors {
final value = _colors;
if (value == null) return null;
if (_colors is EqualUnmodifiableListView) return _colors;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(value);
}
/// Create a copy of UsernameColor
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$UsernameColorCopyWith<_UsernameColor> get copyWith => __$UsernameColorCopyWithImpl<_UsernameColor>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$UsernameColorToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _UsernameColor&&(identical(other.type, type) || other.type == type)&&(identical(other.value, value) || other.value == value)&&(identical(other.direction, direction) || other.direction == direction)&&const DeepCollectionEquality().equals(other._colors, _colors));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,type,value,direction,const DeepCollectionEquality().hash(_colors));
@override
String toString() {
return 'UsernameColor(type: $type, value: $value, direction: $direction, colors: $colors)';
}
}
/// @nodoc
abstract mixin class _$UsernameColorCopyWith<$Res> implements $UsernameColorCopyWith<$Res> {
factory _$UsernameColorCopyWith(_UsernameColor value, $Res Function(_UsernameColor) _then) = __$UsernameColorCopyWithImpl;
@override @useResult
$Res call({
String type, String? value, String? direction, List<String>? colors
});
}
/// @nodoc
class __$UsernameColorCopyWithImpl<$Res>
implements _$UsernameColorCopyWith<$Res> {
__$UsernameColorCopyWithImpl(this._self, this._then);
final _UsernameColor _self;
final $Res Function(_UsernameColor) _then;
/// Create a copy of UsernameColor
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? type = null,Object? value = freezed,Object? direction = freezed,Object? colors = freezed,}) {
return _then(_UsernameColor(
type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
as String,value: freezed == value ? _self.value : value // ignore: cast_nullable_to_non_nullable
as String?,direction: freezed == direction ? _self.direction : direction // ignore: cast_nullable_to_non_nullable
as String?,colors: freezed == colors ? _self._colors : colors // ignore: cast_nullable_to_non_nullable
as List<String>?,
));
}
}
/// @nodoc
mixin _$SnAccountProfile {
String get id; String get firstName; String get middleName; String get lastName; String get bio; String get gender; String get pronouns; String get location; String get timeZone; DateTime? get birthday;@ProfileLinkConverter() List<ProfileLink> get links; DateTime? get lastSeenAt; SnAccountBadge? get activeBadge; int get experience; int get level; double get levelingProgress; SnCloudFile? get picture; SnCloudFile? get background; SnVerificationMark? get verification; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
String get id; String get firstName; String get middleName; String get lastName; String get bio; String get gender; String get pronouns; String get location; String get timeZone; DateTime? get birthday;@ProfileLinkConverter() List<ProfileLink> get links; DateTime? get lastSeenAt; SnAccountBadge? get activeBadge; int get experience; int get level; double get socialCredits; int get socialCreditsLevel; double get levelingProgress; SnCloudFile? get picture; SnCloudFile? get background; SnVerificationMark? get verification; UsernameColor? get usernameColor; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
/// Create a copy of SnAccountProfile
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -626,16 +912,16 @@ $SnAccountProfileCopyWith<SnAccountProfile> get copyWith => _$SnAccountProfileCo
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnAccountProfile&&(identical(other.id, id) || other.id == id)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.middleName, middleName) || other.middleName == middleName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.bio, bio) || other.bio == bio)&&(identical(other.gender, gender) || other.gender == gender)&&(identical(other.pronouns, pronouns) || other.pronouns == pronouns)&&(identical(other.location, location) || other.location == location)&&(identical(other.timeZone, timeZone) || other.timeZone == timeZone)&&(identical(other.birthday, birthday) || other.birthday == birthday)&&const DeepCollectionEquality().equals(other.links, links)&&(identical(other.lastSeenAt, lastSeenAt) || other.lastSeenAt == lastSeenAt)&&(identical(other.activeBadge, activeBadge) || other.activeBadge == activeBadge)&&(identical(other.experience, experience) || other.experience == experience)&&(identical(other.level, level) || other.level == level)&&(identical(other.levelingProgress, levelingProgress) || other.levelingProgress == levelingProgress)&&(identical(other.picture, picture) || other.picture == picture)&&(identical(other.background, background) || other.background == background)&&(identical(other.verification, verification) || other.verification == verification)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnAccountProfile&&(identical(other.id, id) || other.id == id)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.middleName, middleName) || other.middleName == middleName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.bio, bio) || other.bio == bio)&&(identical(other.gender, gender) || other.gender == gender)&&(identical(other.pronouns, pronouns) || other.pronouns == pronouns)&&(identical(other.location, location) || other.location == location)&&(identical(other.timeZone, timeZone) || other.timeZone == timeZone)&&(identical(other.birthday, birthday) || other.birthday == birthday)&&const DeepCollectionEquality().equals(other.links, links)&&(identical(other.lastSeenAt, lastSeenAt) || other.lastSeenAt == lastSeenAt)&&(identical(other.activeBadge, activeBadge) || other.activeBadge == activeBadge)&&(identical(other.experience, experience) || other.experience == experience)&&(identical(other.level, level) || other.level == level)&&(identical(other.socialCredits, socialCredits) || other.socialCredits == socialCredits)&&(identical(other.socialCreditsLevel, socialCreditsLevel) || other.socialCreditsLevel == socialCreditsLevel)&&(identical(other.levelingProgress, levelingProgress) || other.levelingProgress == levelingProgress)&&(identical(other.picture, picture) || other.picture == picture)&&(identical(other.background, background) || other.background == background)&&(identical(other.verification, verification) || other.verification == verification)&&(identical(other.usernameColor, usernameColor) || other.usernameColor == usernameColor)&&(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,firstName,middleName,lastName,bio,gender,pronouns,location,timeZone,birthday,const DeepCollectionEquality().hash(links),lastSeenAt,activeBadge,experience,level,levelingProgress,picture,background,verification,createdAt,updatedAt,deletedAt]);
int get hashCode => Object.hashAll([runtimeType,id,firstName,middleName,lastName,bio,gender,pronouns,location,timeZone,birthday,const DeepCollectionEquality().hash(links),lastSeenAt,activeBadge,experience,level,socialCredits,socialCreditsLevel,levelingProgress,picture,background,verification,usernameColor,createdAt,updatedAt,deletedAt]);
@override
String toString() {
return 'SnAccountProfile(id: $id, firstName: $firstName, middleName: $middleName, lastName: $lastName, bio: $bio, gender: $gender, pronouns: $pronouns, location: $location, timeZone: $timeZone, birthday: $birthday, links: $links, lastSeenAt: $lastSeenAt, activeBadge: $activeBadge, experience: $experience, level: $level, levelingProgress: $levelingProgress, picture: $picture, background: $background, verification: $verification, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
return 'SnAccountProfile(id: $id, firstName: $firstName, middleName: $middleName, lastName: $lastName, bio: $bio, gender: $gender, pronouns: $pronouns, location: $location, timeZone: $timeZone, birthday: $birthday, links: $links, lastSeenAt: $lastSeenAt, activeBadge: $activeBadge, experience: $experience, level: $level, socialCredits: $socialCredits, socialCreditsLevel: $socialCreditsLevel, levelingProgress: $levelingProgress, picture: $picture, background: $background, verification: $verification, usernameColor: $usernameColor, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
@@ -646,11 +932,11 @@ abstract mixin class $SnAccountProfileCopyWith<$Res> {
factory $SnAccountProfileCopyWith(SnAccountProfile value, $Res Function(SnAccountProfile) _then) = _$SnAccountProfileCopyWithImpl;
@useResult
$Res call({
String id, String firstName, String middleName, String lastName, String bio, String gender, String pronouns, String location, String timeZone, DateTime? birthday,@ProfileLinkConverter() List<ProfileLink> links, DateTime? lastSeenAt, SnAccountBadge? activeBadge, int experience, int level, double levelingProgress, SnCloudFile? picture, SnCloudFile? background, SnVerificationMark? verification, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
String id, String firstName, String middleName, String lastName, String bio, String gender, String pronouns, String location, String timeZone, DateTime? birthday,@ProfileLinkConverter() List<ProfileLink> links, DateTime? lastSeenAt, SnAccountBadge? activeBadge, int experience, int level, double socialCredits, int socialCreditsLevel, double levelingProgress, SnCloudFile? picture, SnCloudFile? background, SnVerificationMark? verification, UsernameColor? usernameColor, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
$SnAccountBadgeCopyWith<$Res>? get activeBadge;$SnCloudFileCopyWith<$Res>? get picture;$SnCloudFileCopyWith<$Res>? get background;$SnVerificationMarkCopyWith<$Res>? get verification;
$SnAccountBadgeCopyWith<$Res>? get activeBadge;$SnCloudFileCopyWith<$Res>? get picture;$SnCloudFileCopyWith<$Res>? get background;$SnVerificationMarkCopyWith<$Res>? get verification;$UsernameColorCopyWith<$Res>? get usernameColor;
}
/// @nodoc
@@ -663,7 +949,7 @@ class _$SnAccountProfileCopyWithImpl<$Res>
/// Create a copy of SnAccountProfile
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? firstName = null,Object? middleName = null,Object? lastName = null,Object? bio = null,Object? gender = null,Object? pronouns = null,Object? location = null,Object? timeZone = null,Object? birthday = freezed,Object? links = null,Object? lastSeenAt = freezed,Object? activeBadge = freezed,Object? experience = null,Object? level = null,Object? levelingProgress = null,Object? picture = freezed,Object? background = freezed,Object? verification = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? firstName = null,Object? middleName = null,Object? lastName = null,Object? bio = null,Object? gender = null,Object? pronouns = null,Object? location = null,Object? timeZone = null,Object? birthday = freezed,Object? links = null,Object? lastSeenAt = freezed,Object? activeBadge = freezed,Object? experience = null,Object? level = null,Object? socialCredits = null,Object? socialCreditsLevel = null,Object? levelingProgress = null,Object? picture = freezed,Object? background = freezed,Object? verification = freezed,Object? usernameColor = 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,firstName: null == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable
@@ -680,11 +966,14 @@ as List<ProfileLink>,lastSeenAt: freezed == lastSeenAt ? _self.lastSeenAt : last
as DateTime?,activeBadge: freezed == activeBadge ? _self.activeBadge : activeBadge // ignore: cast_nullable_to_non_nullable
as SnAccountBadge?,experience: null == experience ? _self.experience : experience // ignore: cast_nullable_to_non_nullable
as int,level: null == level ? _self.level : level // ignore: cast_nullable_to_non_nullable
as int,socialCredits: null == socialCredits ? _self.socialCredits : socialCredits // ignore: cast_nullable_to_non_nullable
as double,socialCreditsLevel: null == socialCreditsLevel ? _self.socialCreditsLevel : socialCreditsLevel // ignore: cast_nullable_to_non_nullable
as int,levelingProgress: null == levelingProgress ? _self.levelingProgress : levelingProgress // ignore: cast_nullable_to_non_nullable
as double,picture: freezed == picture ? _self.picture : picture // ignore: cast_nullable_to_non_nullable
as SnCloudFile?,background: freezed == background ? _self.background : background // ignore: cast_nullable_to_non_nullable
as SnCloudFile?,verification: freezed == verification ? _self.verification : verification // ignore: cast_nullable_to_non_nullable
as SnVerificationMark?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as SnVerificationMark?,usernameColor: freezed == usernameColor ? _self.usernameColor : usernameColor // ignore: cast_nullable_to_non_nullable
as UsernameColor?,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?,
@@ -738,6 +1027,18 @@ $SnVerificationMarkCopyWith<$Res>? get verification {
return $SnVerificationMarkCopyWith<$Res>(_self.verification!, (value) {
return _then(_self.copyWith(verification: value));
});
}/// Create a copy of SnAccountProfile
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$UsernameColorCopyWith<$Res>? get usernameColor {
if (_self.usernameColor == null) {
return null;
}
return $UsernameColorCopyWith<$Res>(_self.usernameColor!, (value) {
return _then(_self.copyWith(usernameColor: value));
});
}
}
@@ -817,10 +1118,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String firstName, String middleName, String lastName, String bio, String gender, String pronouns, String location, String timeZone, DateTime? birthday, @ProfileLinkConverter() List<ProfileLink> links, DateTime? lastSeenAt, SnAccountBadge? activeBadge, int experience, int level, double levelingProgress, SnCloudFile? picture, SnCloudFile? background, SnVerificationMark? verification, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String firstName, String middleName, String lastName, String bio, String gender, String pronouns, String location, String timeZone, DateTime? birthday, @ProfileLinkConverter() List<ProfileLink> links, DateTime? lastSeenAt, SnAccountBadge? activeBadge, int experience, int level, double socialCredits, int socialCreditsLevel, double levelingProgress, SnCloudFile? picture, SnCloudFile? background, SnVerificationMark? verification, UsernameColor? usernameColor, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnAccountProfile() when $default != null:
return $default(_that.id,_that.firstName,_that.middleName,_that.lastName,_that.bio,_that.gender,_that.pronouns,_that.location,_that.timeZone,_that.birthday,_that.links,_that.lastSeenAt,_that.activeBadge,_that.experience,_that.level,_that.levelingProgress,_that.picture,_that.background,_that.verification,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return $default(_that.id,_that.firstName,_that.middleName,_that.lastName,_that.bio,_that.gender,_that.pronouns,_that.location,_that.timeZone,_that.birthday,_that.links,_that.lastSeenAt,_that.activeBadge,_that.experience,_that.level,_that.socialCredits,_that.socialCreditsLevel,_that.levelingProgress,_that.picture,_that.background,_that.verification,_that.usernameColor,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return orElse();
}
@@ -838,10 +1139,10 @@ return $default(_that.id,_that.firstName,_that.middleName,_that.lastName,_that.b
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String firstName, String middleName, String lastName, String bio, String gender, String pronouns, String location, String timeZone, DateTime? birthday, @ProfileLinkConverter() List<ProfileLink> links, DateTime? lastSeenAt, SnAccountBadge? activeBadge, int experience, int level, double levelingProgress, SnCloudFile? picture, SnCloudFile? background, SnVerificationMark? verification, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String firstName, String middleName, String lastName, String bio, String gender, String pronouns, String location, String timeZone, DateTime? birthday, @ProfileLinkConverter() List<ProfileLink> links, DateTime? lastSeenAt, SnAccountBadge? activeBadge, int experience, int level, double socialCredits, int socialCreditsLevel, double levelingProgress, SnCloudFile? picture, SnCloudFile? background, SnVerificationMark? verification, UsernameColor? usernameColor, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
switch (_that) {
case _SnAccountProfile():
return $default(_that.id,_that.firstName,_that.middleName,_that.lastName,_that.bio,_that.gender,_that.pronouns,_that.location,_that.timeZone,_that.birthday,_that.links,_that.lastSeenAt,_that.activeBadge,_that.experience,_that.level,_that.levelingProgress,_that.picture,_that.background,_that.verification,_that.createdAt,_that.updatedAt,_that.deletedAt);}
return $default(_that.id,_that.firstName,_that.middleName,_that.lastName,_that.bio,_that.gender,_that.pronouns,_that.location,_that.timeZone,_that.birthday,_that.links,_that.lastSeenAt,_that.activeBadge,_that.experience,_that.level,_that.socialCredits,_that.socialCreditsLevel,_that.levelingProgress,_that.picture,_that.background,_that.verification,_that.usernameColor,_that.createdAt,_that.updatedAt,_that.deletedAt);}
}
/// A variant of `when` that fallback to returning `null`
///
@@ -855,10 +1156,10 @@ return $default(_that.id,_that.firstName,_that.middleName,_that.lastName,_that.b
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String firstName, String middleName, String lastName, String bio, String gender, String pronouns, String location, String timeZone, DateTime? birthday, @ProfileLinkConverter() List<ProfileLink> links, DateTime? lastSeenAt, SnAccountBadge? activeBadge, int experience, int level, double levelingProgress, SnCloudFile? picture, SnCloudFile? background, SnVerificationMark? verification, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String firstName, String middleName, String lastName, String bio, String gender, String pronouns, String location, String timeZone, DateTime? birthday, @ProfileLinkConverter() List<ProfileLink> links, DateTime? lastSeenAt, SnAccountBadge? activeBadge, int experience, int level, double socialCredits, int socialCreditsLevel, double levelingProgress, SnCloudFile? picture, SnCloudFile? background, SnVerificationMark? verification, UsernameColor? usernameColor, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
switch (_that) {
case _SnAccountProfile() when $default != null:
return $default(_that.id,_that.firstName,_that.middleName,_that.lastName,_that.bio,_that.gender,_that.pronouns,_that.location,_that.timeZone,_that.birthday,_that.links,_that.lastSeenAt,_that.activeBadge,_that.experience,_that.level,_that.levelingProgress,_that.picture,_that.background,_that.verification,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return $default(_that.id,_that.firstName,_that.middleName,_that.lastName,_that.bio,_that.gender,_that.pronouns,_that.location,_that.timeZone,_that.birthday,_that.links,_that.lastSeenAt,_that.activeBadge,_that.experience,_that.level,_that.socialCredits,_that.socialCreditsLevel,_that.levelingProgress,_that.picture,_that.background,_that.verification,_that.usernameColor,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return null;
}
@@ -870,7 +1171,7 @@ return $default(_that.id,_that.firstName,_that.middleName,_that.lastName,_that.b
@JsonSerializable()
class _SnAccountProfile implements SnAccountProfile {
const _SnAccountProfile({required this.id, this.firstName = '', this.middleName = '', this.lastName = '', this.bio = '', this.gender = '', this.pronouns = '', this.location = '', this.timeZone = '', this.birthday, @ProfileLinkConverter() final List<ProfileLink> links = const [], this.lastSeenAt, this.activeBadge, required this.experience, required this.level, required this.levelingProgress, required this.picture, required this.background, required this.verification, required this.createdAt, required this.updatedAt, required this.deletedAt}): _links = links;
const _SnAccountProfile({required this.id, this.firstName = '', this.middleName = '', this.lastName = '', this.bio = '', this.gender = '', this.pronouns = '', this.location = '', this.timeZone = '', this.birthday, @ProfileLinkConverter() final List<ProfileLink> links = const [], this.lastSeenAt, this.activeBadge, required this.experience, required this.level, this.socialCredits = 100, this.socialCreditsLevel = 0, required this.levelingProgress, required this.picture, required this.background, required this.verification, this.usernameColor, required this.createdAt, required this.updatedAt, required this.deletedAt}): _links = links;
factory _SnAccountProfile.fromJson(Map<String, dynamic> json) => _$SnAccountProfileFromJson(json);
@override final String id;
@@ -894,10 +1195,13 @@ class _SnAccountProfile implements SnAccountProfile {
@override final SnAccountBadge? activeBadge;
@override final int experience;
@override final int level;
@override@JsonKey() final double socialCredits;
@override@JsonKey() final int socialCreditsLevel;
@override final double levelingProgress;
@override final SnCloudFile? picture;
@override final SnCloudFile? background;
@override final SnVerificationMark? verification;
@override final UsernameColor? usernameColor;
@override final DateTime createdAt;
@override final DateTime updatedAt;
@override final DateTime? deletedAt;
@@ -915,16 +1219,16 @@ Map<String, dynamic> toJson() {
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnAccountProfile&&(identical(other.id, id) || other.id == id)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.middleName, middleName) || other.middleName == middleName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.bio, bio) || other.bio == bio)&&(identical(other.gender, gender) || other.gender == gender)&&(identical(other.pronouns, pronouns) || other.pronouns == pronouns)&&(identical(other.location, location) || other.location == location)&&(identical(other.timeZone, timeZone) || other.timeZone == timeZone)&&(identical(other.birthday, birthday) || other.birthday == birthday)&&const DeepCollectionEquality().equals(other._links, _links)&&(identical(other.lastSeenAt, lastSeenAt) || other.lastSeenAt == lastSeenAt)&&(identical(other.activeBadge, activeBadge) || other.activeBadge == activeBadge)&&(identical(other.experience, experience) || other.experience == experience)&&(identical(other.level, level) || other.level == level)&&(identical(other.levelingProgress, levelingProgress) || other.levelingProgress == levelingProgress)&&(identical(other.picture, picture) || other.picture == picture)&&(identical(other.background, background) || other.background == background)&&(identical(other.verification, verification) || other.verification == verification)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnAccountProfile&&(identical(other.id, id) || other.id == id)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.middleName, middleName) || other.middleName == middleName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.bio, bio) || other.bio == bio)&&(identical(other.gender, gender) || other.gender == gender)&&(identical(other.pronouns, pronouns) || other.pronouns == pronouns)&&(identical(other.location, location) || other.location == location)&&(identical(other.timeZone, timeZone) || other.timeZone == timeZone)&&(identical(other.birthday, birthday) || other.birthday == birthday)&&const DeepCollectionEquality().equals(other._links, _links)&&(identical(other.lastSeenAt, lastSeenAt) || other.lastSeenAt == lastSeenAt)&&(identical(other.activeBadge, activeBadge) || other.activeBadge == activeBadge)&&(identical(other.experience, experience) || other.experience == experience)&&(identical(other.level, level) || other.level == level)&&(identical(other.socialCredits, socialCredits) || other.socialCredits == socialCredits)&&(identical(other.socialCreditsLevel, socialCreditsLevel) || other.socialCreditsLevel == socialCreditsLevel)&&(identical(other.levelingProgress, levelingProgress) || other.levelingProgress == levelingProgress)&&(identical(other.picture, picture) || other.picture == picture)&&(identical(other.background, background) || other.background == background)&&(identical(other.verification, verification) || other.verification == verification)&&(identical(other.usernameColor, usernameColor) || other.usernameColor == usernameColor)&&(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,firstName,middleName,lastName,bio,gender,pronouns,location,timeZone,birthday,const DeepCollectionEquality().hash(_links),lastSeenAt,activeBadge,experience,level,levelingProgress,picture,background,verification,createdAt,updatedAt,deletedAt]);
int get hashCode => Object.hashAll([runtimeType,id,firstName,middleName,lastName,bio,gender,pronouns,location,timeZone,birthday,const DeepCollectionEquality().hash(_links),lastSeenAt,activeBadge,experience,level,socialCredits,socialCreditsLevel,levelingProgress,picture,background,verification,usernameColor,createdAt,updatedAt,deletedAt]);
@override
String toString() {
return 'SnAccountProfile(id: $id, firstName: $firstName, middleName: $middleName, lastName: $lastName, bio: $bio, gender: $gender, pronouns: $pronouns, location: $location, timeZone: $timeZone, birthday: $birthday, links: $links, lastSeenAt: $lastSeenAt, activeBadge: $activeBadge, experience: $experience, level: $level, levelingProgress: $levelingProgress, picture: $picture, background: $background, verification: $verification, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
return 'SnAccountProfile(id: $id, firstName: $firstName, middleName: $middleName, lastName: $lastName, bio: $bio, gender: $gender, pronouns: $pronouns, location: $location, timeZone: $timeZone, birthday: $birthday, links: $links, lastSeenAt: $lastSeenAt, activeBadge: $activeBadge, experience: $experience, level: $level, socialCredits: $socialCredits, socialCreditsLevel: $socialCreditsLevel, levelingProgress: $levelingProgress, picture: $picture, background: $background, verification: $verification, usernameColor: $usernameColor, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
@@ -935,11 +1239,11 @@ abstract mixin class _$SnAccountProfileCopyWith<$Res> implements $SnAccountProfi
factory _$SnAccountProfileCopyWith(_SnAccountProfile value, $Res Function(_SnAccountProfile) _then) = __$SnAccountProfileCopyWithImpl;
@override @useResult
$Res call({
String id, String firstName, String middleName, String lastName, String bio, String gender, String pronouns, String location, String timeZone, DateTime? birthday,@ProfileLinkConverter() List<ProfileLink> links, DateTime? lastSeenAt, SnAccountBadge? activeBadge, int experience, int level, double levelingProgress, SnCloudFile? picture, SnCloudFile? background, SnVerificationMark? verification, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
String id, String firstName, String middleName, String lastName, String bio, String gender, String pronouns, String location, String timeZone, DateTime? birthday,@ProfileLinkConverter() List<ProfileLink> links, DateTime? lastSeenAt, SnAccountBadge? activeBadge, int experience, int level, double socialCredits, int socialCreditsLevel, double levelingProgress, SnCloudFile? picture, SnCloudFile? background, SnVerificationMark? verification, UsernameColor? usernameColor, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
@override $SnAccountBadgeCopyWith<$Res>? get activeBadge;@override $SnCloudFileCopyWith<$Res>? get picture;@override $SnCloudFileCopyWith<$Res>? get background;@override $SnVerificationMarkCopyWith<$Res>? get verification;
@override $SnAccountBadgeCopyWith<$Res>? get activeBadge;@override $SnCloudFileCopyWith<$Res>? get picture;@override $SnCloudFileCopyWith<$Res>? get background;@override $SnVerificationMarkCopyWith<$Res>? get verification;@override $UsernameColorCopyWith<$Res>? get usernameColor;
}
/// @nodoc
@@ -952,7 +1256,7 @@ class __$SnAccountProfileCopyWithImpl<$Res>
/// Create a copy of SnAccountProfile
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? firstName = null,Object? middleName = null,Object? lastName = null,Object? bio = null,Object? gender = null,Object? pronouns = null,Object? location = null,Object? timeZone = null,Object? birthday = freezed,Object? links = null,Object? lastSeenAt = freezed,Object? activeBadge = freezed,Object? experience = null,Object? level = null,Object? levelingProgress = null,Object? picture = freezed,Object? background = freezed,Object? verification = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? firstName = null,Object? middleName = null,Object? lastName = null,Object? bio = null,Object? gender = null,Object? pronouns = null,Object? location = null,Object? timeZone = null,Object? birthday = freezed,Object? links = null,Object? lastSeenAt = freezed,Object? activeBadge = freezed,Object? experience = null,Object? level = null,Object? socialCredits = null,Object? socialCreditsLevel = null,Object? levelingProgress = null,Object? picture = freezed,Object? background = freezed,Object? verification = freezed,Object? usernameColor = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
return _then(_SnAccountProfile(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,firstName: null == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable
@@ -969,11 +1273,14 @@ as List<ProfileLink>,lastSeenAt: freezed == lastSeenAt ? _self.lastSeenAt : last
as DateTime?,activeBadge: freezed == activeBadge ? _self.activeBadge : activeBadge // ignore: cast_nullable_to_non_nullable
as SnAccountBadge?,experience: null == experience ? _self.experience : experience // ignore: cast_nullable_to_non_nullable
as int,level: null == level ? _self.level : level // ignore: cast_nullable_to_non_nullable
as int,socialCredits: null == socialCredits ? _self.socialCredits : socialCredits // ignore: cast_nullable_to_non_nullable
as double,socialCreditsLevel: null == socialCreditsLevel ? _self.socialCreditsLevel : socialCreditsLevel // ignore: cast_nullable_to_non_nullable
as int,levelingProgress: null == levelingProgress ? _self.levelingProgress : levelingProgress // ignore: cast_nullable_to_non_nullable
as double,picture: freezed == picture ? _self.picture : picture // ignore: cast_nullable_to_non_nullable
as SnCloudFile?,background: freezed == background ? _self.background : background // ignore: cast_nullable_to_non_nullable
as SnCloudFile?,verification: freezed == verification ? _self.verification : verification // ignore: cast_nullable_to_non_nullable
as SnVerificationMark?,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as SnVerificationMark?,usernameColor: freezed == usernameColor ? _self.usernameColor : usernameColor // ignore: cast_nullable_to_non_nullable
as UsernameColor?,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?,
@@ -1028,6 +1335,18 @@ $SnVerificationMarkCopyWith<$Res>? get verification {
return $SnVerificationMarkCopyWith<$Res>(_self.verification!, (value) {
return _then(_self.copyWith(verification: value));
});
}/// Create a copy of SnAccountProfile
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$UsernameColorCopyWith<$Res>? get usernameColor {
if (_self.usernameColor == null) {
return null;
}
return $UsernameColorCopyWith<$Res>(_self.usernameColor!, (value) {
return _then(_self.copyWith(usernameColor: value));
});
}
}
@@ -1035,7 +1354,7 @@ $SnVerificationMarkCopyWith<$Res>? get verification {
/// @nodoc
mixin _$SnAccountStatus {
String get id; int get attitude; bool get isOnline; bool get isInvisible; bool get isNotDisturb; bool get isCustomized; String get label; DateTime? get clearedAt; String get accountId; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
String get id; int get attitude; bool get isOnline; bool get isInvisible; bool get isNotDisturb; bool get isCustomized; String get label; Map<String, dynamic>? get meta; DateTime? get clearedAt; String get accountId; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
/// Create a copy of SnAccountStatus
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -1048,16 +1367,16 @@ $SnAccountStatusCopyWith<SnAccountStatus> get copyWith => _$SnAccountStatusCopyW
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnAccountStatus&&(identical(other.id, id) || other.id == id)&&(identical(other.attitude, attitude) || other.attitude == attitude)&&(identical(other.isOnline, isOnline) || other.isOnline == isOnline)&&(identical(other.isInvisible, isInvisible) || other.isInvisible == isInvisible)&&(identical(other.isNotDisturb, isNotDisturb) || other.isNotDisturb == isNotDisturb)&&(identical(other.isCustomized, isCustomized) || other.isCustomized == isCustomized)&&(identical(other.label, label) || other.label == label)&&(identical(other.clearedAt, clearedAt) || other.clearedAt == clearedAt)&&(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 SnAccountStatus&&(identical(other.id, id) || other.id == id)&&(identical(other.attitude, attitude) || other.attitude == attitude)&&(identical(other.isOnline, isOnline) || other.isOnline == isOnline)&&(identical(other.isInvisible, isInvisible) || other.isInvisible == isInvisible)&&(identical(other.isNotDisturb, isNotDisturb) || other.isNotDisturb == isNotDisturb)&&(identical(other.isCustomized, isCustomized) || other.isCustomized == isCustomized)&&(identical(other.label, label) || other.label == label)&&const DeepCollectionEquality().equals(other.meta, meta)&&(identical(other.clearedAt, clearedAt) || other.clearedAt == clearedAt)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,attitude,isOnline,isInvisible,isNotDisturb,isCustomized,label,clearedAt,accountId,createdAt,updatedAt,deletedAt);
int get hashCode => Object.hash(runtimeType,id,attitude,isOnline,isInvisible,isNotDisturb,isCustomized,label,const DeepCollectionEquality().hash(meta),clearedAt,accountId,createdAt,updatedAt,deletedAt);
@override
String toString() {
return 'SnAccountStatus(id: $id, attitude: $attitude, isOnline: $isOnline, isInvisible: $isInvisible, isNotDisturb: $isNotDisturb, isCustomized: $isCustomized, label: $label, clearedAt: $clearedAt, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
return 'SnAccountStatus(id: $id, attitude: $attitude, isOnline: $isOnline, isInvisible: $isInvisible, isNotDisturb: $isNotDisturb, isCustomized: $isCustomized, label: $label, meta: $meta, clearedAt: $clearedAt, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
@@ -1068,7 +1387,7 @@ abstract mixin class $SnAccountStatusCopyWith<$Res> {
factory $SnAccountStatusCopyWith(SnAccountStatus value, $Res Function(SnAccountStatus) _then) = _$SnAccountStatusCopyWithImpl;
@useResult
$Res call({
String id, int attitude, bool isOnline, bool isInvisible, bool isNotDisturb, bool isCustomized, String label, DateTime? clearedAt, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
String id, int attitude, bool isOnline, bool isInvisible, bool isNotDisturb, bool isCustomized, String label, Map<String, dynamic>? meta, DateTime? clearedAt, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
@@ -1085,7 +1404,7 @@ class _$SnAccountStatusCopyWithImpl<$Res>
/// Create a copy of SnAccountStatus
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? attitude = null,Object? isOnline = null,Object? isInvisible = null,Object? isNotDisturb = null,Object? isCustomized = null,Object? label = null,Object? clearedAt = freezed,Object? accountId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? attitude = null,Object? isOnline = null,Object? isInvisible = null,Object? isNotDisturb = null,Object? isCustomized = null,Object? label = null,Object? meta = freezed,Object? clearedAt = 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,attitude: null == attitude ? _self.attitude : attitude // ignore: cast_nullable_to_non_nullable
@@ -1094,7 +1413,8 @@ as bool,isInvisible: null == isInvisible ? _self.isInvisible : isInvisible // ig
as bool,isNotDisturb: null == isNotDisturb ? _self.isNotDisturb : isNotDisturb // ignore: cast_nullable_to_non_nullable
as bool,isCustomized: null == isCustomized ? _self.isCustomized : isCustomized // ignore: cast_nullable_to_non_nullable
as bool,label: null == label ? _self.label : label // ignore: cast_nullable_to_non_nullable
as String,clearedAt: freezed == clearedAt ? _self.clearedAt : clearedAt // ignore: cast_nullable_to_non_nullable
as String,meta: freezed == meta ? _self.meta : meta // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>?,clearedAt: freezed == clearedAt ? _self.clearedAt : clearedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
@@ -1181,10 +1501,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, int attitude, bool isOnline, bool isInvisible, bool isNotDisturb, bool isCustomized, String label, DateTime? clearedAt, 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, int attitude, bool isOnline, bool isInvisible, bool isNotDisturb, bool isCustomized, String label, Map<String, dynamic>? meta, DateTime? clearedAt, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnAccountStatus() when $default != null:
return $default(_that.id,_that.attitude,_that.isOnline,_that.isInvisible,_that.isNotDisturb,_that.isCustomized,_that.label,_that.clearedAt,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return $default(_that.id,_that.attitude,_that.isOnline,_that.isInvisible,_that.isNotDisturb,_that.isCustomized,_that.label,_that.meta,_that.clearedAt,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return orElse();
}
@@ -1202,10 +1522,10 @@ return $default(_that.id,_that.attitude,_that.isOnline,_that.isInvisible,_that.i
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, int attitude, bool isOnline, bool isInvisible, bool isNotDisturb, bool isCustomized, String label, DateTime? clearedAt, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, int attitude, bool isOnline, bool isInvisible, bool isNotDisturb, bool isCustomized, String label, Map<String, dynamic>? meta, DateTime? clearedAt, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
switch (_that) {
case _SnAccountStatus():
return $default(_that.id,_that.attitude,_that.isOnline,_that.isInvisible,_that.isNotDisturb,_that.isCustomized,_that.label,_that.clearedAt,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);}
return $default(_that.id,_that.attitude,_that.isOnline,_that.isInvisible,_that.isNotDisturb,_that.isCustomized,_that.label,_that.meta,_that.clearedAt,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);}
}
/// A variant of `when` that fallback to returning `null`
///
@@ -1219,10 +1539,10 @@ return $default(_that.id,_that.attitude,_that.isOnline,_that.isInvisible,_that.i
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, int attitude, bool isOnline, bool isInvisible, bool isNotDisturb, bool isCustomized, String label, DateTime? clearedAt, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, int attitude, bool isOnline, bool isInvisible, bool isNotDisturb, bool isCustomized, String label, Map<String, dynamic>? meta, DateTime? clearedAt, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
switch (_that) {
case _SnAccountStatus() when $default != null:
return $default(_that.id,_that.attitude,_that.isOnline,_that.isInvisible,_that.isNotDisturb,_that.isCustomized,_that.label,_that.clearedAt,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return $default(_that.id,_that.attitude,_that.isOnline,_that.isInvisible,_that.isNotDisturb,_that.isCustomized,_that.label,_that.meta,_that.clearedAt,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return null;
}
@@ -1234,7 +1554,7 @@ return $default(_that.id,_that.attitude,_that.isOnline,_that.isInvisible,_that.i
@JsonSerializable()
class _SnAccountStatus implements SnAccountStatus {
const _SnAccountStatus({required this.id, required this.attitude, required this.isOnline, required this.isInvisible, required this.isNotDisturb, required this.isCustomized, this.label = "", required this.clearedAt, required this.accountId, required this.createdAt, required this.updatedAt, required this.deletedAt});
const _SnAccountStatus({required this.id, required this.attitude, required this.isOnline, required this.isInvisible, required this.isNotDisturb, required this.isCustomized, this.label = "", required final Map<String, dynamic>? meta, required this.clearedAt, required this.accountId, required this.createdAt, required this.updatedAt, required this.deletedAt}): _meta = meta;
factory _SnAccountStatus.fromJson(Map<String, dynamic> json) => _$SnAccountStatusFromJson(json);
@override final String id;
@@ -1244,6 +1564,15 @@ class _SnAccountStatus implements SnAccountStatus {
@override final bool isNotDisturb;
@override final bool isCustomized;
@override@JsonKey() final String label;
final Map<String, dynamic>? _meta;
@override Map<String, dynamic>? get meta {
final value = _meta;
if (value == null) return null;
if (_meta is EqualUnmodifiableMapView) return _meta;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(value);
}
@override final DateTime? clearedAt;
@override final String accountId;
@override final DateTime createdAt;
@@ -1263,16 +1592,16 @@ Map<String, dynamic> toJson() {
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnAccountStatus&&(identical(other.id, id) || other.id == id)&&(identical(other.attitude, attitude) || other.attitude == attitude)&&(identical(other.isOnline, isOnline) || other.isOnline == isOnline)&&(identical(other.isInvisible, isInvisible) || other.isInvisible == isInvisible)&&(identical(other.isNotDisturb, isNotDisturb) || other.isNotDisturb == isNotDisturb)&&(identical(other.isCustomized, isCustomized) || other.isCustomized == isCustomized)&&(identical(other.label, label) || other.label == label)&&(identical(other.clearedAt, clearedAt) || other.clearedAt == clearedAt)&&(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 _SnAccountStatus&&(identical(other.id, id) || other.id == id)&&(identical(other.attitude, attitude) || other.attitude == attitude)&&(identical(other.isOnline, isOnline) || other.isOnline == isOnline)&&(identical(other.isInvisible, isInvisible) || other.isInvisible == isInvisible)&&(identical(other.isNotDisturb, isNotDisturb) || other.isNotDisturb == isNotDisturb)&&(identical(other.isCustomized, isCustomized) || other.isCustomized == isCustomized)&&(identical(other.label, label) || other.label == label)&&const DeepCollectionEquality().equals(other._meta, _meta)&&(identical(other.clearedAt, clearedAt) || other.clearedAt == clearedAt)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,attitude,isOnline,isInvisible,isNotDisturb,isCustomized,label,clearedAt,accountId,createdAt,updatedAt,deletedAt);
int get hashCode => Object.hash(runtimeType,id,attitude,isOnline,isInvisible,isNotDisturb,isCustomized,label,const DeepCollectionEquality().hash(_meta),clearedAt,accountId,createdAt,updatedAt,deletedAt);
@override
String toString() {
return 'SnAccountStatus(id: $id, attitude: $attitude, isOnline: $isOnline, isInvisible: $isInvisible, isNotDisturb: $isNotDisturb, isCustomized: $isCustomized, label: $label, clearedAt: $clearedAt, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
return 'SnAccountStatus(id: $id, attitude: $attitude, isOnline: $isOnline, isInvisible: $isInvisible, isNotDisturb: $isNotDisturb, isCustomized: $isCustomized, label: $label, meta: $meta, clearedAt: $clearedAt, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
@@ -1283,7 +1612,7 @@ abstract mixin class _$SnAccountStatusCopyWith<$Res> implements $SnAccountStatus
factory _$SnAccountStatusCopyWith(_SnAccountStatus value, $Res Function(_SnAccountStatus) _then) = __$SnAccountStatusCopyWithImpl;
@override @useResult
$Res call({
String id, int attitude, bool isOnline, bool isInvisible, bool isNotDisturb, bool isCustomized, String label, DateTime? clearedAt, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
String id, int attitude, bool isOnline, bool isInvisible, bool isNotDisturb, bool isCustomized, String label, Map<String, dynamic>? meta, DateTime? clearedAt, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
@@ -1300,7 +1629,7 @@ class __$SnAccountStatusCopyWithImpl<$Res>
/// Create a copy of SnAccountStatus
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? attitude = null,Object? isOnline = null,Object? isInvisible = null,Object? isNotDisturb = null,Object? isCustomized = null,Object? label = null,Object? clearedAt = freezed,Object? accountId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? attitude = null,Object? isOnline = null,Object? isInvisible = null,Object? isNotDisturb = null,Object? isCustomized = null,Object? label = null,Object? meta = freezed,Object? clearedAt = freezed,Object? accountId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
return _then(_SnAccountStatus(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,attitude: null == attitude ? _self.attitude : attitude // ignore: cast_nullable_to_non_nullable
@@ -1309,7 +1638,8 @@ as bool,isInvisible: null == isInvisible ? _self.isInvisible : isInvisible // ig
as bool,isNotDisturb: null == isNotDisturb ? _self.isNotDisturb : isNotDisturb // ignore: cast_nullable_to_non_nullable
as bool,isCustomized: null == isCustomized ? _self.isCustomized : isCustomized // ignore: cast_nullable_to_non_nullable
as bool,label: null == label ? _self.label : label // ignore: cast_nullable_to_non_nullable
as String,clearedAt: freezed == clearedAt ? _self.clearedAt : clearedAt // ignore: cast_nullable_to_non_nullable
as String,meta: freezed == meta ? _self._meta : meta // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>?,clearedAt: freezed == clearedAt ? _self.clearedAt : clearedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
@@ -1618,7 +1948,7 @@ as DateTime?,
/// @nodoc
mixin _$SnContactMethod {
String get id; int get type; DateTime? get verifiedAt; bool get isPrimary; String get content; String get accountId; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
String get id; int get type; DateTime? get verifiedAt; bool get isPrimary; bool get isPublic; String get content; String get accountId; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
/// Create a copy of SnContactMethod
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -1631,16 +1961,16 @@ $SnContactMethodCopyWith<SnContactMethod> get copyWith => _$SnContactMethodCopyW
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnContactMethod&&(identical(other.id, id) || other.id == id)&&(identical(other.type, type) || other.type == type)&&(identical(other.verifiedAt, verifiedAt) || other.verifiedAt == verifiedAt)&&(identical(other.isPrimary, isPrimary) || other.isPrimary == isPrimary)&&(identical(other.content, content) || other.content == content)&&(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 SnContactMethod&&(identical(other.id, id) || other.id == id)&&(identical(other.type, type) || other.type == type)&&(identical(other.verifiedAt, verifiedAt) || other.verifiedAt == verifiedAt)&&(identical(other.isPrimary, isPrimary) || other.isPrimary == isPrimary)&&(identical(other.isPublic, isPublic) || other.isPublic == isPublic)&&(identical(other.content, content) || other.content == content)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,type,verifiedAt,isPrimary,content,accountId,createdAt,updatedAt,deletedAt);
int get hashCode => Object.hash(runtimeType,id,type,verifiedAt,isPrimary,isPublic,content,accountId,createdAt,updatedAt,deletedAt);
@override
String toString() {
return 'SnContactMethod(id: $id, type: $type, verifiedAt: $verifiedAt, isPrimary: $isPrimary, content: $content, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
return 'SnContactMethod(id: $id, type: $type, verifiedAt: $verifiedAt, isPrimary: $isPrimary, isPublic: $isPublic, content: $content, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
@@ -1651,7 +1981,7 @@ abstract mixin class $SnContactMethodCopyWith<$Res> {
factory $SnContactMethodCopyWith(SnContactMethod value, $Res Function(SnContactMethod) _then) = _$SnContactMethodCopyWithImpl;
@useResult
$Res call({
String id, int type, DateTime? verifiedAt, bool isPrimary, String content, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
String id, int type, DateTime? verifiedAt, bool isPrimary, bool isPublic, String content, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
@@ -1668,12 +1998,13 @@ class _$SnContactMethodCopyWithImpl<$Res>
/// Create a copy of SnContactMethod
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? type = null,Object? verifiedAt = freezed,Object? isPrimary = null,Object? content = null,Object? accountId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? type = null,Object? verifiedAt = freezed,Object? isPrimary = null,Object? isPublic = null,Object? content = null,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,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
as int,verifiedAt: freezed == verifiedAt ? _self.verifiedAt : verifiedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,isPrimary: null == isPrimary ? _self.isPrimary : isPrimary // ignore: cast_nullable_to_non_nullable
as bool,isPublic: null == isPublic ? _self.isPublic : isPublic // ignore: cast_nullable_to_non_nullable
as bool,content: null == content ? _self.content : content // ignore: cast_nullable_to_non_nullable
as String,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
@@ -1761,10 +2092,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, int type, DateTime? verifiedAt, bool isPrimary, String content, 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, int type, DateTime? verifiedAt, bool isPrimary, bool isPublic, String content, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnContactMethod() when $default != null:
return $default(_that.id,_that.type,_that.verifiedAt,_that.isPrimary,_that.content,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return $default(_that.id,_that.type,_that.verifiedAt,_that.isPrimary,_that.isPublic,_that.content,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return orElse();
}
@@ -1782,10 +2113,10 @@ return $default(_that.id,_that.type,_that.verifiedAt,_that.isPrimary,_that.conte
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, int type, DateTime? verifiedAt, bool isPrimary, String content, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, int type, DateTime? verifiedAt, bool isPrimary, bool isPublic, String content, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
switch (_that) {
case _SnContactMethod():
return $default(_that.id,_that.type,_that.verifiedAt,_that.isPrimary,_that.content,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);}
return $default(_that.id,_that.type,_that.verifiedAt,_that.isPrimary,_that.isPublic,_that.content,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);}
}
/// A variant of `when` that fallback to returning `null`
///
@@ -1799,10 +2130,10 @@ return $default(_that.id,_that.type,_that.verifiedAt,_that.isPrimary,_that.conte
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, int type, DateTime? verifiedAt, bool isPrimary, String content, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, int type, DateTime? verifiedAt, bool isPrimary, bool isPublic, String content, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
switch (_that) {
case _SnContactMethod() when $default != null:
return $default(_that.id,_that.type,_that.verifiedAt,_that.isPrimary,_that.content,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return $default(_that.id,_that.type,_that.verifiedAt,_that.isPrimary,_that.isPublic,_that.content,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return null;
}
@@ -1814,13 +2145,14 @@ return $default(_that.id,_that.type,_that.verifiedAt,_that.isPrimary,_that.conte
@JsonSerializable()
class _SnContactMethod implements SnContactMethod {
const _SnContactMethod({required this.id, required this.type, required this.verifiedAt, required this.isPrimary, required this.content, required this.accountId, required this.createdAt, required this.updatedAt, required this.deletedAt});
const _SnContactMethod({required this.id, required this.type, required this.verifiedAt, required this.isPrimary, required this.isPublic, required this.content, required this.accountId, required this.createdAt, required this.updatedAt, required this.deletedAt});
factory _SnContactMethod.fromJson(Map<String, dynamic> json) => _$SnContactMethodFromJson(json);
@override final String id;
@override final int type;
@override final DateTime? verifiedAt;
@override final bool isPrimary;
@override final bool isPublic;
@override final String content;
@override final String accountId;
@override final DateTime createdAt;
@@ -1840,16 +2172,16 @@ Map<String, dynamic> toJson() {
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnContactMethod&&(identical(other.id, id) || other.id == id)&&(identical(other.type, type) || other.type == type)&&(identical(other.verifiedAt, verifiedAt) || other.verifiedAt == verifiedAt)&&(identical(other.isPrimary, isPrimary) || other.isPrimary == isPrimary)&&(identical(other.content, content) || other.content == content)&&(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 _SnContactMethod&&(identical(other.id, id) || other.id == id)&&(identical(other.type, type) || other.type == type)&&(identical(other.verifiedAt, verifiedAt) || other.verifiedAt == verifiedAt)&&(identical(other.isPrimary, isPrimary) || other.isPrimary == isPrimary)&&(identical(other.isPublic, isPublic) || other.isPublic == isPublic)&&(identical(other.content, content) || other.content == content)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,type,verifiedAt,isPrimary,content,accountId,createdAt,updatedAt,deletedAt);
int get hashCode => Object.hash(runtimeType,id,type,verifiedAt,isPrimary,isPublic,content,accountId,createdAt,updatedAt,deletedAt);
@override
String toString() {
return 'SnContactMethod(id: $id, type: $type, verifiedAt: $verifiedAt, isPrimary: $isPrimary, content: $content, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
return 'SnContactMethod(id: $id, type: $type, verifiedAt: $verifiedAt, isPrimary: $isPrimary, isPublic: $isPublic, content: $content, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
@@ -1860,7 +2192,7 @@ abstract mixin class _$SnContactMethodCopyWith<$Res> implements $SnContactMethod
factory _$SnContactMethodCopyWith(_SnContactMethod value, $Res Function(_SnContactMethod) _then) = __$SnContactMethodCopyWithImpl;
@override @useResult
$Res call({
String id, int type, DateTime? verifiedAt, bool isPrimary, String content, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
String id, int type, DateTime? verifiedAt, bool isPrimary, bool isPublic, String content, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
@@ -1877,12 +2209,13 @@ class __$SnContactMethodCopyWithImpl<$Res>
/// Create a copy of SnContactMethod
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? type = null,Object? verifiedAt = freezed,Object? isPrimary = null,Object? content = null,Object? accountId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? type = null,Object? verifiedAt = freezed,Object? isPrimary = null,Object? isPublic = null,Object? content = null,Object? accountId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
return _then(_SnContactMethod(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
as int,verifiedAt: freezed == verifiedAt ? _self.verifiedAt : verifiedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,isPrimary: null == isPrimary ? _self.isPrimary : isPrimary // ignore: cast_nullable_to_non_nullable
as bool,isPublic: null == isPublic ? _self.isPublic : isPublic // ignore: cast_nullable_to_non_nullable
as bool,content: null == content ? _self.content : content // ignore: cast_nullable_to_non_nullable
as String,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable

View File

@@ -11,6 +11,7 @@ _SnAccount _$SnAccountFromJson(Map<String, dynamic> json) => _SnAccount(
name: json['name'] as String,
nick: json['nick'] as String,
language: json['language'] as String,
region: json['region'] as String? ?? "",
isSuperuser: json['is_superuser'] as bool,
automatedId: json['automated_id'] as String?,
profile: SnAccountProfile.fromJson(json['profile'] as Map<String, dynamic>),
@@ -25,6 +26,11 @@ _SnAccount _$SnAccountFromJson(Map<String, dynamic> json) => _SnAccount(
?.map((e) => SnAccountBadge.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
contacts:
(json['contacts'] as List<dynamic>?)
?.map((e) => SnContactMethod.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
createdAt: DateTime.parse(json['created_at'] as String),
updatedAt: DateTime.parse(json['updated_at'] as String),
deletedAt:
@@ -39,11 +45,13 @@ Map<String, dynamic> _$SnAccountToJson(_SnAccount instance) =>
'name': instance.name,
'nick': instance.nick,
'language': instance.language,
'region': instance.region,
'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(),
'contacts': instance.contacts.map((e) => e.toJson()).toList(),
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
@@ -55,6 +63,23 @@ _ProfileLink _$ProfileLinkFromJson(Map<String, dynamic> json) =>
Map<String, dynamic> _$ProfileLinkToJson(_ProfileLink instance) =>
<String, dynamic>{'name': instance.name, 'url': instance.url};
_UsernameColor _$UsernameColorFromJson(Map<String, dynamic> json) =>
_UsernameColor(
type: json['type'] as String? ?? 'plain',
value: json['value'] as String?,
direction: json['direction'] as String?,
colors:
(json['colors'] as List<dynamic>?)?.map((e) => e as String).toList(),
);
Map<String, dynamic> _$UsernameColorToJson(_UsernameColor instance) =>
<String, dynamic>{
'type': instance.type,
'value': instance.value,
'direction': instance.direction,
'colors': instance.colors,
};
_SnAccountProfile _$SnAccountProfileFromJson(Map<String, dynamic> json) =>
_SnAccountProfile(
id: json['id'] as String,
@@ -86,6 +111,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
@@ -103,6 +130,12 @@ _SnAccountProfile _$SnAccountProfileFromJson(Map<String, dynamic> json) =>
: SnVerificationMark.fromJson(
json['verification'] as Map<String, dynamic>,
),
usernameColor:
json['username_color'] == null
? null
: UsernameColor.fromJson(
json['username_color'] as Map<String, dynamic>,
),
createdAt: DateTime.parse(json['created_at'] as String),
updatedAt: DateTime.parse(json['updated_at'] as String),
deletedAt:
@@ -128,10 +161,13 @@ Map<String, dynamic> _$SnAccountProfileToJson(_SnAccountProfile instance) =>
'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(),
'username_color': instance.usernameColor?.toJson(),
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
@@ -146,6 +182,7 @@ _SnAccountStatus _$SnAccountStatusFromJson(Map<String, dynamic> json) =>
isNotDisturb: json['is_not_disturb'] as bool,
isCustomized: json['is_customized'] as bool,
label: json['label'] as String? ?? "",
meta: json['meta'] as Map<String, dynamic>?,
clearedAt:
json['cleared_at'] == null
? null
@@ -168,6 +205,7 @@ Map<String, dynamic> _$SnAccountStatusToJson(_SnAccountStatus instance) =>
'is_not_disturb': instance.isNotDisturb,
'is_customized': instance.isCustomized,
'label': instance.label,
'meta': instance.meta,
'cleared_at': instance.clearedAt?.toIso8601String(),
'account_id': instance.accountId,
'created_at': instance.createdAt.toIso8601String(),
@@ -223,6 +261,7 @@ _SnContactMethod _$SnContactMethodFromJson(Map<String, dynamic> json) =>
? null
: DateTime.parse(json['verified_at'] as String),
isPrimary: json['is_primary'] as bool,
isPublic: json['is_public'] as bool,
content: json['content'] as String,
accountId: json['account_id'] as String,
createdAt: DateTime.parse(json['created_at'] as String),
@@ -239,6 +278,7 @@ Map<String, dynamic> _$SnContactMethodToJson(_SnContactMethod instance) =>
'type': instance.type,
'verified_at': instance.verifiedAt?.toIso8601String(),
'is_primary': instance.isPrimary,
'is_public': instance.isPublic,
'content': instance.content,
'account_id': instance.accountId,
'created_at': instance.createdAt.toIso8601String(),

View File

@@ -4,6 +4,20 @@ import 'package:island/models/account.dart';
part 'activity.freezed.dart';
part 'activity.g.dart';
@freezed
sealed class SnNotableDay with _$SnNotableDay {
const factory SnNotableDay({
required DateTime date,
required String localName,
required String globalName,
required String countryCode,
required List<int> holidays,
}) = _SnNotableDay;
factory SnNotableDay.fromJson(Map<String, dynamic> json) =>
_$SnNotableDayFromJson(json);
}
@freezed
sealed class SnActivity with _$SnActivity {
const factory SnActivity({
@@ -54,7 +68,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

@@ -12,6 +12,281 @@ part of 'activity.dart';
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$SnNotableDay {
DateTime get date; String get localName; String get globalName; String get countryCode; List<int> get holidays;
/// Create a copy of SnNotableDay
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$SnNotableDayCopyWith<SnNotableDay> get copyWith => _$SnNotableDayCopyWithImpl<SnNotableDay>(this as SnNotableDay, _$identity);
/// Serializes this SnNotableDay to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnNotableDay&&(identical(other.date, date) || other.date == date)&&(identical(other.localName, localName) || other.localName == localName)&&(identical(other.globalName, globalName) || other.globalName == globalName)&&(identical(other.countryCode, countryCode) || other.countryCode == countryCode)&&const DeepCollectionEquality().equals(other.holidays, holidays));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,date,localName,globalName,countryCode,const DeepCollectionEquality().hash(holidays));
@override
String toString() {
return 'SnNotableDay(date: $date, localName: $localName, globalName: $globalName, countryCode: $countryCode, holidays: $holidays)';
}
}
/// @nodoc
abstract mixin class $SnNotableDayCopyWith<$Res> {
factory $SnNotableDayCopyWith(SnNotableDay value, $Res Function(SnNotableDay) _then) = _$SnNotableDayCopyWithImpl;
@useResult
$Res call({
DateTime date, String localName, String globalName, String countryCode, List<int> holidays
});
}
/// @nodoc
class _$SnNotableDayCopyWithImpl<$Res>
implements $SnNotableDayCopyWith<$Res> {
_$SnNotableDayCopyWithImpl(this._self, this._then);
final SnNotableDay _self;
final $Res Function(SnNotableDay) _then;
/// Create a copy of SnNotableDay
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? date = null,Object? localName = null,Object? globalName = null,Object? countryCode = null,Object? holidays = null,}) {
return _then(_self.copyWith(
date: null == date ? _self.date : date // ignore: cast_nullable_to_non_nullable
as DateTime,localName: null == localName ? _self.localName : localName // ignore: cast_nullable_to_non_nullable
as String,globalName: null == globalName ? _self.globalName : globalName // ignore: cast_nullable_to_non_nullable
as String,countryCode: null == countryCode ? _self.countryCode : countryCode // ignore: cast_nullable_to_non_nullable
as String,holidays: null == holidays ? _self.holidays : holidays // ignore: cast_nullable_to_non_nullable
as List<int>,
));
}
}
/// Adds pattern-matching-related methods to [SnNotableDay].
extension SnNotableDayPatterns on SnNotableDay {
/// 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( _SnNotableDay value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _SnNotableDay() 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( _SnNotableDay value) $default,){
final _that = this;
switch (_that) {
case _SnNotableDay():
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( _SnNotableDay value)? $default,){
final _that = this;
switch (_that) {
case _SnNotableDay() 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( DateTime date, String localName, String globalName, String countryCode, List<int> holidays)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnNotableDay() when $default != null:
return $default(_that.date,_that.localName,_that.globalName,_that.countryCode,_that.holidays);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( DateTime date, String localName, String globalName, String countryCode, List<int> holidays) $default,) {final _that = this;
switch (_that) {
case _SnNotableDay():
return $default(_that.date,_that.localName,_that.globalName,_that.countryCode,_that.holidays);}
}
/// 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( DateTime date, String localName, String globalName, String countryCode, List<int> holidays)? $default,) {final _that = this;
switch (_that) {
case _SnNotableDay() when $default != null:
return $default(_that.date,_that.localName,_that.globalName,_that.countryCode,_that.holidays);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _SnNotableDay implements SnNotableDay {
const _SnNotableDay({required this.date, required this.localName, required this.globalName, required this.countryCode, required final List<int> holidays}): _holidays = holidays;
factory _SnNotableDay.fromJson(Map<String, dynamic> json) => _$SnNotableDayFromJson(json);
@override final DateTime date;
@override final String localName;
@override final String globalName;
@override final String countryCode;
final List<int> _holidays;
@override List<int> get holidays {
if (_holidays is EqualUnmodifiableListView) return _holidays;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_holidays);
}
/// Create a copy of SnNotableDay
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$SnNotableDayCopyWith<_SnNotableDay> get copyWith => __$SnNotableDayCopyWithImpl<_SnNotableDay>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$SnNotableDayToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnNotableDay&&(identical(other.date, date) || other.date == date)&&(identical(other.localName, localName) || other.localName == localName)&&(identical(other.globalName, globalName) || other.globalName == globalName)&&(identical(other.countryCode, countryCode) || other.countryCode == countryCode)&&const DeepCollectionEquality().equals(other._holidays, _holidays));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,date,localName,globalName,countryCode,const DeepCollectionEquality().hash(_holidays));
@override
String toString() {
return 'SnNotableDay(date: $date, localName: $localName, globalName: $globalName, countryCode: $countryCode, holidays: $holidays)';
}
}
/// @nodoc
abstract mixin class _$SnNotableDayCopyWith<$Res> implements $SnNotableDayCopyWith<$Res> {
factory _$SnNotableDayCopyWith(_SnNotableDay value, $Res Function(_SnNotableDay) _then) = __$SnNotableDayCopyWithImpl;
@override @useResult
$Res call({
DateTime date, String localName, String globalName, String countryCode, List<int> holidays
});
}
/// @nodoc
class __$SnNotableDayCopyWithImpl<$Res>
implements _$SnNotableDayCopyWith<$Res> {
__$SnNotableDayCopyWithImpl(this._self, this._then);
final _SnNotableDay _self;
final $Res Function(_SnNotableDay) _then;
/// Create a copy of SnNotableDay
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? date = null,Object? localName = null,Object? globalName = null,Object? countryCode = null,Object? holidays = null,}) {
return _then(_SnNotableDay(
date: null == date ? _self.date : date // ignore: cast_nullable_to_non_nullable
as DateTime,localName: null == localName ? _self.localName : localName // ignore: cast_nullable_to_non_nullable
as String,globalName: null == globalName ? _self.globalName : globalName // ignore: cast_nullable_to_non_nullable
as String,countryCode: null == countryCode ? _self.countryCode : countryCode // ignore: cast_nullable_to_non_nullable
as String,holidays: null == holidays ? _self._holidays : holidays // ignore: cast_nullable_to_non_nullable
as List<int>,
));
}
}
/// @nodoc
mixin _$SnActivity {
@@ -861,7 +1136,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 +1169,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 +1191,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 +1285,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 +1306,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 +1323,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 +1338,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 +1384,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 +1406,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

@@ -6,6 +6,27 @@ part of 'activity.dart';
// JsonSerializableGenerator
// **************************************************************************
_SnNotableDay _$SnNotableDayFromJson(Map<String, dynamic> json) =>
_SnNotableDay(
date: DateTime.parse(json['date'] as String),
localName: json['local_name'] as String,
globalName: json['global_name'] as String,
countryCode: json['country_code'] as String,
holidays:
(json['holidays'] as List<dynamic>)
.map((e) => (e as num).toInt())
.toList(),
);
Map<String, dynamic> _$SnNotableDayToJson(_SnNotableDay instance) =>
<String, dynamic>{
'date': instance.date.toIso8601String(),
'local_name': instance.localName,
'global_name': instance.globalName,
'country_code': instance.countryCode,
'holidays': instance.holidays,
};
_SnActivity _$SnActivityFromJson(Map<String, dynamic> json) => _SnActivity(
id: json['id'] as String,
type: json['type'] as String,
@@ -87,7 +108,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 +119,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

@@ -11,11 +11,25 @@ sealed class AppToken with _$AppToken {
_$AppTokenFromJson(json);
}
@freezed
sealed class GeoIpLocation with _$GeoIpLocation {
const factory GeoIpLocation({
required double? latitude,
required double? longitude,
required String? countryCode,
required String? country,
required String? city,
}) = _GeoIpLocation;
factory GeoIpLocation.fromJson(Map<String, dynamic> json) =>
_$GeoIpLocationFromJson(json);
}
@freezed
sealed class SnAuthChallenge with _$SnAuthChallenge {
const factory SnAuthChallenge({
required String id,
required DateTime expiredAt,
required DateTime? expiredAt,
required int stepRemain,
required int stepTotal,
required int failedAttempts,
@@ -26,7 +40,7 @@ sealed class SnAuthChallenge with _$SnAuthChallenge {
required String ipAddress,
required String userAgent,
required String? nonce,
required String? location,
required GeoIpLocation? location,
required String accountId,
required DateTime createdAt,
required DateTime updatedAt,
@@ -43,7 +57,7 @@ sealed class SnAuthSession with _$SnAuthSession {
required String id,
required String? label,
required DateTime lastGrantedAt,
required DateTime expiredAt,
required DateTime? expiredAt,
required String accountId,
required String challengeId,
required SnAuthChallenge challenge,

View File

@@ -269,10 +269,279 @@ as String,
}
/// @nodoc
mixin _$GeoIpLocation {
double? get latitude; double? get longitude; String? get countryCode; String? get country; String? get city;
/// Create a copy of GeoIpLocation
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$GeoIpLocationCopyWith<GeoIpLocation> get copyWith => _$GeoIpLocationCopyWithImpl<GeoIpLocation>(this as GeoIpLocation, _$identity);
/// Serializes this GeoIpLocation to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is GeoIpLocation&&(identical(other.latitude, latitude) || other.latitude == latitude)&&(identical(other.longitude, longitude) || other.longitude == longitude)&&(identical(other.countryCode, countryCode) || other.countryCode == countryCode)&&(identical(other.country, country) || other.country == country)&&(identical(other.city, city) || other.city == city));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,latitude,longitude,countryCode,country,city);
@override
String toString() {
return 'GeoIpLocation(latitude: $latitude, longitude: $longitude, countryCode: $countryCode, country: $country, city: $city)';
}
}
/// @nodoc
abstract mixin class $GeoIpLocationCopyWith<$Res> {
factory $GeoIpLocationCopyWith(GeoIpLocation value, $Res Function(GeoIpLocation) _then) = _$GeoIpLocationCopyWithImpl;
@useResult
$Res call({
double? latitude, double? longitude, String? countryCode, String? country, String? city
});
}
/// @nodoc
class _$GeoIpLocationCopyWithImpl<$Res>
implements $GeoIpLocationCopyWith<$Res> {
_$GeoIpLocationCopyWithImpl(this._self, this._then);
final GeoIpLocation _self;
final $Res Function(GeoIpLocation) _then;
/// Create a copy of GeoIpLocation
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? latitude = freezed,Object? longitude = freezed,Object? countryCode = freezed,Object? country = freezed,Object? city = freezed,}) {
return _then(_self.copyWith(
latitude: freezed == latitude ? _self.latitude : latitude // ignore: cast_nullable_to_non_nullable
as double?,longitude: freezed == longitude ? _self.longitude : longitude // ignore: cast_nullable_to_non_nullable
as double?,countryCode: freezed == countryCode ? _self.countryCode : countryCode // ignore: cast_nullable_to_non_nullable
as String?,country: freezed == country ? _self.country : country // ignore: cast_nullable_to_non_nullable
as String?,city: freezed == city ? _self.city : city // ignore: cast_nullable_to_non_nullable
as String?,
));
}
}
/// Adds pattern-matching-related methods to [GeoIpLocation].
extension GeoIpLocationPatterns on GeoIpLocation {
/// 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( _GeoIpLocation value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _GeoIpLocation() 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( _GeoIpLocation value) $default,){
final _that = this;
switch (_that) {
case _GeoIpLocation():
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( _GeoIpLocation value)? $default,){
final _that = this;
switch (_that) {
case _GeoIpLocation() 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( double? latitude, double? longitude, String? countryCode, String? country, String? city)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _GeoIpLocation() when $default != null:
return $default(_that.latitude,_that.longitude,_that.countryCode,_that.country,_that.city);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( double? latitude, double? longitude, String? countryCode, String? country, String? city) $default,) {final _that = this;
switch (_that) {
case _GeoIpLocation():
return $default(_that.latitude,_that.longitude,_that.countryCode,_that.country,_that.city);}
}
/// 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( double? latitude, double? longitude, String? countryCode, String? country, String? city)? $default,) {final _that = this;
switch (_that) {
case _GeoIpLocation() when $default != null:
return $default(_that.latitude,_that.longitude,_that.countryCode,_that.country,_that.city);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _GeoIpLocation implements GeoIpLocation {
const _GeoIpLocation({required this.latitude, required this.longitude, required this.countryCode, required this.country, required this.city});
factory _GeoIpLocation.fromJson(Map<String, dynamic> json) => _$GeoIpLocationFromJson(json);
@override final double? latitude;
@override final double? longitude;
@override final String? countryCode;
@override final String? country;
@override final String? city;
/// Create a copy of GeoIpLocation
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$GeoIpLocationCopyWith<_GeoIpLocation> get copyWith => __$GeoIpLocationCopyWithImpl<_GeoIpLocation>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$GeoIpLocationToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _GeoIpLocation&&(identical(other.latitude, latitude) || other.latitude == latitude)&&(identical(other.longitude, longitude) || other.longitude == longitude)&&(identical(other.countryCode, countryCode) || other.countryCode == countryCode)&&(identical(other.country, country) || other.country == country)&&(identical(other.city, city) || other.city == city));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,latitude,longitude,countryCode,country,city);
@override
String toString() {
return 'GeoIpLocation(latitude: $latitude, longitude: $longitude, countryCode: $countryCode, country: $country, city: $city)';
}
}
/// @nodoc
abstract mixin class _$GeoIpLocationCopyWith<$Res> implements $GeoIpLocationCopyWith<$Res> {
factory _$GeoIpLocationCopyWith(_GeoIpLocation value, $Res Function(_GeoIpLocation) _then) = __$GeoIpLocationCopyWithImpl;
@override @useResult
$Res call({
double? latitude, double? longitude, String? countryCode, String? country, String? city
});
}
/// @nodoc
class __$GeoIpLocationCopyWithImpl<$Res>
implements _$GeoIpLocationCopyWith<$Res> {
__$GeoIpLocationCopyWithImpl(this._self, this._then);
final _GeoIpLocation _self;
final $Res Function(_GeoIpLocation) _then;
/// Create a copy of GeoIpLocation
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? latitude = freezed,Object? longitude = freezed,Object? countryCode = freezed,Object? country = freezed,Object? city = freezed,}) {
return _then(_GeoIpLocation(
latitude: freezed == latitude ? _self.latitude : latitude // ignore: cast_nullable_to_non_nullable
as double?,longitude: freezed == longitude ? _self.longitude : longitude // ignore: cast_nullable_to_non_nullable
as double?,countryCode: freezed == countryCode ? _self.countryCode : countryCode // ignore: cast_nullable_to_non_nullable
as String?,country: freezed == country ? _self.country : country // ignore: cast_nullable_to_non_nullable
as String?,city: freezed == city ? _self.city : city // ignore: cast_nullable_to_non_nullable
as String?,
));
}
}
/// @nodoc
mixin _$SnAuthChallenge {
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;
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; GeoIpLocation? 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)
@@ -305,11 +574,11 @@ 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 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
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, GeoIpLocation? location, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
$GeoIpLocationCopyWith<$Res>? get location;
}
/// @nodoc
@@ -322,11 +591,11 @@ 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? 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,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? expiredAt = freezed,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 String,expiredAt: freezed == 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,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
@@ -337,14 +606,26 @@ as List<dynamic>,ipAddress: null == ipAddress ? _self.ipAddress : ipAddress // i
as String,userAgent: null == userAgent ? _self.userAgent : userAgent // 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
as GeoIpLocation?,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,
));
}
/// Create a copy of SnAuthChallenge
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$GeoIpLocationCopyWith<$Res>? get location {
if (_self.location == null) {
return null;
}
return $GeoIpLocationCopyWith<$Res>(_self.location!, (value) {
return _then(_self.copyWith(location: value));
});
}
}
@@ -423,7 +704,7 @@ return $default(_that);case _:
/// }
/// ```
@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;
@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, GeoIpLocation? 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.type,_that.blacklistFactors,_that.audiences,_that.scopes,_that.ipAddress,_that.userAgent,_that.nonce,_that.location,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
@@ -444,7 +725,7 @@ 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 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;
@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, GeoIpLocation? 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.type,_that.blacklistFactors,_that.audiences,_that.scopes,_that.ipAddress,_that.userAgent,_that.nonce,_that.location,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);}
@@ -461,7 +742,7 @@ 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 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;
@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, GeoIpLocation? 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.type,_that.blacklistFactors,_that.audiences,_that.scopes,_that.ipAddress,_that.userAgent,_that.nonce,_that.location,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
@@ -480,7 +761,7 @@ class _SnAuthChallenge implements SnAuthChallenge {
factory _SnAuthChallenge.fromJson(Map<String, dynamic> json) => _$SnAuthChallengeFromJson(json);
@override final String id;
@override final DateTime expiredAt;
@override final DateTime? expiredAt;
@override final int stepRemain;
@override final int stepTotal;
@override final int failedAttempts;
@@ -509,7 +790,7 @@ class _SnAuthChallenge implements SnAuthChallenge {
@override final String ipAddress;
@override final String userAgent;
@override final String? nonce;
@override final String? location;
@override final GeoIpLocation? location;
@override final String accountId;
@override final DateTime createdAt;
@override final DateTime updatedAt;
@@ -548,11 +829,11 @@ 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 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
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, GeoIpLocation? location, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
@override $GeoIpLocationCopyWith<$Res>? get location;
}
/// @nodoc
@@ -565,11 +846,11 @@ 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? 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,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? expiredAt = freezed,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 String,expiredAt: freezed == 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,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
@@ -580,7 +861,7 @@ as List<dynamic>,ipAddress: null == ipAddress ? _self.ipAddress : ipAddress // i
as String,userAgent: null == userAgent ? _self.userAgent : userAgent // 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
as GeoIpLocation?,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
@@ -588,14 +869,26 @@ as DateTime?,
));
}
/// Create a copy of SnAuthChallenge
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$GeoIpLocationCopyWith<$Res>? get location {
if (_self.location == null) {
return null;
}
return $GeoIpLocationCopyWith<$Res>(_self.location!, (value) {
return _then(_self.copyWith(location: value));
});
}
}
/// @nodoc
mixin _$SnAuthSession {
String get id; String? get label; DateTime get lastGrantedAt; DateTime get expiredAt; String get accountId; String get challengeId; SnAuthChallenge get challenge; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
String get id; String? get label; DateTime get lastGrantedAt; DateTime? get expiredAt; String get accountId; String get challengeId; SnAuthChallenge get challenge; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
/// Create a copy of SnAuthSession
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -628,7 +921,7 @@ abstract mixin class $SnAuthSessionCopyWith<$Res> {
factory $SnAuthSessionCopyWith(SnAuthSession value, $Res Function(SnAuthSession) _then) = _$SnAuthSessionCopyWithImpl;
@useResult
$Res call({
String id, String? label, DateTime lastGrantedAt, DateTime expiredAt, String accountId, String challengeId, SnAuthChallenge challenge, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
String id, String? label, DateTime lastGrantedAt, DateTime? expiredAt, String accountId, String challengeId, SnAuthChallenge challenge, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
@@ -645,13 +938,13 @@ class _$SnAuthSessionCopyWithImpl<$Res>
/// Create a copy of SnAuthSession
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? label = freezed,Object? lastGrantedAt = null,Object? expiredAt = null,Object? accountId = null,Object? challengeId = null,Object? challenge = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? label = freezed,Object? lastGrantedAt = null,Object? expiredAt = freezed,Object? accountId = null,Object? challengeId = null,Object? challenge = 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,label: freezed == label ? _self.label : label // ignore: cast_nullable_to_non_nullable
as String?,lastGrantedAt: null == lastGrantedAt ? _self.lastGrantedAt : lastGrantedAt // ignore: cast_nullable_to_non_nullable
as DateTime,expiredAt: null == expiredAt ? _self.expiredAt : expiredAt // ignore: cast_nullable_to_non_nullable
as DateTime,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
as DateTime,expiredAt: freezed == expiredAt ? _self.expiredAt : expiredAt // ignore: cast_nullable_to_non_nullable
as DateTime?,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
as String,challengeId: null == challengeId ? _self.challengeId : challengeId // ignore: cast_nullable_to_non_nullable
as String,challenge: null == challenge ? _self.challenge : challenge // ignore: cast_nullable_to_non_nullable
as SnAuthChallenge,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
@@ -748,7 +1041,7 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String? label, DateTime lastGrantedAt, DateTime expiredAt, String accountId, String challengeId, SnAuthChallenge challenge, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String? label, DateTime lastGrantedAt, DateTime? expiredAt, String accountId, String challengeId, SnAuthChallenge challenge, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnAuthSession() when $default != null:
return $default(_that.id,_that.label,_that.lastGrantedAt,_that.expiredAt,_that.accountId,_that.challengeId,_that.challenge,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
@@ -769,7 +1062,7 @@ return $default(_that.id,_that.label,_that.lastGrantedAt,_that.expiredAt,_that.a
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String? label, DateTime lastGrantedAt, DateTime expiredAt, String accountId, String challengeId, SnAuthChallenge challenge, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String? label, DateTime lastGrantedAt, DateTime? expiredAt, String accountId, String challengeId, SnAuthChallenge challenge, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
switch (_that) {
case _SnAuthSession():
return $default(_that.id,_that.label,_that.lastGrantedAt,_that.expiredAt,_that.accountId,_that.challengeId,_that.challenge,_that.createdAt,_that.updatedAt,_that.deletedAt);}
@@ -786,7 +1079,7 @@ return $default(_that.id,_that.label,_that.lastGrantedAt,_that.expiredAt,_that.a
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String? label, DateTime lastGrantedAt, DateTime expiredAt, String accountId, String challengeId, SnAuthChallenge challenge, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String? label, DateTime lastGrantedAt, DateTime? expiredAt, String accountId, String challengeId, SnAuthChallenge challenge, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
switch (_that) {
case _SnAuthSession() when $default != null:
return $default(_that.id,_that.label,_that.lastGrantedAt,_that.expiredAt,_that.accountId,_that.challengeId,_that.challenge,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
@@ -807,7 +1100,7 @@ class _SnAuthSession implements SnAuthSession {
@override final String id;
@override final String? label;
@override final DateTime lastGrantedAt;
@override final DateTime expiredAt;
@override final DateTime? expiredAt;
@override final String accountId;
@override final String challengeId;
@override final SnAuthChallenge challenge;
@@ -848,7 +1141,7 @@ abstract mixin class _$SnAuthSessionCopyWith<$Res> implements $SnAuthSessionCopy
factory _$SnAuthSessionCopyWith(_SnAuthSession value, $Res Function(_SnAuthSession) _then) = __$SnAuthSessionCopyWithImpl;
@override @useResult
$Res call({
String id, String? label, DateTime lastGrantedAt, DateTime expiredAt, String accountId, String challengeId, SnAuthChallenge challenge, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
String id, String? label, DateTime lastGrantedAt, DateTime? expiredAt, String accountId, String challengeId, SnAuthChallenge challenge, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
@@ -865,13 +1158,13 @@ class __$SnAuthSessionCopyWithImpl<$Res>
/// Create a copy of SnAuthSession
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? label = freezed,Object? lastGrantedAt = null,Object? expiredAt = null,Object? accountId = null,Object? challengeId = null,Object? challenge = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? label = freezed,Object? lastGrantedAt = null,Object? expiredAt = freezed,Object? accountId = null,Object? challengeId = null,Object? challenge = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
return _then(_SnAuthSession(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,label: freezed == label ? _self.label : label // ignore: cast_nullable_to_non_nullable
as String?,lastGrantedAt: null == lastGrantedAt ? _self.lastGrantedAt : lastGrantedAt // ignore: cast_nullable_to_non_nullable
as DateTime,expiredAt: null == expiredAt ? _self.expiredAt : expiredAt // ignore: cast_nullable_to_non_nullable
as DateTime,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
as DateTime,expiredAt: freezed == expiredAt ? _self.expiredAt : expiredAt // ignore: cast_nullable_to_non_nullable
as DateTime?,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
as String,challengeId: null == challengeId ? _self.challengeId : challengeId // ignore: cast_nullable_to_non_nullable
as String,challenge: null == challenge ? _self.challenge : challenge // ignore: cast_nullable_to_non_nullable
as SnAuthChallenge,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable

View File

@@ -13,10 +13,31 @@ Map<String, dynamic> _$AppTokenToJson(_AppToken instance) => <String, dynamic>{
'token': instance.token,
};
_GeoIpLocation _$GeoIpLocationFromJson(Map<String, dynamic> json) =>
_GeoIpLocation(
latitude: (json['latitude'] as num?)?.toDouble(),
longitude: (json['longitude'] as num?)?.toDouble(),
countryCode: json['country_code'] as String?,
country: json['country'] as String?,
city: json['city'] as String?,
);
Map<String, dynamic> _$GeoIpLocationToJson(_GeoIpLocation instance) =>
<String, dynamic>{
'latitude': instance.latitude,
'longitude': instance.longitude,
'country_code': instance.countryCode,
'country': instance.country,
'city': instance.city,
};
_SnAuthChallenge _$SnAuthChallengeFromJson(Map<String, dynamic> json) =>
_SnAuthChallenge(
id: json['id'] as String,
expiredAt: DateTime.parse(json['expired_at'] as String),
expiredAt:
json['expired_at'] == null
? null
: DateTime.parse(json['expired_at'] as String),
stepRemain: (json['step_remain'] as num).toInt(),
stepTotal: (json['step_total'] as num).toInt(),
failedAttempts: (json['failed_attempts'] as num).toInt(),
@@ -30,7 +51,12 @@ _SnAuthChallenge _$SnAuthChallengeFromJson(Map<String, dynamic> json) =>
ipAddress: json['ip_address'] as String,
userAgent: json['user_agent'] as String,
nonce: json['nonce'] as String?,
location: json['location'] as String?,
location:
json['location'] == null
? null
: GeoIpLocation.fromJson(
json['location'] as Map<String, dynamic>,
),
accountId: json['account_id'] as String,
createdAt: DateTime.parse(json['created_at'] as String),
updatedAt: DateTime.parse(json['updated_at'] as String),
@@ -43,7 +69,7 @@ _SnAuthChallenge _$SnAuthChallengeFromJson(Map<String, dynamic> json) =>
Map<String, dynamic> _$SnAuthChallengeToJson(_SnAuthChallenge instance) =>
<String, dynamic>{
'id': instance.id,
'expired_at': instance.expiredAt.toIso8601String(),
'expired_at': instance.expiredAt?.toIso8601String(),
'step_remain': instance.stepRemain,
'step_total': instance.stepTotal,
'failed_attempts': instance.failedAttempts,
@@ -54,7 +80,7 @@ Map<String, dynamic> _$SnAuthChallengeToJson(_SnAuthChallenge instance) =>
'ip_address': instance.ipAddress,
'user_agent': instance.userAgent,
'nonce': instance.nonce,
'location': instance.location,
'location': instance.location?.toJson(),
'account_id': instance.accountId,
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
@@ -66,7 +92,10 @@ _SnAuthSession _$SnAuthSessionFromJson(Map<String, dynamic> json) =>
id: json['id'] as String,
label: json['label'] as String?,
lastGrantedAt: DateTime.parse(json['last_granted_at'] as String),
expiredAt: DateTime.parse(json['expired_at'] as String),
expiredAt:
json['expired_at'] == null
? null
: DateTime.parse(json['expired_at'] as String),
accountId: json['account_id'] as String,
challengeId: json['challenge_id'] as String,
challenge: SnAuthChallenge.fromJson(
@@ -85,7 +114,7 @@ Map<String, dynamic> _$SnAuthSessionToJson(_SnAuthSession instance) =>
'id': instance.id,
'label': instance.label,
'last_granted_at': instance.lastGrantedAt.toIso8601String(),
'expired_at': instance.expiredAt.toIso8601String(),
'expired_at': instance.expiredAt?.toIso8601String(),
'account_id': instance.accountId,
'challenge_id': instance.challengeId,
'challenge': instance.challenge.toJson(),

View File

@@ -0,0 +1,16 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'autocomplete_response.freezed.dart';
part 'autocomplete_response.g.dart';
@freezed
sealed class AutocompleteSuggestion with _$AutocompleteSuggestion {
const factory AutocompleteSuggestion({
required String type,
required String keyword,
required dynamic data,
}) = _AutocompleteSuggestion;
factory AutocompleteSuggestion.fromJson(Map<String, dynamic> json) =>
_$AutocompleteSuggestionFromJson(json);
}

View File

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

View File

@@ -0,0 +1,23 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'autocomplete_response.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_AutocompleteSuggestion _$AutocompleteSuggestionFromJson(
Map<String, dynamic> json,
) => _AutocompleteSuggestion(
type: json['type'] as String,
keyword: json['keyword'] as String,
data: json['data'],
);
Map<String, dynamic> _$AutocompleteSuggestionToJson(
_AutocompleteSuggestion instance,
) => <String, dynamic>{
'type': instance.type,
'keyword': instance.keyword,
'data': instance.data,
};

View File

@@ -40,7 +40,7 @@ sealed class SnChatMessage with _$SnChatMessage {
String? content,
String? nonce,
@Default({}) Map<String, dynamic> meta,
@Default([]) List<String> membersMetioned,
@Default([]) List<String> membersMentioned,
DateTime? editedAt,
@Default([]) List<SnCloudFile> attachments,
@Default([]) List<SnChatReaction> reactions,
@@ -117,23 +117,10 @@ class MessageChangeAction {
static const String delete = "delete";
}
@freezed
sealed class MessageChange with _$MessageChange {
const factory MessageChange({
required String messageId,
required String action,
SnChatMessage? message,
required DateTime timestamp,
}) = _MessageChange;
factory MessageChange.fromJson(Map<String, dynamic> json) =>
_$MessageChangeFromJson(json);
}
@freezed
sealed class MessageSyncResponse with _$MessageSyncResponse {
const factory MessageSyncResponse({
@Default([]) List<MessageChange> changes,
@Default([]) List<SnChatMessage> messages,
required DateTime currentTimestamp,
}) = _MessageSyncResponse;

View File

@@ -391,7 +391,7 @@ $SnRealmCopyWith<$Res>? get realm {
/// @nodoc
mixin _$SnChatMessage {
DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; String get id; String get type; String? get content; String? get nonce; Map<String, dynamic> get meta; List<String> get membersMetioned; DateTime? get editedAt; List<SnCloudFile> get attachments; List<SnChatReaction> get reactions; String? get repliedMessageId; String? get forwardedMessageId; String get senderId; SnChatMember get sender; String get chatRoomId;
DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; String get id; String get type; String? get content; String? get nonce; Map<String, dynamic> get meta; List<String> get membersMentioned; DateTime? get editedAt; List<SnCloudFile> get attachments; List<SnChatReaction> get reactions; String? get repliedMessageId; String? get forwardedMessageId; String get senderId; SnChatMember get sender; String get chatRoomId;
/// Create a copy of SnChatMessage
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -404,16 +404,16 @@ $SnChatMessageCopyWith<SnChatMessage> get copyWith => _$SnChatMessageCopyWithImp
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnChatMessage&&(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.type, type) || other.type == type)&&(identical(other.content, content) || other.content == content)&&(identical(other.nonce, nonce) || other.nonce == nonce)&&const DeepCollectionEquality().equals(other.meta, meta)&&const DeepCollectionEquality().equals(other.membersMetioned, membersMetioned)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&const DeepCollectionEquality().equals(other.attachments, attachments)&&const DeepCollectionEquality().equals(other.reactions, reactions)&&(identical(other.repliedMessageId, repliedMessageId) || other.repliedMessageId == repliedMessageId)&&(identical(other.forwardedMessageId, forwardedMessageId) || other.forwardedMessageId == forwardedMessageId)&&(identical(other.senderId, senderId) || other.senderId == senderId)&&(identical(other.sender, sender) || other.sender == sender)&&(identical(other.chatRoomId, chatRoomId) || other.chatRoomId == chatRoomId));
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnChatMessage&&(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.type, type) || other.type == type)&&(identical(other.content, content) || other.content == content)&&(identical(other.nonce, nonce) || other.nonce == nonce)&&const DeepCollectionEquality().equals(other.meta, meta)&&const DeepCollectionEquality().equals(other.membersMentioned, membersMentioned)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&const DeepCollectionEquality().equals(other.attachments, attachments)&&const DeepCollectionEquality().equals(other.reactions, reactions)&&(identical(other.repliedMessageId, repliedMessageId) || other.repliedMessageId == repliedMessageId)&&(identical(other.forwardedMessageId, forwardedMessageId) || other.forwardedMessageId == forwardedMessageId)&&(identical(other.senderId, senderId) || other.senderId == senderId)&&(identical(other.sender, sender) || other.sender == sender)&&(identical(other.chatRoomId, chatRoomId) || other.chatRoomId == chatRoomId));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,createdAt,updatedAt,deletedAt,id,type,content,nonce,const DeepCollectionEquality().hash(meta),const DeepCollectionEquality().hash(membersMetioned),editedAt,const DeepCollectionEquality().hash(attachments),const DeepCollectionEquality().hash(reactions),repliedMessageId,forwardedMessageId,senderId,sender,chatRoomId);
int get hashCode => Object.hash(runtimeType,createdAt,updatedAt,deletedAt,id,type,content,nonce,const DeepCollectionEquality().hash(meta),const DeepCollectionEquality().hash(membersMentioned),editedAt,const DeepCollectionEquality().hash(attachments),const DeepCollectionEquality().hash(reactions),repliedMessageId,forwardedMessageId,senderId,sender,chatRoomId);
@override
String toString() {
return 'SnChatMessage(createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, id: $id, type: $type, content: $content, nonce: $nonce, meta: $meta, membersMetioned: $membersMetioned, editedAt: $editedAt, attachments: $attachments, reactions: $reactions, repliedMessageId: $repliedMessageId, forwardedMessageId: $forwardedMessageId, senderId: $senderId, sender: $sender, chatRoomId: $chatRoomId)';
return 'SnChatMessage(createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, id: $id, type: $type, content: $content, nonce: $nonce, meta: $meta, membersMentioned: $membersMentioned, editedAt: $editedAt, attachments: $attachments, reactions: $reactions, repliedMessageId: $repliedMessageId, forwardedMessageId: $forwardedMessageId, senderId: $senderId, sender: $sender, chatRoomId: $chatRoomId)';
}
@@ -424,7 +424,7 @@ abstract mixin class $SnChatMessageCopyWith<$Res> {
factory $SnChatMessageCopyWith(SnChatMessage value, $Res Function(SnChatMessage) _then) = _$SnChatMessageCopyWithImpl;
@useResult
$Res call({
DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String type, String? content, String? nonce, Map<String, dynamic> meta, List<String> membersMetioned, DateTime? editedAt, List<SnCloudFile> attachments, List<SnChatReaction> reactions, String? repliedMessageId, String? forwardedMessageId, String senderId, SnChatMember sender, String chatRoomId
DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String type, String? content, String? nonce, Map<String, dynamic> meta, List<String> membersMentioned, DateTime? editedAt, List<SnCloudFile> attachments, List<SnChatReaction> reactions, String? repliedMessageId, String? forwardedMessageId, String senderId, SnChatMember sender, String chatRoomId
});
@@ -441,7 +441,7 @@ class _$SnChatMessageCopyWithImpl<$Res>
/// Create a copy of SnChatMessage
/// 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? type = null,Object? content = freezed,Object? nonce = freezed,Object? meta = null,Object? membersMetioned = null,Object? editedAt = freezed,Object? attachments = null,Object? reactions = null,Object? repliedMessageId = freezed,Object? forwardedMessageId = freezed,Object? senderId = null,Object? sender = null,Object? chatRoomId = null,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? id = null,Object? type = null,Object? content = freezed,Object? nonce = freezed,Object? meta = null,Object? membersMentioned = null,Object? editedAt = freezed,Object? attachments = null,Object? reactions = null,Object? repliedMessageId = freezed,Object? forwardedMessageId = freezed,Object? senderId = null,Object? sender = null,Object? chatRoomId = null,}) {
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
@@ -451,7 +451,7 @@ as String,type: null == type ? _self.type : type // ignore: cast_nullable_to_non
as String,content: freezed == content ? _self.content : content // ignore: cast_nullable_to_non_nullable
as String?,nonce: freezed == nonce ? _self.nonce : nonce // ignore: cast_nullable_to_non_nullable
as String?,meta: null == meta ? _self.meta : meta // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>,membersMetioned: null == membersMetioned ? _self.membersMetioned : membersMetioned // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>,membersMentioned: null == membersMentioned ? _self.membersMentioned : membersMentioned // ignore: cast_nullable_to_non_nullable
as List<String>,editedAt: freezed == editedAt ? _self.editedAt : editedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,attachments: null == attachments ? _self.attachments : attachments // ignore: cast_nullable_to_non_nullable
as List<SnCloudFile>,reactions: null == reactions ? _self.reactions : reactions // ignore: cast_nullable_to_non_nullable
@@ -551,10 +551,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String type, String? content, String? nonce, Map<String, dynamic> meta, List<String> membersMetioned, DateTime? editedAt, List<SnCloudFile> attachments, List<SnChatReaction> reactions, String? repliedMessageId, String? forwardedMessageId, String senderId, SnChatMember sender, String chatRoomId)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String type, String? content, String? nonce, Map<String, dynamic> meta, List<String> membersMentioned, DateTime? editedAt, List<SnCloudFile> attachments, List<SnChatReaction> reactions, String? repliedMessageId, String? forwardedMessageId, String senderId, SnChatMember sender, String chatRoomId)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnChatMessage() when $default != null:
return $default(_that.createdAt,_that.updatedAt,_that.deletedAt,_that.id,_that.type,_that.content,_that.nonce,_that.meta,_that.membersMetioned,_that.editedAt,_that.attachments,_that.reactions,_that.repliedMessageId,_that.forwardedMessageId,_that.senderId,_that.sender,_that.chatRoomId);case _:
return $default(_that.createdAt,_that.updatedAt,_that.deletedAt,_that.id,_that.type,_that.content,_that.nonce,_that.meta,_that.membersMentioned,_that.editedAt,_that.attachments,_that.reactions,_that.repliedMessageId,_that.forwardedMessageId,_that.senderId,_that.sender,_that.chatRoomId);case _:
return orElse();
}
@@ -572,10 +572,10 @@ return $default(_that.createdAt,_that.updatedAt,_that.deletedAt,_that.id,_that.t
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String type, String? content, String? nonce, Map<String, dynamic> meta, List<String> membersMetioned, DateTime? editedAt, List<SnCloudFile> attachments, List<SnChatReaction> reactions, String? repliedMessageId, String? forwardedMessageId, String senderId, SnChatMember sender, String chatRoomId) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String type, String? content, String? nonce, Map<String, dynamic> meta, List<String> membersMentioned, DateTime? editedAt, List<SnCloudFile> attachments, List<SnChatReaction> reactions, String? repliedMessageId, String? forwardedMessageId, String senderId, SnChatMember sender, String chatRoomId) $default,) {final _that = this;
switch (_that) {
case _SnChatMessage():
return $default(_that.createdAt,_that.updatedAt,_that.deletedAt,_that.id,_that.type,_that.content,_that.nonce,_that.meta,_that.membersMetioned,_that.editedAt,_that.attachments,_that.reactions,_that.repliedMessageId,_that.forwardedMessageId,_that.senderId,_that.sender,_that.chatRoomId);}
return $default(_that.createdAt,_that.updatedAt,_that.deletedAt,_that.id,_that.type,_that.content,_that.nonce,_that.meta,_that.membersMentioned,_that.editedAt,_that.attachments,_that.reactions,_that.repliedMessageId,_that.forwardedMessageId,_that.senderId,_that.sender,_that.chatRoomId);}
}
/// A variant of `when` that fallback to returning `null`
///
@@ -589,10 +589,10 @@ return $default(_that.createdAt,_that.updatedAt,_that.deletedAt,_that.id,_that.t
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String type, String? content, String? nonce, Map<String, dynamic> meta, List<String> membersMetioned, DateTime? editedAt, List<SnCloudFile> attachments, List<SnChatReaction> reactions, String? repliedMessageId, String? forwardedMessageId, String senderId, SnChatMember sender, String chatRoomId)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String type, String? content, String? nonce, Map<String, dynamic> meta, List<String> membersMentioned, DateTime? editedAt, List<SnCloudFile> attachments, List<SnChatReaction> reactions, String? repliedMessageId, String? forwardedMessageId, String senderId, SnChatMember sender, String chatRoomId)? $default,) {final _that = this;
switch (_that) {
case _SnChatMessage() when $default != null:
return $default(_that.createdAt,_that.updatedAt,_that.deletedAt,_that.id,_that.type,_that.content,_that.nonce,_that.meta,_that.membersMetioned,_that.editedAt,_that.attachments,_that.reactions,_that.repliedMessageId,_that.forwardedMessageId,_that.senderId,_that.sender,_that.chatRoomId);case _:
return $default(_that.createdAt,_that.updatedAt,_that.deletedAt,_that.id,_that.type,_that.content,_that.nonce,_that.meta,_that.membersMentioned,_that.editedAt,_that.attachments,_that.reactions,_that.repliedMessageId,_that.forwardedMessageId,_that.senderId,_that.sender,_that.chatRoomId);case _:
return null;
}
@@ -604,7 +604,7 @@ return $default(_that.createdAt,_that.updatedAt,_that.deletedAt,_that.id,_that.t
@JsonSerializable()
class _SnChatMessage implements SnChatMessage {
const _SnChatMessage({required this.createdAt, required this.updatedAt, this.deletedAt, required this.id, this.type = 'text', this.content, this.nonce, final Map<String, dynamic> meta = const {}, final List<String> membersMetioned = const [], this.editedAt, final List<SnCloudFile> attachments = const [], final List<SnChatReaction> reactions = const [], this.repliedMessageId, this.forwardedMessageId, required this.senderId, required this.sender, required this.chatRoomId}): _meta = meta,_membersMetioned = membersMetioned,_attachments = attachments,_reactions = reactions;
const _SnChatMessage({required this.createdAt, required this.updatedAt, this.deletedAt, required this.id, this.type = 'text', this.content, this.nonce, final Map<String, dynamic> meta = const {}, final List<String> membersMentioned = const [], this.editedAt, final List<SnCloudFile> attachments = const [], final List<SnChatReaction> reactions = const [], this.repliedMessageId, this.forwardedMessageId, required this.senderId, required this.sender, required this.chatRoomId}): _meta = meta,_membersMentioned = membersMentioned,_attachments = attachments,_reactions = reactions;
factory _SnChatMessage.fromJson(Map<String, dynamic> json) => _$SnChatMessageFromJson(json);
@override final DateTime createdAt;
@@ -621,11 +621,11 @@ class _SnChatMessage implements SnChatMessage {
return EqualUnmodifiableMapView(_meta);
}
final List<String> _membersMetioned;
@override@JsonKey() List<String> get membersMetioned {
if (_membersMetioned is EqualUnmodifiableListView) return _membersMetioned;
final List<String> _membersMentioned;
@override@JsonKey() List<String> get membersMentioned {
if (_membersMentioned is EqualUnmodifiableListView) return _membersMentioned;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_membersMetioned);
return EqualUnmodifiableListView(_membersMentioned);
}
@override final DateTime? editedAt;
@@ -662,16 +662,16 @@ Map<String, dynamic> toJson() {
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnChatMessage&&(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.type, type) || other.type == type)&&(identical(other.content, content) || other.content == content)&&(identical(other.nonce, nonce) || other.nonce == nonce)&&const DeepCollectionEquality().equals(other._meta, _meta)&&const DeepCollectionEquality().equals(other._membersMetioned, _membersMetioned)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&const DeepCollectionEquality().equals(other._attachments, _attachments)&&const DeepCollectionEquality().equals(other._reactions, _reactions)&&(identical(other.repliedMessageId, repliedMessageId) || other.repliedMessageId == repliedMessageId)&&(identical(other.forwardedMessageId, forwardedMessageId) || other.forwardedMessageId == forwardedMessageId)&&(identical(other.senderId, senderId) || other.senderId == senderId)&&(identical(other.sender, sender) || other.sender == sender)&&(identical(other.chatRoomId, chatRoomId) || other.chatRoomId == chatRoomId));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnChatMessage&&(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.type, type) || other.type == type)&&(identical(other.content, content) || other.content == content)&&(identical(other.nonce, nonce) || other.nonce == nonce)&&const DeepCollectionEquality().equals(other._meta, _meta)&&const DeepCollectionEquality().equals(other._membersMentioned, _membersMentioned)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&const DeepCollectionEquality().equals(other._attachments, _attachments)&&const DeepCollectionEquality().equals(other._reactions, _reactions)&&(identical(other.repliedMessageId, repliedMessageId) || other.repliedMessageId == repliedMessageId)&&(identical(other.forwardedMessageId, forwardedMessageId) || other.forwardedMessageId == forwardedMessageId)&&(identical(other.senderId, senderId) || other.senderId == senderId)&&(identical(other.sender, sender) || other.sender == sender)&&(identical(other.chatRoomId, chatRoomId) || other.chatRoomId == chatRoomId));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,createdAt,updatedAt,deletedAt,id,type,content,nonce,const DeepCollectionEquality().hash(_meta),const DeepCollectionEquality().hash(_membersMetioned),editedAt,const DeepCollectionEquality().hash(_attachments),const DeepCollectionEquality().hash(_reactions),repliedMessageId,forwardedMessageId,senderId,sender,chatRoomId);
int get hashCode => Object.hash(runtimeType,createdAt,updatedAt,deletedAt,id,type,content,nonce,const DeepCollectionEquality().hash(_meta),const DeepCollectionEquality().hash(_membersMentioned),editedAt,const DeepCollectionEquality().hash(_attachments),const DeepCollectionEquality().hash(_reactions),repliedMessageId,forwardedMessageId,senderId,sender,chatRoomId);
@override
String toString() {
return 'SnChatMessage(createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, id: $id, type: $type, content: $content, nonce: $nonce, meta: $meta, membersMetioned: $membersMetioned, editedAt: $editedAt, attachments: $attachments, reactions: $reactions, repliedMessageId: $repliedMessageId, forwardedMessageId: $forwardedMessageId, senderId: $senderId, sender: $sender, chatRoomId: $chatRoomId)';
return 'SnChatMessage(createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, id: $id, type: $type, content: $content, nonce: $nonce, meta: $meta, membersMentioned: $membersMentioned, editedAt: $editedAt, attachments: $attachments, reactions: $reactions, repliedMessageId: $repliedMessageId, forwardedMessageId: $forwardedMessageId, senderId: $senderId, sender: $sender, chatRoomId: $chatRoomId)';
}
@@ -682,7 +682,7 @@ abstract mixin class _$SnChatMessageCopyWith<$Res> implements $SnChatMessageCopy
factory _$SnChatMessageCopyWith(_SnChatMessage value, $Res Function(_SnChatMessage) _then) = __$SnChatMessageCopyWithImpl;
@override @useResult
$Res call({
DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String type, String? content, String? nonce, Map<String, dynamic> meta, List<String> membersMetioned, DateTime? editedAt, List<SnCloudFile> attachments, List<SnChatReaction> reactions, String? repliedMessageId, String? forwardedMessageId, String senderId, SnChatMember sender, String chatRoomId
DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String type, String? content, String? nonce, Map<String, dynamic> meta, List<String> membersMentioned, DateTime? editedAt, List<SnCloudFile> attachments, List<SnChatReaction> reactions, String? repliedMessageId, String? forwardedMessageId, String senderId, SnChatMember sender, String chatRoomId
});
@@ -699,7 +699,7 @@ class __$SnChatMessageCopyWithImpl<$Res>
/// Create a copy of SnChatMessage
/// 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? type = null,Object? content = freezed,Object? nonce = freezed,Object? meta = null,Object? membersMetioned = null,Object? editedAt = freezed,Object? attachments = null,Object? reactions = null,Object? repliedMessageId = freezed,Object? forwardedMessageId = freezed,Object? senderId = null,Object? sender = null,Object? chatRoomId = null,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? id = null,Object? type = null,Object? content = freezed,Object? nonce = freezed,Object? meta = null,Object? membersMentioned = null,Object? editedAt = freezed,Object? attachments = null,Object? reactions = null,Object? repliedMessageId = freezed,Object? forwardedMessageId = freezed,Object? senderId = null,Object? sender = null,Object? chatRoomId = null,}) {
return _then(_SnChatMessage(
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
@@ -709,7 +709,7 @@ as String,type: null == type ? _self.type : type // ignore: cast_nullable_to_non
as String,content: freezed == content ? _self.content : content // ignore: cast_nullable_to_non_nullable
as String?,nonce: freezed == nonce ? _self.nonce : nonce // ignore: cast_nullable_to_non_nullable
as String?,meta: null == meta ? _self._meta : meta // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>,membersMetioned: null == membersMetioned ? _self._membersMetioned : membersMetioned // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>,membersMentioned: null == membersMentioned ? _self._membersMentioned : membersMentioned // ignore: cast_nullable_to_non_nullable
as List<String>,editedAt: freezed == editedAt ? _self.editedAt : editedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,attachments: null == attachments ? _self._attachments : attachments // ignore: cast_nullable_to_non_nullable
as List<SnCloudFile>,reactions: null == reactions ? _self._reactions : reactions // ignore: cast_nullable_to_non_nullable
@@ -1691,300 +1691,10 @@ $SnChatMessageCopyWith<$Res>? get lastMessage {
}
/// @nodoc
mixin _$MessageChange {
String get messageId; String get action; SnChatMessage? get message; DateTime get timestamp;
/// Create a copy of MessageChange
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$MessageChangeCopyWith<MessageChange> get copyWith => _$MessageChangeCopyWithImpl<MessageChange>(this as MessageChange, _$identity);
/// Serializes this MessageChange to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is MessageChange&&(identical(other.messageId, messageId) || other.messageId == messageId)&&(identical(other.action, action) || other.action == action)&&(identical(other.message, message) || other.message == message)&&(identical(other.timestamp, timestamp) || other.timestamp == timestamp));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,messageId,action,message,timestamp);
@override
String toString() {
return 'MessageChange(messageId: $messageId, action: $action, message: $message, timestamp: $timestamp)';
}
}
/// @nodoc
abstract mixin class $MessageChangeCopyWith<$Res> {
factory $MessageChangeCopyWith(MessageChange value, $Res Function(MessageChange) _then) = _$MessageChangeCopyWithImpl;
@useResult
$Res call({
String messageId, String action, SnChatMessage? message, DateTime timestamp
});
$SnChatMessageCopyWith<$Res>? get message;
}
/// @nodoc
class _$MessageChangeCopyWithImpl<$Res>
implements $MessageChangeCopyWith<$Res> {
_$MessageChangeCopyWithImpl(this._self, this._then);
final MessageChange _self;
final $Res Function(MessageChange) _then;
/// Create a copy of MessageChange
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? messageId = null,Object? action = null,Object? message = freezed,Object? timestamp = null,}) {
return _then(_self.copyWith(
messageId: null == messageId ? _self.messageId : messageId // ignore: cast_nullable_to_non_nullable
as String,action: null == action ? _self.action : action // ignore: cast_nullable_to_non_nullable
as String,message: freezed == message ? _self.message : message // ignore: cast_nullable_to_non_nullable
as SnChatMessage?,timestamp: null == timestamp ? _self.timestamp : timestamp // ignore: cast_nullable_to_non_nullable
as DateTime,
));
}
/// Create a copy of MessageChange
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnChatMessageCopyWith<$Res>? get message {
if (_self.message == null) {
return null;
}
return $SnChatMessageCopyWith<$Res>(_self.message!, (value) {
return _then(_self.copyWith(message: value));
});
}
}
/// Adds pattern-matching-related methods to [MessageChange].
extension MessageChangePatterns on MessageChange {
/// 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( _MessageChange value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _MessageChange() 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( _MessageChange value) $default,){
final _that = this;
switch (_that) {
case _MessageChange():
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( _MessageChange value)? $default,){
final _that = this;
switch (_that) {
case _MessageChange() 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 messageId, String action, SnChatMessage? message, DateTime timestamp)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _MessageChange() when $default != null:
return $default(_that.messageId,_that.action,_that.message,_that.timestamp);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 messageId, String action, SnChatMessage? message, DateTime timestamp) $default,) {final _that = this;
switch (_that) {
case _MessageChange():
return $default(_that.messageId,_that.action,_that.message,_that.timestamp);}
}
/// 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 messageId, String action, SnChatMessage? message, DateTime timestamp)? $default,) {final _that = this;
switch (_that) {
case _MessageChange() when $default != null:
return $default(_that.messageId,_that.action,_that.message,_that.timestamp);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _MessageChange implements MessageChange {
const _MessageChange({required this.messageId, required this.action, this.message, required this.timestamp});
factory _MessageChange.fromJson(Map<String, dynamic> json) => _$MessageChangeFromJson(json);
@override final String messageId;
@override final String action;
@override final SnChatMessage? message;
@override final DateTime timestamp;
/// Create a copy of MessageChange
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$MessageChangeCopyWith<_MessageChange> get copyWith => __$MessageChangeCopyWithImpl<_MessageChange>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$MessageChangeToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _MessageChange&&(identical(other.messageId, messageId) || other.messageId == messageId)&&(identical(other.action, action) || other.action == action)&&(identical(other.message, message) || other.message == message)&&(identical(other.timestamp, timestamp) || other.timestamp == timestamp));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,messageId,action,message,timestamp);
@override
String toString() {
return 'MessageChange(messageId: $messageId, action: $action, message: $message, timestamp: $timestamp)';
}
}
/// @nodoc
abstract mixin class _$MessageChangeCopyWith<$Res> implements $MessageChangeCopyWith<$Res> {
factory _$MessageChangeCopyWith(_MessageChange value, $Res Function(_MessageChange) _then) = __$MessageChangeCopyWithImpl;
@override @useResult
$Res call({
String messageId, String action, SnChatMessage? message, DateTime timestamp
});
@override $SnChatMessageCopyWith<$Res>? get message;
}
/// @nodoc
class __$MessageChangeCopyWithImpl<$Res>
implements _$MessageChangeCopyWith<$Res> {
__$MessageChangeCopyWithImpl(this._self, this._then);
final _MessageChange _self;
final $Res Function(_MessageChange) _then;
/// Create a copy of MessageChange
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? messageId = null,Object? action = null,Object? message = freezed,Object? timestamp = null,}) {
return _then(_MessageChange(
messageId: null == messageId ? _self.messageId : messageId // ignore: cast_nullable_to_non_nullable
as String,action: null == action ? _self.action : action // ignore: cast_nullable_to_non_nullable
as String,message: freezed == message ? _self.message : message // ignore: cast_nullable_to_non_nullable
as SnChatMessage?,timestamp: null == timestamp ? _self.timestamp : timestamp // ignore: cast_nullable_to_non_nullable
as DateTime,
));
}
/// Create a copy of MessageChange
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnChatMessageCopyWith<$Res>? get message {
if (_self.message == null) {
return null;
}
return $SnChatMessageCopyWith<$Res>(_self.message!, (value) {
return _then(_self.copyWith(message: value));
});
}
}
/// @nodoc
mixin _$MessageSyncResponse {
List<MessageChange> get changes; DateTime get currentTimestamp;
List<SnChatMessage> get messages; DateTime get currentTimestamp;
/// Create a copy of MessageSyncResponse
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -1997,16 +1707,16 @@ $MessageSyncResponseCopyWith<MessageSyncResponse> get copyWith => _$MessageSyncR
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is MessageSyncResponse&&const DeepCollectionEquality().equals(other.changes, changes)&&(identical(other.currentTimestamp, currentTimestamp) || other.currentTimestamp == currentTimestamp));
return identical(this, other) || (other.runtimeType == runtimeType&&other is MessageSyncResponse&&const DeepCollectionEquality().equals(other.messages, messages)&&(identical(other.currentTimestamp, currentTimestamp) || other.currentTimestamp == currentTimestamp));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(changes),currentTimestamp);
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(messages),currentTimestamp);
@override
String toString() {
return 'MessageSyncResponse(changes: $changes, currentTimestamp: $currentTimestamp)';
return 'MessageSyncResponse(messages: $messages, currentTimestamp: $currentTimestamp)';
}
@@ -2017,7 +1727,7 @@ abstract mixin class $MessageSyncResponseCopyWith<$Res> {
factory $MessageSyncResponseCopyWith(MessageSyncResponse value, $Res Function(MessageSyncResponse) _then) = _$MessageSyncResponseCopyWithImpl;
@useResult
$Res call({
List<MessageChange> changes, DateTime currentTimestamp
List<SnChatMessage> messages, DateTime currentTimestamp
});
@@ -2034,10 +1744,10 @@ class _$MessageSyncResponseCopyWithImpl<$Res>
/// Create a copy of MessageSyncResponse
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? changes = null,Object? currentTimestamp = null,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? messages = null,Object? currentTimestamp = null,}) {
return _then(_self.copyWith(
changes: null == changes ? _self.changes : changes // ignore: cast_nullable_to_non_nullable
as List<MessageChange>,currentTimestamp: null == currentTimestamp ? _self.currentTimestamp : currentTimestamp // ignore: cast_nullable_to_non_nullable
messages: null == messages ? _self.messages : messages // ignore: cast_nullable_to_non_nullable
as List<SnChatMessage>,currentTimestamp: null == currentTimestamp ? _self.currentTimestamp : currentTimestamp // ignore: cast_nullable_to_non_nullable
as DateTime,
));
}
@@ -2120,10 +1830,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<MessageChange> changes, DateTime currentTimestamp)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<SnChatMessage> messages, DateTime currentTimestamp)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _MessageSyncResponse() when $default != null:
return $default(_that.changes,_that.currentTimestamp);case _:
return $default(_that.messages,_that.currentTimestamp);case _:
return orElse();
}
@@ -2141,10 +1851,10 @@ return $default(_that.changes,_that.currentTimestamp);case _:
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<MessageChange> changes, DateTime currentTimestamp) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<SnChatMessage> messages, DateTime currentTimestamp) $default,) {final _that = this;
switch (_that) {
case _MessageSyncResponse():
return $default(_that.changes,_that.currentTimestamp);}
return $default(_that.messages,_that.currentTimestamp);}
}
/// A variant of `when` that fallback to returning `null`
///
@@ -2158,10 +1868,10 @@ return $default(_that.changes,_that.currentTimestamp);}
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<MessageChange> changes, DateTime currentTimestamp)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<SnChatMessage> messages, DateTime currentTimestamp)? $default,) {final _that = this;
switch (_that) {
case _MessageSyncResponse() when $default != null:
return $default(_that.changes,_that.currentTimestamp);case _:
return $default(_that.messages,_that.currentTimestamp);case _:
return null;
}
@@ -2173,14 +1883,14 @@ return $default(_that.changes,_that.currentTimestamp);case _:
@JsonSerializable()
class _MessageSyncResponse implements MessageSyncResponse {
const _MessageSyncResponse({final List<MessageChange> changes = const [], required this.currentTimestamp}): _changes = changes;
const _MessageSyncResponse({final List<SnChatMessage> messages = const [], required this.currentTimestamp}): _messages = messages;
factory _MessageSyncResponse.fromJson(Map<String, dynamic> json) => _$MessageSyncResponseFromJson(json);
final List<MessageChange> _changes;
@override@JsonKey() List<MessageChange> get changes {
if (_changes is EqualUnmodifiableListView) return _changes;
final List<SnChatMessage> _messages;
@override@JsonKey() List<SnChatMessage> get messages {
if (_messages is EqualUnmodifiableListView) return _messages;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_changes);
return EqualUnmodifiableListView(_messages);
}
@override final DateTime currentTimestamp;
@@ -2198,16 +1908,16 @@ Map<String, dynamic> toJson() {
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _MessageSyncResponse&&const DeepCollectionEquality().equals(other._changes, _changes)&&(identical(other.currentTimestamp, currentTimestamp) || other.currentTimestamp == currentTimestamp));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _MessageSyncResponse&&const DeepCollectionEquality().equals(other._messages, _messages)&&(identical(other.currentTimestamp, currentTimestamp) || other.currentTimestamp == currentTimestamp));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_changes),currentTimestamp);
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_messages),currentTimestamp);
@override
String toString() {
return 'MessageSyncResponse(changes: $changes, currentTimestamp: $currentTimestamp)';
return 'MessageSyncResponse(messages: $messages, currentTimestamp: $currentTimestamp)';
}
@@ -2218,7 +1928,7 @@ abstract mixin class _$MessageSyncResponseCopyWith<$Res> implements $MessageSync
factory _$MessageSyncResponseCopyWith(_MessageSyncResponse value, $Res Function(_MessageSyncResponse) _then) = __$MessageSyncResponseCopyWithImpl;
@override @useResult
$Res call({
List<MessageChange> changes, DateTime currentTimestamp
List<SnChatMessage> messages, DateTime currentTimestamp
});
@@ -2235,10 +1945,10 @@ class __$MessageSyncResponseCopyWithImpl<$Res>
/// Create a copy of MessageSyncResponse
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? changes = null,Object? currentTimestamp = null,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? messages = null,Object? currentTimestamp = null,}) {
return _then(_MessageSyncResponse(
changes: null == changes ? _self._changes : changes // ignore: cast_nullable_to_non_nullable
as List<MessageChange>,currentTimestamp: null == currentTimestamp ? _self.currentTimestamp : currentTimestamp // ignore: cast_nullable_to_non_nullable
messages: null == messages ? _self._messages : messages // ignore: cast_nullable_to_non_nullable
as List<SnChatMessage>,currentTimestamp: null == currentTimestamp ? _self.currentTimestamp : currentTimestamp // ignore: cast_nullable_to_non_nullable
as DateTime,
));
}

View File

@@ -69,8 +69,8 @@ _SnChatMessage _$SnChatMessageFromJson(Map<String, dynamic> json) =>
content: json['content'] as String?,
nonce: json['nonce'] as String?,
meta: json['meta'] as Map<String, dynamic>? ?? const {},
membersMetioned:
(json['members_metioned'] as List<dynamic>?)
membersMentioned:
(json['members_mentioned'] as List<dynamic>?)
?.map((e) => e as String)
.toList() ??
const [],
@@ -105,7 +105,7 @@ Map<String, dynamic> _$SnChatMessageToJson(_SnChatMessage instance) =>
'content': instance.content,
'nonce': instance.nonce,
'meta': instance.meta,
'members_metioned': instance.membersMetioned,
'members_mentioned': instance.membersMentioned,
'edited_at': instance.editedAt?.toIso8601String(),
'attachments': instance.attachments.map((e) => e.toJson()).toList(),
'reactions': instance.reactions.map((e) => e.toJson()).toList(),
@@ -227,30 +227,11 @@ Map<String, dynamic> _$SnChatSummaryToJson(_SnChatSummary instance) =>
'last_message': instance.lastMessage?.toJson(),
};
_MessageChange _$MessageChangeFromJson(Map<String, dynamic> json) =>
_MessageChange(
messageId: json['message_id'] as String,
action: json['action'] as String,
message:
json['message'] == null
? null
: SnChatMessage.fromJson(json['message'] as Map<String, dynamic>),
timestamp: DateTime.parse(json['timestamp'] as String),
);
Map<String, dynamic> _$MessageChangeToJson(_MessageChange instance) =>
<String, dynamic>{
'message_id': instance.messageId,
'action': instance.action,
'message': instance.message?.toJson(),
'timestamp': instance.timestamp.toIso8601String(),
};
_MessageSyncResponse _$MessageSyncResponseFromJson(Map<String, dynamic> json) =>
_MessageSyncResponse(
changes:
(json['changes'] as List<dynamic>?)
?.map((e) => MessageChange.fromJson(e as Map<String, dynamic>))
messages:
(json['messages'] as List<dynamic>?)
?.map((e) => SnChatMessage.fromJson(e as Map<String, dynamic>))
.toList() ??
const [],
currentTimestamp: DateTime.parse(json['current_timestamp'] as String),
@@ -259,7 +240,7 @@ _MessageSyncResponse _$MessageSyncResponseFromJson(Map<String, dynamic> json) =>
Map<String, dynamic> _$MessageSyncResponseToJson(
_MessageSyncResponse instance,
) => <String, dynamic>{
'changes': instance.changes.map((e) => e.toJson()).toList(),
'messages': instance.messages.map((e) => e.toJson()).toList(),
'current_timestamp': instance.currentTimestamp.toIso8601String(),
};

View File

@@ -1,4 +1,5 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:island/models/file_pool.dart';
part 'file.freezed.dart';
part 'file.g.dart';
@@ -13,6 +14,7 @@ sealed class UniversalFile with _$UniversalFile {
required dynamic data,
required UniversalFileType type,
@Default(false) bool isLink,
String? displayName,
}) = _UniversalFile;
factory UniversalFile.fromJson(Map<String, dynamic> json) =>
@@ -30,6 +32,7 @@ sealed class UniversalFile with _$UniversalFile {
'video' => UniversalFileType.video,
_ => UniversalFileType.file,
},
displayName: attachment.name,
);
}
}
@@ -42,6 +45,7 @@ sealed class SnCloudFile with _$SnCloudFile {
required String? description,
required Map<String, dynamic>? fileMeta,
required Map<String, dynamic>? userMeta,
required SnFilePool? pool,
@Default([]) List<int> sensitiveMarks,
required String? mimeType,
required String? hash,

View File

@@ -15,7 +15,7 @@ T _$identity<T>(T value) => value;
/// @nodoc
mixin _$UniversalFile {
dynamic get data; UniversalFileType get type; bool get isLink;
dynamic get data; UniversalFileType get type; bool get isLink; String? get displayName;
/// 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)&&(identical(other.isLink, isLink) || other.isLink == isLink));
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)&&(identical(other.displayName, displayName) || other.displayName == displayName));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(data),type,isLink);
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(data),type,isLink,displayName);
@override
String toString() {
return 'UniversalFile(data: $data, type: $type, isLink: $isLink)';
return 'UniversalFile(data: $data, type: $type, isLink: $isLink, displayName: $displayName)';
}
@@ -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, bool isLink
dynamic data, UniversalFileType type, bool isLink, String? displayName
});
@@ -65,12 +65,13 @@ 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,Object? isLink = null,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? data = freezed,Object? type = null,Object? isLink = null,Object? displayName = freezed,}) {
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,isLink: null == isLink ? _self.isLink : isLink // ignore: cast_nullable_to_non_nullable
as bool,
as bool,displayName: freezed == displayName ? _self.displayName : displayName // ignore: cast_nullable_to_non_nullable
as String?,
));
}
@@ -152,10 +153,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( dynamic data, UniversalFileType type, bool isLink)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( dynamic data, UniversalFileType type, bool isLink, String? displayName)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _UniversalFile() when $default != null:
return $default(_that.data,_that.type,_that.isLink);case _:
return $default(_that.data,_that.type,_that.isLink,_that.displayName);case _:
return orElse();
}
@@ -173,10 +174,10 @@ return $default(_that.data,_that.type,_that.isLink);case _:
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( dynamic data, UniversalFileType type, bool isLink) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( dynamic data, UniversalFileType type, bool isLink, String? displayName) $default,) {final _that = this;
switch (_that) {
case _UniversalFile():
return $default(_that.data,_that.type,_that.isLink);}
return $default(_that.data,_that.type,_that.isLink,_that.displayName);}
}
/// A variant of `when` that fallback to returning `null`
///
@@ -190,10 +191,10 @@ return $default(_that.data,_that.type,_that.isLink);}
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( dynamic data, UniversalFileType type, bool isLink)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( dynamic data, UniversalFileType type, bool isLink, String? displayName)? $default,) {final _that = this;
switch (_that) {
case _UniversalFile() when $default != null:
return $default(_that.data,_that.type,_that.isLink);case _:
return $default(_that.data,_that.type,_that.isLink,_that.displayName);case _:
return null;
}
@@ -205,12 +206,13 @@ return $default(_that.data,_that.type,_that.isLink);case _:
@JsonSerializable()
class _UniversalFile extends UniversalFile {
const _UniversalFile({required this.data, required this.type, this.isLink = false}): super._();
const _UniversalFile({required this.data, required this.type, this.isLink = false, this.displayName}): super._();
factory _UniversalFile.fromJson(Map<String, dynamic> json) => _$UniversalFileFromJson(json);
@override final dynamic data;
@override final UniversalFileType type;
@override@JsonKey() final bool isLink;
@override final String? displayName;
/// Create a copy of UniversalFile
/// with the given fields replaced by the non-null parameter values.
@@ -225,16 +227,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)&&(identical(other.isLink, isLink) || other.isLink == isLink));
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)&&(identical(other.displayName, displayName) || other.displayName == displayName));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(data),type,isLink);
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(data),type,isLink,displayName);
@override
String toString() {
return 'UniversalFile(data: $data, type: $type, isLink: $isLink)';
return 'UniversalFile(data: $data, type: $type, isLink: $isLink, displayName: $displayName)';
}
@@ -245,7 +247,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, bool isLink
dynamic data, UniversalFileType type, bool isLink, String? displayName
});
@@ -262,12 +264,13 @@ 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,Object? isLink = null,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? data = freezed,Object? type = null,Object? isLink = null,Object? displayName = freezed,}) {
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,isLink: null == isLink ? _self.isLink : isLink // ignore: cast_nullable_to_non_nullable
as bool,
as bool,displayName: freezed == displayName ? _self.displayName : displayName // ignore: cast_nullable_to_non_nullable
as String?,
));
}
@@ -278,7 +281,7 @@ as bool,
/// @nodoc
mixin _$SnCloudFile {
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;
String get id; String get name; String? get description; Map<String, dynamic>? get fileMeta; Map<String, dynamic>? get userMeta; SnFilePool? get pool; 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)
@@ -291,16 +294,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)&&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));
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.pool, pool) || other.pool == pool)&&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),const DeepCollectionEquality().hash(sensitiveMarks),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),pool,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, sensitiveMarks: $sensitiveMarks, 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, pool: $pool, sensitiveMarks: $sensitiveMarks, mimeType: $mimeType, hash: $hash, size: $size, uploadedAt: $uploadedAt, uploadedTo: $uploadedTo, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
@@ -311,11 +314,11 @@ 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, List<int> sensitiveMarks, 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, SnFilePool? pool, List<int> sensitiveMarks, String? mimeType, String? hash, int size, DateTime? uploadedAt, String? uploadedTo, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
$SnFilePoolCopyWith<$Res>? get pool;
}
/// @nodoc
@@ -328,14 +331,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? 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,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? fileMeta = freezed,Object? userMeta = freezed,Object? pool = 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>?,sensitiveMarks: null == sensitiveMarks ? _self.sensitiveMarks : sensitiveMarks // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>?,pool: freezed == pool ? _self.pool : pool // ignore: cast_nullable_to_non_nullable
as SnFilePool?,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
@@ -347,7 +351,19 @@ as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ign
as DateTime?,
));
}
/// Create a copy of SnCloudFile
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnFilePoolCopyWith<$Res>? get pool {
if (_self.pool == null) {
return null;
}
return $SnFilePoolCopyWith<$Res>(_self.pool!, (value) {
return _then(_self.copyWith(pool: value));
});
}
}
@@ -426,10 +442,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, 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;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String name, String? description, Map<String, dynamic>? fileMeta, Map<String, dynamic>? userMeta, SnFilePool? pool, 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.sensitiveMarks,_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.pool,_that.sensitiveMarks,_that.mimeType,_that.hash,_that.size,_that.uploadedAt,_that.uploadedTo,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return orElse();
}
@@ -447,10 +463,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, List<int> sensitiveMarks, 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, SnFilePool? pool, 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.sensitiveMarks,_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.pool,_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`
///
@@ -464,10 +480,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, List<int> sensitiveMarks, 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, SnFilePool? pool, 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.sensitiveMarks,_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.pool,_that.sensitiveMarks,_that.mimeType,_that.hash,_that.size,_that.uploadedAt,_that.uploadedTo,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return null;
}
@@ -479,7 +495,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, 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;
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.pool, 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;
@@ -503,6 +519,7 @@ class _SnCloudFile implements SnCloudFile {
return EqualUnmodifiableMapView(value);
}
@override final SnFilePool? pool;
final List<int> _sensitiveMarks;
@override@JsonKey() List<int> get sensitiveMarks {
if (_sensitiveMarks is EqualUnmodifiableListView) return _sensitiveMarks;
@@ -532,16 +549,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)&&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));
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.pool, pool) || other.pool == pool)&&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),const DeepCollectionEquality().hash(_sensitiveMarks),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),pool,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, sensitiveMarks: $sensitiveMarks, 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, pool: $pool, sensitiveMarks: $sensitiveMarks, mimeType: $mimeType, hash: $hash, size: $size, uploadedAt: $uploadedAt, uploadedTo: $uploadedTo, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
@@ -552,11 +569,11 @@ 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, List<int> sensitiveMarks, 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, SnFilePool? pool, List<int> sensitiveMarks, String? mimeType, String? hash, int size, DateTime? uploadedAt, String? uploadedTo, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
});
@override $SnFilePoolCopyWith<$Res>? get pool;
}
/// @nodoc
@@ -569,14 +586,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? 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,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? fileMeta = freezed,Object? userMeta = freezed,Object? pool = 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>?,sensitiveMarks: null == sensitiveMarks ? _self._sensitiveMarks : sensitiveMarks // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>?,pool: freezed == pool ? _self.pool : pool // ignore: cast_nullable_to_non_nullable
as SnFilePool?,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
@@ -589,7 +607,19 @@ as DateTime?,
));
}
/// Create a copy of SnCloudFile
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnFilePoolCopyWith<$Res>? get pool {
if (_self.pool == null) {
return null;
}
return $SnFilePoolCopyWith<$Res>(_self.pool!, (value) {
return _then(_self.copyWith(pool: value));
});
}
}
// dart format on

View File

@@ -11,6 +11,7 @@ _UniversalFile _$UniversalFileFromJson(Map<String, dynamic> json) =>
data: json['data'],
type: $enumDecode(_$UniversalFileTypeEnumMap, json['type']),
isLink: json['is_link'] as bool? ?? false,
displayName: json['display_name'] as String?,
);
Map<String, dynamic> _$UniversalFileToJson(_UniversalFile instance) =>
@@ -18,6 +19,7 @@ Map<String, dynamic> _$UniversalFileToJson(_UniversalFile instance) =>
'data': instance.data,
'type': _$UniversalFileTypeEnumMap[instance.type]!,
'is_link': instance.isLink,
'display_name': instance.displayName,
};
const _$UniversalFileTypeEnumMap = {
@@ -33,6 +35,10 @@ _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>?,
pool:
json['pool'] == null
? null
: SnFilePool.fromJson(json['pool'] as Map<String, dynamic>),
sensitiveMarks:
(json['sensitive_marks'] as List<dynamic>?)
?.map((e) => (e as num).toInt())
@@ -61,6 +67,7 @@ Map<String, dynamic> _$SnCloudFileToJson(_SnCloudFile instance) =>
'description': instance.description,
'file_meta': instance.fileMeta,
'user_meta': instance.userMeta,
'pool': instance.pool?.toJson(),
'sensitive_marks': instance.sensitiveMarks,
'mime_type': instance.mimeType,
'hash': instance.hash,

25
lib/models/file_pool.dart Normal file
View File

@@ -0,0 +1,25 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'file_pool.freezed.dart';
part 'file_pool.g.dart';
@freezed
sealed class SnFilePool with _$SnFilePool {
const factory SnFilePool({
required String id,
required String name,
String? description,
Map<String, dynamic>? storageConfig,
Map<String, dynamic>? billingConfig,
Map<String, dynamic>? policyConfig,
bool? isHidden,
String? accountId,
String? resourceIdentifier,
DateTime? createdAt,
DateTime? updatedAt,
DateTime? deletedAt,
}) = _SnFilePool;
factory SnFilePool.fromJson(Map<String, dynamic> json) =>
_$SnFilePoolFromJson(json);
}

View File

@@ -0,0 +1,328 @@
// 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 'file_pool.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$SnFilePool {
String get id; String get name; String? get description; Map<String, dynamic>? get storageConfig; Map<String, dynamic>? get billingConfig; Map<String, dynamic>? get policyConfig; bool? get isHidden; String? get accountId; String? get resourceIdentifier; DateTime? get createdAt; DateTime? get updatedAt; DateTime? get deletedAt;
/// Create a copy of SnFilePool
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$SnFilePoolCopyWith<SnFilePool> get copyWith => _$SnFilePoolCopyWithImpl<SnFilePool>(this as SnFilePool, _$identity);
/// Serializes this SnFilePool to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnFilePool&&(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.storageConfig, storageConfig)&&const DeepCollectionEquality().equals(other.billingConfig, billingConfig)&&const DeepCollectionEquality().equals(other.policyConfig, policyConfig)&&(identical(other.isHidden, isHidden) || other.isHidden == isHidden)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.resourceIdentifier, resourceIdentifier) || other.resourceIdentifier == resourceIdentifier)&&(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(storageConfig),const DeepCollectionEquality().hash(billingConfig),const DeepCollectionEquality().hash(policyConfig),isHidden,accountId,resourceIdentifier,createdAt,updatedAt,deletedAt);
@override
String toString() {
return 'SnFilePool(id: $id, name: $name, description: $description, storageConfig: $storageConfig, billingConfig: $billingConfig, policyConfig: $policyConfig, isHidden: $isHidden, accountId: $accountId, resourceIdentifier: $resourceIdentifier, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
}
/// @nodoc
abstract mixin class $SnFilePoolCopyWith<$Res> {
factory $SnFilePoolCopyWith(SnFilePool value, $Res Function(SnFilePool) _then) = _$SnFilePoolCopyWithImpl;
@useResult
$Res call({
String id, String name, String? description, Map<String, dynamic>? storageConfig, Map<String, dynamic>? billingConfig, Map<String, dynamic>? policyConfig, bool? isHidden, String? accountId, String? resourceIdentifier, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt
});
}
/// @nodoc
class _$SnFilePoolCopyWithImpl<$Res>
implements $SnFilePoolCopyWith<$Res> {
_$SnFilePoolCopyWithImpl(this._self, this._then);
final SnFilePool _self;
final $Res Function(SnFilePool) _then;
/// Create a copy of SnFilePool
/// 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? storageConfig = freezed,Object? billingConfig = freezed,Object? policyConfig = freezed,Object? isHidden = freezed,Object? accountId = freezed,Object? resourceIdentifier = freezed,Object? createdAt = freezed,Object? updatedAt = freezed,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?,storageConfig: freezed == storageConfig ? _self.storageConfig : storageConfig // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>?,billingConfig: freezed == billingConfig ? _self.billingConfig : billingConfig // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>?,policyConfig: freezed == policyConfig ? _self.policyConfig : policyConfig // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>?,isHidden: freezed == isHidden ? _self.isHidden : isHidden // ignore: cast_nullable_to_non_nullable
as bool?,accountId: freezed == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
as String?,resourceIdentifier: freezed == resourceIdentifier ? _self.resourceIdentifier : resourceIdentifier // ignore: cast_nullable_to_non_nullable
as String?,createdAt: freezed == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as DateTime?,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,
));
}
}
/// Adds pattern-matching-related methods to [SnFilePool].
extension SnFilePoolPatterns on SnFilePool {
/// 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( _SnFilePool value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _SnFilePool() 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( _SnFilePool value) $default,){
final _that = this;
switch (_that) {
case _SnFilePool():
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( _SnFilePool value)? $default,){
final _that = this;
switch (_that) {
case _SnFilePool() 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 name, String? description, Map<String, dynamic>? storageConfig, Map<String, dynamic>? billingConfig, Map<String, dynamic>? policyConfig, bool? isHidden, String? accountId, String? resourceIdentifier, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnFilePool() when $default != null:
return $default(_that.id,_that.name,_that.description,_that.storageConfig,_that.billingConfig,_that.policyConfig,_that.isHidden,_that.accountId,_that.resourceIdentifier,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String name, String? description, Map<String, dynamic>? storageConfig, Map<String, dynamic>? billingConfig, Map<String, dynamic>? policyConfig, bool? isHidden, String? accountId, String? resourceIdentifier, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt) $default,) {final _that = this;
switch (_that) {
case _SnFilePool():
return $default(_that.id,_that.name,_that.description,_that.storageConfig,_that.billingConfig,_that.policyConfig,_that.isHidden,_that.accountId,_that.resourceIdentifier,_that.createdAt,_that.updatedAt,_that.deletedAt);}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String name, String? description, Map<String, dynamic>? storageConfig, Map<String, dynamic>? billingConfig, Map<String, dynamic>? policyConfig, bool? isHidden, String? accountId, String? resourceIdentifier, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
switch (_that) {
case _SnFilePool() when $default != null:
return $default(_that.id,_that.name,_that.description,_that.storageConfig,_that.billingConfig,_that.policyConfig,_that.isHidden,_that.accountId,_that.resourceIdentifier,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _SnFilePool implements SnFilePool {
const _SnFilePool({required this.id, required this.name, this.description, final Map<String, dynamic>? storageConfig, final Map<String, dynamic>? billingConfig, final Map<String, dynamic>? policyConfig, this.isHidden, this.accountId, this.resourceIdentifier, this.createdAt, this.updatedAt, this.deletedAt}): _storageConfig = storageConfig,_billingConfig = billingConfig,_policyConfig = policyConfig;
factory _SnFilePool.fromJson(Map<String, dynamic> json) => _$SnFilePoolFromJson(json);
@override final String id;
@override final String name;
@override final String? description;
final Map<String, dynamic>? _storageConfig;
@override Map<String, dynamic>? get storageConfig {
final value = _storageConfig;
if (value == null) return null;
if (_storageConfig is EqualUnmodifiableMapView) return _storageConfig;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(value);
}
final Map<String, dynamic>? _billingConfig;
@override Map<String, dynamic>? get billingConfig {
final value = _billingConfig;
if (value == null) return null;
if (_billingConfig is EqualUnmodifiableMapView) return _billingConfig;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(value);
}
final Map<String, dynamic>? _policyConfig;
@override Map<String, dynamic>? get policyConfig {
final value = _policyConfig;
if (value == null) return null;
if (_policyConfig is EqualUnmodifiableMapView) return _policyConfig;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(value);
}
@override final bool? isHidden;
@override final String? accountId;
@override final String? resourceIdentifier;
@override final DateTime? createdAt;
@override final DateTime? updatedAt;
@override final DateTime? deletedAt;
/// Create a copy of SnFilePool
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$SnFilePoolCopyWith<_SnFilePool> get copyWith => __$SnFilePoolCopyWithImpl<_SnFilePool>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$SnFilePoolToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnFilePool&&(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._storageConfig, _storageConfig)&&const DeepCollectionEquality().equals(other._billingConfig, _billingConfig)&&const DeepCollectionEquality().equals(other._policyConfig, _policyConfig)&&(identical(other.isHidden, isHidden) || other.isHidden == isHidden)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.resourceIdentifier, resourceIdentifier) || other.resourceIdentifier == resourceIdentifier)&&(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(_storageConfig),const DeepCollectionEquality().hash(_billingConfig),const DeepCollectionEquality().hash(_policyConfig),isHidden,accountId,resourceIdentifier,createdAt,updatedAt,deletedAt);
@override
String toString() {
return 'SnFilePool(id: $id, name: $name, description: $description, storageConfig: $storageConfig, billingConfig: $billingConfig, policyConfig: $policyConfig, isHidden: $isHidden, accountId: $accountId, resourceIdentifier: $resourceIdentifier, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
}
}
/// @nodoc
abstract mixin class _$SnFilePoolCopyWith<$Res> implements $SnFilePoolCopyWith<$Res> {
factory _$SnFilePoolCopyWith(_SnFilePool value, $Res Function(_SnFilePool) _then) = __$SnFilePoolCopyWithImpl;
@override @useResult
$Res call({
String id, String name, String? description, Map<String, dynamic>? storageConfig, Map<String, dynamic>? billingConfig, Map<String, dynamic>? policyConfig, bool? isHidden, String? accountId, String? resourceIdentifier, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt
});
}
/// @nodoc
class __$SnFilePoolCopyWithImpl<$Res>
implements _$SnFilePoolCopyWith<$Res> {
__$SnFilePoolCopyWithImpl(this._self, this._then);
final _SnFilePool _self;
final $Res Function(_SnFilePool) _then;
/// Create a copy of SnFilePool
/// 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? storageConfig = freezed,Object? billingConfig = freezed,Object? policyConfig = freezed,Object? isHidden = freezed,Object? accountId = freezed,Object? resourceIdentifier = freezed,Object? createdAt = freezed,Object? updatedAt = freezed,Object? deletedAt = freezed,}) {
return _then(_SnFilePool(
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?,storageConfig: freezed == storageConfig ? _self._storageConfig : storageConfig // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>?,billingConfig: freezed == billingConfig ? _self._billingConfig : billingConfig // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>?,policyConfig: freezed == policyConfig ? _self._policyConfig : policyConfig // ignore: cast_nullable_to_non_nullable
as Map<String, dynamic>?,isHidden: freezed == isHidden ? _self.isHidden : isHidden // ignore: cast_nullable_to_non_nullable
as bool?,accountId: freezed == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
as String?,resourceIdentifier: freezed == resourceIdentifier ? _self.resourceIdentifier : resourceIdentifier // ignore: cast_nullable_to_non_nullable
as String?,createdAt: freezed == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as DateTime?,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,
));
}
}
// dart format on

View File

@@ -0,0 +1,47 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'file_pool.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_SnFilePool _$SnFilePoolFromJson(Map<String, dynamic> json) => _SnFilePool(
id: json['id'] as String,
name: json['name'] as String,
description: json['description'] as String?,
storageConfig: json['storage_config'] as Map<String, dynamic>?,
billingConfig: json['billing_config'] as Map<String, dynamic>?,
policyConfig: json['policy_config'] as Map<String, dynamic>?,
isHidden: json['is_hidden'] as bool?,
accountId: json['account_id'] as String?,
resourceIdentifier: json['resource_identifier'] as String?,
createdAt:
json['created_at'] == null
? null
: DateTime.parse(json['created_at'] as String),
updatedAt:
json['updated_at'] == null
? null
: DateTime.parse(json['updated_at'] as String),
deletedAt:
json['deleted_at'] == null
? null
: DateTime.parse(json['deleted_at'] as String),
);
Map<String, dynamic> _$SnFilePoolToJson(_SnFilePool instance) =>
<String, dynamic>{
'id': instance.id,
'name': instance.name,
'description': instance.description,
'storage_config': instance.storageConfig,
'billing_config': instance.billingConfig,
'policy_config': instance.policyConfig,
'is_hidden': instance.isHidden,
'account_id': instance.accountId,
'resource_identifier': instance.resourceIdentifier,
'created_at': instance.createdAt?.toIso8601String(),
'updated_at': instance.updatedAt?.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
};

26
lib/models/heatmap.dart Normal file
View File

@@ -0,0 +1,26 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'heatmap.freezed.dart';
part 'heatmap.g.dart';
@freezed
sealed class SnHeatmap with _$SnHeatmap {
const factory SnHeatmap({
required String unit,
@JsonKey(name: 'period_start') required DateTime periodStart,
@JsonKey(name: 'period_end') required DateTime periodEnd,
required List<SnHeatmapItem> items,
}) = _SnHeatmap;
factory SnHeatmap.fromJson(Map<String, dynamic> json) =>
_$SnHeatmapFromJson(json);
}
@freezed
sealed class SnHeatmapItem with _$SnHeatmapItem {
const factory SnHeatmapItem({required DateTime date, required int count}) =
_SnHeatmapItem;
factory SnHeatmapItem.fromJson(Map<String, dynamic> json) =>
_$SnHeatmapItemFromJson(json);
}

View File

@@ -0,0 +1,546 @@
// 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 'heatmap.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$SnHeatmap {
String get unit;@JsonKey(name: 'period_start') DateTime get periodStart;@JsonKey(name: 'period_end') DateTime get periodEnd; List<SnHeatmapItem> get items;
/// Create a copy of SnHeatmap
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$SnHeatmapCopyWith<SnHeatmap> get copyWith => _$SnHeatmapCopyWithImpl<SnHeatmap>(this as SnHeatmap, _$identity);
/// Serializes this SnHeatmap to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnHeatmap&&(identical(other.unit, unit) || other.unit == unit)&&(identical(other.periodStart, periodStart) || other.periodStart == periodStart)&&(identical(other.periodEnd, periodEnd) || other.periodEnd == periodEnd)&&const DeepCollectionEquality().equals(other.items, items));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,unit,periodStart,periodEnd,const DeepCollectionEquality().hash(items));
@override
String toString() {
return 'SnHeatmap(unit: $unit, periodStart: $periodStart, periodEnd: $periodEnd, items: $items)';
}
}
/// @nodoc
abstract mixin class $SnHeatmapCopyWith<$Res> {
factory $SnHeatmapCopyWith(SnHeatmap value, $Res Function(SnHeatmap) _then) = _$SnHeatmapCopyWithImpl;
@useResult
$Res call({
String unit,@JsonKey(name: 'period_start') DateTime periodStart,@JsonKey(name: 'period_end') DateTime periodEnd, List<SnHeatmapItem> items
});
}
/// @nodoc
class _$SnHeatmapCopyWithImpl<$Res>
implements $SnHeatmapCopyWith<$Res> {
_$SnHeatmapCopyWithImpl(this._self, this._then);
final SnHeatmap _self;
final $Res Function(SnHeatmap) _then;
/// Create a copy of SnHeatmap
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? unit = null,Object? periodStart = null,Object? periodEnd = null,Object? items = null,}) {
return _then(_self.copyWith(
unit: null == unit ? _self.unit : unit // ignore: cast_nullable_to_non_nullable
as String,periodStart: null == periodStart ? _self.periodStart : periodStart // ignore: cast_nullable_to_non_nullable
as DateTime,periodEnd: null == periodEnd ? _self.periodEnd : periodEnd // ignore: cast_nullable_to_non_nullable
as DateTime,items: null == items ? _self.items : items // ignore: cast_nullable_to_non_nullable
as List<SnHeatmapItem>,
));
}
}
/// Adds pattern-matching-related methods to [SnHeatmap].
extension SnHeatmapPatterns on SnHeatmap {
/// 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( _SnHeatmap value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _SnHeatmap() 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( _SnHeatmap value) $default,){
final _that = this;
switch (_that) {
case _SnHeatmap():
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( _SnHeatmap value)? $default,){
final _that = this;
switch (_that) {
case _SnHeatmap() 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 unit, @JsonKey(name: 'period_start') DateTime periodStart, @JsonKey(name: 'period_end') DateTime periodEnd, List<SnHeatmapItem> items)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnHeatmap() when $default != null:
return $default(_that.unit,_that.periodStart,_that.periodEnd,_that.items);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 unit, @JsonKey(name: 'period_start') DateTime periodStart, @JsonKey(name: 'period_end') DateTime periodEnd, List<SnHeatmapItem> items) $default,) {final _that = this;
switch (_that) {
case _SnHeatmap():
return $default(_that.unit,_that.periodStart,_that.periodEnd,_that.items);}
}
/// 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 unit, @JsonKey(name: 'period_start') DateTime periodStart, @JsonKey(name: 'period_end') DateTime periodEnd, List<SnHeatmapItem> items)? $default,) {final _that = this;
switch (_that) {
case _SnHeatmap() when $default != null:
return $default(_that.unit,_that.periodStart,_that.periodEnd,_that.items);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _SnHeatmap implements SnHeatmap {
const _SnHeatmap({required this.unit, @JsonKey(name: 'period_start') required this.periodStart, @JsonKey(name: 'period_end') required this.periodEnd, required final List<SnHeatmapItem> items}): _items = items;
factory _SnHeatmap.fromJson(Map<String, dynamic> json) => _$SnHeatmapFromJson(json);
@override final String unit;
@override@JsonKey(name: 'period_start') final DateTime periodStart;
@override@JsonKey(name: 'period_end') final DateTime periodEnd;
final List<SnHeatmapItem> _items;
@override List<SnHeatmapItem> get items {
if (_items is EqualUnmodifiableListView) return _items;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_items);
}
/// Create a copy of SnHeatmap
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$SnHeatmapCopyWith<_SnHeatmap> get copyWith => __$SnHeatmapCopyWithImpl<_SnHeatmap>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$SnHeatmapToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnHeatmap&&(identical(other.unit, unit) || other.unit == unit)&&(identical(other.periodStart, periodStart) || other.periodStart == periodStart)&&(identical(other.periodEnd, periodEnd) || other.periodEnd == periodEnd)&&const DeepCollectionEquality().equals(other._items, _items));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,unit,periodStart,periodEnd,const DeepCollectionEquality().hash(_items));
@override
String toString() {
return 'SnHeatmap(unit: $unit, periodStart: $periodStart, periodEnd: $periodEnd, items: $items)';
}
}
/// @nodoc
abstract mixin class _$SnHeatmapCopyWith<$Res> implements $SnHeatmapCopyWith<$Res> {
factory _$SnHeatmapCopyWith(_SnHeatmap value, $Res Function(_SnHeatmap) _then) = __$SnHeatmapCopyWithImpl;
@override @useResult
$Res call({
String unit,@JsonKey(name: 'period_start') DateTime periodStart,@JsonKey(name: 'period_end') DateTime periodEnd, List<SnHeatmapItem> items
});
}
/// @nodoc
class __$SnHeatmapCopyWithImpl<$Res>
implements _$SnHeatmapCopyWith<$Res> {
__$SnHeatmapCopyWithImpl(this._self, this._then);
final _SnHeatmap _self;
final $Res Function(_SnHeatmap) _then;
/// Create a copy of SnHeatmap
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? unit = null,Object? periodStart = null,Object? periodEnd = null,Object? items = null,}) {
return _then(_SnHeatmap(
unit: null == unit ? _self.unit : unit // ignore: cast_nullable_to_non_nullable
as String,periodStart: null == periodStart ? _self.periodStart : periodStart // ignore: cast_nullable_to_non_nullable
as DateTime,periodEnd: null == periodEnd ? _self.periodEnd : periodEnd // ignore: cast_nullable_to_non_nullable
as DateTime,items: null == items ? _self._items : items // ignore: cast_nullable_to_non_nullable
as List<SnHeatmapItem>,
));
}
}
/// @nodoc
mixin _$SnHeatmapItem {
DateTime get date; int get count;
/// Create a copy of SnHeatmapItem
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$SnHeatmapItemCopyWith<SnHeatmapItem> get copyWith => _$SnHeatmapItemCopyWithImpl<SnHeatmapItem>(this as SnHeatmapItem, _$identity);
/// Serializes this SnHeatmapItem to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnHeatmapItem&&(identical(other.date, date) || other.date == date)&&(identical(other.count, count) || other.count == count));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,date,count);
@override
String toString() {
return 'SnHeatmapItem(date: $date, count: $count)';
}
}
/// @nodoc
abstract mixin class $SnHeatmapItemCopyWith<$Res> {
factory $SnHeatmapItemCopyWith(SnHeatmapItem value, $Res Function(SnHeatmapItem) _then) = _$SnHeatmapItemCopyWithImpl;
@useResult
$Res call({
DateTime date, int count
});
}
/// @nodoc
class _$SnHeatmapItemCopyWithImpl<$Res>
implements $SnHeatmapItemCopyWith<$Res> {
_$SnHeatmapItemCopyWithImpl(this._self, this._then);
final SnHeatmapItem _self;
final $Res Function(SnHeatmapItem) _then;
/// Create a copy of SnHeatmapItem
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? date = null,Object? count = null,}) {
return _then(_self.copyWith(
date: null == date ? _self.date : date // ignore: cast_nullable_to_non_nullable
as DateTime,count: null == count ? _self.count : count // ignore: cast_nullable_to_non_nullable
as int,
));
}
}
/// Adds pattern-matching-related methods to [SnHeatmapItem].
extension SnHeatmapItemPatterns on SnHeatmapItem {
/// 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( _SnHeatmapItem value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _SnHeatmapItem() 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( _SnHeatmapItem value) $default,){
final _that = this;
switch (_that) {
case _SnHeatmapItem():
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( _SnHeatmapItem value)? $default,){
final _that = this;
switch (_that) {
case _SnHeatmapItem() 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( DateTime date, int count)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnHeatmapItem() when $default != null:
return $default(_that.date,_that.count);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( DateTime date, int count) $default,) {final _that = this;
switch (_that) {
case _SnHeatmapItem():
return $default(_that.date,_that.count);}
}
/// 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( DateTime date, int count)? $default,) {final _that = this;
switch (_that) {
case _SnHeatmapItem() when $default != null:
return $default(_that.date,_that.count);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _SnHeatmapItem implements SnHeatmapItem {
const _SnHeatmapItem({required this.date, required this.count});
factory _SnHeatmapItem.fromJson(Map<String, dynamic> json) => _$SnHeatmapItemFromJson(json);
@override final DateTime date;
@override final int count;
/// Create a copy of SnHeatmapItem
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$SnHeatmapItemCopyWith<_SnHeatmapItem> get copyWith => __$SnHeatmapItemCopyWithImpl<_SnHeatmapItem>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$SnHeatmapItemToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnHeatmapItem&&(identical(other.date, date) || other.date == date)&&(identical(other.count, count) || other.count == count));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,date,count);
@override
String toString() {
return 'SnHeatmapItem(date: $date, count: $count)';
}
}
/// @nodoc
abstract mixin class _$SnHeatmapItemCopyWith<$Res> implements $SnHeatmapItemCopyWith<$Res> {
factory _$SnHeatmapItemCopyWith(_SnHeatmapItem value, $Res Function(_SnHeatmapItem) _then) = __$SnHeatmapItemCopyWithImpl;
@override @useResult
$Res call({
DateTime date, int count
});
}
/// @nodoc
class __$SnHeatmapItemCopyWithImpl<$Res>
implements _$SnHeatmapItemCopyWith<$Res> {
__$SnHeatmapItemCopyWithImpl(this._self, this._then);
final _SnHeatmapItem _self;
final $Res Function(_SnHeatmapItem) _then;
/// Create a copy of SnHeatmapItem
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? date = null,Object? count = null,}) {
return _then(_SnHeatmapItem(
date: null == date ? _self.date : date // ignore: cast_nullable_to_non_nullable
as DateTime,count: null == count ? _self.count : count // ignore: cast_nullable_to_non_nullable
as int,
));
}
}
// dart format on

37
lib/models/heatmap.g.dart Normal file
View File

@@ -0,0 +1,37 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'heatmap.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_SnHeatmap _$SnHeatmapFromJson(Map<String, dynamic> json) => _SnHeatmap(
unit: json['unit'] as String,
periodStart: DateTime.parse(json['period_start'] as String),
periodEnd: DateTime.parse(json['period_end'] as String),
items:
(json['items'] as List<dynamic>)
.map((e) => SnHeatmapItem.fromJson(e as Map<String, dynamic>))
.toList(),
);
Map<String, dynamic> _$SnHeatmapToJson(_SnHeatmap instance) =>
<String, dynamic>{
'unit': instance.unit,
'period_start': instance.periodStart.toIso8601String(),
'period_end': instance.periodEnd.toIso8601String(),
'items': instance.items.map((e) => e.toJson()).toList(),
};
_SnHeatmapItem _$SnHeatmapItemFromJson(Map<String, dynamic> json) =>
_SnHeatmapItem(
date: DateTime.parse(json['date'] as String),
count: (json['count'] as num).toInt(),
);
Map<String, dynamic> _$SnHeatmapItemToJson(_SnHeatmapItem instance) =>
<String, dynamic>{
'date': instance.date.toIso8601String(),
'count': instance.count,
};

View File

@@ -1,4 +1,5 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:island/models/account.dart';
import 'package:island/models/publisher.dart';
part 'poll.freezed.dart';
@@ -101,6 +102,7 @@ sealed class SnPollAnswer with _$SnPollAnswer {
required DateTime createdAt,
required DateTime updatedAt,
required DateTime? deletedAt,
SnAccount? account,
}) = _SnPollAnswer;
factory SnPollAnswer.fromJson(Map<String, dynamic> json) =>

View File

@@ -1187,7 +1187,7 @@ as int,
/// @nodoc
mixin _$SnPollAnswer {
String get id; Map<String, dynamic> get answer; String get accountId; String get pollId; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
String get id; Map<String, dynamic> get answer; String get accountId; String get pollId; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; SnAccount? get account;
/// Create a copy of SnPollAnswer
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -1200,16 +1200,16 @@ $SnPollAnswerCopyWith<SnPollAnswer> get copyWith => _$SnPollAnswerCopyWithImpl<S
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPollAnswer&&(identical(other.id, id) || other.id == id)&&const DeepCollectionEquality().equals(other.answer, answer)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.pollId, pollId) || other.pollId == pollId)&&(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 SnPollAnswer&&(identical(other.id, id) || other.id == id)&&const DeepCollectionEquality().equals(other.answer, answer)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.pollId, pollId) || other.pollId == pollId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.account, account) || other.account == account));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,const DeepCollectionEquality().hash(answer),accountId,pollId,createdAt,updatedAt,deletedAt);
int get hashCode => Object.hash(runtimeType,id,const DeepCollectionEquality().hash(answer),accountId,pollId,createdAt,updatedAt,deletedAt,account);
@override
String toString() {
return 'SnPollAnswer(id: $id, answer: $answer, accountId: $accountId, pollId: $pollId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
return 'SnPollAnswer(id: $id, answer: $answer, accountId: $accountId, pollId: $pollId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, account: $account)';
}
@@ -1220,11 +1220,11 @@ abstract mixin class $SnPollAnswerCopyWith<$Res> {
factory $SnPollAnswerCopyWith(SnPollAnswer value, $Res Function(SnPollAnswer) _then) = _$SnPollAnswerCopyWithImpl;
@useResult
$Res call({
String id, Map<String, dynamic> answer, String accountId, String pollId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
String id, Map<String, dynamic> answer, String accountId, String pollId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, SnAccount? account
});
$SnAccountCopyWith<$Res>? get account;
}
/// @nodoc
@@ -1237,7 +1237,7 @@ class _$SnPollAnswerCopyWithImpl<$Res>
/// Create a copy of SnPollAnswer
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? answer = null,Object? accountId = null,Object? pollId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? answer = null,Object? accountId = null,Object? pollId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? account = freezed,}) {
return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,answer: null == answer ? _self.answer : answer // ignore: cast_nullable_to_non_nullable
@@ -1246,10 +1246,23 @@ as String,pollId: null == pollId ? _self.pollId : pollId // ignore: cast_nullabl
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,
as DateTime?,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
as SnAccount?,
));
}
/// Create a copy of SnPollAnswer
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnAccountCopyWith<$Res>? get account {
if (_self.account == null) {
return null;
}
return $SnAccountCopyWith<$Res>(_self.account!, (value) {
return _then(_self.copyWith(account: value));
});
}
}
@@ -1328,10 +1341,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, Map<String, dynamic> answer, String accountId, String pollId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, Map<String, dynamic> answer, String accountId, String pollId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, SnAccount? account)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _SnPollAnswer() when $default != null:
return $default(_that.id,_that.answer,_that.accountId,_that.pollId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return $default(_that.id,_that.answer,_that.accountId,_that.pollId,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.account);case _:
return orElse();
}
@@ -1349,10 +1362,10 @@ return $default(_that.id,_that.answer,_that.accountId,_that.pollId,_that.created
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, Map<String, dynamic> answer, String accountId, String pollId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, Map<String, dynamic> answer, String accountId, String pollId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, SnAccount? account) $default,) {final _that = this;
switch (_that) {
case _SnPollAnswer():
return $default(_that.id,_that.answer,_that.accountId,_that.pollId,_that.createdAt,_that.updatedAt,_that.deletedAt);}
return $default(_that.id,_that.answer,_that.accountId,_that.pollId,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.account);}
}
/// A variant of `when` that fallback to returning `null`
///
@@ -1366,10 +1379,10 @@ return $default(_that.id,_that.answer,_that.accountId,_that.pollId,_that.created
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, Map<String, dynamic> answer, String accountId, String pollId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, Map<String, dynamic> answer, String accountId, String pollId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, SnAccount? account)? $default,) {final _that = this;
switch (_that) {
case _SnPollAnswer() when $default != null:
return $default(_that.id,_that.answer,_that.accountId,_that.pollId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
return $default(_that.id,_that.answer,_that.accountId,_that.pollId,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.account);case _:
return null;
}
@@ -1381,7 +1394,7 @@ return $default(_that.id,_that.answer,_that.accountId,_that.pollId,_that.created
@JsonSerializable()
class _SnPollAnswer implements SnPollAnswer {
const _SnPollAnswer({required this.id, required final Map<String, dynamic> answer, required this.accountId, required this.pollId, required this.createdAt, required this.updatedAt, required this.deletedAt}): _answer = answer;
const _SnPollAnswer({required this.id, required final Map<String, dynamic> answer, required this.accountId, required this.pollId, required this.createdAt, required this.updatedAt, required this.deletedAt, this.account}): _answer = answer;
factory _SnPollAnswer.fromJson(Map<String, dynamic> json) => _$SnPollAnswerFromJson(json);
@override final String id;
@@ -1397,6 +1410,7 @@ class _SnPollAnswer implements SnPollAnswer {
@override final DateTime createdAt;
@override final DateTime updatedAt;
@override final DateTime? deletedAt;
@override final SnAccount? account;
/// Create a copy of SnPollAnswer
/// with the given fields replaced by the non-null parameter values.
@@ -1411,16 +1425,16 @@ Map<String, dynamic> toJson() {
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPollAnswer&&(identical(other.id, id) || other.id == id)&&const DeepCollectionEquality().equals(other._answer, _answer)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.pollId, pollId) || other.pollId == pollId)&&(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 _SnPollAnswer&&(identical(other.id, id) || other.id == id)&&const DeepCollectionEquality().equals(other._answer, _answer)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.pollId, pollId) || other.pollId == pollId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.account, account) || other.account == account));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,const DeepCollectionEquality().hash(_answer),accountId,pollId,createdAt,updatedAt,deletedAt);
int get hashCode => Object.hash(runtimeType,id,const DeepCollectionEquality().hash(_answer),accountId,pollId,createdAt,updatedAt,deletedAt,account);
@override
String toString() {
return 'SnPollAnswer(id: $id, answer: $answer, accountId: $accountId, pollId: $pollId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
return 'SnPollAnswer(id: $id, answer: $answer, accountId: $accountId, pollId: $pollId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, account: $account)';
}
@@ -1431,11 +1445,11 @@ abstract mixin class _$SnPollAnswerCopyWith<$Res> implements $SnPollAnswerCopyWi
factory _$SnPollAnswerCopyWith(_SnPollAnswer value, $Res Function(_SnPollAnswer) _then) = __$SnPollAnswerCopyWithImpl;
@override @useResult
$Res call({
String id, Map<String, dynamic> answer, String accountId, String pollId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
String id, Map<String, dynamic> answer, String accountId, String pollId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, SnAccount? account
});
@override $SnAccountCopyWith<$Res>? get account;
}
/// @nodoc
@@ -1448,7 +1462,7 @@ class __$SnPollAnswerCopyWithImpl<$Res>
/// Create a copy of SnPollAnswer
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? answer = null,Object? accountId = null,Object? pollId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? answer = null,Object? accountId = null,Object? pollId = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? account = freezed,}) {
return _then(_SnPollAnswer(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,answer: null == answer ? _self._answer : answer // ignore: cast_nullable_to_non_nullable
@@ -1457,11 +1471,24 @@ as String,pollId: null == pollId ? _self.pollId : pollId // ignore: cast_nullabl
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,
as DateTime?,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
as SnAccount?,
));
}
/// Create a copy of SnPollAnswer
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnAccountCopyWith<$Res>? get account {
if (_self.account == null) {
return null;
}
return $SnAccountCopyWith<$Res>(_self.account!, (value) {
return _then(_self.copyWith(account: value));
});
}
}
// dart format on

View File

@@ -144,6 +144,10 @@ _SnPollAnswer _$SnPollAnswerFromJson(Map<String, dynamic> json) =>
json['deleted_at'] == null
? null
: DateTime.parse(json['deleted_at'] as String),
account:
json['account'] == null
? null
: SnAccount.fromJson(json['account'] as Map<String, dynamic>),
);
Map<String, dynamic> _$SnPollAnswerToJson(_SnPollAnswer instance) =>
@@ -155,4 +159,5 @@ Map<String, dynamic> _$SnPollAnswerToJson(_SnPollAnswer instance) =>
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
'account': instance.account?.toJson(),
};

View File

@@ -1,4 +1,5 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:island/models/account.dart';
import 'package:island/models/file.dart';
import 'package:island/models/post_category.dart';
import 'package:island/models/post_tag.dart';
@@ -22,11 +23,14 @@ sealed class SnPost with _$SnPost {
String? slug,
@Default(0) int type,
Map<String, dynamic>? meta,
SnPostEmbedView? embedView,
@Default(0) int viewsUnique,
@Default(0) int viewsTotal,
@Default(0) int upvotes,
@Default(0) int downvotes,
@Default(0) int repliesCount,
@Default(0) int awardedScore,
int? pinMode,
String? threadedPostId,
SnPost? threadedPost,
String? repliedPostId,
@@ -104,3 +108,56 @@ const Map<String, ReactInfo> kReactionTemplates = {
'pray': ReactInfo(icon: '🙏', attitude: 0),
'heart': ReactInfo(icon: '❤️', attitude: 0),
};
enum PostEmbedViewRenderer {
@JsonValue(0)
webView,
}
@freezed
sealed class SnPostEmbedView with _$SnPostEmbedView {
const factory SnPostEmbedView({
required String uri,
double? aspectRatio,
@Default(PostEmbedViewRenderer.webView) PostEmbedViewRenderer renderer,
}) = _SnPostEmbedView;
factory SnPostEmbedView.fromJson(Map<String, dynamic> json) =>
_$SnPostEmbedViewFromJson(json);
}
@freezed
sealed class SnPostAward with _$SnPostAward {
const factory SnPostAward({
required String id,
required double amount,
required int attitude,
String? message,
required String postId,
required String accountId,
@Default(null) DateTime? createdAt,
@Default(null) DateTime? updatedAt,
DateTime? deletedAt,
}) = _SnPostAward;
factory SnPostAward.fromJson(Map<String, dynamic> json) =>
_$SnPostAwardFromJson(json);
}
@freezed
sealed class SnPostReaction with _$SnPostReaction {
const factory SnPostReaction({
required String id,
required String symbol,
required int attitude,
required String postId,
required String accountId,
required DateTime createdAt,
required DateTime updatedAt,
@Default(null) SnAccount? account,
DateTime? deletedAt,
}) = _SnPostReaction;
factory SnPostReaction.fromJson(Map<String, dynamic> json) =>
_$SnPostReactionFromJson(json);
}

File diff suppressed because it is too large Load Diff

View File

@@ -24,11 +24,19 @@ _SnPost _$SnPostFromJson(Map<String, dynamic> json) => _SnPost(
slug: json['slug'] as String?,
type: (json['type'] as num?)?.toInt() ?? 0,
meta: json['meta'] as Map<String, dynamic>?,
embedView:
json['embed_view'] == null
? null
: SnPostEmbedView.fromJson(
json['embed_view'] as Map<String, dynamic>,
),
viewsUnique: (json['views_unique'] as num?)?.toInt() ?? 0,
viewsTotal: (json['views_total'] as num?)?.toInt() ?? 0,
upvotes: (json['upvotes'] as num?)?.toInt() ?? 0,
downvotes: (json['downvotes'] as num?)?.toInt() ?? 0,
repliesCount: (json['replies_count'] as num?)?.toInt() ?? 0,
awardedScore: (json['awarded_score'] as num?)?.toInt() ?? 0,
pinMode: (json['pin_mode'] as num?)?.toInt(),
threadedPostId: json['threaded_post_id'] as String?,
threadedPost:
json['threaded_post'] == null
@@ -104,11 +112,14 @@ Map<String, dynamic> _$SnPostToJson(_SnPost instance) => <String, dynamic>{
'slug': instance.slug,
'type': instance.type,
'meta': instance.meta,
'embed_view': instance.embedView?.toJson(),
'views_unique': instance.viewsUnique,
'views_total': instance.viewsTotal,
'upvotes': instance.upvotes,
'downvotes': instance.downvotes,
'replies_count': instance.repliesCount,
'awarded_score': instance.awardedScore,
'pin_mode': instance.pinMode,
'threaded_post_id': instance.threadedPostId,
'threaded_post': instance.threadedPost?.toJson(),
'replied_post_id': instance.repliedPostId,
@@ -164,3 +175,90 @@ Map<String, dynamic> _$SnSubscriptionStatusToJson(
'publisher_id': instance.publisherId,
'publisher_name': instance.publisherName,
};
_SnPostEmbedView _$SnPostEmbedViewFromJson(Map<String, dynamic> json) =>
_SnPostEmbedView(
uri: json['uri'] as String,
aspectRatio: (json['aspect_ratio'] as num?)?.toDouble(),
renderer:
$enumDecodeNullable(
_$PostEmbedViewRendererEnumMap,
json['renderer'],
) ??
PostEmbedViewRenderer.webView,
);
Map<String, dynamic> _$SnPostEmbedViewToJson(_SnPostEmbedView instance) =>
<String, dynamic>{
'uri': instance.uri,
'aspect_ratio': instance.aspectRatio,
'renderer': _$PostEmbedViewRendererEnumMap[instance.renderer]!,
};
const _$PostEmbedViewRendererEnumMap = {PostEmbedViewRenderer.webView: 0};
_SnPostAward _$SnPostAwardFromJson(Map<String, dynamic> json) => _SnPostAward(
id: json['id'] as String,
amount: (json['amount'] as num).toDouble(),
attitude: (json['attitude'] as num).toInt(),
message: json['message'] as String?,
postId: json['post_id'] as String,
accountId: json['account_id'] as String,
createdAt:
json['created_at'] == null
? null
: DateTime.parse(json['created_at'] as String),
updatedAt:
json['updated_at'] == null
? null
: DateTime.parse(json['updated_at'] as String),
deletedAt:
json['deleted_at'] == null
? null
: DateTime.parse(json['deleted_at'] as String),
);
Map<String, dynamic> _$SnPostAwardToJson(_SnPostAward instance) =>
<String, dynamic>{
'id': instance.id,
'amount': instance.amount,
'attitude': instance.attitude,
'message': instance.message,
'post_id': instance.postId,
'account_id': instance.accountId,
'created_at': instance.createdAt?.toIso8601String(),
'updated_at': instance.updatedAt?.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
};
_SnPostReaction _$SnPostReactionFromJson(Map<String, dynamic> json) =>
_SnPostReaction(
id: json['id'] as String,
symbol: json['symbol'] as String,
attitude: (json['attitude'] as num).toInt(),
postId: json['post_id'] as String,
accountId: json['account_id'] as String,
createdAt: DateTime.parse(json['created_at'] as String),
updatedAt: DateTime.parse(json['updated_at'] as String),
account:
json['account'] == null
? null
: SnAccount.fromJson(json['account'] as Map<String, dynamic>),
deletedAt:
json['deleted_at'] == null
? null
: DateTime.parse(json['deleted_at'] as String),
);
Map<String, dynamic> _$SnPostReactionToJson(_SnPostReaction instance) =>
<String, dynamic>{
'id': instance.id,
'symbol': instance.symbol,
'attitude': instance.attitude,
'post_id': instance.postId,
'account_id': instance.accountId,
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'account': instance.account?.toJson(),
'deleted_at': instance.deletedAt?.toIso8601String(),
};

View File

@@ -1,7 +1,7 @@
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';
import 'package:island/utils/text.dart';
part 'post_category.freezed.dart';
part 'post_category.g.dart';

View File

@@ -20,6 +20,24 @@ sealed class SnWallet with _$SnWallet {
_$SnWalletFromJson(json);
}
@freezed
sealed class SnWalletStats with _$SnWalletStats {
const factory SnWalletStats({
required DateTime periodBegin,
required DateTime periodEnd,
required int totalTransactions,
required int totalOrders,
required double totalIncome,
required double totalOutgoing,
required double sum,
@Default({}) Map<String, double> incomeCategories,
@Default({}) Map<String, double> outgoingCategories,
}) = _SnWalletStats;
factory SnWalletStats.fromJson(Map<String, dynamic> json) =>
_$SnWalletStatsFromJson(json);
}
@freezed
sealed class SnWalletPocket with _$SnWalletPocket {
const factory SnWalletPocket({
@@ -108,17 +126,14 @@ sealed class SnWalletOrder with _$SnWalletOrder {
required String id,
required int status,
required String currency,
required dynamic remarks,
required String? remarks,
required String appIdentifier,
@Default({}) Map<String, dynamic> meta,
required int amount,
required DateTime expiredAt,
required String? payeeWalletId,
required SnWallet? payeeWallet,
required String? transactionId,
required SnTransaction? transaction,
required String? issuerAppId,
required dynamic issuerApp,
required DateTime createdAt,
required DateTime updatedAt,
required DateTime? deletedAt,
@@ -127,3 +142,72 @@ sealed class SnWalletOrder with _$SnWalletOrder {
factory SnWalletOrder.fromJson(Map<String, dynamic> json) =>
_$SnWalletOrderFromJson(json);
}
@freezed
sealed class SnWalletGift with _$SnWalletGift {
const factory SnWalletGift({
required String id,
required String giftCode,
required String subscriptionIdentifier,
required String? recipientId,
required SnAccount? recipient,
required String gifterId,
required SnAccount? gifter,
required String? redeemerId,
required SnAccount? redeemer,
required String? message,
required int status,
required DateTime? redeemedAt,
required DateTime? expiredAt,
required String? subscriptionId,
required SnWalletSubscription? subscription,
required DateTime createdAt,
required DateTime updatedAt,
required DateTime? deletedAt,
}) = _SnWalletGift;
factory SnWalletGift.fromJson(Map<String, dynamic> json) =>
_$SnWalletGiftFromJson(json);
}
@freezed
sealed class SnWalletFund with _$SnWalletFund {
const factory SnWalletFund({
required String id,
required String currency,
required double totalAmount,
required int splitType, // 0: even, 1: random
required int
status, // 0: created, 1: partially claimed, 2: fully claimed, 3: expired
required String? message,
required String creatorAccountId,
required SnAccount? creatorAccount,
required DateTime expiredAt,
required List<SnWalletFundRecipient> recipients,
required DateTime createdAt,
required DateTime updatedAt,
required DateTime? deletedAt,
}) = _SnWalletFund;
factory SnWalletFund.fromJson(Map<String, dynamic> json) =>
_$SnWalletFundFromJson(json);
}
@freezed
sealed class SnWalletFundRecipient with _$SnWalletFundRecipient {
const factory SnWalletFundRecipient({
required String id,
required String fundId,
required String recipientAccountId,
required SnAccount? recipientAccount,
required double amount,
required bool isReceived,
required DateTime? receivedAt,
required DateTime createdAt,
required DateTime updatedAt,
required DateTime? deletedAt,
}) = _SnWalletFundRecipient;
factory SnWalletFundRecipient.fromJson(Map<String, dynamic> json) =>
_$SnWalletFundRecipientFromJson(json);
}

File diff suppressed because it is too large Load Diff

View File

@@ -35,6 +35,40 @@ Map<String, dynamic> _$SnWalletToJson(_SnWallet instance) => <String, dynamic>{
'deleted_at': instance.deletedAt?.toIso8601String(),
};
_SnWalletStats _$SnWalletStatsFromJson(Map<String, dynamic> json) =>
_SnWalletStats(
periodBegin: DateTime.parse(json['period_begin'] as String),
periodEnd: DateTime.parse(json['period_end'] as String),
totalTransactions: (json['total_transactions'] as num).toInt(),
totalOrders: (json['total_orders'] as num).toInt(),
totalIncome: (json['total_income'] as num).toDouble(),
totalOutgoing: (json['total_outgoing'] as num).toDouble(),
sum: (json['sum'] as num).toDouble(),
incomeCategories:
(json['income_categories'] as Map<String, dynamic>?)?.map(
(k, e) => MapEntry(k, (e as num).toDouble()),
) ??
const {},
outgoingCategories:
(json['outgoing_categories'] as Map<String, dynamic>?)?.map(
(k, e) => MapEntry(k, (e as num).toDouble()),
) ??
const {},
);
Map<String, dynamic> _$SnWalletStatsToJson(_SnWalletStats instance) =>
<String, dynamic>{
'period_begin': instance.periodBegin.toIso8601String(),
'period_end': instance.periodEnd.toIso8601String(),
'total_transactions': instance.totalTransactions,
'total_orders': instance.totalOrders,
'total_income': instance.totalIncome,
'total_outgoing': instance.totalOutgoing,
'sum': instance.sum,
'income_categories': instance.incomeCategories,
'outgoing_categories': instance.outgoingCategories,
};
_SnWalletPocket _$SnWalletPocketFromJson(Map<String, dynamic> json) =>
_SnWalletPocket(
id: json['id'] as String,
@@ -195,25 +229,14 @@ _SnWalletOrder _$SnWalletOrderFromJson(Map<String, dynamic> json) =>
id: json['id'] as String,
status: (json['status'] as num).toInt(),
currency: json['currency'] as String,
remarks: json['remarks'],
remarks: json['remarks'] as String?,
appIdentifier: json['app_identifier'] as String,
meta: json['meta'] as Map<String, dynamic>? ?? const {},
amount: (json['amount'] as num).toInt(),
expiredAt: DateTime.parse(json['expired_at'] as String),
payeeWalletId: json['payee_wallet_id'] as String?,
payeeWallet:
json['payee_wallet'] == null
? null
: SnWallet.fromJson(json['payee_wallet'] as Map<String, dynamic>),
transactionId: json['transaction_id'] as String?,
transaction:
json['transaction'] == null
? null
: SnTransaction.fromJson(
json['transaction'] as Map<String, dynamic>,
),
issuerAppId: json['issuer_app_id'] as String?,
issuerApp: json['issuer_app'],
createdAt: DateTime.parse(json['created_at'] as String),
updatedAt: DateTime.parse(json['updated_at'] as String),
deletedAt:
@@ -233,12 +256,161 @@ Map<String, dynamic> _$SnWalletOrderToJson(_SnWalletOrder instance) =>
'amount': instance.amount,
'expired_at': instance.expiredAt.toIso8601String(),
'payee_wallet_id': instance.payeeWalletId,
'payee_wallet': instance.payeeWallet?.toJson(),
'transaction_id': instance.transactionId,
'transaction': instance.transaction?.toJson(),
'issuer_app_id': instance.issuerAppId,
'issuer_app': instance.issuerApp,
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
};
_SnWalletGift _$SnWalletGiftFromJson(Map<String, dynamic> json) =>
_SnWalletGift(
id: json['id'] as String,
giftCode: json['gift_code'] as String,
subscriptionIdentifier: json['subscription_identifier'] as String,
recipientId: json['recipient_id'] as String?,
recipient:
json['recipient'] == null
? null
: SnAccount.fromJson(json['recipient'] as Map<String, dynamic>),
gifterId: json['gifter_id'] as String,
gifter:
json['gifter'] == null
? null
: SnAccount.fromJson(json['gifter'] as Map<String, dynamic>),
redeemerId: json['redeemer_id'] as String?,
redeemer:
json['redeemer'] == null
? null
: SnAccount.fromJson(json['redeemer'] as Map<String, dynamic>),
message: json['message'] as String?,
status: (json['status'] as num).toInt(),
redeemedAt:
json['redeemed_at'] == null
? null
: DateTime.parse(json['redeemed_at'] as String),
expiredAt:
json['expired_at'] == null
? null
: DateTime.parse(json['expired_at'] as String),
subscriptionId: json['subscription_id'] as String?,
subscription:
json['subscription'] == null
? null
: SnWalletSubscription.fromJson(
json['subscription'] 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> _$SnWalletGiftToJson(_SnWalletGift instance) =>
<String, dynamic>{
'id': instance.id,
'gift_code': instance.giftCode,
'subscription_identifier': instance.subscriptionIdentifier,
'recipient_id': instance.recipientId,
'recipient': instance.recipient?.toJson(),
'gifter_id': instance.gifterId,
'gifter': instance.gifter?.toJson(),
'redeemer_id': instance.redeemerId,
'redeemer': instance.redeemer?.toJson(),
'message': instance.message,
'status': instance.status,
'redeemed_at': instance.redeemedAt?.toIso8601String(),
'expired_at': instance.expiredAt?.toIso8601String(),
'subscription_id': instance.subscriptionId,
'subscription': instance.subscription?.toJson(),
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
};
_SnWalletFund _$SnWalletFundFromJson(
Map<String, dynamic> json,
) => _SnWalletFund(
id: json['id'] as String,
currency: json['currency'] as String,
totalAmount: (json['total_amount'] as num).toDouble(),
splitType: (json['split_type'] as num).toInt(),
status: (json['status'] as num).toInt(),
message: json['message'] as String?,
creatorAccountId: json['creator_account_id'] as String,
creatorAccount:
json['creator_account'] == null
? null
: SnAccount.fromJson(json['creator_account'] as Map<String, dynamic>),
expiredAt: DateTime.parse(json['expired_at'] as String),
recipients:
(json['recipients'] as List<dynamic>)
.map((e) => SnWalletFundRecipient.fromJson(e as Map<String, dynamic>))
.toList(),
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> _$SnWalletFundToJson(_SnWalletFund instance) =>
<String, dynamic>{
'id': instance.id,
'currency': instance.currency,
'total_amount': instance.totalAmount,
'split_type': instance.splitType,
'status': instance.status,
'message': instance.message,
'creator_account_id': instance.creatorAccountId,
'creator_account': instance.creatorAccount?.toJson(),
'expired_at': instance.expiredAt.toIso8601String(),
'recipients': instance.recipients.map((e) => e.toJson()).toList(),
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
};
_SnWalletFundRecipient _$SnWalletFundRecipientFromJson(
Map<String, dynamic> json,
) => _SnWalletFundRecipient(
id: json['id'] as String,
fundId: json['fund_id'] as String,
recipientAccountId: json['recipient_account_id'] as String,
recipientAccount:
json['recipient_account'] == null
? null
: SnAccount.fromJson(
json['recipient_account'] as Map<String, dynamic>,
),
amount: (json['amount'] as num).toDouble(),
isReceived: json['is_received'] as bool,
receivedAt:
json['received_at'] == null
? null
: DateTime.parse(json['received_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> _$SnWalletFundRecipientToJson(
_SnWalletFundRecipient instance,
) => <String, dynamic>{
'id': instance.id,
'fund_id': instance.fundId,
'recipient_account_id': instance.recipientAccountId,
'recipient_account': instance.recipientAccount?.toJson(),
'amount': instance.amount,
'is_received': instance.isReceived,
'received_at': instance.receivedAt?.toIso8601String(),
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(),
};

View File

@@ -0,0 +1,454 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/account.dart';
import 'package:island/pods/network.dart';
import 'package:island/talker.dart';
import 'package:island/widgets/account/status.dart';
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:shelf_web_socket/shelf_web_socket.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
// Conditional imports for IPC server - use web stubs on web platform
import 'ipc_server.dart' if (dart.library.html) 'ipc_server.web.dart';
const String kRpcLogPrefix = 'arRPC.websocket';
const String kRpcIpcLogPrefix = 'arRPC.ipc';
// IPC Constants
const String kIpcBasePath = 'discord-ipc';
// IPC Packet Types
class IpcTypes {
static const int handshake = 0;
static const int frame = 1;
static const int close = 2;
static const int ping = 3;
static const int pong = 4;
}
// IPC Close Codes
class IpcCloseCodes {
static const int closeNormal = 1000;
static const int closeUnsupported = 1003;
static const int closeAbnormal = 1006;
}
// IPC Error Codes
class IpcErrorCodes {
static const int invalidClientId = 4000;
static const int invalidOrigin = 4001;
static const int rateLimited = 4002;
static const int tokenRevoked = 4003;
static const int invalidVersion = 4004;
static const int invalidEncoding = 4005;
}
// Reference https://github.com/OpenAsar/arrpc/blob/main/src/transports/ipc.js
class ActivityRpcServer {
static const List<int> portRange = [6463, 6472]; // Ports 64636472
Map<String, Function>
handlers; // {connection: (socket), message: (socket, data), close: (socket)}
HttpServer? _httpServer;
IpcServer? _ipcServer;
final List<WebSocketChannel> _wsSockets = [];
ActivityRpcServer(this.handlers);
void updateHandlers(Map<String, Function> newHandlers) {
handlers = newHandlers;
}
// Start the server
Future<void> start() async {
int port = portRange[0];
bool wsSuccess = false;
// Start WebSocket server
while (port <= portRange[1]) {
talker.log('[$kRpcLogPrefix] Trying port $port');
try {
_httpServer = await HttpServer.bind(InternetAddress.loopbackIPv4, port);
talker.log('[$kRpcLogPrefix] Listening on $port');
shelf_io.serveRequests(_httpServer!, (Request request) async {
talker.log('[$kRpcLogPrefix] New request');
if (request.headers['upgrade']?.toLowerCase() == 'websocket') {
final handler = webSocketHandler((WebSocketChannel channel, _) {
_wsSockets.add(channel);
_onWsConnection(channel, request);
});
return handler(request);
}
talker.log('New request disposed due to not websocket');
return Response.notFound('Not a WebSocket request');
});
wsSuccess = true;
break;
} catch (e) {
if (e is SocketException && e.osError?.errorCode == 98) {
talker.log('[$kRpcLogPrefix] $port in use!');
} else {
talker.log('[$kRpcLogPrefix] HTTP error: $e');
}
port++;
await Future.delayed(Duration(milliseconds: 100)); // Add delay
}
}
if (!wsSuccess) {
throw Exception(
'Failed to bind to any port in range ${portRange[0]}${portRange[1]}',
);
}
// Start IPC server
final shouldStartIpc = !Platform.isMacOS && !kIsWeb;
if (shouldStartIpc) {
try {
_ipcServer = MultiPlatformIpcServer();
// Set up IPC handlers
_ipcServer!.handlePacket = (socket, packet, _) {
_handleIpcPacket(socket, packet);
};
await _ipcServer!.start();
} catch (e) {
talker.log('[$kRpcLogPrefix] IPC server error: $e');
}
} else {
talker.log('IPC server disabled on macOS or web in production mode');
}
}
// Stop the server
Future<void> stop() async {
// Stop WebSocket server
for (var socket in _wsSockets) {
try {
await socket.sink.close();
} catch (e) {
talker.log('[$kRpcLogPrefix] Error closing WebSocket: $e');
}
}
_wsSockets.clear();
await _httpServer?.close(force: true);
// Stop IPC server
await _ipcServer?.stop();
talker.log('[$kRpcLogPrefix] Servers stopped');
}
// Handle new WebSocket connection
void _onWsConnection(WebSocketChannel socket, Request request) {
final uri = request.url;
final params = uri.queryParameters;
final ver = int.tryParse(params['v'] ?? '1') ?? 1;
final encoding = params['encoding'] ?? 'json';
final clientId = params['client_id'] ?? '';
final origin = request.headers['origin'] ?? '';
talker.log('New WS connection! origin: $origin, params: $params');
if (origin.isNotEmpty &&
![
'https://discord.com',
'https://ptb.discord.com',
'https://canary.discord.com',
].contains(origin)) {
talker.log('[$kRpcLogPrefix] Disallowed origin: $origin');
socket.sink.close();
return;
}
if (encoding != 'json') {
talker.log('Unsupported encoding requested: $encoding');
socket.sink.close();
return;
}
if (ver != 1) {
talker.log('[$kRpcLogPrefix] Unsupported version requested: $ver');
socket.sink.close();
return;
}
final socketWithMeta = _WsSocketWrapper(socket, clientId, encoding);
socket.stream.listen(
(data) => _onWsMessage(socketWithMeta, data),
onError: (e) {
talker.log('[$kRpcLogPrefix] WS socket error: $e');
},
onDone: () {
talker.log('[$kRpcLogPrefix] WS socket closed');
handlers['close']?.call(socketWithMeta);
_wsSockets.remove(socket);
},
);
handlers['connection']?.call(socketWithMeta);
}
// Handle incoming WebSocket message
Future<void> _onWsMessage(_WsSocketWrapper socket, dynamic data) async {
if (data is! String) {
talker.log('Invalid WebSocket message: not a string');
return;
}
try {
final jsonData = await compute(jsonDecode, data);
if (jsonData is! Map<String, dynamic>) {
talker.log('Invalid WebSocket message: not a JSON object');
return;
}
talker.log('[$kRpcLogPrefix] WS message: $jsonData');
handlers['message']?.call(socket, jsonData);
} catch (e) {
talker.log('[$kRpcLogPrefix] WS message parse error: $e');
}
}
// Handle IPC packet
void _handleIpcPacket(IpcSocketWrapper socket, IpcPacket packet) {
switch (packet.type) {
case IpcTypes.ping:
talker.log('[$kRpcLogPrefix] IPC ping received');
socket.sendPong(packet.data);
break;
case IpcTypes.pong:
talker.log('[$kRpcLogPrefix] IPC pong received');
break;
case IpcTypes.handshake:
if (socket.handshook) {
throw Exception('Already handshook');
}
socket.handshook = true;
_onIpcHandshake(socket, packet.data);
break;
case IpcTypes.frame:
if (!socket.handshook) {
throw Exception('Need to handshake first');
}
talker.log('[$kRpcLogPrefix] IPC frame: ${packet.data}');
handlers['message']?.call(socket, packet.data);
break;
case IpcTypes.close:
socket.close();
break;
default:
throw Exception('Invalid packet type: ${packet.type}');
}
}
// Handle IPC handshake
void _onIpcHandshake(IpcSocketWrapper socket, Map<String, dynamic> params) {
talker.log('[$kRpcLogPrefix] IPC handshake: $params');
final ver = int.tryParse(params['v']?.toString() ?? '1') ?? 1;
final clientId = params['client_id']?.toString() ?? '';
if (ver != 1) {
talker.log('IPC unsupported version requested: $ver');
socket.closeWithCode(IpcErrorCodes.invalidVersion);
return;
}
if (clientId.isEmpty) {
talker.log('[$kRpcLogPrefix] IPC client ID required');
socket.closeWithCode(IpcErrorCodes.invalidClientId);
return;
}
socket.clientId = clientId;
handlers['connection']?.call(socket);
}
}
// WebSocket wrapper
class _WsSocketWrapper {
final WebSocketChannel channel;
final String clientId;
final String encoding;
_WsSocketWrapper(this.channel, this.clientId, this.encoding);
void send(Map<String, dynamic> msg) {
talker.log('[$kRpcLogPrefix] WS sending: $msg');
channel.sink.add(jsonEncode(msg));
}
}
// State management for server status and activities
class ServerState {
final String status;
final List<String> activities;
ServerState({required this.status, this.activities = const []});
ServerState copyWith({String? status, List<String>? activities}) {
return ServerState(
status: status ?? this.status,
activities: activities ?? this.activities,
);
}
}
class ServerStateNotifier extends StateNotifier<ServerState> {
final ActivityRpcServer server;
ServerStateNotifier(this.server)
: super(ServerState(status: 'Server not started'));
Future<void> start() async {
if (!kIsWeb && !Platform.isAndroid && !Platform.isIOS) {
try {
await server.start();
state = state.copyWith(status: 'Server running');
} catch (e) {
state = state.copyWith(status: 'Server failed: $e');
}
} else {
Future(() {
state = state.copyWith(status: 'Server disabled on mobile/web');
});
}
}
void updateStatus(String status) {
state = state.copyWith(status: status);
}
void addActivity(String activity) {
state = state.copyWith(activities: [...state.activities, activity]);
}
}
// Providers
final rpcServerStateProvider =
StateNotifierProvider<ServerStateNotifier, ServerState>((ref) {
final server = ActivityRpcServer({});
final notifier = ServerStateNotifier(server);
server.updateHandlers({
'connection': (socket) {
final clientId =
socket is _WsSocketWrapper
? socket.clientId
: (socket as IpcSocketWrapper).clientId;
notifier.updateStatus('Client connected (ID: $clientId)');
socket.send({
'cmd': 'DISPATCH',
'data': {
'v': 1,
'config': {
'cdn_host': 'fake.cdn',
'api_endpoint': '//fake.api',
'environment': 'dev',
},
'user': {
'id': 'fake_user_id',
'username': 'FakeUser',
'discriminator': '0001',
'avatar': null,
'bot': false,
},
},
'evt': 'READY',
'nonce': '12345',
});
},
'message': (socket, dynamic data) async {
if (data['cmd'] == 'SET_ACTIVITY') {
notifier.addActivity(
'Activity: ${data['args']['activity']['details'] ?? ''}',
);
final label = data['args']['activity']['details'] ?? '';
final appId = socket.clientId;
final meta = data['args']['activity'];
try {
await setRemoteActivityStatus(ref, label, appId, meta);
final now = DateTime.now();
final status = SnAccountStatus(
id: 'local_$appId',
attitude: 0,
isOnline: true,
isInvisible: false,
isNotDisturb: false,
isCustomized: true,
label: label,
meta: meta,
clearedAt: null,
accountId: 'me',
createdAt: now,
updatedAt: now,
deletedAt: null,
);
ref.read(currentAccountStatusProvider.notifier).setStatus(status);
} catch (e) {
talker.log('Failed to set remote activity status: $e');
}
socket.send({
'cmd': 'SET_ACTIVITY',
'data': data['args']['activity'],
'evt': null,
'nonce': data['nonce'],
});
}
},
'close': (socket) async {
notifier.updateStatus('Client disconnected');
final appId = socket.clientId;
try {
await unsetRemoteActivityStatus(ref, appId);
ref.read(currentAccountStatusProvider.notifier).clearStatus();
} catch (e) {
talker.log('Failed to unset remote activity status: $e');
}
},
});
return notifier;
});
final rpcServerProvider = Provider<ActivityRpcServer>((ref) {
final notifier = ref.watch(rpcServerStateProvider.notifier);
return notifier.server;
});
Future<void> setRemoteActivityStatus(
Ref ref,
String label,
String appId,
Map<String, dynamic> meta,
) async {
final apiClient = ref.read(apiClientProvider);
await apiClient.post(
'/id/accounts/me/statuses',
data: {
'is_invisible': false,
'is_not_disturb': false,
'is_automated': true,
'label': label,
'app_identifier': appId,
'meta': meta,
},
);
}
Future<void> unsetRemoteActivityStatus(Ref ref, String appId) async {
final apiClient = ref.read(apiClientProvider);
await apiClient.delete(
'/id/accounts/me/statuses',
queryParameters: {'app': appId},
);
}

View File

@@ -0,0 +1,282 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:dart_ipc/dart_ipc.dart';
import 'package:island/talker.dart';
import 'package:path/path.dart' as path;
const String kRpcIpcLogPrefix = 'arRPC.ipc';
// IPC Packet Types
class IpcTypes {
static const int handshake = 0;
static const int frame = 1;
static const int close = 2;
static const int ping = 3;
static const int pong = 4;
}
// IPC Close Codes
class IpcCloseCodes {
static const int closeNormal = 1000;
static const int closeUnsupported = 1003;
static const int closeAbnormal = 1006;
}
// IPC Error Codes
class IpcErrorCodes {
static const int invalidClientId = 4000;
static const int invalidOrigin = 4001;
static const int rateLimited = 4002;
static const int tokenRevoked = 4003;
static const int invalidVersion = 4004;
static const int invalidEncoding = 4005;
}
// IPC Packet structure
class IpcPacket {
final int type;
final Map<String, dynamic> data;
IpcPacket(this.type, this.data);
}
// Abstract base class for IPC server
abstract class IpcServer {
final List<IpcSocketWrapper> _sockets = [];
// Encode IPC packet
static Uint8List encodeIpcPacket(int type, Map<String, dynamic> data) {
final jsonData = jsonEncode(data);
final dataBytes = utf8.encode(jsonData);
final dataSize = dataBytes.length;
final buffer = ByteData(8 + dataSize);
buffer.setInt32(0, type, Endian.little);
buffer.setInt32(4, dataSize, Endian.little);
buffer.buffer.asUint8List().setRange(8, 8 + dataSize, dataBytes);
return buffer.buffer.asUint8List();
}
Future<void> start();
Future<void> stop();
void addSocket(IpcSocketWrapper socket) {
_sockets.add(socket);
}
void removeSocket(IpcSocketWrapper socket) {
_sockets.remove(socket);
}
List<IpcSocketWrapper> get sockets => _sockets;
void Function(
IpcSocketWrapper socket,
IpcPacket packet,
Map<String, Function> handlers,
)?
handlePacket;
}
// Abstract base class for IPC socket wrapper
abstract class IpcSocketWrapper {
String clientId = '';
bool handshook = false;
final List<int> _buffer = [];
void addData(List<int> data) {
_buffer.addAll(data);
}
void send(Map<String, dynamic> msg);
void sendPong(dynamic data);
void close();
void closeWithCode(int code, [String message = '']);
List<IpcPacket> readPackets() {
final packets = <IpcPacket>[];
while (_buffer.length >= 8) {
final buffer = Uint8List.fromList(_buffer);
final byteData = ByteData.view(buffer.buffer);
final type = byteData.getInt32(0, Endian.little);
final dataSize = byteData.getInt32(4, Endian.little);
if (_buffer.length < 8 + dataSize) break;
final dataBytes = _buffer.sublist(8, 8 + dataSize);
final jsonStr = utf8.decode(dataBytes);
final jsonData = jsonDecode(jsonStr);
packets.add(IpcPacket(type, jsonData));
_buffer.removeRange(0, 8 + dataSize);
}
return packets;
}
}
// Multiplatform IPC Server implementation using dart_ipc
class MultiPlatformIpcServer extends IpcServer {
StreamSubscription? _serverSubscription;
@override
Future<void> start() async {
try {
final ipcPath =
Platform.isWindows
? r'\\.\pipe\discord-ipc-0'
: await _findAvailableUnixIpcPath();
final serverSocket = await bind(ipcPath);
talker.log('IPC listening at $ipcPath');
_serverSubscription = serverSocket.listen((socket) {
final socketWrapper = MultiPlatformIpcSocketWrapper(socket);
addSocket(socketWrapper);
talker.log('New IPC connection!');
_handleIpcData(socketWrapper);
});
} catch (e) {
throw Exception('Failed to start IPC server: $e');
}
}
@override
Future<void> stop() async {
for (var socket in sockets) {
try {
socket.close();
} catch (e) {
talker.log('Error closing IPC socket: $e');
}
}
sockets.clear();
_serverSubscription?.cancel();
}
// Handle incoming IPC data
void _handleIpcData(MultiPlatformIpcSocketWrapper socket) {
final startTime = DateTime.now();
socket.socket.listen(
(data) {
final readStart = DateTime.now();
socket.addData(data);
final readDuration =
DateTime.now().difference(readStart).inMicroseconds;
talker.log('Read data took $readDuration microseconds');
final packets = socket.readPackets();
for (final packet in packets) {
handlePacket?.call(socket, packet, {});
}
},
onDone: () {
talker.log('IPC connection closed');
socket.close();
},
onError: (e) {
talker.log('IPC data error: $e');
socket.closeWithCode(IpcCloseCodes.closeUnsupported, e.toString());
},
);
final totalDuration = DateTime.now().difference(startTime).inMicroseconds;
talker.log('_handleIpcData took $totalDuration microseconds');
}
Future<String> _getMacOsSystemTmpDir() async {
final result = await Process.run('getconf', ['DARWIN_USER_TEMP_DIR']);
return (result.stdout as String).trim();
}
// Find available IPC socket path for Unix-like systems
Future<String> _findAvailableUnixIpcPath() async {
// Build list of directories to try, with macOS-specific handling
final baseDirs = <String>[];
if (Platform.isMacOS) {
try {
final macTempDir = await _getMacOsSystemTmpDir();
if (macTempDir.isNotEmpty) {
baseDirs.add(macTempDir);
}
} catch (e) {
talker.log('Failed to get macOS system temp dir: $e');
}
}
// Add other standard directories
final otherDirs = [
Platform.environment['XDG_RUNTIME_DIR'],
Platform.environment['TMPDIR'],
Platform.environment['TMP'],
Platform.environment['TEMP'],
'/tmp',
];
baseDirs.addAll(
otherDirs.where((dir) => dir != null && dir.isNotEmpty).cast<String>(),
);
for (final baseDir in baseDirs) {
for (int i = 0; i < 10; i++) {
final socketPath = path.join(baseDir, 'discord-ipc-$i');
try {
final socket = await bind(socketPath);
socket.close();
try {
await File(socketPath).delete();
} catch (_) {}
talker.log('IPC socket will be created at: $socketPath');
return socketPath;
} catch (e) {
if (i == 0) {
talker.log('IPC path $socketPath not available: $e');
}
continue;
}
}
}
throw Exception(
'No available IPC socket paths found in any temp directory',
);
}
}
// Multiplatform IPC Socket Wrapper
class MultiPlatformIpcSocketWrapper extends IpcSocketWrapper {
final dynamic socket;
MultiPlatformIpcSocketWrapper(this.socket);
@override
void send(Map<String, dynamic> msg) {
talker.log('IPC sending: $msg');
final packet = IpcServer.encodeIpcPacket(IpcTypes.frame, msg);
socket.add(packet);
}
@override
void sendPong(dynamic data) {
final packet = IpcServer.encodeIpcPacket(IpcTypes.pong, data ?? {});
socket.add(packet);
}
@override
void close() {
socket.close();
}
@override
void closeWithCode(int code, [String message = '']) {
final closeData = {'code': code, 'message': message};
final packet = IpcServer.encodeIpcPacket(IpcTypes.close, closeData);
socket.add(packet);
socket.close();
}
}

View File

@@ -0,0 +1,61 @@
// Stub implementation for web platform
// This file provides empty implementations to avoid import errors on web
// IPC Packet Types
class IpcTypes {
static const int handshake = 0;
static const int frame = 1;
static const int close = 2;
static const int ping = 3;
static const int pong = 4;
}
// IPC Close Codes
class IpcCloseCodes {
static const int closeNormal = 1000;
static const int closeUnsupported = 1003;
static const int closeAbnormal = 1006;
}
// IPC Error Codes
class IpcErrorCodes {
static const int invalidClientId = 4000;
static const int invalidOrigin = 4001;
static const int rateLimited = 4002;
static const int tokenRevoked = 4003;
static const int invalidVersion = 4004;
static const int invalidEncoding = 4005;
}
// IPC Packet structure
class IpcPacket {
final int type;
final Map<String, dynamic> data;
IpcPacket(this.type, this.data);
}
class IpcServer {
Future<void> start() async {}
Future<void> stop() async {}
void Function(dynamic, dynamic, dynamic)? handlePacket;
void addSocket(dynamic socket) {}
void removeSocket(dynamic socket) {}
List<dynamic> get sockets => [];
}
class IpcSocketWrapper {
String clientId = '';
bool handshook = false;
void addData(List<int> data) {}
void send(Map<String, dynamic> msg) {}
void sendPong(dynamic data) {}
void close() {}
void closeWithCode(int code, [String message = '']) {}
List<dynamic> readPackets() => [];
}
class MultiPlatformIpcServer extends IpcServer {}
class MultiPlatformIpcSocketWrapper extends IpcSocketWrapper {}

View File

@@ -1,27 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'call.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
String _$callNotifierHash() => r'18fb807f067eecd3ea42631c1426c3e5f1fb4280';
/// See also [CallNotifier].
@ProviderFor(CallNotifier)
final callNotifierProvider =
AutoDisposeNotifierProvider<CallNotifier, CallState>.internal(
CallNotifier.new,
name: r'callNotifierProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product')
? null
: _$callNotifierHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$CallNotifier = AutoDisposeNotifier<CallState>;
// 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,14 +1,17 @@
import 'dart:async';
import 'dart:developer';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:island/widgets/alert.dart';
import 'package:island/widgets/chat/call_button.dart';
import 'package:livekit_client/livekit_client.dart';
import 'package:livekit_client/livekit_client.dart' as lk;
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:island/pods/network.dart';
import 'package:island/models/chat.dart';
import 'package:wakelock_plus/wakelock_plus.dart';
import 'package:island/talker.dart';
part 'call.g.dart';
part 'call.freezed.dart';
@@ -40,7 +43,7 @@ sealed class CallParticipantLive with _$CallParticipantLive {
const factory CallParticipantLive({
required CallParticipant participant,
required Participant remoteParticipant,
required lk.Participant remoteParticipant,
}) = _CallParticipantLive;
bool get isSpeaking => remoteParticipant.isSpeaking;
@@ -54,23 +57,23 @@ sealed class CallParticipantLive with _$CallParticipantLive {
bool get hasAudio => remoteParticipant.hasAudio;
}
@riverpod
@Riverpod(keepAlive: true)
class CallNotifier extends _$CallNotifier {
Room? _room;
LocalParticipant? _localParticipant;
lk.Room? _room;
lk.LocalParticipant? _localParticipant;
List<CallParticipantLive> _participants = [];
final Map<String, CallParticipant> _participantInfoByIdentity = {};
EventsListener? _roomListener;
lk.EventsListener? _roomListener;
List<CallParticipantLive> get participants =>
List.unmodifiable(_participants);
LocalParticipant? get localParticipant => _localParticipant;
lk.LocalParticipant? get localParticipant => _localParticipant;
Map<String, double> participantsVolumes = {};
Timer? _durationTimer;
Room? get room => _room;
lk.Room? get room => _room;
@override
CallState build() {
@@ -90,10 +93,10 @@ class CallNotifier extends _$CallNotifier {
_roomListener = _room!.createListener();
_room!.addListener(_onRoomChange);
_roomListener!
..on<ParticipantConnectedEvent>((e) {
..on<lk.ParticipantConnectedEvent>((e) {
_refreshLiveParticipants();
})
..on<RoomDisconnectedEvent>((e) {
..on<lk.RoomDisconnectedEvent>((e) {
_participants = [];
state = state.copyWith();
});
@@ -187,7 +190,7 @@ class CallNotifier extends _$CallNotifier {
// Add remote participants
_participants.addAll(
participants.map((p) {
RemoteParticipant? remote;
lk.RemoteParticipant? remote;
for (final r in remotes) {
if (r.identity == p.identity) {
remote = r;
@@ -211,11 +214,11 @@ class CallNotifier extends _$CallNotifier {
Future<void> joinRoom(String roomId) async {
if (_roomId == roomId && _room != null) {
log('[Call] Call skipped. Already has data');
talker.info('[Call] Call skipped. Already has data');
return;
} else if (_room != null) {
if (!_room!.isDisposed &&
_room!.connectionState != ConnectionState.disconnected) {
_room!.connectionState != lk.ConnectionState.disconnected) {
throw Exception('Call already connected');
}
}
@@ -255,15 +258,15 @@ class CallNotifier extends _$CallNotifier {
});
// Connect to LiveKit
_room = Room();
_room = lk.Room();
await _room!.connect(
endpoint,
token,
connectOptions: ConnectOptions(autoSubscribe: true),
roomOptions: RoomOptions(adaptiveStream: true, dynacast: true),
fastConnectOptions: FastConnectOptions(
microphone: TrackOption(enabled: true),
connectOptions: lk.ConnectOptions(autoSubscribe: true),
roomOptions: lk.RoomOptions(adaptiveStream: true, dynacast: true),
fastConnectOptions: lk.FastConnectOptions(
microphone: lk.TrackOption(enabled: true),
),
);
_localParticipant = _room!.localParticipant;
@@ -272,19 +275,32 @@ class CallNotifier extends _$CallNotifier {
_updateLiveParticipants(participants);
if (!kIsWeb && (Platform.isIOS || Platform.isAndroid)) {
Hardware.instance.setSpeakerphoneOn(true);
lk.Hardware.instance.setSpeakerphoneOn(true);
}
// Listen for connection updates
_room!.addListener(() {
final wasConnected = state.isConnected;
final isNowConnected =
_room!.connectionState == lk.ConnectionState.connected;
state = state.copyWith(
isConnected: _room!.connectionState == ConnectionState.connected,
isConnected: isNowConnected,
isMicrophoneEnabled: _localParticipant!.isMicrophoneEnabled(),
isCameraEnabled: _localParticipant!.isCameraEnabled(),
isScreenSharing: _localParticipant!.isScreenShareEnabled(),
);
// Enable wakelock when call connects
if (!wasConnected && isNowConnected) {
WakelockPlus.enable();
}
// Disable wakelock when call disconnects
else if (wasConnected && !isNowConnected) {
WakelockPlus.disable();
}
});
state = state.copyWith(isConnected: true);
// Enable wakelock when call connects
WakelockPlus.enable();
} else {
state = state.copyWith(error: 'Failed to join room');
}
@@ -320,18 +336,43 @@ class CallNotifier extends _$CallNotifier {
}
}
Future<void> toggleScreenShare() async {
Future<void> toggleScreenShare(BuildContext context) async {
if (_localParticipant != null) {
final target = !_localParticipant!.isScreenShareEnabled();
state = state.copyWith(isScreenSharing: target);
await _localParticipant!.setScreenShareEnabled(target);
if (target && lk.lkPlatformIsDesktop()) {
try {
final source = await showDialog<DesktopCapturerSource>(
context: context,
builder: (context) => lk.ScreenSelectDialog(),
);
if (source == null) {
return;
}
var track = await lk.LocalVideoTrack.createScreenShareTrack(
lk.ScreenShareCaptureOptions(
sourceId: source.id,
maxFrameRate: 30.0,
captureScreenAudio: true,
),
);
await _localParticipant!.publishVideoTrack(track);
} catch (err) {
showErrorAlert(err);
}
return;
} else {
await _localParticipant!.setScreenShareEnabled(target);
}
state = state.copyWith();
}
}
Future<void> toggleSpeakerphone() async {
state = state.copyWith(isSpeakerphone: !state.isSpeakerphone);
await Hardware.instance.setSpeakerphoneOn(state.isSpeakerphone);
await lk.Hardware.instance.setSpeakerphoneOn(state.isSpeakerphone);
state = state.copyWith();
}
@@ -344,6 +385,8 @@ class CallNotifier extends _$CallNotifier {
isCameraEnabled: false,
isScreenSharing: false,
);
// Disable wakelock when call disconnects
WakelockPlus.disable();
}
}
@@ -381,5 +424,7 @@ class CallNotifier extends _$CallNotifier {
_durationTimer?.cancel();
_roomId = null;
participantsVolumes = {};
// Disable wakelock when disposing
WakelockPlus.disable();
}
}

View File

@@ -295,7 +295,7 @@ as String?,
/// @nodoc
mixin _$CallParticipantLive implements DiagnosticableTreeMixin {
CallParticipant get participant; Participant get remoteParticipant;
CallParticipant get participant; lk.Participant get remoteParticipant;
/// Create a copy of CallParticipantLive
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -332,7 +332,7 @@ abstract mixin class $CallParticipantLiveCopyWith<$Res> {
factory $CallParticipantLiveCopyWith(CallParticipantLive value, $Res Function(CallParticipantLive) _then) = _$CallParticipantLiveCopyWithImpl;
@useResult
$Res call({
CallParticipant participant, Participant remoteParticipant
CallParticipant participant, lk.Participant remoteParticipant
});
@@ -353,7 +353,7 @@ class _$CallParticipantLiveCopyWithImpl<$Res>
return _then(_self.copyWith(
participant: null == participant ? _self.participant : participant // ignore: cast_nullable_to_non_nullable
as CallParticipant,remoteParticipant: null == remoteParticipant ? _self.remoteParticipant : remoteParticipant // ignore: cast_nullable_to_non_nullable
as Participant,
as lk.Participant,
));
}
/// Create a copy of CallParticipantLive
@@ -444,7 +444,7 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( CallParticipant participant, Participant remoteParticipant)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( CallParticipant participant, lk.Participant remoteParticipant)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _CallParticipantLive() when $default != null:
return $default(_that.participant,_that.remoteParticipant);case _:
@@ -465,7 +465,7 @@ return $default(_that.participant,_that.remoteParticipant);case _:
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( CallParticipant participant, Participant remoteParticipant) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( CallParticipant participant, lk.Participant remoteParticipant) $default,) {final _that = this;
switch (_that) {
case _CallParticipantLive():
return $default(_that.participant,_that.remoteParticipant);}
@@ -482,7 +482,7 @@ return $default(_that.participant,_that.remoteParticipant);}
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( CallParticipant participant, Participant remoteParticipant)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( CallParticipant participant, lk.Participant remoteParticipant)? $default,) {final _that = this;
switch (_that) {
case _CallParticipantLive() when $default != null:
return $default(_that.participant,_that.remoteParticipant);case _:
@@ -501,7 +501,7 @@ class _CallParticipantLive extends CallParticipantLive with DiagnosticableTreeMi
@override final CallParticipant participant;
@override final Participant remoteParticipant;
@override final lk.Participant remoteParticipant;
/// Create a copy of CallParticipantLive
/// with the given fields replaced by the non-null parameter values.
@@ -539,7 +539,7 @@ abstract mixin class _$CallParticipantLiveCopyWith<$Res> implements $CallPartici
factory _$CallParticipantLiveCopyWith(_CallParticipantLive value, $Res Function(_CallParticipantLive) _then) = __$CallParticipantLiveCopyWithImpl;
@override @useResult
$Res call({
CallParticipant participant, Participant remoteParticipant
CallParticipant participant, lk.Participant remoteParticipant
});
@@ -560,7 +560,7 @@ class __$CallParticipantLiveCopyWithImpl<$Res>
return _then(_CallParticipantLive(
participant: null == participant ? _self.participant : participant // ignore: cast_nullable_to_non_nullable
as CallParticipant,remoteParticipant: null == remoteParticipant ? _self.remoteParticipant : remoteParticipant // ignore: cast_nullable_to_non_nullable
as Participant,
as lk.Participant,
));
}

24
lib/pods/chat/call.g.dart Normal file
View File

@@ -0,0 +1,24 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'call.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
String _$callNotifierHash() => r'a8ca3f625c0db3ad9992033ae70864ce15efc281';
/// See also [CallNotifier].
@ProviderFor(CallNotifier)
final callNotifierProvider = NotifierProvider<CallNotifier, CallState>.internal(
CallNotifier.new,
name: r'callNotifierProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product') ? null : _$callNotifierHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$CallNotifier = Notifier<CallState>;
// 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

@@ -0,0 +1,50 @@
import 'dart:async';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:island/pods/network.dart';
import 'package:island/pods/websocket.dart';
import 'package:island/models/account.dart';
part 'chat_online_count.g.dart';
@riverpod
class ChatOnlineCountNotifier extends _$ChatOnlineCountNotifier {
@override
Future<int> build(String chatroomId) async {
final apiClient = ref.watch(apiClientProvider);
final ws = ref.watch(websocketProvider);
// Fetch initial online count
final response = await apiClient.get(
'/sphere/chat/$chatroomId/members/online',
);
final initialCount = response.data as int;
// Listen for websocket status updates
final subscription = ws.dataStream.listen((WebSocketPacket packet) {
if (packet.type == 'accounts.status.update') {
final data = packet.data;
if (data != null && data['chat_room_id'] == chatroomId) {
final status = SnAccountStatus.fromJson(data['status']);
var delta = status.isOnline ? 1 : -1;
if (status.clearedAt != null &&
status.clearedAt!.isBefore(DateTime.now())) {
if (status.isInvisible) delta = 1;
}
// Update count based on online status
state.whenData((currentCount) {
final newCount = currentCount + delta;
state = AsyncData(
newCount.clamp(0, double.infinity).toInt(),
); // Ensure non-negative
});
}
}
});
ref.onDispose(() {
subscription.cancel();
});
return initialCount;
}
}

View File

@@ -0,0 +1,168 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'chat_online_count.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
String _$chatOnlineCountNotifierHash() =>
r'19af8fd0e9f62c65e12a68215406776085235fa3';
/// 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));
}
}
abstract class _$ChatOnlineCountNotifier
extends BuildlessAutoDisposeAsyncNotifier<int> {
late final String chatroomId;
FutureOr<int> build(String chatroomId);
}
/// See also [ChatOnlineCountNotifier].
@ProviderFor(ChatOnlineCountNotifier)
const chatOnlineCountNotifierProvider = ChatOnlineCountNotifierFamily();
/// See also [ChatOnlineCountNotifier].
class ChatOnlineCountNotifierFamily extends Family<AsyncValue<int>> {
/// See also [ChatOnlineCountNotifier].
const ChatOnlineCountNotifierFamily();
/// See also [ChatOnlineCountNotifier].
ChatOnlineCountNotifierProvider call(String chatroomId) {
return ChatOnlineCountNotifierProvider(chatroomId);
}
@override
ChatOnlineCountNotifierProvider getProviderOverride(
covariant ChatOnlineCountNotifierProvider provider,
) {
return call(provider.chatroomId);
}
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'chatOnlineCountNotifierProvider';
}
/// See also [ChatOnlineCountNotifier].
class ChatOnlineCountNotifierProvider
extends AutoDisposeAsyncNotifierProviderImpl<ChatOnlineCountNotifier, int> {
/// See also [ChatOnlineCountNotifier].
ChatOnlineCountNotifierProvider(String chatroomId)
: this._internal(
() => ChatOnlineCountNotifier()..chatroomId = chatroomId,
from: chatOnlineCountNotifierProvider,
name: r'chatOnlineCountNotifierProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product')
? null
: _$chatOnlineCountNotifierHash,
dependencies: ChatOnlineCountNotifierFamily._dependencies,
allTransitiveDependencies:
ChatOnlineCountNotifierFamily._allTransitiveDependencies,
chatroomId: chatroomId,
);
ChatOnlineCountNotifierProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.chatroomId,
}) : super.internal();
final String chatroomId;
@override
FutureOr<int> runNotifierBuild(covariant ChatOnlineCountNotifier notifier) {
return notifier.build(chatroomId);
}
@override
Override overrideWith(ChatOnlineCountNotifier Function() create) {
return ProviderOverride(
origin: this,
override: ChatOnlineCountNotifierProvider._internal(
() => create()..chatroomId = chatroomId,
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
chatroomId: chatroomId,
),
);
}
@override
AutoDisposeAsyncNotifierProviderElement<ChatOnlineCountNotifier, int>
createElement() {
return _ChatOnlineCountNotifierProviderElement(this);
}
@override
bool operator ==(Object other) {
return other is ChatOnlineCountNotifierProvider &&
other.chatroomId == chatroomId;
}
@override
int get hashCode {
var hash = _SystemHash.combine(0, runtimeType.hashCode);
hash = _SystemHash.combine(hash, chatroomId.hashCode);
return _SystemHash.finish(hash);
}
}
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
mixin ChatOnlineCountNotifierRef on AutoDisposeAsyncNotifierProviderRef<int> {
/// The parameter `chatroomId` of this provider.
String get chatroomId;
}
class _ChatOnlineCountNotifierProviderElement
extends
AutoDisposeAsyncNotifierProviderElement<ChatOnlineCountNotifier, int>
with ChatOnlineCountNotifierRef {
_ChatOnlineCountNotifierProviderElement(super.provider);
@override
String get chatroomId =>
(origin as ChatOnlineCountNotifierProvider).chatroomId;
}
// 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

@@ -0,0 +1,5 @@
import "package:hooks_riverpod/hooks_riverpod.dart";
final isSyncingProvider = StateProvider.autoDispose<bool>((ref) => false);
final flashingMessagesProvider = StateProvider<Set<String>>((ref) => {});

View File

@@ -0,0 +1,229 @@
import "dart:async";
import "dart:convert";
import "package:flutter/material.dart";
import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:island/models/chat.dart";
import "package:island/pods/lifecycle.dart";
import "package:island/pods/chat/messages_notifier.dart";
import "package:island/pods/websocket.dart";
import "package:island/screens/chat/chat.dart";
import "package:island/widgets/chat/call_button.dart";
import "package:riverpod_annotation/riverpod_annotation.dart";
part 'chat_subscribe.g.dart';
final currentSubscribedChatIdProvider = StateProvider<String?>((ref) => null);
@riverpod
class ChatSubscribeNotifier extends _$ChatSubscribeNotifier {
late final String _roomId;
late final SnChatRoom _chatRoom;
late final SnChatMember _chatIdentity;
late final MessagesNotifier _messagesNotifier;
final List<SnChatMember> _typingStatuses = [];
Timer? _typingCleanupTimer;
Timer? _typingCooldownTimer;
Timer? _periodicSubscribeTimer;
StreamSubscription? _wsSubscription;
@override
List<SnChatMember> build(String roomId) {
_roomId = roomId;
final ws = ref.watch(websocketProvider);
final chatRoomAsync = ref.watch(chatroomProvider(roomId));
final chatIdentityAsync = ref.watch(chatroomIdentityProvider(roomId));
_messagesNotifier = ref.watch(messagesNotifierProvider(roomId).notifier);
if (chatRoomAsync.isLoading || chatIdentityAsync.isLoading) {
return [];
}
if (chatRoomAsync.value == null || chatIdentityAsync.value == null) {
return [];
}
_chatRoom = chatRoomAsync.value!;
_chatIdentity = chatIdentityAsync.value!;
// Subscribe to messages
final wsState = ref.read(websocketStateProvider.notifier);
wsState.sendMessage(
jsonEncode(
WebSocketPacket(
type: 'messages.subscribe',
data: {'chat_room_id': roomId},
endpoint: 'sphere',
),
),
);
Future.microtask(
() => ref.read(currentSubscribedChatIdProvider.notifier).state = roomId,
);
// Send initial read receipt
sendReadReceipt();
// Set up WebSocket listener
_wsSubscription = ws.dataStream.listen(onMessage);
// Set up typing status cleanup timer
_typingCleanupTimer = Timer.periodic(const Duration(seconds: 5), (_) {
if (_typingStatuses.isNotEmpty) {
// Remove typing statuses older than 5 seconds
final now = DateTime.now();
_typingStatuses.removeWhere((member) {
final lastTyped =
member.lastTyped ??
DateTime.now().subtract(const Duration(milliseconds: 1350));
return now.difference(lastTyped).inSeconds > 5;
});
state = List.of(_typingStatuses);
}
});
// Set up periodic subscribe timer (every 5 minutes)
_periodicSubscribeTimer = Timer.periodic(const Duration(minutes: 5), (_) {
final wsState = ref.read(websocketStateProvider.notifier);
wsState.sendMessage(
jsonEncode(
WebSocketPacket(
type: 'messages.subscribe',
data: {'chat_room_id': roomId},
endpoint: 'sphere',
),
),
);
});
// Listen to app lifecycle changes
ref.listen(appLifecycleStateProvider, (previous, next) {
final lifecycleState = next.value;
if (lifecycleState == AppLifecycleState.paused ||
lifecycleState == AppLifecycleState.inactive) {
// Unsubscribe when app goes to background
final wsState = ref.read(websocketStateProvider.notifier);
wsState.sendMessage(
jsonEncode(
WebSocketPacket(
type: 'messages.unsubscribe',
data: {'chat_room_id': roomId},
endpoint: 'sphere',
),
),
);
} else if (lifecycleState == AppLifecycleState.resumed) {
// Resubscribe when app comes back to foreground
final wsState = ref.read(websocketStateProvider.notifier);
wsState.sendMessage(
jsonEncode(
WebSocketPacket(
type: 'messages.subscribe',
data: {'chat_room_id': roomId},
endpoint: 'sphere',
),
),
);
}
});
// Cleanup on dispose
ref.onDispose(() {
ref.read(currentSubscribedChatIdProvider.notifier).state = null;
wsState.sendMessage(
jsonEncode(
WebSocketPacket(
type: 'messages.unsubscribe',
data: {'chat_room_id': roomId},
endpoint: 'sphere',
),
),
);
_wsSubscription?.cancel();
_typingCleanupTimer?.cancel();
_typingCooldownTimer?.cancel();
_periodicSubscribeTimer?.cancel();
});
return _typingStatuses;
}
void onMessage(WebSocketPacket pkt) {
if (!pkt.type.startsWith('messages')) return;
if (['messages.read'].contains(pkt.type)) return;
if (pkt.type == 'messages.typing' && pkt.data?['sender'] != null) {
if (pkt.data?['room_id'] != _chatRoom.id) return;
if (pkt.data?['sender_id'] == _chatIdentity.id) return;
final sender = SnChatMember.fromJson(
pkt.data?['sender'],
).copyWith(lastTyped: DateTime.now());
// Check if the sender is already in the typing list
final existingIndex = _typingStatuses.indexWhere(
(member) => member.id == sender.id,
);
if (existingIndex >= 0) {
// Update the existing entry with new timestamp
_typingStatuses[existingIndex] = sender;
} else {
// Add new typing status
_typingStatuses.add(sender);
}
state = List.of(_typingStatuses);
return;
}
final message = SnChatMessage.fromJson(pkt.data!);
if (message.chatRoomId != _chatRoom.id) return;
switch (pkt.type) {
case 'messages.new':
case 'messages.update':
case 'messages.delete':
if (message.type.startsWith('call')) {
// Handle the ongoing call.
ref.invalidate(ongoingCallProvider(message.chatRoomId));
}
_messagesNotifier.receiveMessage(message);
// Send read receipt for new message
sendReadReceipt();
}
}
void sendReadReceipt() {
// Send websocket packet
final wsState = ref.read(websocketStateProvider.notifier);
wsState.sendMessage(
jsonEncode(
WebSocketPacket(
type: 'messages.read',
data: {'chat_room_id': _roomId},
endpoint: 'sphere',
),
),
);
}
void sendTypingStatus() {
// Don't send if we're already in a cooldown period
if (_typingCooldownTimer != null) return;
// Send typing status immediately
final wsState = ref.read(websocketStateProvider.notifier);
wsState.sendMessage(
jsonEncode(
WebSocketPacket(
type: 'messages.typing',
data: {'chat_room_id': _roomId},
endpoint: 'sphere',
),
),
);
_typingCooldownTimer = Timer(const Duration(milliseconds: 850), () {
_typingCooldownTimer = null;
});
}
}

View File

@@ -0,0 +1,176 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'chat_subscribe.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
String _$chatSubscribeNotifierHash() =>
r'c605e0c9c45df64e5ba7b65f8de9b47bde8e2b3b';
/// 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));
}
}
abstract class _$ChatSubscribeNotifier
extends BuildlessAutoDisposeNotifier<List<SnChatMember>> {
late final String roomId;
List<SnChatMember> build(String roomId);
}
/// See also [ChatSubscribeNotifier].
@ProviderFor(ChatSubscribeNotifier)
const chatSubscribeNotifierProvider = ChatSubscribeNotifierFamily();
/// See also [ChatSubscribeNotifier].
class ChatSubscribeNotifierFamily extends Family<List<SnChatMember>> {
/// See also [ChatSubscribeNotifier].
const ChatSubscribeNotifierFamily();
/// See also [ChatSubscribeNotifier].
ChatSubscribeNotifierProvider call(String roomId) {
return ChatSubscribeNotifierProvider(roomId);
}
@override
ChatSubscribeNotifierProvider getProviderOverride(
covariant ChatSubscribeNotifierProvider provider,
) {
return call(provider.roomId);
}
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'chatSubscribeNotifierProvider';
}
/// See also [ChatSubscribeNotifier].
class ChatSubscribeNotifierProvider
extends
AutoDisposeNotifierProviderImpl<
ChatSubscribeNotifier,
List<SnChatMember>
> {
/// See also [ChatSubscribeNotifier].
ChatSubscribeNotifierProvider(String roomId)
: this._internal(
() => ChatSubscribeNotifier()..roomId = roomId,
from: chatSubscribeNotifierProvider,
name: r'chatSubscribeNotifierProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product')
? null
: _$chatSubscribeNotifierHash,
dependencies: ChatSubscribeNotifierFamily._dependencies,
allTransitiveDependencies:
ChatSubscribeNotifierFamily._allTransitiveDependencies,
roomId: roomId,
);
ChatSubscribeNotifierProvider._internal(
super._createNotifier, {
required super.name,
required super.dependencies,
required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash,
required super.from,
required this.roomId,
}) : super.internal();
final String roomId;
@override
List<SnChatMember> runNotifierBuild(
covariant ChatSubscribeNotifier notifier,
) {
return notifier.build(roomId);
}
@override
Override overrideWith(ChatSubscribeNotifier Function() create) {
return ProviderOverride(
origin: this,
override: ChatSubscribeNotifierProvider._internal(
() => create()..roomId = roomId,
from: from,
name: null,
dependencies: null,
allTransitiveDependencies: null,
debugGetCreateSourceHash: null,
roomId: roomId,
),
);
}
@override
AutoDisposeNotifierProviderElement<ChatSubscribeNotifier, List<SnChatMember>>
createElement() {
return _ChatSubscribeNotifierProviderElement(this);
}
@override
bool operator ==(Object other) {
return other is ChatSubscribeNotifierProvider && other.roomId == roomId;
}
@override
int get hashCode {
var hash = _SystemHash.combine(0, runtimeType.hashCode);
hash = _SystemHash.combine(hash, roomId.hashCode);
return _SystemHash.finish(hash);
}
}
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
mixin ChatSubscribeNotifierRef
on AutoDisposeNotifierProviderRef<List<SnChatMember>> {
/// The parameter `roomId` of this provider.
String get roomId;
}
class _ChatSubscribeNotifierProviderElement
extends
AutoDisposeNotifierProviderElement<
ChatSubscribeNotifier,
List<SnChatMember>
>
with ChatSubscribeNotifierRef {
_ChatSubscribeNotifierProviderElement(super.provider);
@override
String get roomId => (origin as ChatSubscribeNotifierProvider).roomId;
}
// 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,6 +1,8 @@
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:island/models/chat.dart';
import 'package:island/pods/network.dart';
import 'package:island/pods/websocket.dart';
import 'package:island/pods/chat/chat_subscribe.dart';
part 'chat_summary.g.dart';
@@ -12,9 +14,27 @@ class ChatSummary extends _$ChatSummary {
final resp = await client.get('/sphere/chat/summary');
final Map<String, dynamic> data = resp.data;
return data.map(
final summaries = data.map(
(key, value) => MapEntry(key, SnChatSummary.fromJson(value)),
);
final ws = ref.watch(websocketProvider);
final subscription = ws.dataStream.listen((WebSocketPacket pkt) {
if (!pkt.type.startsWith('messages')) return;
if (pkt.type == 'messages.new') {
final message = SnChatMessage.fromJson(pkt.data!);
updateLastMessage(message.chatRoomId, message);
} else if (pkt.type == 'messages.update') {
final message = SnChatMessage.fromJson(pkt.data!);
updateMessageContent(message.chatRoomId, message);
}
});
ref.onDispose(() {
subscription.cancel();
});
return summaries;
}
Future<void> clearUnreadCount(String chatId) async {
@@ -36,10 +56,12 @@ class ChatSummary extends _$ChatSummary {
state.whenData((summaries) {
final summary = summaries[chatId];
if (summary != null) {
final currentSubscribed = ref.read(currentSubscribedChatIdProvider);
final increment = (chatId != currentSubscribed) ? 1 : 0;
state = AsyncData({
...summaries,
chatId: SnChatSummary(
unreadCount: summary.unreadCount + 1,
unreadCount: summary.unreadCount + increment,
lastMessage: message,
),
});
@@ -61,4 +83,19 @@ class ChatSummary extends _$ChatSummary {
}
});
}
void updateMessageContent(String chatId, SnChatMessage message) {
state.whenData((summaries) {
final summary = summaries[chatId];
if (summary != null && summary.lastMessage?.id == message.id) {
state = AsyncData({
...summaries,
chatId: SnChatSummary(
unreadCount: summary.unreadCount,
lastMessage: message,
),
});
}
});
}
}

View File

@@ -6,7 +6,7 @@ part of 'chat_summary.dart';
// RiverpodGenerator
// **************************************************************************
String _$chatSummaryHash() => r'87a10e4cefa37dc5fa8eadb175ef1b2bed6070bf';
String _$chatSummaryHash() => r'33815a3bd81d20902b7063e8194fe336930df9b4';
/// See also [ChatSummary].
@ProviderFor(ChatSummary)

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,12 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'room.dart';
part of 'messages_notifier.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
String _$messagesNotifierHash() => r'32afe6ea24086d869cc47bd3389c8fd734409ca0';
String _$messagesNotifierHash() => r'6adefd9152cdd686c2a863964993f24c42d405b5';
/// Copied from Dart SDK
class _SystemHash {

View File

@@ -1,9 +1,11 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:island/pods/theme.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:window_manager/window_manager.dart';
part 'config.freezed.dart';
part 'config.g.dart';
@@ -15,14 +17,24 @@ const kNetworkServerStoreKey = 'app_server_url';
const kAppbarTransparentStoreKey = 'app_bar_transparent';
const kAppBackgroundStoreKey = 'app_has_background';
const kAppShowBackgroundImage = 'app_show_background_image';
const kAppColorSchemeStoreKey = 'app_color_scheme';
const kAppCustomColorsStoreKey = 'app_custom_colors';
const kAppNotifyWithHaptic = 'app_notify_with_haptic';
const kAppCustomFonts = 'app_custom_fonts';
const kAppAutoTranslate = 'app_auto_translate';
const kAppDataSavingMode = 'app_data_saving_mode';
const kAppSoundEffects = 'app_sound_effects';
const kAppAprilFoolFeatures = 'app_april_fool_features';
const kAppWindowSize = 'app_window_size';
const kAppWindowOpacity = 'app_window_opacity';
const kAppCardTransparent = 'app_card_transparent';
const kAppEnterToSend = 'app_enter_to_send';
const kAppDefaultPoolId = 'app_default_pool_id';
const kAppMessageDisplayStyle = 'app_message_display_style';
const kAppThemeMode = 'app_theme_mode';
const kMaterialYouToggleStoreKey = 'app_theme_material_you';
const kAppDisableAnimation = 'app_disable_animation';
const kFeaturedPostsCollapsedId =
'featured_posts_collapsed_id'; // Key for storing the ID of the collapsed featured post
@@ -50,17 +62,42 @@ final serverUrlProvider = Provider<String>((ref) {
return prefs.getString(kNetworkServerStoreKey) ?? kNetworkServerDefault;
});
@freezed
sealed class ThemeColors with _$ThemeColors {
factory ThemeColors({
int? primary,
int? secondary,
int? tertiary,
int? surface,
int? background,
int? error,
}) = _ThemeColors;
factory ThemeColors.fromJson(Map<String, dynamic> json) =>
_$ThemeColorsFromJson(json);
}
@freezed
sealed class AppSettings with _$AppSettings {
const factory AppSettings({
required bool autoTranslate,
required bool dataSavingMode,
required bool soundEffects,
required bool aprilFoolFeatures,
required bool enterToSend,
required bool appBarTransparent,
required bool showBackgroundImage,
required String? customFonts,
required int? appColorScheme, // The color stored via the int type
required ThemeColors? customColors,
required Size? windowSize, // The window size for desktop platforms
required double windowOpacity, // The window opacity for desktop platforms
required double cardTransparency, // The card background opacity
required String? defaultPoolId,
required String messageDisplayStyle,
required String? themeMode,
required bool useMaterial3,
required bool disableAnimation,
}) = _AppSettings;
}
@@ -71,13 +108,23 @@ class AppSettingsNotifier extends _$AppSettingsNotifier {
final prefs = ref.watch(sharedPreferencesProvider);
return AppSettings(
autoTranslate: prefs.getBool(kAppAutoTranslate) ?? false,
dataSavingMode: prefs.getBool(kAppDataSavingMode) ?? false,
soundEffects: prefs.getBool(kAppSoundEffects) ?? true,
aprilFoolFeatures: prefs.getBool(kAppAprilFoolFeatures) ?? true,
enterToSend: prefs.getBool(kAppEnterToSend) ?? true,
appBarTransparent: prefs.getBool(kAppbarTransparentStoreKey) ?? false,
showBackgroundImage: prefs.getBool(kAppShowBackgroundImage) ?? true,
customFonts: prefs.getString(kAppCustomFonts),
appColorScheme: prefs.getInt(kAppColorSchemeStoreKey),
customColors: _getThemeColorsFromPrefs(prefs),
windowSize: _getWindowSizeFromPrefs(prefs),
windowOpacity: prefs.getDouble(kAppWindowOpacity) ?? 1.0,
cardTransparency: prefs.getDouble(kAppCardTransparent) ?? 1.0,
defaultPoolId: prefs.getString(kAppDefaultPoolId),
messageDisplayStyle: prefs.getString(kAppMessageDisplayStyle) ?? 'bubble',
themeMode: prefs.getString(kAppThemeMode) ?? 'system',
useMaterial3: prefs.getBool(kMaterialYouToggleStoreKey) ?? true,
disableAnimation: prefs.getBool(kAppDisableAnimation) ?? false,
);
}
@@ -98,12 +145,40 @@ class AppSettingsNotifier extends _$AppSettingsNotifier {
return null;
}
ThemeColors? _getThemeColorsFromPrefs(SharedPreferences prefs) {
final jsonString = prefs.getString(kAppCustomColorsStoreKey);
if (jsonString == null) return null;
try {
final json = jsonDecode(jsonString);
return ThemeColors.fromJson(json);
} catch (e) {
return null;
}
}
void setDefaultPoolId(String? value) {
final prefs = ref.read(sharedPreferencesProvider);
if (value != null) {
prefs.setString(kAppDefaultPoolId, value);
} else {
prefs.remove(kAppDefaultPoolId);
}
state = state.copyWith(defaultPoolId: value);
}
void setAutoTranslate(bool value) {
final prefs = ref.read(sharedPreferencesProvider);
prefs.setBool(kAppAutoTranslate, value);
state = state.copyWith(autoTranslate: value);
}
void setDataSavingMode(bool value) {
final prefs = ref.read(sharedPreferencesProvider);
prefs.setBool(kAppDataSavingMode, value);
state = state.copyWith(dataSavingMode: value);
}
void setSoundEffects(bool value) {
final prefs = ref.read(sharedPreferencesProvider);
prefs.setBool(kAppSoundEffects, value);
@@ -126,21 +201,24 @@ class AppSettingsNotifier extends _$AppSettingsNotifier {
final prefs = ref.read(sharedPreferencesProvider);
prefs.setBool(kAppbarTransparentStoreKey, value);
state = state.copyWith(appBarTransparent: value);
ref.read(themeProvider.notifier).reloadTheme();
}
void setShowBackgroundImage(bool value) {
final prefs = ref.read(sharedPreferencesProvider);
prefs.setBool(kAppShowBackgroundImage, value);
state = state.copyWith(showBackgroundImage: value);
}
void setCustomFonts(String? value) {
final prefs = ref.read(sharedPreferencesProvider);
prefs.setString(kAppCustomFonts, value ?? '');
state = state.copyWith(customFonts: value);
ref.read(themeProvider.notifier).reloadTheme();
}
void setAppColorScheme(int? value) {
final prefs = ref.read(sharedPreferencesProvider);
prefs.setInt(kAppColorSchemeStoreKey, value ?? 0);
state = state.copyWith(appColorScheme: value);
ref.read(themeProvider.notifier).reloadTheme();
}
void setWindowSize(Size? size) {
@@ -156,6 +234,54 @@ class AppSettingsNotifier extends _$AppSettingsNotifier {
Size? getWindowSize() {
return state.windowSize;
}
void setMessageDisplayStyle(String value) {
final prefs = ref.read(sharedPreferencesProvider);
prefs.setString(kAppMessageDisplayStyle, value);
state = state.copyWith(messageDisplayStyle: value);
}
void setWindowOpacity(double value) {
final prefs = ref.read(sharedPreferencesProvider);
prefs.setDouble(kAppWindowOpacity, value);
state = state.copyWith(windowOpacity: value);
Future(() => windowManager.setOpacity(value));
}
void setThemeMode(String value) {
final prefs = ref.read(sharedPreferencesProvider);
prefs.setString(kAppThemeMode, value);
state = state.copyWith(themeMode: value);
}
void setAppTransparentBackground(double value) {
final prefs = ref.read(sharedPreferencesProvider);
prefs.setDouble(kAppCardTransparent, value);
state = state.copyWith(cardTransparency: value);
}
void setUseMaterial3(bool value) {
final prefs = ref.read(sharedPreferencesProvider);
prefs.setBool(kMaterialYouToggleStoreKey, value);
state = state.copyWith(useMaterial3: value);
}
void setCustomColors(ThemeColors? value) {
final prefs = ref.read(sharedPreferencesProvider);
if (value != null) {
final json = jsonEncode(value.toJson());
prefs.setString(kAppCustomColorsStoreKey, json);
} else {
prefs.remove(kAppCustomColorsStoreKey);
}
state = state.copyWith(customColors: value);
}
void setDisableAnimation(bool value) {
final prefs = ref.read(sharedPreferencesProvider);
prefs.setBool(kAppDisableAnimation, value);
state = state.copyWith(disableAnimation: value);
}
}
final updateInfoProvider =

View File

@@ -11,11 +11,286 @@ part of 'config.dart';
// dart format off
T _$identity<T>(T value) => value;
/// @nodoc
mixin _$ThemeColors {
int? get primary; int? get secondary; int? get tertiary; int? get surface; int? get background; int? get error;
/// Create a copy of ThemeColors
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$ThemeColorsCopyWith<ThemeColors> get copyWith => _$ThemeColorsCopyWithImpl<ThemeColors>(this as ThemeColors, _$identity);
/// Serializes this ThemeColors to a JSON map.
Map<String, dynamic> toJson();
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is ThemeColors&&(identical(other.primary, primary) || other.primary == primary)&&(identical(other.secondary, secondary) || other.secondary == secondary)&&(identical(other.tertiary, tertiary) || other.tertiary == tertiary)&&(identical(other.surface, surface) || other.surface == surface)&&(identical(other.background, background) || other.background == background)&&(identical(other.error, error) || other.error == error));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,primary,secondary,tertiary,surface,background,error);
@override
String toString() {
return 'ThemeColors(primary: $primary, secondary: $secondary, tertiary: $tertiary, surface: $surface, background: $background, error: $error)';
}
}
/// @nodoc
abstract mixin class $ThemeColorsCopyWith<$Res> {
factory $ThemeColorsCopyWith(ThemeColors value, $Res Function(ThemeColors) _then) = _$ThemeColorsCopyWithImpl;
@useResult
$Res call({
int? primary, int? secondary, int? tertiary, int? surface, int? background, int? error
});
}
/// @nodoc
class _$ThemeColorsCopyWithImpl<$Res>
implements $ThemeColorsCopyWith<$Res> {
_$ThemeColorsCopyWithImpl(this._self, this._then);
final ThemeColors _self;
final $Res Function(ThemeColors) _then;
/// Create a copy of ThemeColors
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? primary = freezed,Object? secondary = freezed,Object? tertiary = freezed,Object? surface = freezed,Object? background = freezed,Object? error = freezed,}) {
return _then(_self.copyWith(
primary: freezed == primary ? _self.primary : primary // ignore: cast_nullable_to_non_nullable
as int?,secondary: freezed == secondary ? _self.secondary : secondary // ignore: cast_nullable_to_non_nullable
as int?,tertiary: freezed == tertiary ? _self.tertiary : tertiary // ignore: cast_nullable_to_non_nullable
as int?,surface: freezed == surface ? _self.surface : surface // ignore: cast_nullable_to_non_nullable
as int?,background: freezed == background ? _self.background : background // ignore: cast_nullable_to_non_nullable
as int?,error: freezed == error ? _self.error : error // ignore: cast_nullable_to_non_nullable
as int?,
));
}
}
/// Adds pattern-matching-related methods to [ThemeColors].
extension ThemeColorsPatterns on ThemeColors {
/// 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( _ThemeColors value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _ThemeColors() 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( _ThemeColors value) $default,){
final _that = this;
switch (_that) {
case _ThemeColors():
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( _ThemeColors value)? $default,){
final _that = this;
switch (_that) {
case _ThemeColors() 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( int? primary, int? secondary, int? tertiary, int? surface, int? background, int? error)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _ThemeColors() when $default != null:
return $default(_that.primary,_that.secondary,_that.tertiary,_that.surface,_that.background,_that.error);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( int? primary, int? secondary, int? tertiary, int? surface, int? background, int? error) $default,) {final _that = this;
switch (_that) {
case _ThemeColors():
return $default(_that.primary,_that.secondary,_that.tertiary,_that.surface,_that.background,_that.error);}
}
/// 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( int? primary, int? secondary, int? tertiary, int? surface, int? background, int? error)? $default,) {final _that = this;
switch (_that) {
case _ThemeColors() when $default != null:
return $default(_that.primary,_that.secondary,_that.tertiary,_that.surface,_that.background,_that.error);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
class _ThemeColors implements ThemeColors {
_ThemeColors({this.primary, this.secondary, this.tertiary, this.surface, this.background, this.error});
factory _ThemeColors.fromJson(Map<String, dynamic> json) => _$ThemeColorsFromJson(json);
@override final int? primary;
@override final int? secondary;
@override final int? tertiary;
@override final int? surface;
@override final int? background;
@override final int? error;
/// Create a copy of ThemeColors
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$ThemeColorsCopyWith<_ThemeColors> get copyWith => __$ThemeColorsCopyWithImpl<_ThemeColors>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$ThemeColorsToJson(this, );
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _ThemeColors&&(identical(other.primary, primary) || other.primary == primary)&&(identical(other.secondary, secondary) || other.secondary == secondary)&&(identical(other.tertiary, tertiary) || other.tertiary == tertiary)&&(identical(other.surface, surface) || other.surface == surface)&&(identical(other.background, background) || other.background == background)&&(identical(other.error, error) || other.error == error));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,primary,secondary,tertiary,surface,background,error);
@override
String toString() {
return 'ThemeColors(primary: $primary, secondary: $secondary, tertiary: $tertiary, surface: $surface, background: $background, error: $error)';
}
}
/// @nodoc
abstract mixin class _$ThemeColorsCopyWith<$Res> implements $ThemeColorsCopyWith<$Res> {
factory _$ThemeColorsCopyWith(_ThemeColors value, $Res Function(_ThemeColors) _then) = __$ThemeColorsCopyWithImpl;
@override @useResult
$Res call({
int? primary, int? secondary, int? tertiary, int? surface, int? background, int? error
});
}
/// @nodoc
class __$ThemeColorsCopyWithImpl<$Res>
implements _$ThemeColorsCopyWith<$Res> {
__$ThemeColorsCopyWithImpl(this._self, this._then);
final _ThemeColors _self;
final $Res Function(_ThemeColors) _then;
/// Create a copy of ThemeColors
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? primary = freezed,Object? secondary = freezed,Object? tertiary = freezed,Object? surface = freezed,Object? background = freezed,Object? error = freezed,}) {
return _then(_ThemeColors(
primary: freezed == primary ? _self.primary : primary // ignore: cast_nullable_to_non_nullable
as int?,secondary: freezed == secondary ? _self.secondary : secondary // ignore: cast_nullable_to_non_nullable
as int?,tertiary: freezed == tertiary ? _self.tertiary : tertiary // ignore: cast_nullable_to_non_nullable
as int?,surface: freezed == surface ? _self.surface : surface // ignore: cast_nullable_to_non_nullable
as int?,background: freezed == background ? _self.background : background // ignore: cast_nullable_to_non_nullable
as int?,error: freezed == error ? _self.error : error // ignore: cast_nullable_to_non_nullable
as int?,
));
}
}
/// @nodoc
mixin _$AppSettings {
bool get autoTranslate; bool get soundEffects; bool get aprilFoolFeatures; bool get enterToSend; bool get appBarTransparent; String? get customFonts; int? get appColorScheme;// The color stored via the int type
Size? get windowSize;
bool get autoTranslate; bool get dataSavingMode; bool get soundEffects; bool get aprilFoolFeatures; bool get enterToSend; bool get appBarTransparent; bool get showBackgroundImage; String? get customFonts; int? get appColorScheme;// The color stored via the int type
ThemeColors? get customColors; Size? get windowSize;// The window size for desktop platforms
double get windowOpacity;// The window opacity for desktop platforms
double get cardTransparency;// The card background opacity
String? get defaultPoolId; String get messageDisplayStyle; String? get themeMode; bool get useMaterial3; bool get disableAnimation;
/// Create a copy of AppSettings
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -26,16 +301,16 @@ $AppSettingsCopyWith<AppSettings> get copyWith => _$AppSettingsCopyWithImpl<AppS
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is AppSettings&&(identical(other.autoTranslate, autoTranslate) || other.autoTranslate == autoTranslate)&&(identical(other.soundEffects, soundEffects) || other.soundEffects == soundEffects)&&(identical(other.aprilFoolFeatures, aprilFoolFeatures) || other.aprilFoolFeatures == aprilFoolFeatures)&&(identical(other.enterToSend, enterToSend) || other.enterToSend == enterToSend)&&(identical(other.appBarTransparent, appBarTransparent) || other.appBarTransparent == appBarTransparent)&&(identical(other.customFonts, customFonts) || other.customFonts == customFonts)&&(identical(other.appColorScheme, appColorScheme) || other.appColorScheme == appColorScheme)&&(identical(other.windowSize, windowSize) || other.windowSize == windowSize));
return identical(this, other) || (other.runtimeType == runtimeType&&other is AppSettings&&(identical(other.autoTranslate, autoTranslate) || other.autoTranslate == autoTranslate)&&(identical(other.dataSavingMode, dataSavingMode) || other.dataSavingMode == dataSavingMode)&&(identical(other.soundEffects, soundEffects) || other.soundEffects == soundEffects)&&(identical(other.aprilFoolFeatures, aprilFoolFeatures) || other.aprilFoolFeatures == aprilFoolFeatures)&&(identical(other.enterToSend, enterToSend) || other.enterToSend == enterToSend)&&(identical(other.appBarTransparent, appBarTransparent) || other.appBarTransparent == appBarTransparent)&&(identical(other.showBackgroundImage, showBackgroundImage) || other.showBackgroundImage == showBackgroundImage)&&(identical(other.customFonts, customFonts) || other.customFonts == customFonts)&&(identical(other.appColorScheme, appColorScheme) || other.appColorScheme == appColorScheme)&&(identical(other.customColors, customColors) || other.customColors == customColors)&&(identical(other.windowSize, windowSize) || other.windowSize == windowSize)&&(identical(other.windowOpacity, windowOpacity) || other.windowOpacity == windowOpacity)&&(identical(other.cardTransparency, cardTransparency) || other.cardTransparency == cardTransparency)&&(identical(other.defaultPoolId, defaultPoolId) || other.defaultPoolId == defaultPoolId)&&(identical(other.messageDisplayStyle, messageDisplayStyle) || other.messageDisplayStyle == messageDisplayStyle)&&(identical(other.themeMode, themeMode) || other.themeMode == themeMode)&&(identical(other.useMaterial3, useMaterial3) || other.useMaterial3 == useMaterial3)&&(identical(other.disableAnimation, disableAnimation) || other.disableAnimation == disableAnimation));
}
@override
int get hashCode => Object.hash(runtimeType,autoTranslate,soundEffects,aprilFoolFeatures,enterToSend,appBarTransparent,customFonts,appColorScheme,windowSize);
int get hashCode => Object.hash(runtimeType,autoTranslate,dataSavingMode,soundEffects,aprilFoolFeatures,enterToSend,appBarTransparent,showBackgroundImage,customFonts,appColorScheme,customColors,windowSize,windowOpacity,cardTransparency,defaultPoolId,messageDisplayStyle,themeMode,useMaterial3,disableAnimation);
@override
String toString() {
return 'AppSettings(autoTranslate: $autoTranslate, soundEffects: $soundEffects, aprilFoolFeatures: $aprilFoolFeatures, enterToSend: $enterToSend, appBarTransparent: $appBarTransparent, customFonts: $customFonts, appColorScheme: $appColorScheme, windowSize: $windowSize)';
return 'AppSettings(autoTranslate: $autoTranslate, dataSavingMode: $dataSavingMode, soundEffects: $soundEffects, aprilFoolFeatures: $aprilFoolFeatures, enterToSend: $enterToSend, appBarTransparent: $appBarTransparent, showBackgroundImage: $showBackgroundImage, customFonts: $customFonts, appColorScheme: $appColorScheme, customColors: $customColors, windowSize: $windowSize, windowOpacity: $windowOpacity, cardTransparency: $cardTransparency, defaultPoolId: $defaultPoolId, messageDisplayStyle: $messageDisplayStyle, themeMode: $themeMode, useMaterial3: $useMaterial3, disableAnimation: $disableAnimation)';
}
@@ -46,11 +321,11 @@ abstract mixin class $AppSettingsCopyWith<$Res> {
factory $AppSettingsCopyWith(AppSettings value, $Res Function(AppSettings) _then) = _$AppSettingsCopyWithImpl;
@useResult
$Res call({
bool autoTranslate, bool soundEffects, bool aprilFoolFeatures, bool enterToSend, bool appBarTransparent, String? customFonts, int? appColorScheme, Size? windowSize
bool autoTranslate, bool dataSavingMode, bool soundEffects, bool aprilFoolFeatures, bool enterToSend, bool appBarTransparent, bool showBackgroundImage, String? customFonts, int? appColorScheme, ThemeColors? customColors, Size? windowSize, double windowOpacity, double cardTransparency, String? defaultPoolId, String messageDisplayStyle, String? themeMode, bool useMaterial3, bool disableAnimation
});
$ThemeColorsCopyWith<$Res>? get customColors;
}
/// @nodoc
@@ -63,20 +338,42 @@ class _$AppSettingsCopyWithImpl<$Res>
/// Create a copy of AppSettings
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? autoTranslate = null,Object? soundEffects = null,Object? aprilFoolFeatures = null,Object? enterToSend = null,Object? appBarTransparent = null,Object? customFonts = freezed,Object? appColorScheme = freezed,Object? windowSize = freezed,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? autoTranslate = null,Object? dataSavingMode = null,Object? soundEffects = null,Object? aprilFoolFeatures = null,Object? enterToSend = null,Object? appBarTransparent = null,Object? showBackgroundImage = null,Object? customFonts = freezed,Object? appColorScheme = freezed,Object? customColors = freezed,Object? windowSize = freezed,Object? windowOpacity = null,Object? cardTransparency = null,Object? defaultPoolId = freezed,Object? messageDisplayStyle = null,Object? themeMode = freezed,Object? useMaterial3 = null,Object? disableAnimation = null,}) {
return _then(_self.copyWith(
autoTranslate: null == autoTranslate ? _self.autoTranslate : autoTranslate // ignore: cast_nullable_to_non_nullable
as bool,dataSavingMode: null == dataSavingMode ? _self.dataSavingMode : dataSavingMode // ignore: cast_nullable_to_non_nullable
as bool,soundEffects: null == soundEffects ? _self.soundEffects : soundEffects // ignore: cast_nullable_to_non_nullable
as bool,aprilFoolFeatures: null == aprilFoolFeatures ? _self.aprilFoolFeatures : aprilFoolFeatures // ignore: cast_nullable_to_non_nullable
as bool,enterToSend: null == enterToSend ? _self.enterToSend : enterToSend // ignore: cast_nullable_to_non_nullable
as bool,appBarTransparent: null == appBarTransparent ? _self.appBarTransparent : appBarTransparent // ignore: cast_nullable_to_non_nullable
as bool,showBackgroundImage: null == showBackgroundImage ? _self.showBackgroundImage : showBackgroundImage // ignore: cast_nullable_to_non_nullable
as bool,customFonts: freezed == customFonts ? _self.customFonts : customFonts // ignore: cast_nullable_to_non_nullable
as String?,appColorScheme: freezed == appColorScheme ? _self.appColorScheme : appColorScheme // ignore: cast_nullable_to_non_nullable
as int?,windowSize: freezed == windowSize ? _self.windowSize : windowSize // ignore: cast_nullable_to_non_nullable
as Size?,
as int?,customColors: freezed == customColors ? _self.customColors : customColors // ignore: cast_nullable_to_non_nullable
as ThemeColors?,windowSize: freezed == windowSize ? _self.windowSize : windowSize // ignore: cast_nullable_to_non_nullable
as Size?,windowOpacity: null == windowOpacity ? _self.windowOpacity : windowOpacity // ignore: cast_nullable_to_non_nullable
as double,cardTransparency: null == cardTransparency ? _self.cardTransparency : cardTransparency // ignore: cast_nullable_to_non_nullable
as double,defaultPoolId: freezed == defaultPoolId ? _self.defaultPoolId : defaultPoolId // ignore: cast_nullable_to_non_nullable
as String?,messageDisplayStyle: null == messageDisplayStyle ? _self.messageDisplayStyle : messageDisplayStyle // ignore: cast_nullable_to_non_nullable
as String,themeMode: freezed == themeMode ? _self.themeMode : themeMode // ignore: cast_nullable_to_non_nullable
as String?,useMaterial3: null == useMaterial3 ? _self.useMaterial3 : useMaterial3 // ignore: cast_nullable_to_non_nullable
as bool,disableAnimation: null == disableAnimation ? _self.disableAnimation : disableAnimation // ignore: cast_nullable_to_non_nullable
as bool,
));
}
/// Create a copy of AppSettings
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$ThemeColorsCopyWith<$Res>? get customColors {
if (_self.customColors == null) {
return null;
}
return $ThemeColorsCopyWith<$Res>(_self.customColors!, (value) {
return _then(_self.copyWith(customColors: value));
});
}
}
@@ -155,10 +452,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool autoTranslate, bool soundEffects, bool aprilFoolFeatures, bool enterToSend, bool appBarTransparent, String? customFonts, int? appColorScheme, Size? windowSize)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool autoTranslate, bool dataSavingMode, bool soundEffects, bool aprilFoolFeatures, bool enterToSend, bool appBarTransparent, bool showBackgroundImage, String? customFonts, int? appColorScheme, ThemeColors? customColors, Size? windowSize, double windowOpacity, double cardTransparency, String? defaultPoolId, String messageDisplayStyle, String? themeMode, bool useMaterial3, bool disableAnimation)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _AppSettings() when $default != null:
return $default(_that.autoTranslate,_that.soundEffects,_that.aprilFoolFeatures,_that.enterToSend,_that.appBarTransparent,_that.customFonts,_that.appColorScheme,_that.windowSize);case _:
return $default(_that.autoTranslate,_that.dataSavingMode,_that.soundEffects,_that.aprilFoolFeatures,_that.enterToSend,_that.appBarTransparent,_that.showBackgroundImage,_that.customFonts,_that.appColorScheme,_that.customColors,_that.windowSize,_that.windowOpacity,_that.cardTransparency,_that.defaultPoolId,_that.messageDisplayStyle,_that.themeMode,_that.useMaterial3,_that.disableAnimation);case _:
return orElse();
}
@@ -176,10 +473,10 @@ return $default(_that.autoTranslate,_that.soundEffects,_that.aprilFoolFeatures,_
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool autoTranslate, bool soundEffects, bool aprilFoolFeatures, bool enterToSend, bool appBarTransparent, String? customFonts, int? appColorScheme, Size? windowSize) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool autoTranslate, bool dataSavingMode, bool soundEffects, bool aprilFoolFeatures, bool enterToSend, bool appBarTransparent, bool showBackgroundImage, String? customFonts, int? appColorScheme, ThemeColors? customColors, Size? windowSize, double windowOpacity, double cardTransparency, String? defaultPoolId, String messageDisplayStyle, String? themeMode, bool useMaterial3, bool disableAnimation) $default,) {final _that = this;
switch (_that) {
case _AppSettings():
return $default(_that.autoTranslate,_that.soundEffects,_that.aprilFoolFeatures,_that.enterToSend,_that.appBarTransparent,_that.customFonts,_that.appColorScheme,_that.windowSize);}
return $default(_that.autoTranslate,_that.dataSavingMode,_that.soundEffects,_that.aprilFoolFeatures,_that.enterToSend,_that.appBarTransparent,_that.showBackgroundImage,_that.customFonts,_that.appColorScheme,_that.customColors,_that.windowSize,_that.windowOpacity,_that.cardTransparency,_that.defaultPoolId,_that.messageDisplayStyle,_that.themeMode,_that.useMaterial3,_that.disableAnimation);}
}
/// A variant of `when` that fallback to returning `null`
///
@@ -193,10 +490,10 @@ return $default(_that.autoTranslate,_that.soundEffects,_that.aprilFoolFeatures,_
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool autoTranslate, bool soundEffects, bool aprilFoolFeatures, bool enterToSend, bool appBarTransparent, String? customFonts, int? appColorScheme, Size? windowSize)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool autoTranslate, bool dataSavingMode, bool soundEffects, bool aprilFoolFeatures, bool enterToSend, bool appBarTransparent, bool showBackgroundImage, String? customFonts, int? appColorScheme, ThemeColors? customColors, Size? windowSize, double windowOpacity, double cardTransparency, String? defaultPoolId, String messageDisplayStyle, String? themeMode, bool useMaterial3, bool disableAnimation)? $default,) {final _that = this;
switch (_that) {
case _AppSettings() when $default != null:
return $default(_that.autoTranslate,_that.soundEffects,_that.aprilFoolFeatures,_that.enterToSend,_that.appBarTransparent,_that.customFonts,_that.appColorScheme,_that.windowSize);case _:
return $default(_that.autoTranslate,_that.dataSavingMode,_that.soundEffects,_that.aprilFoolFeatures,_that.enterToSend,_that.appBarTransparent,_that.showBackgroundImage,_that.customFonts,_that.appColorScheme,_that.customColors,_that.windowSize,_that.windowOpacity,_that.cardTransparency,_that.defaultPoolId,_that.messageDisplayStyle,_that.themeMode,_that.useMaterial3,_that.disableAnimation);case _:
return null;
}
@@ -208,18 +505,31 @@ return $default(_that.autoTranslate,_that.soundEffects,_that.aprilFoolFeatures,_
class _AppSettings implements AppSettings {
const _AppSettings({required this.autoTranslate, required this.soundEffects, required this.aprilFoolFeatures, required this.enterToSend, required this.appBarTransparent, required this.customFonts, required this.appColorScheme, required this.windowSize});
const _AppSettings({required this.autoTranslate, required this.dataSavingMode, required this.soundEffects, required this.aprilFoolFeatures, required this.enterToSend, required this.appBarTransparent, required this.showBackgroundImage, required this.customFonts, required this.appColorScheme, required this.customColors, required this.windowSize, required this.windowOpacity, required this.cardTransparency, required this.defaultPoolId, required this.messageDisplayStyle, required this.themeMode, required this.useMaterial3, required this.disableAnimation});
@override final bool autoTranslate;
@override final bool dataSavingMode;
@override final bool soundEffects;
@override final bool aprilFoolFeatures;
@override final bool enterToSend;
@override final bool appBarTransparent;
@override final bool showBackgroundImage;
@override final String? customFonts;
@override final int? appColorScheme;
// The color stored via the int type
@override final ThemeColors? customColors;
@override final Size? windowSize;
// The window size for desktop platforms
@override final double windowOpacity;
// The window opacity for desktop platforms
@override final double cardTransparency;
// The card background opacity
@override final String? defaultPoolId;
@override final String messageDisplayStyle;
@override final String? themeMode;
@override final bool useMaterial3;
@override final bool disableAnimation;
/// Create a copy of AppSettings
/// with the given fields replaced by the non-null parameter values.
@@ -231,16 +541,16 @@ _$AppSettingsCopyWith<_AppSettings> get copyWith => __$AppSettingsCopyWithImpl<_
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _AppSettings&&(identical(other.autoTranslate, autoTranslate) || other.autoTranslate == autoTranslate)&&(identical(other.soundEffects, soundEffects) || other.soundEffects == soundEffects)&&(identical(other.aprilFoolFeatures, aprilFoolFeatures) || other.aprilFoolFeatures == aprilFoolFeatures)&&(identical(other.enterToSend, enterToSend) || other.enterToSend == enterToSend)&&(identical(other.appBarTransparent, appBarTransparent) || other.appBarTransparent == appBarTransparent)&&(identical(other.customFonts, customFonts) || other.customFonts == customFonts)&&(identical(other.appColorScheme, appColorScheme) || other.appColorScheme == appColorScheme)&&(identical(other.windowSize, windowSize) || other.windowSize == windowSize));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _AppSettings&&(identical(other.autoTranslate, autoTranslate) || other.autoTranslate == autoTranslate)&&(identical(other.dataSavingMode, dataSavingMode) || other.dataSavingMode == dataSavingMode)&&(identical(other.soundEffects, soundEffects) || other.soundEffects == soundEffects)&&(identical(other.aprilFoolFeatures, aprilFoolFeatures) || other.aprilFoolFeatures == aprilFoolFeatures)&&(identical(other.enterToSend, enterToSend) || other.enterToSend == enterToSend)&&(identical(other.appBarTransparent, appBarTransparent) || other.appBarTransparent == appBarTransparent)&&(identical(other.showBackgroundImage, showBackgroundImage) || other.showBackgroundImage == showBackgroundImage)&&(identical(other.customFonts, customFonts) || other.customFonts == customFonts)&&(identical(other.appColorScheme, appColorScheme) || other.appColorScheme == appColorScheme)&&(identical(other.customColors, customColors) || other.customColors == customColors)&&(identical(other.windowSize, windowSize) || other.windowSize == windowSize)&&(identical(other.windowOpacity, windowOpacity) || other.windowOpacity == windowOpacity)&&(identical(other.cardTransparency, cardTransparency) || other.cardTransparency == cardTransparency)&&(identical(other.defaultPoolId, defaultPoolId) || other.defaultPoolId == defaultPoolId)&&(identical(other.messageDisplayStyle, messageDisplayStyle) || other.messageDisplayStyle == messageDisplayStyle)&&(identical(other.themeMode, themeMode) || other.themeMode == themeMode)&&(identical(other.useMaterial3, useMaterial3) || other.useMaterial3 == useMaterial3)&&(identical(other.disableAnimation, disableAnimation) || other.disableAnimation == disableAnimation));
}
@override
int get hashCode => Object.hash(runtimeType,autoTranslate,soundEffects,aprilFoolFeatures,enterToSend,appBarTransparent,customFonts,appColorScheme,windowSize);
int get hashCode => Object.hash(runtimeType,autoTranslate,dataSavingMode,soundEffects,aprilFoolFeatures,enterToSend,appBarTransparent,showBackgroundImage,customFonts,appColorScheme,customColors,windowSize,windowOpacity,cardTransparency,defaultPoolId,messageDisplayStyle,themeMode,useMaterial3,disableAnimation);
@override
String toString() {
return 'AppSettings(autoTranslate: $autoTranslate, soundEffects: $soundEffects, aprilFoolFeatures: $aprilFoolFeatures, enterToSend: $enterToSend, appBarTransparent: $appBarTransparent, customFonts: $customFonts, appColorScheme: $appColorScheme, windowSize: $windowSize)';
return 'AppSettings(autoTranslate: $autoTranslate, dataSavingMode: $dataSavingMode, soundEffects: $soundEffects, aprilFoolFeatures: $aprilFoolFeatures, enterToSend: $enterToSend, appBarTransparent: $appBarTransparent, showBackgroundImage: $showBackgroundImage, customFonts: $customFonts, appColorScheme: $appColorScheme, customColors: $customColors, windowSize: $windowSize, windowOpacity: $windowOpacity, cardTransparency: $cardTransparency, defaultPoolId: $defaultPoolId, messageDisplayStyle: $messageDisplayStyle, themeMode: $themeMode, useMaterial3: $useMaterial3, disableAnimation: $disableAnimation)';
}
@@ -251,11 +561,11 @@ abstract mixin class _$AppSettingsCopyWith<$Res> implements $AppSettingsCopyWith
factory _$AppSettingsCopyWith(_AppSettings value, $Res Function(_AppSettings) _then) = __$AppSettingsCopyWithImpl;
@override @useResult
$Res call({
bool autoTranslate, bool soundEffects, bool aprilFoolFeatures, bool enterToSend, bool appBarTransparent, String? customFonts, int? appColorScheme, Size? windowSize
bool autoTranslate, bool dataSavingMode, bool soundEffects, bool aprilFoolFeatures, bool enterToSend, bool appBarTransparent, bool showBackgroundImage, String? customFonts, int? appColorScheme, ThemeColors? customColors, Size? windowSize, double windowOpacity, double cardTransparency, String? defaultPoolId, String messageDisplayStyle, String? themeMode, bool useMaterial3, bool disableAnimation
});
@override $ThemeColorsCopyWith<$Res>? get customColors;
}
/// @nodoc
@@ -268,21 +578,43 @@ class __$AppSettingsCopyWithImpl<$Res>
/// Create a copy of AppSettings
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? autoTranslate = null,Object? soundEffects = null,Object? aprilFoolFeatures = null,Object? enterToSend = null,Object? appBarTransparent = null,Object? customFonts = freezed,Object? appColorScheme = freezed,Object? windowSize = freezed,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? autoTranslate = null,Object? dataSavingMode = null,Object? soundEffects = null,Object? aprilFoolFeatures = null,Object? enterToSend = null,Object? appBarTransparent = null,Object? showBackgroundImage = null,Object? customFonts = freezed,Object? appColorScheme = freezed,Object? customColors = freezed,Object? windowSize = freezed,Object? windowOpacity = null,Object? cardTransparency = null,Object? defaultPoolId = freezed,Object? messageDisplayStyle = null,Object? themeMode = freezed,Object? useMaterial3 = null,Object? disableAnimation = null,}) {
return _then(_AppSettings(
autoTranslate: null == autoTranslate ? _self.autoTranslate : autoTranslate // ignore: cast_nullable_to_non_nullable
as bool,dataSavingMode: null == dataSavingMode ? _self.dataSavingMode : dataSavingMode // ignore: cast_nullable_to_non_nullable
as bool,soundEffects: null == soundEffects ? _self.soundEffects : soundEffects // ignore: cast_nullable_to_non_nullable
as bool,aprilFoolFeatures: null == aprilFoolFeatures ? _self.aprilFoolFeatures : aprilFoolFeatures // ignore: cast_nullable_to_non_nullable
as bool,enterToSend: null == enterToSend ? _self.enterToSend : enterToSend // ignore: cast_nullable_to_non_nullable
as bool,appBarTransparent: null == appBarTransparent ? _self.appBarTransparent : appBarTransparent // ignore: cast_nullable_to_non_nullable
as bool,showBackgroundImage: null == showBackgroundImage ? _self.showBackgroundImage : showBackgroundImage // ignore: cast_nullable_to_non_nullable
as bool,customFonts: freezed == customFonts ? _self.customFonts : customFonts // ignore: cast_nullable_to_non_nullable
as String?,appColorScheme: freezed == appColorScheme ? _self.appColorScheme : appColorScheme // ignore: cast_nullable_to_non_nullable
as int?,windowSize: freezed == windowSize ? _self.windowSize : windowSize // ignore: cast_nullable_to_non_nullable
as Size?,
as int?,customColors: freezed == customColors ? _self.customColors : customColors // ignore: cast_nullable_to_non_nullable
as ThemeColors?,windowSize: freezed == windowSize ? _self.windowSize : windowSize // ignore: cast_nullable_to_non_nullable
as Size?,windowOpacity: null == windowOpacity ? _self.windowOpacity : windowOpacity // ignore: cast_nullable_to_non_nullable
as double,cardTransparency: null == cardTransparency ? _self.cardTransparency : cardTransparency // ignore: cast_nullable_to_non_nullable
as double,defaultPoolId: freezed == defaultPoolId ? _self.defaultPoolId : defaultPoolId // ignore: cast_nullable_to_non_nullable
as String?,messageDisplayStyle: null == messageDisplayStyle ? _self.messageDisplayStyle : messageDisplayStyle // ignore: cast_nullable_to_non_nullable
as String,themeMode: freezed == themeMode ? _self.themeMode : themeMode // ignore: cast_nullable_to_non_nullable
as String?,useMaterial3: null == useMaterial3 ? _self.useMaterial3 : useMaterial3 // ignore: cast_nullable_to_non_nullable
as bool,disableAnimation: null == disableAnimation ? _self.disableAnimation : disableAnimation // ignore: cast_nullable_to_non_nullable
as bool,
));
}
/// Create a copy of AppSettings
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$ThemeColorsCopyWith<$Res>? get customColors {
if (_self.customColors == null) {
return null;
}
return $ThemeColorsCopyWith<$Res>(_self.customColors!, (value) {
return _then(_self.copyWith(customColors: value));
});
}
}
// dart format on

View File

@@ -2,12 +2,35 @@
part of 'config.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_ThemeColors _$ThemeColorsFromJson(Map<String, dynamic> json) => _ThemeColors(
primary: (json['primary'] as num?)?.toInt(),
secondary: (json['secondary'] as num?)?.toInt(),
tertiary: (json['tertiary'] as num?)?.toInt(),
surface: (json['surface'] as num?)?.toInt(),
background: (json['background'] as num?)?.toInt(),
error: (json['error'] as num?)?.toInt(),
);
Map<String, dynamic> _$ThemeColorsToJson(_ThemeColors instance) =>
<String, dynamic>{
'primary': instance.primary,
'secondary': instance.secondary,
'tertiary': instance.tertiary,
'surface': instance.surface,
'background': instance.background,
'error': instance.error,
};
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
String _$appSettingsNotifierHash() =>
r'c4f40a3bc4311c6360c2b5e44f8df5e5d7c1bd75';
r'10ebd893c39d24ae588a4c0bf4144ee4656465a4';
/// See also [AppSettingsNotifier].
@ProviderFor(AppSettingsNotifier)

24
lib/pods/file_pool.dart Normal file
View File

@@ -0,0 +1,24 @@
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/file_pool.dart';
import 'package:island/pods/config.dart';
import 'package:island/pods/network.dart';
final poolsProvider = FutureProvider<List<SnFilePool>>((ref) async {
final dio = ref.watch(apiClientProvider);
final response = await dio.get('/drive/pools');
return response.data
.map((e) => SnFilePool.fromJson(e))
.cast<SnFilePool>()
.toList();
});
String? resolveDefaultPoolId(WidgetRef ref, List<SnFilePool> pools) {
final settings = ref.watch(appSettingsNotifierProvider);
final configuredId = settings.defaultPoolId;
if (configuredId != null && pools.any((p) => p.id == configuredId)) {
return configuredId;
}
return pools.firstOrNull?.id;
}

30
lib/pods/lifecycle.dart Normal file
View File

@@ -0,0 +1,30 @@
import "dart:async";
import "package:flutter/material.dart";
import "package:hooks_riverpod/hooks_riverpod.dart";
final appLifecycleStateProvider = StreamProvider<AppLifecycleState>((ref) {
final controller = StreamController<AppLifecycleState>();
final observer = _AppLifecycleObserver((state) {
if (controller.isClosed) return;
controller.add(state);
});
WidgetsBinding.instance.addObserver(observer);
ref.onDispose(() {
WidgetsBinding.instance.removeObserver(observer);
controller.close();
});
return controller.stream;
});
class _AppLifecycleObserver extends WidgetsBindingObserver {
final ValueChanged<AppLifecycleState> onChange;
_AppLifecycleObserver(this.onChange);
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
onChange(state);
}
}

View File

@@ -10,17 +10,19 @@ Future<void> resetDatabase(WidgetRef ref) async {
if (kIsWeb) return;
final db = ref.read(databaseProvider);
final basepath = await getApplicationSupportDirectory();
final file = File(join(basepath.path, 'solar_network_data.sqlite'));
// Close current database connection
db.close();
await db.close();
// Delete database file
// Get the correct database file path
final dbFolder = await getApplicationDocumentsDirectory();
final file = File(join(dbFolder.path, 'solar_network_data.sqlite'));
// Delete database file if it exists
if (await file.exists()) {
await file.delete();
}
// Force refresh the database provider
// Force refresh the database provider to create a new instance
ref.invalidate(databaseProvider);
}

View File

@@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:dio_smart_retry/dio_smart_retry.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:dio/dio.dart';
@@ -10,6 +11,8 @@ import 'package:package_info_plus/package_info_plus.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:island/models/auth.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:talker_dio_logger/talker_dio_logger.dart';
import 'package:island/talker.dart';
import 'config.dart';
@@ -75,7 +78,7 @@ final apiClientProvider = Provider<Dio>((ref) {
),
);
dio.interceptors.add(
dio.interceptors.addAll([
InterceptorsWrapper(
onRequest: (
RequestOptions options,
@@ -97,7 +100,27 @@ final apiClientProvider = Provider<Dio>((ref) {
return handler.next(options);
},
),
);
TalkerDioLogger(
talker: talker,
settings: const TalkerDioLoggerSettings(
printRequestHeaders: false,
printResponseHeaders: false,
printResponseMessage: false,
printRequestData: false,
printResponseData: false,
),
),
RetryInterceptor(
dio: dio,
retries: 3,
retryDelays: const [
Duration(seconds: 1),
Duration(seconds: 2),
Duration(seconds: 3),
],
retryEvaluator: (err, _) => err.requestOptions.method == 'GET',
),
]);
return dio;
});

View File

@@ -1,38 +1,16 @@
import 'package:flutter/material.dart';
import 'package:island/pods/config.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
final themeProvider = StateNotifierProvider<ThemeNotifier, ThemeSet?>((ref) {
return ThemeNotifier();
});
part 'theme.g.dart';
class ThemeNotifier extends StateNotifier<ThemeSet?> {
ThemeNotifier() : super(null) {
_loadTheme();
}
Future<void> _loadTheme() async {
final theme = await createAppThemeSet();
state = theme;
}
void reloadTheme({
Color? seedColorOverride,
bool? useMaterial3,
String? customFonts,
}) async {
final theme = await createAppThemeSet(
seedColorOverride: seedColorOverride,
useMaterial3: useMaterial3,
customFonts: customFonts,
);
state = theme;
}
@riverpod
ThemeSet theme(Ref ref) {
final settings = ref.watch(appSettingsNotifierProvider);
return createAppThemeSet(settings);
}
const kMaterialYouToggleStoreKey = 'app_theme_material_you';
class ThemeSet {
ThemeData light;
ThemeData dark;
@@ -40,52 +18,50 @@ class ThemeSet {
ThemeSet({required this.light, required this.dark});
}
Future<ThemeSet> createAppThemeSet({
Color? seedColorOverride,
bool? useMaterial3,
String? customFonts,
}) async {
ThemeSet createAppThemeSet(AppSettings settings) {
return ThemeSet(
light: await createAppTheme(
Brightness.light,
useMaterial3: useMaterial3,
customFonts: customFonts,
),
dark: await createAppTheme(
Brightness.dark,
useMaterial3: useMaterial3,
customFonts: customFonts,
),
light: createAppTheme(Brightness.light, settings),
dark: createAppTheme(Brightness.dark, settings),
);
}
Future<ThemeData> createAppTheme(
Brightness brightness, {
Color? seedColorOverride,
bool? useMaterial3,
String? customFonts,
}) async {
final prefs = await SharedPreferences.getInstance();
final seedColorString = prefs.getInt(kAppColorSchemeStoreKey);
ThemeData createAppTheme(Brightness brightness, AppSettings settings) {
final seedColor =
seedColorString != null ? Color(seedColorString) : Colors.indigo;
settings.appColorScheme != null
? Color(settings.appColorScheme!)
: Colors.indigo;
final colorScheme = ColorScheme.fromSeed(
seedColor: seedColorOverride ?? seedColor,
var colorScheme = ColorScheme.fromSeed(
seedColor: seedColor,
brightness: brightness,
);
final hasAppBarTransparent =
prefs.getBool(kAppbarTransparentStoreKey) ?? false;
final useM3 =
useMaterial3 ?? (prefs.getBool(kMaterialYouToggleStoreKey) ?? true);
final customColors = settings.customColors;
if (customColors != null) {
colorScheme = colorScheme.copyWith(
primary:
customColors.primary != null ? Color(customColors.primary!) : null,
secondary:
customColors.secondary != null
? Color(customColors.secondary!)
: null,
tertiary:
customColors.tertiary != null ? Color(customColors.tertiary!) : null,
surface:
customColors.surface != null ? Color(customColors.surface!) : null,
background:
customColors.background != null
? Color(customColors.background!)
: null,
error: customColors.error != null ? Color(customColors.error!) : null,
);
}
final hasAppBarTransparent = settings.appBarTransparent;
final useM3 = settings.useMaterial3;
final inUseFonts =
(customFonts ?? prefs.getString(kAppCustomFonts))
?.split(',')
.map((ele) => ele.trim())
.toList() ??
settings.customFonts?.split(',').map((ele) => ele.trim()).toList() ??
['Nunito'];
return ThemeData(
@@ -100,10 +76,6 @@ Future<ThemeData> createAppTheme(
opticalSize: 20,
color: colorScheme.onSurface,
),
snackBarTheme: SnackBarThemeData(
behavior: useM3 ? SnackBarBehavior.floating : SnackBarBehavior.fixed,
width: 480,
),
appBarTheme: AppBarTheme(
centerTitle: true,
elevation: hasAppBarTransparent ? 0 : null,
@@ -112,6 +84,11 @@ Future<ThemeData> createAppTheme(
foregroundColor:
hasAppBarTransparent ? colorScheme.onSurface : colorScheme.onPrimary,
),
cardTheme: CardThemeData(
color: colorScheme.surfaceContainer.withOpacity(
settings.cardTransparency,
),
),
pageTransitionsTheme: PageTransitionsTheme(
builders: {
TargetPlatform.android: ZoomPageTransitionsBuilder(),

26
lib/pods/theme.g.dart Normal file
View File

@@ -0,0 +1,26 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'theme.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
String _$themeHash() => r'a12dbf8b83d75713b7ae4c68e9cdd1a1cc3a35f0';
/// See also [theme].
@ProviderFor(theme)
final themeProvider = AutoDisposeProvider<ThemeSet>.internal(
theme,
name: r'themeProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product') ? null : _$themeHash,
dependencies: null,
allTransitiveDependencies: null,
);
@Deprecated('Will be removed in 3.0. Use Ref instead')
// ignore: unused_element
typedef ThemeRef = AutoDisposeProviderRef<ThemeSet>;
// 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,11 +1,9 @@
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';
@@ -29,10 +27,17 @@ Future<String> translateString(Ref ref, TranslateQuery query) async {
@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;
bool isChinese(String text) {
final chineseRegex = RegExp(r'[\u4e00-\u9fff]');
return chineseRegex.hasMatch(text);
}
bool isEnglish(String text) {
final englishRegex = RegExp(r'[a-zA-Z]');
return englishRegex.hasMatch(text) && !isChinese(text);
}
if (isChinese(text)) return "zh";
if (isEnglish(text)) return "en";
return null;
}

View File

@@ -149,7 +149,7 @@ class _TranslateStringProviderElement
}
String _$detectStringLanguageHash() =>
r'697b68464b3d00927cc43ccc1ba8ba93f2a470ed';
r'24fbf52edbbffcc8dc4f09f7206f82d69728e703';
/// See also [detectStringLanguage].
@ProviderFor(detectStringLanguage)

View File

@@ -1,5 +1,4 @@
import 'dart:convert';
import 'dart:developer';
import 'dart:io' show Platform;
import 'package:dio/dio.dart';
@@ -12,6 +11,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/account.dart';
import 'package:island/pods/config.dart';
import 'package:island/pods/network.dart';
import 'package:island/talker.dart';
class UserInfoNotifier extends StateNotifier<AsyncValue<SnAccount?>> {
final Ref _ref;
@@ -21,7 +21,7 @@ class UserInfoNotifier extends StateNotifier<AsyncValue<SnAccount?>> {
Future<void> fetchUser() async {
final token = _ref.watch(tokenProvider);
if (token == null) {
log('[UserInfo] No token found, not going to fetch...');
talker.info('[UserInfo] No token found, not going to fetch...');
return;
}
try {
@@ -30,7 +30,7 @@ class UserInfoNotifier extends StateNotifier<AsyncValue<SnAccount?>> {
final user = SnAccount.fromJson(response.data);
state = AsyncValue.data(user);
if (kIsWeb || !Platform.isLinux) {
if (kIsWeb || !(Platform.isLinux || Platform.isWindows)) {
FirebaseAnalytics.instance.setUserId(id: user.id);
}
} catch (error, stackTrace) {
@@ -44,9 +44,12 @@ class UserInfoNotifier extends StateNotifier<AsyncValue<SnAccount?>> {
: 'failedToLoadUserInfoNetwork')
.tr()
.trim(),
'${error.response!.statusCode}\n${error.response?.headers}',
jsonEncode(error.response?.data),
].join('\n\n'),
'',
'${error.response?.statusCode ?? 'Network Error'}',
if (error.response?.headers != null) error.response?.headers,
if (error.response?.data != null)
jsonEncode(error.response?.data),
].join('\n'),
iconStyle: IconStyle.error,
neutralButtonTitle: 'retry'.tr(),
negativeButtonTitle: 'okay'.tr(),
@@ -72,11 +75,10 @@ class UserInfoNotifier extends StateNotifier<AsyncValue<SnAccount?>> {
}
});
}
log(
talker.error(
"[UserInfo] Failed to fetch user info...",
name: 'UserInfoNotifier',
error: error,
stackTrace: stackTrace,
error,
stackTrace,
);
state = AsyncValue.data(null);
}
@@ -87,7 +89,7 @@ class UserInfoNotifier extends StateNotifier<AsyncValue<SnAccount?>> {
final prefs = _ref.read(sharedPreferencesProvider);
await prefs.remove(kTokenPairStoreKey);
_ref.invalidate(tokenProvider);
if (kIsWeb || !Platform.isLinux) {
if (kIsWeb || !(Platform.isLinux || Platform.isWindows)) {
FirebaseAnalytics.instance.setUserId(id: null);
}
}

View File

@@ -1,6 +1,5 @@
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';
@@ -8,6 +7,7 @@ import 'package:island/pods/config.dart';
import 'package:island/pods/network.dart';
import 'package:web_socket_channel/io.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
import 'package:island/talker.dart';
part 'websocket.freezed.dart';
part 'websocket.g.dart';
@@ -64,7 +64,7 @@ class WebSocketService {
final url = '$baseUrl/ws'.replaceFirst('http', 'ws');
log('[WebSocket] Trying connecting to $url');
talker.info('[WebSocket] Trying connecting to $url');
try {
if (kIsWeb) {
_channel = WebSocketChannel.connect(Uri.parse('$url?tk=$token'));
@@ -88,24 +88,24 @@ class WebSocketService {
return;
}
_streamController.sink.add(packet);
log(
talker.info(
"[WebSocket] Received packet: ${packet.type} ${packet.errorMessage}",
);
if (packet.type == 'pong' && _heartbeatAt != null) {
var now = DateTime.now();
heartbeatDelay = now.difference(_heartbeatAt!);
log(
talker.info(
"[WebSocket] Server respond last heartbeat for ${heartbeatDelay!.inMilliseconds} ms",
);
}
},
onDone: () {
log('[WebSocket] Connection closed, attempting to reconnect...');
talker.info('[WebSocket] Connection closed, attempting to reconnect...');
_scheduleReconnect();
_statusStreamController.sink.add(WebSocketState.disconnected());
},
onError: (error) {
log('[WebSocket] Error occurred: $error, attempting to reconnect...');
talker.error('[WebSocket] Error occurred: $error, attempting to reconnect...');
_scheduleReconnect();
_statusStreamController.sink.add(
WebSocketState.error(error.toString()),
@@ -113,7 +113,7 @@ class WebSocketService {
},
);
} catch (err) {
log('[WebSocket] Failed to connect: $err');
talker.error('[WebSocket] Failed to connect: $err');
_scheduleReconnect();
}
}
@@ -135,7 +135,7 @@ class WebSocketService {
void _beatTheHeart() {
_heartbeatAt = DateTime.now();
log('[WebSocket] We\'re beating the heart! $_heartbeatAt');
talker.info('[WebSocket] We\'re beating the heart! $_heartbeatAt');
sendMessage(jsonEncode(WebSocketPacket(type: 'ping', data: null)));
}

View File

@@ -6,19 +6,17 @@ 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/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_app.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/files/file_list.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';
@@ -35,21 +33,21 @@ import 'package:island/screens/account/me/profile_update.dart';
import 'package:island/screens/account/leveling.dart';
import 'package:island/screens/account/me/account_settings.dart';
import 'package:island/screens/chat/chat.dart';
import 'package:island/screens/chat/chat_form.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.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/publishers_form.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';
@@ -58,12 +56,14 @@ import 'package:island/screens/auth/login.dart';
import 'package:island/screens/auth/create_account.dart';
import 'package:island/screens/settings.dart';
import 'package:island/screens/realm/realms.dart';
import 'package:island/screens/realm/realm_form.dart';
import 'package:island/screens/realm/realm_detail.dart';
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/talker.dart';
import 'package:island/widgets/post/post_shuffle.dart';
import 'package:talker_flutter/talker_flutter.dart';
// Shell route keys for nested navigation
final rootNavigatorKey = GlobalKey<NavigatorState>();
@@ -85,11 +85,7 @@ Widget _tabPagesTransitionBuilder(
}
bool get _supportsAnalytics =>
kIsWeb ||
Platform.isAndroid ||
Platform.isIOS ||
Platform.isMacOS ||
Platform.isWindows;
kIsWeb || Platform.isAndroid || Platform.isIOS || Platform.isMacOS;
// Provider for the router
final routerProvider = Provider<GoRouter>((ref) {
@@ -99,6 +95,7 @@ final routerProvider = Provider<GoRouter>((ref) {
observers: [
if (_supportsAnalytics)
FirebaseAnalyticsObserver(analytics: FirebaseAnalytics.instance),
TalkerRouteObserver(talker),
],
routes: [
ShellRoute(
@@ -136,262 +133,9 @@ final routerProvider = Provider<GoRouter>((ref) {
},
),
GoRoute(
name: 'accountCalendar',
path: '/account/:name/calendar',
builder: (context, state) {
final name = state.pathParameters['name']!;
return EventCalanderScreen(name: name);
},
),
ShellRoute(
builder:
(context, state, child) => CreatorHubShellScreen(child: child),
routes: [
GoRoute(
name: 'creatorHub',
path: '/creators',
builder: (context, state) => const CreatorHubScreen(),
),
// Web Feed Routes
GoRoute(
name: 'creatorFeeds',
path: '/creators/:name/feeds',
builder: (context, state) {
final name = state.pathParameters['name']!;
return WebFeedListScreen(pubName: name);
},
routes: [
GoRoute(
name: 'creatorFeedNew',
path: 'new',
builder: (context, state) {
return WebFeedNewScreen(
pubName: state.pathParameters['name']!,
);
},
),
GoRoute(
name: 'creatorFeedEdit',
path: ':feedId',
builder: (context, state) {
return WebFeedEditScreen(
pubName: state.pathParameters['name']!,
feedId: state.pathParameters['feedId'],
);
},
),
],
),
GoRoute(
name: 'creatorPosts',
path: '/creators/:name/posts',
builder: (context, state) {
final name = state.pathParameters['name']!;
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',
builder: (context, state) {
final name = state.pathParameters['name']!;
return StickersScreen(pubName: name);
},
),
GoRoute(
name: 'creatorStickerPackNew',
path: '/creators/:name/stickers/new',
builder: (context, state) {
final name = state.pathParameters['name']!;
return NewStickerPacksScreen(pubName: name);
},
),
GoRoute(
name: 'creatorStickerPackEdit',
path: '/creators/:name/stickers/:packId/edit',
builder: (context, state) {
final name = state.pathParameters['name']!;
final packId = state.pathParameters['packId']!;
return EditStickerPacksScreen(pubName: name, packId: packId);
},
),
GoRoute(
name: 'creatorStickerPackDetail',
path: '/creators/:name/stickers/:packId',
builder: (context, state) {
final name = state.pathParameters['name']!;
final packId = state.pathParameters['packId']!;
return StickerPackDetailScreen(pubName: name, id: packId);
},
),
GoRoute(
name: 'creatorStickerNew',
path: '/creators/:name/stickers/:packId/new',
builder: (context, state) {
final packId = state.pathParameters['packId']!;
return NewStickersScreen(packId: packId);
},
),
GoRoute(
name: 'creatorStickerEdit',
path: '/creators/:name/stickers/:packId/:id/edit',
builder: (context, state) {
final packId = state.pathParameters['packId']!;
final id = state.pathParameters['id']!;
return EditStickersScreen(id: id, packId: packId);
},
),
GoRoute(
name: 'creatorNew',
path: '/creators/new',
builder: (context, state) => const NewPublisherScreen(),
),
GoRoute(
name: 'creatorEdit',
path: '/creators/:name/edit',
builder: (context, state) {
final name = state.pathParameters['name']!;
return EditPublisherScreen(name: name);
},
),
],
),
ShellRoute(
builder:
(context, state, child) =>
DeveloperHubShellScreen(child: child),
routes: [
GoRoute(
name: 'developerHub',
path: '/developers',
builder: (context, state) => const DeveloperHubScreen(),
),
GoRoute(
name: 'developerProjects',
path: '/developers/:name/projects',
builder:
(context, state) => DevProjectsScreen(
publisherName: state.pathParameters['name']!,
),
),
GoRoute(
name: 'developerProjectNew',
path: '/developers/:name/projects/new',
builder:
(context, state) => NewProjectScreen(
publisherName: state.pathParameters['name']!,
),
),
GoRoute(
name: 'developerProjectEdit',
path: '/developers/:name/projects/:id/edit',
builder:
(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']!,
),
),
],
),
],
name: 'logs',
path: '/logs',
builder: (context, state) => TalkerScreen(talker: talker),
),
// Web articles
@@ -555,6 +299,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);
},
),
],
),
@@ -651,9 +403,9 @@ final routerProvider = Provider<GoRouter>((ref) {
builder: (context, state) => const WalletScreen(),
),
GoRoute(
name: 'socialCredits',
path: '/account/credits',
builder: (context, state) => const SocialCreditsScreen(),
name: 'files',
path: '/account/files',
builder: (context, state) => const FileListScreen(),
),
GoRoute(
name: 'relationships',
@@ -693,12 +445,195 @@ final routerProvider = Provider<GoRouter>((ref) {
GoRoute(
name: 'accountProfile',
path: '/account/:name',
path: '/accounts/:name',
builder: (context, state) {
final name = state.pathParameters['name']!;
return AccountProfileScreen(name: name);
},
),
// Creator hub tab
GoRoute(
name: 'creatorHub',
path: '/creators',
builder: (context, state) => const CreatorHubScreen(),
routes: [
// Web Feed Routes
GoRoute(
name: 'creatorFeeds',
path: ':name/feeds',
builder: (context, state) {
final name = state.pathParameters['name']!;
return WebFeedListScreen(pubName: name);
},
),
GoRoute(
name: 'creatorPosts',
path: ':name/posts',
builder: (context, state) {
final name = state.pathParameters['name']!;
return CreatorPostListScreen(pubName: name);
},
),
// Poll list route
GoRoute(
name: 'creatorPolls',
path: ':name/polls',
builder: (context, state) {
final name = state.pathParameters['name']!;
return CreatorPollListScreen(pubName: name);
},
),
// Poll routes
GoRoute(
name: 'creatorPollNew',
path: ':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: ':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: ':name/stickers',
builder: (context, state) {
final name = state.pathParameters['name']!;
return StickersScreen(pubName: name);
},
),
GoRoute(
name: 'creatorNew',
path: 'new',
builder: (context, state) => const NewPublisherScreen(),
),
GoRoute(
name: 'creatorEdit',
path: ':name/edit',
builder: (context, state) {
final name = state.pathParameters['name']!;
return EditPublisherScreen(name: name);
},
),
],
),
// Developer hub tab
GoRoute(
name: 'developerHub',
path: '/developers',
builder:
(context, state) => DeveloperHubScreen(
initialPublisherName:
state.uri.queryParameters['publisher'],
initialProjectId: state.uri.queryParameters['project'],
),
routes: [
GoRoute(
name: 'developerProjectNew',
path: ':name/projects/new',
builder:
(context, state) => NewProjectScreen(
publisherName: state.pathParameters['name']!,
),
),
GoRoute(
name: 'developerProjectEdit',
path: ':name/projects/:id/edit',
builder:
(context, state) => EditProjectScreen(
publisherName: state.pathParameters['name']!,
id: state.pathParameters['id']!,
),
),
GoRoute(
name: 'developerProjectDetail',
path: ':name/projects/:projectId',
builder: (context, state) {
final name = state.pathParameters['name']!;
final projectId = state.pathParameters['projectId']!;
// Redirect to hub with project selected
WidgetsBinding.instance.addPostFrameCallback((_) {
context.go(
'/developers?publisher=$name&project=$projectId',
);
});
return const SizedBox.shrink(); // Temporary placeholder
},
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: 'developerBotNew',
path: 'bots/new',
builder:
(context, state) => NewBotScreen(
publisherName: state.pathParameters['name']!,
projectId: state.pathParameters['projectId']!,
),
),
GoRoute(
name: 'developerBotDetail',
path: 'bots/:botId',
builder:
(context, state) => BotDetailScreen(
publisherName: state.pathParameters['name']!,
projectId: state.pathParameters['projectId']!,
botId: state.pathParameters['botId']!,
),
),
GoRoute(
name: 'developerBotEdit',
path: 'bots/:id/edit',
builder:
(context, state) => EditBotScreen(
publisherName: state.pathParameters['name']!,
projectId: state.pathParameters['projectId']!,
id: state.pathParameters['id']!,
),
),
],
),
],
),
],
),
],

View File

@@ -6,7 +6,7 @@ import 'package:flutter/material.dart';
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/services/udid.dart' as udid;
import 'package:island/widgets/alert.dart';
import 'package:island/widgets/app_scaffold.dart';
import 'package:material_symbols_icons/symbols.dart';
@@ -68,7 +68,7 @@ class _AboutScreenState extends ConsumerState<AboutScreen> {
try {
final deviceInfoPlugin = DeviceInfoPlugin();
_deviceInfo = await deviceInfoPlugin.deviceInfo;
_deviceUdid = await getUdid();
_deviceUdid = await udid.getUdid();
if (mounted) {
setState(() {});
}
@@ -174,12 +174,20 @@ class _AboutScreenState extends ConsumerState<AboutScreen> {
context,
title: 'Device Information',
children: [
_buildInfoItem(
context,
icon: Symbols.label,
label: 'aboutDeviceName'.tr(),
value:
_deviceInfo?.data['name'] ?? 'unknown'.tr(),
FutureBuilder<String>(
future: udid.getDeviceName(),
builder: (context, snapshot) {
final value =
snapshot.hasData
? snapshot.data!
: 'unknown'.tr();
return _buildInfoItem(
context,
icon: Symbols.label,
label: 'aboutDeviceName'.tr(),
value: value,
);
},
),
_buildInfoItem(
context,
@@ -203,21 +211,11 @@ class _AboutScreenState extends ConsumerState<AboutScreen> {
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();
svc.checkForUpdates(context);
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(

View File

@@ -66,8 +66,8 @@ class AccountScreen extends HookConsumerWidget {
isNoBackground: isWide,
appBar: AppBar(backgroundColor: Colors.transparent, toolbarHeight: 0),
body: SingleChildScrollView(
padding: getTabbedPadding(context),
child: Column(
spacing: 4,
children: <Widget>[
Card(
child: Column(
@@ -112,20 +112,22 @@ class AccountScreen extends HookConsumerWidget {
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: [
AccountName(
account: user.value!,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
Flexible(
child: AccountName(
account: user.value!,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
),
Text('@${user.value!.name}'),
Flexible(child: Text('@${user.value!.name}')),
],
),
Text(
(user.value!.profile.bio.isNotEmpty)
? user.value!.profile.bio
: 'No description yet.',
: 'descriptionNone'.tr(),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
@@ -138,56 +140,133 @@ class AccountScreen extends HookConsumerWidget {
],
),
).padding(horizontal: 8),
GestureDetector(
child: LevelingProgressCard(
level: user.value!.profile.level,
experience: user.value!.profile.experience,
progress: user.value!.profile.levelingProgress,
),
LevelingProgressCard(
isCompact: true,
level: user.value!.profile.level,
experience: user.value!.profile.experience,
progress: user.value!.profile.levelingProgress,
onTap: () {
context.pushNamed('leveling');
},
).padding(horizontal: 12),
Row(
children: [
Expanded(
child: Card(
if (!isWideScreen(context)) const SizedBox.shrink(),
if (!isWideScreen(context))
Row(
spacing: 8,
children: [
Expanded(
child: Card(
margin: EdgeInsets.zero,
child: InkWell(
borderRadius: BorderRadius.circular(8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(Symbols.draw, size: 28).padding(bottom: 8),
Text(
'creatorHub',
maxLines: 1,
overflow: TextOverflow.ellipsis,
).tr().fontSize(16).bold(),
Text(
'creatorHubDescription',
maxLines: 2,
overflow: TextOverflow.ellipsis,
).tr(),
],
).padding(horizontal: 16, vertical: 12),
onTap: () {
context.goNamed('creatorHub');
},
),
).height(140),
),
Expanded(
child: Card(
margin: EdgeInsets.zero,
child: InkWell(
borderRadius: BorderRadius.circular(8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(Symbols.code, size: 28).padding(bottom: 8),
Text(
'developerPortal',
maxLines: 1,
overflow: TextOverflow.ellipsis,
).tr().fontSize(16).bold(),
Text(
'developerPortalDescription',
maxLines: 2,
overflow: TextOverflow.ellipsis,
).tr(),
],
).padding(horizontal: 16, vertical: 12),
onTap: () {
context.pushNamed('developerHub');
},
),
).height(140),
),
],
).padding(horizontal: 12),
const SizedBox.shrink(),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
spacing: 8,
children: [
Card(
margin: EdgeInsets.zero,
child: InkWell(
borderRadius: BorderRadius.circular(8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
child: Row(
spacing: 8,
children: [
Icon(Symbols.draw, size: 28).padding(bottom: 8),
Text('creatorHub').tr().fontSize(16).bold(),
Text('creatorHubDescription').tr(),
Icon(Symbols.settings, size: 20),
Text('appSettings').tr().fontSize(13).bold(),
],
).padding(horizontal: 16, vertical: 12),
onTap: () {
context.pushNamed('creatorHub');
context.pushNamed('settings');
},
),
).height(140),
),
Expanded(
child: Card(
),
Card(
margin: EdgeInsets.zero,
child: InkWell(
borderRadius: BorderRadius.circular(8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
child: Row(
spacing: 8,
children: [
Icon(Symbols.code, size: 28).padding(bottom: 8),
Text('developerPortal').tr().fontSize(16).bold(),
Text('developerPortalDescription').tr(),
Icon(Symbols.person_edit, size: 20),
Text('updateYourProfile').tr().fontSize(13).bold(),
],
).padding(horizontal: 16, vertical: 12),
onTap: () {
context.pushNamed('developerHub');
context.pushNamed('profileUpdate');
},
),
).height(140),
),
],
).padding(horizontal: 8),
),
Card(
margin: EdgeInsets.zero,
child: InkWell(
borderRadius: BorderRadius.circular(8),
child: Row(
spacing: 8,
children: [
Icon(Symbols.manage_accounts, size: 20),
Text('accountSettings').tr().fontSize(13).bold(),
],
).padding(horizontal: 16, vertical: 12),
onTap: () {
context.pushNamed('accountSettings');
},
),
),
],
).padding(horizontal: 12),
).height(48),
ListTile(
minTileHeight: 48,
leading: const Icon(Symbols.notifications),
@@ -216,6 +295,16 @@ class AccountScreen extends HookConsumerWidget {
context.pushNamed('wallet');
},
),
ListTile(
minTileHeight: 48,
leading: const Icon(Symbols.files),
trailing: const Icon(Symbols.chevron_right),
contentPadding: EdgeInsets.symmetric(horizontal: 24),
title: Text('files').tr(),
onTap: () {
context.pushNamed('files');
},
),
ListTile(
minTileHeight: 48,
leading: const Icon(Symbols.people),
@@ -246,16 +335,6 @@ class AccountScreen extends HookConsumerWidget {
context.pushNamed('webFeedMarketplace');
},
),
ListTile(
minTileHeight: 48,
leading: const Icon(Symbols.star),
trailing: const Icon(Symbols.chevron_right),
contentPadding: EdgeInsets.symmetric(horizontal: 24),
title: Text('credits').tr(),
onTap: () {
context.pushNamed('socialCredits');
},
),
ListTile(
minTileHeight: 48,
title: Text('abuseReport').tr(),
@@ -265,37 +344,6 @@ class AccountScreen extends HookConsumerWidget {
onTap: () => context.pushNamed('reportList'),
),
const Divider(height: 1).padding(vertical: 8),
ListTile(
minTileHeight: 48,
leading: const Icon(Symbols.settings),
trailing: const Icon(Symbols.chevron_right),
contentPadding: EdgeInsets.symmetric(horizontal: 24),
title: Text('appSettings').tr(),
onTap: () {
context.pushNamed('settings');
},
),
ListTile(
minTileHeight: 48,
leading: const Icon(Symbols.person_edit),
trailing: const Icon(Symbols.chevron_right),
contentPadding: EdgeInsets.symmetric(horizontal: 24),
title: Text('updateYourProfile').tr(),
onTap: () {
context.pushNamed('profileUpdate');
},
),
ListTile(
minTileHeight: 48,
leading: const Icon(Symbols.manage_accounts),
trailing: const Icon(Symbols.chevron_right),
contentPadding: EdgeInsets.symmetric(horizontal: 24),
title: Text('accountSettings').tr(),
onTap: () {
context.pushNamed('accountSettings');
},
),
const Divider(height: 1).padding(vertical: 8),
ListTile(
minTileHeight: 48,
leading: const Icon(Symbols.info),
@@ -314,6 +362,8 @@ class AccountScreen extends HookConsumerWidget {
title: Text('debugOptions').tr(),
onTap: () {
showModalBottomSheet(
useRootNavigator: true,
isScrollControlled: true,
context: context,
builder: (context) => DebugSheet(),
);

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