@@ -7,6 +7,8 @@
|
||||
<div v-if="clip.description" class="description">
|
||||
<Mfm :text="clip.description" :is-note="false" :i="$i"/>
|
||||
</div>
|
||||
<MkButton v-if="favorited" v-tooltip="i18n.ts.unfavorite" as-like class="button" rounded primary @click="unfavorite()"><i class="ti ti-heart"></i><span v-if="clip.favoritedCount > 0" style="margin-left: 6px;">{{ clip.favoritedCount }}</span></MkButton>
|
||||
<MkButton v-else v-tooltip="i18n.ts.favorite" as-like class="button" rounded @click="favorite()"><i class="ti ti-heart"></i><span v-if="clip.favoritedCount > 0" style="margin-left: 6px;">{{ clip.favoritedCount }}</span></MkButton>
|
||||
<div class="user">
|
||||
<MkAvatar :user="clip.user" class="avatar" indicator link preview/> <MkUserName :user="clip.user" :nowrap="false"/>
|
||||
</div>
|
||||
@@ -27,12 +29,14 @@ import { i18n } from '@/i18n';
|
||||
import * as os from '@/os';
|
||||
import { definePageMetadata } from '@/scripts/page-metadata';
|
||||
import { url } from '@/config';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
|
||||
const props = defineProps<{
|
||||
clipId: string,
|
||||
}>();
|
||||
|
||||
let clip: misskey.entities.Clip = $ref<misskey.entities.Clip>();
|
||||
let favorited = $ref(false);
|
||||
const pagination = {
|
||||
endpoint: 'clips/notes' as const,
|
||||
limit: 10,
|
||||
@@ -47,12 +51,34 @@ watch(() => props.clipId, async () => {
|
||||
clip = await os.api('clips/show', {
|
||||
clipId: props.clipId,
|
||||
});
|
||||
favorited = clip.isFavorited;
|
||||
}, {
|
||||
immediate: true,
|
||||
});
|
||||
|
||||
provide('currentClipPage', $$(clip));
|
||||
|
||||
function favorite() {
|
||||
os.apiWithDialog('clips/favorite', {
|
||||
clipId: props.clipId,
|
||||
}).then(() => {
|
||||
favorited = true;
|
||||
});
|
||||
}
|
||||
|
||||
async function unfavorite() {
|
||||
const confirm = await os.confirm({
|
||||
type: 'warning',
|
||||
text: i18n.ts.unfavoriteConfirm,
|
||||
});
|
||||
if (confirm.canceled) return;
|
||||
os.apiWithDialog('clips/unfavorite', {
|
||||
clipId: props.clipId,
|
||||
}).then(() => {
|
||||
favorited = false;
|
||||
});
|
||||
}
|
||||
|
||||
const headerActions = $computed(() => clip && isOwned ? [{
|
||||
icon: 'ti ti-pencil',
|
||||
text: i18n.ts.edit,
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<MkStickyContainer>
|
||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
|
||||
<MkSpacer :content-max="700">
|
||||
<div class="qtcaoidl">
|
||||
<MkButton primary class="add" @click="create"><i class="ti ti-plus"></i> {{ i18n.ts.add }}</MkButton>
|
||||
<div v-if="tab === 'my'" class="qtcaoidl">
|
||||
<MkButton primary rounded class="add" @click="create"><i class="ti ti-plus"></i> {{ i18n.ts.add }}</MkButton>
|
||||
|
||||
<MkPagination v-slot="{items}" ref="pagingComponent" :pagination="pagination" class="list">
|
||||
<MkA v-for="item in items" :key="item.id" :to="`/clips/${item.id}`" class="item _panel _margin">
|
||||
@@ -12,12 +12,22 @@
|
||||
</MkA>
|
||||
</MkPagination>
|
||||
</div>
|
||||
<div v-else-if="tab === 'favorites'" class="_gaps">
|
||||
<MkA v-for="item in favorites" :key="item.id" :to="`/clips/${item.id}`" :class="$style.clip" class="_panel">
|
||||
<b>{{ item.name }}</b>
|
||||
<div v-if="item.description" :class="$style.clipDescription">{{ item.description }}</div>
|
||||
<div v-if="item.lastClippedAt">{{ i18n.ts.updatedAt }}: <MkTime :time="item.lastClippedAt" mode="detail"/></div>
|
||||
<div :class="$style.clipUser">
|
||||
<MkAvatar :user="item.user" :class="$style.clipUserAvatar" indicator link preview/> <MkUserName :user="item.user" :nowrap="false"/>
|
||||
</div>
|
||||
</MkA>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { } from 'vue';
|
||||
import { watch } from 'vue';
|
||||
import MkPagination from '@/components/MkPagination.vue';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
import * as os from '@/os';
|
||||
@@ -29,8 +39,15 @@ const pagination = {
|
||||
limit: 10,
|
||||
};
|
||||
|
||||
let tab = $ref('my');
|
||||
let favorites = $ref();
|
||||
|
||||
const pagingComponent = $shallowRef<InstanceType<typeof MkPagination>>();
|
||||
|
||||
watch($$(tab), async () => {
|
||||
favorites = await os.api('clips/my-favorites');
|
||||
});
|
||||
|
||||
async function create() {
|
||||
const { canceled, result } = await os.form(i18n.ts.createNewClip, {
|
||||
name: {
|
||||
@@ -66,7 +83,15 @@ function onClipDeleted() {
|
||||
|
||||
const headerActions = $computed(() => []);
|
||||
|
||||
const headerTabs = $computed(() => []);
|
||||
const headerTabs = $computed(() => [{
|
||||
key: 'my',
|
||||
title: i18n.ts.myClips,
|
||||
icon: 'ti ti-paperclip',
|
||||
}, {
|
||||
key: 'favorites',
|
||||
title: i18n.ts.favorites,
|
||||
icon: 'ti ti-heart',
|
||||
}]);
|
||||
|
||||
definePageMetadata({
|
||||
title: i18n.ts.clip,
|
||||
@@ -98,3 +123,24 @@ definePageMetadata({
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" module>
|
||||
.clip {
|
||||
display: block;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.clipDescription {
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.clipUser {
|
||||
padding-top: 16px;
|
||||
border-top: solid 0.5px var(--divider);
|
||||
}
|
||||
|
||||
.clipUserAvatar {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
</style>
|
||||
|
Reference in New Issue
Block a user