Compare commits

...

10 Commits

Author SHA1 Message Date
xmflsct 6dad65631f
Merge pull request #300 from tooot-app/main
Release v4.0.2
2022-05-18 00:27:47 +02:00
xmflsct 0479e2fc9f
Merge pull request #297 from tooot-app/l10n_main
New Crowdin updates
2022-05-18 00:11:49 +02:00
Zhiyuan Zheng 4dcc561cbf Update error tracing 2022-05-18 00:11:31 +02:00
Zhiyuan Zheng 051dc7be8c Update Screens.tsx
https://github.com/tooot-app/app/issues/298
2022-05-18 00:11:02 +02:00
Zhiyuan Zheng 8a1ccdb305 Update instancesSlice.ts 2022-05-17 23:26:29 +02:00
Zhiyuan Zheng 02360c443f Make error object as optional 2022-05-17 23:18:49 +02:00
Zhiyuan Zheng 4b3b222582 Some Android phones do not have StoreReview? 2022-05-17 23:14:23 +02:00
Zhiyuan Zheng 5d615174cb Fix possible undefined 2022-05-17 23:12:43 +02:00
Zhiyuan Zheng 94e9e023e3 Fix account setting cannot be opened 2022-05-17 23:10:25 +02:00
xmflsct f7e8d90f1a New translations timeline.json (Chinese Simplified) 2022-05-17 03:40:36 +02:00
17 changed files with 55 additions and 55 deletions

View File

@ -4,7 +4,7 @@
"native": "220508",
"major": 4,
"minor": 0,
"patch": 1,
"patch": 2,
"expo": "45.0.0"
},
"description": "tooot app for Mastodon",

View File

