Ghost/ghost/admin/app/components/gh-editor.js
Kevin Ansfield 3d16b95e0f 🎨 Adjusted post settings menu design so it can stay open whilst editing
refs https://github.com/TryGhost/Team/issues/840

We wanted to switch to a settings menu that stays open to the right of the editor rather than a popover that blocks all other interaction with the post to solve two use-cases:

1.  when editing it's fairly common to select some text from the post contents when setting excerpt and meta data text, with the previous design not letting you scroll or select whilst the menu got in the way of that
2. having the menu open with meta data visible before publishing can help you see everything is set as you want and help you feel confident when publishing/sending content

---

- removed `psmRedesign` labs flag
- swapped labs component/css for main component and deleted labs component
- cleaned up now-unused `ui.showSettingsMenu` property and related actions/classes
2021-07-02 19:04:57 +01:00

131 lines
3.4 KiB
JavaScript

import Component from '@ember/component';
import {
IMAGE_EXTENSIONS,
IMAGE_MIME_TYPES
} from 'ghost-admin/components/gh-image-uploader';
import {debounce, run} from '@ember/runloop';
import {inject as service} from '@ember/service';
export default Component.extend({
feature: service(),
ui: service(),
classNameBindings: [
'isDraggedOver:-drag-over',
'isFullScreen:gh-editor-fullscreen',
'isPreview:gh-editor-preview'
],
// Internal attributes
droppedFiles: null,
headerHeight: 0,
imageExtensions: IMAGE_EXTENSIONS,
imageMimeTypes: IMAGE_MIME_TYPES,
isDraggedOver: false,
isFullScreen: false,
isSplitScreen: false,
uploadedImageUrls: null,
// Private
_dragCounter: 0,
_onResizeHandler: null,
_viewActionsWidth: 190,
actions: {
toggleFullScreen(isFullScreen) {
this.set('isFullScreen', isFullScreen);
this.ui.set('isFullScreen', isFullScreen);
},
togglePreview(isPreview) {
this.set('isPreview', isPreview);
},
toggleSplitScreen(isSplitScreen) {
this.set('isSplitScreen', isSplitScreen);
},
uploadImages(fileList, resetInput) {
// convert FileList to an array so that resetting the input doesn't
// clear the file references before upload actions can be triggered
let files = Array.from(fileList);
this.set('droppedFiles', files);
resetInput();
},
uploadComplete(uploads) {
this.set('uploadedImageUrls', uploads.mapBy('url'));
this.set('droppedFiles', null);
},
uploadCancelled() {
this.set('droppedFiles', null);
}
},
_setHeaderHeight() {
if (this.headerClass && this._editorTitleElement) {
let height = this._editorTitleElement.offsetHeight;
return this.set('headerHeight', height);
}
this.set('headerHeight', 0);
},
// dragOver is needed so that drop works
dragOver(event) {
if (!event.dataTransfer) {
return;
}
// this is needed to work around inconsistencies with dropping files
// from Chrome's downloads bar
if (navigator.userAgent.indexOf('Chrome') > -1) {
let eA = event.dataTransfer.effectAllowed;
event.dataTransfer.dropEffect = (eA === 'move' || eA === 'linkMove') ? 'move' : 'copy';
}
event.preventDefault();
event.stopPropagation();
},
// dragEnter is needed so that the drag class is correctly removed
dragEnter(event) {
if (!event.dataTransfer) {
return;
}
event.preventDefault();
event.stopPropagation();
// the counter technique prevents flickering of the drag class when
// dragging across child elements
this._dragCounter += 1;
this.set('isDraggedOver', true);
},
dragLeave(event) {
event.preventDefault();
event.stopPropagation();
this._dragCounter -= 1;
if (this._dragCounter === 0) {
this.set('isDraggedOver', false);
}
},
drop(event) {
event.preventDefault();
event.stopPropagation();
this._dragCounter = 0;
this.set('isDraggedOver', false);
if (event.dataTransfer.files) {
this.set('droppedFiles', event.dataTransfer.files);
}
}
});