mirror of
https://github.com/kokonect-link/cherrypick
synced 2024-11-23 22:56:53 +09:00
feat: 답글로 작성된 노트를 간략화하여 표시할 수 있음 (kokonect-link/cherrypick#495)
- 리액션한 노트는 옵션 활성화 유무와 상관없이 항상 표시됩니다.
This commit is contained in:
parent
0fb27d69d5
commit
42b131c2a2
@ -32,6 +32,8 @@ Misskey의 전체 변경 사항을 확인하려면, [CHANGELOG.md#2024xx](CHANGE
|
||||
- Feat: 위젯 영역을 숨길 수 있음
|
||||
- Feat: '내용 숨기기'로 설정한 내용을 항상 보이기 (kokonect-link/cherrypick#495)
|
||||
- Feat: 내용이 긴 노트의 간략화 여부를 선택할 수 있음 (kokonect-link/cherrypick#495)
|
||||
- Feat: 답글로 작성된 노트를 간략화하여 표시할 수 있음 (kokonect-link/cherrypick#495)
|
||||
- 리액션한 노트는 옵션 활성화 유무와 상관없이 항상 표시됩니다.
|
||||
- Enhance: CherryPick 업데이트 페이지를 제어판 목록에 추가함
|
||||
- Enhance: Webhook 추가 버튼을 헤더로 이동해 디자인 개선
|
||||
- Enhance: 노트 번역 영역에서도 이모지를 눌러 이모지 메뉴를 열 수 있음
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
_lang_: "English"
|
||||
collapseReplies: "Collapse notes written in reply"
|
||||
collapseRepliesDescription: "Collapse and displays notes written as replies.\nReacted notes are not affected."
|
||||
repliedBy: "Replied by {user}"
|
||||
collapseLongNoteContent: "Collapse long notes"
|
||||
alwaysShowCw: "Always show content set to 'Hide content'"
|
||||
forceRenoteVisibilitySelector: "Specify visibility of renote"
|
||||
|
13
locales/index.d.ts
vendored
13
locales/index.d.ts
vendored
@ -13,6 +13,19 @@ export interface Locale extends ILocale {
|
||||
* 日本語
|
||||
*/
|
||||
"_lang_": string;
|
||||
/**
|
||||
* 返信のリノートのスマート省略
|
||||
*/
|
||||
"collapseReplies": string;
|
||||
/**
|
||||
* 返信で作成されたノートをたたんで表示します。
|
||||
* リアクションしたノートは影響を受けません。
|
||||
*/
|
||||
"collapseRepliesDescription": string;
|
||||
/**
|
||||
* {user}が返信を作成しました
|
||||
*/
|
||||
"repliedBy": ParameterizedString<"user">;
|
||||
/**
|
||||
* 内容の長いノートを省略して表示
|
||||
*/
|
||||
|
@ -1,5 +1,8 @@
|
||||
_lang_: "日本語"
|
||||
|
||||
collapseReplies: "返信のリノートのスマート省略"
|
||||
collapseRepliesDescription: "返信で作成されたノートをたたんで表示します。\nリアクションしたノートは影響を受けません。"
|
||||
repliedBy: "{user}が返信を作成しました"
|
||||
collapseLongNoteContent: "内容の長いノートを省略して表示"
|
||||
alwaysShowCw: "「内容を隠す」で設定した内容を常に表示する"
|
||||
forceRenoteVisibilitySelector: "リノートの公開範囲を指定"
|
||||
|
@ -1,5 +1,8 @@
|
||||
---
|
||||
_lang_: "한국어"
|
||||
collapseReplies: "답글로 작성된 노트 간략화하기"
|
||||
collapseRepliesDescription: "답글로 작성된 노트를 접어서 표시해요.\n리액션한 노트는 영향을 받지 않아요."
|
||||
repliedBy: "{user}님이 답글을 작성했어요"
|
||||
collapseLongNoteContent: "내용이 긴 노트 간략화하기"
|
||||
alwaysShowCw: "'내용 가리기'로 설정한 내용을 항상 보이기"
|
||||
forceRenoteVisibilitySelector: "리노트 공개 범위 지정"
|
||||
|
@ -16,11 +16,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<div v-if="pinned" :class="$style.tip"><i class="ti ti-pin"></i> {{ i18n.ts.pinnedNote }}</div>
|
||||
<!--<div v-if="appearNote._prId_" class="tip"><i class="ti ti-speakerphone"></i> {{ i18n.ts.promotion }}<button class="_textButton hide" @click="readPromo()">{{ i18n.ts.hideThisNote }} <i class="ti ti-x"></i></button></div>-->
|
||||
<!--<div v-if="appearNote._featuredId_" class="tip"><i class="ti ti-bolt"></i> {{ i18n.ts.featured }}</div>-->
|
||||
<div v-if="isRenote" :class="$style.renote">
|
||||
<div v-if="isRenote || (appearNote.reply && defaultStore.state.collapseReplies)" :class="$style.renote">
|
||||
<div v-if="note.channel" :class="$style.colorBar" :style="{ background: note.channel.color }"></div>
|
||||
<MkAvatar v-if="!defaultStore.state.hideAvatarsInNote" :class="$style.renoteAvatar" :user="note.user" link preview/>
|
||||
<i class="ti ti-repeat" style="margin-right: 4px;"></i>
|
||||
<I18n :src="i18n.ts.renotedBy" tag="span" :class="$style.renoteText">
|
||||
<i :class="isRenote ? 'ti ti-repeat' : appearNote.reply ? 'ti ti-arrow-back-up' : ''" style="margin-right: 4px;"></i>
|
||||
<I18n :src="isRenote ? i18n.ts.renotedBy : appearNote.reply ? i18n.ts.repliedBy : ''" tag="span" :class="$style.renoteText">
|
||||
<template #user>
|
||||
<MkA v-user-preview="note.userId" :class="$style.renoteUserName" :to="userPage(note.user)">
|
||||
<MkUserName :user="note.user"/>
|
||||
@ -51,13 +51,13 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<MkNoteSub v-if="appearNote.reply && !renoteCollapsed && notification && defaultStore.state.showReplyInNotification" :note="appearNote.reply" :class="$style.replyTo"/>
|
||||
<MkNoteSub v-else-if="appearNote.reply && !renoteCollapsed && !notification" :note="appearNote.reply" :class="$style.replyTo"/>
|
||||
<div v-if="renoteCollapsed" :class="$style.collapsedRenoteTarget">
|
||||
<MkNoteSub v-if="appearNote.reply && !renoteCollapsed && !replyCollapsed && notification && defaultStore.state.showReplyInNotification" :note="appearNote.reply" :class="$style.replyTo"/>
|
||||
<MkNoteSub v-else-if="appearNote.reply && !renoteCollapsed && !replyCollapsed && !notification" :note="appearNote.reply" :class="$style.replyTo"/>
|
||||
<div v-if="renoteCollapsed || replyCollapsed" :class="$style.collapsedRenoteTarget">
|
||||
<MkAvatar v-if="!defaultStore.state.hideAvatarsInNote" :class="$style.collapsedRenoteTargetAvatar" :user="appearNote.user" link preview/>
|
||||
<Mfm :text="getNoteSummary(appearNote)" :plain="true" :nowrap="true" :author="appearNote.user" :nyaize="'respect'" :class="$style.collapsedRenoteTargetText" @click="renoteCollapsed = false"/>
|
||||
<Mfm :text="getNoteSummary(appearNote)" :plain="true" :nowrap="true" :author="appearNote.user" :nyaize="'respect'" :class="$style.collapsedRenoteTargetText" @click="renoteCollapsed ? renoteCollapsed = false : replyCollapsed ? replyCollapsed = false : ''"/>
|
||||
</div>
|
||||
<article v-else :class="$style.article" :style="{ cursor: expandOnNoteClick ? 'pointer' : '', paddingTop: defaultStore.state.showSubNoteFooterButton && appearNote.reply && !renoteCollapsed ? '14px' : '' }" @click.stop="noteClick" @dblclick.stop="noteDblClick" @contextmenu.stop="onContextmenu">
|
||||
<article v-else :class="$style.article" :style="{ cursor: expandOnNoteClick ? 'pointer' : '', paddingTop: defaultStore.state.showSubNoteFooterButton && appearNote.reply && (!renoteCollapsed && !replyCollapsed) ? '14px' : '' }" @click.stop="noteClick" @dblclick.stop="noteDblClick" @contextmenu.stop="onContextmenu">
|
||||
<div style="display: flex; padding-bottom: 10px;">
|
||||
<div v-if="appearNote.channel" :class="$style.colorBar" :style="{ background: appearNote.channel.color }"></div>
|
||||
<MkAvatar v-if="!defaultStore.state.hideAvatarsInNote" :class="[$style.avatar, { [$style.avatarReplyTo]: appearNote.reply, [$style.showEl]: !appearNote.reply && (showEl && ['hideHeaderOnly', 'hideHeaderFloatBtn', 'hide'].includes(<string>defaultStore.state.displayHeaderNavBarWhenScroll)) && mainRouter.currentRoute.value.name === 'index', [$style.showElTab]: !appearNote.reply && (showEl && ['hideHeaderOnly', 'hideHeaderFloatBtn', 'hide'].includes(<string>defaultStore.state.displayHeaderNavBarWhenScroll)) && mainRouter.currentRoute.value.name !== 'index' }]" :user="appearNote.user" :link="!mock" :preview="!mock" noteClick/>
|
||||
@ -352,6 +352,9 @@ const renoteCollapsed = ref(
|
||||
(appearNote.value.myReaction != null)
|
||||
),
|
||||
);
|
||||
const replyCollapsed = ref(
|
||||
defaultStore.state.collapseReplies && appearNote.value.reply && appearNote.value.myReaction == null,
|
||||
);
|
||||
|
||||
const pleaseLoginContext = computed<OpenOnRemoteOptions>(() => ({
|
||||
type: 'lookup',
|
||||
@ -384,32 +387,40 @@ function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string
|
||||
const keymap = {
|
||||
'r': () => {
|
||||
if (renoteCollapsed.value) return;
|
||||
if (replyCollapsed.value) return;
|
||||
reply();
|
||||
},
|
||||
'e|a|plus': () => {
|
||||
if (renoteCollapsed.value) return;
|
||||
if (replyCollapsed.value) return;
|
||||
react();
|
||||
},
|
||||
'q': () => {
|
||||
if (renoteCollapsed.value) return;
|
||||
if (replyCollapsed.value) return;
|
||||
renote();
|
||||
},
|
||||
'm': () => {
|
||||
if (renoteCollapsed.value) return;
|
||||
if (replyCollapsed.value) return;
|
||||
showMenu();
|
||||
},
|
||||
'c': () => {
|
||||
if (renoteCollapsed.value) return;
|
||||
if (replyCollapsed.value) return;
|
||||
if (!defaultStore.state.showClipButtonInNoteFooter) return;
|
||||
clip();
|
||||
},
|
||||
'o': () => {
|
||||
if (renoteCollapsed.value) return;
|
||||
if (replyCollapsed.value) return;
|
||||
galleryEl.value?.openGallery();
|
||||
},
|
||||
'v|enter': () => {
|
||||
if (renoteCollapsed.value) {
|
||||
renoteCollapsed.value = false;
|
||||
} else if (replyCollapsed.value) {
|
||||
replyCollapsed.value = false;
|
||||
} else if (appearNote.value.cw != null) {
|
||||
showContent.value = !showContent.value;
|
||||
} else if (isLong || isMFM) {
|
||||
|
@ -49,7 +49,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</div>
|
||||
<template v-if="appearNote.reply && appearNote.reply.replyId"><MkNoteSub v-for="note in conversation" :key="note.id" :class="$style.replyToMore" :note="note"/></template>
|
||||
<MkNoteSub v-if="appearNote.reply" :note="appearNote.reply" :class="$style.replyTo"/>
|
||||
<article :class="$style.note" :style="{ paddingTop: defaultStore.state.showSubNoteFooterButton && appearNote.reply && !renoteCollapsed ? '14px' : '' }" @contextmenu.stop="onContextmenu">
|
||||
<article :class="$style.note" :style="{ paddingTop: defaultStore.state.showSubNoteFooterButton && appearNote.reply ? '14px' : '' }" @contextmenu.stop="onContextmenu">
|
||||
<header :class="$style.noteHeader">
|
||||
<MkAvatar v-if="!defaultStore.state.hideAvatarsInNote" :class="$style.noteHeaderAvatar" :user="appearNote.user" indicator link preview/>
|
||||
<div style="display: flex; align-items: center; white-space: nowrap; overflow: hidden;">
|
||||
|
@ -47,6 +47,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<template #label>{{ i18n.ts.collapseRenotes }}</template>
|
||||
<template #caption>{{ i18n.ts.collapseRenotesDescription }}</template>
|
||||
</MkSwitch>
|
||||
<MkSwitch v-model="collapseReplies">
|
||||
<template #label>{{ i18n.ts.collapseReplies }}</template>
|
||||
<template #caption>{{ i18n.ts.collapseRepliesDescription }}</template>
|
||||
<span class="_beta">CherryPick</span>
|
||||
</MkSwitch>
|
||||
<MkSwitch v-model="collapseLongNoteContent">{{ i18n.ts.collapseLongNoteContent }} <span class="_beta">CherryPick</span></MkSwitch>
|
||||
<MkSwitch v-model="collapseDefault">{{ i18n.ts.collapseDefault }} <span class="_beta">CherryPick</span></MkSwitch>
|
||||
<MkSwitch v-model="showNoteActionsOnlyHover">{{ i18n.ts.showNoteActionsOnlyHover }}</MkSwitch>
|
||||
@ -411,6 +416,7 @@ const showClipButtonInNoteFooter = computed(defaultStore.makeGetterSetter('showC
|
||||
const reactionsDisplaySize = computed(defaultStore.makeGetterSetter('reactionsDisplaySize'));
|
||||
const limitWidthOfReaction = computed(defaultStore.makeGetterSetter('limitWidthOfReaction'));
|
||||
const collapseRenotes = computed(defaultStore.makeGetterSetter('collapseRenotes'));
|
||||
const collapseReplies = computed(defaultStore.makeGetterSetter('collapseReplies'));
|
||||
const reduceAnimation = computed(defaultStore.makeGetterSetter('animation', v => !v, v => !v));
|
||||
const useBlurEffectForModal = computed(defaultStore.makeGetterSetter('useBlurEffectForModal'));
|
||||
const useBlurEffect = computed(defaultStore.makeGetterSetter('useBlurEffect'));
|
||||
@ -552,6 +558,7 @@ watch([
|
||||
|
||||
watch([
|
||||
collapseRenotes,
|
||||
collapseReplies,
|
||||
enableInfiniteScroll,
|
||||
], () => {
|
||||
reloadTimeline();
|
||||
|
@ -125,6 +125,7 @@ const defaultStoreSaveKeys: (keyof typeof defaultStore['state'])[] = [
|
||||
'vibrateSystem',
|
||||
'hideAvatarsInNote',
|
||||
'newNoteReceivedNotificationBehavior',
|
||||
'collapseReplies',
|
||||
'collapseDefault',
|
||||
'requireRefreshBehavior',
|
||||
'bannerDisplay',
|
||||
|
@ -161,9 +161,11 @@ const withSensitive = computed<boolean>({
|
||||
|
||||
const enableWidgetsArea = ref(defaultStore.state.enableWidgetsArea);
|
||||
const friendlyUiEnableNotificationsArea = ref(defaultStore.state.friendlyUiEnableNotificationsArea);
|
||||
const alwaysShowCw = ref(defaultStore.state.alwaysShowCw);
|
||||
const collapseRenotes = ref(defaultStore.state.collapseRenotes);
|
||||
const collapseReplies = ref(defaultStore.state.collapseReplies);
|
||||
const collapseLongNoteContent = ref(defaultStore.state.collapseLongNoteContent);
|
||||
const collapseDefault = ref(defaultStore.state.collapseDefault);
|
||||
const alwaysShowCw = ref(defaultStore.state.alwaysShowCw);
|
||||
|
||||
watch(src, () => {
|
||||
queue.value = 0;
|
||||
@ -185,10 +187,14 @@ watch(friendlyUiEnableNotificationsArea, (x) => {
|
||||
reloadAsk({ reason: i18n.ts.reloadToApplySetting, unison: true });
|
||||
});
|
||||
|
||||
watch(alwaysShowCw, (x) => {
|
||||
defaultStore.set('alwaysShowCw', x);
|
||||
watch(collapseRenotes, (x) => {
|
||||
defaultStore.set('collapseRenotes', x);
|
||||
reloadTimeline();
|
||||
});
|
||||
|
||||
watch(collapseReplies, (x) => {
|
||||
defaultStore.set('collapseReplies', x);
|
||||
reloadTimeline();
|
||||
reloadNotification();
|
||||
});
|
||||
|
||||
watch(collapseLongNoteContent, (x) => {
|
||||
@ -203,6 +209,12 @@ watch(collapseDefault, (x) => {
|
||||
reloadNotification();
|
||||
});
|
||||
|
||||
watch(alwaysShowCw, (x) => {
|
||||
defaultStore.set('alwaysShowCw', x);
|
||||
reloadTimeline();
|
||||
reloadNotification();
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
globalEvents.on('showEl', (showEl_receive) => {
|
||||
showEl.value = showEl_receive;
|
||||
@ -417,6 +429,14 @@ const headerActions = computed(() => {
|
||||
text: i18n.ts.showCatOnly,
|
||||
ref: onlyCats,
|
||||
}, { type: 'divider' }, {
|
||||
type: 'switch',
|
||||
text: i18n.ts.collapseRenotes,
|
||||
ref: collapseRenotes,
|
||||
}, {
|
||||
type: 'switch',
|
||||
text: i18n.ts.collapseReplies,
|
||||
ref: collapseReplies,
|
||||
}, {
|
||||
type: 'switch',
|
||||
text: i18n.ts.collapseLongNoteContent,
|
||||
ref: collapseLongNoteContent,
|
||||
|
@ -530,6 +530,10 @@ export const defaultStore = markRaw(new Storage('base', {
|
||||
|
||||
// #region CherryPick
|
||||
// - Settings/General
|
||||
collapseReplies: {
|
||||
where: 'account',
|
||||
default: false,
|
||||
},
|
||||
newNoteReceivedNotificationBehavior: {
|
||||
where: 'device',
|
||||
default: 'count' as 'default' | 'count' | 'none',
|
||||
|
Loading…
Reference in New Issue
Block a user