Merge branch 'splashscreen' into shigusegubu-themes3

This commit is contained in:
Henry Jameson 2024-09-16 02:34:25 +03:00
commit e583549718
16 changed files with 293 additions and 63 deletions

View file

@ -0,0 +1 @@
Updated shadow editor, hopefully fixed long-standing bugs, added ability to specify shadow's name.

View file

@ -8,9 +8,99 @@
<style id="pleroma-lazy-styles" type="text/css"></style> <style id="pleroma-lazy-styles" type="text/css"></style>
<!--server-generated-meta--> <!--server-generated-meta-->
</head> </head>
<body class="hidden"> <body style="margin: 0; padding: 0">
<noscript>To use Pleroma, please enable JavaScript.</noscript> <noscript>To use Pleroma, please enable JavaScript.</noscript>
<div id="app"></div> <!-- putting styles here to avoid having to wait for styles to load up -->
<div id="splash" style="
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
background: #0f161e;
font-family: sans-serif;
color: #b9b9ba;
position: absolute;
"
>
<img
style="
width: 30vh";
margin-top: 1vh;
margin-bottom: 0.5vh;
"
src="/static/pleromatan_apology_fox.png"
/>
<div
id="throbber"
style='
--logoChunkSize: 2vh;
display: grid;
margin-top: 2.5vh;
margin-bottom: 0.5vh;
width: 30vw;
grid-template-rows: repeat(8, var(--logoChunkSize));
grid-template-columns: repeat(5, var(--logoChunkSize));
grid-template-areas: "P P . L L"
"P P . L L"
"P P . L L"
"P P . L L"
"P P . . ."
"P P . . ."
"P P . E E"
"P P . E E";
width: auto;
'
>
<div
style="
background-color: #e2b188;
grid-area: P;
border-top-left-radius: calc(var(--logoChunkSize) / 2);
box-shadow: 0.1vh 0.1vh 1vh 0 #e2b188;
"
>
</div>
<div
style="
width: 100%;
height: 100%;
background-color: #e2b188;
grid-area: L;
border-bottom-right-radius: calc(var(--logoChunkSize) / 2);
box-shadow: 0.1vh 0.1vh 1vh 0 #e2b188;
"
>
</div>
<div
style="
width: 100%;
height: 100%;
background-color: #e2b188;
grid-area: E;
border-bottom-right-radius: calc(var(--logoChunkSize) / 2);
box-shadow: 0.1vh 0.1vh 1vh 0 #e2b188;
"
>
</div>
</div>
<div
id="status"
class="css-ok"
style="
margin-top: 3.5vh;
height: 4vh;
line-height: 4vh;
font-size: 4vh;
width: 100%;
text-align: center;
"
>
<span class="initial-text">(。><)</span>
</div>
</div>
<div id="app" class="hidden"></div>
<div id="modal"></div> <div id="modal"></div>
<!-- built files will be auto injected --> <!-- built files will be auto injected -->
<div id="popovers" /> <div id="popovers" />

View file

