enh(frontend): 斜線デザインの調整, Mk.*CardMiniの改修 (taiyme#289)

This commit is contained in:
taiyme 2024-11-02 20:39:51 +09:00 committed by kakkokari-gtyih
parent 224bbd486f
commit f90ed6d3ba
14 changed files with 205 additions and 126 deletions

View File

@ -4,77 +4,147 @@ 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', {
host,
limit: 16 + 1,
span: 'day',
}).then(res => {
// //
res.requests.received.splice(0, 1); res.requests.received.shift();
chartValues.value = res.requests.received; 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) { &,
html[data-color-scheme=light] & {
&.isNotResponding {
--c: color(from color-mix(in srgb, var(--MI_THEME-panel), orange 50%) srgb r g b / 0.25);
}
&.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);
}
&.isBlocked {
--c: color(from color-mix(in srgb, var(--MI_THEME-panel), red 50%) srgb r g b / 0.25);
}
}
html[data-color-scheme=dark] & {
&.isNotResponding {
--c: color(from color-mix(in srgb, var(--MI_THEME-panel), orange 50%) srgb r g b / 0.5);
}
&.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);
}
&.isBlocked {
--c: color(from color-mix(in srgb, var(--MI_THEME-panel), red 50%) srgb r g b / 0.5);
}
}
}
.icon {
display: block; display: block;
width: ($bodyTitleHieght + $bodyInfoHieght); width: ($bodyTitleHieght + $bodyInfoHieght);
height: ($bodyTitleHieght + $bodyInfoHieght); height: ($bodyTitleHieght + $bodyInfoHieght);
object-fit: cover; object-fit: cover;
border-radius: 4px; border-radius: 4px;
margin-right: 10px; margin-right: 12px;
} }
> :global(.body) { .body {
flex: 1; flex: 1;
overflow: hidden; overflow: hidden;
font-size: 0.9em; font-size: 0.9em;
color: var(--MI_THEME-fg); color: var(--fg);
padding-right: 8px; padding-right: 8px;
}
> :global(.host) { .host {
display: block; display: block;
width: 100%; width: 100%;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
line-height: $bodyTitleHieght; line-height: $bodyTitleHieght;
} }
> :global(.sub) { .sub {
display: block; display: block;
width: 100%; width: 100%;
font-size: 80%; font-size: 80%;
@ -83,35 +153,9 @@ function getInstanceIcon(instance): string {
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
}
> :global(.chart) { .chart {
height: 30px; height: 30px;
}
&:global(.blue) {
--c: rgba(0, 42, 255, 0.15);
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) {
--c: rgb(255 196 0 / 15%);
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) {
--c: rgb(255 0 0 / 15%);
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;
}
} }
</style> </style>

View File

@ -166,7 +166,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>
@ -183,7 +183,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>

View File

@ -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 {

View File

@ -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>

View File

@ -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,

View File

@ -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>

View File

@ -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>

View File

@ -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>
@ -49,7 +49,6 @@ SPDX-License-Identifier: AGPL-3.0-only
<div v-else>Period: {{ i18n.ts.indefinitely }}</div> <div v-else>Period: {{ i18n.ts.indefinitely }}</div>
</div> </div>
</div> </div>
</div>
</template> </template>
</MkPagination> </MkPagination>
</div> </div>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>