Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
Vanessa 2025-08-31 01:07:27 +08:00
commit cd65fa9d44
31 changed files with 3800 additions and 2875 deletions

View file

@ -14,10 +14,10 @@ Install pnpm: `npm install -g pnpm@10.15.0`
Set the Electron mirror environment variable and install Electron:
* macOS/Linux: `ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ pnpm install electron@37.3.1 -D`
* macOS/Linux: `ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ pnpm install electron@37.4.0 -D`
* Windows:
* `SET ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/`
* `pnpm install electron@37.3.1 -D`
* `pnpm install electron@37.4.0 -D`
NPM mirror:
@ -27,7 +27,7 @@ NPM mirror:
Enter the app folder and execute:
* `pnpm install electron@37.3.1 -D`
* `pnpm install electron@37.4.0 -D`
* `pnpm run dev`
* `pnpm run start`

View file

@ -14,10 +14,10 @@
设置 Electron 镜像环境变量并安装 Electron
* macOS/Linux`ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ pnpm install electron@37.3.1 -D`
* macOS/Linux`ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ pnpm install electron@37.4.0 -D`
* Windows
* `SET ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/`
* `pnpm install electron@37.3.1 -D`
* `pnpm install electron@37.4.0 -D`
NPM 镜像:
@ -27,7 +27,7 @@ NPM 镜像:
进入 app 文件夹执行:
* `pnpm install electron@37.3.1 -D`
* `pnpm install electron@37.4.0 -D`
* `pnpm run dev`
* `pnpm run start`

View file

@ -58,8 +58,9 @@
"backlinkContainChildrenTip": "عند التمكين، سيتم تضمين الكتل الفرعية في حساب الروابط المرجعية",
"entryNum": "عدد المدخلات",
"workspaceData": "بيانات مساحة العمل",
"confirmRemoveRelationField": "‫هل أنت متأكد من أنك تريد حذف الحقل المرتبط بـ <b>${x}</b>؟‬",
"removeButKeepRelationField": "احذف، لكن حفظ الحقل المرتبط",
"confirmRemoveRelationField": "‫هل أنت متأكد من أنك تريد حذف الحقل <b>${x}</b>؟ بعد حذف هذا الحقل، سيتم حذف حقل العلاقة ثنائية الاتجاه <b>${z}</b> في قاعدة البيانات <b>${y}</b> أيضًا بشكل متزامن.",
"removeBothRelationField": "حذف كلا الحقلين",
"removeButKeepRelationField": "احذف هذا الحقل فقط، احتفظ بحقل العلاقة ثنائية الاتجاه",
"exportPDFLowMemory": "‫الذاكرة المتاحة غير كافية لتصدير هذا PDF، يرجى تقليل المحتوى أو زيادة الذاكرة المتاحة ومحاولة التصدير مرة أخرى‬",
"exportConf": "إعدادات التصدير",
"exportConfTip": "‫لن يتم تصدير الحساب، رمز الإذن بالوصول، المزامنة، رمز API ومفتاح مستودع البيانات‬",
@ -129,6 +130,7 @@
"updateLayout": "تحديث التصميم",
"dndFolderTip": "‫يرجى ملاحظة أن ${x} يقوم فقط بإدراج رابط file:// ولا يقوم بنسخ الملف‬",
"removeCol": "‫هل أنت متأكد من أنك تريد حذف حقل <b>${x}</b> في قاعدة البيانات؟‬",
"removeColConfirm": "⚠️ حذف الحقل",
"video": "الفيديو",
"audio": "الصوت",
"updateAll": "تحديث الكل",
@ -1656,6 +1658,7 @@
"268": "يرجى ملاحظة أن الملف [%s] قد تجاوز بالفعل [%d MB]‎، وقد يؤدي ذلك إلى انخفاض الأداء",
"269": "تمت إضافة هذا المقطع بالفعل إلى قاعدة البيانات [%s]",
"270": "يتم تحسين فهرس البيانات، يرجى الانتظار...",
"271": "اكتملت عملية تحسين فهرس البيانات، تم تحرير [%s] من مساحة القرص"
"271": "اكتملت عملية تحسين فهرس البيانات، تم تحرير [%s] من مساحة القرص",
"272": "حقل غير مسمى"
}
}

View file

@ -58,8 +58,9 @@
"backlinkContainChildrenTip": "Wenn aktiviert, werden untergeordnete Blöcke in die Berechnung der Rückverweise einbezogen",
"entryNum": "Anzahl der Einträge",
"workspaceData": "Arbeitsbereichsdaten",
"confirmRemoveRelationField": "Sind Sie sicher, dass Sie das Feld, das mit <b>${x}</b> verknüpft ist, löschen möchten?",
"removeButKeepRelationField": "Entfernen, aber verknüpftes Feld behalten",
"confirmRemoveRelationField": "Sind Sie sicher, dass Sie das <b>${x}</b> Feld löschen möchten? Nach dem Löschen dieses Feldes wird das bidirektionale Beziehungsfeld <b>${z}</b> in der <b>${y}</b> Datenbank ebenfalls synchron gelöscht.",
"removeBothRelationField": "Beide Felder entfernen",
"removeButKeepRelationField": "Nur dieses Feld entfernen, bidirektionales Beziehungsfeld behalten",
"exportPDFLowMemory": "Nicht genügend verfügbarer Speicher, um dieses PDF zu exportieren, bitte reduzieren Sie den Inhalt oder erhöhen Sie den verfügbaren Speicher und versuchen Sie es erneut",
"exportConf": "Export-Einstellungen",
"exportConfTip": "Konto, Zugriffscode, Synchronisation, API-Token und Daten-Repo-Schlüssel werden nicht exportiert",
@ -129,6 +130,7 @@
"updateLayout": "Layout aktualisieren",
"dndFolderTip": "Bitte beachten Sie, dass ${x} nur den file:// Hyperlink einfügt und die Datei nicht kopiert.",
"removeCol": "Sind Sie sicher, dass Sie die <b>${x}</b> Spalte in der Datenbank löschen möchten?",
"removeColConfirm": "⚠️ Spalte löschen",
"video": "Video",
"audio": "Audio",
"updateAll": "Alle aktualisieren",
@ -1656,6 +1658,7 @@
"268": "Bitte beachten Sie, dass die Datei [%s] bereits [%d MB] überschritten hat, was die Leistung beeinträchtigen kann",
"269": "Dieser Block wurde bereits zur Datenbank [%s] hinzugefügt",
"270": "Datenindex wird optimiert, bitte warten...",
"271": "Datenindex-Optimierung abgeschlossen, [%s] Speicherplatz freigegeben"
"271": "Datenindex-Optimierung abgeschlossen, [%s] Speicherplatz freigegeben",
"272": "Unbenanntes Feld"
}
}

View file

