1
0
mirror of https://github.com/tooot-app/app synced 2025-06-05 22:19:13 +02:00

Merge branch 'main' into candidate

This commit is contained in:
xmflsct
2023-01-30 13:53:49 +01:00
19 changed files with 109 additions and 87 deletions

View File

@@ -20,7 +20,6 @@ import Animated, {
SharedValue, SharedValue,
useAnimatedReaction, useAnimatedReaction,
useAnimatedStyle, useAnimatedStyle,
useDerivedValue,
useSharedValue, useSharedValue,
withTiming withTiming
} from 'react-native-reanimated' } from 'react-native-reanimated'
@@ -28,10 +27,10 @@ import Animated, {
export interface Props { export interface Props {
flRef: RefObject<FlatList<any>> flRef: RefObject<FlatList<any>>
queryKey: QueryKeyTimeline queryKey: QueryKeyTimeline
fetchingActive: React.MutableRefObject<boolean> isFetchingPrev: SharedValue<boolean>
setFetchedCount: React.Dispatch<React.SetStateAction<number | null>> setFetchedCount: React.Dispatch<React.SetStateAction<number | null>>
scrollY: Animated.SharedValue<number> scrollY: SharedValue<number>
fetchingType: Animated.SharedValue<0 | 1 | 2> fetchingType: SharedValue<0 | 1 | 2>
disableRefresh?: boolean disableRefresh?: boolean
readMarker?: 'read_marker_following' readMarker?: 'read_marker_following'
} }
@@ -43,7 +42,7 @@ export const SEPARATION_Y_2 = -(CONTAINER_HEIGHT * 1.5 + StyleConstants.Font.Siz
const TimelineRefresh: React.FC<Props> = ({ const TimelineRefresh: React.FC<Props> = ({
flRef, flRef,
queryKey, queryKey,
fetchingActive, isFetchingPrev,
setFetchedCount, setFetchedCount,
scrollY, scrollY,
fetchingType, fetchingType,
@@ -58,20 +57,11 @@ const TimelineRefresh: React.FC<Props> = ({
} }
const PREV_PER_BATCH = 1 const PREV_PER_BATCH = 1
const prevActive = useRef<boolean>(false)
const prevCache = useRef<(Mastodon.Status | Mastodon.Notification | Mastodon.Conversation)[]>() const prevCache = useRef<(Mastodon.Status | Mastodon.Notification | Mastodon.Conversation)[]>()
const prevStatusId = useRef<Mastodon.Status['id']>() const prevStatusId = useRef<Mastodon.Status['id']>()
const queryClient = useQueryClient() const queryClient = useQueryClient()
const { refetch, isRefetching } = useTimelineQuery({ ...queryKey[1] }) const { refetch } = useTimelineQuery({ ...queryKey[1] })
useDerivedValue(() => {
if (prevActive.current || isRefetching) {
fetchingActive.current = true
} else {
fetchingActive.current = false
}
}, [prevActive.current, isRefetching])
const { t } = useTranslation('componentTimeline') const { t } = useTranslation('componentTimeline')
const { colors } = useTheme() const { colors } = useTheme()
@@ -99,7 +89,7 @@ const TimelineRefresh: React.FC<Props> = ({
const arrowStage = useSharedValue(0) const arrowStage = useSharedValue(0)
useAnimatedReaction( useAnimatedReaction(
() => { () => {
if (fetchingActive.current) { if (isFetchingPrev.value) {
return false return false
} }
switch (arrowStage.value) { switch (arrowStage.value) {
@@ -131,13 +121,12 @@ const TimelineRefresh: React.FC<Props> = ({
if (data) { if (data) {
runOnJS(haptics)('Light') runOnJS(haptics)('Light')
} }
}, }
[fetchingActive.current]
) )
const fetchAndScrolled = useSharedValue(false) const fetchAndScrolled = useSharedValue(false)
const runFetchPrevious = async () => { const runFetchPrevious = async () => {
if (prevActive.current) return if (isFetchingPrev.value) return
const firstPage = const firstPage =
queryClient.getQueryData< queryClient.getQueryData<
@@ -146,7 +135,7 @@ const TimelineRefresh: React.FC<Props> = ({
> >
>(queryKey)?.pages[0] >(queryKey)?.pages[0]
prevActive.current = true isFetchingPrev.value = true
prevStatusId.current = firstPage?.body[0]?.id prevStatusId.current = firstPage?.body[0]?.id
await queryFunctionTimeline({ await queryFunctionTimeline({
@@ -154,7 +143,7 @@ const TimelineRefresh: React.FC<Props> = ({
pageParam: firstPage?.links?.prev, pageParam: firstPage?.links?.prev,
meta: {} meta: {}
}) })
.then(res => { .then(async res => {
setFetchedCount(res.body.length) setFetchedCount(res.body.length)
if (!res.body.length) return if (!res.body.length) return
@@ -177,7 +166,7 @@ const TimelineRefresh: React.FC<Props> = ({
}) })
.then(async nextLength => { .then(async nextLength => {
if (!nextLength) { if (!nextLength) {
prevActive.current = false isFetchingPrev.value = false
return return
} }
@@ -214,7 +203,7 @@ const TimelineRefresh: React.FC<Props> = ({
} }
}) })
} }
prevActive.current = false isFetchingPrev.value = false
}) })
} }

View File

@@ -15,8 +15,8 @@ const TimelineFullConversation = () => {
return queryKey && return queryKey &&
queryKey[1].page !== 'Toot' && queryKey[1].page !== 'Toot' &&
status.in_reply_to_account_id && status.in_reply_to_account_id &&
(status.mentions.length === 0 || (status.mentions?.length === 0 ||
status.mentions.filter(mention => mention.id !== status.in_reply_to_account_id).length) ? ( status.mentions?.filter(mention => mention.id !== status.in_reply_to_account_id).length) ? (
<CustomText <CustomText
fontStyle='S' fontStyle='S'
style={{ style={{

View File

@@ -22,7 +22,7 @@ const HeaderSharedReplies: React.FC = () => {
excludeMentions && excludeMentions &&
(excludeMentions.current = (excludeMentions.current =
mentionsBeginning?.length && status?.mentions mentionsBeginning?.length && status?.mentions
? status.mentions.filter(mention => mentionsBeginning.includes(`@${mention.username}`)) ? status.mentions?.filter(mention => mentionsBeginning.includes(`@${mention.username}`))
: []) : [])
return excludeMentions?.current.length ? ( return excludeMentions?.current.length ? (

View File

@@ -18,6 +18,7 @@ import { FlatList, FlatListProps, Platform, RefreshControl } from 'react-native'
import Animated, { import Animated, {
Easing, Easing,
runOnJS, runOnJS,
useAnimatedReaction,
useAnimatedScrollHandler, useAnimatedScrollHandler,
useAnimatedStyle, useAnimatedStyle,
useDerivedValue, useDerivedValue,
@@ -70,26 +71,44 @@ const Timeline: React.FC<Props> = ({
}) })
const flRef = useRef<FlatList>(null) const flRef = useRef<FlatList>(null)
const fetchingActive = useRef<boolean>(false) const isFetchingPrev = useSharedValue<boolean>(false)
const [fetchedCount, setFetchedCount] = useState<number | null>(null) const [fetchedCount, setFetchedCount] = useState<number | null>(null)
const fetchedNoticeHeight = useSharedValue<number>(100) const fetchedNoticeHeight = useSharedValue<number>(100)
const notifiedFetchedNotice = useSharedValue<boolean>(false)
useAnimatedReaction(
() => isFetchingPrev.value,
(curr, prev) => {
if (curr === true && prev === false) {
notifiedFetchedNotice.value = true
}
}
)
useAnimatedReaction(
() => fetchedCount,
(curr, prev) => {
if (curr !== null && prev === null) {
notifiedFetchedNotice.value = false
}
},
[fetchedCount]
)
const fetchedNoticeTop = useDerivedValue(() => { const fetchedNoticeTop = useDerivedValue(() => {
if ((!isLoading && !isRefetching && isFetching) || fetchedCount !== null) { if (notifiedFetchedNotice.value || fetchedCount !== null) {
return withSequence( return withSequence(
withTiming(fetchedNoticeHeight.value + 16 + 4), withTiming(fetchedNoticeHeight.value + 16 + 4),
withDelay( withDelay(
2000, 2000,
withTiming(0, { easing: Easing.out(Easing.ease) }, finished => { withTiming(
if (finished) { 0,
runOnJS(setFetchedCount)(null) { easing: Easing.out(Easing.ease) },
} finished => finished && runOnJS(setFetchedCount)(null)
}) )
) )
) )
} else { } else {
return 0 return 0
} }
}, [isLoading, isRefetching, isFetching, fetchedCount]) }, [fetchedCount])
const fetchedNoticeAnimate = useAnimatedStyle(() => ({ const fetchedNoticeAnimate = useAnimatedStyle(() => ({
transform: [{ translateY: fetchedNoticeTop.value }] transform: [{ translateY: fetchedNoticeTop.value }]
})) }))
@@ -130,7 +149,12 @@ const Timeline: React.FC<Props> = ({
const marker = readMarker ? getAccountStorage.string(readMarker) : undefined const marker = readMarker ? getAccountStorage.string(readMarker) : undefined
const firstItemId = viewableItems.filter(item => item.isViewable)[0]?.item.id const firstItemId = viewableItems.filter(item => item.isViewable)[0]?.item.id
if (!fetchingActive.current && firstItemId && firstItemId > (marker || '0')) { if (
!isFetchingPrev.value &&
!isRefetching &&
firstItemId &&
firstItemId > (marker || '0')
) {
setAccountStorage([{ key: readMarker, value: firstItemId }]) setAccountStorage([{ key: readMarker, value: firstItemId }])
} else { } else {
// setAccountStorage([{ key: readMarker, value: '109519141378761752' }]) // setAccountStorage([{ key: readMarker, value: '109519141378761752' }])
@@ -170,7 +194,7 @@ const Timeline: React.FC<Props> = ({
<TimelineRefresh <TimelineRefresh
flRef={flRef} flRef={flRef}
queryKey={queryKey} queryKey={queryKey}
fetchingActive={fetchingActive} isFetchingPrev={isFetchingPrev}
setFetchedCount={setFetchedCount} setFetchedCount={setFetchedCount}
scrollY={scrollY} scrollY={scrollY}
fetchingType={fetchingType} fetchingType={fetchingType}
@@ -238,7 +262,7 @@ const Timeline: React.FC<Props> = ({
}) => (fetchedNoticeHeight.value = height)} }) => (fetchedNoticeHeight.value = height)}
> >
<CustomText <CustomText
fontStyle='M' fontStyle='S'
style={{ color: colors.primaryDefault }} style={{ color: colors.primaryDefault }}
children={ children={
fetchedCount !== null fetchedCount !== null

View File

@@ -197,7 +197,7 @@ const menuStatus = ({
hidden: hidden:
!ownAccount && !ownAccount &&
queryKey[1].page !== 'Notifications' && queryKey[1].page !== 'Notifications' &&
!status.mentions.find( !status.mentions?.find(
mention => mention.acct === accountAcct && mention.username === accountAcct mention => mention.acct === accountAcct && mention.username === accountAcct
) && ) &&
!status.muted !status.muted

View File

@@ -17,10 +17,10 @@
"refresh": { "refresh": {
"fetchPreviousPage": "Més recent des d'aquí", "fetchPreviousPage": "Més recent des d'aquí",
"refetch": "A l'últim", "refetch": "A l'últim",
"fetching": "", "fetching": "Obtenint publicacions...",
"fetched": { "fetched": {
"none": "", "none": "No n'hi ha de noves",
"found": "" "found": "S'ha obtingut {{count}}"
} }
}, },
"shared": { "shared": {

View File

@@ -147,7 +147,7 @@
"title": "Marca el contingut com a sensible" "title": "Marca el contingut com a sensible"
}, },
"media": { "media": {
"title": "Visualització de multimèdia", "title": "Multimèdia",
"options": { "options": {
"default": "Amaga els sensibles", "default": "Amaga els sensibles",
"show_all": "Mostra'ls sempre", "show_all": "Mostra'ls sempre",

View File

@@ -17,10 +17,10 @@
"refresh": { "refresh": {
"fetchPreviousPage": "Más reciente desde aquí", "fetchPreviousPage": "Más reciente desde aquí",
"refetch": "Al último", "refetch": "Al último",
"fetching": "", "fetching": "Obteniendo publicaciones...",
"fetched": { "fetched": {
"none": "", "none": "No hay nuevas",
"found": "" "found": "Se ha obtenido {{count}}"
} }
}, },
"shared": { "shared": {

View File

@@ -147,7 +147,7 @@
"title": "Marcar el contenido multimedia como sensibles por defecto" "title": "Marcar el contenido multimedia como sensibles por defecto"
}, },
"media": { "media": {
"title": "Mostrar el contenido multimedia", "title": "Multimedia",
"options": { "options": {
"default": "Ocultar los sensibles", "default": "Ocultar los sensibles",
"show_all": "Mostrar siempre", "show_all": "Mostrar siempre",

View File

@@ -17,10 +17,10 @@
"refresh": { "refresh": {
"fetchPreviousPage": "Nieuwere vanaf hier", "fetchPreviousPage": "Nieuwere vanaf hier",
"refetch": "Naar nieuwste", "refetch": "Naar nieuwste",
"fetching": "", "fetching": "Nieuwere toots ophalen...",
"fetched": { "fetched": {
"none": "", "none": "Geen nieuwere toot",
"found": "" "found": "{{count}} toots opgehaald"
} }
}, },
"shared": { "shared": {

View File

@@ -6,9 +6,9 @@
"action_false": "Seguir usuário", "action_false": "Seguir usuário",
"action_true": "Deixar de seguir usuário" "action_true": "Deixar de seguir usuário"
}, },
"inLists": "", "inLists": "Listas contendo usuário ...",
"showBoosts": { "showBoosts": {
"action_false": "", "action_false": "Mostrar boosts do usuário",
"action_true": "" "action_true": ""
}, },
"mute": { "mute": {

View File

@@ -17,9 +17,9 @@
"refresh": { "refresh": {
"fetchPreviousPage": "Mais novo aqui", "fetchPreviousPage": "Mais novo aqui",
"refetch": "Mais recente", "refetch": "Mais recente",
"fetching": "", "fetching": "Buscando toots mais recentes...",
"fetched": { "fetched": {
"none": "", "none": "Nenhum novo toot",
"found": "" "found": ""
} }
}, },

View File

@@ -61,7 +61,7 @@
"name": "Criar uma lista" "name": "Criar uma lista"
}, },
"listEdit": { "listEdit": {
"name": "" "name": "Editar Detalhes da Lista"
}, },
"lists": { "lists": {
"name": "Listas" "name": "Listas"
@@ -116,7 +116,7 @@
"empty": "Nenhum usuário adicionado a esta lista" "empty": "Nenhum usuário adicionado a esta lista"
}, },
"listEdit": { "listEdit": {
"heading": "", "heading": "Editar detalhes da lista",
"title": "Título", "title": "Título",
"repliesPolicy": { "repliesPolicy": {
"heading": "Mostrar respostas para:", "heading": "Mostrar respostas para:",
@@ -144,7 +144,7 @@
} }
}, },
"sensitive": { "sensitive": {
"title": "" "title": "Marcar mídia como sensível por padrão"
}, },
"media": { "media": {
"title": "", "title": "",
@@ -166,22 +166,22 @@
}, },
"web_only": { "web_only": {
"title": "", "title": "",
"description": "" "description": "As configurações abaixo só podem ser atualizadas usando a interface web"
} }
}, },
"preferencesFilters": { "preferencesFilters": {
"expired": "", "expired": "",
"keywords_one": "", "keywords_one": "{{count}} palavra-chave",
"keywords_other": "", "keywords_other": "{{count}} palavras-chave",
"statuses_one": "", "statuses_one": "{{count}} toot",
"statuses_other": "", "statuses_other": "{{count}} toots",
"context": "", "context": "Aplica-se em <0 />",
"contexts": { "contexts": {
"home": "", "home": "seguindo e listas",
"notifications": "", "notifications": "notificação",
"public": "global", "public": "global",
"thread": "", "thread": "",
"account": "" "account": "perfil"
} }
}, },
"preferencesFilter": { "preferencesFilter": {
@@ -196,22 +196,22 @@
"604800": "Após 1 semana", "604800": "Após 1 semana",
"18144000": "Após 1 mês" "18144000": "Após 1 mês"
}, },
"context": "", "context": "Aplica-se em",
"contexts": { "contexts": {
"home": "", "home": "Seguindo e listas",
"notifications": "", "notifications": "Notificação",
"public": "Linha do tempo global", "public": "Linha do tempo global",
"thread": "", "thread": "",
"account": "" "account": ""
}, },
"action": "", "action": "",
"actions": { "actions": {
"warn": "", "warn": "Recolhido, mas pode ser revelado",
"hide": "" "hide": "Esconder completamente"
}, },
"keywords": "", "keywords": "",
"keyword": "", "keyword": "Palavra-chave",
"statuses": "" "statuses": "Corresponde a estes toots"
}, },
"profile": { "profile": {
"feedback": { "feedback": {
@@ -343,7 +343,7 @@
"heading": "Tema escuro", "heading": "Tema escuro",
"options": { "options": {
"lighter": "Padrão", "lighter": "Padrão",
"darker": "" "darker": "Preto verdadeiro"
} }
}, },
"browser": { "browser": {
@@ -354,7 +354,7 @@
} }
}, },
"autoplayGifv": { "autoplayGifv": {
"heading": "" "heading": "Reproduzir GIFs automaticamente na linha do tempo"
}, },
"feedback": { "feedback": {
"heading": "Pedidos de Funcionalidades" "heading": "Pedidos de Funcionalidades"
@@ -392,7 +392,7 @@
"suspended": "Conta suspensa pelos moderadores do seu servidor" "suspended": "Conta suspensa pelos moderadores do seu servidor"
}, },
"accountInLists": { "accountInLists": {
"name": "", "name": "Listas de @{{username}}",
"inLists": "", "inLists": "",
"notInLists": "Outras listas" "notInLists": "Outras listas"
}, },
@@ -400,8 +400,8 @@
"name": "<0 /><1>\"s mídia</1>" "name": "<0 /><1>\"s mídia</1>"
}, },
"filter": { "filter": {
"name": "", "name": "Adicionar ao filtro",
"existed": "" "existed": "Existe nestes filtros"
}, },
"history": { "history": {
"name": "Histórico de Edição" "name": "Histórico de Edição"

View File

@@ -17,10 +17,10 @@
"refresh": { "refresh": {
"fetchPreviousPage": "З цього моменту", "fetchPreviousPage": "З цього моменту",
"refetch": "До кінця", "refetch": "До кінця",
"fetching": "", "fetching": "Отримання нових дмухів ...",
"fetched": { "fetched": {
"none": "", "none": "Немає нових дмухів",
"found": "" "found": "Отримано {{count}} дмухів"
} }
}, },
"shared": { "shared": {

View File

@@ -17,10 +17,10 @@
"refresh": { "refresh": {
"fetchPreviousPage": "較新的嘟文", "fetchPreviousPage": "較新的嘟文",
"refetch": "到最新的位置", "refetch": "到最新的位置",
"fetching": "", "fetching": "取得較新的嘟文 …",
"fetched": { "fetched": {
"none": "", "none": "沒有更新的嘟文",
"found": "" "found": "已取得 {{count}} 條嘟文"
} }
}, },
"shared": { "shared": {

View File

@@ -169,7 +169,8 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
haptics('Success') haptics('Success')
}} }}
/> />
{composeState.type === 'edit' && featureCheck('edit_media_details') ? ( {composeState.type !== 'edit' ||
(composeState.type === 'edit' && featureCheck('edit_media_details')) ? (
<Button <Button
accessibilityLabel={t('content.root.footer.attachments.edit.accessibilityLabel', { accessibilityLabel={t('content.root.footer.attachments.edit.accessibilityLabel', {
attachment: index + 1 attachment: index + 1

View File

@@ -96,10 +96,10 @@ const Collections: React.FC = () => {
iconBack='chevron-right' iconBack='chevron-right'
title={t('screenTabs:me.stacks.push.name')} title={t('screenTabs:me.stacks.push.name')}
content={ content={
typeof instancePush.global === 'boolean' typeof instancePush?.global === 'boolean'
? t('screenTabs:me.root.push.content', { ? t('screenTabs:me.root.push.content', {
defaultValue: 'false', defaultValue: 'false',
context: instancePush.global.toString() context: instancePush?.global.toString()
}) })
: undefined : undefined
} }

View File

@@ -1,8 +1,10 @@
import * as Sentry from '@sentry/react-native' import * as Sentry from '@sentry/react-native'
import { setGlobalStorage } from '@utils/storage/actions'
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'
import parse from 'url-parse' import parse from 'url-parse'
import { GLOBAL } from '../../../App'
const userAgent = { const userAgent = {
'User-Agent': `tooot/${Constants.expoConfig?.version} ${Platform.OS}/${Platform.Version}` 'User-Agent': `tooot/${Constants.expoConfig?.version} ${Platform.OS}/${Platform.Version}`
@@ -18,6 +20,12 @@ const handleError =
} | void } | void
) => ) =>
(error: any) => { (error: any) => {
if (GLOBAL.connect) {
if (error?.response?.status == 403 && error?.response?.data == 'connect_blocked') {
GLOBAL.connect = false
setGlobalStorage('app.connect', false)
}
}
const shouldReportToSentry = config && (config.captureRequest || config.captureResponse) const shouldReportToSentry = config && (config.captureRequest || config.captureResponse)
shouldReportToSentry && Sentry.setContext('Error object', error) shouldReportToSentry && Sentry.setContext('Error object', error)

View File

@@ -19,5 +19,5 @@ export const appendRemote = {
_remote: true _remote: true
}), }),
mentions: (mentions: Mastodon.Mention[]) => mentions: (mentions: Mastodon.Mention[]) =>
mentions.map(mention => ({ ...mention, _remote: true })) mentions?.map(mention => ({ ...mention, _remote: true }))
} }