mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-10 23:36:14 -05:00
Added TK indicator support to post title (#19231)
closes TryGhost/Product#4208 - added TK indicator to post title - added to TK count in confirmation flow
This commit is contained in:
parent
960fde80db
commit
96320d378a
5 changed files with 80 additions and 7 deletions
|
@ -28,6 +28,15 @@
|
|||
</span>
|
||||
{{/if}}
|
||||
|
||||
{{#if (and (feature "tkReminders") @titleHasTk)}}
|
||||
<div
|
||||
class="tk-indicator" data-testid="tk-indicator"
|
||||
{{on "click" this.focusTitle}}
|
||||
>
|
||||
TK
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<GhTextarea
|
||||
@class="gh-editor-title {{if (and (not @cardOptions.post.showTitleAndFeatureImage) (not this.titleIsFocused)) "faded"}}"
|
||||
@placeholder={{@titlePlaceholder}}
|
||||
|
@ -56,7 +65,7 @@
|
|||
@registerAPI={{this.registerEditorAPI}}
|
||||
@cursorDidExitAtTop={{this.focusTitle}}
|
||||
@updateWordCount={{@updateWordCount}}
|
||||
@updateTkCount={{@updateTkCount}}
|
||||
@updatePostTkCount={{@updatePostTkCount}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -536,7 +536,7 @@ export default class KoenigLexicalEditor extends Component {
|
|||
registerAPI={this.args.registerAPI}
|
||||
/>
|
||||
<WordCountPlugin editorResource={this.editorResource} onChange={this.args.updateWordCount} />
|
||||
{this.feature.tkReminders && <TKPlugin editorResource={this.editorResource} onCountChange={this.args.updateTkCount} />}
|
||||
{this.feature.tkReminders && <TKPlugin editorResource={this.editorResource} onCountChange={this.args.updatePostTkCount} />}
|
||||
</KoenigComposer>
|
||||
</Suspense>
|
||||
</ErrorHandler>
|
||||
|
|
|
@ -35,6 +35,9 @@ const AUTOSAVE_TIMEOUT = 3000;
|
|||
// time in ms to force a save if the user is continuously typing
|
||||
const TIMEDSAVE_TIMEOUT = 60000;
|
||||
|
||||
const TK_REGEX = new RegExp(/(^|.)([^\p{L}\p{N}\s]*(TK)+[^\p{L}\p{N}\s]*)(.)?/u);
|
||||
const WORD_CHAR_REGEX = new RegExp(/\p{L}|\p{N}/u);
|
||||
|
||||
// this array will hold properties we need to watch for this.hasDirtyAttributes
|
||||
let watchedProps = [
|
||||
'post.lexicalScratch',
|
||||
|
@ -127,7 +130,7 @@ export default class LexicalEditorController extends Controller {
|
|||
|
||||
// koenig related properties
|
||||
wordCount = 0;
|
||||
tkCount = 0;
|
||||
postTkCount = 0;
|
||||
|
||||
/* private properties ----------------------------------------------------*/
|
||||
|
||||
|
@ -215,6 +218,55 @@ export default class LexicalEditorController extends Controller {
|
|||
return config.environment !== 'test' && this.get('post.isDraft');
|
||||
}
|
||||
|
||||
TK_REGEX = new RegExp(/(^|.)([^\p{L}\p{N}\s]*(TK)+[^\p{L}\p{N}\s]*)(.)?/u);
|
||||
WORD_CHAR_REGEX = new RegExp(/\p{L}|\p{N}/u);
|
||||
|
||||
@computed('post.titleScratch')
|
||||
get titleHasTk() {
|
||||
let text = this.post.titleScratch;
|
||||
let matchArr = TK_REGEX.exec(text);
|
||||
|
||||
if (matchArr === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
function isValidMatch(match) {
|
||||
// negative lookbehind isn't supported before Safari 16.4
|
||||
// so we capture the preceding char and test it here
|
||||
if (match[1] && match[1].trim() && WORD_CHAR_REGEX.test(match[1])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// we also check any following char in code to avoid an overly
|
||||
// complex regex when looking for word-chars following the optional
|
||||
// trailing symbol char
|
||||
if (match[4] && match[4].trim() && WORD_CHAR_REGEX.test(match[4])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// our regex will match invalid TKs because we can't use negative lookbehind
|
||||
// so we need to loop through the matches discarding any that are invalid
|
||||
// and moving on to any subsequent matches
|
||||
while (matchArr !== null && !isValidMatch(matchArr)) {
|
||||
text = text.slice(matchArr.index + matchArr[0].length - 1);
|
||||
matchArr = TK_REGEX.exec(text);
|
||||
}
|
||||
|
||||
if (matchArr === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@computed('titleHasTk', 'postTkCount')
|
||||
get tkCount() {
|
||||
return (this.titleHasTk ? 1 : 0) + this.postTkCount;
|
||||
}
|
||||
|
||||
@action
|
||||
updateScratch(lexical) {
|
||||
this.set('post.lexicalScratch', JSON.stringify(lexical));
|
||||
|
@ -312,8 +364,8 @@ export default class LexicalEditorController extends Controller {
|
|||
}
|
||||
|
||||
@action
|
||||
updateTkCount(count) {
|
||||
this.set('tkCount', count);
|
||||
updatePostTkCount(count) {
|
||||
this.set('postTkCount', count);
|
||||
}
|
||||
|
||||
@action
|
||||
|
@ -1082,7 +1134,7 @@ export default class LexicalEditorController extends Controller {
|
|||
this.set('shouldFocusTitle', false);
|
||||
this.set('showSettingsMenu', false);
|
||||
this.set('wordCount', 0);
|
||||
this.set('tkCount', 0);
|
||||
this.set('postTkCount', 0);
|
||||
|
||||
// remove the onbeforeunload handler as it's only relevant whilst on
|
||||
// the editor route
|
||||
|
|
|
@ -683,6 +683,17 @@ body[data-user-is-dragging] .gh-editor-feature-image-dropzone {
|
|||
opacity: .5;
|
||||
}
|
||||
|
||||
.gh-editor-title-container .tk-indicator {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: -5.6rem;
|
||||
padding: .4rem;
|
||||
color: #95A1AD;
|
||||
font-size: 1.2rem;
|
||||
font-weight: 500;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.gh-editor-back-button {
|
||||
height: 34px;
|
||||
margin-right: 8px;
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
@title={{readonly this.post.titleScratch}}
|
||||
@titleAutofocus={{this.shouldFocusTitle}}
|
||||
@titlePlaceholder={{concat (capitalize this.post.displayName) " title"}}
|
||||
@titleHasTk={{this.titleHasTk}}
|
||||
@onTitleChange={{this.updateTitleScratch}}
|
||||
@onTitleBlur={{perform this.saveTitleTask}}
|
||||
@body={{readonly this.post.lexicalScratch}}
|
||||
|
@ -77,7 +78,7 @@
|
|||
@scrollOffsetBottomSelector=".gh-mobile-nav-bar"
|
||||
@onEditorCreated={{this.setKoenigEditor}}
|
||||
@updateWordCount={{this.updateWordCount}}
|
||||
@updateTkCount={{this.updateTkCount}}
|
||||
@updatePostTkCount={{this.updatePostTkCount}}
|
||||
@featureImage={{this.post.featureImage}}
|
||||
@featureImageAlt={{this.post.featureImageAlt}}
|
||||
@featureImageCaption={{this.post.featureImageCaption}}
|
||||
|
|
Loading…
Add table
Reference in a new issue