mirror of
				https://github.com/tooot-app/app
				synced 2025-06-05 22:19:13 +02:00 
			
		
		
		
	
							
								
								
									
										2
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							| @@ -25,7 +25,7 @@ jobs: | |||||||
|         run: bundle install |         run: bundle install | ||||||
|       - name: -- Step 5 -- Run fastlane |       - name: -- Step 5 -- Run fastlane | ||||||
|         env: |         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 }} |           ENVIRONMENT: ${{ steps.branch.outputs.branch }} | ||||||
|           SENTRY_ENVIRONMENT: ${{ steps.branch.outputs.branch }} |           SENTRY_ENVIRONMENT: ${{ steps.branch.outputs.branch }} | ||||||
|           LC_ALL: en_US.UTF-8 |           LC_ALL: en_US.UTF-8 | ||||||
|   | |||||||
| @@ -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 | [@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 | [@jk@mastodon.social](https://mastodon.social/@jk) for the famous Mastodon boop sound | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "name": "tooot", |   "name": "tooot", | ||||||
|   "version": "4.5.0", |   "version": "4.5.1", | ||||||
|   "description": "tooot for Mastodon", |   "description": "tooot for Mastodon", | ||||||
|   "author": "xmflsct <me@xmflsct.com>", |   "author": "xmflsct <me@xmflsct.com>", | ||||||
|   "license": "GPL-3.0-or-later", |   "license": "GPL-3.0-or-later", | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| import { ActionSheetProvider } from '@expo/react-native-action-sheet' | import { ActionSheetProvider } from '@expo/react-native-action-sheet' | ||||||
|  | import getLanguage from '@helpers/getLanguage' | ||||||
| import queryClient from '@helpers/queryClient' | import queryClient from '@helpers/queryClient' | ||||||
| import i18n from '@root/i18n/i18n' | import i18n from '@root/i18n/i18n' | ||||||
| import Screens from '@root/Screens' | import Screens from '@root/Screens' | ||||||
| @@ -12,7 +13,7 @@ import timezone from '@root/startup/timezone' | |||||||
| import { persistor, store } from '@root/store' | import { persistor, store } from '@root/store' | ||||||
| import * as Sentry from '@sentry/react-native' | import * as Sentry from '@sentry/react-native' | ||||||
| import AccessibilityManager from '@utils/accessibility/AccessibilityManager' | 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 ThemeManager from '@utils/styles/ThemeManager' | ||||||
| import * as Localization from 'expo-localization' | import * as Localization from 'expo-localization' | ||||||
| import * as SplashScreen from 'expo-splash-screen' | import * as SplashScreen from 'expo-splash-screen' | ||||||
| @@ -83,10 +84,7 @@ const App: React.FC = () => { | |||||||
|               if (bootstrapped) { |               if (bootstrapped) { | ||||||
|                 log('log', 'App', 'loading actual app :)') |                 log('log', 'App', 'loading actual app :)') | ||||||
|                 log('log', 'App', `Locale: ${Localization.locale}`) |                 log('log', 'App', `Locale: ${Localization.locale}`) | ||||||
|                 const language = |                 const language = getLanguage() | ||||||
|                   Platform.OS === 'ios' |  | ||||||
|                     ? Localization.locale |  | ||||||
|                     : getSettingsLanguage(store.getState()) |  | ||||||
|                 if (!language) { |                 if (!language) { | ||||||
|                   if (Platform.OS !== 'ios') { |                   if (Platform.OS !== 'ios') { | ||||||
|                     store.dispatch(changeLanguage('en')) |                     store.dispatch(changeLanguage('en')) | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| import axios from 'axios' | import axios from 'axios' | ||||||
| import Constants from 'expo-constants' |  | ||||||
| import handleError, { ctx } from './handleError' | import handleError, { ctx } from './handleError' | ||||||
|  | import { userAgent } from './helpers' | ||||||
|  |  | ||||||
| export type Params = { | export type Params = { | ||||||
|   method: 'get' | 'post' | 'put' | 'delete' |   method: 'get' | 'post' | 'put' | 'delete' | ||||||
| @@ -44,8 +44,8 @@ const apiGeneral = async <T = unknown>({ | |||||||
|         body && body instanceof FormData |         body && body instanceof FormData | ||||||
|           ? 'multipart/form-data' |           ? 'multipart/form-data' | ||||||
|           : 'application/json', |           : 'application/json', | ||||||
|       'User-Agent': `tooot/${Constants.expoConfig?.version}`, |  | ||||||
|       Accept: '*/*', |       Accept: '*/*', | ||||||
|  |       ...userAgent, | ||||||
|       ...headers |       ...headers | ||||||
|     }, |     }, | ||||||
|     ...(body && { data: body }) |     ...(body && { data: body }) | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								src/api/helpers/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/api/helpers/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -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 } | ||||||
| @@ -1,8 +1,8 @@ | |||||||
| import { RootState } from '@root/store' | import { RootState } from '@root/store' | ||||||
| import axios, { AxiosRequestConfig } from 'axios' | import axios, { AxiosRequestConfig } from 'axios' | ||||||
| import Constants from 'expo-constants' |  | ||||||
| import li from 'li' | import li from 'li' | ||||||
| import handleError, { ctx } from './handleError' | import handleError, { ctx } from './handleError' | ||||||
|  | import { userAgent } from './helpers' | ||||||
|  |  | ||||||
| export type Params = { | export type Params = { | ||||||
|   method: 'get' | 'post' | 'put' | 'delete' | 'patch' |   method: 'get' | 'post' | 'put' | 'delete' | 'patch' | ||||||
| @@ -74,8 +74,8 @@ const apiInstance = async <T = unknown>({ | |||||||
|         body && body instanceof FormData |         body && body instanceof FormData | ||||||
|           ? 'multipart/form-data' |           ? 'multipart/form-data' | ||||||
|           : 'application/json', |           : 'application/json', | ||||||
|       'User-Agent': `tooot/${Constants.expoConfig?.version}`, |  | ||||||
|       Accept: '*/*', |       Accept: '*/*', | ||||||
|  |       ...userAgent, | ||||||
|       ...headers, |       ...headers, | ||||||
|       ...(token && { |       ...(token && { | ||||||
|         Authorization: `Bearer ${token}` |         Authorization: `Bearer ${token}` | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| import * as Sentry from '@sentry/react-native' | import * as Sentry from '@sentry/react-native' | ||||||
| import { mapEnvironment } from '@utils/checkEnvironment' | import { mapEnvironment } from '@utils/checkEnvironment' | ||||||
| import axios from 'axios' | import axios from 'axios' | ||||||
| import Constants from 'expo-constants' |  | ||||||
| import handleError, { ctx } from './handleError' | import handleError, { ctx } from './handleError' | ||||||
|  | import { userAgent } from './helpers' | ||||||
|  |  | ||||||
| export type Params = { | export type Params = { | ||||||
|   method: 'get' | 'post' | 'put' | 'delete' |   method: 'get' | 'post' | 'put' | 'delete' | ||||||
| @@ -50,13 +50,11 @@ const apiTooot = async <T = unknown>({ | |||||||
|         body && body instanceof FormData |         body && body instanceof FormData | ||||||
|           ? 'multipart/form-data' |           ? 'multipart/form-data' | ||||||
|           : 'application/json', |           : 'application/json', | ||||||
|       'User-Agent': `tooot/${Constants.expoConfig?.version}`, |  | ||||||
|       Accept: '*/*', |       Accept: '*/*', | ||||||
|  |       ...userAgent, | ||||||
|       ...headers |       ...headers | ||||||
|     }, |     }, | ||||||
|     ...(body && { data: body }), |     ...(body && { data: body }) | ||||||
|     validateStatus: status => |  | ||||||
|       url.includes('translate') ? status < 500 : status === 200 |  | ||||||
|   }) |   }) | ||||||
|     .then(response => { |     .then(response => { | ||||||
|       return Promise.resolve({ |       return Promise.resolve({ | ||||||
|   | |||||||
| @@ -174,6 +174,12 @@ const contextMenuAccount = ({ | |||||||
|         id: accountId, |         id: accountId, | ||||||
|         payload: { property: 'reports' } |         payload: { property: 'reports' } | ||||||
|       }) |       }) | ||||||
|  |       mutation.mutate({ | ||||||
|  |         type: 'updateAccountProperty', | ||||||
|  |         queryKey, | ||||||
|  |         id: accountId, | ||||||
|  |         payload: { property: 'block', currentValue: false } | ||||||
|  |       }) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| import analytics from '@components/analytics' | import analytics from '@components/analytics' | ||||||
| import { ParseHTML } from '@components/Parse' | import { ParseHTML } from '@components/Parse' | ||||||
| import CustomText from '@components/Text' | import CustomText from '@components/Text' | ||||||
|  | import getLanguage from '@helpers/getLanguage' | ||||||
| import { useTranslateQuery } from '@utils/queryHooks/translate' | import { useTranslateQuery } from '@utils/queryHooks/translate' | ||||||
| import { getSettingsLanguage } from '@utils/slices/settingsSlice' |  | ||||||
| import { StyleConstants } from '@utils/styles/constants' | import { StyleConstants } from '@utils/styles/constants' | ||||||
| import { useTheme } from '@utils/styles/ThemeManager' | import { useTheme } from '@utils/styles/ThemeManager' | ||||||
| import * as Localization from 'expo-localization' | import * as Localization from 'expo-localization' | ||||||
| @@ -11,14 +11,10 @@ import { useTranslation } from 'react-i18next' | |||||||
| import { Pressable } from 'react-native' | import { Pressable } from 'react-native' | ||||||
| import { Circle } from 'react-native-animated-spinkit' | import { Circle } from 'react-native-animated-spinkit' | ||||||
| import detectLanguage from 'react-native-language-detection' | import detectLanguage from 'react-native-language-detection' | ||||||
| import { useSelector } from 'react-redux' |  | ||||||
|  |  | ||||||
| export interface Props { | export interface Props { | ||||||
|   highlighted: boolean |   highlighted: boolean | ||||||
|   status: Pick< |   status: Pick<Mastodon.Status, 'language' | 'spoiler_text' | 'content' | 'emojis'> | ||||||
|     Mastodon.Status, |  | ||||||
|     'language' | 'spoiler_text' | 'content' | 'emojis' |  | ||||||
|   > |  | ||||||
| } | } | ||||||
|  |  | ||||||
| const TimelineTranslate = React.memo( | const TimelineTranslate = React.memo( | ||||||
| @@ -30,9 +26,7 @@ const TimelineTranslate = React.memo( | |||||||
|     const { t } = useTranslation('componentTimeline') |     const { t } = useTranslation('componentTimeline') | ||||||
|     const { colors } = useTheme() |     const { colors } = useTheme() | ||||||
|  |  | ||||||
|     const text = status.spoiler_text |     const text = status.spoiler_text ? [status.spoiler_text, status.content] : [status.content] | ||||||
|       ? [status.spoiler_text, status.content] |  | ||||||
|       : [status.content] |  | ||||||
|  |  | ||||||
|     for (const i in text) { |     for (const i in text) { | ||||||
|       for (const emoji of status.emojis) { |       for (const emoji of status.emojis) { | ||||||
| @@ -56,7 +50,7 @@ const TimelineTranslate = React.memo( | |||||||
|       detect() |       detect() | ||||||
|     }, []) |     }, []) | ||||||
|  |  | ||||||
|     const settingsLanguage = useSelector(getSettingsLanguage) |     const settingsLanguage = getLanguage() | ||||||
|     const targetLanguage = settingsLanguage?.startsWith('en') |     const targetLanguage = settingsLanguage?.startsWith('en') | ||||||
|       ? Localization.locale || settingsLanguage || 'en' |       ? Localization.locale || settingsLanguage || 'en' | ||||||
|       : settingsLanguage || Localization.locale || 'en' |       : settingsLanguage || Localization.locale || 'en' | ||||||
| @@ -107,12 +101,7 @@ const TimelineTranslate = React.memo( | |||||||
|           <CustomText |           <CustomText | ||||||
|             fontStyle='M' |             fontStyle='M' | ||||||
|             style={{ |             style={{ | ||||||
|               color: |               color: isLoading || isSuccess ? colors.secondary : isError ? colors.red : colors.blue | ||||||
|                 isLoading || isSuccess |  | ||||||
|                   ? colors.secondary |  | ||||||
|                   : isError |  | ||||||
|                   ? colors.red |  | ||||||
|                   : colors.blue |  | ||||||
|             }} |             }} | ||||||
|           > |           > | ||||||
|             {isError |             {isError | ||||||
| @@ -127,9 +116,7 @@ const TimelineTranslate = React.memo( | |||||||
|               : t('shared.translate.default')} |               : t('shared.translate.default')} | ||||||
|           </CustomText> |           </CustomText> | ||||||
|           <CustomText> |           <CustomText> | ||||||
|             {__DEV__ |             {__DEV__ ? ` Source: ${detectedLanguage}; Target: ${targetLanguage}` : undefined} | ||||||
|               ? ` Source: ${detectedLanguage}; Target: ${targetLanguage}` |  | ||||||
|               : undefined} |  | ||||||
|           </CustomText> |           </CustomText> | ||||||
|           {isLoading ? ( |           {isLoading ? ( | ||||||
|             <Circle |             <Circle | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								src/helpers/getLanguage.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/helpers/getLanguage.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | import { store } from '@root/store' | ||||||
|  | import { getSettingsLanguage } from '@utils/slices/settingsSlice' | ||||||
|  | import * as Localization from 'expo-localization' | ||||||
|  | import { Platform } from "react-native" | ||||||
|  |  | ||||||
|  | const getLanguage = (): string => { | ||||||
|  |   return Platform.OS === 'ios' | ||||||
|  |     ? Localization.locale | ||||||
|  |     : getSettingsLanguage(store.getState()) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export default getLanguage | ||||||
| @@ -2,7 +2,7 @@ | |||||||
|   "HTML": { |   "HTML": { | ||||||
|     "accessibilityHint": "Nhấn để mở rộng hoặc thu gọn nội dung", |     "accessibilityHint": "Nhấn để mở rộng hoặc thu gọn nội dung", | ||||||
|     "expanded": "{{hint}}{{moreLines}}", |     "expanded": "{{hint}}{{moreLines}}", | ||||||
|     "moreLines": "", |     "moreLines": " ({{count}} dòng nữa)", | ||||||
|     "defaultHint": "Tút dài" |     "defaultHint": "Tút dài" | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @@ -40,9 +40,9 @@ | |||||||
|         "accessibilityLabel": "Đăng lại tút này", |         "accessibilityLabel": "Đăng lại tút này", | ||||||
|         "function": "Đăng lại tút", |         "function": "Đăng lại tút", | ||||||
|         "options": { |         "options": { | ||||||
|           "title": "", |           "title": "Kiểu đăng lại", | ||||||
|           "public": "", |           "public": "Đăng lại công khai", | ||||||
|           "unlisted": "" |           "unlisted": "Đăng lại hạn chế" | ||||||
|         } |         } | ||||||
|       }, |       }, | ||||||
|       "favourited": { |       "favourited": { | ||||||
|   | |||||||
| @@ -14,13 +14,13 @@ | |||||||
|       "base": "將使用系統內建的瀏覽器來登入,tooot 無法讀取您的帳號資訊。" |       "base": "將使用系統內建的瀏覽器來登入,tooot 無法讀取您的帳號資訊。" | ||||||
|     }, |     }, | ||||||
|     "terms": { |     "terms": { | ||||||
|       "base": "登入則表示您同意<0>隱私條款</0>和<1>服務條款</1>。" |       "base": "登入則表示您同意<0>隱私政策</0>和<1>使用條款</1>。" | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   "update": { |   "update": { | ||||||
|     "alert": { |     "alert": { | ||||||
|       "title": "已登入站點", |       "title": "已登入站點", | ||||||
|       "message": "您可以多登入其他的帳號,已登入的帳號會被保留", |       "message": "您可以登入其它的帳號,已登入的帳號會被保留", | ||||||
|       "buttons": { |       "buttons": { | ||||||
|         "cancel": "$t(common:buttons.cancel)", |         "cancel": "$t(common:buttons.cancel)", | ||||||
|         "continue": "繼續" |         "continue": "繼續" | ||||||
|   | |||||||
| @@ -1,10 +1,10 @@ | |||||||
| { | { | ||||||
|   "title": "選擇媒體來源", |   "title": "選擇媒體來源", | ||||||
|   "message": "媒體 EXIF 資料不會被上傳", |   "message": "媒體 Exif 資訊不會被上傳", | ||||||
|   "options": { |   "options": { | ||||||
|     "image": "上傳圖片", |     "image": "上傳圖片", | ||||||
|     "image_max": "上傳圖片(最多 {{max}})", |     "image_max": "上傳圖片(最多 {{max}} 張)", | ||||||
|     "video": "上傳影片", |     "video": "上傳影片", | ||||||
|     "video_max": "上傳影片(最多 {{max}})" |     "video_max": "上傳影片(最多 {{max}} 個)" | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @@ -22,9 +22,9 @@ | |||||||
|     "actioned": { |     "actioned": { | ||||||
|       "pinned": "置頂", |       "pinned": "置頂", | ||||||
|       "favourite": "{{name}} 把您的嘟文加入了最愛", |       "favourite": "{{name}} 把您的嘟文加入了最愛", | ||||||
|       "status": "{{name}} 正發了嘟", |       "status": "{{name}} 剛剛嘟文", | ||||||
|       "follow": "{{name}} 追隨您了", |       "follow": "{{name}} 跟隨了您", | ||||||
|       "follow_request": "{{name}} 要求您允許他的追隨", |       "follow_request": "{{name}} 要求跟隨您", | ||||||
|       "poll": "您曾投過的投票已經結束", |       "poll": "您曾投過的投票已經結束", | ||||||
|       "reblog": { |       "reblog": { | ||||||
|         "default": "{{name}} 轉嘟了", |         "default": "{{name}} 轉嘟了", | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| { | { | ||||||
|   "tabs": { |   "tabs": { | ||||||
|     "local": { |     "local": { | ||||||
|       "name": "追隨中" |       "name": "跟隨中" | ||||||
|     }, |     }, | ||||||
|     "public": { |     "public": { | ||||||
|       "name": "", |       "name": "", | ||||||
| @@ -47,16 +47,16 @@ | |||||||
|         "name": "語言" |         "name": "語言" | ||||||
|       }, |       }, | ||||||
|       "lists": { |       "lists": { | ||||||
|         "name": "清單" |         "name": "列表" | ||||||
|       }, |       }, | ||||||
|       "list": { |       "list": { | ||||||
|         "name": "清單: {{list}}" |         "name": "列表:{{list}}" | ||||||
|       }, |       }, | ||||||
|       "push": { |       "push": { | ||||||
|         "name": "推播通知" |         "name": "推播通知" | ||||||
|       }, |       }, | ||||||
|       "profile": { |       "profile": { | ||||||
|         "name": "編輯個人資料" |         "name": "編輯個人檔案" | ||||||
|       }, |       }, | ||||||
|       "profileName": { |       "profileName": { | ||||||
|         "name": "編輯顯示名稱" |         "name": "編輯顯示名稱" | ||||||
| @@ -71,20 +71,20 @@ | |||||||
|         "name": "App 設定" |         "name": "App 設定" | ||||||
|       }, |       }, | ||||||
|       "webSettings": { |       "webSettings": { | ||||||
|         "name": "更多的帳號設定" |         "name": "更多帳號設定" | ||||||
|       }, |       }, | ||||||
|       "switch": { |       "switch": { | ||||||
|         "name": "切換帳號" |         "name": "切換帳號" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "fontSize": { |     "fontSize": { | ||||||
|       "demo": "<p>這是一條測試用的嘟文😊。以下是可供選擇的字體大小,從小至超大。<br /><br />這個設定僅會調整嘟文的本身字體大小,不影響其它字體大小。</p>", |       "demo": "<p>這是一條測試用的嘟文😊。以下是可供選擇的字體大小,從小到超大。<br /><br />這個設定僅會調整嘟文本身的字體大小,不影響其它介面的字體大小。</p>", | ||||||
|       "sizes": { |       "sizes": { | ||||||
|         "S": "小", |         "S": "小", | ||||||
|         "M": "M - 預設", |         "M": "中 (預設)", | ||||||
|         "L": "大", |         "L": "大", | ||||||
|         "XL": "超大", |         "XL": "特大", | ||||||
|         "XXL": "特大" |         "XXL": "超大" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "profile": { |     "profile": { | ||||||
| @@ -277,7 +277,7 @@ | |||||||
|       }, |       }, | ||||||
|       "analytics": { |       "analytics": { | ||||||
|         "heading": "幫助我們改善", |         "heading": "幫助我們改善", | ||||||
|         "description": "僅收集不與使用者關聯的資料" |         "description": "僅收集不與使用者相關聯的資料" | ||||||
|       }, |       }, | ||||||
|       "version": "Version v{{version}}", |       "version": "Version v{{version}}", | ||||||
|       "instanceVersion": "Mastodon version v{{version}}" |       "instanceVersion": "Mastodon version v{{version}}" | ||||||
|   | |||||||
| @@ -387,7 +387,7 @@ const mutationFunction = async (params: MutationVarsTimeline) => { | |||||||
|             url: `statuses/${params.id}/${ |             url: `statuses/${params.id}/${ | ||||||
|               params.payload.currentValue ? 'un' : '' |               params.payload.currentValue ? 'un' : '' | ||||||
|             }${MapPropertyToUrl[params.payload.property]}`, |             }${MapPropertyToUrl[params.payload.property]}`, | ||||||
|             body |             ...(params.payload.property === 'reblogged' && { body }) | ||||||
|           }) |           }) | ||||||
|       } |       } | ||||||
|     case 'updateAccountProperty': |     case 'updateAccountProperty': | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user