Compare commits
3 Commits
619c90cdd9
...
00fd58fb97
Author | SHA1 | Date | |
---|---|---|---|
00fd58fb97 | |||
ee7d0ddd25 | |||
7656c08832 |
@ -15,6 +15,7 @@ analyzer:
|
|||||||
- "**/*.freezed.dart"
|
- "**/*.freezed.dart"
|
||||||
errors:
|
errors:
|
||||||
invalid_annotation_target: ignore # Due to freezed + json_serializable issue, ref https://github.com/rrousselGit/freezed/issues/488#issuecomment-894358980
|
invalid_annotation_target: ignore # Due to freezed + json_serializable issue, ref https://github.com/rrousselGit/freezed/issues/488#issuecomment-894358980
|
||||||
|
deprecated_member_use: ignore
|
||||||
|
|
||||||
linter:
|
linter:
|
||||||
# The lint rules applied to this project can be customized in the
|
# The lint rules applied to this project can be customized in the
|
||||||
|
@ -279,16 +279,22 @@
|
|||||||
"one": "{} 個附件",
|
"one": "{} 個附件",
|
||||||
"other": "{} 個附件"
|
"other": "{} 個附件"
|
||||||
},
|
},
|
||||||
|
"fieldAttachmentRandomId": "訪問 ID",
|
||||||
"addAttachmentFromAlbum": "從相冊中添加附件",
|
"addAttachmentFromAlbum": "從相冊中添加附件",
|
||||||
"addAttachmentFromClipboard": "粘貼附件",
|
"addAttachmentFromClipboard": "粘貼附件",
|
||||||
"addAttachmentFromCameraPhoto": "拍攝照片",
|
"addAttachmentFromCameraPhoto": "拍攝照片",
|
||||||
"addAttachmentFromCameraVideo": "拍攝視頻",
|
"addAttachmentFromCameraVideo": "拍攝視頻",
|
||||||
|
"addAttachmentFromRandomId": "通過訪問 ID 鏈接",
|
||||||
"attachmentPastedImage": "粘貼的圖片",
|
"attachmentPastedImage": "粘貼的圖片",
|
||||||
"attachmentInsertLink": "插入連接",
|
"attachmentInsertLink": "插入連接",
|
||||||
"attachmentSetAsPostThumbnail": "設置為帖子縮略圖",
|
"attachmentSetAsPostThumbnail": "設置為帖子縮略圖",
|
||||||
"attachmentUnsetAsPostThumbnail": "取消設置為帖子縮略圖",
|
"attachmentUnsetAsPostThumbnail": "取消設置為帖子縮略圖",
|
||||||
"attachmentSetThumbnail": "設置縮略圖",
|
"attachmentSetThumbnail": "設置縮略圖",
|
||||||
|
"attachmentCopyRandomId": "複製訪問 ID",
|
||||||
"attachmentUpload": "上傳",
|
"attachmentUpload": "上傳",
|
||||||
|
"attachmentInputDialog": "上傳附件",
|
||||||
|
"attachmentInputUseRandomId": "使用訪問 ID",
|
||||||
|
"attachmentInputNew": "新上傳附件",
|
||||||
"notification": "通知",
|
"notification": "通知",
|
||||||
"notificationUnreadCount": {
|
"notificationUnreadCount": {
|
||||||
"zero": "無未讀通知",
|
"zero": "無未讀通知",
|
||||||
@ -504,5 +510,6 @@
|
|||||||
"postCategoryKnowledge": "知識",
|
"postCategoryKnowledge": "知識",
|
||||||
"postCategoryLiterature": "文學",
|
"postCategoryLiterature": "文學",
|
||||||
"postCategoryFunny": "搞笑",
|
"postCategoryFunny": "搞笑",
|
||||||
"postCategoryUncategorized": "未分類"
|
"postCategoryUncategorized": "未分類",
|
||||||
|
"waitingForUpload": "等待上傳"
|
||||||
}
|
}
|
||||||
|
@ -7,15 +7,15 @@
|
|||||||
"screenAuthLogin": "登陸",
|
"screenAuthLogin": "登陸",
|
||||||
"screenAuthLoginSubtitle": "使用 Solarpass 登陸 Solar Network",
|
"screenAuthLoginSubtitle": "使用 Solarpass 登陸 Solar Network",
|
||||||
"screenAuthLoginGreeting": "歡迎回來",
|
"screenAuthLoginGreeting": "歡迎回來",
|
||||||
"screenAuthRegister": "建立賬號",
|
"screenAuthRegister": "創建賬號",
|
||||||
"screenAuthRegisterSubtitle": "建立一個 Solarpass 賬號",
|
"screenAuthRegisterSubtitle": "創建一個 Solarpass 賬號",
|
||||||
"screenAccountPublishers": "釋出者",
|
"screenAccountPublishers": "發佈者",
|
||||||
"screenAccountPublisherNew": "新建釋出者",
|
"screenAccountPublisherNew": "新建發佈者",
|
||||||
"screenAccountPublisherEdit": "編輯釋出者",
|
"screenAccountPublisherEdit": "編輯發佈者",
|
||||||
"screenAccountProfileEdit": "編輯資料",
|
"screenAccountProfileEdit": "編輯資料",
|
||||||
"screenAbuseReport": "濫用檢舉",
|
"screenAbuseReport": "濫用檢舉",
|
||||||
"screenSettings": "設定",
|
"screenSettings": "設置",
|
||||||
"screenAlbum": "相簿",
|
"screenAlbum": "相冊",
|
||||||
"screenChat": "聊天",
|
"screenChat": "聊天",
|
||||||
"screenChatManage": "編輯聊天頻道",
|
"screenChatManage": "編輯聊天頻道",
|
||||||
"screenChatNew": "新建聊天頻道",
|
"screenChatNew": "新建聊天頻道",
|
||||||
@ -23,37 +23,37 @@
|
|||||||
"screenRealmManage": "編輯領域",
|
"screenRealmManage": "編輯領域",
|
||||||
"screenRealmNew": "新建領域",
|
"screenRealmNew": "新建領域",
|
||||||
"screenNotification": "通知",
|
"screenNotification": "通知",
|
||||||
"screenPostSearch": "搜尋帖子",
|
"screenPostSearch": "搜索帖子",
|
||||||
"screenFriend": "好友",
|
"screenFriend": "好友",
|
||||||
"dialogOkay": "好的",
|
"dialogOkay": "好的",
|
||||||
"dialogCancel": "取消",
|
"dialogCancel": "取消",
|
||||||
"dialogConfirm": "確認",
|
"dialogConfirm": "確認",
|
||||||
"dialogDismiss": "忽略",
|
"dialogDismiss": "忽略",
|
||||||
"dialogError": "出了點問題",
|
"dialogError": "出了點問題",
|
||||||
"errorRequestBad": "伺服器拒絕了您的請求,請檢查您的輸入。",
|
"errorRequestBad": "服務器拒絕了您的請求,請檢查您的輸入。",
|
||||||
"errorRequestUnauthorized": "未授權的請求,請登入或者嘗試重新登陸。",
|
"errorRequestUnauthorized": "未授權的請求,請登錄或者嘗試重新登陸。",
|
||||||
"errorRequestForbidden": "被禁止的請求,您沒有足夠的許可權去做那件事。",
|
"errorRequestForbidden": "被禁止的請求,您沒有足夠的權限去做那件事。",
|
||||||
"errorRequestNotFound": "您正查詢的資源無法被找到。",
|
"errorRequestNotFound": "您正查找的資源無法被找到。",
|
||||||
"errorRequestConnection": "網路連線錯誤,請檢查您的網路狀態或者檢查我們的服務狀態。",
|
"errorRequestConnection": "網絡連接錯誤,請檢查您的網絡狀態或者檢查我們的服務狀態。",
|
||||||
"errorRequestUnknown": "未知請求錯誤,您可能想將此對話方塊截圖併發送給我們。",
|
"errorRequestUnknown": "未知請求錯誤,您可能想將此對話框截圖併發送給我們。",
|
||||||
"unknown": "未知",
|
"unknown": "未知",
|
||||||
"loading": "載入中…",
|
"loading": "加載中…",
|
||||||
"prev": "上一步",
|
"prev": "上一步",
|
||||||
"next": "下一步",
|
"next": "下一步",
|
||||||
"edit": "編輯",
|
"edit": "編輯",
|
||||||
"apply": "應用",
|
"apply": "應用",
|
||||||
"cancel": "取消",
|
"cancel": "取消",
|
||||||
"create": "建立",
|
"create": "創建",
|
||||||
"preview": "預覽",
|
"preview": "預覽",
|
||||||
"delete": "刪除",
|
"delete": "刪除",
|
||||||
"unlink": "解除連結",
|
"unlink": "解除鏈接",
|
||||||
"crop": "裁剪",
|
"crop": "裁剪",
|
||||||
"compress": "壓縮",
|
"compress": "壓縮",
|
||||||
"report": "檢舉",
|
"report": "檢舉",
|
||||||
"repost": "轉帖",
|
"repost": "轉帖",
|
||||||
"replyPost": "回貼",
|
"replyPost": "回貼",
|
||||||
"reply": "回覆",
|
"reply": "回覆",
|
||||||
"unset": "未設定",
|
"unset": "未設置",
|
||||||
"untitled": "無題",
|
"untitled": "無題",
|
||||||
"postDetail": "帖子詳情",
|
"postDetail": "帖子詳情",
|
||||||
"postNoun": "帖子",
|
"postNoun": "帖子",
|
||||||
@ -64,20 +64,20 @@
|
|||||||
"one": "總計 {} 字",
|
"one": "總計 {} 字",
|
||||||
"other": "總計 {} 字"
|
"other": "總計 {} 字"
|
||||||
},
|
},
|
||||||
"fieldUsername": "使用者名稱",
|
"fieldUsername": "用戶名",
|
||||||
"fieldNickname": "顯示名",
|
"fieldNickname": "顯示名",
|
||||||
"fieldEmail": "電子郵箱地址",
|
"fieldEmail": "電子郵箱地址",
|
||||||
"fieldPassword": "密碼",
|
"fieldPassword": "密碼",
|
||||||
"fieldUsernameAlphanumOnly": "使用者名稱只能包含英文大小寫字母和數字。",
|
"fieldUsernameAlphanumOnly": "用戶名只能包含英文大小寫字母和數字。",
|
||||||
"fieldUsernameLengthLimit": "使用者名稱必須在 {} 和 {} 之間。",
|
"fieldUsernameLengthLimit": "用戶名必須在 {} 和 {} 之間。",
|
||||||
"fieldUsernameCannotEditHint": "使用者名稱在建立後無法修改",
|
"fieldUsernameCannotEditHint": "用戶名在創建後無法修改",
|
||||||
"fieldUsernameLookupHint": "支援使用者名稱、電話號碼或郵箱地址",
|
"fieldUsernameLookupHint": "支持用戶名、電話號碼或郵箱地址",
|
||||||
"fieldNicknameLengthLimit": "暱稱必須在 {} 和 {} 之間。",
|
"fieldNicknameLengthLimit": "暱稱必須在 {} 和 {} 之間。",
|
||||||
"fieldEmailAddressMustBeValid": "電子郵箱地址必須是一個電子郵箱地址。",
|
"fieldEmailAddressMustBeValid": "電子郵箱地址必須是一個電子郵箱地址。",
|
||||||
"fieldFirstName": "名",
|
"fieldFirstName": "名",
|
||||||
"fieldLastName": "姓",
|
"fieldLastName": "姓",
|
||||||
"fieldBirthday": "生日",
|
"fieldBirthday": "生日",
|
||||||
"fieldImageHint": "你可以點選這些個人頭像來編輯它們。",
|
"fieldImageHint": "你可以點擊這些個人頭像來編輯它們。",
|
||||||
"fieldDescription": "簡介",
|
"fieldDescription": "簡介",
|
||||||
"forgotPassword": "忘記密碼",
|
"forgotPassword": "忘記密碼",
|
||||||
"loginPickFactor": "選擇方式驗證",
|
"loginPickFactor": "選擇方式驗證",
|
||||||
@ -85,24 +85,24 @@
|
|||||||
"one": "{} 步驗證",
|
"one": "{} 步驗證",
|
||||||
"other": "{} 步驗證"
|
"other": "{} 步驗證"
|
||||||
},
|
},
|
||||||
"loginEnterPassword": "驗證程式碼",
|
"loginEnterPassword": "驗證代碼",
|
||||||
"loginSuccess": "登入為 {}",
|
"loginSuccess": "登錄為 {}",
|
||||||
"authFactorPassword": "密碼",
|
"authFactorPassword": "密碼",
|
||||||
"authFactorEmail": "電郵一次性驗證碼",
|
"authFactorEmail": "電郵一次性驗證碼",
|
||||||
"accountIntroTitle": "喜歡您來!",
|
"accountIntroTitle": "喜歡您來!",
|
||||||
"accountIntroSubtitle": "登陸以探索更廣大的世界。",
|
"accountIntroSubtitle": "登陸以探索更廣大的世界。",
|
||||||
"accountLogout": "退出登入",
|
"accountLogout": "退出登錄",
|
||||||
"accountLogoutSubtitle": "登出當前賬戶的登陸狀態。",
|
"accountLogoutSubtitle": "註銷當前賬戶的登陸狀態。",
|
||||||
"accountLogoutConfirmTitle": "您確定要退出登入嗎?",
|
"accountLogoutConfirmTitle": "您確定要退出登錄嗎?",
|
||||||
"accountLogoutConfirm": "您需要重新輸入賬號密碼,甚至可能需要多步驗證來再次登陸。",
|
"accountLogoutConfirm": "您需要重新輸入賬號密碼,甚至可能需要多步驗證來再次登陸。",
|
||||||
"accountPublishers": "你的釋出者",
|
"accountPublishers": "你的發佈者",
|
||||||
"accountPublishersSubtitle": "管理你的公共形象。",
|
"accountPublishersSubtitle": "管理你的公共形象。",
|
||||||
"accountProfileEdit": "編輯資料",
|
"accountProfileEdit": "編輯資料",
|
||||||
"accountProfileEditSubtitle": "使你的 Solarpass 賬戶更像你。",
|
"accountProfileEditSubtitle": "使你的 Solarpass 賬戶更像你。",
|
||||||
"accountProfileEditApplied": "個人資料修改已被應用。",
|
"accountProfileEditApplied": "個人資料修改已被應用。",
|
||||||
"publishersNew": "新發布者",
|
"publishersNew": "新發布者",
|
||||||
"publisherNewSubtitle": "建立一個新的公共身份。",
|
"publisherNewSubtitle": "創建一個新的公共身份。",
|
||||||
"publisherSyncWithAccount": "同步賬戶資訊",
|
"publisherSyncWithAccount": "同步賬戶信息",
|
||||||
"publisherTotalUpvote": "總頂數",
|
"publisherTotalUpvote": "總頂數",
|
||||||
"publisherTotalDownvote": "總踩數",
|
"publisherTotalDownvote": "總踩數",
|
||||||
"publisherSocialPoint": "社會信用點",
|
"publisherSocialPoint": "社會信用點",
|
||||||
@ -115,10 +115,10 @@
|
|||||||
"publisherAffiliatedBy": "隸屬於 {}",
|
"publisherAffiliatedBy": "隸屬於 {}",
|
||||||
"publisherRunBy": "由 {} 管理",
|
"publisherRunBy": "由 {} 管理",
|
||||||
"fieldPublisherBelongToRealm": "所屬領域",
|
"fieldPublisherBelongToRealm": "所屬領域",
|
||||||
"fieldPublisherBelongToRealmUnset": "未設定釋出者所屬領域",
|
"fieldPublisherBelongToRealmUnset": "未設置發佈者所屬領域",
|
||||||
"writePostTypeStory": "發動態",
|
"writePostTypeStory": "發動態",
|
||||||
"writePostTypeArticle": "寫文章",
|
"writePostTypeArticle": "寫文章",
|
||||||
"fieldPostPublisher": "帖子釋出者",
|
"fieldPostPublisher": "帖子發佈者",
|
||||||
"fieldPostContent": "發生什麼事了?!",
|
"fieldPostContent": "發生什麼事了?!",
|
||||||
"fieldPostTitle": "標題",
|
"fieldPostTitle": "標題",
|
||||||
"fieldPostDescription": "描述",
|
"fieldPostDescription": "描述",
|
||||||
@ -126,26 +126,26 @@
|
|||||||
"fieldPostCategories": "分類",
|
"fieldPostCategories": "分類",
|
||||||
"fieldPostAlias": "別名",
|
"fieldPostAlias": "別名",
|
||||||
"fieldPostAliasHint": "可選項,用於在 URL 中表示該帖子,應遵循 URL-Safe 的原則。",
|
"fieldPostAliasHint": "可選項,用於在 URL 中表示該帖子,應遵循 URL-Safe 的原則。",
|
||||||
"postPublish": "釋出",
|
"postPublish": "發佈",
|
||||||
"postPublishedAt": "釋出於",
|
"postPublishedAt": "發佈於",
|
||||||
"postPublishedUntil": "取消釋出於",
|
"postPublishedUntil": "取消發佈於",
|
||||||
"postVisibility": "可見性",
|
"postVisibility": "可見性",
|
||||||
"postVisibilityDescription": "帖子可見性決定了誰能檢視該篇帖子。",
|
"postVisibilityDescription": "帖子可見性決定了誰能查看該篇帖子。",
|
||||||
"postVisibilityAll": "所有人可見",
|
"postVisibilityAll": "所有人可見",
|
||||||
"postVisibilityFriends": "僅限好友可見",
|
"postVisibilityFriends": "僅限好友可見",
|
||||||
"postVisibilitySelected": "選定的使用者可見",
|
"postVisibilitySelected": "選定的用戶可見",
|
||||||
"postVisibilityFiltered": "選定使用者不可見",
|
"postVisibilityFiltered": "選定用戶不可見",
|
||||||
"postVisibilityNone": "僅自己可見",
|
"postVisibilityNone": "僅自己可見",
|
||||||
"postVisibleUsers": "可見的使用者",
|
"postVisibleUsers": "可見的用戶",
|
||||||
"postInvisibleUsers": "不可見的使用者",
|
"postInvisibleUsers": "不可見的用戶",
|
||||||
"postSelectedUsers": {
|
"postSelectedUsers": {
|
||||||
"zero": "未選擇使用者",
|
"zero": "未選擇用戶",
|
||||||
"one": "選擇了 {} 個使用者",
|
"one": "選擇了 {} 個用戶",
|
||||||
"other": "選擇了 {} 個使用者"
|
"other": "選擇了 {} 個用戶"
|
||||||
},
|
},
|
||||||
"postEditingNotice": "你正在修改由 {} 釋出的帖子。",
|
"postEditingNotice": "你正在修改由 {} 發佈的帖子。",
|
||||||
"postReplyingNotice": "你正在回覆由 {} 釋出的帖子。",
|
"postReplyingNotice": "你正在回覆由 {} 發佈的帖子。",
|
||||||
"postRepostingNotice": "你正在轉發由 {} 釋出的帖子。",
|
"postRepostingNotice": "你正在轉發由 {} 發佈的帖子。",
|
||||||
"postReact": "反應",
|
"postReact": "反應",
|
||||||
"postPosted": "帖子已經發表。",
|
"postPosted": "帖子已經發表。",
|
||||||
"postReactions": "帖子的反應",
|
"postReactions": "帖子的反應",
|
||||||
@ -164,7 +164,7 @@
|
|||||||
"one": "{} 點社會信用點變更",
|
"one": "{} 點社會信用點變更",
|
||||||
"other": "{} 點社會信用點變更"
|
"other": "{} 點社會信用點變更"
|
||||||
},
|
},
|
||||||
"postReactCompleted": "反應已被新增。",
|
"postReactCompleted": "反應已被添加。",
|
||||||
"postReactUncompleted": "反應已被移除。",
|
"postReactUncompleted": "反應已被移除。",
|
||||||
"postComments": {
|
"postComments": {
|
||||||
"zero": "評論",
|
"zero": "評論",
|
||||||
@ -178,76 +178,76 @@
|
|||||||
},
|
},
|
||||||
"settingsAppearance": "外觀",
|
"settingsAppearance": "外觀",
|
||||||
"settingsBackgroundImage": "背景圖片",
|
"settingsBackgroundImage": "背景圖片",
|
||||||
"settingsBackgroundImageDescription": "設定應用全域性生效的的背景圖片。",
|
"settingsBackgroundImageDescription": "設置應用全局生效的的背景圖片。",
|
||||||
"settingsBackgroundImageClear": "清除現存背景圖",
|
"settingsBackgroundImageClear": "清除現存背景圖",
|
||||||
"settingsBackgroundImageClearDescription": "將應用背景圖重置為空白。",
|
"settingsBackgroundImageClearDescription": "將應用背景圖重置為空白。",
|
||||||
"settingsThemeMaterial3": "使用 Material You 設計正規化",
|
"settingsThemeMaterial3": "使用 Material You 設計範式",
|
||||||
"settingsThemeMaterial3Description": "將應用主題設定為 Material 3 設計正規化的主題。",
|
"settingsThemeMaterial3Description": "將應用主題設置為 Material 3 設計範式的主題。",
|
||||||
"settingsAppBarTransparent": "透明頂欄",
|
"settingsAppBarTransparent": "透明頂欄",
|
||||||
"settingsAppBarTransparentDescription": "為頂欄啟用透明效果。",
|
"settingsAppBarTransparentDescription": "為頂欄啟用透明效果。",
|
||||||
"settingsColorScheme": "主題色",
|
"settingsColorScheme": "主題色",
|
||||||
"settingsColorSchemeDescription": "設定應用主題色。",
|
"settingsColorSchemeDescription": "設置應用主題色。",
|
||||||
"settingsColorSeed": "預設色彩主題",
|
"settingsColorSeed": "預設色彩主題",
|
||||||
"settingsColorSeedDescription": "選擇一個預設色彩主題。",
|
"settingsColorSeedDescription": "選擇一個預設色彩主題。",
|
||||||
"settingsNetwork": "網路",
|
"settingsNetwork": "網絡",
|
||||||
"settingsNetworkServer": "HyperNet 伺服器",
|
"settingsNetworkServer": "HyperNet 服務器",
|
||||||
"settingsNetworkServerDescription": "設定 HyperNet 伺服器地址,選擇我們提供的,或者自己搭建。",
|
"settingsNetworkServerDescription": "設置 HyperNet 服務器地址,選擇我們提供的,或者自己搭建。",
|
||||||
"settingsNetworkServerReset": "重設為官方伺服器",
|
"settingsNetworkServerReset": "重設為官方服務器",
|
||||||
"settingsNetworkServerResetDescription": "重設為 Solar Network 的伺服器地址。",
|
"settingsNetworkServerResetDescription": "重設為 Solar Network 的服務器地址。",
|
||||||
"settingsNetworkServerPreset": "預設的 HyperNet 伺服器",
|
"settingsNetworkServerPreset": "預設的 HyperNet 服務器",
|
||||||
"settingsNetworkServerPresetDescription": "你可以在旁邊的列表中選擇我們提供的預設 HyperNet 伺服器地址。",
|
"settingsNetworkServerPresetDescription": "你可以在旁邊的列表中選擇我們提供的預設 HyperNet 服務器地址。",
|
||||||
"settingsNetworkServerSaved": "伺服器地址已儲存。",
|
"settingsNetworkServerSaved": "服務器地址已保存。",
|
||||||
"settingsPerformance": "效能",
|
"settingsPerformance": "性能",
|
||||||
"settingsImageQuality": "圖片預覽質量",
|
"settingsImageQuality": "圖片預覽質量",
|
||||||
"settingsImageQualityDescription": "設定圖片預覽質量,會影響圖片解碼速度。",
|
"settingsImageQualityDescription": "設置圖片預覽質量,會影響圖片解碼速度。",
|
||||||
"settingsImageQualityLowest": "極低",
|
"settingsImageQualityLowest": "極低",
|
||||||
"settingsImageQualityLow": "低",
|
"settingsImageQualityLow": "低",
|
||||||
"settingsImageQualityMedium": "中",
|
"settingsImageQualityMedium": "中",
|
||||||
"settingsImageQualityHigh": "高",
|
"settingsImageQualityHigh": "高",
|
||||||
"settingsMisc": "雜項",
|
"settingsMisc": "雜項",
|
||||||
"settingsMiscAbout": "關於",
|
"settingsMiscAbout": "關於",
|
||||||
"settingsMiscAboutDescription": "檢視 Solian 的版本資訊。",
|
"settingsMiscAboutDescription": "查看 Solian 的版本信息。",
|
||||||
"sensitiveContent": "敏感內容",
|
"sensitiveContent": "敏感內容",
|
||||||
"sensitiveContentCollapsed": "敏感內容已摺疊。",
|
"sensitiveContentCollapsed": "敏感內容已摺疊。",
|
||||||
"sensitiveContentDescription": "此內容已被標記,可能不適合所有人檢視。",
|
"sensitiveContentDescription": "此內容已被標記,可能不適合所有人查看。",
|
||||||
"sensitiveContentReveal": "顯示內容",
|
"sensitiveContentReveal": "顯示內容",
|
||||||
"serverConnecting": "正在連線伺服器…",
|
"serverConnecting": "正在連接服務器…",
|
||||||
"serverDisconnected": "已與伺服器斷開連線",
|
"serverDisconnected": "已與服務器斷開連接",
|
||||||
"fieldChatAlias": "頻道別名",
|
"fieldChatAlias": "頻道別名",
|
||||||
"fieldChatAliasHint": "全站範圍內唯一的頻道別名,用於在 URL 中表示該頻道,留空則自動生成。應遵循 URL-Safe 的原則。",
|
"fieldChatAliasHint": "全站範圍內唯一的頻道別名,用於在 URL 中表示該頻道,留空則自動生成。應遵循 URL-Safe 的原則。",
|
||||||
"fieldChatName": "名稱",
|
"fieldChatName": "名稱",
|
||||||
"fieldChatDescription": "描述",
|
"fieldChatDescription": "描述",
|
||||||
"fieldChatBelongToRealm": "所屬領域",
|
"fieldChatBelongToRealm": "所屬領域",
|
||||||
"fieldChatBelongToRealmUnset": "未設定頻道所屬領域",
|
"fieldChatBelongToRealmUnset": "未設置頻道所屬領域",
|
||||||
"channelEditingNotice": "您正在編輯頻道 {}",
|
"channelEditingNotice": "您正在編輯頻道 {}",
|
||||||
"channelDeleted": "聊天頻道 {} 已被刪除",
|
"channelDeleted": "聊天頻道 {} 已被刪除",
|
||||||
"channelDelete": "刪除聊天頻道 {}",
|
"channelDelete": "刪除聊天頻道 {}",
|
||||||
"channelDeleteDescription": "你確定要刪除這個聊天頻道嗎?該操作不可撤銷,其頻道內的所有訊息將被永久刪除。",
|
"channelDeleteDescription": "你確定要刪除這個聊天頻道嗎?該操作不可撤銷,其頻道內的所有消息將被永久刪除。",
|
||||||
"channelDetailPersonalRegion": "個人區域",
|
"channelDetailPersonalRegion": "個人區域",
|
||||||
"channelDetailMemberRegion": "成員管理",
|
"channelDetailMemberRegion": "成員管理",
|
||||||
"channelMemberManage": "管理成員",
|
"channelMemberManage": "管理成員",
|
||||||
"channelMemberManageDescription": "管理頻道內現有成員。",
|
"channelMemberManageDescription": "管理頻道內現有成員。",
|
||||||
"channelMemberAdd": "新增成員",
|
"channelMemberAdd": "添加成員",
|
||||||
"channelMemberAddDescription": "給當前頻道新增新成員。",
|
"channelMemberAddDescription": "給當前頻道添加新成員。",
|
||||||
"channelMemberAdded": "頻道成員已新增。",
|
"channelMemberAdded": "頻道成員已添加。",
|
||||||
"fieldMemberRelatedName": "成員名 / 賬戶 ID",
|
"fieldMemberRelatedName": "成員名 / 賬戶 ID",
|
||||||
"channelDetailAdminRegion": "管理區域",
|
"channelDetailAdminRegion": "管理區域",
|
||||||
"channelEditProfile": "更改頻道身份",
|
"channelEditProfile": "更改頻道身份",
|
||||||
"channelEdit": "編輯頻道",
|
"channelEdit": "編輯頻道",
|
||||||
"channelEditDescription": "更改頻道基本資訊,元資料等。",
|
"channelEditDescription": "更改頻道基本信息,元數據等。",
|
||||||
"channelProfileEdit": "編輯頻道身份",
|
"channelProfileEdit": "編輯頻道身份",
|
||||||
"channelActionDelete": "刪除頻道",
|
"channelActionDelete": "刪除頻道",
|
||||||
"channelActionDeleteDescription": "刪除整個頻道,並且刪除頻道里的所有資訊。",
|
"channelActionDeleteDescription": "刪除整個頻道,並且刪除頻道里的所有信息。",
|
||||||
"channelLeave": "退出頻道 {}",
|
"channelLeave": "退出頻道 {}",
|
||||||
"channelLeaveDescription": "退出該頻道,但是你頻道內的資訊不會被移除。",
|
"channelLeaveDescription": "退出該頻道,但是你頻道內的信息不會被移除。",
|
||||||
"channelActionLeave": "退出頻道",
|
"channelActionLeave": "退出頻道",
|
||||||
"channelActionLeaveDescription": "刪除你在這個頻道的身份。",
|
"channelActionLeaveDescription": "刪除你在這個頻道的身份。",
|
||||||
"channelNotifyLevel": "通知級別",
|
"channelNotifyLevel": "通知級別",
|
||||||
"channelNotifyLevelDescription": "有您決定要接受多少來自這個頻道的訊息。",
|
"channelNotifyLevelDescription": "有您決定要接受多少來自這個頻道的消息。",
|
||||||
"channelNotifyLevelAll": "全部通知",
|
"channelNotifyLevelAll": "全部通知",
|
||||||
"channelNotifyLevelMentioned": "僅提及",
|
"channelNotifyLevelMentioned": "僅提及",
|
||||||
"channelNotifyLevelNone": "全部靜音",
|
"channelNotifyLevelNone": "全部靜音",
|
||||||
"channelNotifyLevelApplied": "已經儲存並應用頻道通知級別配置。",
|
"channelNotifyLevelApplied": "已經保存並應用頻道通知級別配置。",
|
||||||
"fieldChannelProfileNick": "頻道內顯示名",
|
"fieldChannelProfileNick": "頻道內顯示名",
|
||||||
"fieldChannelProfileNickHint": "在頻道內顯示的暱稱,留空則使用賬號顯示名。",
|
"fieldChannelProfileNickHint": "在頻道內顯示的暱稱,留空則使用賬號顯示名。",
|
||||||
"fieldRealmAlias": "領域別名",
|
"fieldRealmAlias": "領域別名",
|
||||||
@ -257,38 +257,44 @@
|
|||||||
"realmEditingNotice": "您正在編輯領域 {}",
|
"realmEditingNotice": "您正在編輯領域 {}",
|
||||||
"realmDeleted": "領域 {} 已被刪除",
|
"realmDeleted": "領域 {} 已被刪除",
|
||||||
"realmDelete": "刪除領域 {}",
|
"realmDelete": "刪除領域 {}",
|
||||||
"realmDeleteDescription": "你確定要刪除這個領域嗎?該操作不可撤銷,其隸屬於該領域的所有資源(帖子、聊天頻道、釋出者、製品等)都將被永久刪除。三思而後行!",
|
"realmDeleteDescription": "你確定要刪除這個領域嗎?該操作不可撤銷,其隸屬於該領域的所有資源(帖子、聊天頻道、發佈者、製品等)都將被永久刪除。三思而後行!",
|
||||||
"realmActionDelete": "刪除領域",
|
"realmActionDelete": "刪除領域",
|
||||||
"realmActionDeleteDescription": "刪除整個領域及其附屬的資源。",
|
"realmActionDeleteDescription": "刪除整個領域及其附屬的資源。",
|
||||||
"realmEdit": "編輯領域",
|
"realmEdit": "編輯領域",
|
||||||
"realmEditDescription": "更改領域基本資訊,元資料等。",
|
"realmEditDescription": "更改領域基本信息,元數據等。",
|
||||||
"realmMemberAdd": "新增成員",
|
"realmMemberAdd": "添加成員",
|
||||||
"realmMemberAddDescription": "給當前領域新增新成員。",
|
"realmMemberAddDescription": "給當前領域添加新成員。",
|
||||||
"realmMemberAdded": "領域成員已新增。",
|
"realmMemberAdded": "領域成員已添加。",
|
||||||
"fieldChatMessage": "在 {} 中發訊息",
|
"fieldChatMessage": "在 {} 中發消息",
|
||||||
"fieldChatMessageDirect": "給 {} 發訊息",
|
"fieldChatMessageDirect": "給 {} 發消息",
|
||||||
"eventResourceTag": "訊息 {}",
|
"eventResourceTag": "消息 {}",
|
||||||
"messageDelete": "刪除訊息 {}",
|
"messageDelete": "刪除消息 {}",
|
||||||
"messageDeleteDescription": "你確定要刪除這個訊息嗎?該操作不可撤銷。同時您將留下一條刪除訊息的記錄。",
|
"messageDeleteDescription": "你確定要刪除這個消息嗎?該操作不可撤銷。同時您將留下一條刪除消息的記錄。",
|
||||||
"messageDeleted": "訊息 {} 已被刪除",
|
"messageDeleted": "消息 {} 已被刪除",
|
||||||
"messageEdited": "訊息 {} 已被編輯",
|
"messageEdited": "消息 {} 已被編輯",
|
||||||
"messageEditedHint": "已編輯",
|
"messageEditedHint": "已編輯",
|
||||||
"messageUnsupported": "不支援的訊息 {}",
|
"messageUnsupported": "不支持的消息 {}",
|
||||||
"messageFileHint": {
|
"messageFileHint": {
|
||||||
"zero": "沒有附件",
|
"zero": "沒有附件",
|
||||||
"one": "{} 個附件",
|
"one": "{} 個附件",
|
||||||
"other": "{} 個附件"
|
"other": "{} 個附件"
|
||||||
},
|
},
|
||||||
"addAttachmentFromAlbum": "從相簿中新增附件",
|
"fieldAttachmentRandomId": "訪問 ID",
|
||||||
"addAttachmentFromClipboard": "貼上附件",
|
"addAttachmentFromAlbum": "從相冊中添加附件",
|
||||||
|
"addAttachmentFromClipboard": "粘貼附件",
|
||||||
"addAttachmentFromCameraPhoto": "拍攝照片",
|
"addAttachmentFromCameraPhoto": "拍攝照片",
|
||||||
"addAttachmentFromCameraVideo": "拍攝影片",
|
"addAttachmentFromCameraVideo": "拍攝視頻",
|
||||||
"attachmentPastedImage": "貼上的圖片",
|
"addAttachmentFromRandomId": "通過訪問 ID 鏈接",
|
||||||
"attachmentInsertLink": "插入連線",
|
"attachmentPastedImage": "粘貼的圖片",
|
||||||
"attachmentSetAsPostThumbnail": "設定為帖子縮圖",
|
"attachmentInsertLink": "插入連接",
|
||||||
"attachmentUnsetAsPostThumbnail": "取消設定為帖子縮圖",
|
"attachmentSetAsPostThumbnail": "設置為帖子縮略圖",
|
||||||
"attachmentSetThumbnail": "設定縮圖",
|
"attachmentUnsetAsPostThumbnail": "取消設置為帖子縮略圖",
|
||||||
|
"attachmentSetThumbnail": "設置縮略圖",
|
||||||
|
"attachmentCopyRandomId": "複製訪問 ID",
|
||||||
"attachmentUpload": "上傳",
|
"attachmentUpload": "上傳",
|
||||||
|
"attachmentInputDialog": "上傳附件",
|
||||||
|
"attachmentInputUseRandomId": "使用訪問 ID",
|
||||||
|
"attachmentInputNew": "新上傳附件",
|
||||||
"notification": "通知",
|
"notification": "通知",
|
||||||
"notificationUnreadCount": {
|
"notificationUnreadCount": {
|
||||||
"zero": "無未讀通知",
|
"zero": "無未讀通知",
|
||||||
@ -298,18 +304,18 @@
|
|||||||
"notificationUnread": "未讀",
|
"notificationUnread": "未讀",
|
||||||
"notificationRead": "已讀",
|
"notificationRead": "已讀",
|
||||||
"notificationMarkAllRead": "已讀所有通知",
|
"notificationMarkAllRead": "已讀所有通知",
|
||||||
"notificationMarkAllReadDescription": "您確定要將所有通知設定為已讀嗎?該操作不可撤銷。",
|
"notificationMarkAllReadDescription": "您確定要將所有通知設置為已讀嗎?該操作不可撤銷。",
|
||||||
"notificationMarkAllReadPrompt": {
|
"notificationMarkAllReadPrompt": {
|
||||||
"zero": "已將 0 個通知標記為已讀。",
|
"zero": "已將 0 個通知標記為已讀。",
|
||||||
"one": "已將 {} 個通知標記為已讀。",
|
"one": "已將 {} 個通知標記為已讀。",
|
||||||
"other": "已將 {} 個通知標記為已讀。"
|
"other": "已將 {} 個通知標記為已讀。"
|
||||||
},
|
},
|
||||||
"notificationMarkOneReadPrompt": "已將通知 {} 標記為已讀。",
|
"notificationMarkOneReadPrompt": "已將通知 {} 標記為已讀。",
|
||||||
"search": "搜尋",
|
"search": "搜索",
|
||||||
"postSearchResult": {
|
"postSearchResult": {
|
||||||
"zero": "沒有搜尋到結果",
|
"zero": "沒有搜索到結果",
|
||||||
"one": "搜尋到 {} 個結果",
|
"one": "搜索到 {} 個結果",
|
||||||
"other": "搜尋到 {} 個結果"
|
"other": "搜索到 {} 個結果"
|
||||||
},
|
},
|
||||||
"postSearchTook": "耗時 {}",
|
"postSearchTook": "耗時 {}",
|
||||||
"postDelete": "刪除帖子 {}",
|
"postDelete": "刪除帖子 {}",
|
||||||
@ -321,26 +327,26 @@
|
|||||||
"callResume": "恢復",
|
"callResume": "恢復",
|
||||||
"callMicrophone": "麥克風",
|
"callMicrophone": "麥克風",
|
||||||
"callCamera": "攝像頭",
|
"callCamera": "攝像頭",
|
||||||
"callMicrophoneDisabled": "麥克風已停用",
|
"callMicrophoneDisabled": "麥克風已禁用",
|
||||||
"callMicrophoneSelect": "選擇麥克風",
|
"callMicrophoneSelect": "選擇麥克風",
|
||||||
"callCameraDisabled": "攝像頭已停用",
|
"callCameraDisabled": "攝像頭已禁用",
|
||||||
"callCameraSelect": "選擇攝像頭",
|
"callCameraSelect": "選擇攝像頭",
|
||||||
"callDisconnected": "通話已斷開",
|
"callDisconnected": "通話已斷開",
|
||||||
"callEnded": "通話已結束",
|
"callEnded": "通話已結束",
|
||||||
"callStatusConnected": "已連線",
|
"callStatusConnected": "已連接",
|
||||||
"callStatusDisconnected": "未連線",
|
"callStatusDisconnected": "未連接",
|
||||||
"callStatusConnecting": "正在連線",
|
"callStatusConnecting": "正在連接",
|
||||||
"callStatusReconnecting": "正在重連",
|
"callStatusReconnecting": "正在重連",
|
||||||
"callDisconnect": "斷開連線",
|
"callDisconnect": "斷開連接",
|
||||||
"callDisconnectDescription": "您確定要與通話斷開連線嗎?",
|
"callDisconnectDescription": "您確定要與通話斷開連接嗎?",
|
||||||
"callMicrophoneOff": "關閉麥克風",
|
"callMicrophoneOff": "關閉麥克風",
|
||||||
"callMicrophoneOn": "開啟麥克風",
|
"callMicrophoneOn": "打開麥克風",
|
||||||
"callCameraOff": "關閉攝像頭",
|
"callCameraOff": "關閉攝像頭",
|
||||||
"callCameraOn": "開啟攝像頭",
|
"callCameraOn": "打開攝像頭",
|
||||||
"callVideoFlip": "映象畫面",
|
"callVideoFlip": "鏡像畫面",
|
||||||
"callSpeakerphoneToggle": "切換揚聲器",
|
"callSpeakerphoneToggle": "切換揚聲器",
|
||||||
"callScreenOff": "關閉螢幕共享",
|
"callScreenOff": "關閉屏幕共享",
|
||||||
"callScreenOn": "開啟螢幕共享",
|
"callScreenOn": "開啟屏幕共享",
|
||||||
"callMessageEnded": "通話持續了 {}",
|
"callMessageEnded": "通話持續了 {}",
|
||||||
"callMessageStarted": "通話開始了",
|
"callMessageStarted": "通話開始了",
|
||||||
"dailyCheckIn": "每日簽到",
|
"dailyCheckIn": "每日簽到",
|
||||||
@ -396,27 +402,27 @@
|
|||||||
"pendingFatherDay": "{} 過父親節",
|
"pendingFatherDay": "{} 過父親節",
|
||||||
"pendingHalloween": "{} 過聖誕節",
|
"pendingHalloween": "{} 過聖誕節",
|
||||||
"pendingThanksgiving": "{} 過感恩節",
|
"pendingThanksgiving": "{} 過感恩節",
|
||||||
"friendNew": "新增好友",
|
"friendNew": "添加好友",
|
||||||
"friendRequests": "好友請求",
|
"friendRequests": "好友請求",
|
||||||
"friendRequestsDescription": {
|
"friendRequestsDescription": {
|
||||||
"zero": "你沒有好友請求",
|
"zero": "你沒有好友請求",
|
||||||
"one": "你有 {} 個好友請求",
|
"one": "你有 {} 個好友請求",
|
||||||
"other": "你有 {} 個好友請求"
|
"other": "你有 {} 個好友請求"
|
||||||
},
|
},
|
||||||
"friendBlocklist": "遮蔽列表",
|
"friendBlocklist": "屏蔽列表",
|
||||||
"friendBlocklistDescription": {
|
"friendBlocklistDescription": {
|
||||||
"zero": "你沒有遮蔽任何人",
|
"zero": "你沒有屏蔽任何人",
|
||||||
"one": "你遮蔽了 {} 個使用者",
|
"one": "你屏蔽了 {} 個用戶",
|
||||||
"other": "你遮蔽了 {} 個使用者"
|
"other": "你屏蔽了 {} 個用戶"
|
||||||
},
|
},
|
||||||
"friendStatusPending": "待處理",
|
"friendStatusPending": "待處理",
|
||||||
"friendStatusWaiting": "等待中",
|
"friendStatusWaiting": "等待中",
|
||||||
"friendStatusActive": "正活躍",
|
"friendStatusActive": "正活躍",
|
||||||
"friendStatusBlocked": "已遮蔽",
|
"friendStatusBlocked": "已屏蔽",
|
||||||
"friendRequestSent": "好友請求已傳送。",
|
"friendRequestSent": "好友請求已發送。",
|
||||||
"fieldFriendRelatedName": "好友名 / 賬戶 ID",
|
"fieldFriendRelatedName": "好友名 / 賬戶 ID",
|
||||||
"friendBlock": "遮蔽",
|
"friendBlock": "屏蔽",
|
||||||
"friendUnblock": "解除遮蔽",
|
"friendUnblock": "解除屏蔽",
|
||||||
"friendDeleteAction": "遺忘",
|
"friendDeleteAction": "遺忘",
|
||||||
"friendDelete": "遺忘跟 {} 的關係",
|
"friendDelete": "遺忘跟 {} 的關係",
|
||||||
"friendDeleteDescription": "你確定要遺忘跟 {} 的關係嗎?這個操作無法撤銷。",
|
"friendDeleteDescription": "你確定要遺忘跟 {} 的關係嗎?這個操作無法撤銷。",
|
||||||
@ -432,20 +438,20 @@
|
|||||||
"badgeCompanyStaff": "索爾辛茨士大夫 · 員工",
|
"badgeCompanyStaff": "索爾辛茨士大夫 · 員工",
|
||||||
"badgeSiteMigration": "Solar Network 原住民",
|
"badgeSiteMigration": "Solar Network 原住民",
|
||||||
"accountStatus": "狀態",
|
"accountStatus": "狀態",
|
||||||
"accountStatusOnline": "線上",
|
"accountStatusOnline": "在線",
|
||||||
"accountStatusOffline": "離線",
|
"accountStatusOffline": "離線",
|
||||||
"accountStatusLastSeen": "最後一次上線於 {}",
|
"accountStatusLastSeen": "最後一次上線於 {}",
|
||||||
"postArticle": "Solar Network 上的文章",
|
"postArticle": "Solar Network 上的文章",
|
||||||
"postStory": "Solar Network 上的故事",
|
"postStory": "Solar Network 上的故事",
|
||||||
"articleWrittenAt": "發表於 {}",
|
"articleWrittenAt": "發表於 {}",
|
||||||
"articleEditedAt": "編輯於 {}",
|
"articleEditedAt": "編輯於 {}",
|
||||||
"attachmentSaved": "已儲存到相簿",
|
"attachmentSaved": "已保存到相冊",
|
||||||
"attachmentSavedDesktop": "已儲存到下載目錄",
|
"attachmentSavedDesktop": "已保存到下載目錄",
|
||||||
"openInAlbum": "在相簿中開啟",
|
"openInAlbum": "在相冊中打開",
|
||||||
"postAbuseReport": "檢舉帖子",
|
"postAbuseReport": "檢舉帖子",
|
||||||
"postAbuseReportDescription": "檢舉不符合我們使用者協議以及社群準則的帖子,來幫助我們更好的維護 Solar Network 上的內容。請在下面描述該帖子如何違反我麼的相關規定。請勿填寫任何敏感資訊。我們將會在 24 小時內處理您的檢舉。",
|
"postAbuseReportDescription": "檢舉不符合我們用戶協議以及社區準則的帖子,來幫助我們更好的維護 Solar Network 上的內容。請在下面描述該帖子如何違反我麼的相關規定。請勿填寫任何敏感信息。我們將會在 24 小時內處理您的檢舉。",
|
||||||
"abuseReport": "檢舉",
|
"abuseReport": "檢舉",
|
||||||
"abuseReportDescription": "檢舉不符合我們使用者協議以及社群準則的任何資源,來幫助我們更好的維護 Solar Network 上的內容。請在下面描述資源的位置(提供資源 ID 為佳)以及如何違反我麼的相關規定。請勿填寫任何敏感資訊。我們將會在 24 小時內處理您的檢舉。",
|
"abuseReportDescription": "檢舉不符合我們用戶協議以及社區準則的任何資源,來幫助我們更好的維護 Solar Network 上的內容。請在下面描述資源的位置(提供資源 ID 為佳)以及如何違反我麼的相關規定。請勿填寫任何敏感信息。我們將會在 24 小時內處理您的檢舉。",
|
||||||
"abuseReportAction": "提交檢舉",
|
"abuseReportAction": "提交檢舉",
|
||||||
"abuseReportActionDescription": "檢舉不合規行為。",
|
"abuseReportActionDescription": "檢舉不合規行為。",
|
||||||
"abuseReportResource": "資源位置 / ID",
|
"abuseReportResource": "資源位置 / ID",
|
||||||
@ -453,35 +459,35 @@
|
|||||||
"abuseReportSubmitted": "檢舉已提交,感謝你的貢獻。",
|
"abuseReportSubmitted": "檢舉已提交,感謝你的貢獻。",
|
||||||
"submit": "提交",
|
"submit": "提交",
|
||||||
"accountDeletion": "刪除帳戶",
|
"accountDeletion": "刪除帳戶",
|
||||||
"accountDeletionDescription": "你確定要刪除這個帳戶嗎?該操作不可撤銷,其隸屬於該帳戶的所有資源(帖子、聊天頻道、釋出者、製品等)都將被永久刪除。三思而後行!",
|
"accountDeletionDescription": "你確定要刪除這個帳戶嗎?該操作不可撤銷,其隸屬於該帳戶的所有資源(帖子、聊天頻道、發佈者、製品等)都將被永久刪除。三思而後行!",
|
||||||
"accountDeletionActionDescription": "刪除你的 Solarpass 帳戶。",
|
"accountDeletionActionDescription": "刪除你的 Solarpass 帳戶。",
|
||||||
"accountDeletionSubmitted": "帳戶刪除申請已發出,你可以檢查你的收件箱並根據郵件內的指示完成刪除操作。",
|
"accountDeletionSubmitted": "帳戶刪除申請已發出,你可以檢查你的收件箱並根據郵件內的指示完成刪除操作。",
|
||||||
"channelNewChannel": "新建頻道",
|
"channelNewChannel": "新建頻道",
|
||||||
"channelNewDirectMessage": "發起私信",
|
"channelNewDirectMessage": "發起私信",
|
||||||
"channelDirectMessageDescription": "與 {} 的私聊",
|
"channelDirectMessageDescription": "與 {} 的私聊",
|
||||||
"fieldCannotBeEmpty": "此欄位不能為空。",
|
"fieldCannotBeEmpty": "此字段不能為空。",
|
||||||
"termAcceptLink": "瀏覽條款",
|
"termAcceptLink": "瀏覽條款",
|
||||||
"termAcceptNextWithAgree": "點選 “下一步”,即表示你同意我們的各項條款,包括其之後的更新。",
|
"termAcceptNextWithAgree": "點擊 “下一步”,即表示你同意我們的各項條款,包括其之後的更新。",
|
||||||
"unauthorized": "未登陸",
|
"unauthorized": "未登陸",
|
||||||
"unauthorizedDescription": "登陸以探索整個 Solar Network。",
|
"unauthorizedDescription": "登陸以探索整個 Solar Network。",
|
||||||
"serviceStatus": "服務狀態",
|
"serviceStatus": "服務狀態",
|
||||||
"termRelated": "相關條款",
|
"termRelated": "相關條款",
|
||||||
"appDetails": "應用程式詳情",
|
"appDetails": "應用程序詳情",
|
||||||
"postRecommendation": "推薦帖子",
|
"postRecommendation": "推薦帖子",
|
||||||
"publisherBlockHint": "遮蔽 {}",
|
"publisherBlockHint": "屏蔽 {}",
|
||||||
"publisherBlockHintDescription": "你正要遮蔽此釋出者的運營者,該操作也將遮蔽由同一使用者運營的釋出者。",
|
"publisherBlockHintDescription": "你正要屏蔽此發佈者的運營者,該操作也將屏蔽由同一用戶運營的發佈者。",
|
||||||
"userUnblocked": "已解除遮蔽使用者 {}",
|
"userUnblocked": "已解除屏蔽用戶 {}",
|
||||||
"userBlocked": "已遮蔽使用者 {}",
|
"userBlocked": "已屏蔽用戶 {}",
|
||||||
"postSharingViaPicture": "正在生成帖子截圖,請稍等片刻……",
|
"postSharingViaPicture": "正在生成帖子截圖,請稍等片刻……",
|
||||||
"postImageShareReadMore": "掃描右側 QRCode 檢視全文",
|
"postImageShareReadMore": "掃描右側 QRCode 查看全文",
|
||||||
"postImageShareAds": "來 Solar Network 探索更多有趣帖子",
|
"postImageShareAds": "來 Solar Network 探索更多有趣帖子",
|
||||||
"postShare": "分享",
|
"postShare": "分享",
|
||||||
"postShareImage": "分享帖圖",
|
"postShareImage": "分享帖圖",
|
||||||
"appInitializing": "正在初始化",
|
"appInitializing": "正在初始化",
|
||||||
"poweredBy": "由 {} 提供支援",
|
"poweredBy": "由 {} 提供支持",
|
||||||
"shareIntent": "分享",
|
"shareIntent": "分享",
|
||||||
"shareIntentDescription": "您想對您分享的內容做些什麼?",
|
"shareIntentDescription": "您想對您分享的內容做些什麼?",
|
||||||
"shareIntentPostStory": "釋出動態",
|
"shareIntentPostStory": "發佈動態",
|
||||||
"updateAvailable": "檢測到更新可用",
|
"updateAvailable": "檢測到更新可用",
|
||||||
"updateOngoing": "正在更新,請稍後……",
|
"updateOngoing": "正在更新,請稍後……",
|
||||||
"custom": "自定義",
|
"custom": "自定義",
|
||||||
@ -504,5 +510,6 @@
|
|||||||
"postCategoryKnowledge": "知識",
|
"postCategoryKnowledge": "知識",
|
||||||
"postCategoryLiterature": "文學",
|
"postCategoryLiterature": "文學",
|
||||||
"postCategoryFunny": "搞笑",
|
"postCategoryFunny": "搞笑",
|
||||||
"postCategoryUncategorized": "未分類"
|
"postCategoryUncategorized": "未分類",
|
||||||
|
"waitingForUpload": "等待上傳"
|
||||||
}
|
}
|
||||||
|
@ -15,16 +15,9 @@ import 'package:surface/types/post.dart';
|
|||||||
import 'package:surface/widgets/dialog.dart';
|
import 'package:surface/widgets/dialog.dart';
|
||||||
import 'package:surface/widgets/universal_image.dart';
|
import 'package:surface/widgets/universal_image.dart';
|
||||||
|
|
||||||
enum PostWriteMediaType {
|
|
||||||
image,
|
|
||||||
video,
|
|
||||||
audio,
|
|
||||||
file,
|
|
||||||
}
|
|
||||||
|
|
||||||
class PostWriteMedia {
|
class PostWriteMedia {
|
||||||
late String name;
|
late String name;
|
||||||
late PostWriteMediaType type;
|
late SnMediaType type;
|
||||||
final SnAttachment? attachment;
|
final SnAttachment? attachment;
|
||||||
final XFile? file;
|
final XFile? file;
|
||||||
final Uint8List? raw;
|
final Uint8List? raw;
|
||||||
@ -36,16 +29,16 @@ class PostWriteMedia {
|
|||||||
|
|
||||||
switch (attachment?.mimetype.split('/').firstOrNull) {
|
switch (attachment?.mimetype.split('/').firstOrNull) {
|
||||||
case 'image':
|
case 'image':
|
||||||
type = PostWriteMediaType.image;
|
type = SnMediaType.image;
|
||||||
break;
|
break;
|
||||||
case 'video':
|
case 'video':
|
||||||
type = PostWriteMediaType.video;
|
type = SnMediaType.video;
|
||||||
break;
|
break;
|
||||||
case 'audio':
|
case 'audio':
|
||||||
type = PostWriteMediaType.audio;
|
type = SnMediaType.audio;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
type = PostWriteMediaType.file;
|
type = SnMediaType.file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,16 +50,16 @@ class PostWriteMedia {
|
|||||||
|
|
||||||
switch (mimetype?.split('/').firstOrNull) {
|
switch (mimetype?.split('/').firstOrNull) {
|
||||||
case 'image':
|
case 'image':
|
||||||
type = PostWriteMediaType.image;
|
type = SnMediaType.image;
|
||||||
break;
|
break;
|
||||||
case 'video':
|
case 'video':
|
||||||
type = PostWriteMediaType.video;
|
type = SnMediaType.video;
|
||||||
break;
|
break;
|
||||||
case 'audio':
|
case 'audio':
|
||||||
type = PostWriteMediaType.audio;
|
type = SnMediaType.audio;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
type = PostWriteMediaType.file;
|
type = SnMediaType.file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,7 +237,7 @@ class PostWriteController extends ChangeNotifier {
|
|||||||
media.name,
|
media.name,
|
||||||
'interactive',
|
'interactive',
|
||||||
null,
|
null,
|
||||||
mimetype: media.raw != null && media.type == PostWriteMediaType.image ? 'image/png' : null,
|
mimetype: media.raw != null && media.type == SnMediaType.image ? 'image/png' : null,
|
||||||
);
|
);
|
||||||
|
|
||||||
final item = await attach.chunkedUploadParts(
|
final item = await attach.chunkedUploadParts(
|
||||||
@ -301,7 +294,7 @@ class PostWriteController extends ChangeNotifier {
|
|||||||
media.name,
|
media.name,
|
||||||
'interactive',
|
'interactive',
|
||||||
null,
|
null,
|
||||||
mimetype: media.raw != null && media.type == PostWriteMediaType.image ? 'image/png' : null,
|
mimetype: media.raw != null && media.type == SnMediaType.image ? 'image/png' : null,
|
||||||
);
|
);
|
||||||
|
|
||||||
final item = await attach.chunkedUploadParts(
|
final item = await attach.chunkedUploadParts(
|
||||||
|
@ -217,15 +217,17 @@ class SnAttachmentProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<SnAttachment> updateOne(
|
Future<SnAttachment> updateOne(
|
||||||
int id,
|
int id, {
|
||||||
String alt, {
|
String? alt,
|
||||||
required Map<String, dynamic> metadata,
|
String? thumbnail,
|
||||||
bool isMature = false,
|
Map<String, dynamic>? metadata,
|
||||||
|
bool? isIndexable,
|
||||||
}) async {
|
}) async {
|
||||||
final resp = await _sn.client.put('/cgi/uc/attachments/$id', data: {
|
final resp = await _sn.client.put('/cgi/uc/attachments/$id', data: {
|
||||||
'alt': alt,
|
'alt': alt,
|
||||||
|
'thumbnail': thumbnail,
|
||||||
'metadata': metadata,
|
'metadata': metadata,
|
||||||
'is_mature': isMature,
|
'is_indexable': isIndexable,
|
||||||
});
|
});
|
||||||
return SnAttachment.fromJson(resp.data);
|
return SnAttachment.fromJson(resp.data);
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ class SpecialDayProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
double getSpecialDayProgress(DateTime last, DateTime next) {
|
double getSpecialDayProgress(DateTime last, DateTime next) {
|
||||||
final totalDuration = next.difference(last).inSeconds.toDouble();
|
final totalDuration = next.add(-const Duration(days: 1)).difference(last).inSeconds.toDouble();
|
||||||
final elapsedDuration = DateTime.now().difference(last).inSeconds.toDouble();
|
final elapsedDuration = DateTime.now().difference(last).inSeconds.toDouble();
|
||||||
return (elapsedDuration / totalDuration).clamp(0.0, 1.0);
|
return (elapsedDuration / totalDuration).clamp(0.0, 1.0);
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import 'package:provider/provider.dart';
|
|||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:surface/providers/config.dart';
|
import 'package:surface/providers/config.dart';
|
||||||
import 'package:surface/providers/sn_network.dart';
|
import 'package:surface/providers/sn_network.dart';
|
||||||
import 'package:surface/providers/widget.dart';
|
|
||||||
import 'package:surface/types/account.dart';
|
import 'package:surface/types/account.dart';
|
||||||
|
|
||||||
class UserProvider extends ChangeNotifier {
|
class UserProvider extends ChangeNotifier {
|
||||||
@ -13,12 +12,10 @@ class UserProvider extends ChangeNotifier {
|
|||||||
SnAccount? user;
|
SnAccount? user;
|
||||||
|
|
||||||
late final SnNetworkProvider _sn;
|
late final SnNetworkProvider _sn;
|
||||||
late final HomeWidgetProvider _home;
|
|
||||||
late final ConfigProvider _config;
|
late final ConfigProvider _config;
|
||||||
|
|
||||||
UserProvider(BuildContext context) {
|
UserProvider(BuildContext context) {
|
||||||
_sn = context.read<SnNetworkProvider>();
|
_sn = context.read<SnNetworkProvider>();
|
||||||
_home = context.read<HomeWidgetProvider>();
|
|
||||||
_config = context.read<ConfigProvider>();
|
_config = context.read<ConfigProvider>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,15 +22,14 @@ import 'package:surface/widgets/universal_image.dart';
|
|||||||
|
|
||||||
class AccountPublisherEditScreen extends StatefulWidget {
|
class AccountPublisherEditScreen extends StatefulWidget {
|
||||||
final String name;
|
final String name;
|
||||||
|
|
||||||
const AccountPublisherEditScreen({super.key, required this.name});
|
const AccountPublisherEditScreen({super.key, required this.name});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<AccountPublisherEditScreen> createState() =>
|
State<AccountPublisherEditScreen> createState() => _AccountPublisherEditScreenState();
|
||||||
_AccountPublisherEditScreenState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AccountPublisherEditScreenState
|
class _AccountPublisherEditScreenState extends State<AccountPublisherEditScreen> {
|
||||||
extends State<AccountPublisherEditScreen> {
|
|
||||||
bool _isBusy = false;
|
bool _isBusy = false;
|
||||||
|
|
||||||
SnPublisher? _publisher;
|
SnPublisher? _publisher;
|
||||||
@ -54,7 +53,7 @@ class _AccountPublisherEditScreenState
|
|||||||
_publisher = SnPublisher.fromJson(resp.data);
|
_publisher = SnPublisher.fromJson(resp.data);
|
||||||
_syncWidget();
|
_syncWidget();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
context.showErrorDialog(err);
|
if (mounted) context.showErrorDialog(err);
|
||||||
} finally {
|
} finally {
|
||||||
setState(() => _isBusy = false);
|
setState(() => _isBusy = false);
|
||||||
}
|
}
|
||||||
@ -75,9 +74,9 @@ class _AccountPublisherEditScreenState
|
|||||||
'name': _nameController.text,
|
'name': _nameController.text,
|
||||||
'description': _descriptionController.text,
|
'description': _descriptionController.text,
|
||||||
});
|
});
|
||||||
Navigator.pop(context, true);
|
if (mounted) Navigator.pop(context, true);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
context.showErrorDialog(err);
|
if(mounted) context.showErrorDialog(err);
|
||||||
} finally {
|
} finally {
|
||||||
setState(() => _isBusy = false);
|
setState(() => _isBusy = false);
|
||||||
}
|
}
|
||||||
@ -108,11 +107,9 @@ class _AccountPublisherEditScreenState
|
|||||||
if (image == null) return;
|
if (image == null) return;
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
|
||||||
final ImageProvider imageProvider =
|
final ImageProvider imageProvider = kIsWeb ? NetworkImage(image.path) : FileImage(File(image.path));
|
||||||
kIsWeb ? NetworkImage(image.path) : FileImage(File(image.path));
|
final aspectRatios =
|
||||||
final aspectRatios = place == 'banner'
|
place == 'banner' ? [CropAspectRatio(width: 16, height: 7)] : [CropAspectRatio(width: 1, height: 1)];
|
||||||
? [CropAspectRatio(width: 16, height: 7)]
|
|
||||||
: [CropAspectRatio(width: 1, height: 1)];
|
|
||||||
final result = (!kIsWeb && (Platform.isIOS || Platform.isMacOS))
|
final result = (!kIsWeb && (Platform.isIOS || Platform.isMacOS))
|
||||||
? await showCupertinoImageCropper(
|
? await showCupertinoImageCropper(
|
||||||
// ignore: use_build_context_synchronously
|
// ignore: use_build_context_synchronously
|
||||||
@ -134,10 +131,7 @@ class _AccountPublisherEditScreenState
|
|||||||
|
|
||||||
setState(() => _isBusy = true);
|
setState(() => _isBusy = true);
|
||||||
|
|
||||||
final rawBytes =
|
final rawBytes = (await result.uiImage.toByteData(format: ImageByteFormat.png))!.buffer.asUint8List();
|
||||||
(await result.uiImage.toByteData(format: ImageByteFormat.png))!
|
|
||||||
.buffer
|
|
||||||
.asUint8List();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final attachment = await attach.directUploadOne(
|
final attachment = await attach.directUploadOne(
|
||||||
@ -199,9 +193,7 @@ class _AccountPublisherEditScreenState
|
|||||||
child: AspectRatio(
|
child: AspectRatio(
|
||||||
aspectRatio: 16 / 9,
|
aspectRatio: 16 / 9,
|
||||||
child: Container(
|
child: Container(
|
||||||
color: Theme.of(context)
|
color: Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||||
.colorScheme
|
|
||||||
.surfaceContainerHigh,
|
|
||||||
child: _banner != null
|
child: _banner != null
|
||||||
? AutoResizeUniversalImage(
|
? AutoResizeUniversalImage(
|
||||||
sn.getAttachmentUrl(_banner!),
|
sn.getAttachmentUrl(_banner!),
|
||||||
@ -240,8 +232,7 @@ class _AccountPublisherEditScreenState
|
|||||||
labelText: 'fieldUsername'.tr(),
|
labelText: 'fieldUsername'.tr(),
|
||||||
helperText: 'fieldUsernameCannotEditHint'.tr(),
|
helperText: 'fieldUsernameCannotEditHint'.tr(),
|
||||||
),
|
),
|
||||||
onTapOutside: (_) =>
|
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||||
FocusManager.instance.primaryFocus?.unfocus(),
|
|
||||||
),
|
),
|
||||||
const Gap(4),
|
const Gap(4),
|
||||||
TextField(
|
TextField(
|
||||||
@ -249,8 +240,7 @@ class _AccountPublisherEditScreenState
|
|||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'fieldNickname'.tr(),
|
labelText: 'fieldNickname'.tr(),
|
||||||
),
|
),
|
||||||
onTapOutside: (_) =>
|
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||||
FocusManager.instance.primaryFocus?.unfocus(),
|
|
||||||
),
|
),
|
||||||
const Gap(4),
|
const Gap(4),
|
||||||
TextField(
|
TextField(
|
||||||
@ -260,8 +250,7 @@ class _AccountPublisherEditScreenState
|
|||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'fieldDescription'.tr(),
|
labelText: 'fieldDescription'.tr(),
|
||||||
),
|
),
|
||||||
onTapOutside: (_) =>
|
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||||
FocusManager.instance.primaryFocus?.unfocus(),
|
|
||||||
),
|
),
|
||||||
const Gap(12),
|
const Gap(12),
|
||||||
Row(
|
Row(
|
||||||
|
@ -201,7 +201,7 @@ class _PublisherNewPersonalState extends State<_PublisherNewPersonal> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _PublisherNewOrganization extends StatefulWidget {
|
class _PublisherNewOrganization extends StatefulWidget {
|
||||||
const _PublisherNewOrganization({super.key});
|
const _PublisherNewOrganization();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<_PublisherNewOrganization> createState() =>
|
State<_PublisherNewOrganization> createState() =>
|
||||||
|
@ -105,6 +105,7 @@ class _LoginCheckScreen extends StatefulWidget {
|
|||||||
final SnAuthFactor? factor;
|
final SnAuthFactor? factor;
|
||||||
final Function(SnAuthTicket?) onTicket;
|
final Function(SnAuthTicket?) onTicket;
|
||||||
final Function onNext;
|
final Function onNext;
|
||||||
|
|
||||||
const _LoginCheckScreen({
|
const _LoginCheckScreen({
|
||||||
super.key,
|
super.key,
|
||||||
required this.ticket,
|
required this.ticket,
|
||||||
@ -204,9 +205,7 @@ class _LoginCheckScreenState extends State<_LoginCheckScreen> {
|
|||||||
controller: _passwordController,
|
controller: _passwordController,
|
||||||
obscureText: true,
|
obscureText: true,
|
||||||
autofillHints: [
|
autofillHints: [
|
||||||
(_factorLabelMap[widget.factor!.type]?.$3 ?? true)
|
(_factorLabelMap[widget.factor!.type]?.$3 ?? true) ? AutofillHints.password : AutofillHints.oneTimeCode
|
||||||
? AutofillHints.password
|
|
||||||
: AutofillHints.oneTimeCode
|
|
||||||
],
|
],
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
isDense: true,
|
isDense: true,
|
||||||
@ -243,6 +242,7 @@ class _LoginPickerScreen extends StatefulWidget {
|
|||||||
final Function(SnAuthTicket?) onTicket;
|
final Function(SnAuthTicket?) onTicket;
|
||||||
final Function(SnAuthFactor) onPickFactor;
|
final Function(SnAuthFactor) onPickFactor;
|
||||||
final Function onNext;
|
final Function onNext;
|
||||||
|
|
||||||
const _LoginPickerScreen({
|
const _LoginPickerScreen({
|
||||||
super.key,
|
super.key,
|
||||||
required this.ticket,
|
required this.ticket,
|
||||||
@ -260,8 +260,7 @@ class _LoginPickerScreenState extends State<_LoginPickerScreen> {
|
|||||||
bool _isBusy = false;
|
bool _isBusy = false;
|
||||||
int? _factorPicked;
|
int? _factorPicked;
|
||||||
|
|
||||||
Color get _unFocusColor =>
|
Color get _unFocusColor => Theme.of(context).colorScheme.onSurface.withAlpha((255 * 0.75).round());
|
||||||
Theme.of(context).colorScheme.onSurface.withAlpha((255 * 0.75).round());
|
|
||||||
|
|
||||||
void _performGetFactorCode() async {
|
void _performGetFactorCode() async {
|
||||||
if (_factorPicked == null) return;
|
if (_factorPicked == null) return;
|
||||||
@ -373,6 +372,7 @@ class _LoginLookupScreen extends StatefulWidget {
|
|||||||
final Function(SnAuthTicket?) onTicket;
|
final Function(SnAuthTicket?) onTicket;
|
||||||
final Function(List<SnAuthFactor>?) onFactor;
|
final Function(List<SnAuthFactor>?) onFactor;
|
||||||
final Function onNext;
|
final Function onNext;
|
||||||
|
|
||||||
const _LoginLookupScreen({
|
const _LoginLookupScreen({
|
||||||
super.key,
|
super.key,
|
||||||
required this.ticket,
|
required this.ticket,
|
||||||
@ -401,14 +401,13 @@ class _LoginLookupScreenState extends State<_LoginLookupScreen> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
final sn = context.read<SnNetworkProvider>();
|
final sn = context.read<SnNetworkProvider>();
|
||||||
final lookupResp =
|
final lookupResp = await sn.client.get('/cgi/id/users/lookup?probe=$username');
|
||||||
await sn.client.get('/cgi/id/users/lookup?probe=$username');
|
|
||||||
await sn.client.post('/cgi/id/users/me/password-reset', data: {
|
await sn.client.post('/cgi/id/users/me/password-reset', data: {
|
||||||
'user_id': lookupResp.data['id'],
|
'user_id': lookupResp.data['id'],
|
||||||
});
|
});
|
||||||
context.showModalDialog('done'.tr(), 'signinResetPasswordSent'.tr());
|
if (mounted) context.showModalDialog('done'.tr(), 'signinResetPasswordSent'.tr());
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
context.showErrorDialog(err);
|
if (mounted) context.showErrorDialog(err);
|
||||||
} finally {
|
} finally {
|
||||||
setState(() => _isBusy = false);
|
setState(() => _isBusy = false);
|
||||||
}
|
}
|
||||||
@ -431,8 +430,7 @@ class _LoginLookupScreenState extends State<_LoginLookupScreen> {
|
|||||||
widget.onTicket(result.ticket);
|
widget.onTicket(result.ticket);
|
||||||
|
|
||||||
// Pull factors
|
// Pull factors
|
||||||
final factorResp =
|
final factorResp = await sn.client.get('/cgi/id/auth/factors', queryParameters: {
|
||||||
await sn.client.get('/cgi/id/auth/factors', queryParameters: {
|
|
||||||
'ticketId': result.ticket!.id.toString(),
|
'ticketId': result.ticket!.id.toString(),
|
||||||
});
|
});
|
||||||
widget.onFactor(
|
widget.onFactor(
|
||||||
@ -443,7 +441,7 @@ class _LoginLookupScreenState extends State<_LoginLookupScreen> {
|
|||||||
|
|
||||||
widget.onNext();
|
widget.onNext();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
context.showErrorDialog(err);
|
if(mounted) context.showErrorDialog(err);
|
||||||
return;
|
return;
|
||||||
} finally {
|
} finally {
|
||||||
setState(() => _isBusy = false);
|
setState(() => _isBusy = false);
|
||||||
@ -526,10 +524,7 @@ class _LoginLookupScreenState extends State<_LoginLookupScreen> {
|
|||||||
'termAcceptNextWithAgree'.tr(),
|
'termAcceptNextWithAgree'.tr(),
|
||||||
textAlign: TextAlign.end,
|
textAlign: TextAlign.end,
|
||||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||||
color: Theme.of(context)
|
color: Theme.of(context).colorScheme.onSurface.withAlpha((255 * 0.75).round()),
|
||||||
.colorScheme
|
|
||||||
.onSurface
|
|
||||||
.withAlpha((255 * 0.75).round()),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Material(
|
Material(
|
||||||
|
@ -443,7 +443,7 @@ class _ChannelProfileDetailDialogState
|
|||||||
|
|
||||||
class _ChannelMemberListWidget extends StatefulWidget {
|
class _ChannelMemberListWidget extends StatefulWidget {
|
||||||
final SnChannel channel;
|
final SnChannel channel;
|
||||||
const _ChannelMemberListWidget({super.key, required this.channel});
|
const _ChannelMemberListWidget({required this.channel});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<_ChannelMemberListWidget> createState() =>
|
State<_ChannelMemberListWidget> createState() =>
|
||||||
@ -580,7 +580,7 @@ class _ChannelMemberListWidgetState extends State<_ChannelMemberListWidget> {
|
|||||||
|
|
||||||
class _NewChannelMemberWidget extends StatefulWidget {
|
class _NewChannelMemberWidget extends StatefulWidget {
|
||||||
final SnChannel channel;
|
final SnChannel channel;
|
||||||
const _NewChannelMemberWidget({super.key, required this.channel});
|
const _NewChannelMemberWidget({required this.channel});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<_NewChannelMemberWidget> createState() =>
|
State<_NewChannelMemberWidget> createState() =>
|
||||||
|
@ -97,7 +97,6 @@ class _ChatRoomScreenState extends State<ChatRoomScreen> {
|
|||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
print((err as DioException).response?.data);
|
|
||||||
context.showErrorDialog(err);
|
context.showErrorDialog(err);
|
||||||
} finally {
|
} finally {
|
||||||
setState(() => _isCalling = false);
|
setState(() => _isCalling = false);
|
||||||
|
@ -289,7 +289,7 @@ class _FriendScreenState extends State<FriendScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _NewFriendWidget extends StatefulWidget {
|
class _NewFriendWidget extends StatefulWidget {
|
||||||
const _NewFriendWidget({super.key});
|
const _NewFriendWidget();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<_NewFriendWidget> createState() => _NewFriendWidgetState();
|
State<_NewFriendWidget> createState() => _NewFriendWidgetState();
|
||||||
@ -365,7 +365,7 @@ class _NewFriendWidgetState extends State<_NewFriendWidget> {
|
|||||||
|
|
||||||
class _FriendshipListWidget extends StatefulWidget {
|
class _FriendshipListWidget extends StatefulWidget {
|
||||||
final List<SnRelationship> relations;
|
final List<SnRelationship> relations;
|
||||||
const _FriendshipListWidget({super.key, required this.relations});
|
const _FriendshipListWidget({required this.relations});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<_FriendshipListWidget> createState() => _FriendshipListWidgetState();
|
State<_FriendshipListWidget> createState() => _FriendshipListWidgetState();
|
||||||
|
@ -12,6 +12,7 @@ import 'package:google_fonts/google_fonts.dart';
|
|||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:relative_time/relative_time.dart';
|
import 'package:relative_time/relative_time.dart';
|
||||||
|
import 'package:slide_countdown/slide_countdown.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:surface/providers/config.dart';
|
import 'package:surface/providers/config.dart';
|
||||||
@ -109,7 +110,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
class _HomeDashUpdateWidget extends StatelessWidget {
|
class _HomeDashUpdateWidget extends StatelessWidget {
|
||||||
final EdgeInsets? padding;
|
final EdgeInsets? padding;
|
||||||
|
|
||||||
const _HomeDashUpdateWidget({super.key, this.padding});
|
const _HomeDashUpdateWidget({this.padding});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -153,7 +154,7 @@ class _HomeDashUpdateWidget extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _HomeDashSpecialDayWidget extends StatelessWidget {
|
class _HomeDashSpecialDayWidget extends StatelessWidget {
|
||||||
const _HomeDashSpecialDayWidget({super.key});
|
const _HomeDashSpecialDayWidget();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -188,7 +189,7 @@ class _HomeDashSpecialDayWidget extends StatelessWidget {
|
|||||||
var (name, date) = nextOne;
|
var (name, date) = nextOne;
|
||||||
date = date.add(Duration(days: 1));
|
date = date.add(Duration(days: 1));
|
||||||
final progress = dayz.getSpecialDayProgress(lastOne.$2, date);
|
final progress = dayz.getSpecialDayProgress(lastOne.$2, date);
|
||||||
final diff = nextOne.$2.add(-const Duration(days: 1)).difference(lastOne.$2);
|
final diff = nextOne.$2.difference(DateTime.now());
|
||||||
return Card(
|
return Card(
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
leading: Text(kSpecialDaysSymbol[name] ?? '🎉').fontSize(24),
|
leading: Text(kSpecialDaysSymbol[name] ?? '🎉').fontSize(24),
|
||||||
@ -196,8 +197,15 @@ class _HomeDashSpecialDayWidget extends StatelessWidget {
|
|||||||
subtitle: Row(
|
subtitle: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text('${diff.inDays}d · ${(progress * 100).toStringAsFixed(2)}%'),
|
SlideCountdown(
|
||||||
const Gap(8),
|
duration: diff,
|
||||||
|
style: GoogleFonts.robotoMono(fontSize: 13),
|
||||||
|
separatorStyle: GoogleFonts.robotoMono(fontSize: 13),
|
||||||
|
separatorType: SeparatorType.symbol,
|
||||||
|
decoration: BoxDecoration(),
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
),
|
||||||
|
const Gap(12),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: LinearProgressIndicator(
|
child: LinearProgressIndicator(
|
||||||
value: progress,
|
value: progress,
|
||||||
@ -215,7 +223,7 @@ class _HomeDashSpecialDayWidget extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _HomeDashCheckInWidget extends StatefulWidget {
|
class _HomeDashCheckInWidget extends StatefulWidget {
|
||||||
const _HomeDashCheckInWidget({super.key});
|
const _HomeDashCheckInWidget();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<_HomeDashCheckInWidget> createState() => _HomeDashCheckInWidgetState();
|
State<_HomeDashCheckInWidget> createState() => _HomeDashCheckInWidgetState();
|
||||||
@ -433,7 +441,7 @@ class _HomeDashCheckInWidgetState extends State<_HomeDashCheckInWidget> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _HomeDashNotificationWidget extends StatefulWidget {
|
class _HomeDashNotificationWidget extends StatefulWidget {
|
||||||
const _HomeDashNotificationWidget({super.key});
|
const _HomeDashNotificationWidget();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<_HomeDashNotificationWidget> createState() => _HomeDashNotificationWidgetState();
|
State<_HomeDashNotificationWidget> createState() => _HomeDashNotificationWidgetState();
|
||||||
@ -504,7 +512,7 @@ class _HomeDashNotificationWidgetState extends State<_HomeDashNotificationWidget
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _HomeDashRecommendationPostWidget extends StatefulWidget {
|
class _HomeDashRecommendationPostWidget extends StatefulWidget {
|
||||||
const _HomeDashRecommendationPostWidget({super.key});
|
const _HomeDashRecommendationPostWidget();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<_HomeDashRecommendationPostWidget> createState() => _HomeDashRecommendationPostWidgetState();
|
State<_HomeDashRecommendationPostWidget> createState() => _HomeDashRecommendationPostWidgetState();
|
||||||
|
@ -1,16 +1,11 @@
|
|||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:dropdown_button2/dropdown_button2.dart';
|
import 'package:dropdown_button2/dropdown_button2.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:pasteboard/pasteboard.dart';
|
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
import 'package:surface/controllers/post_write_controller.dart';
|
import 'package:surface/controllers/post_write_controller.dart';
|
||||||
import 'package:surface/providers/config.dart';
|
import 'package:surface/providers/config.dart';
|
||||||
|
@ -580,7 +580,6 @@ class _PublisherPostList extends StatelessWidget {
|
|||||||
final void Function() onDeleted;
|
final void Function() onDeleted;
|
||||||
|
|
||||||
const _PublisherPostList({
|
const _PublisherPostList({
|
||||||
super.key,
|
|
||||||
required this.isBusy,
|
required this.isBusy,
|
||||||
required this.postCount,
|
required this.postCount,
|
||||||
required this.posts,
|
required this.posts,
|
||||||
|
@ -119,7 +119,7 @@ class _RealmDetailHomeWidget extends StatelessWidget {
|
|||||||
final SnRealm? realm;
|
final SnRealm? realm;
|
||||||
final List<SnPublisher>? publishers;
|
final List<SnPublisher>? publishers;
|
||||||
|
|
||||||
const _RealmDetailHomeWidget({super.key, required this.realm, this.publishers});
|
const _RealmDetailHomeWidget({required this.realm, this.publishers});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -175,7 +175,7 @@ class _RealmDetailHomeWidget extends StatelessWidget {
|
|||||||
class _RealmMemberListWidget extends StatefulWidget {
|
class _RealmMemberListWidget extends StatefulWidget {
|
||||||
final SnRealm? realm;
|
final SnRealm? realm;
|
||||||
|
|
||||||
const _RealmMemberListWidget({super.key, this.realm});
|
const _RealmMemberListWidget({this.realm});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<_RealmMemberListWidget> createState() => _RealmMemberListWidgetState();
|
State<_RealmMemberListWidget> createState() => _RealmMemberListWidgetState();
|
||||||
@ -304,7 +304,7 @@ class _RealmMemberListWidgetState extends State<_RealmMemberListWidget> {
|
|||||||
class _NewRealmMemberWidget extends StatefulWidget {
|
class _NewRealmMemberWidget extends StatefulWidget {
|
||||||
final SnRealm realm;
|
final SnRealm realm;
|
||||||
|
|
||||||
const _NewRealmMemberWidget({super.key, required this.realm});
|
const _NewRealmMemberWidget({required this.realm});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<_NewRealmMemberWidget> createState() => _NewRealmMemberWidgetState();
|
State<_NewRealmMemberWidget> createState() => _NewRealmMemberWidgetState();
|
||||||
@ -384,7 +384,7 @@ class _RealmSettingsWidget extends StatefulWidget {
|
|||||||
final SnRealm? realm;
|
final SnRealm? realm;
|
||||||
final Function() onUpdate;
|
final Function() onUpdate;
|
||||||
|
|
||||||
const _RealmSettingsWidget({super.key, required this.realm, required this.onUpdate});
|
const _RealmSettingsWidget({required this.realm, required this.onUpdate});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<_RealmSettingsWidget> createState() => _RealmSettingsWidgetState();
|
State<_RealmSettingsWidget> createState() => _RealmSettingsWidgetState();
|
||||||
|
@ -33,7 +33,6 @@ Future<ThemeData> createAppTheme(
|
|||||||
brightness: brightness,
|
brightness: brightness,
|
||||||
);
|
);
|
||||||
|
|
||||||
final hasBackground = prefs.getBool(kAppBackgroundStoreKey) ?? false;
|
|
||||||
final hasAppBarBlurry = prefs.getBool(kAppbarTransparentStoreKey) ?? false;
|
final hasAppBarBlurry = prefs.getBool(kAppbarTransparentStoreKey) ?? false;
|
||||||
|
|
||||||
return ThemeData(
|
return ThemeData(
|
||||||
|
@ -1,10 +1,20 @@
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
part 'attachment.freezed.dart';
|
part 'attachment.freezed.dart';
|
||||||
|
|
||||||
part 'attachment.g.dart';
|
part 'attachment.g.dart';
|
||||||
|
|
||||||
|
enum SnMediaType {
|
||||||
|
image,
|
||||||
|
video,
|
||||||
|
audio,
|
||||||
|
file,
|
||||||
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class SnAttachment with _$SnAttachment {
|
class SnAttachment with _$SnAttachment {
|
||||||
|
const SnAttachment._();
|
||||||
|
|
||||||
const factory SnAttachment({
|
const factory SnAttachment({
|
||||||
required int id,
|
required int id,
|
||||||
required DateTime createdAt,
|
required DateTime createdAt,
|
||||||
@ -19,9 +29,10 @@ class SnAttachment with _$SnAttachment {
|
|||||||
required String hash,
|
required String hash,
|
||||||
required int destination,
|
required int destination,
|
||||||
required int refCount,
|
required int refCount,
|
||||||
|
@Default(0) int contentRating,
|
||||||
|
@Default(0) int qualityRating,
|
||||||
required dynamic fileChunks,
|
required dynamic fileChunks,
|
||||||
required dynamic cleanedAt,
|
required dynamic cleanedAt,
|
||||||
required bool isMature,
|
|
||||||
required bool isAnalyzed,
|
required bool isAnalyzed,
|
||||||
required bool isUploaded,
|
required bool isUploaded,
|
||||||
required bool isSelfRef,
|
required bool isSelfRef,
|
||||||
@ -30,11 +41,24 @@ class SnAttachment with _$SnAttachment {
|
|||||||
required SnAttachmentPool? pool,
|
required SnAttachmentPool? pool,
|
||||||
required int poolId,
|
required int poolId,
|
||||||
required int accountId,
|
required int accountId,
|
||||||
|
@Default({}) Map<String, dynamic> usermeta,
|
||||||
@Default({}) Map<String, dynamic> metadata,
|
@Default({}) Map<String, dynamic> metadata,
|
||||||
|
String? thumbnail,
|
||||||
}) = _SnAttachment;
|
}) = _SnAttachment;
|
||||||
|
|
||||||
factory SnAttachment.fromJson(Map<String, Object?> json) =>
|
factory SnAttachment.fromJson(Map<String, Object?> json) => _$SnAttachmentFromJson(json);
|
||||||
_$SnAttachmentFromJson(json);
|
|
||||||
|
Map<String, dynamic> get data => {
|
||||||
|
...metadata,
|
||||||
|
...usermeta,
|
||||||
|
};
|
||||||
|
|
||||||
|
SnMediaType get mediaType => switch (mimetype.split('/').firstOrNull) {
|
||||||
|
'image' => SnMediaType.image,
|
||||||
|
'video' => SnMediaType.video,
|
||||||
|
'audio' => SnMediaType.audio,
|
||||||
|
_ => SnMediaType.file,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
@ -51,6 +75,5 @@ class SnAttachmentPool with _$SnAttachmentPool {
|
|||||||
required int? accountId,
|
required int? accountId,
|
||||||
}) = _SnAttachmentPool;
|
}) = _SnAttachmentPool;
|
||||||
|
|
||||||
factory SnAttachmentPool.fromJson(Map<String, Object?> json) =>
|
factory SnAttachmentPool.fromJson(Map<String, Object?> json) => _$SnAttachmentPoolFromJson(json);
|
||||||
_$SnAttachmentPoolFromJson(json);
|
|
||||||
}
|
}
|
||||||
|
@ -33,9 +33,10 @@ mixin _$SnAttachment {
|
|||||||
String get hash => throw _privateConstructorUsedError;
|
String get hash => throw _privateConstructorUsedError;
|
||||||
int get destination => throw _privateConstructorUsedError;
|
int get destination => throw _privateConstructorUsedError;
|
||||||
int get refCount => throw _privateConstructorUsedError;
|
int get refCount => throw _privateConstructorUsedError;
|
||||||
|
int get contentRating => throw _privateConstructorUsedError;
|
||||||
|
int get qualityRating => throw _privateConstructorUsedError;
|
||||||
dynamic get fileChunks => throw _privateConstructorUsedError;
|
dynamic get fileChunks => throw _privateConstructorUsedError;
|
||||||
dynamic get cleanedAt => throw _privateConstructorUsedError;
|
dynamic get cleanedAt => throw _privateConstructorUsedError;
|
||||||
bool get isMature => throw _privateConstructorUsedError;
|
|
||||||
bool get isAnalyzed => throw _privateConstructorUsedError;
|
bool get isAnalyzed => throw _privateConstructorUsedError;
|
||||||
bool get isUploaded => throw _privateConstructorUsedError;
|
bool get isUploaded => throw _privateConstructorUsedError;
|
||||||
bool get isSelfRef => throw _privateConstructorUsedError;
|
bool get isSelfRef => throw _privateConstructorUsedError;
|
||||||
@ -44,7 +45,9 @@ mixin _$SnAttachment {
|
|||||||
SnAttachmentPool? get pool => throw _privateConstructorUsedError;
|
SnAttachmentPool? get pool => throw _privateConstructorUsedError;
|
||||||
int get poolId => throw _privateConstructorUsedError;
|
int get poolId => throw _privateConstructorUsedError;
|
||||||
int get accountId => throw _privateConstructorUsedError;
|
int get accountId => throw _privateConstructorUsedError;
|
||||||
|
Map<String, dynamic> get usermeta => throw _privateConstructorUsedError;
|
||||||
Map<String, dynamic> get metadata => throw _privateConstructorUsedError;
|
Map<String, dynamic> get metadata => throw _privateConstructorUsedError;
|
||||||
|
String? get thumbnail => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
/// Serializes this SnAttachment to a JSON map.
|
/// Serializes this SnAttachment to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@ -76,9 +79,10 @@ abstract class $SnAttachmentCopyWith<$Res> {
|
|||||||
String hash,
|
String hash,
|
||||||
int destination,
|
int destination,
|
||||||
int refCount,
|
int refCount,
|
||||||
|
int contentRating,
|
||||||
|
int qualityRating,
|
||||||
dynamic fileChunks,
|
dynamic fileChunks,
|
||||||
dynamic cleanedAt,
|
dynamic cleanedAt,
|
||||||
bool isMature,
|
|
||||||
bool isAnalyzed,
|
bool isAnalyzed,
|
||||||
bool isUploaded,
|
bool isUploaded,
|
||||||
bool isSelfRef,
|
bool isSelfRef,
|
||||||
@ -87,7 +91,9 @@ abstract class $SnAttachmentCopyWith<$Res> {
|
|||||||
SnAttachmentPool? pool,
|
SnAttachmentPool? pool,
|
||||||
int poolId,
|
int poolId,
|
||||||
int accountId,
|
int accountId,
|
||||||
Map<String, dynamic> metadata});
|
Map<String, dynamic> usermeta,
|
||||||
|
Map<String, dynamic> metadata,
|
||||||
|
String? thumbnail});
|
||||||
|
|
||||||
$SnAttachmentPoolCopyWith<$Res>? get pool;
|
$SnAttachmentPoolCopyWith<$Res>? get pool;
|
||||||
}
|
}
|
||||||
@ -120,9 +126,10 @@ class _$SnAttachmentCopyWithImpl<$Res, $Val extends SnAttachment>
|
|||||||
Object? hash = null,
|
Object? hash = null,
|
||||||
Object? destination = null,
|
Object? destination = null,
|
||||||
Object? refCount = null,
|
Object? refCount = null,
|
||||||
|
Object? contentRating = null,
|
||||||
|
Object? qualityRating = null,
|
||||||
Object? fileChunks = freezed,
|
Object? fileChunks = freezed,
|
||||||
Object? cleanedAt = freezed,
|
Object? cleanedAt = freezed,
|
||||||
Object? isMature = null,
|
|
||||||
Object? isAnalyzed = null,
|
Object? isAnalyzed = null,
|
||||||
Object? isUploaded = null,
|
Object? isUploaded = null,
|
||||||
Object? isSelfRef = null,
|
Object? isSelfRef = null,
|
||||||
@ -131,7 +138,9 @@ class _$SnAttachmentCopyWithImpl<$Res, $Val extends SnAttachment>
|
|||||||
Object? pool = freezed,
|
Object? pool = freezed,
|
||||||
Object? poolId = null,
|
Object? poolId = null,
|
||||||
Object? accountId = null,
|
Object? accountId = null,
|
||||||
|
Object? usermeta = null,
|
||||||
Object? metadata = null,
|
Object? metadata = null,
|
||||||
|
Object? thumbnail = freezed,
|
||||||
}) {
|
}) {
|
||||||
return _then(_value.copyWith(
|
return _then(_value.copyWith(
|
||||||
id: null == id
|
id: null == id
|
||||||
@ -186,6 +195,14 @@ class _$SnAttachmentCopyWithImpl<$Res, $Val extends SnAttachment>
|
|||||||
? _value.refCount
|
? _value.refCount
|
||||||
: refCount // ignore: cast_nullable_to_non_nullable
|
: refCount // ignore: cast_nullable_to_non_nullable
|
||||||
as int,
|
as int,
|
||||||
|
contentRating: null == contentRating
|
||||||
|
? _value.contentRating
|
||||||
|
: contentRating // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
qualityRating: null == qualityRating
|
||||||
|
? _value.qualityRating
|
||||||
|
: qualityRating // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
fileChunks: freezed == fileChunks
|
fileChunks: freezed == fileChunks
|
||||||
? _value.fileChunks
|
? _value.fileChunks
|
||||||
: fileChunks // ignore: cast_nullable_to_non_nullable
|
: fileChunks // ignore: cast_nullable_to_non_nullable
|
||||||
@ -194,10 +211,6 @@ class _$SnAttachmentCopyWithImpl<$Res, $Val extends SnAttachment>
|
|||||||
? _value.cleanedAt
|
? _value.cleanedAt
|
||||||
: cleanedAt // ignore: cast_nullable_to_non_nullable
|
: cleanedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as dynamic,
|
as dynamic,
|
||||||
isMature: null == isMature
|
|
||||||
? _value.isMature
|
|
||||||
: isMature // ignore: cast_nullable_to_non_nullable
|
|
||||||
as bool,
|
|
||||||
isAnalyzed: null == isAnalyzed
|
isAnalyzed: null == isAnalyzed
|
||||||
? _value.isAnalyzed
|
? _value.isAnalyzed
|
||||||
: isAnalyzed // ignore: cast_nullable_to_non_nullable
|
: isAnalyzed // ignore: cast_nullable_to_non_nullable
|
||||||
@ -230,10 +243,18 @@ class _$SnAttachmentCopyWithImpl<$Res, $Val extends SnAttachment>
|
|||||||
? _value.accountId
|
? _value.accountId
|
||||||
: accountId // ignore: cast_nullable_to_non_nullable
|
: accountId // ignore: cast_nullable_to_non_nullable
|
||||||
as int,
|
as int,
|
||||||
|
usermeta: null == usermeta
|
||||||
|
? _value.usermeta
|
||||||
|
: usermeta // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Map<String, dynamic>,
|
||||||
metadata: null == metadata
|
metadata: null == metadata
|
||||||
? _value.metadata
|
? _value.metadata
|
||||||
: metadata // ignore: cast_nullable_to_non_nullable
|
: metadata // ignore: cast_nullable_to_non_nullable
|
||||||
as Map<String, dynamic>,
|
as Map<String, dynamic>,
|
||||||
|
thumbnail: freezed == thumbnail
|
||||||
|
? _value.thumbnail
|
||||||
|
: thumbnail // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,
|
||||||
) as $Val);
|
) as $Val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,9 +295,10 @@ abstract class _$$SnAttachmentImplCopyWith<$Res>
|
|||||||
String hash,
|
String hash,
|
||||||
int destination,
|
int destination,
|
||||||
int refCount,
|
int refCount,
|
||||||
|
int contentRating,
|
||||||
|
int qualityRating,
|
||||||
dynamic fileChunks,
|
dynamic fileChunks,
|
||||||
dynamic cleanedAt,
|
dynamic cleanedAt,
|
||||||
bool isMature,
|
|
||||||
bool isAnalyzed,
|
bool isAnalyzed,
|
||||||
bool isUploaded,
|
bool isUploaded,
|
||||||
bool isSelfRef,
|
bool isSelfRef,
|
||||||
@ -285,7 +307,9 @@ abstract class _$$SnAttachmentImplCopyWith<$Res>
|
|||||||
SnAttachmentPool? pool,
|
SnAttachmentPool? pool,
|
||||||
int poolId,
|
int poolId,
|
||||||
int accountId,
|
int accountId,
|
||||||
Map<String, dynamic> metadata});
|
Map<String, dynamic> usermeta,
|
||||||
|
Map<String, dynamic> metadata,
|
||||||
|
String? thumbnail});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
$SnAttachmentPoolCopyWith<$Res>? get pool;
|
$SnAttachmentPoolCopyWith<$Res>? get pool;
|
||||||
@ -317,9 +341,10 @@ class __$$SnAttachmentImplCopyWithImpl<$Res>
|
|||||||
Object? hash = null,
|
Object? hash = null,
|
||||||
Object? destination = null,
|
Object? destination = null,
|
||||||
Object? refCount = null,
|
Object? refCount = null,
|
||||||
|
Object? contentRating = null,
|
||||||
|
Object? qualityRating = null,
|
||||||
Object? fileChunks = freezed,
|
Object? fileChunks = freezed,
|
||||||
Object? cleanedAt = freezed,
|
Object? cleanedAt = freezed,
|
||||||
Object? isMature = null,
|
|
||||||
Object? isAnalyzed = null,
|
Object? isAnalyzed = null,
|
||||||
Object? isUploaded = null,
|
Object? isUploaded = null,
|
||||||
Object? isSelfRef = null,
|
Object? isSelfRef = null,
|
||||||
@ -328,7 +353,9 @@ class __$$SnAttachmentImplCopyWithImpl<$Res>
|
|||||||
Object? pool = freezed,
|
Object? pool = freezed,
|
||||||
Object? poolId = null,
|
Object? poolId = null,
|
||||||
Object? accountId = null,
|
Object? accountId = null,
|
||||||
|
Object? usermeta = null,
|
||||||
Object? metadata = null,
|
Object? metadata = null,
|
||||||
|
Object? thumbnail = freezed,
|
||||||
}) {
|
}) {
|
||||||
return _then(_$SnAttachmentImpl(
|
return _then(_$SnAttachmentImpl(
|
||||||
id: null == id
|
id: null == id
|
||||||
@ -383,6 +410,14 @@ class __$$SnAttachmentImplCopyWithImpl<$Res>
|
|||||||
? _value.refCount
|
? _value.refCount
|
||||||
: refCount // ignore: cast_nullable_to_non_nullable
|
: refCount // ignore: cast_nullable_to_non_nullable
|
||||||
as int,
|
as int,
|
||||||
|
contentRating: null == contentRating
|
||||||
|
? _value.contentRating
|
||||||
|
: contentRating // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
qualityRating: null == qualityRating
|
||||||
|
? _value.qualityRating
|
||||||
|
: qualityRating // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
fileChunks: freezed == fileChunks
|
fileChunks: freezed == fileChunks
|
||||||
? _value.fileChunks
|
? _value.fileChunks
|
||||||
: fileChunks // ignore: cast_nullable_to_non_nullable
|
: fileChunks // ignore: cast_nullable_to_non_nullable
|
||||||
@ -391,10 +426,6 @@ class __$$SnAttachmentImplCopyWithImpl<$Res>
|
|||||||
? _value.cleanedAt
|
? _value.cleanedAt
|
||||||
: cleanedAt // ignore: cast_nullable_to_non_nullable
|
: cleanedAt // ignore: cast_nullable_to_non_nullable
|
||||||
as dynamic,
|
as dynamic,
|
||||||
isMature: null == isMature
|
|
||||||
? _value.isMature
|
|
||||||
: isMature // ignore: cast_nullable_to_non_nullable
|
|
||||||
as bool,
|
|
||||||
isAnalyzed: null == isAnalyzed
|
isAnalyzed: null == isAnalyzed
|
||||||
? _value.isAnalyzed
|
? _value.isAnalyzed
|
||||||
: isAnalyzed // ignore: cast_nullable_to_non_nullable
|
: isAnalyzed // ignore: cast_nullable_to_non_nullable
|
||||||
@ -427,17 +458,25 @@ class __$$SnAttachmentImplCopyWithImpl<$Res>
|
|||||||
? _value.accountId
|
? _value.accountId
|
||||||
: accountId // ignore: cast_nullable_to_non_nullable
|
: accountId // ignore: cast_nullable_to_non_nullable
|
||||||
as int,
|
as int,
|
||||||
|
usermeta: null == usermeta
|
||||||
|
? _value._usermeta
|
||||||
|
: usermeta // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Map<String, dynamic>,
|
||||||
metadata: null == metadata
|
metadata: null == metadata
|
||||||
? _value._metadata
|
? _value._metadata
|
||||||
: metadata // ignore: cast_nullable_to_non_nullable
|
: metadata // ignore: cast_nullable_to_non_nullable
|
||||||
as Map<String, dynamic>,
|
as Map<String, dynamic>,
|
||||||
|
thumbnail: freezed == thumbnail
|
||||||
|
? _value.thumbnail
|
||||||
|
: thumbnail // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class _$SnAttachmentImpl implements _SnAttachment {
|
class _$SnAttachmentImpl extends _SnAttachment {
|
||||||
const _$SnAttachmentImpl(
|
const _$SnAttachmentImpl(
|
||||||
{required this.id,
|
{required this.id,
|
||||||
required this.createdAt,
|
required this.createdAt,
|
||||||
@ -452,9 +491,10 @@ class _$SnAttachmentImpl implements _SnAttachment {
|
|||||||
required this.hash,
|
required this.hash,
|
||||||
required this.destination,
|
required this.destination,
|
||||||
required this.refCount,
|
required this.refCount,
|
||||||
|
this.contentRating = 0,
|
||||||
|
this.qualityRating = 0,
|
||||||
required this.fileChunks,
|
required this.fileChunks,
|
||||||
required this.cleanedAt,
|
required this.cleanedAt,
|
||||||
required this.isMature,
|
|
||||||
required this.isAnalyzed,
|
required this.isAnalyzed,
|
||||||
required this.isUploaded,
|
required this.isUploaded,
|
||||||
required this.isSelfRef,
|
required this.isSelfRef,
|
||||||
@ -463,8 +503,12 @@ class _$SnAttachmentImpl implements _SnAttachment {
|
|||||||
required this.pool,
|
required this.pool,
|
||||||
required this.poolId,
|
required this.poolId,
|
||||||
required this.accountId,
|
required this.accountId,
|
||||||
final Map<String, dynamic> metadata = const {}})
|
final Map<String, dynamic> usermeta = const {},
|
||||||
: _metadata = metadata;
|
final Map<String, dynamic> metadata = const {},
|
||||||
|
this.thumbnail})
|
||||||
|
: _usermeta = usermeta,
|
||||||
|
_metadata = metadata,
|
||||||
|
super._();
|
||||||
|
|
||||||
factory _$SnAttachmentImpl.fromJson(Map<String, dynamic> json) =>
|
factory _$SnAttachmentImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
_$$SnAttachmentImplFromJson(json);
|
_$$SnAttachmentImplFromJson(json);
|
||||||
@ -496,12 +540,16 @@ class _$SnAttachmentImpl implements _SnAttachment {
|
|||||||
@override
|
@override
|
||||||
final int refCount;
|
final int refCount;
|
||||||
@override
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final int contentRating;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final int qualityRating;
|
||||||
|
@override
|
||||||
final dynamic fileChunks;
|
final dynamic fileChunks;
|
||||||
@override
|
@override
|
||||||
final dynamic cleanedAt;
|
final dynamic cleanedAt;
|
||||||
@override
|
@override
|
||||||
final bool isMature;
|
|
||||||
@override
|
|
||||||
final bool isAnalyzed;
|
final bool isAnalyzed;
|
||||||
@override
|
@override
|
||||||
final bool isUploaded;
|
final bool isUploaded;
|
||||||
@ -517,6 +565,15 @@ class _$SnAttachmentImpl implements _SnAttachment {
|
|||||||
final int poolId;
|
final int poolId;
|
||||||
@override
|
@override
|
||||||
final int accountId;
|
final int accountId;
|
||||||
|
final Map<String, dynamic> _usermeta;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
Map<String, dynamic> get usermeta {
|
||||||
|
if (_usermeta is EqualUnmodifiableMapView) return _usermeta;
|
||||||
|
// ignore: implicit_dynamic_type
|
||||||
|
return EqualUnmodifiableMapView(_usermeta);
|
||||||
|
}
|
||||||
|
|
||||||
final Map<String, dynamic> _metadata;
|
final Map<String, dynamic> _metadata;
|
||||||
@override
|
@override
|
||||||
@JsonKey()
|
@JsonKey()
|
||||||
@ -526,9 +583,12 @@ class _$SnAttachmentImpl implements _SnAttachment {
|
|||||||
return EqualUnmodifiableMapView(_metadata);
|
return EqualUnmodifiableMapView(_metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
final String? thumbnail;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnAttachment(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, rid: $rid, uuid: $uuid, size: $size, name: $name, alt: $alt, mimetype: $mimetype, hash: $hash, destination: $destination, refCount: $refCount, fileChunks: $fileChunks, cleanedAt: $cleanedAt, isMature: $isMature, isAnalyzed: $isAnalyzed, isUploaded: $isUploaded, isSelfRef: $isSelfRef, ref: $ref, refId: $refId, pool: $pool, poolId: $poolId, accountId: $accountId, metadata: $metadata)';
|
return 'SnAttachment(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, rid: $rid, uuid: $uuid, size: $size, name: $name, alt: $alt, mimetype: $mimetype, hash: $hash, destination: $destination, refCount: $refCount, contentRating: $contentRating, qualityRating: $qualityRating, fileChunks: $fileChunks, cleanedAt: $cleanedAt, isAnalyzed: $isAnalyzed, isUploaded: $isUploaded, isSelfRef: $isSelfRef, ref: $ref, refId: $refId, pool: $pool, poolId: $poolId, accountId: $accountId, usermeta: $usermeta, metadata: $metadata, thumbnail: $thumbnail)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -554,11 +614,13 @@ class _$SnAttachmentImpl implements _SnAttachment {
|
|||||||
other.destination == destination) &&
|
other.destination == destination) &&
|
||||||
(identical(other.refCount, refCount) ||
|
(identical(other.refCount, refCount) ||
|
||||||
other.refCount == refCount) &&
|
other.refCount == refCount) &&
|
||||||
|
(identical(other.contentRating, contentRating) ||
|
||||||
|
other.contentRating == contentRating) &&
|
||||||
|
(identical(other.qualityRating, qualityRating) ||
|
||||||
|
other.qualityRating == qualityRating) &&
|
||||||
const DeepCollectionEquality()
|
const DeepCollectionEquality()
|
||||||
.equals(other.fileChunks, fileChunks) &&
|
.equals(other.fileChunks, fileChunks) &&
|
||||||
const DeepCollectionEquality().equals(other.cleanedAt, cleanedAt) &&
|
const DeepCollectionEquality().equals(other.cleanedAt, cleanedAt) &&
|
||||||
(identical(other.isMature, isMature) ||
|
|
||||||
other.isMature == isMature) &&
|
|
||||||
(identical(other.isAnalyzed, isAnalyzed) ||
|
(identical(other.isAnalyzed, isAnalyzed) ||
|
||||||
other.isAnalyzed == isAnalyzed) &&
|
other.isAnalyzed == isAnalyzed) &&
|
||||||
(identical(other.isUploaded, isUploaded) ||
|
(identical(other.isUploaded, isUploaded) ||
|
||||||
@ -571,7 +633,10 @@ class _$SnAttachmentImpl implements _SnAttachment {
|
|||||||
(identical(other.poolId, poolId) || other.poolId == poolId) &&
|
(identical(other.poolId, poolId) || other.poolId == poolId) &&
|
||||||
(identical(other.accountId, accountId) ||
|
(identical(other.accountId, accountId) ||
|
||||||
other.accountId == accountId) &&
|
other.accountId == accountId) &&
|
||||||
const DeepCollectionEquality().equals(other._metadata, _metadata));
|
const DeepCollectionEquality().equals(other._usermeta, _usermeta) &&
|
||||||
|
const DeepCollectionEquality().equals(other._metadata, _metadata) &&
|
||||||
|
(identical(other.thumbnail, thumbnail) ||
|
||||||
|
other.thumbnail == thumbnail));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@ -591,9 +656,10 @@ class _$SnAttachmentImpl implements _SnAttachment {
|
|||||||
hash,
|
hash,
|
||||||
destination,
|
destination,
|
||||||
refCount,
|
refCount,
|
||||||
|
contentRating,
|
||||||
|
qualityRating,
|
||||||
const DeepCollectionEquality().hash(fileChunks),
|
const DeepCollectionEquality().hash(fileChunks),
|
||||||
const DeepCollectionEquality().hash(cleanedAt),
|
const DeepCollectionEquality().hash(cleanedAt),
|
||||||
isMature,
|
|
||||||
isAnalyzed,
|
isAnalyzed,
|
||||||
isUploaded,
|
isUploaded,
|
||||||
isSelfRef,
|
isSelfRef,
|
||||||
@ -602,7 +668,9 @@ class _$SnAttachmentImpl implements _SnAttachment {
|
|||||||
pool,
|
pool,
|
||||||
poolId,
|
poolId,
|
||||||
accountId,
|
accountId,
|
||||||
const DeepCollectionEquality().hash(_metadata)
|
const DeepCollectionEquality().hash(_usermeta),
|
||||||
|
const DeepCollectionEquality().hash(_metadata),
|
||||||
|
thumbnail
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/// Create a copy of SnAttachment
|
/// Create a copy of SnAttachment
|
||||||
@ -621,7 +689,7 @@ class _$SnAttachmentImpl implements _SnAttachment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class _SnAttachment implements SnAttachment {
|
abstract class _SnAttachment extends SnAttachment {
|
||||||
const factory _SnAttachment(
|
const factory _SnAttachment(
|
||||||
{required final int id,
|
{required final int id,
|
||||||
required final DateTime createdAt,
|
required final DateTime createdAt,
|
||||||
@ -636,9 +704,10 @@ abstract class _SnAttachment implements SnAttachment {
|
|||||||
required final String hash,
|
required final String hash,
|
||||||
required final int destination,
|
required final int destination,
|
||||||
required final int refCount,
|
required final int refCount,
|
||||||
|
final int contentRating,
|
||||||
|
final int qualityRating,
|
||||||
required final dynamic fileChunks,
|
required final dynamic fileChunks,
|
||||||
required final dynamic cleanedAt,
|
required final dynamic cleanedAt,
|
||||||
required final bool isMature,
|
|
||||||
required final bool isAnalyzed,
|
required final bool isAnalyzed,
|
||||||
required final bool isUploaded,
|
required final bool isUploaded,
|
||||||
required final bool isSelfRef,
|
required final bool isSelfRef,
|
||||||
@ -647,7 +716,10 @@ abstract class _SnAttachment implements SnAttachment {
|
|||||||
required final SnAttachmentPool? pool,
|
required final SnAttachmentPool? pool,
|
||||||
required final int poolId,
|
required final int poolId,
|
||||||
required final int accountId,
|
required final int accountId,
|
||||||
final Map<String, dynamic> metadata}) = _$SnAttachmentImpl;
|
final Map<String, dynamic> usermeta,
|
||||||
|
final Map<String, dynamic> metadata,
|
||||||
|
final String? thumbnail}) = _$SnAttachmentImpl;
|
||||||
|
const _SnAttachment._() : super._();
|
||||||
|
|
||||||
factory _SnAttachment.fromJson(Map<String, dynamic> json) =
|
factory _SnAttachment.fromJson(Map<String, dynamic> json) =
|
||||||
_$SnAttachmentImpl.fromJson;
|
_$SnAttachmentImpl.fromJson;
|
||||||
@ -679,12 +751,14 @@ abstract class _SnAttachment implements SnAttachment {
|
|||||||
@override
|
@override
|
||||||
int get refCount;
|
int get refCount;
|
||||||
@override
|
@override
|
||||||
|
int get contentRating;
|
||||||
|
@override
|
||||||
|
int get qualityRating;
|
||||||
|
@override
|
||||||
dynamic get fileChunks;
|
dynamic get fileChunks;
|
||||||
@override
|
@override
|
||||||
dynamic get cleanedAt;
|
dynamic get cleanedAt;
|
||||||
@override
|
@override
|
||||||
bool get isMature;
|
|
||||||
@override
|
|
||||||
bool get isAnalyzed;
|
bool get isAnalyzed;
|
||||||
@override
|
@override
|
||||||
bool get isUploaded;
|
bool get isUploaded;
|
||||||
@ -701,7 +775,11 @@ abstract class _SnAttachment implements SnAttachment {
|
|||||||
@override
|
@override
|
||||||
int get accountId;
|
int get accountId;
|
||||||
@override
|
@override
|
||||||
|
Map<String, dynamic> get usermeta;
|
||||||
|
@override
|
||||||
Map<String, dynamic> get metadata;
|
Map<String, dynamic> get metadata;
|
||||||
|
@override
|
||||||
|
String? get thumbnail;
|
||||||
|
|
||||||
/// Create a copy of SnAttachment
|
/// Create a copy of SnAttachment
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@ -21,9 +21,10 @@ _$SnAttachmentImpl _$$SnAttachmentImplFromJson(Map<String, dynamic> json) =>
|
|||||||
hash: json['hash'] as String,
|
hash: json['hash'] as String,
|
||||||
destination: (json['destination'] as num).toInt(),
|
destination: (json['destination'] as num).toInt(),
|
||||||
refCount: (json['ref_count'] as num).toInt(),
|
refCount: (json['ref_count'] as num).toInt(),
|
||||||
|
contentRating: (json['content_rating'] as num?)?.toInt() ?? 0,
|
||||||
|
qualityRating: (json['quality_rating'] as num?)?.toInt() ?? 0,
|
||||||
fileChunks: json['file_chunks'],
|
fileChunks: json['file_chunks'],
|
||||||
cleanedAt: json['cleaned_at'],
|
cleanedAt: json['cleaned_at'],
|
||||||
isMature: json['is_mature'] as bool,
|
|
||||||
isAnalyzed: json['is_analyzed'] as bool,
|
isAnalyzed: json['is_analyzed'] as bool,
|
||||||
isUploaded: json['is_uploaded'] as bool,
|
isUploaded: json['is_uploaded'] as bool,
|
||||||
isSelfRef: json['is_self_ref'] as bool,
|
isSelfRef: json['is_self_ref'] as bool,
|
||||||
@ -34,7 +35,9 @@ _$SnAttachmentImpl _$$SnAttachmentImplFromJson(Map<String, dynamic> json) =>
|
|||||||
: SnAttachmentPool.fromJson(json['pool'] as Map<String, dynamic>),
|
: SnAttachmentPool.fromJson(json['pool'] as Map<String, dynamic>),
|
||||||
poolId: (json['pool_id'] as num).toInt(),
|
poolId: (json['pool_id'] as num).toInt(),
|
||||||
accountId: (json['account_id'] as num).toInt(),
|
accountId: (json['account_id'] as num).toInt(),
|
||||||
|
usermeta: json['usermeta'] as Map<String, dynamic>? ?? const {},
|
||||||
metadata: json['metadata'] as Map<String, dynamic>? ?? const {},
|
metadata: json['metadata'] as Map<String, dynamic>? ?? const {},
|
||||||
|
thumbnail: json['thumbnail'] as String?,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$$SnAttachmentImplToJson(_$SnAttachmentImpl instance) =>
|
Map<String, dynamic> _$$SnAttachmentImplToJson(_$SnAttachmentImpl instance) =>
|
||||||
@ -52,9 +55,10 @@ Map<String, dynamic> _$$SnAttachmentImplToJson(_$SnAttachmentImpl instance) =>
|
|||||||
'hash': instance.hash,
|
'hash': instance.hash,
|
||||||
'destination': instance.destination,
|
'destination': instance.destination,
|
||||||
'ref_count': instance.refCount,
|
'ref_count': instance.refCount,
|
||||||
|
'content_rating': instance.contentRating,
|
||||||
|
'quality_rating': instance.qualityRating,
|
||||||
'file_chunks': instance.fileChunks,
|
'file_chunks': instance.fileChunks,
|
||||||
'cleaned_at': instance.cleanedAt,
|
'cleaned_at': instance.cleanedAt,
|
||||||
'is_mature': instance.isMature,
|
|
||||||
'is_analyzed': instance.isAnalyzed,
|
'is_analyzed': instance.isAnalyzed,
|
||||||
'is_uploaded': instance.isUploaded,
|
'is_uploaded': instance.isUploaded,
|
||||||
'is_self_ref': instance.isSelfRef,
|
'is_self_ref': instance.isSelfRef,
|
||||||
@ -63,7 +67,9 @@ Map<String, dynamic> _$$SnAttachmentImplToJson(_$SnAttachmentImpl instance) =>
|
|||||||
'pool': instance.pool?.toJson(),
|
'pool': instance.pool?.toJson(),
|
||||||
'pool_id': instance.poolId,
|
'pool_id': instance.poolId,
|
||||||
'account_id': instance.accountId,
|
'account_id': instance.accountId,
|
||||||
|
'usermeta': instance.usermeta,
|
||||||
'metadata': instance.metadata,
|
'metadata': instance.metadata,
|
||||||
|
'thumbnail': instance.thumbnail,
|
||||||
};
|
};
|
||||||
|
|
||||||
_$SnAttachmentPoolImpl _$$SnAttachmentPoolImplFromJson(
|
_$SnAttachmentPoolImpl _$$SnAttachmentPoolImplFromJson(
|
||||||
|
@ -32,7 +32,7 @@ class _AccountSelectState extends State<AccountSelect> {
|
|||||||
final List<SnAccount> _pendingUsers = List.empty(growable: true);
|
final List<SnAccount> _pendingUsers = List.empty(growable: true);
|
||||||
final List<SnAccount> _selectedUsers = List.empty(growable: true);
|
final List<SnAccount> _selectedUsers = List.empty(growable: true);
|
||||||
|
|
||||||
int _accountId = 0;
|
final int _accountId = 0;
|
||||||
|
|
||||||
Future<void> _revertSelectedUsers() async {
|
Future<void> _revertSelectedUsers() async {
|
||||||
if (widget.initialSelection?.isEmpty ?? true) return;
|
if (widget.initialSelection?.isEmpty ?? true) return;
|
||||||
|
@ -99,10 +99,10 @@ class _AttachmentInputDialogState extends State<AttachmentInputDialog> {
|
|||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
child: Text('dialogDismiss').tr(),
|
|
||||||
onPressed: _isBusy ? null : () {
|
onPressed: _isBusy ? null : () {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
|
child: Text('dialogDismiss').tr(),
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: _isBusy ? null : () => _finishUp(),
|
onPressed: _isBusy ? null : () => _finishUp(),
|
||||||
|
@ -18,6 +18,7 @@ import 'package:uuid/uuid.dart';
|
|||||||
class AttachmentItem extends StatelessWidget {
|
class AttachmentItem extends StatelessWidget {
|
||||||
final SnAttachment? data;
|
final SnAttachment? data;
|
||||||
final String? heroTag;
|
final String? heroTag;
|
||||||
|
|
||||||
const AttachmentItem({
|
const AttachmentItem({
|
||||||
super.key,
|
super.key,
|
||||||
required this.data,
|
required this.data,
|
||||||
@ -60,9 +61,14 @@ class AttachmentItem extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (data!.isMature) {
|
if (data!.contentRating > 0) {
|
||||||
return _AttachmentItemSensitiveBlur(
|
return LayoutBuilder(
|
||||||
child: _buildContent(context),
|
builder: (context, constraints) {
|
||||||
|
return _AttachmentItemSensitiveBlur(
|
||||||
|
isCompact: constraints.maxHeight < 360,
|
||||||
|
child: _buildContent(context),
|
||||||
|
);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,15 +78,15 @@ class AttachmentItem extends StatelessWidget {
|
|||||||
|
|
||||||
class _AttachmentItemSensitiveBlur extends StatefulWidget {
|
class _AttachmentItemSensitiveBlur extends StatefulWidget {
|
||||||
final Widget child;
|
final Widget child;
|
||||||
const _AttachmentItemSensitiveBlur({super.key, required this.child});
|
final bool isCompact;
|
||||||
|
|
||||||
|
const _AttachmentItemSensitiveBlur({required this.child, this.isCompact = false});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<_AttachmentItemSensitiveBlur> createState() =>
|
State<_AttachmentItemSensitiveBlur> createState() => _AttachmentItemSensitiveBlurState();
|
||||||
_AttachmentItemSensitiveBlurState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AttachmentItemSensitiveBlurState
|
class _AttachmentItemSensitiveBlurState extends State<_AttachmentItemSensitiveBlur> {
|
||||||
extends State<_AttachmentItemSensitiveBlur> {
|
|
||||||
bool _doesShow = false;
|
bool _doesShow = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -104,24 +110,21 @@ class _AttachmentItemSensitiveBlurState
|
|||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
size: 32,
|
size: 32,
|
||||||
),
|
),
|
||||||
const Gap(8),
|
if (!widget.isCompact) const Gap(8),
|
||||||
Text('sensitiveContent', textAlign: TextAlign.center)
|
if (!widget.isCompact)
|
||||||
.tr()
|
Text('sensitiveContent', textAlign: TextAlign.center)
|
||||||
.fontSize(20)
|
|
||||||
.textColor(Colors.white)
|
|
||||||
.bold(),
|
|
||||||
Text(
|
|
||||||
'sensitiveContentDescription',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
)
|
|
||||||
.tr()
|
|
||||||
.fontSize(14)
|
|
||||||
.textColor(Colors.white.withOpacity(0.8)),
|
|
||||||
const Gap(16),
|
|
||||||
InkWell(
|
|
||||||
child: Text('sensitiveContentReveal')
|
|
||||||
.tr()
|
.tr()
|
||||||
.textColor(Colors.white),
|
.fontSize(20)
|
||||||
|
.textColor(Colors.white)
|
||||||
|
.bold(),
|
||||||
|
if (!widget.isCompact)
|
||||||
|
Text(
|
||||||
|
'sensitiveContentDescription',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
).tr().fontSize(14).textColor(Colors.white.withOpacity(0.8)),
|
||||||
|
if (!widget.isCompact) const Gap(16),
|
||||||
|
InkWell(
|
||||||
|
child: Text('sensitiveContentReveal').tr().textColor(Colors.white),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() => _doesShow = !_doesShow);
|
setState(() => _doesShow = !_doesShow);
|
||||||
},
|
},
|
||||||
@ -131,9 +134,7 @@ class _AttachmentItemSensitiveBlurState
|
|||||||
).center(),
|
).center(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
).opacity(_doesShow ? 0 : 1, animate: true).animate(const Duration(milliseconds: 300), Curves.easeInOut),
|
||||||
.opacity(_doesShow ? 0 : 1, animate: true)
|
|
||||||
.animate(const Duration(milliseconds: 300), Curves.easeInOut),
|
|
||||||
if (_doesShow)
|
if (_doesShow)
|
||||||
Positioned(
|
Positioned(
|
||||||
top: 0,
|
top: 0,
|
||||||
@ -163,19 +164,17 @@ class _AttachmentItemSensitiveBlurState
|
|||||||
class _AttachmentItemContentVideo extends StatefulWidget {
|
class _AttachmentItemContentVideo extends StatefulWidget {
|
||||||
final SnAttachment data;
|
final SnAttachment data;
|
||||||
final bool isAutoload;
|
final bool isAutoload;
|
||||||
|
|
||||||
const _AttachmentItemContentVideo({
|
const _AttachmentItemContentVideo({
|
||||||
super.key,
|
|
||||||
required this.data,
|
required this.data,
|
||||||
this.isAutoload = false,
|
this.isAutoload = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<_AttachmentItemContentVideo> createState() =>
|
State<_AttachmentItemContentVideo> createState() => _AttachmentItemContentVideoState();
|
||||||
_AttachmentItemContentVideoState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AttachmentItemContentVideoState
|
class _AttachmentItemContentVideoState extends State<_AttachmentItemContentVideo> {
|
||||||
extends State<_AttachmentItemContentVideo> {
|
|
||||||
bool _showContent = false;
|
bool _showContent = false;
|
||||||
|
|
||||||
Player? _videoPlayer;
|
Player? _videoPlayer;
|
||||||
@ -207,7 +206,7 @@ class _AttachmentItemContentVideoState
|
|||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
final ratio = widget.data.metadata['ratio'] ?? 16 / 9;
|
final ratio = widget.data.data['ratio'] ?? 16 / 9;
|
||||||
|
|
||||||
final sn = context.read<SnNetworkProvider>();
|
final sn = context.read<SnNetworkProvider>();
|
||||||
|
|
||||||
@ -216,9 +215,9 @@ class _AttachmentItemContentVideoState
|
|||||||
behavior: HitTestBehavior.opaque,
|
behavior: HitTestBehavior.opaque,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
if (widget.data.metadata['thumbnail'] != null)
|
if (widget.data.thumbnail != null)
|
||||||
AutoResizeUniversalImage(
|
AutoResizeUniversalImage(
|
||||||
sn.getAttachmentUrl(widget.data.metadata['thumbnail']),
|
sn.getAttachmentUrl(widget.data.thumbnail!),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
@ -266,10 +265,7 @@ class _AttachmentItemContentVideoState
|
|||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
Duration(
|
Duration(
|
||||||
milliseconds:
|
milliseconds: (widget.data.data['duration'] ?? 0).toInt() * 1000,
|
||||||
(widget.data.metadata['duration'] ?? 0)
|
|
||||||
.toInt() *
|
|
||||||
1000,
|
|
||||||
).toString(),
|
).toString(),
|
||||||
style: GoogleFonts.robotoMono(
|
style: GoogleFonts.robotoMono(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
@ -317,19 +313,17 @@ class _AttachmentItemContentVideoState
|
|||||||
class _AttachmentItemContentAudio extends StatefulWidget {
|
class _AttachmentItemContentAudio extends StatefulWidget {
|
||||||
final SnAttachment data;
|
final SnAttachment data;
|
||||||
final bool isAutoload;
|
final bool isAutoload;
|
||||||
|
|
||||||
const _AttachmentItemContentAudio({
|
const _AttachmentItemContentAudio({
|
||||||
super.key,
|
|
||||||
required this.data,
|
required this.data,
|
||||||
this.isAutoload = false,
|
this.isAutoload = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<_AttachmentItemContentAudio> createState() =>
|
State<_AttachmentItemContentAudio> createState() => _AttachmentItemContentAudioState();
|
||||||
_AttachmentItemContentAudioState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AttachmentItemContentAudioState
|
class _AttachmentItemContentAudioState extends State<_AttachmentItemContentAudio> {
|
||||||
extends State<_AttachmentItemContentAudio> {
|
|
||||||
bool _showContent = false;
|
bool _showContent = false;
|
||||||
|
|
||||||
double? _draggingValue;
|
double? _draggingValue;
|
||||||
@ -378,11 +372,11 @@ class _AttachmentItemContentAudioState
|
|||||||
behavior: HitTestBehavior.opaque,
|
behavior: HitTestBehavior.opaque,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
if (widget.data.metadata['thumbnail'] != null)
|
if (widget.data.thumbnail != null)
|
||||||
AspectRatio(
|
AspectRatio(
|
||||||
aspectRatio: 16 / 9,
|
aspectRatio: 16 / 9,
|
||||||
child: AutoResizeUniversalImage(
|
child: AutoResizeUniversalImage(
|
||||||
sn.getAttachmentUrl(widget.data.metadata['thumbnail']),
|
sn.getAttachmentUrl(widget.data.data['thumbnail']),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -463,11 +457,11 @@ class _AttachmentItemContentAudioState
|
|||||||
|
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
if (widget.data.metadata['thumbnail'] != null)
|
if (widget.data.data['thumbnail'] != null)
|
||||||
AspectRatio(
|
AspectRatio(
|
||||||
aspectRatio: 16 / 9,
|
aspectRatio: 16 / 9,
|
||||||
child: AutoResizeUniversalImage(
|
child: AutoResizeUniversalImage(
|
||||||
sn.getAttachmentUrl(widget.data.metadata['thumbnail']),
|
sn.getAttachmentUrl(widget.data.data['thumbnail']),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -499,12 +493,8 @@ class _AttachmentItemContentAudioState
|
|||||||
overlayShape: SliderComponentShape.noOverlay,
|
overlayShape: SliderComponentShape.noOverlay,
|
||||||
),
|
),
|
||||||
child: Slider(
|
child: Slider(
|
||||||
secondaryTrackValue: _bufferedPosition
|
secondaryTrackValue: _bufferedPosition.inMilliseconds.abs().toDouble(),
|
||||||
.inMilliseconds
|
value: _draggingValue?.abs() ?? _position.inMilliseconds.toDouble().abs(),
|
||||||
.abs()
|
|
||||||
.toDouble(),
|
|
||||||
value: _draggingValue?.abs() ??
|
|
||||||
_position.inMilliseconds.toDouble().abs(),
|
|
||||||
min: 0,
|
min: 0,
|
||||||
max: math
|
max: math
|
||||||
.max(
|
.max(
|
||||||
@ -544,9 +534,7 @@ class _AttachmentItemContentAudioState
|
|||||||
),
|
),
|
||||||
const Gap(16),
|
const Gap(16),
|
||||||
IconButton.filled(
|
IconButton.filled(
|
||||||
icon: _isPlaying
|
icon: _isPlaying ? const Icon(Symbols.pause) : const Icon(Symbols.play_arrow),
|
||||||
? const Icon(Symbols.pause)
|
|
||||||
: const Icon(Symbols.play_arrow),
|
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
_audioPlayer!.playOrPause();
|
_audioPlayer!.playOrPause();
|
||||||
},
|
},
|
||||||
|
@ -58,7 +58,7 @@ class _AttachmentListState extends State<AttachmentList> {
|
|||||||
|
|
||||||
if (widget.data.isEmpty) return const SizedBox.shrink();
|
if (widget.data.isEmpty) return const SizedBox.shrink();
|
||||||
if (widget.data.length == 1) {
|
if (widget.data.length == 1) {
|
||||||
final singleAspectRatio = widget.data[0]?.metadata['ratio']?.toDouble() ??
|
final singleAspectRatio = widget.data[0]?.data['ratio']?.toDouble() ??
|
||||||
switch (widget.data[0]?.mimetype.split('/').firstOrNull) {
|
switch (widget.data[0]?.mimetype.split('/').firstOrNull) {
|
||||||
'audio' => 16 / 9,
|
'audio' => 16 / 9,
|
||||||
'video' => 16 / 9,
|
'video' => 16 / 9,
|
||||||
@ -114,6 +114,7 @@ class _AttachmentListState extends State<AttachmentList> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
if (widget.data.firstOrNull?.mediaType != SnMediaType.image) return;
|
||||||
context.pushTransparentRoute(
|
context.pushTransparentRoute(
|
||||||
AttachmentZoomView(
|
AttachmentZoomView(
|
||||||
data: widget.data.where((ele) => ele != null).cast(),
|
data: widget.data.where((ele) => ele != null).cast(),
|
||||||
@ -136,7 +137,7 @@ class _AttachmentListState extends State<AttachmentList> {
|
|||||||
children: widget.data
|
children: widget.data
|
||||||
.mapIndexed(
|
.mapIndexed(
|
||||||
(idx, ele) => AspectRatio(
|
(idx, ele) => AspectRatio(
|
||||||
aspectRatio: (ele?.metadata['ratio'] ?? 1).toDouble(),
|
aspectRatio: (ele?.data['ratio'] ?? 1).toDouble(),
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: backgroundColor,
|
color: backgroundColor,
|
||||||
@ -161,7 +162,7 @@ class _AttachmentListState extends State<AttachmentList> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return AspectRatio(
|
return AspectRatio(
|
||||||
aspectRatio: (widget.data.firstOrNull?.metadata['ratio'] ?? 1).toDouble(),
|
aspectRatio: (widget.data.firstOrNull?.data['ratio'] ?? 1).toDouble(),
|
||||||
child: Container(
|
child: Container(
|
||||||
constraints: BoxConstraints(maxHeight: constraints.maxHeight),
|
constraints: BoxConstraints(maxHeight: constraints.maxHeight),
|
||||||
child: ScrollConfiguration(
|
child: ScrollConfiguration(
|
||||||
@ -173,12 +174,14 @@ class _AttachmentListState extends State<AttachmentList> {
|
|||||||
return Container(
|
return Container(
|
||||||
constraints: constraints,
|
constraints: constraints,
|
||||||
child: AspectRatio(
|
child: AspectRatio(
|
||||||
aspectRatio: (widget.data[idx]?.metadata['ratio'] ?? 1).toDouble(),
|
aspectRatio: (widget.data[idx]?.data['ratio'] ?? 1).toDouble(),
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
if (widget.data[idx]?.mediaType != SnMediaType.image) return;
|
||||||
context.pushTransparentRoute(
|
context.pushTransparentRoute(
|
||||||
AttachmentZoomView(
|
AttachmentZoomView(
|
||||||
data: widget.data.where((ele) => ele != null).cast(),
|
data:
|
||||||
|
widget.data.where((ele) => ele != null && ele.mediaType == SnMediaType.image).cast(),
|
||||||
initialIndex: idx,
|
initialIndex: idx,
|
||||||
heroTags: heroTags,
|
heroTags: heroTags,
|
||||||
),
|
),
|
||||||
|
@ -174,7 +174,7 @@ class ChatMessage extends StatelessWidget {
|
|||||||
class _ChatMessageText extends StatelessWidget {
|
class _ChatMessageText extends StatelessWidget {
|
||||||
final SnChatMessage data;
|
final SnChatMessage data;
|
||||||
|
|
||||||
const _ChatMessageText({super.key, required this.data});
|
const _ChatMessageText({required this.data});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -214,7 +214,7 @@ class _ChatMessageText extends StatelessWidget {
|
|||||||
class _ChatMessageSystemNotify extends StatelessWidget {
|
class _ChatMessageSystemNotify extends StatelessWidget {
|
||||||
final SnChatMessage data;
|
final SnChatMessage data;
|
||||||
|
|
||||||
const _ChatMessageSystemNotify({super.key, required this.data});
|
const _ChatMessageSystemNotify({required this.data});
|
||||||
|
|
||||||
String _formatDuration(Duration duration) {
|
String _formatDuration(Duration duration) {
|
||||||
String negativeSign = duration.isNegative ? '-' : '';
|
String negativeSign = duration.isNegative ? '-' : '';
|
||||||
|
@ -1,18 +1,14 @@
|
|||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.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:image_picker/image_picker.dart';
|
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:pasteboard/pasteboard.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
import 'package:surface/controllers/chat_message_controller.dart';
|
import 'package:surface/controllers/chat_message_controller.dart';
|
||||||
import 'package:surface/controllers/post_write_controller.dart';
|
import 'package:surface/controllers/post_write_controller.dart';
|
||||||
import 'package:surface/providers/sn_attachment.dart';
|
import 'package:surface/providers/sn_attachment.dart';
|
||||||
import 'package:surface/providers/user_directory.dart';
|
import 'package:surface/providers/user_directory.dart';
|
||||||
|
import 'package:surface/types/attachment.dart';
|
||||||
import 'package:surface/types/chat.dart';
|
import 'package:surface/types/chat.dart';
|
||||||
import 'package:surface/widgets/dialog.dart';
|
import 'package:surface/widgets/dialog.dart';
|
||||||
import 'package:surface/widgets/markdown_content.dart';
|
import 'package:surface/widgets/markdown_content.dart';
|
||||||
@ -80,7 +76,7 @@ class ChatMessageInputState extends State<ChatMessageInput> {
|
|||||||
media.name,
|
media.name,
|
||||||
'messaging',
|
'messaging',
|
||||||
null,
|
null,
|
||||||
mimetype: media.raw != null && media.type == PostWriteMediaType.image ? 'image/png' : null,
|
mimetype: media.raw != null && media.type == SnMediaType.image ? 'image/png' : null,
|
||||||
);
|
);
|
||||||
|
|
||||||
final item = await attach.chunkedUploadParts(
|
final item = await attach.chunkedUploadParts(
|
||||||
|
@ -60,7 +60,6 @@ class _LinkPreviewEntry extends StatelessWidget {
|
|||||||
final SnLinkMeta meta;
|
final SnLinkMeta meta;
|
||||||
|
|
||||||
const _LinkPreviewEntry({
|
const _LinkPreviewEntry({
|
||||||
super.key,
|
|
||||||
required this.meta,
|
required this.meta,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -549,7 +549,6 @@ class _PostHeadline extends StatelessWidget {
|
|||||||
final bool isEnlarge;
|
final bool isEnlarge;
|
||||||
|
|
||||||
const _PostHeadline({
|
const _PostHeadline({
|
||||||
super.key,
|
|
||||||
required this.data,
|
required this.data,
|
||||||
this.isEnlarge = false,
|
this.isEnlarge = false,
|
||||||
});
|
});
|
||||||
@ -894,7 +893,6 @@ class _PostQuoteContent extends StatelessWidget {
|
|||||||
final bool isFlatted;
|
final bool isFlatted;
|
||||||
|
|
||||||
const _PostQuoteContent({
|
const _PostQuoteContent({
|
||||||
super.key,
|
|
||||||
this.isRelativeDate = true,
|
this.isRelativeDate = true,
|
||||||
this.isFlatted = false,
|
this.isFlatted = false,
|
||||||
required this.child,
|
required this.child,
|
||||||
@ -962,7 +960,7 @@ class _PostQuoteContent extends StatelessWidget {
|
|||||||
class _PostTagsList extends StatelessWidget {
|
class _PostTagsList extends StatelessWidget {
|
||||||
final SnPost data;
|
final SnPost data;
|
||||||
|
|
||||||
const _PostTagsList({super.key, required this.data});
|
const _PostTagsList({required this.data});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -1035,7 +1033,7 @@ class _PostTagsList extends StatelessWidget {
|
|||||||
class _PostVisibilityHint extends StatelessWidget {
|
class _PostVisibilityHint extends StatelessWidget {
|
||||||
final SnPost data;
|
final SnPost data;
|
||||||
|
|
||||||
const _PostVisibilityHint({super.key, required this.data});
|
const _PostVisibilityHint({required this.data});
|
||||||
|
|
||||||
static const List<IconData> kVisibilityIcons = [
|
static const List<IconData> kVisibilityIcons = [
|
||||||
Symbols.public,
|
Symbols.public,
|
||||||
@ -1060,7 +1058,7 @@ class _PostVisibilityHint extends StatelessWidget {
|
|||||||
class _PostTruncatedHint extends StatelessWidget {
|
class _PostTruncatedHint extends StatelessWidget {
|
||||||
final SnPost data;
|
final SnPost data;
|
||||||
|
|
||||||
const _PostTruncatedHint({super.key, required this.data});
|
const _PostTruncatedHint({required this.data});
|
||||||
|
|
||||||
static const int kHumanReadSpeed = 238;
|
static const int kHumanReadSpeed = 238;
|
||||||
|
|
||||||
@ -1102,7 +1100,7 @@ class _PostTruncatedHint extends StatelessWidget {
|
|||||||
class _PostAbuseReportDialog extends StatefulWidget {
|
class _PostAbuseReportDialog extends StatefulWidget {
|
||||||
final SnPost data;
|
final SnPost data;
|
||||||
|
|
||||||
const _PostAbuseReportDialog({super.key, required this.data});
|
const _PostAbuseReportDialog({required this.data});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<_PostAbuseReportDialog> createState() => _PostAbuseReportDialogState();
|
State<_PostAbuseReportDialog> createState() => _PostAbuseReportDialogState();
|
||||||
|
@ -96,10 +96,7 @@ class PostMediaPendingList extends StatelessWidget {
|
|||||||
if (!context.mounted) return;
|
if (!context.mounted) return;
|
||||||
|
|
||||||
final attach = context.read<SnAttachmentProvider>();
|
final attach = context.read<SnAttachmentProvider>();
|
||||||
final newAttach = await attach.updateOne(attachments[idx].attachment!.id, thumbnail.alt, metadata: {
|
final newAttach = await attach.updateOne(attachments[idx].attachment!.id, thumbnail: thumbnail.rid);
|
||||||
...attachments[idx].attachment!.metadata,
|
|
||||||
'thumbnail': thumbnail.rid,
|
|
||||||
});
|
|
||||||
|
|
||||||
onUpdate!(idx, PostWriteMedia(newAttach));
|
onUpdate!(idx, PostWriteMedia(newAttach));
|
||||||
}
|
}
|
||||||
@ -124,7 +121,7 @@ class PostMediaPendingList extends StatelessWidget {
|
|||||||
ContextMenu _createContextMenu(BuildContext context, int idx, PostWriteMedia media) {
|
ContextMenu _createContextMenu(BuildContext context, int idx, PostWriteMedia media) {
|
||||||
return ContextMenu(
|
return ContextMenu(
|
||||||
entries: [
|
entries: [
|
||||||
if (media.attachment != null && media.type == PostWriteMediaType.video)
|
if (media.attachment != null && media.type == SnMediaType.video)
|
||||||
MenuItem(
|
MenuItem(
|
||||||
label: 'attachmentSetThumbnail'.tr(),
|
label: 'attachmentSetThumbnail'.tr(),
|
||||||
icon: Symbols.image,
|
icon: Symbols.image,
|
||||||
@ -140,7 +137,7 @@ class PostMediaPendingList extends StatelessWidget {
|
|||||||
onUpload!(idx);
|
onUpload!(idx);
|
||||||
}),
|
}),
|
||||||
if (media.attachment != null &&
|
if (media.attachment != null &&
|
||||||
media.type == PostWriteMediaType.image &&
|
media.type == SnMediaType.image &&
|
||||||
onPostSetThumbnail != null &&
|
onPostSetThumbnail != null &&
|
||||||
idx != -1)
|
idx != -1)
|
||||||
MenuItem(
|
MenuItem(
|
||||||
@ -150,7 +147,7 @@ class PostMediaPendingList extends StatelessWidget {
|
|||||||
onPostSetThumbnail!(idx);
|
onPostSetThumbnail!(idx);
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
else if (media.attachment != null && media.type == PostWriteMediaType.image && onPostSetThumbnail != null)
|
else if (media.attachment != null && media.type == SnMediaType.image && onPostSetThumbnail != null)
|
||||||
MenuItem(
|
MenuItem(
|
||||||
label: 'attachmentUnsetAsPostThumbnail'.tr(),
|
label: 'attachmentUnsetAsPostThumbnail'.tr(),
|
||||||
icon: Symbols.cancel,
|
icon: Symbols.cancel,
|
||||||
@ -166,7 +163,7 @@ class PostMediaPendingList extends StatelessWidget {
|
|||||||
onInsertLink!(idx);
|
onInsertLink!(idx);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
if (media.type == PostWriteMediaType.image && media.attachment != null)
|
if (media.type == SnMediaType.image && media.attachment != null)
|
||||||
MenuItem(
|
MenuItem(
|
||||||
label: 'preview'.tr(),
|
label: 'preview'.tr(),
|
||||||
icon: Symbols.preview,
|
icon: Symbols.preview,
|
||||||
@ -177,7 +174,7 @@ class PostMediaPendingList extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
if (media.type == PostWriteMediaType.image && media.attachment == null)
|
if (media.type == SnMediaType.image && media.attachment == null)
|
||||||
MenuItem(
|
MenuItem(
|
||||||
label: 'crop'.tr(),
|
label: 'crop'.tr(),
|
||||||
icon: Symbols.crop,
|
icon: Symbols.crop,
|
||||||
@ -219,10 +216,6 @@ class PostMediaPendingList extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final devicePixelRatio = MediaQuery.of(context).devicePixelRatio;
|
|
||||||
|
|
||||||
final sn = context.read<SnNetworkProvider>();
|
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
constraints: const BoxConstraints(maxHeight: 120),
|
constraints: const BoxConstraints(maxHeight: 120),
|
||||||
child: Row(
|
child: Row(
|
||||||
@ -285,7 +278,7 @@ class _PostMediaPendingItem extends StatelessWidget {
|
|||||||
child: AspectRatio(
|
child: AspectRatio(
|
||||||
aspectRatio: 1,
|
aspectRatio: 1,
|
||||||
child: switch (media.type) {
|
child: switch (media.type) {
|
||||||
PostWriteMediaType.image => Container(
|
SnMediaType.image => Container(
|
||||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||||
child: LayoutBuilder(builder: (context, constraints) {
|
child: LayoutBuilder(builder: (context, constraints) {
|
||||||
return Image(
|
return Image(
|
||||||
@ -298,7 +291,7 @@ class _PostMediaPendingItem extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
PostWriteMediaType.video => Container(
|
SnMediaType.video => Container(
|
||||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||||
child: media.attachment?.metadata['thumbnail'] != null
|
child: media.attachment?.metadata['thumbnail'] != null
|
||||||
? AutoResizeUniversalImage(sn.getAttachmentUrl(media.attachment?.metadata['thumbnail']))
|
? AutoResizeUniversalImage(sn.getAttachmentUrl(media.attachment?.metadata['thumbnail']))
|
||||||
@ -345,7 +338,7 @@ class AddPostMediaButton extends StatelessWidget {
|
|||||||
PostWriteMedia.fromBytes(
|
PostWriteMedia.fromBytes(
|
||||||
imageBytes,
|
imageBytes,
|
||||||
'attachmentPastedImage'.tr(),
|
'attachmentPastedImage'.tr(),
|
||||||
PostWriteMediaType.image,
|
SnMediaType.image,
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
26
pubspec.lock
26
pubspec.lock
@ -490,10 +490,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: file_picker
|
name: file_picker
|
||||||
sha256: c2376a6aae82358a9f9ccdd7d1f4006d08faa39a2767cce01031d9f593a8bd3b
|
sha256: c904b4ab56d53385563c7c39d8e9fa9af086f91495dfc48717ad84a42c3cf204
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.1.6"
|
version: "8.1.7"
|
||||||
file_saver:
|
file_saver:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -763,13 +763,13 @@ packages:
|
|||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
flutter_webrtc:
|
flutter_webrtc:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_webrtc
|
name: flutter_webrtc
|
||||||
sha256: "0e138a0a3bf6830c29c8439b17be0e222d0de27fa72f24e6aee4d34de72f22ef"
|
sha256: "3efe9828f19a07d29a51a726759ad0c70a840d231548a1c7d0332075a94db1df"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.5"
|
version: "0.12.5+hotfix.1"
|
||||||
freezed:
|
freezed:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
@ -1354,6 +1354,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.0"
|
version: "2.3.0"
|
||||||
|
pausable_timer:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pausable_timer
|
||||||
|
sha256: "6ef1a95441ec3439de6fb63f39a011b67e693198e7dae14e20675c3c00e86074"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.0+3"
|
||||||
permission_handler:
|
permission_handler:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -1711,6 +1719,14 @@ packages:
|
|||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
slide_countdown:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: slide_countdown
|
||||||
|
sha256: "363914f96389502467d4dc9c0f26e88f93df3d8e37de2d5ff05b16d981fe973d"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.2"
|
||||||
sliver_tools:
|
sliver_tools:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -113,6 +113,8 @@ dependencies:
|
|||||||
version: ^3.0.2
|
version: ^3.0.2
|
||||||
flutter_colorpicker: ^1.1.0
|
flutter_colorpicker: ^1.1.0
|
||||||
fl_chart: ^0.70.0
|
fl_chart: ^0.70.0
|
||||||
|
flutter_webrtc: ^0.12.5+hotfix.1
|
||||||
|
slide_countdown: ^2.0.2
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user