Merge branch 'main' into candidate

This commit is contained in:
xmflsct 2022-10-30 17:48:26 +01:00
commit 9a17d7de96
35 changed files with 398 additions and 377 deletions

View File

@ -416,6 +416,8 @@ PODS:
- React-Core
- react-native-language-detection (0.1.0):
- React
- react-native-live-text-image-view (0.4.0):
- React-Core
- react-native-netinfo (9.3.6):
- React-Core
- react-native-pager-view (6.0.1):
@ -534,7 +536,7 @@ PODS:
- React-Core
- RNFastImage (8.6.1):
- React-Core
- SDWebImage (~> 5.13.4)
- SDWebImage (~> 5.13.5)
- SDWebImageWebPCoder (~> 0.9.0)
- RNGestureHandler (2.8.0):
- React-Core
@ -575,9 +577,9 @@ PODS:
- React
- RNSVG (13.0.0):
- React-Core
- SDWebImage (5.13.4):
- SDWebImage/Core (= 5.13.4)
- SDWebImage/Core (5.13.4)
- SDWebImage (5.13.5):
- SDWebImage/Core (= 5.13.5)
- SDWebImage/Core (5.13.5)
- SDWebImageWebPCoder (0.9.1):
- libwebp (~> 1.0)
- SDWebImage/Core (~> 5.13)
@ -642,6 +644,7 @@ DEPENDENCIES:
- react-native-context-menu-view (from `../node_modules/react-native-context-menu-view`)
- react-native-image-picker (from `../node_modules/react-native-image-picker`)
- react-native-language-detection (from `../node_modules/react-native-language-detection`)
- react-native-live-text-image-view (from `../node_modules/react-native-live-text-image-view`)
- "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)"
- react-native-pager-view (from `../node_modules/react-native-pager-view`)
- "react-native-paste-input (from `../node_modules/@mattermost/react-native-paste-input`)"
@ -790,6 +793,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-image-picker"
react-native-language-detection:
:path: "../node_modules/react-native-language-detection"
react-native-live-text-image-view:
:path: "../node_modules/react-native-live-text-image-view"
react-native-netinfo:
:path: "../node_modules/@react-native-community/netinfo"
react-native-pager-view:
@ -909,6 +914,7 @@ SPEC CHECKSUMS:
react-native-context-menu-view: b0beca02aad4bd9f9d7d932bf437e0a03baa69ef
react-native-image-picker: 4bc9ed38c8be255b515d8c88babbaf74973f91a8
react-native-language-detection: 0e43195ad014974f1b7a31b64820eff34a243f2d
react-native-live-text-image-view: 483bacfdba464162b8cf176bba555364f18b584c
react-native-netinfo: f80db8cac2151405633324cb645c60af098ee461
react-native-pager-view: 3051346698a0ba0c4e13e40097cc11b00ee03cca
react-native-paste-input: 183ad7dc224e192719616f4258dde5b548627d08
@ -928,14 +934,14 @@ SPEC CHECKSUMS:
ReactCommon: fe7580b9d10f00249facf25659e0ec051320cc8a
RNCAsyncStorage: 0c357f3156fcb16c8589ede67cc036330b6698ca
RNCClipboard: 2834e1c4af68697089cdd455ee4a4cdd198fa7dd
RNFastImage: e6267e27581b81918ebef6432c94c20718ec3b91
RNFastImage: 386e5658bdcc109e8f1fe3265884cb35f0b73541
RNGestureHandler: 62232ba8f562f7dea5ba1b3383494eb5bf97a4d3
RNReanimated: c3e58924b9418883b0bde9e78c4c957302f02435
RNScreens: 34cc502acf1b916c582c60003dc3089fa01dc66d
RNSentry: 694aecc3d8240e4935374974a6636e360ae06394
RNShareMenu: cb9dac548c8bf147d06f0bf07296ad51ea9f5fc3
RNSVG: 42a0c731b11179ebbd27a3eeeafa7201ebb476ff
SDWebImage: e5cc87bf736e60f49592f307bdf9e157189298a3
SDWebImage: 23d714cd599354ee7906dbae26dff89b421c4370
SDWebImageWebPCoder: 18503de6621dd2c420d680e33d46bf8e1d5169b0
Sentry: 2c6053e4cfe6dea6608135dea1928ffbb4ecfba5
Swime: d7b2c277503b6cea317774aedc2dce05613f8b0b

View File

@ -76,6 +76,7 @@
E633A427281EAEAB000E540F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
E633A42F281EAF38000E540F /* ShareViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ShareViewController.swift; path = "../../node_modules/react-native-share-menu/ios/ShareViewController.swift"; sourceTree = "<group>"; };
E633A431281EB55C000E540F /* ShareExtension-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ShareExtension-Bridging-Header.h"; sourceTree = "<group>"; };
E671BDF8290EAFB800287BD0 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
E69EBACA28DF282D0057EDEC /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = "<group>"; };
E69EBACB28DF283A0057EDEC /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = "<group>"; };
E69EBACC28DF28420057EDEC /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/InfoPlist.strings; sourceTree = "<group>"; };
@ -289,6 +290,7 @@
"pt-BR",
vi,
ja,
"zh-Hant",
);
mainGroup = 83CBB9F61A601CBA00E9B192;
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
@ -514,6 +516,7 @@
E69EBACD28DF284D0057EDEC /* pt-BR */,
E69EBACE28DF28560057EDEC /* vi */,
E6C8B26628F5F9FC0062CF2E /* ja */,
E671BDF8290EAFB800287BD0 /* zh-Hant */,
);
name = InfoPlist.strings;
sourceTree = "<group>";

View File

@ -0,0 +1,2 @@
"NSPhotoLibraryAddUsageDescription" = "允許tooot保存圖片至相冊";
"NSPhotoLibraryUsageDescription" = "允許tooot保存圖片至相冊";

View File

