feat: 更新版本至1.1.0,新增包含转录内容选项,优化同步逻辑

This commit is contained in:
huojl 2026-05-07 10:29:41 +08:00
parent 9a018c4494
commit e45cbe6cc7
10 changed files with 53 additions and 28 deletions

View file

@ -1,7 +1,7 @@
{
"id": "sonicnote-sync",
"name": "SonicNote Sync",
"version": "1.0.0",
"version": "1.1.0",
"minAppVersion": "0.15.0",
"description": "Sync recordings from SonicNote to Obsidian as Markdown files",
"author": "EasyLinkIn",

View file

@ -1,6 +1,6 @@
{
"name": "sonicnote-sync",
"version": "1.0.0",
"version": "1.1.0",
"description": "Sync recordings from SonicNote to Obsidian as Markdown files",
"main": "main.js",
"scripts": {

View file

@ -133,10 +133,10 @@
<body>
<header class="header">
<div class="version">v1.0.0</div>
<div class="version">v1.1.0</div>
<h1>SonicNote Sync</h1>
<p>将 SonicNote 妙记的录音、转录、总结同步到 Obsidian以 Markdown 文件管理。</p>
<a class="download-btn" href="sonicnote-sync.zip" download>
<a class="download-btn" href="sonicnote-sync-v1.1.0.zip" download>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
下载插件
</a>
@ -144,6 +144,18 @@
<div class="container">
<div class="card">
<h2>更新记录</h2>
<h3>v1.1.0</h3>
<ul>
<li>修复录音进行中重复创建文件的问题</li>
<li>AI 总结移至转录内容之前,优先阅读</li>
<li>新增"包含转录内容"开关,可按需关闭</li>
<li>文件名去除日期前缀,直接使用录音原始名称</li>
<li>切换为 HTTPS 接口</li>
</ul>
</div>
<div class="card">
<h2>前置要求</h2>
<ul>
@ -155,7 +167,7 @@
<div class="card">
<h2>安装</h2>
<ol>
<li>点击上方按钮下载 <span class="inline-code">sonicnote-sync.zip</span></li>
<li>点击上方按钮下载 <span class="inline-code">sonicnote-sync-v1.1.0.zip</span></li>
<li>解压 zip 文件,得到以下文件:
<ul style="margin-top:4px;">
<li><span class="inline-code">main.js</span></li>
@ -204,8 +216,8 @@
<tbody>
<tr><td>Frontmatter</td><td>录音元数据ID、时间、时长、设备名、标签等</td></tr>
<tr><td>笔记</td><td>你在 App 中手写的笔记内容</td></tr>
<tr><td>转录内容</td><td>AI 转写文本(含说话人、时间戳)</td></tr>
<tr><td>AI 总结</td><td>智能总结内容(要点、行动项等)</td></tr>
<tr><td>转录内容</td><td>AI 转写文本(含说话人、时间戳,可在设置中关闭)</td></tr>
</tbody>
</table>
</div>
@ -216,6 +228,7 @@
<thead><tr><th>设置</th><th>默认值</th><th>说明</th></tr></thead>
<tbody>
<tr><td>同步文件夹</td><td><span class="inline-code">SonicNoteSync</span></td><td>Markdown 文件存放目录</td></tr>
<tr><td>包含转录内容</td><td>开启</td><td>关闭后同步文件中不包含逐字转录</td></tr>
</tbody>
</table>
</div>

Binary file not shown.

Binary file not shown.

View file

@ -11,10 +11,7 @@ export function sanitizeFileName(name: string): string {
export function formatFileName(recording: Recording): string {
const displayName = recording.recordNickName || recording.recordName || '未命名录音';
const date = recording.recordTime
? recording.recordTime.substring(0, 10)
: new Date().toISOString().substring(0, 10);
return `${date}-${sanitizeFileName(displayName)}`;
return sanitizeFileName(displayName);
}
function formatDuration(seconds: string | number): string {
@ -96,6 +93,14 @@ export function toMarkdown(
parts.push('');
}
// Summary section (before transcript)
if (summary && summary.summaryContent) {
parts.push('## AI 总结');
parts.push('');
parts.push(summary.summaryContent.trim());
parts.push('');
}
// Transcript section
if (transcript && transcript.length > 0) {
parts.push('## 转录内容');
@ -104,13 +109,5 @@ export function toMarkdown(
parts.push('');
}
// Summary section
if (summary && summary.summaryContent) {
parts.push('## AI 总结');
parts.push('');
parts.push(summary.summaryContent.trim());
parts.push('');
}
return parts.join('\n');
}

View file

@ -39,6 +39,17 @@ export class SonicNoteSettingTab extends PluginSettingTab {
await this.saveSettings();
}));
// Include transcript
new Setting(containerEl)
.setName('包含转录内容')
.setDesc('关闭后同步的文件中不包含逐字转录内容')
.addToggle(toggle => toggle
.setValue(settings.includeTranscript)
.onChange(async (value) => {
settings.includeTranscript = value;
await this.saveSettings();
}));
// Login status & actions
const loginSection = containerEl.createDiv();
loginSection.createEl('h3', { text: '账号' });

View file

@ -116,20 +116,20 @@ export class SyncService {
private async processRecording(recording: Recording, localIndex: Map<string, LocalFileInfo>, settings: SonicNotePluginSettings): Promise<void> {
const syncTime = new Date().toISOString();
// Check if we need to update
const local = localIndex.get(recording.audioId);
if (local && local.syncTime && recording.updateTime) {
if (recording.updateTime <= local.syncTime) {
// No update needed
// Found existing file for this audioId — update it
if (local && local.path) {
// Skip if no update needed (has updateTime and it's older than syncTime)
if (local.syncTime && recording.updateTime && recording.updateTime <= local.syncTime) {
return;
}
// Check for conflict (user edited file locally after sync)
const file = this.app.vault.getAbstractFileByPath(local.path);
if (file instanceof TFile) {
// Check for conflict (user edited file locally after sync)
const fileMtime = new Date(file.stat.mtime).toISOString();
if (fileMtime > local.syncTime) {
// Conflict — write to a new file instead
if (local.syncTime && fileMtime > local.syncTime) {
await this.writeRecordingToNewFile(recording, syncTime, settings, local.path);
return;
}
@ -172,11 +172,12 @@ export class SyncService {
}
private async buildRecordingContent(recording: Recording, syncTime: string): Promise<string> {
const settings = this.getSettings();
const tasks: [string, Promise<TranscriptSegment[] | SummaryData | string | null>][] = [];
// Fetch transcript if available (status 2 = completed)
// Fetch transcript if enabled and available (status 2 = completed)
let transcript: TranscriptSegment[] | null = null;
if (recording.transcriptStatus === 2) {
if (settings.includeTranscript && recording.transcriptStatus === 2) {
tasks.push(['transcript', this.api.fetchTranscriptResult(recording.audioId).catch(() => null)]);
}

View file

@ -4,6 +4,7 @@ export interface SonicNotePluginSettings {
serverUrl: string;
syncFolder: string;
pageSize: number;
includeTranscript: boolean;
token: string;
phoneNumber: string;
lastSyncTime: string;
@ -13,6 +14,7 @@ export const DEFAULT_SETTINGS: SonicNotePluginSettings = {
serverUrl: 'https://ainote.easylinkin.com:18048/prod-api',
syncFolder: 'SonicNoteSync',
pageSize: 50,
includeTranscript: true,
token: '',
phoneNumber: '',
lastSyncTime: '',

View file

@ -1,3 +1,4 @@
{
"1.0.0": "0.15.0"
"1.0.0": "0.15.0",
"1.1.0": "0.15.0"
}