From fe04faac644a1b1b319e086f654d4f88dece5ab1 Mon Sep 17 00:00:00 2001 From: Gleidson Daniel Silva Date: Fri, 30 Sep 2022 11:50:33 -0300 Subject: [PATCH] Chore: Migrate SettingsView to hooks (#4542) * migrate settings view to hooks * temp - add non-null assertion * fix options * Update app/views/SettingsView/index.tsx Co-authored-by: Reinaldo Neto <47038980+reinaldonetof@users.noreply.github.com> * Update app/views/SettingsView/index.tsx Co-authored-by: Reinaldo Neto <47038980+reinaldonetof@users.noreply.github.com> * fix options Co-authored-by: Reinaldo Neto <47038980+reinaldonetof@users.noreply.github.com> --- app/stacks/InsideStack.tsx | 2 +- app/stacks/MasterDetailStack/index.tsx | 6 +- app/views/SettingsView/index.tsx | 347 ++++++++++++------------- app/views/SidebarView/index.tsx | 34 +-- 4 files changed, 183 insertions(+), 206 deletions(-) diff --git a/app/stacks/InsideStack.tsx b/app/stacks/InsideStack.tsx index 68a3bebd4..0b6475640 100644 --- a/app/stacks/InsideStack.tsx +++ b/app/stacks/InsideStack.tsx @@ -165,7 +165,7 @@ const SettingsStackNavigator = () => { - + { component={ReadReceiptsView} options={props => ReadReceiptsView.navigationOptions!({ ...props, isMasterDetail: true })} /> - SettingsView.navigationOptions!({ ...props, isMasterDetail: true })} - /> + diff --git a/app/views/SettingsView/index.tsx b/app/views/SettingsView/index.tsx index e98fe394e..623b5ec17 100644 --- a/app/views/SettingsView/index.tsx +++ b/app/views/SettingsView/index.tsx @@ -1,62 +1,66 @@ -import CookieManager from '@react-native-cookies/cookies'; -import { StackNavigationOptions } from '@react-navigation/stack'; -import FastImage from 'react-native-fast-image'; -import React from 'react'; -import { Linking, Share } from 'react-native'; import Clipboard from '@react-native-clipboard/clipboard'; -import { connect } from 'react-redux'; +import CookieManager from '@react-native-cookies/cookies'; +import { useNavigation } from '@react-navigation/native'; +import React, { useLayoutEffect } from 'react'; +import { Linking, Share } from 'react-native'; +import FastImage from 'react-native-fast-image'; +import { useDispatch } from 'react-redux'; +import { StackNavigationProp } from '@react-navigation/stack'; import { appStart } from '../../actions/app'; import { logout } from '../../actions/login'; import { selectServerRequest } from '../../actions/server'; -import { APP_STORE_LINK, FDROID_MARKET_LINK, LICENSE_LINK, PLAY_MARKET_LINK, isFDroidBuild, themes } from '../../lib/constants'; import * as HeaderButton from '../../containers/HeaderButton'; import * as List from '../../containers/List'; import SafeAreaView from '../../containers/SafeAreaView'; import StatusBar from '../../containers/StatusBar'; import { LISTENER } from '../../containers/Toast'; -import { IApplicationState, IBaseScreen, IUser, RootEnum } from '../../definitions'; +import { RootEnum } from '../../definitions'; import I18n from '../../i18n'; +import { APP_STORE_LINK, FDROID_MARKET_LINK, isFDroidBuild, LICENSE_LINK, PLAY_MARKET_LINK } from '../../lib/constants'; import database from '../../lib/database'; -import { IServer } from '../../reducers/server'; -import { getUserSelector } from '../../selectors/login'; -import { SettingsStackParamList } from '../../stacks/types'; -import { withTheme } from '../../theme'; +import { useAppSelector } from '../../lib/hooks'; +import { clearCache } from '../../lib/methods'; +import { deleteAllAudioFiles } from '../../lib/methods/audioFile'; import { getDeviceModel, getReadableVersion, isAndroid } from '../../lib/methods/helpers'; import EventEmitter from '../../lib/methods/helpers/events'; import { showConfirmationAlert, showErrorAlert } from '../../lib/methods/helpers/info'; import { events, logEvent } from '../../lib/methods/helpers/log'; import openLink from '../../lib/methods/helpers/openLink'; import { onReviewPress } from '../../lib/methods/helpers/review'; -import SidebarView from '../SidebarView'; -import { clearCache } from '../../lib/methods'; import { Services } from '../../lib/services'; -import { deleteAllAudioFiles } from '../../lib/methods/audioFile'; +import { getUserSelector } from '../../selectors/login'; +import { SettingsStackParamList } from '../../stacks/types'; +import { useTheme } from '../../theme'; +import SidebarView from '../SidebarView'; type TLogScreenName = 'SE_GO_LANGUAGE' | 'SE_GO_DEFAULTBROWSER' | 'SE_GO_THEME' | 'SE_GO_PROFILE' | 'SE_GO_SECURITYPRIVACY'; -interface ISettingsViewProps extends IBaseScreen { - server: IServer; - user: IUser; -} +const SettingsView = (): React.ReactElement => { + const { colors, theme } = useTheme(); + const navigation = useNavigation>(); + const dispatch = useDispatch(); + const isMasterDetail = useAppSelector(state => state.app.isMasterDetail); + const userId = useAppSelector(state => getUserSelector(state).id); + const { server, version } = useAppSelector(state => state.server); -class SettingsView extends React.Component { - static navigationOptions = ({ navigation, isMasterDetail }: ISettingsViewProps): StackNavigationOptions => ({ - headerLeft: () => - isMasterDetail ? ( - - ) : ( - - ), - title: I18n.t('Settings') - }); + useLayoutEffect(() => { + navigation.setOptions({ + headerLeft: () => + isMasterDetail ? ( + + ) : ( + + ), + title: I18n.t('Settings') + }); + }, [navigation, isMasterDetail]); - checkCookiesAndLogout = async () => { - const { dispatch, user } = this.props; + const checkCookiesAndLogout = async () => { const db = database.servers; const usersCollection = db.get('users'); try { - const userRecord = await usersCollection.find(user.id); + const userRecord = await usersCollection.find(userId); if (userRecord.isFromWebView) { showConfirmationAlert({ title: I18n.t('Clear_cookies_alert'), @@ -79,25 +83,21 @@ class SettingsView extends React.Component { } }; - handleLogout = () => { + const handleLogout = () => { logEvent(events.SE_LOG_OUT); showConfirmationAlert({ message: I18n.t('You_will_be_logged_out_of_this_application'), confirmationText: I18n.t('Logout'), - onPress: this.checkCookiesAndLogout + onPress: checkCookiesAndLogout }); }; - handleClearCache = () => { + const handleClearCache = () => { logEvent(events.SE_CLEAR_LOCAL_SERVER_CACHE); showConfirmationAlert({ message: I18n.t('This_will_clear_all_your_offline_data'), confirmationText: I18n.t('Clear'), onPress: async () => { - const { - server: { server }, - dispatch - } = this.props; dispatch(appStart({ root: RootEnum.ROOT_LOADING, text: I18n.t('Clear_cache_loading') })); await deleteAllAudioFiles(server); await clearCache({ server }); @@ -109,14 +109,13 @@ class SettingsView extends React.Component { }); }; - navigateToScreen = (screen: keyof SettingsStackParamList) => { + const navigateToScreen = (screen: keyof SettingsStackParamList) => { const screenName = screen.replace('View', '').toUpperCase(); logEvent(events[`SE_GO_${screenName}` as TLogScreenName]); - const { navigation } = this.props; navigation.navigate(screen); }; - sendEmail = async () => { + const sendEmail = async () => { logEvent(events.SE_CONTACT_US); const subject = encodeURI('Rocket.Chat Mobile App Support'); const email = encodeURI('support@rocket.chat'); @@ -132,7 +131,7 @@ class SettingsView extends React.Component { } }; - shareApp = () => { + const shareApp = () => { let message; if (isAndroid) { message = PLAY_MARKET_LINK; @@ -145,157 +144,139 @@ class SettingsView extends React.Component { Share.share({ message }); }; - copyServerVersion = () => { - const { - server: { version } - } = this.props; - const vers = version as string; - logEvent(events.SE_COPY_SERVER_VERSION, { serverVersion: vers }); - this.saveToClipboard(vers); - }; - - copyAppVersion = () => { - logEvent(events.SE_COPY_APP_VERSION, { appVersion: getReadableVersion }); - this.saveToClipboard(getReadableVersion); - }; - - saveToClipboard = async (content: string) => { + const saveToClipboard = async (content: string) => { await Clipboard.setString(content); EventEmitter.emit(LISTENER, { message: I18n.t('Copied_to_clipboard') }); }; - onPressLicense = () => { + const copyServerVersion = () => { + const vers = version as string; + logEvent(events.SE_COPY_SERVER_VERSION, { serverVersion: vers }); + saveToClipboard(vers); + }; + + const copyAppVersion = () => { + logEvent(events.SE_COPY_APP_VERSION, { appVersion: getReadableVersion }); + saveToClipboard(getReadableVersion); + }; + + const onPressLicense = () => { logEvent(events.SE_READ_LICENSE); - const { theme } = this.props; openLink(LICENSE_LINK, theme); }; - render() { - const { server, isMasterDetail, theme } = this.props; - return ( - - - - {isMasterDetail ? ( + return ( + + + + {isMasterDetail ? ( + <> + + + + + + + + navigateToScreen('DisplayPrefsView')} showActionIndicator /> + + navigateToScreen('ProfileView')} + showActionIndicator + testID='settings-profile' + /> + + + + ) : null} + + + + + + navigateToScreen('LanguageView')} + showActionIndicator + testID='settings-view-language' + /> + + {!isFDroidBuild ? ( <> - - - - - - - - this.navigateToScreen('DisplayPrefsView')} showActionIndicator /> - - this.navigateToScreen('ProfileView')} - showActionIndicator - testID='settings-profile' - /> - - + ) : null} + + + + navigateToScreen('DefaultBrowserView')} + testID='settings-view-default-browser' + /> + + navigateToScreen('ThemeView')} + testID='settings-view-theme' + /> + + navigateToScreen('SecurityPrivacyView')} + testID='settings-view-security-privacy' + /> + + - - - - - this.navigateToScreen('LanguageView')} - showActionIndicator - testID='settings-view-language' - /> - - {!isFDroidBuild ? ( - <> - - - ) : null} - - - - this.navigateToScreen('DefaultBrowserView')} - testID='settings-view-default-browser' - /> - - this.navigateToScreen('ThemeView')} - testID='settings-view-theme' - /> - - this.navigateToScreen('SecurityPrivacyView')} - testID='settings-view-security-privacy' - /> - - + + + + + + + + + - - - - - - - - - + + + + + + + + + + ); +}; - - - - - - - - - - ); - } -} - -const mapStateToProps = (state: IApplicationState) => ({ - server: state.server, - user: getUserSelector(state), - isMasterDetail: state.app.isMasterDetail -}); - -export default connect(mapStateToProps)(withTheme(SettingsView)); +export default SettingsView; diff --git a/app/views/SidebarView/index.tsx b/app/views/SidebarView/index.tsx index 028584ecd..068d9257e 100644 --- a/app/views/SidebarView/index.tsx +++ b/app/views/SidebarView/index.tsx @@ -32,7 +32,7 @@ interface ISidebarProps { state?: DrawerNavigationState; Site_Name: string; user: IUser; - theme: TSupportedThemes; + theme?: TSupportedThemes; loadingServer: boolean; useRealName: boolean; allowStatusMessage: boolean; @@ -167,10 +167,10 @@ class Sidebar extends Component { } + left={} onPress={() => this.sidebarNavigate(routeName)} testID='sidebar-admin' - theme={theme} + theme={theme!} current={this.currentItemKey === routeName} /> @@ -183,34 +183,34 @@ class Sidebar extends Component { <> } + left={} onPress={() => this.sidebarNavigate('ChatsStackNavigator')} testID='sidebar-chats' - theme={theme} + theme={theme!} current={this.currentItemKey === 'ChatsStackNavigator'} /> } + left={} onPress={() => this.sidebarNavigate('ProfileStackNavigator')} testID='sidebar-profile' - theme={theme} + theme={theme!} current={this.currentItemKey === 'ProfileStackNavigator'} /> } + left={} onPress={() => this.sidebarNavigate('DisplayPrefStackNavigator')} testID='sidebar-display' - theme={theme} + theme={theme!} current={this.currentItemKey === 'DisplayPrefStackNavigator'} /> } + left={} onPress={() => this.sidebarNavigate('SettingsStackNavigator')} testID='sidebar-settings' - theme={theme} + theme={theme!} current={this.currentItemKey === 'SettingsStackNavigator'} /> {this.renderAdmin()} @@ -224,8 +224,8 @@ class Sidebar extends Component { } - theme={theme} - right={} + theme={theme!} + right={} onPress={() => this.sidebarNavigate('StatusView')} testID={`sidebar-custom-status-${user.status}`} /> @@ -239,12 +239,12 @@ class Sidebar extends Component { return null; } return ( - + { - + {useRealName ? user.name : user.username}