Compare commits
260 Commits
1cc34240da
...
refactor/w
| Author | SHA1 | Date | |
|---|---|---|---|
| 0622498f4e | |||
| 844efcda1a | |||
| 98e39cce6a | |||
| 0c459bf7e3 | |||
| a2576abee0 | |||
| f4b28c3fa2 | |||
|
43d767bc03
|
|||
|
0910be88ef
|
|||
|
e96b1fd9d4
|
|||
|
3f83bbc1d8
|
|||
| 001549b190 | |||
| 4595865ad3 | |||
|
|
1834643167 | ||
|
|
0e816eaa3e | ||
|
|
7c1f24b824 | ||
|
c6594ea2ce
|
|||
|
3bec6e683e
|
|||
|
83e92e2eed
|
|||
|
|
b7d44d96ba | ||
|
a83b929d42
|
|||
|
9423affa75
|
|||
|
cda23db609
|
|||
|
61074bc5a3
|
|||
|
5feafa9255
|
|||
|
e604577c1f
|
|||
|
af0ddd1273
|
|||
|
8a6bb34808
|
|||
|
4ef8445c77
|
|||
|
ec39ad6ca3
|
|||
|
eabb3154f1
|
|||
|
910bf20eef
|
|||
|
5efa9b2ae8
|
|||
|
dd3e39e891
|
|||
|
b6896ded23
|
|||
|
f28a73ff9c
|
|||
|
a014b64235
|
|||
|
7e0e7c20d7
|
|||
|
389fa515ba
|
|||
|
681ead02eb
|
|||
|
8d1c145b0b
|
|||
|
51b4754182
|
|||
|
8a2b321701
|
|||
|
f685a7a249
|
|||
|
76009147e9
|
|||
|
ce12f28e56
|
|||
|
3604373a1e
|
|||
|
9704a4c2c7
|
|||
|
67def56ad1
|
|||
|
1be33916af
|
|||
|
e8ff1bfd22
|
|||
|
3ae56f3d89
|
|||
|
707143e998
|
|||
|
1fd34eb2a3
|
|||
|
d7ca41e946
|
|||
|
ad9fb0719a
|
|||
|
e2d315afd4
|
|||
|
6124dbfd79
|
|||
|
5327f04ec0
|
|||
|
41c56a2319
|
|||
|
f9d033542e
|
|||
|
91784e65e6
|
|||
|
9d39c6a825
|
|||
|
537e49f1a4
|
|||
|
75bbd4df71
|
|||
|
6ef4580d93
|
|||
|
6ffd498761
|
|||
|
27157e7cc1
|
|||
|
bbb07d574a
|
|||
|
c660a419e2
|
|||
|
c3f61467c8
|
|||
|
9bc47df452
|
|||
|
9ef8ca4d45
|
|||
|
b55cbd08d1
|
|||
|
8c6bd0feaa
|
|||
|
7dd4b20628
|
|||
|
fec0cb7640
|
|||
|
75deb04a2b
|
|||
|
7c7ed21a96
|
|||
|
a201f20793
|
|||
|
598c51bc1a
|
|||
|
e1ea61c5f1
|
|||
|
ac424bde36
|
|||
|
b43b70df3f
|
|||
|
4321aa621a
|
|||
|
d5d275fb43
|
|||
|
6bb3307144
|
|||
|
391604d4a2
|
|||
|
1d9361c12f
|
|||
|
a129b9cdd0
|
|||
|
3bf815ac61
|
|||
|
77bae4d6fd
|
|||
|
0a301c4c9b
|
|||
|
27b390a51c
|
|||
|
018386d14e
|
|||
|
3825d7c6c7
|
|||
|
bf930291e4
|
|||
|
a8c4988790
|
|||
|
28dd204b1a
|
|||
|
3cbc1a59a7
|
|||
|
277e9ae3d1
|
|||
|
27b3ca25b7
|
|||
|
f871cd3b62
|
|||
|
a8a59ee30c
|
|||
|
2cd1416a13
|
|||
|
6be7dfbc61
|
|||
|
1abbd85614
|
|||
|
31ac5ad07c
|
|||
|
ae2ba495e9
|
|||
|
637aa44548
|
|||
|
44dbfc36d9
|
|||
|
5dbe7371cb
|
|||
|
6c91093198
|
|||
|
3f640b7898
|
|||
|
7db164fda6
|
|||
|
6df1d96cc9
|
|||
|
122a796f8c
|
|||
|
fbc7812a16
|
|||
|
0b1a23e81a
|
|||
|
c87e6cfe07
|
|||
|
53d51b8a0e
|
|||
|
337ae39e08
|
|||
|
8fe3a664a6
|
|||
|
3bfc0b8181
|
|||
| ac2951479b | |||
| 2bfd13d843 | |||
| 28db6f9f01 | |||
|
a4f7b8415d
|
|||
|
2255d3d591
|
|||
|
97792ae734
|
|||
|
a5d13250cc
|
|||
|
de9e235d0c
|
|||
|
56fb5451cd
|
|||
|
870de961f5
|
|||
|
22bf6d1c33
|
|||
|
5b62f89531
|
|||
|
b1326d8f04
|
|||
|
fffca4a78c
|
|||
|
42bd7f97cb
|
|||
| 6377856ae0 | |||
| 0f1c52b9e3 | |||
| 6ed6f60fbc | |||
| e65a414065 | |||
| 214d5c4a53 | |||
| fe33931304 | |||
| 113309257e | |||
| b95a8b2ed2 | |||
|
|
e922971a5e | ||
| 9d5b71bead | |||
| 890efa2efb | |||
| 674097e425 | |||
|
3379dcb7f3
|
|||
| eb5a849e1f | |||
|
4981a23e8e
|
|||
|
c64d4bacb6
|
|||
|
838d18013b
|
|||
|
3f7902e463
|
|||
|
54560ad5d8
|
|||
|
0c729db639
|
|||
|
1fbaac8d88
|
|||
|
b9dc724f0b
|
|||
|
a2cc55696f
|
|||
|
e79f857feb
|
|||
|
affba29c04
|
|||
|
756746b144
|
|||
|
28b6eade48
|
|||
| 1de7ef8c96 | |||
| 67eac5dcf5 | |||
|
7a44bfa075
|
|||
|
1c2f25a152
|
|||
|
be26ea280e
|
|||
|
b4996d069f
|
|||
|
bf4892b34d
|
|||
|
5f84751fd5
|
|||
|
457d1bac60
|
|||
|
02ec11845b
|
|||
|
612f1bf004
|
|||
|
fd80b713ad
|
|||
|
508805368c
|
|||
|
98eb28a4ec
|
|||
|
d1a2f59dd1
|
|||
|
bb9adb963a
|
|||
|
83e40cd860
|
|||
|
c06fb12f6a
|
|||
|
6600cf4df8
|
|||
|
4293daaa2f
|
|||
|
866674ddde
|
|||
|
27d478ba4f
|
|||
|
cccade763f
|
|||
|
f760b85186
|
|||
|
e68c5f4f92
|
|||
|
b0f3b6b5c3
|
|||
|
cb2af379fa
|
|||
|
38f8103265
|
|||
|
06bb18bdaa
|
|||
|
84c38500d0
|
|||
|
9529bbf08b
|
|||
|
8baf77bcf7
|
|||
|
b2ac5fbef2
|
|||
|
c79b1d7aab
|
|||
|
|
4f55a8209c | ||
|
|
ace302111a | ||
|
|
1391fa0dde | ||
|
|
cbdc7acdcd | ||
|
|
b80d91825a | ||
|
|
1a703b7eba | ||
|
|
3621ea7744 | ||
|
|
b638343f02 | ||
|
|
269a64cabb | ||
|
406e5187a8
|
|||
|
9bdd08d8dd
|
|||
|
d737232dcf
|
|||
|
c9d751479e
|
|||
|
a2c2bfe585
|
|||
|
c7f9da0dee
|
|||
|
|
a243cda1df | ||
|
|
7b238f32fd | ||
|
313af28d7f
|
|||
|
c64e1e208c
|
|||
|
c9b07a9a2a
|
|||
| 55c0e355f1 | |||
| be414891ec | |||
| 787876ab6a | |||
|
8578cde620
|
|||
|
14d55d45a8
|
|||
|
724391584e
|
|||
| 3a5e45808a | |||
|
488055955c
|
|||
|
|
313ebc64cc | ||
|
|
1ed8b1d0c1 | ||
| 4af816d931 | |||
| 1c058a4323 | |||
| 461ed1fcda | |||
|
5363afa558
|
|||
|
f0d2737da8
|
|||
|
1f2f80aa3e
|
|||
|
240a872e65
|
|||
| c1ec6f0849 | |||
| ab42686d4d | |||
|
c9727e92b8
|
|||
|
9b8768061d
|
|||
|
0949f0da54
|
|||
|
215ca705ac
|
|||
|
03457af04a
|
|||
|
73c6a1febf
|
|||
|
ba8d30bcde
|
|||
|
8449658b47
|
|||
|
c7f417234e
|
|||
|
6c847ee1e1
|
|||
|
18ad4d376e
|
|||
|
c4d5ba5c9d
|
|||
|
1069669049
|
|||
|
aa648fec62
|
|||
|
541900673a
|
|||
|
265502ffd0
|
|||
|
3bd79350d1
|
|||
|
5294d1fb23
|
|||
|
ec1269dcf1
|
|||
|
edb0a25f34
|
|||
|
7cd10118cc
|
|||
|
fcddc8f345
|
@@ -14,13 +14,13 @@ The backend of the Solar Network is written in Go and is a microservices app. Th
|
|||||||
|
|
||||||
## Commit Messages
|
## 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
|
All the commit message should follow `:[gitmoji]: <commit message>` syntax
|
||||||
|
|
||||||
## Translations & Localization
|
## 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
|
## 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
|
## 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!
|
We appreciate every single commit you contributed. Let's work together and create a better Solar Network!
|
||||||
|
|
||||||
|
|||||||
@@ -75,3 +75,4 @@ dependencies {
|
|||||||
flutter {
|
flutter {
|
||||||
source = "../.."
|
source = "../.."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,12 @@
|
|||||||
<data android:scheme="http" android:host="solian.app" />
|
<data android:scheme="http" android:host="solian.app" />
|
||||||
<data android:scheme="https" />
|
<data android:scheme="https" />
|
||||||
</intent-filter>
|
</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 -->
|
<!-- Share Intent Filters -->
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
1079
assets/i18n/es-ES.json
Normal file
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
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
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
1079
assets/i18n/zh-OG.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -116,7 +116,7 @@
|
|||||||
},
|
},
|
||||||
"postHasAttachments": {
|
"postHasAttachments": {
|
||||||
"one": "{} 個附件",
|
"one": "{} 個附件",
|
||||||
"other": "{}個附件"
|
"other": "{} 個附件"
|
||||||
},
|
},
|
||||||
"edited": "已編輯",
|
"edited": "已編輯",
|
||||||
"addVideo": "添加視頻",
|
"addVideo": "添加視頻",
|
||||||
@@ -303,8 +303,7 @@
|
|||||||
"notifications": "通知",
|
"notifications": "通知",
|
||||||
"posts": "帖子",
|
"posts": "帖子",
|
||||||
"settingsBackgroundImage": "背景圖片",
|
"settingsBackgroundImage": "背景圖片",
|
||||||
"settingsBackgroundImageEnable": "顯示背景圖片",
|
"settingsBackgroundImageClear": "清除背景圖片",
|
||||||
"settingsBackgroundImageClear": "清除背景圖片",
|
|
||||||
"settingsBackgroundGenerateColor": "從背景圖像生成主題色",
|
"settingsBackgroundGenerateColor": "從背景圖像生成主題色",
|
||||||
"messageNone": "沒有內容可顯示",
|
"messageNone": "沒有內容可顯示",
|
||||||
"unreadMessages": {
|
"unreadMessages": {
|
||||||
@@ -315,8 +314,6 @@
|
|||||||
"settingsRealmCompactView": "緊湊領域視圖",
|
"settingsRealmCompactView": "緊湊領域視圖",
|
||||||
"settingsMixedFeed": "混合動態",
|
"settingsMixedFeed": "混合動態",
|
||||||
"settingsAutoTranslate": "自動翻譯",
|
"settingsAutoTranslate": "自動翻譯",
|
||||||
"settingsDataSavingMode": "低數據模式",
|
|
||||||
"dataSavingHint": "低數據模式",
|
|
||||||
"settingsHideBottomNav": "隱藏底部導航",
|
"settingsHideBottomNav": "隱藏底部導航",
|
||||||
"settingsSoundEffects": "音效",
|
"settingsSoundEffects": "音效",
|
||||||
"settingsAprilFoolFeatures": "愚人節功能",
|
"settingsAprilFoolFeatures": "愚人節功能",
|
||||||
@@ -671,7 +668,6 @@
|
|||||||
"publisherFeatureDevelopDescription": "為你的開發者解鎖包括應用套件,API 及更多開發功能。",
|
"publisherFeatureDevelopDescription": "為你的開發者解鎖包括應用套件,API 及更多開發功能。",
|
||||||
"publisherFeatureDevelopHint": "目前該功能還在開發中,你需要邀請才可解鎖。",
|
"publisherFeatureDevelopHint": "目前該功能還在開發中,你需要邀請才可解鎖。",
|
||||||
"learnMore": "瞭解更多",
|
"learnMore": "瞭解更多",
|
||||||
"discoverWebArticles": "來自站外的文章",
|
|
||||||
"webArticlesStand": "文章亭",
|
"webArticlesStand": "文章亭",
|
||||||
"about": "關於",
|
"about": "關於",
|
||||||
"somethingWentWrong": "發生了一些錯誤",
|
"somethingWentWrong": "發生了一些錯誤",
|
||||||
@@ -694,8 +690,6 @@
|
|||||||
"sharePostPhoto": "通過圖片分享帖子",
|
"sharePostPhoto": "通過圖片分享帖子",
|
||||||
"wouldYouLikeToNavigateToChat": "你想要前往聊天頁面嗎?",
|
"wouldYouLikeToNavigateToChat": "你想要前往聊天頁面嗎?",
|
||||||
"abuseReports": "舉報",
|
"abuseReports": "舉報",
|
||||||
"discoverRealms": "發現領域",
|
|
||||||
"discoverPublishers": "發現發佈者",
|
|
||||||
"membershipCancel": "取消會員訂閱",
|
"membershipCancel": "取消會員訂閱",
|
||||||
"membershipCancelConfirm": "你確定要取消會員訂閱嗎?",
|
"membershipCancelConfirm": "你確定要取消會員訂閱嗎?",
|
||||||
"membershipCancelHint": "你確定要取消會員訂閱嗎?你將不會再次被扣費。你的會員資格將在當前計費週期結束前保持有效。並且你將無法重新訂閱,直到當前訂閱結束。",
|
"membershipCancelHint": "你確定要取消會員訂閱嗎?你將不會再次被扣費。你的會員資格將在當前計費週期結束前保持有效。並且你將無法重新訂閱,直到當前訂閱結束。",
|
||||||
@@ -815,6 +809,159 @@
|
|||||||
"one": "+{} 個文件被摺疊",
|
"one": "+{} 個文件被摺疊",
|
||||||
"other": "+{} 個文件被摺疊"
|
"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": "應用程式詳情",
|
"appDetails": "應用程式詳情",
|
||||||
"secrets": "密鑰",
|
"secrets": "密鑰",
|
||||||
"appNotFound": "找不到應用程式。",
|
"appNotFound": "找不到應用程式。",
|
||||||
@@ -826,5 +973,109 @@
|
|||||||
"newSecretGenerated": "已產生新密鑰",
|
"newSecretGenerated": "已產生新密鑰",
|
||||||
"copySecretHint": "請複製此密鑰並將其存放在安全的地方。您將無法再次看到它。",
|
"copySecretHint": "請複製此密鑰並將其存放在安全的地方。您將無法再次看到它。",
|
||||||
"expiresIn": "過期時間(秒)",
|
"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": "發佈帖子"
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
assets/images/stickers/angry.png
Normal file
BIN
assets/images/stickers/angry.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 MiB |
BIN
assets/images/stickers/clap.png
Normal file
BIN
assets/images/stickers/clap.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 MiB |
BIN
assets/images/stickers/confuse.png
Normal file
BIN
assets/images/stickers/confuse.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 668 KiB |
BIN
assets/images/stickers/party.png
Normal file
BIN
assets/images/stickers/party.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
BIN
assets/images/stickers/pray.png
Normal file
BIN
assets/images/stickers/pray.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 666 KiB |
BIN
assets/images/stickers/thumb_up.png
Normal file
BIN
assets/images/stickers/thumb_up.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 623 KiB |
@@ -5,3 +5,7 @@ targets:
|
|||||||
options:
|
options:
|
||||||
explicit_to_json: true
|
explicit_to_json: true
|
||||||
field_rename: snake
|
field_rename: snake
|
||||||
|
drift_dev:
|
||||||
|
options:
|
||||||
|
databases:
|
||||||
|
app_database: lib/database/drift_db.dart
|
||||||
|
|||||||
1
drift_schemas/app_database/drift_schema_v6.json
Normal file
1
drift_schemas/app_database/drift_schema_v6.json
Normal file
File diff suppressed because one or more lines are too long
181
ios/Podfile.lock
181
ios/Podfile.lock
@@ -1,6 +1,6 @@
|
|||||||
PODS:
|
PODS:
|
||||||
- Alamofire (5.10.2)
|
- Alamofire (5.10.2)
|
||||||
- connectivity_plus (0.0.1):
|
- app_links (6.4.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- croppy (0.0.1):
|
- croppy (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
@@ -42,83 +42,83 @@ PODS:
|
|||||||
- Flutter
|
- Flutter
|
||||||
- file_saver (0.0.1):
|
- file_saver (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- Firebase/CoreOnly (12.2.0):
|
- Firebase/CoreOnly (12.4.0):
|
||||||
- FirebaseCore (~> 12.2.0)
|
- FirebaseCore (~> 12.4.0)
|
||||||
- Firebase/Crashlytics (12.2.0):
|
- Firebase/Crashlytics (12.4.0):
|
||||||
- Firebase/CoreOnly
|
- Firebase/CoreOnly
|
||||||
- FirebaseCrashlytics (~> 12.2.0)
|
- FirebaseCrashlytics (~> 12.4.0)
|
||||||
- Firebase/Messaging (12.2.0):
|
- Firebase/Messaging (12.4.0):
|
||||||
- Firebase/CoreOnly
|
- Firebase/CoreOnly
|
||||||
- FirebaseMessaging (~> 12.2.0)
|
- FirebaseMessaging (~> 12.4.0)
|
||||||
- firebase_analytics (12.0.1):
|
- firebase_analytics (12.0.3):
|
||||||
- firebase_core
|
- firebase_core
|
||||||
- FirebaseAnalytics (= 12.2.0)
|
- FirebaseAnalytics (= 12.4.0)
|
||||||
- Flutter
|
- Flutter
|
||||||
- firebase_core (4.1.0):
|
- firebase_core (4.2.0):
|
||||||
- Firebase/CoreOnly (= 12.2.0)
|
- Firebase/CoreOnly (= 12.4.0)
|
||||||
- Flutter
|
- Flutter
|
||||||
- firebase_crashlytics (5.0.1):
|
- firebase_crashlytics (5.0.3):
|
||||||
- Firebase/Crashlytics (= 12.2.0)
|
- Firebase/Crashlytics (= 12.4.0)
|
||||||
- firebase_core
|
- firebase_core
|
||||||
- Flutter
|
- Flutter
|
||||||
- firebase_messaging (16.0.1):
|
- firebase_messaging (16.0.3):
|
||||||
- Firebase/Messaging (= 12.2.0)
|
- Firebase/Messaging (= 12.4.0)
|
||||||
- firebase_core
|
- firebase_core
|
||||||
- Flutter
|
- Flutter
|
||||||
- FirebaseAnalytics (12.2.0):
|
- FirebaseAnalytics (12.4.0):
|
||||||
- FirebaseAnalytics/Default (= 12.2.0)
|
- FirebaseAnalytics/Default (= 12.4.0)
|
||||||
- FirebaseCore (~> 12.2.0)
|
- FirebaseCore (~> 12.4.0)
|
||||||
- FirebaseInstallations (~> 12.2.0)
|
- FirebaseInstallations (~> 12.4.0)
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
||||||
- GoogleUtilities/MethodSwizzler (~> 8.1)
|
- GoogleUtilities/MethodSwizzler (~> 8.1)
|
||||||
- GoogleUtilities/Network (~> 8.1)
|
- GoogleUtilities/Network (~> 8.1)
|
||||||
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
||||||
- nanopb (~> 3.30910.0)
|
- nanopb (~> 3.30910.0)
|
||||||
- FirebaseAnalytics/Default (12.2.0):
|
- FirebaseAnalytics/Default (12.4.0):
|
||||||
- FirebaseCore (~> 12.2.0)
|
- FirebaseCore (~> 12.4.0)
|
||||||
- FirebaseInstallations (~> 12.2.0)
|
- FirebaseInstallations (~> 12.4.0)
|
||||||
- GoogleAppMeasurement/Default (= 12.2.0)
|
- GoogleAppMeasurement/Default (= 12.4.0)
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
||||||
- GoogleUtilities/MethodSwizzler (~> 8.1)
|
- GoogleUtilities/MethodSwizzler (~> 8.1)
|
||||||
- GoogleUtilities/Network (~> 8.1)
|
- GoogleUtilities/Network (~> 8.1)
|
||||||
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
||||||
- nanopb (~> 3.30910.0)
|
- nanopb (~> 3.30910.0)
|
||||||
- FirebaseCore (12.2.0):
|
- FirebaseCore (12.4.0):
|
||||||
- FirebaseCoreInternal (~> 12.2.0)
|
- FirebaseCoreInternal (~> 12.4.0)
|
||||||
- GoogleUtilities/Environment (~> 8.1)
|
- GoogleUtilities/Environment (~> 8.1)
|
||||||
- GoogleUtilities/Logger (~> 8.1)
|
- GoogleUtilities/Logger (~> 8.1)
|
||||||
- FirebaseCoreExtension (12.2.0):
|
- FirebaseCoreExtension (12.4.0):
|
||||||
- FirebaseCore (~> 12.2.0)
|
- FirebaseCore (~> 12.4.0)
|
||||||
- FirebaseCoreInternal (12.2.0):
|
- FirebaseCoreInternal (12.4.0):
|
||||||
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
||||||
- FirebaseCrashlytics (12.2.0):
|
- FirebaseCrashlytics (12.4.0):
|
||||||
- FirebaseCore (~> 12.2.0)
|
- FirebaseCore (~> 12.4.0)
|
||||||
- FirebaseInstallations (~> 12.2.0)
|
- FirebaseInstallations (~> 12.4.0)
|
||||||
- FirebaseRemoteConfigInterop (~> 12.2.0)
|
- FirebaseRemoteConfigInterop (~> 12.4.0)
|
||||||
- FirebaseSessions (~> 12.2.0)
|
- FirebaseSessions (~> 12.4.0)
|
||||||
- GoogleDataTransport (~> 10.1)
|
- GoogleDataTransport (~> 10.1)
|
||||||
- GoogleUtilities/Environment (~> 8.1)
|
- GoogleUtilities/Environment (~> 8.1)
|
||||||
- nanopb (~> 3.30910.0)
|
- nanopb (~> 3.30910.0)
|
||||||
- PromisesObjC (~> 2.4)
|
- PromisesObjC (~> 2.4)
|
||||||
- FirebaseInstallations (12.2.0):
|
- FirebaseInstallations (12.4.0):
|
||||||
- FirebaseCore (~> 12.2.0)
|
- FirebaseCore (~> 12.4.0)
|
||||||
- GoogleUtilities/Environment (~> 8.1)
|
- GoogleUtilities/Environment (~> 8.1)
|
||||||
- GoogleUtilities/UserDefaults (~> 8.1)
|
- GoogleUtilities/UserDefaults (~> 8.1)
|
||||||
- PromisesObjC (~> 2.4)
|
- PromisesObjC (~> 2.4)
|
||||||
- FirebaseMessaging (12.2.0):
|
- FirebaseMessaging (12.4.0):
|
||||||
- FirebaseCore (~> 12.2.0)
|
- FirebaseCore (~> 12.4.0)
|
||||||
- FirebaseInstallations (~> 12.2.0)
|
- FirebaseInstallations (~> 12.4.0)
|
||||||
- GoogleDataTransport (~> 10.1)
|
- GoogleDataTransport (~> 10.1)
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
||||||
- GoogleUtilities/Environment (~> 8.1)
|
- GoogleUtilities/Environment (~> 8.1)
|
||||||
- GoogleUtilities/Reachability (~> 8.1)
|
- GoogleUtilities/Reachability (~> 8.1)
|
||||||
- GoogleUtilities/UserDefaults (~> 8.1)
|
- GoogleUtilities/UserDefaults (~> 8.1)
|
||||||
- nanopb (~> 3.30910.0)
|
- nanopb (~> 3.30910.0)
|
||||||
- FirebaseRemoteConfigInterop (12.2.0)
|
- FirebaseRemoteConfigInterop (12.4.0)
|
||||||
- FirebaseSessions (12.2.0):
|
- FirebaseSessions (12.4.0):
|
||||||
- FirebaseCore (~> 12.2.0)
|
- FirebaseCore (~> 12.4.0)
|
||||||
- FirebaseCoreExtension (~> 12.2.0)
|
- FirebaseCoreExtension (~> 12.4.0)
|
||||||
- FirebaseInstallations (~> 12.2.0)
|
- FirebaseInstallations (~> 12.4.0)
|
||||||
- GoogleDataTransport (~> 10.1)
|
- GoogleDataTransport (~> 10.1)
|
||||||
- GoogleUtilities/Environment (~> 8.1)
|
- GoogleUtilities/Environment (~> 8.1)
|
||||||
- GoogleUtilities/UserDefaults (~> 8.1)
|
- GoogleUtilities/UserDefaults (~> 8.1)
|
||||||
@@ -149,33 +149,34 @@ PODS:
|
|||||||
- flutter_udid (0.0.1):
|
- flutter_udid (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- SAMKeychain
|
- SAMKeychain
|
||||||
- flutter_webrtc (1.1.0):
|
- flutter_webrtc (1.2.0):
|
||||||
- Flutter
|
- Flutter
|
||||||
- WebRTC-SDK (= 137.7151.03)
|
- WebRTC-SDK (= 137.7151.04)
|
||||||
- gal (1.0.0):
|
- gal (1.0.0):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- GoogleAdsOnDeviceConversion (2.3.0):
|
- GoogleAdsOnDeviceConversion (3.1.0):
|
||||||
|
- GoogleUtilities/Environment (~> 8.1)
|
||||||
- GoogleUtilities/Logger (~> 8.1)
|
- GoogleUtilities/Logger (~> 8.1)
|
||||||
- GoogleUtilities/Network (~> 8.1)
|
- GoogleUtilities/Network (~> 8.1)
|
||||||
- nanopb (~> 3.30910.0)
|
- nanopb (~> 3.30910.0)
|
||||||
- GoogleAppMeasurement/Core (12.2.0):
|
- GoogleAppMeasurement/Core (12.4.0):
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
||||||
- GoogleUtilities/MethodSwizzler (~> 8.1)
|
- GoogleUtilities/MethodSwizzler (~> 8.1)
|
||||||
- GoogleUtilities/Network (~> 8.1)
|
- GoogleUtilities/Network (~> 8.1)
|
||||||
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
||||||
- nanopb (~> 3.30910.0)
|
- nanopb (~> 3.30910.0)
|
||||||
- GoogleAppMeasurement/Default (12.2.0):
|
- GoogleAppMeasurement/Default (12.4.0):
|
||||||
- GoogleAdsOnDeviceConversion (= 2.3.0)
|
- GoogleAdsOnDeviceConversion (~> 3.1.0)
|
||||||
- GoogleAppMeasurement/Core (= 12.2.0)
|
- GoogleAppMeasurement/Core (= 12.4.0)
|
||||||
- GoogleAppMeasurement/IdentitySupport (= 12.2.0)
|
- GoogleAppMeasurement/IdentitySupport (= 12.4.0)
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
||||||
- GoogleUtilities/MethodSwizzler (~> 8.1)
|
- GoogleUtilities/MethodSwizzler (~> 8.1)
|
||||||
- GoogleUtilities/Network (~> 8.1)
|
- GoogleUtilities/Network (~> 8.1)
|
||||||
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
- "GoogleUtilities/NSData+zlib (~> 8.1)"
|
||||||
- nanopb (~> 3.30910.0)
|
- nanopb (~> 3.30910.0)
|
||||||
- GoogleAppMeasurement/IdentitySupport (12.2.0):
|
- GoogleAppMeasurement/IdentitySupport (12.4.0):
|
||||||
- GoogleAppMeasurement/Core (= 12.2.0)
|
- GoogleAppMeasurement/Core (= 12.4.0)
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
|
||||||
- GoogleUtilities/MethodSwizzler (~> 8.1)
|
- GoogleUtilities/MethodSwizzler (~> 8.1)
|
||||||
- GoogleUtilities/Network (~> 8.1)
|
- GoogleUtilities/Network (~> 8.1)
|
||||||
@@ -215,11 +216,7 @@ PODS:
|
|||||||
- Flutter
|
- Flutter
|
||||||
- irondash_engine_context (0.0.1):
|
- irondash_engine_context (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- Kingfisher (8.5.0)
|
- Kingfisher (8.6.0)
|
||||||
- livekit_client (2.5.0):
|
|
||||||
- Flutter
|
|
||||||
- flutter_webrtc
|
|
||||||
- WebRTC-SDK (= 137.7151.03)
|
|
||||||
- local_auth_darwin (0.0.1):
|
- local_auth_darwin (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
@@ -252,9 +249,9 @@ PODS:
|
|||||||
- record_ios (1.1.0):
|
- record_ios (1.1.0):
|
||||||
- Flutter
|
- Flutter
|
||||||
- SAMKeychain (1.5.3)
|
- SAMKeychain (1.5.3)
|
||||||
- SDWebImage (5.21.2):
|
- SDWebImage (5.21.3):
|
||||||
- SDWebImage/Core (= 5.21.2)
|
- SDWebImage/Core (= 5.21.3)
|
||||||
- SDWebImage/Core (5.21.2)
|
- SDWebImage/Core (5.21.3)
|
||||||
- share_plus (0.0.1):
|
- share_plus (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- shared_preferences_foundation (0.0.1):
|
- shared_preferences_foundation (0.0.1):
|
||||||
@@ -293,17 +290,19 @@ PODS:
|
|||||||
- super_native_extensions (0.0.1):
|
- super_native_extensions (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- SwiftyGif (5.4.5)
|
- SwiftyGif (5.4.5)
|
||||||
|
- syncfusion_flutter_pdfviewer (0.0.1):
|
||||||
|
- Flutter
|
||||||
- url_launcher_ios (0.0.1):
|
- url_launcher_ios (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- volume_controller (0.0.1):
|
- volume_controller (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- wakelock_plus (0.0.1):
|
- wakelock_plus (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- WebRTC-SDK (137.7151.03)
|
- WebRTC-SDK (137.7151.04)
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- Alamofire
|
- Alamofire
|
||||||
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
|
- app_links (from `.symlinks/plugins/app_links/ios`)
|
||||||
- croppy (from `.symlinks/plugins/croppy/ios`)
|
- croppy (from `.symlinks/plugins/croppy/ios`)
|
||||||
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
||||||
- file_picker (from `.symlinks/plugins/file_picker/ios`)
|
- file_picker (from `.symlinks/plugins/file_picker/ios`)
|
||||||
@@ -327,7 +326,6 @@ DEPENDENCIES:
|
|||||||
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
|
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
|
||||||
- irondash_engine_context (from `.symlinks/plugins/irondash_engine_context/ios`)
|
- irondash_engine_context (from `.symlinks/plugins/irondash_engine_context/ios`)
|
||||||
- Kingfisher (~> 8.0)
|
- Kingfisher (~> 8.0)
|
||||||
- livekit_client (from `.symlinks/plugins/livekit_client/ios`)
|
|
||||||
- local_auth_darwin (from `.symlinks/plugins/local_auth_darwin/darwin`)
|
- local_auth_darwin (from `.symlinks/plugins/local_auth_darwin/darwin`)
|
||||||
- media_kit_libs_ios_video (from `.symlinks/plugins/media_kit_libs_ios_video/ios`)
|
- media_kit_libs_ios_video (from `.symlinks/plugins/media_kit_libs_ios_video/ios`)
|
||||||
- media_kit_video (from `.symlinks/plugins/media_kit_video/ios`)
|
- media_kit_video (from `.symlinks/plugins/media_kit_video/ios`)
|
||||||
@@ -344,6 +342,7 @@ DEPENDENCIES:
|
|||||||
- sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
|
- sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
|
||||||
- sqlite3_flutter_libs (from `.symlinks/plugins/sqlite3_flutter_libs/darwin`)
|
- sqlite3_flutter_libs (from `.symlinks/plugins/sqlite3_flutter_libs/darwin`)
|
||||||
- super_native_extensions (from `.symlinks/plugins/super_native_extensions/ios`)
|
- 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`)
|
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||||
- volume_controller (from `.symlinks/plugins/volume_controller/ios`)
|
- volume_controller (from `.symlinks/plugins/volume_controller/ios`)
|
||||||
- wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
|
- wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
|
||||||
@@ -379,8 +378,8 @@ SPEC REPOS:
|
|||||||
- WebRTC-SDK
|
- WebRTC-SDK
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
connectivity_plus:
|
app_links:
|
||||||
:path: ".symlinks/plugins/connectivity_plus/ios"
|
:path: ".symlinks/plugins/app_links/ios"
|
||||||
croppy:
|
croppy:
|
||||||
:path: ".symlinks/plugins/croppy/ios"
|
:path: ".symlinks/plugins/croppy/ios"
|
||||||
device_info_plus:
|
device_info_plus:
|
||||||
@@ -425,8 +424,6 @@ EXTERNAL SOURCES:
|
|||||||
:path: ".symlinks/plugins/image_picker_ios/ios"
|
:path: ".symlinks/plugins/image_picker_ios/ios"
|
||||||
irondash_engine_context:
|
irondash_engine_context:
|
||||||
:path: ".symlinks/plugins/irondash_engine_context/ios"
|
:path: ".symlinks/plugins/irondash_engine_context/ios"
|
||||||
livekit_client:
|
|
||||||
:path: ".symlinks/plugins/livekit_client/ios"
|
|
||||||
local_auth_darwin:
|
local_auth_darwin:
|
||||||
:path: ".symlinks/plugins/local_auth_darwin/darwin"
|
:path: ".symlinks/plugins/local_auth_darwin/darwin"
|
||||||
media_kit_libs_ios_video:
|
media_kit_libs_ios_video:
|
||||||
@@ -459,6 +456,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: ".symlinks/plugins/sqlite3_flutter_libs/darwin"
|
:path: ".symlinks/plugins/sqlite3_flutter_libs/darwin"
|
||||||
super_native_extensions:
|
super_native_extensions:
|
||||||
:path: ".symlinks/plugins/super_native_extensions/ios"
|
:path: ".symlinks/plugins/super_native_extensions/ios"
|
||||||
|
syncfusion_flutter_pdfviewer:
|
||||||
|
:path: ".symlinks/plugins/syncfusion_flutter_pdfviewer/ios"
|
||||||
url_launcher_ios:
|
url_launcher_ios:
|
||||||
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
||||||
volume_controller:
|
volume_controller:
|
||||||
@@ -468,27 +467,27 @@ EXTERNAL SOURCES:
|
|||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
Alamofire: 7193b3b92c74a07f85569e1a6c4f4237291e7496
|
Alamofire: 7193b3b92c74a07f85569e1a6c4f4237291e7496
|
||||||
connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd
|
app_links: 3dbc685f76b1693c66a6d9dd1e9ab6f73d97dc0a
|
||||||
croppy: 979e8ddc254f4642bffe7d52dc7193354b27ba30
|
croppy: 979e8ddc254f4642bffe7d52dc7193354b27ba30
|
||||||
device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe
|
device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe
|
||||||
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
|
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
|
||||||
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
|
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
|
||||||
file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be
|
file_picker: a0560bc09d61de87f12d246fc47d2119e6ef37be
|
||||||
file_saver: 6cdbcddd690cb02b0c1a0c225b37cd805c2bf8b6
|
file_saver: 6cdbcddd690cb02b0c1a0c225b37cd805c2bf8b6
|
||||||
Firebase: 26f6f8d460603af3df970ad505b16b15f5e2e9a1
|
Firebase: f07b15ae5a6ec0f93713e30b923d9970d144af3e
|
||||||
firebase_analytics: 111ff65791a430356bd6c7e4d7339537fc6a15ae
|
firebase_analytics: 1d024068b1d4707d5ba7a42a12976ddf3316d835
|
||||||
firebase_core: 3ff52146406557dddd01d570e807e203ec7e1302
|
firebase_core: 744984dbbed8b3036abf34f0b98d80f130a7e464
|
||||||
firebase_crashlytics: 3637078b718a52dc9fb4d64e37c969e86b87ff6f
|
firebase_crashlytics: f3a9a4338ab99b67042f64e9e22e1bf349cb44ed
|
||||||
firebase_messaging: 3dcc998dd98e1e54af75d0cccae8606eba43553c
|
firebase_messaging: 82c70650c426a0a14873e1acdb9ec2b443c4e8b4
|
||||||
FirebaseAnalytics: e04e23bc070e3014aa5cf4980f9df7ce5cd79ec8
|
FirebaseAnalytics: 0fc2b20091f0ddd21bf73397cf8f0eb5346dc24f
|
||||||
FirebaseCore: 311c48a147ad4a0ab7febbaed89e8025c67510cd
|
FirebaseCore: bb595f3114953664e3c1dc032f008a244147cfd3
|
||||||
FirebaseCoreExtension: 73af080c22a2f7b44cefa391dc08f7e4ee162cb5
|
FirebaseCoreExtension: 7e1f7118ee970e001a8013719fb90950ee5e0018
|
||||||
FirebaseCoreInternal: 56ea29f3dad2894f81b060f706f9d53509b6ed3b
|
FirebaseCoreInternal: d7f5a043c2cd01a08103ab586587c1468047bca6
|
||||||
FirebaseCrashlytics: f83cbf176d5c637ade108c0aacf1ccbd5ec499bf
|
FirebaseCrashlytics: a6ece278a837c7e88de2d9b5da0a3542f2342395
|
||||||
FirebaseInstallations: 3e884b01feabdf67582a80f3250425a00979b4ed
|
FirebaseInstallations: ae9f4902cb5bf1d0c5eaa31ec1f4e5495a0714e2
|
||||||
FirebaseMessaging: 43ec73bbfedd0c385a849bb91593ab4ad4b9e48e
|
FirebaseMessaging: d33971b7bb252745ea6cd31ab190d1a1df4b8ed5
|
||||||
FirebaseRemoteConfigInterop: 0896fd52ab72586a355c8f389ff85aaa9e5375e1
|
FirebaseRemoteConfigInterop: 1e31ec72b89c9924367c59bfb5ec9ab60d1d6766
|
||||||
FirebaseSessions: f4692789e770bec66ce17d772c0e9561c4f11737
|
FirebaseSessions: ba7c7a7ca8696a8d540eb3fe3800fbe98c79786d
|
||||||
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
|
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
|
||||||
flutter_app_update: 816fdb2e30e4832a7c45e3f108d391c42ef040a9
|
flutter_app_update: 816fdb2e30e4832a7c45e3f108d391c42ef040a9
|
||||||
flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
|
flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
|
||||||
@@ -499,17 +498,16 @@ SPEC CHECKSUMS:
|
|||||||
flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13
|
flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13
|
||||||
flutter_timezone: 7c838e17ffd4645d261e87037e5bebf6d38fe544
|
flutter_timezone: 7c838e17ffd4645d261e87037e5bebf6d38fe544
|
||||||
flutter_udid: f7c3884e6ec2951efe4f9de082257fc77c4d15e9
|
flutter_udid: f7c3884e6ec2951efe4f9de082257fc77c4d15e9
|
||||||
flutter_webrtc: b0b2e04411747142962164a1cfa43a1af9a0afac
|
flutter_webrtc: c3e21fc0dcd9d8eb246ae4d5256fcbeb2f5ecd22
|
||||||
gal: baecd024ebfd13c441269ca7404792a7152fde89
|
gal: baecd024ebfd13c441269ca7404792a7152fde89
|
||||||
GoogleAdsOnDeviceConversion: 9090c435cde08903e8dd1ba2c77fbec9e46d9afe
|
GoogleAdsOnDeviceConversion: e03a386840803ea7eef3fd22a061930142c039c1
|
||||||
GoogleAppMeasurement: 09f341dfa8527d1612a09cbfe809a242c0b737af
|
GoogleAppMeasurement: 1e718274b7e015cefd846ac1fcf7820c70dc017d
|
||||||
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
|
||||||
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
|
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
|
||||||
image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
|
image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
|
||||||
irondash_engine_context: 8e58ca8e0212ee9d1c7dc6a42121849986c88486
|
irondash_engine_context: 8e58ca8e0212ee9d1c7dc6a42121849986c88486
|
||||||
Kingfisher: ff0d31a1f07bdff6a1ebb3ba08b8e6e567b6500c
|
Kingfisher: 64278f126a815d0e2d391cdf71311b85882c4de0
|
||||||
livekit_client: f810c81bbbc229a84f60b09e66603ac4e93f7599
|
local_auth_darwin: c3ee6cce0a8d56be34c8ccb66ba31f7f180aaebb
|
||||||
local_auth_darwin: d2e8c53ef0c4f43c646462e3415432c4dab3ae19
|
|
||||||
media_kit_libs_ios_video: 5a18affdb97d1f5d466dc79988b13eff6c5e2854
|
media_kit_libs_ios_video: 5a18affdb97d1f5d466dc79988b13eff6c5e2854
|
||||||
media_kit_video: 1746e198cb697d1ffb734b1d05ec429d1fcd1474
|
media_kit_video: 1746e198cb697d1ffb734b1d05ec429d1fcd1474
|
||||||
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
|
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
|
||||||
@@ -524,7 +522,7 @@ SPEC CHECKSUMS:
|
|||||||
receive_sharing_intent: 222384f00ffe7e952bbfabaa9e3967cb87e5fe00
|
receive_sharing_intent: 222384f00ffe7e952bbfabaa9e3967cb87e5fe00
|
||||||
record_ios: f75fa1d57f840012775c0e93a38a7f3ceea1a374
|
record_ios: f75fa1d57f840012775c0e93a38a7f3ceea1a374
|
||||||
SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c
|
SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c
|
||||||
SDWebImage: 9f177d83116802728e122410fb25ad88f5c7608a
|
SDWebImage: 16309af6d214ba3f77a7c6f6fdda888cb313a50a
|
||||||
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
|
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
|
||||||
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
|
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
|
||||||
sign_in_with_apple: c5dcc141574c8c54d5ac99dd2163c0c72ad22418
|
sign_in_with_apple: c5dcc141574c8c54d5ac99dd2163c0c72ad22418
|
||||||
@@ -533,10 +531,11 @@ SPEC CHECKSUMS:
|
|||||||
sqlite3_flutter_libs: 83f8e9f5b6554077f1d93119fe20ebaa5f3a9ef1
|
sqlite3_flutter_libs: 83f8e9f5b6554077f1d93119fe20ebaa5f3a9ef1
|
||||||
super_native_extensions: b763c02dc3a8fd078389f410bf15149179020cb4
|
super_native_extensions: b763c02dc3a8fd078389f410bf15149179020cb4
|
||||||
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
|
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
|
||||||
|
syncfusion_flutter_pdfviewer: 90dc48305d2e33d4aa20681d1e98ddeda891bc14
|
||||||
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
|
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
|
||||||
volume_controller: 3657a1f65bedb98fa41ff7dc5793537919f31b12
|
volume_controller: 3657a1f65bedb98fa41ff7dc5793537919f31b12
|
||||||
wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556
|
wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556
|
||||||
WebRTC-SDK: 69d4e56b0b4b27d788e87bab9b9a1326ed05b1e3
|
WebRTC-SDK: 40d4f5ba05cadff14e4db5614aec402a633f007e
|
||||||
|
|
||||||
PODFILE CHECKSUM: c818292390b02fa379036ea099713a332bd7193f
|
PODFILE CHECKSUM: c818292390b02fa379036ea099713a332bd7193f
|
||||||
|
|
||||||
|
|||||||
@@ -566,7 +566,7 @@
|
|||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
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 */ = {
|
4815E0A19398E51078F4160D /* [CP] Check Pods Manifest.lock */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
@@ -883,6 +883,7 @@
|
|||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = dev.solsynth.solian;
|
PRODUCT_BUNDLE_IDENTIFIER = dev.solsynth.solian;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SWIFT_ENABLE_EXPLICIT_MODULES = "$(SWIFT_USE_INTEGRATED_DRIVER)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
@@ -1096,6 +1097,7 @@
|
|||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_ENABLE_EXPLICIT_MODULES = NO;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
@@ -1137,6 +1139,7 @@
|
|||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_ENABLE_EXPLICIT_MODULES = NO;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
};
|
};
|
||||||
@@ -1177,6 +1180,7 @@
|
|||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_ENABLE_EXPLICIT_MODULES = NO;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
};
|
};
|
||||||
@@ -1434,6 +1438,7 @@
|
|||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = dev.solsynth.solian;
|
PRODUCT_BUNDLE_IDENTIFIER = dev.solsynth.solian;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SWIFT_ENABLE_EXPLICIT_MODULES = "$(SWIFT_USE_INTEGRATED_DRIVER)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
@@ -1462,6 +1467,7 @@
|
|||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = dev.solsynth.solian;
|
PRODUCT_BUNDLE_IDENTIFIER = dev.solsynth.solian;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SWIFT_ENABLE_EXPLICIT_MODULES = "$(SWIFT_USE_INTEGRATED_DRIVER)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import UIKit
|
|||||||
UNUserNotificationCenter.current().delegate = notifyDelegate
|
UNUserNotificationCenter.current().delegate = notifyDelegate
|
||||||
|
|
||||||
let replyableMessageCategory = UNNotificationCategory(
|
let replyableMessageCategory = UNNotificationCategory(
|
||||||
identifier: "REPLYABLE_MESSAGE",
|
identifier: "CHAT_MESSAGE",
|
||||||
actions: [
|
actions: [
|
||||||
UNTextInputNotificationAction(
|
UNTextInputNotificationAction(
|
||||||
identifier: "reply_action",
|
identifier: "reply_action",
|
||||||
|
|||||||
@@ -36,6 +36,14 @@
|
|||||||
<string>ShareMedia-$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
<string>ShareMedia-$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleTypeRole</key>
|
||||||
|
<string>Viewer</string>
|
||||||
|
<key>CFBundleURLSchemes</key>
|
||||||
|
<array>
|
||||||
|
<string>solian</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ class NotificationService: UNNotificationServiceExtension {
|
|||||||
private func processNotification(request: UNNotificationRequest, content: UNMutableNotificationContent) throws {
|
private func processNotification(request: UNNotificationRequest, content: UNMutableNotificationContent) throws {
|
||||||
switch content.userInfo["type"] as? String {
|
switch content.userInfo["type"] as? String {
|
||||||
case "messages.new":
|
case "messages.new":
|
||||||
content.categoryIdentifier = "REPLYABLE_MESSAGE"
|
|
||||||
try handleMessagingNotification(request: request, content: content)
|
try handleMessagingNotification(request: request, content: content)
|
||||||
default:
|
default:
|
||||||
try handleDefaultNotification(content: content)
|
try handleDefaultNotification(content: content)
|
||||||
@@ -89,7 +88,12 @@ class NotificationService: UNNotificationServiceExtension {
|
|||||||
let intent = self.createMessageIntent(with: sender, meta: metaCopy, body: content.body)
|
let intent = self.createMessageIntent(with: sender, meta: metaCopy, body: content.body)
|
||||||
self.donateInteraction(for: intent)
|
self.donateInteraction(for: intent)
|
||||||
let updatedContent = try? request.content.updating(from: 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)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:drift/wasm.dart';
|
import 'package:drift/wasm.dart';
|
||||||
import 'package:island/database/drift_db.dart';
|
import 'package:island/database/drift_db.dart';
|
||||||
|
import 'package:island/talker.dart';
|
||||||
|
|
||||||
AppDatabase constructDb() {
|
AppDatabase constructDb() {
|
||||||
return AppDatabase(connectOnWeb());
|
return AppDatabase(connectOnWeb());
|
||||||
@@ -9,12 +10,17 @@ AppDatabase constructDb() {
|
|||||||
DatabaseConnection connectOnWeb() {
|
DatabaseConnection connectOnWeb() {
|
||||||
return DatabaseConnection.delayed(
|
return DatabaseConnection.delayed(
|
||||||
Future(() async {
|
Future(() async {
|
||||||
final result = await WasmDatabase.open(
|
try {
|
||||||
databaseName: 'solar_network_data',
|
final result = await WasmDatabase.open(
|
||||||
sqlite3Uri: Uri.parse('sqlite3.wasm'),
|
databaseName: 'solar_network_data',
|
||||||
driftWorkerUri: Uri.parse('drift_worker.dart.js'),
|
sqlite3Uri: Uri.parse('sqlite3.wasm'),
|
||||||
);
|
driftWorkerUri: Uri.parse('drift_worker.dart.js'),
|
||||||
return result.resolvedExecutor;
|
);
|
||||||
|
return result.resolvedExecutor;
|
||||||
|
} catch (e, stackTrace) {
|
||||||
|
talker.error('Failed to open WASM database...', e, stackTrace);
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,15 @@ import 'package:drift/drift.dart';
|
|||||||
|
|
||||||
class PostDrafts extends Table {
|
class PostDrafts extends Table {
|
||||||
TextColumn get id => text()();
|
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()();
|
DateTimeColumn get lastModified => dateTime()();
|
||||||
|
// Full post data stored as JSON for complete restoration
|
||||||
|
TextColumn get postData => text()();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Set<Column> get primaryKey => {id};
|
Set<Column> get primaryKey => {id};
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class AppDatabase extends _$AppDatabase {
|
|||||||
AppDatabase(super.e);
|
AppDatabase(super.e);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get schemaVersion => 4;
|
int get schemaVersion => 7;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
MigrationStrategy get migration => MigrationStrategy(
|
MigrationStrategy get migration => MigrationStrategy(
|
||||||
@@ -21,16 +21,97 @@ class AppDatabase extends _$AppDatabase {
|
|||||||
},
|
},
|
||||||
onUpgrade: (Migrator m, int from, int to) async {
|
onUpgrade: (Migrator m, int from, int to) async {
|
||||||
if (from < 2) {
|
if (from < 2) {
|
||||||
// Add isRead column with default value false
|
// Add isDeleted column with default value false
|
||||||
await m.addColumn(chatMessages, chatMessages.isRead);
|
await m.addColumn(chatMessages, chatMessages.isDeleted);
|
||||||
}
|
}
|
||||||
if (from < 4) {
|
if (from < 4) {
|
||||||
// Drop old draft tables if they exist
|
// Drop old draft tables if they exist
|
||||||
await m.createTable(postDrafts);
|
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
|
// Methods for chat messages
|
||||||
Future<List<ChatMessage>> getMessagesForRoom(
|
Future<List<ChatMessage>> getMessagesForRoom(
|
||||||
String roomId, {
|
String roomId, {
|
||||||
@@ -58,36 +139,40 @@ class AppDatabase extends _$AppDatabase {
|
|||||||
)).write(ChatMessagesCompanion(status: Value(status)));
|
)).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) {
|
Future<int> deleteMessage(String id) {
|
||||||
return (delete(chatMessages)..where((m) => m.id.equals(id))).go();
|
return (delete(chatMessages)..where((m) => m.id.equals(id))).go();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<int> getTotalMessagesForRoom(String roomId) {
|
Future<int> getTotalMessagesForRoom(String roomId) {
|
||||||
return (select(chatMessages)..where((m) => m.roomId.equals(roomId))).get().then((list) => list.length);
|
return (select(
|
||||||
|
chatMessages,
|
||||||
|
)..where((m) => m.roomId.equals(roomId))).get().then((list) => list.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<LocalChatMessage>> searchMessages(
|
Future<List<LocalChatMessage>> searchMessages(
|
||||||
String roomId,
|
String roomId,
|
||||||
String query,
|
String query, {
|
||||||
) async {
|
bool? withAttachments,
|
||||||
|
}) async {
|
||||||
var selectStatement = select(chatMessages)
|
var selectStatement = select(chatMessages)
|
||||||
..where((m) => m.roomId.equals(roomId));
|
..where((m) => m.roomId.equals(roomId));
|
||||||
|
|
||||||
if (query.isNotEmpty) {
|
if (query.isNotEmpty) {
|
||||||
|
final searchTerm = '%$query%';
|
||||||
selectStatement =
|
selectStatement =
|
||||||
selectStatement
|
selectStatement..where(
|
||||||
..where((m) => m.content.like('%${query.toLowerCase()}%'));
|
(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 =
|
final messages =
|
||||||
await (selectStatement
|
await (selectStatement
|
||||||
@@ -98,16 +183,26 @@ class AppDatabase extends _$AppDatabase {
|
|||||||
|
|
||||||
// Convert between Drift and model objects
|
// Convert between Drift and model objects
|
||||||
ChatMessagesCompanion messageToCompanion(LocalChatMessage message) {
|
ChatMessagesCompanion messageToCompanion(LocalChatMessage message) {
|
||||||
|
final remote = message.toRemoteMessage();
|
||||||
return ChatMessagesCompanion(
|
return ChatMessagesCompanion(
|
||||||
id: Value(message.id),
|
id: Value(message.id),
|
||||||
roomId: Value(message.roomId),
|
roomId: Value(message.roomId),
|
||||||
senderId: Value(message.senderId),
|
senderId: Value(message.senderId),
|
||||||
content: Value(message.toRemoteMessage().content),
|
content: Value(remote.content),
|
||||||
nonce: Value(message.nonce),
|
nonce: Value(message.nonce),
|
||||||
data: Value(jsonEncode(message.data)),
|
data: Value(jsonEncode(message.data)),
|
||||||
createdAt: Value(message.createdAt),
|
createdAt: Value(message.createdAt),
|
||||||
status: Value(message.status),
|
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),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +216,18 @@ class AppDatabase extends _$AppDatabase {
|
|||||||
createdAt: dbMessage.createdAt,
|
createdAt: dbMessage.createdAt,
|
||||||
status: dbMessage.status,
|
status: dbMessage.status,
|
||||||
nonce: dbMessage.nonce,
|
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,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,10 +235,31 @@ class AppDatabase extends _$AppDatabase {
|
|||||||
Future<List<SnPost>> getAllPostDrafts() async {
|
Future<List<SnPost>> getAllPostDrafts() async {
|
||||||
final drafts = await select(postDrafts).get();
|
final drafts = await select(postDrafts).get();
|
||||||
return drafts
|
return drafts
|
||||||
.map((draft) => SnPost.fromJson(jsonDecode(draft.post)))
|
.map((draft) => SnPost.fromJson(jsonDecode(draft.postData)))
|
||||||
.toList();
|
.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 {
|
Future<void> addPostDraft(PostDraftsCompanion entry) async {
|
||||||
await into(postDrafts).insert(entry, mode: InsertMode.replace);
|
await into(postDrafts).insert(entry, mode: InsertMode.replace);
|
||||||
}
|
}
|
||||||
@@ -144,4 +271,9 @@ class AppDatabase extends _$AppDatabase {
|
|||||||
Future<void> clearAllPostDrafts() async {
|
Future<void> clearAllPostDrafts() async {
|
||||||
await delete(postDrafts).go();
|
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
@@ -1,7 +1,41 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:island/models/chat.dart';
|
import 'package:island/models/chat.dart';
|
||||||
import 'package:island/models/file.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 {
|
class ChatMessages extends Table {
|
||||||
TextColumn get id => text()();
|
TextColumn get id => text()();
|
||||||
TextColumn get roomId => text()();
|
TextColumn get roomId => text()();
|
||||||
@@ -11,7 +45,24 @@ class ChatMessages extends Table {
|
|||||||
TextColumn get data => text()();
|
TextColumn get data => text()();
|
||||||
DateTimeColumn get createdAt => dateTime()();
|
DateTimeColumn get createdAt => dateTime()();
|
||||||
IntColumn get status => intEnum<MessageStatus>()();
|
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
|
@override
|
||||||
Set<Column> get primaryKey => {id};
|
Set<Column> get primaryKey => {id};
|
||||||
@@ -25,8 +76,19 @@ class LocalChatMessage {
|
|||||||
final DateTime createdAt;
|
final DateTime createdAt;
|
||||||
MessageStatus status;
|
MessageStatus status;
|
||||||
final String? nonce;
|
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;
|
List<UniversalFile>? localAttachments;
|
||||||
bool isRead;
|
|
||||||
|
|
||||||
LocalChatMessage({
|
LocalChatMessage({
|
||||||
required this.id,
|
required this.id,
|
||||||
@@ -36,8 +98,19 @@ class LocalChatMessage {
|
|||||||
required this.createdAt,
|
required this.createdAt,
|
||||||
required this.nonce,
|
required this.nonce,
|
||||||
required this.status,
|
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.localAttachments,
|
||||||
this.isRead = false,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
SnChatMessage toRemoteMessage() {
|
SnChatMessage toRemoteMessage() {
|
||||||
@@ -48,7 +121,6 @@ class LocalChatMessage {
|
|||||||
SnChatMessage message,
|
SnChatMessage message,
|
||||||
MessageStatus status, {
|
MessageStatus status, {
|
||||||
String? nonce,
|
String? nonce,
|
||||||
bool isRead = false,
|
|
||||||
}) {
|
}) {
|
||||||
return LocalChatMessage(
|
return LocalChatMessage(
|
||||||
id: message.id,
|
id: message.id,
|
||||||
@@ -58,7 +130,18 @@ class LocalChatMessage {
|
|||||||
createdAt: message.createdAt,
|
createdAt: message.createdAt,
|
||||||
status: status,
|
status: status,
|
||||||
nonce: nonce ?? message.nonce,
|
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,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
145
lib/main.dart
145
lib/main.dart
@@ -1,6 +1,4 @@
|
|||||||
import 'dart:developer';
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:croppy/croppy.dart';
|
import 'package:croppy/croppy.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart' hide TextDirection;
|
import 'package:easy_localization/easy_localization.dart' hide TextDirection;
|
||||||
import 'package:firebase_core/firebase_core.dart';
|
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:firebase_messaging/firebase_messaging.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:image_picker_android/image_picker_android.dart';
|
import 'package:image_picker_android/image_picker_android.dart';
|
||||||
|
import 'package:island/talker.dart';
|
||||||
import 'package:island/firebase_options.dart';
|
import 'package:island/firebase_options.dart';
|
||||||
import 'package:island/pods/config.dart';
|
import 'package:island/pods/config.dart';
|
||||||
import 'package:island/pods/network.dart';
|
import 'package:island/pods/network.dart';
|
||||||
import 'package:island/pods/theme.dart';
|
import 'package:island/pods/theme.dart';
|
||||||
import 'package:bitsdojo_window/bitsdojo_window.dart';
|
|
||||||
import 'package:island/pods/userinfo.dart';
|
import 'package:island/pods/userinfo.dart';
|
||||||
import 'package:island/pods/websocket.dart';
|
import 'package:island/pods/websocket.dart';
|
||||||
import 'package:island/route.dart';
|
import 'package:island/route.dart';
|
||||||
@@ -29,18 +26,21 @@ import 'package:relative_time/relative_time.dart';
|
|||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:image_picker_platform_interface/image_picker_platform_interface.dart';
|
import 'package:image_picker_platform_interface/image_picker_platform_interface.dart';
|
||||||
import 'package:flutter_native_splash/flutter_native_splash.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:url_launcher/url_launcher_string.dart';
|
||||||
|
import 'package:window_manager/window_manager.dart';
|
||||||
|
|
||||||
@pragma('vm:entry-point')
|
@pragma('vm:entry-point')
|
||||||
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
|
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
|
||||||
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
|
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
|
||||||
log('Handling a background message: ${message.messageId}');
|
talker.info('Handling a background message: ${message.messageId}');
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
final widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
|
final widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
|
||||||
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) {
|
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) {
|
||||||
log(
|
talker.info(
|
||||||
"[SplashScreen] Keeping the flash screen to loading other resources...",
|
"[SplashScreen] Keeping the flash screen to loading other resources...",
|
||||||
);
|
);
|
||||||
FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
|
FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
|
||||||
@@ -73,49 +73,71 @@ void main() async {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log("[SplashScreen] Firebase is ready!");
|
talker.info("[SplashScreen] Firebase is ready!");
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
showErrorAlert(err);
|
showErrorAlert(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
log("[SplashScreen] Loading timezone database...");
|
talker.info("[SplashScreen] Loading timezone database...");
|
||||||
await initializeTzdb();
|
await initializeTzdb();
|
||||||
log("[SplashScreen] Time zone database was loaded!");
|
talker.info("[SplashScreen] Time zone database was loaded!");
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log("[SplashScreen] Failed to load timezone database... $err");
|
talker.error("[SplashScreen] Failed to load timezone database... $err");
|
||||||
}
|
}
|
||||||
|
|
||||||
final prefs = await SharedPreferences.getInstance();
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
|
||||||
if (!kIsWeb && (Platform.isMacOS || Platform.isLinux || Platform.isWindows)) {
|
if (!kIsWeb && (Platform.isMacOS || Platform.isLinux || Platform.isWindows)) {
|
||||||
doWhenWindowReady(() {
|
await windowManager.ensureInitialized();
|
||||||
const defaultSize = Size(360, 640);
|
|
||||||
|
|
||||||
// Get saved window size from preferences
|
const defaultSize = Size(360, 640);
|
||||||
final savedSizeString = prefs.getString(kAppWindowSize);
|
|
||||||
Size initialSize = defaultSize;
|
|
||||||
|
|
||||||
if (savedSizeString != null) {
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WindowOptions windowOptions = WindowOptions(
|
||||||
|
size: initialSize,
|
||||||
|
center: true,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
skipTaskbar: false,
|
||||||
|
titleBarStyle: TitleBarStyle.hidden,
|
||||||
|
windowButtonVisibility: true,
|
||||||
|
);
|
||||||
|
windowManager.waitUntilReadyToShow(windowOptions, () async {
|
||||||
|
final env = Platform.environment;
|
||||||
|
final isWayland = env.containsKey('WAYLAND_DISPLAY');
|
||||||
|
|
||||||
|
if (isWayland) {
|
||||||
try {
|
try {
|
||||||
final parts = savedSizeString.split(',');
|
await windowManager.setAsFrameless();
|
||||||
if (parts.length == 2) {
|
|
||||||
final width = double.parse(parts[0]);
|
|
||||||
final height = double.parse(parts[1]);
|
|
||||||
initialSize = Size(width, height);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log("[SplashScreen] Failed to parse saved window size: $e");
|
debugPrint('[Wayland] setAsFrameless failed: $e');
|
||||||
initialSize = defaultSize;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
await windowManager.setMinimumSize(defaultSize);
|
||||||
appWindow.minSize = defaultSize;
|
await windowManager.show();
|
||||||
appWindow.size = initialSize;
|
await windowManager.focus();
|
||||||
appWindow.alignment = Alignment.center;
|
final opacity = prefs.getDouble(kAppWindowOpacity) ?? 1.0;
|
||||||
appWindow.show();
|
await windowManager.setOpacity(opacity);
|
||||||
log(
|
talker.info(
|
||||||
"[SplashScreen] Desktop window is ready with size: ${initialSize.width}x${initialSize.height}",
|
"[SplashScreen] Desktop window is ready with size: ${initialSize.width}x${initialSize.height}"
|
||||||
|
"${isWayland ? " (Wayland frameless fix applied)" : ""}",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -126,16 +148,27 @@ void main() async {
|
|||||||
if (imagePickerImplementation is ImagePickerAndroid) {
|
if (imagePickerImplementation is ImagePickerAndroid) {
|
||||||
imagePickerImplementation.useAndroidPhotoPicker = true;
|
imagePickerImplementation.useAndroidPhotoPicker = true;
|
||||||
}
|
}
|
||||||
log("[SplashScreen] Android image picker is ready!");
|
talker.info("[SplashScreen] Android image picker is ready!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) {
|
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) {
|
||||||
FlutterNativeSplash.remove();
|
FlutterNativeSplash.remove();
|
||||||
log("[SplashScreen] Now hiding the splash screen...");
|
talker.info("[SplashScreen] Now hiding the splash screen...");
|
||||||
}
|
}
|
||||||
|
|
||||||
runApp(
|
runApp(
|
||||||
ProviderScope(
|
ProviderScope(
|
||||||
|
observers: [
|
||||||
|
TalkerRiverpodObserver(
|
||||||
|
talker: talker,
|
||||||
|
settings: TalkerRiverpodLoggerSettings(
|
||||||
|
printProviderAdded: false,
|
||||||
|
printProviderDisposed: false,
|
||||||
|
printProviderUpdated: false,
|
||||||
|
printStateFullData: false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
overrides: [sharedPreferencesProvider.overrideWithValue(prefs)],
|
overrides: [sharedPreferencesProvider.overrideWithValue(prefs)],
|
||||||
child: Directionality(
|
child: Directionality(
|
||||||
textDirection: TextDirection.ltr,
|
textDirection: TextDirection.ltr,
|
||||||
@@ -144,6 +177,10 @@ void main() async {
|
|||||||
Locale('en', 'US'),
|
Locale('en', 'US'),
|
||||||
Locale('zh', 'CN'),
|
Locale('zh', 'CN'),
|
||||||
Locale('zh', 'TW'),
|
Locale('zh', 'TW'),
|
||||||
|
Locale('zh', 'OG'),
|
||||||
|
Locale('ja', 'JP'),
|
||||||
|
Locale('ko', 'KR'),
|
||||||
|
Locale('es', 'ES'),
|
||||||
],
|
],
|
||||||
path: 'assets/i18n',
|
path: 'assets/i18n',
|
||||||
fallbackLocale: Locale('en', 'US'),
|
fallbackLocale: Locale('en', 'US'),
|
||||||
@@ -165,6 +202,21 @@ class IslandApp extends HookConsumerWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final theme = ref.watch(themeProvider);
|
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) {
|
void handleMessage(RemoteMessage notification) {
|
||||||
if (notification.data['meta']?['action_uri'] != null) {
|
if (notification.data['meta']?['action_uri'] != null) {
|
||||||
@@ -181,7 +233,7 @@ class IslandApp extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() {
|
useEffect(() {
|
||||||
if (!kIsWeb && Platform.isLinux) {
|
if (!kIsWeb && (Platform.isLinux || Platform.isWindows)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,7 +253,9 @@ class IslandApp extends HookConsumerWidget {
|
|||||||
final onMessageSubscription = FirebaseMessaging.onMessage.listen((
|
final onMessageSubscription = FirebaseMessaging.onMessage.listen((
|
||||||
message,
|
message,
|
||||||
) {
|
) {
|
||||||
log('Foreground message received: ${message.messageId}');
|
talker.info(
|
||||||
|
'[Notification] foreground message received: ${message.messageId}',
|
||||||
|
);
|
||||||
handleMessage(message);
|
handleMessage(message);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -215,7 +269,7 @@ class IslandApp extends HookConsumerWidget {
|
|||||||
// Load userinfo
|
// Load userinfo
|
||||||
final userNotifier = ref.read(userInfoProvider.notifier);
|
final userNotifier = ref.read(userInfoProvider.notifier);
|
||||||
ref.listen(websocketStateProvider, (_, state) {
|
ref.listen(websocketStateProvider, (_, state) {
|
||||||
log('[WebSocket] $state');
|
talker.info('[WebSocket] $state');
|
||||||
});
|
});
|
||||||
Future(() {
|
Future(() {
|
||||||
userNotifier.fetchUser().then((_) {
|
userNotifier.fetchUser().then((_) {
|
||||||
@@ -235,9 +289,10 @@ class IslandApp extends HookConsumerWidget {
|
|||||||
final router = ref.watch(routerProvider);
|
final router = ref.watch(routerProvider);
|
||||||
|
|
||||||
return MaterialApp.router(
|
return MaterialApp.router(
|
||||||
theme: theme?.light,
|
color: Colors.transparent,
|
||||||
darkTheme: theme?.dark,
|
theme: theme.light,
|
||||||
themeMode: ThemeMode.system,
|
darkTheme: theme.dark,
|
||||||
|
themeMode: getThemeMode(),
|
||||||
routerConfig: router,
|
routerConfig: router,
|
||||||
supportedLocales: context.supportedLocales,
|
supportedLocales: context.supportedLocales,
|
||||||
scrollBehavior: AppScrollBehavior(),
|
scrollBehavior: AppScrollBehavior(),
|
||||||
@@ -252,9 +307,15 @@ class IslandApp extends HookConsumerWidget {
|
|||||||
key: globalOverlay,
|
key: globalOverlay,
|
||||||
initialEntries: [
|
initialEntries: [
|
||||||
OverlayEntry(
|
OverlayEntry(
|
||||||
builder:
|
builder: (_) {
|
||||||
(_) =>
|
return TalkerWrapper(
|
||||||
WindowScaffold(child: child ?? const SizedBox.shrink()),
|
talker: talker,
|
||||||
|
options: const TalkerWrapperOptions(enableErrorAlerts: true),
|
||||||
|
child: WindowScaffold(
|
||||||
|
child: child ?? const SizedBox.shrink(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -55,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
|
@freezed
|
||||||
sealed class SnAccountProfile with _$SnAccountProfile {
|
sealed class SnAccountProfile with _$SnAccountProfile {
|
||||||
const factory SnAccountProfile({
|
const factory SnAccountProfile({
|
||||||
@@ -79,6 +92,7 @@ sealed class SnAccountProfile with _$SnAccountProfile {
|
|||||||
required SnCloudFile? picture,
|
required SnCloudFile? picture,
|
||||||
required SnCloudFile? background,
|
required SnCloudFile? background,
|
||||||
required SnVerificationMark? verification,
|
required SnVerificationMark? verification,
|
||||||
|
UsernameColor? usernameColor,
|
||||||
required DateTime createdAt,
|
required DateTime createdAt,
|
||||||
required DateTime updatedAt,
|
required DateTime updatedAt,
|
||||||
required DateTime? deletedAt,
|
required DateTime? deletedAt,
|
||||||
@@ -98,6 +112,7 @@ sealed class SnAccountStatus with _$SnAccountStatus {
|
|||||||
required bool isNotDisturb,
|
required bool isNotDisturb,
|
||||||
required bool isCustomized,
|
required bool isCustomized,
|
||||||
@Default("") String label,
|
@Default("") String label,
|
||||||
|
required Map<String, dynamic>? meta,
|
||||||
required DateTime? clearedAt,
|
required DateTime? clearedAt,
|
||||||
required String accountId,
|
required String accountId,
|
||||||
required DateTime createdAt,
|
required DateTime createdAt,
|
||||||
|
|||||||
@@ -622,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
|
/// @nodoc
|
||||||
mixin _$SnAccountProfile {
|
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 socialCredits; int get socialCreditsLevel; 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
|
/// Create a copy of SnAccountProfile
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@@ -638,16 +912,16 @@ $SnAccountProfileCopyWith<SnAccountProfile> get copyWith => _$SnAccountProfileCo
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnAccountProfile&&(identical(other.id, id) || other.id == id)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.middleName, middleName) || other.middleName == middleName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.bio, bio) || other.bio == bio)&&(identical(other.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.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)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@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,socialCredits,socialCreditsLevel,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
|
@override
|
||||||
String toString() {
|
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, socialCredits: $socialCredits, socialCreditsLevel: $socialCreditsLevel, 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)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -658,11 +932,11 @@ abstract mixin class $SnAccountProfileCopyWith<$Res> {
|
|||||||
factory $SnAccountProfileCopyWith(SnAccountProfile value, $Res Function(SnAccountProfile) _then) = _$SnAccountProfileCopyWithImpl;
|
factory $SnAccountProfileCopyWith(SnAccountProfile value, $Res Function(SnAccountProfile) _then) = _$SnAccountProfileCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, String firstName, String middleName, String lastName, String bio, String 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, 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
|
/// @nodoc
|
||||||
@@ -675,7 +949,7 @@ class _$SnAccountProfileCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnAccountProfile
|
/// Create a copy of SnAccountProfile
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? firstName = 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? 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(
|
return _then(_self.copyWith(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,firstName: null == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable
|
as String,firstName: null == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -698,7 +972,8 @@ as int,levelingProgress: null == levelingProgress ? _self.levelingProgress : lev
|
|||||||
as double,picture: freezed == picture ? _self.picture : picture // ignore: cast_nullable_to_non_nullable
|
as double,picture: freezed == picture ? _self.picture : picture // ignore: cast_nullable_to_non_nullable
|
||||||
as SnCloudFile?,background: freezed == background ? _self.background : background // 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 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,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,
|
as DateTime?,
|
||||||
@@ -752,6 +1027,18 @@ $SnVerificationMarkCopyWith<$Res>? get verification {
|
|||||||
return $SnVerificationMarkCopyWith<$Res>(_self.verification!, (value) {
|
return $SnVerificationMarkCopyWith<$Res>(_self.verification!, (value) {
|
||||||
return _then(_self.copyWith(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));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -831,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 socialCredits, int socialCreditsLevel, 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) {
|
switch (_that) {
|
||||||
case _SnAccountProfile() when $default != null:
|
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.socialCredits,_that.socialCreditsLevel,_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();
|
return orElse();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -852,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 socialCredits, int socialCreditsLevel, 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) {
|
switch (_that) {
|
||||||
case _SnAccountProfile():
|
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.socialCredits,_that.socialCreditsLevel,_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`
|
/// A variant of `when` that fallback to returning `null`
|
||||||
///
|
///
|
||||||
@@ -869,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 socialCredits, int socialCreditsLevel, 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) {
|
switch (_that) {
|
||||||
case _SnAccountProfile() when $default != null:
|
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.socialCredits,_that.socialCreditsLevel,_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;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -884,7 +1171,7 @@ return $default(_that.id,_that.firstName,_that.middleName,_that.lastName,_that.b
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _SnAccountProfile implements SnAccountProfile {
|
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, this.socialCredits = 100, this.socialCreditsLevel = 0, 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);
|
factory _SnAccountProfile.fromJson(Map<String, dynamic> json) => _$SnAccountProfileFromJson(json);
|
||||||
|
|
||||||
@override final String id;
|
@override final String id;
|
||||||
@@ -914,6 +1201,7 @@ class _SnAccountProfile implements SnAccountProfile {
|
|||||||
@override final SnCloudFile? picture;
|
@override final SnCloudFile? picture;
|
||||||
@override final SnCloudFile? background;
|
@override final SnCloudFile? background;
|
||||||
@override final SnVerificationMark? verification;
|
@override final SnVerificationMark? verification;
|
||||||
|
@override final UsernameColor? usernameColor;
|
||||||
@override final DateTime createdAt;
|
@override final DateTime createdAt;
|
||||||
@override final DateTime updatedAt;
|
@override final DateTime updatedAt;
|
||||||
@override final DateTime? deletedAt;
|
@override final DateTime? deletedAt;
|
||||||
@@ -931,16 +1219,16 @@ Map<String, dynamic> toJson() {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnAccountProfile&&(identical(other.id, id) || other.id == id)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.middleName, middleName) || other.middleName == middleName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.bio, bio) || other.bio == bio)&&(identical(other.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.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)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@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,socialCredits,socialCreditsLevel,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
|
@override
|
||||||
String toString() {
|
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, socialCredits: $socialCredits, socialCreditsLevel: $socialCreditsLevel, 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)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -951,11 +1239,11 @@ abstract mixin class _$SnAccountProfileCopyWith<$Res> implements $SnAccountProfi
|
|||||||
factory _$SnAccountProfileCopyWith(_SnAccountProfile value, $Res Function(_SnAccountProfile) _then) = __$SnAccountProfileCopyWithImpl;
|
factory _$SnAccountProfileCopyWith(_SnAccountProfile value, $Res Function(_SnAccountProfile) _then) = __$SnAccountProfileCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, String firstName, String middleName, String lastName, String bio, String 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, 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
|
/// @nodoc
|
||||||
@@ -968,7 +1256,7 @@ class __$SnAccountProfileCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnAccountProfile
|
/// Create a copy of SnAccountProfile
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? firstName = 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? 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(
|
return _then(_SnAccountProfile(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,firstName: null == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable
|
as String,firstName: null == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -991,7 +1279,8 @@ as int,levelingProgress: null == levelingProgress ? _self.levelingProgress : lev
|
|||||||
as double,picture: freezed == picture ? _self.picture : picture // ignore: cast_nullable_to_non_nullable
|
as double,picture: freezed == picture ? _self.picture : picture // ignore: cast_nullable_to_non_nullable
|
||||||
as SnCloudFile?,background: freezed == background ? _self.background : background // 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 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,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,
|
as DateTime?,
|
||||||
@@ -1046,6 +1335,18 @@ $SnVerificationMarkCopyWith<$Res>? get verification {
|
|||||||
return $SnVerificationMarkCopyWith<$Res>(_self.verification!, (value) {
|
return $SnVerificationMarkCopyWith<$Res>(_self.verification!, (value) {
|
||||||
return _then(_self.copyWith(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));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1053,7 +1354,7 @@ $SnVerificationMarkCopyWith<$Res>? get verification {
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$SnAccountStatus {
|
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
|
/// Create a copy of SnAccountStatus
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@@ -1066,16 +1367,16 @@ $SnAccountStatusCopyWith<SnAccountStatus> get copyWith => _$SnAccountStatusCopyW
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
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)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@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
|
@override
|
||||||
String toString() {
|
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)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1086,7 +1387,7 @@ abstract mixin class $SnAccountStatusCopyWith<$Res> {
|
|||||||
factory $SnAccountStatusCopyWith(SnAccountStatus value, $Res Function(SnAccountStatus) _then) = _$SnAccountStatusCopyWithImpl;
|
factory $SnAccountStatusCopyWith(SnAccountStatus value, $Res Function(SnAccountStatus) _then) = _$SnAccountStatusCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$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
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -1103,7 +1404,7 @@ class _$SnAccountStatusCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnAccountStatus
|
/// Create a copy of SnAccountStatus
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? 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(
|
return _then(_self.copyWith(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,attitude: null == attitude ? _self.attitude : attitude // ignore: cast_nullable_to_non_nullable
|
as String,attitude: null == attitude ? _self.attitude : attitude // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -1112,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,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,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 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 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 String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -1199,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) {
|
switch (_that) {
|
||||||
case _SnAccountStatus() when $default != null:
|
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();
|
return orElse();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1220,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) {
|
switch (_that) {
|
||||||
case _SnAccountStatus():
|
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`
|
/// A variant of `when` that fallback to returning `null`
|
||||||
///
|
///
|
||||||
@@ -1237,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) {
|
switch (_that) {
|
||||||
case _SnAccountStatus() when $default != null:
|
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;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1252,7 +1554,7 @@ return $default(_that.id,_that.attitude,_that.isOnline,_that.isInvisible,_that.i
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _SnAccountStatus implements SnAccountStatus {
|
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);
|
factory _SnAccountStatus.fromJson(Map<String, dynamic> json) => _$SnAccountStatusFromJson(json);
|
||||||
|
|
||||||
@override final String id;
|
@override final String id;
|
||||||
@@ -1262,6 +1564,15 @@ class _SnAccountStatus implements SnAccountStatus {
|
|||||||
@override final bool isNotDisturb;
|
@override final bool isNotDisturb;
|
||||||
@override final bool isCustomized;
|
@override final bool isCustomized;
|
||||||
@override@JsonKey() final String label;
|
@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 DateTime? clearedAt;
|
||||||
@override final String accountId;
|
@override final String accountId;
|
||||||
@override final DateTime createdAt;
|
@override final DateTime createdAt;
|
||||||
@@ -1281,16 +1592,16 @@ Map<String, dynamic> toJson() {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
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)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@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
|
@override
|
||||||
String toString() {
|
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)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1301,7 +1612,7 @@ abstract mixin class _$SnAccountStatusCopyWith<$Res> implements $SnAccountStatus
|
|||||||
factory _$SnAccountStatusCopyWith(_SnAccountStatus value, $Res Function(_SnAccountStatus) _then) = __$SnAccountStatusCopyWithImpl;
|
factory _$SnAccountStatusCopyWith(_SnAccountStatus value, $Res Function(_SnAccountStatus) _then) = __$SnAccountStatusCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$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
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -1318,7 +1629,7 @@ class __$SnAccountStatusCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnAccountStatus
|
/// Create a copy of SnAccountStatus
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? 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(
|
return _then(_SnAccountStatus(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,attitude: null == attitude ? _self.attitude : attitude // ignore: cast_nullable_to_non_nullable
|
as String,attitude: null == attitude ? _self.attitude : attitude // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -1327,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,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,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 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 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 String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
|||||||
@@ -63,6 +63,23 @@ _ProfileLink _$ProfileLinkFromJson(Map<String, dynamic> json) =>
|
|||||||
Map<String, dynamic> _$ProfileLinkToJson(_ProfileLink instance) =>
|
Map<String, dynamic> _$ProfileLinkToJson(_ProfileLink instance) =>
|
||||||
<String, dynamic>{'name': instance.name, 'url': instance.url};
|
<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 _$SnAccountProfileFromJson(Map<String, dynamic> json) =>
|
||||||
_SnAccountProfile(
|
_SnAccountProfile(
|
||||||
id: json['id'] as String,
|
id: json['id'] as String,
|
||||||
@@ -113,6 +130,12 @@ _SnAccountProfile _$SnAccountProfileFromJson(Map<String, dynamic> json) =>
|
|||||||
: SnVerificationMark.fromJson(
|
: SnVerificationMark.fromJson(
|
||||||
json['verification'] as Map<String, dynamic>,
|
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),
|
createdAt: DateTime.parse(json['created_at'] as String),
|
||||||
updatedAt: DateTime.parse(json['updated_at'] as String),
|
updatedAt: DateTime.parse(json['updated_at'] as String),
|
||||||
deletedAt:
|
deletedAt:
|
||||||
@@ -144,6 +167,7 @@ Map<String, dynamic> _$SnAccountProfileToJson(_SnAccountProfile instance) =>
|
|||||||
'picture': instance.picture?.toJson(),
|
'picture': instance.picture?.toJson(),
|
||||||
'background': instance.background?.toJson(),
|
'background': instance.background?.toJson(),
|
||||||
'verification': instance.verification?.toJson(),
|
'verification': instance.verification?.toJson(),
|
||||||
|
'username_color': instance.usernameColor?.toJson(),
|
||||||
'created_at': instance.createdAt.toIso8601String(),
|
'created_at': instance.createdAt.toIso8601String(),
|
||||||
'updated_at': instance.updatedAt.toIso8601String(),
|
'updated_at': instance.updatedAt.toIso8601String(),
|
||||||
'deleted_at': instance.deletedAt?.toIso8601String(),
|
'deleted_at': instance.deletedAt?.toIso8601String(),
|
||||||
@@ -158,6 +182,7 @@ _SnAccountStatus _$SnAccountStatusFromJson(Map<String, dynamic> json) =>
|
|||||||
isNotDisturb: json['is_not_disturb'] as bool,
|
isNotDisturb: json['is_not_disturb'] as bool,
|
||||||
isCustomized: json['is_customized'] as bool,
|
isCustomized: json['is_customized'] as bool,
|
||||||
label: json['label'] as String? ?? "",
|
label: json['label'] as String? ?? "",
|
||||||
|
meta: json['meta'] as Map<String, dynamic>?,
|
||||||
clearedAt:
|
clearedAt:
|
||||||
json['cleared_at'] == null
|
json['cleared_at'] == null
|
||||||
? null
|
? null
|
||||||
@@ -180,6 +205,7 @@ Map<String, dynamic> _$SnAccountStatusToJson(_SnAccountStatus instance) =>
|
|||||||
'is_not_disturb': instance.isNotDisturb,
|
'is_not_disturb': instance.isNotDisturb,
|
||||||
'is_customized': instance.isCustomized,
|
'is_customized': instance.isCustomized,
|
||||||
'label': instance.label,
|
'label': instance.label,
|
||||||
|
'meta': instance.meta,
|
||||||
'cleared_at': instance.clearedAt?.toIso8601String(),
|
'cleared_at': instance.clearedAt?.toIso8601String(),
|
||||||
'account_id': instance.accountId,
|
'account_id': instance.accountId,
|
||||||
'created_at': instance.createdAt.toIso8601String(),
|
'created_at': instance.createdAt.toIso8601String(),
|
||||||
|
|||||||
@@ -14,11 +14,11 @@ sealed class AppToken with _$AppToken {
|
|||||||
@freezed
|
@freezed
|
||||||
sealed class GeoIpLocation with _$GeoIpLocation {
|
sealed class GeoIpLocation with _$GeoIpLocation {
|
||||||
const factory GeoIpLocation({
|
const factory GeoIpLocation({
|
||||||
required double latitude,
|
required double? latitude,
|
||||||
required double longitude,
|
required double? longitude,
|
||||||
required String countryCode,
|
required String? countryCode,
|
||||||
required String country,
|
required String? country,
|
||||||
required String city,
|
required String? city,
|
||||||
}) = _GeoIpLocation;
|
}) = _GeoIpLocation;
|
||||||
|
|
||||||
factory GeoIpLocation.fromJson(Map<String, dynamic> json) =>
|
factory GeoIpLocation.fromJson(Map<String, dynamic> json) =>
|
||||||
@@ -29,7 +29,7 @@ sealed class GeoIpLocation with _$GeoIpLocation {
|
|||||||
sealed class SnAuthChallenge with _$SnAuthChallenge {
|
sealed class SnAuthChallenge with _$SnAuthChallenge {
|
||||||
const factory SnAuthChallenge({
|
const factory SnAuthChallenge({
|
||||||
required String id,
|
required String id,
|
||||||
required DateTime expiredAt,
|
required DateTime? expiredAt,
|
||||||
required int stepRemain,
|
required int stepRemain,
|
||||||
required int stepTotal,
|
required int stepTotal,
|
||||||
required int failedAttempts,
|
required int failedAttempts,
|
||||||
@@ -57,7 +57,7 @@ sealed class SnAuthSession with _$SnAuthSession {
|
|||||||
required String id,
|
required String id,
|
||||||
required String? label,
|
required String? label,
|
||||||
required DateTime lastGrantedAt,
|
required DateTime lastGrantedAt,
|
||||||
required DateTime expiredAt,
|
required DateTime? expiredAt,
|
||||||
required String accountId,
|
required String accountId,
|
||||||
required String challengeId,
|
required String challengeId,
|
||||||
required SnAuthChallenge challenge,
|
required SnAuthChallenge challenge,
|
||||||
|
|||||||
@@ -272,7 +272,7 @@ as String,
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$GeoIpLocation {
|
mixin _$GeoIpLocation {
|
||||||
|
|
||||||
double get latitude; double get longitude; String get countryCode; String get country; String get city;
|
double? get latitude; double? get longitude; String? get countryCode; String? get country; String? get city;
|
||||||
/// Create a copy of GeoIpLocation
|
/// Create a copy of GeoIpLocation
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@@ -305,7 +305,7 @@ abstract mixin class $GeoIpLocationCopyWith<$Res> {
|
|||||||
factory $GeoIpLocationCopyWith(GeoIpLocation value, $Res Function(GeoIpLocation) _then) = _$GeoIpLocationCopyWithImpl;
|
factory $GeoIpLocationCopyWith(GeoIpLocation value, $Res Function(GeoIpLocation) _then) = _$GeoIpLocationCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
double latitude, double longitude, String countryCode, String country, String city
|
double? latitude, double? longitude, String? countryCode, String? country, String? city
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -322,14 +322,14 @@ class _$GeoIpLocationCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of GeoIpLocation
|
/// Create a copy of GeoIpLocation
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? latitude = null,Object? longitude = null,Object? countryCode = null,Object? country = null,Object? city = null,}) {
|
@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(
|
return _then(_self.copyWith(
|
||||||
latitude: null == latitude ? _self.latitude : latitude // ignore: cast_nullable_to_non_nullable
|
latitude: freezed == latitude ? _self.latitude : latitude // ignore: cast_nullable_to_non_nullable
|
||||||
as double,longitude: null == longitude ? _self.longitude : longitude // ignore: cast_nullable_to_non_nullable
|
as double?,longitude: freezed == longitude ? _self.longitude : longitude // ignore: cast_nullable_to_non_nullable
|
||||||
as double,countryCode: null == countryCode ? _self.countryCode : countryCode // ignore: cast_nullable_to_non_nullable
|
as double?,countryCode: freezed == countryCode ? _self.countryCode : countryCode // ignore: cast_nullable_to_non_nullable
|
||||||
as String,country: null == country ? _self.country : country // ignore: cast_nullable_to_non_nullable
|
as String?,country: freezed == country ? _self.country : country // ignore: cast_nullable_to_non_nullable
|
||||||
as String,city: null == city ? _self.city : city // ignore: cast_nullable_to_non_nullable
|
as String?,city: freezed == city ? _self.city : city // ignore: cast_nullable_to_non_nullable
|
||||||
as String,
|
as String?,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,7 +411,7 @@ return $default(_that);case _:
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@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;
|
@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) {
|
switch (_that) {
|
||||||
case _GeoIpLocation() when $default != null:
|
case _GeoIpLocation() when $default != null:
|
||||||
return $default(_that.latitude,_that.longitude,_that.countryCode,_that.country,_that.city);case _:
|
return $default(_that.latitude,_that.longitude,_that.countryCode,_that.country,_that.city);case _:
|
||||||
@@ -432,7 +432,7 @@ return $default(_that.latitude,_that.longitude,_that.countryCode,_that.country,_
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( double latitude, double longitude, String countryCode, String country, String city) $default,) {final _that = this;
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( double? latitude, double? longitude, String? countryCode, String? country, String? city) $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _GeoIpLocation():
|
case _GeoIpLocation():
|
||||||
return $default(_that.latitude,_that.longitude,_that.countryCode,_that.country,_that.city);}
|
return $default(_that.latitude,_that.longitude,_that.countryCode,_that.country,_that.city);}
|
||||||
@@ -449,7 +449,7 @@ return $default(_that.latitude,_that.longitude,_that.countryCode,_that.country,_
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( double latitude, double longitude, String countryCode, String country, String city)? $default,) {final _that = this;
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( double? latitude, double? longitude, String? countryCode, String? country, String? city)? $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _GeoIpLocation() when $default != null:
|
case _GeoIpLocation() when $default != null:
|
||||||
return $default(_that.latitude,_that.longitude,_that.countryCode,_that.country,_that.city);case _:
|
return $default(_that.latitude,_that.longitude,_that.countryCode,_that.country,_that.city);case _:
|
||||||
@@ -467,11 +467,11 @@ class _GeoIpLocation implements GeoIpLocation {
|
|||||||
const _GeoIpLocation({required this.latitude, required this.longitude, required this.countryCode, required this.country, required this.city});
|
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);
|
factory _GeoIpLocation.fromJson(Map<String, dynamic> json) => _$GeoIpLocationFromJson(json);
|
||||||
|
|
||||||
@override final double latitude;
|
@override final double? latitude;
|
||||||
@override final double longitude;
|
@override final double? longitude;
|
||||||
@override final String countryCode;
|
@override final String? countryCode;
|
||||||
@override final String country;
|
@override final String? country;
|
||||||
@override final String city;
|
@override final String? city;
|
||||||
|
|
||||||
/// Create a copy of GeoIpLocation
|
/// Create a copy of GeoIpLocation
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@@ -506,7 +506,7 @@ abstract mixin class _$GeoIpLocationCopyWith<$Res> implements $GeoIpLocationCopy
|
|||||||
factory _$GeoIpLocationCopyWith(_GeoIpLocation value, $Res Function(_GeoIpLocation) _then) = __$GeoIpLocationCopyWithImpl;
|
factory _$GeoIpLocationCopyWith(_GeoIpLocation value, $Res Function(_GeoIpLocation) _then) = __$GeoIpLocationCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
double latitude, double longitude, String countryCode, String country, String city
|
double? latitude, double? longitude, String? countryCode, String? country, String? city
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -523,14 +523,14 @@ class __$GeoIpLocationCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of GeoIpLocation
|
/// Create a copy of GeoIpLocation
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? latitude = null,Object? longitude = null,Object? countryCode = null,Object? country = null,Object? city = null,}) {
|
@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(
|
return _then(_GeoIpLocation(
|
||||||
latitude: null == latitude ? _self.latitude : latitude // ignore: cast_nullable_to_non_nullable
|
latitude: freezed == latitude ? _self.latitude : latitude // ignore: cast_nullable_to_non_nullable
|
||||||
as double,longitude: null == longitude ? _self.longitude : longitude // ignore: cast_nullable_to_non_nullable
|
as double?,longitude: freezed == longitude ? _self.longitude : longitude // ignore: cast_nullable_to_non_nullable
|
||||||
as double,countryCode: null == countryCode ? _self.countryCode : countryCode // ignore: cast_nullable_to_non_nullable
|
as double?,countryCode: freezed == countryCode ? _self.countryCode : countryCode // ignore: cast_nullable_to_non_nullable
|
||||||
as String,country: null == country ? _self.country : country // ignore: cast_nullable_to_non_nullable
|
as String?,country: freezed == country ? _self.country : country // ignore: cast_nullable_to_non_nullable
|
||||||
as String,city: null == city ? _self.city : city // ignore: cast_nullable_to_non_nullable
|
as String?,city: freezed == city ? _self.city : city // ignore: cast_nullable_to_non_nullable
|
||||||
as String,
|
as String?,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,7 +541,7 @@ as String,
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$SnAuthChallenge {
|
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; GeoIpLocation? 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
|
/// Create a copy of SnAuthChallenge
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@@ -574,7 +574,7 @@ abstract mixin class $SnAuthChallengeCopyWith<$Res> {
|
|||||||
factory $SnAuthChallengeCopyWith(SnAuthChallenge value, $Res Function(SnAuthChallenge) _then) = _$SnAuthChallengeCopyWithImpl;
|
factory $SnAuthChallengeCopyWith(SnAuthChallenge value, $Res Function(SnAuthChallenge) _then) = _$SnAuthChallengeCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$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, GeoIpLocation? 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
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -591,11 +591,11 @@ class _$SnAuthChallengeCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnAuthChallenge
|
/// Create a copy of SnAuthChallenge
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? 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(
|
return _then(_self.copyWith(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,expiredAt: null == expiredAt ? _self.expiredAt : expiredAt // 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 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,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,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
|
as int,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -704,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, GeoIpLocation? 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) {
|
switch (_that) {
|
||||||
case _SnAuthChallenge() when $default != null:
|
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 _:
|
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 _:
|
||||||
@@ -725,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, GeoIpLocation? 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) {
|
switch (_that) {
|
||||||
case _SnAuthChallenge():
|
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);}
|
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);}
|
||||||
@@ -742,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, GeoIpLocation? 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) {
|
switch (_that) {
|
||||||
case _SnAuthChallenge() when $default != null:
|
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 _:
|
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 _:
|
||||||
@@ -761,7 +761,7 @@ class _SnAuthChallenge implements SnAuthChallenge {
|
|||||||
factory _SnAuthChallenge.fromJson(Map<String, dynamic> json) => _$SnAuthChallengeFromJson(json);
|
factory _SnAuthChallenge.fromJson(Map<String, dynamic> json) => _$SnAuthChallengeFromJson(json);
|
||||||
|
|
||||||
@override final String id;
|
@override final String id;
|
||||||
@override final DateTime expiredAt;
|
@override final DateTime? expiredAt;
|
||||||
@override final int stepRemain;
|
@override final int stepRemain;
|
||||||
@override final int stepTotal;
|
@override final int stepTotal;
|
||||||
@override final int failedAttempts;
|
@override final int failedAttempts;
|
||||||
@@ -829,7 +829,7 @@ abstract mixin class _$SnAuthChallengeCopyWith<$Res> implements $SnAuthChallenge
|
|||||||
factory _$SnAuthChallengeCopyWith(_SnAuthChallenge value, $Res Function(_SnAuthChallenge) _then) = __$SnAuthChallengeCopyWithImpl;
|
factory _$SnAuthChallengeCopyWith(_SnAuthChallenge value, $Res Function(_SnAuthChallenge) _then) = __$SnAuthChallengeCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$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, GeoIpLocation? 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
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -846,11 +846,11 @@ class __$SnAuthChallengeCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnAuthChallenge
|
/// Create a copy of SnAuthChallenge
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? 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(
|
return _then(_SnAuthChallenge(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,expiredAt: null == expiredAt ? _self.expiredAt : expiredAt // 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 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,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,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
|
as int,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -888,7 +888,7 @@ $GeoIpLocationCopyWith<$Res>? get location {
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$SnAuthSession {
|
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
|
/// Create a copy of SnAuthSession
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@@ -921,7 +921,7 @@ abstract mixin class $SnAuthSessionCopyWith<$Res> {
|
|||||||
factory $SnAuthSessionCopyWith(SnAuthSession value, $Res Function(SnAuthSession) _then) = _$SnAuthSessionCopyWithImpl;
|
factory $SnAuthSessionCopyWith(SnAuthSession value, $Res Function(SnAuthSession) _then) = _$SnAuthSessionCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$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
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -938,13 +938,13 @@ class _$SnAuthSessionCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnAuthSession
|
/// Create a copy of SnAuthSession
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? 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(
|
return _then(_self.copyWith(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,label: freezed == label ? _self.label : label // 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 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,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 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,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 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
|
as SnAuthChallenge,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -1041,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) {
|
switch (_that) {
|
||||||
case _SnAuthSession() when $default != null:
|
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 _:
|
return $default(_that.id,_that.label,_that.lastGrantedAt,_that.expiredAt,_that.accountId,_that.challengeId,_that.challenge,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
|
||||||
@@ -1062,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) {
|
switch (_that) {
|
||||||
case _SnAuthSession():
|
case _SnAuthSession():
|
||||||
return $default(_that.id,_that.label,_that.lastGrantedAt,_that.expiredAt,_that.accountId,_that.challengeId,_that.challenge,_that.createdAt,_that.updatedAt,_that.deletedAt);}
|
return $default(_that.id,_that.label,_that.lastGrantedAt,_that.expiredAt,_that.accountId,_that.challengeId,_that.challenge,_that.createdAt,_that.updatedAt,_that.deletedAt);}
|
||||||
@@ -1079,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) {
|
switch (_that) {
|
||||||
case _SnAuthSession() when $default != null:
|
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 _:
|
return $default(_that.id,_that.label,_that.lastGrantedAt,_that.expiredAt,_that.accountId,_that.challengeId,_that.challenge,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
|
||||||
@@ -1100,7 +1100,7 @@ class _SnAuthSession implements SnAuthSession {
|
|||||||
@override final String id;
|
@override final String id;
|
||||||
@override final String? label;
|
@override final String? label;
|
||||||
@override final DateTime lastGrantedAt;
|
@override final DateTime lastGrantedAt;
|
||||||
@override final DateTime expiredAt;
|
@override final DateTime? expiredAt;
|
||||||
@override final String accountId;
|
@override final String accountId;
|
||||||
@override final String challengeId;
|
@override final String challengeId;
|
||||||
@override final SnAuthChallenge challenge;
|
@override final SnAuthChallenge challenge;
|
||||||
@@ -1141,7 +1141,7 @@ abstract mixin class _$SnAuthSessionCopyWith<$Res> implements $SnAuthSessionCopy
|
|||||||
factory _$SnAuthSessionCopyWith(_SnAuthSession value, $Res Function(_SnAuthSession) _then) = __$SnAuthSessionCopyWithImpl;
|
factory _$SnAuthSessionCopyWith(_SnAuthSession value, $Res Function(_SnAuthSession) _then) = __$SnAuthSessionCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$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
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -1158,13 +1158,13 @@ class __$SnAuthSessionCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnAuthSession
|
/// Create a copy of SnAuthSession
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? 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(
|
return _then(_SnAuthSession(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,label: freezed == label ? _self.label : label // 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 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,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 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,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 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
|
as SnAuthChallenge,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
|||||||
@@ -15,11 +15,11 @@ Map<String, dynamic> _$AppTokenToJson(_AppToken instance) => <String, dynamic>{
|
|||||||
|
|
||||||
_GeoIpLocation _$GeoIpLocationFromJson(Map<String, dynamic> json) =>
|
_GeoIpLocation _$GeoIpLocationFromJson(Map<String, dynamic> json) =>
|
||||||
_GeoIpLocation(
|
_GeoIpLocation(
|
||||||
latitude: (json['latitude'] as num).toDouble(),
|
latitude: (json['latitude'] as num?)?.toDouble(),
|
||||||
longitude: (json['longitude'] as num).toDouble(),
|
longitude: (json['longitude'] as num?)?.toDouble(),
|
||||||
countryCode: json['country_code'] as String,
|
countryCode: json['country_code'] as String?,
|
||||||
country: json['country'] as String,
|
country: json['country'] as String?,
|
||||||
city: json['city'] as String,
|
city: json['city'] as String?,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$GeoIpLocationToJson(_GeoIpLocation instance) =>
|
Map<String, dynamic> _$GeoIpLocationToJson(_GeoIpLocation instance) =>
|
||||||
@@ -34,7 +34,10 @@ Map<String, dynamic> _$GeoIpLocationToJson(_GeoIpLocation instance) =>
|
|||||||
_SnAuthChallenge _$SnAuthChallengeFromJson(Map<String, dynamic> json) =>
|
_SnAuthChallenge _$SnAuthChallengeFromJson(Map<String, dynamic> json) =>
|
||||||
_SnAuthChallenge(
|
_SnAuthChallenge(
|
||||||
id: json['id'] as String,
|
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(),
|
stepRemain: (json['step_remain'] as num).toInt(),
|
||||||
stepTotal: (json['step_total'] as num).toInt(),
|
stepTotal: (json['step_total'] as num).toInt(),
|
||||||
failedAttempts: (json['failed_attempts'] as num).toInt(),
|
failedAttempts: (json['failed_attempts'] as num).toInt(),
|
||||||
@@ -66,7 +69,7 @@ _SnAuthChallenge _$SnAuthChallengeFromJson(Map<String, dynamic> json) =>
|
|||||||
Map<String, dynamic> _$SnAuthChallengeToJson(_SnAuthChallenge instance) =>
|
Map<String, dynamic> _$SnAuthChallengeToJson(_SnAuthChallenge instance) =>
|
||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
'id': instance.id,
|
'id': instance.id,
|
||||||
'expired_at': instance.expiredAt.toIso8601String(),
|
'expired_at': instance.expiredAt?.toIso8601String(),
|
||||||
'step_remain': instance.stepRemain,
|
'step_remain': instance.stepRemain,
|
||||||
'step_total': instance.stepTotal,
|
'step_total': instance.stepTotal,
|
||||||
'failed_attempts': instance.failedAttempts,
|
'failed_attempts': instance.failedAttempts,
|
||||||
@@ -89,7 +92,10 @@ _SnAuthSession _$SnAuthSessionFromJson(Map<String, dynamic> json) =>
|
|||||||
id: json['id'] as String,
|
id: json['id'] as String,
|
||||||
label: json['label'] as String?,
|
label: json['label'] as String?,
|
||||||
lastGrantedAt: DateTime.parse(json['last_granted_at'] 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,
|
accountId: json['account_id'] as String,
|
||||||
challengeId: json['challenge_id'] as String,
|
challengeId: json['challenge_id'] as String,
|
||||||
challenge: SnAuthChallenge.fromJson(
|
challenge: SnAuthChallenge.fromJson(
|
||||||
@@ -108,7 +114,7 @@ Map<String, dynamic> _$SnAuthSessionToJson(_SnAuthSession instance) =>
|
|||||||
'id': instance.id,
|
'id': instance.id,
|
||||||
'label': instance.label,
|
'label': instance.label,
|
||||||
'last_granted_at': instance.lastGrantedAt.toIso8601String(),
|
'last_granted_at': instance.lastGrantedAt.toIso8601String(),
|
||||||
'expired_at': instance.expiredAt.toIso8601String(),
|
'expired_at': instance.expiredAt?.toIso8601String(),
|
||||||
'account_id': instance.accountId,
|
'account_id': instance.accountId,
|
||||||
'challenge_id': instance.challengeId,
|
'challenge_id': instance.challengeId,
|
||||||
'challenge': instance.challenge.toJson(),
|
'challenge': instance.challenge.toJson(),
|
||||||
|
|||||||
16
lib/models/autocomplete_response.dart
Normal file
16
lib/models/autocomplete_response.dart
Normal 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);
|
||||||
|
}
|
||||||
277
lib/models/autocomplete_response.freezed.dart
Normal file
277
lib/models/autocomplete_response.freezed.dart
Normal 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
|
||||||
23
lib/models/autocomplete_response.g.dart
Normal file
23
lib/models/autocomplete_response.g.dart
Normal 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,
|
||||||
|
};
|
||||||
@@ -40,7 +40,7 @@ sealed class SnChatMessage with _$SnChatMessage {
|
|||||||
String? content,
|
String? content,
|
||||||
String? nonce,
|
String? nonce,
|
||||||
@Default({}) Map<String, dynamic> meta,
|
@Default({}) Map<String, dynamic> meta,
|
||||||
@Default([]) List<String> membersMetioned,
|
@Default([]) List<String> membersMentioned,
|
||||||
DateTime? editedAt,
|
DateTime? editedAt,
|
||||||
@Default([]) List<SnCloudFile> attachments,
|
@Default([]) List<SnCloudFile> attachments,
|
||||||
@Default([]) List<SnChatReaction> reactions,
|
@Default([]) List<SnChatReaction> reactions,
|
||||||
@@ -117,23 +117,10 @@ class MessageChangeAction {
|
|||||||
static const String delete = "delete";
|
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
|
@freezed
|
||||||
sealed class MessageSyncResponse with _$MessageSyncResponse {
|
sealed class MessageSyncResponse with _$MessageSyncResponse {
|
||||||
const factory MessageSyncResponse({
|
const factory MessageSyncResponse({
|
||||||
@Default([]) List<MessageChange> changes,
|
@Default([]) List<SnChatMessage> messages,
|
||||||
required DateTime currentTimestamp,
|
required DateTime currentTimestamp,
|
||||||
}) = _MessageSyncResponse;
|
}) = _MessageSyncResponse;
|
||||||
|
|
||||||
@@ -162,6 +149,8 @@ sealed class CallParticipant with _$CallParticipant {
|
|||||||
const factory CallParticipant({
|
const factory CallParticipant({
|
||||||
required String identity,
|
required String identity,
|
||||||
required String name,
|
required String name,
|
||||||
|
required String accountId,
|
||||||
|
@Default(null) SnAccount? account,
|
||||||
required DateTime joinedAt,
|
required DateTime joinedAt,
|
||||||
}) = _CallParticipant;
|
}) = _CallParticipant;
|
||||||
|
|
||||||
|
|||||||
@@ -391,7 +391,7 @@ $SnRealmCopyWith<$Res>? get realm {
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$SnChatMessage {
|
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
|
/// Create a copy of SnChatMessage
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@@ -404,16 +404,16 @@ $SnChatMessageCopyWith<SnChatMessage> get copyWith => _$SnChatMessageCopyWithImp
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
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)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@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
|
@override
|
||||||
String toString() {
|
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;
|
factory $SnChatMessageCopyWith(SnChatMessage value, $Res Function(SnChatMessage) _then) = _$SnChatMessageCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$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
|
/// Create a copy of SnChatMessage
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? 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(
|
return _then(_self.copyWith(
|
||||||
createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -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,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?,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 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 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 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
|
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) {
|
switch (_that) {
|
||||||
case _SnChatMessage() when $default != null:
|
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();
|
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) {
|
switch (_that) {
|
||||||
case _SnChatMessage():
|
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`
|
/// 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) {
|
switch (_that) {
|
||||||
case _SnChatMessage() when $default != null:
|
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;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -604,7 +604,7 @@ return $default(_that.createdAt,_that.updatedAt,_that.deletedAt,_that.id,_that.t
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _SnChatMessage implements SnChatMessage {
|
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);
|
factory _SnChatMessage.fromJson(Map<String, dynamic> json) => _$SnChatMessageFromJson(json);
|
||||||
|
|
||||||
@override final DateTime createdAt;
|
@override final DateTime createdAt;
|
||||||
@@ -621,11 +621,11 @@ class _SnChatMessage implements SnChatMessage {
|
|||||||
return EqualUnmodifiableMapView(_meta);
|
return EqualUnmodifiableMapView(_meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<String> _membersMetioned;
|
final List<String> _membersMentioned;
|
||||||
@override@JsonKey() List<String> get membersMetioned {
|
@override@JsonKey() List<String> get membersMentioned {
|
||||||
if (_membersMetioned is EqualUnmodifiableListView) return _membersMetioned;
|
if (_membersMentioned is EqualUnmodifiableListView) return _membersMentioned;
|
||||||
// ignore: implicit_dynamic_type
|
// ignore: implicit_dynamic_type
|
||||||
return EqualUnmodifiableListView(_membersMetioned);
|
return EqualUnmodifiableListView(_membersMentioned);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override final DateTime? editedAt;
|
@override final DateTime? editedAt;
|
||||||
@@ -662,16 +662,16 @@ Map<String, dynamic> toJson() {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
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)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@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
|
@override
|
||||||
String toString() {
|
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;
|
factory _$SnChatMessageCopyWith(_SnChatMessage value, $Res Function(_SnChatMessage) _then) = __$SnChatMessageCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$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
|
/// Create a copy of SnChatMessage
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? 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(
|
return _then(_SnChatMessage(
|
||||||
createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -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,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?,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 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 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 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
|
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
|
/// @nodoc
|
||||||
mixin _$MessageSyncResponse {
|
mixin _$MessageSyncResponse {
|
||||||
|
|
||||||
List<MessageChange> get changes; DateTime get currentTimestamp;
|
List<SnChatMessage> get messages; DateTime get currentTimestamp;
|
||||||
/// Create a copy of MessageSyncResponse
|
/// Create a copy of MessageSyncResponse
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@@ -1997,16 +1707,16 @@ $MessageSyncResponseCopyWith<MessageSyncResponse> get copyWith => _$MessageSyncR
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
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)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(changes),currentTimestamp);
|
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(messages),currentTimestamp);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
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;
|
factory $MessageSyncResponseCopyWith(MessageSyncResponse value, $Res Function(MessageSyncResponse) _then) = _$MessageSyncResponseCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
List<MessageChange> changes, DateTime currentTimestamp
|
List<SnChatMessage> messages, DateTime currentTimestamp
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -2034,10 +1744,10 @@ class _$MessageSyncResponseCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of MessageSyncResponse
|
/// Create a copy of MessageSyncResponse
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? changes = null,Object? currentTimestamp = null,}) {
|
@pragma('vm:prefer-inline') @override $Res call({Object? messages = null,Object? currentTimestamp = null,}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
changes: null == changes ? _self.changes : changes // ignore: cast_nullable_to_non_nullable
|
messages: null == messages ? _self.messages : messages // ignore: cast_nullable_to_non_nullable
|
||||||
as List<MessageChange>,currentTimestamp: null == currentTimestamp ? _self.currentTimestamp : currentTimestamp // ignore: cast_nullable_to_non_nullable
|
as List<SnChatMessage>,currentTimestamp: null == currentTimestamp ? _self.currentTimestamp : currentTimestamp // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,
|
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) {
|
switch (_that) {
|
||||||
case _MessageSyncResponse() when $default != null:
|
case _MessageSyncResponse() when $default != null:
|
||||||
return $default(_that.changes,_that.currentTimestamp);case _:
|
return $default(_that.messages,_that.currentTimestamp);case _:
|
||||||
return orElse();
|
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) {
|
switch (_that) {
|
||||||
case _MessageSyncResponse():
|
case _MessageSyncResponse():
|
||||||
return $default(_that.changes,_that.currentTimestamp);}
|
return $default(_that.messages,_that.currentTimestamp);}
|
||||||
}
|
}
|
||||||
/// A variant of `when` that fallback to returning `null`
|
/// 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) {
|
switch (_that) {
|
||||||
case _MessageSyncResponse() when $default != null:
|
case _MessageSyncResponse() when $default != null:
|
||||||
return $default(_that.changes,_that.currentTimestamp);case _:
|
return $default(_that.messages,_that.currentTimestamp);case _:
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2173,14 +1883,14 @@ return $default(_that.changes,_that.currentTimestamp);case _:
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _MessageSyncResponse implements MessageSyncResponse {
|
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);
|
factory _MessageSyncResponse.fromJson(Map<String, dynamic> json) => _$MessageSyncResponseFromJson(json);
|
||||||
|
|
||||||
final List<MessageChange> _changes;
|
final List<SnChatMessage> _messages;
|
||||||
@override@JsonKey() List<MessageChange> get changes {
|
@override@JsonKey() List<SnChatMessage> get messages {
|
||||||
if (_changes is EqualUnmodifiableListView) return _changes;
|
if (_messages is EqualUnmodifiableListView) return _messages;
|
||||||
// ignore: implicit_dynamic_type
|
// ignore: implicit_dynamic_type
|
||||||
return EqualUnmodifiableListView(_changes);
|
return EqualUnmodifiableListView(_messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override final DateTime currentTimestamp;
|
@override final DateTime currentTimestamp;
|
||||||
@@ -2198,16 +1908,16 @@ Map<String, dynamic> toJson() {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
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)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_changes),currentTimestamp);
|
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_messages),currentTimestamp);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
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;
|
factory _$MessageSyncResponseCopyWith(_MessageSyncResponse value, $Res Function(_MessageSyncResponse) _then) = __$MessageSyncResponseCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
List<MessageChange> changes, DateTime currentTimestamp
|
List<SnChatMessage> messages, DateTime currentTimestamp
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -2235,10 +1945,10 @@ class __$MessageSyncResponseCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of MessageSyncResponse
|
/// Create a copy of MessageSyncResponse
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? changes = null,Object? currentTimestamp = null,}) {
|
@override @pragma('vm:prefer-inline') $Res call({Object? messages = null,Object? currentTimestamp = null,}) {
|
||||||
return _then(_MessageSyncResponse(
|
return _then(_MessageSyncResponse(
|
||||||
changes: null == changes ? _self._changes : changes // ignore: cast_nullable_to_non_nullable
|
messages: null == messages ? _self._messages : messages // ignore: cast_nullable_to_non_nullable
|
||||||
as List<MessageChange>,currentTimestamp: null == currentTimestamp ? _self.currentTimestamp : currentTimestamp // ignore: cast_nullable_to_non_nullable
|
as List<SnChatMessage>,currentTimestamp: null == currentTimestamp ? _self.currentTimestamp : currentTimestamp // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,
|
as DateTime,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -2531,7 +2241,7 @@ as List<CallParticipant>,
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$CallParticipant {
|
mixin _$CallParticipant {
|
||||||
|
|
||||||
String get identity; String get name; DateTime get joinedAt;
|
String get identity; String get name; String get accountId; SnAccount? get account; DateTime get joinedAt;
|
||||||
/// Create a copy of CallParticipant
|
/// Create a copy of CallParticipant
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@@ -2544,16 +2254,16 @@ $CallParticipantCopyWith<CallParticipant> get copyWith => _$CallParticipantCopyW
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is CallParticipant&&(identical(other.identity, identity) || other.identity == identity)&&(identical(other.name, name) || other.name == name)&&(identical(other.joinedAt, joinedAt) || other.joinedAt == joinedAt));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is CallParticipant&&(identical(other.identity, identity) || other.identity == identity)&&(identical(other.name, name) || other.name == name)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.account, account) || other.account == account)&&(identical(other.joinedAt, joinedAt) || other.joinedAt == joinedAt));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,identity,name,joinedAt);
|
int get hashCode => Object.hash(runtimeType,identity,name,accountId,account,joinedAt);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'CallParticipant(identity: $identity, name: $name, joinedAt: $joinedAt)';
|
return 'CallParticipant(identity: $identity, name: $name, accountId: $accountId, account: $account, joinedAt: $joinedAt)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2564,11 +2274,11 @@ abstract mixin class $CallParticipantCopyWith<$Res> {
|
|||||||
factory $CallParticipantCopyWith(CallParticipant value, $Res Function(CallParticipant) _then) = _$CallParticipantCopyWithImpl;
|
factory $CallParticipantCopyWith(CallParticipant value, $Res Function(CallParticipant) _then) = _$CallParticipantCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String identity, String name, DateTime joinedAt
|
String identity, String name, String accountId, SnAccount? account, DateTime joinedAt
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$SnAccountCopyWith<$Res>? get account;
|
||||||
|
|
||||||
}
|
}
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -2581,15 +2291,29 @@ class _$CallParticipantCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of CallParticipant
|
/// Create a copy of CallParticipant
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? identity = null,Object? name = null,Object? joinedAt = null,}) {
|
@pragma('vm:prefer-inline') @override $Res call({Object? identity = null,Object? name = null,Object? accountId = null,Object? account = freezed,Object? joinedAt = null,}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
identity: null == identity ? _self.identity : identity // ignore: cast_nullable_to_non_nullable
|
identity: null == identity ? _self.identity : identity // ignore: cast_nullable_to_non_nullable
|
||||||
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||||
as String,joinedAt: null == joinedAt ? _self.joinedAt : joinedAt // ignore: cast_nullable_to_non_nullable
|
as String,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnAccount?,joinedAt: null == joinedAt ? _self.joinedAt : joinedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,
|
as DateTime,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
/// Create a copy of CallParticipant
|
||||||
|
/// 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));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2668,10 +2392,10 @@ return $default(_that);case _:
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String identity, String name, DateTime joinedAt)? $default,{required TResult orElse(),}) {final _that = this;
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String identity, String name, String accountId, SnAccount? account, DateTime joinedAt)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _CallParticipant() when $default != null:
|
case _CallParticipant() when $default != null:
|
||||||
return $default(_that.identity,_that.name,_that.joinedAt);case _:
|
return $default(_that.identity,_that.name,_that.accountId,_that.account,_that.joinedAt);case _:
|
||||||
return orElse();
|
return orElse();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2689,10 +2413,10 @@ return $default(_that.identity,_that.name,_that.joinedAt);case _:
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String identity, String name, DateTime joinedAt) $default,) {final _that = this;
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String identity, String name, String accountId, SnAccount? account, DateTime joinedAt) $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _CallParticipant():
|
case _CallParticipant():
|
||||||
return $default(_that.identity,_that.name,_that.joinedAt);}
|
return $default(_that.identity,_that.name,_that.accountId,_that.account,_that.joinedAt);}
|
||||||
}
|
}
|
||||||
/// A variant of `when` that fallback to returning `null`
|
/// A variant of `when` that fallback to returning `null`
|
||||||
///
|
///
|
||||||
@@ -2706,10 +2430,10 @@ return $default(_that.identity,_that.name,_that.joinedAt);}
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String identity, String name, DateTime joinedAt)? $default,) {final _that = this;
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String identity, String name, String accountId, SnAccount? account, DateTime joinedAt)? $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _CallParticipant() when $default != null:
|
case _CallParticipant() when $default != null:
|
||||||
return $default(_that.identity,_that.name,_that.joinedAt);case _:
|
return $default(_that.identity,_that.name,_that.accountId,_that.account,_that.joinedAt);case _:
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2721,11 +2445,13 @@ return $default(_that.identity,_that.name,_that.joinedAt);case _:
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _CallParticipant implements CallParticipant {
|
class _CallParticipant implements CallParticipant {
|
||||||
const _CallParticipant({required this.identity, required this.name, required this.joinedAt});
|
const _CallParticipant({required this.identity, required this.name, required this.accountId, this.account = null, required this.joinedAt});
|
||||||
factory _CallParticipant.fromJson(Map<String, dynamic> json) => _$CallParticipantFromJson(json);
|
factory _CallParticipant.fromJson(Map<String, dynamic> json) => _$CallParticipantFromJson(json);
|
||||||
|
|
||||||
@override final String identity;
|
@override final String identity;
|
||||||
@override final String name;
|
@override final String name;
|
||||||
|
@override final String accountId;
|
||||||
|
@override@JsonKey() final SnAccount? account;
|
||||||
@override final DateTime joinedAt;
|
@override final DateTime joinedAt;
|
||||||
|
|
||||||
/// Create a copy of CallParticipant
|
/// Create a copy of CallParticipant
|
||||||
@@ -2741,16 +2467,16 @@ Map<String, dynamic> toJson() {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _CallParticipant&&(identical(other.identity, identity) || other.identity == identity)&&(identical(other.name, name) || other.name == name)&&(identical(other.joinedAt, joinedAt) || other.joinedAt == joinedAt));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _CallParticipant&&(identical(other.identity, identity) || other.identity == identity)&&(identical(other.name, name) || other.name == name)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.account, account) || other.account == account)&&(identical(other.joinedAt, joinedAt) || other.joinedAt == joinedAt));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,identity,name,joinedAt);
|
int get hashCode => Object.hash(runtimeType,identity,name,accountId,account,joinedAt);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'CallParticipant(identity: $identity, name: $name, joinedAt: $joinedAt)';
|
return 'CallParticipant(identity: $identity, name: $name, accountId: $accountId, account: $account, joinedAt: $joinedAt)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2761,11 +2487,11 @@ abstract mixin class _$CallParticipantCopyWith<$Res> implements $CallParticipant
|
|||||||
factory _$CallParticipantCopyWith(_CallParticipant value, $Res Function(_CallParticipant) _then) = __$CallParticipantCopyWithImpl;
|
factory _$CallParticipantCopyWith(_CallParticipant value, $Res Function(_CallParticipant) _then) = __$CallParticipantCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String identity, String name, DateTime joinedAt
|
String identity, String name, String accountId, SnAccount? account, DateTime joinedAt
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@override $SnAccountCopyWith<$Res>? get account;
|
||||||
|
|
||||||
}
|
}
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@@ -2778,16 +2504,30 @@ class __$CallParticipantCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of CallParticipant
|
/// Create a copy of CallParticipant
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? identity = null,Object? name = null,Object? joinedAt = null,}) {
|
@override @pragma('vm:prefer-inline') $Res call({Object? identity = null,Object? name = null,Object? accountId = null,Object? account = freezed,Object? joinedAt = null,}) {
|
||||||
return _then(_CallParticipant(
|
return _then(_CallParticipant(
|
||||||
identity: null == identity ? _self.identity : identity // ignore: cast_nullable_to_non_nullable
|
identity: null == identity ? _self.identity : identity // ignore: cast_nullable_to_non_nullable
|
||||||
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||||
as String,joinedAt: null == joinedAt ? _self.joinedAt : joinedAt // ignore: cast_nullable_to_non_nullable
|
as String,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnAccount?,joinedAt: null == joinedAt ? _self.joinedAt : joinedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,
|
as DateTime,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a copy of CallParticipant
|
||||||
|
/// 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));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -69,8 +69,8 @@ _SnChatMessage _$SnChatMessageFromJson(Map<String, dynamic> json) =>
|
|||||||
content: json['content'] as String?,
|
content: json['content'] as String?,
|
||||||
nonce: json['nonce'] as String?,
|
nonce: json['nonce'] as String?,
|
||||||
meta: json['meta'] as Map<String, dynamic>? ?? const {},
|
meta: json['meta'] as Map<String, dynamic>? ?? const {},
|
||||||
membersMetioned:
|
membersMentioned:
|
||||||
(json['members_metioned'] as List<dynamic>?)
|
(json['members_mentioned'] as List<dynamic>?)
|
||||||
?.map((e) => e as String)
|
?.map((e) => e as String)
|
||||||
.toList() ??
|
.toList() ??
|
||||||
const [],
|
const [],
|
||||||
@@ -105,7 +105,7 @@ Map<String, dynamic> _$SnChatMessageToJson(_SnChatMessage instance) =>
|
|||||||
'content': instance.content,
|
'content': instance.content,
|
||||||
'nonce': instance.nonce,
|
'nonce': instance.nonce,
|
||||||
'meta': instance.meta,
|
'meta': instance.meta,
|
||||||
'members_metioned': instance.membersMetioned,
|
'members_mentioned': instance.membersMentioned,
|
||||||
'edited_at': instance.editedAt?.toIso8601String(),
|
'edited_at': instance.editedAt?.toIso8601String(),
|
||||||
'attachments': instance.attachments.map((e) => e.toJson()).toList(),
|
'attachments': instance.attachments.map((e) => e.toJson()).toList(),
|
||||||
'reactions': instance.reactions.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(),
|
'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 _$MessageSyncResponseFromJson(Map<String, dynamic> json) =>
|
||||||
_MessageSyncResponse(
|
_MessageSyncResponse(
|
||||||
changes:
|
messages:
|
||||||
(json['changes'] as List<dynamic>?)
|
(json['messages'] as List<dynamic>?)
|
||||||
?.map((e) => MessageChange.fromJson(e as Map<String, dynamic>))
|
?.map((e) => SnChatMessage.fromJson(e as Map<String, dynamic>))
|
||||||
.toList() ??
|
.toList() ??
|
||||||
const [],
|
const [],
|
||||||
currentTimestamp: DateTime.parse(json['current_timestamp'] as String),
|
currentTimestamp: DateTime.parse(json['current_timestamp'] as String),
|
||||||
@@ -259,7 +240,7 @@ _MessageSyncResponse _$MessageSyncResponseFromJson(Map<String, dynamic> json) =>
|
|||||||
Map<String, dynamic> _$MessageSyncResponseToJson(
|
Map<String, dynamic> _$MessageSyncResponseToJson(
|
||||||
_MessageSyncResponse instance,
|
_MessageSyncResponse instance,
|
||||||
) => <String, dynamic>{
|
) => <String, dynamic>{
|
||||||
'changes': instance.changes.map((e) => e.toJson()).toList(),
|
'messages': instance.messages.map((e) => e.toJson()).toList(),
|
||||||
'current_timestamp': instance.currentTimestamp.toIso8601String(),
|
'current_timestamp': instance.currentTimestamp.toIso8601String(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -294,6 +275,11 @@ _CallParticipant _$CallParticipantFromJson(Map<String, dynamic> json) =>
|
|||||||
_CallParticipant(
|
_CallParticipant(
|
||||||
identity: json['identity'] as String,
|
identity: json['identity'] as String,
|
||||||
name: json['name'] as String,
|
name: json['name'] as String,
|
||||||
|
accountId: json['account_id'] as String,
|
||||||
|
account:
|
||||||
|
json['account'] == null
|
||||||
|
? null
|
||||||
|
: SnAccount.fromJson(json['account'] as Map<String, dynamic>),
|
||||||
joinedAt: DateTime.parse(json['joined_at'] as String),
|
joinedAt: DateTime.parse(json['joined_at'] as String),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -301,6 +287,8 @@ Map<String, dynamic> _$CallParticipantToJson(_CallParticipant instance) =>
|
|||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
'identity': instance.identity,
|
'identity': instance.identity,
|
||||||
'name': instance.name,
|
'name': instance.name,
|
||||||
|
'account_id': instance.accountId,
|
||||||
|
'account': instance.account?.toJson(),
|
||||||
'joined_at': instance.joinedAt.toIso8601String(),
|
'joined_at': instance.joinedAt.toIso8601String(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'package:island/models/file_pool.dart';
|
||||||
|
|
||||||
part 'file.freezed.dart';
|
part 'file.freezed.dart';
|
||||||
part 'file.g.dart';
|
part 'file.g.dart';
|
||||||
@@ -13,6 +14,7 @@ sealed class UniversalFile with _$UniversalFile {
|
|||||||
required dynamic data,
|
required dynamic data,
|
||||||
required UniversalFileType type,
|
required UniversalFileType type,
|
||||||
@Default(false) bool isLink,
|
@Default(false) bool isLink,
|
||||||
|
String? displayName,
|
||||||
}) = _UniversalFile;
|
}) = _UniversalFile;
|
||||||
|
|
||||||
factory UniversalFile.fromJson(Map<String, dynamic> json) =>
|
factory UniversalFile.fromJson(Map<String, dynamic> json) =>
|
||||||
@@ -30,6 +32,7 @@ sealed class UniversalFile with _$UniversalFile {
|
|||||||
'video' => UniversalFileType.video,
|
'video' => UniversalFileType.video,
|
||||||
_ => UniversalFileType.file,
|
_ => UniversalFileType.file,
|
||||||
},
|
},
|
||||||
|
displayName: attachment.name,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -42,6 +45,7 @@ sealed class SnCloudFile with _$SnCloudFile {
|
|||||||
required String? description,
|
required String? description,
|
||||||
required Map<String, dynamic>? fileMeta,
|
required Map<String, dynamic>? fileMeta,
|
||||||
required Map<String, dynamic>? userMeta,
|
required Map<String, dynamic>? userMeta,
|
||||||
|
required SnFilePool? pool,
|
||||||
@Default([]) List<int> sensitiveMarks,
|
@Default([]) List<int> sensitiveMarks,
|
||||||
required String? mimeType,
|
required String? mimeType,
|
||||||
required String? hash,
|
required String? hash,
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ T _$identity<T>(T value) => value;
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$UniversalFile {
|
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
|
/// Create a copy of UniversalFile
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@@ -28,16 +28,16 @@ $UniversalFileCopyWith<UniversalFile> get copyWith => _$UniversalFileCopyWithImp
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
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)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@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
|
@override
|
||||||
String toString() {
|
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;
|
factory $UniversalFileCopyWith(UniversalFile value, $Res Function(UniversalFile) _then) = _$UniversalFileCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$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
|
/// Create a copy of UniversalFile
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? 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(
|
return _then(_self.copyWith(
|
||||||
data: freezed == data ? _self.data : data // ignore: cast_nullable_to_non_nullable
|
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 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 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) {
|
switch (_that) {
|
||||||
case _UniversalFile() when $default != null:
|
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();
|
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) {
|
switch (_that) {
|
||||||
case _UniversalFile():
|
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`
|
/// 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) {
|
switch (_that) {
|
||||||
case _UniversalFile() when $default != null:
|
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;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -205,12 +206,13 @@ return $default(_that.data,_that.type,_that.isLink);case _:
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _UniversalFile extends UniversalFile {
|
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);
|
factory _UniversalFile.fromJson(Map<String, dynamic> json) => _$UniversalFileFromJson(json);
|
||||||
|
|
||||||
@override final dynamic data;
|
@override final dynamic data;
|
||||||
@override final UniversalFileType type;
|
@override final UniversalFileType type;
|
||||||
@override@JsonKey() final bool isLink;
|
@override@JsonKey() final bool isLink;
|
||||||
|
@override final String? displayName;
|
||||||
|
|
||||||
/// Create a copy of UniversalFile
|
/// Create a copy of UniversalFile
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@@ -225,16 +227,16 @@ Map<String, dynamic> toJson() {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
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)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@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
|
@override
|
||||||
String toString() {
|
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;
|
factory _$UniversalFileCopyWith(_UniversalFile value, $Res Function(_UniversalFile) _then) = __$UniversalFileCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$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
|
/// Create a copy of UniversalFile
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? 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(
|
return _then(_UniversalFile(
|
||||||
data: freezed == data ? _self.data : data // ignore: cast_nullable_to_non_nullable
|
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 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 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
|
/// @nodoc
|
||||||
mixin _$SnCloudFile {
|
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
|
/// Create a copy of SnCloudFile
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@@ -291,16 +294,16 @@ $SnCloudFileCopyWith<SnCloudFile> get copyWith => _$SnCloudFileCopyWithImpl<SnCl
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnCloudFile&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&const DeepCollectionEquality().equals(other.fileMeta, fileMeta)&&const DeepCollectionEquality().equals(other.userMeta, userMeta)&&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)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@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
|
@override
|
||||||
String toString() {
|
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;
|
factory $SnCloudFileCopyWith(SnCloudFile value, $Res Function(SnCloudFile) _then) = _$SnCloudFileCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, String name, String? description, Map<String, dynamic>? fileMeta, Map<String, dynamic>? userMeta, 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
|
/// @nodoc
|
||||||
@@ -328,14 +331,15 @@ class _$SnCloudFileCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnCloudFile
|
/// Create a copy of SnCloudFile
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? fileMeta = freezed,Object? userMeta = freezed,Object? 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(
|
return _then(_self.copyWith(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||||
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,fileMeta: freezed == fileMeta ? _self.fileMeta : fileMeta // 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>?,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 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?,hash: freezed == hash ? _self.hash : hash // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,size: null == size ? _self.size : size // ignore: cast_nullable_to_non_nullable
|
as 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?,
|
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) {
|
switch (_that) {
|
||||||
case _SnCloudFile() when $default != null:
|
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();
|
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) {
|
switch (_that) {
|
||||||
case _SnCloudFile():
|
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`
|
/// 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) {
|
switch (_that) {
|
||||||
case _SnCloudFile() when $default != null:
|
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;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -479,7 +495,7 @@ return $default(_that.id,_that.name,_that.description,_that.fileMeta,_that.userM
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _SnCloudFile implements SnCloudFile {
|
class _SnCloudFile implements SnCloudFile {
|
||||||
const _SnCloudFile({required this.id, required this.name, required this.description, required final Map<String, dynamic>? fileMeta, required final Map<String, dynamic>? userMeta, 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);
|
factory _SnCloudFile.fromJson(Map<String, dynamic> json) => _$SnCloudFileFromJson(json);
|
||||||
|
|
||||||
@override final String id;
|
@override final String id;
|
||||||
@@ -503,6 +519,7 @@ class _SnCloudFile implements SnCloudFile {
|
|||||||
return EqualUnmodifiableMapView(value);
|
return EqualUnmodifiableMapView(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override final SnFilePool? pool;
|
||||||
final List<int> _sensitiveMarks;
|
final List<int> _sensitiveMarks;
|
||||||
@override@JsonKey() List<int> get sensitiveMarks {
|
@override@JsonKey() List<int> get sensitiveMarks {
|
||||||
if (_sensitiveMarks is EqualUnmodifiableListView) return _sensitiveMarks;
|
if (_sensitiveMarks is EqualUnmodifiableListView) return _sensitiveMarks;
|
||||||
@@ -532,16 +549,16 @@ Map<String, dynamic> toJson() {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnCloudFile&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.description, description) || other.description == description)&&const DeepCollectionEquality().equals(other._fileMeta, _fileMeta)&&const DeepCollectionEquality().equals(other._userMeta, _userMeta)&&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)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@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
|
@override
|
||||||
String toString() {
|
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;
|
factory _$SnCloudFileCopyWith(_SnCloudFile value, $Res Function(_SnCloudFile) _then) = __$SnCloudFileCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, String name, String? description, Map<String, dynamic>? fileMeta, Map<String, dynamic>? userMeta, 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
|
/// @nodoc
|
||||||
@@ -569,14 +586,15 @@ class __$SnCloudFileCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnCloudFile
|
/// Create a copy of SnCloudFile
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? description = freezed,Object? fileMeta = freezed,Object? userMeta = freezed,Object? 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(
|
return _then(_SnCloudFile(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||||
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
as String,description: freezed == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,fileMeta: freezed == fileMeta ? _self._fileMeta : fileMeta // 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>?,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 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?,hash: freezed == hash ? _self.hash : hash // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,size: null == size ? _self.size : size // ignore: cast_nullable_to_non_nullable
|
as 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
|
// dart format on
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ _UniversalFile _$UniversalFileFromJson(Map<String, dynamic> json) =>
|
|||||||
data: json['data'],
|
data: json['data'],
|
||||||
type: $enumDecode(_$UniversalFileTypeEnumMap, json['type']),
|
type: $enumDecode(_$UniversalFileTypeEnumMap, json['type']),
|
||||||
isLink: json['is_link'] as bool? ?? false,
|
isLink: json['is_link'] as bool? ?? false,
|
||||||
|
displayName: json['display_name'] as String?,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$UniversalFileToJson(_UniversalFile instance) =>
|
Map<String, dynamic> _$UniversalFileToJson(_UniversalFile instance) =>
|
||||||
@@ -18,6 +19,7 @@ Map<String, dynamic> _$UniversalFileToJson(_UniversalFile instance) =>
|
|||||||
'data': instance.data,
|
'data': instance.data,
|
||||||
'type': _$UniversalFileTypeEnumMap[instance.type]!,
|
'type': _$UniversalFileTypeEnumMap[instance.type]!,
|
||||||
'is_link': instance.isLink,
|
'is_link': instance.isLink,
|
||||||
|
'display_name': instance.displayName,
|
||||||
};
|
};
|
||||||
|
|
||||||
const _$UniversalFileTypeEnumMap = {
|
const _$UniversalFileTypeEnumMap = {
|
||||||
@@ -33,6 +35,10 @@ _SnCloudFile _$SnCloudFileFromJson(Map<String, dynamic> json) => _SnCloudFile(
|
|||||||
description: json['description'] as String?,
|
description: json['description'] as String?,
|
||||||
fileMeta: json['file_meta'] as Map<String, dynamic>?,
|
fileMeta: json['file_meta'] as Map<String, dynamic>?,
|
||||||
userMeta: json['user_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:
|
sensitiveMarks:
|
||||||
(json['sensitive_marks'] as List<dynamic>?)
|
(json['sensitive_marks'] as List<dynamic>?)
|
||||||
?.map((e) => (e as num).toInt())
|
?.map((e) => (e as num).toInt())
|
||||||
@@ -61,6 +67,7 @@ Map<String, dynamic> _$SnCloudFileToJson(_SnCloudFile instance) =>
|
|||||||
'description': instance.description,
|
'description': instance.description,
|
||||||
'file_meta': instance.fileMeta,
|
'file_meta': instance.fileMeta,
|
||||||
'user_meta': instance.userMeta,
|
'user_meta': instance.userMeta,
|
||||||
|
'pool': instance.pool?.toJson(),
|
||||||
'sensitive_marks': instance.sensitiveMarks,
|
'sensitive_marks': instance.sensitiveMarks,
|
||||||
'mime_type': instance.mimeType,
|
'mime_type': instance.mimeType,
|
||||||
'hash': instance.hash,
|
'hash': instance.hash,
|
||||||
|
|||||||
25
lib/models/file_pool.dart
Normal file
25
lib/models/file_pool.dart
Normal 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);
|
||||||
|
}
|
||||||
328
lib/models/file_pool.freezed.dart
Normal file
328
lib/models/file_pool.freezed.dart
Normal 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
|
||||||
47
lib/models/file_pool.g.dart
Normal file
47
lib/models/file_pool.g.dart
Normal 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
26
lib/models/heatmap.dart
Normal 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);
|
||||||
|
}
|
||||||
546
lib/models/heatmap.freezed.dart
Normal file
546
lib/models/heatmap.freezed.dart
Normal 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
37
lib/models/heatmap.g.dart
Normal 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,
|
||||||
|
};
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'package:island/models/account.dart';
|
||||||
import 'package:island/models/publisher.dart';
|
import 'package:island/models/publisher.dart';
|
||||||
|
|
||||||
part 'poll.freezed.dart';
|
part 'poll.freezed.dart';
|
||||||
@@ -101,6 +102,7 @@ sealed class SnPollAnswer with _$SnPollAnswer {
|
|||||||
required DateTime createdAt,
|
required DateTime createdAt,
|
||||||
required DateTime updatedAt,
|
required DateTime updatedAt,
|
||||||
required DateTime? deletedAt,
|
required DateTime? deletedAt,
|
||||||
|
SnAccount? account,
|
||||||
}) = _SnPollAnswer;
|
}) = _SnPollAnswer;
|
||||||
|
|
||||||
factory SnPollAnswer.fromJson(Map<String, dynamic> json) =>
|
factory SnPollAnswer.fromJson(Map<String, dynamic> json) =>
|
||||||
|
|||||||
@@ -1187,7 +1187,7 @@ as int,
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$SnPollAnswer {
|
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
|
/// Create a copy of SnPollAnswer
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@@ -1200,16 +1200,16 @@ $SnPollAnswerCopyWith<SnPollAnswer> get copyWith => _$SnPollAnswerCopyWithImpl<S
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
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)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@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
|
@override
|
||||||
String toString() {
|
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;
|
factory $SnPollAnswerCopyWith(SnPollAnswer value, $Res Function(SnPollAnswer) _then) = _$SnPollAnswerCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$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
|
/// @nodoc
|
||||||
@@ -1237,7 +1237,7 @@ class _$SnPollAnswerCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnPollAnswer
|
/// Create a copy of SnPollAnswer
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? 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(
|
return _then(_self.copyWith(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,answer: null == answer ? _self.answer : answer // 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 String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,
|
as DateTime?,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) {
|
switch (_that) {
|
||||||
case _SnPollAnswer() when $default != null:
|
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();
|
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) {
|
switch (_that) {
|
||||||
case _SnPollAnswer():
|
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`
|
/// 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) {
|
switch (_that) {
|
||||||
case _SnPollAnswer() when $default != null:
|
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;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1381,7 +1394,7 @@ return $default(_that.id,_that.answer,_that.accountId,_that.pollId,_that.created
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _SnPollAnswer implements SnPollAnswer {
|
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);
|
factory _SnPollAnswer.fromJson(Map<String, dynamic> json) => _$SnPollAnswerFromJson(json);
|
||||||
|
|
||||||
@override final String id;
|
@override final String id;
|
||||||
@@ -1397,6 +1410,7 @@ class _SnPollAnswer implements SnPollAnswer {
|
|||||||
@override final DateTime createdAt;
|
@override final DateTime createdAt;
|
||||||
@override final DateTime updatedAt;
|
@override final DateTime updatedAt;
|
||||||
@override final DateTime? deletedAt;
|
@override final DateTime? deletedAt;
|
||||||
|
@override final SnAccount? account;
|
||||||
|
|
||||||
/// Create a copy of SnPollAnswer
|
/// Create a copy of SnPollAnswer
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@@ -1411,16 +1425,16 @@ Map<String, dynamic> toJson() {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
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)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@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
|
@override
|
||||||
String toString() {
|
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;
|
factory _$SnPollAnswerCopyWith(_SnPollAnswer value, $Res Function(_SnPollAnswer) _then) = __$SnPollAnswerCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$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
|
/// @nodoc
|
||||||
@@ -1448,7 +1462,7 @@ class __$SnPollAnswerCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnPollAnswer
|
/// Create a copy of SnPollAnswer
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? 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(
|
return _then(_SnPollAnswer(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,answer: null == answer ? _self._answer : answer // 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 String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,
|
as DateTime?,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
|
// dart format on
|
||||||
|
|||||||
@@ -144,6 +144,10 @@ _SnPollAnswer _$SnPollAnswerFromJson(Map<String, dynamic> json) =>
|
|||||||
json['deleted_at'] == null
|
json['deleted_at'] == null
|
||||||
? null
|
? null
|
||||||
: DateTime.parse(json['deleted_at'] as String),
|
: 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) =>
|
Map<String, dynamic> _$SnPollAnswerToJson(_SnPollAnswer instance) =>
|
||||||
@@ -155,4 +159,5 @@ Map<String, dynamic> _$SnPollAnswerToJson(_SnPollAnswer instance) =>
|
|||||||
'created_at': instance.createdAt.toIso8601String(),
|
'created_at': instance.createdAt.toIso8601String(),
|
||||||
'updated_at': instance.updatedAt.toIso8601String(),
|
'updated_at': instance.updatedAt.toIso8601String(),
|
||||||
'deleted_at': instance.deletedAt?.toIso8601String(),
|
'deleted_at': instance.deletedAt?.toIso8601String(),
|
||||||
|
'account': instance.account?.toJson(),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'package:island/models/account.dart';
|
||||||
import 'package:island/models/file.dart';
|
import 'package:island/models/file.dart';
|
||||||
import 'package:island/models/post_category.dart';
|
import 'package:island/models/post_category.dart';
|
||||||
import 'package:island/models/post_tag.dart';
|
import 'package:island/models/post_tag.dart';
|
||||||
@@ -28,6 +29,7 @@ sealed class SnPost with _$SnPost {
|
|||||||
@Default(0) int upvotes,
|
@Default(0) int upvotes,
|
||||||
@Default(0) int downvotes,
|
@Default(0) int downvotes,
|
||||||
@Default(0) int repliesCount,
|
@Default(0) int repliesCount,
|
||||||
|
@Default(0) int awardedScore,
|
||||||
int? pinMode,
|
int? pinMode,
|
||||||
String? threadedPostId,
|
String? threadedPostId,
|
||||||
SnPost? threadedPost,
|
SnPost? threadedPost,
|
||||||
@@ -123,3 +125,39 @@ sealed class SnPostEmbedView with _$SnPostEmbedView {
|
|||||||
factory SnPostEmbedView.fromJson(Map<String, dynamic> json) =>
|
factory SnPostEmbedView.fromJson(Map<String, dynamic> json) =>
|
||||||
_$SnPostEmbedViewFromJson(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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ T _$identity<T>(T value) => value;
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$SnPost {
|
mixin _$SnPost {
|
||||||
|
|
||||||
String get id; String? get title; String? get description; String? get language; DateTime? get editedAt; DateTime? get publishedAt; int get visibility; String? get content; String? get slug; int get type; Map<String, dynamic>? get meta; SnPostEmbedView? get embedView; int get viewsUnique; int get viewsTotal; int get upvotes; int get downvotes; int get repliesCount; int? get pinMode; String? get threadedPostId; SnPost? get threadedPost; String? get repliedPostId; SnPost? get repliedPost; String? get forwardedPostId; SnPost? get forwardedPost; String? get realmId; SnRealm? get realm; List<SnCloudFile> get attachments; SnPublisher get publisher; Map<String, int> get reactionsCount; Map<String, bool> get reactionsMade; List<dynamic> get reactions; List<SnPostTag> get tags; List<SnPostCategory> get categories; List<dynamic> get collections; DateTime? get createdAt; DateTime? get updatedAt; DateTime? get deletedAt; bool get isTruncated;
|
String get id; String? get title; String? get description; String? get language; DateTime? get editedAt; DateTime? get publishedAt; int get visibility; String? get content; String? get slug; int get type; Map<String, dynamic>? get meta; SnPostEmbedView? get embedView; int get viewsUnique; int get viewsTotal; int get upvotes; int get downvotes; int get repliesCount; int get awardedScore; int? get pinMode; String? get threadedPostId; SnPost? get threadedPost; String? get repliedPostId; SnPost? get repliedPost; String? get forwardedPostId; SnPost? get forwardedPost; String? get realmId; SnRealm? get realm; List<SnCloudFile> get attachments; SnPublisher get publisher; Map<String, int> get reactionsCount; Map<String, bool> get reactionsMade; List<dynamic> get reactions; List<SnPostTag> get tags; List<SnPostCategory> get categories; List<dynamic> get collections; DateTime? get createdAt; DateTime? get updatedAt; DateTime? get deletedAt; bool get isTruncated;
|
||||||
/// Create a copy of SnPost
|
/// Create a copy of SnPost
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@@ -28,16 +28,16 @@ $SnPostCopyWith<SnPost> get copyWith => _$SnPostCopyWithImpl<SnPost>(this as SnP
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPost&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.language, language) || other.language == language)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.visibility, visibility) || other.visibility == visibility)&&(identical(other.content, content) || other.content == content)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other.meta, meta)&&(identical(other.embedView, embedView) || other.embedView == embedView)&&(identical(other.viewsUnique, viewsUnique) || other.viewsUnique == viewsUnique)&&(identical(other.viewsTotal, viewsTotal) || other.viewsTotal == viewsTotal)&&(identical(other.upvotes, upvotes) || other.upvotes == upvotes)&&(identical(other.downvotes, downvotes) || other.downvotes == downvotes)&&(identical(other.repliesCount, repliesCount) || other.repliesCount == repliesCount)&&(identical(other.pinMode, pinMode) || other.pinMode == pinMode)&&(identical(other.threadedPostId, threadedPostId) || other.threadedPostId == threadedPostId)&&(identical(other.threadedPost, threadedPost) || other.threadedPost == threadedPost)&&(identical(other.repliedPostId, repliedPostId) || other.repliedPostId == repliedPostId)&&(identical(other.repliedPost, repliedPost) || other.repliedPost == repliedPost)&&(identical(other.forwardedPostId, forwardedPostId) || other.forwardedPostId == forwardedPostId)&&(identical(other.forwardedPost, forwardedPost) || other.forwardedPost == forwardedPost)&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&const DeepCollectionEquality().equals(other.attachments, attachments)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&const DeepCollectionEquality().equals(other.reactionsCount, reactionsCount)&&const DeepCollectionEquality().equals(other.reactionsMade, reactionsMade)&&const DeepCollectionEquality().equals(other.reactions, reactions)&&const DeepCollectionEquality().equals(other.tags, tags)&&const DeepCollectionEquality().equals(other.categories, categories)&&const DeepCollectionEquality().equals(other.collections, collections)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.isTruncated, isTruncated) || other.isTruncated == isTruncated));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPost&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.language, language) || other.language == language)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.visibility, visibility) || other.visibility == visibility)&&(identical(other.content, content) || other.content == content)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other.meta, meta)&&(identical(other.embedView, embedView) || other.embedView == embedView)&&(identical(other.viewsUnique, viewsUnique) || other.viewsUnique == viewsUnique)&&(identical(other.viewsTotal, viewsTotal) || other.viewsTotal == viewsTotal)&&(identical(other.upvotes, upvotes) || other.upvotes == upvotes)&&(identical(other.downvotes, downvotes) || other.downvotes == downvotes)&&(identical(other.repliesCount, repliesCount) || other.repliesCount == repliesCount)&&(identical(other.awardedScore, awardedScore) || other.awardedScore == awardedScore)&&(identical(other.pinMode, pinMode) || other.pinMode == pinMode)&&(identical(other.threadedPostId, threadedPostId) || other.threadedPostId == threadedPostId)&&(identical(other.threadedPost, threadedPost) || other.threadedPost == threadedPost)&&(identical(other.repliedPostId, repliedPostId) || other.repliedPostId == repliedPostId)&&(identical(other.repliedPost, repliedPost) || other.repliedPost == repliedPost)&&(identical(other.forwardedPostId, forwardedPostId) || other.forwardedPostId == forwardedPostId)&&(identical(other.forwardedPost, forwardedPost) || other.forwardedPost == forwardedPost)&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&const DeepCollectionEquality().equals(other.attachments, attachments)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&const DeepCollectionEquality().equals(other.reactionsCount, reactionsCount)&&const DeepCollectionEquality().equals(other.reactionsMade, reactionsMade)&&const DeepCollectionEquality().equals(other.reactions, reactions)&&const DeepCollectionEquality().equals(other.tags, tags)&&const DeepCollectionEquality().equals(other.categories, categories)&&const DeepCollectionEquality().equals(other.collections, collections)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.isTruncated, isTruncated) || other.isTruncated == isTruncated));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hashAll([runtimeType,id,title,description,language,editedAt,publishedAt,visibility,content,slug,type,const DeepCollectionEquality().hash(meta),embedView,viewsUnique,viewsTotal,upvotes,downvotes,repliesCount,pinMode,threadedPostId,threadedPost,repliedPostId,repliedPost,forwardedPostId,forwardedPost,realmId,realm,const DeepCollectionEquality().hash(attachments),publisher,const DeepCollectionEquality().hash(reactionsCount),const DeepCollectionEquality().hash(reactionsMade),const DeepCollectionEquality().hash(reactions),const DeepCollectionEquality().hash(tags),const DeepCollectionEquality().hash(categories),const DeepCollectionEquality().hash(collections),createdAt,updatedAt,deletedAt,isTruncated]);
|
int get hashCode => Object.hashAll([runtimeType,id,title,description,language,editedAt,publishedAt,visibility,content,slug,type,const DeepCollectionEquality().hash(meta),embedView,viewsUnique,viewsTotal,upvotes,downvotes,repliesCount,awardedScore,pinMode,threadedPostId,threadedPost,repliedPostId,repliedPost,forwardedPostId,forwardedPost,realmId,realm,const DeepCollectionEquality().hash(attachments),publisher,const DeepCollectionEquality().hash(reactionsCount),const DeepCollectionEquality().hash(reactionsMade),const DeepCollectionEquality().hash(reactions),const DeepCollectionEquality().hash(tags),const DeepCollectionEquality().hash(categories),const DeepCollectionEquality().hash(collections),createdAt,updatedAt,deletedAt,isTruncated]);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnPost(id: $id, title: $title, description: $description, language: $language, editedAt: $editedAt, publishedAt: $publishedAt, visibility: $visibility, content: $content, slug: $slug, type: $type, meta: $meta, embedView: $embedView, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, repliesCount: $repliesCount, pinMode: $pinMode, threadedPostId: $threadedPostId, threadedPost: $threadedPost, repliedPostId: $repliedPostId, repliedPost: $repliedPost, forwardedPostId: $forwardedPostId, forwardedPost: $forwardedPost, realmId: $realmId, realm: $realm, attachments: $attachments, publisher: $publisher, reactionsCount: $reactionsCount, reactionsMade: $reactionsMade, reactions: $reactions, tags: $tags, categories: $categories, collections: $collections, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, isTruncated: $isTruncated)';
|
return 'SnPost(id: $id, title: $title, description: $description, language: $language, editedAt: $editedAt, publishedAt: $publishedAt, visibility: $visibility, content: $content, slug: $slug, type: $type, meta: $meta, embedView: $embedView, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, repliesCount: $repliesCount, awardedScore: $awardedScore, pinMode: $pinMode, threadedPostId: $threadedPostId, threadedPost: $threadedPost, repliedPostId: $repliedPostId, repliedPost: $repliedPost, forwardedPostId: $forwardedPostId, forwardedPost: $forwardedPost, realmId: $realmId, realm: $realm, attachments: $attachments, publisher: $publisher, reactionsCount: $reactionsCount, reactionsMade: $reactionsMade, reactions: $reactions, tags: $tags, categories: $categories, collections: $collections, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, isTruncated: $isTruncated)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ abstract mixin class $SnPostCopyWith<$Res> {
|
|||||||
factory $SnPostCopyWith(SnPost value, $Res Function(SnPost) _then) = _$SnPostCopyWithImpl;
|
factory $SnPostCopyWith(SnPost value, $Res Function(SnPost) _then) = _$SnPostCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated
|
String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ class _$SnPostCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnPost
|
/// Create a copy of SnPost
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? title = freezed,Object? description = freezed,Object? language = freezed,Object? editedAt = freezed,Object? publishedAt = freezed,Object? visibility = null,Object? content = freezed,Object? slug = freezed,Object? type = null,Object? meta = freezed,Object? embedView = freezed,Object? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? repliesCount = null,Object? pinMode = freezed,Object? threadedPostId = freezed,Object? threadedPost = freezed,Object? repliedPostId = freezed,Object? repliedPost = freezed,Object? forwardedPostId = freezed,Object? forwardedPost = freezed,Object? realmId = freezed,Object? realm = freezed,Object? attachments = null,Object? publisher = null,Object? reactionsCount = null,Object? reactionsMade = null,Object? reactions = null,Object? tags = null,Object? categories = null,Object? collections = null,Object? createdAt = freezed,Object? updatedAt = freezed,Object? deletedAt = freezed,Object? isTruncated = null,}) {
|
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? title = freezed,Object? description = freezed,Object? language = freezed,Object? editedAt = freezed,Object? publishedAt = freezed,Object? visibility = null,Object? content = freezed,Object? slug = freezed,Object? type = null,Object? meta = freezed,Object? embedView = freezed,Object? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? repliesCount = null,Object? awardedScore = null,Object? pinMode = freezed,Object? threadedPostId = freezed,Object? threadedPost = freezed,Object? repliedPostId = freezed,Object? repliedPost = freezed,Object? forwardedPostId = freezed,Object? forwardedPost = freezed,Object? realmId = freezed,Object? realm = freezed,Object? attachments = null,Object? publisher = null,Object? reactionsCount = null,Object? reactionsMade = null,Object? reactions = null,Object? tags = null,Object? categories = null,Object? collections = null,Object? createdAt = freezed,Object? updatedAt = freezed,Object? deletedAt = freezed,Object? isTruncated = null,}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,title: freezed == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
as String,title: freezed == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -84,6 +84,7 @@ as int,viewsTotal: null == viewsTotal ? _self.viewsTotal : viewsTotal // ignore:
|
|||||||
as int,upvotes: null == upvotes ? _self.upvotes : upvotes // ignore: cast_nullable_to_non_nullable
|
as int,upvotes: null == upvotes ? _self.upvotes : upvotes // ignore: cast_nullable_to_non_nullable
|
||||||
as int,downvotes: null == downvotes ? _self.downvotes : downvotes // ignore: cast_nullable_to_non_nullable
|
as int,downvotes: null == downvotes ? _self.downvotes : downvotes // ignore: cast_nullable_to_non_nullable
|
||||||
as int,repliesCount: null == repliesCount ? _self.repliesCount : repliesCount // ignore: cast_nullable_to_non_nullable
|
as int,repliesCount: null == repliesCount ? _self.repliesCount : repliesCount // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,awardedScore: null == awardedScore ? _self.awardedScore : awardedScore // ignore: cast_nullable_to_non_nullable
|
||||||
as int,pinMode: freezed == pinMode ? _self.pinMode : pinMode // ignore: cast_nullable_to_non_nullable
|
as int,pinMode: freezed == pinMode ? _self.pinMode : pinMode // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,threadedPostId: freezed == threadedPostId ? _self.threadedPostId : threadedPostId // ignore: cast_nullable_to_non_nullable
|
as int?,threadedPostId: freezed == threadedPostId ? _self.threadedPostId : threadedPostId // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,threadedPost: freezed == threadedPost ? _self.threadedPost : threadedPost // ignore: cast_nullable_to_non_nullable
|
as String?,threadedPost: freezed == threadedPost ? _self.threadedPost : threadedPost // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -256,10 +257,10 @@ return $default(_that);case _:
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated)? $default,{required TResult orElse(),}) {final _that = this;
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _SnPost() when $default != null:
|
case _SnPost() when $default != null:
|
||||||
return $default(_that.id,_that.title,_that.description,_that.language,_that.editedAt,_that.publishedAt,_that.visibility,_that.content,_that.slug,_that.type,_that.meta,_that.embedView,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.pinMode,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.realmId,_that.realm,_that.attachments,_that.publisher,_that.reactionsCount,_that.reactionsMade,_that.reactions,_that.tags,_that.categories,_that.collections,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.isTruncated);case _:
|
return $default(_that.id,_that.title,_that.description,_that.language,_that.editedAt,_that.publishedAt,_that.visibility,_that.content,_that.slug,_that.type,_that.meta,_that.embedView,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.awardedScore,_that.pinMode,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.realmId,_that.realm,_that.attachments,_that.publisher,_that.reactionsCount,_that.reactionsMade,_that.reactions,_that.tags,_that.categories,_that.collections,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.isTruncated);case _:
|
||||||
return orElse();
|
return orElse();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -277,10 +278,10 @@ return $default(_that.id,_that.title,_that.description,_that.language,_that.edit
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated) $default,) {final _that = this;
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated) $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _SnPost():
|
case _SnPost():
|
||||||
return $default(_that.id,_that.title,_that.description,_that.language,_that.editedAt,_that.publishedAt,_that.visibility,_that.content,_that.slug,_that.type,_that.meta,_that.embedView,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.pinMode,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.realmId,_that.realm,_that.attachments,_that.publisher,_that.reactionsCount,_that.reactionsMade,_that.reactions,_that.tags,_that.categories,_that.collections,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.isTruncated);}
|
return $default(_that.id,_that.title,_that.description,_that.language,_that.editedAt,_that.publishedAt,_that.visibility,_that.content,_that.slug,_that.type,_that.meta,_that.embedView,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.awardedScore,_that.pinMode,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.realmId,_that.realm,_that.attachments,_that.publisher,_that.reactionsCount,_that.reactionsMade,_that.reactions,_that.tags,_that.categories,_that.collections,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.isTruncated);}
|
||||||
}
|
}
|
||||||
/// A variant of `when` that fallback to returning `null`
|
/// A variant of `when` that fallback to returning `null`
|
||||||
///
|
///
|
||||||
@@ -294,10 +295,10 @@ return $default(_that.id,_that.title,_that.description,_that.language,_that.edit
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated)? $default,) {final _that = this;
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated)? $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _SnPost() when $default != null:
|
case _SnPost() when $default != null:
|
||||||
return $default(_that.id,_that.title,_that.description,_that.language,_that.editedAt,_that.publishedAt,_that.visibility,_that.content,_that.slug,_that.type,_that.meta,_that.embedView,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.pinMode,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.realmId,_that.realm,_that.attachments,_that.publisher,_that.reactionsCount,_that.reactionsMade,_that.reactions,_that.tags,_that.categories,_that.collections,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.isTruncated);case _:
|
return $default(_that.id,_that.title,_that.description,_that.language,_that.editedAt,_that.publishedAt,_that.visibility,_that.content,_that.slug,_that.type,_that.meta,_that.embedView,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.awardedScore,_that.pinMode,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.realmId,_that.realm,_that.attachments,_that.publisher,_that.reactionsCount,_that.reactionsMade,_that.reactions,_that.tags,_that.categories,_that.collections,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.isTruncated);case _:
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -309,7 +310,7 @@ return $default(_that.id,_that.title,_that.description,_that.language,_that.edit
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _SnPost implements SnPost {
|
class _SnPost implements SnPost {
|
||||||
const _SnPost({required this.id, this.title, this.description, this.language, this.editedAt, this.publishedAt = null, this.visibility = 0, this.content, this.slug, this.type = 0, final Map<String, dynamic>? meta, this.embedView, this.viewsUnique = 0, this.viewsTotal = 0, this.upvotes = 0, this.downvotes = 0, this.repliesCount = 0, this.pinMode, this.threadedPostId, this.threadedPost, this.repliedPostId, this.repliedPost, this.forwardedPostId, this.forwardedPost, this.realmId, this.realm, final List<SnCloudFile> attachments = const [], required this.publisher, final Map<String, int> reactionsCount = const {}, final Map<String, bool> reactionsMade = const {}, final List<dynamic> reactions = const [], final List<SnPostTag> tags = const [], final List<SnPostCategory> categories = const [], final List<dynamic> collections = const [], this.createdAt = null, this.updatedAt = null, this.deletedAt, this.isTruncated = false}): _meta = meta,_attachments = attachments,_reactionsCount = reactionsCount,_reactionsMade = reactionsMade,_reactions = reactions,_tags = tags,_categories = categories,_collections = collections;
|
const _SnPost({required this.id, this.title, this.description, this.language, this.editedAt, this.publishedAt = null, this.visibility = 0, this.content, this.slug, this.type = 0, final Map<String, dynamic>? meta, this.embedView, this.viewsUnique = 0, this.viewsTotal = 0, this.upvotes = 0, this.downvotes = 0, this.repliesCount = 0, this.awardedScore = 0, this.pinMode, this.threadedPostId, this.threadedPost, this.repliedPostId, this.repliedPost, this.forwardedPostId, this.forwardedPost, this.realmId, this.realm, final List<SnCloudFile> attachments = const [], required this.publisher, final Map<String, int> reactionsCount = const {}, final Map<String, bool> reactionsMade = const {}, final List<dynamic> reactions = const [], final List<SnPostTag> tags = const [], final List<SnPostCategory> categories = const [], final List<dynamic> collections = const [], this.createdAt = null, this.updatedAt = null, this.deletedAt, this.isTruncated = false}): _meta = meta,_attachments = attachments,_reactionsCount = reactionsCount,_reactionsMade = reactionsMade,_reactions = reactions,_tags = tags,_categories = categories,_collections = collections;
|
||||||
factory _SnPost.fromJson(Map<String, dynamic> json) => _$SnPostFromJson(json);
|
factory _SnPost.fromJson(Map<String, dynamic> json) => _$SnPostFromJson(json);
|
||||||
|
|
||||||
@override final String id;
|
@override final String id;
|
||||||
@@ -337,6 +338,7 @@ class _SnPost implements SnPost {
|
|||||||
@override@JsonKey() final int upvotes;
|
@override@JsonKey() final int upvotes;
|
||||||
@override@JsonKey() final int downvotes;
|
@override@JsonKey() final int downvotes;
|
||||||
@override@JsonKey() final int repliesCount;
|
@override@JsonKey() final int repliesCount;
|
||||||
|
@override@JsonKey() final int awardedScore;
|
||||||
@override final int? pinMode;
|
@override final int? pinMode;
|
||||||
@override final String? threadedPostId;
|
@override final String? threadedPostId;
|
||||||
@override final SnPost? threadedPost;
|
@override final SnPost? threadedPost;
|
||||||
@@ -414,16 +416,16 @@ Map<String, dynamic> toJson() {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPost&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.language, language) || other.language == language)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.visibility, visibility) || other.visibility == visibility)&&(identical(other.content, content) || other.content == content)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other._meta, _meta)&&(identical(other.embedView, embedView) || other.embedView == embedView)&&(identical(other.viewsUnique, viewsUnique) || other.viewsUnique == viewsUnique)&&(identical(other.viewsTotal, viewsTotal) || other.viewsTotal == viewsTotal)&&(identical(other.upvotes, upvotes) || other.upvotes == upvotes)&&(identical(other.downvotes, downvotes) || other.downvotes == downvotes)&&(identical(other.repliesCount, repliesCount) || other.repliesCount == repliesCount)&&(identical(other.pinMode, pinMode) || other.pinMode == pinMode)&&(identical(other.threadedPostId, threadedPostId) || other.threadedPostId == threadedPostId)&&(identical(other.threadedPost, threadedPost) || other.threadedPost == threadedPost)&&(identical(other.repliedPostId, repliedPostId) || other.repliedPostId == repliedPostId)&&(identical(other.repliedPost, repliedPost) || other.repliedPost == repliedPost)&&(identical(other.forwardedPostId, forwardedPostId) || other.forwardedPostId == forwardedPostId)&&(identical(other.forwardedPost, forwardedPost) || other.forwardedPost == forwardedPost)&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&const DeepCollectionEquality().equals(other._attachments, _attachments)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&const DeepCollectionEquality().equals(other._reactionsCount, _reactionsCount)&&const DeepCollectionEquality().equals(other._reactionsMade, _reactionsMade)&&const DeepCollectionEquality().equals(other._reactions, _reactions)&&const DeepCollectionEquality().equals(other._tags, _tags)&&const DeepCollectionEquality().equals(other._categories, _categories)&&const DeepCollectionEquality().equals(other._collections, _collections)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.isTruncated, isTruncated) || other.isTruncated == isTruncated));
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPost&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.language, language) || other.language == language)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.visibility, visibility) || other.visibility == visibility)&&(identical(other.content, content) || other.content == content)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other._meta, _meta)&&(identical(other.embedView, embedView) || other.embedView == embedView)&&(identical(other.viewsUnique, viewsUnique) || other.viewsUnique == viewsUnique)&&(identical(other.viewsTotal, viewsTotal) || other.viewsTotal == viewsTotal)&&(identical(other.upvotes, upvotes) || other.upvotes == upvotes)&&(identical(other.downvotes, downvotes) || other.downvotes == downvotes)&&(identical(other.repliesCount, repliesCount) || other.repliesCount == repliesCount)&&(identical(other.awardedScore, awardedScore) || other.awardedScore == awardedScore)&&(identical(other.pinMode, pinMode) || other.pinMode == pinMode)&&(identical(other.threadedPostId, threadedPostId) || other.threadedPostId == threadedPostId)&&(identical(other.threadedPost, threadedPost) || other.threadedPost == threadedPost)&&(identical(other.repliedPostId, repliedPostId) || other.repliedPostId == repliedPostId)&&(identical(other.repliedPost, repliedPost) || other.repliedPost == repliedPost)&&(identical(other.forwardedPostId, forwardedPostId) || other.forwardedPostId == forwardedPostId)&&(identical(other.forwardedPost, forwardedPost) || other.forwardedPost == forwardedPost)&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&const DeepCollectionEquality().equals(other._attachments, _attachments)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&const DeepCollectionEquality().equals(other._reactionsCount, _reactionsCount)&&const DeepCollectionEquality().equals(other._reactionsMade, _reactionsMade)&&const DeepCollectionEquality().equals(other._reactions, _reactions)&&const DeepCollectionEquality().equals(other._tags, _tags)&&const DeepCollectionEquality().equals(other._categories, _categories)&&const DeepCollectionEquality().equals(other._collections, _collections)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.isTruncated, isTruncated) || other.isTruncated == isTruncated));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hashAll([runtimeType,id,title,description,language,editedAt,publishedAt,visibility,content,slug,type,const DeepCollectionEquality().hash(_meta),embedView,viewsUnique,viewsTotal,upvotes,downvotes,repliesCount,pinMode,threadedPostId,threadedPost,repliedPostId,repliedPost,forwardedPostId,forwardedPost,realmId,realm,const DeepCollectionEquality().hash(_attachments),publisher,const DeepCollectionEquality().hash(_reactionsCount),const DeepCollectionEquality().hash(_reactionsMade),const DeepCollectionEquality().hash(_reactions),const DeepCollectionEquality().hash(_tags),const DeepCollectionEquality().hash(_categories),const DeepCollectionEquality().hash(_collections),createdAt,updatedAt,deletedAt,isTruncated]);
|
int get hashCode => Object.hashAll([runtimeType,id,title,description,language,editedAt,publishedAt,visibility,content,slug,type,const DeepCollectionEquality().hash(_meta),embedView,viewsUnique,viewsTotal,upvotes,downvotes,repliesCount,awardedScore,pinMode,threadedPostId,threadedPost,repliedPostId,repliedPost,forwardedPostId,forwardedPost,realmId,realm,const DeepCollectionEquality().hash(_attachments),publisher,const DeepCollectionEquality().hash(_reactionsCount),const DeepCollectionEquality().hash(_reactionsMade),const DeepCollectionEquality().hash(_reactions),const DeepCollectionEquality().hash(_tags),const DeepCollectionEquality().hash(_categories),const DeepCollectionEquality().hash(_collections),createdAt,updatedAt,deletedAt,isTruncated]);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnPost(id: $id, title: $title, description: $description, language: $language, editedAt: $editedAt, publishedAt: $publishedAt, visibility: $visibility, content: $content, slug: $slug, type: $type, meta: $meta, embedView: $embedView, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, repliesCount: $repliesCount, pinMode: $pinMode, threadedPostId: $threadedPostId, threadedPost: $threadedPost, repliedPostId: $repliedPostId, repliedPost: $repliedPost, forwardedPostId: $forwardedPostId, forwardedPost: $forwardedPost, realmId: $realmId, realm: $realm, attachments: $attachments, publisher: $publisher, reactionsCount: $reactionsCount, reactionsMade: $reactionsMade, reactions: $reactions, tags: $tags, categories: $categories, collections: $collections, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, isTruncated: $isTruncated)';
|
return 'SnPost(id: $id, title: $title, description: $description, language: $language, editedAt: $editedAt, publishedAt: $publishedAt, visibility: $visibility, content: $content, slug: $slug, type: $type, meta: $meta, embedView: $embedView, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, repliesCount: $repliesCount, awardedScore: $awardedScore, pinMode: $pinMode, threadedPostId: $threadedPostId, threadedPost: $threadedPost, repliedPostId: $repliedPostId, repliedPost: $repliedPost, forwardedPostId: $forwardedPostId, forwardedPost: $forwardedPost, realmId: $realmId, realm: $realm, attachments: $attachments, publisher: $publisher, reactionsCount: $reactionsCount, reactionsMade: $reactionsMade, reactions: $reactions, tags: $tags, categories: $categories, collections: $collections, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, isTruncated: $isTruncated)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -434,7 +436,7 @@ abstract mixin class _$SnPostCopyWith<$Res> implements $SnPostCopyWith<$Res> {
|
|||||||
factory _$SnPostCopyWith(_SnPost value, $Res Function(_SnPost) _then) = __$SnPostCopyWithImpl;
|
factory _$SnPostCopyWith(_SnPost value, $Res Function(_SnPost) _then) = __$SnPostCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated
|
String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map<String, dynamic>? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, Map<String, bool> reactionsMade, List<dynamic> reactions, List<SnPostTag> tags, List<SnPostCategory> categories, List<dynamic> collections, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool isTruncated
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -451,7 +453,7 @@ class __$SnPostCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of SnPost
|
/// Create a copy of SnPost
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? title = freezed,Object? description = freezed,Object? language = freezed,Object? editedAt = freezed,Object? publishedAt = freezed,Object? visibility = null,Object? content = freezed,Object? slug = freezed,Object? type = null,Object? meta = freezed,Object? embedView = freezed,Object? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? repliesCount = null,Object? pinMode = freezed,Object? threadedPostId = freezed,Object? threadedPost = freezed,Object? repliedPostId = freezed,Object? repliedPost = freezed,Object? forwardedPostId = freezed,Object? forwardedPost = freezed,Object? realmId = freezed,Object? realm = freezed,Object? attachments = null,Object? publisher = null,Object? reactionsCount = null,Object? reactionsMade = null,Object? reactions = null,Object? tags = null,Object? categories = null,Object? collections = null,Object? createdAt = freezed,Object? updatedAt = freezed,Object? deletedAt = freezed,Object? isTruncated = null,}) {
|
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? title = freezed,Object? description = freezed,Object? language = freezed,Object? editedAt = freezed,Object? publishedAt = freezed,Object? visibility = null,Object? content = freezed,Object? slug = freezed,Object? type = null,Object? meta = freezed,Object? embedView = freezed,Object? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? repliesCount = null,Object? awardedScore = null,Object? pinMode = freezed,Object? threadedPostId = freezed,Object? threadedPost = freezed,Object? repliedPostId = freezed,Object? repliedPost = freezed,Object? forwardedPostId = freezed,Object? forwardedPost = freezed,Object? realmId = freezed,Object? realm = freezed,Object? attachments = null,Object? publisher = null,Object? reactionsCount = null,Object? reactionsMade = null,Object? reactions = null,Object? tags = null,Object? categories = null,Object? collections = null,Object? createdAt = freezed,Object? updatedAt = freezed,Object? deletedAt = freezed,Object? isTruncated = null,}) {
|
||||||
return _then(_SnPost(
|
return _then(_SnPost(
|
||||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
as String,title: freezed == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
as String,title: freezed == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -470,6 +472,7 @@ as int,viewsTotal: null == viewsTotal ? _self.viewsTotal : viewsTotal // ignore:
|
|||||||
as int,upvotes: null == upvotes ? _self.upvotes : upvotes // ignore: cast_nullable_to_non_nullable
|
as int,upvotes: null == upvotes ? _self.upvotes : upvotes // ignore: cast_nullable_to_non_nullable
|
||||||
as int,downvotes: null == downvotes ? _self.downvotes : downvotes // ignore: cast_nullable_to_non_nullable
|
as int,downvotes: null == downvotes ? _self.downvotes : downvotes // ignore: cast_nullable_to_non_nullable
|
||||||
as int,repliesCount: null == repliesCount ? _self.repliesCount : repliesCount // ignore: cast_nullable_to_non_nullable
|
as int,repliesCount: null == repliesCount ? _self.repliesCount : repliesCount // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,awardedScore: null == awardedScore ? _self.awardedScore : awardedScore // ignore: cast_nullable_to_non_nullable
|
||||||
as int,pinMode: freezed == pinMode ? _self.pinMode : pinMode // ignore: cast_nullable_to_non_nullable
|
as int,pinMode: freezed == pinMode ? _self.pinMode : pinMode // ignore: cast_nullable_to_non_nullable
|
||||||
as int?,threadedPostId: freezed == threadedPostId ? _self.threadedPostId : threadedPostId // ignore: cast_nullable_to_non_nullable
|
as int?,threadedPostId: freezed == threadedPostId ? _self.threadedPostId : threadedPostId // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,threadedPost: freezed == threadedPost ? _self.threadedPost : threadedPost // ignore: cast_nullable_to_non_nullable
|
as String?,threadedPost: freezed == threadedPost ? _self.threadedPost : threadedPost // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -1616,4 +1619,590 @@ as PostEmbedViewRenderer,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$SnPostAward {
|
||||||
|
|
||||||
|
String get id; double get amount; int get attitude; String? get message; String get postId; String get accountId; DateTime? get createdAt; DateTime? get updatedAt; DateTime? get deletedAt;
|
||||||
|
/// Create a copy of SnPostAward
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnPostAwardCopyWith<SnPostAward> get copyWith => _$SnPostAwardCopyWithImpl<SnPostAward>(this as SnPostAward, _$identity);
|
||||||
|
|
||||||
|
/// Serializes this SnPostAward to a JSON map.
|
||||||
|
Map<String, dynamic> toJson();
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPostAward&&(identical(other.id, id) || other.id == id)&&(identical(other.amount, amount) || other.amount == amount)&&(identical(other.attitude, attitude) || other.attitude == attitude)&&(identical(other.message, message) || other.message == message)&&(identical(other.postId, postId) || other.postId == postId)&&(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,amount,attitude,message,postId,accountId,createdAt,updatedAt,deletedAt);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'SnPostAward(id: $id, amount: $amount, attitude: $attitude, message: $message, postId: $postId, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $SnPostAwardCopyWith<$Res> {
|
||||||
|
factory $SnPostAwardCopyWith(SnPostAward value, $Res Function(SnPostAward) _then) = _$SnPostAwardCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
String id, double amount, int attitude, String? message, String postId, String accountId, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$SnPostAwardCopyWithImpl<$Res>
|
||||||
|
implements $SnPostAwardCopyWith<$Res> {
|
||||||
|
_$SnPostAwardCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final SnPostAward _self;
|
||||||
|
final $Res Function(SnPostAward) _then;
|
||||||
|
|
||||||
|
/// Create a copy of SnPostAward
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? amount = null,Object? attitude = null,Object? message = freezed,Object? postId = null,Object? accountId = null,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,amount: null == amount ? _self.amount : amount // ignore: cast_nullable_to_non_nullable
|
||||||
|
as double,attitude: null == attitude ? _self.attitude : attitude // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,message: freezed == message ? _self.message : message // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,postId: null == postId ? _self.postId : postId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,accountId: null == accountId ? _self.accountId : accountId // 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 [SnPostAward].
|
||||||
|
extension SnPostAwardPatterns on SnPostAward {
|
||||||
|
/// 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( _SnPostAward value)? $default,{required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SnPostAward() 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( _SnPostAward value) $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SnPostAward():
|
||||||
|
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( _SnPostAward value)? $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SnPostAward() 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, double amount, int attitude, String? message, String postId, String accountId, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SnPostAward() when $default != null:
|
||||||
|
return $default(_that.id,_that.amount,_that.attitude,_that.message,_that.postId,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, double amount, int attitude, String? message, String postId, String accountId, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt) $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SnPostAward():
|
||||||
|
return $default(_that.id,_that.amount,_that.attitude,_that.message,_that.postId,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, double amount, int attitude, String? message, String postId, String accountId, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt)? $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SnPostAward() when $default != null:
|
||||||
|
return $default(_that.id,_that.amount,_that.attitude,_that.message,_that.postId,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
|
||||||
|
class _SnPostAward implements SnPostAward {
|
||||||
|
const _SnPostAward({required this.id, required this.amount, required this.attitude, this.message, required this.postId, required this.accountId, this.createdAt = null, this.updatedAt = null, this.deletedAt});
|
||||||
|
factory _SnPostAward.fromJson(Map<String, dynamic> json) => _$SnPostAwardFromJson(json);
|
||||||
|
|
||||||
|
@override final String id;
|
||||||
|
@override final double amount;
|
||||||
|
@override final int attitude;
|
||||||
|
@override final String? message;
|
||||||
|
@override final String postId;
|
||||||
|
@override final String accountId;
|
||||||
|
@override@JsonKey() final DateTime? createdAt;
|
||||||
|
@override@JsonKey() final DateTime? updatedAt;
|
||||||
|
@override final DateTime? deletedAt;
|
||||||
|
|
||||||
|
/// Create a copy of SnPostAward
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$SnPostAwardCopyWith<_SnPostAward> get copyWith => __$SnPostAwardCopyWithImpl<_SnPostAward>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$SnPostAwardToJson(this, );
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPostAward&&(identical(other.id, id) || other.id == id)&&(identical(other.amount, amount) || other.amount == amount)&&(identical(other.attitude, attitude) || other.attitude == attitude)&&(identical(other.message, message) || other.message == message)&&(identical(other.postId, postId) || other.postId == postId)&&(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,amount,attitude,message,postId,accountId,createdAt,updatedAt,deletedAt);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'SnPostAward(id: $id, amount: $amount, attitude: $attitude, message: $message, postId: $postId, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$SnPostAwardCopyWith<$Res> implements $SnPostAwardCopyWith<$Res> {
|
||||||
|
factory _$SnPostAwardCopyWith(_SnPostAward value, $Res Function(_SnPostAward) _then) = __$SnPostAwardCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
String id, double amount, int attitude, String? message, String postId, String accountId, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$SnPostAwardCopyWithImpl<$Res>
|
||||||
|
implements _$SnPostAwardCopyWith<$Res> {
|
||||||
|
__$SnPostAwardCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _SnPostAward _self;
|
||||||
|
final $Res Function(_SnPostAward) _then;
|
||||||
|
|
||||||
|
/// Create a copy of SnPostAward
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? amount = null,Object? attitude = null,Object? message = freezed,Object? postId = null,Object? accountId = null,Object? createdAt = freezed,Object? updatedAt = freezed,Object? deletedAt = freezed,}) {
|
||||||
|
return _then(_SnPostAward(
|
||||||
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,amount: null == amount ? _self.amount : amount // ignore: cast_nullable_to_non_nullable
|
||||||
|
as double,attitude: null == attitude ? _self.attitude : attitude // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,message: freezed == message ? _self.message : message // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,postId: null == postId ? _self.postId : postId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,accountId: null == accountId ? _self.accountId : accountId // 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?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$SnPostReaction {
|
||||||
|
|
||||||
|
String get id; String get symbol; int get attitude; String get postId; String get accountId; DateTime get createdAt; DateTime get updatedAt; SnAccount? get account; DateTime? get deletedAt;
|
||||||
|
/// Create a copy of SnPostReaction
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnPostReactionCopyWith<SnPostReaction> get copyWith => _$SnPostReactionCopyWithImpl<SnPostReaction>(this as SnPostReaction, _$identity);
|
||||||
|
|
||||||
|
/// Serializes this SnPostReaction to a JSON map.
|
||||||
|
Map<String, dynamic> toJson();
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPostReaction&&(identical(other.id, id) || other.id == id)&&(identical(other.symbol, symbol) || other.symbol == symbol)&&(identical(other.attitude, attitude) || other.attitude == attitude)&&(identical(other.postId, postId) || other.postId == postId)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.account, account) || other.account == account)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,id,symbol,attitude,postId,accountId,createdAt,updatedAt,account,deletedAt);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'SnPostReaction(id: $id, symbol: $symbol, attitude: $attitude, postId: $postId, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, account: $account, deletedAt: $deletedAt)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $SnPostReactionCopyWith<$Res> {
|
||||||
|
factory $SnPostReactionCopyWith(SnPostReaction value, $Res Function(SnPostReaction) _then) = _$SnPostReactionCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
String id, String symbol, int attitude, String postId, String accountId, DateTime createdAt, DateTime updatedAt, SnAccount? account, DateTime? deletedAt
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$SnAccountCopyWith<$Res>? get account;
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$SnPostReactionCopyWithImpl<$Res>
|
||||||
|
implements $SnPostReactionCopyWith<$Res> {
|
||||||
|
_$SnPostReactionCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final SnPostReaction _self;
|
||||||
|
final $Res Function(SnPostReaction) _then;
|
||||||
|
|
||||||
|
/// Create a copy of SnPostReaction
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? symbol = null,Object? attitude = null,Object? postId = null,Object? accountId = null,Object? createdAt = null,Object? updatedAt = null,Object? account = freezed,Object? deletedAt = freezed,}) {
|
||||||
|
return _then(_self.copyWith(
|
||||||
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,symbol: null == symbol ? _self.symbol : symbol // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,attitude: null == attitude ? _self.attitude : attitude // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,postId: null == postId ? _self.postId : postId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnAccount?,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
/// Create a copy of SnPostReaction
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnAccountCopyWith<$Res>? get account {
|
||||||
|
if (_self.account == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SnAccountCopyWith<$Res>(_self.account!, (value) {
|
||||||
|
return _then(_self.copyWith(account: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [SnPostReaction].
|
||||||
|
extension SnPostReactionPatterns on SnPostReaction {
|
||||||
|
/// 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( _SnPostReaction value)? $default,{required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SnPostReaction() 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( _SnPostReaction value) $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SnPostReaction():
|
||||||
|
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( _SnPostReaction value)? $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SnPostReaction() 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 symbol, int attitude, String postId, String accountId, DateTime createdAt, DateTime updatedAt, SnAccount? account, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SnPostReaction() when $default != null:
|
||||||
|
return $default(_that.id,_that.symbol,_that.attitude,_that.postId,_that.accountId,_that.createdAt,_that.updatedAt,_that.account,_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 symbol, int attitude, String postId, String accountId, DateTime createdAt, DateTime updatedAt, SnAccount? account, DateTime? deletedAt) $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SnPostReaction():
|
||||||
|
return $default(_that.id,_that.symbol,_that.attitude,_that.postId,_that.accountId,_that.createdAt,_that.updatedAt,_that.account,_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 symbol, int attitude, String postId, String accountId, DateTime createdAt, DateTime updatedAt, SnAccount? account, DateTime? deletedAt)? $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SnPostReaction() when $default != null:
|
||||||
|
return $default(_that.id,_that.symbol,_that.attitude,_that.postId,_that.accountId,_that.createdAt,_that.updatedAt,_that.account,_that.deletedAt);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
|
||||||
|
class _SnPostReaction implements SnPostReaction {
|
||||||
|
const _SnPostReaction({required this.id, required this.symbol, required this.attitude, required this.postId, required this.accountId, required this.createdAt, required this.updatedAt, this.account = null, this.deletedAt});
|
||||||
|
factory _SnPostReaction.fromJson(Map<String, dynamic> json) => _$SnPostReactionFromJson(json);
|
||||||
|
|
||||||
|
@override final String id;
|
||||||
|
@override final String symbol;
|
||||||
|
@override final int attitude;
|
||||||
|
@override final String postId;
|
||||||
|
@override final String accountId;
|
||||||
|
@override final DateTime createdAt;
|
||||||
|
@override final DateTime updatedAt;
|
||||||
|
@override@JsonKey() final SnAccount? account;
|
||||||
|
@override final DateTime? deletedAt;
|
||||||
|
|
||||||
|
/// Create a copy of SnPostReaction
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$SnPostReactionCopyWith<_SnPostReaction> get copyWith => __$SnPostReactionCopyWithImpl<_SnPostReaction>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$SnPostReactionToJson(this, );
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPostReaction&&(identical(other.id, id) || other.id == id)&&(identical(other.symbol, symbol) || other.symbol == symbol)&&(identical(other.attitude, attitude) || other.attitude == attitude)&&(identical(other.postId, postId) || other.postId == postId)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.account, account) || other.account == account)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,id,symbol,attitude,postId,accountId,createdAt,updatedAt,account,deletedAt);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'SnPostReaction(id: $id, symbol: $symbol, attitude: $attitude, postId: $postId, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, account: $account, deletedAt: $deletedAt)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$SnPostReactionCopyWith<$Res> implements $SnPostReactionCopyWith<$Res> {
|
||||||
|
factory _$SnPostReactionCopyWith(_SnPostReaction value, $Res Function(_SnPostReaction) _then) = __$SnPostReactionCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
String id, String symbol, int attitude, String postId, String accountId, DateTime createdAt, DateTime updatedAt, SnAccount? account, DateTime? deletedAt
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@override $SnAccountCopyWith<$Res>? get account;
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$SnPostReactionCopyWithImpl<$Res>
|
||||||
|
implements _$SnPostReactionCopyWith<$Res> {
|
||||||
|
__$SnPostReactionCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _SnPostReaction _self;
|
||||||
|
final $Res Function(_SnPostReaction) _then;
|
||||||
|
|
||||||
|
/// Create a copy of SnPostReaction
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? symbol = null,Object? attitude = null,Object? postId = null,Object? accountId = null,Object? createdAt = null,Object? updatedAt = null,Object? account = freezed,Object? deletedAt = freezed,}) {
|
||||||
|
return _then(_SnPostReaction(
|
||||||
|
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,symbol: null == symbol ? _self.symbol : symbol // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,attitude: null == attitude ? _self.attitude : attitude // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,postId: null == postId ? _self.postId : postId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnAccount?,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a copy of SnPostReaction
|
||||||
|
/// 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
|
// dart format on
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ _SnPost _$SnPostFromJson(Map<String, dynamic> json) => _SnPost(
|
|||||||
upvotes: (json['upvotes'] as num?)?.toInt() ?? 0,
|
upvotes: (json['upvotes'] as num?)?.toInt() ?? 0,
|
||||||
downvotes: (json['downvotes'] as num?)?.toInt() ?? 0,
|
downvotes: (json['downvotes'] as num?)?.toInt() ?? 0,
|
||||||
repliesCount: (json['replies_count'] 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(),
|
pinMode: (json['pin_mode'] as num?)?.toInt(),
|
||||||
threadedPostId: json['threaded_post_id'] as String?,
|
threadedPostId: json['threaded_post_id'] as String?,
|
||||||
threadedPost:
|
threadedPost:
|
||||||
@@ -117,6 +118,7 @@ Map<String, dynamic> _$SnPostToJson(_SnPost instance) => <String, dynamic>{
|
|||||||
'upvotes': instance.upvotes,
|
'upvotes': instance.upvotes,
|
||||||
'downvotes': instance.downvotes,
|
'downvotes': instance.downvotes,
|
||||||
'replies_count': instance.repliesCount,
|
'replies_count': instance.repliesCount,
|
||||||
|
'awarded_score': instance.awardedScore,
|
||||||
'pin_mode': instance.pinMode,
|
'pin_mode': instance.pinMode,
|
||||||
'threaded_post_id': instance.threadedPostId,
|
'threaded_post_id': instance.threadedPostId,
|
||||||
'threaded_post': instance.threadedPost?.toJson(),
|
'threaded_post': instance.threadedPost?.toJson(),
|
||||||
@@ -194,3 +196,69 @@ Map<String, dynamic> _$SnPostEmbedViewToJson(_SnPostEmbedView instance) =>
|
|||||||
};
|
};
|
||||||
|
|
||||||
const _$PostEmbedViewRendererEnumMap = {PostEmbedViewRenderer.webView: 0};
|
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(),
|
||||||
|
};
|
||||||
|
|||||||
@@ -20,6 +20,24 @@ sealed class SnWallet with _$SnWallet {
|
|||||||
_$SnWalletFromJson(json);
|
_$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
|
@freezed
|
||||||
sealed class SnWalletPocket with _$SnWalletPocket {
|
sealed class SnWalletPocket with _$SnWalletPocket {
|
||||||
const factory SnWalletPocket({
|
const factory SnWalletPocket({
|
||||||
@@ -108,17 +126,14 @@ sealed class SnWalletOrder with _$SnWalletOrder {
|
|||||||
required String id,
|
required String id,
|
||||||
required int status,
|
required int status,
|
||||||
required String currency,
|
required String currency,
|
||||||
required dynamic remarks,
|
required String? remarks,
|
||||||
required String appIdentifier,
|
required String appIdentifier,
|
||||||
@Default({}) Map<String, dynamic> meta,
|
@Default({}) Map<String, dynamic> meta,
|
||||||
required int amount,
|
required int amount,
|
||||||
required DateTime expiredAt,
|
required DateTime expiredAt,
|
||||||
required String? payeeWalletId,
|
required String? payeeWalletId,
|
||||||
required SnWallet? payeeWallet,
|
|
||||||
required String? transactionId,
|
required String? transactionId,
|
||||||
required SnTransaction? transaction,
|
|
||||||
required String? issuerAppId,
|
required String? issuerAppId,
|
||||||
required dynamic issuerApp,
|
|
||||||
required DateTime createdAt,
|
required DateTime createdAt,
|
||||||
required DateTime updatedAt,
|
required DateTime updatedAt,
|
||||||
required DateTime? deletedAt,
|
required DateTime? deletedAt,
|
||||||
@@ -127,3 +142,72 @@ sealed class SnWalletOrder with _$SnWalletOrder {
|
|||||||
factory SnWalletOrder.fromJson(Map<String, dynamic> json) =>
|
factory SnWalletOrder.fromJson(Map<String, dynamic> json) =>
|
||||||
_$SnWalletOrderFromJson(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
@@ -35,6 +35,40 @@ Map<String, dynamic> _$SnWalletToJson(_SnWallet instance) => <String, dynamic>{
|
|||||||
'deleted_at': instance.deletedAt?.toIso8601String(),
|
'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 _$SnWalletPocketFromJson(Map<String, dynamic> json) =>
|
||||||
_SnWalletPocket(
|
_SnWalletPocket(
|
||||||
id: json['id'] as String,
|
id: json['id'] as String,
|
||||||
@@ -195,25 +229,14 @@ _SnWalletOrder _$SnWalletOrderFromJson(Map<String, dynamic> json) =>
|
|||||||
id: json['id'] as String,
|
id: json['id'] as String,
|
||||||
status: (json['status'] as num).toInt(),
|
status: (json['status'] as num).toInt(),
|
||||||
currency: json['currency'] as String,
|
currency: json['currency'] as String,
|
||||||
remarks: json['remarks'],
|
remarks: json['remarks'] as String?,
|
||||||
appIdentifier: json['app_identifier'] as String,
|
appIdentifier: json['app_identifier'] as String,
|
||||||
meta: json['meta'] as Map<String, dynamic>? ?? const {},
|
meta: json['meta'] as Map<String, dynamic>? ?? const {},
|
||||||
amount: (json['amount'] as num).toInt(),
|
amount: (json['amount'] as num).toInt(),
|
||||||
expiredAt: DateTime.parse(json['expired_at'] as String),
|
expiredAt: DateTime.parse(json['expired_at'] as String),
|
||||||
payeeWalletId: json['payee_wallet_id'] 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?,
|
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?,
|
issuerAppId: json['issuer_app_id'] as String?,
|
||||||
issuerApp: json['issuer_app'],
|
|
||||||
createdAt: DateTime.parse(json['created_at'] as String),
|
createdAt: DateTime.parse(json['created_at'] as String),
|
||||||
updatedAt: DateTime.parse(json['updated_at'] as String),
|
updatedAt: DateTime.parse(json['updated_at'] as String),
|
||||||
deletedAt:
|
deletedAt:
|
||||||
@@ -233,12 +256,161 @@ Map<String, dynamic> _$SnWalletOrderToJson(_SnWalletOrder instance) =>
|
|||||||
'amount': instance.amount,
|
'amount': instance.amount,
|
||||||
'expired_at': instance.expiredAt.toIso8601String(),
|
'expired_at': instance.expiredAt.toIso8601String(),
|
||||||
'payee_wallet_id': instance.payeeWalletId,
|
'payee_wallet_id': instance.payeeWalletId,
|
||||||
'payee_wallet': instance.payeeWallet?.toJson(),
|
|
||||||
'transaction_id': instance.transactionId,
|
'transaction_id': instance.transactionId,
|
||||||
'transaction': instance.transaction?.toJson(),
|
|
||||||
'issuer_app_id': instance.issuerAppId,
|
'issuer_app_id': instance.issuerAppId,
|
||||||
'issuer_app': instance.issuerApp,
|
|
||||||
'created_at': instance.createdAt.toIso8601String(),
|
'created_at': instance.createdAt.toIso8601String(),
|
||||||
'updated_at': instance.updatedAt.toIso8601String(),
|
'updated_at': instance.updatedAt.toIso8601String(),
|
||||||
'deleted_at': instance.deletedAt?.toIso8601String(),
|
'deleted_at': instance.deletedAt?.toIso8601String(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_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(),
|
||||||
|
};
|
||||||
|
|||||||
454
lib/pods/activity/activity_rpc.dart
Normal file
454
lib/pods/activity/activity_rpc.dart
Normal 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 6463–6472
|
||||||
|
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},
|
||||||
|
);
|
||||||
|
}
|
||||||
282
lib/pods/activity/ipc_server.dart
Normal file
282
lib/pods/activity/ipc_server.dart
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
61
lib/pods/activity/ipc_server.web.dart
Normal file
61
lib/pods/activity/ipc_server.web.dart
Normal 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 {}
|
||||||
@@ -1,403 +0,0 @@
|
|||||||
import 'dart:async';
|
|
||||||
import 'dart:developer';
|
|
||||||
import 'dart:io';
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter_webrtc/flutter_webrtc.dart';
|
|
||||||
import 'package:island/widgets/chat/call_button.dart';
|
|
||||||
import 'package:livekit_client/livekit_client.dart';
|
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
||||||
import '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';
|
|
||||||
|
|
||||||
part 'call.g.dart';
|
|
||||||
part 'call.freezed.dart';
|
|
||||||
|
|
||||||
String formatDuration(Duration duration) {
|
|
||||||
String negativeSign = duration.isNegative ? '-' : '';
|
|
||||||
String twoDigits(int n) => n.toString().padLeft(2, "0");
|
|
||||||
String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60).abs());
|
|
||||||
String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60).abs());
|
|
||||||
return "$negativeSign${twoDigits(duration.inHours)}:$twoDigitMinutes:$twoDigitSeconds";
|
|
||||||
}
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
sealed class CallState with _$CallState {
|
|
||||||
const factory CallState({
|
|
||||||
required bool isConnected,
|
|
||||||
required bool isMicrophoneEnabled,
|
|
||||||
required bool isCameraEnabled,
|
|
||||||
required bool isScreenSharing,
|
|
||||||
required bool isSpeakerphone,
|
|
||||||
@Default(Duration(seconds: 0)) Duration duration,
|
|
||||||
String? error,
|
|
||||||
}) = _CallState;
|
|
||||||
}
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
sealed class CallParticipantLive with _$CallParticipantLive {
|
|
||||||
const CallParticipantLive._();
|
|
||||||
|
|
||||||
const factory CallParticipantLive({
|
|
||||||
required CallParticipant participant,
|
|
||||||
required Participant remoteParticipant,
|
|
||||||
}) = _CallParticipantLive;
|
|
||||||
|
|
||||||
bool get isSpeaking => remoteParticipant.isSpeaking;
|
|
||||||
bool get isMuted =>
|
|
||||||
remoteParticipant.isMuted || !remoteParticipant.isMicrophoneEnabled();
|
|
||||||
bool get isScreenSharing => remoteParticipant.isScreenShareEnabled();
|
|
||||||
bool get isScreenSharingWithAudio =>
|
|
||||||
remoteParticipant.isScreenShareAudioEnabled();
|
|
||||||
|
|
||||||
bool get hasVideo => remoteParticipant.hasVideo;
|
|
||||||
bool get hasAudio => remoteParticipant.hasAudio;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Riverpod(keepAlive: true)
|
|
||||||
class CallNotifier extends _$CallNotifier {
|
|
||||||
Room? _room;
|
|
||||||
LocalParticipant? _localParticipant;
|
|
||||||
List<CallParticipantLive> _participants = [];
|
|
||||||
final Map<String, CallParticipant> _participantInfoByIdentity = {};
|
|
||||||
EventsListener? _roomListener;
|
|
||||||
|
|
||||||
List<CallParticipantLive> get participants =>
|
|
||||||
List.unmodifiable(_participants);
|
|
||||||
LocalParticipant? get localParticipant => _localParticipant;
|
|
||||||
|
|
||||||
Map<String, double> participantsVolumes = {};
|
|
||||||
|
|
||||||
Timer? _durationTimer;
|
|
||||||
|
|
||||||
Room? get room => _room;
|
|
||||||
|
|
||||||
@override
|
|
||||||
CallState build() {
|
|
||||||
// Subscribe to websocket updates
|
|
||||||
return const CallState(
|
|
||||||
isConnected: false,
|
|
||||||
isMicrophoneEnabled: true,
|
|
||||||
isCameraEnabled: false,
|
|
||||||
isScreenSharing: false,
|
|
||||||
isSpeakerphone: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _initRoomListeners() {
|
|
||||||
if (_room == null) return;
|
|
||||||
_roomListener?.dispose();
|
|
||||||
_roomListener = _room!.createListener();
|
|
||||||
_room!.addListener(_onRoomChange);
|
|
||||||
_roomListener!
|
|
||||||
..on<ParticipantConnectedEvent>((e) {
|
|
||||||
_refreshLiveParticipants();
|
|
||||||
})
|
|
||||||
..on<RoomDisconnectedEvent>((e) {
|
|
||||||
_participants = [];
|
|
||||||
state = state.copyWith();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void _onRoomChange() {
|
|
||||||
_refreshLiveParticipants();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _refreshLiveParticipants() {
|
|
||||||
if (_room == null) return;
|
|
||||||
final remoteParticipants = _room!.remoteParticipants;
|
|
||||||
_participants = [];
|
|
||||||
// Add local participant first if available
|
|
||||||
if (_localParticipant != null) {
|
|
||||||
final localInfo = _buildParticipant();
|
|
||||||
_participants.add(
|
|
||||||
CallParticipantLive(
|
|
||||||
participant: localInfo,
|
|
||||||
remoteParticipant: _localParticipant!,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// Add remote participants
|
|
||||||
_participants.addAll(
|
|
||||||
remoteParticipants.values.map((remote) {
|
|
||||||
final match =
|
|
||||||
_participantInfoByIdentity[remote.identity] ??
|
|
||||||
CallParticipant(
|
|
||||||
identity: remote.identity,
|
|
||||||
name: remote.identity,
|
|
||||||
joinedAt: DateTime.now(),
|
|
||||||
);
|
|
||||||
return CallParticipantLive(
|
|
||||||
participant: match,
|
|
||||||
remoteParticipant: remote,
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
state = state.copyWith();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Builds the CallParticipant object for the local participant.
|
|
||||||
/// Optionally, pass [participants] if you want to prioritize info from the latest list.
|
|
||||||
CallParticipant _buildParticipant({List<CallParticipant>? participants}) {
|
|
||||||
if (_localParticipant == null) {
|
|
||||||
throw StateError('No local participant available');
|
|
||||||
}
|
|
||||||
// Prefer info from the latest participants list if available
|
|
||||||
if (participants != null) {
|
|
||||||
final idx = participants.indexWhere(
|
|
||||||
(p) => p.identity == _localParticipant!.identity,
|
|
||||||
);
|
|
||||||
if (idx != -1) return participants[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, use info from the identity map or fallback to minimal
|
|
||||||
return _participantInfoByIdentity[_localParticipant!.identity] ??
|
|
||||||
CallParticipant(
|
|
||||||
identity: _localParticipant!.identity,
|
|
||||||
name: _localParticipant!.identity,
|
|
||||||
joinedAt: DateTime.now(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _updateLiveParticipants(List<CallParticipant> participants) {
|
|
||||||
// Update the info map for lookup
|
|
||||||
for (final p in participants) {
|
|
||||||
_participantInfoByIdentity[p.identity] = p;
|
|
||||||
}
|
|
||||||
if (_room == null) {
|
|
||||||
// Can't build live objects, just store empty
|
|
||||||
_participants = [];
|
|
||||||
state = state.copyWith();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final remoteParticipants = _room!.remoteParticipants;
|
|
||||||
final remotes = remoteParticipants.values.toList();
|
|
||||||
_participants = [];
|
|
||||||
// Add local participant if present in the list
|
|
||||||
if (_localParticipant != null) {
|
|
||||||
final localInfo = _buildParticipant(participants: participants);
|
|
||||||
_participants.add(
|
|
||||||
CallParticipantLive(
|
|
||||||
participant: localInfo,
|
|
||||||
remoteParticipant: _localParticipant!,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
state = state.copyWith();
|
|
||||||
}
|
|
||||||
// Add remote participants
|
|
||||||
_participants.addAll(
|
|
||||||
participants.map((p) {
|
|
||||||
RemoteParticipant? remote;
|
|
||||||
for (final r in remotes) {
|
|
||||||
if (r.identity == p.identity) {
|
|
||||||
remote = r;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (_localParticipant != null &&
|
|
||||||
p.identity == _localParticipant!.identity) {
|
|
||||||
return null; // Already added local
|
|
||||||
}
|
|
||||||
return remote != null
|
|
||||||
? CallParticipantLive(participant: p, remoteParticipant: remote)
|
|
||||||
: null;
|
|
||||||
}).whereType<CallParticipantLive>(),
|
|
||||||
);
|
|
||||||
state = state.copyWith();
|
|
||||||
}
|
|
||||||
|
|
||||||
String? _roomId;
|
|
||||||
String? get roomId => _roomId;
|
|
||||||
|
|
||||||
Future<void> joinRoom(String roomId) async {
|
|
||||||
if (_roomId == roomId && _room != null) {
|
|
||||||
log('[Call] Call skipped. Already has data');
|
|
||||||
return;
|
|
||||||
} else if (_room != null) {
|
|
||||||
if (!_room!.isDisposed &&
|
|
||||||
_room!.connectionState != ConnectionState.disconnected) {
|
|
||||||
throw Exception('Call already connected');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_roomId = roomId;
|
|
||||||
if (_room != null) {
|
|
||||||
await _room!.disconnect();
|
|
||||||
await _room!.dispose();
|
|
||||||
_room = null;
|
|
||||||
_localParticipant = null;
|
|
||||||
_participants = [];
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
final apiClient = ref.read(apiClientProvider);
|
|
||||||
final ongoingCall = await ref.read(ongoingCallProvider(roomId).future);
|
|
||||||
final response = await apiClient.get(
|
|
||||||
'/sphere/chat/realtime/$roomId/join',
|
|
||||||
);
|
|
||||||
if (response.statusCode == 200 && response.data != null) {
|
|
||||||
final data = response.data;
|
|
||||||
// Parse join response
|
|
||||||
final joinResponse = ChatRealtimeJoinResponse.fromJson(data);
|
|
||||||
final participants = joinResponse.participants;
|
|
||||||
final String endpoint = joinResponse.endpoint;
|
|
||||||
final String token = joinResponse.token;
|
|
||||||
|
|
||||||
// Setup duration timer
|
|
||||||
_durationTimer?.cancel();
|
|
||||||
_durationTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
|
||||||
state = state.copyWith(
|
|
||||||
duration: Duration(
|
|
||||||
milliseconds:
|
|
||||||
(DateTime.now().millisecondsSinceEpoch -
|
|
||||||
(ongoingCall?.createdAt.millisecondsSinceEpoch ??
|
|
||||||
DateTime.now().millisecondsSinceEpoch)),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Connect to LiveKit
|
|
||||||
_room = Room();
|
|
||||||
|
|
||||||
await _room!.connect(
|
|
||||||
endpoint,
|
|
||||||
token,
|
|
||||||
connectOptions: ConnectOptions(autoSubscribe: true),
|
|
||||||
roomOptions: RoomOptions(adaptiveStream: true, dynacast: true),
|
|
||||||
fastConnectOptions: FastConnectOptions(
|
|
||||||
microphone: TrackOption(enabled: true),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
_localParticipant = _room!.localParticipant;
|
|
||||||
|
|
||||||
_initRoomListeners();
|
|
||||||
_updateLiveParticipants(participants);
|
|
||||||
|
|
||||||
if (!kIsWeb && (Platform.isIOS || Platform.isAndroid)) {
|
|
||||||
Hardware.instance.setSpeakerphoneOn(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listen for connection updates
|
|
||||||
_room!.addListener(() {
|
|
||||||
final wasConnected = state.isConnected;
|
|
||||||
final isNowConnected =
|
|
||||||
_room!.connectionState == ConnectionState.connected;
|
|
||||||
state = state.copyWith(
|
|
||||||
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');
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
state = state.copyWith(error: e.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> toggleMicrophone() async {
|
|
||||||
if (_localParticipant != null) {
|
|
||||||
const autostop = true;
|
|
||||||
final target = !_localParticipant!.isMicrophoneEnabled();
|
|
||||||
state = state.copyWith(isMicrophoneEnabled: target);
|
|
||||||
if (target) {
|
|
||||||
await _localParticipant!.audioTrackPublications.firstOrNull?.unmute(
|
|
||||||
stopOnMute: autostop,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
await _localParticipant!.audioTrackPublications.firstOrNull?.mute(
|
|
||||||
stopOnMute: autostop,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
state = state.copyWith();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> toggleCamera() async {
|
|
||||||
if (_localParticipant != null) {
|
|
||||||
final target = !_localParticipant!.isCameraEnabled();
|
|
||||||
state = state.copyWith(isCameraEnabled: target);
|
|
||||||
await _localParticipant!.setCameraEnabled(target);
|
|
||||||
state = state.copyWith();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> toggleScreenShare() async {
|
|
||||||
if (_localParticipant != null) {
|
|
||||||
final target = !_localParticipant!.isScreenShareEnabled();
|
|
||||||
state = state.copyWith(isScreenSharing: target);
|
|
||||||
await _localParticipant!.setScreenShareEnabled(target);
|
|
||||||
state = state.copyWith();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> toggleSpeakerphone() async {
|
|
||||||
state = state.copyWith(isSpeakerphone: !state.isSpeakerphone);
|
|
||||||
await Hardware.instance.setSpeakerphoneOn(state.isSpeakerphone);
|
|
||||||
state = state.copyWith();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> disconnect() async {
|
|
||||||
if (_room != null) {
|
|
||||||
await _room!.disconnect();
|
|
||||||
state = state.copyWith(
|
|
||||||
isConnected: false,
|
|
||||||
isMicrophoneEnabled: false,
|
|
||||||
isCameraEnabled: false,
|
|
||||||
isScreenSharing: false,
|
|
||||||
);
|
|
||||||
// Disable wakelock when call disconnects
|
|
||||||
WakelockPlus.disable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setParticipantVolume(CallParticipantLive live, double volume) {
|
|
||||||
if (participantsVolumes[live.remoteParticipant.sid] == null) {
|
|
||||||
participantsVolumes[live.remoteParticipant.sid] = 1;
|
|
||||||
}
|
|
||||||
Helper.setVolume(
|
|
||||||
volume,
|
|
||||||
live
|
|
||||||
.remoteParticipant
|
|
||||||
.audioTrackPublications
|
|
||||||
.first
|
|
||||||
.track!
|
|
||||||
.mediaStreamTrack,
|
|
||||||
);
|
|
||||||
participantsVolumes[live.remoteParticipant.sid] = volume;
|
|
||||||
}
|
|
||||||
|
|
||||||
double getParticipantVolume(CallParticipantLive live) {
|
|
||||||
return participantsVolumes[live.remoteParticipant.sid] ?? 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dispose() {
|
|
||||||
state = state.copyWith(
|
|
||||||
error: null,
|
|
||||||
isConnected: false,
|
|
||||||
isMicrophoneEnabled: false,
|
|
||||||
isCameraEnabled: false,
|
|
||||||
isScreenSharing: false,
|
|
||||||
);
|
|
||||||
_roomListener?.dispose();
|
|
||||||
_room?.removeListener(_onRoomChange);
|
|
||||||
_room?.dispose();
|
|
||||||
_durationTimer?.cancel();
|
|
||||||
_roomId = null;
|
|
||||||
participantsVolumes = {};
|
|
||||||
// Disable wakelock when disposing
|
|
||||||
WakelockPlus.disable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
436
lib/pods/chat/call.dart
Normal file
436
lib/pods/chat/call.dart
Normal file
@@ -0,0 +1,436 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_webrtc/flutter_webrtc.dart';
|
||||||
|
import 'package:island/pods/config.dart';
|
||||||
|
import 'package:island/pods/userinfo.dart';
|
||||||
|
import 'package:island/widgets/chat/call_button.dart';
|
||||||
|
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:island/models/account.dart';
|
||||||
|
import 'package:island/pods/chat/webrtc_manager.dart';
|
||||||
|
import 'package:wakelock_plus/wakelock_plus.dart';
|
||||||
|
import 'package:island/talker.dart';
|
||||||
|
|
||||||
|
part 'call.g.dart';
|
||||||
|
part 'call.freezed.dart';
|
||||||
|
|
||||||
|
String formatDuration(Duration duration) {
|
||||||
|
String negativeSign = duration.isNegative ? '-' : '';
|
||||||
|
String twoDigits(int n) => n.toString().padLeft(2, "0");
|
||||||
|
String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60).abs());
|
||||||
|
String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60).abs());
|
||||||
|
return "$negativeSign${twoDigits(duration.inHours)}:$twoDigitMinutes:$twoDigitSeconds";
|
||||||
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
sealed class CallState with _$CallState {
|
||||||
|
const factory CallState({
|
||||||
|
required bool isConnected,
|
||||||
|
required bool isMicrophoneEnabled,
|
||||||
|
required bool isCameraEnabled,
|
||||||
|
required bool isScreenSharing,
|
||||||
|
required bool isSpeakerphone,
|
||||||
|
@Default(Duration(seconds: 0)) Duration duration,
|
||||||
|
String? error,
|
||||||
|
}) = _CallState;
|
||||||
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
sealed class CallParticipantLive with _$CallParticipantLive {
|
||||||
|
const CallParticipantLive._();
|
||||||
|
|
||||||
|
const factory CallParticipantLive({
|
||||||
|
required CallParticipant participant,
|
||||||
|
required WebRTCParticipant remoteParticipant,
|
||||||
|
}) = _CallParticipantLive;
|
||||||
|
|
||||||
|
bool get isSpeaking {
|
||||||
|
// Use the actual audio level from WebRTC monitoring
|
||||||
|
return remoteParticipant.audioLevel > 0.1; // Threshold for speaking
|
||||||
|
}
|
||||||
|
|
||||||
|
double get audioLevel => remoteParticipant.audioLevel;
|
||||||
|
|
||||||
|
bool get isMuted => !remoteParticipant.isAudioEnabled;
|
||||||
|
bool get isScreenSharing => remoteParticipant.isVideoEnabled; // Simplified
|
||||||
|
bool get isScreenSharingWithAudio => false; // TODO: Implement screen sharing
|
||||||
|
|
||||||
|
bool get hasVideo => remoteParticipant.isVideoEnabled;
|
||||||
|
bool get hasAudio => remoteParticipant.isAudioEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Riverpod(keepAlive: true)
|
||||||
|
class CallNotifier extends _$CallNotifier {
|
||||||
|
WebRTCManager? _webrtcManager;
|
||||||
|
List<CallParticipantLive> _participants = [];
|
||||||
|
final Map<String, CallParticipant> _participantInfoByIdentity = {};
|
||||||
|
StreamSubscription<WebRTCParticipant>? _participantJoinedSubscription;
|
||||||
|
StreamSubscription<String>? _participantLeftSubscription;
|
||||||
|
|
||||||
|
List<CallParticipantLive> get participants =>
|
||||||
|
List.unmodifiable(_participants);
|
||||||
|
|
||||||
|
Map<String, double> participantsVolumes = {};
|
||||||
|
|
||||||
|
Timer? _durationTimer;
|
||||||
|
|
||||||
|
String? _roomId;
|
||||||
|
String? get roomId => _roomId;
|
||||||
|
WebRTCManager? get webrtcManager => _webrtcManager;
|
||||||
|
|
||||||
|
@override
|
||||||
|
CallState build() {
|
||||||
|
// Subscribe to websocket updates
|
||||||
|
return const CallState(
|
||||||
|
isConnected: false,
|
||||||
|
isMicrophoneEnabled:
|
||||||
|
true, // Audio enabled by default (matches WebRTC init)
|
||||||
|
isCameraEnabled: true, // Video enabled by default (matches WebRTC init)
|
||||||
|
isScreenSharing: false,
|
||||||
|
isSpeakerphone: true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _initWebRTCListeners() {
|
||||||
|
_participantJoinedSubscription?.cancel();
|
||||||
|
_participantLeftSubscription?.cancel();
|
||||||
|
|
||||||
|
_participantJoinedSubscription = _webrtcManager?.onParticipantJoined.listen(
|
||||||
|
(participant) {
|
||||||
|
_updateLiveParticipantsFromWebRTC();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
_participantLeftSubscription = _webrtcManager?.onParticipantLeft.listen((
|
||||||
|
participantId,
|
||||||
|
) {
|
||||||
|
_participants.removeWhere((p) => p.remoteParticipant.id == participantId);
|
||||||
|
state = state.copyWith();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add local participant immediately when WebRTC is initialized
|
||||||
|
final userinfo = ref.watch(userInfoProvider);
|
||||||
|
if (userinfo.value != null) {
|
||||||
|
_addLocalParticipant(userinfo.value!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _addLocalParticipant(SnAccount userinfo) {
|
||||||
|
if (_webrtcManager == null) return;
|
||||||
|
|
||||||
|
// Remove any existing local participant first
|
||||||
|
_participants.removeWhere((p) => p.participant.identity == userinfo.id);
|
||||||
|
|
||||||
|
// Add local participant (current user)
|
||||||
|
final localParticipant = CallParticipantLive(
|
||||||
|
participant: CallParticipant(
|
||||||
|
identity: userinfo.id, // Use roomId as local identity
|
||||||
|
name: userinfo.name,
|
||||||
|
accountId: userinfo.id,
|
||||||
|
account: userinfo,
|
||||||
|
joinedAt: DateTime.now(),
|
||||||
|
),
|
||||||
|
remoteParticipant: WebRTCParticipant(
|
||||||
|
id: _webrtcManager!.roomId,
|
||||||
|
name: userinfo.nick,
|
||||||
|
userinfo: userinfo,
|
||||||
|
isLocal: true,
|
||||||
|
)..remoteStream = _webrtcManager!.localStream, // Access local stream
|
||||||
|
);
|
||||||
|
|
||||||
|
_participants.insert(0, localParticipant); // Add at the beginning
|
||||||
|
state = state.copyWith();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _updateLiveParticipantsFromWebRTC() {
|
||||||
|
if (_webrtcManager == null) return;
|
||||||
|
|
||||||
|
final webrtcParticipants = _webrtcManager!.participants;
|
||||||
|
|
||||||
|
// Always ensure local participant exists
|
||||||
|
final existingLocalParticipant =
|
||||||
|
_participants.isNotEmpty &&
|
||||||
|
_participants[0].remoteParticipant.id == _webrtcManager!.roomId
|
||||||
|
? _participants[0]
|
||||||
|
: null;
|
||||||
|
|
||||||
|
final localParticipant =
|
||||||
|
existingLocalParticipant ?? _createLocalParticipant();
|
||||||
|
|
||||||
|
// Add remote participants
|
||||||
|
final remoteParticipants =
|
||||||
|
webrtcParticipants.map((p) {
|
||||||
|
final participantInfo =
|
||||||
|
_participantInfoByIdentity[p.id] ??
|
||||||
|
CallParticipant(
|
||||||
|
identity: p.id,
|
||||||
|
name: p.name,
|
||||||
|
accountId: p.userinfo.id,
|
||||||
|
account: p.userinfo,
|
||||||
|
joinedAt: DateTime.now(),
|
||||||
|
);
|
||||||
|
return CallParticipantLive(
|
||||||
|
participant: participantInfo,
|
||||||
|
remoteParticipant: p,
|
||||||
|
);
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
// Combine local participant with remote participants
|
||||||
|
_participants = [localParticipant, ...remoteParticipants];
|
||||||
|
|
||||||
|
state = state.copyWith();
|
||||||
|
}
|
||||||
|
|
||||||
|
CallParticipantLive _createLocalParticipant() {
|
||||||
|
return CallParticipantLive(
|
||||||
|
participant: CallParticipant(
|
||||||
|
identity: _webrtcManager!.roomId, // Use roomId as local identity
|
||||||
|
name: 'You',
|
||||||
|
accountId: '',
|
||||||
|
account: null,
|
||||||
|
joinedAt: DateTime.now(),
|
||||||
|
),
|
||||||
|
remoteParticipant: WebRTCParticipant(
|
||||||
|
id: _webrtcManager!.roomId,
|
||||||
|
name: 'You',
|
||||||
|
userinfo: SnAccount(
|
||||||
|
id: '',
|
||||||
|
name: '',
|
||||||
|
nick: '',
|
||||||
|
language: '',
|
||||||
|
isSuperuser: false,
|
||||||
|
automatedId: null,
|
||||||
|
profile: SnAccountProfile(
|
||||||
|
id: '',
|
||||||
|
firstName: '',
|
||||||
|
middleName: '',
|
||||||
|
lastName: '',
|
||||||
|
bio: '',
|
||||||
|
gender: '',
|
||||||
|
pronouns: '',
|
||||||
|
location: '',
|
||||||
|
timeZone: '',
|
||||||
|
links: [],
|
||||||
|
experience: 0,
|
||||||
|
level: 0,
|
||||||
|
socialCredits: 0,
|
||||||
|
socialCreditsLevel: 0,
|
||||||
|
levelingProgress: 0,
|
||||||
|
picture: null,
|
||||||
|
background: null,
|
||||||
|
verification: null,
|
||||||
|
usernameColor: null,
|
||||||
|
createdAt: DateTime.now(),
|
||||||
|
updatedAt: DateTime.now(),
|
||||||
|
deletedAt: null,
|
||||||
|
),
|
||||||
|
perkSubscription: null,
|
||||||
|
createdAt: DateTime.now(),
|
||||||
|
updatedAt: DateTime.now(),
|
||||||
|
deletedAt: null,
|
||||||
|
),
|
||||||
|
)..remoteStream = _webrtcManager!.localStream, // Access local stream
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> joinRoom(String roomId) async {
|
||||||
|
if (_roomId == roomId && _webrtcManager != null) {
|
||||||
|
talker.info('[Call] Call skipped. Already connected to this room');
|
||||||
|
// Ensure state is connected even if we skip the join process
|
||||||
|
if (!state.isConnected) {
|
||||||
|
state = state.copyWith(isConnected: true);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_roomId = roomId;
|
||||||
|
|
||||||
|
// Clean up existing connection
|
||||||
|
await disconnect();
|
||||||
|
|
||||||
|
try {
|
||||||
|
final apiClient = ref.read(apiClientProvider);
|
||||||
|
final ongoingCall = await ref.read(ongoingCallProvider(roomId).future);
|
||||||
|
final response = await apiClient.get(
|
||||||
|
'/sphere/chat/realtime/$roomId/join',
|
||||||
|
);
|
||||||
|
if (response.statusCode == 200 && response.data != null) {
|
||||||
|
final data = response.data;
|
||||||
|
// Parse join response
|
||||||
|
final joinResponse = ChatRealtimeJoinResponse.fromJson(data);
|
||||||
|
final participants = joinResponse.participants;
|
||||||
|
|
||||||
|
// Update participant info map
|
||||||
|
for (final p in participants) {
|
||||||
|
_participantInfoByIdentity[p.identity] = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup duration timer
|
||||||
|
_durationTimer?.cancel();
|
||||||
|
_durationTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
||||||
|
state = state.copyWith(
|
||||||
|
duration: Duration(
|
||||||
|
milliseconds:
|
||||||
|
(DateTime.now().millisecondsSinceEpoch -
|
||||||
|
(ongoingCall?.createdAt.millisecondsSinceEpoch ??
|
||||||
|
DateTime.now().millisecondsSinceEpoch)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initialize WebRTC manager
|
||||||
|
final serverUrl = ref.watch(serverUrlProvider);
|
||||||
|
|
||||||
|
_webrtcManager = WebRTCManager(roomId: roomId, serverUrl: serverUrl);
|
||||||
|
|
||||||
|
await _webrtcManager!.initialize(ref);
|
||||||
|
_initWebRTCListeners();
|
||||||
|
|
||||||
|
if (!kIsWeb && (Platform.isIOS || Platform.isAndroid)) {
|
||||||
|
// TODO: Implement speakerphone control for WebRTC
|
||||||
|
}
|
||||||
|
|
||||||
|
state = state.copyWith(isConnected: true);
|
||||||
|
// Enable wakelock when call connects
|
||||||
|
WakelockPlus.enable();
|
||||||
|
} else {
|
||||||
|
state = state.copyWith(error: 'Failed to join room');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
state = state.copyWith(error: e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> toggleMicrophone() async {
|
||||||
|
final target = !state.isMicrophoneEnabled;
|
||||||
|
state = state.copyWith(isMicrophoneEnabled: target);
|
||||||
|
await _webrtcManager?.toggleMicrophone(target);
|
||||||
|
|
||||||
|
// Update local participant's audio state
|
||||||
|
if (_participants.isNotEmpty) {
|
||||||
|
_participants[0].remoteParticipant.isAudioEnabled = target;
|
||||||
|
state = state.copyWith(); // Trigger UI update
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> toggleCamera() async {
|
||||||
|
final target = !state.isCameraEnabled;
|
||||||
|
state = state.copyWith(isCameraEnabled: target);
|
||||||
|
await _webrtcManager?.toggleCamera(target);
|
||||||
|
|
||||||
|
// Update local participant's video state
|
||||||
|
if (_participants.isNotEmpty) {
|
||||||
|
_participants[0].remoteParticipant.isVideoEnabled = target;
|
||||||
|
state = state.copyWith(); // Trigger UI update
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> toggleScreenShare(BuildContext context) async {
|
||||||
|
if (_webrtcManager == null) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (state.isScreenSharing) {
|
||||||
|
// Stop screen sharing - switch back to camera
|
||||||
|
await _webrtcManager!.toggleCamera(state.isCameraEnabled);
|
||||||
|
state = state.copyWith(isScreenSharing: false);
|
||||||
|
} else {
|
||||||
|
// Start screen sharing
|
||||||
|
if (WebRTC.platformIsDesktop) {
|
||||||
|
// For desktop, we need to get screen capture source
|
||||||
|
// This would require implementing a screen selection dialog
|
||||||
|
// For now, just toggle the state
|
||||||
|
state = state.copyWith(isScreenSharing: true);
|
||||||
|
} else if (WebRTC.platformIsWeb) {
|
||||||
|
// For web, get display media directly
|
||||||
|
await navigator.mediaDevices.getDisplayMedia({
|
||||||
|
'video': true,
|
||||||
|
'audio':
|
||||||
|
false, // Screen sharing typically doesn't include system audio
|
||||||
|
});
|
||||||
|
|
||||||
|
// Replace video track with screen sharing track
|
||||||
|
// This is a simplified implementation
|
||||||
|
state = state.copyWith(isScreenSharing: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
talker.error('[Call] Screen sharing error: $e');
|
||||||
|
state = state.copyWith(error: 'Failed to toggle screen sharing: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> toggleSpeakerphone() async {
|
||||||
|
if (!kIsWeb && (Platform.isIOS || Platform.isAndroid)) {
|
||||||
|
try {
|
||||||
|
// For mobile platforms, we can control audio routing
|
||||||
|
// This is a simplified implementation
|
||||||
|
final newSpeakerphoneState = !state.isSpeakerphone;
|
||||||
|
state = state.copyWith(isSpeakerphone: newSpeakerphoneState);
|
||||||
|
|
||||||
|
// Note: Actual speakerphone control would require platform-specific code
|
||||||
|
// For a full implementation, you'd need to use platform channels
|
||||||
|
// to control audio routing on iOS/Android
|
||||||
|
talker.info('[Call] Speakerphone toggled to: $newSpeakerphoneState');
|
||||||
|
} catch (e) {
|
||||||
|
talker.error('[Call] Speakerphone control error: $e');
|
||||||
|
state = state.copyWith(error: 'Failed to toggle speakerphone: $e');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// For web/desktop, speakerphone control is handled by the browser/OS
|
||||||
|
state = state.copyWith(isSpeakerphone: !state.isSpeakerphone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> disconnect() async {
|
||||||
|
_webrtcManager?.dispose();
|
||||||
|
_webrtcManager = null;
|
||||||
|
_participantJoinedSubscription?.cancel();
|
||||||
|
_participantLeftSubscription?.cancel();
|
||||||
|
_participants.clear();
|
||||||
|
state = state.copyWith(
|
||||||
|
isConnected: false,
|
||||||
|
isMicrophoneEnabled: false,
|
||||||
|
isCameraEnabled: false,
|
||||||
|
isScreenSharing: false,
|
||||||
|
);
|
||||||
|
// Disable wakelock when call disconnects
|
||||||
|
WakelockPlus.disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setParticipantVolume(CallParticipantLive live, double volume) {
|
||||||
|
// Store volume setting for this participant
|
||||||
|
// Note: WebRTC doesn't have built-in per-participant volume control
|
||||||
|
// This is just storing the preference for UI purposes
|
||||||
|
// Actual volume control would need to be implemented at the audio rendering level
|
||||||
|
participantsVolumes[live.remoteParticipant.id] = volume.clamp(0.0, 1.0);
|
||||||
|
talker.info(
|
||||||
|
'[Call] Volume set to $volume for participant ${live.remoteParticipant.id}',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
double getParticipantVolume(CallParticipantLive live) {
|
||||||
|
return participantsVolumes[live.remoteParticipant.id] ?? 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dispose() {
|
||||||
|
state = state.copyWith(
|
||||||
|
error: null,
|
||||||
|
isConnected: false,
|
||||||
|
isMicrophoneEnabled: false,
|
||||||
|
isCameraEnabled: false,
|
||||||
|
isScreenSharing: false,
|
||||||
|
);
|
||||||
|
_participantJoinedSubscription?.cancel();
|
||||||
|
_participantLeftSubscription?.cancel();
|
||||||
|
_webrtcManager?.dispose();
|
||||||
|
_webrtcManager = null;
|
||||||
|
_durationTimer?.cancel();
|
||||||
|
_roomId = null;
|
||||||
|
participantsVolumes = {};
|
||||||
|
// Disable wakelock when disposing
|
||||||
|
WakelockPlus.disable();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -295,7 +295,7 @@ as String?,
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$CallParticipantLive implements DiagnosticableTreeMixin {
|
mixin _$CallParticipantLive implements DiagnosticableTreeMixin {
|
||||||
|
|
||||||
CallParticipant get participant; Participant get remoteParticipant;
|
CallParticipant get participant; WebRTCParticipant get remoteParticipant;
|
||||||
/// Create a copy of CallParticipantLive
|
/// Create a copy of CallParticipantLive
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@@ -332,7 +332,7 @@ abstract mixin class $CallParticipantLiveCopyWith<$Res> {
|
|||||||
factory $CallParticipantLiveCopyWith(CallParticipantLive value, $Res Function(CallParticipantLive) _then) = _$CallParticipantLiveCopyWithImpl;
|
factory $CallParticipantLiveCopyWith(CallParticipantLive value, $Res Function(CallParticipantLive) _then) = _$CallParticipantLiveCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
CallParticipant participant, Participant remoteParticipant
|
CallParticipant participant, WebRTCParticipant remoteParticipant
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -353,7 +353,7 @@ class _$CallParticipantLiveCopyWithImpl<$Res>
|
|||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
participant: null == participant ? _self.participant : participant // ignore: cast_nullable_to_non_nullable
|
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 CallParticipant,remoteParticipant: null == remoteParticipant ? _self.remoteParticipant : remoteParticipant // ignore: cast_nullable_to_non_nullable
|
||||||
as Participant,
|
as WebRTCParticipant,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
/// Create a copy of CallParticipantLive
|
/// 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, WebRTCParticipant remoteParticipant)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _CallParticipantLive() when $default != null:
|
case _CallParticipantLive() when $default != null:
|
||||||
return $default(_that.participant,_that.remoteParticipant);case _:
|
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, WebRTCParticipant remoteParticipant) $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _CallParticipantLive():
|
case _CallParticipantLive():
|
||||||
return $default(_that.participant,_that.remoteParticipant);}
|
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, WebRTCParticipant remoteParticipant)? $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _CallParticipantLive() when $default != null:
|
case _CallParticipantLive() when $default != null:
|
||||||
return $default(_that.participant,_that.remoteParticipant);case _:
|
return $default(_that.participant,_that.remoteParticipant);case _:
|
||||||
@@ -501,7 +501,7 @@ class _CallParticipantLive extends CallParticipantLive with DiagnosticableTreeMi
|
|||||||
|
|
||||||
|
|
||||||
@override final CallParticipant participant;
|
@override final CallParticipant participant;
|
||||||
@override final Participant remoteParticipant;
|
@override final WebRTCParticipant remoteParticipant;
|
||||||
|
|
||||||
/// Create a copy of CallParticipantLive
|
/// Create a copy of CallParticipantLive
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// 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;
|
factory _$CallParticipantLiveCopyWith(_CallParticipantLive value, $Res Function(_CallParticipantLive) _then) = __$CallParticipantLiveCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
CallParticipant participant, Participant remoteParticipant
|
CallParticipant participant, WebRTCParticipant remoteParticipant
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -560,7 +560,7 @@ class __$CallParticipantLiveCopyWithImpl<$Res>
|
|||||||
return _then(_CallParticipantLive(
|
return _then(_CallParticipantLive(
|
||||||
participant: null == participant ? _self.participant : participant // ignore: cast_nullable_to_non_nullable
|
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 CallParticipant,remoteParticipant: null == remoteParticipant ? _self.remoteParticipant : remoteParticipant // ignore: cast_nullable_to_non_nullable
|
||||||
as Participant,
|
as WebRTCParticipant,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6,7 +6,7 @@ part of 'call.dart';
|
|||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$callNotifierHash() => r'eb9bd41b97e9b5e9d54007c8327edb6567458846';
|
String _$callNotifierHash() => r'4015d326388553c46859fe537e84d2c9da4236c9';
|
||||||
|
|
||||||
/// See also [CallNotifier].
|
/// See also [CallNotifier].
|
||||||
@ProviderFor(CallNotifier)
|
@ProviderFor(CallNotifier)
|
||||||
50
lib/pods/chat/chat_online_count.dart
Normal file
50
lib/pods/chat/chat_online_count.dart
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
168
lib/pods/chat/chat_online_count.g.dart
Normal file
168
lib/pods/chat/chat_online_count.g.dart
Normal 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
|
||||||
5
lib/pods/chat/chat_rooms.dart
Normal file
5
lib/pods/chat/chat_rooms.dart
Normal 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) => {});
|
||||||
229
lib/pods/chat/chat_subscribe.dart
Normal file
229
lib/pods/chat/chat_subscribe.dart
Normal 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;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
176
lib/pods/chat/chat_subscribe.g.dart
Normal file
176
lib/pods/chat/chat_subscribe.g.dart
Normal 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
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
import 'package:island/models/chat.dart';
|
import 'package:island/models/chat.dart';
|
||||||
import 'package:island/pods/network.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';
|
part 'chat_summary.g.dart';
|
||||||
|
|
||||||
@@ -12,9 +14,27 @@ class ChatSummary extends _$ChatSummary {
|
|||||||
final resp = await client.get('/sphere/chat/summary');
|
final resp = await client.get('/sphere/chat/summary');
|
||||||
|
|
||||||
final Map<String, dynamic> data = resp.data;
|
final Map<String, dynamic> data = resp.data;
|
||||||
return data.map(
|
final summaries = data.map(
|
||||||
(key, value) => MapEntry(key, SnChatSummary.fromJson(value)),
|
(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 {
|
Future<void> clearUnreadCount(String chatId) async {
|
||||||
@@ -36,10 +56,12 @@ class ChatSummary extends _$ChatSummary {
|
|||||||
state.whenData((summaries) {
|
state.whenData((summaries) {
|
||||||
final summary = summaries[chatId];
|
final summary = summaries[chatId];
|
||||||
if (summary != null) {
|
if (summary != null) {
|
||||||
|
final currentSubscribed = ref.read(currentSubscribedChatIdProvider);
|
||||||
|
final increment = (chatId != currentSubscribed) ? 1 : 0;
|
||||||
state = AsyncData({
|
state = AsyncData({
|
||||||
...summaries,
|
...summaries,
|
||||||
chatId: SnChatSummary(
|
chatId: SnChatSummary(
|
||||||
unreadCount: summary.unreadCount + 1,
|
unreadCount: summary.unreadCount + increment,
|
||||||
lastMessage: message,
|
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,
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -6,7 +6,7 @@ part of 'chat_summary.dart';
|
|||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$chatSummaryHash() => r'87a10e4cefa37dc5fa8eadb175ef1b2bed6070bf';
|
String _$chatSummaryHash() => r'33815a3bd81d20902b7063e8194fe336930df9b4';
|
||||||
|
|
||||||
/// See also [ChatSummary].
|
/// See also [ChatSummary].
|
||||||
@ProviderFor(ChatSummary)
|
@ProviderFor(ChatSummary)
|
||||||
1026
lib/pods/chat/messages_notifier.dart
Normal file
1026
lib/pods/chat/messages_notifier.dart
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,12 +1,12 @@
|
|||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
part of 'room.dart';
|
part of 'messages_notifier.dart';
|
||||||
|
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$messagesNotifierHash() => r'fc3b66dfb8dd3fc55d142dae5c5e7bdc67eca5d4';
|
String _$messagesNotifierHash() => r'6adefd9152cdd686c2a863964993f24c42d405b5';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
476
lib/pods/chat/webrtc_manager.dart
Normal file
476
lib/pods/chat/webrtc_manager.dart
Normal file
@@ -0,0 +1,476 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:flutter_webrtc/flutter_webrtc.dart';
|
||||||
|
import 'package:island/models/account.dart';
|
||||||
|
import 'package:island/pods/chat/webrtc_signaling.dart';
|
||||||
|
import 'package:island/pods/userinfo.dart';
|
||||||
|
import 'package:island/talker.dart';
|
||||||
|
|
||||||
|
class WebRTCParticipant {
|
||||||
|
final String id;
|
||||||
|
final String name;
|
||||||
|
final SnAccount userinfo;
|
||||||
|
RTCPeerConnection? peerConnection;
|
||||||
|
MediaStream? remoteStream;
|
||||||
|
List<RTCIceCandidate> remoteCandidates = [];
|
||||||
|
bool isAudioEnabled = true;
|
||||||
|
bool isVideoEnabled = false;
|
||||||
|
bool isConnected = false;
|
||||||
|
bool isLocal = false;
|
||||||
|
double audioLevel = 0.0;
|
||||||
|
|
||||||
|
WebRTCParticipant({
|
||||||
|
required this.id,
|
||||||
|
required this.name,
|
||||||
|
required this.userinfo,
|
||||||
|
this.isAudioEnabled = true,
|
||||||
|
this.isVideoEnabled = false,
|
||||||
|
this.isLocal = false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class WebRTCManager {
|
||||||
|
final String roomId;
|
||||||
|
final String serverUrl;
|
||||||
|
late WebRTCSignaling _signaling;
|
||||||
|
final Map<String, WebRTCParticipant> _participants = {};
|
||||||
|
final Map<String, RTCPeerConnection> _peerConnections = {};
|
||||||
|
|
||||||
|
MediaStream? _localStream;
|
||||||
|
Timer? _audioLevelTimer;
|
||||||
|
|
||||||
|
MediaStream? get localStream => _localStream;
|
||||||
|
final StreamController<WebRTCParticipant> _participantController =
|
||||||
|
StreamController<WebRTCParticipant>.broadcast();
|
||||||
|
final StreamController<String> _participantLeftController =
|
||||||
|
StreamController<String>.broadcast();
|
||||||
|
|
||||||
|
Stream<WebRTCParticipant> get onParticipantJoined =>
|
||||||
|
_participantController.stream;
|
||||||
|
Stream<String> get onParticipantLeft => _participantLeftController.stream;
|
||||||
|
|
||||||
|
WebRTCManager({required this.roomId, required this.serverUrl}) {
|
||||||
|
_signaling = WebRTCSignaling(roomId: roomId);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> initialize(Ref ref) async {
|
||||||
|
final user = ref.watch(userInfoProvider).value!;
|
||||||
|
_signaling.userId = user.id;
|
||||||
|
_signaling.userName = user.name;
|
||||||
|
_signaling.user = user;
|
||||||
|
await _initializeLocalStream();
|
||||||
|
_setupSignalingListeners();
|
||||||
|
await _signaling.connect(ref);
|
||||||
|
_startAudioLevelMonitoring();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _initializeLocalStream() async {
|
||||||
|
try {
|
||||||
|
_localStream = await navigator.mediaDevices.getUserMedia({
|
||||||
|
'audio': true,
|
||||||
|
'video': true,
|
||||||
|
});
|
||||||
|
talker.info('[WebRTC] Local stream initialized');
|
||||||
|
} catch (e) {
|
||||||
|
talker.error('[WebRTC] Failed to initialize local stream: $e');
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _setupSignalingListeners() {
|
||||||
|
_signaling.messages.listen((message) async {
|
||||||
|
switch (message.type) {
|
||||||
|
case 'offer':
|
||||||
|
await _handleOffer(message.accountId, message.account, message.data);
|
||||||
|
break;
|
||||||
|
case 'answer':
|
||||||
|
await _handleAnswer(message.accountId, message.data);
|
||||||
|
break;
|
||||||
|
case 'ice-candidate':
|
||||||
|
await _handleIceCandidate(message.accountId, message.data);
|
||||||
|
break;
|
||||||
|
// CHANGED: Listen for new users joining the room.
|
||||||
|
case 'user-joined':
|
||||||
|
await _handleUserJoined(message.accountId, message.account);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
talker.warning(
|
||||||
|
'[WebRTC Manager] Receieved an unknown type singaling message: ${message.type} with ${message.data}',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// CHANGED: The welcome message now drives connection initiation.
|
||||||
|
_signaling.welcomeMessages.listen((welcome) {
|
||||||
|
talker.info('[WebRTC Manager] Connected to room: ${welcome.roomId}');
|
||||||
|
final existingParticipants =
|
||||||
|
welcome.participants; // Assuming the server sends this.
|
||||||
|
talker.info(
|
||||||
|
'[WebRTC Manager] Existing participants: $existingParticipants',
|
||||||
|
);
|
||||||
|
|
||||||
|
// The newcomer is responsible for initiating the connection to everyone else.
|
||||||
|
for (final participant in existingParticipants) {
|
||||||
|
if (participant.identity != _signaling.userId) {
|
||||||
|
if (!_participants.containsKey(participant.identity)) {
|
||||||
|
final webrtcParticipant = WebRTCParticipant(
|
||||||
|
id: participant.identity,
|
||||||
|
name: participant.name,
|
||||||
|
userinfo: participant.account!,
|
||||||
|
);
|
||||||
|
_participants[participant.identity] = webrtcParticipant;
|
||||||
|
_participantController.add(webrtcParticipant);
|
||||||
|
}
|
||||||
|
_createPeerConnection(participant.identity, isInitiator: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHANGED: New handler for when an existing user is notified of a new peer.
|
||||||
|
Future<void> _handleUserJoined(
|
||||||
|
String participantId,
|
||||||
|
SnAccount account,
|
||||||
|
) async {
|
||||||
|
talker.info(
|
||||||
|
'[WebRTC Manager] User joined: $participantId. Waiting for their offer.',
|
||||||
|
);
|
||||||
|
// We don't need to be the initiator here. The newcomer will send us an offer.
|
||||||
|
// We just create the peer connection to be ready for it.
|
||||||
|
if (!_peerConnections.containsKey(participantId)) {
|
||||||
|
// Create a participant object to represent the new user
|
||||||
|
if (!_participants.containsKey(participantId)) {
|
||||||
|
final participant = WebRTCParticipant(
|
||||||
|
id: participantId,
|
||||||
|
name: participantId,
|
||||||
|
userinfo: account,
|
||||||
|
); // Placeholder name
|
||||||
|
_participants[participantId] = participant;
|
||||||
|
_participantController.add(participant);
|
||||||
|
}
|
||||||
|
await _createPeerConnection(participantId, isInitiator: false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _createPeerConnection(
|
||||||
|
String participantId, {
|
||||||
|
bool isInitiator = false,
|
||||||
|
}) async {
|
||||||
|
talker.info(
|
||||||
|
'[WebRTC] Creating peer connection to $participantId (initiator: $isInitiator)',
|
||||||
|
);
|
||||||
|
final configuration = {
|
||||||
|
'iceServers': [
|
||||||
|
{'urls': 'stun:stun.l.google.com:19302'},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
final peerConnection = await createPeerConnection(configuration);
|
||||||
|
_peerConnections[participantId] = peerConnection;
|
||||||
|
_participants[participantId]!.peerConnection = peerConnection;
|
||||||
|
|
||||||
|
if (_localStream != null) {
|
||||||
|
for (final track in _localStream!.getTracks()) {
|
||||||
|
await peerConnection.addTrack(track, _localStream!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
peerConnection.onTrack = (event) {
|
||||||
|
if (event.streams.isNotEmpty) {
|
||||||
|
final participant = _participants[participantId];
|
||||||
|
if (participant != null) {
|
||||||
|
participant.remoteStream = event.streams[0];
|
||||||
|
participant.isConnected = true;
|
||||||
|
|
||||||
|
// Detect video tracks and update video enabled state
|
||||||
|
final videoTracks = event.streams[0].getVideoTracks();
|
||||||
|
if (videoTracks.isNotEmpty) {
|
||||||
|
participant.isVideoEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_participantController.add(participant);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
peerConnection.onIceCandidate = (candidate) {
|
||||||
|
// CHANGED: Send candidate to the specific participant
|
||||||
|
_signaling.sendIceCandidate(participantId, candidate);
|
||||||
|
};
|
||||||
|
|
||||||
|
peerConnection.onConnectionState = (state) {
|
||||||
|
talker.info('[WebRTC] Connection state for $participantId: $state');
|
||||||
|
final participant = _participants[participantId];
|
||||||
|
if (participant != null) {
|
||||||
|
participant.isConnected =
|
||||||
|
state == RTCPeerConnectionState.RTCPeerConnectionStateConnected;
|
||||||
|
_participantController.add(participant);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isInitiator) {
|
||||||
|
final offer = await peerConnection.createOffer();
|
||||||
|
await peerConnection.setLocalDescription(offer);
|
||||||
|
// CHANGED: Send offer to the specific participant
|
||||||
|
_signaling.sendOffer(participantId, offer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _handleOffer(
|
||||||
|
String from,
|
||||||
|
SnAccount account,
|
||||||
|
Map<String, dynamic> data,
|
||||||
|
) async {
|
||||||
|
final participantId = from;
|
||||||
|
talker.info('[WebRTC Manager] Handling offer from $participantId');
|
||||||
|
final offer = RTCSessionDescription(data['sdp'], data['type']);
|
||||||
|
|
||||||
|
if (!_peerConnections.containsKey(participantId)) {
|
||||||
|
if (!_participants.containsKey(participantId)) {
|
||||||
|
final participant = WebRTCParticipant(
|
||||||
|
id: participantId,
|
||||||
|
name: participantId,
|
||||||
|
userinfo: account,
|
||||||
|
);
|
||||||
|
_participants[participantId] = participant;
|
||||||
|
_participantController.add(participant);
|
||||||
|
}
|
||||||
|
await _createPeerConnection(participantId, isInitiator: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
final peerConnection = _peerConnections[participantId]!;
|
||||||
|
await peerConnection.setRemoteDescription(offer);
|
||||||
|
|
||||||
|
final answer = await peerConnection.createAnswer();
|
||||||
|
await peerConnection.setLocalDescription(answer);
|
||||||
|
// CHANGED: Send answer to the specific participant
|
||||||
|
_signaling.sendAnswer(participantId, answer);
|
||||||
|
|
||||||
|
// Process any queued ICE candidates
|
||||||
|
final participant = _participants[participantId];
|
||||||
|
if (participant != null) {
|
||||||
|
for (final candidate in participant.remoteCandidates) {
|
||||||
|
await peerConnection.addCandidate(candidate);
|
||||||
|
}
|
||||||
|
participant.remoteCandidates.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _handleAnswer(String from, Map<String, dynamic> data) async {
|
||||||
|
final participantId = from;
|
||||||
|
talker.info('[WebRTC Manager] Handling answer from $participantId');
|
||||||
|
final answer = RTCSessionDescription(data['sdp'], data['type']);
|
||||||
|
|
||||||
|
final peerConnection = _peerConnections[participantId];
|
||||||
|
if (peerConnection != null) {
|
||||||
|
await peerConnection.setRemoteDescription(answer);
|
||||||
|
|
||||||
|
// Process any queued ICE candidates
|
||||||
|
final participant = _participants[participantId];
|
||||||
|
if (participant != null) {
|
||||||
|
for (final candidate in participant.remoteCandidates) {
|
||||||
|
await peerConnection.addCandidate(candidate);
|
||||||
|
}
|
||||||
|
participant.remoteCandidates.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _handleIceCandidate(
|
||||||
|
String from,
|
||||||
|
Map<String, dynamic> data,
|
||||||
|
) async {
|
||||||
|
final participantId = from;
|
||||||
|
final candidate = RTCIceCandidate(
|
||||||
|
data['candidate'],
|
||||||
|
data['sdpMid'],
|
||||||
|
data['sdpMLineIndex'],
|
||||||
|
);
|
||||||
|
|
||||||
|
final participant = _participants[participantId];
|
||||||
|
if (participant != null) {
|
||||||
|
final pc = participant.peerConnection;
|
||||||
|
if (pc != null) {
|
||||||
|
await pc.addCandidate(candidate);
|
||||||
|
} else {
|
||||||
|
participant.remoteCandidates.add(candidate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> replaceMediaStream(Map<String, dynamic> constraints) async {
|
||||||
|
try {
|
||||||
|
final newStream = await navigator.mediaDevices.getUserMedia(constraints);
|
||||||
|
final newVideoTrack = newStream.getVideoTracks().firstOrNull;
|
||||||
|
final newAudioTrack = newStream.getAudioTracks().firstOrNull;
|
||||||
|
|
||||||
|
if (_localStream != null) {
|
||||||
|
final oldVideoTrack = _localStream!.getVideoTracks().firstOrNull;
|
||||||
|
final oldAudioTrack = _localStream!.getAudioTracks().firstOrNull;
|
||||||
|
|
||||||
|
// Replace tracks in all existing peer connections
|
||||||
|
for (final pc in _peerConnections.values) {
|
||||||
|
final senders = await pc.getSenders();
|
||||||
|
for (final sender in senders) {
|
||||||
|
if (newVideoTrack != null && sender.track == oldVideoTrack) {
|
||||||
|
await sender.replaceTrack(newVideoTrack);
|
||||||
|
} else if (newAudioTrack != null && sender.track == oldAudioTrack) {
|
||||||
|
await sender.replaceTrack(newAudioTrack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop old tracks and update local stream
|
||||||
|
for (final track in _localStream!.getTracks()) {
|
||||||
|
track.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_localStream = newStream;
|
||||||
|
talker.info('[WebRTC] Media stream replaced with new constraints');
|
||||||
|
} catch (e) {
|
||||||
|
talker.error('[WebRTC] Failed to replace media stream: $e');
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> toggleMicrophone(bool enabled) async {
|
||||||
|
if (_localStream != null) {
|
||||||
|
final audioTracks = _localStream!.getAudioTracks();
|
||||||
|
for (final track in audioTracks) {
|
||||||
|
track.enabled = enabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> toggleCamera(bool enabled) async {
|
||||||
|
if (_localStream != null) {
|
||||||
|
_localStream!.getVideoTracks().forEach((track) {
|
||||||
|
track.enabled = enabled;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> switchCamera(String deviceId) async {
|
||||||
|
await replaceMediaStream({
|
||||||
|
'audio': _localStream?.getAudioTracks().isNotEmpty ?? true,
|
||||||
|
'video': {'deviceId': deviceId},
|
||||||
|
});
|
||||||
|
talker.info('[WebRTC] Switched to camera device: $deviceId');
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> switchMicrophone(String deviceId) async {
|
||||||
|
await replaceMediaStream({
|
||||||
|
'audio': {'deviceId': deviceId},
|
||||||
|
'video': _localStream?.getVideoTracks().isNotEmpty ?? true,
|
||||||
|
});
|
||||||
|
talker.info('[WebRTC] Switched to microphone device: $deviceId');
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<MediaDeviceInfo>> getVideoDevices() async {
|
||||||
|
try {
|
||||||
|
final devices = await navigator.mediaDevices.enumerateDevices();
|
||||||
|
return devices.where((device) => device.kind == 'videoinput').toList();
|
||||||
|
} catch (e) {
|
||||||
|
talker.error('[WebRTC] Failed to enumerate video devices: $e');
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<MediaDeviceInfo>> getAudioDevices() async {
|
||||||
|
try {
|
||||||
|
final devices = await navigator.mediaDevices.enumerateDevices();
|
||||||
|
return devices.where((device) => device.kind == 'audioinput').toList();
|
||||||
|
} catch (e) {
|
||||||
|
talker.error('[WebRTC] Failed to enumerate audio devices: $e');
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _startAudioLevelMonitoring() {
|
||||||
|
_audioLevelTimer?.cancel();
|
||||||
|
_audioLevelTimer = Timer.periodic(const Duration(milliseconds: 100), (_) {
|
||||||
|
_updateAudioLevels();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _stopAudioLevelMonitoring() {
|
||||||
|
_audioLevelTimer?.cancel();
|
||||||
|
_audioLevelTimer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _updateAudioLevels() async {
|
||||||
|
bool hasUpdates = false;
|
||||||
|
|
||||||
|
for (final participant in _participants.values) {
|
||||||
|
if (participant.remoteStream != null && participant.isAudioEnabled) {
|
||||||
|
final audioTracks = participant.remoteStream!.getAudioTracks();
|
||||||
|
if (audioTracks.isNotEmpty) {
|
||||||
|
try {
|
||||||
|
// Try to get stats for more accurate audio level detection
|
||||||
|
final pc = participant.peerConnection;
|
||||||
|
if (pc != null) {
|
||||||
|
final stats = await pc.getStats();
|
||||||
|
double maxAudioLevel = 0.0;
|
||||||
|
|
||||||
|
// Look for audio receiver stats
|
||||||
|
for (var report in stats) {
|
||||||
|
if (report.type == 'inbound-rtp' &&
|
||||||
|
report.values['mediaType'] == 'audio') {
|
||||||
|
final audioLevel = report.values['audioLevel'] as double?;
|
||||||
|
if (audioLevel != null && audioLevel > maxAudioLevel) {
|
||||||
|
maxAudioLevel = audioLevel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we got stats, use them; otherwise use a simple heuristic
|
||||||
|
if (maxAudioLevel > 0) {
|
||||||
|
participant.audioLevel = maxAudioLevel.clamp(0.0, 1.0);
|
||||||
|
} else {
|
||||||
|
// Simple heuristic: if audio track is enabled, assume some level
|
||||||
|
// In a real app, you'd analyze the actual audio data
|
||||||
|
participant.audioLevel = audioTracks[0].enabled ? 0.5 : 0.0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Fallback for local participant or when no PC available
|
||||||
|
participant.audioLevel = participant.isLocal ? 0.0 : 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
hasUpdates = true;
|
||||||
|
} catch (e) {
|
||||||
|
talker.warning('[WebRTC] Failed to update audio level for ${participant.id}: $e');
|
||||||
|
participant.audioLevel = 0.0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
participant.audioLevel = 0.0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
participant.audioLevel = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify listeners if there were updates (throttled to avoid excessive updates)
|
||||||
|
if (hasUpdates) {
|
||||||
|
// This will trigger UI updates for speaking indicators
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<WebRTCParticipant> get participants => _participants.values.toList();
|
||||||
|
|
||||||
|
void dispose() {
|
||||||
|
_stopAudioLevelMonitoring();
|
||||||
|
_signaling.disconnect();
|
||||||
|
for (final pc in _peerConnections.values) {
|
||||||
|
pc.close();
|
||||||
|
}
|
||||||
|
_peerConnections.clear();
|
||||||
|
for (var p in _participants.values) {
|
||||||
|
p.remoteCandidates.clear();
|
||||||
|
}
|
||||||
|
_participants.clear();
|
||||||
|
_localStream?.dispose();
|
||||||
|
_participantController.close();
|
||||||
|
_participantLeftController.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
211
lib/pods/chat/webrtc_signaling.dart
Normal file
211
lib/pods/chat/webrtc_signaling.dart
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:flutter_webrtc/flutter_webrtc.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'package:island/models/account.dart';
|
||||||
|
import 'package:island/models/chat.dart';
|
||||||
|
import 'package:island/pods/config.dart';
|
||||||
|
import 'package:island/pods/network.dart';
|
||||||
|
import 'package:island/pods/websocket.dart';
|
||||||
|
import 'package:web_socket_channel/io.dart';
|
||||||
|
import 'package:web_socket_channel/web_socket_channel.dart';
|
||||||
|
import 'package:island/talker.dart';
|
||||||
|
|
||||||
|
part 'webrtc_signaling.freezed.dart';
|
||||||
|
part 'webrtc_signaling.g.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
sealed class SignalingMessage with _$SignalingMessage {
|
||||||
|
const factory SignalingMessage({
|
||||||
|
required String type,
|
||||||
|
// CHANGED: Added 'to' field for directed messaging
|
||||||
|
String? to,
|
||||||
|
required String accountId,
|
||||||
|
required SnAccount account,
|
||||||
|
required Map<String, dynamic> data,
|
||||||
|
}) = _SignalingMessage;
|
||||||
|
|
||||||
|
factory SignalingMessage.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$SignalingMessageFromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
sealed class WebRTCWelcomeMessage with _$WebRTCWelcomeMessage {
|
||||||
|
const factory WebRTCWelcomeMessage({
|
||||||
|
required String userId,
|
||||||
|
required String roomId,
|
||||||
|
required String message,
|
||||||
|
required String timestamp,
|
||||||
|
// CHANGED: Added participants list
|
||||||
|
@Default([]) List<CallParticipant> participants,
|
||||||
|
}) = _WebRTCWelcomeMessage;
|
||||||
|
|
||||||
|
factory WebRTCWelcomeMessage.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$WebRTCWelcomeMessageFromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
class WebRTCSignaling {
|
||||||
|
final String roomId;
|
||||||
|
late final String userId;
|
||||||
|
late final String userName;
|
||||||
|
late SnAccount user;
|
||||||
|
final StreamController<SignalingMessage> _messageController =
|
||||||
|
StreamController<SignalingMessage>.broadcast();
|
||||||
|
final StreamController<WebRTCWelcomeMessage> _welcomeController =
|
||||||
|
StreamController<WebRTCWelcomeMessage>.broadcast();
|
||||||
|
WebSocketChannel? _channel;
|
||||||
|
Timer? _heartbeatTimer;
|
||||||
|
|
||||||
|
Stream<SignalingMessage> get messages => _messageController.stream;
|
||||||
|
Stream<WebRTCWelcomeMessage> get welcomeMessages => _welcomeController.stream;
|
||||||
|
|
||||||
|
WebRTCSignaling({required this.roomId});
|
||||||
|
|
||||||
|
Future<void> connect(Ref ref) async {
|
||||||
|
final baseUrl = ref.watch(serverUrlProvider);
|
||||||
|
final token = await getToken(ref.watch(tokenProvider));
|
||||||
|
|
||||||
|
final url = '$baseUrl/sphere/chat/realtime/$roomId'.replaceFirst(
|
||||||
|
'http',
|
||||||
|
'ws',
|
||||||
|
);
|
||||||
|
|
||||||
|
talker.info('[WebRTC Signaling] Trying connecting to $url');
|
||||||
|
try {
|
||||||
|
if (kIsWeb) {
|
||||||
|
_channel = WebSocketChannel.connect(Uri.parse('$url?tk=$token'));
|
||||||
|
} else {
|
||||||
|
_channel = IOWebSocketChannel.connect(
|
||||||
|
Uri.parse(url),
|
||||||
|
headers: {'Authorization': 'AtField $token'},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
await _channel!.ready;
|
||||||
|
|
||||||
|
// Start heartbeat timer
|
||||||
|
_heartbeatTimer = Timer.periodic(const Duration(seconds: 30), (timer) => _sendHeartbeat());
|
||||||
|
|
||||||
|
_channel!.stream.listen(
|
||||||
|
(data) {
|
||||||
|
final dataStr =
|
||||||
|
data is Uint8List ? utf8.decode(data) : data.toString();
|
||||||
|
final packet = WebSocketPacket.fromJson(jsonDecode(dataStr));
|
||||||
|
talker.info(
|
||||||
|
'[WebRTC Signaling] Recieved a singal message with packet type: ${packet.type}',
|
||||||
|
);
|
||||||
|
if (packet.type == 'webrtc') {
|
||||||
|
try {
|
||||||
|
final welcomeMessage = WebRTCWelcomeMessage.fromJson(
|
||||||
|
packet.data!,
|
||||||
|
);
|
||||||
|
_welcomeController.add(welcomeMessage);
|
||||||
|
talker.info(
|
||||||
|
'[WebRTC Signaling] Welcome message received: ${welcomeMessage.message}',
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
talker.error(
|
||||||
|
'[WebRTC Signaling] Failed to parse welcome message: $e',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (packet.type == 'webrtc.signal') {
|
||||||
|
try {
|
||||||
|
final signalingMessage = SignalingMessage.fromJson(packet.data!);
|
||||||
|
// CHANGED: Ensure we only process messages intended for us if the 'to' field is present
|
||||||
|
if (signalingMessage.to == null ||
|
||||||
|
signalingMessage.to == userId) {
|
||||||
|
_messageController.add(signalingMessage);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
talker.error(
|
||||||
|
'[WebRTC Signaling] Failed to parse signaling message: $e',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onError: (error) {
|
||||||
|
talker.error('[WebRTC Signaling] WebSocket error: $error');
|
||||||
|
_messageController.addError(error);
|
||||||
|
_welcomeController.addError(error);
|
||||||
|
},
|
||||||
|
onDone: () {
|
||||||
|
talker.info('[WebRTC Signaling] WebSocket connection closed');
|
||||||
|
_messageController.close();
|
||||||
|
_welcomeController.close();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
talker.error('[WebRTC Signaling] Failed to connect: $err');
|
||||||
|
_messageController.addError(err);
|
||||||
|
_welcomeController.addError(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendMessage(SignalingMessage message) {
|
||||||
|
if (_channel == null) return;
|
||||||
|
talker.info(
|
||||||
|
'[WebRTC Signaling] Sending a message with message type: ${message.type} to ${message.to}',
|
||||||
|
);
|
||||||
|
final packet = WebSocketPacket(
|
||||||
|
type: 'webrtc.signal',
|
||||||
|
data: message.toJson(),
|
||||||
|
);
|
||||||
|
_channel!.sink.add(jsonEncode(packet.toJson()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHANGED: All send methods now correctly use the `to` parameter
|
||||||
|
void sendOffer(String to, RTCSessionDescription offer) {
|
||||||
|
sendMessage(
|
||||||
|
SignalingMessage(
|
||||||
|
type: 'offer',
|
||||||
|
to: to,
|
||||||
|
accountId: userId,
|
||||||
|
account: user,
|
||||||
|
data: {'sdp': offer.sdp, 'type': offer.type},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendAnswer(String to, RTCSessionDescription answer) {
|
||||||
|
sendMessage(
|
||||||
|
SignalingMessage(
|
||||||
|
type: 'answer',
|
||||||
|
to: to,
|
||||||
|
accountId: userId,
|
||||||
|
account: user,
|
||||||
|
data: {'sdp': answer.sdp, 'type': answer.type},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendIceCandidate(String to, RTCIceCandidate candidate) {
|
||||||
|
sendMessage(
|
||||||
|
SignalingMessage(
|
||||||
|
type: 'ice-candidate',
|
||||||
|
to: to,
|
||||||
|
accountId: userId,
|
||||||
|
account: user,
|
||||||
|
data: {
|
||||||
|
'candidate': candidate.candidate,
|
||||||
|
'sdpMid': candidate.sdpMid,
|
||||||
|
'sdpMLineIndex': candidate.sdpMLineIndex,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _sendHeartbeat() {
|
||||||
|
if (_channel == null) return;
|
||||||
|
talker.info('[WebRTC Signaling] Sending heartbeat');
|
||||||
|
final packet = WebSocketPacket(type: 'heartbeat', data: null);
|
||||||
|
_channel!.sink.add(jsonEncode(packet.toJson()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void disconnect() {
|
||||||
|
_heartbeatTimer?.cancel();
|
||||||
|
_channel?.sink.close();
|
||||||
|
_messageController.close();
|
||||||
|
_welcomeController.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
611
lib/pods/chat/webrtc_signaling.freezed.dart
Normal file
611
lib/pods/chat/webrtc_signaling.freezed.dart
Normal file
@@ -0,0 +1,611 @@
|
|||||||
|
// 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 'webrtc_signaling.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
// dart format off
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$SignalingMessage implements DiagnosticableTreeMixin {
|
||||||
|
|
||||||
|
String get type;// CHANGED: Added 'to' field for directed messaging
|
||||||
|
String? get to; String get accountId; SnAccount get account; Map<String, dynamic> get data;
|
||||||
|
/// Create a copy of SignalingMessage
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SignalingMessageCopyWith<SignalingMessage> get copyWith => _$SignalingMessageCopyWithImpl<SignalingMessage>(this as SignalingMessage, _$identity);
|
||||||
|
|
||||||
|
/// Serializes this SignalingMessage to a JSON map.
|
||||||
|
Map<String, dynamic> toJson();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||||
|
properties
|
||||||
|
..add(DiagnosticsProperty('type', 'SignalingMessage'))
|
||||||
|
..add(DiagnosticsProperty('type', type))..add(DiagnosticsProperty('to', to))..add(DiagnosticsProperty('accountId', accountId))..add(DiagnosticsProperty('account', account))..add(DiagnosticsProperty('data', data));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is SignalingMessage&&(identical(other.type, type) || other.type == type)&&(identical(other.to, to) || other.to == to)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.account, account) || other.account == account)&&const DeepCollectionEquality().equals(other.data, data));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,type,to,accountId,account,const DeepCollectionEquality().hash(data));
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
|
||||||
|
return 'SignalingMessage(type: $type, to: $to, accountId: $accountId, account: $account, data: $data)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $SignalingMessageCopyWith<$Res> {
|
||||||
|
factory $SignalingMessageCopyWith(SignalingMessage value, $Res Function(SignalingMessage) _then) = _$SignalingMessageCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
String type, String? to, String accountId, SnAccount account, Map<String, dynamic> data
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$SnAccountCopyWith<$Res> get account;
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$SignalingMessageCopyWithImpl<$Res>
|
||||||
|
implements $SignalingMessageCopyWith<$Res> {
|
||||||
|
_$SignalingMessageCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final SignalingMessage _self;
|
||||||
|
final $Res Function(SignalingMessage) _then;
|
||||||
|
|
||||||
|
/// Create a copy of SignalingMessage
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? type = null,Object? to = freezed,Object? accountId = null,Object? account = null,Object? data = null,}) {
|
||||||
|
return _then(_self.copyWith(
|
||||||
|
type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,to: freezed == to ? _self.to : to // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,account: null == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnAccount,data: null == data ? _self.data : data // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Map<String, dynamic>,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
/// Create a copy of SignalingMessage
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnAccountCopyWith<$Res> get account {
|
||||||
|
|
||||||
|
return $SnAccountCopyWith<$Res>(_self.account, (value) {
|
||||||
|
return _then(_self.copyWith(account: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [SignalingMessage].
|
||||||
|
extension SignalingMessagePatterns on SignalingMessage {
|
||||||
|
/// 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( _SignalingMessage value)? $default,{required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SignalingMessage() 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( _SignalingMessage value) $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SignalingMessage():
|
||||||
|
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( _SignalingMessage value)? $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SignalingMessage() 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? to, String accountId, SnAccount account, Map<String, dynamic> data)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SignalingMessage() when $default != null:
|
||||||
|
return $default(_that.type,_that.to,_that.accountId,_that.account,_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? to, String accountId, SnAccount account, Map<String, dynamic> data) $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SignalingMessage():
|
||||||
|
return $default(_that.type,_that.to,_that.accountId,_that.account,_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? to, String accountId, SnAccount account, Map<String, dynamic> data)? $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _SignalingMessage() when $default != null:
|
||||||
|
return $default(_that.type,_that.to,_that.accountId,_that.account,_that.data);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
|
||||||
|
class _SignalingMessage with DiagnosticableTreeMixin implements SignalingMessage {
|
||||||
|
const _SignalingMessage({required this.type, this.to, required this.accountId, required this.account, required final Map<String, dynamic> data}): _data = data;
|
||||||
|
factory _SignalingMessage.fromJson(Map<String, dynamic> json) => _$SignalingMessageFromJson(json);
|
||||||
|
|
||||||
|
@override final String type;
|
||||||
|
// CHANGED: Added 'to' field for directed messaging
|
||||||
|
@override final String? to;
|
||||||
|
@override final String accountId;
|
||||||
|
@override final SnAccount account;
|
||||||
|
final Map<String, dynamic> _data;
|
||||||
|
@override Map<String, dynamic> get data {
|
||||||
|
if (_data is EqualUnmodifiableMapView) return _data;
|
||||||
|
// ignore: implicit_dynamic_type
|
||||||
|
return EqualUnmodifiableMapView(_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Create a copy of SignalingMessage
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$SignalingMessageCopyWith<_SignalingMessage> get copyWith => __$SignalingMessageCopyWithImpl<_SignalingMessage>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$SignalingMessageToJson(this, );
|
||||||
|
}
|
||||||
|
@override
|
||||||
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||||
|
properties
|
||||||
|
..add(DiagnosticsProperty('type', 'SignalingMessage'))
|
||||||
|
..add(DiagnosticsProperty('type', type))..add(DiagnosticsProperty('to', to))..add(DiagnosticsProperty('accountId', accountId))..add(DiagnosticsProperty('account', account))..add(DiagnosticsProperty('data', data));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SignalingMessage&&(identical(other.type, type) || other.type == type)&&(identical(other.to, to) || other.to == to)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.account, account) || other.account == account)&&const DeepCollectionEquality().equals(other._data, _data));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,type,to,accountId,account,const DeepCollectionEquality().hash(_data));
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
|
||||||
|
return 'SignalingMessage(type: $type, to: $to, accountId: $accountId, account: $account, data: $data)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$SignalingMessageCopyWith<$Res> implements $SignalingMessageCopyWith<$Res> {
|
||||||
|
factory _$SignalingMessageCopyWith(_SignalingMessage value, $Res Function(_SignalingMessage) _then) = __$SignalingMessageCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
String type, String? to, String accountId, SnAccount account, Map<String, dynamic> data
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@override $SnAccountCopyWith<$Res> get account;
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$SignalingMessageCopyWithImpl<$Res>
|
||||||
|
implements _$SignalingMessageCopyWith<$Res> {
|
||||||
|
__$SignalingMessageCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _SignalingMessage _self;
|
||||||
|
final $Res Function(_SignalingMessage) _then;
|
||||||
|
|
||||||
|
/// Create a copy of SignalingMessage
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? type = null,Object? to = freezed,Object? accountId = null,Object? account = null,Object? data = null,}) {
|
||||||
|
return _then(_SignalingMessage(
|
||||||
|
type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,to: freezed == to ? _self.to : to // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,account: null == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnAccount,data: null == data ? _self._data : data // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Map<String, dynamic>,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a copy of SignalingMessage
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnAccountCopyWith<$Res> get account {
|
||||||
|
|
||||||
|
return $SnAccountCopyWith<$Res>(_self.account, (value) {
|
||||||
|
return _then(_self.copyWith(account: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$WebRTCWelcomeMessage implements DiagnosticableTreeMixin {
|
||||||
|
|
||||||
|
String get userId; String get roomId; String get message; String get timestamp;// CHANGED: Added participants list
|
||||||
|
List<CallParticipant> get participants;
|
||||||
|
/// Create a copy of WebRTCWelcomeMessage
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$WebRTCWelcomeMessageCopyWith<WebRTCWelcomeMessage> get copyWith => _$WebRTCWelcomeMessageCopyWithImpl<WebRTCWelcomeMessage>(this as WebRTCWelcomeMessage, _$identity);
|
||||||
|
|
||||||
|
/// Serializes this WebRTCWelcomeMessage to a JSON map.
|
||||||
|
Map<String, dynamic> toJson();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||||
|
properties
|
||||||
|
..add(DiagnosticsProperty('type', 'WebRTCWelcomeMessage'))
|
||||||
|
..add(DiagnosticsProperty('userId', userId))..add(DiagnosticsProperty('roomId', roomId))..add(DiagnosticsProperty('message', message))..add(DiagnosticsProperty('timestamp', timestamp))..add(DiagnosticsProperty('participants', participants));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is WebRTCWelcomeMessage&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.roomId, roomId) || other.roomId == roomId)&&(identical(other.message, message) || other.message == message)&&(identical(other.timestamp, timestamp) || other.timestamp == timestamp)&&const DeepCollectionEquality().equals(other.participants, participants));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,userId,roomId,message,timestamp,const DeepCollectionEquality().hash(participants));
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
|
||||||
|
return 'WebRTCWelcomeMessage(userId: $userId, roomId: $roomId, message: $message, timestamp: $timestamp, participants: $participants)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $WebRTCWelcomeMessageCopyWith<$Res> {
|
||||||
|
factory $WebRTCWelcomeMessageCopyWith(WebRTCWelcomeMessage value, $Res Function(WebRTCWelcomeMessage) _then) = _$WebRTCWelcomeMessageCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
String userId, String roomId, String message, String timestamp, List<CallParticipant> participants
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$WebRTCWelcomeMessageCopyWithImpl<$Res>
|
||||||
|
implements $WebRTCWelcomeMessageCopyWith<$Res> {
|
||||||
|
_$WebRTCWelcomeMessageCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final WebRTCWelcomeMessage _self;
|
||||||
|
final $Res Function(WebRTCWelcomeMessage) _then;
|
||||||
|
|
||||||
|
/// Create a copy of WebRTCWelcomeMessage
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? userId = null,Object? roomId = null,Object? message = null,Object? timestamp = null,Object? participants = null,}) {
|
||||||
|
return _then(_self.copyWith(
|
||||||
|
userId: null == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,roomId: null == roomId ? _self.roomId : roomId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,message: null == message ? _self.message : message // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,timestamp: null == timestamp ? _self.timestamp : timestamp // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,participants: null == participants ? _self.participants : participants // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<CallParticipant>,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [WebRTCWelcomeMessage].
|
||||||
|
extension WebRTCWelcomeMessagePatterns on WebRTCWelcomeMessage {
|
||||||
|
/// 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( _WebRTCWelcomeMessage value)? $default,{required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _WebRTCWelcomeMessage() 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( _WebRTCWelcomeMessage value) $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _WebRTCWelcomeMessage():
|
||||||
|
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( _WebRTCWelcomeMessage value)? $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _WebRTCWelcomeMessage() 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 userId, String roomId, String message, String timestamp, List<CallParticipant> participants)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _WebRTCWelcomeMessage() when $default != null:
|
||||||
|
return $default(_that.userId,_that.roomId,_that.message,_that.timestamp,_that.participants);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 userId, String roomId, String message, String timestamp, List<CallParticipant> participants) $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _WebRTCWelcomeMessage():
|
||||||
|
return $default(_that.userId,_that.roomId,_that.message,_that.timestamp,_that.participants);}
|
||||||
|
}
|
||||||
|
/// 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 userId, String roomId, String message, String timestamp, List<CallParticipant> participants)? $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _WebRTCWelcomeMessage() when $default != null:
|
||||||
|
return $default(_that.userId,_that.roomId,_that.message,_that.timestamp,_that.participants);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
|
||||||
|
class _WebRTCWelcomeMessage with DiagnosticableTreeMixin implements WebRTCWelcomeMessage {
|
||||||
|
const _WebRTCWelcomeMessage({required this.userId, required this.roomId, required this.message, required this.timestamp, final List<CallParticipant> participants = const []}): _participants = participants;
|
||||||
|
factory _WebRTCWelcomeMessage.fromJson(Map<String, dynamic> json) => _$WebRTCWelcomeMessageFromJson(json);
|
||||||
|
|
||||||
|
@override final String userId;
|
||||||
|
@override final String roomId;
|
||||||
|
@override final String message;
|
||||||
|
@override final String timestamp;
|
||||||
|
// CHANGED: Added participants list
|
||||||
|
final List<CallParticipant> _participants;
|
||||||
|
// CHANGED: Added participants list
|
||||||
|
@override@JsonKey() List<CallParticipant> get participants {
|
||||||
|
if (_participants is EqualUnmodifiableListView) return _participants;
|
||||||
|
// ignore: implicit_dynamic_type
|
||||||
|
return EqualUnmodifiableListView(_participants);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Create a copy of WebRTCWelcomeMessage
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$WebRTCWelcomeMessageCopyWith<_WebRTCWelcomeMessage> get copyWith => __$WebRTCWelcomeMessageCopyWithImpl<_WebRTCWelcomeMessage>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$WebRTCWelcomeMessageToJson(this, );
|
||||||
|
}
|
||||||
|
@override
|
||||||
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||||
|
properties
|
||||||
|
..add(DiagnosticsProperty('type', 'WebRTCWelcomeMessage'))
|
||||||
|
..add(DiagnosticsProperty('userId', userId))..add(DiagnosticsProperty('roomId', roomId))..add(DiagnosticsProperty('message', message))..add(DiagnosticsProperty('timestamp', timestamp))..add(DiagnosticsProperty('participants', participants));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _WebRTCWelcomeMessage&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.roomId, roomId) || other.roomId == roomId)&&(identical(other.message, message) || other.message == message)&&(identical(other.timestamp, timestamp) || other.timestamp == timestamp)&&const DeepCollectionEquality().equals(other._participants, _participants));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,userId,roomId,message,timestamp,const DeepCollectionEquality().hash(_participants));
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
|
||||||
|
return 'WebRTCWelcomeMessage(userId: $userId, roomId: $roomId, message: $message, timestamp: $timestamp, participants: $participants)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$WebRTCWelcomeMessageCopyWith<$Res> implements $WebRTCWelcomeMessageCopyWith<$Res> {
|
||||||
|
factory _$WebRTCWelcomeMessageCopyWith(_WebRTCWelcomeMessage value, $Res Function(_WebRTCWelcomeMessage) _then) = __$WebRTCWelcomeMessageCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
String userId, String roomId, String message, String timestamp, List<CallParticipant> participants
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$WebRTCWelcomeMessageCopyWithImpl<$Res>
|
||||||
|
implements _$WebRTCWelcomeMessageCopyWith<$Res> {
|
||||||
|
__$WebRTCWelcomeMessageCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _WebRTCWelcomeMessage _self;
|
||||||
|
final $Res Function(_WebRTCWelcomeMessage) _then;
|
||||||
|
|
||||||
|
/// Create a copy of WebRTCWelcomeMessage
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? userId = null,Object? roomId = null,Object? message = null,Object? timestamp = null,Object? participants = null,}) {
|
||||||
|
return _then(_WebRTCWelcomeMessage(
|
||||||
|
userId: null == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,roomId: null == roomId ? _self.roomId : roomId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,message: null == message ? _self.message : message // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,timestamp: null == timestamp ? _self.timestamp : timestamp // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,participants: null == participants ? _self._participants : participants // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<CallParticipant>,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// dart format on
|
||||||
49
lib/pods/chat/webrtc_signaling.g.dart
Normal file
49
lib/pods/chat/webrtc_signaling.g.dart
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'webrtc_signaling.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
_SignalingMessage _$SignalingMessageFromJson(Map<String, dynamic> json) =>
|
||||||
|
_SignalingMessage(
|
||||||
|
type: json['type'] as String,
|
||||||
|
to: json['to'] as String?,
|
||||||
|
accountId: json['account_id'] as String,
|
||||||
|
account: SnAccount.fromJson(json['account'] as Map<String, dynamic>),
|
||||||
|
data: json['data'] as Map<String, dynamic>,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$SignalingMessageToJson(_SignalingMessage instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'type': instance.type,
|
||||||
|
'to': instance.to,
|
||||||
|
'account_id': instance.accountId,
|
||||||
|
'account': instance.account.toJson(),
|
||||||
|
'data': instance.data,
|
||||||
|
};
|
||||||
|
|
||||||
|
_WebRTCWelcomeMessage _$WebRTCWelcomeMessageFromJson(
|
||||||
|
Map<String, dynamic> json,
|
||||||
|
) => _WebRTCWelcomeMessage(
|
||||||
|
userId: json['user_id'] as String,
|
||||||
|
roomId: json['room_id'] as String,
|
||||||
|
message: json['message'] as String,
|
||||||
|
timestamp: json['timestamp'] as String,
|
||||||
|
participants:
|
||||||
|
(json['participants'] as List<dynamic>?)
|
||||||
|
?.map((e) => CallParticipant.fromJson(e as Map<String, dynamic>))
|
||||||
|
.toList() ??
|
||||||
|
const [],
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$WebRTCWelcomeMessageToJson(
|
||||||
|
_WebRTCWelcomeMessage instance,
|
||||||
|
) => <String, dynamic>{
|
||||||
|
'user_id': instance.userId,
|
||||||
|
'room_id': instance.roomId,
|
||||||
|
'message': instance.message,
|
||||||
|
'timestamp': instance.timestamp,
|
||||||
|
'participants': instance.participants.map((e) => e.toJson()).toList(),
|
||||||
|
};
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'package:island/pods/theme.dart';
|
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
import 'package:window_manager/window_manager.dart';
|
||||||
|
|
||||||
part 'config.freezed.dart';
|
part 'config.freezed.dart';
|
||||||
part 'config.g.dart';
|
part 'config.g.dart';
|
||||||
@@ -17,6 +19,7 @@ const kAppbarTransparentStoreKey = 'app_bar_transparent';
|
|||||||
const kAppBackgroundStoreKey = 'app_has_background';
|
const kAppBackgroundStoreKey = 'app_has_background';
|
||||||
const kAppShowBackgroundImage = 'app_show_background_image';
|
const kAppShowBackgroundImage = 'app_show_background_image';
|
||||||
const kAppColorSchemeStoreKey = 'app_color_scheme';
|
const kAppColorSchemeStoreKey = 'app_color_scheme';
|
||||||
|
const kAppCustomColorsStoreKey = 'app_custom_colors';
|
||||||
const kAppNotifyWithHaptic = 'app_notify_with_haptic';
|
const kAppNotifyWithHaptic = 'app_notify_with_haptic';
|
||||||
const kAppCustomFonts = 'app_custom_fonts';
|
const kAppCustomFonts = 'app_custom_fonts';
|
||||||
const kAppAutoTranslate = 'app_auto_translate';
|
const kAppAutoTranslate = 'app_auto_translate';
|
||||||
@@ -24,7 +27,14 @@ const kAppDataSavingMode = 'app_data_saving_mode';
|
|||||||
const kAppSoundEffects = 'app_sound_effects';
|
const kAppSoundEffects = 'app_sound_effects';
|
||||||
const kAppAprilFoolFeatures = 'app_april_fool_features';
|
const kAppAprilFoolFeatures = 'app_april_fool_features';
|
||||||
const kAppWindowSize = 'app_window_size';
|
const kAppWindowSize = 'app_window_size';
|
||||||
|
const kAppWindowOpacity = 'app_window_opacity';
|
||||||
|
const kAppCardTransparent = 'app_card_transparent';
|
||||||
const kAppEnterToSend = 'app_enter_to_send';
|
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 =
|
const kFeaturedPostsCollapsedId =
|
||||||
'featured_posts_collapsed_id'; // Key for storing the ID of the collapsed featured post
|
'featured_posts_collapsed_id'; // Key for storing the ID of the collapsed featured post
|
||||||
|
|
||||||
@@ -52,6 +62,21 @@ final serverUrlProvider = Provider<String>((ref) {
|
|||||||
return prefs.getString(kNetworkServerStoreKey) ?? kNetworkServerDefault;
|
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
|
@freezed
|
||||||
sealed class AppSettings with _$AppSettings {
|
sealed class AppSettings with _$AppSettings {
|
||||||
const factory AppSettings({
|
const factory AppSettings({
|
||||||
@@ -64,7 +89,15 @@ sealed class AppSettings with _$AppSettings {
|
|||||||
required bool showBackgroundImage,
|
required bool showBackgroundImage,
|
||||||
required String? customFonts,
|
required String? customFonts,
|
||||||
required int? appColorScheme, // The color stored via the int type
|
required int? appColorScheme, // The color stored via the int type
|
||||||
|
required ThemeColors? customColors,
|
||||||
required Size? windowSize, // The window size for desktop platforms
|
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;
|
}) = _AppSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +116,15 @@ class AppSettingsNotifier extends _$AppSettingsNotifier {
|
|||||||
showBackgroundImage: prefs.getBool(kAppShowBackgroundImage) ?? true,
|
showBackgroundImage: prefs.getBool(kAppShowBackgroundImage) ?? true,
|
||||||
customFonts: prefs.getString(kAppCustomFonts),
|
customFonts: prefs.getString(kAppCustomFonts),
|
||||||
appColorScheme: prefs.getInt(kAppColorSchemeStoreKey),
|
appColorScheme: prefs.getInt(kAppColorSchemeStoreKey),
|
||||||
|
customColors: _getThemeColorsFromPrefs(prefs),
|
||||||
windowSize: _getWindowSizeFromPrefs(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,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,13 +145,35 @@ class AppSettingsNotifier extends _$AppSettingsNotifier {
|
|||||||
return null;
|
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) {
|
void setAutoTranslate(bool value) {
|
||||||
final prefs = ref.read(sharedPreferencesProvider);
|
final prefs = ref.read(sharedPreferencesProvider);
|
||||||
prefs.setBool(kAppAutoTranslate, value);
|
prefs.setBool(kAppAutoTranslate, value);
|
||||||
state = state.copyWith(autoTranslate: value);
|
state = state.copyWith(autoTranslate: value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setDataSavingMode(bool value){
|
void setDataSavingMode(bool value) {
|
||||||
final prefs = ref.read(sharedPreferencesProvider);
|
final prefs = ref.read(sharedPreferencesProvider);
|
||||||
prefs.setBool(kAppDataSavingMode, value);
|
prefs.setBool(kAppDataSavingMode, value);
|
||||||
state = state.copyWith(dataSavingMode: value);
|
state = state.copyWith(dataSavingMode: value);
|
||||||
@@ -138,7 +201,6 @@ class AppSettingsNotifier extends _$AppSettingsNotifier {
|
|||||||
final prefs = ref.read(sharedPreferencesProvider);
|
final prefs = ref.read(sharedPreferencesProvider);
|
||||||
prefs.setBool(kAppbarTransparentStoreKey, value);
|
prefs.setBool(kAppbarTransparentStoreKey, value);
|
||||||
state = state.copyWith(appBarTransparent: value);
|
state = state.copyWith(appBarTransparent: value);
|
||||||
ref.read(themeProvider.notifier).reloadTheme();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setShowBackgroundImage(bool value) {
|
void setShowBackgroundImage(bool value) {
|
||||||
@@ -151,14 +213,12 @@ class AppSettingsNotifier extends _$AppSettingsNotifier {
|
|||||||
final prefs = ref.read(sharedPreferencesProvider);
|
final prefs = ref.read(sharedPreferencesProvider);
|
||||||
prefs.setString(kAppCustomFonts, value ?? '');
|
prefs.setString(kAppCustomFonts, value ?? '');
|
||||||
state = state.copyWith(customFonts: value);
|
state = state.copyWith(customFonts: value);
|
||||||
ref.read(themeProvider.notifier).reloadTheme();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setAppColorScheme(int? value) {
|
void setAppColorScheme(int? value) {
|
||||||
final prefs = ref.read(sharedPreferencesProvider);
|
final prefs = ref.read(sharedPreferencesProvider);
|
||||||
prefs.setInt(kAppColorSchemeStoreKey, value ?? 0);
|
prefs.setInt(kAppColorSchemeStoreKey, value ?? 0);
|
||||||
state = state.copyWith(appColorScheme: value);
|
state = state.copyWith(appColorScheme: value);
|
||||||
ref.read(themeProvider.notifier).reloadTheme();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWindowSize(Size? size) {
|
void setWindowSize(Size? size) {
|
||||||
@@ -174,6 +234,54 @@ class AppSettingsNotifier extends _$AppSettingsNotifier {
|
|||||||
Size? getWindowSize() {
|
Size? getWindowSize() {
|
||||||
return state.windowSize;
|
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 =
|
final updateInfoProvider =
|
||||||
|
|||||||
@@ -11,11 +11,286 @@ part of 'config.dart';
|
|||||||
|
|
||||||
// dart format off
|
// dart format off
|
||||||
T _$identity<T>(T value) => value;
|
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
|
/// @nodoc
|
||||||
mixin _$AppSettings {
|
mixin _$AppSettings {
|
||||||
|
|
||||||
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
|
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
|
||||||
Size? get windowSize;
|
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
|
/// Create a copy of AppSettings
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@@ -26,16 +301,16 @@ $AppSettingsCopyWith<AppSettings> get copyWith => _$AppSettingsCopyWithImpl<AppS
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is AppSettings&&(identical(other.autoTranslate, autoTranslate) || other.autoTranslate == autoTranslate)&&(identical(other.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.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
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,autoTranslate,dataSavingMode,soundEffects,aprilFoolFeatures,enterToSend,appBarTransparent,showBackgroundImage,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
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'AppSettings(autoTranslate: $autoTranslate, dataSavingMode: $dataSavingMode, soundEffects: $soundEffects, aprilFoolFeatures: $aprilFoolFeatures, enterToSend: $enterToSend, appBarTransparent: $appBarTransparent, showBackgroundImage: $showBackgroundImage, 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;
|
factory $AppSettingsCopyWith(AppSettings value, $Res Function(AppSettings) _then) = _$AppSettingsCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
bool autoTranslate, bool dataSavingMode, bool soundEffects, bool aprilFoolFeatures, bool enterToSend, bool appBarTransparent, bool showBackgroundImage, 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
|
/// @nodoc
|
||||||
@@ -63,7 +338,7 @@ class _$AppSettingsCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of AppSettings
|
/// Create a copy of AppSettings
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? autoTranslate = null,Object? dataSavingMode = null,Object? soundEffects = null,Object? aprilFoolFeatures = null,Object? enterToSend = null,Object? appBarTransparent = null,Object? showBackgroundImage = 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(
|
return _then(_self.copyWith(
|
||||||
autoTranslate: null == autoTranslate ? _self.autoTranslate : autoTranslate // ignore: cast_nullable_to_non_nullable
|
autoTranslate: null == autoTranslate ? _self.autoTranslate : autoTranslate // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,dataSavingMode: null == dataSavingMode ? _self.dataSavingMode : dataSavingMode // ignore: cast_nullable_to_non_nullable
|
as bool,dataSavingMode: null == dataSavingMode ? _self.dataSavingMode : dataSavingMode // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -74,11 +349,31 @@ as bool,appBarTransparent: null == appBarTransparent ? _self.appBarTransparent :
|
|||||||
as bool,showBackgroundImage: null == showBackgroundImage ? _self.showBackgroundImage : showBackgroundImage // 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 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 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 int?,customColors: freezed == customColors ? _self.customColors : customColors // ignore: cast_nullable_to_non_nullable
|
||||||
as Size?,
|
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));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -157,10 +452,10 @@ return $default(_that);case _:
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@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, 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) {
|
switch (_that) {
|
||||||
case _AppSettings() when $default != null:
|
case _AppSettings() when $default != null:
|
||||||
return $default(_that.autoTranslate,_that.dataSavingMode,_that.soundEffects,_that.aprilFoolFeatures,_that.enterToSend,_that.appBarTransparent,_that.showBackgroundImage,_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();
|
return orElse();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -178,10 +473,10 @@ return $default(_that.autoTranslate,_that.dataSavingMode,_that.soundEffects,_tha
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@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, 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) {
|
switch (_that) {
|
||||||
case _AppSettings():
|
case _AppSettings():
|
||||||
return $default(_that.autoTranslate,_that.dataSavingMode,_that.soundEffects,_that.aprilFoolFeatures,_that.enterToSend,_that.appBarTransparent,_that.showBackgroundImage,_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`
|
/// A variant of `when` that fallback to returning `null`
|
||||||
///
|
///
|
||||||
@@ -195,10 +490,10 @@ return $default(_that.autoTranslate,_that.dataSavingMode,_that.soundEffects,_tha
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@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, 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) {
|
switch (_that) {
|
||||||
case _AppSettings() when $default != null:
|
case _AppSettings() when $default != null:
|
||||||
return $default(_that.autoTranslate,_that.dataSavingMode,_that.soundEffects,_that.aprilFoolFeatures,_that.enterToSend,_that.appBarTransparent,_that.showBackgroundImage,_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;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -210,7 +505,7 @@ return $default(_that.autoTranslate,_that.dataSavingMode,_that.soundEffects,_tha
|
|||||||
|
|
||||||
|
|
||||||
class _AppSettings implements AppSettings {
|
class _AppSettings implements AppSettings {
|
||||||
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.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 autoTranslate;
|
||||||
@@ -223,7 +518,18 @@ class _AppSettings implements AppSettings {
|
|||||||
@override final String? customFonts;
|
@override final String? customFonts;
|
||||||
@override final int? appColorScheme;
|
@override final int? appColorScheme;
|
||||||
// The color stored via the int type
|
// The color stored via the int type
|
||||||
|
@override final ThemeColors? customColors;
|
||||||
@override final Size? windowSize;
|
@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
|
/// Create a copy of AppSettings
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@@ -235,16 +541,16 @@ _$AppSettingsCopyWith<_AppSettings> get copyWith => __$AppSettingsCopyWithImpl<_
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _AppSettings&&(identical(other.autoTranslate, autoTranslate) || other.autoTranslate == autoTranslate)&&(identical(other.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.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
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,autoTranslate,dataSavingMode,soundEffects,aprilFoolFeatures,enterToSend,appBarTransparent,showBackgroundImage,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
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'AppSettings(autoTranslate: $autoTranslate, dataSavingMode: $dataSavingMode, soundEffects: $soundEffects, aprilFoolFeatures: $aprilFoolFeatures, enterToSend: $enterToSend, appBarTransparent: $appBarTransparent, showBackgroundImage: $showBackgroundImage, 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)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -255,11 +561,11 @@ abstract mixin class _$AppSettingsCopyWith<$Res> implements $AppSettingsCopyWith
|
|||||||
factory _$AppSettingsCopyWith(_AppSettings value, $Res Function(_AppSettings) _then) = __$AppSettingsCopyWithImpl;
|
factory _$AppSettingsCopyWith(_AppSettings value, $Res Function(_AppSettings) _then) = __$AppSettingsCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
bool autoTranslate, bool dataSavingMode, bool soundEffects, bool aprilFoolFeatures, bool enterToSend, bool appBarTransparent, bool showBackgroundImage, 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
|
/// @nodoc
|
||||||
@@ -272,7 +578,7 @@ class __$AppSettingsCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of AppSettings
|
/// Create a copy of AppSettings
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? autoTranslate = null,Object? dataSavingMode = null,Object? soundEffects = null,Object? aprilFoolFeatures = null,Object? enterToSend = null,Object? appBarTransparent = null,Object? showBackgroundImage = 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(
|
return _then(_AppSettings(
|
||||||
autoTranslate: null == autoTranslate ? _self.autoTranslate : autoTranslate // ignore: cast_nullable_to_non_nullable
|
autoTranslate: null == autoTranslate ? _self.autoTranslate : autoTranslate // ignore: cast_nullable_to_non_nullable
|
||||||
as bool,dataSavingMode: null == dataSavingMode ? _self.dataSavingMode : dataSavingMode // ignore: cast_nullable_to_non_nullable
|
as bool,dataSavingMode: null == dataSavingMode ? _self.dataSavingMode : dataSavingMode // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -283,12 +589,32 @@ as bool,appBarTransparent: null == appBarTransparent ? _self.appBarTransparent :
|
|||||||
as bool,showBackgroundImage: null == showBackgroundImage ? _self.showBackgroundImage : showBackgroundImage // 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 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 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 int?,customColors: freezed == customColors ? _self.customColors : customColors // ignore: cast_nullable_to_non_nullable
|
||||||
as Size?,
|
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
|
// dart format on
|
||||||
|
|||||||
@@ -2,12 +2,35 @@
|
|||||||
|
|
||||||
part of 'config.dart';
|
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
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$appSettingsNotifierHash() =>
|
String _$appSettingsNotifierHash() =>
|
||||||
r'cd18bff2614a94e3523634e6c577cefad0367eba';
|
r'10ebd893c39d24ae588a4c0bf4144ee4656465a4';
|
||||||
|
|
||||||
/// See also [AppSettingsNotifier].
|
/// See also [AppSettingsNotifier].
|
||||||
@ProviderFor(AppSettingsNotifier)
|
@ProviderFor(AppSettingsNotifier)
|
||||||
|
|||||||
24
lib/pods/file_pool.dart
Normal file
24
lib/pods/file_pool.dart
Normal 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
30
lib/pods/lifecycle.dart
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,17 +10,19 @@ Future<void> resetDatabase(WidgetRef ref) async {
|
|||||||
if (kIsWeb) return;
|
if (kIsWeb) return;
|
||||||
|
|
||||||
final db = ref.read(databaseProvider);
|
final db = ref.read(databaseProvider);
|
||||||
final basepath = await getApplicationSupportDirectory();
|
|
||||||
final file = File(join(basepath.path, 'solar_network_data.sqlite'));
|
|
||||||
|
|
||||||
// Close current database connection
|
// 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()) {
|
if (await file.exists()) {
|
||||||
await file.delete();
|
await file.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force refresh the database provider
|
// Force refresh the database provider to create a new instance
|
||||||
ref.invalidate(databaseProvider);
|
ref.invalidate(databaseProvider);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import 'dart:async';
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:dio_smart_retry/dio_smart_retry.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:dio/dio.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:device_info_plus/device_info_plus.dart';
|
||||||
import 'package:island/models/auth.dart';
|
import 'package:island/models/auth.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.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';
|
import 'config.dart';
|
||||||
|
|
||||||
@@ -75,7 +78,7 @@ final apiClientProvider = Provider<Dio>((ref) {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
dio.interceptors.add(
|
dio.interceptors.addAll([
|
||||||
InterceptorsWrapper(
|
InterceptorsWrapper(
|
||||||
onRequest: (
|
onRequest: (
|
||||||
RequestOptions options,
|
RequestOptions options,
|
||||||
@@ -97,7 +100,27 @@ final apiClientProvider = Provider<Dio>((ref) {
|
|||||||
return handler.next(options);
|
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(milliseconds: 300),
|
||||||
|
Duration(milliseconds: 500),
|
||||||
|
Duration(milliseconds: 1000),
|
||||||
|
],
|
||||||
|
retryEvaluator: (err, _) => err.requestOptions.method == 'GET',
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
return dio;
|
return dio;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,38 +1,16 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:island/pods/config.dart';
|
import 'package:island/pods/config.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
|
|
||||||
final themeProvider = StateNotifierProvider<ThemeNotifier, ThemeSet?>((ref) {
|
part 'theme.g.dart';
|
||||||
return ThemeNotifier();
|
|
||||||
});
|
|
||||||
|
|
||||||
class ThemeNotifier extends StateNotifier<ThemeSet?> {
|
@riverpod
|
||||||
ThemeNotifier() : super(null) {
|
ThemeSet theme(Ref ref) {
|
||||||
_loadTheme();
|
final settings = ref.watch(appSettingsNotifierProvider);
|
||||||
}
|
return createAppThemeSet(settings);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const kMaterialYouToggleStoreKey = 'app_theme_material_you';
|
|
||||||
|
|
||||||
class ThemeSet {
|
class ThemeSet {
|
||||||
ThemeData light;
|
ThemeData light;
|
||||||
ThemeData dark;
|
ThemeData dark;
|
||||||
@@ -40,52 +18,50 @@ class ThemeSet {
|
|||||||
ThemeSet({required this.light, required this.dark});
|
ThemeSet({required this.light, required this.dark});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<ThemeSet> createAppThemeSet({
|
ThemeSet createAppThemeSet(AppSettings settings) {
|
||||||
Color? seedColorOverride,
|
|
||||||
bool? useMaterial3,
|
|
||||||
String? customFonts,
|
|
||||||
}) async {
|
|
||||||
return ThemeSet(
|
return ThemeSet(
|
||||||
light: await createAppTheme(
|
light: createAppTheme(Brightness.light, settings),
|
||||||
Brightness.light,
|
dark: createAppTheme(Brightness.dark, settings),
|
||||||
useMaterial3: useMaterial3,
|
|
||||||
customFonts: customFonts,
|
|
||||||
),
|
|
||||||
dark: await createAppTheme(
|
|
||||||
Brightness.dark,
|
|
||||||
useMaterial3: useMaterial3,
|
|
||||||
customFonts: customFonts,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<ThemeData> createAppTheme(
|
ThemeData createAppTheme(Brightness brightness, AppSettings settings) {
|
||||||
Brightness brightness, {
|
|
||||||
Color? seedColorOverride,
|
|
||||||
bool? useMaterial3,
|
|
||||||
String? customFonts,
|
|
||||||
}) async {
|
|
||||||
final prefs = await SharedPreferences.getInstance();
|
|
||||||
|
|
||||||
final seedColorString = prefs.getInt(kAppColorSchemeStoreKey);
|
|
||||||
final seedColor =
|
final seedColor =
|
||||||
seedColorString != null ? Color(seedColorString) : Colors.indigo;
|
settings.appColorScheme != null
|
||||||
|
? Color(settings.appColorScheme!)
|
||||||
|
: Colors.indigo;
|
||||||
|
|
||||||
final colorScheme = ColorScheme.fromSeed(
|
var colorScheme = ColorScheme.fromSeed(
|
||||||
seedColor: seedColorOverride ?? seedColor,
|
seedColor: seedColor,
|
||||||
brightness: brightness,
|
brightness: brightness,
|
||||||
);
|
);
|
||||||
|
|
||||||
final hasAppBarTransparent =
|
final customColors = settings.customColors;
|
||||||
prefs.getBool(kAppbarTransparentStoreKey) ?? false;
|
if (customColors != null) {
|
||||||
final useM3 =
|
colorScheme = colorScheme.copyWith(
|
||||||
useMaterial3 ?? (prefs.getBool(kMaterialYouToggleStoreKey) ?? true);
|
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 =
|
final inUseFonts =
|
||||||
(customFonts ?? prefs.getString(kAppCustomFonts))
|
settings.customFonts?.split(',').map((ele) => ele.trim()).toList() ??
|
||||||
?.split(',')
|
|
||||||
.map((ele) => ele.trim())
|
|
||||||
.toList() ??
|
|
||||||
['Nunito'];
|
['Nunito'];
|
||||||
|
|
||||||
return ThemeData(
|
return ThemeData(
|
||||||
@@ -100,10 +76,6 @@ Future<ThemeData> createAppTheme(
|
|||||||
opticalSize: 20,
|
opticalSize: 20,
|
||||||
color: colorScheme.onSurface,
|
color: colorScheme.onSurface,
|
||||||
),
|
),
|
||||||
snackBarTheme: SnackBarThemeData(
|
|
||||||
behavior: useM3 ? SnackBarBehavior.floating : SnackBarBehavior.fixed,
|
|
||||||
width: 480,
|
|
||||||
),
|
|
||||||
appBarTheme: AppBarTheme(
|
appBarTheme: AppBarTheme(
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
elevation: hasAppBarTransparent ? 0 : null,
|
elevation: hasAppBarTransparent ? 0 : null,
|
||||||
@@ -112,6 +84,12 @@ Future<ThemeData> createAppTheme(
|
|||||||
foregroundColor:
|
foregroundColor:
|
||||||
hasAppBarTransparent ? colorScheme.onSurface : colorScheme.onPrimary,
|
hasAppBarTransparent ? colorScheme.onSurface : colorScheme.onPrimary,
|
||||||
),
|
),
|
||||||
|
cardTheme: CardThemeData(
|
||||||
|
color: colorScheme.surfaceContainer.withOpacity(
|
||||||
|
settings.cardTransparency,
|
||||||
|
),
|
||||||
|
elevation: settings.cardTransparency <= 1 ? 0 : null,
|
||||||
|
),
|
||||||
pageTransitionsTheme: PageTransitionsTheme(
|
pageTransitionsTheme: PageTransitionsTheme(
|
||||||
builders: {
|
builders: {
|
||||||
TargetPlatform.android: ZoomPageTransitionsBuilder(),
|
TargetPlatform.android: ZoomPageTransitionsBuilder(),
|
||||||
|
|||||||
26
lib/pods/theme.g.dart
Normal file
26
lib/pods/theme.g.dart
Normal 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
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:developer';
|
|
||||||
import 'dart:io' show Platform;
|
import 'dart:io' show Platform;
|
||||||
|
|
||||||
import 'package:dio/dio.dart';
|
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/models/account.dart';
|
||||||
import 'package:island/pods/config.dart';
|
import 'package:island/pods/config.dart';
|
||||||
import 'package:island/pods/network.dart';
|
import 'package:island/pods/network.dart';
|
||||||
|
import 'package:island/talker.dart';
|
||||||
|
|
||||||
class UserInfoNotifier extends StateNotifier<AsyncValue<SnAccount?>> {
|
class UserInfoNotifier extends StateNotifier<AsyncValue<SnAccount?>> {
|
||||||
final Ref _ref;
|
final Ref _ref;
|
||||||
@@ -21,7 +21,7 @@ class UserInfoNotifier extends StateNotifier<AsyncValue<SnAccount?>> {
|
|||||||
Future<void> fetchUser() async {
|
Future<void> fetchUser() async {
|
||||||
final token = _ref.watch(tokenProvider);
|
final token = _ref.watch(tokenProvider);
|
||||||
if (token == null) {
|
if (token == null) {
|
||||||
log('[UserInfo] No token found, not going to fetch...');
|
talker.info('[UserInfo] No token found, not going to fetch...');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -30,7 +30,7 @@ class UserInfoNotifier extends StateNotifier<AsyncValue<SnAccount?>> {
|
|||||||
final user = SnAccount.fromJson(response.data);
|
final user = SnAccount.fromJson(response.data);
|
||||||
state = AsyncValue.data(user);
|
state = AsyncValue.data(user);
|
||||||
|
|
||||||
if (kIsWeb || !Platform.isLinux) {
|
if (kIsWeb || !(Platform.isLinux || Platform.isWindows)) {
|
||||||
FirebaseAnalytics.instance.setUserId(id: user.id);
|
FirebaseAnalytics.instance.setUserId(id: user.id);
|
||||||
}
|
}
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stackTrace) {
|
||||||
@@ -44,9 +44,12 @@ class UserInfoNotifier extends StateNotifier<AsyncValue<SnAccount?>> {
|
|||||||
: 'failedToLoadUserInfoNetwork')
|
: 'failedToLoadUserInfoNetwork')
|
||||||
.tr()
|
.tr()
|
||||||
.trim(),
|
.trim(),
|
||||||
'${error.response!.statusCode}\n${error.response?.headers}',
|
'',
|
||||||
jsonEncode(error.response?.data),
|
'${error.response?.statusCode ?? 'Network Error'}',
|
||||||
].join('\n\n'),
|
if (error.response?.headers != null) error.response?.headers,
|
||||||
|
if (error.response?.data != null)
|
||||||
|
jsonEncode(error.response?.data),
|
||||||
|
].join('\n'),
|
||||||
iconStyle: IconStyle.error,
|
iconStyle: IconStyle.error,
|
||||||
neutralButtonTitle: 'retry'.tr(),
|
neutralButtonTitle: 'retry'.tr(),
|
||||||
negativeButtonTitle: 'okay'.tr(),
|
negativeButtonTitle: 'okay'.tr(),
|
||||||
@@ -72,11 +75,10 @@ class UserInfoNotifier extends StateNotifier<AsyncValue<SnAccount?>> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
log(
|
talker.error(
|
||||||
"[UserInfo] Failed to fetch user info...",
|
"[UserInfo] Failed to fetch user info...",
|
||||||
name: 'UserInfoNotifier',
|
error,
|
||||||
error: error,
|
stackTrace,
|
||||||
stackTrace: stackTrace,
|
|
||||||
);
|
);
|
||||||
state = AsyncValue.data(null);
|
state = AsyncValue.data(null);
|
||||||
}
|
}
|
||||||
@@ -87,7 +89,7 @@ class UserInfoNotifier extends StateNotifier<AsyncValue<SnAccount?>> {
|
|||||||
final prefs = _ref.read(sharedPreferencesProvider);
|
final prefs = _ref.read(sharedPreferencesProvider);
|
||||||
await prefs.remove(kTokenPairStoreKey);
|
await prefs.remove(kTokenPairStoreKey);
|
||||||
_ref.invalidate(tokenProvider);
|
_ref.invalidate(tokenProvider);
|
||||||
if (kIsWeb || !Platform.isLinux) {
|
if (kIsWeb || !(Platform.isLinux || Platform.isWindows)) {
|
||||||
FirebaseAnalytics.instance.setUserId(id: null);
|
FirebaseAnalytics.instance.setUserId(id: null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:developer';
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
@@ -8,6 +7,7 @@ import 'package:island/pods/config.dart';
|
|||||||
import 'package:island/pods/network.dart';
|
import 'package:island/pods/network.dart';
|
||||||
import 'package:web_socket_channel/io.dart';
|
import 'package:web_socket_channel/io.dart';
|
||||||
import 'package:web_socket_channel/web_socket_channel.dart';
|
import 'package:web_socket_channel/web_socket_channel.dart';
|
||||||
|
import 'package:island/talker.dart';
|
||||||
|
|
||||||
part 'websocket.freezed.dart';
|
part 'websocket.freezed.dart';
|
||||||
part 'websocket.g.dart';
|
part 'websocket.g.dart';
|
||||||
@@ -64,7 +64,7 @@ class WebSocketService {
|
|||||||
|
|
||||||
final url = '$baseUrl/ws'.replaceFirst('http', 'ws');
|
final url = '$baseUrl/ws'.replaceFirst('http', 'ws');
|
||||||
|
|
||||||
log('[WebSocket] Trying connecting to $url');
|
talker.info('[WebSocket] Trying connecting to $url');
|
||||||
try {
|
try {
|
||||||
if (kIsWeb) {
|
if (kIsWeb) {
|
||||||
_channel = WebSocketChannel.connect(Uri.parse('$url?tk=$token'));
|
_channel = WebSocketChannel.connect(Uri.parse('$url?tk=$token'));
|
||||||
@@ -88,24 +88,28 @@ class WebSocketService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_streamController.sink.add(packet);
|
_streamController.sink.add(packet);
|
||||||
log(
|
talker.info(
|
||||||
"[WebSocket] Received packet: ${packet.type} ${packet.errorMessage}",
|
"[WebSocket] Received packet: ${packet.type} ${packet.errorMessage}",
|
||||||
);
|
);
|
||||||
if (packet.type == 'pong' && _heartbeatAt != null) {
|
if (packet.type == 'pong' && _heartbeatAt != null) {
|
||||||
var now = DateTime.now();
|
var now = DateTime.now();
|
||||||
heartbeatDelay = now.difference(_heartbeatAt!);
|
heartbeatDelay = now.difference(_heartbeatAt!);
|
||||||
log(
|
talker.info(
|
||||||
"[WebSocket] Server respond last heartbeat for ${heartbeatDelay!.inMilliseconds} ms",
|
"[WebSocket] Server respond last heartbeat for ${heartbeatDelay!.inMilliseconds} ms",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onDone: () {
|
onDone: () {
|
||||||
log('[WebSocket] Connection closed, attempting to reconnect...');
|
talker.info(
|
||||||
|
'[WebSocket] Connection closed, attempting to reconnect...',
|
||||||
|
);
|
||||||
_scheduleReconnect();
|
_scheduleReconnect();
|
||||||
_statusStreamController.sink.add(WebSocketState.disconnected());
|
_statusStreamController.sink.add(WebSocketState.disconnected());
|
||||||
},
|
},
|
||||||
onError: (error) {
|
onError: (error) {
|
||||||
log('[WebSocket] Error occurred: $error, attempting to reconnect...');
|
talker.error(
|
||||||
|
'[WebSocket] Error occurred: $error, attempting to reconnect...',
|
||||||
|
);
|
||||||
_scheduleReconnect();
|
_scheduleReconnect();
|
||||||
_statusStreamController.sink.add(
|
_statusStreamController.sink.add(
|
||||||
WebSocketState.error(error.toString()),
|
WebSocketState.error(error.toString()),
|
||||||
@@ -113,7 +117,7 @@ class WebSocketService {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log('[WebSocket] Failed to connect: $err');
|
talker.error('[WebSocket] Failed to connect: $err');
|
||||||
_scheduleReconnect();
|
_scheduleReconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,7 +139,7 @@ class WebSocketService {
|
|||||||
|
|
||||||
void _beatTheHeart() {
|
void _beatTheHeart() {
|
||||||
_heartbeatAt = DateTime.now();
|
_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)));
|
sendMessage(jsonEncode(WebSocketPacket(type: 'ping', data: null)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
480
lib/route.dart
480
lib/route.dart
@@ -6,19 +6,17 @@ import 'package:flutter/foundation.dart' show kIsWeb;
|
|||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:island/screens/about.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/app_detail.dart';
|
||||||
import 'package:island/screens/developers/bot_detail.dart';
|
import 'package:island/screens/developers/bot_detail.dart';
|
||||||
import 'package:island/screens/developers/edit_app.dart';
|
import 'package:island/screens/developers/edit_app.dart';
|
||||||
import 'package:island/screens/developers/edit_bot.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/hub.dart';
|
||||||
|
import 'package:island/screens/developers/new_app.dart';
|
||||||
import 'package:island/screens/developers/new_bot.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/edit_project.dart';
|
||||||
import 'package:island/screens/developers/new_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/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_categories_list.dart';
|
||||||
import 'package:island/screens/posts/post_category_detail.dart';
|
import 'package:island/screens/posts/post_category_detail.dart';
|
||||||
import 'package:island/screens/posts/post_search.dart';
|
import 'package:island/screens/posts/post_search.dart';
|
||||||
@@ -27,7 +25,6 @@ import 'package:island/screens/tabs.dart';
|
|||||||
import 'package:island/screens/explore.dart';
|
import 'package:island/screens/explore.dart';
|
||||||
import 'package:island/screens/discovery/article_detail.dart';
|
import 'package:island/screens/discovery/article_detail.dart';
|
||||||
import 'package:island/screens/account.dart';
|
import 'package:island/screens/account.dart';
|
||||||
import 'package:island/screens/notification.dart';
|
|
||||||
import 'package:island/screens/wallet.dart';
|
import 'package:island/screens/wallet.dart';
|
||||||
import 'package:island/screens/account/relationship.dart';
|
import 'package:island/screens/account/relationship.dart';
|
||||||
import 'package:island/screens/account/profile.dart';
|
import 'package:island/screens/account/profile.dart';
|
||||||
@@ -35,22 +32,21 @@ import 'package:island/screens/account/me/profile_update.dart';
|
|||||||
import 'package:island/screens/account/leveling.dart';
|
import 'package:island/screens/account/leveling.dart';
|
||||||
import 'package:island/screens/account/me/account_settings.dart';
|
import 'package:island/screens/account/me/account_settings.dart';
|
||||||
import 'package:island/screens/chat/chat.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.dart';
|
||||||
import 'package:island/screens/chat/room_detail.dart';
|
import 'package:island/screens/chat/room_detail.dart';
|
||||||
import 'package:island/screens/chat/call.dart';
|
import 'package:island/screens/chat/call.dart';
|
||||||
import 'package:island/screens/chat/search_messages_screen.dart';
|
import 'package:island/screens/chat/search_messages.dart';
|
||||||
import 'package:island/screens/creators/hub.dart';
|
import 'package:island/screens/creators/hub.dart';
|
||||||
import 'package:island/screens/creators/posts/post_manage_list.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/stickers.dart';
|
||||||
import 'package:island/screens/creators/stickers/pack_detail.dart';
|
|
||||||
import 'package:island/screens/stickers/sticker_marketplace.dart';
|
import 'package:island/screens/stickers/sticker_marketplace.dart';
|
||||||
import 'package:island/screens/stickers/pack_detail.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_marketplace.dart';
|
||||||
import 'package:island/screens/discovery/feeds/feed_detail.dart';
|
import 'package:island/screens/discovery/feeds/feed_detail.dart';
|
||||||
import 'package:island/screens/creators/poll/poll_list.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_list.dart';
|
||||||
import 'package:island/screens/creators/webfeed/webfeed_edit.dart';
|
|
||||||
import 'package:island/screens/poll/poll_editor.dart';
|
import 'package:island/screens/poll/poll_editor.dart';
|
||||||
import 'package:island/screens/posts/compose.dart';
|
import 'package:island/screens/posts/compose.dart';
|
||||||
import 'package:island/screens/posts/post_detail.dart';
|
import 'package:island/screens/posts/post_detail.dart';
|
||||||
@@ -59,12 +55,14 @@ import 'package:island/screens/auth/login.dart';
|
|||||||
import 'package:island/screens/auth/create_account.dart';
|
import 'package:island/screens/auth/create_account.dart';
|
||||||
import 'package:island/screens/settings.dart';
|
import 'package:island/screens/settings.dart';
|
||||||
import 'package:island/screens/realm/realms.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/realm/realm_detail.dart';
|
||||||
import 'package:island/screens/account/event_calendar.dart';
|
|
||||||
import 'package:island/screens/discovery/realms.dart';
|
import 'package:island/screens/discovery/realms.dart';
|
||||||
import 'package:island/screens/reports/report_detail.dart';
|
import 'package:island/screens/reports/report_detail.dart';
|
||||||
import 'package:island/screens/reports/report_list.dart';
|
import 'package:island/screens/reports/report_list.dart';
|
||||||
|
import 'package:island/talker.dart';
|
||||||
import 'package:island/widgets/post/post_shuffle.dart';
|
import 'package:island/widgets/post/post_shuffle.dart';
|
||||||
|
import 'package:talker_flutter/talker_flutter.dart';
|
||||||
|
|
||||||
// Shell route keys for nested navigation
|
// Shell route keys for nested navigation
|
||||||
final rootNavigatorKey = GlobalKey<NavigatorState>();
|
final rootNavigatorKey = GlobalKey<NavigatorState>();
|
||||||
@@ -86,11 +84,7 @@ Widget _tabPagesTransitionBuilder(
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool get _supportsAnalytics =>
|
bool get _supportsAnalytics =>
|
||||||
kIsWeb ||
|
kIsWeb || Platform.isAndroid || Platform.isIOS || Platform.isMacOS;
|
||||||
Platform.isAndroid ||
|
|
||||||
Platform.isIOS ||
|
|
||||||
Platform.isMacOS ||
|
|
||||||
Platform.isWindows;
|
|
||||||
|
|
||||||
// Provider for the router
|
// Provider for the router
|
||||||
final routerProvider = Provider<GoRouter>((ref) {
|
final routerProvider = Provider<GoRouter>((ref) {
|
||||||
@@ -100,6 +94,7 @@ final routerProvider = Provider<GoRouter>((ref) {
|
|||||||
observers: [
|
observers: [
|
||||||
if (_supportsAnalytics)
|
if (_supportsAnalytics)
|
||||||
FirebaseAnalyticsObserver(analytics: FirebaseAnalytics.instance),
|
FirebaseAnalyticsObserver(analytics: FirebaseAnalytics.instance),
|
||||||
|
TalkerRouteObserver(talker),
|
||||||
],
|
],
|
||||||
routes: [
|
routes: [
|
||||||
ShellRoute(
|
ShellRoute(
|
||||||
@@ -137,262 +132,9 @@ final routerProvider = Provider<GoRouter>((ref) {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
name: 'accountCalendar',
|
name: 'logs',
|
||||||
path: '/account/:name/calendar',
|
path: '/logs',
|
||||||
builder: (context, state) {
|
builder: (context, state) => TalkerScreen(talker: talker),
|
||||||
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']!,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
|
|
||||||
// Web articles
|
// Web articles
|
||||||
@@ -649,20 +391,15 @@ final routerProvider = Provider<GoRouter>((ref) {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
GoRoute(
|
|
||||||
name: 'notifications',
|
|
||||||
path: '/account/notifications',
|
|
||||||
builder: (context, state) => const NotificationScreen(),
|
|
||||||
),
|
|
||||||
GoRoute(
|
GoRoute(
|
||||||
name: 'wallet',
|
name: 'wallet',
|
||||||
path: '/account/wallet',
|
path: '/account/wallet',
|
||||||
builder: (context, state) => const WalletScreen(),
|
builder: (context, state) => const WalletScreen(),
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
name: 'socialCredits',
|
name: 'files',
|
||||||
path: '/account/credits',
|
path: '/account/files',
|
||||||
builder: (context, state) => const SocialCreditsScreen(),
|
builder: (context, state) => const FileListScreen(),
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
name: 'relationships',
|
name: 'relationships',
|
||||||
@@ -702,12 +439,195 @@ final routerProvider = Provider<GoRouter>((ref) {
|
|||||||
|
|
||||||
GoRoute(
|
GoRoute(
|
||||||
name: 'accountProfile',
|
name: 'accountProfile',
|
||||||
path: '/account/:name',
|
path: '/accounts/:name',
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
final name = state.pathParameters['name']!;
|
final name = state.pathParameters['name']!;
|
||||||
return AccountProfileScreen(name: 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']!,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.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/alert.dart';
|
||||||
import 'package:island/widgets/app_scaffold.dart';
|
import 'package:island/widgets/app_scaffold.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
@@ -68,7 +68,7 @@ class _AboutScreenState extends ConsumerState<AboutScreen> {
|
|||||||
try {
|
try {
|
||||||
final deviceInfoPlugin = DeviceInfoPlugin();
|
final deviceInfoPlugin = DeviceInfoPlugin();
|
||||||
_deviceInfo = await deviceInfoPlugin.deviceInfo;
|
_deviceInfo = await deviceInfoPlugin.deviceInfo;
|
||||||
_deviceUdid = await getUdid();
|
_deviceUdid = await udid.getUdid();
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
@@ -174,12 +174,20 @@ class _AboutScreenState extends ConsumerState<AboutScreen> {
|
|||||||
context,
|
context,
|
||||||
title: 'Device Information',
|
title: 'Device Information',
|
||||||
children: [
|
children: [
|
||||||
_buildInfoItem(
|
FutureBuilder<String>(
|
||||||
context,
|
future: udid.getDeviceName(),
|
||||||
icon: Symbols.label,
|
builder: (context, snapshot) {
|
||||||
label: 'aboutDeviceName'.tr(),
|
final value =
|
||||||
value:
|
snapshot.hasData
|
||||||
_deviceInfo?.data['name'] ?? 'unknown'.tr(),
|
? snapshot.data!
|
||||||
|
: 'unknown'.tr();
|
||||||
|
return _buildInfoItem(
|
||||||
|
context,
|
||||||
|
icon: Symbols.label,
|
||||||
|
label: 'aboutDeviceName'.tr(),
|
||||||
|
value: value,
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
_buildInfoItem(
|
_buildInfoItem(
|
||||||
context,
|
context,
|
||||||
@@ -203,21 +211,11 @@ class _AboutScreenState extends ConsumerState<AboutScreen> {
|
|||||||
icon: Symbols.system_update,
|
icon: Symbols.system_update,
|
||||||
title: 'Check for updates',
|
title: 'Check for updates',
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
// Fetch latest release and show the unified sheet
|
|
||||||
final svc = UpdateService();
|
final svc = UpdateService();
|
||||||
// Reuse service fetch + compare to decide content
|
|
||||||
showLoadingModal(context);
|
showLoadingModal(context);
|
||||||
final release = await svc.fetchLatestRelease();
|
svc.checkForUpdates(context);
|
||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
hideLoadingModal(context);
|
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(
|
_buildListTile(
|
||||||
|
|||||||
@@ -66,7 +66,6 @@ class AccountScreen extends HookConsumerWidget {
|
|||||||
isNoBackground: isWide,
|
isNoBackground: isWide,
|
||||||
appBar: AppBar(backgroundColor: Colors.transparent, toolbarHeight: 0),
|
appBar: AppBar(backgroundColor: Colors.transparent, toolbarHeight: 0),
|
||||||
body: SingleChildScrollView(
|
body: SingleChildScrollView(
|
||||||
padding: getTabbedPadding(context),
|
|
||||||
child: Column(
|
child: Column(
|
||||||
spacing: 4,
|
spacing: 4,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
@@ -141,72 +140,133 @@ class AccountScreen extends HookConsumerWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
).padding(horizontal: 8),
|
).padding(horizontal: 8),
|
||||||
GestureDetector(
|
LevelingProgressCard(
|
||||||
child: LevelingProgressCard(
|
isCompact: true,
|
||||||
level: user.value!.profile.level,
|
level: user.value!.profile.level,
|
||||||
experience: user.value!.profile.experience,
|
experience: user.value!.profile.experience,
|
||||||
progress: user.value!.profile.levelingProgress,
|
progress: user.value!.profile.levelingProgress,
|
||||||
),
|
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.pushNamed('leveling');
|
context.pushNamed('leveling');
|
||||||
},
|
},
|
||||||
).padding(horizontal: 12),
|
).padding(horizontal: 12),
|
||||||
Row(
|
if (!isWideScreen(context)) const SizedBox.shrink(),
|
||||||
children: [
|
if (!isWideScreen(context))
|
||||||
Expanded(
|
Row(
|
||||||
child: Card(
|
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(
|
child: InkWell(
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
child: Column(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
spacing: 8,
|
||||||
children: [
|
children: [
|
||||||
Icon(Symbols.draw, size: 28).padding(bottom: 8),
|
Icon(Symbols.settings, size: 20),
|
||||||
Text(
|
Text('appSettings').tr().fontSize(13).bold(),
|
||||||
'creatorHub',
|
|
||||||
maxLines: 1,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
).tr().fontSize(16).bold(),
|
|
||||||
Text(
|
|
||||||
'creatorHubDescription',
|
|
||||||
maxLines: 2,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
).tr(),
|
|
||||||
],
|
],
|
||||||
).padding(horizontal: 16, vertical: 12),
|
).padding(horizontal: 16, vertical: 12),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.pushNamed('creatorHub');
|
context.pushNamed('settings');
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
).height(140),
|
),
|
||||||
),
|
Card(
|
||||||
Expanded(
|
margin: EdgeInsets.zero,
|
||||||
child: Card(
|
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
child: Column(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
spacing: 8,
|
||||||
children: [
|
children: [
|
||||||
Icon(Symbols.code, size: 28).padding(bottom: 8),
|
Icon(Symbols.person_edit, size: 20),
|
||||||
Text(
|
Text('updateYourProfile').tr().fontSize(13).bold(),
|
||||||
'developerPortal',
|
|
||||||
maxLines: 1,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
).tr().fontSize(16).bold(),
|
|
||||||
Text(
|
|
||||||
'developerPortalDescription',
|
|
||||||
maxLines: 2,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
).tr(),
|
|
||||||
],
|
],
|
||||||
).padding(horizontal: 16, vertical: 12),
|
).padding(horizontal: 16, vertical: 12),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.pushNamed('developerHub');
|
context.pushNamed('profileUpdate');
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
).height(140),
|
),
|
||||||
),
|
Card(
|
||||||
],
|
margin: EdgeInsets.zero,
|
||||||
).padding(horizontal: 8),
|
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(
|
ListTile(
|
||||||
minTileHeight: 48,
|
minTileHeight: 48,
|
||||||
leading: const Icon(Symbols.notifications),
|
leading: const Icon(Symbols.notifications),
|
||||||
@@ -222,7 +282,12 @@ class AccountScreen extends HookConsumerWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.pushNamed('notifications');
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
isScrollControlled: true,
|
||||||
|
useRootNavigator: true,
|
||||||
|
builder: (context) => const NotificationSheet(),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
@@ -235,6 +300,16 @@ class AccountScreen extends HookConsumerWidget {
|
|||||||
context.pushNamed('wallet');
|
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(
|
ListTile(
|
||||||
minTileHeight: 48,
|
minTileHeight: 48,
|
||||||
leading: const Icon(Symbols.people),
|
leading: const Icon(Symbols.people),
|
||||||
@@ -265,16 +340,6 @@ class AccountScreen extends HookConsumerWidget {
|
|||||||
context.pushNamed('webFeedMarketplace');
|
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(
|
ListTile(
|
||||||
minTileHeight: 48,
|
minTileHeight: 48,
|
||||||
title: Text('abuseReport').tr(),
|
title: Text('abuseReport').tr(),
|
||||||
@@ -284,37 +349,6 @@ class AccountScreen extends HookConsumerWidget {
|
|||||||
onTap: () => context.pushNamed('reportList'),
|
onTap: () => context.pushNamed('reportList'),
|
||||||
),
|
),
|
||||||
const Divider(height: 1).padding(vertical: 8),
|
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(
|
ListTile(
|
||||||
minTileHeight: 48,
|
minTileHeight: 48,
|
||||||
leading: const Icon(Symbols.info),
|
leading: const Icon(Symbols.info),
|
||||||
@@ -333,6 +367,8 @@ class AccountScreen extends HookConsumerWidget {
|
|||||||
title: Text('debugOptions').tr(),
|
title: Text('debugOptions').tr(),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
|
useRootNavigator: true,
|
||||||
|
isScrollControlled: true,
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => DebugSheet(),
|
builder: (context) => DebugSheet(),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import 'package:gap/gap.dart';
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:island/models/account.dart';
|
import 'package:island/models/account.dart';
|
||||||
import 'package:island/pods/network.dart';
|
import 'package:island/pods/network.dart';
|
||||||
import 'package:island/widgets/app_scaffold.dart';
|
|
||||||
import 'package:material_symbols_icons/material_symbols_icons.dart';
|
import 'package:material_symbols_icons/material_symbols_icons.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';
|
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';
|
||||||
@@ -59,94 +58,93 @@ class SocialCreditHistoryNotifier extends _$SocialCreditHistoryNotifier
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SocialCreditsScreen extends HookConsumerWidget {
|
class SocialCreditsTab extends HookConsumerWidget {
|
||||||
const SocialCreditsScreen({super.key});
|
const SocialCreditsTab({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final socialCredits = ref.watch(socialCreditsProvider);
|
final socialCredits = ref.watch(socialCreditsProvider);
|
||||||
|
return Column(
|
||||||
return AppScaffold(
|
children: [
|
||||||
appBar: AppBar(title: Text('socialCredits').tr()),
|
const Gap(8),
|
||||||
body: Column(
|
Card(
|
||||||
children: [
|
margin: const EdgeInsets.only(left: 16, right: 16, top: 8),
|
||||||
Card(
|
child: socialCredits
|
||||||
margin: EdgeInsets.only(left: 16, right: 16, top: 8),
|
.when(
|
||||||
child: socialCredits
|
data:
|
||||||
.when(
|
(credits) => Stack(
|
||||||
data:
|
children: [
|
||||||
(credits) => Stack(
|
Column(
|
||||||
children: [
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
Column(
|
children: [
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
Text(
|
||||||
children: [
|
credits < 100
|
||||||
Text(
|
? 'socialCreditsLevelPoor'.tr()
|
||||||
credits < 100
|
: credits < 150
|
||||||
? 'socialCreditsLevelPoor'.tr()
|
? 'socialCreditsLevelNormal'.tr()
|
||||||
: credits < 150
|
: credits < 200
|
||||||
? 'socialCreditsLevelNormal'.tr()
|
? 'socialCreditsLevelGood'.tr()
|
||||||
: credits < 200
|
: 'socialCreditsLevelExcellent'.tr(),
|
||||||
? 'socialCreditsLevelGood'.tr()
|
).tr().bold().fontSize(20),
|
||||||
: 'socialCreditsLevelExcellent'.tr(),
|
Text(
|
||||||
).tr().bold().fontSize(20),
|
'${credits.toStringAsFixed(2)} pts',
|
||||||
Text(
|
).fontSize(14),
|
||||||
'${credits.toStringAsFixed(2)} pts',
|
const Gap(8),
|
||||||
).fontSize(14),
|
LinearProgressIndicator(value: credits / 200),
|
||||||
const Gap(8),
|
],
|
||||||
LinearProgressIndicator(value: credits / 200),
|
),
|
||||||
],
|
Positioned(
|
||||||
|
right: 0,
|
||||||
|
top: 0,
|
||||||
|
child: IconButton(
|
||||||
|
onPressed: () {},
|
||||||
|
icon: const Icon(Symbols.info),
|
||||||
|
tooltip: 'socialCreditsDescription'.tr(),
|
||||||
),
|
),
|
||||||
Positioned(
|
),
|
||||||
right: 0,
|
],
|
||||||
top: 0,
|
),
|
||||||
child: IconButton(
|
error: (_, _) => Text('Error loading credits'),
|
||||||
onPressed: () {},
|
loading: () => const LinearProgressIndicator(),
|
||||||
icon: const Icon(Symbols.info),
|
)
|
||||||
tooltip: 'socialCreditsDescription'.tr(),
|
.padding(horizontal: 20, vertical: 16),
|
||||||
),
|
),
|
||||||
),
|
Expanded(
|
||||||
],
|
child: PagingHelperView(
|
||||||
|
provider: socialCreditHistoryNotifierProvider,
|
||||||
|
futureRefreshable: socialCreditHistoryNotifierProvider.future,
|
||||||
|
notifierRefreshable: socialCreditHistoryNotifierProvider.notifier,
|
||||||
|
contentBuilder:
|
||||||
|
(data, widgetCount, endItemView) => ListView.builder(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
itemCount: widgetCount,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
if (index == widgetCount - 1) {
|
||||||
|
return endItemView;
|
||||||
|
}
|
||||||
|
final record = data.items[index];
|
||||||
|
return ListTile(
|
||||||
|
contentPadding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 24,
|
||||||
),
|
),
|
||||||
error: (_, _) => Text('Error loading credits'),
|
title: Text(record.reason),
|
||||||
loading: () => const LinearProgressIndicator(),
|
subtitle: Text(
|
||||||
)
|
DateFormat.yMMMd().format(record.createdAt),
|
||||||
.padding(horizontal: 20, vertical: 16),
|
),
|
||||||
),
|
trailing: Text(
|
||||||
Expanded(
|
record.delta > 0
|
||||||
child: PagingHelperView(
|
? '+${record.delta}'
|
||||||
provider: socialCreditHistoryNotifierProvider,
|
: '${record.delta}',
|
||||||
futureRefreshable: socialCreditHistoryNotifierProvider.future,
|
style: TextStyle(
|
||||||
notifierRefreshable: socialCreditHistoryNotifierProvider.notifier,
|
color: record.delta > 0 ? Colors.green : Colors.red,
|
||||||
contentBuilder:
|
|
||||||
(data, widgetCount, endItemView) => ListView.builder(
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
itemCount: widgetCount,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
if (index == widgetCount - 1) {
|
|
||||||
return endItemView;
|
|
||||||
}
|
|
||||||
final record = data.items[index];
|
|
||||||
return ListTile(
|
|
||||||
contentPadding: EdgeInsets.symmetric(horizontal: 24),
|
|
||||||
title: Text(record.reason),
|
|
||||||
subtitle: Text(
|
|
||||||
DateFormat.yMMMd().format(record.createdAt),
|
|
||||||
),
|
),
|
||||||
trailing: Text(
|
),
|
||||||
record.delta > 0
|
);
|
||||||
? '+${record.delta}'
|
},
|
||||||
: '${record.delta}',
|
),
|
||||||
style: TextStyle(
|
|
||||||
color: record.delta > 0 ? Colors.green : Colors.red,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,42 +1,21 @@
|
|||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:dio/dio.dart';
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:island/models/account.dart';
|
import 'package:island/models/account.dart';
|
||||||
import 'package:island/models/wallet.dart';
|
|
||||||
import 'package:island/pods/network.dart';
|
import 'package:island/pods/network.dart';
|
||||||
import 'package:island/pods/userinfo.dart';
|
import 'package:island/pods/userinfo.dart';
|
||||||
import 'package:island/services/responsive.dart';
|
import 'package:island/screens/account/credits.dart';
|
||||||
import 'package:island/services/time.dart';
|
import 'package:island/services/time.dart';
|
||||||
import 'package:island/widgets/account/leveling_progress.dart';
|
import 'package:island/widgets/account/leveling_progress.dart';
|
||||||
import 'package:island/widgets/account/restore_purchase_sheet.dart';
|
import 'package:island/widgets/account/stellar_program_tab.dart';
|
||||||
import 'package:island/widgets/alert.dart';
|
|
||||||
import 'package:island/widgets/app_scaffold.dart';
|
import 'package:island/widgets/app_scaffold.dart';
|
||||||
import 'package:island/widgets/payment/payment_overlay.dart';
|
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';
|
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
|
||||||
part 'leveling.g.dart';
|
part 'leveling.g.dart';
|
||||||
|
|
||||||
@riverpod
|
|
||||||
Future<SnWalletSubscription?> accountStellarSubscription(Ref ref) async {
|
|
||||||
try {
|
|
||||||
final client = ref.watch(apiClientProvider);
|
|
||||||
final resp = await client.get('/id/subscriptions/fuzzy/solian.stellar');
|
|
||||||
return SnWalletSubscription.fromJson(resp.data);
|
|
||||||
} catch (err) {
|
|
||||||
if (err is DioException && err.response?.statusCode == 404) return null;
|
|
||||||
rethrow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
class LevelingHistoryNotifier extends _$LevelingHistoryNotifier
|
class LevelingHistoryNotifier extends _$LevelingHistoryNotifier
|
||||||
with CursorPagingNotifierMixin<SnExperienceRecord> {
|
with CursorPagingNotifierMixin<SnExperienceRecord> {
|
||||||
@@ -89,7 +68,7 @@ class LevelingScreen extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return DefaultTabController(
|
return DefaultTabController(
|
||||||
length: 2,
|
length: 3,
|
||||||
child: AppScaffold(
|
child: AppScaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text('levelingProgress'.tr()),
|
title: Text('levelingProgress'.tr()),
|
||||||
@@ -104,6 +83,15 @@ class LevelingScreen extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
Tab(
|
||||||
|
child: Text(
|
||||||
|
'socialCredits'.tr(),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Theme.of(context).appBarTheme.foregroundColor!,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
Tab(
|
Tab(
|
||||||
child: Text(
|
child: Text(
|
||||||
'stellarProgram'.tr(),
|
'stellarProgram'.tr(),
|
||||||
@@ -119,7 +107,8 @@ class LevelingScreen extends HookConsumerWidget {
|
|||||||
body: TabBarView(
|
body: TabBarView(
|
||||||
children: [
|
children: [
|
||||||
_buildLevelingTab(context, ref, user.value!),
|
_buildLevelingTab(context, ref, user.value!),
|
||||||
_buildStellarProgramTab(context, ref),
|
const SocialCreditsTab(),
|
||||||
|
const StellarProgramTab(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -138,7 +127,6 @@ class LevelingScreen extends HookConsumerWidget {
|
|||||||
return Center(
|
return Center(
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||||
constraints: const BoxConstraints(maxWidth: 480),
|
|
||||||
child: CustomScrollView(
|
child: CustomScrollView(
|
||||||
slivers: [
|
slivers: [
|
||||||
const SliverGap(20),
|
const SliverGap(20),
|
||||||
@@ -164,10 +152,33 @@ class LevelingScreen extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
const SliverGap(16),
|
const SliverGap(16),
|
||||||
|
|
||||||
// Stairs visualization with fixed height and horizontal scroll
|
SliverToBoxAdapter(
|
||||||
SliverToBoxAdapter(child: _buildLevelStairs(context, currentLevel)),
|
child: Card(
|
||||||
const SliverGap(24),
|
margin: EdgeInsets.zero,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'${'levelingProgressLevel'.tr(args: [currentLevel.toString()])} / 120',
|
||||||
|
textAlign: TextAlign.start,
|
||||||
|
style: Theme.of(context).textTheme.bodySmall,
|
||||||
|
),
|
||||||
|
const Gap(8),
|
||||||
|
LinearProgressIndicator(
|
||||||
|
value: currentLevel / 120,
|
||||||
|
minHeight: 10,
|
||||||
|
stopIndicatorRadius: 0,
|
||||||
|
trackGap: 0,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
backgroundColor:
|
||||||
|
Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||||
|
borderRadius: BorderRadius.circular(32),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).padding(horizontal: 16, top: 16, bottom: 12),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SliverGap(16),
|
||||||
// Leveling History
|
// Leveling History
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: Text(
|
child: Text(
|
||||||
@@ -227,585 +238,12 @@ class LevelingScreen extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
SliverGap(getTabbedPadding(context, vertical: 20).vertical),
|
SliverGap(20),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildStellarProgramTab(BuildContext context, WidgetRef ref) {
|
|
||||||
final stellarSubscription = ref.watch(accountStellarSubscriptionProvider);
|
|
||||||
|
|
||||||
return SingleChildScrollView(
|
|
||||||
padding: getTabbedPadding(context, horizontal: 20, vertical: 20),
|
|
||||||
child: Center(
|
|
||||||
child: ConstrainedBox(
|
|
||||||
constraints: const BoxConstraints(maxWidth: 480),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
||||||
children: [
|
|
||||||
_buildMembershipSection(context, ref, stellarSubscription),
|
|
||||||
const Gap(16),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildLevelStairs(BuildContext context, int currentLevel) {
|
|
||||||
const totalLevels = 14;
|
|
||||||
const stairHeight = 20.0;
|
|
||||||
const stairWidth = 50.0;
|
|
||||||
const containerHeight = 280.0;
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
height: containerHeight,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
border: Border.all(
|
|
||||||
color: Theme.of(context).colorScheme.outline.withOpacity(0.2),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.horizontal,
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
|
||||||
child: SizedBox(
|
|
||||||
width: (totalLevels * (stairWidth + 8)) + 40,
|
|
||||||
height: containerHeight,
|
|
||||||
child: CustomPaint(
|
|
||||||
painter: LevelStairsPainter(
|
|
||||||
currentLevel: currentLevel,
|
|
||||||
totalLevels: totalLevels,
|
|
||||||
primaryColor: Theme.of(context).colorScheme.primary,
|
|
||||||
surfaceColor: Theme.of(context).colorScheme.surfaceContainerHigh,
|
|
||||||
onSurfaceColor: Theme.of(context).colorScheme.onSurface,
|
|
||||||
stairHeight: stairHeight,
|
|
||||||
stairWidth: stairWidth,
|
|
||||||
),
|
|
||||||
child: Stack(
|
|
||||||
children: List.generate(totalLevels, (index) {
|
|
||||||
final level = index + 1;
|
|
||||||
final isCompleted = level <= currentLevel;
|
|
||||||
final isCurrent = level == currentLevel;
|
|
||||||
|
|
||||||
// Calculate position from bottom
|
|
||||||
final bottomPosition = 0.0;
|
|
||||||
final leftPosition = 20.0 + (index * (stairWidth + 8));
|
|
||||||
|
|
||||||
// Make higher levels progressively taller
|
|
||||||
final progressiveHeight =
|
|
||||||
40.0 + (index * 15.0); // Base height + progressive increase
|
|
||||||
|
|
||||||
return Positioned(
|
|
||||||
left: leftPosition,
|
|
||||||
bottom: bottomPosition,
|
|
||||||
child: Container(
|
|
||||||
width: stairWidth,
|
|
||||||
height: progressiveHeight,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color:
|
|
||||||
isCompleted
|
|
||||||
? Theme.of(context).colorScheme.primary
|
|
||||||
: Theme.of(
|
|
||||||
context,
|
|
||||||
).colorScheme.surfaceContainerHigh,
|
|
||||||
borderRadius: const BorderRadius.only(
|
|
||||||
topLeft: Radius.circular(6),
|
|
||||||
topRight: Radius.circular(6),
|
|
||||||
),
|
|
||||||
border:
|
|
||||||
isCurrent
|
|
||||||
? Border.all(
|
|
||||||
color: Theme.of(context).colorScheme.primary,
|
|
||||||
width: 2,
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
boxShadow:
|
|
||||||
isCurrent
|
|
||||||
? [
|
|
||||||
BoxShadow(
|
|
||||||
color: Theme.of(
|
|
||||||
context,
|
|
||||||
).colorScheme.primary.withOpacity(0.3),
|
|
||||||
blurRadius: 6,
|
|
||||||
spreadRadius: 1,
|
|
||||||
),
|
|
||||||
]
|
|
||||||
: null,
|
|
||||||
),
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.only(top: 8),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
level.toString(),
|
|
||||||
style: GoogleFonts.robotoMono(
|
|
||||||
fontSize: 14,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color:
|
|
||||||
isCompleted
|
|
||||||
? Theme.of(context).colorScheme.onPrimary
|
|
||||||
: Theme.of(context).colorScheme.onSurface,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (isCurrent) ...[
|
|
||||||
const Gap(4),
|
|
||||||
Container(
|
|
||||||
width: 4,
|
|
||||||
height: 4,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Theme.of(context).colorScheme.onPrimary,
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildMembershipSection(
|
|
||||||
BuildContext context,
|
|
||||||
WidgetRef ref,
|
|
||||||
AsyncValue<SnWalletSubscription?> stellarSubscriptionAsync,
|
|
||||||
) {
|
|
||||||
return stellarSubscriptionAsync.when(
|
|
||||||
data: (membership) => _buildMembershipContent(context, ref, membership),
|
|
||||||
loading:
|
|
||||||
() => Container(
|
|
||||||
width: double.infinity,
|
|
||||||
padding: const EdgeInsets.all(16),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
gradient: LinearGradient(
|
|
||||||
colors: [
|
|
||||||
Theme.of(context).colorScheme.primaryContainer,
|
|
||||||
Theme.of(context).colorScheme.secondaryContainer,
|
|
||||||
],
|
|
||||||
begin: Alignment.topLeft,
|
|
||||||
end: Alignment.bottomRight,
|
|
||||||
),
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
),
|
|
||||||
child: const Center(child: CircularProgressIndicator()),
|
|
||||||
),
|
|
||||||
error:
|
|
||||||
(error, stack) => Container(
|
|
||||||
width: double.infinity,
|
|
||||||
padding: const EdgeInsets.all(16),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
gradient: LinearGradient(
|
|
||||||
colors: [
|
|
||||||
Theme.of(context).colorScheme.primaryContainer,
|
|
||||||
Theme.of(context).colorScheme.secondaryContainer,
|
|
||||||
],
|
|
||||||
begin: Alignment.topLeft,
|
|
||||||
end: Alignment.bottomRight,
|
|
||||||
),
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
),
|
|
||||||
child: Text('Error loading membership: $error'),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildMembershipContent(
|
|
||||||
BuildContext context,
|
|
||||||
WidgetRef ref,
|
|
||||||
SnWalletSubscription? membership,
|
|
||||||
) {
|
|
||||||
final isActive = membership?.isActive ?? false;
|
|
||||||
|
|
||||||
Future<void> membershipCancel() async {
|
|
||||||
if (!isActive || membership == null) return;
|
|
||||||
|
|
||||||
final confirm = await showConfirmAlert(
|
|
||||||
'membershipCancelHint'.tr(),
|
|
||||||
'membershipCancelConfirm'.tr(),
|
|
||||||
);
|
|
||||||
if (!confirm || !context.mounted) return;
|
|
||||||
|
|
||||||
try {
|
|
||||||
showLoadingModal(context);
|
|
||||||
final client = ref.watch(apiClientProvider);
|
|
||||||
await client.post('/id/subscriptions/${membership.identifier}/cancel');
|
|
||||||
ref.invalidate(accountStellarSubscriptionProvider);
|
|
||||||
ref.read(userInfoProvider.notifier).fetchUser();
|
|
||||||
if (context.mounted) {
|
|
||||||
hideLoadingModal(context);
|
|
||||||
showSnackBar('membershipCancelSuccess'.tr());
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
if (context.mounted) hideLoadingModal(context);
|
|
||||||
showErrorAlert(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
width: double.infinity,
|
|
||||||
padding: const EdgeInsets.all(16),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
gradient: LinearGradient(
|
|
||||||
colors: [
|
|
||||||
Theme.of(context).colorScheme.primaryContainer,
|
|
||||||
Theme.of(context).colorScheme.secondaryContainer,
|
|
||||||
],
|
|
||||||
begin: Alignment.topLeft,
|
|
||||||
end: Alignment.bottomRight,
|
|
||||||
),
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
isActive ? Icons.star : Icons.star_border,
|
|
||||||
color: Theme.of(context).colorScheme.primary,
|
|
||||||
size: 24,
|
|
||||||
),
|
|
||||||
const Gap(8),
|
|
||||||
Text(
|
|
||||||
'stellarMembership'.tr(),
|
|
||||||
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const Gap(12),
|
|
||||||
|
|
||||||
if (isActive) ...[
|
|
||||||
_buildCurrentMembershipCard(context, membership!),
|
|
||||||
const Gap(12),
|
|
||||||
FilledButton.icon(
|
|
||||||
style: ButtonStyle(
|
|
||||||
backgroundColor: WidgetStateProperty.all(
|
|
||||||
Theme.of(context).colorScheme.error,
|
|
||||||
),
|
|
||||||
foregroundColor: WidgetStateProperty.all(
|
|
||||||
Theme.of(context).colorScheme.onError,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onPressed: membershipCancel,
|
|
||||||
icon: const Icon(Symbols.cancel),
|
|
||||||
label: Text('membershipCancel'.tr()),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
|
|
||||||
if (!isActive) ...[
|
|
||||||
Text(
|
|
||||||
'chooseYourPlan'.tr(),
|
|
||||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
|
|
||||||
),
|
|
||||||
const Gap(12),
|
|
||||||
_buildMembershipTiers(context, ref, membership),
|
|
||||||
],
|
|
||||||
|
|
||||||
// Restore Purchase Button
|
|
||||||
// As you know Apple platform need IAP
|
|
||||||
if (kIsWeb || !(Platform.isIOS || Platform.isMacOS))
|
|
||||||
OutlinedButton.icon(
|
|
||||||
onPressed: () => _showRestorePurchaseSheet(context, ref),
|
|
||||||
icon: const Icon(Icons.restore),
|
|
||||||
label: Text('restorePurchase'.tr()),
|
|
||||||
style: OutlinedButton.styleFrom(
|
|
||||||
minimumSize: const Size(double.infinity, 48),
|
|
||||||
),
|
|
||||||
).padding(top: 12),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildCurrentMembershipCard(
|
|
||||||
BuildContext context,
|
|
||||||
SnWalletSubscription membership,
|
|
||||||
) {
|
|
||||||
final tierName = _getMembershipTierName(membership.identifier);
|
|
||||||
final tierColor = _getMembershipTierColor(context, membership.identifier);
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
padding: const EdgeInsets.all(12),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: tierColor.withOpacity(0.1),
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
border: Border.all(color: tierColor, width: 1),
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Icon(Icons.verified, color: tierColor, size: 20),
|
|
||||||
const Gap(8),
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'currentMembership'.tr(args: [tierName]),
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: tierColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (membership.endedAt != null)
|
|
||||||
Text(
|
|
||||||
'membershipExpires'.tr(
|
|
||||||
args: [membership.endedAt!.formatSystem()],
|
|
||||||
),
|
|
||||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
|
||||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildMembershipTiers(
|
|
||||||
BuildContext context,
|
|
||||||
WidgetRef ref,
|
|
||||||
SnWalletSubscription? currentMembership,
|
|
||||||
) {
|
|
||||||
final tiers = [
|
|
||||||
{
|
|
||||||
'id': 'solian.stellar.primary',
|
|
||||||
'name': 'membershipTierStellar'.tr(),
|
|
||||||
'price': 'membershipPriceStellar'.tr(),
|
|
||||||
'color': Colors.blue,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'id': 'solian.stellar.nova',
|
|
||||||
'name': 'membershipTierNova'.tr(),
|
|
||||||
'price': 'membershipPriceNova'.tr(),
|
|
||||||
'color': Color.fromRGBO(57, 197, 187, 1),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'id': 'solian.stellar.supernova',
|
|
||||||
'name': 'membershipTierSupernova'.tr(),
|
|
||||||
'price': 'membershipPriceSupernova'.tr(),
|
|
||||||
'color': Colors.orange,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
return Column(
|
|
||||||
children:
|
|
||||||
tiers.map((tier) {
|
|
||||||
final isCurrentTier = currentMembership?.identifier == tier['id'];
|
|
||||||
final tierColor = tier['color'] as Color;
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
margin: const EdgeInsets.only(bottom: 8),
|
|
||||||
child: Material(
|
|
||||||
color: Colors.transparent,
|
|
||||||
child: InkWell(
|
|
||||||
onTap:
|
|
||||||
isCurrentTier
|
|
||||||
? null
|
|
||||||
: () => _purchaseMembership(
|
|
||||||
context,
|
|
||||||
ref,
|
|
||||||
tier['id'] as String,
|
|
||||||
),
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
child: Container(
|
|
||||||
padding: const EdgeInsets.all(12),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color:
|
|
||||||
isCurrentTier
|
|
||||||
? tierColor.withOpacity(0.1)
|
|
||||||
: Theme.of(context).colorScheme.surface,
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
border: Border.all(
|
|
||||||
color:
|
|
||||||
isCurrentTier
|
|
||||||
? tierColor
|
|
||||||
: Theme.of(
|
|
||||||
context,
|
|
||||||
).colorScheme.outline.withOpacity(0.2),
|
|
||||||
width: isCurrentTier ? 2 : 1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
width: 4,
|
|
||||||
height: 40,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: tierColor,
|
|
||||||
borderRadius: BorderRadius.circular(2),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Gap(12),
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
tier['name'] as String,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: isCurrentTier ? tierColor : null,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Gap(8),
|
|
||||||
if (isCurrentTier)
|
|
||||||
Container(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 6,
|
|
||||||
vertical: 2,
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: tierColor,
|
|
||||||
borderRadius: BorderRadius.circular(4),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
'membershipCurrentBadge'.tr(),
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 10,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
tier['price'] as String,
|
|
||||||
style: Theme.of(
|
|
||||||
context,
|
|
||||||
).textTheme.bodyMedium?.copyWith(
|
|
||||||
color:
|
|
||||||
Theme.of(
|
|
||||||
context,
|
|
||||||
).colorScheme.onSurfaceVariant,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (!isCurrentTier)
|
|
||||||
Icon(
|
|
||||||
Icons.arrow_forward_ios,
|
|
||||||
size: 16,
|
|
||||||
color:
|
|
||||||
Theme.of(context).colorScheme.onSurfaceVariant,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}).toList(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
String _getMembershipTierName(String identifier) {
|
|
||||||
switch (identifier) {
|
|
||||||
case 'solian.stellar.primary':
|
|
||||||
return 'membershipTierStellar'.tr();
|
|
||||||
case 'solian.stellar.nova':
|
|
||||||
return 'membershipTierNova'.tr();
|
|
||||||
case 'solian.stellar.supernova':
|
|
||||||
return 'membershipTierSupernova'.tr();
|
|
||||||
default:
|
|
||||||
return 'membershipTierUnknown'.tr();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Color _getMembershipTierColor(BuildContext context, String identifier) {
|
|
||||||
switch (identifier) {
|
|
||||||
case 'solian.stellar.primary':
|
|
||||||
return Colors.blue;
|
|
||||||
case 'solian.stellar.nova':
|
|
||||||
return Colors.purple;
|
|
||||||
case 'solian.stellar.supernova':
|
|
||||||
return Colors.orange;
|
|
||||||
default:
|
|
||||||
return Theme.of(context).colorScheme.primary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _showRestorePurchaseSheet(
|
|
||||||
BuildContext context,
|
|
||||||
WidgetRef ref,
|
|
||||||
) async {
|
|
||||||
await showModalBottomSheet(
|
|
||||||
context: context,
|
|
||||||
builder: (context) => const RestorePurchaseSheet(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _purchaseMembership(
|
|
||||||
BuildContext context,
|
|
||||||
WidgetRef ref,
|
|
||||||
String tierId,
|
|
||||||
) async {
|
|
||||||
final client = ref.watch(apiClientProvider);
|
|
||||||
try {
|
|
||||||
showLoadingModal(context);
|
|
||||||
final resp = await client.post(
|
|
||||||
'/id/subscriptions',
|
|
||||||
data: {
|
|
||||||
'identifier': tierId,
|
|
||||||
'payment_method': 'solian.wallet',
|
|
||||||
'payment_details': {'currency': 'golds'},
|
|
||||||
'cycle_duration_days': 30,
|
|
||||||
},
|
|
||||||
options: Options(headers: {'X-Noop': true}),
|
|
||||||
);
|
|
||||||
final subscription = SnWalletSubscription.fromJson(resp.data);
|
|
||||||
if (subscription.status == 1) return;
|
|
||||||
final orderResp = await client.post(
|
|
||||||
'/id/subscriptions/${subscription.identifier}/order',
|
|
||||||
);
|
|
||||||
final order = SnWalletOrder.fromJson(orderResp.data);
|
|
||||||
|
|
||||||
if (context.mounted) hideLoadingModal(context);
|
|
||||||
|
|
||||||
// Show payment overlay to complete the payment
|
|
||||||
if (!context.mounted) return;
|
|
||||||
final paidOrder = await PaymentOverlay.show(
|
|
||||||
context: context,
|
|
||||||
order: order,
|
|
||||||
enableBiometric: true,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (context.mounted) showLoadingModal(context);
|
|
||||||
|
|
||||||
if (paidOrder != null) {
|
|
||||||
await client.post(
|
|
||||||
'/id/subscriptions/order/handle',
|
|
||||||
data: {'order_id': paidOrder.id},
|
|
||||||
);
|
|
||||||
|
|
||||||
ref.invalidate(accountStellarSubscriptionProvider);
|
|
||||||
ref.read(userInfoProvider.notifier).fetchUser();
|
|
||||||
if (context.mounted) {
|
|
||||||
showSnackBar('membershipPurchaseSuccess'.tr());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
showErrorAlert(err);
|
|
||||||
} finally {
|
|
||||||
if (context.mounted) hideLoadingModal(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class LevelStairsPainter extends CustomPainter {
|
class LevelStairsPainter extends CustomPainter {
|
||||||
|
|||||||
@@ -6,27 +6,6 @@ part of 'leveling.dart';
|
|||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$accountStellarSubscriptionHash() =>
|
|
||||||
r'80abcdefb3868775fd8fe3c980215713efff5948';
|
|
||||||
|
|
||||||
/// See also [accountStellarSubscription].
|
|
||||||
@ProviderFor(accountStellarSubscription)
|
|
||||||
final accountStellarSubscriptionProvider =
|
|
||||||
AutoDisposeFutureProvider<SnWalletSubscription?>.internal(
|
|
||||||
accountStellarSubscription,
|
|
||||||
name: r'accountStellarSubscriptionProvider',
|
|
||||||
debugGetCreateSourceHash:
|
|
||||||
const bool.fromEnvironment('dart.vm.product')
|
|
||||||
? null
|
|
||||||
: _$accountStellarSubscriptionHash,
|
|
||||||
dependencies: null,
|
|
||||||
allTransitiveDependencies: null,
|
|
||||||
);
|
|
||||||
|
|
||||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
|
||||||
// ignore: unused_element
|
|
||||||
typedef AccountStellarSubscriptionRef =
|
|
||||||
AutoDisposeFutureProviderRef<SnWalletSubscription?>;
|
|
||||||
String _$levelingHistoryNotifierHash() =>
|
String _$levelingHistoryNotifierHash() =>
|
||||||
r'e795f9b7911c9e50f15c095ea237cb0e87bf1e89';
|
r'e795f9b7911c9e50f15c095ea237cb0e87bf1e89';
|
||||||
|
|
||||||
|
|||||||
@@ -9,11 +9,12 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:island/models/file.dart';
|
import 'package:island/models/file.dart';
|
||||||
import 'package:island/models/account.dart';
|
import 'package:island/models/account.dart';
|
||||||
import 'package:island/pods/config.dart';
|
|
||||||
import 'package:island/pods/network.dart';
|
import 'package:island/pods/network.dart';
|
||||||
import 'package:island/pods/userinfo.dart';
|
import 'package:island/pods/userinfo.dart';
|
||||||
import 'package:island/services/file.dart';
|
import 'package:island/services/file.dart';
|
||||||
|
import 'package:island/services/file_uploader.dart';
|
||||||
import 'package:island/services/timezone.dart';
|
import 'package:island/services/timezone.dart';
|
||||||
|
import 'package:island/widgets/account/account_name.dart';
|
||||||
import 'package:island/widgets/alert.dart';
|
import 'package:island/widgets/alert.dart';
|
||||||
import 'package:island/widgets/app_scaffold.dart';
|
import 'package:island/widgets/app_scaffold.dart';
|
||||||
import 'package:island/widgets/content/cloud_files.dart';
|
import 'package:island/widgets/content/cloud_files.dart';
|
||||||
@@ -24,6 +25,17 @@ const kServerSupportedLanguages = {'en-US': 'en-us', 'zh-CN': 'zh-hans'};
|
|||||||
const kServerSupportedRegions = ['US', 'JP', 'CN'];
|
const kServerSupportedRegions = ['US', 'JP', 'CN'];
|
||||||
|
|
||||||
class UpdateProfileScreen extends HookConsumerWidget {
|
class UpdateProfileScreen extends HookConsumerWidget {
|
||||||
|
bool _isValidHexColor(String color) {
|
||||||
|
if (!color.startsWith('#')) return false;
|
||||||
|
if (color.length != 7) return false; // #RRGGBB format
|
||||||
|
try {
|
||||||
|
int.parse(color.substring(1), radix: 16);
|
||||||
|
return true;
|
||||||
|
} catch (_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const UpdateProfileScreen({super.key});
|
const UpdateProfileScreen({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -62,19 +74,13 @@ class UpdateProfileScreen extends HookConsumerWidget {
|
|||||||
|
|
||||||
submitting.value = true;
|
submitting.value = true;
|
||||||
try {
|
try {
|
||||||
final baseUrl = ref.watch(serverUrlProvider);
|
|
||||||
final token = await getToken(ref.watch(tokenProvider));
|
|
||||||
if (token == null) throw ArgumentError('Token is null');
|
|
||||||
final cloudFile =
|
final cloudFile =
|
||||||
await putMediaToCloud(
|
await FileUploader.createCloudFile(
|
||||||
|
client: ref.read(apiClientProvider),
|
||||||
fileData: UniversalFile(
|
fileData: UniversalFile(
|
||||||
data: result,
|
data: result,
|
||||||
type: UniversalFileType.image,
|
type: UniversalFileType.image,
|
||||||
),
|
),
|
||||||
atk: token,
|
|
||||||
baseUrl: baseUrl,
|
|
||||||
filename: result.name,
|
|
||||||
mimetype: result.mimeType ?? 'image/jpeg',
|
|
||||||
).future;
|
).future;
|
||||||
if (cloudFile == null) {
|
if (cloudFile == null) {
|
||||||
throw ArgumentError('Failed to upload the file...');
|
throw ArgumentError('Failed to upload the file...');
|
||||||
@@ -154,12 +160,39 @@ class UpdateProfileScreen extends HookConsumerWidget {
|
|||||||
text: user.value!.profile.timeZone,
|
text: user.value!.profile.timeZone,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Username color state
|
||||||
|
final usernameColorType = useState<String>(
|
||||||
|
user.value!.profile.usernameColor?.type ?? 'plain',
|
||||||
|
);
|
||||||
|
final usernameColorValue = useTextEditingController(
|
||||||
|
text: user.value!.profile.usernameColor?.value,
|
||||||
|
);
|
||||||
|
final usernameColorDirection = useTextEditingController(
|
||||||
|
text: user.value!.profile.usernameColor?.direction,
|
||||||
|
);
|
||||||
|
final usernameColorColors = useState<List<String>>(
|
||||||
|
user.value!.profile.usernameColor?.colors ?? [],
|
||||||
|
);
|
||||||
|
|
||||||
void updateProfile() async {
|
void updateProfile() async {
|
||||||
if (!formKeyProfile.currentState!.validate()) return;
|
if (!formKeyProfile.currentState!.validate()) return;
|
||||||
|
|
||||||
submitting.value = true;
|
submitting.value = true;
|
||||||
try {
|
try {
|
||||||
final client = ref.watch(apiClientProvider);
|
final client = ref.watch(apiClientProvider);
|
||||||
|
final usernameColorData = {
|
||||||
|
'type': usernameColorType.value,
|
||||||
|
if (usernameColorType.value == 'plain' &&
|
||||||
|
usernameColorValue.text.isNotEmpty)
|
||||||
|
'value': usernameColorValue.text,
|
||||||
|
if (usernameColorType.value == 'gradient') ...{
|
||||||
|
if (usernameColorDirection.text.isNotEmpty)
|
||||||
|
'direction': usernameColorDirection.text,
|
||||||
|
'colors':
|
||||||
|
usernameColorColors.value.where((c) => c.isNotEmpty).toList(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
await client.patch(
|
await client.patch(
|
||||||
'/id/accounts/me/profile',
|
'/id/accounts/me/profile',
|
||||||
data: {
|
data: {
|
||||||
@@ -172,6 +205,7 @@ class UpdateProfileScreen extends HookConsumerWidget {
|
|||||||
'location': locationController.text,
|
'location': locationController.text,
|
||||||
'time_zone': timeZoneController.text,
|
'time_zone': timeZoneController.text,
|
||||||
'birthday': birthday.value?.toUtc().toIso8601String(),
|
'birthday': birthday.value?.toUtc().toIso8601String(),
|
||||||
|
'username_color': usernameColorData,
|
||||||
'links':
|
'links':
|
||||||
links.value
|
links.value
|
||||||
.where((e) => e.name.isNotEmpty && e.url.isNotEmpty)
|
.where((e) => e.name.isNotEmpty && e.url.isNotEmpty)
|
||||||
@@ -599,6 +633,320 @@ class UpdateProfileScreen extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
Text(
|
||||||
|
'usernameColor',
|
||||||
|
).tr().bold().fontSize(18).padding(top: 16),
|
||||||
|
Column(
|
||||||
|
spacing: 16,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// Preview section
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color:
|
||||||
|
Theme.of(
|
||||||
|
context,
|
||||||
|
).colorScheme.surfaceContainerHighest,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text('preview').tr().bold().fontSize(14),
|
||||||
|
const Gap(8),
|
||||||
|
// Create a preview account with the current settings
|
||||||
|
Builder(
|
||||||
|
builder: (context) {
|
||||||
|
final previewAccount = user.value!.copyWith(
|
||||||
|
profile: user.value!.profile.copyWith(
|
||||||
|
usernameColor: UsernameColor(
|
||||||
|
type: usernameColorType.value,
|
||||||
|
value:
|
||||||
|
usernameColorType.value == 'plain' &&
|
||||||
|
usernameColorValue
|
||||||
|
.text
|
||||||
|
.isNotEmpty
|
||||||
|
? usernameColorValue.text
|
||||||
|
: null,
|
||||||
|
direction:
|
||||||
|
usernameColorType.value ==
|
||||||
|
'gradient' &&
|
||||||
|
usernameColorDirection
|
||||||
|
.text
|
||||||
|
.isNotEmpty
|
||||||
|
? usernameColorDirection.text
|
||||||
|
: null,
|
||||||
|
colors:
|
||||||
|
usernameColorType.value == 'gradient'
|
||||||
|
? usernameColorColors.value
|
||||||
|
.where((c) => c.isNotEmpty)
|
||||||
|
.toList()
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check if user can use this color
|
||||||
|
final tier =
|
||||||
|
user.value!.perkSubscription?.identifier;
|
||||||
|
final canUseColor = switch (tier) {
|
||||||
|
'solian.stellar.primary' =>
|
||||||
|
usernameColorType.value == 'plain' &&
|
||||||
|
(kUsernamePlainColors.containsKey(
|
||||||
|
usernameColorValue.text,
|
||||||
|
) ||
|
||||||
|
(usernameColorValue.text.startsWith(
|
||||||
|
'#',
|
||||||
|
) &&
|
||||||
|
_isValidHexColor(
|
||||||
|
usernameColorValue.text,
|
||||||
|
))),
|
||||||
|
'solian.stellar.nova' =>
|
||||||
|
usernameColorType.value == 'plain',
|
||||||
|
'solian.stellar.supernova' => true,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
AccountName(
|
||||||
|
account: previewAccount,
|
||||||
|
style: const TextStyle(fontSize: 18),
|
||||||
|
ignorePermissions: true,
|
||||||
|
),
|
||||||
|
const Gap(4),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
canUseColor
|
||||||
|
? Symbols.check_circle
|
||||||
|
: Symbols.error,
|
||||||
|
size: 16,
|
||||||
|
color:
|
||||||
|
canUseColor
|
||||||
|
? Colors.green
|
||||||
|
: Colors.red,
|
||||||
|
),
|
||||||
|
const Gap(4),
|
||||||
|
Text(
|
||||||
|
canUseColor
|
||||||
|
? 'availableWithYourPlan'.tr()
|
||||||
|
: 'upgradeRequired'.tr(),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color:
|
||||||
|
canUseColor
|
||||||
|
? Colors.green
|
||||||
|
: Colors.red,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
DropdownButtonFormField2<String>(
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: 'colorType'.tr(),
|
||||||
|
),
|
||||||
|
items: [
|
||||||
|
DropdownMenuItem(
|
||||||
|
value: 'plain',
|
||||||
|
child: Text('plain'.tr()),
|
||||||
|
),
|
||||||
|
DropdownMenuItem(
|
||||||
|
value: 'gradient',
|
||||||
|
child: Text('gradient'.tr()),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
value: usernameColorType.value,
|
||||||
|
onChanged: (value) {
|
||||||
|
usernameColorType.value = value ?? 'plain';
|
||||||
|
},
|
||||||
|
customButton: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(child: Text(usernameColorType.value).tr()),
|
||||||
|
Icon(Symbols.arrow_drop_down),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (usernameColorType.value == 'plain')
|
||||||
|
Autocomplete<String>(
|
||||||
|
optionsBuilder: (TextEditingValue textEditingValue) {
|
||||||
|
final options = kUsernamePlainColors.keys.toList();
|
||||||
|
if (textEditingValue.text == '') {
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
return options.where(
|
||||||
|
(option) => option.toLowerCase().contains(
|
||||||
|
textEditingValue.text.toLowerCase(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onSelected: (String selection) {
|
||||||
|
usernameColorValue.text = selection;
|
||||||
|
},
|
||||||
|
fieldViewBuilder: (
|
||||||
|
context,
|
||||||
|
controller,
|
||||||
|
focusNode,
|
||||||
|
onFieldSubmitted,
|
||||||
|
) {
|
||||||
|
// Initialize the controller with the current value
|
||||||
|
if (controller.text.isEmpty &&
|
||||||
|
usernameColorValue.text.isNotEmpty) {
|
||||||
|
controller.text = usernameColorValue.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TextFormField(
|
||||||
|
controller: controller,
|
||||||
|
focusNode: focusNode,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: 'colorValue'.tr(),
|
||||||
|
hintText: 'e.g. red or #ff6600',
|
||||||
|
),
|
||||||
|
onChanged: (value) {
|
||||||
|
usernameColorValue.text = value;
|
||||||
|
},
|
||||||
|
onTapOutside:
|
||||||
|
(_) =>
|
||||||
|
FocusManager.instance.primaryFocus
|
||||||
|
?.unfocus(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
if (usernameColorType.value == 'gradient') ...[
|
||||||
|
DropdownButtonFormField2<String>(
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: 'gradientDirection'.tr(),
|
||||||
|
),
|
||||||
|
items: [
|
||||||
|
DropdownMenuItem(
|
||||||
|
value: 'to right',
|
||||||
|
child: Text('gradientDirectionToRight'.tr()),
|
||||||
|
),
|
||||||
|
DropdownMenuItem(
|
||||||
|
value: 'to left',
|
||||||
|
child: Text('gradientDirectionToLeft'.tr()),
|
||||||
|
),
|
||||||
|
DropdownMenuItem(
|
||||||
|
value: 'to bottom',
|
||||||
|
child: Text('gradientDirectionToBottom'.tr()),
|
||||||
|
),
|
||||||
|
DropdownMenuItem(
|
||||||
|
value: 'to top',
|
||||||
|
child: Text('gradientDirectionToTop'.tr()),
|
||||||
|
),
|
||||||
|
DropdownMenuItem(
|
||||||
|
value: 'to bottom right',
|
||||||
|
child: Text(
|
||||||
|
'gradientDirectionToBottomRight'.tr(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
DropdownMenuItem(
|
||||||
|
value: 'to bottom left',
|
||||||
|
child: Text('gradientDirectionToBottomLeft'.tr()),
|
||||||
|
),
|
||||||
|
DropdownMenuItem(
|
||||||
|
value: 'to top right',
|
||||||
|
child: Text('gradientDirectionToTopRight'.tr()),
|
||||||
|
),
|
||||||
|
DropdownMenuItem(
|
||||||
|
value: 'to top left',
|
||||||
|
child: Text('gradientDirectionToTopLeft'.tr()),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
value:
|
||||||
|
usernameColorDirection.text.isNotEmpty
|
||||||
|
? usernameColorDirection.text
|
||||||
|
: 'to right',
|
||||||
|
onChanged: (value) {
|
||||||
|
usernameColorDirection.text = value ?? 'to right';
|
||||||
|
},
|
||||||
|
customButton: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
usernameColorDirection.text.isNotEmpty
|
||||||
|
? usernameColorDirection.text
|
||||||
|
: 'to right',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Icon(Symbols.arrow_drop_down),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'gradientColors',
|
||||||
|
).tr().bold().fontSize(14).padding(top: 8),
|
||||||
|
Column(
|
||||||
|
spacing: 8,
|
||||||
|
children: [
|
||||||
|
for (
|
||||||
|
var i = 0;
|
||||||
|
i < usernameColorColors.value.length;
|
||||||
|
i++
|
||||||
|
)
|
||||||
|
Row(
|
||||||
|
key: ValueKey(
|
||||||
|
usernameColorColors.value[i].hashCode,
|
||||||
|
),
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: TextFormField(
|
||||||
|
initialValue:
|
||||||
|
usernameColorColors.value[i],
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: 'color'.tr(),
|
||||||
|
hintText: 'e.g. #ff0000',
|
||||||
|
isDense: true,
|
||||||
|
),
|
||||||
|
onChanged: (value) {
|
||||||
|
usernameColorColors.value[i] = value;
|
||||||
|
},
|
||||||
|
onTapOutside:
|
||||||
|
(_) =>
|
||||||
|
FocusManager.instance.primaryFocus
|
||||||
|
?.unfocus(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Symbols.delete),
|
||||||
|
onPressed: () {
|
||||||
|
usernameColorColors.value =
|
||||||
|
usernameColorColors.value
|
||||||
|
.whereIndexed(
|
||||||
|
(idx, _) => idx != i,
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
child: FilledButton.icon(
|
||||||
|
onPressed: () {
|
||||||
|
usernameColorColors.value = List.from(
|
||||||
|
usernameColorColors.value,
|
||||||
|
)..add('');
|
||||||
|
},
|
||||||
|
label: Text('addColor').tr(),
|
||||||
|
icon: const Icon(Symbols.add),
|
||||||
|
).padding(top: 8),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
Text('links').tr().bold().fontSize(18).padding(top: 16),
|
Text('links').tr().bold().fontSize(18).padding(top: 16),
|
||||||
Column(
|
Column(
|
||||||
spacing: 8,
|
spacing: 8,
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ class AccountConnectionNewSheet extends HookConsumerWidget {
|
|||||||
scopes: [AppleIDAuthorizationScopes.email],
|
scopes: [AppleIDAuthorizationScopes.email],
|
||||||
webAuthenticationOptions: WebAuthenticationOptions(
|
webAuthenticationOptions: WebAuthenticationOptions(
|
||||||
clientId: 'dev.solsynth.solarpass',
|
clientId: 'dev.solsynth.solarpass',
|
||||||
redirectUri: Uri.parse('https://id.solian.app/auth/callback'),
|
redirectUri: Uri.parse('https://solian.app/auth/callback'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import 'package:island/widgets/content/cloud_files.dart';
|
|||||||
import 'package:island/widgets/content/markdown.dart';
|
import 'package:island/widgets/content/markdown.dart';
|
||||||
import 'package:island/widgets/safety/abuse_report_helper.dart';
|
import 'package:island/widgets/safety/abuse_report_helper.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:palette_generator/palette_generator.dart';
|
import 'package:island/services/color_extraction.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
import 'package:share_plus/share_plus.dart';
|
import 'package:share_plus/share_plus.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
@@ -97,9 +97,7 @@ class _AccountBasicInfo extends StatelessWidget {
|
|||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
SharePlus.instance.share(
|
SharePlus.instance.share(
|
||||||
ShareParams(
|
ShareParams(uri: Uri.parse('https://solian.app/@${data.name}')),
|
||||||
uri: Uri.parse('https://id.solian.app/@${data.name}'),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
icon: const Icon(Symbols.share),
|
icon: const Icon(Symbols.share),
|
||||||
@@ -581,14 +579,14 @@ Future<Color?> accountAppbarForcegroundColor(Ref ref, String uname) async {
|
|||||||
try {
|
try {
|
||||||
final account = await ref.watch(accountProvider(uname).future);
|
final account = await ref.watch(accountProvider(uname).future);
|
||||||
if (account.profile.background == null) return null;
|
if (account.profile.background == null) return null;
|
||||||
final palette = await PaletteGenerator.fromImageProvider(
|
final colors = await ColorExtractionService.getColorsFromImage(
|
||||||
CloudImageWidget.provider(
|
CloudImageWidget.provider(
|
||||||
fileId: account.profile.background!.id,
|
fileId: account.profile.background!.id,
|
||||||
serverUrl: ref.watch(serverUrlProvider),
|
serverUrl: ref.watch(serverUrlProvider),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
final dominantColor = palette.dominantColor?.color;
|
if (colors.isEmpty) return null;
|
||||||
if (dominantColor == null) return null;
|
final dominantColor = colors.first;
|
||||||
return dominantColor.computeLuminance() > 0.5 ? Colors.black : Colors.white;
|
return dominantColor.computeLuminance() > 0.5 ? Colors.black : Colors.white;
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
return null;
|
return null;
|
||||||
@@ -879,7 +877,7 @@ class AccountProfileScreen extends HookConsumerWidget {
|
|||||||
child: Card(
|
child: Card(
|
||||||
child: FortuneGraphWidget(
|
child: FortuneGraphWidget(
|
||||||
events: accountEvents,
|
events: accountEvents,
|
||||||
eventCalanderUser: data.name,
|
eventCalandarUser: data.name,
|
||||||
margin: EdgeInsets.zero,
|
margin: EdgeInsets.zero,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -1004,7 +1002,7 @@ class AccountProfileScreen extends HookConsumerWidget {
|
|||||||
child: Card(
|
child: Card(
|
||||||
child: FortuneGraphWidget(
|
child: FortuneGraphWidget(
|
||||||
events: accountEvents,
|
events: accountEvents,
|
||||||
eventCalanderUser: data.name,
|
eventCalandarUser: data.name,
|
||||||
),
|
),
|
||||||
).padding(horizontal: 4),
|
).padding(horizontal: 4),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -268,7 +268,7 @@ class _AccountBadgesProviderElement
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _$accountAppbarForcegroundColorHash() =>
|
String _$accountAppbarForcegroundColorHash() =>
|
||||||
r'8ee0cae10817b77fb09548a482f5247662b4374c';
|
r'127fcc7fd6ec6a41ac4a6975276b5271aa4fa7d0';
|
||||||
|
|
||||||
/// See also [accountAppbarForcegroundColor].
|
/// See also [accountAppbarForcegroundColor].
|
||||||
@ProviderFor(accountAppbarForcegroundColor)
|
@ProviderFor(accountAppbarForcegroundColor)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user