From ccb87c09e5bfc4c09a07461ca0cfd843ddf1ae46 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Tue, 26 Sep 2017 11:04:15 -0500 Subject: [PATCH] Add moment.js --- package.json | 1 + src/Styles.js | 18 +++++++------- src/app.js | 24 +++++++++++++++---- src/components/ButtonCell.js | 13 +++++----- src/components/SectionedAccessoryTableCell.js | 6 ++--- src/components/SectionedTableCell.js | 1 - src/containers/ManageNote.js | 8 +++---- src/containers/account/AuthSection.js | 12 +++------- src/containers/account/CompanySection.js | 12 +++------- src/containers/account/OptionsSection.js | 8 ++----- src/containers/account/PasscodeSection.js | 8 ++----- .../account/RegistrationConfirmSection.js | 15 ++++++------ src/containers/account/ThemesSection.js | 2 -- src/models/api/item.js | 24 +++++++++++-------- src/screens/Authenticate.js | 8 ++----- src/screens/Compose.js | 5 ++++ src/screens/Filter.js | 3 --- src/screens/InputModal.js | 13 ++++++---- 18 files changed, 89 insertions(+), 92 deletions(-) diff --git a/package.json b/package.json index 6c3f9586..abb712e6 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "bugsnag-react-native": "^2.3.2", "immutable": "^3.8.1", "lodash": "^4.17.4", + "moment": "^2.18.1", "react": "16.0.0-beta.5", "react-native": "^0.48.4", "react-native-keychain": "^1.2.1", diff --git a/src/Styles.js b/src/Styles.js index 2fa1d6de..e64b15f0 100644 --- a/src/Styles.js +++ b/src/Styles.js @@ -250,7 +250,7 @@ export default class GlobalStyles { flexContainer: { flex: 1, - flexDirection: 'row', + flexDirection: 'column', }, uiText: { @@ -269,7 +269,6 @@ export default class GlobalStyles { }, sectionHeader: { - color: constants.mainDimColor, fontSize: constants.mainTextFontSize - 4, paddingLeft: constants.paddingLeft, paddingBottom: 10, @@ -278,7 +277,6 @@ export default class GlobalStyles { }, sectionHeaderAndroid: { - color: constants.mainDimColor, fontSize: constants.mainTextFontSize - 2, }, @@ -320,27 +318,27 @@ export default class GlobalStyles { sectionedAccessoryTableCellLabel: { fontSize: constants.mainTextFontSize, color: constants.mainTextColor, - paddingTop: 12, + // paddingTop: 12, }, buttonCell: { - paddingLeft: 0, paddingTop: 0, - minHeight: 45, - flexGrow: 0, + paddingBottom: 0, backgroundColor: constants.mainBackgroundColor, + flex: 1, + justifyContent: 'center', + alignItems: 'center' }, buttonCellButton: { textAlign: "center", + textAlignVertical: "center", color: Platform.OS == "android" ? constants.mainTextColor : constants.mainTintColor, fontSize: constants.mainTextFontSize, - height: "100%", - paddingTop: 13, }, buttonCellButtonAndroid: { - paddingTop: 11 + // paddingTop: 11 }, buttonCellButtonLeft: { diff --git a/src/app.js b/src/app.js index d6a21422..f99cc2cb 100644 --- a/src/app.js +++ b/src/app.js @@ -7,7 +7,8 @@ import { Platform, StatusBar, BackHandler, - DeviceEventEmitter + DeviceEventEmitter, + NativeModules } from 'react-native'; import {Navigation, ScreenVisibilityListener} from 'react-native-navigation'; @@ -18,7 +19,7 @@ import Auth from './lib/auth' import GlobalStyles from "./Styles" import Icons from "./Icons" import OptionsState from "./OptionsState" - +var moment = require('moment/min/moment-with-locales.min.js'); import { Client } from 'bugsnag-react-native'; var _ = require('lodash'); @@ -52,16 +53,20 @@ export default class App { this.readyObservers = []; this.lockStatusObservers = []; - this.optionsState = new OptionsState(); - this._isAndroid = Platform.OS === "android"; + // Configure Moment locale + moment.locale(this.getLocale()); + + // Initialize Options (sort by, filter, selected tags, etc) + this.optionsState = new OptionsState(); this.optionsState.addChangeObserver((options) => { if(!this.loading) { options.persist(); } }) + // Screen visibility listener this.listener = new ScreenVisibilityListener({ willAppear: ({screen, startTime, endTime, commandType}) => { // This handles authentication for the initial app launch. We wait for the Notes component to be ready @@ -75,6 +80,7 @@ export default class App { }); this.listener.register(); + // Listen to sign out event this.signoutObserver = Auth.getInstance().addEventObserver([Auth.DidSignOutEvent, Auth.WillSignInEvent], function(event){ if(event == Auth.DidSignOutEvent) { this.optionsState.reset(); @@ -82,6 +88,14 @@ export default class App { }.bind(this)); } + getLocale() { + if (Platform.OS === 'android') { + return NativeModules.I18nManager.localeIdentifier; + } else { + return NativeModules.SettingsManager.settings.AppleLocale.replace(/_/, '-'); + } + } + handleAppStateChange = (nextAppState) => { console.log("handleAppStateChange|App.js", nextAppState, "starting app?", this.isStartingApp); @@ -376,3 +390,5 @@ export default class App { this.startApp(); } } + +export {moment} diff --git a/src/components/ButtonCell.js b/src/components/ButtonCell.js index 1a5848fb..d343a524 100644 --- a/src/components/ButtonCell.js +++ b/src/components/ButtonCell.js @@ -1,23 +1,24 @@ import React, { Component } from 'react'; -import {TouchableOpacity, Text} from 'react-native'; - +import {TouchableHighlight, Text} from 'react-native'; +import SectionedTableCell from './SectionedTableCell' import GlobalStyles from "../Styles" -export default class ButtonCell extends Component { +export default class ButtonCell extends SectionedTableCell { rules() { - var rules = [GlobalStyles.stylesForKey("buttonCellButton")]; + var rules = super.rules().concat([GlobalStyles.stylesForKey("buttonCellButton")]); if(this.props.leftAligned) { rules.push(GlobalStyles.styles().buttonCellButtonLeft) } if(this.props.bold) { rules.push(GlobalStyles.styles().bold) } if(this.props.disabled) { rules.push({color: "gray", opacity: 0.6}) } + if(this.props.maxHeight) { rules.push({maxHeight: this.props.maxHeight}) } return rules; } render() { return ( - + {this.props.title} - + ) } } diff --git a/src/components/SectionedAccessoryTableCell.js b/src/components/SectionedAccessoryTableCell.js index 6f8b3265..7f4eb9a6 100644 --- a/src/components/SectionedAccessoryTableCell.js +++ b/src/components/SectionedAccessoryTableCell.js @@ -48,7 +48,7 @@ export default class SectionedAccessoryTableCell extends SectionedTableCell { if(Platform.OS == "android") { iconSize -= 5; - iconStyles.paddingTop = left ? 11 : 4; + iconStyles.paddingTop = left ? 12 : 4; color = GlobalStyles.constants().mainDimColor; } @@ -65,8 +65,8 @@ export default class SectionedAccessoryTableCell extends SectionedTableCell { var textStyles = [GlobalStyles.styles().sectionedAccessoryTableCellLabel]; if(this.props.leftAlignIcon) { textStyles.push({ - position: "absolute", - left: iconStyles.left + iconStyles.width + 12, + // position: "absolute", + left: iconStyles.left + iconStyles.width + 3, top: 0 }); } diff --git a/src/components/SectionedTableCell.js b/src/components/SectionedTableCell.js index add6af06..a2e1b0a9 100644 --- a/src/components/SectionedTableCell.js +++ b/src/components/SectionedTableCell.js @@ -7,7 +7,6 @@ export default class SectionedTableCell extends Component { rules() { var rules = [GlobalStyles.styles().sectionedTableCell]; - if(this.props.buttonCell) { rules.push(GlobalStyles.styles().buttonCell); } if(this.props.first) { rules.push(GlobalStyles.styles().sectionedTableCellFirst); } if(this.props.textInputCell) {rules.push(GlobalStyles.styles().textInputCell); } if(this.props.height) {rules.push({height: this.props.height})}; diff --git a/src/containers/ManageNote.js b/src/containers/ManageNote.js index 47ecc8a0..21adaae0 100644 --- a/src/containers/ManageNote.js +++ b/src/containers/ManageNote.js @@ -31,28 +31,28 @@ export default class SortSection extends Component { {this.onPress(pinAction.toLowerCase())}} - first={true} text={pinAction} buttonCell={true} + first={true} text={pinAction} leftAlignIcon={true} /> {this.onPress(archiveOption.toLowerCase())}} - text={archiveOption} buttonCell={true} + text={archiveOption} leftAlignIcon={true} /> {this.onPress("share")}} - text={"Share"} buttonCell={true} + text={"Share"} leftAlignIcon={true} /> {this.onPress("delete")}} - text={"Delete"} buttonCell={true} + text={"Delete"} leftAlignIcon={true} /> diff --git a/src/containers/account/AuthSection.js b/src/containers/account/AuthSection.js index 47c6054a..97e63636 100644 --- a/src/containers/account/AuthSection.js +++ b/src/containers/account/AuthSection.js @@ -94,18 +94,12 @@ export default class AuthSection extends AbstractComponent { } - - this.onSignInPress()} /> - + this.onSignInPress()} /> - - this.onRegisterPress()} /> - + this.onRegisterPress()} /> {!this.state.showAdvanced && - - this.showAdvanced()} /> - + this.showAdvanced()} /> } diff --git a/src/containers/account/CompanySection.js b/src/containers/account/CompanySection.js index d01bb368..77887ced 100644 --- a/src/containers/account/CompanySection.js +++ b/src/containers/account/CompanySection.js @@ -15,17 +15,11 @@ export default class CompanySection extends Component { - - this.props.onAction("feedback")} /> - + this.props.onAction("feedback")} /> - - this.props.onAction("learn_more")} /> - + this.props.onAction("learn_more")} /> - - this.props.onAction("privacy")} /> - + this.props.onAction("privacy")} /> ); diff --git a/src/containers/account/OptionsSection.js b/src/containers/account/OptionsSection.js index c3efd726..32643c9d 100644 --- a/src/containers/account/OptionsSection.js +++ b/src/containers/account/OptionsSection.js @@ -16,14 +16,10 @@ export default class OptionsSection extends Component { {this.props.signedIn && - - - + } - - - + ); diff --git a/src/containers/account/PasscodeSection.js b/src/containers/account/PasscodeSection.js index c04218b8..564118c4 100644 --- a/src/containers/account/PasscodeSection.js +++ b/src/containers/account/PasscodeSection.js @@ -71,13 +71,9 @@ export default class PasscodeSection extends Component { - - - + - - - + {this.props.hasPasscode && diff --git a/src/containers/account/RegistrationConfirmSection.js b/src/containers/account/RegistrationConfirmSection.js index 1d2a5130..7ca3bed6 100644 --- a/src/containers/account/RegistrationConfirmSection.js +++ b/src/containers/account/RegistrationConfirmSection.js @@ -49,15 +49,14 @@ export default class RegistrationConfirmSection extends Component { /> - - this.onConfirmPress()} /> - + this.onConfirmPress()} + /> - - this.onCancel()} /> - + this.onCancel()} /> diff --git a/src/containers/account/ThemesSection.js b/src/containers/account/ThemesSection.js index 7af29fc5..51d7a2c1 100644 --- a/src/containers/account/ThemesSection.js +++ b/src/containers/account/ThemesSection.js @@ -24,7 +24,6 @@ export default class ThemesSection extends Component { key={theme.uuid} first={i == 0} selected={() => {return theme.active}} - buttonCell={true} dimmed={theme.notAvailableOnMobile} /> ) @@ -34,7 +33,6 @@ export default class ThemesSection extends Component { Linking.openURL("https://standardnotes.org/extensions")} text={"More Themes"} - buttonCell={true} /> } diff --git a/src/models/api/item.js b/src/models/api/item.js index b4181e08..47dd1fc5 100644 --- a/src/models/api/item.js +++ b/src/models/api/item.js @@ -1,4 +1,5 @@ import Crypto from "../../lib/crypto" +import {moment} from "../../app" var _ = require('lodash') @@ -51,8 +52,8 @@ export default class Item { _.merge(this, json); if(this.created_at) { - this.created_at = new Date(this.created_at); - this.updated_at = new Date(this.updated_at); + this.created_at = moment(this.created_at); + this.updated_at = moment(this.updated_at); } else { this.created_at = new Date(); this.updated_at = new Date(); @@ -133,18 +134,21 @@ export default class Item { return []; } - createdAt() { - var date = this.created_at; - var string = date.toLocaleDateString() + ", " + date.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'}); - - return string; + createdAt(withTime) { + return this.dateToString(this.created_at, withTime); } updatedAt() { - var date = this.updated_at; - var string = date.toLocaleDateString() + ", " + date.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'}); + return this.dateToString(this.updated_at, true); + } - return string; + dateToString(date, withTime) { + if(withTime) { + return moment(date).format('lll') + } else { + return moment(date).format('l') + } + // return this.created_at.fromNow() } doNotEncrypt() { diff --git a/src/screens/Authenticate.js b/src/screens/Authenticate.js index bec35c19..d0c2a403 100644 --- a/src/screens/Authenticate.js +++ b/src/screens/Authenticate.js @@ -147,9 +147,7 @@ export default class Authenticate extends Abstract { /> - - this.onUnlockPress()} /> - + this.onUnlockPress()} /> } @@ -172,9 +170,7 @@ export default class Authenticate extends Abstract { /> - - this.onSavePress()} /> - + this.onSavePress()} /> } diff --git a/src/screens/Compose.js b/src/screens/Compose.js index 5214151e..c66374b4 100644 --- a/src/screens/Compose.js +++ b/src/screens/Compose.js @@ -75,6 +75,10 @@ export default class Compose extends Abstract { return; } + if(!this.note.uuid) { + return; + } + var tagButton = { title: "Manage", id: 'tags', @@ -162,6 +166,7 @@ export default class Compose extends Abstract { if(!this.note.uuid) { this.note.initUUID().then(function(){ this.save(); + this.configureNavBar(true); }.bind(this)); } else { this.save(); diff --git a/src/screens/Filter.js b/src/screens/Filter.js index 05d77962..e685eb8c 100644 --- a/src/screens/Filter.js +++ b/src/screens/Filter.js @@ -363,7 +363,6 @@ class TagsSection extends Component { key={tag.uuid} first={i == 0} selected={() => {return root.state.selected.includes(tag.uuid)}} - buttonCell={true} /> ) })} @@ -394,7 +393,6 @@ class OptionsSection extends Component { text={"Show only archived notes"} first={true} selected={() => {return this.props.archivedOnly}} - buttonCell={true} /> @@ -431,7 +429,6 @@ class SortSection extends Component { key={option.key} first={i == 0} selected={() => {return option.key == root.state.sortBy}} - buttonCell={true} /> ) })} diff --git a/src/screens/InputModal.js b/src/screens/InputModal.js index ec3fbfa9..19eced85 100644 --- a/src/screens/InputModal.js +++ b/src/screens/InputModal.js @@ -21,8 +21,7 @@ export default class InputModal extends Abstract { { title: 'Cancel', id: 'cancel', - showAsAction: 'ifRoom', - buttonColor: GlobalStyles.constants().mainTintColor, + showAsAction: 'ifRoom' }, ], animated: false @@ -37,6 +36,12 @@ export default class InputModal extends Abstract { } onSave = () => { + if(this.props.validate) { + if(!this.props.validate(this.state.text)) { + this.props.onError(this.state.text); + return; + } + } this.props.onSave(this.state.text); this.props.navigator.dismissModal({animationType: "slide-down"}); } @@ -64,9 +69,7 @@ export default class InputModal extends Abstract { /> - - this.onSave()} /> - + this.onSave()} />