This commit is contained in:
Zhiyuan Zheng 2021-02-11 01:33:31 +01:00
parent a40a645337
commit d1bddc696a
No known key found for this signature in database
GPG Key ID: 078A93AB607D85E0
50 changed files with 271 additions and 269 deletions

View File

@ -1 +0,0 @@
<a rel="me" href="https://social.xmflsct.com/@tooot">@tooot@xmflsct.com</a>

View File

@ -25,6 +25,7 @@ public class BasePackageList {
new expo.modules.localization.LocalizationPackage(), new expo.modules.localization.LocalizationPackage(),
new expo.modules.location.LocationPackage(), new expo.modules.location.LocationPackage(),
new expo.modules.permissions.PermissionsPackage(), new expo.modules.permissions.PermissionsPackage(),
new expo.modules.screencapture.ScreenCapturePackage(),
new expo.modules.securestore.SecureStorePackage(), new expo.modules.securestore.SecureStorePackage(),
new expo.modules.splashscreen.SplashScreenPackage(), new expo.modules.splashscreen.SplashScreenPackage(),
new expo.modules.sqlite.SQLitePackage(), new expo.modules.sqlite.SQLitePackage(),

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 68 KiB

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- Below line is handled by '@expo/configure-splash-screen' command and it's discouraged to modify it manually --> <!-- Below line is handled by '@expo/configure-splash-screen' command and it's discouraged to modify it manually -->
<color name="splashscreen_background">#191919</color> <color name="splashscreen_background">#121212</color>
</resources> </resources>

View File

@ -30,10 +30,6 @@ export default (): ExpoConfig => ({
} }
] ]
}, },
locales: {
en: './src/i18n/en/system.json',
zh: './src/i18n/zh-Hans/system.json'
},
android: { android: {
versionCode: 4, versionCode: 4,
package: 'com.xmflsct.app.tooot', package: 'com.xmflsct.app.tooot',

View File

@ -450,8 +450,6 @@ PODS:
- RNSentry (2.1.1): - RNSentry (2.1.1):
- React-Core - React-Core
- Sentry (= 6.0.9) - Sentry (= 6.0.9)
- RNSharedElement (0.7.0):
- React
- RNSVG (12.1.0): - RNSVG (12.1.0):
- React - React
- SDWebImage (5.10.3): - SDWebImage (5.10.3):
@ -551,7 +549,6 @@ DEPENDENCIES:
- RNReanimated (from `../node_modules/react-native-reanimated`) - RNReanimated (from `../node_modules/react-native-reanimated`)
- RNScreens (from `../node_modules/react-native-screens`) - RNScreens (from `../node_modules/react-native-screens`)
- "RNSentry (from `../node_modules/@sentry/react-native`)" - "RNSentry (from `../node_modules/@sentry/react-native`)"
- RNSharedElement (from `../node_modules/react-native-shared-element`)
- RNSVG (from `../node_modules/react-native-svg`) - RNSVG (from `../node_modules/react-native-svg`)
- UMAppLoader (from `../node_modules/unimodules-app-loader/ios`) - UMAppLoader (from `../node_modules/unimodules-app-loader/ios`)
- UMBarCodeScannerInterface (from `../node_modules/unimodules-barcode-scanner-interface/ios`) - UMBarCodeScannerInterface (from `../node_modules/unimodules-barcode-scanner-interface/ios`)
@ -721,8 +718,6 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-screens" :path: "../node_modules/react-native-screens"
RNSentry: RNSentry:
:path: "../node_modules/@sentry/react-native" :path: "../node_modules/@sentry/react-native"
RNSharedElement:
:path: "../node_modules/react-native-shared-element"
RNSVG: RNSVG:
:path: "../node_modules/react-native-svg" :path: "../node_modules/react-native-svg"
UMAppLoader: UMAppLoader:
@ -835,7 +830,6 @@ SPEC CHECKSUMS:
RNReanimated: e8a1520b15df106c96214161078c69e4a23b8b29 RNReanimated: e8a1520b15df106c96214161078c69e4a23b8b29
RNScreens: b6c9607e6fe47c1b6e2f1910d2acd46dd7ecea3a RNScreens: b6c9607e6fe47c1b6e2f1910d2acd46dd7ecea3a
RNSentry: 6b46b6fc1d715a378fbaa5d7d43bc9ce99b500e5 RNSentry: 6b46b6fc1d715a378fbaa5d7d43bc9ce99b500e5
RNSharedElement: 00b1a1420d213a34459bb9a5aacabb38107d7948
RNSVG: ce9d996113475209013317e48b05c21ee988d42e RNSVG: ce9d996113475209013317e48b05c21ee988d42e
SDWebImage: e378178472b735e84b007bfb55514c97948a0598 SDWebImage: e378178472b735e84b007bfb55514c97948a0598
SDWebImageWebPCoder: d0dac55073088d24b2ac1b191a71a8f8d0adac21 SDWebImageWebPCoder: d0dac55073088d24b2ac1b191a71a8f8d0adac21

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 68 KiB

View File

@ -23,9 +23,9 @@
"color-space" : "srgb", "color-space" : "srgb",
"components" : { "components" : {
"alpha" : "1.000", "alpha" : "1.000",
"blue" : "25", "blue" : "18",
"green" : "25", "green" : "18",
"red" : "25" "red" : "18"
} }
}, },
"idiom" : "universal" "idiom" : "universal"

View File

@ -43,6 +43,7 @@
"expo-video-thumbnails": "~4.4.0", "expo-video-thumbnails": "~4.4.0",
"expo-web-browser": "~8.6.0", "expo-web-browser": "~8.6.0",
"i18next": "^19.8.5", "i18next": "^19.8.5",
"li": "^1.3.0",
"lodash": "^4.17.20", "lodash": "^4.17.20",
"react": "16.13.1", "react": "16.13.1",
"react-dom": "16.13.1", "react-dom": "16.13.1",
@ -108,8 +109,8 @@
"versions": { "versions": {
"native": "210201", "native": "210201",
"major": 0, "major": 0,
"minor": 3, "minor": 4,
"patch": 1, "patch": 0,
"expo": "40.0.0" "expo": "40.0.0"
} }
} }

9
src/@types/app.d.ts vendored
View File

@ -15,10 +15,9 @@ declare namespace App {
| 'Favourites' | 'Favourites'
interface IImageInfo { interface IImageInfo {
url: string uri: string
width?: number width: number
height?: number height: number
originUrl?: string type?: 'image' | 'video'
props?: any
} }
} }

View File