@ -58,8 +58,9 @@
"backlinkContainChildrenTip": "When enabled, child blocks will be included in the backlink calculation",
"entryNum": "Number of entries",
"workspaceData": "Workspace data",
"confirmRemoveRelationField": "Are you sure you want to delete the field associated with <b>${x}</b>?",
"removeButKeepRelationField": "Remove, but keep related field",
"confirmRemoveRelationField": "Are you sure you want to delete the <b>${x}</b> field? After deleting this field, the bidirectional relation field <b>${z}</b> in the <b>${y}</b> database will also be deleted synchronously.",
"removeBothRelationField": "Remove both fields",
"removeButKeepRelationField": "Remove only this field, keep bidirectional relation field",
"exportPDFLowMemory": "Insufficient available memory to export this PDF, please reduce the content or increase available memory and try exporting again",
"exportConf": "Export settings",
"exportConfTip": "Account, access authorization code, synchronization, API token and data repo key will not be exported",
@ -129,6 +130,7 @@
"updateLayout": "Update layout",
"dndFolderTip": "Please note that ${x} only inserts the file:// hyperlink and does not copy the file",
"removeCol": "Are you sure you want to delete the <b>${x}</b> field in the database?",
"removeColConfirm": "⚠️ Delete field",
"video": "Video",
"audio": "Audio",
"updateAll": "Update all",
@ -1656,6 +1658,7 @@
"268": "Please note that the file [%s] has already exceeded [%d MB], which may cause performance degradation",
"269": "This block has already been added to the database [%s]",
"270": "Optimizing data index, please wait...",
"271": "Data index optimization completed, [%s] disk space freed"
"271": "Data index optimization completed, [%s] disk space freed",
"272": "Unnamed field"
}
}

View file

@ -58,8 +58,9 @@
"backlinkContainChildrenTip": "Una vez habilitado, los bloques secundarios se incluirán en el cálculo de los enlaces inversos",
"entryNum": "Número de entradas",
"workspaceData": "Datos del espacio de trabajo",
"confirmRemoveRelationField": "¿Está seguro de que desea eliminar el campo asociado a <b>${x}</b>?",
"removeButKeepRelationField": "Eliminar, pero mantener el campo relacionado",
"confirmRemoveRelationField": "¿Está seguro de que desea eliminar el campo <b>${x}</b>? Después de eliminar este campo, el campo de relación bidireccional <b>${z}</b> en la base de datos <b>${y}</b> también se eliminará de forma sincrónica.",
"removeBothRelationField": "Eliminar ambos campos",
"removeButKeepRelationField": "Eliminar solo este campo, mantener el campo de relación bidireccional",
"exportPDFLowMemory": "Memoria disponible insuficiente para exportar este PDF, por favor reduzca el contenido o aumente la memoria disponible y vuelva a intentar exportar",
"exportConf": "Configuración de exportación",
"exportConfTip": "Las cuentas, los códigos de acceso, la sincronización, los tokens API y las claves del almacén de datos no se exportarán",
@ -129,6 +130,7 @@
"updateLayout": "Actualizar diseño",
"dndFolderTip": "Tenga en cuenta que ${x} solo inserta el hipervínculo file:// y no copia el archivo",
"removeCol": "¿Está seguro de que desea eliminar la columna <b>${x}</b> en la base de datos?",
"removeColConfirm": "⚠️ Eliminar columna",
"vídeo": "Vídeo",
"audio": "Audio",
"updateAll": "Actualizar todo",
@ -1656,6 +1658,7 @@
"268": "Atención: el archivo [%s] ya ha superado los [%d MB], lo que puede causar una disminución del rendimiento",
"269": "Este bloque ya ha sido añadido a la base de datos [%s]",
"270": "Optimizando el índice de datos, por favor espere...",
"271": "Optimización del índice de datos completada, se liberaron [%s] de espacio en disco"
"271": "Optimización del índice de datos completada, se liberaron [%s] de espacio en disco",
"272": "Campo sin nombre"
}
}

View file

@ -1,8 +1,8 @@
{
"vacuumDataIndex": "Optimiser lindex",
"vacuumDataIndexTip": "Vérifiez lindex des données, libérez de lespace et améliorez les performances de lindex",
"rebuildDataIndex": "Reconstruire lindex",
"rebuildDataIndexTip": "Reconstruction complète de lindex des données, cela peut prendre du temps, veuillez patienter",
"vacuumDataIndex": "Optimiser l'index",
"vacuumDataIndexTip": "Vérifiez l'index des données, libérez de l'espace et améliorez les performances de l'index",
"rebuildDataIndex": "Reconstruire l'index",
"rebuildDataIndexTip": "Reconstruction complète de l'index des données, cela peut prendre du temps, veuillez patienter",
"displayFieldName": "Afficher le nom du champ",
"sortBySelectOption": "Trier par option",
"groupStep": "Intervalle de regroupement",
@ -58,8 +58,9 @@
"backlinkContainChildrenTip": "Une fois activé, les sous-blocs seront inclus dans le calcul des liens retour",
"entryNum": "Nombre d'entrées",
"workspaceData": "Données de l'espace de travail",
"confirmRemoveRelationField": "Êtes-vous sûr de vouloir supprimer le champ associé à <b>${x}</b>?",
"removeButKeepRelationField": "Supprimer, mais conserver le champ associé",
"confirmRemoveRelationField": "Êtes-vous sûr de vouloir supprimer le champ <b>${x}</b> ? Après la suppression de ce champ, le champ de relation bidirectionnelle <b>${z}</b> dans la base de données <b>${y}</b> sera également supprimé de manière synchrone.",
"removeBothRelationField": "Supprimer les deux champs",
"removeButKeepRelationField": "Supprimer seulement ce champ, conserver le champ de relation bidirectionnelle",
"exportPDFLowMemory": "Mémoire disponible insuffisante pour exporter ce PDF, veuillez réduire le contenu ou augmenter la mémoire disponible et réessayer d'exporter",
"exportConf": "Exporter les paramètres",
"exportConfTip": "Les comptes, codes d'accès, synchronisation, tokens API et clés d'entrepôt de données ne seront pas exportés",
@ -129,6 +130,7 @@
"updateLayout": "Mettre à jour la mise en page",
"dndFolderTip": "Veuillez noter que ${x} insère uniquement le lien hypertexte file:// et ne copie pas le fichier",
"removeCol": "Êtes-vous sûr de vouloir supprimer la colonne <b>${x}</b> de la base de données ?",
"removeColConfirm": "⚠️ Supprimer la colonne",
"video": "Vidéo",
"audio": "Audio",
"updateAll": "Tout mettre à jour",
@ -495,7 +497,7 @@
"workspaceList": "Espaces de travail",
"removeWorkspaceTip": "Supprimer des espaces de travail",
"new": "Nouveau",
"share2LiandiConfirmTip": "Êtes-vous sûr de vouloir <b>publier</b> ce document dans la <a href=\"${accountServer}\" target=\"_blank\">communauté</a> ?<br>Après la publication, tout le monde pourra voir ce document, assurez-vous qu'il ne contient pas d'informations sensibles",
"share2LiandiConfirmTip": "Êtes-vous sûr de vouloir <b>publier</b> ce document dans la <a href=\"${accountServer}\" target=\"_blank\">communauté</a> ?<br>Après la publication, tout le monde pourra voir ce document, assurez-vous qu'il ne contient pas d'informations sensibles",
"share2Liandi": "Partager avec communauté",
"noDueCard": "Excellent travail ! Il n'y a plus de tâches de révision pour le moment, revenez plus tard !",
"createDeck": "Créer un deck",
@ -757,7 +759,7 @@
"findHighlight": "Tout surligner",
"findEntireWord": "Mots entiers",
"presentationMode": "Basculer en mode présentation",
"focusOutline": "Trouver lélément de plan actuel",
"focusOutline": "Trouver l'élément de plan actuel",
"previousLabel": "Précédent",
"nextLabel": "Suivant",
"pageScaleWidth": "Pleine largeur",
@ -768,12 +770,12 @@
"loading": "Chargement…",
"toggleSidebarNotification2Title": "Afficher/Masquer le panneau latéral (le document contient des signets/pièces jointes/calques)",
"toggleSidebarTitle": "Afficher/Masquer le panneau latéral",
"loadingError": "Une erreur sest produite lors du chargement du fichier PDF.",
"loadingError": "Une erreur s'est produite lors du chargement du fichier PDF.",
"invalidFileError": "Fichier PDF invalide ou corrompu.",
"missingFileError": "Fichier PDF manquant.",
"unexpectedResponseError": "Réponse inattendue du serveur.",
"printingNotSupported": "Attention : limpression nest pas totalement prise en charge par ce navigateur.",
"printingNotReady": "Attention : le PDF nest pas entièrement chargé pour pouvoir limprimer.",
"printingNotSupported": "Attention : l'impression n'est pas totalement prise en charge par ce navigateur.",
"printingNotReady": "Attention : le PDF n'est pas entièrement chargé pour pouvoir l'imprimer.",
"unitInches": "in",
"unitMillimeters": "mm",
"additionalLayers": "Calques additionnels",
@ -1655,7 +1657,8 @@
"267": "Base de données sans nom",
"268": "Attention : le fichier [%s] a déjà dépassé [%d MB], ce qui peut entraîner une baisse des performances",
"269": "Ce bloc a déjà été ajouté à la base de données [%s]",
"270": "Optimisation de lindex des données en cours, veuillez patienter...",
"271": "Optimisation de lindex des données terminée, [%s] despace disque libéré"
"270": "Optimisation de l'index des données en cours, veuillez patienter...",
"271": "Optimisation de l'index des données terminée, [%s] d'espace disque libéré",
"272": "Champ sans nom"
}
}

