note-improvements (#9734)
Not sure if this is the best way to jump to the post This also lets you select text w/out clicking to the post (and clicking normally on top of the text opens the post) Co-authored-by: Freeplay <Freeplay@duck.com> Reviewed-on: https://codeberg.org/calckey/calckey/pulls/9734 Co-authored-by: Free <freeplay@duck.com> Co-committed-by: Free <freeplay@duck.com>
This commit is contained in:
parent
d75a4e56e3
commit
c2df136dda
4 changed files with 48 additions and 15 deletions
|
@ -33,7 +33,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<article class="article" @contextmenu.stop="onContextmenu" @click="router.push(notePage(appearNote))">
|
||||
<article class="article" @contextmenu.stop="onContextmenu" @click="noteClick">
|
||||
<div class="main">
|
||||
<div class="header-container">
|
||||
<MkAvatar class="avatar" :user="appearNote.user"/>
|
||||
|
@ -41,16 +41,16 @@
|
|||
</div>
|
||||
<div class="body">
|
||||
<p v-if="appearNote.cw != null" class="cw">
|
||||
<Mfm v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis" @click.stop/>
|
||||
<Mfm v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :custom-emojis="appearNote.emojis" :i="$i"/>
|
||||
<XCwButton v-model="showContent" :note="appearNote"/>
|
||||
</p>
|
||||
<div v-show="appearNote.cw == null || showContent" class="content" :class="{ collapsed, isLong }">
|
||||
<div class="text">
|
||||
<Mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis" @click.stop/>
|
||||
<Mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis"/>
|
||||
<!-- <a v-if="appearNote.renote != null" class="rp">RN:</a> -->
|
||||
<div v-if="translating || translation" class="translation">
|
||||
<MkLoading v-if="translating" mini/>
|
||||
<div v-else class="translated" @click.stop>
|
||||
<div v-else class="translated">
|
||||
<b>{{ i18n.t('translatedFrom', { x: translation.sourceLang }) }}: </b>
|
||||
<Mfm :text="translation.text" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis"/>
|
||||
</div>
|
||||
|
@ -264,6 +264,14 @@ function focusAfter() {
|
|||
focusNext(el.value);
|
||||
}
|
||||
|
||||
function noteClick(e) {
|
||||
if (document.getSelection().type === 'Range') {
|
||||
e.stopPropagation();
|
||||
} else {
|
||||
router.push(notePage(appearNote))
|
||||
}
|
||||
}
|
||||
|
||||
function readPromo() {
|
||||
os.api('promo/read', {
|
||||
noteId: appearNote.id,
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
:tabindex="!isDeleted ? '-1' : null"
|
||||
:class="{ renote: isRenote }"
|
||||
>
|
||||
<MkNoteSub v-for="note in conversation" :key="note.id" class="reply-to-more" :note="note" @click.self="router.push(notePage(note))"/>
|
||||
<MkNoteSub v-if="appearNote.reply" :note="appearNote.reply" class="reply-to" @click.self="router.push(notePage(appearNote))"/>
|
||||
<MkNoteSub v-for="note in conversation" :key="note.id" class="reply-to-more" :note="note"/>
|
||||
<MkNoteSub v-if="appearNote.reply" :note="appearNote.reply" class="reply-to"/>
|
||||
<div v-if="isRenote" class="renote">
|
||||
<MkAvatar class="avatar" :user="note.user"/>
|
||||
<i class="ph-repeat ph-bold ph-lg"></i>
|
||||
|
@ -29,7 +29,7 @@
|
|||
<MkVisibility :note="note"/>
|
||||
</div>
|
||||
</div>
|
||||
<article class="article" @contextmenu.stop="onContextmenu">
|
||||
<article ref="noteEl" class="article" @contextmenu.stop="onContextmenu" tabindex="-1">
|
||||
<header class="header">
|
||||
<MkAvatar class="avatar" :user="appearNote.user" :show-indicator="true"/>
|
||||
<div class="body">
|
||||
|
@ -99,7 +99,7 @@
|
|||
</footer>
|
||||
</div>
|
||||
</article>
|
||||
<MkNoteSub v-for="note in directReplies" :key="note.id" :note="note" class="reply" :conversation="replies" @click.self="router.push(notePage(note))"/>
|
||||
<MkNoteSub v-for="note in directReplies" :key="note.id" :note="note" class="reply" :conversation="replies"/>
|
||||
</div>
|
||||
<div v-else class="_panel muted" @click="muted = false">
|
||||
<I18n :src="i18n.ts.userSaysSomething" tag="small">
|
||||
|
@ -113,7 +113,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, inject, onMounted, onUnmounted, reactive, ref } from 'vue';
|
||||
import { computed, inject, onMounted, onUnmounted, onUpdated, reactive, ref } from 'vue';
|
||||
import * as mfm from 'mfm-js';
|
||||
import type * as misskey from 'calckey-js';
|
||||
import MkNoteSub from '@/components/MkNoteSub.vue';
|
||||
|
@ -175,6 +175,7 @@ const isRenote = (
|
|||
);
|
||||
|
||||
const el = ref<HTMLElement>();
|
||||
const noteEl = $ref();
|
||||
const menuButton = ref<HTMLElement>();
|
||||
const starButton = ref<InstanceType<typeof XStarButton>>();
|
||||
const renoteButton = ref<InstanceType<typeof XRenoteButton>>();
|
||||
|
@ -192,6 +193,8 @@ const showTicker = (defaultStore.state.instanceTicker === 'always') || (defaultS
|
|||
const conversation = ref<misskey.entities.Note[]>([]);
|
||||
const replies = ref<misskey.entities.Note[]>([]);
|
||||
const directReplies = ref<misskey.entities.Note[]>([]);
|
||||
let isScrolling;
|
||||
|
||||
|
||||
const keymap = {
|
||||
'r': () => reply(true),
|
||||
|
@ -281,11 +284,11 @@ function showRenoteMenu(viaKeyboard = false): void {
|
|||
}
|
||||
|
||||
function focus() {
|
||||
el.value.focus();
|
||||
noteEl.focus();
|
||||
}
|
||||
|
||||
function blur() {
|
||||
el.value.blur();
|
||||
noteEl.blur();
|
||||
}
|
||||
|
||||
os.api('notes/children', {
|
||||
|
@ -302,6 +305,7 @@ if (appearNote.replyId) {
|
|||
noteId: appearNote.replyId,
|
||||
}).then(res => {
|
||||
conversation.value = res.reverse();
|
||||
focus();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -322,13 +326,26 @@ function onNoteReplied(noteData: NoteUpdatedEvent): void {
|
|||
|
||||
}
|
||||
|
||||
document.addEventListener("wheel", () => {
|
||||
isScrolling = true;
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
stream.on("noteUpdated", onNoteReplied);
|
||||
isScrolling = false;
|
||||
noteEl.scrollIntoView();
|
||||
});
|
||||
|
||||
onUpdated(() => {
|
||||
if (!isScrolling) {
|
||||
noteEl.scrollIntoView()
|
||||
}
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
stream.off("noteUpdated", onNoteReplied);
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -434,7 +451,8 @@ onUnmounted(() => {
|
|||
}
|
||||
font-size: 1.2em;
|
||||
overflow: clip;
|
||||
|
||||
outline: none;
|
||||
scroll-margin-top: calc(var(--stickyTop) + 20vh);
|
||||
> .header {
|
||||
display: flex;
|
||||
position: relative;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div v-size="{ max: [450, 500] }" class="wrpstxzv" :class="{ children: depth > 1, singleStart: replies.length == 1, firstColumn: depth == 1 && conversation }">
|
||||
<div v-if="conversation && depth > 1" class="line"></div>
|
||||
<div class="main" @click="router.push(notePage(note))">
|
||||
<div class="main" @click="noteClick">
|
||||
<div class="avatar-container">
|
||||
<MkAvatar class="avatar" :user="note.user"/>
|
||||
<div v-if="(!conversation) || replies.length > 0" class="line"></div>
|
||||
|
@ -19,7 +19,7 @@
|
|||
<Mfm v-if="note.cw != ''" class="text" :text="note.cw" :author="note.user" :i="$i" :custom-emojis="note.emojis"/>
|
||||
<XCwButton v-model="showContent" :note="note"/>
|
||||
</p>
|
||||
<div v-show="note.cw == null || showContent" class="content" @click="router.push(notePage(note))">
|
||||
<div v-show="note.cw == null || showContent" class="content">
|
||||
<MkSubNoteContent class="text" :note="note" :detailed="true" :parentId="note.parentId" :conversation="conversation"/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -68,6 +68,14 @@ const props = withDefaults(defineProps<{
|
|||
|
||||
let showContent = $ref(false);
|
||||
const replies: misskey.entities.Note[] = props.conversation?.filter(item => item.replyId === props.note.id || item.renoteId === props.note.id).reverse() ?? [];
|
||||
|
||||
function noteClick(e) {
|
||||
if (document.getSelection().type === 'Range') {
|
||||
e.stopPropagation();
|
||||
} else {
|
||||
router.push(notePage(props.note))
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -88,7 +88,6 @@ html._themeChanging_ {
|
|||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
a {
|
||||
|
|
Loading…
Reference in a new issue