forked from mirror/misskey
feat: リストをピン留めできるように
This commit is contained in:
parent
184890154f
commit
8bfc9f1165
@ -1,33 +1,29 @@
|
||||
<!--
|
||||
SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="_gaps_m">
|
||||
<FormSlot>
|
||||
<template #label>{{ i18n.ts.timelineHeader }}</template>
|
||||
<MkContainer :showHeader="false">
|
||||
<Sortable
|
||||
v-model="items"
|
||||
itemKey="id"
|
||||
:animation="150"
|
||||
:handle="'.' + $style.itemHandle"
|
||||
@start="e => e.item.classList.add('active')"
|
||||
@end="e => e.item.classList.remove('active')"
|
||||
>
|
||||
<template #item="{element,index}">
|
||||
<div
|
||||
v-if="element.type === '-' || timelineHeaderItemDef[element.type]"
|
||||
:class="$style.item"
|
||||
>
|
||||
<button class="_button" :class="$style.itemHandle"><i class="ti ti-menu"></i></button>
|
||||
|
||||
<i class="ti-fw" :class="[$style.itemIcon, timelineHeaderItemDef[element.type]?.icon]"></i><span :class="$style.itemText">{{ timelineHeaderItemDef[element.type]?.title }}</span>
|
||||
<button class="_button" :class="$style.itemRemove" @click="removeItem(index)"><i class="ti ti-x"></i></button>
|
||||
</div>
|
||||
</template>
|
||||
</Sortable>
|
||||
<div style="overflow-x: auto;">
|
||||
<Sortable
|
||||
v-model="items"
|
||||
itemKey="id"
|
||||
:class="$style.container"
|
||||
:animation="150"
|
||||
:handle="'.' + $style.itemHandle"
|
||||
@start="e => e.item.classList.add('active')"
|
||||
@end="e => e.item.classList.remove('active')"
|
||||
>
|
||||
<template #item="{element,index}">
|
||||
<div
|
||||
:class="$style.item"
|
||||
>
|
||||
<button class="_button" :class="$style.itemHandle"><i class="ti ti-menu"></i></button>
|
||||
<i class="ti-fw" :class="[$style.itemIcon, timelineHeaderItemDef[element.type]?.icon]"></i><span :class="$style.itemText">{{ timelineHeaderItemDef[element.type]?.title }}</span>
|
||||
<button class="_button" :class="$style.itemRemove" @click="removeItem(index)"><i class="ti ti-x"></i></button>
|
||||
</div>
|
||||
</template>
|
||||
</Sortable>
|
||||
</div>
|
||||
</MkContainer>
|
||||
</FormSlot>
|
||||
<div class="_buttons">
|
||||
@ -116,6 +112,7 @@ definePageMetadata(() => ({
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
color: var(--navFg);
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
.itemIcon {
|
||||
@ -146,4 +143,8 @@ definePageMetadata(() => ({
|
||||
margin: 0 8px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.container{
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
||||
|
@ -5,12 +5,9 @@
|
||||
|
||||
import { reactive } from 'vue';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { antennasCache, favoritedChannelsCache, userListsCache } from '@/cache.js';
|
||||
import { MenuItem } from '@/types/menu.js';
|
||||
import * as os from '@/os.js';
|
||||
import { miLocalStorage } from '@/local-storage.js';
|
||||
import { userListsCache } from '@/cache.js';
|
||||
import { isLocalTimelineAvailable, isGlobalTimelineAvailable } from '@/store.js';
|
||||
|
||||
const lists = await userListsCache.fetch();
|
||||
export const timelineHeaderItemDef = reactive({
|
||||
home: {
|
||||
title: i18n.ts._timelines.home,
|
||||
@ -19,7 +16,6 @@ export const timelineHeaderItemDef = reactive({
|
||||
},
|
||||
...(isLocalTimelineAvailable ? {
|
||||
local: {
|
||||
key: 'local',
|
||||
title: i18n.ts._timelines.local,
|
||||
icon: 'ti ti-planet',
|
||||
iconOnly: true,
|
||||
@ -30,7 +26,6 @@ export const timelineHeaderItemDef = reactive({
|
||||
iconOnly: true,
|
||||
} } : {}),
|
||||
...(isGlobalTimelineAvailable ? { global: {
|
||||
key: 'global',
|
||||
title: i18n.ts._timelines.global,
|
||||
icon: 'ti ti-whirl',
|
||||
iconOnly: true,
|
||||
@ -50,68 +45,12 @@ export const timelineHeaderItemDef = reactive({
|
||||
title: i18n.ts.channel,
|
||||
iconOnly: true,
|
||||
},
|
||||
...lists.reduce((acc, l) => {
|
||||
acc['list:' + l.id] = {
|
||||
title: i18n.ts.lists + ':' + l.name,
|
||||
icon: 'ti ti-star',
|
||||
iconOnly: true,
|
||||
};
|
||||
return acc;
|
||||
}, {}),
|
||||
});
|
||||
|
||||
async function chooseList(ev: MouseEvent): Promise<void> {
|
||||
const lists = await userListsCache.fetch();
|
||||
const items: MenuItem[] = [
|
||||
...lists.map(list => ({
|
||||
type: 'link' as const,
|
||||
text: list.name,
|
||||
to: `/timeline/list/${list.id}`,
|
||||
})),
|
||||
(lists.length === 0 ? undefined : { type: 'divider' }),
|
||||
{
|
||||
type: 'link' as const,
|
||||
icon: 'ti ti-plus',
|
||||
text: i18n.ts.createNew,
|
||||
to: '/my/lists',
|
||||
},
|
||||
];
|
||||
os.popupMenu(items, ev.currentTarget ?? ev.target);
|
||||
}
|
||||
|
||||
async function chooseAntenna(ev: MouseEvent): Promise<void> {
|
||||
const antennas = await antennasCache.fetch();
|
||||
const items: MenuItem[] = [
|
||||
...antennas.map(antenna => ({
|
||||
type: 'link' as const,
|
||||
text: antenna.name,
|
||||
indicate: antenna.hasUnreadNote,
|
||||
to: `/timeline/antenna/${antenna.id}`,
|
||||
})),
|
||||
(antennas.length === 0 ? undefined : { type: 'divider' }),
|
||||
{
|
||||
type: 'link' as const,
|
||||
icon: 'ti ti-plus',
|
||||
text: i18n.ts.createNew,
|
||||
to: '/my/antennas',
|
||||
},
|
||||
];
|
||||
os.popupMenu(items, ev.currentTarget ?? ev.target);
|
||||
}
|
||||
|
||||
async function chooseChannel(ev: MouseEvent): Promise<void> {
|
||||
const channels = await favoritedChannelsCache.fetch();
|
||||
const items: MenuItem[] = [
|
||||
...channels.map(channel => {
|
||||
const lastReadedAt = miLocalStorage.getItemAsJson(`channelLastReadedAt:${channel.id}`) ?? null;
|
||||
const hasUnreadNote = (lastReadedAt && channel.lastNotedAt) ? Date.parse(channel.lastNotedAt) > lastReadedAt : !!(!lastReadedAt && channel.lastNotedAt);
|
||||
|
||||
return {
|
||||
type: 'link' as const,
|
||||
text: channel.name,
|
||||
indicate: hasUnreadNote,
|
||||
to: `/channels/${channel.id}`,
|
||||
};
|
||||
}),
|
||||
(channels.length === 0 ? undefined : { type: 'divider' }),
|
||||
{
|
||||
type: 'link' as const,
|
||||
icon: 'ti ti-plus',
|
||||
text: i18n.ts.createNew,
|
||||
to: '/channels',
|
||||
},
|
||||
];
|
||||
os.popupMenu(items, ev.currentTarget ?? ev.target);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user