arbitrary limit with option to overcome it
This commit is contained in:
parent
29e6e62e7c
commit
6511a744a2
9 changed files with 113 additions and 35 deletions
12
src/App.scss
12
src/App.scss
|
@ -658,6 +658,18 @@ nav {
|
||||||
color: var(--alertErrorPanelText, $fallback--text);
|
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 {
|
.faint {
|
||||||
|
|
|
@ -17,6 +17,7 @@ $fallback--cGreen: #0fa00f;
|
||||||
$fallback--cOrange: orange;
|
$fallback--cOrange: orange;
|
||||||
|
|
||||||
$fallback--alertError: rgba(211,16,20,.5);
|
$fallback--alertError: rgba(211,16,20,.5);
|
||||||
|
$fallback--alertWarning: rgba(111,111,20,.5);
|
||||||
|
|
||||||
$fallback--panelRadius: 10px;
|
$fallback--panelRadius: 10px;
|
||||||
$fallback--checkboxRadius: 2px;
|
$fallback--checkboxRadius: 2px;
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
import { set } from 'vue'
|
import { set } from 'vue'
|
||||||
|
|
||||||
|
const LOAD_EMOJI_BY = 50
|
||||||
|
const LOAD_EMOJI_INTERVAL = 100
|
||||||
|
const LOAD_EMOJI_SANE_AMOUNT = 500
|
||||||
|
|
||||||
const filterByKeyword = (list, keyword = '') => {
|
const filterByKeyword = (list, keyword = '') => {
|
||||||
return list.filter(x => x.displayText.includes(keyword))
|
return list.filter(x => x.displayText.includes(keyword))
|
||||||
}
|
}
|
||||||
|
@ -21,13 +25,17 @@ const EmojiPicker = {
|
||||||
groupsScrolledClass: 'scrolled-top',
|
groupsScrolledClass: 'scrolled-top',
|
||||||
keepOpen: false,
|
keepOpen: false,
|
||||||
customEmojiBuffer: [],
|
customEmojiBuffer: [],
|
||||||
customEmojiInterval: null,
|
customEmojiTimeout: null,
|
||||||
customEmojiCounter: 0
|
customEmojiCounter: 0,
|
||||||
|
customEmojiLoadAllConfirmed: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
StickerPicker: () => import('../sticker_picker/sticker_picker.vue')
|
StickerPicker: () => import('../sticker_picker/sticker_picker.vue')
|
||||||
},
|
},
|
||||||
|
mounted () {
|
||||||
|
this.startEmojiLoad()
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onEmoji (emoji) {
|
onEmoji (emoji) {
|
||||||
const value = emoji.imageUrl ? `:${emoji.displayText}:` : emoji.replacement
|
const value = emoji.imageUrl ? `:${emoji.displayText}:` : emoji.replacement
|
||||||
|
@ -61,35 +69,39 @@ const EmojiPicker = {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
restartInterval () {
|
loadEmojiInsane () {
|
||||||
const customEmojis = filterByKeyword(
|
this.customEmojiLoadAllConfirmed = true
|
||||||
this.$store.state.instance.customEmoji || [],
|
this.continueEmojiLoad()
|
||||||
this.keyword
|
},
|
||||||
)
|
loadEmoji () {
|
||||||
const amount = 50
|
const allLoaded = this.customEmojiBuffer.length === this.filteredEmoji.length
|
||||||
const interval = 100
|
const saneLoaded = this.customEmojiBuffer.length >= LOAD_EMOJI_SANE_AMOUNT &&
|
||||||
|
!this.customEmojiLoadAllConfirmed
|
||||||
|
|
||||||
if (this.customEmojiInterval) {
|
if (allLoaded || saneLoaded) {
|
||||||
window.clearInterval(this.customEmojiInterval)
|
return
|
||||||
}
|
}
|
||||||
window.setTimeout(
|
|
||||||
window.clearInterval(this.customEmojiInterval),
|
this.customEmojiBuffer.push(
|
||||||
1000
|
...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', [])
|
set(this, 'customEmojiBuffer', [])
|
||||||
this.customEmojiCounter = 0
|
this.customEmojiCounter = 0
|
||||||
this.customEmojiInterval = window.setInterval(() => {
|
this.customEmojiTimeout = window.setTimeout(this.loadEmoji, LOAD_EMOJI_INTERVAL)
|
||||||
console.log(this.customEmojiBuffer.length)
|
},
|
||||||
console.log(customEmojis.length)
|
continueEmojiLoad () {
|
||||||
if (this.customEmojiBuffer.length < customEmojis.length) {
|
this.customEmojiTimeout = window.setTimeout(this.loadEmoji, LOAD_EMOJI_INTERVAL)
|
||||||
this.customEmojiBuffer.push(
|
|
||||||
...customEmojis.slice(this.customEmojiCounter, this.customEmojiCounter + amount)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
window.clearInterval(this.customEmojiInterval)
|
|
||||||
}
|
|
||||||
this.customEmojiCounter += amount
|
|
||||||
}, interval)
|
|
||||||
},
|
},
|
||||||
toggleStickers () {
|
toggleStickers () {
|
||||||
this.showingStickers = !this.showingStickers
|
this.showingStickers = !this.showingStickers
|
||||||
|
@ -107,7 +119,7 @@ const EmojiPicker = {
|
||||||
watch: {
|
watch: {
|
||||||
keyword () {
|
keyword () {
|
||||||
this.scrolledGroup()
|
this.scrolledGroup()
|
||||||
this.restartInterval()
|
this.startEmojiLoad()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -120,6 +132,20 @@ const EmojiPicker = {
|
||||||
}
|
}
|
||||||
return 0
|
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 () {
|
emojis () {
|
||||||
const standardEmojis = this.$store.state.instance.emoji || []
|
const standardEmojis = this.$store.state.instance.emoji || []
|
||||||
const customEmojis = this.customEmojiBuffer
|
const customEmojis = this.customEmojiBuffer
|
||||||
|
|
|
@ -6,14 +6,20 @@
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
height: 320px;
|
|
||||||
margin: 0 !important;
|
margin: 0 !important;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
|
||||||
.keep-open {
|
.keep-open,
|
||||||
|
.too-many-emoji {
|
||||||
padding: 7px;
|
padding: 7px;
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.too-many-emoji {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
.keep-open-label {
|
.keep-open-label {
|
||||||
padding: 0 7px;
|
padding: 0 7px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -28,7 +34,7 @@
|
||||||
.content {
|
.content {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex: 1 1 0;
|
flex: 1 1 auto;
|
||||||
min-height: 0px;
|
min-height: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,12 +42,16 @@
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.emoji-groups {
|
||||||
|
min-height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
.additional-tabs {
|
.additional-tabs {
|
||||||
border-left: 1px solid;
|
border-left: 1px solid;
|
||||||
border-left-color: $fallback--icon;
|
border-left-color: $fallback--icon;
|
||||||
border-left-color: var(--icon, $fallback--icon);
|
border-left-color: var(--icon, $fallback--icon);
|
||||||
padding-left: 7px;
|
padding-left: 7px;
|
||||||
flex: 0 0 0;
|
flex: 0 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.additional-tabs,
|
.additional-tabs,
|
||||||
|
@ -72,7 +82,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.sticker-picker {
|
.sticker-picker {
|
||||||
flex: 1 1 0
|
flex: 1 1 auto
|
||||||
}
|
}
|
||||||
|
|
||||||
.stickers,
|
.stickers,
|
||||||
|
@ -80,7 +90,7 @@
|
||||||
&-content {
|
&-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex: 1 1 0;
|
flex: 1 1 auto;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
|
|
||||||
&.hidden {
|
&.hidden {
|
||||||
|
@ -94,7 +104,7 @@
|
||||||
.emoji {
|
.emoji {
|
||||||
&-search {
|
&-search {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
flex: 0 0 0;
|
flex: 0 0 auto;
|
||||||
|
|
||||||
input {
|
input {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
@ -92,6 +92,17 @@
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="too-many-emoji" v-if="askForSanity">
|
||||||
|
<div class="alert warning hint">
|
||||||
|
{{ $t('emoji.load_all_hint', { saneAmount } ) }}
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
class="btn btn-default"
|
||||||
|
@click="loadEmojiInsane"
|
||||||
|
>
|
||||||
|
{{ $t('emoji.load_all', { emojiAmount: filteredEmoji.length } ) }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="showingStickers"
|
v-if="showingStickers"
|
||||||
|
|
|
@ -73,6 +73,7 @@ export default {
|
||||||
topBarLinkColorLocal: undefined,
|
topBarLinkColorLocal: undefined,
|
||||||
|
|
||||||
alertErrorColorLocal: undefined,
|
alertErrorColorLocal: undefined,
|
||||||
|
alertWarningColorLocal: undefined,
|
||||||
|
|
||||||
badgeOpacityLocal: undefined,
|
badgeOpacityLocal: undefined,
|
||||||
badgeNotificationColorLocal: undefined,
|
badgeNotificationColorLocal: undefined,
|
||||||
|
@ -146,6 +147,7 @@ export default {
|
||||||
btnText: this.btnTextColorLocal,
|
btnText: this.btnTextColorLocal,
|
||||||
|
|
||||||
alertError: this.alertErrorColorLocal,
|
alertError: this.alertErrorColorLocal,
|
||||||
|
alertWarning: this.alertWarningColorLocal,
|
||||||
badgeNotification: this.badgeNotificationColorLocal,
|
badgeNotification: this.badgeNotificationColorLocal,
|
||||||
|
|
||||||
faint: this.faintColorLocal,
|
faint: this.faintColorLocal,
|
||||||
|
@ -229,6 +231,7 @@ export default {
|
||||||
topBar: hex2rgb(colors.topBar),
|
topBar: hex2rgb(colors.topBar),
|
||||||
input: hex2rgb(colors.input),
|
input: hex2rgb(colors.input),
|
||||||
alertError: hex2rgb(colors.alertError),
|
alertError: hex2rgb(colors.alertError),
|
||||||
|
alertWarning: hex2rgb(colors.alertWarning),
|
||||||
badgeNotification: hex2rgb(colors.badgeNotification)
|
badgeNotification: hex2rgb(colors.badgeNotification)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -216,6 +216,13 @@
|
||||||
:fallback="previewTheme.colors.alertError"
|
:fallback="previewTheme.colors.alertError"
|
||||||
/>
|
/>
|
||||||
<ContrastRatio :contrast="previewContrast.alertError" />
|
<ContrastRatio :contrast="previewContrast.alertError" />
|
||||||
|
<ColorInput
|
||||||
|
v-model="alertWarningColorLocal"
|
||||||
|
name="alertWarning"
|
||||||
|
:label="$t('settings.style.advanced_colors.alert_warning')"
|
||||||
|
:fallback="previewTheme.colors.alertWarning"
|
||||||
|
/>
|
||||||
|
<ContrastRatio :contrast="previewContrast.alertWarning" />
|
||||||
</div>
|
</div>
|
||||||
<div class="color-item">
|
<div class="color-item">
|
||||||
<h4>{{ $t('settings.style.advanced_colors.badge') }}</h4>
|
<h4>{{ $t('settings.style.advanced_colors.badge') }}</h4>
|
||||||
|
|
|
@ -114,7 +114,9 @@
|
||||||
"search_emoji": "Search for an emoji",
|
"search_emoji": "Search for an emoji",
|
||||||
"add_emoji": "Insert emoji",
|
"add_emoji": "Insert emoji",
|
||||||
"custom": "Custom 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": {
|
"interactions": {
|
||||||
"favs_repeats": "Repeats and Favorites",
|
"favs_repeats": "Repeats and Favorites",
|
||||||
|
@ -387,6 +389,7 @@
|
||||||
"_tab_label": "Advanced",
|
"_tab_label": "Advanced",
|
||||||
"alert": "Alert background",
|
"alert": "Alert background",
|
||||||
"alert_error": "Error",
|
"alert_error": "Error",
|
||||||
|
"alert_warning": "Warning",
|
||||||
"badge": "Badge background",
|
"badge": "Badge background",
|
||||||
"badge_notification": "Notification",
|
"badge_notification": "Notification",
|
||||||
"panel_header": "Panel header",
|
"panel_header": "Panel header",
|
||||||
|
|
|
@ -215,6 +215,10 @@ const generateColors = (input) => {
|
||||||
colors.alertErrorText = getTextColor(alphaBlend(colors.alertError, opacity.alert, colors.bg), colors.text)
|
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.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.badgeNotification = col.badgeNotification || Object.assign({}, colors.cRed)
|
||||||
colors.badgeNotificationText = contrastRatio(colors.badgeNotification).rgb
|
colors.badgeNotificationText = contrastRatio(colors.badgeNotification).rgb
|
||||||
|
|
||||||
|
@ -222,6 +226,7 @@ const generateColors = (input) => {
|
||||||
if (typeof v === 'undefined') return
|
if (typeof v === 'undefined') return
|
||||||
if (k === 'alert') {
|
if (k === 'alert') {
|
||||||
colors.alertError.a = v
|
colors.alertError.a = v
|
||||||
|
colors.alertWarning.a = v
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (k === 'faint') {
|
if (k === 'faint') {
|
||||||
|
|
Loading…
Reference in a new issue