Compare commits

...

9 commits

Author SHA1 Message Date
Henry Jameson
53d1931acb Merge branch 'splashscreen' into shigusegubu-themes3 2024-09-18 17:37:16 +03:00
Henry Jameson
711eb24504 cleanup 2024-09-18 17:36:50 +03:00
Henry Jameson
82936aed38 cleanup, styles, fox random, and better "animation" for orz 2024-09-18 03:37:59 +03:00
Henry Jameson
414947d755 margin for credit 2024-09-18 02:54:38 +03:00
Henry Jameson
189bb02436 a11y 2024-09-18 02:54:25 +03:00
Henry Jameson
ce7ac02871 better error log 2024-09-18 02:50:51 +03:00
Henry Jameson
d2f85f4f25 revert interface.js since it's an action it will be always asynchronous 2024-09-18 02:49:27 +03:00
Henry Jameson
6c6d356f70 fix obvious mistakes 2024-09-18 02:41:55 +03:00
HJ
7c8308a410 Apply 1 suggestion(s) to 1 file(s) 2024-09-17 23:19:35 +00:00
7 changed files with 132 additions and 140 deletions

View file

@ -4,11 +4,8 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1,user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1,user-scalable=no">
<link rel="icon" type="image/png" href="/favicon.png"> <link rel="icon" type="image/png" href="/favicon.png">
<!-- putting styles here to avoid having to wait for styles to load up -->
<style id="splashscreen"> <style id="splashscreen">
#webpack-hot-middleware-clientOverlay {
z-index: 9999999999999999999999999999;
}
#splash { #splash {
--scale: 1; --scale: 1;
width: 100vw; width: 100vw;
@ -32,8 +29,8 @@
#splash-credit { #splash-credit {
position: absolute; position: absolute;
font-size: 14px; font-size: 14px;
bottom: 0; bottom: 16px;
right: 0; right: 16px;
} }
#splash-container { #splash-container {
@ -44,30 +41,25 @@
display: flex; display: flex;
align-items: flex-end; align-items: flex-end;
justify-content: center; justify-content: center;
perspective: 60em;
perspective-origin: 0 -15em;
transform-style: preserve-3d;
} }
#mascot:not(.orz) { #mascot {
margin-bottom: 2em
object-position: 2.5em 0;
}
#mascot-temp.orz {
margin-bottom: 2em
object-position: 2.5em 0;
}
#mascot,
#mascot-temp {
width: calc(10em * var(--scale)); width: calc(10em * var(--scale));
height: calc(8em * var(--scale)); height: calc(10em * var(--scale));
object-fit: contain; object-fit: contain;
object-position: bottom; object-position: bottom;
transform: translateZ(-2em);
} }
#throbber { #throbber {
display: grid; display: grid;
width: calc(5em * 0.5 * var(--scale)); width: calc(5em * 0.5 * var(--scale));
height: calc(8em * 0.5 * var(--scale)); height: calc(8em * 0.5 * var(--scale));
margin-left: 5.1em;
z-index: 2;
grid-template-rows: repeat(8, 1fr); grid-template-rows: repeat(8, 1fr);
grid-template-columns: repeat(5, 1fr); grid-template-columns: repeat(5, 1fr);
grid-template-areas: "P P . L L" grid-template-areas: "P P . L L"
@ -101,6 +93,7 @@
} }
#status { #status {
margin-top: 0.5em;
line-height: 2; line-height: 2;
width: 100%; width: 100%;
text-align: center; text-align: center;
@ -108,7 +101,7 @@
@media (prefers-reduced-motion) { @media (prefers-reduced-motion) {
#throbber { #throbber {
animation: none; animation: none !important;
} }
} }
</style> </style>
@ -118,13 +111,13 @@
</head> </head>
<body style="margin: 0; padding: 0"> <body style="margin: 0; padding: 0">
<noscript>To use Pleroma, please enable JavaScript.</noscript> <noscript>To use Pleroma, please enable JavaScript.</noscript>
<!-- putting styles here to avoid having to wait for styles to load up -->
<div id="splash"> <div id="splash">
<div id="splash-credit"> <!-- we are hiding entire graphic so no point showing credit -->
<div aria-hidden="true" id="splash-credit">
Art by pipivovott Art by pipivovott
</div> </div>
<div id="splash-container"> <div id="splash-container">
<div id="mascot-container"> <div aria-hidden="true" id="mascot-container">
<div id="throbber"> <div id="throbber">
<div class="chunk" id="chunk-P"> <div class="chunk" id="chunk-P">
</div> </div>
@ -133,11 +126,12 @@
<div class="chunk" id="chunk-E"> <div class="chunk" id="chunk-E">
</div> </div>
</div> </div>
<img id="mascot" src="/static/pleromatan_apology_fox.png"> <img id="mascot" src="/static/pleromatan_apology.png">
</div> </div>
<div id="status" class="css-ok"> <div id="status" class="css-ok">
<!-- (。><) --> <!-- (。><) -->
<span class="initial-text">(。&gt;&lt;)</span> <!-- it's a pseudographic, don't want screenreader read out nonsense -->
<span aria-hidden="true" class="initial-text">(。&gt;&lt;)</span>
</div> </div>
</div> </div>
</div> </div>

