Skip to content
This repository has been archived by the owner on Nov 28, 2022. It is now read-only.

Commit

Permalink
Refactor new->edit transition to avoid editor re-renders
Browse files Browse the repository at this point in the history
closes TryGhost/Ghost#8287
closes TryGhost/Ghost#8750
- moved all editor model functionality into the new `editor` route+controller
- moved editor template from `editor/edit.hbs` to `editor.hbs`
- refactored `editor` controller and the `editor.new`/`editor.edit` routes to work with a persistent editor rather than a teardown/re-render when transitioning from new->edit
- fixed issue in `{{gh-markdown-editor}}` for `autofocus` behaviour when the component isn't re-rendered
- fixed issue in `{{gh-simplemde}}` that was causing multiple updates to the `value` property when a new value is passed in to the component
- added `{{gh-scheduled-post-countdown}}` component to lower the noise in the editor controller
- removed editor route/controller mixins
- removed the `editor.edit` and `editor.new` controllers
  • Loading branch information
kevinansfield committed Jan 16, 2018
1 parent 5a54a60 commit 2ce3f57
Show file tree
Hide file tree
Showing 16 changed files with 919 additions and 963 deletions.
7 changes: 7 additions & 0 deletions app/components/gh-markdown-editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,13 @@ export default Component.extend(ShortcutsMixin, {
let markdown = mobiledoc.cards[0][1].markdown;
this.set('markdown', markdown);

// focus the editor when the markdown value changes, this is necessary
// because both the autofocus and markdown values can change without a
// re-render, eg. navigating from edit->new
if (this._editor && markdown !== this._editor.value() && this.get('autofocus')) {
this.send('focusEditor');
}

// use internal values to avoid updating bound values
if (!isEmpty(this.get('isFullScreen'))) {
this.set('_isFullScreen', this.get('isFullScreen'));
Expand Down
28 changes: 28 additions & 0 deletions app/components/gh-scheduled-post-countdown.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Component from '@ember/component';
import moment from 'moment';
import {computed} from '@ember/object';
import {inject as service} from '@ember/service';

export default Component.extend({
clock: service(),

post: null,

// countdown timer to show the time left until publish time for a scheduled post
// starts 15 minutes before scheduled time
countdown: computed('post.{publishedAtUTC,isScheduled}', 'clock.second', function () {
let isScheduled = this.get('post.isScheduled');
let publishTime = this.get('post.publishedAtUTC') || moment.utc();
let timeUntilPublished = publishTime.diff(moment.utc(), 'minutes', true);
let isPublishedSoon = timeUntilPublished > 0 && timeUntilPublished < 15;

// force a recompute
this.get('clock.second');

if (isScheduled && isPublishedSoon) {
return moment(publishTime).fromNow();
} else {
return false;
}
})
});
8 changes: 6 additions & 2 deletions app/components/gh-simplemde.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,12 @@ export default TextArea.extend({
this._editor = new SimpleMDE(editorOptions);
this._editor.value(this.get('value') || '');

this._editor.codemirror.on('change', () => {
this.onChange(this._editor.value());
this._editor.codemirror.on('change', (instance, changeObj) => {
// avoid a "modified x twice in a single render" error that occurs
// when the underlying value is completely swapped out
if (changeObj.origin !== 'setValue') {
this.onChange(this._editor.value());
}
});

this._editor.codemirror.on('focus', () => {
Expand Down

0 comments on commit 2ce3f57

Please sign in to comment.