feat: メディアを含むすべてのノートを省略して表示ことができる

This commit is contained in:
NoriDev 2023-10-01 16:29:47 +09:00
parent 719d6c9213
commit d8f3f7e0ff
9 changed files with 40 additions and 8 deletions

View file

@ -34,6 +34,7 @@ Misskey의 전체 변경 사항을 확인하려면, [CHANGELOG.md#2023xx](CHANGE
- Feat: 움직이는 이미지를 표시하는 방법을 세분화
- 마우스를 움직이거나 화면을 터치하고 있으면 이미지를 재생
- 일정 시간이 경과하면 이미지 재생을 중지
- Feat: 미디어가 포함된 모든 노트를 접을 수 있음
- Fix: 로그인하지 않은 상태에서 노트 상세 페이지의 노트 작성 폼을 조작할 수 있음
### Server

View file

@ -1,5 +1,6 @@
---
_lang_: "English"
allMediaNoteCollapse: "Collapse all media notes"
showingAnimatedImagesDescription: "When set to \"Animate on interaction\", the image will play when you hover over it or touch it."
showFixedPostFormInReplies: "Show posting form in replies"
showFixedPostFormInRepliesDescription: "Only visible in desktop and tablet environments."

1
locales/index.d.ts vendored
View file

@ -3,6 +3,7 @@
// Do not edit this file directly.
export interface Locale {
"_lang_": string;
"allMediaNoteCollapse": string;
"showingAnimatedImagesDescription": string;
"showFixedPostFormInReplies": string;
"showFixedPostFormInRepliesDescription": string;

View file

@ -1,5 +1,6 @@
_lang_: "日本語"
allMediaNoteCollapse: "すべてのメディアノートを省略して表示"
showingAnimatedImagesDescription: "「インタラクト時に再生」に設定すると、画像の上にマウスを置いたり、画像をタッチすると再生されます。"
showFixedPostFormInReplies: "返信に投稿フォームを表示する"
showFixedPostFormInRepliesDescription: "デスクトップとタブレット環境でのみ表示されます。"

View file

@ -1,5 +1,6 @@
---
_lang_: "한국어"
allMediaNoteCollapse: "모든 미디어 노트 간략화하기"
showingAnimatedImagesDescription: "'건드리면 움직임'으로 설정하면 이미지 위에 마우스를 올리거나 이미지를 터치하면 움직여요."
showFixedPostFormInReplies: "답글에 글 작성란 표시"
showFixedPostFormInRepliesDescription: "데스크톱과 태블릿 환경에서만 표시돼요."

View file

@ -99,10 +99,13 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
<MkPoll v-if="appearNote.poll" :note="appearNote" :class="$style.poll"/>
<MkUrlPreview v-for="url in urls" :key="url" :url="url" :compact="true" :detail="false" :class="$style.urlPreview"/>
<button v-if="(isLong || (isMFM && defaultStore.state.collapseDefault)) && collapsed" v-vibrate="5" :class="$style.collapsed" class="_button" @click="collapsed = false">
<span :class="$style.collapsedLabel">{{ i18n.ts.showMore }}</span>
<button v-if="(isLong || (isMFM && defaultStore.state.collapseDefault) || defaultStore.state.allMediaNoteCollapse) && collapsed" v-vibrate="5" :class="$style.collapsed" class="_button" @click="collapsed = false">
<span :class="$style.collapsedLabel">
{{ i18n.ts.showMore }}
<span v-if="appearNote.files.length > 0" :class="$style.label">({{ collapseLabel }})</span>
</span>
</button>
<button v-else-if="(isLong || (isMFM && defaultStore.state.collapseDefault)) && !collapsed" v-vibrate="5" :class="$style.showLess" class="_button" @click="collapsed = true">
<button v-else-if="(isLong || (isMFM && defaultStore.state.collapseDefault) || defaultStore.state.allMediaNoteCollapse) && !collapsed" v-vibrate="5" :class="$style.showLess" class="_button" @click="collapsed = true">
<span :class="$style.showLessLabel">{{ i18n.ts.showLess }}</span>
</button>
</div>
@ -212,6 +215,7 @@ import { mainRouter } from '@/router.js';
import { notePage } from '@/filters/note.js';
import { miLocalStorage } from '@/local-storage.js';
import { instance } from '@/instance.js';
import { concat } from '@/scripts/array.js';
let showEl = $ref(false);
@ -259,7 +263,7 @@ const showContent = ref(false);
const urls = appearNote.text ? extractUrlFromMfm(mfm.parse(appearNote.text)) : null;
const isLong = shouldCollapsed(appearNote);
const isMFM = shouldMfmCollapsed(appearNote);
const collapsed = ref(appearNote.cw == null && (isLong || (isMFM && defaultStore.state.collapseDefault)));
const collapsed = ref(appearNote.cw == null && (isLong || (isMFM && defaultStore.state.collapseDefault) || defaultStore.state.allMediaNoteCollapse));
const isDeleted = ref(false);
const muted = ref(checkWordMute(appearNote, $i, defaultStore.state.mutedWords));
const translation = ref<any>(null);
@ -267,6 +271,12 @@ const translating = ref(false);
const canRenote = computed(() => ['public', 'home'].includes(appearNote.visibility) || appearNote.userId === $i.id);
let renoteCollapsed = $ref(defaultStore.state.collapseRenotes && isRenote && (($i && ($i.id === note.userId || $i.id === appearNote.userId)) || (appearNote.myReaction != null)));
const collapseLabel = computed(() => {
return concat([
appearNote.files && appearNote.files.length !== 0 ? [i18n.t('_cw.files', { count: appearNote.files.length })] : [],
] as string[][]).join(' / ');
});
const keymap = {
'r': () => reply(true),
'e|a|plus': () => react(true),

View file

@ -37,10 +37,13 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</div>
</div>
<button v-if="(isLong || (isMFM && defaultStore.state.collapseDefault)) && collapsed" v-vibrate="5" :class="$style.fade" class="_button" @click="collapsed = false">
<span :class="$style.fadeLabel">{{ i18n.ts.showMore }}</span>
<button v-if="(isLong || (isMFM && defaultStore.state.collapseDefault) || defaultStore.state.allMediaNoteCollapse) && collapsed" v-vibrate="5" :class="$style.fade" class="_button" @click="collapsed = false">
<span :class="$style.fadeLabel">
{{ i18n.ts.showMore }}
<span v-if="note.files.length > 0" :class="$style.label">({{ collapseLabel }})</span>
</span>
</button>
<button v-else-if="(isLong || (isMFM && defaultStore.state.collapseDefault)) && !collapsed" v-vibrate="5" :class="$style.showLess" class="_button" @click="collapsed = true">
<button v-else-if="(isLong || (isMFM && defaultStore.state.collapseDefault) || defaultStore.state.allMediaNoteCollapse) && !collapsed" v-vibrate="5" :class="$style.showLess" class="_button" @click="collapsed = true">
<span :class="$style.showLessLabel">{{ i18n.ts.showLess }}</span>
</button>
<div v-if="showSubNoteFooterButton">
@ -124,6 +127,7 @@ import { reactionPicker } from '@/scripts/reaction-picker.js';
import { claimAchievement } from '@/scripts/achievements.js';
import { useNoteCapture } from '@/scripts/use-note-capture.js';
import { MenuItem } from '@/types/menu.js';
import { concat } from '@/scripts/array.js';
const el = shallowRef<HTMLElement>();
const menuButton = shallowRef<HTMLElement>();
@ -139,6 +143,12 @@ const showContent = ref(false);
const translation = ref<any>(null);
const translating = ref(false);
const collapseLabel = computed(() => {
return concat([
props.note.files && props.note.files.length !== 0 ? [i18n.t('_cw.files', { count: props.note.files.length })] : [],
] as string[][]).join(' / ');
});
const props = defineProps<{
note: Misskey.entities.Note;
showSubNoteFooterButton: boolean;
@ -149,7 +159,7 @@ let note = $ref(deepClone(props.note));
const isLong = shouldCollapsed(props.note);
const isMFM = shouldMfmCollapsed(props.note);
const collapsed = $ref(isLong || (isMFM && defaultStore.state.collapseDefault));
const collapsed = $ref(isLong || (isMFM && defaultStore.state.collapseDefault) || defaultStore.state.allMediaNoteCollapse);
useNoteCapture({
rootEl: el,

View file

@ -75,6 +75,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSwitch v-model="showReplyInNotification">{{ i18n.ts.showReplyInNotification }} <span class="_beta">CherryPick</span></MkSwitch>
<MkSwitch v-model="renoteQuoteButtonSeparation">{{ i18n.ts.renoteQuoteButtonSeparation }} <span class="_beta">CherryPick</span></MkSwitch>
<MkSwitch v-model="showFixedPostFormInReplies">{{ i18n.ts.showFixedPostFormInReplies }}<template #caption>{{ i18n.ts.showFixedPostFormInRepliesDescription }}</template> <span class="_beta">CherryPick</span></MkSwitch>
<MkSwitch v-model="allMediaNoteCollapse">{{ i18n.ts.allMediaNoteCollapse }} <span class="_beta">CherryPick</span></MkSwitch>
</div>
<MkSelect v-model="instanceTicker">
@ -366,6 +367,7 @@ const showReplyInNotification = computed(defaultStore.makeGetterSetter('showRepl
const renoteQuoteButtonSeparation = computed(defaultStore.makeGetterSetter('renoteQuoteButtonSeparation'));
const showFixedPostFormInReplies = computed(defaultStore.makeGetterSetter('showFixedPostFormInReplies'));
const showingAnimatedImages = computed(defaultStore.makeGetterSetter('showingAnimatedImages'));
const allMediaNoteCollapse = computed(defaultStore.makeGetterSetter('allMediaNoteCollapse'));
watch(lang, () => {
miLocalStorage.setItem('lang', lang.value as string);
@ -423,6 +425,7 @@ watch([
renoteQuoteButtonSeparation,
showFixedPostFormInReplies,
showingAnimatedImages,
allMediaNoteCollapse,
], async () => {
await reloadAsk();
});

View file

@ -445,6 +445,10 @@ export const defaultStore = markRaw(new Storage('base', {
where: 'device',
default: true,
},
allMediaNoteCollapse: {
where: 'device',
default: false,
},
// - Settings/Timeline
enableHomeTimeline: {