forked from Ivasoft/mattermost-mobile
[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:
@@ -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]);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
39
app/screens/home/account/index.ts
Normal file
39
app/screens/home/account/index.ts
Normal 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));
|
||||
@@ -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 {
|
||||
@@ -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';
|
||||
|
||||
@@ -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`}
|
||||
@@ -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 {
|
||||
@@ -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}
|
||||
@@ -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)));
|
||||
@@ -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;
|
||||
@@ -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 = () => {
|
||||
@@ -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}
|
||||
@@ -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}
|
||||
@@ -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 = {
|
||||
@@ -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 = () => {
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user