Compare commits

...

8 commits

Author SHA1 Message Date
Henry Jameson
ef31db498d Merge remote-tracking branch 'origin/develop' into shigusegubu-themes3 2026-08-12 01:48:26 +03:00
HJ
117e5bdd87 Merge pull request 'Fix Theme 2 fonts after upgrade' (#3548) from fix/theme2-font-cache-recovery into develop
Reviewed-on: https://git.pleroma.social/pleroma/pleroma-fe/pulls/3548
2026-08-11 18:00:47 +00:00
Lain Soykaf
341b1c1c3e
fix: restore Theme 2 font families 2026-08-11 21:51:24 +04:00
HJ
9e4592df59 Merge pull request 'fix status index approxmiation in timeline rendering for dynamically changing viewport geometries' (#3543) from iamtakingiteasy/pleroma-fe:fix-timeline-rendering-status-index-approx into develop
Reviewed-on: https://git.pleroma.social/pleroma/pleroma-fe/pulls/3543
2026-08-10 13:50:37 +00:00
HJ
ba9c30aaf4 Merge pull request 'fix server-side domain mutes rendering/api calls' (#3544) from iamtakingiteasy/pleroma-fe:fix-serverside-domain-mutes-rendering-apicalls into develop
Reviewed-on: https://git.pleroma.social/pleroma/pleroma-fe/pulls/3544
2026-08-10 13:48:50 +00:00
Alexander Tumin
54b36e8f8e fix server-side domain mutes rendering/api calls 2026-08-09 12:31:33 +03:00
Alexander Tumin
58fdd50838 fix status index approxmiation in timeline rendering for dynamically changing viewport geometries 2026-08-09 12:23:57 +03:00
HJ
92e8190f63 Merge pull request 'fix timelines' (#3540) from fix-timelines into develop
Reviewed-on: https://git.pleroma.social/pleroma/pleroma-fe/pulls/3540
2026-08-07 13:07:22 +00:00
10 changed files with 85 additions and 6 deletions

View file

@ -0,0 +1 @@
Fixed server-side domain mutes rendering/api calls

View file

@ -0,0 +1 @@
Fix Theme 2 fonts falling back to serif after upgrade

View file

@ -0,0 +1 @@
Fixed status index approxmiation in timeline rendering for dynamically changing viewport geometries

View file

@ -153,7 +153,6 @@
</div> </div>
</template> </template>
<template #item="{item}"> <template #item="{item}">
{{ item }}
<DomainMuteCard :domain="item" /> <DomainMuteCard :domain="item" />
</template> </template>
<template #empty> <template #empty>

View file

@ -263,7 +263,10 @@ const Timeline = {
// Start from approximating the index of some visible status by using the // Start from approximating the index of some visible status by using the
// the center of the screen on the timeline. // the center of the screen on the timeline.
let approxIndex = Math.floor(statuses.length * (centerOfScreen / height)) let approxIndex = Math.min(
Math.floor(statuses.length * (centerOfScreen / height)),
statuses.length - 1,
)
let err = statuses[approxIndex].getBoundingClientRect().y let err = statuses[approxIndex].getBoundingClientRect().y
// if we have a previous scroll index that can be used, test if it's // if we have a previous scroll index that can be used, test if it's

View file

@ -37,8 +37,10 @@ import {
import { import {
blockUser as apiBlockUser, blockUser as apiBlockUser,
editUserNote as apiEditUserNote, editUserNote as apiEditUserNote,
muteDomain as apiMuteDomain,
muteUser as apiMuteUser, muteUser as apiMuteUser,
unblockUser as apiUnblockUser, unblockUser as apiUnblockUser,
unmuteDomain as apiUnmuteDomain,
unmuteUser as apiUnmuteUser, unmuteUser as apiUnmuteUser,
fetchBlocks, fetchBlocks,
fetchDomainMutes, fetchDomainMutes,
@ -170,14 +172,14 @@ const showReblogs = (store, userId) => {
} }
const muteDomain = (store, domain) => { const muteDomain = (store, domain) => {
return muteDomain({ return apiMuteDomain({
domain, domain,
credentials: useOAuthStore().token, credentials: useOAuthStore().token,
}).then(() => store.commit('addDomainMute', domain)) }).then(() => store.commit('addDomainMute', domain))
} }
const unmuteDomain = (store, domain) => { const unmuteDomain = (store, domain) => {
return unmuteDomain({ return apiUnmuteDomain({
domain, domain,
credentials: useOAuthStore().token, credentials: useOAuthStore().token,
}).then(() => store.commit('removeDomainMute', domain)) }).then(() => store.commit('removeDomainMute', domain))

View file

@ -92,6 +92,11 @@ export const adoptStyleSheets = throttle(() => {
const EAGER_STYLE_ID = 'pleroma-eager-styles' const EAGER_STYLE_ID = 'pleroma-eager-styles'
const LAZY_STYLE_ID = 'pleroma-lazy-styles' const LAZY_STYLE_ID = 'pleroma-lazy-styles'
export const hasInvalidCachedThemeRules = (data) =>
data
.flat()
.some((rule) => /--(?:mono)?font:\s*\[object Object\](?:;|$)/i.test(rule))
const generateTheme = (inputRuleset, callbacks, debug) => { const generateTheme = (inputRuleset, callbacks, debug) => {
const { const {
onNewRule = () => { onNewRule = () => {
@ -151,7 +156,8 @@ export const tryLoadCache = async () => {
if ( if (
cache.engineChecksum === getEngineChecksum() && cache.engineChecksum === getEngineChecksum() &&
cache.checksum !== undefined && cache.checksum !== undefined &&
cache.checksum === useMergedConfigStore().mergedConfig.themeChecksum cache.checksum === useMergedConfigStore().mergedConfig.themeChecksum &&
!hasInvalidCachedThemeRules(cache.data)
) { ) {
const eagerStyles = createStyleSheet(EAGER_STYLE_ID, 10) const eagerStyles = createStyleSheet(EAGER_STYLE_ID, 10)
const lazyStyles = createStyleSheet(LAZY_STYLE_ID, 20) const lazyStyles = createStyleSheet(LAZY_STYLE_ID, 20)

View file

@ -266,7 +266,7 @@ export const convertTheme2To3 = (data) => {
Object.keys(data.fonts || {}).forEach((key) => { Object.keys(data.fonts || {}).forEach((key) => {
if (!fontsKeys.has(key)) return if (!fontsKeys.has(key)) return
if (!data.fonts[key]) return if (!data.fonts[key]) return
const originalFont = data.fonts[key] const originalFont = data.fonts[key].family
const rule = { source: '2to3' } const rule = { source: '2to3' }
switch (key) { switch (key) {

View file

@ -0,0 +1,24 @@
import { hasInvalidCachedThemeRules } from 'src/services/style_setter/style_setter.js'
describe('style setter cache', () => {
it('rejects cached rules containing serialized objects', () => {
expect(
hasInvalidCachedThemeRules([
['html { --font: [object Object]; }'],
['.post { --font: sans-serif; }'],
]),
).to.equal(true)
})
it('accepts cached rules containing valid font families', () => {
expect(
hasInvalidCachedThemeRules([
['html { --font: sans-serif; }'],
[
'.post { --font: "Atkinson Hyperlegible"; }',
'.post::after { content: "[object Object]"; }',
],
]),
).to.equal(false)
})
})

View file

@ -0,0 +1,42 @@
import {
basePaletteKeys,
convertTheme2To3,
} from 'src/services/theme_data/theme2_to_theme3.js'
describe('Theme 2 to Theme 3 conversion', () => {
it('converts font descriptors to CSS font families', () => {
const colors = Object.fromEntries(
[...basePaletteKeys].map((key) => [key, '#000000']),
)
const rules = convertTheme2To3({
colors,
fonts: {
interface: { family: 'sans-serif' },
input: { family: 'Open Sans' },
post: { family: 'Atkinson Hyperlegible' },
postCode: { family: 'monospace' },
},
})
expect(rules).to.deep.include({
source: '2to3',
component: 'Root',
directives: { '--font': 'generic | sans-serif' },
})
expect(rules).to.deep.include({
source: '2to3',
component: 'Root',
directives: { '--monoFont': 'generic | monospace' },
})
expect(rules).to.deep.include({
source: '2to3',
component: 'Input',
directives: { '--font': 'generic | Open Sans' },
})
expect(rules).to.deep.include({
source: '2to3',
component: 'RichContent',
directives: { '--font': 'generic | Atkinson Hyperlegible' },
})
})
})