@ -79,6 +79,7 @@
"react-native-htmlview": "^0.16.0",
"react-native-image-picker": "^4.10.0",
"react-native-language-detection": "^0.1.0",
"react-native-live-text-image-view": "^0.4.0",
"react-native-pager-view": "^6.0.1",
"react-native-reanimated": "^2.12.0",
"react-native-reanimated-zoom": "^0.3.1",

View File

@ -1,5 +1,5 @@
diff --git a/node_modules/react-native-fast-image/RNFastImage.podspec b/node_modules/react-native-fast-image/RNFastImage.podspec
index db0fada..c68771e 100644
index db0fada..1aae975 100644
--- a/node_modules/react-native-fast-image/RNFastImage.podspec
+++ b/node_modules/react-native-fast-image/RNFastImage.podspec
@@ -16,6 +16,6 @@ Pod::Spec.new do |s|
@ -8,7 +8,7 @@ index db0fada..c68771e 100644
s.dependency 'React-Core'
- s.dependency 'SDWebImage', '~> 5.11.1'
- s.dependency 'SDWebImageWebPCoder', '~> 0.8.4'
+ s.dependency 'SDWebImage', '~> 5.13.4'
+ s.dependency 'SDWebImage', '~> 5.13.5'
+ s.dependency 'SDWebImageWebPCoder', '~> 0.9.0'
end
diff --git a/node_modules/react-native-fast-image/android/build.gradle b/node_modules/react-native-fast-image/android/build.gradle

View File

@ -326,11 +326,7 @@ const Screens: React.FC<Props> = ({ localCorrupt }) => {
<Stack.Screen
name='Screen-ImagesViewer'
component={ScreenImagesViewer}
options={{
headerShown: false,
presentation: 'fullScreenModal',
animation: 'fade'
}}
options={{ headerShown: false, animation: 'fade' }}
/>
<Stack.Screen
name='Screen-AccountSelection'

View File

@ -272,9 +272,9 @@ const ParseHTML = React.memo(
}}
children={t('HTML.expanded', {
hint: expandHint,
totalLines:
moreLines:
numberOfLines > 1 && typeof totalLines === 'number'
? t('HTML.totalLines', { count: totalLines })
? t('HTML.moreLines', { count: totalLines - numberOfLines })
: ''
})}
/>

View File

@ -1,8 +1,8 @@
{
"HTML": {
"accessibilityHint": "",
"expanded": "{{hint}}{{totalLines}}",
"totalLines": "",
"expanded": "{{hint}}{{moreLines}}",
"moreLines": "",
"defaultHint": ""
}
}

View File

@ -1,8 +1,8 @@
{
"HTML": {
"accessibilityHint": "Tap to expand or collapse content",
"expanded": "{{hint}}{{totalLines}}",
"totalLines": " ({{count}} lines)",
"expanded": "{{hint}}{{moreLines}}",
"moreLines": " ({{count}} more lines)",
"defaultHint": "Long toot"
}
}

View File

