[Gekidou] optimizations, fix & moved files (#6177)

* Freeze unfocused tabs

* Fix syntax_highlight when multiple code blocks present in the same post

* Move @components/channel_list to @screens/home/channels_list/categories_list

* Update app/screens/channel/channel.tsx

Co-authored-by: Avinash Lingaloo <avinashlng1080@gmail.com>

* Add support for Freeze on Android

* Fix render on tablets

Co-authored-by: Avinash Lingaloo <avinashlng1080@gmail.com>
This commit is contained in:
Elias Nahum
2022-04-18 08:49:17 -04:00
committed by GitHub
parent 1a5583034e
commit d547bddc2b
52 changed files with 192 additions and 142 deletions

View File

@@ -29,9 +29,6 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
borderRadius: 8,
elevation: 3,
},
hidden: {
display: 'none',
},
searchContainer: {
...Platform.select({
android: {
@@ -128,22 +125,19 @@ const Autocomplete = ({
if (isSearch) {
s.push(style.base, style.searchContainer, {height: maxListHeight});
}
if (!hasElements) {
s.push(style.hidden);
}
return s;
}, [style, isSearch && maxListHeight, hasElements]);
const containerStyles = useMemo(() => {
const s = [style.borders];
const s = [];
if (!isSearch && !fixedBottomPosition) {
const offset = isTablet ? -OFFSET_TABLET : 0;
s.push(style.base, {bottom: postInputTop + LIST_BOTTOM + offset});
} else if (fixedBottomPosition) {
s.push(style.base, {bottom: 0});
}
if (!hasElements) {
s.push(style.hidden);
if (hasElements) {
s.push(style.borders);
}
return s;
}, [!isSearch, isTablet, hasElements, postInputTop]);

View File

@@ -3,8 +3,9 @@
import React from 'react';
import {Freeze} from 'react-freeze';
import {View} from 'react-native';
import {StyleSheet, View} from 'react-native';
import {useIsTablet} from '@hooks/device';
import useFreeze from '@hooks/freeze';
type FreezePlaceholderProps = {
@@ -13,25 +14,66 @@ type FreezePlaceholderProps = {
type FreezeScreenProps = {
children: React.ReactNode;
freeze?: boolean;
}
const FreezePlaceholder = ({backgroundColor}: FreezePlaceholderProps) => {
export const FreezePlaceholder = ({backgroundColor}: FreezePlaceholderProps) => {
return <View style={{flex: 1, backgroundColor}}/>;
};
const FreezeScreen = ({children}: FreezeScreenProps) => {
const {freeze, backgroundColor} = useFreeze();
interface ViewConfig extends View {
viewConfig: {
validAttributes: {
style: {
display: boolean;
};
};
};
}
// This solves the keeping of position on Android
const handleRef = (ref: ViewConfig) => {
if (ref?.viewConfig?.validAttributes?.style) {
ref.viewConfig.validAttributes.style = {
...ref.viewConfig.validAttributes.style,
display: false,
};
}
};
const style = StyleSheet.create({
freeze: {
height: '100%',
width: '100%',
position: 'absolute',
},
});
function FreezeScreen({freeze: freezeFromProps, children}: FreezeScreenProps) {
const {freeze, backgroundColor} = useFreeze();
const isTablet = useIsTablet();
const placeholder = (<FreezePlaceholder backgroundColor={backgroundColor}/>);
let component = children;
if (!isTablet) {
component = (
<View
ref={handleRef}
style={style.freeze}
>
{children}
</View>
);
}
return (
<Freeze
freeze={freeze}
freeze={freezeFromProps || freeze}
placeholder={placeholder}
>
{children}
{component}
</Freeze>
);
};
}
export default FreezeScreen;

View File

@@ -5,6 +5,7 @@ import React, {useCallback} from 'react';
import {FlatList, ScrollView, StyleSheet, Text} from 'react-native';
import {createStyleObject} from 'react-syntax-highlighter/create-element';
import {generateId} from '@utils/general';
import {changeOpacity} from '@utils/theme';
type CreateChildren = {
@@ -136,6 +137,7 @@ const CodeHighlightRenderer = ({defaultColor, digits, fontFamily, fontSize, rows
<FlatList
data={rows}
renderItem={renderItem}
listKey={generateId()}
/>
</ScrollView>
);

View File

@@ -2,7 +2,7 @@
// See LICENSE.txt for license information.
import {useEffect, useState} from 'react';
import {DeviceEventEmitter, Platform} from 'react-native';
import {DeviceEventEmitter} from 'react-native';
import {Events} from '@constants';
@@ -12,11 +12,8 @@ const useFreeze = () => {
useEffect(() => {
const freezeListener = DeviceEventEmitter.addListener(Events.FREEZE_SCREEN, (shouldFreeze: boolean, color = '#000') => {
// kept until this https://github.com/software-mansion/react-freeze/issues/7 is fixed
if (Platform.OS === 'ios') {
setFreeze(shouldFreeze);
setBackgroundColor(color);
}
setFreeze(shouldFreeze);
setBackgroundColor(color);
});
return () => freezeListener.remove();

View File

@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useCallback, useEffect, useMemo, useRef} from 'react';
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
import {useIntl} from 'react-intl';
import {DeviceEventEmitter, Keyboard, Platform, StyleSheet, View} from 'react-native';
import {KeyboardTrackingViewRef} from 'react-native-keyboard-tracking-view';
@@ -47,6 +47,7 @@ const Channel = ({channelId, componentId, displayName, isOwnDirectMessage, membe
const appState = useAppState();
const isTablet = useIsTablet();
const insets = useSafeAreaInsets();
const [shouldRenderPosts, setShouldRenderPosts] = useState(false);
const theme = useTheme();
const defaultHeight = useDefaultHeaderHeight();
const postDraftRef = useRef<KeyboardTrackingViewRef>(null);
@@ -109,7 +110,15 @@ const Channel = ({channelId, componentId, displayName, isOwnDirectMessage, membe
}
const marginTop = defaultHeight + (isTablet ? insets.top : 0);
const channelIsSet = Boolean(channelId);
useEffect(() => {
// This is done so that the header renders
// and the screen does not look totally blank
const t = requestAnimationFrame(() => {
setShouldRenderPosts(Boolean(channelId));
});
return () => cancelAnimationFrame(t);
}, [channelId]);
return (
<FreezeScreen>
@@ -130,7 +139,7 @@ const Channel = ({channelId, componentId, displayName, isOwnDirectMessage, membe
subtitleCompanion={subtitleCompanion}
title={title}
/>
{channelIsSet &&
{shouldRenderPosts && Boolean(channelId) &&
<>
<View style={[styles.flex, {marginTop}]}>
<ChannelPostList

View File

@@ -1,29 +1,22 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {useRoute} from '@react-navigation/native';
import {useIsFocused, useRoute} from '@react-navigation/native';
import React, {useCallback, useState} from 'react';
import {ScrollView, View} from 'react-native';
import Animated, {useAnimatedStyle, withTiming} from 'react-native-reanimated';
import {Edge, SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context';
import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import FreezeScreen from '@components/freeze_screen';
import {View as ViewConstants} from '@constants';
import {useTheme} from '@context/theme';
import {useIsTablet} from '@hooks/device';
import {observeConfig} from '@queries/servers/system';
import {observeCurrentUser} from '@queries/servers/user';
import {isCustomStatusExpirySupported, isMinimumServerVersion} from '@utils/helpers';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import AccountOptions from './components/options';
import AccountTabletView from './components/tablet_view';
import AccountUserInfo from './components/user_info';
import type {WithDatabaseArgs} from '@typings/database/database';
import type UserModel from '@typings/database/models/servers/user';
type AccountScreenProps = {
@@ -66,6 +59,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
const AccountScreen = ({currentUser, enableCustomUserStatuses, customStatusExpirySupported, showFullName}: AccountScreenProps) => {
const theme = useTheme();
const isFocused = useIsFocused();
const [start, setStart] = useState(false);
const route = useRoute();
const insets = useSafeAreaInsets();
@@ -101,67 +95,47 @@ const AccountScreen = ({currentUser, enableCustomUserStatuses, customStatusExpir
const styles = getStyleSheet(theme);
return (
<SafeAreaView
edges={edges}
style={styles.container}
testID='account.screen'
>
<View style={[{height: insets.top, flexDirection: 'row'}]}>
<View style={[styles.container, tabletSidebarStyle]}/>
{isTablet && <View style={styles.tabletContainer}/>}
</View>
<Animated.View
onLayout={onLayout}
style={[styles.flexRow, animated]}
<FreezeScreen freeze={!isFocused}>
<SafeAreaView
edges={edges}
style={styles.container}
testID='account.screen'
>
<ScrollView
contentContainerStyle={styles.flex}
alwaysBounceVertical={false}
style={tabletSidebarStyle}
>
<AccountUserInfo
user={currentUser}
showFullName={showFullName}
theme={theme}
/>
<AccountOptions
enableCustomUserStatuses={enableCustomUserStatuses}
isCustomStatusExpirySupported={customStatusExpirySupported}
isTablet={isTablet}
user={currentUser}
theme={theme}
/>
</ScrollView>
{isTablet &&
<View style={[styles.tabletContainer, styles.tabletDivider]}>
<AccountTabletView/>
<View style={[{height: insets.top, flexDirection: 'row'}]}>
<View style={[styles.container, tabletSidebarStyle]}/>
{isTablet && <View style={styles.tabletContainer}/>}
</View>
}
</Animated.View>
</SafeAreaView>
<Animated.View
onLayout={onLayout}
style={[styles.flexRow, animated]}
>
<ScrollView
contentContainerStyle={styles.flex}
alwaysBounceVertical={false}
style={tabletSidebarStyle}
>
<AccountUserInfo
user={currentUser}
showFullName={showFullName}
theme={theme}
/>
<AccountOptions
enableCustomUserStatuses={enableCustomUserStatuses}
isCustomStatusExpirySupported={customStatusExpirySupported}
isTablet={isTablet}
user={currentUser}
theme={theme}
/>
</ScrollView>
{isTablet &&
<View style={[styles.tabletContainer, styles.tabletDivider]}>
<AccountTabletView/>
</View>
}
</Animated.View>
</SafeAreaView>
</FreezeScreen>
);
};
const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
const config = observeConfig(database);
const showFullName = config.pipe((switchMap((cfg) => of$(cfg?.ShowFullName === 'true'))));
const enableCustomUserStatuses = config.pipe((switchMap((cfg) => {
return of$(cfg?.EnableCustomUserStatuses === 'true' && isMinimumServerVersion(cfg?.Version || '', 5, 36));
})));
const version = config.pipe(
switchMap((cfg) => of$(cfg?.Version || '')),
);
const customStatusExpirySupported = config.pipe(
switchMap((cfg) => of$(isCustomStatusExpirySupported(cfg?.Version || ''))),
);
return {
currentUser: observeCurrentUser(database),
enableCustomUserStatuses,
customStatusExpirySupported,
showFullName,
version,
};
});
export default withDatabase(enhanced(AccountScreen));
export default AccountScreen;

View File

@@ -0,0 +1,39 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {observeConfig} from '@queries/servers/system';
import {observeCurrentUser} from '@queries/servers/user';
import {isCustomStatusExpirySupported, isMinimumServerVersion} from '@utils/helpers';
import AccountScreen from './account';
import type {WithDatabaseArgs} from '@typings/database/database';
const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
const config = observeConfig(database);
const showFullName = config.pipe((switchMap((cfg) => of$(cfg?.ShowFullName === 'true'))));
const enableCustomUserStatuses = config.pipe((switchMap((cfg) => {
return of$(cfg?.EnableCustomUserStatuses === 'true' && isMinimumServerVersion(cfg?.Version || '', 5, 36));
})));
const version = config.pipe(
switchMap((cfg) => of$(cfg?.Version || '')),
);
const customStatusExpirySupported = config.pipe(
switchMap((cfg) => of$(isCustomStatusExpirySupported(cfg?.Version || ''))),
);
return {
currentUser: observeCurrentUser(database),
enableCustomUserStatuses,
customStatusExpirySupported,
showFullName,
version,
};
});
export default withDatabase(enhanced(AccountScreen));

View File

@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`components/channel_list should render channels error 1`] = `
exports[`components/categories_list should render channels error 1`] = `
<View
animatedStyle={
Object {
@@ -304,7 +304,7 @@ exports[`components/channel_list should render channels error 1`] = `
</View>
`;
exports[`components/channel_list should render team error 1`] = `
exports[`components/categories_list should render team error 1`] = `
<View
animatedStyle={
Object {

View File

@@ -9,7 +9,7 @@ import {DEFAULT_LOCALE} from '@i18n';
import {renderWithEverything} from '@test/intl-test-helper';
import TestHelper from '@test/test_helper';
import CategoryBody from './';
import CategoryBody from '.';
import type CategoryModel from '@typings/database/models/servers/category';

View File

@@ -7,7 +7,7 @@ import {FlatList} from 'react-native';
import {DMS_CATEGORY} from '@constants/categories';
import ChannelModel from '@typings/database/models/servers/channel';
import ChannelListItem from './channel';
import ChannelItem from './channel_item';
import type CategoryModel from '@typings/database/models/servers/category';
@@ -37,7 +37,7 @@ const CategoryBody = ({sortedChannels, category, hiddenChannelIds, limit}: Props
const renderItem = useCallback(({item}: {item: ChannelModel}) => {
return (
<ChannelListItem
<ChannelItem
channel={item}
collapsed={category.collapsed}
testID={`category.${category.displayName.replace(/ /g, '_').toLocaleLowerCase()}.channel_list_item`}

View File

@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`components/channel_list/categories/body/channel/item should match snapshot 1`] = `
exports[`components/channel_list/categories/body/channel_item should match snapshot 1`] = `
<View
animatedStyle={
Object {

View File

@@ -8,12 +8,12 @@ import {MM_TABLES} from '@constants/database';
import {renderWithIntlAndTheme} from '@test/intl-test-helper';
import TestHelper from '@test/test_helper';
import ChannelListItem from './channel_list_item';
import ChannelItem from './channel_item';
import type ChannelModel from '@typings/database/models/servers/channel';
import type MyChannelModel from '@typings/database/models/servers/my_channel';
describe('components/channel_list/categories/body/channel/item', () => {
describe('components/channel_list/categories/body/channel_item', () => {
let database: Database;
let myChannel: MyChannelModel;
@@ -30,7 +30,7 @@ describe('components/channel_list/categories/body/channel/item', () => {
it('should match snapshot', () => {
const wrapper = renderWithIntlAndTheme(
<ChannelListItem
<ChannelItem
channel={{displayName: 'Hello!', type: 'G', shared: false, name: 'hello', deleteAt: 0} as ChannelModel}
isActive={false}
myChannel={myChannel}

View File

@@ -15,7 +15,7 @@ import {observeCurrentChannelId, observeCurrentUserId} from '@queries/servers/sy
import ChannelModel from '@typings/database/models/servers/channel';
import MyChannelModel from '@typings/database/models/servers/my_channel';
import ChannelListItem from './channel_list_item';
import ChannelItem from './channel_item';
import type {WithDatabaseArgs} from '@typings/database/database';
import type PreferenceModel from '@typings/database/models/servers/preference';
@@ -65,4 +65,4 @@ const enhance = withObservables(['channel', 'isUnreads'], ({channel, isUnreads,
};
});
export default React.memo(withDatabase(enhance(ChannelListItem)));
export default React.memo(withDatabase(enhance(ChannelItem)));

View File

@@ -7,7 +7,7 @@ import React from 'react';
import {renderWithEverything} from '@test/intl-test-helper';
import TestHelper from '@test/test_helper';
import Categories from './';
import Categories from '.';
describe('components/channel_list/categories', () => {
let database: Database;

View File

@@ -5,7 +5,7 @@ import React, {useCallback, useState} from 'react';
import {useIntl} from 'react-intl';
import {retryInitialTeamAndChannel} from '@actions/remote/retry';
import LoadingError from '@components/channel_list/loading_error';
import LoadingError from '@components/loading_error';
import {useServerDisplayName, useServerUrl} from '@context/server';
const LoadCategoriesError = () => {

View File

@@ -9,7 +9,7 @@ import {useTheme} from '@context/theme';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
import ChannelListItem from '../body/channel';
import ChannelItem from '../body/channel_item';
import type ChannelModel from '@typings/database/models/servers/channel';
@@ -25,7 +25,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
const renderItem = ({item}: {item: ChannelModel}) => {
return (
<ChannelListItem
<ChannelItem
channel={item}
collapsed={false}
isUnreads={true}

View File

@@ -10,9 +10,9 @@ import {getTeamById} from '@queries/servers/team';
import {renderWithEverything} from '@test/intl-test-helper';
import TestHelper from '@test/test_helper';
import ChannelsList from './';
import CategoriesList from '.';
describe('components/channel_list', () => {
describe('components/categories_list', () => {
let database: Database;
let operator: ServerDataOperator;
beforeAll(async () => {
@@ -30,7 +30,7 @@ describe('components/channel_list', () => {
it('should render', () => {
const wrapper = renderWithEverything(
<ChannelsList
<CategoriesList
isTablet={false}
teamsCount={1}
currentTeamId={TestHelper.basicTeam!.id}
@@ -48,7 +48,7 @@ describe('components/channel_list', () => {
});
const wrapper = renderWithEverything(
<ChannelsList
<CategoriesList
isTablet={false}
teamsCount={0}
currentTeamId='TestHelper.basicTeam!.id'
@@ -67,7 +67,7 @@ describe('components/channel_list', () => {
it('should render channels error', () => {
const wrapper = renderWithEverything(
<ChannelsList
<CategoriesList
isTablet={false}
teamsCount={1}
currentTeamId={TestHelper.basicTeam!.id}

View File

@@ -5,7 +5,7 @@ import React, {useCallback, useState} from 'react';
import {useIntl} from 'react-intl';
import {retryInitialChannel} from '@actions/remote/retry';
import LoadingError from '@components/channel_list/loading_error';
import LoadingError from '@components/loading_error';
import {useServerUrl} from '@context/server';
type Props = {

View File

@@ -5,7 +5,7 @@ import React, {useCallback, useState} from 'react';
import {useIntl} from 'react-intl';
import {retryInitialTeamAndChannel} from '@actions/remote/retry';
import LoadingError from '@components/channel_list/loading_error';
import LoadingError from '@components/loading_error';
import {useServerDisplayName, useServerUrl} from '@context/server';
const LoadTeamsError = () => {

View File

@@ -8,13 +8,13 @@ import {StyleSheet} from 'react-native';
import Animated, {useAnimatedStyle, withTiming} from 'react-native-reanimated';
import {Edge, SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context';
import ChannelList from '@components/channel_list';
import FreezeScreen from '@components/freeze_screen';
import TeamSidebar from '@components/team_sidebar';
import {useTheme} from '@context/theme';
import {useIsTablet} from '@hooks/device';
import Channel from '@screens/channel';
import CategoriesList from './categories_list';
import Servers from './servers';
type ChannelProps = {
@@ -68,8 +68,8 @@ const ChannelListScreen = (props: ChannelProps) => {
return {height: insets.top, backgroundColor: theme.sidebarBg};
}, [theme]);
const content = (
<>
return (
<FreezeScreen freeze={!isFocused}>
{<Animated.View style={top}/>}
<SafeAreaView
style={styles.content}
@@ -84,7 +84,7 @@ const ChannelListScreen = (props: ChannelProps) => {
iconPad={canAddOtherServers}
teamsCount={props.teamsCount}
/>
<ChannelList
<CategoriesList
iconPad={canAddOtherServers && props.teamsCount <= 1}
isTablet={isTablet}
teamsCount={props.teamsCount}
@@ -96,18 +96,8 @@ const ChannelListScreen = (props: ChannelProps) => {
}
</Animated.View>
</SafeAreaView>
</>
</FreezeScreen>
);
if (isTablet) {
return (
<FreezeScreen>
{content}
</FreezeScreen>
);
}
return content;
};
export default ChannelListScreen;

View File

@@ -53,7 +53,7 @@ export default function HomeScreen(props: HomeProps) {
dark: false,
colors: {
primary: theme.centerChannelColor,
background: theme.centerChannelBg,
background: 'transparent',
card: theme.centerChannelBg,
text: theme.centerChannelColor,
border: 'white',
@@ -62,7 +62,7 @@ export default function HomeScreen(props: HomeProps) {
}}
>
<Tab.Navigator
screenOptions={{headerShown: false, lazy: true, unmountOnBlur: true}}
screenOptions={{headerShown: false, lazy: true, unmountOnBlur: false}}
tabBar={(tabProps: BottomTabBarProps) => (
<TabBar
{...tabProps}
@@ -78,17 +78,17 @@ export default function HomeScreen(props: HomeProps) {
<Tab.Screen
name={Screens.SEARCH}
component={Search}
options={{unmountOnBlur: false, tabBarTestID: 'tab_bar.search.tab'}}
options={{unmountOnBlur: false, lazy: true, tabBarTestID: 'tab_bar.search.tab'}}
/>
<Tab.Screen
name={Screens.MENTIONS}
component={RecentMentions}
options={{tabBarTestID: 'tab_bar.mentions.tab'}}
options={{tabBarTestID: 'tab_bar.mentions.tab', lazy: true, unmountOnBlur: false}}
/>
<Tab.Screen
name={Screens.ACCOUNT}
component={Account}
options={{tabBarTestID: 'tab_bar.account.tab'}}
options={{tabBarTestID: 'tab_bar.account.tab', lazy: true, unmountOnBlur: false}}
/>
</Tab.Navigator>
</NavigationContainer>

View File

@@ -4,11 +4,12 @@
import {useIsFocused, useRoute} from '@react-navigation/native';
import React, {useCallback, useState, useEffect, useMemo} from 'react';
import {useIntl} from 'react-intl';
import {StyleSheet, View, ActivityIndicator, FlatList, DeviceEventEmitter} from 'react-native';
import {ActivityIndicator, DeviceEventEmitter, FlatList, StyleSheet, View} from 'react-native';
import Animated, {useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated';
import {SafeAreaView, Edge} from 'react-native-safe-area-context';
import {fetchRecentMentions} from '@actions/remote/search';
import FreezeScreen from '@components/freeze_screen';
import NavigationHeader from '@components/navigation_header';
import DateSeparator from '@components/post_list/date_separator';
import PostWithChannelInfo from '@components/post_with_channel_info';
@@ -145,7 +146,7 @@ const RecentMentionsScreen = ({mentions, currentTimezone, isTimezoneEnabled}: Pr
}, []);
return (
<>
<FreezeScreen freeze={!isFocused}>
<NavigationHeader
isLargeTitle={isLargeTitle}
showBackButton={false}
@@ -178,7 +179,7 @@ const RecentMentionsScreen = ({mentions, currentTimezone, isTimezoneEnabled}: Pr
/>
</Animated.View>
</SafeAreaView>
</>
</FreezeScreen>
);
};

View File

@@ -9,6 +9,7 @@ import Animated, {useAnimatedStyle, withTiming} from 'react-native-reanimated';
import {SafeAreaView} from 'react-native-safe-area-context';
import Badge from '@components/badge';
import FreezeScreen from '@components/freeze_screen';
import NavigationHeader from '@components/navigation_header';
import {useTheme} from '@context/theme';
import {useCollapsibleHeader} from '@hooks/header';
@@ -89,7 +90,7 @@ const SearchScreen = () => {
];
return (
<>
<FreezeScreen freeze={!isFocused}>
<NavigationHeader
isLargeTitle={isLargeTitle}
leftComponent={leftComponent}
@@ -141,7 +142,7 @@ const SearchScreen = () => {
/>
</Animated.View>
</SafeAreaView>
</>
</FreezeScreen>
);
};

View File

@@ -6,6 +6,7 @@ import {StyleSheet, View} from 'react-native';
import {KeyboardTrackingViewRef} from 'react-native-keyboard-tracking-view';
import {Edge, SafeAreaView} from 'react-native-safe-area-context';
import FreezeScreen from '@components/freeze_screen';
import PostDraft from '@components/post_draft';
import {THREAD_ACCESSORIES_CONTAINER_NATIVE_ID} from '@constants/post_draft';
import {useAppState} from '@hooks/device';
@@ -32,7 +33,7 @@ const Thread = ({rootPost}: ThreadProps) => {
const postDraftRef = useRef<KeyboardTrackingViewRef>(null);
return (
<>
<FreezeScreen>
<SafeAreaView
style={styles.flex}
mode='margin'
@@ -57,7 +58,7 @@ const Thread = ({rootPost}: ThreadProps) => {
</>
}
</SafeAreaView>
</>
</FreezeScreen>
);
};