View file

@ -58,8 +58,9 @@
"backlinkContainChildrenTip": "לאחר ההפעלה, בלוקים משניים ייכללו בחישוב הקישורים החוזרים",
"entryNum": "מספר ערכים",
"workspaceData": "נתוני סביבת עבודה",
"confirmRemoveRelationField": "האם אתה בטוח שברצונך למחוק את השדה המשויך ל-<b>${x}</b>?",
"removeButKeepRelationField": "מחק, אך שמור על שדה הקשר",
"confirmRemoveRelationField": "האם אתה בטוח שברצונך למחוק את השדה <b>${x}</b>? לאחר מחיקת שדה זה, שדה הקשר הדו-כיווני <b>${z}</b> במסד הנתונים <b>${y}</b> יימחק גם הוא באופן סינכרוני.",
"removeBothRelationField": "מחק את שני השדות",
"removeButKeepRelationField": "מחק רק שדה זה, שמור על שדה הקשר הדו-כיווני",
"exportPDFLowMemory": "אין מספיק זיכרון זמין במערכת כדי לייצא את ה-PDF הזה, נא לצמצם את התוכן או להגדיל את הזיכרון הזמין ולנסות שוב לייצא",
"exportConf": "הגדרות ייצוא",
"exportConfTip": "פרטי חשבון, קוד אישור גישה, סנכרון, אסימון API ומפתח מאגר נתונים לא ייוצאו",
@ -129,6 +130,7 @@
"updateLayout": "עדכן עימוד",
"dndFolderTip": "שים לב כי ${x} ניחש את ה-hyperlink file:// ואינו מעתיק את הקובץ",
"removeCol": "האם אתה בטוח שברצונך למחוק את העמודה <b>${x}</b> במסד הנתונים?",
"removeColConfirm": "⚠️ מחק עמודה",
"video": "וידאו",
"audio": "אודיו",
"updateAll": "עדכן הכל",
@ -1656,6 +1658,7 @@
"268": "שים לב שהקובץ [%s] כבר חרג מ-[%d MB], דבר שעלול לגרום לירידה בביצועים",
"269": "הבלוק נוסף כבר למסד הנתונים [%s]",
"270": "מתבצעת אופטימיזציה של אינדקס הנתונים, נא להמתין...",
"271": "אופטימיזציית אינדקס הנתונים הושלמה, שוחררו [%s] שטח דיסק"
"271": "אופטימיזציית אינדקס הנתונים הושלמה, שוחררו [%s] שטח דיסק",
"272": "שדה ללא שם"
}
}

View file

@ -58,8 +58,9 @@
"backlinkContainChildrenTip": "Dopo l'attivazione, i blocchi figli saranno inclusi nel calcolo dei backlink",
"entryNum": "Numero di voci",
"workspaceData": "Dati dello spazio di lavoro",
"confirmRemoveRelationField": "Sei sicuro di voler eliminare il campo associato a <b>${x}</b>?",
"removeButKeepRelationField": "Rimuovi, ma mantieni il campo correlato",
"confirmRemoveRelationField": "Sei sicuro di voler eliminare il campo <b>${x}</b>? Dopo aver eliminato questo campo, il campo di relazione bidirezionale <b>${z}</b> nel database <b>${y}</b> verrà eliminato anche in modo sincrono.",
"removeBothRelationField": "Rimuovi entrambi i campi",
"removeButKeepRelationField": "Rimuovi solo questo campo, mantieni il campo di relazione bidirezionale",
"exportPDFLowMemory": "Memoria disponibile insufficiente per esportare questo PDF, riduci il contenuto o aumenta la memoria disponibile e riprova a esportare",
"exportConf": "Impostazioni di esportazione",
"exportConfTip": "Account, codici di accesso, sincronizzazione, token API e chiavi di data warehouse non verranno esportati",
@ -129,6 +130,7 @@
"updateLayout": "Aggiorna layout",
"dndFolderTip": "Nota che ${x} inserisce solo il collegamento file:// e non copia il file",
"removeCol": "Sei sicuro di voler eliminare la colonna <b>${x}</b> nel database?",
"removeColConfirm": "⚠️ Elimina colonna",
"video": "Video",
"audio": "Audio",
"updateAll": "Aggiorna tutto",
@ -1656,6 +1658,7 @@
"268": "Attenzione: il file [%s] ha già superato [%d MB], il che potrebbe causare un calo delle prestazioni",
"269": "Questo blocco è già stato aggiunto al database [%s]",
"270": "Ottimizzazione dell'indice dei dati in corso, attendere prego...",
"271": "Ottimizzazione dell'indice dei dati completata, liberati [%s] di spazio su disco"
"271": "Ottimizzazione dell'indice dei dati completata, liberati [%s] di spazio su disco",
"272": "Campo senza nome"
}
}

View file

