forked from AkkomaGang/akkoma-fe
avatars shadows, also allows drop-shadow use
This commit is contained in:
parent
b45fc6c652
commit
406df4399b
11 changed files with 82 additions and 8 deletions
|
@ -6,7 +6,8 @@ import { highlightClass, highlightStyle } from '../../services/user_highlighter/
|
||||||
const Notification = {
|
const Notification = {
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
userExpanded: false
|
userExpanded: false,
|
||||||
|
betterShadow: this.$store.state.interface.browserSupport.cssFilter
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: [
|
props: [
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<status v-if="notification.type === 'mention'" :compact="true" :statusoid="notification.status"></status>
|
<status v-if="notification.type === 'mention'" :compact="true" :statusoid="notification.status"></status>
|
||||||
<div class="non-mention" :class="[userClass, { highlighted: userStyle }]" :style="[ userStyle ]"v-else>
|
<div class="non-mention" :class="[userClass, { highlighted: userStyle }]" :style="[ userStyle ]"v-else>
|
||||||
<a class='avatar-container' :href="notification.action.user.statusnet_profile_url" @click.stop.prevent.capture="toggleUserExpanded">
|
<a class='avatar-container' :href="notification.action.user.statusnet_profile_url" @click.stop.prevent.capture="toggleUserExpanded">
|
||||||
<StillImage class='avatar-compact' :src="notification.action.user.profile_image_url_original"/>
|
<StillImage class='avatar-compact' :class="{'better-shadow': betterShadow}" :src="notification.action.user.profile_image_url_original"/>
|
||||||
</a>
|
</a>
|
||||||
<div class='notification-right'>
|
<div class='notification-right'>
|
||||||
<div class="usercard notification-usercard" v-if="userExpanded">
|
<div class="usercard notification-usercard" v-if="userExpanded">
|
||||||
|
|
|
@ -49,11 +49,17 @@
|
||||||
.avatar-compact {
|
.avatar-compact {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
|
box-shadow: var(--avatarStatusShadow);
|
||||||
border-radius: $fallback--avatarAltRadius;
|
border-radius: $fallback--avatarAltRadius;
|
||||||
border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
|
border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
line-height: 0;
|
line-height: 0;
|
||||||
|
|
||||||
|
&.better-shadow {
|
||||||
|
box-shadow: none;
|
||||||
|
filter: drop-shadow(var(--avatarStatusShadowFilter))
|
||||||
|
}
|
||||||
|
|
||||||
&.animated::before {
|
&.animated::before {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,8 @@ const Status = {
|
||||||
showingTall: false,
|
showingTall: false,
|
||||||
expandingSubject: typeof this.$store.state.config.collapseMessageWithSubject === 'undefined'
|
expandingSubject: typeof this.$store.state.config.collapseMessageWithSubject === 'undefined'
|
||||||
? !this.$store.state.instance.collapseMessageWithSubject
|
? !this.$store.state.instance.collapseMessageWithSubject
|
||||||
: !this.$store.state.config.collapseMessageWithSubject
|
: !this.$store.state.config.collapseMessageWithSubject,
|
||||||
|
betterShadow: this.$store.state.interface.browserSupport.cssFilter
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
<div :class="[userClass, { highlighted: userStyle, 'is-retweet': retweet }]" :style="[ userStyle ]" class="media status">
|
<div :class="[userClass, { highlighted: userStyle, 'is-retweet': retweet }]" :style="[ userStyle ]" class="media status">
|
||||||
<div v-if="!noHeading" class="media-left">
|
<div v-if="!noHeading" class="media-left">
|
||||||
<a :href="status.user.statusnet_profile_url" @click.stop.prevent.capture="toggleUserExpanded">
|
<a :href="status.user.statusnet_profile_url" @click.stop.prevent.capture="toggleUserExpanded">
|
||||||
<StillImage class='avatar' :class="{'avatar-compact': compact}" :src="status.user.profile_image_url_original"/>
|
<StillImage class='avatar' :class="{'avatar-compact': compact, 'better-shadow': betterShadow}" :src="status.user.profile_image_url_original"/>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="status-body">
|
<div class="status-body">
|
||||||
|
@ -464,8 +464,14 @@
|
||||||
.status .avatar-compact {
|
.status .avatar-compact {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
|
box-shadow: var(--avatarStatusShadow);
|
||||||
border-radius: $fallback--avatarAltRadius;
|
border-radius: $fallback--avatarAltRadius;
|
||||||
border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
|
border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
|
||||||
|
|
||||||
|
&.better-shadow {
|
||||||
|
box-shadow: none;
|
||||||
|
filter: drop-shadow(var(--avatarStatusShadowFilter))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar {
|
.avatar {
|
||||||
|
@ -477,6 +483,11 @@
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
&.better-shadow {
|
||||||
|
box-shadow: none;
|
||||||
|
filter: drop-shadow(var(--avatarStatusShadowFilter))
|
||||||
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
|
@ -278,6 +278,18 @@
|
||||||
<button class="btn" @click="clearShadows">{{$t('settings.style.switcher.clear_all')}}</button>
|
<button class="btn" @click="clearShadows">{{$t('settings.style.switcher.clear_all')}}</button>
|
||||||
</div>
|
</div>
|
||||||
<shadow-control :ready="!!currentShadowFallback" :fallback="currentShadowFallback" v-model="currentShadow"/>
|
<shadow-control :ready="!!currentShadowFallback" :fallback="currentShadowFallback" v-model="currentShadow"/>
|
||||||
|
<div v-if="shadowSelected === 'avatar' || shadowSelected === 'avatarStatus'">
|
||||||
|
<i18n path="settings.style.shadows.filter_hint.always_drop_shadow" tag="p">
|
||||||
|
<code>filter: drop-shadow()</code>
|
||||||
|
</i18n>
|
||||||
|
<i18n path="settings.style.shadows.filter_hint.text" tag="p">
|
||||||
|
<code>drop-shadow</code>
|
||||||
|
<code>spread-radius</code>
|
||||||
|
<code>inset</code>
|
||||||
|
</i18n>
|
||||||
|
<p>{{$t('settings.style.shadows.filter_hint.inset_ignored')}}</p>
|
||||||
|
<p>{{$t('settings.style.shadows.filter_hint.spread_zero')}}</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div :label="$t('settings.style.fonts._tab_label')" class="fonts-container">
|
<div :label="$t('settings.style.fonts._tab_label')" class="fonts-container">
|
||||||
<div class="tab-header">
|
<div class="tab-header">
|
||||||
|
|
|
@ -7,7 +7,8 @@ export default {
|
||||||
return {
|
return {
|
||||||
hideUserStatsLocal: typeof this.$store.state.config.hideUserStats === 'undefined'
|
hideUserStatsLocal: typeof this.$store.state.config.hideUserStats === 'undefined'
|
||||||
? this.$store.state.instance.hideUserStats
|
? this.$store.state.instance.hideUserStats
|
||||||
: this.$store.state.config.hideUserStats
|
: this.$store.state.config.hideUserStats,
|
||||||
|
betterShadow: this.$store.state.interface.browserSupport.cssFilter
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
</a>
|
</a>
|
||||||
<div class='container'>
|
<div class='container'>
|
||||||
<router-link :to="{ name: 'user-profile', params: { id: user.id } }">
|
<router-link :to="{ name: 'user-profile', params: { id: user.id } }">
|
||||||
<StillImage class="avatar" :src="user.profile_image_url_original"/>
|
<StillImage class="avatar" :class='{ "better-shadow": betterShadow }' :src="user.profile_image_url_original"/>
|
||||||
</router-link>
|
</router-link>
|
||||||
<div class="name-and-screen-name">
|
<div class="name-and-screen-name">
|
||||||
<div :title="user.name" class='user-name' v-if="user.name_html" v-html="user.name_html"></div>
|
<div :title="user.name" class='user-name' v-if="user.name_html" v-html="user.name_html"></div>
|
||||||
|
@ -159,6 +159,11 @@
|
||||||
box-shadow: var(--avatarShadow);
|
box-shadow: var(--avatarShadow);
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
|
|
||||||
|
&.better-shadow {
|
||||||
|
box-shadow: none;
|
||||||
|
filter: drop-shadow(var(--avatarStatusShadowFilter))
|
||||||
|
}
|
||||||
|
|
||||||
&.animated::before {
|
&.animated::before {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,6 +236,13 @@
|
||||||
"spread": "Spread",
|
"spread": "Spread",
|
||||||
"inset": "Inset",
|
"inset": "Inset",
|
||||||
"hint": "For shadows you can also use --variable as a color value to use CSS3 variables. Please note that setting opacity won't work in this case.",
|
"hint": "For shadows you can also use --variable as a color value to use CSS3 variables. Please note that setting opacity won't work in this case.",
|
||||||
|
"filter_hint": {
|
||||||
|
"always_drop_shadow": "Warning, this shadow always uses {0} when browser supports it.",
|
||||||
|
"text": "Please note that {0} does not support {1} parameter and {2} keyword.",
|
||||||
|
"spread_zero": "Shadows with spread > 0 will appear as if it was set to zero",
|
||||||
|
"inset_ignored": "Inset shadows using will be ignored",
|
||||||
|
"inset_substituted": "Inset shadows will be substituted with {1} equivalent"
|
||||||
|
},
|
||||||
"components": {
|
"components": {
|
||||||
"panel": "Panel",
|
"panel": "Panel",
|
||||||
"panelHeader": "Panel header",
|
"panelHeader": "Panel header",
|
||||||
|
|
|
@ -4,6 +4,12 @@ const defaultState = {
|
||||||
settings: {
|
settings: {
|
||||||
currentSaveStateNotice: null,
|
currentSaveStateNotice: null,
|
||||||
noticeClearTimeout: null
|
noticeClearTimeout: null
|
||||||
|
},
|
||||||
|
browserSupport: {
|
||||||
|
cssFilter: window.CSS && window.CSS.supports && (
|
||||||
|
window.CSS.supports('filter', 'drop-shadow(0 0)') ||
|
||||||
|
window.CSS.supports('-webkit-filter', 'drop-shadow(0 0)')
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -110,6 +110,24 @@ const getCssShadow = (input) => {
|
||||||
]).join(' ')).join(', ')
|
]).join(' ')).join(', ')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getCssShadowFilter = (input) => {
|
||||||
|
if (input.length === 0) {
|
||||||
|
return 'none'
|
||||||
|
}
|
||||||
|
|
||||||
|
return input
|
||||||
|
// drop-shadow doesn't support inset or spread
|
||||||
|
.filter((shad) => console.log(shad) || !shad.inset && Number(shad.spread) === 0)
|
||||||
|
.map((shad) => [
|
||||||
|
shad.x,
|
||||||
|
shad.y,
|
||||||
|
// drop-shadow's blur is twice as strong compared to box-shadow
|
||||||
|
shad.blur / 2
|
||||||
|
].map(_ => _ + 'px').concat([
|
||||||
|
getCssColor(shad.color, shad.alpha)
|
||||||
|
]).join(' ')).join(', ')
|
||||||
|
}
|
||||||
|
|
||||||
const getCssColor = (input, a) => {
|
const getCssColor = (input, a) => {
|
||||||
let rgb = {}
|
let rgb = {}
|
||||||
if (typeof input === 'object') {
|
if (typeof input === 'object') {
|
||||||
|
@ -384,7 +402,12 @@ const generateShadows = (input) => {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
rules: {
|
rules: {
|
||||||
shadows: Object.entries(shadows).map(([k, v]) => `--${k}Shadow: ${getCssShadow(v)}`).join(';')
|
shadows: Object
|
||||||
|
.entries(shadows)
|
||||||
|
// TODO for v2.1: if shadow doesn't have non-inset shadows with spread > 0 - optionally
|
||||||
|
// convert all non-inset shadows into filter: drop-shadow() to boost performance
|
||||||
|
.map(([k, v]) => `--${k}Shadow: ${getCssShadow(v)}; --${k}ShadowFilter: ${getCssShadowFilter(v)}`)
|
||||||
|
.join(';')
|
||||||
},
|
},
|
||||||
theme: {
|
theme: {
|
||||||
shadows
|
shadows
|
||||||
|
@ -467,5 +490,6 @@ export {
|
||||||
generateFonts,
|
generateFonts,
|
||||||
generatePreset,
|
generatePreset,
|
||||||
composePreset,
|
composePreset,
|
||||||
getCssShadow
|
getCssShadow,
|
||||||
|
getCssShadowFilter
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue