Fixes #1176
Fixes #957
This commit is contained in:
Vlad Filippov 2018-06-25 15:36:23 -04:00 коммит произвёл GitHub
Родитель 499d0d9184
Коммит 1c44a6e92f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
11 изменённых файлов: 126 добавлений и 36 удалений

Просмотреть файл

@ -123,3 +123,77 @@ newNote=New Note
makePlainText=Make Plain Text
deleteNote=Delete Note
insufficientStorage=Notes Storage Full
#
# The following strings are used in the mobile app
# LOCALIZATION NOTE (welcomeTitle4): This string is the login panel of the mobile app
welcomeTitle4=Notes by Firefox
# LOCALIZATION NOTE (welcomeHeadline): This string is the login panel of the mobile app
welcomeHeadline=A simple, secure notepad app that syncs with Firefox
# LOCALIZATION NOTE (signIn): This string is in the button in the login panel of the mobile app
signIn=Sign In
# LOCALIZATION NOTE (usageHint): This string is the login panel of the mobile app
usageHint=To use Notes, youll need a Firefox Account and the free Notes browser extension from Firefox Test Pilot.
# LOCALIZATION NOTE (usageLearnMore): This string is a link to the documentation
usageLearnMore=Learn more
# LOCALIZATION NOTE (drawerBtnFeedback): This string is a button in the mobile app options drawer
drawerBtnFeedback=Feedback
# LOCALIZATION NOTE (drawerBtnLogOut): This string is a button in the mobile app options drawer
drawerBtnLogOut=Log out
# LOCALIZATION NOTE (toastOffline): This string shows up as an Android notification toast.
toastOffline=You are offline.
# LOCALIZATION NOTE (toastLoggedInAs): Notification, {email} is the user's Firefox Account email.
toastLoggedInAs=Logged in as {email}
# LOCALIZATION NOTE (toastLoggedInError): Notification, {err} is an error string, example "Component failed".
toastLoggedInError=Something went wrong. {err}
# LOCALIZATION NOTE (statusLabelOffline): Shows the offline status label in the mobile app options drawer
statusLabelOfflineDrawer=Offline
# LOCALIZATION NOTE (statusLabelSyncing): Shows the syncing status label in the mobile app options drawer
statusLabelSyncingDrawer=Syncing…
# LOCALIZATION NOTE (statusLabelOpeningLoginDrawer): Shows the syncing status label in the mobile app options drawer
statusLabelOpeningLoginDrawer=Opening login…
# LOCALIZATION NOTE (statusLabelTimeDrawer): {time} is the time of syncing. Such as 5:33pm or 17:33. If this
# structure doesn't work for your locale, you can translate this as "Synced ({time})". Status label in the mobile app options drawer
statusLabelTimeDrawer=Last synced {time}
# LOCALIZATION NOTE (editorLabelOffline): Shows the offline status in the editor
editorLabelOffline=Offline
# LOCALIZATION NOTE (editorLabelSyncing): Shows the syncing status in the editor
editorLabelSyncing=Syncing…
# LOCALIZATION NOTE (editorLabelSynced): Shows the synced status in the editor
editorLabelSynced=Synced
# LOCALIZATION NOTE (snackbarSynced): The synced status in Android Material Design snackbar
snackbarSynced=Notes synced!
# LOCALIZATION NOTE (snackbarDeleted): The note deleted message in Android Material Design snackbar
snackbarDeleted=Notes deleted.
# LOCALIZATION NOTE (snackbarUndo): The undo button in Android Material Design snackbar
snackbarUndo=Undo
# LOCALIZATION NOTE (editorMenuDelete): The delete button in the editor menu
editorMenuDelete=Delete
# LOCALIZATION NOTE (noteListSelection): A selection of notes in the list view
noteListSelection=Selection
# LOCALIZATION NOTE (noNotesMessage): Message shown when the user has no notes created
noNotesMessage=Your notes will show up here and are synced across your connected devices.

Просмотреть файл

