mirror of
https://github.com/tooot-app/app
synced 2025-06-05 22:19:13 +02:00
@@ -1 +1,3 @@
|
|||||||
Enjoy using tooot
|
Enjoy toooting! This version includes following improvements and fixes:
|
||||||
|
- Fix toot attribution of favourites etc.
|
||||||
|
- Fix switching language
|
@@ -1 +1,3 @@
|
|||||||
tooot使用愉快
|
toooting愉快!此版本包括以下改进和修复:
|
||||||
|
- 修复嘟文收藏等显示
|
||||||
|
- 修复不能切换语言
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "tooot",
|
"name": "tooot",
|
||||||
"version": "4.6.5",
|
"version": "4.6.6",
|
||||||
"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'
|
||||||
@@ -85,7 +86,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 = getSettingsLanguage(store.getState())
|
const language = getLanguage()
|
||||||
if (!language) {
|
if (!language) {
|
||||||
if (Platform.OS !== 'ios') {
|
if (Platform.OS !== 'ios') {
|
||||||
store.dispatch(changeLanguage('en'))
|
store.dispatch(changeLanguage('en'))
|
||||||
|
@@ -39,10 +39,7 @@ const apiGeneral = async <T = unknown>({
|
|||||||
url,
|
url,
|
||||||
params,
|
params,
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type':
|
'Content-Type': body && body instanceof FormData ? 'multipart/form-data' : 'application/json',
|
||||||
body && body instanceof FormData
|
|
||||||
? 'multipart/form-data'
|
|
||||||
: 'application/json',
|
|
||||||
Accept: '*/*',
|
Accept: '*/*',
|
||||||
...userAgent,
|
...userAgent,
|
||||||
...headers
|
...headers
|
||||||
@@ -54,7 +51,7 @@ const apiGeneral = async <T = unknown>({
|
|||||||
body: response.data
|
body: response.data
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.catch(handleError)
|
.catch(handleError())
|
||||||
}
|
}
|
||||||
|
|
||||||
export default apiGeneral
|
export default apiGeneral
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
import * as Sentry from '@sentry/react-native'
|
||||||
import chalk from 'chalk'
|
import chalk from 'chalk'
|
||||||
import Constants from 'expo-constants'
|
import Constants from 'expo-constants'
|
||||||
import { Platform } from 'react-native'
|
import { Platform } from 'react-native'
|
||||||
@@ -7,8 +8,31 @@ const userAgent = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ctx = new chalk.Instance({ level: 3 })
|
const ctx = new chalk.Instance({ level: 3 })
|
||||||
const handleError = (error: any) => {
|
const handleError =
|
||||||
|
(
|
||||||
|
config: {
|
||||||
|
message: string
|
||||||
|
captureRequest?: { url: string; params: any; body: any }
|
||||||
|
captureResponse?: boolean
|
||||||
|
} | void
|
||||||
|
) =>
|
||||||
|
(error: any) => {
|
||||||
|
const shouldReportToSentry = config && (config.captureRequest || config.captureResponse)
|
||||||
|
shouldReportToSentry && Sentry.setContext('Error object', error)
|
||||||
|
|
||||||
|
if (config?.captureRequest) {
|
||||||
|
Sentry.setContext('Error request', config.captureRequest)
|
||||||
|
}
|
||||||
|
|
||||||
if (error?.response) {
|
if (error?.response) {
|
||||||
|
if (config?.captureResponse) {
|
||||||
|
Sentry.setContext('Error response', {
|
||||||
|
data: error.response.data,
|
||||||
|
status: error.response.status,
|
||||||
|
headers: error.response.headers
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// The request was made and the server responded with a status code
|
// The request was made and the server responded with a status code
|
||||||
// that falls out of the range of 2xx
|
// that falls out of the range of 2xx
|
||||||
console.error(
|
console.error(
|
||||||
@@ -17,6 +41,8 @@ const handleError = (error: any) => {
|
|||||||
error.response.status,
|
error.response.status,
|
||||||
error?.response.data?.error || error?.response.message || 'Unknown error'
|
error?.response.data?.error || error?.response.message || 'Unknown error'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
shouldReportToSentry && Sentry.captureMessage(config.message)
|
||||||
return Promise.reject({
|
return Promise.reject({
|
||||||
status: error?.response.status,
|
status: error?.response.status,
|
||||||
message: error?.response.data?.error || error?.response.message || 'Unknown error'
|
message: error?.response.data?.error || error?.response.message || 'Unknown error'
|
||||||
@@ -26,9 +52,13 @@ const handleError = (error: any) => {
|
|||||||
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
|
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
|
||||||
// http.ClientRequest in node.js
|
// http.ClientRequest in node.js
|
||||||
console.error(ctx.bold(' API '), ctx.bold('request'), error)
|
console.error(ctx.bold(' API '), ctx.bold('request'), error)
|
||||||
|
|
||||||
|
shouldReportToSentry && Sentry.captureMessage(config.message)
|
||||||
return Promise.reject()
|
return Promise.reject()
|
||||||
} else {
|
} else {
|
||||||
console.error(ctx.bold(' API '), ctx.bold('internal'), error?.message)
|
console.error(ctx.bold(' API '), ctx.bold('internal'), error?.message)
|
||||||
|
|
||||||
|
shouldReportToSentry && Sentry.captureMessage(config.message)
|
||||||
return Promise.reject()
|
return Promise.reject()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -86,7 +86,7 @@ const apiInstance = async <T = unknown>({
|
|||||||
links: { prev, next }
|
links: { prev, next }
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.catch(handleError)
|
.catch(handleError())
|
||||||
}
|
}
|
||||||
|
|
||||||
export default apiInstance
|
export default apiInstance
|
||||||
|
@@ -55,16 +55,13 @@ const apiTooot = async <T = unknown>({
|
|||||||
body: response.data
|
body: response.data
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(
|
||||||
Sentry.setContext('API request', { url, params, body })
|
handleError({
|
||||||
Sentry.setContext('Error response', {
|
message: 'API error',
|
||||||
...(error?.response && { response: error.response?._response })
|
captureRequest: { url, params, body },
|
||||||
})
|
captureResponse: true
|
||||||
Sentry.setContext('Error object', { error })
|
|
||||||
Sentry.captureMessage('API error')
|
|
||||||
|
|
||||||
return handleError(error)
|
|
||||||
})
|
})
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default apiTooot
|
export default apiTooot
|
||||||
|
@@ -120,7 +120,7 @@ const TimelineDefault: React.FC<Props> = ({
|
|||||||
queryKey,
|
queryKey,
|
||||||
rootQueryKey,
|
rootQueryKey,
|
||||||
status,
|
status,
|
||||||
isReblog: !!item.reblog,
|
reblogStatus: item.reblog ? item : undefined,
|
||||||
ownAccount,
|
ownAccount,
|
||||||
spoilerHidden,
|
spoilerHidden,
|
||||||
copiableContent,
|
copiableContent,
|
||||||
|
@@ -38,7 +38,7 @@ const TimelineNotifications: React.FC<Props> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const instanceAccount = useSelector(getInstanceAccount, () => true)
|
const instanceAccount = useSelector(getInstanceAccount, () => true)
|
||||||
|
|
||||||
const status = notification.status
|
const status = notification.status?.reblog ? notification.status.reblog : notification.status
|
||||||
const account = notification.status ? notification.status.account : notification.account
|
const account = notification.status ? notification.status.account : notification.account
|
||||||
const ownAccount = notification.account?.id === instanceAccount?.id
|
const ownAccount = notification.account?.id === instanceAccount?.id
|
||||||
const [spoilerExpanded, setSpoilerExpanded] = useState(
|
const [spoilerExpanded, setSpoilerExpanded] = useState(
|
||||||
@@ -78,7 +78,11 @@ const TimelineNotifications: React.FC<Props> = ({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{notification.type !== 'mention' ? (
|
{notification.type !== 'mention' ? (
|
||||||
<TimelineActioned action={notification.type} isNotification account={account} />
|
<TimelineActioned
|
||||||
|
action={notification.type}
|
||||||
|
isNotification
|
||||||
|
account={notification.account}
|
||||||
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<View
|
<View
|
||||||
@@ -132,7 +136,6 @@ const TimelineNotifications: React.FC<Props> = ({
|
|||||||
value={{
|
value={{
|
||||||
queryKey,
|
queryKey,
|
||||||
status,
|
status,
|
||||||
isReblog: !!status?.reblog,
|
|
||||||
ownAccount,
|
ownAccount,
|
||||||
spoilerHidden,
|
spoilerHidden,
|
||||||
copiableContent,
|
copiableContent,
|
||||||
|
@@ -13,12 +13,12 @@ import StatusContext from './Context'
|
|||||||
export interface Props {
|
export interface Props {
|
||||||
action: Mastodon.Notification['type'] | 'reblog' | 'pinned'
|
action: Mastodon.Notification['type'] | 'reblog' | 'pinned'
|
||||||
isNotification?: boolean
|
isNotification?: boolean
|
||||||
account?: Mastodon.Account
|
account?: Mastodon.Account // For notification
|
||||||
}
|
}
|
||||||
|
|
||||||
const TimelineActioned: React.FC<Props> = ({ action, isNotification, ...rest }) => {
|
const TimelineActioned: React.FC<Props> = ({ action, isNotification, ...rest }) => {
|
||||||
const { status } = useContext(StatusContext)
|
const { status, reblogStatus } = useContext(StatusContext)
|
||||||
const account = isNotification ? rest.account : status?.account
|
const account = rest.account || (reblogStatus ? reblogStatus.account : status?.account)
|
||||||
if (!status || !account) return null
|
if (!status || !account) return null
|
||||||
|
|
||||||
const { t } = useTranslation('componentTimeline')
|
const { t } = useTranslation('componentTimeline')
|
||||||
|
@@ -22,7 +22,7 @@ import { useSelector } from 'react-redux'
|
|||||||
import StatusContext from './Context'
|
import StatusContext from './Context'
|
||||||
|
|
||||||
const TimelineActions: React.FC = () => {
|
const TimelineActions: React.FC = () => {
|
||||||
const { queryKey, rootQueryKey, status, isReblog, ownAccount, highlighted, disableDetails } =
|
const { queryKey, rootQueryKey, status, reblogStatus, ownAccount, highlighted, disableDetails } =
|
||||||
useContext(StatusContext)
|
useContext(StatusContext)
|
||||||
if (!queryKey || !status || disableDetails) return null
|
if (!queryKey || !status || disableDetails) return null
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ const TimelineActions: React.FC = () => {
|
|||||||
queryKey,
|
queryKey,
|
||||||
rootQueryKey,
|
rootQueryKey,
|
||||||
id: status.id,
|
id: status.id,
|
||||||
isReblog,
|
isReblog: !!reblogStatus,
|
||||||
payload: {
|
payload: {
|
||||||
property: 'reblogged',
|
property: 'reblogged',
|
||||||
currentValue: status.reblogged,
|
currentValue: status.reblogged,
|
||||||
@@ -125,7 +125,7 @@ const TimelineActions: React.FC = () => {
|
|||||||
queryKey,
|
queryKey,
|
||||||
rootQueryKey,
|
rootQueryKey,
|
||||||
id: status.id,
|
id: status.id,
|
||||||
isReblog,
|
isReblog: !!reblogStatus,
|
||||||
payload: {
|
payload: {
|
||||||
property: 'reblogged',
|
property: 'reblogged',
|
||||||
currentValue: status.reblogged,
|
currentValue: status.reblogged,
|
||||||
@@ -144,7 +144,7 @@ const TimelineActions: React.FC = () => {
|
|||||||
queryKey,
|
queryKey,
|
||||||
rootQueryKey,
|
rootQueryKey,
|
||||||
id: status.id,
|
id: status.id,
|
||||||
isReblog,
|
isReblog: !!reblogStatus,
|
||||||
payload: {
|
payload: {
|
||||||
property: 'reblogged',
|
property: 'reblogged',
|
||||||
currentValue: status.reblogged,
|
currentValue: status.reblogged,
|
||||||
@@ -161,7 +161,7 @@ const TimelineActions: React.FC = () => {
|
|||||||
queryKey,
|
queryKey,
|
||||||
rootQueryKey,
|
rootQueryKey,
|
||||||
id: status.id,
|
id: status.id,
|
||||||
isReblog,
|
isReblog: !!reblogStatus,
|
||||||
payload: {
|
payload: {
|
||||||
property: 'favourited',
|
property: 'favourited',
|
||||||
currentValue: status.favourited,
|
currentValue: status.favourited,
|
||||||
@@ -176,7 +176,7 @@ const TimelineActions: React.FC = () => {
|
|||||||
queryKey,
|
queryKey,
|
||||||
rootQueryKey,
|
rootQueryKey,
|
||||||
id: status.id,
|
id: status.id,
|
||||||
isReblog,
|
isReblog: !!reblogStatus,
|
||||||
payload: {
|
payload: {
|
||||||
property: 'bookmarked',
|
property: 'bookmarked',
|
||||||
currentValue: status.bookmarked,
|
currentValue: status.bookmarked,
|
||||||
|
@@ -7,7 +7,7 @@ type ContextType = {
|
|||||||
|
|
||||||
status?: Mastodon.Status
|
status?: Mastodon.Status
|
||||||
|
|
||||||
isReblog?: boolean
|
reblogStatus?: Mastodon.Status // When it is a reblog, pass the root status
|
||||||
ownAccount?: boolean
|
ownAccount?: boolean
|
||||||
spoilerHidden?: boolean
|
spoilerHidden?: boolean
|
||||||
copiableContent?: React.MutableRefObject<{
|
copiableContent?: React.MutableRefObject<{
|
||||||
|
@@ -20,8 +20,15 @@ import { useQueryClient } from 'react-query'
|
|||||||
import StatusContext from './Context'
|
import StatusContext from './Context'
|
||||||
|
|
||||||
const TimelinePoll: React.FC = () => {
|
const TimelinePoll: React.FC = () => {
|
||||||
const { queryKey, rootQueryKey, status, isReblog, ownAccount, spoilerHidden, disableDetails } =
|
const {
|
||||||
useContext(StatusContext)
|
queryKey,
|
||||||
|
rootQueryKey,
|
||||||
|
status,
|
||||||
|
reblogStatus,
|
||||||
|
ownAccount,
|
||||||
|
spoilerHidden,
|
||||||
|
disableDetails
|
||||||
|
} = useContext(StatusContext)
|
||||||
if (!queryKey || !status || !status.poll) return null
|
if (!queryKey || !status || !status.poll) return null
|
||||||
const poll = status.poll
|
const poll = status.poll
|
||||||
|
|
||||||
@@ -78,7 +85,7 @@ const TimelinePoll: React.FC = () => {
|
|||||||
queryKey,
|
queryKey,
|
||||||
rootQueryKey,
|
rootQueryKey,
|
||||||
id: status.id,
|
id: status.id,
|
||||||
isReblog,
|
isReblog: !!reblogStatus,
|
||||||
payload: {
|
payload: {
|
||||||
property: 'poll',
|
property: 'poll',
|
||||||
id: poll.id,
|
id: poll.id,
|
||||||
@@ -104,7 +111,7 @@ const TimelinePoll: React.FC = () => {
|
|||||||
queryKey,
|
queryKey,
|
||||||
rootQueryKey,
|
rootQueryKey,
|
||||||
id: status.id,
|
id: status.id,
|
||||||
isReblog,
|
isReblog: !!reblogStatus,
|
||||||
payload: {
|
payload: {
|
||||||
property: 'poll',
|
property: 'poll',
|
||||||
id: poll.id,
|
id: poll.id,
|
||||||
|
@@ -20,8 +20,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"at": {
|
"at": {
|
||||||
"direct": "",
|
"direct": "Missatge directe",
|
||||||
"public": ""
|
"public": "Missatge públic"
|
||||||
},
|
},
|
||||||
"copy": {
|
"copy": {
|
||||||
"action": "Copia la publicació",
|
"action": "Copia la publicació",
|
||||||
|
@@ -352,7 +352,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"trending": {
|
"trending": {
|
||||||
"tags": ""
|
"tags": "Etiquetes en tendència"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sections": {
|
"sections": {
|
||||||
|
@@ -20,8 +20,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"at": {
|
"at": {
|
||||||
"direct": "",
|
"direct": "Mensaje directo",
|
||||||
"public": ""
|
"public": "Mensaje público"
|
||||||
},
|
},
|
||||||
"copy": {
|
"copy": {
|
||||||
"action": "Copiar toot",
|
"action": "Copiar toot",
|
||||||
|
@@ -352,7 +352,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"trending": {
|
"trending": {
|
||||||
"tags": ""
|
"tags": "Etiquetas en tendencia"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sections": {
|
"sections": {
|
||||||
|
@@ -20,8 +20,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"at": {
|
"at": {
|
||||||
"direct": "",
|
"direct": "ダイレクトメッセージ",
|
||||||
"public": ""
|
"public": "パブリックメッセージ"
|
||||||
},
|
},
|
||||||
"copy": {
|
"copy": {
|
||||||
"action": "トゥートをコピー",
|
"action": "トゥートをコピー",
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
"action_false": "Volg gebruiker",
|
"action_false": "Volg gebruiker",
|
||||||
"action_true": "Ontvolg"
|
"action_true": "Ontvolg"
|
||||||
},
|
},
|
||||||
"inLists": "Gebruiker van lijsten beheren",
|
"inLists": "Gebruiker op lijsten beheren",
|
||||||
"mute": {
|
"mute": {
|
||||||
"action_false": "Gebruiker dempen",
|
"action_false": "Gebruiker dempen",
|
||||||
"action_true": "Dempen opheffen voor gebruiker"
|
"action_true": "Dempen opheffen voor gebruiker"
|
||||||
@@ -20,8 +20,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"at": {
|
"at": {
|
||||||
"direct": "",
|
"direct": "Direct bericht",
|
||||||
"public": ""
|
"public": "Openbaar bericht"
|
||||||
},
|
},
|
||||||
"copy": {
|
"copy": {
|
||||||
"action": "Toot kopiëren",
|
"action": "Toot kopiëren",
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"title": "Selecteer mediabron",
|
"title": "Selecteer mediabron",
|
||||||
"message": "Media EXIF-gegevens zijn niet geüpload",
|
"message": "Media EXIF gegevens worden niet geüpload",
|
||||||
"options": {
|
"options": {
|
||||||
"image": "Foto's uploaden",
|
"image": "Foto's uploaden",
|
||||||
"image_max": "Foto's uploaden (max {{max}})",
|
"image_max": "Foto's uploaden (max {{max}})",
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"screenshot": {
|
"screenshot": {
|
||||||
"title": "Privacy Bescherming",
|
"title": "Privacy Bescherming",
|
||||||
"message": "Gelieve de identiteit van een andere gebruiker niet openbaar te maken, zoals gebruikersnaam, avatar enz. Bedankt!",
|
"message": "Gelieve de identiteit van een andere gebruiker niet openbaar te maken, zoals gebruikersnaam of avatar en meer. Bedankt!",
|
||||||
"button": "Bevestig"
|
"button": "Bevestig"
|
||||||
},
|
},
|
||||||
"localCorrupt": {
|
"localCorrupt": {
|
||||||
|
@@ -290,7 +290,7 @@
|
|||||||
"heading": "Tooot beoordelen"
|
"heading": "Tooot beoordelen"
|
||||||
},
|
},
|
||||||
"contact": {
|
"contact": {
|
||||||
"heading": "Contacteer tooot"
|
"heading": "Tooot contacteren"
|
||||||
},
|
},
|
||||||
"version": "Version v{{version}}",
|
"version": "Version v{{version}}",
|
||||||
"instanceVersion": "Mastodon versie v{{version}}"
|
"instanceVersion": "Mastodon versie v{{version}}"
|
||||||
@@ -341,7 +341,7 @@
|
|||||||
"placeholder": "naar..."
|
"placeholder": "naar..."
|
||||||
},
|
},
|
||||||
"empty": {
|
"empty": {
|
||||||
"general": "Enter keyword to search for <bold>$t(screenTabs:shared.search.sections.accounts)</bold>、<bold>$t(screenTabs:shared.search.sections.hashtags)</bold> or <bold>$t(screenTabs:shared.search.sections.statuses)</bold>",
|
"general": "Voer trefwoord in om te zoeken naar <bold>$t(screenTabs:shared.search.sections.accounts)</bold>, <bold>$t(screenTabs:shared.search.sections.hashtags)</bold> of <bold>$t(screenTabs:shared.search.sections.statuses)</bold>",
|
||||||
"advanced": {
|
"advanced": {
|
||||||
"header": "Geavanceerd zoeken",
|
"header": "Geavanceerd zoeken",
|
||||||
"example": {
|
"example": {
|
||||||
@@ -352,7 +352,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"trending": {
|
"trending": {
|
||||||
"tags": ""
|
"tags": "Trending tags"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sections": {
|
"sections": {
|
||||||
@@ -363,7 +363,7 @@
|
|||||||
"notFound": "Kan <bold>{{searchTerm}}</bold> niet vinden gerelateerd aan {{type}}"
|
"notFound": "Kan <bold>{{searchTerm}}</bold> niet vinden gerelateerd aan {{type}}"
|
||||||
},
|
},
|
||||||
"toot": {
|
"toot": {
|
||||||
"name": "Discussies"
|
"name": "Gesprek"
|
||||||
},
|
},
|
||||||
"users": {
|
"users": {
|
||||||
"accounts": {
|
"accounts": {
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
"discard": "Bỏ qua",
|
"discard": "Bỏ qua",
|
||||||
"continue": "Tiếp tục",
|
"continue": "Tiếp tục",
|
||||||
"delete": "Xóa",
|
"delete": "Xóa",
|
||||||
"done": ""
|
"done": "Xong"
|
||||||
},
|
},
|
||||||
"customEmoji": {
|
"customEmoji": {
|
||||||
"accessibilityLabel": "Tùy chỉnh emoji {{emoji}}"
|
"accessibilityLabel": "Tùy chỉnh emoji {{emoji}}"
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
"action_false": "Theo dõi người này",
|
"action_false": "Theo dõi người này",
|
||||||
"action_true": "Ngưng theo dõi người này"
|
"action_true": "Ngưng theo dõi người này"
|
||||||
},
|
},
|
||||||
"inLists": "",
|
"inLists": "Quản lý người trong danh sách",
|
||||||
"mute": {
|
"mute": {
|
||||||
"action_false": "Ẩn người này",
|
"action_false": "Ẩn người này",
|
||||||
"action_true": "Bỏ ẩn người dùng"
|
"action_true": "Bỏ ẩn người dùng"
|
||||||
@@ -20,8 +20,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"at": {
|
"at": {
|
||||||
"direct": "",
|
"direct": "Nhắn riêng",
|
||||||
"public": ""
|
"public": "Công khai"
|
||||||
},
|
},
|
||||||
"copy": {
|
"copy": {
|
||||||
"action": "Sao chép tút",
|
"action": "Sao chép tút",
|
||||||
|
@@ -321,9 +321,9 @@
|
|||||||
"suspended": "Người này đã bị vô hiệu hóa"
|
"suspended": "Người này đã bị vô hiệu hóa"
|
||||||
},
|
},
|
||||||
"accountInLists": {
|
"accountInLists": {
|
||||||
"name": "",
|
"name": "Danh sách của @{{username}}",
|
||||||
"inLists": "",
|
"inLists": "Trong danh sách",
|
||||||
"notInLists": ""
|
"notInLists": "Danh sách khác"
|
||||||
},
|
},
|
||||||
"attachments": {
|
"attachments": {
|
||||||
"name": "<0 /><1>'s media</1>"
|
"name": "<0 /><1>'s media</1>"
|
||||||
@@ -352,7 +352,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"trending": {
|
"trending": {
|
||||||
"tags": ""
|
"tags": "Hashtag xu hướng"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sections": {
|
"sections": {
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
import { handleError } from '@api/helpers'
|
||||||
import { ComponentEmojis } from '@components/Emojis'
|
import { ComponentEmojis } from '@components/Emojis'
|
||||||
import { EmojisState } from '@components/Emojis/helpers/EmojisContext'
|
import { EmojisState } from '@components/Emojis/helpers/EmojisContext'
|
||||||
import { HeaderLeft, HeaderRight } from '@components/Header'
|
import { HeaderLeft, HeaderRight } from '@components/Header'
|
||||||
@@ -6,7 +7,6 @@ import haptics from '@root/components/haptics'
|
|||||||
import { useAppDispatch } from '@root/store'
|
import { useAppDispatch } from '@root/store'
|
||||||
import ComposeRoot from '@screens/Compose/Root'
|
import ComposeRoot from '@screens/Compose/Root'
|
||||||
import formatText from '@screens/Compose/utils/formatText'
|
import formatText from '@screens/Compose/utils/formatText'
|
||||||
import * as Sentry from '@sentry/react-native'
|
|
||||||
import { RootStackScreenProps } from '@utils/navigation/navigators'
|
import { RootStackScreenProps } from '@utils/navigation/navigators'
|
||||||
import { useTimelineMutation } from '@utils/queryHooks/timeline'
|
import { useTimelineMutation } from '@utils/queryHooks/timeline'
|
||||||
import { updateStoreReview } from '@utils/slices/contextsSlice'
|
import { updateStoreReview } from '@utils/slices/contextsSlice'
|
||||||
@@ -319,9 +319,8 @@ const ScreenCompose: React.FC<RootStackScreenProps<'Screen-Compose'>> = ({
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Sentry.setContext('Error object', { error })
|
|
||||||
Sentry.captureMessage('Posting error')
|
|
||||||
haptics('Error')
|
haptics('Error')
|
||||||
|
handleError({ message: 'Posting error', captureResponse: true })
|
||||||
composeDispatch({ type: 'posting', payload: false })
|
composeDispatch({ type: 'posting', payload: false })
|
||||||
Alert.alert(t('heading.right.alert.default.title'), undefined, [
|
Alert.alert(t('heading.right.alert.default.title'), undefined, [
|
||||||
{
|
{
|
||||||
|
@@ -23,7 +23,13 @@ const AccountInformationNote = React.memo(
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.note}>
|
<View style={styles.note}>
|
||||||
<ParseHTML content={account.note!} size={'M'} emojis={account.emojis} selectable />
|
<ParseHTML
|
||||||
|
content={account.note!}
|
||||||
|
size={'M'}
|
||||||
|
emojis={account.emojis}
|
||||||
|
selectable
|
||||||
|
numberOfLines={999}
|
||||||
|
/>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
@@ -4,8 +4,8 @@ import log from './log'
|
|||||||
const audio = () => {
|
const audio = () => {
|
||||||
log('log', 'audio', 'setting audio playback default options')
|
log('log', 'audio', 'setting audio playback default options')
|
||||||
Audio.setAudioModeAsync({
|
Audio.setAudioModeAsync({
|
||||||
interruptionModeIOS: InterruptionModeIOS.DuckOthers,
|
interruptionModeIOS: InterruptionModeIOS.DoNotMix,
|
||||||
interruptionModeAndroid: InterruptionModeAndroid.DuckOthers,
|
interruptionModeAndroid: InterruptionModeAndroid.DoNotMix,
|
||||||
playsInSilentModeIOS: true,
|
playsInSilentModeIOS: true,
|
||||||
staysActiveInBackground: false
|
staysActiveInBackground: false
|
||||||
})
|
})
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import apiGeneral from '@api/general'
|
import apiGeneral from '@api/general'
|
||||||
|
import { handleError } from '@api/helpers'
|
||||||
import apiTooot from '@api/tooot'
|
import apiTooot from '@api/tooot'
|
||||||
import { displayMessage } from '@components/Message'
|
import { displayMessage } from '@components/Message'
|
||||||
import navigationRef from '@helpers/navigationRef'
|
import navigationRef from '@helpers/navigationRef'
|
||||||
@@ -33,11 +34,8 @@ const pushUseConnect = () => {
|
|||||||
})
|
})
|
||||||
.then(() => Notifications.setBadgeCountAsync(0))
|
.then(() => Notifications.setBadgeCountAsync(0))
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
Sentry.setContext('Error response', {
|
handleError({ message: 'Push connect error', captureResponse: true })
|
||||||
...(error?.response && { response: error.response?._response })
|
|
||||||
})
|
|
||||||
Sentry.setContext('Error object', { error })
|
|
||||||
Sentry.captureMessage('Push connect error')
|
|
||||||
Notifications.setBadgeCountAsync(0)
|
Notifications.setBadgeCountAsync(0)
|
||||||
if (error?.status == 404) {
|
if (error?.status == 404) {
|
||||||
displayMessage({
|
displayMessage({
|
||||||
|
Reference in New Issue
Block a user