@ -58,8 +58,9 @@
"backlinkContainChildrenTip": "有効にすると、子ブロックがバックリンク計算に含まれます",
"entryNum": "エントリ数",
"workspaceData": "ワークスペースデータ",
"confirmRemoveRelationField": "<b>${x}</b> に関連するフィールドを同時に削除してもよろしいですか?",
"removeButKeepRelationField": "削除して関連フィールドを保持",
"confirmRemoveRelationField": "<b>${x}</b> フィールドを削除してもよろしいですか?このフィールドを削除すると、<b>${y}</b> データベースの双方向関連フィールド <b>${z}</b> も同時に削除されます。",
"removeBothRelationField": "両方のフィールドを削除",
"removeButKeepRelationField": "このフィールドのみ削除し、双方向関連フィールドを保持",
"exportPDFLowMemory": "システムの利用可能なメモリが不足しているため、この PDF をエクスポートできません。内容を減らすか、利用可能なメモリを増やしてから再試行してください",
"exportConf": "設定のエクスポート",
"exportConfTip": "アカウント、アクセスコード、同期、API トークン、データウェアハウスキーはエクスポートされません",
@ -129,6 +130,7 @@
"updateLayout": "レイアウトを更新",
"dndFolderTip": "${x} は file:// 形式のハイパーリンクを挿入するだけでファイルはコピーされないので注意してください",
"removeCol": "データベースの <b>${x}</b> 列を削除してもよろしいですか?",
"removeColConfirm": "⚠️ 列を削除",
"video": "ビデオ",
"audio": "音声",
"updateAll": "すべて更新",
@ -1656,6 +1658,7 @@
"268": "ファイル [%s] はすでに [%d MB] を超えており、パフォーマンスが低下する可能性があります",
"269": "このブロックはすでにデータベース [%s] に追加されています",
"270": "データインデックスを最適化しています。しばらくお待ちください...",
"271": "データインデックスの最適化が完了しました。合計 [%s] のディスク容量が解放されました"
"271": "データインデックスの最適化が完了しました。合計 [%s] のディスク容量が解放されました",
"272": "未命名フィールド"
}
}

View file

@ -58,8 +58,9 @@
"backlinkContainChildrenTip": "Po włączeniu bloki podrzędne zostaną uwzględnione w obliczeniach linków zwrotnych",
"entryNum": "Количество записей",
"workspaceData": "Dane przestrzeni roboczej",
"confirmRemoveRelationField": "Czy na pewno chcesz usunąć pole powiązane z <b>${x}</b>?",
"removeButKeepRelationField": "Usuń, ale zachowaj powiązane pole",
"confirmRemoveRelationField": "Czy na pewno chcesz usunąć pole <b>${x}</b>? Po usunięciu tego pola, dwukierunkowe pole relacji <b>${z}</b> w bazie danych <b>${y}</b> również zostanie usunięte synchronicznie.",
"removeBothRelationField": "Usuń oba pola",
"removeButKeepRelationField": "Usuń tylko to pole, zachowaj dwukierunkowe pole relacji",
"exportPDFLowMemory": "Za mało dostępnej pamięci, aby wyeksportować ten PDF, proszę zmniejszyć zawartość lub zwiększyć dostępną pamięć i spróbować ponownie",
"exportConf": "Ustawienia eksportu",
"exportConfTip": "Konto, kod autoryzacji dostępu, synchronizacja, token API i klucz repozytorium danych nie będą eksportowane",
@ -129,6 +130,7 @@
"updateLayout": "Zaktualizuj układ",
"dndFolderTip": "Proszę pamiętać, że ${x} tylko wstawia link file:// i nie kopiuje pliku",
"removeCol": "Czy na pewno chcesz usunąć <b>${x}</b> kolumnę w bazie danych?",
"removeColConfirm": "⚠️ Usuń kolumnę",
"video": "Wideo",
"audio": "Audio",
"updateAll": "Zaktualizuj wszystko",
@ -1656,6 +1658,7 @@
"268": "Uwaga: plik [%s] przekroczył już [%d MB], co może spowodować spadek wydajności",
"269": "Ten blok został już dodany do bazy danych [%s]",
"270": "Optymalizacja indeksu danych, proszę czekać...",
"271": "Optymalizacja indeksu danych zakończona, zwolniono [%s] miejsca na dysku"
"271": "Optymalizacja indeksu danych zakończona, zwolniono [%s] miejsca na dysku",
"272": "Nienazwane pole"
}
}

View file

@ -58,8 +58,9 @@
"backlinkContainChildrenTip": "Quando ativado, os blocos filhos serão incluídos no cálculo do backlink",
"entryNum": "Número de entradas",
"workspaceData": "Dados do espaço de trabalho",
"confirmRemoveRelationField": "Tem certeza que deseja excluir o campo associado a <b>${x}</b>?",
"removeButKeepRelationField": "Remover, mas manter campo relacionado",
"confirmRemoveRelationField": "Tem certeza que deseja excluir o campo <b>${x}</b>? Após excluir este campo, o campo de relação bidirecional <b>${z}</b> no banco de dados <b>${y}</b> também será excluído de forma síncrona.",
"removeBothRelationField": "Remover ambos os campos",
"removeButKeepRelationField": "Remover apenas este campo, manter campo de relação bidirecional",
"exportPDFLowMemory": "Memória disponível insuficiente para exportar este PDF, reduza o conteúdo ou aumente a memória disponível e tente exportar novamente",
"exportConf": "Configurações de exportação",
"exportConfTip": "Conta, código de autorização de acesso, sincronização, token de API e chave do repositório de dados não serão exportados",
@ -129,6 +130,7 @@
"updateLayout": "Atualizar layout",
"dndFolderTip": "Observe que ${x} apenas insere o hiperlink file:// e não copia o arquivo",
"removeCol": "Tem certeza que deseja excluir o campo <b>${x}</b> no banco de dados?",
"removeColConfirm": "⚠️ Excluir campo",
"video": "Vídeo",
"audio": "Áudio",
"updateAll": "Atualizar tudo",
@ -1656,6 +1658,7 @@
"268": "Atenção: o arquivo [%s] já excedeu [%d MB], o que pode causar queda de desempenho",
"269": "Este bloco já foi adicionado ao banco de dados [%s]",
"270": "Otimizando o índice de dados, por favor aguarde...",
"271": "Otimização do índice de dados concluída, [%s] de espaço liberado"
"271": "Otimização do índice de dados concluída, [%s] de espaço liberado",
"272": "Campo sem nome"
}
}

View file

