feat: メディアを含むすべてのノートを省略して表示ことができる
This commit is contained in:
parent
719d6c9213
commit
d8f3f7e0ff
|
@ -34,6 +34,7 @@ Misskey의 전체 변경 사항을 확인하려면, [CHANGELOG.md#2023xx](CHANGE
|
|||
- Feat: 움직이는 이미지를 표시하는 방법을 세분화
|
||||
- 마우스를 움직이거나 화면을 터치하고 있으면 이미지를 재생
|
||||
- 일정 시간이 경과하면 이미지 재생을 중지
|
||||
- Feat: 미디어가 포함된 모든 노트를 접을 수 있음
|
||||
- Fix: 로그인하지 않은 상태에서 노트 상세 페이지의 노트 작성 폼을 조작할 수 있음
|
||||
|
||||
### Server
|
||||
|
|
|
@ -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
1
locales/index.d.ts
vendored
|
@ -3,6 +3,7 @@
|
|||
// Do not edit this file directly.
|
||||
export interface Locale {
|
||||
"_lang_": string;
|
||||
"allMediaNoteCollapse": string;
|
||||
"showingAnimatedImagesDescription": string;
|
||||
"showFixedPostFormInReplies": string;
|
||||
"showFixedPostFormInRepliesDescription": string;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
_lang_: "日本語"
|
||||
|
||||
allMediaNoteCollapse: "すべてのメディアノートを省略して表示"
|
||||
showingAnimatedImagesDescription: "「インタラクト時に再生」に設定すると、画像の上にマウスを置いたり、画像をタッチすると再生されます。"
|
||||
showFixedPostFormInReplies: "返信に投稿フォームを表示する"
|
||||
showFixedPostFormInRepliesDescription: "デスクトップとタブレット環境でのみ表示されます。"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
_lang_: "한국어"
|
||||
allMediaNoteCollapse: "모든 미디어 노트 간략화하기"
|
||||
showingAnimatedImagesDescription: "'건드리면 움직임'으로 설정하면 이미지 위에 마우스를 올리거나 이미지를 터치하면 움직여요."
|
||||
showFixedPostFormInReplies: "답글에 글 작성란 표시"
|
||||
showFixedPostFormInRepliesDescription: "데스크톱과 태블릿 환경에서만 표시돼요."
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
|
|
|
@ -445,6 +445,10 @@ export const defaultStore = markRaw(new Storage('base', {
|
|||
where: 'device',
|
||||
default: true,
|
||||
},
|
||||
allMediaNoteCollapse: {
|
||||
where: 'device',
|
||||
default: false,
|
||||
},
|
||||
|
||||
// - Settings/Timeline
|
||||
enableHomeTimeline: {
|
||||
|
|
Loading…
Reference in a new issue