@ -34,7 +34,7 @@ export function openingLogin() {
export function reconnectSync() {
trackEvent('reconnect-sync');
return { type: RECONNECT_SYNC, message: 'Reconnect to Sync' };
return { type: RECONNECT_SYNC, message: browser.i18n.getMessage('reconnectSync') };
}
export function syncing() {

Просмотреть файл

@ -48,7 +48,7 @@ class DrawerItems extends React.Component {
// DrawerItemsData store our drawer button list
this.drawerItemsData = [
{
label : 'Log out',
label: browser.i18n.getMessage('drawerBtnLogOut'),
action: () => {
navigateToLogin(props);
// We delay disconnect event to avoid empty UI while drawer is closing
@ -58,8 +58,8 @@ class DrawerItems extends React.Component {
}
},
{
label : 'Feedback',
action : () => {
label: browser.i18n.getMessage('drawerBtnFeedback'),
action: () => {
trackEvent('give-feedback');
return Linking.openURL(SURVEY_PATH);
}
@ -91,7 +91,7 @@ class DrawerItems extends React.Component {
if (this.props.state.sync.isConnected === false) {
if (this.props.navigation.state.isDrawerOpen) {
props.navigation.dispatch(DrawerActions.closeDrawer());
ToastAndroid.show('You are offline.', ToastAndroid.LONG);
ToastAndroid.show(browser.i18n.getMessage('toastOffline'), ToastAndroid.LONG);
}
} else if (!this.props.state.sync.loginDetails) {
this._requestReconnect();
@ -141,11 +141,12 @@ class DrawerItems extends React.Component {
let statusLabel;
if (this.props.state.sync.isConnected === false) {
statusLabel = 'Offline';
statusLabel = browser.i18n.getMessage('statusLabelOfflineDrawer');
} else if (this.props.state.sync.isSyncing) {
statusLabel = 'Syncing…';
statusLabel = browser.i18n.getMessage('statusLabelSyncingDrawer');
} else {
statusLabel = `Last synced ${ moment(this.props.state.sync.lastSynced).format('LT') }`;
let time = moment(this.props.state.sync.lastSynced).format('LT');
statusLabel = browser.i18n.getMessage('statusLabelTimeDrawer', time);
}
return (
@ -172,7 +173,7 @@ class DrawerItems extends React.Component {
{ this.props.state.sync.error ?
<TouchableRipple style={styles.footer} onPress={this._requestReconnect}>
<View style={styles.footerWrapper}>
<Text style={{ color: COLOR_DARK_WARNING, fontSize: 13 }}>{ this.props.state.sync.isOpeningLogin ? 'Opening login…' : this.props.state.sync.error }</Text>
<Text style={{ color: COLOR_DARK_WARNING, fontSize: 13 }}>{ this.props.state.sync.isOpeningLogin ? browser.i18n.getMessage('statusLabelOpeningLoginDrawer') : this.props.state.sync.error }</Text>
<MaterialIcons
name='warning'
style={{ color: COLOR_DARK_WARNING }}

Просмотреть файл

@ -7,6 +7,7 @@ import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import { Toolbar, ToolbarContent, ToolbarAction } from 'react-native-paper';
import { COLOR_APP_BAR, COLOR_NOTES_BLUE, COLOR_DARK_WARNING } from '../utils/constants';
import MoreMenu from './MoreMenu';
import browser from '../browser';
class EditorPanelHeader extends Component {
@ -18,7 +19,7 @@ class EditorPanelHeader extends Component {
let color = COLOR_NOTES_BLUE;
if (props.state.sync.isConnected === false) {
content = 'Offline';
content = browser.i18n.getMessage('editorLabelOffline');
} else if (props.state.sync.error) {
content = props.state.sync.error;
color = COLOR_DARK_WARNING;
@ -73,13 +74,13 @@ class EditorPanelHeader extends Component {
clearTimeout(this.timer);
if (newProps.state.sync.isConnected === false) {
this._setToolbarContent('Offline');
this._setToolbarContent(browser.i18n.getMessage('editorLabelOffline'));
} else if (newProps.state.sync.error) {
this._setToolbarContent(newProps.state.sync.error, COLOR_DARK_WARNING);
} else if (newProps.state.sync.isSyncing) {
this._setToolbarContent('Syncing...');
this._setToolbarContent(browser.i18n.getMessage('editorLabelSyncing'));
} else if (this.props.state.sync.isSyncing && !newProps.state.sync.isSyncing) {
this._setToolbarContent('Synced');
this._setToolbarContent(browser.i18n.getMessage('editorLabelSynced'));
this.timer = setTimeout(() => {
const note = newProps.state.notes.find((note) => newProps.state.sync.focusedNoteId === note.id);
this.timer = this._setToolbarContent(note ? note.firstLine : '');

Просмотреть файл

@ -24,7 +24,7 @@ const SNACKBAR_ANIMATION_DURATION = 250;
const SNACKBAR_HEIGHT = 48;
const SYNCED_SNACKBAR = {
text: 'Notes synced!',
text: browser.i18n.getMessage('snackbarSynced'),
color: COLOR_DARK_SYNC,
action: null,
onDismiss: null,
@ -49,7 +49,7 @@ class ListPanel extends React.Component {
this._onRefresh = () => {
if (this.props.state.sync.isConnected === false) {
ToastAndroid.show('You are offline.', ToastAndroid.LONG);
ToastAndroid.show(browser.i18n.getMessage('toastOffline'), ToastAndroid.LONG);
} else {
trackEvent('webext-button-authenticate');
this.setState({ refreshing: true });
@ -260,10 +260,10 @@ class ListPanel extends React.Component {
// Show snackbar
this._showSnackbar({
text: 'Notes deleted.',
text: browser.i18n.getMessage('snackbarDeleted'),
color: COLOR_NOTES_BLUE,
action: {
text: 'UNDO',
text: browser.i18n.getMessage('snackbarUndo').toUpperCase(),
onPress: () => {
this._undoDelete(deletedNote);
}

Просмотреть файл

@ -1,8 +1,10 @@
import React from 'react';
import { View, Text, StyleSheet, Image } from 'react-native';
import browser from '../browser';
const noNotesMessage = browser.i18n.getMessage('noNotesMessage');
class ListPanelEmpty extends React.Component {
render() {
return (
<View style={styles.noNotes}>
@ -10,7 +12,7 @@ class ListPanelEmpty extends React.Component {
style={{width: 150, height: 150, marginBottom: 30 }}
source={require('../assets/notes-1024.png')}
/>
<Text style={styles.centered}>Your notes will show up here and are synced across your connected devices.</Text>
<Text style={styles.centered}>{noNotesMessage}</Text>
</View>
);
}

Просмотреть файл

@ -7,7 +7,7 @@ import { resetSelect, deleteNotes } from "../actions";
import { Toolbar, ToolbarContent, ToolbarAction } from 'react-native-paper';
import { COLOR_APP_BAR, COLOR_NOTES_BLUE, COLOR_DARK_TEXT } from '../utils/constants';
import browser from '../browser';
class ListPanelHeader extends Component {
constructor(props) {
@ -42,7 +42,7 @@ class ListPanelHeader extends Component {
<ToolbarContent
style={{ paddingLeft: 0, }}
titleStyle={{ fontSize: 18, color: COLOR_DARK_TEXT }}
title='Selection' />
title={ browser.i18n.getMessage('noteListSelection') } />
<ToolbarAction
size={20}
style={{ paddingTop: 4 }}
@ -64,7 +64,7 @@ class ListPanelHeader extends Component {
<ToolbarContent
style={{ paddingLeft: 0, paddingHorizontal: 0 }}
titleStyle={{ fontSize: 18, color: COLOR_NOTES_BLUE }}
title='Notes' />
title={ browser.i18n.getMessage('welcomeTitle4') } />
</Toolbar>
);
}

Просмотреть файл

@ -10,6 +10,7 @@ import { authenticate, kintoLoad } from '../actions';
import { COLOR_NOTES_BLUE } from '../utils/constants';
import i18nGetMessage from '../utils/i18n';
import { trackEvent } from '../utils/metrics';
import browser from '../browser';
class LoadingPanel extends React.Component {
@ -23,7 +24,8 @@ class LoadingPanel extends React.Component {
.then((loginDetails) => {
trackEvent('login-success');
this.props.dispatch(authenticate(loginDetails));
ToastAndroid.show('Logged in as ' + loginDetails.profile.email, ToastAndroid.LONG);
let email = loginDetails.profile.email;
ToastAndroid.show(browser.i18n.getMessage('toastLoggedInAs', email), ToastAndroid.LONG);
this.props.dispatch(kintoLoad());
@ -35,7 +37,7 @@ class LoadingPanel extends React.Component {
return Promise.resolve();
}).catch((err) => {
console.log('onAuth', err);
ToastAndroid.show('Something went wrong. ' + err, ToastAndroid.LONG);
ToastAndroid.show(browser.i18n.getMessage('toastLoggedInError', err), ToastAndroid.LONG);
trackEvent('login-failed');
const resetAction = StackActions.reset({
index: 0,

Просмотреть файл

@ -3,10 +3,9 @@ import React from 'react';
import { connect } from 'react-redux';
import { Button } from 'react-native-paper';
import { NavigationActions, StackActions } from 'react-navigation';
import { View, Text, ProgressBarAndroid, ToastAndroid, Image, StyleSheet } from 'react-native';
import { COLOR_NOTES_BLUE } from '../utils/constants';
import i18nGetMessage from '../utils/i18n';
import { View, Text, ProgressBarAndroid, ToastAndroid, Image, StyleSheet, Linking } from 'react-native';
import { COLOR_NOTES_BLUE } from '../utils/constants';
import i18nGetMessage from '../utils/i18n';
class LoginPanel extends React.Component {
@ -27,17 +26,26 @@ class LoginPanel extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<View style={{ flexGrow: 1, alignItems: 'center', justifyContent: 'center', paddingTop: 30 }}>
<View style={{ flexGrow: 1, alignItems: 'center', justifyContent: 'center', paddingTop: 15 }}>
<Image
style={{width: 150, height: 150 }}
source={require('../assets/notes-1024.png')}
/>
<Text style={{ fontWeight: 'bold', fontSize: 18, padding: 10 }}>
{ i18nGetMessage('welcomeTitle3') }
<Text style={{ fontWeight: 'bold', fontSize: 24, padding: 10, paddingTop: 30 }}>
{ i18nGetMessage('welcomeTitle4') }
</Text>
<Text style={{ fontSize: 16, padding: 10 }}>Access your Test Pilot Notes</Text>
<Text style={{ fontWeight: 'bold', fontSize: 12, paddingBottom: 30 }}>{ i18nGetMessage('welcomeHeadline') }</Text>
<Button loading={this.state.isLoading} raised onPress={this.onAuth.bind(this)} color={COLOR_NOTES_BLUE}
style={styles.btnSignin}>SIGN IN</Button>
style={styles.btnSignin}><Text style={{ fontSize: 14 }}>{ i18nGetMessage('signIn') }</Text></Button>
</View>
<View style={{ flexGrow: 1, alignItems: 'center', justifyContent: 'center', paddingTop: 15 }}>
<Text style={{ fontSize: 12, paddingTop: 20, textAlign: 'center' }}>
{ i18nGetMessage('usageHint') }
</Text>
<Text style={{color: COLOR_NOTES_BLUE, fontSize: 12}}
onPress={() => Linking.openURL('https://testpilot.firefox.com/experiments/notes')}>
{ i18nGetMessage('usageLearnMore') }
</Text>
</View>
</View>
);

Просмотреть файл

@ -8,7 +8,7 @@ import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import {
COLOR_NOTES_BLUE
} from '../utils/constants';
import browser from '../browser';
const UIManager = NativeModules.UIManager;
/**
@ -55,7 +55,7 @@ class MoreMenu extends Component {
};
render() {
const labels = ['Delete'];
const labels = [browser.i18n.getMessage('editorMenuDelete')];
return (
<View style={{ flexDirection: 'row' }}>

Просмотреть файл

@ -65,7 +65,9 @@ if (! localeStrings) {
}
function getMessage(messageName, content) {
const message = localeStrings[messageName];
const message = localeStrings[messageName] || LOCALE_FILES['en_US'][messageName] || {
message: messageName
};
if (message.placeholders) {
message.message = message.message.replace(/\$.*\$/g, content);