Merge f6f96f24d1
into 763c708253
This commit is contained in:
commit
f0fe171198
|
@ -34,8 +34,13 @@ defineProps<{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
--color: color(from var(--MI_THEME-error) srgb r g b / 0.25);
|
background-image: repeating-linear-gradient(
|
||||||
background-size: auto auto;
|
135deg,
|
||||||
background-image: repeating-linear-gradient(135deg, transparent, transparent 10px, var(--color) 4px, var(--color) 14px);
|
transparent,
|
||||||
|
transparent 10px,
|
||||||
|
var(--c) 6px,
|
||||||
|
var(--c) 16px
|
||||||
|
);
|
||||||
|
--c: color(from var(--MI_THEME-error) srgb r g b / 0.25);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -83,12 +83,27 @@ function cancel() {
|
||||||
|
|
||||||
<style lang="scss" module>
|
<style lang="scss" module>
|
||||||
.emojiImgWrapper {
|
.emojiImgWrapper {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
height: 40cqh;
|
height: 40cqh;
|
||||||
background-image: repeating-linear-gradient(45deg, transparent, transparent 8px, var(--MI_THEME-X5) 8px, var(--MI_THEME-X5) 14px);
|
border-radius: var(--MI-radius);
|
||||||
border-radius: var(--MI-radius);
|
margin: auto;
|
||||||
margin: auto;
|
overflow-y: hidden;
|
||||||
overflow-y: hidden;
|
background-image: repeating-linear-gradient(
|
||||||
|
135deg,
|
||||||
|
transparent,
|
||||||
|
transparent 10px,
|
||||||
|
var(--c) 6px,
|
||||||
|
var(--c) 16px
|
||||||
|
);
|
||||||
|
|
||||||
|
&,
|
||||||
|
html[data-color-scheme=light] & {
|
||||||
|
--c: rgb(0 0 0 / 0.02);
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-color-scheme=dark] & {
|
||||||
|
--c: rgb(255 255 255 / 0.02);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.aliases {
|
.aliases {
|
||||||
|
|
|
@ -306,9 +306,14 @@ onUnmounted(() => {
|
||||||
|
|
||||||
.embedCodeGenPreviewRoot {
|
.embedCodeGenPreviewRoot {
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: var(--MI_THEME-bg);
|
background-color: var(--bg);
|
||||||
background-size: auto auto;
|
background-image: repeating-linear-gradient(
|
||||||
background-image: repeating-linear-gradient(135deg, transparent, transparent 6px, var(--MI_THEME-panel) 6px, var(--MI_THEME-panel) 12px);
|
135deg,
|
||||||
|
transparent,
|
||||||
|
transparent 10px,
|
||||||
|
var(--panel) 6px,
|
||||||
|
var(--panel) 16px
|
||||||
|
);
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,9 +91,13 @@ const props = defineProps<{
|
||||||
}
|
}
|
||||||
|
|
||||||
&:global(.gray) {
|
&:global(.gray) {
|
||||||
--c: var(--MI_THEME-bg);
|
background-image: repeating-linear-gradient(
|
||||||
background-image: linear-gradient(45deg, var(--c) 16.67%, transparent 16.67%, transparent 50%, var(--c) 50%, var(--c) 66.67%, transparent 66.67%, transparent 100%);
|
135deg,
|
||||||
background-size: 16px 16px;
|
transparent,
|
||||||
|
transparent 10px,
|
||||||
|
var(--MI_THEME-bg) 6px,
|
||||||
|
var(--MI_THEME-bg) 16px
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 700px) {
|
@media (max-width: 700px) {
|
||||||
|
|
|
@ -238,8 +238,13 @@ onMounted(() => {
|
||||||
background: var(--MI_THEME-acrylicBg);
|
background: var(--MI_THEME-acrylicBg);
|
||||||
-webkit-backdrop-filter: var(--MI-blur, blur(15px));
|
-webkit-backdrop-filter: var(--MI-blur, blur(15px));
|
||||||
backdrop-filter: var(--MI-blur, blur(15px));
|
backdrop-filter: var(--MI-blur, blur(15px));
|
||||||
background-size: auto auto;
|
background-image: repeating-linear-gradient(
|
||||||
background-image: repeating-linear-gradient(135deg, transparent, transparent 5px, var(--MI_THEME-panel) 5px, var(--MI_THEME-panel) 10px);
|
135deg,
|
||||||
|
transparent,
|
||||||
|
transparent 10px,
|
||||||
|
var(--MI_THEME-panel) 6px,
|
||||||
|
var(--MI_THEME-panel) 16px
|
||||||
|
);
|
||||||
border-radius: 0 0 6px 6px;
|
border-radius: 0 0 6px 6px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -4,114 +4,158 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div :class="[$style.root, { yellow: instance.isNotResponding, red: instance.isBlocked, gray: instance.isSuspended, blue: instance.isSilenced }]">
|
<div
|
||||||
<img class="icon" :src="getInstanceIcon(instance)" alt="" loading="lazy"/>
|
:class="[$style.root, {
|
||||||
<div class="body">
|
[$style.isNotResponding]: instance.isNotResponding,
|
||||||
<span class="host">{{ instance.name ?? instance.host }}</span>
|
[$style.isSilenced]: instance.isSilenced,
|
||||||
<span class="sub _monospace"><b>{{ instance.host }}</b> / {{ instance.softwareName || '?' }} {{ instance.softwareVersion }}</span>
|
[$style.isSuspended]: instance.isSuspended,
|
||||||
|
[$style.isBlocked]: instance.isBlocked,
|
||||||
|
}]"
|
||||||
|
>
|
||||||
|
<img :class="$style.icon" :src="getInstanceIcon(instance)" alt="" loading="lazy"/>
|
||||||
|
<div :class="$style.body">
|
||||||
|
<span :class="$style.host">{{ instance.name || instance.host }}</span>
|
||||||
|
<span :class="$style.sub">
|
||||||
|
<span class="_monospace">
|
||||||
|
<span style="font-weight: 700;">{{ instance.host }}</span> / {{ instance.softwareName || '?' }} {{ instance.softwareVersion }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<MkMiniChart v-if="chartValues" class="chart" :src="chartValues"/>
|
<MkMiniChart v-if="chartValues" :class="$style.chart" :src="chartValues"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from 'vue';
|
import { shallowRef, watch } from 'vue';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import MkMiniChart from '@/components/MkMiniChart.vue';
|
|
||||||
import { misskeyApiGet } from '@/scripts/misskey-api.js';
|
import { misskeyApiGet } from '@/scripts/misskey-api.js';
|
||||||
import { getProxiedImageUrlNullable } from '@/scripts/media-proxy.js';
|
import { getProxiedImageUrlNullable } from '@/scripts/media-proxy.js';
|
||||||
|
import MkMiniChart from '@/components/MkMiniChart.vue';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
instance: Misskey.entities.FederationInstance;
|
instance: Misskey.entities.FederationInstance;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const chartValues = ref<number[] | null>(null);
|
const chartValues = shallowRef<number[] | null>(null);
|
||||||
|
|
||||||
misskeyApiGet('charts/instance', { host: props.instance.host, limit: 16 + 1, span: 'day' }).then(res => {
|
watch(() => props.instance.host, (host) => {
|
||||||
// 今日のぶんの値はまだ途中の値であり、それも含めると大抵の場合前日よりも下降しているようなグラフになってしまうため今日は弾く
|
misskeyApiGet('charts/instance', {
|
||||||
res.requests.received.splice(0, 1);
|
host,
|
||||||
chartValues.value = res.requests.received;
|
limit: 16 + 1,
|
||||||
|
span: 'day',
|
||||||
|
}).then(res => {
|
||||||
|
// 今日のぶんの値はまだ途中の値であり、それも含めると大抵の場合前日よりも下降しているようなグラフになってしまうため今日は弾く
|
||||||
|
res.requests.received.shift();
|
||||||
|
chartValues.value = res.requests.received;
|
||||||
|
}).catch(() => {
|
||||||
|
chartValues.value = null;
|
||||||
|
});
|
||||||
|
}, {
|
||||||
|
immediate: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
function getInstanceIcon(instance): string {
|
const getInstanceIcon = (instance: Misskey.entities.FederationInstance) => (
|
||||||
return getProxiedImageUrlNullable(instance.iconUrl, 'preview') ?? getProxiedImageUrlNullable(instance.faviconUrl, 'preview') ?? '/client-assets/dummy.png';
|
getProxiedImageUrlNullable(instance.iconUrl, 'preview')
|
||||||
}
|
?? getProxiedImageUrlNullable(instance.faviconUrl, 'preview')
|
||||||
|
?? '/client-assets/dummy.png'
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" module>
|
<style lang="scss" module>
|
||||||
.root {
|
$bodyTitleHieght: 18px;
|
||||||
$bodyTitleHieght: 18px;
|
$bodyInfoHieght: 16px;
|
||||||
$bodyInfoHieght: 16px;
|
|
||||||
|
|
||||||
|
.root {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
background: var(--MI_THEME-panel);
|
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
background-color: var(--MI_THEME-panel);
|
||||||
|
background-image: repeating-linear-gradient(
|
||||||
|
135deg,
|
||||||
|
transparent,
|
||||||
|
transparent 10px,
|
||||||
|
var(--c) 6px,
|
||||||
|
var(--c) 16px
|
||||||
|
);
|
||||||
|
--c: transparent;
|
||||||
|
|
||||||
> :global(.icon) {
|
&,
|
||||||
display: block;
|
html[data-color-scheme=light] & {
|
||||||
width: ($bodyTitleHieght + $bodyInfoHieght);
|
&.isNotResponding {
|
||||||
height: ($bodyTitleHieght + $bodyInfoHieght);
|
--c: color(from color-mix(in srgb, var(--MI_THEME-panel), orange 50%) srgb r g b / 0.25);
|
||||||
object-fit: cover;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> :global(.body) {
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
font-size: 0.9em;
|
|
||||||
color: var(--MI_THEME-fg);
|
|
||||||
padding-right: 8px;
|
|
||||||
|
|
||||||
> :global(.host) {
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
line-height: $bodyTitleHieght;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
> :global(.sub) {
|
&.isSilenced {
|
||||||
display: block;
|
--c: color(from color-mix(in srgb, var(--MI_THEME-panel), blue 50%) srgb r g b / 0.25);
|
||||||
width: 100%;
|
}
|
||||||
font-size: 80%;
|
|
||||||
opacity: 0.7;
|
&.isSuspended {
|
||||||
line-height: $bodyInfoHieght;
|
--c: color(from color-mix(in srgb, var(--MI_THEME-panel), black 15%) srgb r g b / 0.25);
|
||||||
white-space: nowrap;
|
}
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
&.isBlocked {
|
||||||
|
--c: color(from color-mix(in srgb, var(--MI_THEME-panel), red 50%) srgb r g b / 0.25);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> :global(.chart) {
|
html[data-color-scheme=dark] & {
|
||||||
height: 30px;
|
&.isNotResponding {
|
||||||
}
|
--c: color(from color-mix(in srgb, var(--MI_THEME-panel), orange 50%) srgb r g b / 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
&:global(.blue) {
|
&.isSilenced {
|
||||||
--c: rgba(0, 42, 255, 0.15);
|
--c: color(from color-mix(in srgb, var(--MI_THEME-panel), blue 50%) srgb r g b / 0.5);
|
||||||
background-image: linear-gradient(45deg, var(--c) 16.67%, transparent 16.67%, transparent 50%, var(--c) 50%, var(--c) 66.67%, transparent 66.67%, transparent 100%);
|
}
|
||||||
background-size: 16px 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:global(.yellow) {
|
&.isSuspended {
|
||||||
--c: rgb(255 196 0 / 15%);
|
--c: color(from color-mix(in srgb, var(--MI_THEME-panel), white 15%) srgb r g b / 0.5);
|
||||||
background-image: linear-gradient(45deg, var(--c) 16.67%, transparent 16.67%, transparent 50%, var(--c) 50%, var(--c) 66.67%, transparent 66.67%, transparent 100%);
|
}
|
||||||
background-size: 16px 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:global(.red) {
|
&.isBlocked {
|
||||||
--c: rgb(255 0 0 / 15%);
|
--c: color(from color-mix(in srgb, var(--MI_THEME-panel), red 50%) srgb r g b / 0.5);
|
||||||
background-image: linear-gradient(45deg, var(--c) 16.67%, transparent 16.67%, transparent 50%, var(--c) 50%, var(--c) 66.67%, transparent 66.67%, transparent 100%);
|
}
|
||||||
background-size: 16px 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:global(.gray) {
|
|
||||||
--c: var(--MI_THEME-bg);
|
|
||||||
background-image: linear-gradient(45deg, var(--c) 16.67%, transparent 16.67%, transparent 50%, var(--c) 50%, var(--c) 66.67%, transparent 66.67%, transparent 100%);
|
|
||||||
background-size: 16px 16px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
display: block;
|
||||||
|
width: ($bodyTitleHieght + $bodyInfoHieght);
|
||||||
|
height: ($bodyTitleHieght + $bodyInfoHieght);
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.body {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
font-size: 0.9em;
|
||||||
|
color: var(--fg);
|
||||||
|
padding-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.host {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
line-height: $bodyTitleHieght;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
font-size: 80%;
|
||||||
|
opacity: 0.7;
|
||||||
|
line-height: $bodyInfoHieght;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart {
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -173,7 +173,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<template #default="{ items }">
|
<template #default="{ items }">
|
||||||
<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); grid-gap: 12px;">
|
<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); grid-gap: 12px;">
|
||||||
<MkA v-for="item in items" :key="item.id" :to="userPage(item.user)">
|
<MkA v-for="item in items" :key="item.id" :to="userPage(item.user)">
|
||||||
<MkUserCardMini :user="item.user" :withChart="false"/>
|
<MkUserCardMini :user="item.user"/>
|
||||||
</MkA>
|
</MkA>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -190,7 +190,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<template #default="{ items }">
|
<template #default="{ items }">
|
||||||
<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); grid-gap: 12px;">
|
<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); grid-gap: 12px;">
|
||||||
<MkA v-for="item in items" :key="item.id" :to="userPage(item.user)">
|
<MkA v-for="item in items" :key="item.id" :to="userPage(item.user)">
|
||||||
<MkUserCardMini :user="item.user" :withChart="false"/>
|
<MkUserCardMini :user="item.user"/>
|
||||||
</MkA>
|
</MkA>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1197,15 +1197,22 @@ defineExpose({
|
||||||
min-height: 75px;
|
min-height: 75px;
|
||||||
max-height: 150px;
|
max-height: 150px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
background-size: auto auto;
|
background-image: repeating-linear-gradient(
|
||||||
}
|
135deg,
|
||||||
|
transparent,
|
||||||
|
transparent 10px,
|
||||||
|
var(--c) 6px,
|
||||||
|
var(--c) 16px
|
||||||
|
);
|
||||||
|
|
||||||
html[data-color-scheme=dark] .preview {
|
&,
|
||||||
background-image: repeating-linear-gradient(135deg, transparent, transparent 5px, #0004 5px, #0004 10px);
|
html[data-color-scheme=light] & {
|
||||||
}
|
--c: rgb(0 0 0 / 0.02);
|
||||||
|
}
|
||||||
|
|
||||||
html[data-color-scheme=light] .preview {
|
html[data-color-scheme=dark] & {
|
||||||
background-image: repeating-linear-gradient(135deg, transparent, transparent 5px, #00000005 5px, #00000005 10px);
|
--c: rgb(255 255 255 / 0.02);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.targetNote {
|
.targetNote {
|
||||||
|
|
|
@ -4,7 +4,12 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-adaptive-bg :class="[$style.root]">
|
<div
|
||||||
|
:class="[$style.root, {
|
||||||
|
[$style.isSilenced]: 'isSilenced' in user && user.isSilenced,
|
||||||
|
[$style.isSuspended]: 'isSuspended' in user && user.isSuspended,
|
||||||
|
}]"
|
||||||
|
>
|
||||||
<MkAvatar :class="$style.avatar" :user="user" indicator/>
|
<MkAvatar :class="$style.avatar" :user="user" indicator/>
|
||||||
<div :class="$style.body">
|
<div :class="$style.body">
|
||||||
<span :class="$style.name"><MkUserName :user="user"/></span>
|
<span :class="$style.name"><MkUserName :user="user"/></span>
|
||||||
|
@ -15,29 +20,42 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import { shallowRef, watch } from 'vue';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import { onMounted, ref } from 'vue';
|
|
||||||
import MkMiniChart from '@/components/MkMiniChart.vue';
|
|
||||||
import { misskeyApiGet } from '@/scripts/misskey-api.js';
|
import { misskeyApiGet } from '@/scripts/misskey-api.js';
|
||||||
import { acct } from '@/filters/user.js';
|
import { acct } from '@/filters/user.js';
|
||||||
|
import MkMiniChart from '@/components/MkMiniChart.vue';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
user: Misskey.entities.User;
|
user: Misskey.entities.User;
|
||||||
withChart?: boolean;
|
withChart?: boolean;
|
||||||
}>(), {
|
}>(), {
|
||||||
withChart: true,
|
withChart: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const chartValues = ref<number[] | null>(null);
|
const chartValues = shallowRef<number[] | null>(null);
|
||||||
|
|
||||||
onMounted(() => {
|
watch([
|
||||||
if (props.withChart) {
|
() => props.user.id,
|
||||||
misskeyApiGet('charts/user/notes', { userId: props.user.id, limit: 16 + 1, span: 'day' }).then(res => {
|
() => props.withChart,
|
||||||
|
], ([userId, withChart]) => {
|
||||||
|
if (withChart) {
|
||||||
|
misskeyApiGet('charts/user/notes', {
|
||||||
|
userId,
|
||||||
|
limit: 16 + 1,
|
||||||
|
span: 'day',
|
||||||
|
}).then(res => {
|
||||||
// 今日のぶんの値はまだ途中の値であり、それも含めると大抵の場合前日よりも下降しているようなグラフになってしまうため今日は弾く
|
// 今日のぶんの値はまだ途中の値であり、それも含めると大抵の場合前日よりも下降しているようなグラフになってしまうため今日は弾く
|
||||||
res.inc.splice(0, 1);
|
res.inc.shift();
|
||||||
chartValues.value = res.inc;
|
chartValues.value = res.inc;
|
||||||
|
}).catch(() => {
|
||||||
|
chartValues.value = null;
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
chartValues.value = null;
|
||||||
}
|
}
|
||||||
|
}, {
|
||||||
|
immediate: true,
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -49,8 +67,37 @@ $bodyInfoHieght: 16px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
background: var(--MI_THEME-panel);
|
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
background-color: var(--MI-THEME-panel);
|
||||||
|
background-image: repeating-linear-gradient(
|
||||||
|
135deg,
|
||||||
|
transparent,
|
||||||
|
transparent 10px,
|
||||||
|
var(--c) 6px,
|
||||||
|
var(--c) 16px
|
||||||
|
);
|
||||||
|
--c: transparent;
|
||||||
|
|
||||||
|
&,
|
||||||
|
html[data-color-scheme=light] & {
|
||||||
|
&.isSilenced {
|
||||||
|
--c: color(from color-mix(in srgb, var(--MI_THEME-panel), blue 50%) srgb r g b / 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.isSuspended {
|
||||||
|
--c: color(from color-mix(in srgb, var(--MI_THEME-panel), black 15%) srgb r g b / 0.25);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-color-scheme=dark] & {
|
||||||
|
&.isSilenced {
|
||||||
|
--c: color(from color-mix(in srgb, var(--MI_THEME-panel), blue 50%) srgb r g b / 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.isSuspended {
|
||||||
|
--c: color(from color-mix(in srgb, var(--MI_THEME-panel), white 15%) srgb r g b / 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar {
|
.avatar {
|
||||||
|
|
|
@ -4,13 +4,9 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div :class="[$style.spacer, defaultStore.reactiveState.darkMode.value ? $style.dark : $style.light]"></div>
|
<div :class="$style.spacer"></div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { defaultStore } from '@/store.js';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" module>
|
<style lang="scss" module>
|
||||||
.spacer {
|
.spacer {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
@ -18,15 +14,21 @@ import { defaultStore } from '@/store.js';
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
height: 300px;
|
height: 300px;
|
||||||
background-clip: content-box;
|
background-clip: content-box;
|
||||||
background-size: auto auto;
|
background-image: repeating-linear-gradient(
|
||||||
background-color: rgba(255, 255, 255, 0);
|
135deg,
|
||||||
|
transparent,
|
||||||
|
transparent 10px,
|
||||||
|
var(--c) 6px,
|
||||||
|
var(--c) 16px
|
||||||
|
);
|
||||||
|
|
||||||
&.light {
|
&,
|
||||||
background-image: repeating-linear-gradient(135deg, transparent, transparent 16px, #00000010 16px, #00000010 20px );
|
html[data-color-scheme=light] & {
|
||||||
|
--c: rgb(0 0 0 / 0.02);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.dark {
|
html[data-color-scheme=dark] & {
|
||||||
background-image: repeating-linear-gradient(135deg, transparent, transparent 16px, #FFFFFF16 16px, #FFFFFF16 20px );
|
--c: rgb(255 255 255 / 0.02);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-if="show" ref="el" :class="[$style.root]" :style="{ background: bg }">
|
<div v-if="show" ref="el" :class="[$style.root]">
|
||||||
<div :class="[$style.upper, { [$style.slim]: narrow, [$style.thin]: thin_ }]">
|
<div :class="[$style.upper, { [$style.slim]: narrow, [$style.thin]: thin_ }]">
|
||||||
<div v-if="!thin_ && narrow && props.displayMyAvatar && $i" class="_button" :class="$style.buttonsLeft" @click="openAccountMenu">
|
<div v-if="!thin_ && narrow && props.displayMyAvatar && $i" class="_button" :class="$style.buttonsLeft" @click="openAccountMenu">
|
||||||
<MkAvatar :class="$style.avatar" :user="$i"/>
|
<MkAvatar :class="$style.avatar" :user="$i"/>
|
||||||
|
@ -42,13 +42,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, onUnmounted, ref, inject, shallowRef, computed } from 'vue';
|
import { onMounted, onUnmounted, ref, inject, shallowRef, computed } from 'vue';
|
||||||
import tinycolor from 'tinycolor2';
|
|
||||||
import XTabs, { Tab } from './MkPageHeader.tabs.vue';
|
|
||||||
import { scrollToTop } from '@@/js/scroll.js';
|
import { scrollToTop } from '@@/js/scroll.js';
|
||||||
import { globalEvents } from '@/events.js';
|
import XTabs, { Tab } from './MkPageHeader.tabs.vue';
|
||||||
|
import type { PageHeaderItem } from '@/types/page-header.js';
|
||||||
import { injectReactiveMetadata } from '@/scripts/page-metadata.js';
|
import { injectReactiveMetadata } from '@/scripts/page-metadata.js';
|
||||||
import { $i, openAccountMenu as openAccountMenu_ } from '@/account.js';
|
import { $i, openAccountMenu as openAccountMenu_ } from '@/account.js';
|
||||||
import { PageHeaderItem } from '@/types/page-header.js';
|
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
tabs?: Tab[];
|
tabs?: Tab[];
|
||||||
|
@ -70,7 +68,6 @@ const hideTitle = inject('shouldOmitHeaderTitle', false);
|
||||||
const thin_ = props.thin || inject('shouldHeaderThin', false);
|
const thin_ = props.thin || inject('shouldHeaderThin', false);
|
||||||
|
|
||||||
const el = shallowRef<HTMLElement | undefined>(undefined);
|
const el = shallowRef<HTMLElement | undefined>(undefined);
|
||||||
const bg = ref<string | undefined>(undefined);
|
|
||||||
const narrow = ref(false);
|
const narrow = ref(false);
|
||||||
const hasTabs = computed(() => props.tabs.length > 0);
|
const hasTabs = computed(() => props.tabs.length > 0);
|
||||||
const hasActions = computed(() => props.actions && props.actions.length > 0);
|
const hasActions = computed(() => props.actions && props.actions.length > 0);
|
||||||
|
@ -98,19 +95,9 @@ function onTabClick(): void {
|
||||||
top();
|
top();
|
||||||
}
|
}
|
||||||
|
|
||||||
const calcBg = () => {
|
|
||||||
const rawBg = 'var(--MI_THEME-bg)';
|
|
||||||
const tinyBg = tinycolor(rawBg.startsWith('var(') ? getComputedStyle(document.documentElement).getPropertyValue(rawBg.slice(4, -1)) : rawBg);
|
|
||||||
tinyBg.setAlpha(0.85);
|
|
||||||
bg.value = tinyBg.toRgbString();
|
|
||||||
};
|
|
||||||
|
|
||||||
let ro: ResizeObserver | null;
|
let ro: ResizeObserver | null;
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
calcBg();
|
|
||||||
globalEvents.on('themeChanged', calcBg);
|
|
||||||
|
|
||||||
if (el.value && el.value.parentElement) {
|
if (el.value && el.value.parentElement) {
|
||||||
narrow.value = el.value.parentElement.offsetWidth < 500;
|
narrow.value = el.value.parentElement.offsetWidth < 500;
|
||||||
ro = new ResizeObserver((entries, observer) => {
|
ro = new ResizeObserver((entries, observer) => {
|
||||||
|
@ -123,7 +110,6 @@ onMounted(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
globalEvents.off('themeChanged', calcBg);
|
|
||||||
if (ro) ro.disconnect();
|
if (ro) ro.disconnect();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -134,6 +120,7 @@ onUnmounted(() => {
|
||||||
backdrop-filter: var(--MI-blur, blur(15px));
|
backdrop-filter: var(--MI-blur, blur(15px));
|
||||||
border-bottom: solid 0.5px var(--MI_THEME-divider);
|
border-bottom: solid 0.5px var(--MI_THEME-divider);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
background: color(from var(--MI_THEME-bg) srgb r g b / 0.85);
|
||||||
}
|
}
|
||||||
|
|
||||||
.upper,
|
.upper,
|
||||||
|
|
|
@ -34,7 +34,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</MkKeyValue>
|
</MkKeyValue>
|
||||||
</div>
|
</div>
|
||||||
<MkA v-if="file.user" class="user" :to="`/admin/user/${file.user.id}`">
|
<MkA v-if="file.user" class="user" :to="`/admin/user/${file.user.id}`">
|
||||||
<MkUserCardMini :user="file.user"/>
|
<MkUserCardMini :user="file.user" withChart/>
|
||||||
</MkA>
|
</MkA>
|
||||||
<div>
|
<div>
|
||||||
<MkSwitch v-model="isSensitive" @update:modelValue="toggleIsSensitive">{{ i18n.ts.sensitive }}</MkSwitch>
|
<MkSwitch v-model="isSensitive" @update:modelValue="toggleIsSensitive">{{ i18n.ts.sensitive }}</MkSwitch>
|
||||||
|
|
|
@ -8,8 +8,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<Transition :name="defaultStore.state.animation ? '_transition_zoom' : ''" mode="out-in">
|
<Transition :name="defaultStore.state.animation ? '_transition_zoom' : ''" mode="out-in">
|
||||||
<MkLoading v-if="fetching"/>
|
<MkLoading v-if="fetching"/>
|
||||||
<div v-else class="users">
|
<div v-else class="users">
|
||||||
<MkA v-for="(user, i) in newUsers" :key="user.id" :to="`/admin/user/${user.id}`" class="user">
|
<MkA v-for="user in newUsers" :key="user.id" :to="`/admin/user/${user.id}`" class="user">
|
||||||
<MkUserCardMini :user="user"/>
|
<MkUserCardMini :user="user" withChart/>
|
||||||
</MkA>
|
</MkA>
|
||||||
</div>
|
</div>
|
||||||
</Transition>
|
</Transition>
|
||||||
|
|
|
@ -38,7 +38,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<div v-for="item in items" :key="item.user.id" :class="[$style.userItem, { [$style.userItemOpend]: expandedItems.includes(item.id) }]">
|
<div v-for="item in items" :key="item.user.id" :class="[$style.userItem, { [$style.userItemOpend]: expandedItems.includes(item.id) }]">
|
||||||
<div :class="$style.userItemMain">
|
<div :class="$style.userItemMain">
|
||||||
<MkA :class="$style.userItemMainBody" :to="`/admin/user/${item.user.id}`">
|
<MkA :class="$style.userItemMainBody" :to="`/admin/user/${item.user.id}`">
|
||||||
<MkUserCardMini :user="item.user"/>
|
<MkUserCardMini :user="item.user" withChart/>
|
||||||
</MkA>
|
</MkA>
|
||||||
<button class="_button" :class="$style.userToggle" @click="toggleItem(item)"><i :class="$style.chevron" class="ti ti-chevron-down"></i></button>
|
<button class="_button" :class="$style.userToggle" @click="toggleItem(item)"><i :class="$style.chevron" class="ti ti-chevron-down"></i></button>
|
||||||
<button class="_button" :class="$style.unassign" @click="unassign(item.user, $event)"><i class="ti ti-x"></i></button>
|
<button class="_button" :class="$style.unassign" @click="unassign(item.user, $event)"><i class="ti ti-x"></i></button>
|
||||||
|
|
|
@ -46,7 +46,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<MkPagination v-slot="{items}" ref="paginationComponent" :pagination="pagination">
|
<MkPagination v-slot="{items}" ref="paginationComponent" :pagination="pagination">
|
||||||
<div :class="$style.users">
|
<div :class="$style.users">
|
||||||
<MkA v-for="user in items" :key="user.id" v-tooltip.mfm="`Last posted: ${dateString(user.updatedAt)}`" :class="$style.user" :to="`/admin/user/${user.id}`">
|
<MkA v-for="user in items" :key="user.id" v-tooltip.mfm="`Last posted: ${dateString(user.updatedAt)}`" :class="$style.user" :to="`/admin/user/${user.id}`">
|
||||||
<MkUserCardMini :user="user"/>
|
<MkUserCardMini :user="user" withChart/>
|
||||||
</MkA>
|
</MkA>
|
||||||
</div>
|
</div>
|
||||||
</MkPagination>
|
</MkPagination>
|
||||||
|
|
|
@ -119,7 +119,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<div v-else-if="tab === 'users'" key="users" class="_gaps_m">
|
<div v-else-if="tab === 'users'" key="users" class="_gaps_m">
|
||||||
<MkPagination v-slot="{items}" :pagination="usersPagination" style="display: grid; grid-template-columns: repeat(auto-fill,minmax(270px,1fr)); grid-gap: 12px;">
|
<MkPagination v-slot="{items}" :pagination="usersPagination" style="display: grid; grid-template-columns: repeat(auto-fill,minmax(270px,1fr)); grid-gap: 12px;">
|
||||||
<MkA v-for="user in items" :key="user.id" v-tooltip.mfm="`Last posted: ${dateString(user.updatedAt)}`" class="user" :to="`/admin/user/${user.id}`">
|
<MkA v-for="user in items" :key="user.id" v-tooltip.mfm="`Last posted: ${dateString(user.updatedAt)}`" class="user" :to="`/admin/user/${user.id}`">
|
||||||
<MkUserCardMini :user="user"/>
|
<MkUserCardMini :user="user" withChart/>
|
||||||
</MkA>
|
</MkA>
|
||||||
</MkPagination>
|
</MkPagination>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -21,7 +21,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<div class="_gaps_s">
|
<div class="_gaps_s">
|
||||||
<div v-for="user in users" :key="user.id" :class="$style.userItem">
|
<div v-for="user in users" :key="user.id" :class="$style.userItem">
|
||||||
<MkA :class="$style.userItemBody" :to="`${userPage(user)}`">
|
<MkA :class="$style.userItemBody" :to="`${userPage(user)}`">
|
||||||
<MkUserCardMini :user="user"/>
|
<MkUserCardMini :user="user" withChart/>
|
||||||
</MkA>
|
</MkA>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -36,7 +36,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<div v-for="item in items" :key="item.id">
|
<div v-for="item in items" :key="item.id">
|
||||||
<div :class="$style.userItem">
|
<div :class="$style.userItem">
|
||||||
<MkA :class="$style.userItemBody" :to="`${userPage(item.user)}`">
|
<MkA :class="$style.userItemBody" :to="`${userPage(item.user)}`">
|
||||||
<MkUserCardMini :user="item.user"/>
|
<MkUserCardMini :user="item.user" withChart/>
|
||||||
</MkA>
|
</MkA>
|
||||||
<button class="_button" :class="$style.menu" @click="showMembershipMenu(item, $event)"><i class="ti ti-dots"></i></button>
|
<button class="_button" :class="$style.menu" @click="showMembershipMenu(item, $event)"><i class="ti ti-dots"></i></button>
|
||||||
<button class="_button" :class="$style.remove" @click="removeUser(item, $event)"><i class="ti ti-x"></i></button>
|
<button class="_button" :class="$style.remove" @click="removeUser(item, $event)"><i class="ti ti-x"></i></button>
|
||||||
|
|
|
@ -29,7 +29,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<div class="_gaps">
|
<div class="_gaps">
|
||||||
<div :class="$style.userItem">
|
<div :class="$style.userItem">
|
||||||
<MkUserCardMini v-if="user" :class="$style.userCard" :user="user" :withChart="false"/>
|
<MkUserCardMini v-if="user" :class="$style.userCard" :user="user"/>
|
||||||
<MkButton v-if="user == null && $i != null" transparent :class="$style.addMeButton" @click="selectSelf"><div :class="$style.addUserButtonInner"><span><i class="ti ti-plus"></i><i class="ti ti-user"></i></span><span>{{ i18n.ts.selectSelf }}</span></div></MkButton>
|
<MkButton v-if="user == null && $i != null" transparent :class="$style.addMeButton" @click="selectSelf"><div :class="$style.addUserButtonInner"><span><i class="ti ti-plus"></i><i class="ti ti-user"></i></span><span>{{ i18n.ts.selectSelf }}</span></div></MkButton>
|
||||||
<MkButton v-if="user == null" transparent :class="$style.addUserButton" @click="selectUser"><div :class="$style.addUserButtonInner"><i class="ti ti-plus"></i><span>{{ i18n.ts.selectUser }}</span></div></MkButton>
|
<MkButton v-if="user == null" transparent :class="$style.addUserButton" @click="selectUser"><div :class="$style.addUserButtonInner"><i class="ti ti-plus"></i><span>{{ i18n.ts.selectUser }}</span></div></MkButton>
|
||||||
<button class="_button" :class="$style.remove" :disabled="user == null" @click="removeUser"><i class="ti ti-x"></i></button>
|
<button class="_button" :class="$style.remove" :disabled="user == null" @click="removeUser"><i class="ti ti-x"></i></button>
|
||||||
|
|
|
@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<MkButton @click="init"><i class="ti ti-refresh"></i> {{ i18n.ts.reloadAccountsList }}</MkButton>
|
<MkButton @click="init"><i class="ti ti-refresh"></i> {{ i18n.ts.reloadAccountsList }}</MkButton>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<MkUserCardMini v-for="user in accounts" :key="user.id" :user="user" :class="$style.user" @click.prevent="menu(user, $event)"/>
|
<MkUserCardMini v-for="user in accounts" :key="user.id" :user="user" withChart :class="$style.user" @click.prevent="menu(user, $event)"/>
|
||||||
</div>
|
</div>
|
||||||
</FormSuspense>
|
</FormSuspense>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -444,14 +444,17 @@ rt {
|
||||||
box-shadow: 0 6px 16px #0007, 0 0 1px 1px #693410, inset 0 0 2px 1px #ce8a5c;
|
box-shadow: 0 6px 16px #0007, 0 0 1px 1px #693410, inset 0 0 2px 1px #ce8a5c;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
|
|
||||||
--MI_THEME-bg: #F1E8DC;
|
&,
|
||||||
--MI_THEME-fg: #693410;
|
html[data-color-scheme=light] & {
|
||||||
}
|
--bg: #F1E8DC;
|
||||||
|
--fg: #693410;
|
||||||
|
}
|
||||||
|
|
||||||
html[data-color-scheme=dark] ._woodenFrame {
|
html[data-color-scheme=dark] & {
|
||||||
--MI_THEME-bg: #1d0c02;
|
--bg: #1d0c02;
|
||||||
--MI_THEME-fg: #F1E8DC;
|
--fg: #F1E8DC;
|
||||||
--MI_THEME-panel: #192320;
|
--panel: #192320;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
._woodenFrameH {
|
._woodenFrameH {
|
||||||
|
|
Loading…
Reference in New Issue