forked from Ivasoft/mattermost-mobile
Fix theming and navigation stack tracking (#6443)
This commit is contained in:
@@ -37,7 +37,6 @@ const InfoBox = ({channelId, containerStyle, showAsLabel = false, testID}: Props
|
||||
testID: 'close.channel_info.button',
|
||||
}],
|
||||
},
|
||||
modal: {swipeToDismiss: false},
|
||||
};
|
||||
showModal(Screens.CHANNEL_INFO, title, {channelId, closeButtonId}, options);
|
||||
}, [intl, channelId, theme]);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import React from 'react';
|
||||
import {Text, TextStyle} from 'react-native';
|
||||
|
||||
import {popToRoot, showSearchModal, dismissAllModals} from '@screens/navigation';
|
||||
import {popToRoot, dismissAllModals} from '@screens/navigation';
|
||||
|
||||
type HashtagProps = {
|
||||
hashtag: string;
|
||||
@@ -17,7 +17,7 @@ const Hashtag = ({hashtag, linkStyle}: HashtagProps) => {
|
||||
await dismissAllModals();
|
||||
await popToRoot();
|
||||
|
||||
showSearchModal('#' + hashtag);
|
||||
// showSearchModal('#' + hashtag);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -120,7 +120,7 @@ const Reactions = ({currentUserId, canAddReaction, canRemoveReaction, disabled,
|
||||
onEmojiPress: handleAddReactionToPost,
|
||||
};
|
||||
|
||||
showModal(Screens.EMOJI_PICKER, title, passProps, {modal: {swipeToDismiss: false}});
|
||||
showModal(Screens.EMOJI_PICKER, title, passProps);
|
||||
}), [intl, theme]);
|
||||
|
||||
const handleReactionPress = useCallback(async (emoji: string, remove: boolean) => {
|
||||
|
||||
@@ -117,7 +117,7 @@ export default {
|
||||
USER_PROFILE,
|
||||
};
|
||||
|
||||
export const MODAL_SCREENS_WITHOUT_BACK = [
|
||||
export const MODAL_SCREENS_WITHOUT_BACK = new Set<string>([
|
||||
BROWSE_CHANNELS,
|
||||
CHANNEL_INFO,
|
||||
CREATE_DIRECT_MESSAGE,
|
||||
@@ -131,7 +131,17 @@ export const MODAL_SCREENS_WITHOUT_BACK = [
|
||||
GALLERY,
|
||||
PERMALINK,
|
||||
REACTIONS,
|
||||
];
|
||||
]);
|
||||
|
||||
export const SCREENS_WITH_TRANSPARENT_BACKGROUND = new Set<string>([
|
||||
BOTTOM_SHEET,
|
||||
POST_OPTIONS,
|
||||
THREAD_OPTIONS,
|
||||
PERMALINK,
|
||||
REACTIONS,
|
||||
SNACK_BAR,
|
||||
USER_PROFILE,
|
||||
]);
|
||||
|
||||
export const NOT_READY = [
|
||||
CHANNEL_ADD_PEOPLE,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import withObservables from '@nozbe/with-observables';
|
||||
import React, {ComponentType, createContext, useEffect} from 'react';
|
||||
import React, {ComponentType, createContext, useEffect, useState} from 'react';
|
||||
import {Appearance} from 'react-native';
|
||||
|
||||
import {Preferences} from '@constants';
|
||||
@@ -33,35 +33,43 @@ export function getDefaultThemeByAppearance(): Theme {
|
||||
export const ThemeContext = createContext(getDefaultThemeByAppearance());
|
||||
const {Consumer, Provider} = ThemeContext;
|
||||
|
||||
const ThemeProvider = ({currentTeamId, children, themes}: Props) => {
|
||||
const getTheme = (): Theme => {
|
||||
if (currentTeamId) {
|
||||
const teamTheme = themes.find((t) => t.name === currentTeamId) || themes[0];
|
||||
if (teamTheme?.value) {
|
||||
try {
|
||||
const theme = setThemeDefaults(JSON.parse(teamTheme.value));
|
||||
updateThemeIfNeeded(theme);
|
||||
|
||||
return theme;
|
||||
} catch {
|
||||
// no theme change
|
||||
}
|
||||
const getTheme = (teamId: string | undefined, themes: PreferenceModel[]): Theme => {
|
||||
if (teamId) {
|
||||
const teamTheme = themes.find((t) => t.name === teamId) || themes[0];
|
||||
if (teamTheme?.value) {
|
||||
try {
|
||||
const theme = setThemeDefaults(JSON.parse(teamTheme.value));
|
||||
return theme;
|
||||
} catch {
|
||||
// no theme change
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const defaultTheme = getDefaultThemeByAppearance();
|
||||
updateThemeIfNeeded(defaultTheme);
|
||||
const defaultTheme = getDefaultThemeByAppearance();
|
||||
|
||||
return defaultTheme;
|
||||
};
|
||||
return defaultTheme;
|
||||
};
|
||||
|
||||
const ThemeProvider = ({currentTeamId, children, themes}: Props) => {
|
||||
const [theme, setTheme] = useState(() => getTheme(currentTeamId, themes));
|
||||
|
||||
useEffect(() => {
|
||||
const listener = Appearance.addChangeListener(getTheme);
|
||||
const listener = Appearance.addChangeListener(() => {
|
||||
const newTheme = getTheme(currentTeamId, themes);
|
||||
if (theme !== newTheme) {
|
||||
setTheme(newTheme);
|
||||
}
|
||||
});
|
||||
|
||||
return () => listener.remove();
|
||||
}, []);
|
||||
}, [currentTeamId, themes, theme]);
|
||||
|
||||
return (<Provider value={getTheme()}>{children}</Provider>);
|
||||
useEffect(() => {
|
||||
updateThemeIfNeeded(theme);
|
||||
}, [theme]);
|
||||
|
||||
return (<Provider value={theme}>{children}</Provider>);
|
||||
};
|
||||
|
||||
export function withTheme<T extends WithThemeProps>(Component: ComponentType<T>): ComponentType<T> {
|
||||
|
||||
@@ -114,7 +114,6 @@ const ChannelHeader = ({
|
||||
testID: 'close.channel_info.button',
|
||||
}],
|
||||
},
|
||||
modal: {swipeToDismiss: false},
|
||||
};
|
||||
showModal(Screens.CHANNEL_INFO, title, {channelId, closeButtonId}, options);
|
||||
}), [channelId, channelType, intl, theme]);
|
||||
|
||||
@@ -284,7 +284,7 @@ class CustomStatusModal extends NavigationComponent<Props, State> {
|
||||
const title = intl.formatMessage({id: 'mobile.custom_status.choose_emoji', defaultMessage: 'Choose an emoji'});
|
||||
const passProps = {closeButton: source, onEmojiPress: this.handleEmojiClick};
|
||||
|
||||
showModal(screen, title, passProps, {modal: {swipeToDismiss: false}});
|
||||
showModal(screen, title, passProps);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -43,14 +43,14 @@ const QuickOptions = ({canCreateChannels, canJoinChannels, close}: Props) => {
|
||||
await close();
|
||||
showModal(Screens.BROWSE_CHANNELS, title, {
|
||||
closeButton,
|
||||
}, {modal: {swipeToDismiss: false}});
|
||||
});
|
||||
}, [intl, theme]);
|
||||
|
||||
const createNewChannel = useCallback(async () => {
|
||||
const title = intl.formatMessage({id: 'mobile.create_channel.title', defaultMessage: 'New channel'});
|
||||
|
||||
await close();
|
||||
showModal(Screens.CREATE_OR_EDIT_CHANNEL, title, undefined, {modal: {swipeToDismiss: false}});
|
||||
showModal(Screens.CREATE_OR_EDIT_CHANNEL, title);
|
||||
}, [intl]);
|
||||
|
||||
const openDirectMessage = useCallback(async () => {
|
||||
@@ -60,7 +60,7 @@ const QuickOptions = ({canCreateChannels, canJoinChannels, close}: Props) => {
|
||||
await close();
|
||||
showModal(Screens.CREATE_DIRECT_MESSAGE, title, {
|
||||
closeButton,
|
||||
}, {modal: {swipeToDismiss: false}});
|
||||
});
|
||||
}, [intl, theme]);
|
||||
|
||||
return (
|
||||
|
||||
@@ -28,14 +28,14 @@ const PlusMenuList = ({canCreateChannels, canJoinChannels}: Props) => {
|
||||
|
||||
showModal(Screens.BROWSE_CHANNELS, title, {
|
||||
closeButton,
|
||||
}, {modal: {swipeToDismiss: false}});
|
||||
});
|
||||
}, [intl, theme]);
|
||||
|
||||
const createNewChannel = useCallback(async () => {
|
||||
await dismissBottomSheet();
|
||||
|
||||
const title = intl.formatMessage({id: 'mobile.create_channel.title', defaultMessage: 'New channel'});
|
||||
showModal(Screens.CREATE_OR_EDIT_CHANNEL, title, undefined, {modal: {swipeToDismiss: false}});
|
||||
showModal(Screens.CREATE_OR_EDIT_CHANNEL, title);
|
||||
}, [intl]);
|
||||
|
||||
const openDirectMessage = useCallback(async () => {
|
||||
@@ -45,7 +45,7 @@ const PlusMenuList = ({canCreateChannels, canJoinChannels}: Props) => {
|
||||
const closeButton = await CompassIcon.getImageSource('close', 24, theme.sidebarHeaderTextColor);
|
||||
showModal(Screens.CREATE_DIRECT_MESSAGE, title, {
|
||||
closeButton,
|
||||
}, {modal: {swipeToDismiss: false}});
|
||||
});
|
||||
}, [intl, theme]);
|
||||
|
||||
return (
|
||||
|
||||
@@ -84,9 +84,6 @@ export const bottomSheetModalOptions = (theme: Theme, closeButtonId?: string) =>
|
||||
const closeButtonTestId = `${closeButtonId.replace('close-', 'close.').replace(/-/g, '_')}.button`;
|
||||
return {
|
||||
modalPresentationStyle: OptionsModalPresentationStyle.formSheet,
|
||||
modal: {
|
||||
swipeToDismiss: true,
|
||||
},
|
||||
topBar: {
|
||||
leftButtons: [{
|
||||
id: closeButtonId,
|
||||
@@ -117,7 +114,6 @@ export const bottomSheetModalOptions = (theme: Theme, closeButtonId?: string) =>
|
||||
ios: OptionsModalPresentationStyle.overFullScreen,
|
||||
default: OptionsModalPresentationStyle.overCurrentContext,
|
||||
}),
|
||||
modal: {swipeToDismiss: true},
|
||||
statusBar: {
|
||||
backgroundColor: null,
|
||||
drawBehind: true,
|
||||
@@ -465,6 +461,7 @@ export function showModal(name: string, title: string, passProps = {}, options =
|
||||
leftButtonColor: theme.sidebarHeaderTextColor,
|
||||
rightButtonColor: theme.sidebarHeaderTextColor,
|
||||
},
|
||||
modal: {swipeToDismiss: false},
|
||||
};
|
||||
|
||||
NavigationStore.addNavigationModal(name);
|
||||
@@ -544,25 +541,6 @@ export function showModalOverCurrentContext(name: string, passProps = {}, option
|
||||
showModal(name, title, passProps, mergeOptions);
|
||||
}
|
||||
|
||||
export function showSearchModal(initialValue = '') {
|
||||
const name = 'Search';
|
||||
const title = '';
|
||||
const passProps = {initialValue};
|
||||
const options = {
|
||||
topBar: {
|
||||
visible: false,
|
||||
height: 0,
|
||||
},
|
||||
...Platform.select({
|
||||
ios: {
|
||||
modalPresentationStyle: 'pageSheet',
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
showModal(name, title, passProps, options);
|
||||
}
|
||||
|
||||
export async function dismissModal(options?: Options & { componentId: string}) {
|
||||
if (!NavigationStore.hasModalsOpened()) {
|
||||
return;
|
||||
@@ -717,7 +695,7 @@ export const showAppForm = async (form: AppForm, call: AppCallRequest) => {
|
||||
};
|
||||
|
||||
export async function findChannels(title: string, theme: Theme) {
|
||||
const options: Options = {modal: {swipeToDismiss: false}};
|
||||
const options: Options = {};
|
||||
const closeButtonId = 'close-find-channels';
|
||||
const closeButton = CompassIcon.getImageSourceSync('close', 24, theme.sidebarHeaderTextColor);
|
||||
options.topBar = {
|
||||
|
||||
@@ -29,7 +29,6 @@ const EditOption = ({post, canDelete}: Props) => {
|
||||
const closeButtonId = 'close-edit-post';
|
||||
const passProps = {post, closeButtonId, canDelete};
|
||||
const options = {
|
||||
modal: {swipeToDismiss: false},
|
||||
topBar: {
|
||||
leftButtons: [{
|
||||
id: closeButtonId,
|
||||
|
||||
@@ -62,7 +62,7 @@ const ReactionBar = ({recentEmojis = [], postId}: QuickReactionProps) => {
|
||||
const title = intl.formatMessage({id: 'mobile.post_info.add_reaction', defaultMessage: 'Add Reaction'});
|
||||
const passProps = {closeButton, onEmojiPress: handleEmojiPress};
|
||||
|
||||
showModal(screen, title, passProps, {modal: {swipeToDismiss: false}});
|
||||
showModal(screen, title, passProps);
|
||||
}, [intl, theme]);
|
||||
|
||||
let containerSize = LARGE_CONTAINER_SIZE;
|
||||
|
||||
@@ -241,7 +241,6 @@ function buildServerModalOptions(theme: Theme, closeButtonId: string) {
|
||||
backgroundColor: theme.centerChannelBg,
|
||||
componentBackgroundColor: theme.centerChannelBg,
|
||||
},
|
||||
modal: {swipeToDismiss: false},
|
||||
topBar: {
|
||||
visible: true,
|
||||
drawBehind: true,
|
||||
|
||||
@@ -6,7 +6,7 @@ import {StatusBar, StyleSheet} from 'react-native';
|
||||
import tinyColor from 'tinycolor2';
|
||||
|
||||
import {Preferences} from '@constants';
|
||||
import {MODAL_SCREENS_WITHOUT_BACK} from '@constants/screens';
|
||||
import {MODAL_SCREENS_WITHOUT_BACK, SCREENS_WITH_TRANSPARENT_BACKGROUND} from '@constants/screens';
|
||||
import EphemeralStore from '@store/ephemeral_store';
|
||||
import NavigationStore from '@store/navigation_store';
|
||||
import {appearanceControlledScreens, mergeNavigationOptions} from '@utils/navigation';
|
||||
@@ -96,12 +96,15 @@ export function setNavigatorStyles(componentId: string, theme: Theme, additional
|
||||
backgroundColor: theme.sidebarBg,
|
||||
style: isDark ? 'light' : 'dark',
|
||||
},
|
||||
layout: {
|
||||
componentBackgroundColor: theme.centerChannelBg,
|
||||
},
|
||||
};
|
||||
|
||||
if (!MODAL_SCREENS_WITHOUT_BACK.includes(componentId) && options.topBar) {
|
||||
if (!SCREENS_WITH_TRANSPARENT_BACKGROUND.has(componentId)) {
|
||||
options.layout = {
|
||||
componentBackgroundColor: theme.centerChannelBg,
|
||||
};
|
||||
}
|
||||
|
||||
if (!MODAL_SCREENS_WITHOUT_BACK.has(componentId) && options.topBar) {
|
||||
options.topBar.backButton = {
|
||||
color: theme.sidebarHeaderTextColor,
|
||||
};
|
||||
|
||||
@@ -332,7 +332,6 @@ jest.mock('@screens/navigation', () => ({
|
||||
popTopScreen: jest.fn(),
|
||||
showModal: jest.fn(),
|
||||
showModalOverCurrentContext: jest.fn(),
|
||||
showSearchModal: jest.fn(),
|
||||
setButtons: jest.fn(),
|
||||
showOverlay: jest.fn(),
|
||||
mergeNavigationOptions: jest.fn(),
|
||||
|
||||
Reference in New Issue
Block a user