View file

@ -937,12 +937,6 @@ option {
} }
} }
#mascot-container {
perspective: 60em;
perspective-origin: 0 -15em;
transform-style: preserve-3d;
}
#throbber { #throbber {
animation-duration: 3s; animation-duration: 3s;
animation-name: bounce; animation-name: bounce;
@ -950,12 +944,9 @@ option {
animation-direction: normal; animation-direction: normal;
transform-origin: bottom center; transform-origin: bottom center;
--defaultY: 0;
&.dead { &.dead {
animation-name: dead; animation-name: dead;
animation-duration: 3s; animation-duration: 2s;
// animation-iteration-count: 1;
animation-iteration-count: 1; animation-iteration-count: 1;
transform: rotateX(90deg) rotateY(0) rotateZ(-45deg); transform: rotateX(90deg) rotateY(0) rotateZ(-45deg);
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 396 KiB

After

Width:  |  Height:  |  Size: 35 B

View file

@ -0,0 +1 @@
../../static/pleromatan_apology.png

Before

Width:  |  Height:  |  Size: 396 KiB

After

Width:  |  Height:  |  Size: 35 B

View file

@ -349,7 +349,7 @@ const afterStoreSetup = async ({ store, i18n }) => {
await setConfig({ store }) await setConfig({ store })
document.querySelector('#status').textContent = i18n.global.t('splash.theme') document.querySelector('#status').textContent = i18n.global.t('splash.theme')
try { try {
await store.dispatch('setTheme').catch((e) => { console.log(e) }) await store.dispatch('setTheme').catch((e) => { console.error('Error setting theme', e) })
} catch (e) { } catch (e) {
return Promise.reject(e) return Promise.reject(e)
} }

View file

@ -48,16 +48,6 @@ const i18n = createI18n({
messages.setLanguage(i18n.global, currentLocale) 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 = { const persistedStateOptions = {
paths: [ paths: [
'serverSideStorage.cache', 'serverSideStorage.cache',
@ -68,6 +58,18 @@ const persistedStateOptions = {
}; };
(async () => { (async () => {
const isFox = Math.floor(Math.random() * 2) > 0 ? '_fox' : ''
const splashError = (i18n, e) => {
const throbber = document.querySelector('#throbber')
throbber.addEventListener('animationend', () => {
document.querySelector('#mascot').src = `/static/pleromatan_orz${isFox}.png`
})
throbber.classList.add('dead')
document.querySelector('#status').textContent = i18n.global.t('splash.error')
console.error('PleromaFE failed to initialize: ', e)
}
try { try {
let storageError let storageError
const plugins = [pushNotifications] const plugins = [pushNotifications]
@ -78,6 +80,7 @@ const persistedStateOptions = {
console.error('Storage error', e) console.error('Storage error', e)
storageError = e storageError = e
} }
document.querySelector('#mascot').src = `/static/pleromatan_apology${isFox}.png`
document.querySelector('#status').removeAttribute('class') document.querySelector('#status').removeAttribute('class')
document.querySelector('#status').textContent = i18n.global.t('splash.loading') document.querySelector('#status').textContent = i18n.global.t('splash.loading')
document.querySelector('#splash-credit').textContent = i18n.global.t('update.art_by', { linkToArtist: 'pipivovott' }) document.querySelector('#splash-credit').textContent = i18n.global.t('update.art_by', { linkToArtist: 'pipivovott' })

View file

@ -56,6 +56,9 @@ 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
}, },
@ -117,9 +120,6 @@ 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 ({ dispatch, commit, rootState }, { themeName, themeData, recompile, saveData } = {}) { setTheme ({ commit, rootState }, { themeName, themeData, recompile, saveData } = {}) {
const { const {
theme: instanceThemeName theme: instanceThemeName
} = rootState.instance } = rootState.instance
@ -230,27 +230,27 @@ const interfaceMod = {
const forceRecompile = forceThemeRecompilation || recompile const forceRecompile = forceThemeRecompilation || recompile
let result = null let promise = null
if (themeData) { if (themeData) {
result = normalizeThemeData(themeData) promise = Promise.resolve(normalizeThemeData(themeData))
} else if (themeName) { } else if (themeName) {
result = normalizeThemeData(getPreset(themeName)) promise = getPreset(themeName).then(themeData => normalizeThemeData(themeData))
.then(themeData => normalizeThemeData(themeData))
} else if (userThemeSource || userThemeSnapshot) { } else if (userThemeSource || userThemeSnapshot) {
result = normalizeThemeData({ promise = Promise.resolve(normalizeThemeData({
_pleroma_theme_version: 2, _pleroma_theme_version: 2,
theme: userThemeSnapshot, theme: userThemeSnapshot,
source: userThemeSource source: userThemeSource
}) }))
} else if (actualThemeName && actualThemeName !== 'custom') { } else if (actualThemeName && actualThemeName !== 'custom') {
const themeData = actualThemeName promise = getPreset(actualThemeName).then(themeData => {
const realThemeData = normalizeThemeData(themeData) const realThemeData = normalizeThemeData(themeData)
if (actualThemeName === instanceThemeName) { if (actualThemeName === instanceThemeName) {
// This sole line is the reason why this whole block is above the recompilation check // This sole line is the reason why this whole block is above the recompilation check
commit('setInstanceOption', { name: 'themeData', value: { theme: realThemeData } }) commit('setInstanceOption', { name: 'themeData', value: { theme: realThemeData } })
} }
result = realThemeData return realThemeData
})
} else { } else {
throw new Error('Cannot load any theme!') throw new Error('Cannot load any theme!')
} }
@ -258,92 +258,96 @@ 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()) {
dispatch('setThemeApplied') commit('setThemeApplied')
return Promise.resolve() return
} }
const realThemeData = result promise
const theme2ruleset = convertTheme2To3(realThemeData) .then(realThemeData => {
const theme2ruleset = convertTheme2To3(realThemeData)
if (saveData) { if (saveData) {
commit('setOption', { name: 'theme', value: themeName || actualThemeName }) commit('setOption', { name: 'theme', value: themeName || actualThemeName })
commit('setOption', { name: 'customTheme', value: realThemeData }) commit('setOption', { name: 'customTheme', value: realThemeData })
commit('setOption', { name: 'customThemeSource', 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
} }
case 'underlay': { const hacks = []
if (value !== 'none') {
const newRule = { Object.entries(theme3hacks).forEach(([key, value]) => {
component: 'Underlay', switch (key) {
directives: {} 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
} }
if (value === 'opaque') { case 'underlay': {
newRule.directives.opacity = 1 if (value !== 'none') {
newRule.directives.background = '--wallpaper' 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
} }
if (value === 'transparent') {
newRule.directives.opacity = 0
}
hacks.push(newRule)
} }
break })
}
}
})
const ruleset = [ const ruleset = [
...theme2ruleset, ...theme2ruleset,
...hacks ...hacks
] ]
applyTheme( applyTheme(
ruleset, ruleset,
() => dispatch('setThemeApplied'), () => commit('setThemeApplied'),
themeDebug themeDebug
) )
})
return promise
} }
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 KiB