diff --git a/index.html b/index.html
index 6d9c4ce5..85371c8b 100644
--- a/index.html
+++ b/index.html
@@ -8,9 +8,99 @@
-
+
-
+
+
+
+
+
+ (。>﹏<)
+
+
+
diff --git a/src/App.js b/src/App.js
index b7eb2f72..6f140612 100644
--- a/src/App.js
+++ b/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 [
{
diff --git a/src/App.scss b/src/App.scss
index 9d1ce77a..408ba402 100644
--- a/src/App.scss
+++ b/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;
+ }
+ }
+ }
+}
diff --git a/src/boot/after_store.js b/src/boot/after_store.js
index 6cad05f6..6691ff3e 100644
--- a/src/boot/after_store.js
+++ b/src/boot/after_store.js
@@ -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
}
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 3f7ea282..d30b07ef 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -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",
}
}
diff --git a/src/main.js b/src/main.js
index 85eb1f4c..580c5005 100644
--- a/src/main.js
+++ b/src/main.js
@@ -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: {
diff --git a/src/modules/interface.js b/src/modules/interface.js
index 57bfe0c6..3f180cf5 100644
--- a/src/modules/interface.js
+++ b/src/modules/interface.js
@@ -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
)
})
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index e54a95bf..2b3f88a8 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -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 = () => {
diff --git a/static/pleromatan_apology_fox.png b/static/pleromatan_apology_fox.png
new file mode 120000
index 00000000..99f0ab91
--- /dev/null
+++ b/static/pleromatan_apology_fox.png
@@ -0,0 +1 @@
+/home/bocchi/Repos/Mine/pleroma-fe/src/assets/pleromatan_apology_fox.png
\ No newline at end of file