@ -9,6 +9,7 @@ import ko from '@root/i18n/ko/_all'
import pt_BR from '@root/i18n/pt_BR/_all'
import vi from '@root/i18n/vi/_all'
import zh_Hans from '@root/i18n/zh-Hans/_all'
import zh_Hant from '@root/i18n/zh-Hant/_all'
import '@formatjs/intl-getcanonicallocales/polyfill'
import '@formatjs/intl-locale/polyfill'
@ -32,6 +33,7 @@ import '@formatjs/intl-numberformat/locale-data/ko'
import '@formatjs/intl-numberformat/locale-data/pt'
import '@formatjs/intl-numberformat/locale-data/vi'
import '@formatjs/intl-numberformat/locale-data/zh-Hans'
import '@formatjs/intl-numberformat/locale-data/zh-Hant'
import '@formatjs/intl-datetimeformat/polyfill'
import '@formatjs/intl-datetimeformat/locale-data/de'
@ -42,6 +44,7 @@ import '@formatjs/intl-datetimeformat/locale-data/ko'
import '@formatjs/intl-datetimeformat/locale-data/pt'
import '@formatjs/intl-datetimeformat/locale-data/vi'
import '@formatjs/intl-datetimeformat/locale-data/zh-Hans'
import '@formatjs/intl-datetimeformat/locale-data/zh-Hant'
import '@formatjs/intl-datetimeformat/add-all-tz'
import '@formatjs/intl-relativetimeformat/polyfill'
@ -53,6 +56,7 @@ import '@formatjs/intl-relativetimeformat/locale-data/ko'
import '@formatjs/intl-relativetimeformat/locale-data/pt'
import '@formatjs/intl-relativetimeformat/locale-data/vi'
import '@formatjs/intl-relativetimeformat/locale-data/zh-Hans'
import '@formatjs/intl-relativetimeformat/locale-data/zh-Hant'
i18n.use(initReactI18next).init({
lng: 'en',
@ -61,7 +65,7 @@ i18n.use(initReactI18next).init({
ns: ['common'],
defaultNS: 'common',
resources: { de, en, it, ja, ko, 'pt-BR': pt_BR, vi, 'zh-Hans': zh_Hans },
resources: { de, en, it, ja, ko, 'pt-BR': pt_BR, vi, 'zh-Hans': zh_Hans, 'zh-Hant': zh_Hant },
returnEmptyString: false,
saveMissing: true,

View File

@ -1,8 +1,8 @@
{
"HTML": {
"accessibilityHint": "",
"expanded": "{{hint}}{{totalLines}}",
"totalLines": "",
"expanded": "{{hint}}{{moreLines}}",
"moreLines": "",
"defaultHint": ""
}
}

View File

@ -1,8 +1,8 @@
{
"HTML": {
"accessibilityHint": "タップして内容を展開または折りたたむ",
"expanded": "{{hint}}{{totalLines}}",
"totalLines": " ({{count}} 行)",
"expanded": "{{hint}}{{moreLines}}",
"moreLines": "",
"defaultHint": "長いトゥート"
}
}

View File

@ -1,8 +1,8 @@
{
"HTML": {
"accessibilityHint": "",
"expanded": "{{hint}}{{totalLines}}",
"totalLines": "",
"expanded": "{{hint}}{{moreLines}}",
"moreLines": "",
"defaultHint": ""
}
}

View File

@ -6,7 +6,8 @@ const LOCALES = {
ko: '한국어',
'pt-BR': 'Português (Brasil)',
vi: 'Tiếng Việt',
'zh-Hans': '简体中文'
'zh-Hans': '简体中文',
'zh-Hant': '繁體中文'
}
export { LOCALES }

View File

@ -1,8 +1,8 @@
{
"HTML": {
"accessibilityHint": "Toque para expandir ou recolher conteúdo",
"expanded": "{{hint}}{{totalLines}}",
"totalLines": "",
"expanded": "{{hint}}{{moreLines}}",
"moreLines": "",
"defaultHint": ""
}
}

View File

@ -1,8 +1,8 @@
{
"HTML": {
"accessibilityHint": "Nhấn để mở rộng hoặc thu gọn nội dung",
"expanded": "{{hint}}{{totalLines}}",
"totalLines": " ({{count}} dòng)",
"expanded": "{{hint}}{{moreLines}}",
"moreLines": "",
"defaultHint": "Tút dài"
}
}

View File

@ -48,7 +48,7 @@
"action": "删除嘟文",
"alert": {
"title": "确认删除?",
"message": "所转发及收藏将被清除,包括所有回复。",
"message": "所转发及收藏将被清除,包括所有回复。",
"buttons": {
"confirm": "确认"
}
@ -58,7 +58,7 @@
"action": "删除嘟文并重新发布",
"alert": {
"title": "确认删除并重新发布?",
"message": "所转发及收藏将被清除,包括所有回复。",
"message": "所转发及收藏将被清除,包括所有回复。",
"buttons": {
"confirm": "确认"
}

View File

@ -1,8 +1,8 @@
{
"HTML": {
"accessibilityHint": "点击展开或折叠内容",
"expanded": "{{hint}}{{totalLines}}",
"totalLines": " ({{count}} 行)",
"expanded": "{{hint}}{{moreLines}}",
"moreLines": "(还有 {{count}} 行)",
"defaultHint": "长嘟文"
}
}

18
src/i18n/zh-Hant/_all.ts Normal file
View File

@ -0,0 +1,18 @@
export default {
common: require('./common'),
screens: require('./screens'),
screenActions: require('./screens/actions'),
screenAnnouncements: require('./screens/announcements'),
screenCompose: require('./screens/compose'),
screenImageViewer: require('./screens/imageViewer'),
screenTabs: require('./screens/tabs'),
componentContextMenu: require('./components/contextMenu'),
componentEmojis: require('./components/emojis'),
componentInstance: require('./components/instance'),
componentMediaSelector: require('./components/mediaSelector'),
componentParse: require('./components/parse'),
componentRelationship: require('./components/relationship'),
componentTimeline: require('./components/timeline')
}

View File

@ -9,7 +9,7 @@
},
"message": {
"success": {
"message": "{{function}} 成功完成"
"message": "{{function}} 成功"
},
"warning": {
"message": ""

View File

@ -1,76 +1,76 @@
{
"accessibilityHint": "",
"accessibilityHint": "更多關於此條嘟文,例如發佈者等",
"account": {
"title": "",
"title": "使用者操作",
"mute": {
"action_false": "",
"action_true": ""
"action_false": "靜音使用者",
"action_true": "解除靜音使用者"
},
"block": {
"action_false": "",
"action_true": ""
"action_false": "封鎖使用者",
"action_true": "解除封鎖使用者"
},
"reports": {
"action": ""
"action": "檢舉並封鎖"
}
},
"copy": {
"action": "",
"succeed": ""
"action": "複製嘟文",
"succeed": "已複製"
},
"instance": {
"title": "",
"title": "站點操作",
"block": {
"action": "",
"action": "封鎖站點 {{instance}}",
"alert": {
"title": "",
"message": "",
"title": "確認封鎖站點 {{instance}}",
"message": "多數情況下,靜音或封鎖特定使用者即可。\n\n封鎖之後來自此站點的所有內容將被移除。",
"buttons": {
"confirm": ""
"confirm": "確認"
}
}
}
},
"share": {
"status": {
"action": ""
"action": "分享嘟文"
},
"account": {
"action": ""
"action": "分享使用者"
}
},
"status": {
"title": "",
"title": "嘟文操作",
"edit": {
"action": ""
"action": "編輯嘟文"
},
"delete": {
"action": "",
"action": "刪除嘟文",
"alert": {
"title": "",
"message": "",
"title": "確認刪除?",
"message": "所有轉嘟及最愛將被清除,也包含所有回覆。",
"buttons": {
"confirm": ""
"confirm": "確認"
}
}
},
"deleteEdit": {
"action": "",
"action": "刪除嘟文並重新發佈",
"alert": {
"title": "",
"message": "",
"title": "確認刪除並重新發佈?",
"message": "所有轉嘟及最愛將被清除,也包含所有回覆。",
"buttons": {
"confirm": ""
"confirm": "確認"
}
}
},
"mute": {
"action_false": "",
"action_true": ""
"action_false": "靜音嘟文及回覆",
"action_true": "解除靜音嘟文及回覆"
},
"pin": {
"action_false": "",
"action_true": ""
"action_false": "釘選嘟文",
"action_true": "取消釘選嘟文"
}
}
}

View File

@ -11,10 +11,10 @@
"domains": "串聯宇宙"
},
"disclaimer": {
"base": ""
"base": "將使用系統內建的瀏覽器來登入tooot 無法讀取您的帳號資訊。"
},
"terms": {
"base": ""
"base": "登入則表示您同意<0>隱私條款</0>和<1>服務條款</1>。"
}
},
"update": {

View File

@ -1,10 +1,10 @@
{
"title": "選擇媒體來源",
"message": "",
"message": "媒體 EXIF 資料不會被上傳",
"options": {
"image": "",
"image_max": "",
"video": "",
"video_max": ""
"image": "上傳圖片",
"image_max": "上傳圖片(最大 {{max}}",
"video": "上傳影片",
"video_max": "上傳影片(最大 {{max}}"
}
}

View File

@ -1,8 +1,8 @@
{
"HTML": {
"accessibilityHint": "",
"expanded": "{{hint}}{{totalLines}}",
"totalLines": "",
"defaultHint": ""
"accessibilityHint": "點擊展開或折疊內容",
"expanded": "{{hint}}{{moreLines}}",
"moreLines": "(還有 {{count}} 行)",
"defaultHint": "長嘟文"
}
}

View File

@ -15,7 +15,7 @@
"message": "上次閱讀於"
},
"refresh": {
"fetchPreviousPage": "",
"fetchPreviousPage": "較新的嘟文",
"refetch": "到最新的位置"
},
"shared": {
@ -30,7 +30,7 @@
"default": "{{name}} 轉嘟了",
"notification": "{{name}} 轉嘟了您的嘟文"
},
"update": ""
"update": "轉嘟已編輯"
},
"actions": {
"reply": {
@ -64,82 +64,82 @@
"accessibilityLabel": "嘟文被編輯了 {{count}} 次",
"accessibilityHint": "點擊查看編輯紀錄",
"text_one": "{{count}} 次編輯",
"text_other": ""
"text_other": "{{count}} 次編輯"
}
},
"attachment": {
"sensitive": {
"button": ""
"button": "顯示敏感內容"
},
"unsupported": {
"text": "",
"button": ""
"text": "載入錯誤",
"button": "嘗試遠端連接"
}
},
"avatar": {
"accessibilityLabel": "",
"accessibilityHint": ""
"accessibilityLabel": "{{name}} 的大頭貼",
"accessibilityHint": "點擊進入 {{name}} 的頁面"
},
"content": {
"expandHint": ""
"expandHint": "隱藏內容"
},
"filtered": "",
"fullConversation": "",
"filtered": "已過濾",
"fullConversation": "閱讀全部對話",
"translate": {
"default": "",
"succeed": "",
"failed": "",
"source_not_supported": "",
"target_not_supported": ""
"default": "翻譯",
"succeed": "由 {{provider}} 翻譯自 {{source}}",
"failed": "翻譯失敗",
"source_not_supported": "不支援嘟文的語言",
"target_not_supported": "不支援目標翻譯語言"
},
"header": {
"shared": {
"account": {
"name": {
"accessibilityHint": ""
"accessibilityHint": "使用者顯示名稱"
},
"account": {
"accessibilityHint": ""
"accessibilityHint": "使用者帳戶"
}
},
"application": "",
"application": "{{application}}",
"edited": {
"accessibilityLabel": ""
"accessibilityLabel": "嘟文已編輯"
},
"muted": {
"accessibilityLabel": ""
"accessibilityLabel": "已靜音此嘟文"
},
"visibility": {
"direct": {
"accessibilityLabel": ""
"accessibilityLabel": "此嘟文是私訊"
},
"private": {
"accessibilityLabel": ""
"accessibilityLabel": "此嘟文僅跟隨者可見"
}
}
},
"conversation": {
"withAccounts": "",
"withAccounts": "@",
"delete": {
"function": ""
"function": "刪除私訊"
}
}
},
"poll": {
"meta": {
"button": {
"vote": "",
"refresh": ""
"vote": "投票",
"refresh": "重新整理"
},
"count": {
"voters_one": "",
"voters_other": "",
"votes_one": "",
"votes_other": ""
"voters_one": "{{count}} 人投票",
"voters_other": "{{count}} 人投票",
"votes_one": "{{count}} 票",
"votes_other": "{{count}} 票"
},
"expiration": {
"expired": "",
"until": ""
"expired": "投票已結束",
"until": "<0 />截止"
}
}
}

View File

@ -1,18 +1,18 @@
{
"screenshot": {
"title": "保護隱私",
"title": "隱私權保護",
"message": "請不要散佈使用者的身份,像是使用者名稱、大頭照等,謝謝你!",
"button": "確認"
},
"localCorrupt": {
"message": "登入狀態已過期,請再登入一次"
"message": "登入狀態已過期,請重新登入"
},
"pushError": {
"message": "推播服務錯誤",
"description": "請在設定重新啟用推播"
"description": "請在設定重新啟用推播"
},
"shareError": {
"imageNotSupported": "",
"videoNotSupported": ""
"imageNotSupported": "不支援 {{type}} 類型的圖片",
"videoNotSupported": "不支援 {{type}} 類型的影片"
}
}

View File

@ -1,6 +1,6 @@
{
"heading": "",
"heading": "分享到...",
"content": {
"select_account": ""
"select_account": "選擇帳號"
}
}

View File

@ -1,19 +1,19 @@
{
"content": {
"altText": {
"heading": ""
"heading": "替代文字"
},
"notificationsFilter": {
"heading": "",
"heading": "顯示通知類型",
"content": {
"follow": "",
"follow_request": "",
"favourite": "",
"reblog": "",
"mention": "",
"poll": "",
"status": "",
"update": ""
"follow": "$t(screenTabs:me.push.follow.heading)",
"follow_request": "跟隨請求",
"favourite": "$t(screenTabs:me.push.favourite.heading)",
"reblog": "$t(screenTabs:me.push.reblog.heading)",
"mention": "$t(screenTabs:me.push.mention.heading)",
"poll": "$t(screenTabs:me.push.poll.heading)",
"status": "訂閱使用者的嘟文",
"update": "轉嘟被編輯"
}
}
}

View File

@ -1,10 +1,10 @@
{
"heading": "",
"heading": "公告",
"content": {
"published": "",
"published": "發佈於 <0 />",
"button": {
"read": "",
"unread": ""
"read": "已讀",
"unread": "標記為已讀"
}
}
}

View File

@ -1,35 +1,35 @@
{
"heading": {
"left": {
"button": "",
"button": "取消",
"alert": {
"title": "",
"title": "確認取消編輯?",
"buttons": {
"save": "",
"delete": "",
"cancel": ""
"save": "儲存草稿",
"delete": "刪除草稿",
"cancel": "取消"
}
}
},
"right": {
"button": {
"default": "",
"conversation": "",
"reply": "",
"deleteEdit": "",
"edit": "",
"share": ""
"default": "發嘟",
"conversation": "發送私訊",
"reply": "發佈回覆",
"deleteEdit": "發嘟",
"edit": "發嘟",
"share": "發嘟"
},
"alert": {
"default": {
"title": "",
"button": ""
"title": "發嘟失敗",
"button": "再試一次"
},
"removeReply": {
"title": "",
"description": "",
"cancel": "",
"confirm": ""
"title": "回覆的嘟文不存在",
"description": "回覆的嘟文可能已被刪除。確認移除回覆嘟文的關聯?",
"cancel": "$t(common:buttons.cancel)",
"confirm": "移除關聯"
}
}
}
@ -37,143 +37,143 @@
"content": {
"root": {
"header": {
"postingAs": "",
"postingAs": "以 @{{acct}}@{{domain}} 發嘟",
"spoilerInput": {
"placeholder": ""
"placeholder": "警告訊息"
},
"textInput": {
"placeholder": "",
"placeholder": "正在想些什麼嗎?",
"keyboardImage": {
"exceedMaximum": {
"title": "",
"OK": ""
"title": "已達附件數量上限",
"OK": "$t(common:buttons.OK)"
}
}
}
},
"footer": {
"attachments": {
"sensitive": "",
"sensitive": "標記附件為敏感內容",
"remove": {
"accessibilityLabel": ""
"accessibilityLabel": "刪除已上傳的附件,序號 {{attachment}}"
},
"edit": {
"accessibilityLabel": ""
"accessibilityLabel": "編輯已上傳的附件,序號 {{attachment}}"
},
"upload": {
"accessibilityLabel": ""
"accessibilityLabel": "上傳更多附件"
}
},
"emojis": {
"accessibilityHint": ""
"accessibilityHint": "點擊新增表情符號到嘟文"
},
"poll": {
"option": {
"placeholder": {
"accessibilityLabel": "",
"single": "",
"multiple": ""
"accessibilityLabel": "投票選項 {{index}}",
"single": "單選題",
"multiple": "複選題"
}
},
"quantity": {
"reduce": {
"accessibilityLabel": "",
"accessibilityHint": ""
"accessibilityLabel": "減少至 {{amount}} 選項",
"accessibilityHint": "已達到最低選項數,目前有 {{amount}} 選項"
},
"increase": {
"accessibilityLabel": "",
"accessibilityHint": ""
"accessibilityLabel": "增加至 {{amount}} 選項",
"accessibilityHint": "已達到最高選項數,目前有 {{amount}} 選項"
}
},
"multiple": {
"heading": "",
"heading": "選擇類型",
"options": {
"single": "",
"multiple": "",
"cancel": ""
"single": "單選題",
"multiple": "複選題",
"cancel": "$t(common:buttons.cancel)"
}
},
"expiration": {
"heading": "",
"heading": "結束時間",
"options": {
"300": "",
"1800": "",
"3600": "",
"21600": "",
"86400": "",
"259200": "",
"604800": "",
"cancel": ""
"300": "5 分鐘",
"1800": "30 分鐘",
"3600": "1 小時",
"21600": "6 小時",
"86400": "1 天",
"259200": "3 天",
"604800": "7 天",
"cancel": "$t(common:buttons.cancel)"
}
}
}
},
"actions": {
"attachment": {
"accessibilityLabel": "",
"accessibilityHint": "",
"accessibilityLabel": "上傳附件",
"accessibilityHint": "當有附件時,投票功能將被禁用",
"failed": {
"alert": {
"title": "",
"button": ""
"title": "上傳失敗",
"button": "再試一次"
}
}
},
"poll": {
"accessibilityLabel": "",
"accessibilityHint": ""
"accessibilityLabel": "新增投票",
"accessibilityHint": "當啟用投票功能時,附件功能將被禁用"
},
"visibility": {
"accessibilityLabel": "",
"title": "",
"accessibilityLabel": "此嘟文公開範圍為 {{visibility}}",
"title": "嘟文公開範圍",
"options": {
"public": "",
"unlisted": "",
"private": "",
"direct": "",
"cancel": ""
"public": "公開",
"unlisted": "不公開",
"private": "僅限跟隨者",
"direct": "私訊",
"cancel": "$t(common:buttons.cancel)"
}
},
"spoiler": {
"accessibilityLabel": ""
"accessibilityLabel": "劇透"
},
"emoji": {
"accessibilityLabel": "",
"accessibilityHint": ""
"accessibilityLabel": "新增表情符號",
"accessibilityHint": "打開表情選擇面板,水平滑動切換頁面"
}
},
"drafts_one": "",
"drafts_other": ""
"drafts_one": "草稿 ({{count}})",
"drafts_other": "草稿 ({{count}})"
},
"editAttachment": {
"header": {
"title": "",
"title": "編輯附件",
"right": {
"accessibilityLabel": "",
"accessibilityLabel": "儲存編輯附件",
"failed": {
"title": "",
"button": ""
"title": "編輯失敗",
"button": "再試一次"
}
}
},
"content": {
"altText": {
"heading": "",
"placeholder": ""
"heading": "為附件增加文字說明",
"placeholder": "你可以為附件增加文字說明,以便更多人可以查看他們(包括視力障礙或視力受損人士)。\n\n優質的描述應該簡潔明瞭但要準確地描述照片中的內容以便使用者理解其含義。"
},
"imageFocus": ""
"imageFocus": "在預覽圖上拖動圓圈,以選擇縮略圖的焦點"
}
},
"draftsList": {
"header": {
"title": ""
"title": "草稿"
},
"warning": "",
"warning": "草稿只儲存在你的設備上,在部分情況下可能丟失。建議不要長期儲存草稿。",
"content": {
"accessibilityHint": "",
"textEmpty": ""
"accessibilityHint": "已儲存的草稿,點擊編輯此草稿",
"textEmpty": "沒有內容"
},
"checkAttachment": ""
"checkAttachment": "正在檢查伺服器上的附件..."
}
}
}

View File

@ -1,17 +1,17 @@
{
"content": {
"actions": {
"accessibilityLabel": "",
"accessibilityHint": ""
"accessibilityLabel": "更多此圖片的操作",
"accessibilityHint": "您可以儲存或分享此圖片"
},
"options": {
"save": "",
"share": "",
"cancel": ""
"save": "儲存圖片",
"share": "分享圖片",
"cancel": "$t(common:buttons.cancel)"
},
"save": {
"succeed": "",
"failed": ""
"succeed": "圖片已儲存",
"failed": "儲存圖片失敗"
}
}
}

View File

@ -25,8 +25,8 @@
},
"notifications": {
"filter": {
"accessibilityLabel": "篩選器",
"accessibilityHint": ""
"accessibilityLabel": "過濾器",
"accessibilityHint": "過濾顯示的通知類型"
}
},
"me": {
@ -44,7 +44,7 @@
"name": "嘟文字體大小"
},
"language": {
"name": ""
"name": "語言"
},
"lists": {
"name": "清單"
@ -78,276 +78,276 @@
}
},
"fontSize": {
"demo": "",
"demo": "<p>這是一條測試用的嘟文😊。以下是可供選擇的字體大小,從小至超大。<br /><br />這個設定僅會調整嘟文的本身字體大小,不影響其它字體大小。</p>",
"sizes": {
"S": "",
"M": "",
"L": "",
"XL": "",
"XXL": ""
"S": "",
"M": "M - 預設",
"L": "",
"XL": "超大",
"XXL": "特大"
}
},
"profile": {
"cancellation": {
"title": "",
"message": "",
"title": "變更尚未儲存",
"message": "您的變更尚未儲存。是否放棄儲存變更?",
"buttons": {
"cancel": "",
"discard": ""
"cancel": "$t(common:buttons.cancel)",
"discard": "不儲存"
}
},
"feedback": {
"succeed": "",
"failed": ""
"succeed": "{{type}} 已更新",
"failed": "{{type}} 更新失敗,請重試。"
},
"root": {
"name": {
"title": ""
"title": "顯示名稱"
},
"avatar": {
"title": "",
"description": ""
"title": "大頭貼",
"description": "會按比例縮小成 400x400 像素"
},
"header": {
"title": "",
"description": ""
"title": "頁面頂端",
"description": "會按比例縮小成 1500x500 像素"
},
"note": {
"title": ""
"title": "簡介"
},
"fields": {
"title": "描述資料",
"total_one": "",
"total_other": ""
"total_one": "{{count}} 項",
"total_other": "{{count}} 項"
},
"visibility": {
"title": "",
"title": "嘟文預設公開範圍",
"options": {
"public": "",
"unlisted": "",
"private": "",
"cancel": ""
"public": "公開",
"unlisted": "不公開",
"private": "僅限跟隨者",
"cancel": "$t(common:buttons.cancel)"
}
},
"sensitive": {
"title": ""
"title": "媒體預設標為敏感"
},
"lock": {
"title": "",
"description": ""
"title": "鎖定帳號",
"description": "需要您手動批准跟隨請求"
},
"bot": {
"title": "",
"description": ""
"title": "機器人帳號",
"description": "此帳號主要執行自動操作且可能未被監控"
}
},
"fields": {
"group": "",
"label": "",
"content": ""
"group": "第 {{index}} 組",
"label": "標籤",
"content": "內容"
},
"mediaSelectionFailed": ""
"mediaSelectionFailed": "圖片處理失敗,請重試"
},
"push": {
"notAvailable": "",
"notAvailable": "您的手機不支援 tooot 推播通知",
"enable": {
"direct": "",
"settings": ""
"direct": "啟用推播通知",
"settings": "在設定中啟用"
},
"global": {
"heading": "",
"description": ""
"heading": "啟用 {{acct}}",
"description": "通知訊息將經由 tooot 伺服器轉發"
},
"decode": {
"heading": "",
"description": ""
"heading": "顯示通知內容",
"description": "經由 tooot 伺服器轉發的通知訊息已被加密,但可以允許 tooot 伺服器解密並轉發訊息。tooot 訊息伺服器為開放原始碼,且不儲存任何日誌。"
},
"default": {
"heading": ""
"heading": "預設"
},
"follow": {
"heading": ""
"heading": "新的跟隨者"
},
"follow_request": {
"heading": ""
"heading": "跟隨請求"
},
"favourite": {
"heading": ""
"heading": "嘟文被喜歡"
},
"reblog": {
"heading": ""
"heading": "嘟文被轉嘟"
},
"mention": {
"heading": ""
"heading": "嘟文提及您"
},
"poll": {
"heading": ""
"heading": "投票更新"
},
"status": {
"heading": ""
"heading": "訂閱使用者的嘟文"
},
"howitworks": ""
"howitworks": "了解通知訊息轉發如何工作"
},
"root": {
"announcements": {
"content": {
"unread": "",
"read": "",
"empty": ""
"unread": "{{amount}} 條未讀",
"read": "全部已讀",
"empty": ""
}
},
"push": {
"content": {
"enabled": "",
"disabled": ""
"enabled": "啟用",
"disabled": "關閉"
}
},
"update": {
"title": ""
"title": "已更新到最新版本"
},
"logout": {
"button": "",
"button": "登出",
"alert": {
"title": "",
"message": "",
"title": "確定要登出?",
"message": "登出後,需要重新驗證帳號",
"buttons": {
"logout": "",
"cancel": ""
"logout": "登出",
"cancel": "$t(common:buttons.cancel)"
}
}
}
},
"settings": {
"fontsize": {
"heading": "",
"heading": "$t(me.stacks.fontSize.name)",
"content": {
"S": "",
"M": "",
"L": "",
"XL": "",
"XXL": ""
"S": "$t(me.fontSize.sizes.S)",
"M": "$t(me.fontSize.sizes.M)",
"L": "$t(me.fontSize.sizes.L)",
"XL": "$t(me.fontSize.sizes.XL)",
"XXL": "$t(me.fontSize.sizes.XXL)"
}
},
"language": {
"heading": "",
"heading": "$t(me.stacks.language.name)",
"options": {
"cancel": ""
"cancel": "$t(common:buttons.cancel)"
}
},
"theme": {
"heading": "",
"heading": "外觀",
"options": {
"auto": "",
"light": "",
"dark": "",
"cancel": ""
"auto": "跟隨系統",
"light": "淺色模式",
"dark": "深色模式",
"cancel": "$t(common:buttons.cancel)"
}
},
"darkTheme": {
"heading": "",
"heading": "深色主題",
"options": {
"lighter": "",
"darker": "",
"cancel": ""
"lighter": "暗淡",
"darker": "暗黑",
"cancel": "$t(common:buttons.cancel)"
}
},
"browser": {
"heading": "",
"heading": "開啟連結",
"options": {
"internal": "",
"external": "",
"cancel": ""
"internal": "從應用程式內開啟",
"external": "使用系統瀏覽器開啟",
"cancel": "$t(common:buttons.cancel)"
}
},
"staticEmoji": {
"heading": "",
"description": ""
"heading": "使用靜態表情",
"description": "如果您在查看表情列表時經常遇到程式無預警退出,您可以嘗試使用靜態表情。"
},
"feedback": {
"heading": ""
"heading": "功能建議"
},
"support": {
"heading": ""
"heading": "贊助 tooot 開發"
},
"review": {
"heading": ""
"heading": "給 tooot 評分"
},
"contact": {
"heading": ""
"heading": "聯繫 tooot"
},
"analytics": {
"heading": "",
"description": ""
"heading": "幫助我們改善",
"description": "僅收集不與使用者關聯的資料"
},
"version": "",
"instanceVersion": ""
"version": "Version v{{version}}",
"instanceVersion": "Mastodon version v{{version}}"
},
"switch": {
"existing": "",
"new": ""
"existing": "選擇已登入的帳號",
"new": "登入新站點"
}
},
"shared": {
"account": {
"actions": {
"accessibilityLabel": "",
"accessibilityHint": ""
"accessibilityLabel": "對使用者 {{user}} 的操作",
"accessibilityHint": "您可以靜音、封鎖、檢舉或分享此使用者"
},
"followed_by": "",
"moved": "",
"created_at": "",
"followed_by": " 正在跟隨你",
"moved": "使用者已轉移",
"created_at": "加入於:{{date}}",
"summary": {
"statuses_count": "",
"following_count": "",
"followers_count": ""
"statuses_count": "{{count}} 條嘟文",
"following_count": "$t(shared.users.accounts.following)",
"followers_count": "$t(shared.users.accounts.followers)"
},
"toots": {
"default": "",
"all": ""
"default": "嘟文",
"all": "嘟文與回覆"
}
},
"attachments": {
"name": ""
"name": "<0 /><1>的媒體</1>"
},
"search": {
"header": {
"prefix": "",
"placeholder": ""
"prefix": "搜尋",
"placeholder": "什麼呢"
},
"empty": {
"general": "",
"general": "輸入關鍵字搜尋<bold>$t(screenTabs:shared.search.sections.accounts)</bold>、<bold>$t(screenTabs:shared.search.sections.hashtags)</bold>或<bold>$t(screenTabs:shared.search.sections.statuses)</bold>",
"advanced": {
"header": "",
"header": "進階搜尋",
"example": {
"account": "",
"hashtag": "",
"statusLink": "",
"accountLink": ""
"account": "$t(shared.search.header.prefix) $t(shared.search.sections.accounts)",
"hashtag": "$t(shared.search.header.prefix) $t(shared.search.sections.hashtags)",
"statusLink": "$t(shared.search.header.prefix) $t(shared.search.sections.statuses)",
"accountLink": "$t(shared.search.header.prefix) $t(shared.search.sections.accounts)"
}
}
},
"sections": {
"accounts": "",
"hashtags": "",
"statuses": ""
"accounts": "使用者",
"hashtags": "主題標籤",
"statuses": "嘟文"
},
"notFound": ""
"notFound": "找不到 <bold>{{searchTerm}}</bold> 相關的 {{type}}"
},
"toot": {
"name": ""
"name": "討論"
},
"users": {
"accounts": {
"following": "",
"followers": ""
"following": "正在跟隨 {{count}} 人",
"followers": "被 {{count}} 人跟隨"
},
"statuses": {
"reblogged_by": "",
"favourited_by": ""
"reblogged_by": "{{count}} 人轉嘟",
"favourited_by": "{{count}} 人喜歡"
}
},
"history": {
"name": ""
"name": "編輯歷史"
}
}
}

View File

@ -5,22 +5,18 @@ import { RootStackParamList } from '@utils/navigation/navigators'
import { Theme } from '@utils/styles/themes'
import * as FileSystem from 'expo-file-system'
import i18next from 'i18next'
import { RefObject } from 'react'
import { PermissionsAndroid, Platform } from 'react-native'
import FlashMessage from 'react-native-flash-message'
type CommonProps = {
messageRef: RefObject<FlashMessage>
theme: Theme
image: RootStackParamList['Screen-ImagesViewer']['imageUrls'][0]
}
const saveIos = async ({ messageRef, theme, image }: CommonProps) => {
const saveIos = async ({ theme, image }: CommonProps) => {
CameraRoll.save(image.url)
.then(() => {
haptics('Success')
displayMessage({
ref: messageRef,
theme,
type: 'success',
message: i18next.t('screenImageViewer:content.save.succeed')
@ -32,7 +28,6 @@ const saveIos = async ({ messageRef, theme, image }: CommonProps) => {
.then(() => {
haptics('Success')
displayMessage({
ref: messageRef,
theme,
type: 'success',
message: i18next.t('screenImageViewer:content.save.succeed')
@ -41,7 +36,6 @@ const saveIos = async ({ messageRef, theme, image }: CommonProps) => {
.catch(() => {
haptics('Error')
displayMessage({
ref: messageRef,
theme,
type: 'error',
message: i18next.t('screenImageViewer:content.save.failed')
@ -50,7 +44,6 @@ const saveIos = async ({ messageRef, theme, image }: CommonProps) => {
} else {
haptics('Error')
displayMessage({
ref: messageRef,
theme,
type: 'error',
message: i18next.t('screenImageViewer:content.save.failed')
@ -59,7 +52,7 @@ const saveIos = async ({ messageRef, theme, image }: CommonProps) => {
})
}
const saveAndroid = async ({ messageRef, theme, image }: CommonProps) => {
const saveAndroid = async ({ theme, image }: CommonProps) => {
const fileUri: string = `${FileSystem.documentDirectory}${image.id}.jpg`
const downloadedFile: FileSystem.FileSystemDownloadResult =
await FileSystem.downloadAsync(image.url, fileUri)
@ -67,7 +60,6 @@ const saveAndroid = async ({ messageRef, theme, image }: CommonProps) => {
if (downloadedFile.status != 200) {
haptics('Error')
displayMessage({
ref: messageRef,
theme,
type: 'error',
message: i18next.t('screenImageViewer:content.save.failed')
@ -83,7 +75,6 @@ const saveAndroid = async ({ messageRef, theme, image }: CommonProps) => {
if (status !== 'granted') {
haptics('Error')
displayMessage({
ref: messageRef,
theme,
type: 'error',
message: i18next.t('screenImageViewer:content.save.failed')
@ -96,7 +87,6 @@ const saveAndroid = async ({ messageRef, theme, image }: CommonProps) => {
.then(() => {
haptics('Success')
displayMessage({
ref: messageRef,
theme,
type: 'success',
message: i18next.t('screenImageViewer:content.save.succeed')
@ -105,7 +95,6 @@ const saveAndroid = async ({ messageRef, theme, image }: CommonProps) => {
.catch(() => {
haptics('Error')
displayMessage({
ref: messageRef,
theme,
type: 'error',
message: i18next.t('screenImageViewer:content.save.failed')

View File

@ -1,7 +1,6 @@
import analytics from '@components/analytics'
import GracefullyImage from '@components/GracefullyImage'
import { HeaderCenter, HeaderLeft, HeaderRight } from '@components/Header'
import { Message } from '@components/Message'
import { useActionSheet } from '@expo/react-native-action-sheet'
import { RootStackScreenProps } from '@utils/navigation/navigators'
import { useTheme } from '@utils/styles/ThemeManager'
@ -23,6 +22,7 @@ import {
FlingGestureHandler,
LongPressGestureHandler
} from 'react-native-gesture-handler'
import { LiveTextImageView } from 'react-native-live-text-image-view'
import { Zoom, createZoomListComponent } from 'react-native-reanimated-zoom'
import { SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context'
import saveImage from './ImageViewer/save'
@ -51,7 +51,6 @@ const ScreenImagesViewer = ({
const initialIndex = imageUrls.findIndex(image => image.id === id)
const [currentIndex, setCurrentIndex] = useState(initialIndex)
const listRef = useRef<FlatList>(null)
const messageRef = useRef<FlashMessage>(null)
const { showActionSheetWithOptions } = useActionSheet()
@ -71,7 +70,7 @@ const ScreenImagesViewer = ({
switch (buttonIndex) {
case 0:
analytics('imageviewer_more_save_press')
saveImage({ messageRef, theme, image: imageUrls[currentIndex] })
saveImage({ theme, image: imageUrls[currentIndex] })
break
case 1:
analytics('imageviewer_more_share_press')
@ -117,6 +116,7 @@ const ScreenImagesViewer = ({
justifyContent: 'center'
}}
>
<LiveTextImageView>
<GracefullyImage
uri={{ preview: item.preview_url, remote: item.remote_url, original: item.url }}
blurhash={item.blurhash}
@ -131,6 +131,7 @@ const ScreenImagesViewer = ({
: (SCREEN_WIDTH / imageWidth) * imageHeight
}}
/>
</LiveTextImageView>
</View>
}
/>
@ -193,11 +194,7 @@ const ScreenImagesViewer = ({
switch (buttonIndex) {
case 0:
analytics('imageviewer_more_save_press')
saveImage({
messageRef,
theme,
image: imageUrls[currentIndex]
})
saveImage({ theme, image: imageUrls[currentIndex] })
break
case 1:
analytics('imageviewer_more_share_press')
@ -236,7 +233,6 @@ const ScreenImagesViewer = ({
/>
</LongPressGestureHandler>
</FlingGestureHandler>
<Message ref={messageRef} />
</SafeAreaProvider>
)
}

View File

@ -7069,6 +7069,11 @@ react-native-language-detection@^0.1.0:
resolved "https://registry.yarnpkg.com/react-native-language-detection/-/react-native-language-detection-0.1.0.tgz#06b5d20bffb60dbbd599c8e62b6acf500952afa8"
integrity sha512-26CLndVMmMbVp40Y9Herza73nfR08JFTcYkJ3MX5MIQbGRoqgNAG89z8pA1y7dPHHK1Nfa6AWKAYpNv7tMRCaw==
react-native-live-text-image-view@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/react-native-live-text-image-view/-/react-native-live-text-image-view-0.4.0.tgz#d23d5850788609fd1448533213fc6c453c584761"
integrity sha512-PhVFE0YogSLrTlnHIxUWL80CrmbDvxk1JvLx4UHiRHRwLda4dV/e/9Q+Pyh7Vq7qwAPE6vGoN6sjbXNaj4WCew==
react-native-pager-view@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/react-native-pager-view/-/react-native-pager-view-6.0.1.tgz#353abf38d3c2b91ed7c586f10af0f94700f5b1dc"