[Gekidou] multiple fixes (#6335)

* Fix navigation stack tracking

* Fix hardwareBackPress handlers

* Use user locale for formattedTime

* Show in-app notifications when in a thread but hide when in the same thread

* Fix post draft archived & read only safe area

* Do not show reply post option in thread screen

* Open permalink as full screen modal

* Fix crash when using chinese locale

* Fix team list and call handle team change
This commit is contained in:
Elias Nahum
2022-06-03 07:18:29 -04:00
committed by GitHub
parent 088d125792
commit 0b4980cf65
26 changed files with 179 additions and 78 deletions

View File

@@ -119,6 +119,7 @@ export const switchToThread = async (serverUrl: string, rootId: string) => {
subtitle = subtitle.replace('{channelName}', channel.displayName);
}
EphemeralStore.setLastViewedThreadId(rootId);
goToScreen(Screens.THREAD, '', {rootId}, {
topBar: {
title: {

View File

@@ -6,6 +6,8 @@ import React from 'react';
import {useIntl} from 'react-intl';
import {Text, TextProps} from 'react-native';
import {getLocaleFromLanguage} from '@i18n';
type FormattedDateProps = TextProps & {
format?: string;
timezone?: string | UserTimezone | null;
@@ -14,7 +16,7 @@ type FormattedDateProps = TextProps & {
const FormattedDate = ({format = 'MMM DD, YYYY', timezone, value, ...props}: FormattedDateProps) => {
const {locale} = useIntl();
moment.locale(locale);
moment.locale(getLocaleFromLanguage(locale).toLowerCase());
let formattedDate = moment(value).format(format);
if (timezone) {
let zone: string;

View File

@@ -3,8 +3,11 @@
import moment from 'moment-timezone';
import React from 'react';
import {useIntl} from 'react-intl';
import {Text, TextProps} from 'react-native';
import {getLocaleFromLanguage} from '@i18n';
type FormattedTimeProps = TextProps & {
isMilitaryTime: boolean;
timezone: UserTimezone | string;
@@ -12,6 +15,8 @@ type FormattedTimeProps = TextProps & {
}
const FormattedTime = ({isMilitaryTime, timezone, value, ...props}: FormattedTimeProps) => {
const {locale} = useIntl();
moment.locale(getLocaleFromLanguage(locale).toLowerCase());
const getFormattedTime = () => {
let format = 'H:mm';
if (!isMilitaryTime) {

View File

@@ -2,8 +2,8 @@
// See LICENSE.txt for license information.
import React, {useCallback} from 'react';
import {View} from 'react-native';
import Button from 'react-native-button';
import {Edge, SafeAreaView} from 'react-native-safe-area-context';
import {switchToPenultimateChannel} from '@actions/remote/channel';
import FormattedMarkdownText from '@components/formatted_markdown_text';
@@ -47,6 +47,8 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => ({
},
}));
const edges: Edge[] = ['bottom'];
export default function Archived({
testID,
deactivated,
@@ -78,7 +80,8 @@ export default function Archived({
}
return (
<View
<SafeAreaView
edges={edges}
testID={testID}
style={style.archivedWrapper}
>
@@ -98,6 +101,6 @@ export default function Archived({
style={style.closeButtonText}
/>
</Button>
</View>
</SafeAreaView>
);
}

View File

@@ -3,7 +3,7 @@
import React from 'react';
import {View} from 'react-native';
import {SafeAreaView} from 'react-native-safe-area-context';
import {Edge, SafeAreaView} from 'react-native-safe-area-context';
import CompassIcon from '@components/compass_icon';
import FormattedText from '@components/formatted_text';
@@ -40,14 +40,14 @@ const getStyle = makeStyleSheetFromTheme((theme: Theme) => ({
},
}));
const safeAreaEdges = ['bottom' as const];
const edges: Edge[] = ['bottom'];
const ReadOnlyChannnel = ({testID}: ReadOnlyProps) => {
const theme = useTheme();
const style = getStyle(theme);
return (
<SafeAreaView
edges={safeAreaEdges}
edges={edges}
style={style.background}
>
<View

View File

@@ -4,6 +4,8 @@
import React, {useCallback} from 'react';
import {useIntl} from 'react-intl';
import {handleTeamChange} from '@actions/remote/team';
import {useServerUrl} from '@context/server';
import BottomSheetContent from '@screens/bottom_sheet/content';
import {dismissBottomSheet} from '@screens/navigation';
@@ -18,15 +20,17 @@ type Props = {
export default function AddTeamSlideUp({otherTeams, showTitle = true}: Props) {
const intl = useIntl();
const serverUrl = useServerUrl();
const onPressCreate = useCallback(() => {
//TODO Create team screen https://mattermost.atlassian.net/browse/MM-43622
dismissBottomSheet();
}, []);
const onTeamAdded = useCallback(() => {
dismissBottomSheet();
}, []);
const onTeamAdded = useCallback(async (teamId: string) => {
await dismissBottomSheet();
handleTeamChange(serverUrl, teamId);
}, [serverUrl]);
return (
<BottomSheetContent

View File

@@ -69,7 +69,7 @@ export default function AddTeam({otherTeams}: Props) {
let height = CONTAINER_HEIGHT;
if (otherTeams.length) {
height = Math.min(maxHeight, HEADER_HEIGHT + (otherTeams.length * ITEM_HEIGHT));
height = Math.min(maxHeight, HEADER_HEIGHT + ((otherTeams.length + 1) * ITEM_HEIGHT));
}
bottomSheet({

View File

@@ -9,7 +9,7 @@ import TeamIcon from '@components/team_sidebar/team_list/team_item/team_icon';
import TouchableWithFeedback from '@components/touchable_with_feedback';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
import {makeStyleSheetFromTheme} from '@utils/theme';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
import type TeamModel from '@typings/database/models/servers/team';
@@ -54,8 +54,10 @@ export default function TeamListItem({team, currentUserId, textColor, iconTextCo
const styles = getStyleSheet(theme);
const serverUrl = useServerUrl();
const onPress = useCallback(async () => {
await addUserToTeam(serverUrl, team.id, currentUserId);
onTeamAdded(team.id);
const {error} = await addUserToTeam(serverUrl, team.id, currentUserId);
if (!error) {
onTeamAdded(team.id);
}
}, [onTeamAdded]);
const displayName = 'displayName' in team ? team.displayName : team.display_name;
@@ -75,13 +77,13 @@ export default function TeamListItem({team, currentUserId, textColor, iconTextCo
displayName={displayName}
lastIconUpdate={lastTeamIconUpdateAt}
selected={false}
textColor={iconTextColor}
backgroundColor={iconBackgroundColor}
textColor={iconTextColor || theme.centerChannelColor}
backgroundColor={iconBackgroundColor || changeOpacity(theme.centerChannelColor, 0.16)}
testID={`${teamListItemTestId}.team_icon`}
/>
</View>
<Text
style={[styles.text, {color: textColor}]}
style={[styles.text, textColor && {color: textColor}]}
numberOfLines={1}
>
{displayName}

View File

@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import moment from 'moment';
import moment from 'moment-timezone';
import {getLocales} from 'react-native-localize';
import en from '@assets/i18n/en.json';
@@ -149,7 +149,8 @@ function loadTranslation(locale?: string) {
}
if (momentData && locale) {
moment.updateLocale(locale.toLowerCase(), momentData);
const lang = getLocaleFromLanguage(locale).toLowerCase();
moment.updateLocale(lang, momentData);
} else {
resetMomentLocale();
}
@@ -173,10 +174,11 @@ export function getLocaleFromLanguage(lang: string) {
}
export function resetMomentLocale(locale?: string) {
moment.locale(locale || DEFAULT_LOCALE.split('-')[0]);
moment.locale(locale?.split('-')[0] || DEFAULT_LOCALE.split('-')[0]);
}
export function getTranslations(locale?: string) {
export function getTranslations(lang: string) {
const locale = getLocaleFromLanguage(lang);
return loadTranslation(locale);
}

View File

@@ -147,12 +147,13 @@ class PushNotifications {
}
const isDifferentChannel = payload?.channel_id !== channelId;
const isVisibleThread = payload?.root_id === EphemeralStore.getLastViewedThreadId() && EphemeralStore.getNavigationTopComponentId() === Screens.THREAD;
let isChannelScreenVisible = EphemeralStore.getNavigationTopComponentId() === Screens.CHANNEL;
if (isTabletDevice) {
isChannelScreenVisible = EphemeralStore.getVisibleTab() === Screens.HOME;
}
if (isDifferentChannel || !isChannelScreenVisible) {
if (isDifferentChannel || (!isChannelScreenVisible && !isVisibleThread)) {
DeviceEventEmitter.emit(Navigation.NAVIGATION_SHOW_OVERLAY);
const screen = Screens.IN_APP_NOTIFICATION;

View File

@@ -12,6 +12,7 @@ import {Events} from '@constants';
import {useTheme} from '@context/theme';
import {useIsTablet} from '@hooks/device';
import {dismissModal} from '@screens/navigation';
import EphemeralStore from '@store/ephemeral_store';
import {hapticFeedback} from '@utils/general';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
@@ -55,12 +56,15 @@ const BottomSheet = ({closeButtonId, componentId, initialSnapIndex = 0, renderCo
useEffect(() => {
const listener = BackHandler.addEventListener('hardwareBackPress', () => {
if (sheetRef.current) {
sheetRef.current.snapTo(1);
} else {
close();
if (EphemeralStore.getNavigationTopComponentId() === componentId) {
if (sheetRef.current) {
sheetRef.current.snapTo(1);
} else {
close();
}
return true;
}
return true;
return false;
});
return () => listener.remove();

View File

@@ -14,6 +14,7 @@ import {useAppState, useIsTablet} from '@hooks/device';
import {useDefaultHeaderHeight} from '@hooks/header';
import {useTeamSwitch} from '@hooks/team_switch';
import {popTopScreen} from '@screens/navigation';
import EphemeralStore from '@store/ephemeral_store';
import ChannelPostList from './channel_post_list';
import ChannelHeader from './header';
@@ -57,8 +58,12 @@ const Channel = ({channelId, componentId}: ChannelProps) => {
let back: NativeEventSubscription|undefined;
if (!isTablet && componentId) {
back = BackHandler.addEventListener('hardwareBackPress', () => {
popTopScreen(componentId);
return true;
if (EphemeralStore.getNavigationTopComponentId() === componentId) {
popTopScreen(componentId);
return true;
}
return false;
});
}

View File

@@ -23,6 +23,7 @@ import {withTheme} from '@context/theme';
import {observeConfig, observeRecentCustomStatus} from '@queries/servers/system';
import {observeCurrentUser} from '@queries/servers/user';
import {dismissModal, goToScreen, showModal} from '@screens/navigation';
import EphemeralStore from '@store/ephemeral_store';
import {getCurrentMomentForTimezone, getRoundedTime, isCustomStatusExpirySupported} from '@utils/helpers';
import {mergeNavigationOptions} from '@utils/navigation';
import {preventDoubleTap} from '@utils/tap';
@@ -164,12 +165,16 @@ class CustomStatusModal extends NavigationComponent<Props, State> {
}
onBackPress = () => {
if (this.props.isTablet) {
DeviceEventEmitter.emit(Events.ACCOUNT_SELECT_TABLET_VIEW, '');
} else {
dismissModal();
const {componentId} = this.props;
if (EphemeralStore.getNavigationTopComponentId() === componentId) {
if (this.props.isTablet) {
DeviceEventEmitter.emit(Events.ACCOUNT_SELECT_TABLET_VIEW, '');
} else {
dismissModal({componentId});
}
return true;
}
return true;
return false;
};
handleSetStatus = async () => {

View File

@@ -18,6 +18,7 @@ import {
import {CustomStatusDuration} from '@constants/custom_status';
import {observeCurrentUser} from '@queries/servers/user';
import {dismissModal, popTopScreen} from '@screens/navigation';
import EphemeralStore from '@store/ephemeral_store';
import {mergeNavigationOptions} from '@utils/navigation';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
@@ -111,24 +112,28 @@ class ClearAfterModal extends NavigationComponent<Props, State> {
}
onBackPress = () => {
if (this.props.isModal) {
dismissModal();
} else {
popTopScreen();
}
const {componentId} = this.props;
if (EphemeralStore.getNavigationTopComponentId() === componentId) {
if (this.props.isModal) {
dismissModal({componentId});
} else {
popTopScreen(componentId);
}
return true;
return true;
}
return false;
};
onDone = () => {
const {handleClearAfterClick, isModal} = this.props;
const {componentId, handleClearAfterClick, isModal} = this.props;
handleClearAfterClick(this.state.duration, this.state.expiresAt);
if (isModal) {
dismissModal();
dismissModal({componentId});
return;
}
popTopScreen();
popTopScreen(componentId);
};
handleItemClick = (duration: CustomStatusDuration, expiresAt: string) =>

View File

@@ -16,6 +16,7 @@ import {Events} from '@constants';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
import {dismissModal, popTopScreen, setButtons} from '@screens/navigation';
import EphemeralStore from '@store/ephemeral_store';
import {preventDoubleTap} from '@utils/tap';
import ProfileForm from './components/form';
@@ -104,7 +105,14 @@ const EditProfile = ({
}, [userInfo]);
useEffect(() => {
const backHandler = BackHandler.addEventListener('hardwareBackPress', close);
const backHandler = BackHandler.addEventListener('hardwareBackPress', () => {
if (EphemeralStore.getNavigationTopComponentId() === componentId) {
close();
return true;
}
return false;
});
return () => {
backHandler.remove();
};
@@ -127,8 +135,6 @@ const EditProfile = ({
} else {
popTopScreen(componentId);
}
return true;
}, []);
const enableSaveButton = useCallback((value: boolean) => {

View File

@@ -5,13 +5,13 @@ import {useManagedConfig} from '@mattermost/react-native-emm';
import {useIsFocused, useNavigation, useRoute} from '@react-navigation/native';
import React, {useCallback, useEffect} from 'react';
import {useIntl} from 'react-intl';
import {BackHandler, StyleSheet, ToastAndroid} from 'react-native';
import {BackHandler, DeviceEventEmitter, StyleSheet, ToastAndroid} from 'react-native';
import Animated, {useAnimatedStyle, withTiming} from 'react-native-reanimated';
import {Edge, SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context';
import FreezeScreen from '@components/freeze_screen';
import TeamSidebar from '@components/team_sidebar';
import {Screens} from '@constants';
import {Navigation as NavigationConstants, Screens} from '@constants';
import {useTheme} from '@context/theme';
import {useIsTablet} from '@hooks/device';
import {resetToTeams} from '@screens/navigation';
@@ -54,7 +54,9 @@ const ChannelListScreen = (props: ChannelProps) => {
const canAddOtherServers = managedConfig?.allowOtherServers !== 'false';
const handleBackPress = useCallback(() => {
const focused = navigation.isFocused() && EphemeralStore.getNavigationTopComponentId() === Screens.HOME;
const isHomeScreen = EphemeralStore.getNavigationTopComponentId() === Screens.HOME;
const homeTab = EphemeralStore.getVisibleTab() === Screens.HOME;
const focused = navigation.isFocused() && isHomeScreen && homeTab;
if (!backPressedCount && focused) {
backPressedCount++;
ToastAndroid.show(intl.formatMessage({
@@ -70,6 +72,9 @@ const ChannelListScreen = (props: ChannelProps) => {
backPressedCount = 0;
}, 2000);
return true;
} else if (isHomeScreen && !homeTab) {
DeviceEventEmitter.emit(NavigationConstants.NAVIGATION_HOME);
return true;
}
return false;
}, [intl]);

View File

@@ -103,6 +103,7 @@ export default function HomeScreen(props: HomeProps) {
>
<Tab.Navigator
screenOptions={{headerShown: false, lazy: true, unmountOnBlur: false}}
backBehavior='none'
tabBar={(tabProps: BottomTabBarProps) => (
<TabBar
{...tabProps}

View File

@@ -32,7 +32,7 @@ const withIntl = (Screen: React.ComponentType) => {
return (
<IntlProvider
locale={DEFAULT_LOCALE}
messages={getTranslations()}
messages={getTranslations(DEFAULT_LOCALE)}
>
<Screen {...props}/>
</IntlProvider>

View File

@@ -581,12 +581,11 @@ export async function dismissAllModals() {
}
try {
const modals = EphemeralStore.navigationModalStack;
const modals = [...EphemeralStore.getAllNavigationModals()];
for await (const modal of modals) {
EphemeralStore.removeNavigationModal(modal);
await Navigation.dismissModal(modal, {animations: {dismissModal: {enabled: false}}});
}
EphemeralStore.clearNavigationModals();
} catch (error) {
// RNN returns a promise rejection if there are no modals to
// dismiss. We'll do nothing in this case.

View File

@@ -4,7 +4,7 @@
import React, {useCallback, useEffect, useMemo, useState} from 'react';
import {BackHandler, Text, TouchableOpacity, View} from 'react-native';
import Animated from 'react-native-reanimated';
import {SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context';
import {Edge, SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context';
import {switchToChannelById} from '@actions/remote/channel';
import {fetchPostsAround} from '@actions/remote/post';
@@ -16,17 +16,21 @@ import {Screens} from '@constants';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
import {dismissModal} from '@screens/navigation';
import ChannelModel from '@typings/database/models/servers/channel';
import PostModel from '@typings/database/models/servers/post';
import EphemeralStore from '@store/ephemeral_store';
import {closePermalink} from '@utils/permalink';
import {preventDoubleTap} from '@utils/tap';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import type ChannelModel from '@typings/database/models/servers/channel';
import type PostModel from '@typings/database/models/servers/post';
type Props = {
postId: PostModel['id'];
channel?: ChannelModel;
}
const edges: Edge[] = ['left', 'right', 'top'];
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
container: {
flex: 1,
@@ -145,8 +149,12 @@ function Permalink({channel, postId}: Props) {
useEffect(() => {
const listener = BackHandler.addEventListener('hardwareBackPress', () => {
handleClose();
return true;
if (EphemeralStore.getNavigationTopComponentId() === Screens.PERMALINK) {
handleClose();
return true;
}
return false;
});
return () => {
@@ -164,6 +172,7 @@ function Permalink({channel, postId}: Props) {
<SafeAreaView
style={containerStyle}
testID='permalink.screen'
edges={edges}
>
<Animated.View style={style.wrapper}>
<View style={style.header}>

View File

@@ -81,7 +81,7 @@ const PostOptions = ({
return (
<>
{canAddReaction && <ReactionBar postId={post.id}/>}
{canReply && <ReplyOption post={post}/>}
{canReply && sourceScreen !== Screens.THREAD && <ReplyOption post={post}/>}
{shouldRenderFollow &&
<FollowThreadOption thread={thread}/>
}

View File

@@ -16,6 +16,7 @@ import {Events, Screens} from '@constants';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
import {dismissModal} from '@screens/navigation';
import EphemeralStore from '@store/ephemeral_store';
import {isDateLine, getDateForDateLine, selectOrderedPosts} from '@utils/post_list';
import EmptyState from './components/empty';
@@ -72,10 +73,7 @@ function SavedMessages({
const close = () => {
if (componentId) {
dismissModal({componentId});
return true;
}
return false;
};
useEffect(() => {
@@ -106,7 +104,14 @@ function SavedMessages({
useEffect(() => {
let listener: EventSubscription|undefined;
if (!isTablet && componentId) {
listener = BackHandler.addEventListener('hardwareBackPress', close);
listener = BackHandler.addEventListener('hardwareBackPress', () => {
if (EphemeralStore.getNavigationTopComponentId() === componentId) {
close();
return true;
}
return false;
});
}
return () => listener?.remove();

View File

@@ -12,6 +12,7 @@ import {Screens} from '@constants';
import {useServerDisplayName} from '@context/server';
import {useTheme} from '@context/theme';
import {dismissModal, goToScreen, setButtons} from '@screens/navigation';
import EphemeralStore from '@store/ephemeral_store';
import {preventDoubleTap} from '@utils/tap';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
@@ -84,8 +85,6 @@ const Settings = ({componentId, showHelp, siteName}: SettingsProps) => {
const close = useCallback(() => {
dismissModal({componentId});
return true;
}, []);
useEffect(() => {
@@ -95,7 +94,14 @@ const Settings = ({componentId, showHelp, siteName}: SettingsProps) => {
}, []);
useEffect(() => {
const backHandler = BackHandler.addEventListener('hardwareBackPress', close);
const backHandler = BackHandler.addEventListener('hardwareBackPress', () => {
if (EphemeralStore.getNavigationTopComponentId() === componentId) {
close();
return true;
}
return false;
});
return () => {
backHandler.remove();
};

View File

@@ -21,6 +21,7 @@ class EphemeralStore {
private leavingChannels = new Set<string>();
private archivingChannels = new Set<string>();
private convertingChannels = new Set<string>();
private lastViewedThreadId = '';
addNavigationComponentId = (componentId: string) => {
this.addToNavigationComponentIdStack(componentId);
@@ -36,7 +37,7 @@ class EphemeralStore {
addToNavigationComponentIdStack = (componentId: string) => {
const index = this.navigationComponentIdStack.indexOf(componentId);
if (index >= 0) {
this.navigationComponentIdStack = this.navigationComponentIdStack.slice(index, 1);
this.navigationComponentIdStack.splice(index, 1);
}
this.navigationComponentIdStack.unshift(componentId);
@@ -58,6 +59,8 @@ class EphemeralStore {
getAllNavigationComponents = () => this.allNavigationComponentIds;
getAllNavigationModals = () => this.navigationModalStack;
getNavigationTopComponentId = () => {
return this.navigationComponentIdStack[0];
};
@@ -90,7 +93,7 @@ class EphemeralStore {
};
removeNavigationModal = (componentId: string) => {
this.removeNavigationComponent(componentId);
this.removeNavigationComponentId(componentId);
const index = this.navigationModalStack.indexOf(componentId);
if (index >= 0) {
@@ -209,6 +212,15 @@ class EphemeralStore {
getPushProxyVerificationState = (serverUrl: string) => {
return this.pushProxyVerification[serverUrl];
};
// Ephemeral for the last viewed thread
getLastViewedThreadId = () => {
return this.lastViewedThreadId;
};
setLastViewedThreadId = (id: string) => {
this.lastViewedThreadId = id;
};
}
export default new EphemeralStore();

View File

@@ -2,6 +2,7 @@
// See LICENSE.txt for license information.
import {Keyboard} from 'react-native';
import {OptionsModalPresentationStyle} from 'react-native-navigation';
import {dismissAllModals, showModalOverCurrentContext} from '@screens/navigation';
import {changeOpacity} from '@utils/theme';
@@ -22,6 +23,7 @@ export const displayPermalink = async (teamName: string, postId: string, openAsP
};
const options = {
modalPresentationStyle: OptionsModalPresentationStyle.fullScreen,
layout: {
componentBackgroundColor: changeOpacity('#000', 0.2),
},

View File

@@ -4,7 +4,7 @@
import {DeviceEventEmitter, LogBox} from 'react-native';
import {RUNNING_E2E} from 'react-native-dotenv';
import 'react-native-gesture-handler';
import {ComponentDidAppearEvent, ComponentDidDisappearEvent, Navigation} from 'react-native-navigation';
import {ComponentDidAppearEvent, ComponentDidDisappearEvent, ModalDismissedEvent, Navigation, ScreenPoppedEvent} from 'react-native-navigation';
import {Events, Screens} from './app/constants';
import DatabaseManager from './app/database/manager';
@@ -75,12 +75,14 @@ Navigation.events().registerAppLaunchedListener(async () => {
});
const registerNavigationListeners = () => {
Navigation.events().registerComponentDidAppearListener(componentDidAppearListener);
Navigation.events().registerComponentDidDisappearListener(componentDidDisappearListener);
Navigation.events().registerComponentWillAppearListener(componentWillAppear);
Navigation.events().registerComponentDidAppearListener(screenDidAppearListener);
Navigation.events().registerComponentDidDisappearListener(screenDidDisappearListener);
Navigation.events().registerComponentWillAppearListener(screenWillAppear);
Navigation.events().registerScreenPoppedListener(screenPoppedListener);
Navigation.events().registerModalDismissedListener(modalDismissedListener);
};
function componentWillAppear({componentId}: ComponentDidAppearEvent) {
function screenWillAppear({componentId}: ComponentDidAppearEvent) {
if (componentId === Screens.HOME) {
DeviceEventEmitter.emit(Events.TAB_BAR_VISIBLE, true);
} else if ([Screens.EDIT_POST, Screens.THREAD].includes(componentId)) {
@@ -88,16 +90,14 @@ function componentWillAppear({componentId}: ComponentDidAppearEvent) {
}
}
function componentDidAppearListener({componentId, passProps}: ComponentDidAppearEvent) {
if (!(passProps as any)?.overlay) {
function screenDidAppearListener({componentId, passProps, componentType}: ComponentDidAppearEvent) {
if (!(passProps as any)?.overlay && componentType === 'Component') {
EphemeralStore.addNavigationComponentId(componentId);
}
}
function componentDidDisappearListener({componentId}: ComponentDidDisappearEvent) {
function screenDidDisappearListener({componentId}: ComponentDidDisappearEvent) {
if (componentId !== Screens.HOME) {
EphemeralStore.removeNavigationComponentId(componentId);
if ([Screens.EDIT_POST, Screens.THREAD].includes(componentId)) {
DeviceEventEmitter.emit(Events.PAUSE_KEYBOARD_TRACKING_VIEW, false);
}
@@ -107,3 +107,20 @@ function componentDidDisappearListener({componentId}: ComponentDidDisappearEvent
}
}
}
function screenPoppedListener({componentId}: ScreenPoppedEvent) {
EphemeralStore.removeNavigationComponentId(componentId);
if (EphemeralStore.getNavigationTopComponentId() === Screens.HOME) {
DeviceEventEmitter.emit(Events.TAB_BAR_VISIBLE, true);
}
}
function modalDismissedListener({componentId}: ModalDismissedEvent) {
const topScreen = EphemeralStore.getNavigationTopComponentId();
const topModal = EphemeralStore.getNavigationTopModalId();
const toRemove = topScreen === topModal ? topModal : componentId;
EphemeralStore.removeNavigationModal(toRemove);
if (EphemeralStore.getNavigationTopComponentId() === Screens.HOME) {
DeviceEventEmitter.emit(Events.TAB_BAR_VISIBLE, true);
}
}