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); 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 {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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