<!-- SPDX-FileCopyrightText: syuilo and misskey-project SPDX-License-Identifier: AGPL-3.0-only --> <template> <div :class="[$style.root, { [$style.children]: depth > 1 }]"> <div :class="$style.main"> <div v-if="note.channel" :class="$style.colorBar" :style="{ background: note.channel.color }"></div> <EmAvatar :class="$style.avatar" :user="note.user" link preview/> <div :class="$style.body"> <EmNoteHeader :class="$style.header" :note="note" :mini="true"/> <div> <p v-if="note.cw != null" :class="$style.cw"> <EmMfm v-if="note.cw != ''" style="margin-right: 8px;" :text="note.cw" :author="note.user" :nyaize="'respect'"/> <button style="display: block; width: 100%;" class="_buttonGray _buttonRounded" @click="showContent = !showContent">{{ showContent ? i18n.ts._cw.hide : i18n.ts._cw.show }}</button> </p> <div v-show="note.cw == null || showContent"> <EmSubNoteContent :class="$style.text" :note="note"/> </div> </div> </div> </div> <template v-if="depth < 5"> <EmNoteSub v-for="reply in replies" :key="reply.id" :note="reply" :class="$style.reply" :detail="true" :depth="depth + 1"/> </template> <div v-else :class="$style.more"> <EmA class="_link" :to="notePage(note)">{{ i18n.ts.continueThread }} <i class="ti ti-chevron-double-right"></i></EmA> </div> </div> </template> <script lang="ts" setup> import { ref } from 'vue'; import * as Misskey from 'misskey-js'; import EmA from '@/components/EmA.vue'; import EmAvatar from '@/components/EmAvatar.vue'; import EmNoteHeader from '@/components/EmNoteHeader.vue'; import EmSubNoteContent from '@/components/EmSubNoteContent.vue'; import { notePage } from '@/utils.js'; import { misskeyApi } from '@/misskey-api.js'; import { i18n } from '@/i18n.js'; import EmMfm from '@/components/EmMfm.js'; const props = withDefaults(defineProps<{ note: Misskey.entities.Note; detail?: boolean; // how many notes are in between this one and the note being viewed in detail depth?: number; }>(), { depth: 1, }); const showContent = ref(false); const replies = ref<Misskey.entities.Note[]>([]); if (props.detail) { misskeyApi('notes/children', { noteId: props.note.id, limit: 5, }).then(res => { replies.value = res; }); } </script> <style lang="scss" module> .root { padding: 16px 32px; font-size: 0.9em; position: relative; &.children { padding: 10px 0 0 16px; font-size: 1em; } } .main { display: flex; } .colorBar { position: absolute; top: 8px; left: 8px; width: 5px; height: calc(100% - 8px); border-radius: 999px; pointer-events: none; } .avatar { flex-shrink: 0; display: block; margin: 0 8px 0 0; width: 38px; height: 38px; border-radius: 8px; } .body { flex: 1; min-width: 0; } .header { margin-bottom: 2px; } .cw { cursor: default; display: block; margin: 0; padding: 0; overflow-wrap: break-word; } .text { margin: 0; padding: 0; } .reply, .more { border-left: solid 0.5px var(--MI_THEME-divider); margin-top: 10px; } .more { padding: 10px 0 0 16px; } @container (max-width: 450px) { .root { padding: 14px 16px; &.children { padding: 10px 0 0 8px; } } } .muted { text-align: center; padding: 8px !important; border: 1px solid var(--MI_THEME-divider); margin: 8px 8px 0 8px; border-radius: 8px; } </style>