зеркало из https://github.com/mozilla/notes.git
Fix synced status (#1233)
Fixes #1218 Fixes #1221 Fixes #1205 Fixes #1116 Fixes #1050
This commit is contained in:
Родитель
a840f54cb0
Коммит
5a03a1295b
|
@ -103,7 +103,7 @@
|
|||
</head>
|
||||
|
||||
<body id="notes">
|
||||
<input id="fake" type="text" style="height: 1px; border: 0; padding: 0; margin: 0; color: white; background: none!important;" />
|
||||
<input id="fake" type="text" style="height: 1px; border: 0; padding: 0; margin: 0; color: white; position: absolute; background: none!important;" />
|
||||
<div id="editor"> </div>
|
||||
<script>
|
||||
function init() {
|
||||
|
@ -117,34 +117,34 @@
|
|||
|
||||
zss_editor.setContentHTML = function(html) {
|
||||
editor.setData(html || '<p></p>');
|
||||
|
||||
setTimeout(function () {
|
||||
// Android won't popup the keyboard on focused <div>s, first focus a fake input then focus the div
|
||||
var fakeInput = document.querySelectorAll("#fake")[0];
|
||||
fakeInput.focus();
|
||||
|
||||
setTimeout(function () {
|
||||
// the following was taken from http://stackoverflow.com/questions/1125292/how-to-move-cursor-to-end-of-contenteditable-entity/3866442#3866442
|
||||
// and ensures we move the cursor to the end of the editor
|
||||
var editorSelector = document.querySelectorAll('.' + "ck-editor__editable");
|
||||
var range = document.createRange();
|
||||
range.selectNodeContents(editorSelector[0]);
|
||||
range.collapse(false);
|
||||
var selection = window.getSelection();
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
editorSelector[0].focus();
|
||||
fakeInput.disabled = true;
|
||||
fakeInput.parentNode.removeChild(fakeInput);
|
||||
}, 300);
|
||||
|
||||
}, 300);
|
||||
};
|
||||
|
||||
this.editor = editor;
|
||||
|
||||
postMessage(JSON.stringify({type: 'ZSS_INITIALIZED'}));
|
||||
|
||||
setTimeout(function () {
|
||||
// Android won't popup the keyboard on focused <div>s, first focus a fake input then focus the div
|
||||
var fakeInput = document.querySelectorAll("#fake")[0];
|
||||
fakeInput.focus();
|
||||
|
||||
setTimeout(function () {
|
||||
// the following was taken from http://stackoverflow.com/questions/1125292/how-to-move-cursor-to-end-of-contenteditable-entity/3866442#3866442
|
||||
// and ensures we move the cursor to the end of the editor
|
||||
var editorSelector = document.querySelectorAll('.' + "ck-editor__editable");
|
||||
var range = document.createRange();
|
||||
range.selectNodeContents(editorSelector[0]);
|
||||
range.collapse(false);
|
||||
var selection = window.getSelection();
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
editorSelector[0].focus();
|
||||
fakeInput.disabled = true;
|
||||
fakeInput.parentNode.removeChild(fakeInput);
|
||||
}, 300);
|
||||
|
||||
}, 300);
|
||||
|
||||
editor.model.document.on('change', (eventInfo, name) => {
|
||||
// skip change notification on load
|
||||
if (initd) {
|
||||
|
|
|
@ -146,7 +146,7 @@ class DrawerItems extends React.Component {
|
|||
statusLabel = browser.i18n.getMessage('statusLabelSyncingDrawer');
|
||||
} else {
|
||||
let time = moment(this.props.state.sync.lastSynced).format('LT');
|
||||
statusLabel = browser.i18n.getMessage('statusLabelTimeDrawer', time);
|
||||
statusLabel = browser.i18n.getMessage('editorLabelSynced') + ' ' + time;
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
@ -30,17 +30,17 @@ class RichTextExample extends Component {
|
|||
|
||||
componentDidMount() {
|
||||
this.richtext.registerContentChangeListener((e) => {
|
||||
if (!this.note) { // new note has been paragraphed, we push on redux
|
||||
if (!this.note && e !== '<p> </p>') { // new note has been paragraphed, we push on redux
|
||||
this.note = { content: e };
|
||||
this.props.dispatch(createNote(this.note)).then((note) => {
|
||||
this.note.id = note.id;
|
||||
this.props.dispatch(setFocusedNote(note.id));
|
||||
});
|
||||
} else if (this.note && e === '') { // if we delete all caracters from a note
|
||||
} else if (this.note && (e === '' || e === '<p> </p>')) { // if we delete all caracters from a note
|
||||
this.props.dispatch(deleteNotes([ this.note.id ], 'blank-note'));
|
||||
this.note = null;
|
||||
this.props.dispatch(setFocusedNote());
|
||||
} else if (this.note && e !== '') { // default case, on modification we save
|
||||
} else if (this.note && (e !== '' || e !== '<p> </p>')) { // default case, on modification we save
|
||||
this.props.dispatch(updateNote(this.note.id, e, new Date()));
|
||||
}
|
||||
});
|
||||
|
@ -50,10 +50,14 @@ class RichTextExample extends Component {
|
|||
switch(eventData.action) {
|
||||
case KINTO_LOADED:
|
||||
if (this.note && this.props.navigation.isFocused()) {
|
||||
newNote = this.props.state.notes.find((note) => note.id === this.note.id);
|
||||
let newNote = this.props.state.notes.find((note) => note.id === this.note.id);
|
||||
// only force update content if content is different
|
||||
if (newNote) {
|
||||
this.note = newNote;
|
||||
this.richtext.setContentHTML(this.note.content);
|
||||
if(newNote.content !== this.note.content) {
|
||||
this.note = newNote;
|
||||
// Disable this for now, only conflict notes once out of the view...
|
||||
//this.richtext.setContentHTML(this.note.content);
|
||||
}
|
||||
} else {
|
||||
this.props.navigation.goBack();
|
||||
}
|
||||
|
|
|
@ -40,16 +40,15 @@ class ListPanel extends React.Component {
|
|||
ToastAndroid.show(browser.i18n.getMessage('toastOffline'), ToastAndroid.LONG);
|
||||
} else {
|
||||
trackEvent('webext-button-authenticate');
|
||||
this.setState({ refreshing: true });
|
||||
if (!this.props.state.refreshing) {
|
||||
this.setState({refreshing: true});
|
||||
this.setState({refreshing: false});
|
||||
}
|
||||
props.dispatch(kintoLoad()).then(() => {
|
||||
this.setState({ refreshing: false });
|
||||
}).catch(() => {
|
||||
this.setState({ refreshing: false });
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
this.setState({ refreshing: false });
|
||||
}, 12000)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,6 +151,7 @@ class ListPanel extends React.Component {
|
|||
})}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
enabled={! this.state.refreshing || ! this.state.sync.selected || ! this.state.sync.isSyncing}
|
||||
refreshing={this.state.refreshing}
|
||||
colors={[ COLOR_NOTES_BLUE ]}
|
||||
onRefresh={this._onRefresh.bind(this)}
|
||||
|
|
|
@ -296,84 +296,6 @@ class ListPanelWrapper extends React.Component {
|
|||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
renderList() {
|
||||
const { navigate } = this.props.navigation;
|
||||
if (!this.props.state.kinto.isLoaded) {
|
||||
return (
|
||||
<ListPanelLoading></ListPanelLoading>
|
||||
)
|
||||
} else {
|
||||
let styleList = {};
|
||||
if (this.props.state.notes.length === 0) {
|
||||
styleList = {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
paddingRight: 40,
|
||||
paddingLeft: 40
|
||||
};
|
||||
} else {
|
||||
styleList = { marginBottom:90 };
|
||||
}
|
||||
|
||||
return (
|
||||
<FlatList
|
||||
contentContainerStyle={styleList}
|
||||
data={this.props.state.notes.sort((a, b) => {
|
||||
const aStamp = new Date(a.lastModified).getTime();
|
||||
const bStamp = new Date(b.lastModified).getTime();
|
||||
return aStamp <= bStamp ? 1 : -1
|
||||
})}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={this.state.refreshing}
|
||||
colors={[ COLOR_NOTES_BLUE ]}
|
||||
onRefresh={this._onRefresh.bind(this)}
|
||||
/>
|
||||
}
|
||||
ListEmptyComponent={() => {
|
||||
return (
|
||||
<ListPanelEmpty></ListPanelEmpty>
|
||||
)
|
||||
}}
|
||||
ListHeaderComponent={() => {
|
||||
return this.props.state.notes && this.props.state.notes.length > 0 ?
|
||||
(
|
||||
<View style={{ backgroundColor: 'white', height: 10}}></View>
|
||||
)
|
||||
: null;
|
||||
}}
|
||||
keyExtractor={ (item) => item.id }
|
||||
renderItem={({item}) => {
|
||||
return (
|
||||
<ListItem
|
||||
note={item}
|
||||
navigate={navigate}
|
||||
/>
|
||||
)
|
||||
}}
|
||||
ListFooterComponent={() => {
|
||||
return this.props.state.notes && this.props.state.notes.length > 0 ?
|
||||
(
|
||||
<View style={{
|
||||
height: 1,
|
||||
backgroundColor: '#F9F9FA',
|
||||
overflow: 'visible',
|
||||
marginBottom: 90,
|
||||
elevation: 1,
|
||||
shadowColor: '#000',
|
||||
shadowOpacity: 0.24,
|
||||
shadowOffset: { width: 0, height: 0.75},
|
||||
shadowRadius: 1.5}}>
|
||||
</View>
|
||||
)
|
||||
: null;
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
|
|
|
@ -25,16 +25,19 @@ class LoadingPanel extends React.Component {
|
|||
trackEvent('login-success');
|
||||
this.props.dispatch(authenticate(loginDetails));
|
||||
let email = loginDetails.profile.email;
|
||||
ToastAndroid.show(browser.i18n.getMessage('toastLoggedInAs', email), ToastAndroid.LONG);
|
||||
ToastAndroid.show(browser.i18n.getMessage('toastLoggedInAs', email), ToastAndroid.SHORT);
|
||||
|
||||
this.props.dispatch(kintoLoad());
|
||||
|
||||
const resetAction = StackActions.reset({
|
||||
index: 0,
|
||||
actions: [NavigationActions.navigate({ routeName: 'ListPanel' })],
|
||||
});
|
||||
this.props.navigation.dispatch(resetAction);
|
||||
return Promise.resolve();
|
||||
setTimeout(() => {
|
||||
const resetAction = StackActions.reset({
|
||||
index: 0,
|
||||
actions: [NavigationActions.navigate({ routeName: 'ListPanel' })],
|
||||
});
|
||||
this.props.navigation.dispatch(resetAction);
|
||||
return Promise.resolve();
|
||||
}, 1500)
|
||||
|
||||
}).catch((err) => {
|
||||
console.log('onAuth', err);
|
||||
ToastAndroid.show(browser.i18n.getMessage('toastLoggedInError', err), ToastAndroid.LONG);
|
||||
|
|
|
@ -103,7 +103,7 @@
|
|||
</head>
|
||||
|
||||
<body id="notes">
|
||||
<input id="fake" type="text" style="height: 1px; border: 0; padding: 0; margin: 0; color: white; background: none!important;" />
|
||||
<input id="fake" type="text" style="height: 1px; border: 0; padding: 0; margin: 0; color: white; position: absolute; background: none!important;" />
|
||||
<div id="editor"> </div>
|
||||
<script>
|
||||
function init() {
|
||||
|
@ -117,34 +117,34 @@
|
|||
|
||||
zss_editor.setContentHTML = function(html) {
|
||||
editor.setData(html || '<p></p>');
|
||||
|
||||
setTimeout(function () {
|
||||
// Android won't popup the keyboard on focused <div>s, first focus a fake input then focus the div
|
||||
var fakeInput = document.querySelectorAll("#fake")[0];
|
||||
fakeInput.focus();
|
||||
|
||||
setTimeout(function () {
|
||||
// the following was taken from http://stackoverflow.com/questions/1125292/how-to-move-cursor-to-end-of-contenteditable-entity/3866442#3866442
|
||||
// and ensures we move the cursor to the end of the editor
|
||||
var editorSelector = document.querySelectorAll('.' + "ck-editor__editable");
|
||||
var range = document.createRange();
|
||||
range.selectNodeContents(editorSelector[0]);
|
||||
range.collapse(false);
|
||||
var selection = window.getSelection();
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
editorSelector[0].focus();
|
||||
fakeInput.disabled = true;
|
||||
fakeInput.parentNode.removeChild(fakeInput);
|
||||
}, 300);
|
||||
|
||||
}, 300);
|
||||
};
|
||||
|
||||
this.editor = editor;
|
||||
|
||||
postMessage(JSON.stringify({type: 'ZSS_INITIALIZED'}));
|
||||
|
||||
setTimeout(function () {
|
||||
// Android won't popup the keyboard on focused <div>s, first focus a fake input then focus the div
|
||||
var fakeInput = document.querySelectorAll("#fake")[0];
|
||||
fakeInput.focus();
|
||||
|
||||
setTimeout(function () {
|
||||
// the following was taken from http://stackoverflow.com/questions/1125292/how-to-move-cursor-to-end-of-contenteditable-entity/3866442#3866442
|
||||
// and ensures we move the cursor to the end of the editor
|
||||
var editorSelector = document.querySelectorAll('.' + "ck-editor__editable");
|
||||
var range = document.createRange();
|
||||
range.selectNodeContents(editorSelector[0]);
|
||||
range.collapse(false);
|
||||
var selection = window.getSelection();
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
editorSelector[0].focus();
|
||||
fakeInput.disabled = true;
|
||||
fakeInput.parentNode.removeChild(fakeInput);
|
||||
}, 300);
|
||||
|
||||
}, 300);
|
||||
|
||||
editor.model.document.on('change', (eventInfo, name) => {
|
||||
// skip change notification on load
|
||||
if (initd) {
|
||||
|
|
|
@ -52,6 +52,10 @@ function appUpdates(appUpdates = {}, action) {
|
|||
return Object.assign({}, appUpdates, {
|
||||
updateNote: Date.now(),
|
||||
});
|
||||
case DELETE_NOTE:
|
||||
return Object.assign({}, appUpdates, {
|
||||
deleteNote: Date.now(),
|
||||
});
|
||||
default:
|
||||
return appUpdates;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче