Merge pull request #485 from tooot-app/main

Test v4.6.3
This commit is contained in:
xmflsct 2022-11-22 22:04:51 +01:00 committed by GitHub
commit 5097dfa4d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 275 additions and 309 deletions

View File

@ -108,29 +108,6 @@ private_lane :build_android do
end end
end end
desc "Build Android apk"
private_lane :build_android_apk do
sh("echo #{ENV["ANDROID_KEYSTORE"]} | base64 -d | tee #{File.expand_path('..', Dir.pwd)}/android/tooot.jks >/dev/null", log: false)
prepare_playstore_android
build_android_app(
task: 'assemble',
build_type: 'release',
project_dir: "./android",
print_command: true,
print_command_output: true,
properties: {
"android.injected.signing.store.file" => "#{File.expand_path('..', Dir.pwd)}/android/tooot.jks",
"android.injected.signing.store.password" => ENV["ANDROID_KEYSTORE_PASSWORD"],
"android.injected.signing.key.alias" => ENV["ANDROID_KEYSTORE_ALIAS"],
"android.injected.signing.key.password" => ENV["ANDROID_KEYSTORE_KEY_PASSWORD"],
}
)
sh "mv #{lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH]} #{File.expand_path('..', Dir.pwd)}/tooot-#{GITHUB_RELEASE}.apk"
end
lane :ios do lane :ios do
cocoapods(clean_install: true, podfile: "./ios/Podfile") cocoapods(clean_install: true, podfile: "./ios/Podfile")
build_ios build_ios
@ -144,15 +121,13 @@ end
lane :release do lane :release do
if ENVIRONMENT == 'release' if ENVIRONMENT == 'release'
build_android_apk
set_github_release( set_github_release(
repository_name: GITHUB_REPO, repository_name: GITHUB_REPO,
name: GITHUB_RELEASE, name: GITHUB_RELEASE,
tag_name: GITHUB_RELEASE, tag_name: GITHUB_RELEASE,
description: "No changelog provided", description: "No changelog provided",
commitish: git_branch, commitish: git_branch,
is_prerelease: false, is_prerelease: false
upload_assets: ["#{File.expand_path('..', Dir.pwd)}/tooot-#{GITHUB_RELEASE}.apk"]
) )
end end
rocket rocket

View File

@ -23,7 +23,7 @@ PODS:
- ExpoModulesCore - ExpoModulesCore
- EXNotifications (0.17.0): - EXNotifications (0.17.0):
- ExpoModulesCore - ExpoModulesCore
- Expo (47.0.6): - Expo (47.0.7):
- ExpoModulesCore - ExpoModulesCore
- ExpoCrypto (12.0.0): - ExpoCrypto (12.0.0):
- ExpoModulesCore - ExpoModulesCore
@ -419,7 +419,7 @@ PODS:
- React-Core - React-Core
- react-native-netinfo (9.3.6): - react-native-netinfo (9.3.6):
- React-Core - React-Core
- react-native-pager-view (6.1.0): - react-native-pager-view (6.1.1):
- React-Core - React-Core
- react-native-paste-input (0.5.1): - react-native-paste-input (0.5.1):
- React-Core - React-Core
@ -830,7 +830,7 @@ SPEC CHECKSUMS:
EXFirebaseCore: d0d88cb904e893af07f809ab08c0892489bc6956 EXFirebaseCore: d0d88cb904e893af07f809ab08c0892489bc6956
EXFont: 319606bfe48c33b5b5063fb0994afdc496befe80 EXFont: 319606bfe48c33b5b5063fb0994afdc496befe80
EXNotifications: babce2a87b7922051354fcfe7a74dd279b7e272a EXNotifications: babce2a87b7922051354fcfe7a74dd279b7e272a
Expo: a581e979539bae3e49cd02d9dee2432947383d3b Expo: a37d568e9ae87645b74ed597dd0f0fd89e2daf2d
ExpoCrypto: 51e7662c7f5bfeab25b7909b8a5d545ec15d4877 ExpoCrypto: 51e7662c7f5bfeab25b7909b8a5d545ec15d4877
ExpoHaptics: 5a56d30a87ea213dd00b09566dc4b441a4dff97f ExpoHaptics: 5a56d30a87ea213dd00b09566dc4b441a4dff97f
ExpoKeepAwake: 69b59d0a8d2b24de9f82759c39b3821fec030318 ExpoKeepAwake: 69b59d0a8d2b24de9f82759c39b3821fec030318
@ -884,7 +884,7 @@ SPEC CHECKSUMS:
react-native-language-detection: 0e43195ad014974f1b7a31b64820eff34a243f2d react-native-language-detection: 0e43195ad014974f1b7a31b64820eff34a243f2d
react-native-live-text-image-view: 483bacfdba464162b8cf176bba555364f18b584c react-native-live-text-image-view: 483bacfdba464162b8cf176bba555364f18b584c
react-native-netinfo: f80db8cac2151405633324cb645c60af098ee461 react-native-netinfo: f80db8cac2151405633324cb645c60af098ee461
react-native-pager-view: 7abf89f9834d9a4021b2fb6a5ef2abff570b46fb react-native-pager-view: 3c66c4e2f3ab423643d07b2c7041f8ac48395f72
react-native-paste-input: 183ad7dc224e192719616f4258dde5b548627d08 react-native-paste-input: 183ad7dc224e192719616f4258dde5b548627d08
react-native-safe-area-context: 99b24a0c5acd0d5dcac2b1a7f18c49ea317be99a react-native-safe-area-context: 99b24a0c5acd0d5dcac2b1a7f18c49ea317be99a
react-native-segmented-control: 65df6cd0619b780b3843d574a72d4c7cec396097 react-native-segmented-control: 65df6cd0619b780b3843d574a72d4c7cec396097

View File