@ -44,6 +44,13 @@ export default {
data: () => ({ data: () => ({
mobileActivePanel: 'timeline' mobileActivePanel: 'timeline'
}), }),
watch: {
themeApplied (value) {
document.querySelector('#app').classList.remove('hidden')
document.querySelector('#splash').className = 'hidden'
document.querySelector('#status').textContent = this.$t('splash.fun_' + Math.ceil(Math.random() * 4))
}
},
created () { created () {
// Load the locale from the storage // Load the locale from the storage
const val = this.$store.getters.mergedConfig.interfaceLanguage const val = this.$store.getters.mergedConfig.interfaceLanguage
@ -54,6 +61,9 @@ export default {
window.removeEventListener('resize', this.updateMobileState) window.removeEventListener('resize', this.updateMobileState)
}, },
computed: { computed: {
themeApplied () {
return this.$store.state.interface.themeApplied
},
classes () { classes () {
return [ return [
{ {

View file

@ -914,3 +914,103 @@ option {
color: var(--selectionText); color: var(--selectionText);
background-color: var(--selectionBackground); background-color: var(--selectionBackground);
} }
#splash {
pointer-events: none;
transition: opacity 2s;
opacity: 1;
z-index: 9999999999999999999999999999;
&.hidden {
opacity: 0;
}
#status {
&.css-ok {
&::before {
display: inline-block;
content: "CSS OK";
}
}
.initial-text {
display: none;
}
}
#throbber {
animation-duration: 2s;
animation-name: bounce;
animation-iteration-count: infinite;
animation-direction: normal;
transform-origin: bottom center;
@keyframes bounce {
0% {
scale: 1 1;
translate: 0 0;
animation-timing-function: ease-out;
}
10% {
scale: 1.2 0.8;
translate: 0 0;
animation-timing-function: ease-out;
}
30% {
scale: 0.9 1.1;
translate: 0 -40%;
animation-timing-function: ease-in;
}
40% {
scale: 1.1 0.9;
translate: 0 -50%;
animation-timing-function: ease-in;
}
45% {
scale: 0.9 1.1;
translate: 0 -45%;
animation-timing-function: ease-in;
}
50% {
scale: 1.05 0.95;
translate: 0 -40%;
animation-timing-function: ease-in;
}
55% {
scale: 0.985 1.025;
translate: 0 -35%;
animation-timing-function: ease-in;
}
60% {
scale: 1.0125 0.9985;
translate: 0 -30%;
animation-timing-function: ease-in;
}
80% {
scale: 1.0063 0.9938;
translate: 0 -10%;
animation-timing-function: ease-in-ou;
}
90% {
scale: 1.2 0.8;
translate: 0 0;
animation-timing-function: ease-out;
}
100% {
scale: 1 1;
translate: 0 0;
animation-timing-function: ease-out;
}
}
}
}

View file

@ -352,10 +352,12 @@ const afterStoreSetup = async ({ store, i18n }) => {
await setConfig({ store }) await setConfig({ store })
await store.dispatch('setTheme') await store.dispatch('setTheme')
applyConfig(store.state.config) document.querySelector('#status').textContent = i18n.global.t('splash.theme')
applyConfig(store.state.config, i18n.global)
// Now we can try getting the server settings and logging in // Now we can try getting the server settings and logging in
// Most of these are preloaded into the index.html so blocking is minimized // Most of these are preloaded into the index.html so blocking is minimized
document.querySelector('#status').textContent = i18n.global.t('splash.instance')
await Promise.all([ await Promise.all([
checkOAuthToken({ store }), checkOAuthToken({ store }),
getInstancePanel({ store }), getInstancePanel({ store }),
@ -395,9 +397,9 @@ const afterStoreSetup = async ({ store, i18n }) => {
// remove after vue 3.3 // remove after vue 3.3
app.config.unwrapInjectedRef = true app.config.unwrapInjectedRef = true
document.querySelector('#status').textContent = i18n.global.t('splash.almost')
app.mount('#app') app.mount('#app')
return app return app
} }

View file

@ -15,7 +15,7 @@
:model-value="present" :model-value="present"
:disabled="disabled" :disabled="disabled"
class="opt" class="opt"
@update:modelValue="$emit('update:modelValue', typeof modelValue === 'undefined' ? fallback : undefined)" @update:modelValue="update(typeof modelValue === 'undefined' ? fallback : undefined)"
/> />
<div <div
class="input color-input-field" class="input color-input-field"
@ -28,7 +28,7 @@
type="text" type="text"
:value="modelValue || fallback" :value="modelValue || fallback"
:disabled="!present || disabled" :disabled="!present || disabled"
@input="$emit('update:modelValue', $event.target.value)" @input="updateValue($event.target.value)"
> >
<div <div
v-if="validColor" v-if="validColor"
@ -57,7 +57,7 @@
:value="modelValue || fallback" :value="modelValue || fallback"
:disabled="!present || disabled" :disabled="!present || disabled"
:class="{ disabled: !present || disabled }" :class="{ disabled: !present || disabled }"
@input="$emit('update:modelValue', $event.target.value)" @input="updateValue($event.target.value)"
> >
</label> </label>
</div> </div>
@ -66,6 +66,7 @@
<script> <script>
import Checkbox from '../checkbox/checkbox.vue' import Checkbox from '../checkbox/checkbox.vue'
import { hex2rgb } from '../../services/color_convert/color_convert.js' import { hex2rgb } from '../../services/color_convert/color_convert.js'
import { throttle } from 'lodash'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { import {
@ -131,6 +132,11 @@ export default {
computedColor () { computedColor () {
return this.modelValue && this.modelValue.startsWith('--') return this.modelValue && this.modelValue.startsWith('--')
} }
},
methods: {
updateValue: throttle(function (value) {
this.$emit('update:modelValue', value)
}, 100)
} }
} }
</script> </script>

View file

@ -27,11 +27,6 @@
label.Select { label.Select {
padding: 0; padding: 0;
&.disabled,
&:disabled {
background-color: var(--background);
}
select { select {
appearance: none; appearance: none;
background: transparent; background: transparent;
@ -52,7 +47,7 @@ label.Select {
padding: 0.2em; padding: 0.2em;
option { option {
background: transparent; background-color: transparent;
&.-active { &.-active {
color: var(--selectionText); color: var(--selectionText);
@ -62,6 +57,22 @@ label.Select {
} }
} }
&.disabled,
&:disabled {
background-color: var(--background);
opacity: 1; /* override browser */
select {
&[multiple],
&[size] {
option.-active {
color: var(--text);
background: transparent;
}
}
}
}
.select-down-icon { .select-down-icon {
position: absolute; position: absolute;
top: 0; top: 0;

View file

@ -339,7 +339,6 @@ export default {
return this.shadowsLocal[this.shadowSelected] return this.shadowsLocal[this.shadowSelected]
}, },
set (v) { set (v) {
console.log('TT', v)
this.shadowsLocal[this.shadowSelected] = v this.shadowsLocal[this.shadowSelected] = v
} }
}, },

View file

@ -4,8 +4,8 @@ import Select from 'src/components/select/select.vue'
import Checkbox from 'src/components/checkbox/checkbox.vue' import Checkbox from 'src/components/checkbox/checkbox.vue'
import Popover from 'src/components/popover/popover.vue' import Popover from 'src/components/popover/popover.vue'
import { getCssShadow, getCssShadowFilter } from '../../services/theme_data/theme_data.service.js' import { getCssShadow, getCssShadowFilter } from '../../services/theme_data/theme_data.service.js'
import { hex2rgb } from '../../services/color_convert/color_convert.js'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { throttle } from 'lodash'
import { import {
faTimes, faTimes,
faChevronDown, faChevronDown,
@ -41,7 +41,7 @@ export default {
lightGrid: false, lightGrid: false,
selectedId: 0, selectedId: 0,
// TODO there are some bugs regarding display of array (it's not getting updated when deleting for some reason) // TODO there are some bugs regarding display of array (it's not getting updated when deleting for some reason)
cValue: (this.modelValue || this.fallback || []).map(toModel) cValue: (this.modelValue ?? this.fallback ?? []).map(toModel)
} }
}, },
components: { components: {
@ -52,7 +52,7 @@ export default {
Popover Popover
}, },
beforeUpdate () { beforeUpdate () {
this.cValue = (this.modelValue || this.fallback || []).map(toModel) this.cValue = (this.modelValue ?? this.fallback ?? []).map(toModel)
}, },
computed: { computed: {
selected () { selected () {
@ -68,12 +68,6 @@ export default {
shadowsAreNull () { shadowsAreNull () {
return this.modelValue == null return this.modelValue == null
}, },
anyShadows () {
return this.cValue.length > 0
},
anyShadowsFallback () {
return this.fallback.length > 0
},
currentFallback () { currentFallback () {
return this.fallback?.[this.selectedId] return this.fallback?.[this.selectedId]
}, },
@ -86,27 +80,28 @@ export default {
usingFallback () { usingFallback () {
return this.modelValue == null return this.modelValue == null
}, },
rgb () {
return hex2rgb(this.selected.color)
},
style () { style () {
if (!this.ready) return {} console.log(this.separateInset)
if (this.separateInset) { if (this.separateInset) {
return { return {
filter: getCssShadowFilter(this.fallback), filter: getCssShadowFilter(this.cValue),
boxShadow: getCssShadow(this.fallback, true) boxShadow: getCssShadow(this.cValue, true)
} }
} }
return { return {
boxShadow: getCssShadow(this.fallback) boxShadow: getCssShadow(this.cValue)
} }
} }
}, },
methods: { methods: {
updateProperty (prop, value) { updateProperty: throttle(function (prop, value) {
console.log(prop, value)
this.cValue[this.selectedId][prop] = value this.cValue[this.selectedId][prop] = value
if (prop === 'inset' && value === false && this.separateInset) {
this.cValue[this.selectedId].spread = 0
}
this.$emit('update:modelValue', this.cValue) this.$emit('update:modelValue', this.cValue)
}, }, 100),
add () { add () {
this.cValue.push(toModel(this.selected)) this.cValue.push(toModel(this.selected))
this.selectedId = Math.max(this.cValue.length - 1, 0) this.selectedId = Math.max(this.cValue.length - 1, 0)

View file

@ -22,7 +22,6 @@
display: grid; display: grid;
grid-auto-columns: 1fr; grid-auto-columns: 1fr;
grid-auto-flow: column; grid-auto-flow: column;
grid-gap: 0.125em;
margin-top: 0.25em; margin-top: 0.25em;
.button-default { .button-default {

View file

@ -56,7 +56,7 @@
@input="e => updateProperty('x', e.target.value)" @input="e => updateProperty('x', e.target.value)"
> >
<Checkbox <Checkbox
id="inset" id="lightGrid"
v-model="lightGrid" v-model="lightGrid"
:disabled="!present" :disabled="!present"
name="lightGrid" name="lightGrid"
@ -83,7 +83,7 @@
</option> </option>
</Select> </Select>
<div <div
class="id-control arrange-buttons" class="id-control btn-group arrange-buttons"
> >
<button <button
class="btn button-default" class="btn button-default"
@ -132,12 +132,11 @@
</div> </div>
<div class="shadow-tweak"> <div class="shadow-tweak">
<div <div
:disabled="!present"
:class="{ disabled: !present }" :class="{ disabled: !present }"
class="name-control style-control" class="name-control style-control"
> >
<label <label
for="spread" for="name"
class="label" class="label"
:class="{ faint: !present }" :class="{ faint: !present }"
> >
@ -163,7 +162,7 @@
:disabled="!present" :disabled="!present"
name="inset" name="inset"
class="input-inset input-boolean" class="input-inset input-boolean"
@input="e => updateProperty('inset', e.target.value)" @input="e => updateProperty('inset', e.target.checked)"
> >
<template #before> <template #before>
{{ $t('settings.style.shadows.inset') }} {{ $t('settings.style.shadows.inset') }}
@ -176,7 +175,7 @@
class="blur-control style-control" class="blur-control style-control"
> >
<label <label
for="spread" for="blur"
class="label" class="label"
:class="{ faint: !present }" :class="{ faint: !present }"
> >
@ -205,22 +204,21 @@
> >
</div> </div>
<div <div
:disabled="!present"
class="spread-control style-control" class="spread-control style-control"
:class="{ disabled: !present }" :class="{ disabled: !present || (separateInset && !selected?.inset) }"
> >
<label <label
for="spread" for="spread"
class="label" class="label"
:class="{ faint: !present }" :class="{ faint: !present || (separateInset && !selected?.inset) }"
> >
{{ $t('settings.style.shadows.spread') }} {{ $t('settings.style.shadows.spread') }}
</label> </label>
<input <input
id="spread" id="spread"
:value="selected?.spread" :value="selected?.spread"
:disabled="!present" :disabled="!present || (separateInset && !selected?.inset)"
:class="{ disabled: !present }" :class="{ disabled: !present || (separateInset && !selected?.inset) }"
name="spread" name="spread"
class="input input-range" class="input input-range"
type="range" type="range"
@ -230,26 +228,26 @@
> >
<input <input
:value="selected?.spread" :value="selected?.spread"
:disabled="!present" :disabled="{ disabled: !present || (separateInset && !selected?.inset) }"
:class="{ disabled: !present }" :class="{ disabled: !present || (separateInset && !selected?.inset) }"
class="input input-number" class="input input-number"
type="number" type="number"
@input="e => updateProperty('spread', e.target.value)" @input="e => updateProperty('spread', e.target.value)"
> >
</div> </div>
<ColorInput <ColorInput
:modelValue="selected?.color" :model-value="selected?.color"
:disabled="!present" :disabled="!present"
:label="$t('settings.style.common.color')" :label="$t('settings.style.common.color')"
:fallback="currentFallback?.color" :fallback="currentFallback?.color"
:show-optional-tickbox="false" :show-optional-tickbox="false"
name="shadow" name="shadow"
@update:modelValue="e => updateProperty('color', e.target.value)" @update:modelValue="e => updateProperty('color', e)"
/> />
<OpacityInput <OpacityInput
:modelValue="selected?.alpha" :model-value="selected?.alpha"
:disabled="!present" :disabled="!present"
@update:modelValue="e => updateProperty('alpha', e.target.value)" @update:modelValue="e => updateProperty('alpha', e)"
/> />
<i18n-t <i18n-t
scope="global" scope="global"
@ -260,8 +258,8 @@
<code>--variable,mod</code> <code>--variable,mod</code>
</i18n-t> </i18n-t>
<Popover <Popover
trigger="hover"
v-if="separateInset" v-if="separateInset"
trigger="hover"
> >
<template #trigger> <template #trigger>
<div <div

View file

@ -1405,5 +1405,16 @@
}, },
"unicode_domain_indicator": { "unicode_domain_indicator": {
"tooltip": "This domain contains non-ascii characters." "tooltip": "This domain contains non-ascii characters."
},
"splash": {
"loading": "Loading...",
"theme": "Applying theme, please wait warmly...",
"instance": "Getting instance info...",
"splines": "Reticulating splines...",
"almost": "Almost there!",
"fun_1": "Drink more water!",
"fun_2": "Take it easy!",
"fun_3": "Suya..",
"fun_4": "#cofe",
} }
} }

View file

@ -67,6 +67,8 @@ const persistedStateOptions = {
console.error(e) console.error(e)
storageError = true storageError = true
} }
document.querySelector('#status').removeAttribute('class')
document.querySelector('#status').textContent = i18n.global.t('splash.loading')
const store = createStore({ const store = createStore({
modules: { modules: {
i18n: { i18n: {

View file

@ -56,9 +56,6 @@ const interfaceMod = {
state.temporaryChangesConfirm = () => {} state.temporaryChangesConfirm = () => {}
state.temporaryChangesRevert = () => {} state.temporaryChangesRevert = () => {}
}, },
setThemeApplied (state) {
state.themeApplied = true
},
setNotificationPermission (state, permission) { setNotificationPermission (state, permission) {
state.notificationPermission = permission state.notificationPermission = permission
}, },
@ -120,6 +117,9 @@ const interfaceMod = {
setPageTitle ({ rootState }, option = '') { setPageTitle ({ rootState }, option = '') {
document.title = `${option} ${rootState.instance.name}` document.title = `${option} ${rootState.instance.name}`
}, },
setThemeApplied ({ state, rootGetters }) {
state.themeApplied = true
},
settingsSaved ({ commit, dispatch }, { success, error }) { settingsSaved ({ commit, dispatch }, { success, error }) {
commit('settingsSaved', { success, error }) commit('settingsSaved', { success, error })
}, },
@ -212,7 +212,7 @@ const interfaceMod = {
setLastTimeline ({ commit }, value) { setLastTimeline ({ commit }, value) {
commit('setLastTimeline', value) commit('setLastTimeline', value)
}, },
setTheme ({ commit, rootState }, { themeName, themeData, recompile, saveData } = {}) { setTheme ({ dispatch, commit, rootState }, { themeName, themeData, recompile, saveData } = {}) {
const { const {
theme: instanceThemeName theme: instanceThemeName
} = rootState.instance } = rootState.instance
@ -258,7 +258,7 @@ const interfaceMod = {
// If we're not not forced to recompile try using // If we're not not forced to recompile try using
// cache (tryLoadCache return true if load successful) // cache (tryLoadCache return true if load successful)
if (!forceRecompile && !themeDebug && tryLoadCache()) { if (!forceRecompile && !themeDebug && tryLoadCache()) {
commit('setThemeApplied') dispatch('setThemeApplied')
return return
} }
@ -342,7 +342,7 @@ const interfaceMod = {
applyTheme( applyTheme(
ruleset, ruleset,
() => commit('setThemeApplied'), () => dispatch('setThemeApplied'),
themeDebug themeDebug
) )
}) })

View file

@ -169,7 +169,16 @@ export const applyTheme = async (input, onFinish = (data) => {}, debug) => {
adoptStyleSheets([eagerStyles, lazyStyles]) adoptStyleSheets([eagerStyles, lazyStyles])
const cache = { engineChecksum: getEngineChecksum(), data: [eagerStyles.rules, lazyStyles.rules] } const cache = { engineChecksum: getEngineChecksum(), data: [eagerStyles.rules, lazyStyles.rules] }
onFinish(cache) onFinish(cache)
try {
localStorage.setItem('pleroma-fe-theme-cache', JSON.stringify(cache)) localStorage.setItem('pleroma-fe-theme-cache', JSON.stringify(cache))
} catch (e) {
localStorage.removeItem('pleroma-fe-theme-cache')
try {
localStorage.setItem('pleroma-fe-theme-cache', JSON.stringify(cache))
} catch (e) {
console.warn('cannot save cache!', e)
}
}
} }
}, },
debug debug
@ -222,7 +231,7 @@ const extractStyleConfig = ({
const defaultStyleConfig = extractStyleConfig(defaultState) const defaultStyleConfig = extractStyleConfig(defaultState)
export const applyConfig = (input) => { export const applyConfig = (input, i18n) => {
const config = extractStyleConfig(input) const config = extractStyleConfig(input)
if (config === defaultStyleConfig) { if (config === defaultStyleConfig) {
@ -230,8 +239,6 @@ export const applyConfig = (input) => {
} }
const head = document.head const head = document.head
const body = document.body
body.classList.add('hidden')
const rules = Object const rules = Object
.entries(config) .entries(config)
@ -252,8 +259,6 @@ export const applyConfig = (input) => {
--roundness: var(--forcedRoundness) !important; --roundness: var(--forcedRoundness) !important;
}`, 'index-max') }`, 'index-max')
} }
body.classList.remove('hidden')
} }
export const getThemes = () => { export const getThemes = () => {

View file

@ -0,0 +1 @@
/home/bocchi/Repos/Mine/pleroma-fe/src/assets/pleromatan_apology_fox.png