@ -1,4 +1,5 @@
declare module 'gl-react-blurhash' declare module 'gl-react-blurhash'
declare module 'li'
declare module 'react-native-feather' declare module 'react-native-feather'
declare module 'react-native-htmlview' declare module 'react-native-htmlview'
declare module 'react-native-toast-message' declare module 'react-native-toast-message'

View File

@ -90,7 +90,7 @@ const Screens: React.FC<Props> = ({ localCorrupt }) => {
url: `announcements` url: `announcements`
}) })
.then(res => { .then(res => {
if (res?.filter(announcement => !announcement.read).length) { if (res.body.filter(announcement => !announcement.read).length) {
navigationRef.current?.navigate('Screen-Announcements', { navigationRef.current?.navigate('Screen-Announcements', {
showAll: false showAll: false
}) })

View File

@ -1,6 +1,7 @@
import { RootState } from '@root/store' import { RootState } from '@root/store'
import axios from 'axios' import axios from 'axios'
import chalk from 'chalk' import chalk from 'chalk'
import li from 'li'
const ctx = new chalk.Instance({ level: 3 }) const ctx = new chalk.Instance({ level: 3 })
@ -28,7 +29,7 @@ const client = async <T = unknown>({
headers?: { [key: string]: string } headers?: { [key: string]: string }
body?: FormData body?: FormData
onUploadProgress?: (progressEvent: any) => void onUploadProgress?: (progressEvent: any) => void
}): Promise<T> => { }): Promise<{ body: T; links: { prev?: string; next?: string } }> => {
const { store } = require('@root/store') const { store } = require('@root/store')
const state = (store.getState() as RootState).instances const state = (store.getState() as RootState).instances
const theLocalIndex = const theLocalIndex =
@ -78,7 +79,19 @@ const client = async <T = unknown>({
...(body && { data: body }), ...(body && { data: body }),
...(onUploadProgress && { onUploadProgress: onUploadProgress }) ...(onUploadProgress && { onUploadProgress: onUploadProgress })
}) })
.then(response => Promise.resolve(response.data)) .then(response => {
let prev
let next
if (response.headers.link) {
const headersLinks = li.parse(response.headers.link)
prev = headersLinks.prev?.match(/_id=([0-9]*)/)[1]
next = headersLinks.next?.match(/_id=([0-9]*)/)[1]
}
return Promise.resolve({
body: response.data,
links: { prev, next }
})
})
.catch(error => { .catch(error => {
if (error.response) { if (error.response) {
// The request was made and the server responded with a status code // The request was made and the server responded with a status code
@ -97,8 +110,13 @@ const client = async <T = unknown>({
console.error(ctx.bold(' API '), ctx.bold('request'), error) console.error(ctx.bold(' API '), ctx.bold('request'), error)
return Promise.reject() return Promise.reject()
} else { } else {
console.error(ctx.bold(' API '), ctx.bold('other'), error.message) console.error(
return Promise.reject({ body: error.message }) ctx.bold(' API '),
ctx.bold('internal'),
error.message,
url
)
return Promise.reject()
} }
}) })
} }

View File

@ -4,7 +4,7 @@ import { QueryKeyTimeline, useTimelineQuery } from '@utils/queryHooks/timeline'
import { getLocalActiveIndex } from '@utils/slices/instancesSlice' import { getLocalActiveIndex } from '@utils/slices/instancesSlice'
import { StyleConstants } from '@utils/styles/constants' import { StyleConstants } from '@utils/styles/constants'
import { findIndex } from 'lodash' import { findIndex } from 'lodash'
import React, { useCallback, useEffect, useMemo, useRef } from 'react' import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { FlatListProps, StyleSheet } from 'react-native' import { FlatListProps, StyleSheet } from 'react-native'
import { FlatList } from 'react-native-gesture-handler' import { FlatList } from 'react-native-gesture-handler'
import Animated, { import Animated, {
@ -14,6 +14,7 @@ import Animated, {
} from 'react-native-reanimated' } from 'react-native-reanimated'
import { InfiniteData, useQueryClient } from 'react-query' import { InfiniteData, useQueryClient } from 'react-query'
import { useSelector } from 'react-redux' import { useSelector } from 'react-redux'
import haptics from './haptics'
import TimelineConversation from './Timeline/Conversation' import TimelineConversation from './Timeline/Conversation'
import TimelineDefault from './Timeline/Default' import TimelineDefault from './Timeline/Default'
import TimelineEmpty from './Timeline/Empty' import TimelineEmpty from './Timeline/Empty'
@ -68,30 +69,18 @@ const Timeline: React.FC<Props> = ({
} = useTimelineQuery({ } = useTimelineQuery({
...queryKeyParams, ...queryKeyParams,
options: { options: {
getPreviousPageParam: firstPage => { getPreviousPageParam: firstPage =>
return Array.isArray(firstPage) && firstPage.length firstPage.links?.prev && {
? { min_id: firstPage.links.prev,
direction: 'prev', // https://github.com/facebook/react-native/issues/25239#issuecomment-731100372
id: firstPage[0].last_status limit: '3'
? firstPage[0].last_status.id },
: firstPage[0].id getNextPageParam: lastPage =>
} lastPage.links?.next && { max_id: lastPage.links.next }
: undefined
},
getNextPageParam: lastPage => {
return Array.isArray(lastPage) && lastPage.length
? {
direction: 'next',
id: lastPage[lastPage.length - 1].last_status
? lastPage[lastPage.length - 1].last_status.id
: lastPage[lastPage.length - 1].id
}
: undefined
}
} }
}) })
const flattenData = data?.pages ? data.pages.flatMap(d => [...d]) : [] const flattenData = data?.pages ? data.pages.flatMap(d => [...d.body]) : []
const flRef = useRef<FlatList<any>>(null) const flRef = useRef<FlatList<any>>(null)
const scrolled = useRef(false) const scrolled = useRef(false)
@ -109,22 +98,30 @@ const Timeline: React.FC<Props> = ({
}, [isSuccess, flattenData.length, scrolled]) }, [isSuccess, flattenData.length, scrolled])
const keyExtractor = useCallback(({ id }) => id, []) const keyExtractor = useCallback(({ id }) => id, [])
const renderItem = useCallback(({ item }) => { const renderItem = useCallback(
switch (page) { ({ item }) => {
case 'Conversations': switch (page) {
return <TimelineConversation conversation={item} queryKey={queryKey} /> case 'Conversations':
case 'Notifications': return (
return <TimelineNotifications notification={item} queryKey={queryKey} /> <TimelineConversation conversation={item} queryKey={queryKey} />
default: )
return ( case 'Notifications':
<TimelineDefault return (
item={item} <TimelineNotifications notification={item} queryKey={queryKey} />
queryKey={queryKey} )
{...(toot === item.id && { highlighted: true })} default:
/> return (
) <TimelineDefault
} item={item}
}, []) queryKey={queryKey}
{...(toot === item.id && { highlighted: true })}
{...(data?.pages[0].pinned && { pinned: data?.pages[0].pinned })}
/>
)
}
},
[data?.pages[0]]
)
const ItemSeparatorComponent = useCallback( const ItemSeparatorComponent = useCallback(
({ leadingItem }) => ( ({ leadingItem }) => (
<ComponentSeparator <ComponentSeparator
@ -146,22 +143,6 @@ const Timeline: React.FC<Props> = ({
() => !disableInfinity && !isFetchingNextPage && fetchNextPage(), () => !disableInfinity && !isFetchingNextPage && fetchNextPage(),
[isFetchingNextPage] [isFetchingNextPage]
) )
const prevId = useSharedValue(null)
const headerPadding = useAnimatedStyle(() => {
if (hasPreviousPage) {
if (isFetchingPreviousPage) {
return { paddingTop: withTiming(StyleConstants.Spacing.XL) }
} else {
return { paddingTop: withTiming(0) }
}
} else {
return { paddingTop: withTiming(0) }
}
}, [hasPreviousPage, isFetchingPreviousPage])
const ListHeaderComponent = useMemo(
() => <Animated.View style={headerPadding} />,
[]
)
const ListFooterComponent = useMemo( const ListFooterComponent = useMemo(
() => <TimelineEnd hasNextPage={!disableInfinity ? hasNextPage : false} />, () => <TimelineEnd hasNextPage={!disableInfinity ? hasNextPage : false} />,
[hasNextPage] [hasNextPage]
@ -180,38 +161,60 @@ const Timeline: React.FC<Props> = ({
useScrollToTop(flRef) useScrollToTop(flRef)
const queryClient = useQueryClient() const queryClient = useQueryClient()
const scrollY = useSharedValue(0) const scrollY = useSharedValue(0)
const onScroll = useCallback( const [isFetchingLatest, setIsFetchingLatest] = useState(false)
({ nativeEvent }) => (scrollY.value = nativeEvent.contentOffset.y), useEffect(() => {
[] // https://github.com/facebook/react-native/issues/25239#issuecomment-731100372
) if (isFetchingLatest) {
if (!isFetchingPreviousPage) {
fetchPreviousPage()
} else {
if (data?.pages[0].body.length === 0) {
setIsFetchingLatest(false)
queryClient.setQueryData<InfiniteData<any> | undefined>(
queryKey,
data => {
if (data?.pages[0].body.length === 0) {
return {
pages: data.pages.slice(1),
pageParams: data.pageParams.slice(1)
}
} else {
return data
}
}
)
}
}
}
}, [isFetchingPreviousPage, isFetchingLatest, data?.pages[0].body])
const onScroll = useCallback(({ nativeEvent }) => {
scrollY.value = nativeEvent.contentOffset.y
}, [])
const onResponderRelease = useCallback(() => { const onResponderRelease = useCallback(() => {
if ( if (
scrollY.value <= -StyleConstants.Spacing.XL && scrollY.value <= -StyleConstants.Spacing.XL &&
!isFetchingPreviousPage && !isFetchingLatest &&
!disableRefresh !disableRefresh
) { ) {
queryClient.setQueryData<InfiniteData<any> | undefined>( haptics('Light')
queryKey, setIsFetchingLatest(true)
data => { flRef.current?.scrollToOffset({
if (data?.pages[0].length === 0) { animated: true,
if (data.pages[1]) { offset: 1
prevId.value = data.pages[1][0].id })
}
return {
pages: data.pages.slice(1),
pageParams: data.pageParams.slice(1)
}
} else {
prevId.value = data?.pages[0][0].id
return data
}
}
)
// https://github.com/facebook/react-native/issues/25239#issuecomment-731100372
fetchPreviousPage()
flRef.current?.scrollToOffset({ animated: true, offset: 1 })
} }
}, [scrollY.value, isFetchingPreviousPage, disableRefresh]) }, [scrollY.value, isFetchingLatest, disableRefresh])
const headerPadding = useAnimatedStyle(() => {
if (isFetchingLatest) {
return { paddingTop: withTiming(StyleConstants.Spacing.XL) }
} else {
return { paddingTop: withTiming(0) }
}
}, [isFetchingLatest])
const ListHeaderComponent = useMemo(
() => <Animated.View style={headerPadding} />,
[]
)
return ( return (
<> <>

View File

@ -24,6 +24,7 @@ export interface Props {
highlighted?: boolean highlighted?: boolean
disableDetails?: boolean disableDetails?: boolean
disableOnPress?: boolean disableOnPress?: boolean
pinned: Mastodon.Status['id'][]
} }
// When the poll is long // When the poll is long
@ -33,7 +34,8 @@ const TimelineDefault: React.FC<Props> = ({
origin, origin,
highlighted = false, highlighted = false,
disableDetails = false, disableDetails = false,
disableOnPress = false disableOnPress = false,
pinned
}) => { }) => {
const { theme } = useTheme() const { theme } = useTheme()
const localAccount = useSelector( const localAccount = useSelector(
@ -73,7 +75,7 @@ const TimelineDefault: React.FC<Props> = ({
> >
{item.reblog ? ( {item.reblog ? (
<TimelineActioned action='reblog' account={item.account} /> <TimelineActioned action='reblog' account={item.account} />
) : item.isPinned ? ( ) : pinned && pinned.includes(item.id) ? (
<TimelineActioned action='pinned' account={item.account} /> <TimelineActioned action='pinned' account={item.account} />
) : null} ) : null}
@ -113,9 +115,11 @@ const TimelineDefault: React.FC<Props> = ({
sameAccount={actualStatus.account.id === localAccount?.id} sameAccount={actualStatus.account.id === localAccount?.id}
/> />
) : null} ) : null}
{!disableDetails && actualStatus.media_attachments.length > 0 && ( {!disableDetails &&
Array.isArray(actualStatus.media_attachments) &&
actualStatus.media_attachments.length ? (
<TimelineAttachment status={actualStatus} /> <TimelineAttachment status={actualStatus} />
)} ) : null}
{!disableDetails && actualStatus.card && ( {!disableDetails && actualStatus.card && (
<TimelineCard card={actualStatus.card} /> <TimelineCard card={actualStatus.card} />
)} )}

View File

@ -46,7 +46,7 @@ const TimelineHeaderNotification: React.FC<Props> = ({
onPress={() => onPress={() =>
navigation.navigate('Screen-Actions', { navigation.navigate('Screen-Actions', {
queryKey, queryKey,
status, status: notification.status,
url: notification.status?.url || notification.status?.uri, url: notification.status?.url || notification.status?.uri,
type: 'status' type: 'status'
}) })

View File

@ -1,4 +0,0 @@
{
"NSCameraUsageDescription": "Allow camera access to upload attachments",
"NSPhotoLibraryUsageDescription": "Allow photo library access to upload attachments"
}

View File

@ -1,4 +0,0 @@
{
"NSCameraUsageDescription": "允许tooot使用相机拍摄上传附件",
"NSPhotoLibraryUsageDescription": "允许tooot读取相册上传附件"
}

View File

@ -100,16 +100,17 @@ const ActionsStatus: React.FC<Props> = ({
} }
) )
dismiss() dismiss()
const res = (await mutation.mutateAsync({ const res = await mutation.mutateAsync({
type: 'deleteItem', type: 'deleteItem',
source: 'statuses', source: 'statuses',
queryKey, queryKey,
id: status.id id: status.id
})) as Mastodon.Status })
if (res.id) { if (res.body.id) {
// @ts-ignore
navigation.navigate('Screen-Compose', { navigation.navigate('Screen-Compose', {
type: 'edit', type: 'edit',
incomingStatus: res, incomingStatus: res.body,
queryKey queryKey
}) })
} }

View File

@ -64,7 +64,7 @@ const ComposeDraftsListRoot: React.FC<Props> = ({ timestamp }) => {
url: `media/${attachment.remote?.id}` url: `media/${attachment.remote?.id}`
}) })
.then(res => { .then(res => {
if (res.id === attachment.remote?.id) { if (res.body.id === attachment.remote?.id) {
tempUploads.push(attachment) tempUploads.push(attachment)
} }
}) })

View File

@ -3,15 +3,10 @@ import analytics from '@components/analytics'
import haptics from '@components/haptics' import haptics from '@components/haptics'
import { HeaderCenter, HeaderLeft, HeaderRight } from '@components/Header' import { HeaderCenter, HeaderLeft, HeaderRight } from '@components/Header'
import { StackScreenProps } from '@react-navigation/stack' import { StackScreenProps } from '@react-navigation/stack'
import React, { import React, { useCallback, useContext, useEffect, useState } from 'react'
useCallback,
useContext,
useEffect,
useRef,
useState
} from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { Alert, KeyboardAvoidingView, Platform } from 'react-native' import { Alert, KeyboardAvoidingView, Platform } from 'react-native'
import { useSharedValue } from 'react-native-reanimated'
import { SafeAreaView } from 'react-native-safe-area-context' import { SafeAreaView } from 'react-native-safe-area-context'
import { createNativeStackNavigator } from 'react-native-screens/native-stack' import { createNativeStackNavigator } from 'react-native-screens/native-stack'
import ComposeEditAttachmentRoot from './EditAttachment/Root' import ComposeEditAttachmentRoot from './EditAttachment/Root'
@ -39,34 +34,31 @@ const ComposeEditAttachment: React.FC<ScreenComposeEditAttachmentProp> = ({
const [altText, setAltText] = useState<string | undefined>( const [altText, setAltText] = useState<string | undefined>(
theAttachment.description theAttachment.description
) )
const focus = useRef({ x: 0, y: 0 }) const focus = useSharedValue({
x: theAttachment.meta.focus.x,
y: theAttachment.meta.focus.y
})
useEffect(() => { useEffect(() => {
const unsubscribe = navigation.addListener('beforeRemove', () => { const unsubscribe = navigation.addListener('beforeRemove', () => {
let needUpdate = false composeDispatch({
type: 'attachment/edit',
if (theAttachment.description !== altText) { payload: {
theAttachment.description = altText ...theAttachment,
needUpdate = true description: altText,
} meta: {
...theAttachment.meta,
if (theAttachment.type === 'image') { focus: {
if (focus.current.x !== 0 || focus.current.y !== 0) { x: focus.value.x > 1 ? 1 : focus.value.x,
theAttachment.meta && y: focus.value.y > 1 ? 1 : focus.value.y
(theAttachment.meta.focus = { }
x: focus.current.x > 1 ? 1 : focus.current.x, }
y: focus.current.y > 1 ? 1 : focus.current.y
})
needUpdate = true
} }
} })
if (needUpdate) {
composeDispatch({ type: 'attachment/edit', payload: theAttachment })
}
}) })
return unsubscribe return unsubscribe
}, [focus, altText]) }, [focus.value.x, focus.value.y, altText])
const headerLeft = useCallback( const headerLeft = useCallback(
() => ( () => (
@ -86,7 +78,7 @@ const ComposeEditAttachment: React.FC<ScreenComposeEditAttachmentProp> = ({
loading={isSubmitting} loading={isSubmitting}
onPress={() => { onPress={() => {
analytics('editattachment_confirm_press') analytics('editattachment_confirm_press')
if (!altText && focus.current.x === 0 && focus.current.y === 0) { if (!altText && focus.value.x === 0 && focus.value.y === 0) {
navigation.goBack() navigation.goBack()
return return
} }
@ -95,8 +87,8 @@ const ComposeEditAttachment: React.FC<ScreenComposeEditAttachmentProp> = ({
if (altText) { if (altText) {
formData.append('description', altText) formData.append('description', altText)
} }
if (focus.current.x !== 0 || focus.current.y !== 0) { if (focus.value.x !== 0 || focus.value.y !== 0) {
formData.append('focus', `${focus.current.x},${focus.current.y}`) formData.append('focus', `${focus.value.x},${focus.value.y}`)
} }
client<Mastodon.Attachment>({ client<Mastodon.Attachment>({
@ -129,7 +121,7 @@ const ComposeEditAttachment: React.FC<ScreenComposeEditAttachmentProp> = ({
/> />
), ),
[] [isSubmitting, altText, focus.value.x, focus.value.y]
) )
const children = useCallback( const children = useCallback(

View File

@ -1,6 +1,6 @@
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, { MutableRefObject, useContext } from 'react' import React, { useContext } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { Dimensions, StyleSheet, Text, View } from 'react-native' import { Dimensions, StyleSheet, Text, View } from 'react-native'
import FastImage from 'react-native-fast-image' import FastImage from 'react-native-fast-image'
@ -18,7 +18,7 @@ import ComposeContext from '../utils/createContext'
export interface Props { export interface Props {
index: number index: number
focus: MutableRefObject<{ focus: Animated.SharedValue<{
x: number x: number
y: number y: number
}> }>
@ -57,7 +57,7 @@ const ComposeEditAttachmentImage: React.FC<Props> = ({ index, focus }) => {
2 2
) )
const updateFocus = ({ x, y }: { x: number; y: number }) => { const updateFocus = ({ x, y }: { x: number; y: number }) => {
focus.current = { x, y } focus.value = { x, y }
} }
type PanContext = { type PanContext = {
startX: number startX: number
@ -110,7 +110,7 @@ const ComposeEditAttachmentImage: React.FC<Props> = ({ index, focus }) => {
return ( return (
<> <>
<View style={{ overflow: 'hidden', flex: 1, alignItems: 'center' }}> <View style={styles.base}>
<FastImage <FastImage
style={{ style={{
width: imageDimensionis.width, width: imageDimensionis.width,
@ -160,6 +160,7 @@ const ComposeEditAttachmentImage: React.FC<Props> = ({ index, focus }) => {
} }
const styles = StyleSheet.create({ const styles = StyleSheet.create({
base: { overflow: 'hidden', flex: 1, alignItems: 'center' },
imageFocusText: { imageFocusText: {
...StyleConstants.FontStyle.M, ...StyleConstants.FontStyle.M,
padding: StyleConstants.Spacing.Global.PagePadding padding: StyleConstants.Spacing.Global.PagePadding

View File

@ -1,21 +1,16 @@
import AttachmentVideo from '@components/Timeline/Shared/Attachment/Video' import AttachmentVideo from '@components/Timeline/Shared/Attachment/Video'
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, { import React, { Dispatch, SetStateAction, useContext, useMemo } from 'react'
Dispatch,
MutableRefObject,
SetStateAction,
useContext,
useMemo
} from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { ScrollView, StyleSheet, Text, TextInput, View } from 'react-native' import { ScrollView, StyleSheet, Text, TextInput, View } from 'react-native'
import Animated from 'react-native-reanimated'
import ComposeContext from '../utils/createContext' import ComposeContext from '../utils/createContext'
import ComposeEditAttachmentImage from './Image' import ComposeEditAttachmentImage from './Image'
export interface Props { export interface Props {
index: number index: number
focus: MutableRefObject<{ focus: Animated.SharedValue<{
x: number x: number
y: number y: number
}> }>

View File

@ -32,7 +32,6 @@ const ComposeAttachments: React.FC = () => {
const navigation = useNavigation() const navigation = useNavigation()
const flatListRef = useRef<FlatList>(null) const flatListRef = useRef<FlatList>(null)
let prevOffsets = useRef<number[]>()
const sensitiveOnPress = useCallback(() => { const sensitiveOnPress = useCallback(() => {
analytics('compose_attachment_sensitive_press', { analytics('compose_attachment_sensitive_press', {
@ -92,7 +91,7 @@ const ComposeAttachments: React.FC = () => {
] ]
: attachmentsOffsets : attachmentsOffsets
}, [composeState.attachments.uploads.length]) }, [composeState.attachments.uploads.length])
let prevOffsets = useRef<number[]>()
useEffect(() => { useEffect(() => {
if ( if (
snapToOffsets.length > snapToOffsets.length >
@ -105,7 +104,7 @@ const ComposeAttachments: React.FC = () => {
}) })
} }
prevOffsets.current = snapToOffsets prevOffsets.current = snapToOffsets
}, [snapToOffsets, prevOffsets]) }, [snapToOffsets, prevOffsets.current])
const renderAttachment = useCallback( const renderAttachment = useCallback(
({ item, index }: { item: ExtendedAttachment; index: number }) => { ({ item, index }: { item: ExtendedAttachment; index: number }) => {
@ -251,7 +250,7 @@ const ComposeAttachments: React.FC = () => {
showsHorizontalScrollIndicator={false} showsHorizontalScrollIndicator={false}
data={composeState.attachments.uploads} data={composeState.attachments.uploads}
keyExtractor={item => keyExtractor={item =>
item.local?.url || item.remote?.url || Math.random().toString() item.local?.uri || item.remote?.url || Math.random().toString()
} }
ListFooterComponent={ ListFooterComponent={
composeState.attachments.uploads.length < 4 ? listFooter : null composeState.attachments.uploads.length < 4 ? listFooter : null

View File

@ -22,7 +22,7 @@ const SingleEmoji = ({ emoji }: { emoji: Mastodon.Emoji }) => {
// type: 'emoji', // type: 'emoji',
// payload: { ...composeState.emoji, active: false } // payload: { ...composeState.emoji, active: false }
// }) // })
haptics('Success') haptics('Light')
}, [composeState]) }, [composeState])
const children = useMemo( const children = useMemo(
() => <FastImage source={{ uri: emoji.url }} style={styles.emoji} />, () => <FastImage source={{ uri: emoji.url }} style={styles.emoji} />,

View File

@ -113,10 +113,10 @@ const addAttachment = async ({
body: formData body: formData
}) })
.then(res => { .then(res => {
if (res.id) { if (res.body.id) {
composeDispatch({ composeDispatch({
type: 'attachment/upload/end', type: 'attachment/upload/end',
payload: { remote: res, local: result } payload: { remote: res.body, local: result }
}) })
} else { } else {
uploadFailed() uploadFailed()

View File

@ -70,7 +70,7 @@ const composeReducer = (
attachments: { attachments: {
...state.attachments, ...state.attachments,
uploads: state.attachments.uploads.filter( uploads: state.attachments.uploads.filter(
upload => upload.local.hash !== action.payload upload => upload.local?.hash !== action.payload
) )
} }
} }

View File

@ -28,6 +28,10 @@ const ScreenImagesViewer = ({
}, },
navigation navigation
}: ScreenImagesViewerProp) => { }: ScreenImagesViewerProp) => {
if (imageUrls.length === 0) {
return null
}
const [currentIndex, setCurrentIndex] = useState( const [currentIndex, setCurrentIndex] = useState(
findIndex(imageUrls, ['imageIndex', imageIndex]) findIndex(imageUrls, ['imageIndex', imageIndex])
) )

View File

@ -145,10 +145,11 @@ const ScreenTabs = React.memo(
options: { options: {
notifyOnChangeProps: [], notifyOnChangeProps: [],
select: data => { select: data => {
if (data.pages[0].length) { if (data.pages[0].body.length) {
dispatch( dispatch(
updateLocalNotification({ updateLocalNotification({
latestTime: data.pages[0][0].created_at // @ts-ignore
latestTime: data.pages[0].body[0].created_at
}) })
) )
} }

View File

@ -77,7 +77,9 @@ const SettingsTooot: React.FC = () => {
iconBack='ChevronRight' iconBack='ChevronRight'
onPress={() => { onPress={() => {
const foundAccounts = data?.accounts.filter( const foundAccounts = data?.accounts.filter(
account => account.acct === 'tooot@xmflsct.com' account =>
account.acct === 'tooot@xmflsct.com' ||
account.url === 'https://social.xmflsct.com/@tooot'
) )
if (foundAccounts?.length === 1) { if (foundAccounts?.length === 1) {
navigation.navigate('Screen-Compose', { navigation.navigate('Screen-Compose', {

View File

@ -41,6 +41,7 @@ const TabSharedAccount: React.FC<SharedAccountProp> = ({
analytics('bottomsheet_open_press', { analytics('bottomsheet_open_press', {
page: 'account' page: 'account'
}) })
// @ts-ignore
navigation.navigate('Screen-Actions', { navigation.navigate('Screen-Actions', {
type: 'account', type: 'account',
account account

View File

@ -39,7 +39,7 @@ const AccountAttachments = React.memo(
page: 'Account_Attachments' as 'Account_Attachments', page: 'Account_Attachments' as 'Account_Attachments',
account: account?.id account: account?.id
} }
const { data, refetch } = useTimelineQuery<Mastodon.Status[]>({ const { data, refetch } = useTimelineQuery({
...queryKeyParams, ...queryKeyParams,
options: { enabled: false } options: { enabled: false }
}) })
@ -51,8 +51,8 @@ const AccountAttachments = React.memo(
const flattenData = data?.pages const flattenData = data?.pages
? data.pages ? data.pages
.flatMap(d => [...d]) .flatMap(d => [...d.body])
.filter(status => !status.sensitive) .filter(status => !(status as Mastodon.Status).sensitive)
.splice(0, DISPLAY_AMOUNT) .splice(0, DISPLAY_AMOUNT)
: [] : []

View File

@ -26,17 +26,13 @@ const RelationshipsList: React.FC<Props> = ({ id, type }) => {
type, type,
id, id,
options: { options: {
getNextPageParam: lastPage => { getPreviousPageParam: firstPage =>
return lastPage.length firstPage.links?.prev && { since_id: firstPage.links.next },
? { getNextPageParam: lastPage =>
direction: 'next', lastPage.links?.next && { max_id: lastPage.links.next }
id: lastPage[lastPage.length - 1].id
}
: undefined
}
} }
}) })
const flattenData = data?.pages ? data.pages.flatMap(d => [...d]) : [] const flattenData = data?.pages ? data.pages.flatMap(d => [...d.body]) : []
const flRef = useRef<FlatList<Mastodon.Account>>(null) const flRef = useRef<FlatList<Mastodon.Account>>(null)

View File

@ -27,7 +27,7 @@ const netInfo = async (): Promise<{
.then(res => { .then(res => {
log('log', 'netInfo', 'local credential check passed') log('log', 'netInfo', 'local credential check passed')
if ( if (
res.id !== res.body.id !==
store.getState().instances.local?.instances[activeIndex].account.id store.getState().instances.local?.instances[activeIndex].account.id
) { ) {
log('error', 'netInfo', 'local id does not match remote id') log('error', 'netInfo', 'local id does not match remote id')
@ -36,8 +36,8 @@ const netInfo = async (): Promise<{
} else { } else {
store.dispatch( store.dispatch(
updateLocalAccount({ updateLocalAccount({
acct: res.acct, acct: res.body.acct,
avatarStatic: res.avatar_static avatarStatic: res.body.avatar_static
}) })
) )
return Promise.resolve({ connected: true }) return Promise.resolve({ connected: true })

View File

@ -11,7 +11,7 @@ const queryFunction = ({ queryKey }: { queryKey: QueryKey }) => {
method: 'get', method: 'get',
instance: 'local', instance: 'local',
url: `accounts/${id}` url: `accounts/${id}`
}) }).then(res => res.body)
} }
const useAccountQuery = <TData = Mastodon.Account>({ const useAccountQuery = <TData = Mastodon.Account>({

View File

@ -19,7 +19,7 @@ const queryFunction = async ({ queryKey }: { queryKey: QueryKey }) => {
instance: 'local', instance: 'local',
localIndex: index, localIndex: index,
url: `accounts/${id}` url: `accounts/${id}`
}) }).then(res => res.body)
} }
const useAccountCheckQuery = <TData = Mastodon.Account>({ const useAccountCheckQuery = <TData = Mastodon.Account>({

View File

@ -21,7 +21,7 @@ const queryFunction = ({ queryKey }: { queryKey: QueryKeyAnnouncement }) => {
with_dismissed: 'true' with_dismissed: 'true'
} }
}) })
}) }).then(res => res.body)
} }
const useAnnouncementQuery = <TData = Mastodon.Announcement[]>({ const useAnnouncementQuery = <TData = Mastodon.Announcement[]>({

View File

@ -25,7 +25,7 @@ const queryFunction = ({ queryKey }: { queryKey: QueryKey }) => {
instanceDomain, instanceDomain,
url: `apps`, url: `apps`,
body: formData body: formData
}) }).then(res => res.body)
} }
const useAppsQuery = <TData = Mastodon.Apps>({ const useAppsQuery = <TData = Mastodon.Apps>({

View File

@ -9,7 +9,7 @@ const queryFunction = () => {
method: 'get', method: 'get',
instance: 'local', instance: 'local',
url: 'custom_emojis' url: 'custom_emojis'
}) }).then(res => res.body)
} }
const useEmojisQuery = <TData = Mastodon.Emoji[]>({ const useEmojisQuery = <TData = Mastodon.Emoji[]>({

View File

@ -12,7 +12,7 @@ const queryFunction = ({ queryKey }: { queryKey: QueryKey }) => {
instance: 'remote', instance: 'remote',
instanceDomain, instanceDomain,
url: `instance` url: `instance`
}) }).then(res => res.body)
} }
const useInstanceQuery = < const useInstanceQuery = <

View File

@ -9,7 +9,7 @@ const queryFunction = () => {
method: 'get', method: 'get',
instance: 'local', instance: 'local',
url: 'lists' url: 'lists'
}) }).then(res => res.body)
} }
const useListsQuery = <TData = Mastodon.List[]>({ const useListsQuery = <TData = Mastodon.List[]>({

View File

@ -22,7 +22,7 @@ const queryFunction = ({ queryKey }: { queryKey: QueryKeyRelationship }) => {
params: { params: {
'id[]': id 'id[]': id
} }
}) }).then(res => res.body)
} }
const useRelationshipQuery = ({ const useRelationshipQuery = ({
@ -61,7 +61,7 @@ const mutationFunction = async (params: MutationVarsRelationship) => {
method: 'post', method: 'post',
instance: 'local', instance: 'local',
url: `follow_requests/${params.id}/${params.payload.action}` url: `follow_requests/${params.id}/${params.payload.action}`
}) }).then(res => res.body)
case 'outgoing': case 'outgoing':
return client<Mastodon.Relationship>({ return client<Mastodon.Relationship>({
method: 'post', method: 'post',
@ -69,7 +69,7 @@ const mutationFunction = async (params: MutationVarsRelationship) => {
url: `accounts/${params.id}/${params.payload.state ? 'un' : ''}${ url: `accounts/${params.id}/${params.payload.state ? 'un' : ''}${
params.payload.action params.payload.action
}` }`
}) }).then(res => res.body)
} }
} }

View File

@ -12,18 +12,10 @@ const queryFunction = ({
pageParam pageParam
}: { }: {
queryKey: QueryKey queryKey: QueryKey
pageParam?: { direction: 'next'; id: Mastodon.Status['id'] } pageParam?: { [key: string]: string }
}) => { }) => {
const { type, id } = queryKey[1] const { type, id } = queryKey[1]
let params: { [key: string]: string } = {} let params: { [key: string]: string } = { ...pageParam }
if (pageParam) {
switch (pageParam.direction) {
case 'next':
params.max_id = pageParam.id
break
}
}
return client<Mastodon.Account[]>({ return client<Mastodon.Account[]>({
method: 'get', method: 'get',
@ -37,7 +29,14 @@ const useRelationshipsQuery = <TData = Mastodon.Account[]>({
options, options,
...queryKeyParams ...queryKeyParams
}: QueryKey[1] & { }: QueryKey[1] & {
options?: UseInfiniteQueryOptions<Mastodon.Account[], AxiosError, TData> options?: UseInfiniteQueryOptions<
{
body: Mastodon.Account[]
links?: { prev?: string; next?: string }
},
AxiosError,
TData
>
}) => { }) => {
const queryKey: QueryKey = ['Relationships', { ...queryKeyParams }] const queryKey: QueryKey = ['Relationships', { ...queryKeyParams }]
return useInfiniteQuery(queryKey, queryFunction, options) return useInfiniteQuery(queryKey, queryFunction, options)

View File

@ -25,7 +25,7 @@ const queryFunction = ({ queryKey }: { queryKey: QueryKey }) => {
instance: 'local', instance: 'local',
url: 'search', url: 'search',
params: { ...(type && { type }), ...(term && { q: term }), limit } params: { ...(type && { type }), ...(term && { q: term }), limit }
}) }).then(res => res.body)
} }
const useSearchQuery = <TData = SearchResult>({ const useSearchQuery = <TData = SearchResult>({

View File

@ -28,29 +28,10 @@ const queryFunction = ({
pageParam pageParam
}: { }: {
queryKey: QueryKeyTimeline queryKey: QueryKeyTimeline
pageParam?: { direction: 'prev' | 'next'; id: Mastodon.Status['id'] } pageParam?: { [key: string]: string }
}) => { }) => {
const { page, account, hashtag, list, toot } = queryKey[1] const { page, account, hashtag, list, toot } = queryKey[1]
let params: { [key: string]: string } = {} let params: { [key: string]: string } = { ...pageParam }
if (pageParam) {
switch (pageParam.direction) {
case 'prev':
if (page === 'Bookmarks' || page === 'Favourites') {
params.max_id = pageParam.id
} else {
params.min_id = pageParam.id
}
break
case 'next':
if (page === 'Bookmarks' || page === 'Favourites') {
params.min_id = pageParam.id
} else {
params.max_id = pageParam.id
}
break
}
}
switch (page) { switch (page) {
case 'Following': case 'Following':
@ -89,7 +70,7 @@ const queryFunction = ({
}) })
case 'Account_Default': case 'Account_Default':
if (pageParam && pageParam.direction === 'next') { if (pageParam && pageParam.pointer === 'max_id') {
return client<Mastodon.Status[]>({ return client<Mastodon.Status[]>({
method: 'get', method: 'get',
instance: 'local', instance: 'local',
@ -108,10 +89,8 @@ const queryFunction = ({
pinned: 'true' pinned: 'true'
} }
}).then(async res1 => { }).then(async res1 => {
let toots = res1.map(status => { let pinned: Mastodon.Status['id'][] = []
status.isPinned = true res1.body.forEach(status => pinned.push(status.id))
return status
})
const res2 = await client<Mastodon.Status[]>({ const res2 = await client<Mastodon.Status[]>({
method: 'get', method: 'get',
instance: 'local', instance: 'local',
@ -120,7 +99,11 @@ const queryFunction = ({
exclude_replies: 'true' exclude_replies: 'true'
} }
}) })
return uniqBy([...toots, ...res2], 'id') return {
body: uniqBy([...res1.body, ...res2.body], 'id'),
...(res2.links.next && { links: { max_id: res2.links.next } }),
pinned
}
}) })
} }
@ -197,7 +180,9 @@ const queryFunction = ({
instance: 'local', instance: 'local',
url: `statuses/${toot}/context` url: `statuses/${toot}/context`
}) })
return [...res2.ancestors, res1, ...res2.descendants] return {
body: [...res2.body.ancestors, res1.body, ...res2.body.descendants]
}
}) })
default: default:
return Promise.reject() return Promise.reject()
@ -210,7 +195,18 @@ const useTimelineQuery = <TData = TimelineData>({
options, options,
...queryKeyParams ...queryKeyParams
}: QueryKeyTimeline[1] & { }: QueryKeyTimeline[1] & {
options?: UseInfiniteQueryOptions<any, AxiosError, TData> options?: UseInfiniteQueryOptions<
{
body:
| Mastodon.Status[]
| Mastodon.Notification[]
| Mastodon.Conversation[]
links?: { prev?: string; next?: string }
pinned?: Mastodon.Status['id'][]
},
AxiosError,
TData
>
}) => { }) => {
const queryKey: QueryKeyTimeline = ['Timeline', { ...queryKeyParams }] const queryKey: QueryKeyTimeline = ['Timeline', { ...queryKeyParams }]
return useInfiniteQuery(queryKey, queryFunction, options) return useInfiniteQuery(queryKey, queryFunction, options)
@ -354,7 +350,7 @@ const mutationFunction = async (params: MutationVarsTimeline) => {
} }
type MutationOptionsTimeline = MutationOptions< type MutationOptionsTimeline = MutationOptions<
Mastodon.Conversation | Mastodon.Notification | Mastodon.Status, { body: Mastodon.Conversation | Mastodon.Notification | Mastodon.Status },
AxiosError, AxiosError,
MutationVarsTimeline MutationVarsTimeline
> >
@ -373,7 +369,7 @@ const useTimelineMutation = ({
onSuccess?: MutationOptionsTimeline['onSuccess'] | boolean onSuccess?: MutationOptionsTimeline['onSuccess'] | boolean
}) => { }) => {
return useMutation< return useMutation<
Mastodon.Conversation | Mastodon.Notification | Mastodon.Status, { body: Mastodon.Conversation | Mastodon.Notification | Mastodon.Status },
AxiosError, AxiosError,
MutationVarsTimeline MutationVarsTimeline
>(mutationFunction, { >(mutationFunction, {

View File

@ -1,5 +1,5 @@
import { InfiniteData, QueryClient } from 'react-query' import { InfiniteData, QueryClient } from 'react-query'
import { QueryKeyTimeline } from '../timeline' import { QueryKeyTimeline, TimelineData } from '../timeline'
const deleteItem = ({ const deleteItem = ({
queryClient, queryClient,
@ -10,16 +10,15 @@ const deleteItem = ({
queryKey: QueryKeyTimeline queryKey: QueryKeyTimeline
id: Mastodon.Status['id'] id: Mastodon.Status['id']
}) => { }) => {
queryClient.setQueryData<InfiniteData<Mastodon.Conversation[]> | undefined>( queryClient.setQueryData<InfiniteData<any> | undefined>(queryKey, old => {
queryKey, if (old) {
old => { old.pages = old.pages.map(page => {
if (old) { page.body = page.body.filter((item: Mastodon.Status) => item.id !== id)
old.pages = old.pages.map(page => page.filter(item => item.id !== id)) return page
} })
return old return old
} }
) })
} }
export default deleteItem export default deleteItem

View File

@ -32,9 +32,10 @@ const updateStatusProperty = ({
return page return page
} else { } else {
if ( if (
typeof (page as Mastodon.Conversation[])[0].unread === 'boolean' typeof (page.body as Mastodon.Conversation[])[0].unread ===
'boolean'
) { ) {
const items = page as Mastodon.Conversation[] const items = page.body as Mastodon.Conversation[]
const tootIndex = findIndex(items, ['last_status.id', id]) const tootIndex = findIndex(items, ['last_status.id', id])
if (tootIndex >= 0) { if (tootIndex >= 0) {
foundToot = true foundToot = true
@ -42,16 +43,16 @@ const updateStatusProperty = ({
} }
return page return page
} else if ( } else if (
typeof (page as Mastodon.Notification[])[0].type === 'string' typeof (page.body as Mastodon.Notification[])[0].type === 'string'
) { ) {
const items = page as Mastodon.Notification[] const items = page.body as Mastodon.Notification[]
const tootIndex = findIndex(items, ['status.id', id]) const tootIndex = findIndex(items, ['status.id', id])
if (tootIndex >= 0) { if (tootIndex >= 0) {
foundToot = true foundToot = true
updateNotification({ item: items[tootIndex], payload }) updateNotification({ item: items[tootIndex], payload })
} }
} else { } else {
const items = page as Mastodon.Status[] const items = page.body as Mastodon.Status[]
const tootIndex = findIndex(items, [ const tootIndex = findIndex(items, [
reblog ? 'reblog.id' : 'id', reblog ? 'reblog.id' : 'id',
id id

View File

@ -44,13 +44,13 @@ export type InstancesState = {
export const updateLocalAccountPreferences = createAsyncThunk( export const updateLocalAccountPreferences = createAsyncThunk(
'instances/updateLocalAccountPreferences', 'instances/updateLocalAccountPreferences',
async (): Promise<Mastodon.Preferences> => { async (): Promise<Mastodon.Preferences> => {
const preferences = await client<Mastodon.Preferences>({ const res = await client<Mastodon.Preferences>({
method: 'get', method: 'get',
instance: 'local', instance: 'local',
url: `preferences` url: `preferences`
}) })
return Promise.resolve(preferences) return Promise.resolve(res.body)
} }
) )
@ -73,7 +73,9 @@ export const localAddInstance = createAsyncThunk(
const instanceLocal: InstancesState['local'] = store.getState().instances const instanceLocal: InstancesState['local'] = store.getState().instances
.local .local
const { id, acct, avatar_static } = await client<Mastodon.Account>({ const {
body: { id, acct, avatar_static }
} = await client<Mastodon.Account>({
method: 'get', method: 'get',
instance: 'remote', instance: 'remote',
instanceDomain: url, instanceDomain: url,
@ -100,7 +102,7 @@ export const localAddInstance = createAsyncThunk(
type = 'add' type = 'add'
} }
const preferences = await client<Mastodon.Preferences>({ const { body: preferences } = await client<Mastodon.Preferences>({
method: 'get', method: 'get',
instance: 'remote', instance: 'remote',
instanceDomain: url, instanceDomain: url,

View File

@ -48,15 +48,15 @@ const themeColors: {
background: { background: {
light: 'rgb(250, 250, 250)', light: 'rgb(250, 250, 250)',
dark: 'rgb(25, 25, 25)' dark: 'rgb(18, 18, 18)'
}, },
backgroundGradientStart: { backgroundGradientStart: {
light: 'rgba(250, 250, 250, 0.5)', light: 'rgba(250, 250, 250, 0.5)',
dark: 'rgba(25, 25, 25, 0.5)' dark: 'rgba(18, 18, 18, 0.5)'
}, },
backgroundGradientEnd: { backgroundGradientEnd: {
light: 'rgba(250, 250, 250, 1)', light: 'rgba(250, 250, 250, 1)',
dark: 'rgba(25, 25, 25, 1)' dark: 'rgba(18, 18, 18, 1)'
}, },
backgroundOverlay: { backgroundOverlay: {
light: 'rgba(25, 25, 25, 0.5)', light: 'rgba(25, 25, 25, 0.5)',

View File

@ -6968,6 +6968,11 @@ levn@~0.3.0:
prelude-ls "~1.1.2" prelude-ls "~1.1.2"
type-check "~0.3.2" type-check "~0.3.2"
li@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/li/-/li-1.3.0.tgz#22c59bcaefaa9a8ef359cf759784e4bf106aea1b"
integrity sha1-IsWbyu+qmo7zWc91l4TkvxBq6hs=
lie@3.1.1: lie@3.1.1:
version "3.1.1" version "3.1.1"
resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e" resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e"