diff --git a/src/components/ParseContent.tsx b/src/components/ParseContent.tsx index b98bb2ed..abceea38 100644 --- a/src/components/ParseContent.tsx +++ b/src/components/ParseContent.tsx @@ -74,7 +74,7 @@ const renderNode = ({ ) } } else { - const domain = href.split(new RegExp(/:\/\/(.*?)\//)) + const domain = href.split(new RegExp(/:\/\/(.[^\/]+)/)) return ( = ({ @@ -28,8 +27,7 @@ const Timeline: React.FC = ({ list, toot, account, - disableRefresh = false, - scrollEnabled = true + disableRefresh = false }) => { setFocusHandler(handleFocus => { const handleAppStateChange = (appState: string) => { @@ -160,7 +158,6 @@ const Timeline: React.FC = ({ renderItem={flRenderItem} onEndReached={flOnEndReach} keyExtractor={flKeyExtrator} - scrollEnabled={scrollEnabled} // For timeline in Account view ListFooterComponent={flFooter} ListEmptyComponent={flItemEmptyComponent} ItemSeparatorComponent={flItemSeparatorComponent} diff --git a/src/components/Timelines/Timeline/Default.tsx b/src/components/Timelines/Timeline/Default.tsx index 69101365..64f156ee 100644 --- a/src/components/Timelines/Timeline/Default.tsx +++ b/src/components/Timelines/Timeline/Default.tsx @@ -44,7 +44,7 @@ const TimelineDefault: React.FC = ({ const tootOnPress = useCallback( () => !isRemotePublic && - navigation.navigate('Screen-Shared-Toot', { + navigation.push('Screen-Shared-Toot', { toot: actualStatus }), [] diff --git a/src/components/Timelines/Timeline/Shared/Avatar.tsx b/src/components/Timelines/Timeline/Shared/Avatar.tsx index 5a2ad366..b45aea70 100644 --- a/src/components/Timelines/Timeline/Shared/Avatar.tsx +++ b/src/components/Timelines/Timeline/Shared/Avatar.tsx @@ -1,7 +1,7 @@ import React, { useCallback } from 'react' import { Image, Pressable, StyleSheet } from 'react-native' -import { useNavigation } from '@react-navigation/native' import { StyleConstants } from '@utils/styles/constants' +import { useNavigation } from '@react-navigation/native' export interface Props { queryKey?: App.QueryKey @@ -13,7 +13,7 @@ const TimelineAvatar: React.FC = ({ queryKey, account }) => { // Need to fix go back root const onPress = useCallback(() => { queryKey && - navigation.navigate('Screen-Shared-Account', { + navigation.push('Screen-Shared-Account', { id: account.id }) }, []) diff --git a/src/screens/Me/Root.tsx b/src/screens/Me/Root.tsx index 2eab2080..67293811 100644 --- a/src/screens/Me/Root.tsx +++ b/src/screens/Me/Root.tsx @@ -1,5 +1,5 @@ -import React, { useRef } from 'react' -import { ScrollView } from 'react-native' +import React, { useRef, useState } from 'react' +import { Animated, ScrollView } from 'react-native' import { useSelector } from 'react-redux' import { getLocalUrl } from '@utils/slices/instancesSlice' @@ -10,6 +10,8 @@ import Collections from '@screens/Me/Root/Collections' import Settings from '@screens/Me/Root/Settings' import Logout from '@screens/Me/Root/Logout' import { useScrollToTop } from '@react-navigation/native' +import { AccountState } from '../Shared/Account' +import AccountNav from '../Shared/Account/Nav' const ScreenMeRoot: React.FC = () => { const localRegistered = useSelector(getLocalUrl) @@ -17,13 +19,34 @@ const ScreenMeRoot: React.FC = () => { const scrollRef = useRef(null) useScrollToTop(scrollRef) + const scrollY = useRef(new Animated.Value(0)).current + const [data, setData] = useState() + return ( - - {localRegistered ? : } - {localRegistered && } - - {localRegistered && } - + <> + {localRegistered && data ? ( + + ) : null} + + {localRegistered ? : } + {localRegistered && } + + {localRegistered && } + + ) } diff --git a/src/screens/Me/Root/MyInfo.tsx b/src/screens/Me/Root/MyInfo.tsx index c8eb90d5..84d0ab0b 100644 --- a/src/screens/Me/Root/MyInfo.tsx +++ b/src/screens/Me/Root/MyInfo.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useEffect } from 'react' import { useQuery } from 'react-query' import { accountFetch } from '@utils/fetches/accountFetch' @@ -6,14 +6,28 @@ import AccountHeader from '@screens/Shared/Account/Header' import AccountInformation from '@screens/Shared/Account/Information' import { useSelector } from 'react-redux' import { getLocalAccountId } from '@utils/slices/instancesSlice' +import { AccountState } from '@root/screens/Shared/Account' -const MyInfo: React.FC = () => { +export interface Props { + setData: React.Dispatch> +} + +const MyInfo: React.FC = ({ setData }) => { const localAccountId = useSelector(getLocalAccountId) const { data } = useQuery(['Account', { id: localAccountId }], accountFetch) + useEffect(() => { + if (data) { + setData(data) + } + }, [data]) return ( <> - + ) diff --git a/src/screens/Shared/Account.tsx b/src/screens/Shared/Account.tsx index 2c0c1ac5..07fa0d80 100644 --- a/src/screens/Shared/Account.tsx +++ b/src/screens/Shared/Account.tsx @@ -1,4 +1,4 @@ -import React, { createContext, Dispatch, useReducer, useRef } from 'react' +import React, { useReducer, useRef } from 'react' import { Animated, ScrollView } from 'react-native' // import * as relationshipsSlice from 'src/stacks/common/relationshipsSlice' @@ -62,11 +62,6 @@ const accountReducer = ( throw new Error('Unexpected action') } } -type ContextType = { - accountState: AccountState - accountDispatch: Dispatch -} -export const AccountContext = createContext({} as ContextType) const ScreenSharedAccount: React.FC = ({ route: { @@ -83,23 +78,38 @@ const ScreenSharedAccount: React.FC = ({ ) return ( - - - + <> + + - - - + + + - + ) } diff --git a/src/screens/Shared/Account/Header.tsx b/src/screens/Shared/Account/Header.tsx index 086998ed..a898239b 100644 --- a/src/screens/Shared/Account/Header.tsx +++ b/src/screens/Shared/Account/Header.tsx @@ -1,25 +1,39 @@ -import React, { useContext, useEffect, useRef } from 'react' +import React, { Dispatch, useEffect, useRef, useState } from 'react' import { Animated, Dimensions, Image, StyleSheet } from 'react-native' -import { AccountContext } from '../Account' +import { AccountAction, AccountState } from '../Account' export interface Props { - uri?: Mastodon.Account['header'] + accountState: AccountState + accountDispatch?: Dispatch + account?: Mastodon.Account limitHeight?: boolean } -const AccountHeader: React.FC = ({ uri, limitHeight = false }) => { - const { accountState, accountDispatch } = useContext(AccountContext) +const AccountHeader: React.FC = ({ + accountState, + accountDispatch, + account, + limitHeight = false +}) => { + const [imageShown, setImageShown] = useState(true) useEffect(() => { - if (uri) { - if (uri.includes('/headers/original/missing.png')) { + if (account?.header) { + if (account.header.includes('/headers/original/missing.png')) { animateNewSize(accountState.headerRatio) } else { + if (account.header !== account.header_static) { + setImageShown(false) + } Image.getSize( - uri, + account.header, (width, height) => { if (!limitHeight) { - accountDispatch({ type: 'headerRatio', payload: height / width }) + accountDispatch && + accountDispatch({ + type: 'headerRatio', + payload: height / width + }) } animateNewSize( limitHeight ? accountState.headerRatio : height / width @@ -30,10 +44,12 @@ const AccountHeader: React.FC = ({ uri, limitHeight = false }) => { } ) } - } else { - animateNewSize(accountState.headerRatio) } - }, [uri]) + }, [account]) + + const theImage = imageShown ? ( + + ) : null const windowWidth = Dimensions.get('window').width const imageHeight = useRef( @@ -44,12 +60,16 @@ const AccountHeader: React.FC = ({ uri, limitHeight = false }) => { toValue: windowWidth * ratio, duration: 350, useNativeDriver: false - }).start() + }).start(({ finished }) => { + if (finished) { + setImageShown(true) + } + }) } return ( - + {theImage} ) } diff --git a/src/screens/Shared/Account/Information.tsx b/src/screens/Shared/Account/Information.tsx index 337c62f3..784cbd33 100644 --- a/src/screens/Shared/Account/Information.tsx +++ b/src/screens/Shared/Account/Information.tsx @@ -1,4 +1,4 @@ -import React, { createRef, useContext, useEffect, useState } from 'react' +import React, { createRef, Dispatch, useEffect, useState } from 'react' import { Animated, Image, StyleSheet, Text, View } from 'react-native' import { createShimmerPlaceholder } from 'react-native-shimmer-placeholder' import { Feather } from '@expo/vector-icons' @@ -9,14 +9,14 @@ import { StyleConstants } from '@utils/styles/constants' import { useTranslation } from 'react-i18next' import Emojis from '@components/Timelines/Timeline/Shared/Emojis' import { LinearGradient } from 'expo-linear-gradient' -import { AccountContext } from '../Account' +import { AccountAction } from '../Account' export interface Props { + accountDispatch?: Dispatch account: Mastodon.Account | undefined } -const AccountInformation: React.FC = ({ account }) => { - const { accountDispatch } = useContext(AccountContext) +const AccountInformation: React.FC = ({ accountDispatch, account }) => { const { t } = useTranslation('sharedAccount') const { theme } = useTheme() const [avatarLoaded, setAvatarLoaded] = useState(false) @@ -48,6 +48,7 @@ const AccountInformation: React.FC = ({ account }) => { + accountDispatch && accountDispatch({ type: 'informationLayout', payload: { diff --git a/src/screens/Shared/Account/Nav.tsx b/src/screens/Shared/Account/Nav.tsx index f2460e92..94567408 100644 --- a/src/screens/Shared/Account/Nav.tsx +++ b/src/screens/Shared/Account/Nav.tsx @@ -1,18 +1,18 @@ import Emojis from '@root/components/Timelines/Timeline/Shared/Emojis' import { StyleConstants } from '@root/utils/styles/constants' import { useTheme } from '@root/utils/styles/ThemeManager' -import React, { useContext } from 'react' +import React from 'react' import { Animated, Dimensions, StyleSheet, Text, View } from 'react-native' import { useSafeAreaInsets } from 'react-native-safe-area-context' -import { AccountContext } from '../Account' +import { AccountState } from '../Account' export interface Props { + accountState: AccountState scrollY: Animated.Value account: Mastodon.Account | undefined } -const AccountNav: React.FC = ({ scrollY, account }) => { - const { accountState } = useContext(AccountContext) +const AccountNav: React.FC = ({ accountState, scrollY, account }) => { const { theme } = useTheme() const headerHeight = useSafeAreaInsets().top + 44 diff --git a/src/screens/Shared/Account/SegmentedControl.tsx b/src/screens/Shared/Account/SegmentedControl.tsx index b8af5103..4860f944 100644 --- a/src/screens/Shared/Account/SegmentedControl.tsx +++ b/src/screens/Shared/Account/SegmentedControl.tsx @@ -1,18 +1,23 @@ import SegmentedControl from '@react-native-community/segmented-control' import { StyleConstants } from '@root/utils/styles/constants' import { useTheme } from '@root/utils/styles/ThemeManager' -import React, { useContext } from 'react' +import React, { Dispatch } from 'react' import { useTranslation } from 'react-i18next' import { Animated, StyleSheet } from 'react-native' import { useSafeAreaInsets } from 'react-native-safe-area-context' -import { AccountContext } from '../Account' +import { AccountAction, AccountState } from '../Account' export interface Props { + accountState: AccountState + accountDispatch: Dispatch scrollY: Animated.Value } -const AccountSegmentedControl: React.FC = ({ scrollY }) => { - const { accountState, accountDispatch } = useContext(AccountContext) +const AccountSegmentedControl: React.FC = ({ + accountState, + accountDispatch, + scrollY +}) => { const { t } = useTranslation('sharedAccount') const { mode, theme } = useTheme() @@ -69,12 +74,10 @@ const AccountSegmentedControl: React.FC = ({ scrollY }) => { const styles = StyleSheet.create({ base: { ...StyleSheet.absoluteFillObject, - position: 'absolute', - left: 0, - right: 0, zIndex: 99, borderTopWidth: StyleSheet.hairlineWidth, - padding: StyleConstants.Spacing.Global.PagePadding + padding: StyleConstants.Spacing.Global.PagePadding, + paddingBottom: StyleConstants.Spacing.Global.PagePadding * 3 } }) diff --git a/src/screens/Shared/Account/Toots.tsx b/src/screens/Shared/Account/Toots.tsx index ea8f9729..877df4ef 100644 --- a/src/screens/Shared/Account/Toots.tsx +++ b/src/screens/Shared/Account/Toots.tsx @@ -1,32 +1,29 @@ -import React, { useCallback, useContext, useState } from 'react' +import React, { Dispatch, useCallback, useState } from 'react' import { Dimensions, StyleSheet } from 'react-native' -import { TabView, SceneMap } from 'react-native-tab-view' +import { SceneMap, TabView } from 'react-native-tab-view' import Timeline from '@components/Timelines/Timeline' -import { AccountContext } from '../Account' +import { AccountAction, AccountState } from '../Account' import { StyleConstants } from '@root/utils/styles/constants' export interface Props { + accountState: AccountState + accountDispatch: Dispatch id: Mastodon.Account['id'] } -const AccountToots: React.FC = ({ id }) => { - const { accountState, accountDispatch } = useContext(AccountContext) - +const AccountToots: React.FC = ({ + accountState, + accountDispatch, + id +}) => { const [routes] = useState([ { key: 'Account_Default' }, { key: 'Account_All' }, { key: 'Account_Media' } ]) const singleScene = useCallback( - ({ route }) => ( - - ), + ({ route }) => , [] ) const renderScene = SceneMap({ diff --git a/src/screens/Shared/Webview.tsx b/src/screens/Shared/Webview.tsx index a4ed24a3..87c8103c 100644 --- a/src/screens/Shared/Webview.tsx +++ b/src/screens/Shared/Webview.tsx @@ -51,6 +51,7 @@ const ScreenSharedWebview: React.FC = ({ {() => ( <>