diff --git a/app/components/autocomplete/autocomplete.tsx b/app/components/autocomplete/autocomplete.tsx index c6cfbf25fd..933dcbe558 100644 --- a/app/components/autocomplete/autocomplete.tsx +++ b/app/components/autocomplete/autocomplete.tsx @@ -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]); diff --git a/app/components/freeze_screen/index.tsx b/app/components/freeze_screen/index.tsx index a5186f2a5b..dcbdf5ba33 100644 --- a/app/components/freeze_screen/index.tsx +++ b/app/components/freeze_screen/index.tsx @@ -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 ; }; -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 = (); + let component = children; + if (!isTablet) { + component = ( + + {children} + + ); + } + return ( - {children} + {component} ); -}; +} export default FreezeScreen; diff --git a/app/components/channel_list/loading_error/__snapshots__/index.test.tsx.snap b/app/components/loading_error/__snapshots__/index.test.tsx.snap similarity index 100% rename from app/components/channel_list/loading_error/__snapshots__/index.test.tsx.snap rename to app/components/loading_error/__snapshots__/index.test.tsx.snap diff --git a/app/components/channel_list/loading_error/index.test.tsx b/app/components/loading_error/index.test.tsx similarity index 100% rename from app/components/channel_list/loading_error/index.test.tsx rename to app/components/loading_error/index.test.tsx diff --git a/app/components/channel_list/loading_error/index.tsx b/app/components/loading_error/index.tsx similarity index 100% rename from app/components/channel_list/loading_error/index.tsx rename to app/components/loading_error/index.tsx diff --git a/app/components/syntax_highlight/renderer.tsx b/app/components/syntax_highlight/renderer.tsx index d08be58a91..222d34d396 100644 --- a/app/components/syntax_highlight/renderer.tsx +++ b/app/components/syntax_highlight/renderer.tsx @@ -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 ); diff --git a/app/hooks/freeze.ts b/app/hooks/freeze.ts index 41e5105581..00466c5af9 100644 --- a/app/hooks/freeze.ts +++ b/app/hooks/freeze.ts @@ -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(); diff --git a/app/screens/channel/channel.tsx b/app/screens/channel/channel.tsx index e4da8ac426..4b2ca632fc 100644 --- a/app/screens/channel/channel.tsx +++ b/app/screens/channel/channel.tsx @@ -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(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 ( @@ -130,7 +139,7 @@ const Channel = ({channelId, componentId, displayName, isOwnDirectMessage, membe subtitleCompanion={subtitleCompanion} title={title} /> - {channelIsSet && + {shouldRenderPosts && Boolean(channelId) && <> { 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 ( - - - - {isTablet && } - - + - - - - - {isTablet && - - + + + {isTablet && } - } - - + + + + + + {isTablet && + + + + } + + + ); }; -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; diff --git a/app/screens/home/account/index.ts b/app/screens/home/account/index.ts new file mode 100644 index 0000000000..bcd2b8b97d --- /dev/null +++ b/app/screens/home/account/index.ts @@ -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)); diff --git a/app/components/channel_list/__snapshots__/index.test.tsx.snap b/app/screens/home/channel_list/categories_list/__snapshots__/index.test.tsx.snap similarity index 99% rename from app/components/channel_list/__snapshots__/index.test.tsx.snap rename to app/screens/home/channel_list/categories_list/__snapshots__/index.test.tsx.snap index 4894321965..e16d81c76b 100644 --- a/app/components/channel_list/__snapshots__/index.test.tsx.snap +++ b/app/screens/home/channel_list/categories_list/__snapshots__/index.test.tsx.snap @@ -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`] = ` `; -exports[`components/channel_list should render team error 1`] = ` +exports[`components/categories_list should render team error 1`] = ` { return ( - { +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( - { let database: Database; diff --git a/app/components/channel_list/categories/categories.tsx b/app/screens/home/channel_list/categories_list/categories/categories.tsx similarity index 100% rename from app/components/channel_list/categories/categories.tsx rename to app/screens/home/channel_list/categories_list/categories/categories.tsx diff --git a/app/components/channel_list/categories/error.tsx b/app/screens/home/channel_list/categories_list/categories/error.tsx similarity index 94% rename from app/components/channel_list/categories/error.tsx rename to app/screens/home/channel_list/categories_list/categories/error.tsx index 1866d27c8b..e7a61b7510 100644 --- a/app/components/channel_list/categories/error.tsx +++ b/app/screens/home/channel_list/categories_list/categories/error.tsx @@ -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 = () => { diff --git a/app/components/channel_list/categories/header/__snapshots__/header.test.tsx.snap b/app/screens/home/channel_list/categories_list/categories/header/__snapshots__/header.test.tsx.snap similarity index 100% rename from app/components/channel_list/categories/header/__snapshots__/header.test.tsx.snap rename to app/screens/home/channel_list/categories_list/categories/header/__snapshots__/header.test.tsx.snap diff --git a/app/components/channel_list/categories/header/header.test.tsx b/app/screens/home/channel_list/categories_list/categories/header/header.test.tsx similarity index 100% rename from app/components/channel_list/categories/header/header.test.tsx rename to app/screens/home/channel_list/categories_list/categories/header/header.test.tsx diff --git a/app/components/channel_list/categories/header/header.tsx b/app/screens/home/channel_list/categories_list/categories/header/header.tsx similarity index 100% rename from app/components/channel_list/categories/header/header.tsx rename to app/screens/home/channel_list/categories_list/categories/header/header.tsx diff --git a/app/components/channel_list/categories/header/index.ts b/app/screens/home/channel_list/categories_list/categories/header/index.ts similarity index 100% rename from app/components/channel_list/categories/header/index.ts rename to app/screens/home/channel_list/categories_list/categories/header/index.ts diff --git a/app/components/channel_list/categories/index.ts b/app/screens/home/channel_list/categories_list/categories/index.ts similarity index 100% rename from app/components/channel_list/categories/index.ts rename to app/screens/home/channel_list/categories_list/categories/index.ts diff --git a/app/components/channel_list/categories/unreads/index.ts b/app/screens/home/channel_list/categories_list/categories/unreads/index.ts similarity index 100% rename from app/components/channel_list/categories/unreads/index.ts rename to app/screens/home/channel_list/categories_list/categories/unreads/index.ts diff --git a/app/components/channel_list/categories/unreads/unreads.test.tsx b/app/screens/home/channel_list/categories_list/categories/unreads/unreads.test.tsx similarity index 100% rename from app/components/channel_list/categories/unreads/unreads.test.tsx rename to app/screens/home/channel_list/categories_list/categories/unreads/unreads.test.tsx diff --git a/app/components/channel_list/categories/unreads/unreads.tsx b/app/screens/home/channel_list/categories_list/categories/unreads/unreads.tsx similarity index 95% rename from app/components/channel_list/categories/unreads/unreads.tsx rename to app/screens/home/channel_list/categories_list/categories/unreads/unreads.tsx index 7f90cedb41..c301b77c47 100644 --- a/app/components/channel_list/categories/unreads/unreads.tsx +++ b/app/screens/home/channel_list/categories_list/categories/unreads/unreads.tsx @@ -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 ( - { +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( - { }); const wrapper = renderWithEverything( - { it('should render channels error', () => { const wrapper = renderWithEverything( - { diff --git a/app/components/channel_list/search/__snapshots__/index.test.tsx.snap b/app/screens/home/channel_list/categories_list/search/__snapshots__/index.test.tsx.snap similarity index 100% rename from app/components/channel_list/search/__snapshots__/index.test.tsx.snap rename to app/screens/home/channel_list/categories_list/search/__snapshots__/index.test.tsx.snap diff --git a/app/components/channel_list/search/index.test.tsx b/app/screens/home/channel_list/categories_list/search/index.test.tsx similarity index 100% rename from app/components/channel_list/search/index.test.tsx rename to app/screens/home/channel_list/categories_list/search/index.test.tsx diff --git a/app/components/channel_list/search/index.tsx b/app/screens/home/channel_list/categories_list/search/index.tsx similarity index 100% rename from app/components/channel_list/search/index.tsx rename to app/screens/home/channel_list/categories_list/search/index.tsx diff --git a/app/components/channel_list/threads/__snapshots__/index.test.tsx.snap b/app/screens/home/channel_list/categories_list/threads/__snapshots__/index.test.tsx.snap similarity index 100% rename from app/components/channel_list/threads/__snapshots__/index.test.tsx.snap rename to app/screens/home/channel_list/categories_list/threads/__snapshots__/index.test.tsx.snap diff --git a/app/components/channel_list/threads/index.test.tsx b/app/screens/home/channel_list/categories_list/threads/index.test.tsx similarity index 100% rename from app/components/channel_list/threads/index.test.tsx rename to app/screens/home/channel_list/categories_list/threads/index.test.tsx diff --git a/app/components/channel_list/threads/index.tsx b/app/screens/home/channel_list/categories_list/threads/index.tsx similarity index 100% rename from app/components/channel_list/threads/index.tsx rename to app/screens/home/channel_list/categories_list/threads/index.tsx diff --git a/app/screens/home/channel_list/channel_list.tsx b/app/screens/home/channel_list/channel_list.tsx index 8b19b70a68..d25c9e1e42 100644 --- a/app/screens/home/channel_list/channel_list.tsx +++ b/app/screens/home/channel_list/channel_list.tsx @@ -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 ( + {} { iconPad={canAddOtherServers} teamsCount={props.teamsCount} /> - { } - + ); - - if (isTablet) { - return ( - - {content} - - ); - } - - return content; }; export default ChannelListScreen; diff --git a/app/screens/home/index.tsx b/app/screens/home/index.tsx index 3afa1ebb0c..d33b0d987b 100644 --- a/app/screens/home/index.tsx +++ b/app/screens/home/index.tsx @@ -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) { }} > ( diff --git a/app/screens/home/recent_mentions/recent_mentions.tsx b/app/screens/home/recent_mentions/recent_mentions.tsx index 7b08fb6200..12a7bb8d5f 100644 --- a/app/screens/home/recent_mentions/recent_mentions.tsx +++ b/app/screens/home/recent_mentions/recent_mentions.tsx @@ -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 ( - <> + - + ); }; diff --git a/app/screens/home/search/index.tsx b/app/screens/home/search/index.tsx index 3c8f0802d9..13b7745f4d 100644 --- a/app/screens/home/search/index.tsx +++ b/app/screens/home/search/index.tsx @@ -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 ( - <> + { /> - + ); }; diff --git a/app/screens/thread/thread.tsx b/app/screens/thread/thread.tsx index 0ba4bdd513..04883cbda7 100644 --- a/app/screens/thread/thread.tsx +++ b/app/screens/thread/thread.tsx @@ -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(null); return ( - <> + { } - + ); };