0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-10 23:36:14 -05:00

Added TK support to feature image caption editor (#19285)

closes https://github.com/TryGhost/Product/issues/4227

- added `@onTKCountChange` to `<KoenigLexicalEditorInput>`
  - when present the `isTKEnabled` flag will be turned on and the `<TKCountPlugin>` registered
- added `@registerAPI` support to `<KoenigLexicalEditorInput>` 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
This commit is contained in:
Kevin Ansfield 2023-12-07 15:46:23 +00:00 committed by GitHub
parent e5c6b0a23f
commit 309aaf98aa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 57 additions and 5 deletions

View file

@ -50,7 +50,7 @@
{{svg-jar "koenig/kg-trash"}}
</button>
</div>
<div class="flex justify-between align-center">
<div class="relative flex justify-between align-center">
{{#if this.isEditingAlt}}
<input
type="text"
@ -70,6 +70,8 @@
@placeholderText={{if this.captionInputFocused "" "Add a caption to the feature image"}}
@onFocus={{fn (mut this.captionInputFocused) true}}
@onBlur={{this.handleCaptionBlur}}
@onTKCountChange={{this.onTKCountChange}}
@registerAPI={{this.registerEditorAPI}}
/>
{{/if}}
<button
@ -78,6 +80,12 @@
>
Alt
</button>
{{#if (and this.tkCount (not this.isEditingAlt))}}
<div class="tk-indicator" data-testid="feature-image-tk-indicator" role="button" {{on "click" this.focusCaptionEditor}}>
TK
</div>
{{/if}}
</div>
{{else}}
{{!-- no-image state --}}

View file

@ -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);
}
}
}

View file

@ -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}}
/>
<div class="gh-editor-title-container page-improvements">

View file

@ -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}
>
<KoenigComposableEditor
editorResource={this.editorResource}
@ -112,9 +118,11 @@ export default class KoenigLexicalEditorInput extends Component {
className={`koenig-lexical-editor-input ${this.feature.nightShift ? 'dark' : ''}`}
placeholderText={props.placeholderText}
placeholderClassName="koenig-lexical-editor-input-placeholder"
registerAPI={this.args.registerAPI}
>
<HtmlOutputPlugin editorResource={this.editorResource} html={props.html} setHtml={props.onChangeHtml} />
{this.emojiPicker ? <EmojiPickerPlugin editorResource={this.editorResource} /> : null}
{this.args.onTKCountChange ? <TKCountPlugin editorResource={this.editorResource} onChange={this.args.onTKCountChange} /> : null}
</KoenigComposableEditor>
</KoenigComposer>
</Suspense>

View file

@ -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

View file

@ -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 {

View file

@ -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}}