diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 42ee26b5..330e04a4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,7 +25,7 @@ jobs: run: bundle install - name: -- Step 5 -- Run fastlane env: - DEVELOPER_DIR: /Applications/Xcode_14.0.1.app/Contents/Developer + DEVELOPER_DIR: /Applications/Xcode_14.1.app/Contents/Developer ENVIRONMENT: ${{ steps.branch.outputs.branch }} SENTRY_ENVIRONMENT: ${{ steps.branch.outputs.branch }} LC_ALL: en_US.UTF-8 diff --git a/README.md b/README.md index 551b20e3..83aad20c 100644 --- a/README.md +++ b/README.md @@ -23,4 +23,6 @@ Please **do not** create a pull request to update translation. tooot's translati [@duy@mas.to](https://mas.to/@duy) for Vietnamese translation +[@jimmyorz](https://github.com/jimmyorz) for Traditional Chinese translation + [@jk@mastodon.social](https://mastodon.social/@jk) for the famous Mastodon boop sound diff --git a/package.json b/package.json index 3267ad27..40860e42 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tooot", - "version": "4.5.0", + "version": "4.5.1", "description": "tooot for Mastodon", "author": "xmflsct ", "license": "GPL-3.0-or-later", diff --git a/src/App.tsx b/src/App.tsx index d88682bf..01275460 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,5 @@ import { ActionSheetProvider } from '@expo/react-native-action-sheet' +import getLanguage from '@helpers/getLanguage' import queryClient from '@helpers/queryClient' import i18n from '@root/i18n/i18n' import Screens from '@root/Screens' @@ -12,7 +13,7 @@ import timezone from '@root/startup/timezone' import { persistor, store } from '@root/store' import * as Sentry from '@sentry/react-native' import AccessibilityManager from '@utils/accessibility/AccessibilityManager' -import { changeLanguage, getSettingsLanguage } from '@utils/slices/settingsSlice' +import { changeLanguage } from '@utils/slices/settingsSlice' import ThemeManager from '@utils/styles/ThemeManager' import * as Localization from 'expo-localization' import * as SplashScreen from 'expo-splash-screen' @@ -83,10 +84,7 @@ const App: React.FC = () => { if (bootstrapped) { log('log', 'App', 'loading actual app :)') log('log', 'App', `Locale: ${Localization.locale}`) - const language = - Platform.OS === 'ios' - ? Localization.locale - : getSettingsLanguage(store.getState()) + const language = getLanguage() if (!language) { if (Platform.OS !== 'ios') { store.dispatch(changeLanguage('en')) diff --git a/src/api/general.ts b/src/api/general.ts index 35b971dd..29e49158 100644 --- a/src/api/general.ts +++ b/src/api/general.ts @@ -1,6 +1,6 @@ import axios from 'axios' -import Constants from 'expo-constants' import handleError, { ctx } from './handleError' +import { userAgent } from './helpers' export type Params = { method: 'get' | 'post' | 'put' | 'delete' @@ -44,8 +44,8 @@ const apiGeneral = async ({ body && body instanceof FormData ? 'multipart/form-data' : 'application/json', - 'User-Agent': `tooot/${Constants.expoConfig?.version}`, Accept: '*/*', + ...userAgent, ...headers }, ...(body && { data: body }) diff --git a/src/api/helpers/index.ts b/src/api/helpers/index.ts new file mode 100644 index 00000000..799b7d11 --- /dev/null +++ b/src/api/helpers/index.ts @@ -0,0 +1,6 @@ +import Constants from "expo-constants" +import { Platform } from "react-native" + +const userAgent = { 'User-Agent': `tooot/${Constants.expoConfig?.version} ${Platform.OS}/${Platform.Version}` } + +export { userAgent } \ No newline at end of file diff --git a/src/api/instance.ts b/src/api/instance.ts index c15d5bcc..6df9974d 100644 --- a/src/api/instance.ts +++ b/src/api/instance.ts @@ -1,8 +1,8 @@ import { RootState } from '@root/store' import axios, { AxiosRequestConfig } from 'axios' -import Constants from 'expo-constants' import li from 'li' import handleError, { ctx } from './handleError' +import { userAgent } from './helpers' export type Params = { method: 'get' | 'post' | 'put' | 'delete' | 'patch' @@ -53,13 +53,13 @@ const apiInstance = async ({ console.log( ctx.bgGreen.bold(' API instance ') + - ' ' + - domain + - ' ' + - method + - ctx.green(' -> ') + - `/${url}` + - (params ? ctx.green(' -> ') : ''), + ' ' + + domain + + ' ' + + method + + ctx.green(' -> ') + + `/${url}` + + (params ? ctx.green(' -> ') : ''), params ? params : '' ) @@ -74,8 +74,8 @@ const apiInstance = async ({ body && body instanceof FormData ? 'multipart/form-data' : 'application/json', - 'User-Agent': `tooot/${Constants.expoConfig?.version}`, Accept: '*/*', + ...userAgent, ...headers, ...(token && { Authorization: `Bearer ${token}` diff --git a/src/api/tooot.ts b/src/api/tooot.ts index 09a8e6d7..96f0ed66 100644 --- a/src/api/tooot.ts +++ b/src/api/tooot.ts @@ -1,8 +1,8 @@ import * as Sentry from '@sentry/react-native' import { mapEnvironment } from '@utils/checkEnvironment' import axios from 'axios' -import Constants from 'expo-constants' import handleError, { ctx } from './handleError' +import { userAgent } from './helpers' export type Params = { method: 'get' | 'post' | 'put' | 'delete' @@ -50,13 +50,11 @@ const apiTooot = async ({ body && body instanceof FormData ? 'multipart/form-data' : 'application/json', - 'User-Agent': `tooot/${Constants.expoConfig?.version}`, Accept: '*/*', + ...userAgent, ...headers }, - ...(body && { data: body }), - validateStatus: status => - url.includes('translate') ? status < 500 : status === 200 + ...(body && { data: body }) }) .then(response => { return Promise.resolve({ diff --git a/src/components/ContextMenu/account.ts b/src/components/ContextMenu/account.ts index 53a9aa44..e9fe2c2d 100644 --- a/src/components/ContextMenu/account.ts +++ b/src/components/ContextMenu/account.ts @@ -174,6 +174,12 @@ const contextMenuAccount = ({ id: accountId, payload: { property: 'reports' } }) + mutation.mutate({ + type: 'updateAccountProperty', + queryKey, + id: accountId, + payload: { property: 'block', currentValue: false } + }) } } } diff --git a/src/components/Timeline/Shared/Translate.tsx b/src/components/Timeline/Shared/Translate.tsx index 29a2864c..fcabf8a1 100644 --- a/src/components/Timeline/Shared/Translate.tsx +++ b/src/components/Timeline/Shared/Translate.tsx @@ -1,8 +1,8 @@ import analytics from '@components/analytics' import { ParseHTML } from '@components/Parse' import CustomText from '@components/Text' +import getLanguage from '@helpers/getLanguage' import { useTranslateQuery } from '@utils/queryHooks/translate' -import { getSettingsLanguage } from '@utils/slices/settingsSlice' import { StyleConstants } from '@utils/styles/constants' import { useTheme } from '@utils/styles/ThemeManager' import * as Localization from 'expo-localization' @@ -11,14 +11,10 @@ import { useTranslation } from 'react-i18next' import { Pressable } from 'react-native' import { Circle } from 'react-native-animated-spinkit' import detectLanguage from 'react-native-language-detection' -import { useSelector } from 'react-redux' export interface Props { highlighted: boolean - status: Pick< - Mastodon.Status, - 'language' | 'spoiler_text' | 'content' | 'emojis' - > + status: Pick } const TimelineTranslate = React.memo( @@ -30,9 +26,7 @@ const TimelineTranslate = React.memo( const { t } = useTranslation('componentTimeline') const { colors } = useTheme() - const text = status.spoiler_text - ? [status.spoiler_text, status.content] - : [status.content] + const text = status.spoiler_text ? [status.spoiler_text, status.content] : [status.content] for (const i in text) { for (const emoji of status.emojis) { @@ -56,7 +50,7 @@ const TimelineTranslate = React.memo( detect() }, []) - const settingsLanguage = useSelector(getSettingsLanguage) + const settingsLanguage = getLanguage() const targetLanguage = settingsLanguage?.startsWith('en') ? Localization.locale || settingsLanguage || 'en' : settingsLanguage || Localization.locale || 'en' @@ -107,12 +101,7 @@ const TimelineTranslate = React.memo( {isError @@ -127,9 +116,7 @@ const TimelineTranslate = React.memo( : t('shared.translate.default')} - {__DEV__ - ? ` Source: ${detectedLanguage}; Target: ${targetLanguage}` - : undefined} + {__DEV__ ? ` Source: ${detectedLanguage}; Target: ${targetLanguage}` : undefined} {isLoading ? ( { + return Platform.OS === 'ios' + ? Localization.locale + : getSettingsLanguage(store.getState()) +} + +export default getLanguage \ No newline at end of file diff --git a/src/i18n/vi/components/parse.json b/src/i18n/vi/components/parse.json index b27596b7..d2560ac5 100644 --- a/src/i18n/vi/components/parse.json +++ b/src/i18n/vi/components/parse.json @@ -2,7 +2,7 @@ "HTML": { "accessibilityHint": "Nhấn để mở rộng hoặc thu gọn nội dung", "expanded": "{{hint}}{{moreLines}}", - "moreLines": "", + "moreLines": " ({{count}} dòng nữa)", "defaultHint": "Tút dài" } } \ No newline at end of file diff --git a/src/i18n/vi/components/timeline.json b/src/i18n/vi/components/timeline.json index ddc59ca6..236e157f 100644 --- a/src/i18n/vi/components/timeline.json +++ b/src/i18n/vi/components/timeline.json @@ -40,9 +40,9 @@ "accessibilityLabel": "Đăng lại tút này", "function": "Đăng lại tút", "options": { - "title": "", - "public": "", - "unlisted": "" + "title": "Kiểu đăng lại", + "public": "Đăng lại công khai", + "unlisted": "Đăng lại hạn chế" } }, "favourited": { diff --git a/src/i18n/zh-Hant/components/instance.json b/src/i18n/zh-Hant/components/instance.json index 55797647..7acbe363 100644 --- a/src/i18n/zh-Hant/components/instance.json +++ b/src/i18n/zh-Hant/components/instance.json @@ -14,13 +14,13 @@ "base": "將使用系統內建的瀏覽器來登入,tooot 無法讀取您的帳號資訊。" }, "terms": { - "base": "登入則表示您同意<0>隱私條款和<1>服務條款。" + "base": "登入則表示您同意<0>隱私政策和<1>使用條款。" } }, "update": { "alert": { "title": "已登入站點", - "message": "您可以多登入其他的帳號,已登入的帳號會被保留", + "message": "您可以登入其它的帳號,已登入的帳號會被保留", "buttons": { "cancel": "$t(common:buttons.cancel)", "continue": "繼續" diff --git a/src/i18n/zh-Hant/components/mediaSelector.json b/src/i18n/zh-Hant/components/mediaSelector.json index dc3758fb..509d1f4e 100644 --- a/src/i18n/zh-Hant/components/mediaSelector.json +++ b/src/i18n/zh-Hant/components/mediaSelector.json @@ -1,10 +1,10 @@ { "title": "選擇媒體來源", - "message": "媒體 EXIF 資料不會被上傳", + "message": "媒體 Exif 資訊不會被上傳", "options": { "image": "上傳圖片", - "image_max": "上傳圖片(最多 {{max}})", + "image_max": "上傳圖片(最多 {{max}} 張)", "video": "上傳影片", - "video_max": "上傳影片(最多 {{max}})" + "video_max": "上傳影片(最多 {{max}} 個)" } } \ No newline at end of file diff --git a/src/i18n/zh-Hant/components/timeline.json b/src/i18n/zh-Hant/components/timeline.json index c2b1ad4f..a1bf4529 100644 --- a/src/i18n/zh-Hant/components/timeline.json +++ b/src/i18n/zh-Hant/components/timeline.json @@ -22,9 +22,9 @@ "actioned": { "pinned": "置頂", "favourite": "{{name}} 把您的嘟文加入了最愛", - "status": "{{name}} 正發了嘟", - "follow": "{{name}} 追隨您了", - "follow_request": "{{name}} 要求您允許他的追隨", + "status": "{{name}} 剛剛嘟文", + "follow": "{{name}} 跟隨了您", + "follow_request": "{{name}} 要求跟隨您", "poll": "您曾投過的投票已經結束", "reblog": { "default": "{{name}} 轉嘟了", diff --git a/src/i18n/zh-Hant/screens/tabs.json b/src/i18n/zh-Hant/screens/tabs.json index 5da0f1b2..ad026420 100644 --- a/src/i18n/zh-Hant/screens/tabs.json +++ b/src/i18n/zh-Hant/screens/tabs.json @@ -1,7 +1,7 @@ { "tabs": { "local": { - "name": "追隨中" + "name": "跟隨中" }, "public": { "name": "", @@ -47,16 +47,16 @@ "name": "語言" }, "lists": { - "name": "清單" + "name": "列表" }, "list": { - "name": "清單: {{list}}" + "name": "列表:{{list}}" }, "push": { "name": "推播通知" }, "profile": { - "name": "編輯個人資料" + "name": "編輯個人檔案" }, "profileName": { "name": "編輯顯示名稱" @@ -71,20 +71,20 @@ "name": "App 設定" }, "webSettings": { - "name": "更多的帳號設定" + "name": "更多帳號設定" }, "switch": { "name": "切換帳號" } }, "fontSize": { - "demo": "

這是一條測試用的嘟文😊。以下是可供選擇的字體大小,從小至超大。

這個設定僅會調整嘟文的本身字體大小,不影響其它字體大小。

", + "demo": "

這是一條測試用的嘟文😊。以下是可供選擇的字體大小,從小到超大。

這個設定僅會調整嘟文本身的字體大小,不影響其它介面的字體大小。

", "sizes": { "S": "小", - "M": "M - 預設", + "M": "中 (預設)", "L": "大", - "XL": "超大", - "XXL": "特大" + "XL": "特大", + "XXL": "超大" } }, "profile": { @@ -277,7 +277,7 @@ }, "analytics": { "heading": "幫助我們改善", - "description": "僅收集不與使用者關聯的資料" + "description": "僅收集不與使用者相關聯的資料" }, "version": "Version v{{version}}", "instanceVersion": "Mastodon version v{{version}}" diff --git a/src/utils/queryHooks/timeline.ts b/src/utils/queryHooks/timeline.ts index 440969e9..fc3756b6 100644 --- a/src/utils/queryHooks/timeline.ts +++ b/src/utils/queryHooks/timeline.ts @@ -387,7 +387,7 @@ const mutationFunction = async (params: MutationVarsTimeline) => { url: `statuses/${params.id}/${ params.payload.currentValue ? 'un' : '' }${MapPropertyToUrl[params.payload.property]}`, - body + ...(params.payload.property === 'reblogged' && { body }) }) } case 'updateAccountProperty':