From a586b9f6d241c879f7081aa3e0116fd720d6e026 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 12 Sep 2024 12:46:47 +0300 Subject: fix themes3 specificity sorting --- src/services/theme_data/theme_data_3.service.js | 36 ++++++++++++++++++------- 1 file changed, 27 insertions(+), 9 deletions(-) (limited to 'src/services') diff --git a/src/services/theme_data/theme_data_3.service.js b/src/services/theme_data/theme_data_3.service.js index cf58da11..8a0c170b 100644 --- a/src/services/theme_data/theme_data_3.service.js +++ b/src/services/theme_data/theme_data_3.service.js @@ -182,7 +182,7 @@ export const init = ({ const rulesetUnsorted = [ ...Object.values(components) - .map(c => (c.defaultRules || []).map(r => ({ component: c.name, ...r, source: 'Built-in' }))) + .map(c => (c.defaultRules || []).map(r => ({ source: 'Built-in', component: c.name, ...r }))) .reduce((acc, arr) => [...acc, ...arr], []), ...inputRuleset ].map(rule => { @@ -198,18 +198,33 @@ export const init = ({ const ruleset = rulesetUnsorted .map((data, index) => ({ data, index })) - .sort(({ data: a, index: ai }, { data: b, index: bi }) => { + .toSorted(({ data: a, index: ai }, { data: b, index: bi }) => { const parentsA = unroll(a).length const parentsB = unroll(b).length - if (parentsA === parentsB) { - if (a.component === 'Text') return -1 - if (b.component === 'Text') return 1 + let aScore = 0 + let bScore = 0 + + aScore += parentsA * 1000 + bScore += parentsB * 1000 + + aScore += a.variant !== 'normal' ? 100 : 0 + bScore += b.variant !== 'normal' ? 100 : 0 + + aScore += a.state.filter(x => x !== 'normal').length * 1000 + bScore += b.state.filter(x => x !== 'normal').length * 1000 + + aScore += a.component === 'Text' ? 1 : 0 + bScore += b.component === 'Text' ? 1 : 0 + + // Debug + a.specifityScore = aScore + b.specifityScore = bScore + + if (aScore === bScore) { return ai - bi } - if (parentsA === 0 && parentsB !== 0) return -1 - if (parentsB === 0 && parentsA !== 0) return 1 - return parentsA - parentsB + return aScore - bScore }) .map(({ data }) => data) @@ -235,7 +250,10 @@ export const init = ({ // Inheriting all of the applicable rules const existingRules = ruleset.filter(findRules(combination)) - const computedDirectives = existingRules.map(r => r.directives).reduce((acc, directives) => ({ ...acc, ...directives }), {}) + const computedDirectives = + existingRules + .map(r => r.directives) + .reduce((acc, directives) => ({ ...acc, ...directives }), {}) const computedRule = { ...combination, directives: computedDirectives -- cgit v1.2.3-70-g09d2 From aa7a3361833f4c88ec685c4a92ff7727ed7249a7 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 12 Sep 2024 19:31:19 +0300 Subject: Updated shadow control to be able to handle "absolute null" situation --- .../settings_modal/tabs/theme_tab/theme_tab.js | 14 ++- .../settings_modal/tabs/theme_tab/theme_tab.vue | 46 +------- src/components/shadow_control/shadow_control.js | 122 +++++++++++---------- src/components/shadow_control/shadow_control.scss | 17 ++- src/components/shadow_control/shadow_control.vue | 103 +++++++++++++---- src/i18n/en.json | 1 + src/services/theme_data/theme_data.service.js | 2 +- 7 files changed, 179 insertions(+), 126 deletions(-) (limited to 'src/services') diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.js b/src/components/settings_modal/tabs/theme_tab/theme_tab.js index 25836559..a295e880 100644 --- a/src/components/settings_modal/tabs/theme_tab/theme_tab.js +++ b/src/components/settings_modal/tabs/theme_tab/theme_tab.js @@ -314,7 +314,18 @@ export default { }, set (val) { if (val) { - this.shadowsLocal[this.shadowSelected] = this.currentShadowFallback.map(_ => Object.assign({}, _)) + this.shadowsLocal[this.shadowSelected] = (this.currentShadowFallback || []) + .map(s => ({ + name: null, + x: 0, + y: 0, + blur: 0, + spread: 0, + inset: false, + color: '#000000', + alpha: 1, + ...s + })) } else { delete this.shadowsLocal[this.shadowSelected] } @@ -328,6 +339,7 @@ export default { return this.shadowsLocal[this.shadowSelected] }, set (v) { + console.log('TT', v) this.shadowsLocal[this.shadowSelected] = v } }, diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.vue b/src/components/settings_modal/tabs/theme_tab/theme_tab.vue index d975c61d..00a55832 100644 --- a/src/components/settings_modal/tabs/theme_tab/theme_tab.vue +++ b/src/components/settings_modal/tabs/theme_tab/theme_tab.vue @@ -937,24 +937,14 @@
- - {{ ' ' }} - -
@@ -141,11 +145,12 @@
diff --git a/src/i18n/en.json b/src/i18n/en.json index b27c36d7..1b67d4f7 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -880,6 +880,7 @@ "filter_hint": { "always_drop_shadow": "Warning, this shadow always uses {0} when browser supports it.", "drop_shadow_syntax": "{0} does not support {1} parameter and {2} keyword.", + "avatar_inset_short": "Separate inset shadow", "avatar_inset": "Please note that combining both inset and non-inset shadows on avatars might give unexpected results with transparent avatars.", "spread_zero": "Shadows with spread > 0 will appear as if it was set to zero", "inset_classic": "Inset shadows will be using {0}" diff --git a/src/services/theme_data/theme_data.service.js b/src/services/theme_data/theme_data.service.js index 2dddfa04..ef7ec645 100644 --- a/src/services/theme_data/theme_data.service.js +++ b/src/services/theme_data/theme_data.service.js @@ -452,7 +452,7 @@ export const getCssShadow = (input, usesDropShadow) => { ]).join(' ')).join(', ') } -const getCssShadowFilter = (input) => { +export const getCssShadowFilter = (input) => { if (input.length === 0) { return 'none' } -- cgit v1.2.3-70-g09d2 From 00df9c9c32832feea80d6cd6d66c69fabacfab42 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Mon, 16 Sep 2024 02:34:02 +0300 Subject: initial splashscreen implementation --- index.html | 94 +++++++++++++++++++++++++++- src/App.js | 10 +++ src/App.scss | 100 ++++++++++++++++++++++++++++++ src/boot/after_store.js | 6 +- src/i18n/en.json | 11 ++++ src/main.js | 2 + src/modules/interface.js | 12 ++-- src/services/style_setter/style_setter.js | 17 +++-- static/pleromatan_apology_fox.png | 1 + 9 files changed, 237 insertions(+), 16 deletions(-) create mode 120000 static/pleromatan_apology_fox.png (limited to 'src/services') 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 -- cgit v1.2.3-70-g09d2 From 7550b8cbd2152c86fb32258c846c1ad2fe139c89 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Tue, 17 Sep 2024 05:04:52 +0300 Subject: splashscreen is now smaller, big cleanup on aisle themes - removed a lot unnecessary sync/awaits and promises that were sequential anyway --- index.html | 197 +++++++++++++----------- src/App.scss | 79 +++++++++- src/boot/after_store.js | 17 +- src/i18n/en.json | 11 +- src/main.js | 110 +++++++------ src/modules/interface.js | 182 +++++++++++----------- src/services/style_setter/style_setter.js | 10 +- src/services/theme_data/theme_data_3.service.js | 5 + static/pleromatan_orz.png | Bin 0 -> 1113445 bytes static/pleromatan_orz_fox.png | Bin 0 -> 1301128 bytes 10 files changed, 362 insertions(+), 249 deletions(-) create mode 100644 static/pleromatan_orz.png create mode 100644 static/pleromatan_orz_fox.png (limited to 'src/services') diff --git a/index.html b/index.html index 474c0244..6588a287 100644 --- a/index.html +++ b/index.html @@ -4,6 +4,101 @@ + @@ -11,95 +106,23 @@ -
- -
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+ + (。>﹏<)
-
-
-
-
- - (。>﹏<)
diff --git a/src/App.scss b/src/App.scss index 408ba402..5e7d3656 100644 --- a/src/App.scss +++ b/src/App.scss @@ -919,7 +919,6 @@ option { pointer-events: none; transition: opacity 2s; opacity: 1; - z-index: 9999999999999999999999999999; &.hidden { opacity: 0; @@ -938,13 +937,80 @@ option { } } + #mascot-container { + perspective: 60em; + perspective-origin: 0 -15em; + transform-style: preserve-3d; + } + #throbber { - animation-duration: 2s; + animation-duration: 3s; animation-name: bounce; animation-iteration-count: infinite; animation-direction: normal; transform-origin: bottom center; + --defaultY: 0; + + &.dead { + animation-name: dead; + animation-duration: 3s; + // animation-iteration-count: 1; + animation-iteration-count: 1; + transform: rotateX(90deg) rotateY(0) rotateZ(-45deg); + } + + @keyframes dead { + 0% { + transform: rotateX(0) rotateY(0) rotateZ(0); + } + + 5% { + transform: rotateX(0) rotateY(0) rotateZ(1deg); + } + + 10% { + transform: rotateX(0) rotateY(0) rotateZ(-2deg); + } + + 15% { + transform: rotateX(0) rotateY(0) rotateZ(3deg); + } + + 20% { + transform: rotateX(0) rotateY(0) rotateZ(0); + } + + 25% { + transform: rotateX(0) rotateY(0) rotateZ(0); + } + + 30% { + transform: rotateX(10deg) rotateY(0) rotateZ(0); + } + + 35% { + transform: rotateX(-10deg) rotateY(0) rotateZ(0); + } + + 40% { + transform: rotateX(10deg) rotateY(0) rotateZ(0); + } + + 45% { + transform: rotateX(-10deg) rotateY(0) rotateZ(0); + } + + 50% { + transform: rotateX(10deg) rotateY(0) rotateZ(0); + } + + 100% { + transform: rotateX(90deg) rotateY(0) rotateZ(-45deg); + transition-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); /* easeInQuint */ + } + } + @keyframes bounce { 0% { scale: 1 1; @@ -955,24 +1021,28 @@ option { 10% { scale: 1.2 0.8; translate: 0 0; + transform: rotateZ(var(--defaultZ)); animation-timing-function: ease-out; } 30% { scale: 0.9 1.1; translate: 0 -40%; + transform: rotateZ(var(--defaultZ)); animation-timing-function: ease-in; } 40% { scale: 1.1 0.9; translate: 0 -50%; + transform: rotateZ(var(--defaultZ)); animation-timing-function: ease-in; } 45% { scale: 0.9 1.1; translate: 0 -45%; + transform: rotateZ(var(--defaultZ)); animation-timing-function: ease-in; } @@ -985,30 +1055,35 @@ option { 55% { scale: 0.985 1.025; translate: 0 -35%; + transform: rotateZ(var(--defaultZ)); animation-timing-function: ease-in; } 60% { scale: 1.0125 0.9985; translate: 0 -30%; + transform: rotateZ(var(--defaultZ)); animation-timing-function: ease-in; } 80% { scale: 1.0063 0.9938; translate: 0 -10%; + transform: rotateZ(var(--defaultZ)); animation-timing-function: ease-in-ou; } 90% { scale: 1.2 0.8; translate: 0 0; + transform: rotateZ(var(--defaultZ)); animation-timing-function: ease-out; } 100% { scale: 1 1; translate: 0 0; + transform: rotateZ(var(--defaultZ)); animation-timing-function: ease-out; } } diff --git a/src/boot/after_store.js b/src/boot/after_store.js index 6691ff3e..356b09fa 100644 --- a/src/boot/after_store.js +++ b/src/boot/after_store.js @@ -327,11 +327,7 @@ const setConfig = async ({ store }) => { const checkOAuthToken = async ({ store }) => { if (store.getters.getUserToken()) { - try { - await store.dispatch('loginUser', store.getters.getUserToken()) - } catch (e) { - console.error(e) - } + return store.dispatch('loginUser', store.getters.getUserToken()) } return Promise.resolve() } @@ -349,10 +345,15 @@ const afterStoreSetup = async ({ store, i18n }) => { const server = (typeof overrides.target !== 'undefined') ? overrides.target : window.location.origin store.dispatch('setInstanceOption', { name: 'server', value: server }) + document.querySelector('#status').textContent = i18n.global.t('splash.settings') await setConfig({ store }) - await store.dispatch('setTheme') - document.querySelector('#status').textContent = i18n.global.t('splash.theme') + try { + await store.dispatch('setTheme').catch((e) => { console.log(e) }) + } catch (e) { + return Promise.reject(e) + } + applyConfig(store.state.config, i18n.global) // Now we can try getting the server settings and logging in @@ -363,7 +364,7 @@ const afterStoreSetup = async ({ store, i18n }) => { getInstancePanel({ store }), getNodeInfo({ store }), getInstanceConfig({ store }) - ]) + ]).catch(e => Promise.reject(e)) // Start fetching things that don't need to block the UI store.dispatch('fetchMutes') diff --git a/src/i18n/en.json b/src/i18n/en.json index 0d4609b5..8d6a9bfe 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -1406,11 +1406,12 @@ "loading": "Loading...", "theme": "Applying theme, please wait warmly...", "instance": "Getting instance info...", - "splines": "Reticulating splines...", - "almost": "Almost there!", - "fun_1": "Drink more water!", + "settings": "Applying settings...", + "almost": "Reticulating splines...", + "fun_1": "Drink more water", "fun_2": "Take it easy!", - "fun_3": "Suya..", - "fun_4": "#cofe" + "fun_3": "Suya...", + "fun_4": "My Pleroma machine is full power!", + "error": "Something went wrong" } } diff --git a/src/main.js b/src/main.js index 580c5005..40347e6d 100644 --- a/src/main.js +++ b/src/main.js @@ -48,6 +48,16 @@ const i18n = createI18n({ messages.setLanguage(i18n.global, currentLocale) +const splashError = (i18n, e) => { + document.querySelector('#mascot').src = (Math.floor(Math.random() * 2) > 0) + ? '/static/pleromatan_orz_fox.png' + : '/static/pleromatan_orz.png' + document.querySelector('#mascot').classList.add('orz') + document.querySelector('#throbber').classList.add('dead') + document.querySelector('#status').textContent = i18n.global.t('splash.error') + console.error('PleromaFE failed to initialize: ', e) +} + const persistedStateOptions = { paths: [ 'serverSideStorage.cache', @@ -58,57 +68,61 @@ const persistedStateOptions = { }; (async () => { - let storageError = false - const plugins = [pushNotifications] try { - const persistedState = await createPersistedState(persistedStateOptions) - plugins.push(persistedState) - } catch (e) { - console.error(e) - storageError = true - } - document.querySelector('#status').removeAttribute('class') - document.querySelector('#status').textContent = i18n.global.t('splash.loading') - const store = createStore({ - modules: { - i18n: { - getters: { - i18n: () => i18n.global - } + let storageError + const plugins = [pushNotifications] + try { + const persistedState = await createPersistedState(persistedStateOptions) + plugins.push(persistedState) + } catch (e) { + console.error('Storage error', e) + storageError = e + } + document.querySelector('#status').removeAttribute('class') + document.querySelector('#status').textContent = i18n.global.t('splash.loading') + const store = createStore({ + modules: { + i18n: { + getters: { + i18n: () => i18n.global + } + }, + interface: interfaceModule, + instance: instanceModule, + // TODO refactor users/statuses modules, they depend on each other + users: usersModule, + statuses: statusesModule, + notifications: notificationsModule, + lists: listsModule, + api: apiModule, + config: configModule, + profileConfig: profileConfigModule, + serverSideStorage: serverSideStorageModule, + adminSettings: adminSettingsModule, + shout: shoutModule, + oauth: oauthModule, + authFlow: authFlowModule, + mediaViewer: mediaViewerModule, + oauthTokens: oauthTokensModule, + reports: reportsModule, + polls: pollsModule, + postStatus: postStatusModule, + editStatus: editStatusModule, + statusHistory: statusHistoryModule, + chats: chatsModule, + announcements: announcementsModule }, - interface: interfaceModule, - instance: instanceModule, - // TODO refactor users/statuses modules, they depend on each other - users: usersModule, - statuses: statusesModule, - notifications: notificationsModule, - lists: listsModule, - api: apiModule, - config: configModule, - profileConfig: profileConfigModule, - serverSideStorage: serverSideStorageModule, - adminSettings: adminSettingsModule, - shout: shoutModule, - oauth: oauthModule, - authFlow: authFlowModule, - mediaViewer: mediaViewerModule, - oauthTokens: oauthTokensModule, - reports: reportsModule, - polls: pollsModule, - postStatus: postStatusModule, - editStatus: editStatusModule, - statusHistory: statusHistoryModule, - chats: chatsModule, - announcements: announcementsModule - }, - plugins, - strict: false // Socket modifies itself, let's ignore this for now. - // strict: process.env.NODE_ENV !== 'production' - }) - if (storageError) { - store.dispatch('pushGlobalNotice', { messageKey: 'errors.storage_unavailable', level: 'error' }) + plugins, + strict: false // Socket modifies itself, let's ignore this for now. + // strict: process.env.NODE_ENV !== 'production' + }) + if (storageError) { + store.dispatch('pushGlobalNotice', { messageKey: 'errors.storage_unavailable', level: 'error' }) + } + return await afterStoreSetup({ store, i18n }) + } catch (e) { + splashError(i18n, e) } - afterStoreSetup({ store, i18n }) })() // These are inlined by webpack's DefinePlugin diff --git a/src/modules/interface.js b/src/modules/interface.js index 3f180cf5..68b51015 100644 --- a/src/modules/interface.js +++ b/src/modules/interface.js @@ -230,27 +230,27 @@ const interfaceMod = { const forceRecompile = forceThemeRecompilation || recompile - let promise = null + let result = null if (themeData) { - promise = Promise.resolve(normalizeThemeData(themeData)) + result = normalizeThemeData(themeData) } else if (themeName) { - promise = getPreset(themeName).then(themeData => normalizeThemeData(themeData)) + result = normalizeThemeData(getPreset(themeName)) + .then(themeData => normalizeThemeData(themeData)) } else if (userThemeSource || userThemeSnapshot) { - promise = Promise.resolve(normalizeThemeData({ + result = normalizeThemeData({ _pleroma_theme_version: 2, theme: userThemeSnapshot, source: userThemeSource - })) - } else if (actualThemeName && actualThemeName !== 'custom') { - promise = getPreset(actualThemeName).then(themeData => { - const realThemeData = normalizeThemeData(themeData) - if (actualThemeName === instanceThemeName) { - // This sole line is the reason why this whole block is above the recompilation check - commit('setInstanceOption', { name: 'themeData', value: { theme: realThemeData } }) - } - return realThemeData }) + } else if (actualThemeName && actualThemeName !== 'custom') { + const themeData = actualThemeName + const realThemeData = normalizeThemeData(themeData) + if (actualThemeName === instanceThemeName) { + // This sole line is the reason why this whole block is above the recompilation check + commit('setInstanceOption', { name: 'themeData', value: { theme: realThemeData } }) + } + result = realThemeData } else { throw new Error('Cannot load any theme!') } @@ -259,95 +259,91 @@ const interfaceMod = { // cache (tryLoadCache return true if load successful) if (!forceRecompile && !themeDebug && tryLoadCache()) { dispatch('setThemeApplied') - return + return Promise.resolve() } - promise - .then(realThemeData => { - const theme2ruleset = convertTheme2To3(realThemeData) + const realThemeData = result + const theme2ruleset = convertTheme2To3(realThemeData) - if (saveData) { - commit('setOption', { name: 'theme', value: themeName || actualThemeName }) - commit('setOption', { name: 'customTheme', value: realThemeData }) - commit('setOption', { name: 'customThemeSource', value: realThemeData }) - } - const hacks = [] + if (saveData) { + commit('setOption', { name: 'theme', value: themeName || actualThemeName }) + commit('setOption', { name: 'customTheme', value: realThemeData }) + commit('setOption', { name: 'customThemeSource', value: realThemeData }) + } + const hacks = [] - Object.entries(theme3hacks).forEach(([key, value]) => { - switch (key) { - case 'fonts': { - Object.entries(theme3hacks.fonts).forEach(([fontKey, font]) => { - if (!font?.family) return - switch (fontKey) { - case 'interface': - hacks.push({ - component: 'Root', - directives: { - '--font': 'generic | ' + font.family - } - }) - break - case 'input': - hacks.push({ - component: 'Input', - directives: { - '--font': 'generic | ' + font.family - } - }) - break - case 'post': - hacks.push({ - component: 'RichContent', - directives: { - '--font': 'generic | ' + font.family - } - }) - break - case 'monospace': - hacks.push({ - component: 'Root', - directives: { - '--monoFont': 'generic | ' + font.family - } - }) - break - } - }) - break + Object.entries(theme3hacks).forEach(([key, value]) => { + switch (key) { + case 'fonts': { + Object.entries(theme3hacks.fonts).forEach(([fontKey, font]) => { + if (!font?.family) return + switch (fontKey) { + case 'interface': + hacks.push({ + component: 'Root', + directives: { + '--font': 'generic | ' + font.family + } + }) + break + case 'input': + hacks.push({ + component: 'Input', + directives: { + '--font': 'generic | ' + font.family + } + }) + break + case 'post': + hacks.push({ + component: 'RichContent', + directives: { + '--font': 'generic | ' + font.family + } + }) + break + case 'monospace': + hacks.push({ + component: 'Root', + directives: { + '--monoFont': 'generic | ' + font.family + } + }) + break } - case 'underlay': { - if (value !== 'none') { - const newRule = { - component: 'Underlay', - directives: {} - } - if (value === 'opaque') { - newRule.directives.opacity = 1 - newRule.directives.background = '--wallpaper' - } - if (value === 'transparent') { - newRule.directives.opacity = 0 - } - hacks.push(newRule) - } - break + }) + break + } + case 'underlay': { + if (value !== 'none') { + const newRule = { + component: 'Underlay', + directives: {} } + if (value === 'opaque') { + newRule.directives.opacity = 1 + newRule.directives.background = '--wallpaper' + } + if (value === 'transparent') { + newRule.directives.opacity = 0 + } + hacks.push(newRule) } - }) - - const ruleset = [ - ...theme2ruleset, - ...hacks - ] + break + } + } + }) - applyTheme( - ruleset, - () => dispatch('setThemeApplied'), - themeDebug - ) - }) + const ruleset = [ + ...theme2ruleset, + ...hacks + ] - return promise + applyTheme( + ruleset, + () => dispatch('setThemeApplied'), + themeDebug + ) } } } diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js index 2b3f88a8..c1603f39 100644 --- a/src/services/style_setter/style_setter.js +++ b/src/services/style_setter/style_setter.js @@ -43,16 +43,16 @@ const adoptStyleSheets = (styles) => { // is nothing to do here. } -export const generateTheme = async (inputRuleset, callbacks, debug) => { +export const generateTheme = (inputRuleset, callbacks, debug) => { const { onNewRule = (rule, isLazy) => {}, onLazyFinished = () => {}, onEagerFinished = () => {} } = callbacks - // Assuming that "worst case scenario background" is panel background since it's the most likely one const themes3 = init({ inputRuleset, + // Assuming that "worst case scenario background" is panel background since it's the most likely one ultimateBackgroundColor: inputRuleset[0].directives['--bg'].split('|')[1].trim(), debug }) @@ -146,11 +146,11 @@ export const tryLoadCache = () => { } } -export const applyTheme = async (input, onFinish = (data) => {}, debug) => { +export const applyTheme = (input, onFinish = (data) => {}, debug) => { const eagerStyles = createStyleSheet(EAGER_STYLE_ID) const lazyStyles = createStyleSheet(LAZY_STYLE_ID) - const { lazyProcessFunc } = await generateTheme( + const { lazyProcessFunc } = generateTheme( input, { onNewRule (rule, isLazy) { @@ -185,8 +185,6 @@ export const applyTheme = async (input, onFinish = (data) => {}, debug) => { ) setTimeout(lazyProcessFunc, 0) - - return Promise.resolve() } const extractStyleConfig = ({ diff --git a/src/services/theme_data/theme_data_3.service.js b/src/services/theme_data/theme_data_3.service.js index cf58da11..056b78f7 100644 --- a/src/services/theme_data/theme_data_3.service.js +++ b/src/services/theme_data/theme_data_3.service.js @@ -196,6 +196,11 @@ export const init = ({ return rule }) + const i = 4 + if (2 + 2 === i) { + throw new Error('test') + } + const ruleset = rulesetUnsorted .map((data, index) => ({ data, index })) .sort(({ data: a, index: ai }, { data: b, index: bi }) => { diff --git a/static/pleromatan_orz.png b/static/pleromatan_orz.png new file mode 100644 index 00000000..aa54411f Binary files /dev/null and b/static/pleromatan_orz.png differ diff --git a/static/pleromatan_orz_fox.png b/static/pleromatan_orz_fox.png new file mode 100644 index 00000000..936e42f1 Binary files /dev/null and b/static/pleromatan_orz_fox.png differ -- cgit v1.2.3-70-g09d2 From 05577aea546296e675c2722d248bf7f515961c0d Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Tue, 17 Sep 2024 22:56:06 +0300 Subject: replace toSorted with sort, add artist credit --- index.html | 16 ++++++++++++++++ src/main.js | 1 + src/services/theme_data/theme_data_3.service.js | 5 ----- 3 files changed, 17 insertions(+), 5 deletions(-) (limited to 'src/services') diff --git a/index.html b/index.html index 6588a287..702acfe8 100644 --- a/index.html +++ b/index.html @@ -29,6 +29,13 @@ font-size: calc(1vw + 1vh + 1vmin); } + #splash-credit { + position: absolute; + font-size: 14px; + bottom: 0; + right: 0; + } + #splash-container { align-items: center; } @@ -98,6 +105,12 @@ width: 100%; text-align: center; } + + @media (prefers-reduced-motion) { + #throbber { + animation: none; + } + } @@ -107,6 +120,9 @@
+
+ Art by pipivovott +
diff --git a/src/main.js b/src/main.js index 40347e6d..4ccdabb9 100644 --- a/src/main.js +++ b/src/main.js @@ -80,6 +80,7 @@ const persistedStateOptions = { } document.querySelector('#status').removeAttribute('class') document.querySelector('#status').textContent = i18n.global.t('splash.loading') + document.querySelector('#splash-credit').textContent = i18n.global.t('update.art_by', { linkToArtist: 'pipivovott' }) const store = createStore({ modules: { i18n: { diff --git a/src/services/theme_data/theme_data_3.service.js b/src/services/theme_data/theme_data_3.service.js index 056b78f7..cf58da11 100644 --- a/src/services/theme_data/theme_data_3.service.js +++ b/src/services/theme_data/theme_data_3.service.js @@ -196,11 +196,6 @@ export const init = ({ return rule }) - const i = 4 - if (2 + 2 === i) { - throw new Error('test') - } - const ruleset = rulesetUnsorted .map((data, index) => ({ data, index })) .sort(({ data: a, index: ai }, { data: b, index: bi }) => { -- cgit v1.2.3-70-g09d2