-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New timezone pages #12201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New timezone pages #12201
Changes from all commits
9704e1e
c9cad55
bcae580
b173e21
f1bc673
cfbdb16
8e3bf2e
b9fd35a
2221e56
06dfa1d
05e67bf
d2afbd9
c2c7e70
9e6eb14
45951b4
c51cc57
a7758c8
c02e802
cf1ca69
5213617
97df428
d61aac0
467760b
818ac83
f13ab5f
1ab9ee9
4c1910e
2be55f9
717fbc4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| import lodashGet from 'lodash/get'; | ||
| import React from 'react'; | ||
| import {View} from 'react-native'; | ||
| import moment from 'moment-timezone'; | ||
| import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from '../../../components/withCurrentUserPersonalDetails'; | ||
| import ScreenWrapper from '../../../components/ScreenWrapper'; | ||
| import HeaderWithCloseButton from '../../../components/HeaderWithCloseButton'; | ||
| import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; | ||
| import ROUTES from '../../../ROUTES'; | ||
| import CONST from '../../../CONST'; | ||
| import Text from '../../../components/Text'; | ||
| import styles from '../../../styles/styles'; | ||
| import Navigation from '../../../libs/Navigation/Navigation'; | ||
| import * as PersonalDetails from '../../../libs/actions/PersonalDetails'; | ||
| import compose from '../../../libs/compose'; | ||
| import Switch from '../../../components/Switch'; | ||
| import MenuItemWithTopDescription from '../../../components/MenuItemWithTopDescription'; | ||
|
|
||
| const propTypes = { | ||
| ...withLocalizePropTypes, | ||
| ...withCurrentUserPersonalDetailsPropTypes, | ||
| }; | ||
|
|
||
| const defaultProps = { | ||
| ...withCurrentUserPersonalDetailsDefaultProps, | ||
| }; | ||
|
|
||
| const TimezoneInitialPage = (props) => { | ||
| const timezone = lodashGet(props.currentUserPersonalDetails, 'timezone', CONST.DEFAULT_TIME_ZONE); | ||
|
|
||
| /** | ||
| * Updates setting for automatic timezone selection. | ||
| * Note: If we are updating automatically, we'll immediately calculate the user's timezone. | ||
| * | ||
| * @param {Boolean} isAutomatic | ||
| */ | ||
| const updateAutomaticTimezone = (isAutomatic) => { | ||
| PersonalDetails.updateAutomaticTimezone({ | ||
| automatic: isAutomatic, | ||
| selected: isAutomatic ? moment.tz.guess() : timezone.selected, | ||
| }); | ||
| }; | ||
|
|
||
| return ( | ||
| <ScreenWrapper> | ||
| <HeaderWithCloseButton | ||
| title={props.translate('timezonePage.timezone')} | ||
| shouldShowBackButton | ||
| onBackButtonPress={() => Navigation.navigate(ROUTES.SETTINGS_PROFILE)} | ||
| onCloseButtonPress={() => Navigation.dismissModal(true)} | ||
| /> | ||
| <View style={[styles.ph5]}> | ||
| <Text style={[styles.mb5]}> | ||
| {props.translate('timezonePage.isShownOnProfile')} | ||
| </Text> | ||
| <View style={[styles.flexRow, styles.mb5, styles.alignItemsCenter, styles.justifyContentBetween]}> | ||
| <Text> | ||
| {props.translate('timezonePage.getLocationAutomatically')} | ||
| </Text> | ||
| <Switch | ||
| isOn={timezone.automatic} | ||
| onToggle={updateAutomaticTimezone} | ||
| /> | ||
| </View> | ||
| </View> | ||
| <MenuItemWithTopDescription | ||
| title={timezone.selected} | ||
| description={props.translate('timezonePage.timezone')} | ||
| shouldShowRightIcon | ||
| wrapperStyle={[styles.ph2, styles.mb3]} | ||
| disabled={timezone.automatic} | ||
| onPress={() => Navigation.navigate(ROUTES.SETTINGS_TIMEZONE_SELECT)} | ||
| /> | ||
| </ScreenWrapper> | ||
| ); | ||
| }; | ||
|
|
||
| TimezoneInitialPage.propTypes = propTypes; | ||
| TimezoneInitialPage.defaultProps = defaultProps; | ||
| TimezoneInitialPage.displayName = 'TimezoneInitialPage'; | ||
|
|
||
| export default compose( | ||
| withLocalize, | ||
| withCurrentUserPersonalDetails, | ||
| )(TimezoneInitialPage); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| import lodashGet from 'lodash/get'; | ||
| import React, {Component} from 'react'; | ||
| import _ from 'underscore'; | ||
| import moment from 'moment-timezone'; | ||
| import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from '../../../components/withCurrentUserPersonalDetails'; | ||
| import ScreenWrapper from '../../../components/ScreenWrapper'; | ||
| import HeaderWithCloseButton from '../../../components/HeaderWithCloseButton'; | ||
| import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; | ||
| import ROUTES from '../../../ROUTES'; | ||
| import CONST from '../../../CONST'; | ||
| import styles from '../../../styles/styles'; | ||
| import Navigation from '../../../libs/Navigation/Navigation'; | ||
| import * as PersonalDetails from '../../../libs/actions/PersonalDetails'; | ||
| import compose from '../../../libs/compose'; | ||
| import OptionsSelector from '../../../components/OptionsSelector'; | ||
| import themeColors from '../../../styles/themes/default'; | ||
| import * as Expensicons from '../../../components/Icon/Expensicons'; | ||
|
|
||
| const propTypes = { | ||
| ...withLocalizePropTypes, | ||
| ...withCurrentUserPersonalDetailsPropTypes, | ||
| }; | ||
|
|
||
| const defaultProps = { | ||
| ...withCurrentUserPersonalDetailsDefaultProps, | ||
| }; | ||
|
|
||
| class TimezoneSelectPage extends Component { | ||
| constructor(props) { | ||
| super(props); | ||
|
|
||
| this.saveSelectedTimezone = this.saveSelectedTimezone.bind(this); | ||
| this.filterShownTimezones = this.filterShownTimezones.bind(this); | ||
|
|
||
| this.currentSelectedTimezone = lodashGet(props.currentUserPersonalDetails, 'timezone.selected', CONST.DEFAULT_TIME_ZONE.selected); | ||
| this.allTimezones = _.chain(moment.tz.names()) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NAB - style: maybe it'll be easier to read the constructor if we create a |
||
| .filter(timezone => !timezone.startsWith('Etc/GMT')) | ||
| .map(timezone => ({ | ||
| text: timezone, | ||
| keyForList: timezone, | ||
|
|
||
| // Add green checkmark icon & bold the timezone text | ||
| customIcon: timezone === this.currentSelectedTimezone | ||
| ? {src: Expensicons.Checkmark, color: themeColors.success} | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi all! When we added this new feature of adding a checkmark, we created an inconsistency - Other pages like currency selection didn't get any checkmarks making them unhappy. It was out of scope of this PR, but we should have created a follow up issue for it!
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oooooo fair point, thanks for noting that! We always like happy pages and happy code |
||
| : null, | ||
| isUnread: timezone === this.currentSelectedTimezone, | ||
| })) | ||
| .value(); | ||
|
|
||
| this.state = { | ||
| timezoneInputText: this.currentSelectedTimezone, | ||
| timezoneOptions: this.allTimezones, | ||
| }; | ||
| } | ||
|
|
||
| /** | ||
| * @param {Object} timezone | ||
| * @param {String} timezone.text | ||
| */ | ||
| saveSelectedTimezone({text}) { | ||
| PersonalDetails.updateSelectedTimezone(text); | ||
| } | ||
|
|
||
| /** | ||
| * @param {String} searchText | ||
| */ | ||
| filterShownTimezones(searchText) { | ||
| this.setState({ | ||
| timezoneInputText: searchText, | ||
| timezoneOptions: _.filter(this.allTimezones, (tz => tz.text.toLowerCase().includes(searchText.toLowerCase()))), | ||
| }); | ||
| } | ||
|
|
||
| render() { | ||
| return ( | ||
| <ScreenWrapper> | ||
| <HeaderWithCloseButton | ||
| title={this.props.translate('timezonePage.timezone')} | ||
| shouldShowBackButton | ||
| onBackButtonPress={() => Navigation.navigate(ROUTES.SETTINGS_TIMEZONE)} | ||
| onCloseButtonPress={() => Navigation.dismissModal(true)} | ||
| /> | ||
| <OptionsSelector | ||
| textInputLabel={this.props.translate('timezonePage.timezone')} | ||
| value={this.state.timezoneInputText} | ||
| onChangeText={this.filterShownTimezones} | ||
| onSelectRow={this.saveSelectedTimezone} | ||
| optionHoveredStyle={styles.hoveredComponentBG} | ||
| sections={[{data: this.state.timezoneOptions}]} | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Beamanator feel free to ignore if it doesn't make the code cleaner. |
||
| shouldHaveOptionSeparator | ||
| /> | ||
| </ScreenWrapper> | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| TimezoneSelectPage.propTypes = propTypes; | ||
| TimezoneSelectPage.defaultProps = defaultProps; | ||
|
|
||
| export default compose( | ||
| withLocalize, | ||
| withCurrentUserPersonalDetails, | ||
| )(TimezoneSelectPage); | ||
Uh oh!
There was an error while loading. Please reload this page.