文件
mynode/packages/lib/services/noteList/noteListSnippetUtils.ts
chen 301194963b
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
feat: Initial clean release of CHM
2026-11-04 11:29:39 +08:00

109 行
3.3 KiB
TypeScript

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

import { NoteEntity } from '../database/types';
export interface NoteListItemEntity extends NoteEntity {
is_pinned?: number;
}
/**
* 清理 Markdown 正文并提取前 80 字符的纯文本摘要(对标 Apple 备忘录副标题摘要)
*
* @param body 笔记正文内容
* @param title 笔记标题(若首行与标题相同则自动过滤跳过)
*/
export const cleanSnippet = (body: string, title?: string): string => {
if (!body || !body.trim()) return '';
const lines = body.split('\n');
const cleanedSegments: string[] = [];
const normalizedTitle = title ? title.trim().toLowerCase() : '';
for (const line of lines) {
const trimmed = line.trim();
if (!trimmed) continue;
// 如果当前行与标题相同或为标题的 Markdown 形式(如 # 标题),予以跳过
const headingStripped = trimmed.replace(/^#{1,6}\s+/, '').trim().toLowerCase();
if (normalizedTitle && (trimmed.toLowerCase() === normalizedTitle || headingStripped === normalizedTitle)) {
continue;
}
// 移除各种 Markdown 格式控制符
const text = trimmed
.replace(/^#{1,6}\s+/, '')
.replace(/^[>*+-]\s+\[[ xX]\]\s*/, '')
.replace(/^[>*+-]\s+/, '')
.replace(/^\d+\.\s+\[[ xX]\]\s*/, '')
.replace(/^\d+\.\s+/, '')
.replace(/!\[([^\]]*)\]\([^)]*\)/g, '') // 移除图片
.replace(/\[([^\]]+)\]\([^)]*\)/g, '$1') // 链接仅保留描述文本
.replace(/```[\s\S]*?```/g, '') // 代码块标记
.replace(/[`*_~]/g, '') // 加粗、斜体、删除线、行内代码
.replace(/<[^>]+>/g, '') // HTML 标签
.trim();
if (text) {
cleanedSegments.push(text);
if (cleanedSegments.join(' ').length >= 90) break;
}
}
const combined = cleanedSegments.join(' ').replace(/\s+/g, ' ').trim();
if (combined.length > 70) {
return combined.slice(0, 70) + '…';
}
return combined;
};
/**
* 苹果备忘录风格的时间格式化:
* - 今天:仅展示时分(如 15:30)
* - 本年:展示月/日(如 10/25)
* - 往年:展示年/月/日(如 2025/10/25)
*/
export const formatNoteListDate = (updatedTimeMs: number): string => {
if (!updatedTimeMs) return '';
const now = new Date();
const date = new Date(updatedTimeMs);
const isToday =
date.getFullYear() === now.getFullYear() &&
date.getMonth() === now.getMonth() &&
date.getDate() === now.getDate();
if (isToday) {
const hours = date.getHours().toString().padStart(2, '0');
const minutes = date.getMinutes().toString().padStart(2, '0');
return `${hours}:${minutes}`;
}
const isThisYear = date.getFullYear() === now.getFullYear();
if (isThisYear) {
return `${date.getMonth() + 1}/${date.getDate()}`;
}
return `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`;
};
/**
* 将置顶笔记重排至列表顶端,并注入 is_pinned 属性
*/
export const reorderNotesWithPinned = (notes: NoteListItemEntity[], pinnedNoteIds: string[] = []): NoteListItemEntity[] => {
if (!pinnedNoteIds || !pinnedNoteIds.length || !notes || !notes.length) {
return notes;
}
const pinnedSet = new Set(pinnedNoteIds);
const pinned: NoteListItemEntity[] = [];
const unpinned: NoteListItemEntity[] = [];
for (const note of notes) {
if (pinnedSet.has(note.id)) {
pinned.push({ ...note, is_pinned: 1 });
} else {
unpinned.push(note);
}
}
return [...pinned, ...unpinned];
};