forked from Mirrors/elk
feat: respect Media Display preferences (#2065)
This commit is contained in:
parent
a3116e703a
commit
d9e7a09d24
5 changed files with 49 additions and 10 deletions
|
@ -22,6 +22,12 @@ const isFiltered = $computed(() => status.account.id !== currentUser.value?.acco
|
||||||
// check spoiler text or media attachment
|
// check spoiler text or media attachment
|
||||||
// needed to handle accounts that mark all their posts as sensitive
|
// needed to handle accounts that mark all their posts as sensitive
|
||||||
const hasSpoilerOrSensitiveMedia = $computed(() => !!status.spoilerText || (status.sensitive && !!status.mediaAttachments.length))
|
const hasSpoilerOrSensitiveMedia = $computed(() => !!status.spoilerText || (status.sensitive && !!status.mediaAttachments.length))
|
||||||
|
const isSensitiveNonSpoiler = computed(() => status.sensitive && !status.spoilerText)
|
||||||
|
const hideAllMedia = computed(
|
||||||
|
() => {
|
||||||
|
return currentUser.value ? (getHideMediaByDefault(currentUser.value.account) && !!status.mediaAttachments.length) : false
|
||||||
|
},
|
||||||
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -32,15 +38,15 @@ const hasSpoilerOrSensitiveMedia = $computed(() => !!status.spoilerText || (stat
|
||||||
'ms--3.5 mt--1 ms--1': isDM && context !== 'details',
|
'ms--3.5 mt--1 ms--1': isDM && context !== 'details',
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<StatusBody v-if="!isFiltered && status.sensitive && !status.spoilerText" :status="status" :newer="newer" :with-action="!isDetails" :class="isDetails ? 'text-xl' : ''" />
|
<StatusBody v-if="(!isFiltered && isSensitiveNonSpoiler) || hideAllMedia" :status="status" :newer="newer" :with-action="!isDetails" :class="isDetails ? 'text-xl' : ''" />
|
||||||
<StatusSpoiler :enabled="hasSpoilerOrSensitiveMedia || isFiltered" :filter="isFiltered" :is-d-m="isDM">
|
<StatusSpoiler :enabled="hasSpoilerOrSensitiveMedia || isFiltered" :filter="isFiltered" :sensitive-non-spoiler="isSensitiveNonSpoiler || hideAllMedia" :is-d-m="isDM">
|
||||||
<template v-if="status.spoilerText" #spoiler>
|
<template v-if="status.spoilerText" #spoiler>
|
||||||
<p>{{ status.spoilerText }}</p>
|
<p>{{ status.spoilerText }}</p>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="filterPhrase" #spoiler>
|
<template v-else-if="filterPhrase" #spoiler>
|
||||||
<p>{{ `${$t('status.filter_hidden_phrase')}: ${filterPhrase}` }}</p>
|
<p>{{ `${$t('status.filter_hidden_phrase')}: ${filterPhrase}` }}</p>
|
||||||
</template>
|
</template>
|
||||||
<StatusBody v-if="!status.sensitive || status.spoilerText" :status="status" :newer="newer" :with-action="!isDetails" :class="isDetails ? 'text-xl' : ''" />
|
<StatusBody v-if="!(isSensitiveNonSpoiler || hideAllMedia)" :status="status" :newer="newer" :with-action="!isDetails" :class="isDetails ? 'text-xl' : ''" />
|
||||||
<StatusTranslation :status="status" />
|
<StatusTranslation :status="status" />
|
||||||
<StatusPoll v-if="status.poll" :status="status" />
|
<StatusPoll v-if="status.poll" :status="status" />
|
||||||
<StatusMedia
|
<StatusMedia
|
||||||
|
|
|
@ -1,18 +1,31 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const props = defineProps<{ enabled?: boolean; filter?: boolean; isDM?: boolean }>()
|
const props = defineProps<{ enabled?: boolean; filter?: boolean; isDM?: boolean; sensitiveNonSpoiler?: boolean }>()
|
||||||
|
|
||||||
const expandSpoilersByDefault = computed(() => currentUser.value ? getExpandSpoilersByDefault(currentUser.value.account) : false)
|
const expandSpoilers = computed(() => {
|
||||||
|
const expandCW = currentUser.value ? getExpandSpoilersByDefault(currentUser.value.account) : false
|
||||||
|
const expandMedia = currentUser.value ? getExpandMediaByDefault(currentUser.value.account) : false
|
||||||
|
|
||||||
const showContent = ref(expandSpoilersByDefault.value ? true : !props.enabled)
|
return !props.filter // always prevent expansion if filtered
|
||||||
|
&& ((props.sensitiveNonSpoiler && expandMedia)
|
||||||
|
|| (!props.sensitiveNonSpoiler && expandCW))
|
||||||
|
})
|
||||||
|
|
||||||
|
const hideContent = props.enabled || props.sensitiveNonSpoiler
|
||||||
|
const showContent = ref(expandSpoilers.value ? true : !hideContent)
|
||||||
const toggleContent = useToggle(showContent)
|
const toggleContent = useToggle(showContent)
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
showContent.value = expandSpoilersByDefault.value ? true : !props.enabled
|
showContent.value = expandSpoilers.value ? true : !hideContent
|
||||||
})
|
})
|
||||||
|
function getToggleText() {
|
||||||
|
if (props.sensitiveNonSpoiler)
|
||||||
|
return 'status.spoiler_media_hidden'
|
||||||
|
return props.filter ? 'status.filter_show_anyway' : 'status.spoiler_show_more'
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-if="enabled" flex flex-col items-start>
|
<div v-if="hideContent" flex flex-col items-start>
|
||||||
<div class="content-rich" p="x-4 b-2.5" text-center text-secondary w-full border="~ base" border-0 border-b-dotted border-b-3 mt-2>
|
<div class="content-rich" p="x-4 b-2.5" text-center text-secondary w-full border="~ base" border-0 border-b-dotted border-b-3 mt-2>
|
||||||
<slot name="spoiler" />
|
<slot name="spoiler" />
|
||||||
</div>
|
</div>
|
||||||
|
@ -20,9 +33,9 @@ watchEffect(() => {
|
||||||
<button btn-text px-2 py-1 :bg="isDM ? 'transparent' : 'base'" flex="~ center gap-2" :class="showContent ? '' : 'filter-saturate-0 hover:filter-saturate-100'" @click="toggleContent()">
|
<button btn-text px-2 py-1 :bg="isDM ? 'transparent' : 'base'" flex="~ center gap-2" :class="showContent ? '' : 'filter-saturate-0 hover:filter-saturate-100'" @click="toggleContent()">
|
||||||
<div v-if="showContent" i-ri:eye-line />
|
<div v-if="showContent" i-ri:eye-line />
|
||||||
<div v-else i-ri:eye-close-line />
|
<div v-else i-ri:eye-close-line />
|
||||||
{{ showContent ? $t('status.spoiler_show_less') : $t(filter ? 'status.filter_show_anyway' : 'status.spoiler_show_more') }}
|
{{ showContent ? $t('status.spoiler_show_less') : $t(getToggleText()) }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<slot v-if="!enabled || showContent" />
|
<slot v-if="!hideContent || showContent" />
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -170,10 +170,28 @@ export async function loginTo(masto: ElkMasto, user: Overwrite<UserLogin, { acco
|
||||||
}
|
}
|
||||||
|
|
||||||
const accountPreferencesMap = new Map<string, mastodon.v1.Preference>()
|
const accountPreferencesMap = new Map<string, mastodon.v1.Preference>()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns `true` when user ticked the preference to always expand posts with content warnings
|
||||||
|
*/
|
||||||
export function getExpandSpoilersByDefault(account: mastodon.v1.AccountCredentials) {
|
export function getExpandSpoilersByDefault(account: mastodon.v1.AccountCredentials) {
|
||||||
return accountPreferencesMap.get(account.acct)?.['reading:expand:spoilers'] ?? false
|
return accountPreferencesMap.get(account.acct)?.['reading:expand:spoilers'] ?? false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns `true` when user selected "Always show media" as Media Display preference
|
||||||
|
*/
|
||||||
|
export function getExpandMediaByDefault(account: mastodon.v1.AccountCredentials) {
|
||||||
|
return accountPreferencesMap.get(account.acct)?.['reading:expand:media'] === 'show_all' ?? false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns `true` when user selected "Always hide media" as Media Display preference
|
||||||
|
*/
|
||||||
|
export function getHideMediaByDefault(account: mastodon.v1.AccountCredentials) {
|
||||||
|
return accountPreferencesMap.get(account.acct)?.['reading:expand:media'] === 'hide_all' ?? false
|
||||||
|
}
|
||||||
|
|
||||||
export async function fetchAccountInfo(client: mastodon.Client, server: string) {
|
export async function fetchAccountInfo(client: mastodon.Client, server: string) {
|
||||||
const [account, preferences] = await Promise.all([
|
const [account, preferences] = await Promise.all([
|
||||||
client.v1.accounts.verifyCredentials(),
|
client.v1.accounts.verifyCredentials(),
|
||||||
|
|
|
@ -527,6 +527,7 @@
|
||||||
"replying_to": "Replying to {0}",
|
"replying_to": "Replying to {0}",
|
||||||
"show_full_thread": "Show Full thread",
|
"show_full_thread": "Show Full thread",
|
||||||
"someone": "someone",
|
"someone": "someone",
|
||||||
|
"spoiler_media_hidden": "Media hidden",
|
||||||
"spoiler_show_less": "Show less",
|
"spoiler_show_less": "Show less",
|
||||||
"spoiler_show_more": "Show more",
|
"spoiler_show_more": "Show more",
|
||||||
"thread": "Thread",
|
"thread": "Thread",
|
||||||
|
|
|
@ -523,6 +523,7 @@
|
||||||
"replying_to": "Sumasagot kay {0}",
|
"replying_to": "Sumasagot kay {0}",
|
||||||
"show_full_thread": "Ipakita ang buong thread",
|
"show_full_thread": "Ipakita ang buong thread",
|
||||||
"someone": "isa",
|
"someone": "isa",
|
||||||
|
"spoiler_media_hidden": "Nakatago and media",
|
||||||
"spoiler_show_less": "Ipakita nang mas kaunti",
|
"spoiler_show_less": "Ipakita nang mas kaunti",
|
||||||
"spoiler_show_more": "Ipakita nang mas marami",
|
"spoiler_show_more": "Ipakita nang mas marami",
|
||||||
"thread": "Thread",
|
"thread": "Thread",
|
||||||
|
|
Loading…
Reference in a new issue