diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 00000000..5e6575f2
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "javascript.inlayHints.functionLikeReturnTypes.enabled": false
+}
\ No newline at end of file
diff --git a/src/App.tsx b/src/App.tsx
index 96433aeb..6419e708 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -74,37 +74,6 @@ const App: React.FC = () => {
}
}, [])
- const children = useCallback(
- bootstrapped => {
- log('log', 'App', 'bootstrapped')
- if (bootstrapped) {
- log('log', 'App', 'loading actual app :)')
- const language = getSettingsLanguage(store.getState())
- if (!language) {
- store.dispatch(changeLanguage('en'))
- i18n.changeLanguage('en')
- } else {
- i18n.changeLanguage(language)
- }
-
- return (
-
-
-
-
-
-
-
-
-
- )
- } else {
- return null
- }
- },
- [localCorrupt]
- )
-
return (
@@ -112,7 +81,33 @@ const App: React.FC = () => {
{
+ log('log', 'App', 'bootstrapped')
+ if (bootstrapped) {
+ log('log', 'App', 'loading actual app :)')
+ const language = getSettingsLanguage(store.getState())
+ if (!language) {
+ store.dispatch(changeLanguage('en'))
+ i18n.changeLanguage('en')
+ } else {
+ i18n.changeLanguage(language)
+ }
+
+ return (
+
+
+
+
+
+
+
+
+
+ )
+ } else {
+ return null
+ }
+ }}
/>
diff --git a/src/Screens.tsx b/src/Screens.tsx
index f83cf37c..79d43b5b 100644
--- a/src/Screens.tsx
+++ b/src/Screens.tsx
@@ -170,6 +170,7 @@ const Screens: React.FC = ({ localCorrupt }) => {
}
| { data: string | string[]; mimeType: string }
) => {
+ console.log('item', item)
if (instanceActive < 0) {
return
}
@@ -253,6 +254,7 @@ const Screens: React.FC = ({ localCorrupt }) => {
if (!text && !media.length) {
return
} else {
+ console.log('media', media)
navigationRef.navigate('Screen-Compose', { type: 'share', text, media })
}
},
diff --git a/src/components/Emojis.tsx b/src/components/Emojis.tsx
index 0eafa302..044dce6d 100644
--- a/src/components/Emojis.tsx
+++ b/src/components/Emojis.tsx
@@ -7,6 +7,7 @@ import { chunk, forEach, groupBy, sortBy } from 'lodash'
import React, {
Dispatch,
MutableRefObject,
+ PropsWithChildren,
SetStateAction,
useCallback,
useEffect,
@@ -57,7 +58,7 @@ export interface Props {
maxLength?: number
}
-const ComponentEmojis: React.FC = ({
+const ComponentEmojis: React.FC = ({
enabled = false,
value,
setValue,
diff --git a/src/components/Emojis/List.tsx b/src/components/Emojis/List.tsx
index 48eb8ba3..32a2a931 100644
--- a/src/components/Emojis/List.tsx
+++ b/src/components/Emojis/List.tsx
@@ -27,18 +27,6 @@ const EmojisList = React.memo(
const { emojisState, emojisDispatch } = useContext(EmojisContext)
const { colors } = useTheme()
- const listHeader = useCallback(
- ({ section: { title } }) => (
-
- {title}
-
- ),
- []
- )
-
const listItem = useCallback(
({ index, item }: { item: Mastodon.Emoji[]; index: number }) => {
return (
@@ -112,7 +100,14 @@ const EmojisList = React.memo(
keyboardShouldPersistTaps='always'
sections={emojisState.emojis}
keyExtractor={item => item[0].shortcode}
- renderSectionHeader={listHeader}
+ renderSectionHeader={({ section: { title } }) => (
+
+ {title}
+
+ )}
renderItem={listItem}
windowSize={4}
/>
diff --git a/src/components/Input.tsx b/src/components/Input.tsx
index d3f7f34b..5c3752c2 100644
--- a/src/components/Input.tsx
+++ b/src/components/Input.tsx
@@ -4,7 +4,6 @@ import { useTheme } from '@utils/styles/ThemeManager'
import React, {
Dispatch,
SetStateAction,
- useCallback,
useEffect,
useRef,
useState
@@ -81,10 +80,6 @@ const Input: React.FC = ({
}
: { start: 0, end: 0 }
)
- const onSelectionChange = useCallback(
- ({ nativeEvent: { selection } }) => (selectionRange.current = selection),
- []
- )
const [inputFocused, setInputFocused] = useState(false)
useEffect(() => {
@@ -128,7 +123,9 @@ const Input: React.FC = ({
: undefined
}}
onChangeText={setValue}
- onSelectionChange={onSelectionChange}
+ onSelectionChange={({ nativeEvent: { selection } }) =>
+ (selectionRange.current = selection)
+ }
value={value}
{...(multiline && {
multiline,
diff --git a/src/components/Instance.tsx b/src/components/Instance.tsx
index 1158fe76..b37361c2 100644
--- a/src/components/Instance.tsx
+++ b/src/components/Instance.tsx
@@ -88,21 +88,6 @@ const ComponentInstance: React.FC = ({
}
}, [domain])
- const onSubmitEditing = useCallback(
- ({ nativeEvent: { text } }) => {
- analytics('instance_textinput_submit', { match: text === domain })
- if (
- text === domain &&
- instanceQuery.isSuccess &&
- instanceQuery.data &&
- instanceQuery.data.uri
- ) {
- processUpdate()
- }
- },
- [domain, instanceQuery.isSuccess, instanceQuery.data]
- )
-
const requestAuth = useMemo(() => {
if (
domain &&
@@ -180,7 +165,17 @@ const ComponentInstance: React.FC = ({
clearButtonMode='never'
keyboardType='url'
textContentType='URL'
- onSubmitEditing={onSubmitEditing}
+ onSubmitEditing={({ nativeEvent: { text } }) => {
+ analytics('instance_textinput_submit', { match: text === domain })
+ if (
+ text === domain &&
+ instanceQuery.isSuccess &&
+ instanceQuery.data &&
+ instanceQuery.data.uri
+ ) {
+ processUpdate()
+ }
+ }}
placeholder={' ' + t('server.textInput.placeholder')}
placeholderTextColor={colors.secondary}
returnKeyType='go'
diff --git a/src/components/Parse/HTML.tsx b/src/components/Parse/HTML.tsx
index 3c1b26f4..51aab5c7 100644
--- a/src/components/Parse/HTML.tsx
+++ b/src/components/Parse/HTML.tsx
@@ -215,7 +215,7 @@ const ParseHTML = React.memo(
}
const renderNodeCallback = useCallback(
- (node, index) =>
+ (node: any, index: any) =>
renderNode({
routeParams: route.params,
colors,
@@ -231,7 +231,7 @@ const ParseHTML = React.memo(
}),
[]
)
- const textComponent = useCallback(({ children }) => {
+ const textComponent = useCallback(({ children }: any) => {
if (children) {
return (
{
+ ({ children }: any) => {
const { t } = useTranslation('componentParse')
const [expandAllow, setExpandAllow] = useState(false)
const [expanded, setExpanded] = useState(highlighted)
- const onTextLayout = useCallback(({ nativeEvent }) => {
- if (
- numberOfLines === 1 ||
- nativeEvent.lines.length >= numberOfLines + 5
- ) {
- setExpandAllow(true)
- }
- }, [])
-
return (
{
+ if (
+ numberOfLines === 1 ||
+ nativeEvent.lines.length >= numberOfLines + 5
+ ) {
+ setExpandAllow(true)
+ }
+ }}
numberOfLines={
expandAllow ? (expanded ? 999 : numberOfLines) : undefined
}
diff --git a/src/components/Timeline.tsx b/src/components/Timeline.tsx
index 6908a321..2f73d636 100644
--- a/src/components/Timeline.tsx
+++ b/src/components/Timeline.tsx
@@ -64,17 +64,6 @@ const Timeline: React.FC = ({
? data.pages?.flatMap(page => [...page.body])
: []
- const ItemSeparatorComponent = useCallback(
- ({ leadingItem }) =>
- queryKey[1].page === 'Toot' && queryKey[1].toot === leadingItem.id ? (
-
- ) : (
-
- ),
- []
- )
const onEndReached = useCallback(
() => !disableInfinity && !isFetchingNextPage && fetchNextPage(),
[isFetchingNextPage]
@@ -151,7 +140,17 @@ const Timeline: React.FC = ({
/>
}
ListEmptyComponent={}
- ItemSeparatorComponent={ItemSeparatorComponent}
+ ItemSeparatorComponent={({ leadingItem }) =>
+ queryKey[1].page === 'Toot' && queryKey[1].toot === leadingItem.id ? (
+
+ ) : (
+
+ )
+ }
maintainVisibleContentPosition={
isFetching
? {
diff --git a/src/components/Timeline/Refresh.tsx b/src/components/Timeline/Refresh.tsx
index f5d5ad2a..38cfdcdd 100644
--- a/src/components/Timeline/Refresh.tsx
+++ b/src/components/Timeline/Refresh.tsx
@@ -9,7 +9,7 @@ import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import React, { RefObject, useCallback, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
-import { FlatList, Platform, StyleSheet, Text, View } from 'react-native'
+import { FlatList, LayoutChangeEvent, Platform, StyleSheet, Text, View } from 'react-native'
import { Circle } from 'react-native-animated-spinkit'
import Animated, {
Extrapolate,
@@ -169,7 +169,7 @@ const TimelineRefresh: React.FC = ({
const arrowStage = useSharedValue(0)
const onLayout = useCallback(
- ({ nativeEvent }) => {
+ ({ nativeEvent }: LayoutChangeEvent) => {
if (nativeEvent.layout.x + nativeEvent.layout.width > textRight) {
setTextRight(nativeEvent.layout.x + nativeEvent.layout.width)
}
diff --git a/src/components/mediaSelector.ts b/src/components/mediaSelector.ts
index 313bcef2..89404cd2 100644
--- a/src/components/mediaSelector.ts
+++ b/src/components/mediaSelector.ts
@@ -1,15 +1,8 @@
-import analytics from '@components/analytics'
import { ActionSheetOptions } from '@expo/react-native-action-sheet'
import { store } from '@root/store'
import { getInstanceConfigurationStatusMaxAttachments } from '@utils/slices/instancesSlice'
-import { manipulateAsync, SaveFormat } from 'expo-image-manipulator'
-import * as ExpoImagePicker from 'expo-image-picker'
import i18next from 'i18next'
-import { Alert, Linking, Platform } from 'react-native'
-import ImagePicker, {
- Image,
- ImageOrVideo
-} from 'react-native-image-crop-picker'
+import { Asset, launchImageLibrary } from 'react-native-image-picker'
export interface Props {
mediaType?: 'photo' | 'video'
@@ -28,43 +21,7 @@ const mediaSelector = async ({
maximum,
indicateMaximum = false,
showActionSheetWithOptions
-}: Props): Promise<({ uri: string } & Omit)[]> => {
- const checkLibraryPermission = async (): Promise => {
- const { status } =
- await ExpoImagePicker.requestMediaLibraryPermissionsAsync()
- if (status !== 'granted') {
- Alert.alert(
- i18next.t('componentMediaSelector:library.alert.title'),
- i18next.t('componentMediaSelector:library.alert.message'),
- [
- {
- text: i18next.t('common:buttons.cancel'),
- style: 'cancel',
- onPress: () =>
- analytics('mediaSelector_nopermission', {
- action: 'cancel'
- })
- },
- {
- text: i18next.t(
- 'componentMediaSelector:library.alert.buttons.settings'
- ),
- style: 'default',
- onPress: () => {
- analytics('mediaSelector_nopermission', {
- action: 'settings'
- })
- Linking.openURL('app-settings:')
- }
- }
- ]
- )
- return false
- } else {
- return true
- }
- }
-
+}: Props): Promise => {
const _maximum =
maximum ||
getInstanceConfigurationStatusMaxAttachments(store.getState()) ||
@@ -105,79 +62,30 @@ const mediaSelector = async ({
return new Promise((resolve, reject) => {
const selectImage = async () => {
- const images = await ImagePicker.openPicker({
+ const images = await launchImageLibrary({
mediaType: 'photo',
- includeExif: false,
- multiple: true,
- minFiles: 1,
- maxFiles: _maximum,
- smartAlbums: ['UserLibrary'],
- writeTempFile: false,
- loadingLabelText: ''
- }).catch(() => {})
+ ...(resize && { maxWidth: resize.width, maxHeight: resize.height }),
+ includeBase64: false,
+ includeExtra: false,
+ selectionLimit: _maximum
+ })
- if (!images) {
+ if (!images.assets) {
return reject()
}
- // react-native-image-crop-picker may return HEIC as JPG that causes upload failure
- if (Platform.OS === 'ios') {
- for (const [index, image] of images.entries()) {
- if (image.mime === 'image/heic') {
- const converted = await manipulateAsync(image.sourceURL!, [], {
- base64: false,
- compress: 0.8,
- format: SaveFormat.JPEG
- })
- images[index] = {
- ...images[index],
- sourceURL: converted.uri,
- mime: 'image/jpeg'
- }
- }
- }
- }
-
- if (!resize) {
- return resolve(
- images.map(image => ({
- ...image,
- uri: image.sourceURL || `file://${image.path}`
- }))
- )
- } else {
- const croppedImages: Image[] = []
- for (const image of images) {
- const croppedImage = await ImagePicker.openCropper({
- mediaType: 'photo',
- path: image.sourceURL || image.path,
- width: resize.width,
- height: resize.height,
- cropperChooseText: i18next.t('common:buttons.apply'),
- cropperCancelText: i18next.t('common:buttons.cancel'),
- hideBottomControls: true
- }).catch(() => {})
- croppedImage && croppedImages.push(croppedImage)
- }
- return resolve(
- croppedImages.map(image => ({
- ...image,
- uri: `file://${image.path}`
- }))
- )
- }
+ return resolve(images.assets)
}
const selectVideo = async () => {
- const video = await ImagePicker.openPicker({
+ const video = await launchImageLibrary({
mediaType: 'video',
- includeExif: false,
- loadingLabelText: ''
- }).catch(() => {})
+ includeBase64: false,
+ includeExtra: false,
+ selectionLimit: 1
+ })
- if (video) {
- return resolve([
- { ...video, uri: video.sourceURL || `file://${video.path}` }
- ])
+ if (video.assets?.[0]) {
+ return resolve(video.assets)
} else {
return reject()
}
@@ -189,10 +97,6 @@ const mediaSelector = async ({
cancelButtonIndex: mediaType ? 1 : 2
},
async buttonIndex => {
- if (!(await checkLibraryPermission())) {
- return reject()
- }
-
switch (mediaType) {
case 'photo':
if (buttonIndex === 0) {
diff --git a/src/components/mediaTransformation.ts b/src/components/mediaTransformation.ts
deleted file mode 100644
index 29bb542d..00000000
--- a/src/components/mediaTransformation.ts
+++ /dev/null
@@ -1,149 +0,0 @@
-import { store } from '@root/store'
-import { getInstanceConfigurationMediaAttachments } from '@utils/slices/instancesSlice'
-import { Action, manipulateAsync, SaveFormat } from 'expo-image-manipulator'
-import i18next from 'i18next'
-import { Platform } from 'react-native'
-import ImagePicker from 'react-native-image-crop-picker'
-
-export interface Props {
- type: 'image' | 'video'
- uri: string // This can be pure path or uri starting with file://
- mime?: string
- transform: {
- imageFormat?: SaveFormat.JPEG | SaveFormat.PNG
- resize?: boolean
- width?: number
- height?: number
- }
-}
-
-const getFileExtension = (uri: string) => {
- const extension = uri.split('.').pop()
- // Using mime type standard of jpeg
- return extension === 'jpg' ? 'jpeg' : extension
-}
-
-const mediaTransformation = async ({
- type,
- uri,
- mime,
- transform
-}: Props): Promise<{
- uri: string
- mime: string
- width: number
- height: number
-}> => {
- const configurationMediaAttachments =
- getInstanceConfigurationMediaAttachments(store.getState())
-
- const fileExtension = getFileExtension(uri)
-
- switch (type) {
- case 'image':
- if (mime === 'image/gif' || fileExtension === 'gif') {
- return Promise.reject('GIFs should not be transformed')
- }
- let targetFormat: SaveFormat.JPEG | SaveFormat.PNG = SaveFormat.JPEG
-
- const supportedImageTypes =
- configurationMediaAttachments.supported_mime_types.filter(mime =>
- mime.startsWith('image/')
- )
-
- // @ts-ignore
- const transformations: Action[] = [
- !transform.resize && (transform.width || transform.height)
- ? {
- resize: { width: transform.width, height: transform.height }
- }
- : null
- ].filter(t => !!t)
-
- if (mime) {
- if (
- mime !== `image/${fileExtension}` ||
- !supportedImageTypes.includes(mime)
- ) {
- targetFormat = transform.imageFormat || SaveFormat.JPEG
- } else {
- targetFormat = mime.split('/').pop() as any
- }
- } else {
- if (!fileExtension) {
- return Promise.reject('Unable to get file extension')
- }
- if (!supportedImageTypes.includes(`image/${fileExtension}`)) {
- targetFormat = transform.imageFormat || SaveFormat.JPEG
- } else {
- targetFormat = fileExtension as any
- }
- }
-
- const converted = await manipulateAsync(uri, transformations, {
- base64: false,
- compress: Platform.OS === 'ios' ? 0.8 : 1,
- format: targetFormat
- })
-
- if (transform.resize) {
- const resized = await ImagePicker.openCropper({
- mediaType: 'photo',
- path: converted.uri,
- width: transform.width,
- height: transform.height,
- cropperChooseText: i18next.t('common:buttons.apply'),
- cropperCancelText: i18next.t('common:buttons.cancel'),
- hideBottomControls: true
- })
- if (!resized) {
- return Promise.reject('Resize failed')
- } else {
- return {
- uri: resized.path,
- mime: resized.mime,
- width: resized.width,
- height: resized.height
- }
- }
- } else {
- return {
- uri: converted.uri,
- mime: transform.imageFormat || SaveFormat.JPEG,
- width: converted.width,
- height: converted.height
- }
- }
- case 'video':
- const supportedVideoTypes =
- configurationMediaAttachments.supported_mime_types.filter(mime =>
- mime.startsWith('video/')
- )
-
- if (mime) {
- if (mime !== `video/${fileExtension}`) {
- console.warn('Video mime type and file extension does not match')
- }
- if (!supportedVideoTypes.includes(mime)) {
- return Promise.reject('Video file type is not supported')
- }
- } else {
- if (!fileExtension) {
- return Promise.reject('Unable to get file extension')
- }
- if (!supportedVideoTypes.includes(`video/${fileExtension}`)) {
- return Promise.reject('Video file type is not supported')
- }
- }
-
- return {
- uri: uri,
- mime: mime || `video/${fileExtension}`,
- width: 0,
- height: 0
- }
- break
- }
-}
-
-export default mediaTransformation
diff --git a/src/screens/Announcements.tsx b/src/screens/Announcements.tsx
index e38df48c..2b04312b 100644
--- a/src/screens/Announcements.tsx
+++ b/src/screens/Announcements.tsx
@@ -15,8 +15,15 @@ import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import React, { useCallback, useEffect, useState } from 'react'
import { Trans, useTranslation } from 'react-i18next'
-import { FormattedRelativeTime } from 'react-intl'
-import { Dimensions, Platform, Pressable, StyleSheet, View } from 'react-native'
+import {
+ Dimensions,
+ NativeScrollEvent,
+ NativeSyntheticEvent,
+ Platform,
+ Pressable,
+ StyleSheet,
+ View
+} from 'react-native'
import { Circle } from 'react-native-animated-spinkit'
import FastImage from 'react-native-fast-image'
import { FlatList, ScrollView } from 'react-native-gesture-handler'
@@ -92,9 +99,7 @@ const ScreenAnnouncements: React.FC<
>
- ]}
+ components={[]}
/>
{
+ }: NativeSyntheticEvent) => {
setIndex(Math.floor(x / width))
},
[]
diff --git a/src/screens/Compose.tsx b/src/screens/Compose.tsx
index d0695c9d..3a7aa3ab 100644
--- a/src/screens/Compose.tsx
+++ b/src/screens/Compose.tsx
@@ -150,7 +150,7 @@ const ScreenCompose: React.FC> = ({
for (const m of params.media) {
uploadAttachment({
composeDispatch,
- media: { ...m, width: 100, height: 100 }
+ media: { uri: m.uri, fileName: 'temp.jpg', type: m.mime }
})
}
}
diff --git a/src/screens/Compose/DraftsList/Root.tsx b/src/screens/Compose/DraftsList/Root.tsx
index 3c1abed3..12c44384 100644
--- a/src/screens/Compose/DraftsList/Root.tsx
+++ b/src/screens/Compose/DraftsList/Root.tsx
@@ -47,10 +47,6 @@ const ComposeDraftsListRoot: React.FC = ({ timestamp }) => {
const [checkingAttachments, setCheckingAttachments] = useState(false)
- const removeDraft = useCallback(ts => {
- dispatch(removeInstanceDraft(ts))
- }, [])
-
const renderItem = useCallback(
({ item }: { item: ComposeStateDraft }) => {
return (
@@ -144,7 +140,7 @@ const ComposeDraftsListRoot: React.FC = ({ timestamp }) => {
}}
source={{
uri:
- attachment.local?.local_thumbnail ||
+ attachment.local?.thumbnail ||
attachment.remote?.preview_url
}}
/>
@@ -157,38 +153,6 @@ const ComposeDraftsListRoot: React.FC = ({ timestamp }) => {
},
[theme]
)
- const renderHiddenItem = useCallback(
- ({ item }) => (
- removeDraft(item.timestamp)}
- children={
-
- }
- />
- }
- />
- ),
- [theme]
- )
return (
<>
@@ -220,7 +184,35 @@ const ComposeDraftsListRoot: React.FC = ({ timestamp }) => {
(
+ dispatch(removeInstanceDraft(item.timestamp))}
+ children={
+
+ }
+ />
+ }
+ />
+ )}
disableRightSwipe={true}
rightOpenValue={-actionWidth}
// previewRowKey={
diff --git a/src/screens/Compose/EditAttachment/Root.tsx b/src/screens/Compose/EditAttachment/Root.tsx
index bff60bd9..24e89f3f 100644
--- a/src/screens/Compose/EditAttachment/Root.tsx
+++ b/src/screens/Compose/EditAttachment/Root.tsx
@@ -35,7 +35,7 @@ const ComposeEditAttachmentRoot: React.FC = ({ index }) => {
video.local
? ({
url: video.local.uri,
- preview_url: video.local.local_thumbnail,
+ preview_url: video.local.thumbnail,
blurhash: video.remote?.blurhash
} as Mastodon.AttachmentVideo)
: (video.remote as Mastodon.AttachmentVideo)
diff --git a/src/screens/Compose/Root.tsx b/src/screens/Compose/Root.tsx
index f2270d8a..5afeaf54 100644
--- a/src/screens/Compose/Root.tsx
+++ b/src/screens/Compose/Root.tsx
@@ -4,13 +4,7 @@ import { useSearchQuery } from '@utils/queryHooks/search'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import { chunk, forEach, groupBy, sortBy } from 'lodash'
-import React, {
- useCallback,
- useContext,
- useEffect,
- useMemo,
- useRef
-} from 'react'
+import React, { useContext, useEffect, useMemo, useRef } from 'react'
import {
AccessibilityInfo,
findNodeHandle,
@@ -147,35 +141,25 @@ const ComposeRoot = React.memo(
}
}, [isFetching])
- const listItem = useCallback(
- ({ item }) => (
-
- ),
- [composeState]
- )
-
- const ListFooter = useCallback(
- () => (
-
- ),
- []
- )
-
return (
(
+
+ )}
ListEmptyComponent={listEmpty}
keyboardShouldPersistTaps='always'
ListHeaderComponent={ComposeRootHeader}
- ListFooterComponent={ListFooter}
+ ListFooterComponent={() => (
+
+ )}
ItemSeparatorComponent={ComponentSeparator}
// @ts-ignore
data={data ? data[composeState.tag?.type] : undefined}
diff --git a/src/screens/Compose/Root/Footer/Attachments.tsx b/src/screens/Compose/Root/Footer/Attachments.tsx
index 8df70266..da5c7496 100644
--- a/src/screens/Compose/Root/Footer/Attachments.tsx
+++ b/src/screens/Compose/Root/Footer/Attachments.tsx
@@ -56,9 +56,12 @@ const ComposeAttachments: React.FC = ({ accessibleRefAttachments }) => {
})
}, [composeState.attachments.sensitive])
- const calculateWidth = useCallback(item => {
+ const calculateWidth = useCallback((item: ExtendedAttachment) => {
if (item.local) {
- return (item.local.width / item.local.height) * DEFAULT_HEIGHT
+ return (
+ ((item.local.width || 100) / (item.local.height || 100)) *
+ DEFAULT_HEIGHT
+ )
} else {
if (item.remote) {
if (item.remote.meta.original.aspect) {
@@ -135,7 +138,7 @@ const ComposeAttachments: React.FC = ({ accessibleRefAttachments }) => {
{item.remote?.meta?.original?.duration ? (
diff --git a/src/screens/Compose/Root/Footer/Emojis.tsx b/src/screens/Compose/Root/Footer/Emojis.tsx
index 552d755d..eb6ee6b2 100644
--- a/src/screens/Compose/Root/Footer/Emojis.tsx
+++ b/src/screens/Compose/Root/Footer/Emojis.tsx
@@ -42,22 +42,6 @@ const ComposeEmojis: React.FC = ({ accessibleRefEmojis }) => {
}
}, [composeState.emoji.active])
- const listHeader = useCallback(
- ({ section: { title } }) => (
-
- {title}
-
- ),
- []
- )
-
const listItem = useCallback(
({ index, item }: { item: Mastodon.Emoji[]; index: number }) => {
return (
@@ -155,7 +139,18 @@ const ComposeEmojis: React.FC = ({ accessibleRefEmojis }) => {
keyboardShouldPersistTaps='always'
sections={composeState.emoji.emojis || []}
keyExtractor={item => item[0].shortcode}
- renderSectionHeader={listHeader}
+ renderSectionHeader={({ section: { title } }) => (
+
+ {title}
+
+ )}
renderItem={listItem}
windowSize={2}
/>
diff --git a/src/screens/Compose/Root/Footer/addAttachment.ts b/src/screens/Compose/Root/Footer/addAttachment.ts
index 63e11904..676e67d9 100644
--- a/src/screens/Compose/Root/Footer/addAttachment.ts
+++ b/src/screens/Compose/Root/Footer/addAttachment.ts
@@ -7,7 +7,7 @@ import { ActionSheetOptions } from '@expo/react-native-action-sheet'
import i18next from 'i18next'
import apiInstance from '@api/instance'
import mediaSelector from '@components/mediaSelector'
-import { ImageOrVideo } from 'react-native-image-crop-picker'
+import { Asset } from 'react-native-image-picker'
export interface Props {
composeDispatch: Dispatch
@@ -22,46 +22,40 @@ export const uploadAttachment = async ({
media
}: {
composeDispatch: Dispatch
- media: { uri: string } & Pick
+ media: Required>
}) => {
const hash = await Crypto.digestStringAsync(
Crypto.CryptoDigestAlgorithm.SHA256,
media.uri + Math.random()
)
- switch (media.mime.split('/')[0]) {
+ switch (media.type.split('/')[0]) {
case 'image':
composeDispatch({
type: 'attachment/upload/start',
payload: {
- local: { ...media, type: 'image', local_thumbnail: media.uri, hash },
+ local: { ...media, thumbnail: media.uri, hash },
uploading: true
}
})
break
case 'video':
VideoThumbnails.getThumbnailAsync(media.uri)
- .then(({ uri, width, height }) =>
+ .then(({ uri, width, height }) => {
+ console.log('new', uri, width, height)
composeDispatch({
type: 'attachment/upload/start',
payload: {
- local: {
- ...media,
- type: 'video',
- local_thumbnail: uri,
- hash,
- width,
- height
- },
+ local: { ...media, thumbnail: uri, hash, width, height },
uploading: true
}
})
- )
+ })
.catch(() =>
composeDispatch({
type: 'attachment/upload/start',
payload: {
- local: { ...media, type: 'video', hash },
+ local: { ...media, hash },
uploading: true
}
})
@@ -71,7 +65,7 @@ export const uploadAttachment = async ({
composeDispatch({
type: 'attachment/upload/start',
payload: {
- local: { ...media, type: 'unknown', hash },
+ local: { ...media, hash },
uploading: true
}
})
@@ -102,8 +96,8 @@ export const uploadAttachment = async ({
const formData = new FormData()
formData.append('file', {
uri: media.uri,
- name: media.uri.match(new RegExp(/.*\/(.*)/))?.[1] || 'file.jpg',
- type: media.mime
+ name: media.fileName,
+ type: media.type
} as any)
return apiInstance({
@@ -140,7 +134,8 @@ const chooseAndUploadAttachment = async ({
showActionSheetWithOptions
})
for (const media of result) {
- uploadAttachment({ composeDispatch, media })
+ const requiredMedia = media as Required
+ uploadAttachment({ composeDispatch, media: requiredMedia })
await new Promise(res => setTimeout(res, 500))
}
}
diff --git a/src/screens/Compose/Root/Header/TextInput.tsx b/src/screens/Compose/Root/Header/TextInput.tsx
index aa0ed691..f107cebf 100644
--- a/src/screens/Compose/Root/Header/TextInput.tsx
+++ b/src/screens/Compose/Root/Header/TextInput.tsx
@@ -101,15 +101,7 @@ const ComposeTextInput: React.FC = () => {
}
for (const file of files) {
- uploadAttachment({
- composeDispatch,
- media: {
- uri: file.uri,
- mime: file.type,
- width: 100,
- height: 100
- }
- })
+ uploadAttachment({ composeDispatch, media: file })
}
}}
>
diff --git a/src/screens/Compose/utils/types.d.ts b/src/screens/Compose/utils/types.d.ts
index 586be113..3b89b956 100644
--- a/src/screens/Compose/utils/types.d.ts
+++ b/src/screens/Compose/utils/types.d.ts
@@ -1,12 +1,8 @@
-import { ImageOrVideo } from 'react-native-image-crop-picker'
+import { Asset } from 'react-native-image-picker'
export type ExtendedAttachment = {
remote?: Mastodon.Attachment
- local?: { uri: string } & Pick & {
- type: 'image' | 'video' | 'unknown'
- local_thumbnail?: string
- hash?: string
- }
+ local?: Asset & { thumbnail?: string; hash: string }
uploading?: boolean
}
@@ -121,10 +117,7 @@ export type ComposeAction =
}
| {
type: 'attachment/upload/end'
- payload: {
- remote: Mastodon.Attachment
- local: { uri: string } & Pick
- }
+ payload: { remote: Mastodon.Attachment; local: Asset }
}
| {
type: 'attachment/upload/fail'
diff --git a/src/screens/ImageViewer/hooks/usePanResponder.ts b/src/screens/ImageViewer/hooks/usePanResponder.ts
index d4ed1fe1..69f0eb9a 100644
--- a/src/screens/ImageViewer/hooks/usePanResponder.ts
+++ b/src/screens/ImageViewer/hooks/usePanResponder.ts
@@ -50,11 +50,9 @@ const usePanResponder = ({
onLongPress,
delayLongPress,
onRequestClose
-}: Props): Readonly<[
- GestureResponderHandlers,
- Animated.Value,
- Animated.ValueXY
-]> => {
+}: Props): Readonly<
+ [GestureResponderHandlers, Animated.Value, Animated.ValueXY]
+> => {
let numberInitialTouches = 1
let initialTouches: NativeTouchEvent[] = []
let currentScale = initialScale
@@ -137,6 +135,7 @@ const usePanResponder = ({
if (gestureState.numberActiveTouches > 1) return
+ // @ts-ignore
longPressHandlerRef = setTimeout(onLongPress, delayLongPress)
},
onStart: (
@@ -150,6 +149,7 @@ const usePanResponder = ({
const tapTS = Date.now()
!timer &&
+ // @ts-ignore
(timer = setTimeout(() => onRequestClose(), DOUBLE_TAP_DELAY + 50))
// Handle double tap event by calculating diff between first and second taps timestamps
@@ -158,6 +158,7 @@ const usePanResponder = ({
)
if (doubleTapToZoomEnabled && isDoubleTapPerformed) {
+ // @ts-ignore
clearTimeout(timer)
const isScaled = currentTranslate.x !== initialTranslate.x // currentScale !== initialScale;
const { pageX: touchX, pageY: touchY } = event.nativeEvent.touches[0]
@@ -291,9 +292,8 @@ const usePanResponder = ({
if (isTapGesture && currentScale > initialScale) {
const { x, y } = currentTranslate
const { dx, dy } = gestureState
- const [topBound, leftBound, bottomBound, rightBound] = getBounds(
- currentScale
- )
+ const [topBound, leftBound, bottomBound, rightBound] =
+ getBounds(currentScale)
let nextTranslateX = x + dx
let nextTranslateY = y + dy
@@ -357,9 +357,8 @@ const usePanResponder = ({
if (tmpTranslate) {
const { x, y } = tmpTranslate
- const [topBound, leftBound, bottomBound, rightBound] = getBounds(
- currentScale
- )
+ const [topBound, leftBound, bottomBound, rightBound] =
+ getBounds(currentScale)
let nextTranslateX = x
let nextTranslateY = y
diff --git a/src/screens/ImageViewer/utils.ts b/src/screens/ImageViewer/utils.ts
index 54703ac5..c75a8ae8 100644
--- a/src/screens/ImageViewer/utils.ts
+++ b/src/screens/ImageViewer/utils.ts
@@ -44,6 +44,7 @@ export const getImageStyles = (
const transform = translate.getTranslateTransform()
if (scale) {
+ // @ts-ignore
transform.push({ scale }, { perspective: new Animated.Value(1000) })
}
diff --git a/src/screens/Tabs.tsx b/src/screens/Tabs.tsx
index 0c18965e..6efb3266 100644
--- a/src/screens/Tabs.tsx
+++ b/src/screens/Tabs.tsx
@@ -1,10 +1,7 @@
import GracefullyImage from '@components/GracefullyImage'
import haptics from '@components/haptics'
import Icon from '@components/Icon'
-import {
- BottomTabNavigationOptions,
- createBottomTabNavigator
-} from '@react-navigation/bottom-tabs'
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'
import { useAppDispatch } from '@root/store'
import {
RootStackScreenProps,
@@ -15,10 +12,7 @@ import {
getInstanceAccount,
getInstanceActive
} from '@utils/slices/instancesSlice'
-import {
- getVersionUpdate,
- retriveVersionLatest
-} from '@utils/slices/appSlice'
+import { getVersionUpdate, retriveVersionLatest } from '@utils/slices/appSlice'
import { useTheme } from '@utils/styles/ThemeManager'
import React, { useCallback, useEffect, useMemo } from 'react'
import { Platform } from 'react-native'
@@ -32,7 +26,7 @@ const Tab = createBottomTabNavigator()
const ScreenTabs = React.memo(
({ navigation }: RootStackScreenProps<'Screen-Tabs'>) => {
- const { colors, theme } = useTheme()
+ const { colors } = useTheme()
const instanceActive = useSelector(getInstanceActive)
const instanceAccount = useSelector(
@@ -40,57 +34,6 @@ const ScreenTabs = React.memo(
(prev, next) => prev?.avatarStatic === next?.avatarStatic
)
- const screenOptions = useCallback(
- ({ route }): BottomTabNavigationOptions => ({
- headerShown: false,
- tabBarActiveTintColor: colors.primaryDefault,
- tabBarInactiveTintColor: colors.secondary,
- tabBarShowLabel: false,
- ...(Platform.OS === 'android' && { tabBarHideOnKeyboard: true }),
- tabBarStyle: { display: instanceActive !== -1 ? 'flex' : 'none' },
- tabBarIcon: ({
- focused,
- color,
- size
- }: {
- focused: boolean
- color: string
- size: number
- }) => {
- switch (route.name) {
- case 'Tab-Local':
- return
- case 'Tab-Public':
- return
- case 'Tab-Compose':
- return
- case 'Tab-Notifications':
- return
- case 'Tab-Me':
- return (
-
- )
- default:
- return
- }
- }
- }),
- [instanceAccount?.avatarStatic, instanceActive, theme]
- )
-
const composeListeners = useMemo(
() => ({
tabPress: (e: any) => {
@@ -132,7 +75,53 @@ const ScreenTabs = React.memo(
return (
({
+ headerShown: false,
+ tabBarActiveTintColor: colors.primaryDefault,
+ tabBarInactiveTintColor: colors.secondary,
+ tabBarShowLabel: false,
+ ...(Platform.OS === 'android' && { tabBarHideOnKeyboard: true }),
+ tabBarStyle: { display: instanceActive !== -1 ? 'flex' : 'none' },
+ tabBarIcon: ({
+ focused,
+ color,
+ size
+ }: {
+ focused: boolean
+ color: string
+ size: number
+ }) => {
+ switch (route.name) {
+ case 'Tab-Local':
+ return
+ case 'Tab-Public':
+ return
+ case 'Tab-Compose':
+ return
+ case 'Tab-Notifications':
+ return
+ case 'Tab-Me':
+ return (
+
+ )
+ default:
+ return
+ }
+ }
+ })}
>
diff --git a/src/screens/Tabs/Local.tsx b/src/screens/Tabs/Local.tsx
index 53cadbb2..30c073fd 100644
--- a/src/screens/Tabs/Local.tsx
+++ b/src/screens/Tabs/Local.tsx
@@ -44,16 +44,16 @@ const TabLocal = React.memo(
)
const queryKey: QueryKeyTimeline = ['Timeline', { page: 'Following' }]
- const renderItem = useCallback(
- ({ item }) => ,
- []
- )
const children = useCallback(
() => (
(
+
+ )
+ }}
/>
),
[]
diff --git a/src/screens/Tabs/Me/Bookmarks.tsx b/src/screens/Tabs/Me/Bookmarks.tsx
index aad868e8..a6bdd1f2 100644
--- a/src/screens/Tabs/Me/Bookmarks.tsx
+++ b/src/screens/Tabs/Me/Bookmarks.tsx
@@ -1,16 +1,22 @@
import Timeline from '@components/Timeline'
import TimelineDefault from '@components/Timeline/Default'
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
-import React, { useCallback } from 'react'
+import React from 'react'
const TabMeBookmarks = React.memo(
() => {
const queryKey: QueryKeyTimeline = ['Timeline', { page: 'Bookmarks' }]
- const renderItem = useCallback(
- ({ item }) => ,
- []
+
+ return (
+ (
+
+ )
+ }}
+ />
)
- return
},
() => true
)
diff --git a/src/screens/Tabs/Me/Cconversations.tsx b/src/screens/Tabs/Me/Cconversations.tsx
index 65eecd6d..48d2410e 100644
--- a/src/screens/Tabs/Me/Cconversations.tsx
+++ b/src/screens/Tabs/Me/Cconversations.tsx
@@ -1,19 +1,22 @@
import Timeline from '@components/Timeline'
import TimelineConversation from '@components/Timeline/Conversation'
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
-import React, { useCallback } from 'react'
+import React from 'react'
const TabMeConversations = React.memo(
() => {
const queryKey: QueryKeyTimeline = ['Timeline', { page: 'Conversations' }]
- const renderItem = useCallback(
- ({ item }) => (
-
- ),
- []
- )
- return
+ return (
+ (
+
+ )
+ }}
+ />
+ )
},
() => true
)
diff --git a/src/screens/Tabs/Me/Favourites.tsx b/src/screens/Tabs/Me/Favourites.tsx
index fe799f19..c712fe4a 100644
--- a/src/screens/Tabs/Me/Favourites.tsx
+++ b/src/screens/Tabs/Me/Favourites.tsx
@@ -1,17 +1,22 @@
import Timeline from '@components/Timeline'
import TimelineDefault from '@components/Timeline/Default'
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
-import React, { useCallback } from 'react'
+import React from 'react'
const TabMeFavourites = React.memo(
() => {
const queryKey: QueryKeyTimeline = ['Timeline', { page: 'Favourites' }]
- const renderItem = useCallback(
- ({ item }) => ,
- []
- )
- return
+ return (
+ (
+
+ )
+ }}
+ />
+ )
},
() => true
)
diff --git a/src/screens/Tabs/Me/ListsList.tsx b/src/screens/Tabs/Me/ListsList.tsx
index ad94eb04..3c76cf85 100644
--- a/src/screens/Tabs/Me/ListsList.tsx
+++ b/src/screens/Tabs/Me/ListsList.tsx
@@ -2,7 +2,7 @@ import Timeline from '@components/Timeline'
import TimelineDefault from '@components/Timeline/Default'
import { TabMeStackScreenProps } from '@utils/navigation/navigators'
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
-import React, { useCallback } from 'react'
+import React from 'react'
const TabMeListsList: React.FC> = ({
route: {
@@ -10,12 +10,17 @@ const TabMeListsList: React.FC> = ({
}
}) => {
const queryKey: QueryKeyTimeline = ['Timeline', { page: 'List', list }]
- const renderItem = useCallback(
- ({ item }) => ,
- []
- )
- return
+ return (
+ (
+
+ )
+ }}
+ />
+ )
}
export default TabMeListsList
diff --git a/src/screens/Tabs/Notifications.tsx b/src/screens/Tabs/Notifications.tsx
index a6746b4a..32b8f0c2 100644
--- a/src/screens/Tabs/Notifications.tsx
+++ b/src/screens/Tabs/Notifications.tsx
@@ -43,14 +43,17 @@ const TabNotifications = React.memo(
)
const queryKey: QueryKeyTimeline = ['Timeline', { page: 'Notifications' }]
- const renderItem = useCallback(
- ({ item }) => (
-
- ),
- []
- )
const children = useCallback(
- () => ,
+ () => (
+ (
+
+ )
+ }}
+ />
+ ),
[]
)
diff --git a/src/screens/Tabs/Shared/Account.tsx b/src/screens/Tabs/Shared/Account.tsx
index d9562b42..cc1f561d 100644
--- a/src/screens/Tabs/Shared/Account.tsx
+++ b/src/screens/Tabs/Shared/Account.tsx
@@ -30,18 +30,10 @@ const TabSharedAccount: React.FC<
const scrollY = useSharedValue(0)
- const onScroll = useCallback(({ nativeEvent }) => {
- scrollY.value = nativeEvent.contentOffset.y
- }, [])
-
const [queryKey, setQueryKey] = useState([
'Timeline',
{ page: 'Account_Default', account: account.id }
])
- const renderItem = useCallback(
- ({ item }) => ,
- []
- )
const isFetchingTimeline = useIsFetching(queryKey)
const fetchedTimeline = useRef(false)
useEffect(() => {
@@ -97,8 +89,11 @@ const TabSharedAccount: React.FC<
queryKey={queryKey}
disableRefresh
customProps={{
- renderItem,
- onScroll,
+ renderItem: ({ item }) => (
+
+ ),
+ onScroll: ({ nativeEvent }) =>
+ (scrollY.value = nativeEvent.contentOffset.y),
ListHeaderComponent,
maintainVisibleContentPosition: undefined
}}
diff --git a/src/screens/Tabs/Shared/Account/Information.tsx b/src/screens/Tabs/Shared/Account/Information.tsx
index f91d3860..82b47204 100644
--- a/src/screens/Tabs/Shared/Account/Information.tsx
+++ b/src/screens/Tabs/Shared/Account/Information.tsx
@@ -1,7 +1,7 @@
import { useRoute } from '@react-navigation/native'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
-import React, { useCallback } from 'react'
+import React from 'react'
import { StyleSheet, View } from 'react-native'
import { Placeholder, Fade } from 'rn-placeholder'
import AccountInformationAccount from './Information/Account'
@@ -19,21 +19,21 @@ export interface Props {
const AccountInformation = React.memo(
({ account }: Props) => {
- const { colors, theme } = useTheme()
+ const { colors } = useTheme()
const { name } = useRoute()
const myInfo = name !== 'Tab-Shared-Account'
- const animation = useCallback(
- props => (
-
- ),
- [theme]
- )
-
return (
-
+ (
+
+ )}
+ >
diff --git a/src/screens/Tabs/Shared/Attachments.tsx b/src/screens/Tabs/Shared/Attachments.tsx
index 75036656..773b3938 100644
--- a/src/screens/Tabs/Shared/Attachments.tsx
+++ b/src/screens/Tabs/Shared/Attachments.tsx
@@ -2,11 +2,11 @@ import Timeline from '@components/Timeline'
import TimelineDefault from '@components/Timeline/Default'
import { TabSharedStackScreenProps } from '@utils/navigation/navigators'
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
-import React, { useCallback } from 'react'
+import React from 'react'
-const TabSharedAttachments: React.FC> = ({
+const TabSharedAttachments: React.FC<
+ TabSharedStackScreenProps<'Tab-Shared-Attachments'>
+> = ({
route: {
params: { account }
}
@@ -15,11 +15,16 @@ const TabSharedAttachments: React.FC ,
- []
+ return (
+ (
+
+ )
+ }}
+ />
)
- return
}
export default TabSharedAttachments
diff --git a/src/screens/Tabs/Shared/Hashtag.tsx b/src/screens/Tabs/Shared/Hashtag.tsx
index 6afd083a..93cd5061 100644
--- a/src/screens/Tabs/Shared/Hashtag.tsx
+++ b/src/screens/Tabs/Shared/Hashtag.tsx
@@ -2,21 +2,26 @@ import Timeline from '@components/Timeline'
import TimelineDefault from '@components/Timeline/Default'
import { TabSharedStackScreenProps } from '@utils/navigation/navigators'
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
-import React, { useCallback } from 'react'
+import React from 'react'
-const TabSharedHashtag: React.FC> = ({
+const TabSharedHashtag: React.FC<
+ TabSharedStackScreenProps<'Tab-Shared-Hashtag'>
+> = ({
route: {
params: { hashtag }
}
}) => {
const queryKey: QueryKeyTimeline = ['Timeline', { page: 'Hashtag', hashtag }]
- const renderItem = useCallback(
- ({ item }) => ,
- []
+ return (
+ (
+
+ )
+ }}
+ />
)
- return
}
export default TabSharedHashtag
diff --git a/src/screens/Tabs/Shared/Search.tsx b/src/screens/Tabs/Shared/Search.tsx
index fd5d885c..4f883807 100644
--- a/src/screens/Tabs/Shared/Search.tsx
+++ b/src/screens/Tabs/Shared/Search.tsx
@@ -139,65 +139,22 @@ const TabSharedSearch: React.FC<
)
}, [status])
- const sectionHeader = useCallback(
- ({ section: { translation } }) => (
-
-
- {translation}
-
-
- ),
+
+ const listItem = useCallback(
+ ({ item, section }: { item: any; section: any }) => {
+ switch (section.title) {
+ case 'accounts':
+ return
+ case 'hashtags':
+ return
+ case 'statuses':
+ return
+ default:
+ return null
+ }
+ },
[]
)
- const sectionFooter = useCallback(
- ({ section: { data, translation } }) =>
- !data.length ? (
-
-
-
- }}
- />
-
-
- ) : null,
- [text]
- )
- const listItem = useCallback(({ item, section }) => {
- switch (section.title) {
- case 'accounts':
- return
- case 'hashtags':
- return
- case 'statuses':
- return
- default:
- return null
- }
- }, [])
return (
(
+
+
+ {translation}
+
+
+ )}
+ renderSectionFooter={({ section: { data, translation } }) =>
+ !data.length ? (
+
+
+
+ }}
+ />
+
+
+ ) : null
+ }
keyExtractor={(item, index) => item + index}
SectionSeparatorComponent={ComponentSeparator}
ItemSeparatorComponent={ComponentSeparator}
diff --git a/src/screens/Tabs/Shared/Toot.tsx b/src/screens/Tabs/Shared/Toot.tsx
index 63a6a6ea..b238ebad 100644
--- a/src/screens/Tabs/Shared/Toot.tsx
+++ b/src/screens/Tabs/Shared/Toot.tsx
@@ -3,7 +3,7 @@ import TimelineDefault from '@components/Timeline/Default'
import { useNavigation } from '@react-navigation/native'
import { TabSharedStackScreenProps } from '@utils/navigation/navigators'
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
-import React, { useCallback, useEffect, useRef, useState } from 'react'
+import React, { useEffect, useRef, useState } from 'react'
import { FlatList } from 'react-native'
import { InfiniteQueryObserver, useQueryClient } from 'react-query'
@@ -59,43 +59,35 @@ const TabSharedToot: React.FC> = ({
})
}, [scrolled.current])
- // Toot page auto scroll to selected toot
- const onScrollToIndexFailed = useCallback(
- error => {
- const offset = error.averageItemLength * error.index
- flRef.current?.scrollToOffset({ offset })
- try {
- error.index < itemsLength &&
- setTimeout(
- () =>
- flRef.current?.scrollToIndex({
- index: error.index,
- viewOffset: 100
- }),
- 500
- )
- } catch {}
- },
- [itemsLength]
- )
-
- const renderItem = useCallback(
- ({ item }) => (
-
- ),
- []
- )
-
return (
(
+
+ ),
+ onScrollToIndexFailed: error => {
+ const offset = error.averageItemLength * error.index
+ flRef.current?.scrollToOffset({ offset })
+ try {
+ error.index < itemsLength &&
+ setTimeout(
+ () =>
+ flRef.current?.scrollToIndex({
+ index: error.index,
+ viewOffset: 100
+ }),
+ 500
+ )
+ } catch {}
+ }
+ }}
disableRefresh
disableInfinity
/>
diff --git a/src/screens/Tabs/Shared/Users.tsx b/src/screens/Tabs/Shared/Users.tsx
index 34134664..187f3b11 100644
--- a/src/screens/Tabs/Shared/Users.tsx
+++ b/src/screens/Tabs/Shared/Users.tsx
@@ -9,28 +9,20 @@ import { FlatList } from 'react-native-gesture-handler'
const TabSharedUsers = React.memo(
({ route: { params } }: TabSharedStackScreenProps<'Tab-Shared-Users'>) => {
const queryKey: QueryKeyUsers = ['Users', params]
- const {
- data,
- hasNextPage,
- fetchNextPage,
- isFetchingNextPage
- } = useUsersQuery({
- ...queryKey[1],
- options: {
- getPreviousPageParam: firstPage =>
- firstPage.links?.prev && { since_id: firstPage.links.next },
- getNextPageParam: lastPage =>
- lastPage.links?.next && { max_id: lastPage.links.next }
- }
- })
+ const { data, hasNextPage, fetchNextPage, isFetchingNextPage } =
+ useUsersQuery({
+ ...queryKey[1],
+ options: {
+ getPreviousPageParam: firstPage =>
+ firstPage.links?.prev && { since_id: firstPage.links.next },
+ getNextPageParam: lastPage =>
+ lastPage.links?.next && { max_id: lastPage.links.next }
+ }
+ })
const flattenData = data?.pages
? data.pages.flatMap(page => [...page.body])
: []
- const renderItem = useCallback(
- ({ item }) => ,
- []
- )
const onEndReached = useCallback(
() => hasNextPage && !isFetchingNextPage && fetchNextPage(),
[hasNextPage, isFetchingNextPage]
@@ -41,7 +33,9 @@ const TabSharedUsers = React.memo(
windowSize={7}
data={flattenData}
style={styles.flatList}
- renderItem={renderItem}
+ renderItem={({ item }) => (
+
+ )}
onEndReached={onEndReached}
onEndReachedThreshold={0.75}
ItemSeparatorComponent={ComponentSeparator}
diff --git a/src/utils/accessibility/AccessibilityManager.tsx b/src/utils/accessibility/AccessibilityManager.tsx
index 871db497..28ab4ed8 100644
--- a/src/utils/accessibility/AccessibilityManager.tsx
+++ b/src/utils/accessibility/AccessibilityManager.tsx
@@ -1,4 +1,10 @@
-import React, { createContext, useContext, useEffect, useState } from 'react'
+import React, {
+ createContext,
+ PropsWithChildren,
+ useContext,
+ useEffect,
+ useState
+} from 'react'
import { AccessibilityInfo } from 'react-native'
type ContextType = {
@@ -15,7 +21,7 @@ const AccessibilityContext = createContext({
export const useAccessibility = () => useContext(AccessibilityContext)
-const AccessibilityManager: React.FC = ({ children }) => {
+const AccessibilityManager: React.FC = ({ children }) => {
const [reduceMotionEnabled, setReduceMotionEnabled] = useState(false)
const [screenReaderEnabled, setScreenReaderEnabled] = useState(false)
const [boldTextEnabled, setBoldTextEnabled] = useState(false)
diff --git a/src/utils/styles/ThemeManager.tsx b/src/utils/styles/ThemeManager.tsx
index a5d9ea17..21959cab 100644
--- a/src/utils/styles/ThemeManager.tsx
+++ b/src/utils/styles/ThemeManager.tsx
@@ -1,4 +1,10 @@
-import React, { createContext, useContext, useEffect, useState } from 'react'
+import React, {
+ createContext,
+ PropsWithChildren,
+ useContext,
+ useEffect,
+ useState
+} from 'react'
import { Appearance } from 'react-native'
import { useSelector } from 'react-redux'
import { ColorDefinitions, getColors, Theme } from '@utils/styles/themes'
@@ -74,7 +80,7 @@ const determineTheme = (
}
}
-const ThemeManager: React.FC = ({ children }) => {
+const ThemeManager: React.FC = ({ children }) => {
const osTheme = useColorSchemeDelay()
const userTheme = useSelector(getSettingsTheme)
const darkTheme = useSelector(getSettingsDarkTheme)