Merge branch 'main' into release

This commit is contained in:
xmflsct 2023-01-11 22:54:44 +01:00
commit f401f5fcb7
16 changed files with 76 additions and 39 deletions

View File

@ -1,6 +1,6 @@
{
"name": "tooot",
"version": "4.8.0",
"version": "4.8.1",
"description": "tooot for Mastodon",
"author": "xmflsct <me@xmflsct.com>",
"license": "GPL-3.0-or-later",
@ -81,6 +81,7 @@
"react-native-language-detection": "^0.2.2",
"react-native-mmkv": "^2.5.1",
"react-native-pager-view": "^6.1.2",
"react-native-quick-base64": "^2.0.5",
"react-native-reanimated": "^2.13.0",
"react-native-reanimated-zoom": "^0.3.3",
"react-native-safe-area-context": "^4.4.1",

View File

@ -60,7 +60,10 @@ const GracefullyImage = ({
uri: reduceMotionEnabled && uri.static ? uri.static : currentUri
}
useEffect(() => {
if (currentUri !== uri.original && currentUri !== uri.remote) {
if (
(uri.original ? currentUri !== uri.original : true) &&
(uri.remote ? currentUri !== uri.remote : true)
) {
setCurrentUri(uri.original || uri.remote)
}
}, [currentUri, uri.original, uri.remote])

View File

@ -19,12 +19,14 @@ import {
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import * as AuthSession from 'expo-auth-session'
import * as Random from 'expo-random'
import * as WebBrowser from 'expo-web-browser'
import { debounce } from 'lodash'
import React, { RefObject, useCallback, useState } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import { Alert, Image, KeyboardAvoidingView, Platform, TextInput, View } from 'react-native'
import { ScrollView } from 'react-native-gesture-handler'
import { fromByteArray } from 'react-native-quick-base64'
import parse from 'url-parse'
import CustomText from '../Text'
@ -158,7 +160,7 @@ const ComponentInstance: React.FC<Props> = ({
'admin.sign_up': false,
'admin.report': false
},
key: Math.random().toString(36).slice(2, 12)
key: fromByteArray(Random.getRandomBytes(16))
},
page_local: {
showBoosts: true,
@ -182,7 +184,7 @@ const ComponentInstance: React.FC<Props> = ({
)
if (!account) {
setGlobalStorage('accounts', accounts?.concat([accountKey]))
setGlobalStorage('accounts', (accounts || []).concat([accountKey]))
}
setAccount(accountKey)

View File

@ -197,7 +197,8 @@ const TimelineRefresh: React.FC<Props> = ({
const insert = prevCache.current?.slice(-PREV_PER_BATCH)
prevCache.current = prevCache.current?.slice(0, -PREV_PER_BATCH)
if (insert) {
return { ...page, body: [...insert, ...page.body] }
page.body.unshift(...insert)
return page
} else {
return page
}

View File

@ -14,9 +14,11 @@ const HeaderSharedReplies: React.FC = () => {
const { t } = useTranslation(['common', 'componentTimeline'])
const { colors } = useTheme()
const mentionsBeginning = rawContent?.current?.[0]
.match(new RegExp(/^(?:@\S+\s+)+/))?.[0]
?.match(new RegExp(/@\S+/, 'g'))
const mentionsBeginning = rawContent?.current?.[0]?.length
? rawContent?.current?.[0]
.match(new RegExp(/^(?:@\S+\s+)+/))?.[0]
?.match(new RegExp(/@\S+/, 'g'))
: undefined
excludeMentions &&
(excludeMentions.current =
mentionsBeginning?.length && status?.mentions

View File

@ -92,7 +92,7 @@ const ScreenAccountSelection = ({
const { colors } = useTheme()
const { t } = useTranslation('screenAccountSelection')
const accounts = getReadableAccounts()
const accounts = getReadableAccounts(true)
return (
<ScrollView

View File

@ -17,7 +17,7 @@ const ComposeDrafts: React.FC<Props> = ({ accessibleRefDrafts }) => {
const navigation = useNavigation<any>()
const { composeState } = useContext(ComposeContext)
const [drafts] = useAccountStorage.object('drafts')
const draftsCount = drafts.filter(draft => draft.timestamp !== composeState.timestamp).length
const draftsCount = drafts?.filter(draft => draft.timestamp !== composeState.timestamp).length
useEffect(() => {
layoutAnimation()

View File

@ -7,8 +7,8 @@ import { useTranslation } from 'react-i18next'
import { View } from 'react-native'
const ComposePostingAs = () => {
const accounts = useGlobalStorage.object('accounts')
if (!accounts.length) return null
const [accounts] = useGlobalStorage.object('accounts')
if (!accounts?.length) return null
const { t } = useTranslation('screenCompose')
const { colors } = useTheme()

View File

@ -7,7 +7,7 @@ import ComposeRoot from '@screens/Compose/Root'
import { formatText } from '@screens/Compose/utils/processText'
import { useQueryClient } from '@tanstack/react-query'
import { handleError } from '@utils/api/helpers'
import { RootStackScreenProps, useNavState } from '@utils/navigation/navigators'
import { RootStackScreenProps } from '@utils/navigation/navigators'
import { useInstanceQuery } from '@utils/queryHooks/instance'
import { usePreferencesQuery } from '@utils/queryHooks/preferences'
import { searchLocalStatus } from '@utils/queryHooks/search'
@ -346,13 +346,6 @@ const ScreenCompose: React.FC<RootStackScreenProps<'Screen-Compose'>> = ({
}
switch (params?.type) {
case undefined:
queryClient.invalidateQueries({
queryKey: ['Timeline', { page: 'Following' }],
exact: false
})
break
case 'conversation':
case 'edit': // doesn't work
// mutateTimeline.mutate({
// type: 'editItem',
@ -361,11 +354,20 @@ const ScreenCompose: React.FC<RootStackScreenProps<'Screen-Compose'>> = ({
// })
// break
case 'deleteEdit':
case 'reply':
for (const navState of params.navigationState) {
navState && queryClient.invalidateQueries(navState)
}
break
case 'conversation':
case 'reply':
if (params.navigationState) {
for (const navState of params.navigationState) {
navState &&
navState[1].page !== 'Following' &&
queryClient.invalidateQueries(navState)
}
}
break
}
removeDraft(composeState.timestamp)
navigation.goBack()

View File

@ -17,10 +17,12 @@ import { StyleConstants } from '@utils/styles/constants'
import layoutAnimation from '@utils/styles/layoutAnimation'
import { useTheme } from '@utils/styles/ThemeManager'
import * as Notifications from 'expo-notifications'
import * as Random from 'expo-random'
import * as WebBrowser from 'expo-web-browser'
import React, { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { AppState, Linking, Platform, ScrollView, View } from 'react-native'
import { fromByteArray } from 'react-native-quick-base64'
const TabMePush: React.FC = () => {
const { colors } = useTheme()
@ -178,6 +180,11 @@ const TabMePush: React.FC = () => {
setAccountStorage([{ key: 'push', value: { ...push, global: false } }])
} else {
// Fix a bug for some users of v4.8.0
let authKey = push.key
if (push.key.length <= 10) {
authKey = fromByteArray(Random.getRandomBytes(16))
}
// Turning on
const randomPath = (Math.random() + 1).toString(36).substring(2)
@ -189,7 +196,7 @@ const TabMePush: React.FC = () => {
'subscription[keys][p256dh]',
'BMn2PLpZrMefG981elzG6SB1EY9gU7QZwmtZ/a/J2vUeWG+zXgeskMPwHh4T/bxsD4l7/8QT94F57CbZqYRRfJo='
)
formData.append('subscription[keys][auth]', push.key)
formData.append('subscription[keys][auth]', authKey)
for (const [key, value] of Object.entries(push.alerts)) {
formData.append(`data[alerts][${key}]`, value.toString())
}
@ -225,7 +232,9 @@ const TabMePush: React.FC = () => {
}
})
setAccountStorage([{ key: 'push', value: { ...push, global: true } }])
setAccountStorage([
{ key: 'push', value: { ...push, global: true, key: authKey } }
])
if (Platform.OS === 'android') {
setChannels(true)

View File

@ -60,7 +60,7 @@ const Collections: React.FC = () => {
title={t('screenTabs:me.stacks.favourites.name')}
onPress={() => navigation.navigate('Tab-Me-Favourites')}
/>
{pageMe.lists.shown ? (
{pageMe.lists?.shown ? (
<MenuRow
iconFront='List'
iconBack='ChevronRight'
@ -68,7 +68,7 @@ const Collections: React.FC = () => {
onPress={() => navigation.navigate('Tab-Me-List-List')}
/>
) : null}
{pageMe.followedTags.shown ? (
{pageMe.followedTags?.shown ? (
<MenuRow
iconFront='Hash'
iconBack='ChevronRight'
@ -76,7 +76,7 @@ const Collections: React.FC = () => {
onPress={() => navigation.navigate('Tab-Me-FollowedTags')}
/>
) : null}
{pageMe.announcements.shown ? (
{pageMe.announcements?.shown ? (
<MenuRow
iconFront='Clipboard'
iconBack='ChevronRight'

View File

@ -70,8 +70,8 @@ const TabNotificationsFilters: React.FC<
<MenuRow
key={index}
title={t(`screenTabs:me.push.${type}.heading`)}
switchValue={filters[type]}
switchOnValueChange={() => setFilters({ ...filters, [type]: !filters[type] })}
switchValue={filters?.[type]}
switchOnValueChange={() => setFilters({ ...filters, [type]: !filters?.[type] })}
/>
))}
</MenuContainer>
@ -80,8 +80,8 @@ const TabNotificationsFilters: React.FC<
<MenuRow
key={type}
title={t(`screenTabs:me.push.${type}.heading`)}
switchValue={filters[type]}
switchOnValueChange={() => setFilters({ ...filters, [type]: !filters[type] })}
switchValue={filters?.[type]}
switchOnValueChange={() => setFilters({ ...filters, [type]: !filters?.[type] })}
/>
))}
</MenuContainer>

View File

@ -38,7 +38,10 @@ const Root: React.FC<NativeStackScreenProps<TabPublicStackParamList, 'Tab-Public
const previousSegment = getGlobalStorage.string('app.prev_public_segment')
const segments: StorageGlobal['app.prev_public_segment'][] = ['Local', 'LocalPublic', 'Trending']
const [segment, setSegment] = useState<number>(
segments.findIndex(segment => segment === previousSegment)
Math.min(
0,
segments.findIndex(segment => segment === previousSegment)
)
)
const [routes] = useState([
{ key: 'Local', title: t('tabs.public.segments.local') },

View File

@ -52,7 +52,7 @@ export const searchLocalStatus = async (uri: Mastodon.Status['uri']): Promise<Ma
return await queryClient
.fetchQuery(queryKey, queryFunction, { staleTime: 3600, cacheTime: 3600 })
.then(res =>
res.statuses[0].uri === uri || res.statuses[0].url === uri
res.statuses[0]?.uri === uri || res.statuses[0]?.url === uri
? res.statuses[0]
: Promise.reject()
)

View File

@ -233,14 +233,15 @@ export type ReadableAccountType = {
key: string
active: boolean
}
export const getReadableAccounts = (): ReadableAccountType[] => {
const accountActive = getGlobalStorage.string('account.active')
export const getReadableAccounts = (withoutActive: boolean = false): ReadableAccountType[] => {
const accountActive = !withoutActive && getGlobalStorage.string('account.active')
const accounts = getGlobalStorage.object('accounts')?.sort((a, b) => a.localeCompare(b))
accounts?.splice(
accounts.findIndex(a => a === accountActive),
1
)
accounts?.unshift(accountActive || '')
!withoutActive &&
accounts?.splice(
accounts.findIndex(a => a === accountActive),
1
)
!withoutActive && accounts?.unshift(accountActive || '')
return (
accounts?.map(account => {
const details = getAccountDetails(

View File

@ -9718,6 +9718,18 @@ __metadata:
languageName: node
linkType: hard
"react-native-quick-base64@npm:^2.0.5":
version: 2.0.5
resolution: "react-native-quick-base64@npm:2.0.5"
dependencies:
base64-js: ^1.5.1
peerDependencies:
react: "*"
react-native: "*"
checksum: 964599ad68d54dd741357850c72b4a5e08f247fa294590f18866896662107b734b6810703fdd972560cee8087095f14f06fc6ef69944c59c41dbbd885a7832bb
languageName: node
linkType: hard
"react-native-reanimated-zoom@npm:^0.3.3":
version: 0.3.3
resolution: "react-native-reanimated-zoom@npm:0.3.3"
@ -11412,6 +11424,7 @@ __metadata:
react-native-language-detection: ^0.2.2
react-native-mmkv: ^2.5.1
react-native-pager-view: ^6.1.2
react-native-quick-base64: ^2.0.5
react-native-reanimated: ^2.13.0
react-native-reanimated-zoom: ^0.3.3
react-native-safe-area-context: ^4.4.1