@ -58,8 +58,9 @@
"backlinkContainChildrenTip": "После включения дочерние блоки будут включены в расчет обратных ссылок",
"entryNum": "Количество записей",
"workspaceData": "Данные рабочей области",
"confirmRemoveRelationField": "Вы уверены, что хотите удалить поле, связанное с <b>${x}</b>?",
"removeButKeepRelationField": "Удалить, но сохранить связанное поле",
"confirmRemoveRelationField": "Вы уверены, что хотите удалить поле <b>${x}</b>? После удаления этого поля двунаправленное поле связи <b>${z}</b> в базе данных <b>${y}</b> также будет синхронно удалено.",
"removeBothRelationField": "Удалить оба поля",
"removeButKeepRelationField": "Удалить только это поле, сохранить двунаправленное поле связи",
"exportPDFLowMemory": "Недостаточно доступной памяти для экспорта этого PDF, пожалуйста, уменьшите содержимое или увеличьте доступную память и повторите попытку экспорта",
"exportConf": "Экспорт настроек",
"exportConfTip": "Учетная запись, код авторизации доступа, синхронизация, API токен и ключ репозитория данных не будут экспортированы",
@ -129,6 +130,7 @@
"updateLayout": "Обновить макет",
"dndFolderTip": "Пожалуйста, обратите внимание, что ${x} только вставляет файл:// гиперссылку и не копирует файл",
"removeCol": "Вы уверены, что хотите удалить колонку <b>${x}</b> в базе данных?",
"removeColConfirm": "⚠️ Удалить колонку",
"video": "Видео",
"audio": "Аудио",
"updateAll": "Обновить все",
@ -1656,6 +1658,7 @@
"268": "Обратите внимание, что файл [%s] уже превышает [%d МБ], это может привести к снижению производительности",
"269": "Этот блок уже добавлен в базу данных [%s]",
"270": "Оптимизация индекса данных, пожалуйста, подождите...",
"271": "Оптимизация индекса данных завершена, освобождено [%s] дискового пространства"
"271": "Оптимизация индекса данных завершена, освобождено [%s] дискового пространства",
"272": "Неименованное поле"
}
}

View file

@ -22,8 +22,8 @@
"insertItemAfter": "在後方插入${x}條",
"allViews": "所有視圖",
"copyAVID": "複製資料庫 ID",
"hideEmptyFields": "隱藏空字段",
"displayEmptyFields": "顯示空字段",
"hideEmptyFields": "隱藏空欄位",
"displayEmptyFields": "顯示空欄位",
"cardAspectRatio": "預覽區寬高比",
"cardPreview1": "卡片預覽",
"contentImage": "內容圖片",
@ -34,7 +34,7 @@
"fitImage": "自動調整圖片大小",
"showIcon": "顯示圖標",
"showAllEntriesIcons": "顯示條目圖標",
"wrapAllFields": "字段自動換行",
"wrapAllFields": "欄位自動換行",
"gallery": "卡片",
"newTag": "新建標籤",
"pleaseWait": "請稍等片刻...",
@ -58,8 +58,9 @@
"backlinkContainChildrenTip": "啟用後子塊將被納入到反向鏈接計算中",
"entryNum": "條目數",
"workspaceData": "工作空間數據",
"confirmRemoveRelationField": "確定同時刪除關聯至 <b>${x}</b> 中的字段嗎?",
"removeButKeepRelationField": "刪除,但保留關聯字段",
"confirmRemoveRelationField": "確定要刪除 <b>${x}</b> 欄位嗎?刪除本欄位後,<b>${y}</b> 數據庫中的雙向關聯欄位 <b>${z}</b> 也會同步刪除。",
"removeBothRelationField": "同時刪除兩個欄位",
"removeButKeepRelationField": "僅刪除本欄位,保留雙向關聯欄位",
"exportPDFLowMemory": "系統可用記憶體不足,無法導出該 PDF請減少內容或者增加可用記憶體後再嘗試導出",
"exportConf": "匯出設定",
"exportConfTip": "帳號、存取授權碼、同步、API token 和資料倉儲金鑰不會被匯出",
@ -129,6 +130,7 @@
"updateLayout": "更新版面配置",
"dndFolderTip": "請注意 ${x} 僅插入 file:// 超鏈接,不複製檔案",
"removeCol": "確定刪除資料庫中的 <b>${x}</b> 欄位?",
"removeColConfirm": "⚠️ 刪除欄位",
"video": "影片",
"audio": "音訊",
"updateAll": "全部更新",
@ -1649,13 +1651,14 @@
"261": "今天",
"262": "明天",
"263": "未來 %d 天",
"264": "字段 [%s] 為空",
"264": "欄位 [%s] 為空",
"265": "不在範圍內",
"266": "Tesseract OCR 未安裝或未配置,請參考 用戶指南-資料文件 章節進行配置",
"267": "未命名資料庫",
"268": "請注意該檔案 [%s] 已經超過 [%d MB],可能會導致效能下降",
"269": "該塊已經添加到資料庫 [%s] 中",
"270": "正在優化資料索引,請稍等...",
"271": "資料索引優化完畢,共釋放 [%s] 磁碟空間"
"271": "資料索引優化完畢,共釋放 [%s] 磁碟空間",
"272": "未命名欄位"
}
}

View file

@ -58,8 +58,9 @@
"backlinkContainChildrenTip": "启用后子块将被纳入到反向链接计算中",
"entryNum": "条目数",
"workspaceData": "工作空间数据",
"confirmRemoveRelationField": "确定同时删除关联至 <b>${x}</b> 中的字段吗?",
"removeButKeepRelationField": "删除,但保留关联字段",
"confirmRemoveRelationField": "确定要删除 <b>${x}</b> 字段吗?删除本字段后,<b>${y}</b> 数据库中的双向关联字段 <b>${z}</b> 也会同步删除。",
"removeBothRelationField": "同时删除两个字段",
"removeButKeepRelationField": "仅删除本字段,保留双向关联字段",
"exportPDFLowMemory": "系统可用内存不足,无法导出该 PDF请减少内容或者增加可用内存后再尝试导出",
"exportConf": "导出设置",
"exportConfTip": "账号、访问授权码、同步、API token 和数据仓库密钥不会被导出",
@ -129,6 +130,7 @@
"updateLayout": "更新布局",
"dndFolderTip": "请注意 ${x} 仅插入 file:// 超链接,不复制文件",
"removeCol": "确定删除数据库中的 <b>${x}</b> 字段?",
"removeColConfirm": "⚠️ 删除字段",
"video": "视频",
"audio": "音频",
"updateAll": "全部更新",
@ -1656,6 +1658,7 @@
"268": "请注意该文件 [%s] 已经超过 [%d MB],可能会导致性能下降",
"269": "该块已经添加到数据库 [%s] 中",
"270": "正在优化数据索引,请稍等...",
"271": "数据索引优化完毕,共释放 [%s] 磁盘空间"
"271": "数据索引优化完毕,共释放 [%s] 磁盘空间",
"272": "未命名字段"
}
}

View file

@ -58,7 +58,7 @@
"clean-webpack-plugin": "^4.0.0",
"css-loader": "^7.1.2",
"dayjs": "^1.11.5",
"electron": "37.3.1",
"electron": "37.4.0",
"electron-builder": "26.0.12",
"encoding": "^0.1.13",
"esbuild-loader": "^3.0.1",

6300
app/pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

View file

