initial splashscreen implementation
This commit is contained in:
parent
8ee5122909
commit
00df9c9c32
94
index.html
94
index.html
|
@ -8,9 +8,99 @@
|
|||
<style id="pleroma-lazy-styles" type="text/css"></style>
|
||||
<!--server-generated-meta-->
|
||||
</head>
|
||||
<body class="hidden">
|
||||
<body style="margin: 0; padding: 0">
|
||||
<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>
|
||||
<!-- built files will be auto injected -->
|
||||
<div id="popovers" />
|
||||
|
|
10
src/App.js
10
src/App.js
|
@ -44,6 +44,13 @@ export default {
|
|||
data: () => ({
|
||||
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 () {
|
||||
// Load the locale from the storage
|
||||
const val = this.$store.getters.mergedConfig.interfaceLanguage
|
||||
|
@ -54,6 +61,9 @@ export default {
|
|||
window.removeEventListener('resize', this.updateMobileState)
|
||||
},
|
||||
computed: {
|
||||
themeApplied () {
|
||||
return this.$store.state.interface.themeApplied
|
||||
},
|
||||
classes () {
|
||||
return [
|
||||
{
|
||||
|
|
100
src/App.scss
100
src/App.scss
|
@ -914,3 +914,103 @@ option {
|
|||
color: var(--selectionText);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -352,10 +352,12 @@ const afterStoreSetup = async ({ store, i18n }) => {
|
|||
await setConfig({ store })
|
||||
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
|
||||
// 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([
|
||||
checkOAuthToken({ store }),
|
||||
getInstancePanel({ store }),
|
||||
|
@ -395,9 +397,9 @@ const afterStoreSetup = async ({ store, i18n }) => {
|
|||
|
||||
// remove after vue 3.3
|
||||
app.config.unwrapInjectedRef = true
|
||||
document.querySelector('#status').textContent = i18n.global.t('splash.almost')
|
||||
|
||||
app.mount('#app')
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
|
|
|
@ -1401,5 +1401,16 @@
|
|||
},
|
||||
"unicode_domain_indicator": {
|
||||
"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",
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,6 +67,8 @@ const persistedStateOptions = {
|
|||
console.error(e)
|
||||
storageError = true
|
||||
}
|
||||
document.querySelector('#status').removeAttribute('class')
|
||||
document.querySelector('#status').textContent = i18n.global.t('splash.loading')
|
||||
const store = createStore({
|
||||
modules: {
|
||||
i18n: {
|
||||
|
|
|
@ -56,9 +56,6 @@ const interfaceMod = {
|
|||
state.temporaryChangesConfirm = () => {}
|
||||
state.temporaryChangesRevert = () => {}
|
||||
},
|
||||
setThemeApplied (state) {
|
||||
state.themeApplied = true
|
||||
},
|
||||
setNotificationPermission (state, permission) {
|
||||
state.notificationPermission = permission
|
||||
},
|
||||
|
@ -120,6 +117,9 @@ const interfaceMod = {
|
|||
setPageTitle ({ rootState }, option = '') {
|
||||
document.title = `${option} ${rootState.instance.name}`
|
||||
},
|
||||
setThemeApplied ({ state, rootGetters }) {
|
||||
state.themeApplied = true
|
||||
},
|
||||
settingsSaved ({ commit, dispatch }, { success, error }) {
|
||||
commit('settingsSaved', { success, error })
|
||||
},
|
||||
|
@ -212,7 +212,7 @@ const interfaceMod = {
|
|||
setLastTimeline ({ commit }, value) {
|
||||
commit('setLastTimeline', value)
|
||||
},
|
||||
setTheme ({ commit, rootState }, { themeName, themeData, recompile, saveData } = {}) {
|
||||
setTheme ({ dispatch, commit, rootState }, { themeName, themeData, recompile, saveData } = {}) {
|
||||
const {
|
||||
theme: instanceThemeName
|
||||
} = rootState.instance
|
||||
|
@ -258,7 +258,7 @@ const interfaceMod = {
|
|||
// If we're not not forced to recompile try using
|
||||
// cache (tryLoadCache return true if load successful)
|
||||
if (!forceRecompile && !themeDebug && tryLoadCache()) {
|
||||
commit('setThemeApplied')
|
||||
dispatch('setThemeApplied')
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -342,7 +342,7 @@ const interfaceMod = {
|
|||
|
||||
applyTheme(
|
||||
ruleset,
|
||||
() => commit('setThemeApplied'),
|
||||
() => dispatch('setThemeApplied'),
|
||||
themeDebug
|
||||
)
|
||||
})
|
||||
|
|
|
@ -169,7 +169,16 @@ export const applyTheme = async (input, onFinish = (data) => {}, debug) => {
|
|||
adoptStyleSheets([eagerStyles, lazyStyles])
|
||||
const cache = { engineChecksum: getEngineChecksum(), data: [eagerStyles.rules, lazyStyles.rules] }
|
||||
onFinish(cache)
|
||||
localStorage.setItem('pleroma-fe-theme-cache', JSON.stringify(cache))
|
||||
try {
|
||||
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
|
||||
|
@ -222,7 +231,7 @@ const extractStyleConfig = ({
|
|||
|
||||
const defaultStyleConfig = extractStyleConfig(defaultState)
|
||||
|
||||
export const applyConfig = (input) => {
|
||||
export const applyConfig = (input, i18n) => {
|
||||
const config = extractStyleConfig(input)
|
||||
|
||||
if (config === defaultStyleConfig) {
|
||||
|
@ -230,8 +239,6 @@ export const applyConfig = (input) => {
|
|||
}
|
||||
|
||||
const head = document.head
|
||||
const body = document.body
|
||||
body.classList.add('hidden')
|
||||
|
||||
const rules = Object
|
||||
.entries(config)
|
||||
|
@ -252,8 +259,6 @@ export const applyConfig = (input) => {
|
|||
--roundness: var(--forcedRoundness) !important;
|
||||
}`, 'index-max')
|
||||
}
|
||||
|
||||
body.classList.remove('hidden')
|
||||
}
|
||||
|
||||
export const getThemes = () => {
|
||||
|
|
1
static/pleromatan_apology_fox.png
Symbolic link
1
static/pleromatan_apology_fox.png
Symbolic link
|
@ -0,0 +1 @@
|
|||
/home/bocchi/Repos/Mine/pleroma-fe/src/assets/pleromatan_apology_fox.png
|
Loading…
Reference in a new issue