feat: チャンネルをお気に入りに登録できるように

Resolve #10097
This commit is contained in:
syuilo
2023-03-31 11:30:27 +09:00
parent 5d94062581
commit 3cb0cc7989
17 changed files with 327 additions and 10 deletions

View File

@@ -16,6 +16,9 @@
<Mfm :text="channel.description" :is-note="false" :i="$i"/>
</div>
</div>
<MkButton v-if="favorited" v-tooltip="i18n.ts.unfavorite" as-like class="button" rounded primary @click="unfavorite()"><i class="ti ti-star"></i></MkButton>
<MkButton v-else v-tooltip="i18n.ts.favorite" as-like class="button" rounded @click="favorite()"><i class="ti ti-star"></i></MkButton>
</div>
<div v-if="channel && tab === 'timeline'" class="_gaps">
<!-- スマホタブレットの場合キーボードが表示されると投稿が見づらくなるのでデスクトップ場合のみ自動でフォーカスを当てる -->
@@ -63,6 +66,7 @@ const props = defineProps<{
let tab = $ref('timeline');
let channel = $ref(null);
let favorited = $ref(false);
const featuredPagination = $computed(() => ({
endpoint: 'notes/featured' as const,
limit: 10,
@@ -76,6 +80,7 @@ watch(() => props.channelId, async () => {
channel = await os.api('channels/show', {
channelId: props.channelId,
});
favorited = channel.isFavorited;
}, { immediate: true });
function edit() {
@@ -90,6 +95,27 @@ function openPostForm() {
});
}
function favorite() {
os.apiWithDialog('channels/favorite', {
channelId: channel.id,
}).then(() => {
favorited = true;
});
}
async function unfavorite() {
const confirm = await os.confirm({
type: 'warning',
text: i18n.ts.unfavoriteConfirm,
});
if (confirm.canceled) return;
os.apiWithDialog('channels/unfavorite', {
channelId: channel.id,
}).then(() => {
favorited = false;
});
}
const headerActions = $computed(() => {
if (channel && channel.userId) {
const share = {

View File

@@ -2,17 +2,22 @@
<MkStickyContainer>
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
<MkSpacer :content-max="700">
<div v-if="tab === 'featured'" class="grwlizim featured">
<div v-if="tab === 'featured'">
<MkPagination v-slot="{items}" :pagination="featuredPagination">
<MkChannelPreview v-for="channel in items" :key="channel.id" class="_margin" :channel="channel"/>
</MkPagination>
</div>
<div v-else-if="tab === 'following'" class="grwlizim following">
<div v-else-if="tab === 'favorites'">
<MkPagination v-slot="{items}" :pagination="favoritesPagination">
<MkChannelPreview v-for="channel in items" :key="channel.id" class="_margin" :channel="channel"/>
</MkPagination>
</div>
<div v-else-if="tab === 'following'">
<MkPagination v-slot="{items}" :pagination="followingPagination">
<MkChannelPreview v-for="channel in items" :key="channel.id" class="_margin" :channel="channel"/>
</MkPagination>
</div>
<div v-else-if="tab === 'owned'" class="grwlizim owned">
<div v-else-if="tab === 'owned'">
<MkButton class="new" @click="create()"><i class="ti ti-plus"></i></MkButton>
<MkPagination v-slot="{items}" :pagination="ownedPagination">
<MkChannelPreview v-for="channel in items" :key="channel.id" class="_margin" :channel="channel"/>
@@ -39,13 +44,17 @@ const featuredPagination = {
endpoint: 'channels/featured' as const,
noPaging: true,
};
const favoritesPagination = {
endpoint: 'channels/my-favorites' as const,
limit: 100,
};
const followingPagination = {
endpoint: 'channels/followed' as const,
limit: 5,
limit: 10,
};
const ownedPagination = {
endpoint: 'channels/owned' as const,
limit: 5,
limit: 10,
};
function create() {
@@ -62,10 +71,14 @@ const headerTabs = $computed(() => [{
key: 'featured',
title: i18n.ts._channel.featured,
icon: 'ti ti-comet',
}, {
key: 'favorites',
title: i18n.ts.favorites,
icon: 'ti ti-star',
}, {
key: 'following',
title: i18n.ts._channel.following,
icon: 'ti ti-heart',
icon: 'ti ti-eye',
}, {
key: 'owned',
title: i18n.ts._channel.owned,

View File

@@ -83,7 +83,7 @@ async function chooseAntenna(ev: MouseEvent): Promise<void> {
}
async function chooseChannel(ev: MouseEvent): Promise<void> {
const channels = await os.api('channels/followed', {
const channels = await os.api('channels/my-favorites', {
limit: 100,
});
const items = channels.map(channel => ({