@ -186,7 +186,7 @@ ${unicode2Emoji(getNotebookIcon(item.box) || window.siyuan.storage[Constants.LOC
<svg class="b3-list-item__graphic"><use xlink:href="#${getIconByType(childItem.type)}"></use></svg>
${unicode2Emoji(childItem.ial.icon, "b3-list-item__graphic", true)}
<span class="b3-list-item__text">${childItem.content}</span>
${childItem.tag ? `<span class="b3-list-item__meta b3-list-item__meta--ellipsis">${childItem.tag.split("# #").map(tag => `${tag.replace("#", "")}`).join(" ").replace("#", "")}</span>` : ""}
${childItem.tag ? `<span class="b3-list-item__meta b3-list-item__meta--ellipsis">${childItem.tag.replace(/#/g, "")}</span>` : ""}
</div>`;
});
resultHTML += "</div>";
@ -206,7 +206,7 @@ ${childItem.tag ? `<span class="b3-list-item__meta b3-list-item__meta--ellipsis"
<span class="b3-list-item__text">${item.content}</span>
</div>
<div class="fn__flex">
${item.tag ? `<span class="b3-list-item__meta b3-list-item__meta--ellipsis">${item.tag.split("# #").map(tag => `${tag.replace("#", "")}`).join(" ").replace("#", "")}</span><span class="fn__space"></span>` : ""}
${item.tag ? `<span class="b3-list-item__meta b3-list-item__meta--ellipsis">${item.tag.replace(/#/g, "")}</span><span class="fn__space"></span>` : ""}
<span class="b3-list-item__text b3-list-item__meta">${escapeGreat(title)}</span>
</div>
</div>`;

View file

@ -468,11 +468,11 @@ export const bindEditEvent = (options: {
});
if (oldValue.avID) {
fetchPost("/api/av/getAttributeView", {id: oldValue.avID}, (response) => {
goSearchElement.querySelector(".b3-menu__accelerator").textContent = oldValue.avID === avID ? window.siyuan.languages.thisDatabase : (response.data.av.name || window.siyuan.languages.title);
goSearchElement.querySelector(".b3-menu__accelerator").textContent = oldValue.avID === avID ? window.siyuan.languages.thisDatabase : (response.data.av.name || window.siyuan.languages._kernel[267]);
response.data.av.keyValues.find((item: { key: { id: string, name: string } }) => {
if (item.key.id === oldValue.backKeyID) {
inputElement.setAttribute("data-old-value", item.key.name || window.siyuan.languages.title);
inputElement.value = item.key.name || window.siyuan.languages.title;
inputElement.setAttribute("data-old-value", item.key.name || window.siyuan.languages._kernel[272]);
inputElement.value = item.key.name || window.siyuan.languages._kernel[272];
return true;
}
});
@ -1003,16 +1003,20 @@ export const showColMenu = (protyle: IProtyle, blockElement: Element, cellElemen
if (colData.key.relation?.isTwoWay) {
const relResponse = await fetchSyncPost("/api/av/getAttributeView", {id: colData.key.relation.avID});
const dialog = new Dialog({
title: window.siyuan.languages.removeCol.replace("${x}", colData.key.name),
title: window.siyuan.languages.removeColConfirm,
content: `<div class="b3-dialog__content">
${window.siyuan.languages.confirmRemoveRelationField.replace("${x}", relResponse.data.av.name)}
${window.siyuan.languages.confirmRemoveRelationField
.replace("${x}", colData.key.name || window.siyuan.languages._kernel[272])
.replace("${y}", relResponse.data.av.name || window.siyuan.languages._kernel[267])
.replace("${z}", relResponse.data.av.keyValues.find((item: {key: {id: string}}) => item.key.id === colData.key.relation.backKeyID).key.name || window.siyuan.languages._kernel[272])}
<div class="fn__hr--b"></div>
<button class="fn__block b3-button b3-button--remove" data-action="delete">${window.siyuan.languages.delete}</button>
<button class="fn__block b3-button b3-button--remove" data-action="delete">${window.siyuan.languages.removeBothRelationField}</button>
<div class="fn__hr"></div>
<button class="fn__block b3-button b3-button--remove" data-action="keep-relation">${window.siyuan.languages.removeButKeepRelationField}</button>
<div class="fn__hr"></div>
<button class="fn__block b3-button b3-button--cancel">${window.siyuan.languages.cancel}</button>
</div>`,
width: "520px",
});
dialog.element.addEventListener("click", (event) => {
let target = event.target as HTMLElement;

View file

@ -1198,16 +1198,21 @@ export const openMenuPanel = (options: {
const isTwoWay = colData.type === "relation" && colData.relation?.isTwoWay;
if (isCustomAttr || isTwoWay) {
const dialog = new Dialog({
title: isTwoWay ? window.siyuan.languages.removeCol.replace("${x}", menuElement.querySelector("input").value) : window.siyuan.languages.deleteOpConfirm,
title: isTwoWay ? window.siyuan.languages.removeColConfirm : window.siyuan.languages.deleteOpConfirm,
content: `<div class="b3-dialog__content">
${isTwoWay ? window.siyuan.languages.confirmRemoveRelationField.replace("${x}", menuElement.querySelector('.b3-menu__item[data-type="goSearchAV"] .b3-menu__accelerator').textContent) : window.siyuan.languages.removeCol.replace("${x}", menuElement.querySelector("input").value)}
${isTwoWay ? window.siyuan.languages.confirmRemoveRelationField
.replace("${x}", menuElement.querySelector("input").value || window.siyuan.languages._kernel[272])
.replace("${y}", menuElement.querySelector('.b3-menu__item[data-type="goSearchAV"] .b3-menu__accelerator').textContent)
.replace("${z}", (menuElement.querySelector('input[data-type="colName"]') as HTMLInputElement).value || window.siyuan.languages._kernel[272])
: window.siyuan.languages.removeCol.replace("${x}", menuElement.querySelector("input").value || window.siyuan.languages._kernel[272])}
<div class="fn__hr--b"></div>
<button class="fn__block b3-button b3-button--remove" data-action="delete">${window.siyuan.languages.delete}</button>
<button class="fn__block b3-button b3-button--remove" data-action="delete">${isTwoWay ? window.siyuan.languages.removeBothRelationField : window.siyuan.languages.delete}</button>
<div class="fn__hr"></div>
<button class="fn__block b3-button b3-button--remove${isTwoWay ? "" : " fn__none"}" data-action="keep-relation">${window.siyuan.languages.removeButKeepRelationField}</button>
<div class="fn__hr"></div>
<button class="fn__block b3-button b3-button--cancel">${window.siyuan.languages.cancel}</button>
</div>`,
width: "520px",
});
dialog.element.addEventListener("click", (dialogEvent) => {
let target = dialogEvent.target as HTMLElement;

View file

@ -1346,7 +1346,7 @@ ${unicode2Emoji(getNotebookIcon(item.box) || window.siyuan.storage[Constants.LOC
${unicode2Emoji(childItem.ial.icon, "b3-list-item__graphic", true)}
<span class="b3-list-item__text">${childItem.content}</span>
${getAttr(childItem)}
${childItem.tag ? `<span class="b3-list-item__meta b3-list-item__meta--ellipsis">${childItem.tag.split("# #").map(tag => `${tag.replace("#", "")}`).join(" ").replace("#", "")}</span>` : ""}
${childItem.tag ? `<span class="b3-list-item__meta b3-list-item__meta--ellipsis">${childItem.tag.replace(/#/g, "")}</span>` : ""}
</div>`;
});
resultHTML += "</div>";
@ -1364,7 +1364,7 @@ ${childItem.tag ? `<span class="b3-list-item__meta b3-list-item__meta--ellipsis"
${unicode2Emoji(item.ial.icon, "b3-list-item__graphic", true)}
<span class="b3-list-item__text">${item.content}</span>
${getAttr(item)}
${item.tag ? `<span class="b3-list-item__meta b3-list-item__meta--ellipsis">${item.tag.split("# #").map(tag => `${tag.replace("#", "")}`).join(" ").replace("#", "")}</span>` : ""}
${item.tag ? `<span class="b3-list-item__meta b3-list-item__meta--ellipsis">${item.tag.replace(/#/g, "")}</span>` : ""}
<span class="b3-list-item__meta b3-list-item__meta--ellipsis ariaLabel" aria-label="${escapeAriaLabel(title)}">${escapeGreat(title)}</span>
</div>`;
}

View file

@ -27,6 +27,44 @@ import (
"github.com/siyuan-note/siyuan/kernel/util"
)
func getAttributeViewItemIDsByBoundIDs(c *gin.Context) {
ret := gulu.Ret.NewResult()
defer c.JSON(http.StatusOK, ret)
arg, ok := util.JsonArg(c, ret)
if !ok {
return
}
avID := arg["avID"].(string)
blockIDsArg := arg["blockIDs"].([]interface{})
var blockIDs []string
for _, v := range blockIDsArg {
blockIDs = append(blockIDs, v.(string))
}
ret.Data = model.GetAttributeViewItemIDs(avID, blockIDs)
}
func getAttributeViewBoundBlockIDsByItemIDs(c *gin.Context) {
ret := gulu.Ret.NewResult()
defer c.JSON(http.StatusOK, ret)
arg, ok := util.JsonArg(c, ret)
if !ok {
return
}
avID := arg["avID"].(string)
itemIDsArg := arg["itemIDs"].([]interface{})
var itemIDs []string
for _, v := range itemIDsArg {
itemIDs = append(itemIDs, v.(string))
}
ret.Data = model.GetAttributeViewBoundBlockIDs(avID, itemIDs)
}
// getAttributeViewAddingBlockDefaultValues 用于获取添加块时的默认值。
// 存在过滤或分组条件时,添加块时需要填充默认值到过滤字段或分组字段中,前端需要调用该接口来获取这些默认值以便填充。
func getAttributeViewAddingBlockDefaultValues(c *gin.Context) {

View file

@ -465,6 +465,8 @@ func ServeAPI(ginServer *gin.Engine) {
ginServer.Handle("POST", "/api/av/setAttrViewGroup", model.CheckAuth, setAttrViewGroup)
ginServer.Handle("POST", "/api/av/batchReplaceAttributeViewBlocks", model.CheckAuth, batchReplaceAttributeViewBlocks)
ginServer.Handle("POST", "/api/av/getAttributeViewAddingBlockDefaultValues", model.CheckAuth, getAttributeViewAddingBlockDefaultValues)
ginServer.Handle("POST", "/api/av/getAttributeViewBoundBlockIDsByItemIDs", model.CheckAuth, getAttributeViewBoundBlockIDsByItemIDs)
ginServer.Handle("POST", "/api/av/getAttributeViewItemIDsByBoundIDs", model.CheckAuth, getAttributeViewItemIDsByBoundIDs)
ginServer.Handle("POST", "/api/ai/chatGPT", model.CheckAuth, model.CheckAdminRole, chatGPT)
ginServer.Handle("POST", "/api/ai/chatGPTWithAction", model.CheckAuth, model.CheckAdminRole, chatGPTWithAction)

View file

@ -44,6 +44,48 @@ import (
"github.com/xrash/smetrics"
)
func GetAttributeViewItemIDs(avID string, blockIDs []string) (ret map[string]string) {
ret = map[string]string{}
for _, blockID := range blockIDs {
ret[blockID] = ""
}
attrView, err := av.ParseAttributeView(avID)
if err != nil {
logging.LogErrorf("parse attribute view [%s] failed: %s", avID, err)
return
}
blockKv := attrView.GetBlockKeyValues()
for _, b := range blockKv.Values {
if _, ok := ret[b.Block.ID]; ok {
ret[b.Block.ID] = b.BlockID
}
}
return
}
func GetAttributeViewBoundBlockIDs(avID string, itemIDs []string) (ret map[string]string) {
ret = map[string]string{}
for _, itemID := range itemIDs {
ret[itemID] = ""
}
attrView, err := av.ParseAttributeView(avID)
if err != nil {
logging.LogErrorf("parse attribute view [%s] failed: %s", avID, err)
return
}
blockKv := attrView.GetBlockKeyValues()
for _, b := range blockKv.Values {
if _, ok := ret[b.BlockID]; ok {
ret[b.BlockID] = b.Block.ID
}
}
return
}
func GetAttrViewAddingBlockDefaultValues(avID, viewID, groupID, previousBlockID, addingBlockID string) (ret map[string]*av.Value) {
ret = map[string]*av.Value{}
@ -1488,7 +1530,7 @@ func GetBlockAttributeViewKeys(nodeID string) (ret []*BlockAttributeViewKeys) {
keyValues = append(keyValues, kValues)
} else {
// 如果没有值,那么就补一个默认值
kValues.Values = append(kValues.Values, av.GetAttributeViewDefaultValue(ast.NewNodeID(), kv.Key.ID, itemID, kv.Key.Type))
kValues.Values = append(kValues.Values, av.GetAttributeViewDefaultValue(itemID[:14]+ast.NewNodeID()[14:], kv.Key.ID, itemID, kv.Key.Type))
keyValues = append(keyValues, kValues)
}
}
@ -3027,11 +3069,6 @@ func addAttributeViewBlock(now int64, avID, dbBlockID, viewID, groupID, previous
}
}
if addingItemID == addingBoundBlockID {
addingItemID = ast.NewNodeID()
logging.LogWarnf("the adding item ID is the same as the bound block ID [%s], generate a new one item id [%s]", addingBoundBlockID, addingItemID)
}
attrView, err := av.ParseAttributeView(avID)
if err != nil {
return
@ -4367,8 +4404,8 @@ func BatchReplaceAttributeViewBlocks(avID string, isDetached bool, oldNew []map[
}
for _, oldNewMap := range oldNew {
for oldBlockID, newBlockID := range oldNewMap {
if err = replaceAttributeViewBlock0(attrView, oldBlockID, newBlockID, isDetached, nil); nil != err {
for oldBlockID, newNodeID := range oldNewMap {
if err = replaceAttributeViewBlock0(attrView, oldBlockID, newNodeID, isDetached, nil); nil != err {
return
}
}

View file

@ -61,6 +61,7 @@ type Block struct {
Children []*Block `json:"children"`
Depth int `json:"depth"`
Count int `json:"count"`
RefCount int `json:"refCount"`
Sort int `json:"sort"`
Created string `json:"created"`
Updated string `json:"updated"`
@ -765,7 +766,7 @@ func GetBlockKramdown(id, mode string) (ret string) {
if "md" == mode {
// `/api/block/getBlockKramdown` link/image URLs are no longer encoded with spaces https://github.com/siyuan-note/siyuan/issues/15611
luteEngine.SetPreventEncodeLinkSpace(true)
ret = treenode.ExportNodeStdMd(root, luteEngine)
} else {
tree.Root = root

View file

@ -1024,7 +1024,11 @@ func CreateDocByMd(boxID, p, title, md string, sorts []string) (tree *parse.Tree
}
FlushTxQueue()
ChangeFileTreeSort(box.ID, sorts)
if 0 < len(sorts) {
ChangeFileTreeSort(box.ID, sorts)
} else {
box.addMinSort(path.Dir(tree.Path), tree.ID)
}
return
}

View file

@ -671,7 +671,6 @@ func (box *Box) generateDocHistory0() {
func clearOutdatedHistoryDir(historyDir string) {
if !gulu.File.IsExist(historyDir) {
logging.LogWarnf("history dir [%s] not exist", historyDir)
return
}

View file

@ -50,6 +50,13 @@ func CreateBox(name string) (id string, err error) {
createDocLock.Lock()
defer createDocLock.Unlock()
boxes, _ := ListNotebooks()
for i, b := range boxes {
c := b.GetConf()
c.Sort = i + 1
b.SaveConf(c)
}
id = ast.NewNodeID()
boxLocalPath := filepath.Join(util.DataDir, id)
err = os.MkdirAll(boxLocalPath, 0755)

View file

@ -314,6 +314,9 @@ func buildEmbedBlock(embedBlockID string, excludeIDs []string, headingMode int,
func SearchRefBlock(id, rootID, keyword string, beforeLen int, isSquareBrackets, isDatabase bool) (ret []*Block, newDoc bool) {
cachedTrees := map[string]*parse.Tree{}
nodeTrees := map[string]*parse.Tree{}
var nodeIDs []string
var nodes []*ast.Node
onlyDoc := false
if isSquareBrackets {
@ -332,6 +335,7 @@ func SearchRefBlock(id, rootID, keyword string, beforeLen int, isSquareBrackets,
}
btsID = gulu.Str.RemoveDuplicatedElem(btsID)
bts := treenode.GetBlockTrees(btsID)
for _, ref := range refs {
tree := cachedTrees[ref.DefBlockRootID]
if nil == tree {
@ -347,6 +351,15 @@ func SearchRefBlock(id, rootID, keyword string, beforeLen int, isSquareBrackets,
continue
}
nodes = append(nodes, node)
nodeIDs = append(nodeIDs, node.ID)
nodeTrees[node.ID] = tree
}
refCount := sql.QueryRefCount(nodeIDs)
for _, node := range nodes {
tree := nodeTrees[node.ID]
sqlBlock := sql.BuildBlockFromNode(node, tree)
if nil == sqlBlock {
return
@ -355,8 +368,10 @@ func SearchRefBlock(id, rootID, keyword string, beforeLen int, isSquareBrackets,
block := fromSQLBlock(sqlBlock, "", 0)
block.RefText = getNodeRefText(node)
block.RefText = maxContent(block.RefText, Conf.Editor.BlockRefDynamicAnchorTextMaxLen)
block.RefCount = refCount[node.ID]
ret = append(ret, block)
}
if 1 > len(ret) {
ret = []*Block{}
}
@ -388,7 +403,7 @@ func SearchRefBlock(id, rootID, keyword string, beforeLen int, isSquareBrackets,
hitFirstChildID := false
if b.IsContainerBlock() && "NodeDocument" != b.Type {
// `((` 引用候选中排除当前块的父块 https://github.com/siyuan-note/siyuan/issues/4538
tree := cachedTrees[b.RootID]
tree = cachedTrees[b.RootID]
if nil == tree {
tree, _ = loadTreeByBlockTree(bts[b.RootID])
cachedTrees[b.RootID] = tree
@ -404,16 +419,25 @@ func SearchRefBlock(id, rootID, keyword string, beforeLen int, isSquareBrackets,
if "NodeAttributeView" == b.Type {
// 数据库块可以添加到自身数据库块中,当前文档也可以添加到自身数据库块中
tmp = append(tmp, b)
nodeIDs = append(nodeIDs, b.ID)
nodeTrees[b.ID] = tree
} else {
// 排除自身块、父块和根块
if b.ID != id && !hitFirstChildID && b.ID != rootID {
tmp = append(tmp, b)
nodeIDs = append(nodeIDs, b.ID)
nodeTrees[b.ID] = tree
}
}
}
ret = tmp
refCount := sql.QueryRefCount(nodeIDs)
for _, b := range ret {
b.RefCount = refCount[b.ID]
}
if !isDatabase {
// 如果非数据库中搜索块引,则不允许新建重名文档
if block := treenode.GetBlockTree(id); nil != block {
@ -1296,6 +1320,16 @@ func FullTextSearchBlock(query string, boxes, paths []string, types map[string]b
if 0 == groupBy {
filterSelfHPath(ret)
}
var nodeIDs []string
for _, b := range ret {
nodeIDs = append(nodeIDs, b.ID)
}
refCount := sql.QueryRefCount(nodeIDs)
for _, b := range ret {
b.RefCount = refCount[b.ID]
}
return
}

View file

@ -961,10 +961,8 @@ func (tx *Transaction) syncDelete2Block(node *ast.Node, nodeTree *parse.Tree) (c
pushBroadcastAttrTransactions(oldAttrs, toChangNode)
}
nodeTreeID := nodeTree.ID
for _, tree := range trees {
self := nodeTreeID == tree.ID
if !self {
if nodeTree.ID != tree.ID {
indexWriteTreeUpsertQueue(tree)
}
}
@ -1461,6 +1459,11 @@ func (tx *Transaction) doUpdate(operation *Operation) (ret *TxErr) {
updatedNode.Tokens = []byte(strings.Join(newLines, "\n"))
}
removedNodes := getRemovedNodes(oldNode, updatedNode)
for _, n := range removedNodes {
syncDelete2AvBlock(n, tree, tx)
}
// 替换为新节点
oldNode.InsertAfter(updatedNode)
oldNode.Unlink()
@ -1520,6 +1523,30 @@ func getRefDefIDs(node *ast.Node) (refDefIDs []string) {
return
}
func getRemovedNodes(oldNode, newNode *ast.Node) (ret []*ast.Node) {
oldNodes := map[string]*ast.Node{}
ast.Walk(oldNode, func(n *ast.Node, entering bool) ast.WalkStatus {
if !entering || !n.IsBlock() {
return ast.WalkContinue
}
oldNodes[n.ID] = n
return ast.WalkContinue
})
ast.Walk(newNode, func(n *ast.Node, entering bool) ast.WalkStatus {
if !entering || !n.IsBlock() {
return ast.WalkContinue
}
if _, ok := oldNodes[n.ID]; ok {
delete(oldNodes, n.ID)
}
return ast.WalkContinue
})
for _, n := range oldNodes {
ret = append(ret, n)
}
return
}
func upsertAvBlockRel(node *ast.Node) {
var affectedAvIDs []string
ast.Walk(node, func(n *ast.Node, entering bool) ast.WalkStatus {

View file

@ -96,7 +96,7 @@ func RenderAttributeViewGallery(attrView *av.AttributeView, view *av.View, query
if nil == fieldValue {
fieldValue = &av.GalleryFieldValue{
BaseValue: &av.BaseValue{
ID: ast.NewNodeID(),
ID: cardID[:14] + ast.NewNodeID()[14:],
ValueType: field.Type,
},
}