-
({{ i18n.ts.private }})
-
-
-
-
-
-
{{ i18n.tsx.translatedFrom({ x: translation.sourceLang }) }}:
-
+
+
+
+
({{ i18n.ts.private }})
+
+
+
+
+
+ {{ i18n.tsx.translatedFrom({ x: translation.sourceLang }) }}:
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
{{ appearNote.channel.name }}
@@ -196,7 +198,7 @@ import { getNoteSummary } from '@/scripts/get-note-summary.js';
import { MenuItem } from '@/types/menu.js';
import MkRippleEffect from '@/components/MkRippleEffect.vue';
import { showMovedDialog } from '@/scripts/show-moved-dialog.js';
-import { shouldCollapsed } from '@/scripts/collapsed.js';
+import { shouldCollapsedLegacy, shouldCollapsed } from '@/scripts/collapsed.js';
import { isEnabledUrlPreview } from '@/instance.js';
const props = withDefaults(defineProps<{
@@ -260,8 +262,22 @@ const isMyRenote = $i && ($i.id === note.value.userId);
const showContent = ref(false);
const parsed = computed(() => appearNote.value.text ? mfm.parse(appearNote.value.text) : null);
const urls = computed(() => parsed.value ? extractUrlFromMfm(parsed.value).filter((url) => appearNote.value.renote?.url !== url && appearNote.value.renote?.uri !== url) : null);
-const isLong = shouldCollapsed(appearNote.value, parsed.value, urls.value ?? []);
-const collapsed = ref(appearNote.value.cw == null && isLong);
+const collapsibleArea = ref(null);
+const collapseSize = computed(() => ({
+ small: 9,
+ medium: 13.5,
+ large: 18,
+})[defaultStore.state.collapsingNoteSize]);
+const isLong = computed(() => {
+ switch (defaultStore.state.collapsingNoteCondition) {
+ case 'detailedCalculation': return shouldCollapsed(appearNote.value, collapseSize.value, parsed.value, urls.value ?? []);
+ case 'seeRenderedSize': return collapsibleArea.value == null ? false : collapsibleInner.value.clientHeight > collapseSize.value * parseFloat(getComputedStyle(collapsibleInner.value).fontSize);
+ // fail safe
+ case 'legacyCalculation':
+ default: return shouldCollapsedLegacy(appearNote.value, urls.value ?? []);
+ }
+});
+const collapsed = ref(appearNote.value.cw == null && isLong.value);
const isDeleted = ref(false);
const muted = ref(checkMute(appearNote.value, $i?.mutedWords));
const hardMuted = ref(props.withHardMute && checkMute(appearNote.value, $i?.hardMutedWords, true));
@@ -808,7 +824,6 @@ function emitUpdReaction(emoji: string, delta: number) {
.contentCollapsed {
position: relative;
- max-height: 9em;
overflow: clip;
}
diff --git a/packages/frontend/src/pages/settings/general.vue b/packages/frontend/src/pages/settings/general.vue
index cfc63f2a08..69104165cc 100644
--- a/packages/frontend/src/pages/settings/general.vue
+++ b/packages/frontend/src/pages/settings/general.vue
@@ -92,6 +92,18 @@ SPDX-License-Identifier: AGPL-3.0-only
+
+ {{ i18n.ts.collapsingNoteCondition }}
+
+
+
+
+
+ {{ i18n.ts.collapsingNoteSize }}
+
+
+
+
@@ -306,6 +318,8 @@ const useReactionPickerForContextMenu = computed(defaultStore.makeGetterSetter('
const squareAvatars = computed(defaultStore.makeGetterSetter('squareAvatars'));
const showAvatarDecorations = computed(defaultStore.makeGetterSetter('showAvatarDecorations'));
const mediaListWithOneImageAppearance = computed(defaultStore.makeGetterSetter('mediaListWithOneImageAppearance'));
+const collapsingNoteSize = computed(defaultStore.makeGetterSetter('collapsingNoteSize'));
+const collapsingNoteCondition = computed(defaultStore.makeGetterSetter('collapsingNoteCondition'));
const notificationPosition = computed(defaultStore.makeGetterSetter('notificationPosition'));
const notificationStackAxis = computed(defaultStore.makeGetterSetter('notificationStackAxis'));
const keepScreenOn = computed(defaultStore.makeGetterSetter('keepScreenOn'));
diff --git a/packages/frontend/src/pages/settings/preferences-backups.vue b/packages/frontend/src/pages/settings/preferences-backups.vue
index b6f1043154..31e7c189e4 100644
--- a/packages/frontend/src/pages/settings/preferences-backups.vue
+++ b/packages/frontend/src/pages/settings/preferences-backups.vue
@@ -102,6 +102,8 @@ const defaultStoreSaveKeys: (keyof typeof defaultStore['state'])[] = [
'aiChanMode',
'devMode',
'mediaListWithOneImageAppearance',
+ 'collapsingNoteSize',
+ 'collapsingNoteCondition',
'notificationPosition',
'notificationStackAxis',
'enableCondensedLineForAcct',
diff --git a/packages/frontend/src/scripts/collapsed.ts b/packages/frontend/src/scripts/collapsed.ts
index 4724bfee58..47d90465d4 100644
--- a/packages/frontend/src/scripts/collapsed.ts
+++ b/packages/frontend/src/scripts/collapsed.ts
@@ -23,7 +23,7 @@ export function shouldCollapsedLegacy(note: Misskey.entities.Note, urls: string[
return collapsed;
}
-export function shouldCollapsed(note: Misskey.entities.Note, ast?: mfm.MfmNode[] | null, urls?: string[]): boolean {
+export function shouldCollapsed(note: Misskey.entities.Note, limitY: number, ast?: mfm.MfmNode[] | null, urls?: string[]): boolean {
if (note.cw != null) return false;
if (note.text == null) return false;
if (note.files && note.files.length >= 5) return true;
@@ -34,7 +34,7 @@ export function shouldCollapsed(note: Misskey.entities.Note, ast?: mfm.MfmNode[]
// しきい値(X方向の文字数は半角換算)
const limitX = 55;
- const limitY = 13.5;
+ // const limitY = 13.5;
let forceCollapsed = false;
@@ -171,6 +171,12 @@ export function shouldCollapsed(note: Misskey.entities.Note, ast?: mfm.MfmNode[]
break;
}
+ case 'border': {
+ const width = safeParseFloat(node.props.args.width) ?? 1;
+ addHeightsInline(getHeightForEachLine(node.children, depth + 1).map(l => l + (width * 2)));
+ break;
+ }
+
default: {
addHeightsInline(getHeightForEachLine(node.children, depth + 1));
break;
diff --git a/packages/frontend/src/store.ts b/packages/frontend/src/store.ts
index e8eb5a1ed7..15521c14c3 100644
--- a/packages/frontend/src/store.ts
+++ b/packages/frontend/src/store.ts
@@ -382,6 +382,14 @@ export const defaultStore = markRaw(new Storage('base', {
where: 'device',
default: 'expand' as 'expand' | '16_9' | '1_1' | '2_3',
},
+ collapsingNoteSize: {
+ where: 'device',
+ default: 'medium' as 'small' | 'medium' | 'large',
+ },
+ collapsingNoteCondition: {
+ where: 'device',
+ default: 'detailedCalculation' as 'detailedCalculation' | 'legacyCalculation' | 'seeRenderedSize',
+ },
notificationPosition: {
where: 'device',
default: 'rightBottom' as 'leftTop' | 'leftBottom' | 'rightTop' | 'rightBottom',