diff --git a/src/App.scss b/src/App.scss index 2190f91a..fe271ce1 100644 --- a/src/App.scss +++ b/src/App.scss @@ -658,6 +658,18 @@ nav { color: var(--alertErrorPanelText, $fallback--text); } } + + &.warning { + background-color: $fallback--alertWarning; + background-color: var(--alertWarning, $fallback--alertWarning); + color: $fallback--text; + color: var(--alertWarningText, $fallback--text); + + .panel-heading & { + color: $fallback--text; + color: var(--alertWarningPanelText, $fallback--text); + } + } } .faint { diff --git a/src/_variables.scss b/src/_variables.scss index 150e4fb5..e18101f0 100644 --- a/src/_variables.scss +++ b/src/_variables.scss @@ -17,6 +17,7 @@ $fallback--cGreen: #0fa00f; $fallback--cOrange: orange; $fallback--alertError: rgba(211,16,20,.5); +$fallback--alertWarning: rgba(111,111,20,.5); $fallback--panelRadius: 10px; $fallback--checkboxRadius: 2px; diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index 81f7437f..11dbdf44 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -1,5 +1,9 @@ import { set } from 'vue' +const LOAD_EMOJI_BY = 50 +const LOAD_EMOJI_INTERVAL = 100 +const LOAD_EMOJI_SANE_AMOUNT = 500 + const filterByKeyword = (list, keyword = '') => { return list.filter(x => x.displayText.includes(keyword)) } @@ -21,13 +25,17 @@ const EmojiPicker = { groupsScrolledClass: 'scrolled-top', keepOpen: false, customEmojiBuffer: [], - customEmojiInterval: null, - customEmojiCounter: 0 + customEmojiTimeout: null, + customEmojiCounter: 0, + customEmojiLoadAllConfirmed: false } }, components: { StickerPicker: () => import('../sticker_picker/sticker_picker.vue') }, + mounted () { + this.startEmojiLoad() + }, methods: { onEmoji (emoji) { const value = emoji.imageUrl ? `:${emoji.displayText}:` : emoji.replacement @@ -61,35 +69,39 @@ const EmojiPicker = { }) }) }, - restartInterval () { - const customEmojis = filterByKeyword( - this.$store.state.instance.customEmoji || [], - this.keyword - ) - const amount = 50 - const interval = 100 + loadEmojiInsane () { + this.customEmojiLoadAllConfirmed = true + this.continueEmojiLoad() + }, + loadEmoji () { + const allLoaded = this.customEmojiBuffer.length === this.filteredEmoji.length + const saneLoaded = this.customEmojiBuffer.length >= LOAD_EMOJI_SANE_AMOUNT && + !this.customEmojiLoadAllConfirmed - if (this.customEmojiInterval) { - window.clearInterval(this.customEmojiInterval) + if (allLoaded || saneLoaded) { + return } - window.setTimeout( - window.clearInterval(this.customEmojiInterval), - 1000 + + this.customEmojiBuffer.push( + ...this.filteredEmoji.slice( + this.customEmojiCounter, + this.customEmojiCounter + LOAD_EMOJI_BY + ) ) + this.customEmojiTimeout = window.setTimeout(this.loadEmoji, LOAD_EMOJI_INTERVAL) + this.customEmojiCounter += LOAD_EMOJI_BY + }, + startEmojiLoad () { + if (this.customEmojiTimeout) { + window.clearTimeout(this.customEmojiTimeout) + } + set(this, 'customEmojiBuffer', []) this.customEmojiCounter = 0 - this.customEmojiInterval = window.setInterval(() => { - console.log(this.customEmojiBuffer.length) - console.log(customEmojis.length) - if (this.customEmojiBuffer.length < customEmojis.length) { - this.customEmojiBuffer.push( - ...customEmojis.slice(this.customEmojiCounter, this.customEmojiCounter + amount) - ) - } else { - window.clearInterval(this.customEmojiInterval) - } - this.customEmojiCounter += amount - }, interval) + this.customEmojiTimeout = window.setTimeout(this.loadEmoji, LOAD_EMOJI_INTERVAL) + }, + continueEmojiLoad () { + this.customEmojiTimeout = window.setTimeout(this.loadEmoji, LOAD_EMOJI_INTERVAL) }, toggleStickers () { this.showingStickers = !this.showingStickers @@ -107,7 +119,7 @@ const EmojiPicker = { watch: { keyword () { this.scrolledGroup() - this.restartInterval() + this.startEmojiLoad() } }, computed: { @@ -120,6 +132,20 @@ const EmojiPicker = { } return 0 }, + saneAmount () { + // for UI + return LOAD_EMOJI_SANE_AMOUNT + }, + filteredEmoji () { + return filterByKeyword( + this.$store.state.instance.customEmoji || [], + this.keyword + ) + }, + askForSanity () { + return this.customEmojiBuffer.length >= LOAD_EMOJI_SANE_AMOUNT && + !this.customEmojiLoadAllConfirmed + }, emojis () { const standardEmojis = this.$store.state.instance.emoji || [] const customEmojis = this.customEmojiBuffer diff --git a/src/components/emoji_picker/emoji_picker.scss b/src/components/emoji_picker/emoji_picker.scss index b0ed00e9..6608f393 100644 --- a/src/components/emoji_picker/emoji_picker.scss +++ b/src/components/emoji_picker/emoji_picker.scss @@ -6,14 +6,20 @@ position: absolute; right: 0; left: 0; - height: 320px; margin: 0 !important; z-index: 1; - .keep-open { + .keep-open, + .too-many-emoji { padding: 7px; line-height: normal; } + + .too-many-emoji { + display: flex; + flex-direction: column; + } + .keep-open-label { padding: 0 7px; display: flex; @@ -28,7 +34,7 @@ .content { display: flex; flex-direction: column; - flex: 1 1 0; + flex: 1 1 auto; min-height: 0px; } @@ -36,12 +42,16 @@ flex-grow: 1; } + .emoji-groups { + min-height: 200px; + } + .additional-tabs { border-left: 1px solid; border-left-color: $fallback--icon; border-left-color: var(--icon, $fallback--icon); padding-left: 7px; - flex: 0 0 0; + flex: 0 0 auto; } .additional-tabs, @@ -72,7 +82,7 @@ } .sticker-picker { - flex: 1 1 0 + flex: 1 1 auto } .stickers, @@ -80,7 +90,7 @@ &-content { display: flex; flex-direction: column; - flex: 1 1 0; + flex: 1 1 auto; min-height: 0; &.hidden { @@ -94,7 +104,7 @@ .emoji { &-search { padding: 5px; - flex: 0 0 0; + flex: 0 0 auto; input { width: 100%; diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue index 42f20130..d9daac3e 100644 --- a/src/components/emoji_picker/emoji_picker.vue +++ b/src/components/emoji_picker/emoji_picker.vue @@ -92,6 +92,17 @@ +
+
+ {{ $t('emoji.load_all_hint', { saneAmount } ) }} +
+ +
+ +

{{ $t('settings.style.advanced_colors.badge') }}

diff --git a/src/i18n/en.json b/src/i18n/en.json index 32c25e3e..c6c98c48 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -114,7 +114,9 @@ "search_emoji": "Search for an emoji", "add_emoji": "Insert emoji", "custom": "Custom emoji", - "unicode": "Unicode emoji" + "unicode": "Unicode emoji", + "load_all_hint": "Loaded first {saneAmount} emoji, loading all emoji may cause performance issues.", + "load_all": "Loading all {emojiAmount} emoji" }, "interactions": { "favs_repeats": "Repeats and Favorites", @@ -387,6 +389,7 @@ "_tab_label": "Advanced", "alert": "Alert background", "alert_error": "Error", + "alert_warning": "Warning", "badge": "Badge background", "badge_notification": "Notification", "panel_header": "Panel header", diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js index 1cf7edc3..eaa495c4 100644 --- a/src/services/style_setter/style_setter.js +++ b/src/services/style_setter/style_setter.js @@ -215,6 +215,10 @@ const generateColors = (input) => { colors.alertErrorText = getTextColor(alphaBlend(colors.alertError, opacity.alert, colors.bg), colors.text) colors.alertErrorPanelText = getTextColor(alphaBlend(colors.alertError, opacity.alert, colors.panel), colors.panelText) + colors.alertWarning = col.alertWarning || Object.assign({}, colors.cOrange) + colors.alertWarningText = getTextColor(alphaBlend(colors.alertWarning, opacity.alert, colors.bg), colors.text) + colors.alertWarningPanelText = getTextColor(alphaBlend(colors.alertWarning, opacity.alert, colors.panel), colors.panelText) + colors.badgeNotification = col.badgeNotification || Object.assign({}, colors.cRed) colors.badgeNotificationText = contrastRatio(colors.badgeNotification).rgb @@ -222,6 +226,7 @@ const generateColors = (input) => { if (typeof v === 'undefined') return if (k === 'alert') { colors.alertError.a = v + colors.alertWarning.a = v return } if (k === 'faint') {