ae5d052274
to keep things manageable i merged a lot of one off values into just a handful of common sizes, so some parts of the ui will look different than upstream even with the "Misskey" rounding mode
101 lines
2.5 KiB
Vue
101 lines
2.5 KiB
Vue
<!--
|
|
SPDX-FileCopyrightText: syuilo and other misskey contributors
|
|
SPDX-License-Identifier: AGPL-3.0-only
|
|
-->
|
|
|
|
<template>
|
|
<MkStickyContainer>
|
|
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
|
<MkSpacer :contentMax="700">
|
|
<div class="_gaps">
|
|
<div v-if="items.length === 0" class="empty">
|
|
<div class="_fullinfo">
|
|
<img :src="infoImageUrl" class="_ghost"/>
|
|
<div>{{ i18n.ts.nothing }}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<MkButton primary rounded style="margin: 0 auto;" @click="create"><i class="ph-plus ph-bold ph-lg"></i> {{ i18n.ts.createList }}</MkButton>
|
|
|
|
<div v-if="items.length > 0" class="_gaps">
|
|
<MkA v-for="list in items" :key="list.id" class="_panel" :class="$style.list" :to="`/my/lists/${ list.id }`">
|
|
<div style="margin-bottom: 4px;">{{ list.name }} <span :class="$style.nUsers">({{ i18n.t('nUsers', { n: `${list.userIds.length}/${$i?.policies['userEachUserListsLimit']}` }) }})</span></div>
|
|
<MkAvatars :userIds="list.userIds" :limit="10"/>
|
|
</MkA>
|
|
</div>
|
|
</div>
|
|
</MkSpacer>
|
|
</MkStickyContainer>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { onActivated } from 'vue';
|
|
import MkButton from '@/components/MkButton.vue';
|
|
import MkAvatars from '@/components/MkAvatars.vue';
|
|
import * as os from '@/os.js';
|
|
import { i18n } from '@/i18n.js';
|
|
import { definePageMetadata } from '@/scripts/page-metadata.js';
|
|
import { userListsCache } from '@/cache';
|
|
import { infoImageUrl } from '@/instance.js';
|
|
import { $i } from '@/account.js';
|
|
|
|
const items = $computed(() => userListsCache.value.value ?? []);
|
|
|
|
function fetch() {
|
|
userListsCache.fetch();
|
|
}
|
|
|
|
fetch();
|
|
|
|
async function create() {
|
|
const { canceled, result: name } = await os.inputText({
|
|
title: i18n.ts.enterListName,
|
|
});
|
|
if (canceled) return;
|
|
await os.apiWithDialog('users/lists/create', { name: name });
|
|
userListsCache.delete();
|
|
fetch();
|
|
}
|
|
|
|
const headerActions = $computed(() => [{
|
|
asFullButton: true,
|
|
icon: 'ph-arrows-counter-clockwise ph-bold pg-lg',
|
|
text: i18n.ts.reload,
|
|
handler: () => {
|
|
userListsCache.delete();
|
|
fetch();
|
|
},
|
|
}]);
|
|
|
|
const headerTabs = $computed(() => []);
|
|
|
|
definePageMetadata({
|
|
title: i18n.ts.manageLists,
|
|
icon: 'ph-list ph-bold pg-lg',
|
|
});
|
|
|
|
onActivated(() => {
|
|
fetch();
|
|
});
|
|
</script>
|
|
|
|
<style lang="scss" module>
|
|
.list {
|
|
display: block;
|
|
padding: 16px;
|
|
border: solid 1px var(--divider);
|
|
border-radius: var(--radius-sm);
|
|
margin-bottom: 8px;
|
|
|
|
&:hover {
|
|
border: solid 1px var(--accent);
|
|
text-decoration: none;
|
|
}
|
|
}
|
|
|
|
.nUsers {
|
|
font-size: .9em;
|
|
opacity: .7;
|
|
}
|
|
</style>
|