From 309aaf98aa545ff69d7bfdb69fd22218a9c17cdb Mon Sep 17 00:00:00 2001 From: Kevin Ansfield Date: Thu, 7 Dec 2023 15:46:23 +0000 Subject: [PATCH] Added TK support to feature image caption editor (#19285) closes https://github.com/TryGhost/Product/issues/4227 - added `@onTKCountChange` to `` - when present the `isTKEnabled` flag will be turned on and the `` registered - added `@registerAPI` support to `` so we can focus the caption editor when its TK indicator is clicked - added manual display of TK indicator for the caption input - default editor indicator positioning doesn't work for this input because its container is not full editor width - hid it by adding `overflow: hidden` to the inner caption container - added custom indicator button shown when we have a non-zero count --- .../components/gh-editor-feature-image.hbs | 10 ++++++++- .../app/components/gh-editor-feature-image.js | 21 +++++++++++++++++++ .../components/gh-koenig-editor-lexical.hbs | 1 + .../components/koenig-lexical-editor-input.js | 8 +++++++ ghost/admin/app/controllers/lexical-editor.js | 11 ++++++++-- ghost/admin/app/styles/layouts/editor.css | 10 +++++++-- ghost/admin/app/templates/lexical-editor.hbs | 1 + 7 files changed, 57 insertions(+), 5 deletions(-) diff --git a/ghost/admin/app/components/gh-editor-feature-image.hbs b/ghost/admin/app/components/gh-editor-feature-image.hbs index aaf68c256a..ddda57309c 100644 --- a/ghost/admin/app/components/gh-editor-feature-image.hbs +++ b/ghost/admin/app/components/gh-editor-feature-image.hbs @@ -50,7 +50,7 @@ {{svg-jar "koenig/kg-trash"}} -
+
{{#if this.isEditingAlt}} {{/if}} + + {{#if (and this.tkCount (not this.isEditingAlt))}} +
+ TK +
+ {{/if}}
{{else}} {{!-- no-image state --}} diff --git a/ghost/admin/app/components/gh-editor-feature-image.js b/ghost/admin/app/components/gh-editor-feature-image.js index 0bc821093d..d621d0de5f 100644 --- a/ghost/admin/app/components/gh-editor-feature-image.js +++ b/ghost/admin/app/components/gh-editor-feature-image.js @@ -18,6 +18,7 @@ export default class GhEditorFeatureImageComponent extends Component { @tracked captionInputFocused = false; @tracked showUnsplashSelector = false; @tracked canDrop = false; + @tracked tkCount = 0; get caption() { const content = this.args.caption; @@ -34,6 +35,18 @@ export default class GhEditorFeatureImageComponent extends Component { this.args.updateCaption(cleanedHtml); } + @action + registerEditorAPI(API) { + this.editorAPI = API; + } + + @action + focusCaptionEditor() { + if (this.editorAPI) { + this.editorAPI.focusEditor({position: 'bottom'}); + } + } + @action handleCaptionBlur() { this.captionInputFocused = false; @@ -116,4 +129,12 @@ export default class GhEditorFeatureImageComponent extends Component { this.canDrop = false; setFiles([imageFile]); } + + @action + onTKCountChange(count) { + if (this.args.onTKCountChange) { + this.tkCount = count; + this.args.onTKCountChange(count); + } + } } diff --git a/ghost/admin/app/components/gh-koenig-editor-lexical.hbs b/ghost/admin/app/components/gh-koenig-editor-lexical.hbs index a8efb4d02e..12b88c3032 100644 --- a/ghost/admin/app/components/gh-koenig-editor-lexical.hbs +++ b/ghost/admin/app/components/gh-koenig-editor-lexical.hbs @@ -19,6 +19,7 @@ @handleCaptionBlur={{@handleFeatureImageCaptionBlur}} @forceButtonDisplay={{or (not @title) (eq @title "(Untitled)") this.titleIsHovered this.titleIsFocused}} @isHidden={{or (not @cardOptions.post.showTitleAndFeatureImage) false}} + @onTKCountChange={{@updateFeatureImageTkCount}} />
diff --git a/ghost/admin/app/components/koenig-lexical-editor-input.js b/ghost/admin/app/components/koenig-lexical-editor-input.js index 526b6cd34b..19bcbdd705 100644 --- a/ghost/admin/app/components/koenig-lexical-editor-input.js +++ b/ghost/admin/app/components/koenig-lexical-editor-input.js @@ -57,6 +57,11 @@ const EmojiPickerPlugin = ({editorResource, ...props}) => { return <_EmojiPickerPlugin {...props} />; }; +const TKCountPlugin = ({editorResource, ...props}) => { + const {TKCountPlugin: _TKCountPlugin} = editorResource.read(); + return <_TKCountPlugin {...props} />; +}; + export default class KoenigLexicalEditorInput extends Component { @service ajax; @service feature; @@ -100,6 +105,7 @@ export default class KoenigLexicalEditorInput extends Component { editorResource={this.editorResource} initialEditorState={this.args.lexical} onError={this.onError} + isTKEnabled={this.args.onTKCountChange ? true : false} > {this.emojiPicker ? : null} + {this.args.onTKCountChange ? : null} diff --git a/ghost/admin/app/controllers/lexical-editor.js b/ghost/admin/app/controllers/lexical-editor.js index ce21935936..a233e409e6 100644 --- a/ghost/admin/app/controllers/lexical-editor.js +++ b/ghost/admin/app/controllers/lexical-editor.js @@ -131,6 +131,7 @@ export default class LexicalEditorController extends Controller { // koenig related properties wordCount = 0; postTkCount = 0; + featureImageTkCount = 0; /* private properties ----------------------------------------------------*/ @@ -262,9 +263,9 @@ export default class LexicalEditorController extends Controller { return true; } - @computed('titleHasTk', 'postTkCount') + @computed('titleHasTk', 'postTkCount', 'featureImageTkCount') get tkCount() { - return (this.titleHasTk ? 1 : 0) + this.postTkCount; + return (this.titleHasTk ? 1 : 0) + this.postTkCount + this.featureImageTkCount; } @action @@ -368,6 +369,11 @@ export default class LexicalEditorController extends Controller { this.set('postTkCount', count); } + @action + updateFeatureImageTkCount(count) { + this.set('featureImageTkCount', count); + } + @action setFeatureImage(url) { this.post.set('featureImage', url); @@ -1135,6 +1141,7 @@ export default class LexicalEditorController extends Controller { this.set('showSettingsMenu', false); this.set('wordCount', 0); this.set('postTkCount', 0); + this.set('featureImageTkCount', 0); // remove the onbeforeunload handler as it's only relevant whilst on // the editor route diff --git a/ghost/admin/app/styles/layouts/editor.css b/ghost/admin/app/styles/layouts/editor.css index 2af885244b..be44f97f09 100644 --- a/ghost/admin/app/styles/layouts/editor.css +++ b/ghost/admin/app/styles/layouts/editor.css @@ -635,6 +635,7 @@ body[data-user-is-dragging] .gh-editor-feature-image-dropzone { background-color: transparent !important; transition: border-color .15s linear; -webkit-appearance: none; + overflow: hidden; /* Hides any indicators such as TK */ } .gh-editor-feature-image-alttext::placeholder, @@ -683,7 +684,7 @@ body[data-user-is-dragging] .gh-editor-feature-image-dropzone { opacity: .5; } -.gh-editor-title-container .tk-indicator { +.gh-editor .tk-indicator { position: absolute; top: 15px; right: -5.6rem; @@ -691,7 +692,12 @@ body[data-user-is-dragging] .gh-editor-feature-image-dropzone { color: #95A1AD; font-size: 1.2rem; font-weight: 500; - cursor: default; + cursor: pointer; +} + +.gh-editor-feature-image-container .tk-indicator { + top: 0; + padding: 0 .4rem; } .gh-editor-back-button { diff --git a/ghost/admin/app/templates/lexical-editor.hbs b/ghost/admin/app/templates/lexical-editor.hbs index d0cb2d14b2..3d7cd95c9a 100644 --- a/ghost/admin/app/templates/lexical-editor.hbs +++ b/ghost/admin/app/templates/lexical-editor.hbs @@ -79,6 +79,7 @@ @onEditorCreated={{this.setKoenigEditor}} @updateWordCount={{this.updateWordCount}} @updatePostTkCount={{this.updatePostTkCount}} + @updateFeatureImageTkCount={{if (feature "tkReminders") this.updateFeatureImageTkCount}} @featureImage={{this.post.featureImage}} @featureImageAlt={{this.post.featureImageAlt}} @featureImageCaption={{this.post.featureImageCaption}}