зеркало из https://github.com/mozilla/notes.git
Родитель
499d0d9184
Коммит
1c44a6e92f
|
@ -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, you’ll 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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче