From 2e807adae220a05a638ca67a29a170579032205e Mon Sep 17 00:00:00 2001 From: "Mr. Stallion" Date: Sun, 28 May 2023 21:13:16 -0700 Subject: [PATCH] eicon picker --- CHANGELOG.md | 5 +- bbcode/EIconSelector.vue | 237 +++++++++++++++++++++++++++++++++++++++ bbcode/Editor.vue | 77 +++++++++++-- chat/ChatView.vue | 26 ++++- chat/StatusSwitcher.vue | 4 + chat/ads/AdCenter.vue | 5 + learn/eicon/store.ts | 34 ++++-- learn/eicon/updater.ts | 4 +- 8 files changed, 367 insertions(+), 25 deletions(-) create mode 100644 bbcode/EIconSelector.vue diff --git a/CHANGELOG.md b/CHANGELOG.md index fc04fe7..6394276 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,14 @@ # Changelog -## 1.23.0 +## Canary * Cleaned up top menu * Profile Helper now only shows up if you have anything to fix; otherwise the profile helper can be found in the Settings menu * Post Ads and Ad Editor have been merged together + +## 1.23.0 * Improved text editor * eicon picker (courtesy of @Xariah Dailstone) * color picker - * unicode emoji picker * Added [privacy statement](PRIVACY.md) ## 1.22.0 diff --git a/bbcode/EIconSelector.vue b/bbcode/EIconSelector.vue new file mode 100644 index 0000000..ef353f9 --- /dev/null +++ b/bbcode/EIconSelector.vue @@ -0,0 +1,237 @@ + + + + + diff --git a/bbcode/Editor.vue b/bbcode/Editor.vue index 357f748..de935c7 100644 --- a/bbcode/Editor.vue +++ b/bbcode/Editor.vue @@ -16,6 +16,12 @@ +
+
+ +
+
+
@@ -59,10 +65,12 @@ import {defaultButtons, EditorButton, EditorSelection} from './editor'; import {BBCodeParser} from './parser'; import {default as IconView} from './IconView.vue'; + import {default as EIconSelector} from './EIconSelector.vue'; @Component({ components: { - 'icon': IconView + 'icon': IconView, + 'EIconSelector': EIconSelector }, mixins: [ clickaway ] }) @@ -96,6 +104,7 @@ buttonColors = ['red', 'orange', 'yellow', 'green', 'cyan', 'purple', 'blue', 'pink', 'black', 'brown', 'white', 'gray']; colorPopupVisible = false; + eiconPopupVisible = false; preview = false; previewWarnings: ReadonlyArray = []; @@ -176,7 +185,7 @@ for(let i = 0, l = this.extras.length; i < l; i++) buttons.push(this.extras[i]); - const colorButtonIndex = _.findIndex(buttons, (b) => b.icon === 'fa-eye-dropper')!; + const colorButtonIndex = _.findIndex(buttons, (b) => b.tag === 'color'); if (this.colorPopupVisible) { const colorButton = _.cloneDeep(buttons[colorButtonIndex]); @@ -185,11 +194,26 @@ buttons[colorButtonIndex] = colorButton; } + const eiconButtonIndex = _.findIndex(buttons, (b) => b.tag === 'eicon'); + + if (this.eiconPopupVisible) { + const eiconButton = _.cloneDeep(buttons[eiconButtonIndex]); + eiconButton.outerClass = 'toggled'; + + buttons[eiconButtonIndex] = eiconButton; + } + return buttons; } - getColorButton(): EditorButton { - return _.find(this.buttons, (b) => b.icon === 'fa-eye-dropper')!; + getButtonByTag(tag: string): EditorButton { + const btn = _.find(this.buttons, (b) => b.tag === tag); + + if (!btn) { + throw new Error('Unknown button'); + } + + return btn; } @Watch('value') @@ -228,16 +252,16 @@ this.element.setSelectionRange(start, end); } - applyText(startText: string, endText: string): void { + applyText(startText: string, endText: string, withInject?: string): void { const selection = this.getSelection(); if(selection.length > 0) { - const replacement = startText + selection.text + endText; + const replacement = startText + (withInject || selection.text) + endText; this.text = this.replaceSelection(replacement); this.setSelection(selection.start, selection.start + replacement.length); } else { const start = this.text.substr(0, selection.start) + startText; const end = endText + this.text.substr(selection.start); - this.text = start + end; + this.text = start + (withInject || '') + end; this.$nextTick(() => this.setSelection(start.length)); } this.$emit('input', this.text); @@ -248,27 +272,47 @@ } colorApply(btnColor: string): void { - const button = this.getColorButton(); + const button = this.getButtonByTag('color'); this.applyButtonEffect(button, btnColor); this.colorPopupVisible = false; } + dismissEIconSelector(): void { + this.eiconPopupVisible = false; + } + + onSelectEIcon(eiconId: string): void { + this.eiconApply(eiconId); + } + + eiconApply(eiconId: string): void { + const button = this.getButtonByTag('eicon'); + + this.applyButtonEffect(button, undefined, eiconId); + + this.eiconPopupVisible = false; + } + apply(button: EditorButton): void { if (button.tag === 'color') { this.colorPopupVisible = !this.colorPopupVisible; return; } else if (button.tag === 'eicon') { + this.eiconPopupVisible = !this.eiconPopupVisible; - } else if (button.tag === 'emoji') { + if (this.eiconPopupVisible) { + setTimeout(() => (this.$refs.eIconSelector as any).setFocus(), 100); + } + return; } this.applyButtonEffect(button); } - applyButtonEffect(button: EditorButton, withArgument?: string): void { + applyButtonEffect(button: EditorButton, withArgument?: string, withInject?: string): void { // Allow emitted variations for custom buttons. this.$once('insert', (startText: string, endText: string) => this.applyText(startText, endText)); // noinspection TypeScriptValidateTypes @@ -285,7 +329,7 @@ const sbl = button.startText ? button.startText.length : 0; if(this.text.length + sbl + ebl > this.maxlength) return; - this.applyText(button.startText || '', button.endText || ''); + this.applyText(button.startText || '', button.endText || '', withInject); this.lastInput = Date.now(); } @@ -402,6 +446,17 @@ } } + .eicon-selector { + width: 550px; + max-width: 550px; + top: -169px; + left: 0; + line-height: 1; + z-index: 1000; + background-color: var(--input-bg); + min-height: 170px; + } + .color-selector { max-width: 145px; top: -57px; diff --git a/chat/ChatView.vue b/chat/ChatView.vue index 36b9a98..7dcec56 100644 --- a/chat/ChatView.vue +++ b/chat/ChatView.vue @@ -65,7 +65,7 @@
- Open Conversation + Open Conversation
@@ -86,7 +86,7 @@ - Join Channel + Join Channel
@@ -136,7 +136,7 @@ /me