@ -1,6 +1,6 @@
{ {
"name": "tooot", "name": "tooot",
"version": "4.6.2", "version": "4.6.3",
"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",
@ -33,15 +33,15 @@
"@react-native-community/blur": "^4.3.0", "@react-native-community/blur": "^4.3.0",
"@react-native-community/netinfo": "9.3.6", "@react-native-community/netinfo": "9.3.6",
"@react-native-community/segmented-control": "^2.2.2", "@react-native-community/segmented-control": "^2.2.2",
"@react-navigation/bottom-tabs": "^6.4.0", "@react-navigation/bottom-tabs": "^6.4.1",
"@react-navigation/native": "^6.0.13", "@react-navigation/native": "^6.0.14",
"@react-navigation/native-stack": "^6.9.1", "@react-navigation/native-stack": "^6.9.2",
"@react-navigation/stack": "^6.3.4", "@react-navigation/stack": "^6.3.5",
"@reduxjs/toolkit": "^1.9.0", "@reduxjs/toolkit": "^1.9.0",
"@sentry/react-native": "4.8.0", "@sentry/react-native": "4.8.0",
"@sharcoux/slider": "^6.0.3", "@sharcoux/slider": "^6.0.3",
"axios": "^0.27.2", "axios": "^0.27.2",
"expo": "^47.0.6", "expo": "^47.0.7",
"expo-auth-session": "^3.7.2", "expo-auth-session": "^3.7.2",
"expo-av": "^13.0.1", "expo-av": "^13.0.1",
"expo-constants": "^14.0.2", "expo-constants": "^14.0.2",
@ -80,7 +80,7 @@
"react-native-image-picker": "^4.10.1", "react-native-image-picker": "^4.10.1",
"react-native-language-detection": "^0.1.0", "react-native-language-detection": "^0.1.0",
"react-native-live-text-image-view": "^0.4.0", "react-native-live-text-image-view": "^0.4.0",
"react-native-pager-view": "^6.1.0", "react-native-pager-view": "^6.1.1",
"react-native-reanimated": "^2.13.0", "react-native-reanimated": "^2.13.0",
"react-native-reanimated-zoom": "^0.3.3", "react-native-reanimated-zoom": "^0.3.3",
"react-native-safe-area-context": "^4.4.1", "react-native-safe-area-context": "^4.4.1",

View File

@ -131,6 +131,9 @@ const contextMenuAccount = ({ actions, type, queryKey, rootQueryKey, id: account
} }
return (index: number) => { return (index: number) => {
if (typeof index !== 'number' || !actions[index]) {
return // For Android
}
if (actions[index].id === 'account-mute') { if (actions[index].id === 'account-mute') {
analytics('timeline_shared_headeractions_account_mute_press', { analytics('timeline_shared_headeractions_account_mute_press', {
page: queryKey && queryKey[1].page page: queryKey && queryKey[1].page

View File

@ -1,9 +1,6 @@
import analytics from '@components/analytics' import analytics from '@components/analytics'
import { displayMessage } from '@components/Message' import { displayMessage } from '@components/Message'
import { import { QueryKeyTimeline, useTimelineMutation } from '@utils/queryHooks/timeline'
QueryKeyTimeline,
useTimelineMutation
} from '@utils/queryHooks/timeline'
import { getInstanceUrl } from '@utils/slices/instancesSlice' import { getInstanceUrl } from '@utils/slices/instancesSlice'
import { useTheme } from '@utils/styles/ThemeManager' import { useTheme } from '@utils/styles/ThemeManager'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
@ -19,12 +16,7 @@ export interface Props {
rootQueryKey?: QueryKeyTimeline rootQueryKey?: QueryKeyTimeline
} }
const contextMenuInstance = ({ const contextMenuInstance = ({ actions, status, queryKey, rootQueryKey }: Props) => {
actions,
status,
queryKey,
rootQueryKey
}: Props) => {
const { t } = useTranslation('componentContextMenu') const { t } = useTranslation('componentContextMenu')
const { theme } = useTheme() const { theme } = useTheme()
@ -72,10 +64,12 @@ const contextMenuInstance = ({
} }
return (index: number) => { return (index: number) => {
if (typeof index !== 'number' || !actions[index]) {
return // For Android
}
if ( if (
actions[index].id === 'instance-block' || actions[index].id === 'instance-block' ||
(actions[index].id === 'instance' && (actions[index].id === 'instance' && actions[index].actions?.[0].id === 'instance-block')
actions[index].actions?.[0].id === 'instance-block')
) { ) {
analytics('timeline_shared_headeractions_domain_block_press', { analytics('timeline_shared_headeractions_domain_block_press', {
page: queryKey[1].page page: queryKey[1].page

View File

@ -25,7 +25,8 @@ const contextMenuShare = ({ copiableContent, actions, type, url }: Props) => {
title: t(`share.${type}.action`), title: t(`share.${type}.action`),
systemIcon: 'square.and.arrow.up' systemIcon: 'square.and.arrow.up'
}) })
Platform.OS !== 'android' && type === 'status' && Platform.OS !== 'android' &&
type === 'status' &&
actions.push({ actions.push({
id: 'copy', id: 'copy',
title: t(`copy.action`), title: t(`copy.action`),
@ -34,6 +35,9 @@ const contextMenuShare = ({ copiableContent, actions, type, url }: Props) => {
}) })
return (index: number) => { return (index: number) => {
if (typeof index !== 'number' || !actions[index]) {
return // For Android
}
if (actions[index].id === 'copy') { if (actions[index].id === 'copy') {
analytics('timeline_shared_headeractions_copy_press') analytics('timeline_shared_headeractions_copy_press')
Clipboard.setString(copiableContent?.current.content || '') Clipboard.setString(copiableContent?.current.content || '')

View File

@ -9,10 +9,7 @@ import {
QueryKeyTimeline, QueryKeyTimeline,
useTimelineMutation useTimelineMutation
} from '@utils/queryHooks/timeline' } from '@utils/queryHooks/timeline'
import { import { checkInstanceFeature, getInstanceAccount } from '@utils/slices/instancesSlice'
checkInstanceFeature,
getInstanceAccount
} from '@utils/slices/instancesSlice'
import { useTheme } from '@utils/styles/ThemeManager' import { useTheme } from '@utils/styles/ThemeManager'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { Alert } from 'react-native' import { Alert } from 'react-native'
@ -27,16 +24,8 @@ export interface Props {
rootQueryKey?: QueryKeyTimeline rootQueryKey?: QueryKeyTimeline
} }
const contextMenuStatus = ({ const contextMenuStatus = ({ actions, status, queryKey, rootQueryKey }: Props) => {
actions, const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList, 'Screen-Tabs'>>()
status,
queryKey,
rootQueryKey
}: Props) => {
const navigation =
useNavigation<
NativeStackNavigationProp<RootStackParamList, 'Screen-Tabs'>
>()
const { theme } = useTheme() const { theme } = useTheme()
const { t } = useTranslation('componentContextMenu') const { t } = useTranslation('componentContextMenu')
@ -44,8 +33,7 @@ const contextMenuStatus = ({
const mutation = useTimelineMutation({ const mutation = useTimelineMutation({
onMutate: true, onMutate: true,
onError: (err: any, params, oldData) => { onError: (err: any, params, oldData) => {
const theFunction = (params as MutationVarsTimelineUpdateStatusProperty) const theFunction = (params as MutationVarsTimelineUpdateStatusProperty).payload
.payload
? (params as MutationVarsTimelineUpdateStatusProperty).payload.property ? (params as MutationVarsTimelineUpdateStatusProperty).payload.property
: 'delete' : 'delete'
displayMessage({ displayMessage({
@ -59,17 +47,14 @@ const contextMenuStatus = ({
err.data && err.data &&
err.data.error && err.data.error &&
typeof err.data.error === 'string' && { typeof err.data.error === 'string' && {
description: err.data.error description: err.data.error
}) })
}) })
queryClient.setQueryData(queryKey, oldData) queryClient.setQueryData(queryKey, oldData)
} }
}) })
const instanceAccount = useSelector( const instanceAccount = useSelector(getInstanceAccount, (prev, next) => prev.id === next.id)
getInstanceAccount,
(prev, next) => prev.id === next.id
)
const ownAccount = instanceAccount?.id === status?.account?.id const ownAccount = instanceAccount?.id === status?.account?.id
if (ownAccount) { if (ownAccount) {
@ -118,83 +103,75 @@ const contextMenuStatus = ({
} }
return async (index: number) => { return async (index: number) => {
if (typeof index !== 'number' || !actions[index]) {
return // For Android
}
if (actions[index].id === 'status-delete') { if (actions[index].id === 'status-delete') {
analytics('timeline_shared_headeractions_status_delete_press', { analytics('timeline_shared_headeractions_status_delete_press', {
page: queryKey && queryKey[1].page page: queryKey && queryKey[1].page
}) })
Alert.alert( Alert.alert(t('status.delete.alert.title'), t('status.delete.alert.message'), [
t('status.delete.alert.title'), {
t('status.delete.alert.message'), text: t('status.delete.alert.buttons.confirm'),
[ style: 'destructive',
{ onPress: async () => {
text: t('status.delete.alert.buttons.confirm'), analytics('timeline_shared_headeractions_status_delete_confirm', {
style: 'destructive', page: queryKey && queryKey[1].page
onPress: async () => { })
analytics('timeline_shared_headeractions_status_delete_confirm', { mutation.mutate({
page: queryKey && queryKey[1].page type: 'deleteItem',
}) source: 'statuses',
mutation.mutate({ queryKey,
type: 'deleteItem', rootQueryKey,
source: 'statuses', id: status.id
queryKey, })
rootQueryKey,
id: status.id
})
}
},
{
text: t('common:buttons.cancel')
} }
] },
) {
text: t('common:buttons.cancel')
}
])
} }
if (actions[index].id === 'status-delete-edit') { if (actions[index].id === 'status-delete-edit') {
analytics('timeline_shared_headeractions_status_deleteedit_press', { analytics('timeline_shared_headeractions_status_deleteedit_press', {
page: queryKey && queryKey[1].page page: queryKey && queryKey[1].page
}) })
Alert.alert( Alert.alert(t('status.deleteEdit.alert.title'), t('status.deleteEdit.alert.message'), [
t('status.deleteEdit.alert.title'), {
t('status.deleteEdit.alert.message'), text: t('status.deleteEdit.alert.buttons.confirm'),
[ style: 'destructive',
{ onPress: async () => {
text: t('status.deleteEdit.alert.buttons.confirm'), analytics('timeline_shared_headeractions_status_deleteedit_confirm', {
style: 'destructive', page: queryKey && queryKey[1].page
onPress: async () => { })
analytics( let replyToStatus: Mastodon.Status | undefined = undefined
'timeline_shared_headeractions_status_deleteedit_confirm', if (status.in_reply_to_id) {
{ replyToStatus = await apiInstance<Mastodon.Status>({
page: queryKey && queryKey[1].page method: 'get',
} url: `statuses/${status.in_reply_to_id}`
) }).then(res => res.body)
let replyToStatus: Mastodon.Status | undefined = undefined
if (status.in_reply_to_id) {
replyToStatus = await apiInstance<Mastodon.Status>({
method: 'get',
url: `statuses/${status.in_reply_to_id}`
}).then(res => res.body)
}
mutation
.mutateAsync({
type: 'deleteItem',
source: 'statuses',
queryKey,
id: status.id
})
.then(res => {
navigation.navigate('Screen-Compose', {
type: 'deleteEdit',
incomingStatus: res.body as Mastodon.Status,
...(replyToStatus && { replyToStatus }),
queryKey
})
})
} }
}, mutation
{ .mutateAsync({
text: t('common:buttons.cancel') type: 'deleteItem',
source: 'statuses',
queryKey,
id: status.id
})
.then(res => {
navigation.navigate('Screen-Compose', {
type: 'deleteEdit',
incomingStatus: res.body as Mastodon.Status,
...(replyToStatus && { replyToStatus }),
queryKey
})
})
} }
] },
) {
text: t('common:buttons.cancel')
}
])
} }
if (actions[index].id === 'status-mute') { if (actions[index].id === 'status-mute') {
analytics('timeline_shared_headeractions_status_mute_press', { analytics('timeline_shared_headeractions_status_mute_press', {

View File

@ -157,15 +157,6 @@ const TimelineDefault: React.FC<Props> = ({
return disableOnPress ? ( return disableOnPress ? (
<View style={mainStyle}>{main()}</View> <View style={mainStyle}>{main()}</View>
) : Platform.OS === 'android' ? (
<Pressable
accessible={highlighted ? false : true}
style={mainStyle}
onPress={onPress}
onLongPress={() => {}}
>
{main()}
</Pressable>
) : ( ) : (
<TimelineContextMenu <TimelineContextMenu
copiableContent={copiableContent} copiableContent={copiableContent}

View File

@ -64,7 +64,7 @@ const AttachmentVideo: React.FC<Props> = ({
}, []) }, [])
const _handleAppStateChange = async (nextAppState: AppStateStatus) => { const _handleAppStateChange = async (nextAppState: AppStateStatus) => {
if (appState.current.match(/active/) && nextAppState.match(/inactive/)) { if (appState.current.match(/active/) && nextAppState.match(/inactive/)) {
await videoPlayer.current?.stopAsync() // await videoPlayer.current?.stopAsync()
} else if (gifv && appState.current.match(/background/) && nextAppState.match(/active/)) { } else if (gifv && appState.current.match(/background/) && nextAppState.match(/active/)) {
await videoPlayer.current?.setIsMutedAsync(true) await videoPlayer.current?.setIsMutedAsync(true)
await videoPlayer.current?.playAsync() await videoPlayer.current?.playAsync()

View File

@ -3,13 +3,14 @@ import contextMenuInstance from '@components/ContextMenu/instance'
import contextMenuShare from '@components/ContextMenu/share' import contextMenuShare from '@components/ContextMenu/share'
import contextMenuStatus from '@components/ContextMenu/status' import contextMenuStatus from '@components/ContextMenu/status'
import Icon from '@components/Icon' import Icon from '@components/Icon'
import { useActionSheet } from '@expo/react-native-action-sheet'
import { QueryKeyTimeline } from '@utils/queryHooks/timeline' import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
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 React from 'react' import React from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { Pressable, View } from 'react-native' import { Pressable, View } from 'react-native'
import ContextMenu, { ContextMenuAction } from 'react-native-context-menu-view' import { ContextMenuAction } from 'react-native-context-menu-view'
import HeaderSharedAccount from './HeaderShared/Account' import HeaderSharedAccount from './HeaderShared/Account'
import HeaderSharedApplication from './HeaderShared/Application' import HeaderSharedApplication from './HeaderShared/Application'
import HeaderSharedCreated from './HeaderShared/Created' import HeaderSharedCreated from './HeaderShared/Created'
@ -55,6 +56,8 @@ const TimelineHeaderDefault = ({ queryKey, status, highlighted }: Props) => {
queryKey queryKey
}) })
const { showActionSheetWithOptions } = useActionSheet()
return ( return (
<View style={{ flex: 1, flexDirection: 'row' }}> <View style={{ flex: 1, flexDirection: 'row' }}>
<View style={{ flex: 7 }}> <View style={{ flex: 7 }}>
@ -82,25 +85,26 @@ const TimelineHeaderDefault = ({ queryKey, status, highlighted }: Props) => {
<Pressable <Pressable
accessibilityHint={t('accessibilityHint')} accessibilityHint={t('accessibilityHint')}
style={{ flex: 1, flexBasis: StyleConstants.Font.Size.L }} style={{ flex: 1, flexBasis: StyleConstants.Font.Size.L }}
onLongPress={() => null} onPress={() =>
> showActionSheetWithOptions(
<ContextMenu {
style={{ flex: 1, alignItems: 'center' }} options: actions.map(action => action.title),
dropdownMenuMode cancelButtonIndex: 999,
actions={actions} destructiveButtonIndex: actions
onPress={({ nativeEvent: { index } }) => { .map((action, index) => (action.destructive ? index : 999))
for (const on of [shareOnPress, statusOnPress, accountOnPress, instanceOnPress]) { .filter(num => num !== 999)
on && on(index) },
index => {
if (index !== undefined) {
for (const on of [shareOnPress, statusOnPress, accountOnPress, instanceOnPress]) {
on && on(index)
}
}
} }
}} )
children={ }
<Icon >
name='MoreHorizontal' <Icon name='MoreHorizontal' color={colors.secondary} size={StyleConstants.Font.Size.L} />
color={colors.secondary}
size={StyleConstants.Font.Size.L}
/>
}
/>
</Pressable> </Pressable>
) : null} ) : null}
</View> </View>

View File

@ -4,12 +4,13 @@ import contextMenuShare from '@components/ContextMenu/share'
import contextMenuStatus from '@components/ContextMenu/status' import contextMenuStatus from '@components/ContextMenu/status'
import Icon from '@components/Icon' import Icon from '@components/Icon'
import { RelationshipIncoming, RelationshipOutgoing } from '@components/Relationship' import { RelationshipIncoming, RelationshipOutgoing } from '@components/Relationship'
import { useActionSheet } from '@expo/react-native-action-sheet'
import { QueryKeyTimeline } from '@utils/queryHooks/timeline' import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
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 React, { useMemo } from 'react' import React, { useMemo } from 'react'
import { Pressable, View } from 'react-native' import { Pressable, View } from 'react-native'
import ContextMenu, { ContextMenuAction } from 'react-native-context-menu-view' import { ContextMenuAction } from 'react-native-context-menu-view'
import HeaderSharedAccount from './HeaderShared/Account' import HeaderSharedAccount from './HeaderShared/Account'
import HeaderSharedApplication from './HeaderShared/Application' import HeaderSharedApplication from './HeaderShared/Application'
import HeaderSharedCreated from './HeaderShared/Created' import HeaderSharedCreated from './HeaderShared/Created'
@ -57,6 +58,8 @@ const TimelineHeaderNotification = ({ queryKey, notification }: Props) => {
queryKey queryKey
}) })
const { showActionSheetWithOptions } = useActionSheet()
const actions = useMemo(() => { const actions = useMemo(() => {
switch (notification.type) { switch (notification.type) {
case 'follow': case 'follow':
@ -68,29 +71,34 @@ const TimelineHeaderNotification = ({ queryKey, notification }: Props) => {
return ( return (
<Pressable <Pressable
style={{ flex: 1, flexBasis: StyleConstants.Font.Size.L }} style={{ flex: 1, flexBasis: StyleConstants.Font.Size.L }}
onLongPress={() => null} onPress={() =>
children={ showActionSheetWithOptions(
<ContextMenu {
style={{ flex: 1, alignItems: 'center' }} options: contextMenuActions.map(action => action.title),
dropdownMenuMode cancelButtonIndex: 999,
actions={contextMenuActions} destructiveButtonIndex: contextMenuActions
onPress={({ nativeEvent: { index } }) => { .map((action, index) => (action.destructive ? index : 999))
for (const on of [ .filter(num => num !== 999)
shareOnPress, },
statusOnPress, index => {
accountOnPress, if (index !== undefined) {
instanceOnPress for (const on of [
]) { shareOnPress,
on && on(index) statusOnPress,
accountOnPress,
instanceOnPress
]) {
on && on(index)
}
} }
}}
children={
<Icon
name='MoreHorizontal'
color={colors.secondary}
size={StyleConstants.Font.Size.L}
/>
} }
)
}
children={
<Icon
name='MoreHorizontal'
color={colors.secondary}
size={StyleConstants.Font.Size.L}
/> />
} }
/> />

View File

@ -26,7 +26,6 @@ const HeaderSharedApplication = React.memo(
application.website && (await openLink(application.website)) application.website && (await openLink(application.website))
}} }}
style={{ style={{
flex: 1,
marginLeft: StyleConstants.Spacing.S, marginLeft: StyleConstants.Spacing.S,
color: colors.secondary color: colors.secondary
}} }}

View File

@ -36,7 +36,7 @@
"action": "Tröt teilen" "action": "Tröt teilen"
}, },
"account": { "account": {
"action": "User verlinken" "action": "Link zum Profil teilen"
} }
}, },
"status": { "status": {
@ -55,17 +55,17 @@
} }
}, },
"deleteEdit": { "deleteEdit": {
"action": "Tröt und Boost entfernen", "action": "Tröt neu entwerfen",
"alert": { "alert": {
"title": "Löschen und Boost bestätigen?", "title": "Beitrag wirklich entfernen?",
"message": "Alle Boosts und Favoriten inklusive der Antworten werden gelöscht.", "message": "Alle Boosts und Likes inklusive der Antworten werden gelöscht.",
"buttons": { "buttons": {
"confirm": "Bestätigen" "confirm": "Bestätigen"
} }
} }
}, },
"mute": { "mute": {
"action_false": "Diesen Tröt sowie die Antworten stummschalten", "action_false": "Diskussion stummschalten",
"action_true": "Tröt und Antworten nicht mehr stummschalten" "action_true": "Tröt und Antworten nicht mehr stummschalten"
}, },
"pin": { "pin": {

View File

@ -11,7 +11,7 @@
"domains": "Domains" "domains": "Domains"
}, },
"disclaimer": { "disclaimer": {
"base": "Der Login erfolgt über den Browser, so dass Ihre Kontoinformationen für die Toot-App nicht sichtbar sind." "base": "Der Login erfolgt über den Browser, sodass deine Kontoinformationen für die App nicht sichtbar sind."
}, },
"terms": { "terms": {
"base": "Mit dem Login stimmst du der <0>Datenschutzrichtlinie</0> und den <1>Nutzungsbedingungen</1> zu." "base": "Mit dem Login stimmst du der <0>Datenschutzrichtlinie</0> und den <1>Nutzungsbedingungen</1> zu."

View File

@ -47,7 +47,7 @@
}, },
"favourited": { "favourited": {
"accessibilityLabel": "Favorit", "accessibilityLabel": "Favorit",
"function": "Sternen" "function": "Liken"
}, },
"bookmarked": { "bookmarked": {
"accessibilityLabel": "Lesezeichen hinzufügen", "accessibilityLabel": "Lesezeichen hinzufügen",
@ -67,7 +67,7 @@
}, },
"history": { "history": {
"accessibilityLabel": "Dieser Tröt wurde {{count}} mal bearbeitet", "accessibilityLabel": "Dieser Tröt wurde {{count}} mal bearbeitet",
"accessibilityHint": "Für den vollständigen Verlauf auswählen", "accessibilityHint": "Bearbeitungsverlauf anzeigen",
"text_one": "{{count}} Bearbeitung", "text_one": "{{count}} Bearbeitung",
"text_other": "{{count}} mal bearbeitet" "text_other": "{{count}} mal bearbeitet"
} }

View File

@ -12,7 +12,7 @@
"reblog": "$t(screenTabs:me.push.reblog.heading)", "reblog": "$t(screenTabs:me.push.reblog.heading)",
"mention": "$t(screenTabs:me.push.mention.heading)", "mention": "$t(screenTabs:me.push.mention.heading)",
"poll": "$t(screenTabs:me.push.poll.heading)", "poll": "$t(screenTabs:me.push.poll.heading)",
"status": "Toot eines abonnierten Nutzers", "status": "Tt eines abonnierten Nutzers",
"update": "Boost wurde bearbeitet" "update": "Boost wurde bearbeitet"
} }
} }

View File

@ -125,7 +125,7 @@
"options": { "options": {
"public": "Öffentlich", "public": "Öffentlich",
"unlisted": "Ungelistet", "unlisted": "Ungelistet",
"private": "Nur für Folgende", "private": "Nur für Follower",
"cancel": "$t(common:buttons.cancel)" "cancel": "$t(common:buttons.cancel)"
} }
}, },

View File

@ -312,7 +312,7 @@
}, },
"hashtag": { "hashtag": {
"follow": "フォロー", "follow": "フォロー",
"unfollow": "フォローをやめる" "unfollow": "フォロー解除"
}, },
"history": { "history": {
"name": "編集履歴" "name": "編集履歴"

View File

@ -39,7 +39,7 @@
"header": { "header": {
"postingAs": "Skriver som @{{acct}}@{{domain}}", "postingAs": "Skriver som @{{acct}}@{{domain}}",
"spoilerInput": { "spoilerInput": {
"placeholder": "Spoilervarningsmeddelande" "placeholder": "Innehållsvarning"
}, },
"textInput": { "textInput": {
"placeholder": "Vad tänker du på", "placeholder": "Vad tänker du på",
@ -71,8 +71,8 @@
"option": { "option": {
"placeholder": { "placeholder": {
"accessibilityLabel": "Omröstningsalternativ {{index}}", "accessibilityLabel": "Omröstningsalternativ {{index}}",
"single": "Enval", "single": "Alternativ",
"multiple": "Flera val" "multiple": "Alternativ"
} }
}, },
"quantity": { "quantity": {
@ -89,7 +89,7 @@
"heading": "Typ av val", "heading": "Typ av val",
"options": { "options": {
"single": "Enval", "single": "Enval",
"multiple": "Flera val", "multiple": "Flerval",
"cancel": "$t(common:buttons.cancel)" "cancel": "$t(common:buttons.cancel)"
} }
}, },
@ -135,7 +135,7 @@
} }
}, },
"spoiler": { "spoiler": {
"accessibilityLabel": "Spoiler" "accessibilityLabel": "Innehållsvarning"
}, },
"emoji": { "emoji": {
"accessibilityLabel": "Lägg till emoji", "accessibilityLabel": "Lägg till emoji",

View File

@ -78,7 +78,7 @@
} }
}, },
"fontSize": { "fontSize": {
"demo": "<p>Det här är ett demoinlägg😊. Du kan välja mellan flera alternativ nedan.<br /><br />Denna inställning påverkar endast huvudinnehållet i inlägg men inte andra teckenstorlekar.</p>", "demo": "<p>Det här är ett demoinlägg 😊. Du kan välja mellan flera alternativ ovan.<br /><br />Denna inställning påverkar endast huvudinnehållet i inlägg men inte andra teckenstorlekar.</p>",
"sizes": { "sizes": {
"S": "S", "S": "S",
"M": "M - Standard", "M": "M - Standard",
@ -252,7 +252,7 @@
} }
}, },
"browser": { "browser": {
"heading": "Öppnar länk", "heading": "Öppna länk",
"options": { "options": {
"internal": "Inuti appen", "internal": "Inuti appen",
"external": "Använd systemets webbläsare", "external": "Använd systemets webbläsare",
@ -320,7 +320,7 @@
"search": { "search": {
"header": { "header": {
"prefix": "Söker", "prefix": "Söker",
"placeholder": "r..." "placeholder": "efter..."
}, },
"empty": { "empty": {
"general": "Ange sökord för att söka efter <bold>$t(screenTabs:shared.search.sections.accounts)</bold>, <bold>$t(screenTabs:shared.search.sections.hashtags)</bold> eller <bold>$t(screenTabs:shared.search.sections.statuses)</bold>", "general": "Ange sökord för att söka efter <bold>$t(screenTabs:shared.search.sections.accounts)</bold>, <bold>$t(screenTabs:shared.search.sections.hashtags)</bold> eller <bold>$t(screenTabs:shared.search.sections.statuses)</bold>",

View File

@ -4,7 +4,7 @@ import { AnyAction, configureStore, Reducer } from '@reduxjs/toolkit'
import contextsMigration from '@utils/migrations/contexts/migration' import contextsMigration from '@utils/migrations/contexts/migration'
import instancesMigration from '@utils/migrations/instances/migration' import instancesMigration from '@utils/migrations/instances/migration'
import settingsMigration from '@utils/migrations/settings/migration' import settingsMigration from '@utils/migrations/settings/migration'
import appSlice from '@utils/slices/appSlice' import appSlice, { AppState } from '@utils/slices/appSlice'
import contextsSlice, { ContextsState } from '@utils/slices/contextsSlice' import contextsSlice, { ContextsState } from '@utils/slices/contextsSlice'
import instancesSlice, { InstancesState } from '@utils/slices/instancesSlice' import instancesSlice, { InstancesState } from '@utils/slices/instancesSlice'
import settingsSlice, { SettingsState } from '@utils/slices/settingsSlice' import settingsSlice, { SettingsState } from '@utils/slices/settingsSlice'
@ -26,6 +26,13 @@ const secureStorage = createSecureStore()
const prefix = 'tooot' const prefix = 'tooot'
const appPersistConfig = {
key: 'app',
prefix,
storage: AsyncStorage,
version: 0
}
const contextsPersistConfig = { const contextsPersistConfig = {
key: 'contexts', key: 'contexts',
prefix, prefix,
@ -55,19 +62,19 @@ const settingsPersistConfig = {
const store = configureStore({ const store = configureStore({
reducer: { reducer: {
app: persistReducer(appPersistConfig, appSlice) as Reducer<AppState, AnyAction>,
contexts: persistReducer(contextsPersistConfig, contextsSlice) as Reducer< contexts: persistReducer(contextsPersistConfig, contextsSlice) as Reducer<
ContextsState, ContextsState,
AnyAction AnyAction
>, >,
instances: persistReducer( instances: persistReducer(instancesPersistConfig, instancesSlice) as Reducer<
instancesPersistConfig, InstancesState,
instancesSlice AnyAction
) as Reducer<InstancesState, AnyAction>, >,
settings: persistReducer(settingsPersistConfig, settingsSlice) as Reducer< settings: persistReducer(settingsPersistConfig, settingsSlice) as Reducer<
SettingsState, SettingsState,
AnyAction AnyAction
>, >
app: appSlice
}, },
middleware: getDefaultMiddleware => middleware: getDefaultMiddleware =>
getDefaultMiddleware({ getDefaultMiddleware({

View File

@ -0,0 +1,4 @@
export type AppV0 = {
expoToken?: string
versionUpdate: boolean
}

View File

@ -33,53 +33,55 @@ const pushUseConnect = ({ t, instances }: Params) => {
method: 'get', method: 'get',
url: `push/connect/${expoToken}`, url: `push/connect/${expoToken}`,
sentry: true sentry: true
}).catch(error => {
Sentry.setExtras({
API: 'tooot',
...(error?.response && { response: error.response }),
...(error?.request && { request: error.request })
})
Sentry.captureException(error)
Notifications.setBadgeCountAsync(0)
if (error?.status == 404) {
displayMessage({
theme,
type: 'error',
duration: 'long',
message: t('pushError.message'),
description: t('pushError.description'),
onPress: () => {
navigationRef.navigate('Screen-Tabs', {
screen: 'Tab-Me',
params: {
screen: 'Tab-Me-Root'
}
})
navigationRef.navigate('Screen-Tabs', {
screen: 'Tab-Me',
params: {
screen: 'Tab-Me-Settings'
}
})
}
})
dispatch(disableAllPushes())
instances.forEach(instance => {
if (instance.push.global.value) {
apiGeneral<{}>({
method: 'delete',
domain: instance.url,
url: 'api/v1/push/subscription',
headers: {
Authorization: `Bearer ${instance.token}`
}
}).catch(() => console.log('error!!!'))
}
})
}
}) })
.then(() => Notifications.setBadgeCountAsync(0))
.catch(error => {
Sentry.setExtras({
API: 'tooot',
...(error?.response && { response: error.response }),
...(error?.request && { request: error.request })
})
Sentry.captureException(error)
Notifications.setBadgeCountAsync(0)
if (error?.status == 404) {
displayMessage({
theme,
type: 'error',
duration: 'long',
message: t('pushError.message'),
description: t('pushError.description'),
onPress: () => {
navigationRef.navigate('Screen-Tabs', {
screen: 'Tab-Me',
params: {
screen: 'Tab-Me-Root'
}
})
navigationRef.navigate('Screen-Tabs', {
screen: 'Tab-Me',
params: {
screen: 'Tab-Me-Settings'
}
})
}
})
dispatch(disableAllPushes())
instances.forEach(instance => {
if (instance.push.global.value) {
apiGeneral<{}>({
method: 'delete',
domain: instance.url,
url: 'api/v1/push/subscription',
headers: {
Authorization: `Bearer ${instance.token}`
}
}).catch(() => console.log('error!!!'))
}
})
}
})
} }
const pushEnabled = instances.filter(instance => instance.push.global.value) const pushEnabled = instances.filter(instance => instance.push.global.value)
@ -89,7 +91,6 @@ const pushUseConnect = ({ t, instances }: Params) => {
if (expoToken && pushEnabled.length && state === 'active') { if (expoToken && pushEnabled.length && state === 'active') {
Notifications.getBadgeCountAsync().then(count => { Notifications.getBadgeCountAsync().then(count => {
if (count > 0) { if (count > 0) {
Notifications.setBadgeCountAsync(0)
connect() connect()
} }
}) })
@ -102,7 +103,6 @@ const pushUseConnect = ({ t, instances }: Params) => {
}, [expoToken, pushEnabled.length]) }, [expoToken, pushEnabled.length])
return useEffect(() => { return useEffect(() => {
Notifications.setBadgeCountAsync(0)
if (expoToken && pushEnabled.length) { if (expoToken && pushEnabled.length) {
connect() connect()
} }

View File

@ -1141,13 +1141,13 @@
mv "~2" mv "~2"
safe-json-stringify "~1" safe-json-stringify "~1"
"@expo/cli@0.4.9": "@expo/cli@0.4.10":
version "0.4.9" version "0.4.10"
resolved "https://registry.yarnpkg.com/@expo/cli/-/cli-0.4.9.tgz#24a2714b11a918b588138220c79b4ec9b553adba" resolved "https://registry.yarnpkg.com/@expo/cli/-/cli-0.4.10.tgz#e965b97888c83cecdaddbb8dca3d5827643a0f36"
integrity sha512-/9ljfK4eMWXb97XWSJgxcSWpuKXABHFd7Q8Kswp24B2Y5w4MIyaEPhSErIJYTq/FJH7p98Ti1zhk/PhBL0vVTw== integrity sha512-c8NJOVa5b8g9CYj8ahdaN21cVE2wPwUaFrtTE0kLeRR5ASy8reWLFEOcstEtt6eufdcN/uGgBWQ0FLovgLZuzw==
dependencies: dependencies:
"@babel/runtime" "^7.14.0" "@babel/runtime" "^7.14.0"
"@expo/code-signing-certificates" "^0.0.2" "@expo/code-signing-certificates" "0.0.5"
"@expo/config" "~7.0.2" "@expo/config" "~7.0.2"
"@expo/config-plugins" "~5.0.3" "@expo/config-plugins" "~5.0.3"
"@expo/dev-server" "0.1.123" "@expo/dev-server" "0.1.123"
@ -1208,10 +1208,10 @@
uuid "^3.4.0" uuid "^3.4.0"
wrap-ansi "^7.0.0" wrap-ansi "^7.0.0"
"@expo/code-signing-certificates@^0.0.2": "@expo/code-signing-certificates@0.0.5":
version "0.0.2" version "0.0.5"
resolved "https://registry.yarnpkg.com/@expo/code-signing-certificates/-/code-signing-certificates-0.0.2.tgz#65cd615800e6724b54831c966dd1a90145017246" resolved "https://registry.yarnpkg.com/@expo/code-signing-certificates/-/code-signing-certificates-0.0.5.tgz#a693ff684fb20c4725dade4b88a6a9f96b02496c"
integrity sha512-vnPHFjwOqxQ1VLztktY+fYCfwvLzjqpzKn09rchcQE7Sdf0wtW5fFtIZBEFOOY5wasp8tXSnp627zrAwazPHzg== integrity sha512-BNhXkY1bblxKZpltzAx98G2Egj9g1Q+JRcvR7E99DOj862FTCX+ZPsAUtPTr7aHxwtrL7+fL3r0JSmM9kBm+Bw==
dependencies: dependencies:
node-forge "^1.2.1" node-forge "^1.2.1"
nullthrows "^1.1.1" nullthrows "^1.1.1"
@ -2139,19 +2139,19 @@
resolved "https://registry.yarnpkg.com/@react-native/polyfills/-/polyfills-2.0.0.tgz#4c40b74655c83982c8cf47530ee7dc13d957b6aa" resolved "https://registry.yarnpkg.com/@react-native/polyfills/-/polyfills-2.0.0.tgz#4c40b74655c83982c8cf47530ee7dc13d957b6aa"
integrity sha512-K0aGNn1TjalKj+65D7ycc1//H9roAQ51GJVk5ZJQFb2teECGmzd86bYDC0aYdbRf7gtovescq4Zt6FR0tgXiHQ== integrity sha512-K0aGNn1TjalKj+65D7ycc1//H9roAQ51GJVk5ZJQFb2teECGmzd86bYDC0aYdbRf7gtovescq4Zt6FR0tgXiHQ==
"@react-navigation/bottom-tabs@^6.4.0": "@react-navigation/bottom-tabs@^6.4.1":
version "6.4.0" version "6.4.1"
resolved "https://registry.yarnpkg.com/@react-navigation/bottom-tabs/-/bottom-tabs-6.4.0.tgz#63743874648f92adedf37186cb7cedcd47826ee9" resolved "https://registry.yarnpkg.com/@react-navigation/bottom-tabs/-/bottom-tabs-6.4.1.tgz#54e469077f7c9f3750e6727ec8f298d5497b6ae5"
integrity sha512-90CapiXjiWudbCiki9e6fOr/CECQRguIxv5OD7IBfbAMGX5GGiJpX8aqiHAz2DxpAz31v4JZcUr945+lFhXBfA== integrity sha512-b12o0aVe+A9bUVP31kQLVcZ5l4Inm/7XhpSS5FvwhoI9L2iwofK1tt98uEQd79NIAklfui+IqRqr2X6XKkygbA==
dependencies: dependencies:
"@react-navigation/elements" "^1.3.6" "@react-navigation/elements" "^1.3.7"
color "^4.2.3" color "^4.2.3"
warn-once "^0.1.0" warn-once "^0.1.0"
"@react-navigation/core@^6.4.0": "@react-navigation/core@^6.4.1":
version "6.4.0" version "6.4.1"
resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-6.4.0.tgz#c44d33a8d8ef010a102c7f831fc8add772678509" resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-6.4.1.tgz#2d290cadc23992e914c45b5712efa30e5f37587f"
integrity sha512-tpc0Ak/DiHfU3LlYaRmIY7vI4sM/Ru0xCet6runLUh9aABf4wiLgxyFJ5BtoWq6xFF8ymYEA/KWtDhetQ24YiA== integrity sha512-M1rTS+qaw84ZItvObwFTjuvXfrJRnXL2uJJeiDVwSvu7/30Wp6bkL3/MfLUEA6I4CzJhL74iRSfCKSVe7kVhlw==
dependencies: dependencies:
"@react-navigation/routers" "^6.1.3" "@react-navigation/routers" "^6.1.3"
escape-string-regexp "^4.0.0" escape-string-regexp "^4.0.0"
@ -2160,25 +2160,25 @@
react-is "^16.13.0" react-is "^16.13.0"
use-latest-callback "^0.1.5" use-latest-callback "^0.1.5"
"@react-navigation/elements@^1.3.6": "@react-navigation/elements@^1.3.7":
version "1.3.6" version "1.3.7"
resolved "https://registry.yarnpkg.com/@react-navigation/elements/-/elements-1.3.6.tgz#fa700318528db93f05144b1be4b691b9c1dd1abe" resolved "https://registry.yarnpkg.com/@react-navigation/elements/-/elements-1.3.7.tgz#40d80a7f34d645b605289da10bc4b6c3a7667215"
integrity sha512-pNJ8R9JMga6SXOw6wGVN0tjmE6vegwPmJBL45SEMX2fqTfAk2ykDnlJHodRpHpAgsv0DaI8qX76z3A+aqKSU0w== integrity sha512-OZg2N/dd2tl6qkfrWvmUjFsYsbEyHEv4NbZSBuT+CR+d1pzmexN2IeVmi4cEMoR7U7GwhFcHRevF36yBsjU/dw==
"@react-navigation/native-stack@^6.9.1": "@react-navigation/native-stack@^6.9.2":
version "6.9.1" version "6.9.2"
resolved "https://registry.yarnpkg.com/@react-navigation/native-stack/-/native-stack-6.9.1.tgz#6013300e4cd0b33e242aa18593e4dff7db2ab3d1" resolved "https://registry.yarnpkg.com/@react-navigation/native-stack/-/native-stack-6.9.2.tgz#8c861a59a2a86aaf25f0f33a990958edc36ddac4"
integrity sha512-aOuJP97ge6NRz8wH6sDKfLTfdygGmraYh0apKrrVbGvMnflbPX4kpjQiAQcUPUpMeas0betH/Su8QubNL8HEkg== integrity sha512-W5CYX+mYVyOYUgWoN15O34Pv/JieX2/pU09yh+kacxPHPEm4gYTQM/OIHACOov5T2WyiNSU6iIHjfzQ6e7M9zw==
dependencies: dependencies:
"@react-navigation/elements" "^1.3.6" "@react-navigation/elements" "^1.3.7"
warn-once "^0.1.0" warn-once "^0.1.0"
"@react-navigation/native@^6.0.13": "@react-navigation/native@^6.0.14":
version "6.0.13" version "6.0.14"
resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-6.0.13.tgz#ec504120e193ea6a7f24ffa765a1338be5a3160a" resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-6.0.14.tgz#3ce3a4176ac7dc5495241d56a28db18449baf754"
integrity sha512-CwaJcAGbhv3p3ECablxBkw8QBCGDWXqVRwQ4QbelajNW623m3sNTC9dOF6kjp8au6Rg9B5e0KmeuY0xWbPk79A== integrity sha512-Z95bJrRkZerBJq6Qc/xjA/kibPpB+UvPeMWS1CBhRF8FaX1483UdHqPqSbW879tPwjP2R4XfoA4dtoEHswrOjA==
dependencies: dependencies:
"@react-navigation/core" "^6.4.0" "@react-navigation/core" "^6.4.1"
escape-string-regexp "^4.0.0" escape-string-regexp "^4.0.0"
fast-deep-equal "^3.1.3" fast-deep-equal "^3.1.3"
nanoid "^3.1.23" nanoid "^3.1.23"
@ -2190,12 +2190,12 @@
dependencies: dependencies:
nanoid "^3.1.23" nanoid "^3.1.23"
"@react-navigation/stack@^6.3.4": "@react-navigation/stack@^6.3.5":
version "6.3.4" version "6.3.5"
resolved "https://registry.yarnpkg.com/@react-navigation/stack/-/stack-6.3.4.tgz#c3b7a479aea609c0de609f91be7b2539dbae37c2" resolved "https://registry.yarnpkg.com/@react-navigation/stack/-/stack-6.3.5.tgz#c616ef78cbaa55938da993d871d9fc41801d41f4"
integrity sha512-f4vQcbaDPSFHF1i6CnEYbA0Bnk5jRGMoCIs2/Tq0HwsUI62Mui1q5vvIlRDIi5QomJoHzhfTBp9IzMQ/sUQJlg== integrity sha512-G706Ow+8fhiLT5Cf48566YsjboU5h5ll9nva90xX3br7V6x0JMoGMvXjvbORZyzLuUytQO3mf0T3nVUuO52vZQ==
dependencies: dependencies:
"@react-navigation/elements" "^1.3.6" "@react-navigation/elements" "^1.3.7"
color "^4.2.3" color "^4.2.3"
warn-once "^0.1.0" warn-once "^0.1.0"
@ -5728,13 +5728,13 @@ expo-web-browser@~12.0.0:
dependencies: dependencies:
compare-urls "^2.0.0" compare-urls "^2.0.0"
expo@^47.0.6: expo@^47.0.7:
version "47.0.6" version "47.0.7"
resolved "https://registry.yarnpkg.com/expo/-/expo-47.0.6.tgz#4436bf0f667b6282f9189e987ddf67cd64807140" resolved "https://registry.yarnpkg.com/expo/-/expo-47.0.7.tgz#4fe95529c6b1e6d8026a164847ce1048f6dc5ccd"
integrity sha512-XFcTnkOWEbc5mbrpdgIkPq3Heuem+8OErdjnWshwiDtaCdqK0EKToJtE2ufhCxb/RzfeJ5k07mpk+8CRRayi4w== integrity sha512-uHTxvPdD4K7W277tXVAdFmgjSZ0Hg+0g5bnez0jXyXQINa+0CTtGmulgFehBOrbrUZBqwosN0K8TsrxADwcXZQ==
dependencies: dependencies:
"@babel/runtime" "^7.14.0" "@babel/runtime" "^7.14.0"
"@expo/cli" "0.4.9" "@expo/cli" "0.4.10"
"@expo/config" "7.0.3" "@expo/config" "7.0.3"
"@expo/config-plugins" "5.0.4" "@expo/config-plugins" "5.0.4"
"@expo/vector-icons" "^13.0.0" "@expo/vector-icons" "^13.0.0"
@ -10507,10 +10507,10 @@ react-native-live-text-image-view@^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" 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== integrity sha512-PhVFE0YogSLrTlnHIxUWL80CrmbDvxk1JvLx4UHiRHRwLda4dV/e/9Q+Pyh7Vq7qwAPE6vGoN6sjbXNaj4WCew==
react-native-pager-view@^6.1.0: react-native-pager-view@^6.1.1:
version "6.1.0" version "6.1.1"
resolved "https://registry.yarnpkg.com/react-native-pager-view/-/react-native-pager-view-6.1.0.tgz#6cb13fb6f2db8836c89ee8261b07603e97527ceb" resolved "https://registry.yarnpkg.com/react-native-pager-view/-/react-native-pager-view-6.1.1.tgz#e396b0c78d74931a92d1c9bf28c450eb356b904d"
integrity sha512-wBtc77l+lWRDS1FlpeO+rE0iG/ecRtVhHrERMkm7CACQvhB+ty8NL2zlAzOCCbS83DZrIdtWuPu9VqziKHzJPw== integrity sha512-4WqR0YWBjaUtc3iPVk8w6wsTsMq+r0plNiXdqPXOiUdQIhxKfsP1iqb6hRzdeJKOo8UH7RCP6zI7dxdFEAXzrw==
react-native-reanimated-zoom@^0.3.3: react-native-reanimated-zoom@^0.3.3:
version "0.3.3" version "0.3.3"