@ -54,6 +54,7 @@ import { enableFreeze } from 'react-native-screens'
import { QueryClientProvider } from 'react-query'
import { Provider } from 'react-redux'
import { PersistGate } from 'redux-persist/integration/react'
import * as Sentry from 'sentry-expo'
Platform.select({
android: LogBox.ignoreLogs(['Setting a timer for a long period of time'])
@ -128,13 +129,15 @@ const App: React.FC = () => {
}
return (
<ActionSheetProvider>
<AccessibilityManager>
<ThemeManager>
<Screens localCorrupt={localCorrupt} />
</ThemeManager>
</AccessibilityManager>
</ActionSheetProvider>
<Sentry.Native.TouchEventBoundary>
<ActionSheetProvider>
<AccessibilityManager>
<ThemeManager>
<Screens localCorrupt={localCorrupt} />
</ThemeManager>
</AccessibilityManager>
</ActionSheetProvider>
</Sentry.Native.TouchEventBoundary>
)
} else {
return null

View File

@ -322,7 +322,11 @@ const Screens: React.FC<Props> = ({ localCorrupt }) => {
return (
<IntlProvider locale={i18n.language}>
<StatusBar backgroundColor={colors.backgroundDefault} />
<StatusBar
{...(Platform.OS === 'ios' && {
backgroundColor: colors.backgroundDefault
})}
/>
<NavigationContainer
ref={navigationRef}
theme={themes[theme]}

View File

@ -58,16 +58,7 @@ const apiGeneral = async <T = unknown>({
})
})
.catch(error => {
// if (sentry && Math.random() < 0.01) {
// Sentry.Native.setExtras({
// API: 'general',
// ...(error.response && { response: error.response }),
// ...(error.request && { request: error.request })
// })
// Sentry.Native.captureException(error)
// }
if (error.response) {
if (error?.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
console.error(
@ -80,7 +71,7 @@ const apiGeneral = async <T = unknown>({
status: error.response.status,
message: error.response.data.error
})
} else if (error.request) {
} else if (error?.request) {
// The request was made but no response was received
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
// http.ClientRequest in node.js
@ -94,7 +85,7 @@ const apiGeneral = async <T = unknown>({
console.error(
ctx.bold(' API general '),
ctx.bold('internal'),
error.message,
error?.message,
url
)
return Promise.reject()

View File

@ -100,16 +100,7 @@ const apiInstance = async <T = unknown>({
})
})
.catch(error => {
// if (Math.random() < 0.001) {
// Sentry.Native.setExtras({
// API: 'instance',
// ...(error.response && { response: error.response }),
// ...(error.request && { request: error.request })
// })
// Sentry.Native.captureException(error)
// }
if (error.response) {
if (error?.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
console.error(
@ -122,7 +113,7 @@ const apiInstance = async <T = unknown>({
status: error.response.status,
message: error.response.data.error
})
} else if (error.request) {
} else if (error?.request) {
// The request was made but no response was received
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
// http.ClientRequest in node.js
@ -132,7 +123,7 @@ const apiInstance = async <T = unknown>({
console.error(
ctx.bold(' API instance '),
ctx.bold('internal'),
error.message,
error?.message,
url
)
return Promise.reject()

View File

@ -66,16 +66,16 @@ const apiTooot = async <T = unknown>({
})
})
.catch(error => {
if (sentry && Math.random() < 0.01) {
if (sentry && Math.random() < 0.1) {
Sentry.Native.setExtras({
API: 'tooot',
...(error.response && { response: error.response }),
...(error.request && { request: error.request })
...(error?.response && { response: error.response }),
...(error?.request && { request: error.request })
})
Sentry.Native.captureException(error)
}
if (error.response) {
if (error?.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
console.error(
@ -88,7 +88,7 @@ const apiTooot = async <T = unknown>({
status: error.response.status,
message: error.response.data.error
})
} else if (error.request) {
} else if (error?.request) {
// The request was made but no response was received
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
// http.ClientRequest in node.js
@ -102,7 +102,7 @@ const apiTooot = async <T = unknown>({
console.error(
ctx.bold(' API tooot '),
ctx.bold('internal'),
error.message,
error?.message,
url
)
return Promise.reject()

View File

@ -22,7 +22,7 @@ const TimelineActioned = React.memo(
const { colors } = useTheme()
const navigation =
useNavigation<StackNavigationProp<TabLocalStackParamList>>()
const name = account.display_name || account.username
const name = account?.display_name || account.username
const iconColor = colors.primaryDefault
const content = (content: string) => (

View File

@ -101,7 +101,7 @@
"accessibilityHint": "用户帐户名"
}
},
"application": "发自{{application}}",
"application": "发自 {{application}}",
"edited": {
"accessibilityLabel": "嘟文已编辑"
},

View File

@ -354,7 +354,7 @@ const ScreenCompose: React.FC<RootStackScreenProps<'Screen-Compose'>> = ({
navigation.goBack()
})
.catch(error => {
if (error.removeReply) {
if (error?.removeReply) {
Alert.alert(
t('heading.right.alert.removeReply.title'),
t('heading.right.alert.removeReply.description'),
@ -377,7 +377,12 @@ const ScreenCompose: React.FC<RootStackScreenProps<'Screen-Compose'>> = ({
]
)
} else {
Sentry.Native.captureMessage('Compose posting', error)
Sentry.Native.captureMessage('Compose posting', {
contexts: {
errorObject: error,
errorString: error.toString()
}
})
haptics('Error')
composeDispatch({ type: 'posting', payload: false })
Alert.alert(t('heading.right.alert.default.title'), undefined, [

View File

@ -28,7 +28,8 @@ const Settings: React.FC = () => {
onPress={() =>
WebBrowser.openAuthSessionAsync(
`https://${url}/settings/preferences`,
''
'tooot://tooot',
{ dismissButtonStyle: 'done', readerMode: false }
)
}
/>

View File

@ -64,8 +64,8 @@ const SettingsTooot: React.FC = () => {
iconBack='ChevronRight'
onPress={() => {
analytics('settings_review_press')
StoreReview.isAvailableAsync().then(() =>
StoreReview.requestReview()
StoreReview?.isAvailableAsync().then(() =>
StoreReview?.requestReview()
)
}}
/>

View File

@ -35,7 +35,7 @@ const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
result.data.pages.flatMap(d => [...d.body])
: []
// Auto go back when toot page is empty
if (flattenData.length === 0) {
if (flattenData.length < 1) {
navigation.goBack()
return
}
@ -46,13 +46,14 @@ const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
if (pointer < 1) return
try {
setTimeout(() => {
console.log('scrolling')
flRef.current?.scrollToIndex({
index: pointer,
viewOffset: 100
})
}, 500)
} catch {}
} catch (error) {
return
}
}
}
})

View File

@ -41,10 +41,10 @@ const netInfo = async (): Promise<{
}).then(res => res.body)
} catch (error: any) {
log('error', 'netInfo', 'local credential check failed')
if (error.status && error.status == 401) {
if (error?.status && error.status == 401) {
store.dispatch(removeInstance(instance))
}
return Promise.resolve({ corrupted: error.data.error })
return Promise.resolve({ corrupted: error.data?.error })
}
log('log', 'netInfo', 'local credential check passed')

View File

@ -6,8 +6,9 @@ const sentry = () => {
log('log', 'Sentry', 'initializing')
Sentry.init({
dsn: 'https://53348b60ff844d52886e90251b3a5f41@o917354.ingest.sentry.io/6410576',
enableInExpoDevelopment: true,
debug: !isRelease
enableInExpoDevelopment: false,
debug: !isRelease,
autoSessionTracking: true
})
}

View File

@ -35,7 +35,7 @@ const pushUseConnect = ({ t, instances }: Params) => {
url: `push/connect/${expoToken}`,
sentry: true
}).catch(error => {
if (error.status == 404) {
if (error?.status == 404) {
displayMessage({
theme,
type: 'error',

View File

@ -41,7 +41,9 @@ const contextsSlice = createSlice({
if (Updates.releaseChannel.includes('release')) {
state.storeReview.current = state.storeReview.current + action.payload
if (state.storeReview.current === state.storeReview.context) {
StoreReview.isAvailableAsync().then(() => StoreReview.requestReview())
StoreReview?.isAvailableAsync().then(() =>
StoreReview.requestReview()
)
}
}
},

View File

@ -306,6 +306,7 @@ const instancesSlice = createSlice({
// Check if frequently used emojis still exist
.addCase(checkEmojis.fulfilled, (state, action) => {
if (!action.payload || !action.payload.length) return
const activeIndex = findInstanceActive(state.instances)
state.instances[activeIndex].frequentEmojis = state.instances[
activeIndex