arbitrary limit with option to overcome it

This commit is contained in:
Henry Jameson 2019-10-07 23:46:40 +03:00
parent 29e6e62e7c
commit 6511a744a2
9 changed files with 113 additions and 35 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -92,6 +92,17 @@
</div>
</label>
</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
v-if="showingStickers"

View file

@ -73,6 +73,7 @@ export default {
topBarLinkColorLocal: undefined,
alertErrorColorLocal: undefined,
alertWarningColorLocal: undefined,
badgeOpacityLocal: undefined,
badgeNotificationColorLocal: undefined,
@ -146,6 +147,7 @@ export default {
btnText: this.btnTextColorLocal,
alertError: this.alertErrorColorLocal,
alertWarning: this.alertWarningColorLocal,
badgeNotification: this.badgeNotificationColorLocal,
faint: this.faintColorLocal,
@ -229,6 +231,7 @@ export default {
topBar: hex2rgb(colors.topBar),
input: hex2rgb(colors.input),
alertError: hex2rgb(colors.alertError),
alertWarning: hex2rgb(colors.alertWarning),
badgeNotification: hex2rgb(colors.badgeNotification)
}

View file

@ -216,6 +216,13 @@
:fallback="previewTheme.colors.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 class="color-item">
<h4>{{ $t('settings.style.advanced_colors.badge') }}</h4>

View file

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

View file

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