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

This commit is contained in:
Jeffrey Chen 2024-12-24 16:31:56 +08:00
commit 246d4d04f5
30 changed files with 268 additions and 132 deletions

View file

@ -9,7 +9,7 @@
<Identity Name="89C2A984.SiYuan"
ProcessorArchitecture="x64"
Publisher="CN=087C656E-C1D9-42D8-8807-CED45A74FC0F"
Version="3.1.16.0"/>
Version="3.1.17.0"/>
<Properties>
<DisplayName>SiYuan</DisplayName>
<PublisherDisplayName>云南链滴科技有限公司</PublisherDisplayName>

View file

@ -0,0 +1,42 @@
## Overview
This version reduces startup time when sync is enabled.
## Changelogs
Below are the detailed changes in this version.
### Enhancement
* [Database-bound block primary key supports setting static anchor text](https://github.com/siyuan-note/siyuan/issues/10049)
* [The text pasted into the database supports the use of `\t` and `\n` for segmentation and line breaks](https://github.com/siyuan-note/siyuan/issues/13259)
* [Adjust window buttons when the interface is scaled on macOS](https://github.com/siyuan-note/siyuan/issues/13526)
* [The mobile database always displays the `Calculation` row](https://github.com/siyuan-note/siyuan/issues/13535)
* [Improve Attribute Panel - Database - Remove block](https://github.com/siyuan-note/siyuan/issues/13536)
* [Improve list item multi-select indentation interaction](https://github.com/siyuan-note/siyuan/issues/13555)
* [Remove browser default Ctrl+B/I/U](https://github.com/siyuan-note/siyuan/issues/13571)
* [Reduce startup time when sync is enabled](https://github.com/siyuan-note/siyuan/issues/13589)
### Bugfix
* [Emoji not displayed on Linux](https://github.com/siyuan-note/siyuan/issues/13213)
* [Database paste causes crash](https://github.com/siyuan-note/siyuan/issues/13410)
* [Results not highlighted when searching using query syntax](https://github.com/siyuan-note/siyuan/issues/13532)
* [Document cannot be exported as Markdown](https://github.com/siyuan-note/siyuan/issues/13545)
* [Incorrect list item styles in exported PDF](https://github.com/siyuan-note/siyuan/issues/13550)
* [Cannot export Data on mobile](https://github.com/siyuan-note/siyuan/issues/13565)
### Refactor
* [Upgrade to AWS SDK for Go v2](https://github.com/siyuan-note/siyuan/issues/13557)
* [Upgrade to Electron v32.2.7](https://github.com/siyuan-note/siyuan/issues/13566)
### Development
* [Add `renderAVAttribute` method to Protyle](https://github.com/siyuan-note/siyuan/pull/13547)
* [Add plugin function `getAllModels`](https://github.com/siyuan-note/siyuan/issues/13579)
## Download
* [B3log](https://b3log.org/siyuan/en/download.html)
* [GitHub](https://github.com/siyuan-note/siyuan/releases)

View file

@ -0,0 +1,42 @@
## 概述
此版本改變降低了啟用同步時的啟動時間。
## 變更記錄
以下是此版本中的詳細變更。
### 改進功能
* [資料庫綁定區塊主鍵支援設定靜態錨文本](https://github.com/siyuan-note/siyuan/issues/10049)
* [貼到資料庫中的文字支援使用 `\t` 和 `\n` 進行分割和換行](https://github.com/siyuan-note/siyuan/issues/13259)
* [在 macOS 上調整介面縮放時的視窗按鈕](https://github.com/siyuan-note/siyuan/issues/13526)
* [行動資料庫總是顯示 `計算` 行](https://github.com/siyuan-note/siyuan/issues/13535)
* [改進屬性面板 - 資料庫 - 刪除區塊](https://github.com/siyuan-note/siyuan/issues/13536)
* [改進清單項目多選縮排互動](https://github.com/siyuan-note/siyuan/issues/13555)
* [移除瀏覽器預設的 Ctrl+B/I/U](https://github.com/siyuan-note/siyuan/issues/13571)
* [啟用同步時減少啟動時間](https://github.com/siyuan-note/siyuan/issues/13589)
### 修復缺陷
* [Linux 上不顯示表情符號](https://github.com/siyuan-note/siyuan/issues/13213)
* [貼到資料庫導致崩潰](https://github.com/siyuan-note/siyuan/issues/13410)
* [使用查詢語法搜尋時結果未高亮顯示](https://github.com/siyuan-note/siyuan/issues/13532)
* [文件無法匯出為 Markdown](https://github.com/siyuan-note/siyuan/issues/13545)
* [匯出的 PDF 中清單項目樣式不正確](https://github.com/siyuan-note/siyuan/issues/13550)
* [無法在行動裝置上匯出資料](https://github.com/siyuan-note/siyuan/issues/13565)
### 開發重構
* [升級至 AWS SDK for Go v2](https://github.com/siyuan-note/siyuan/issues/13557)
* [升級至 Electron v32.2.7](https://github.com/siyuan-note/siyuan/issues/13566)
### 開發者
* [為 Protyle 新增 `renderAVAttribute` 方法](https://github.com/siyuan-note/siyuan/pull/13547)
* [新增外掛程式 `getAllModels`](https://github.com/siyuan-note/siyuan/issues/13579)
## 下載
* [B3log](https://b3log.org/siyuan/download.html)
* [GitHub](https://github.com/siyuan-note/siyuan/releases)

View file

@ -0,0 +1,42 @@
## 概述
该版本改降低了启用同步时的启动时间。
## 变更记录
以下是此版本中的详细变更。
### 改进功能
* [数据库绑定块主键支持设置静态锚文本](https://github.com/siyuan-note/siyuan/issues/10049)
* [粘贴到数据库中的文本支持使用 `\t` 和 `\n` 进行分割和换行](https://github.com/siyuan-note/siyuan/issues/13259)
* [在 macOS 上调整界面缩放时的窗口按钮](https://github.com/siyuan-note/siyuan/issues/13526)
* [移动数据库始终显示 `计算` 行](https://github.com/siyuan-note/siyuan/issues/13535)
* [改进属性面板 - 数据库 - 删除块](https://github.com/siyuan-note/siyuan/issues/13536)
* [改进列表项多选缩进交互](https://github.com/siyuan-note/siyuan/issues/13555)
* [移除浏览器默认的 Ctrl+B/I/U](https://github.com/siyuan-note/siyuan/issues/13571)
* [启用同步时减少启动时间](https://github.com/siyuan-note/siyuan/issues/13589)
### 修复缺陷
* [Linux 上不显示表情符号](https://github.com/siyuan-note/siyuan/issues/13213)
* [粘贴到数据库导致崩溃](https://github.com/siyuan-note/siyuan/issues/13410)
* [使用查询语法搜索时结果未高亮显示](https://github.com/siyuan-note/siyuan/issues/13532)
* [文档无法导出为 Markdown](https://github.com/siyuan-note/siyuan/issues/13545)
* [导出的 PDF 中列表项样式不正确](https://github.com/siyuan-note/siyuan/issues/13550)
* [无法在移动设备上导出数据](https://github.com/siyuan-note/siyuan/issues/13565)
### 开发重构
* [升级到 AWS SDK for Go v2](https://github.com/siyuan-note/siyuan/issues/13557)
* [升级到 Electron v32.2.7](https://github.com/siyuan-note/siyuan/issues/13566)
### 开发者
* [为 Protyle 添加 `renderAVAttribute` 方法](https://github.com/siyuan-note/siyuan/pull/13547)
* [添加插件函数 `getAllModels`](https://github.com/siyuan-note/siyuan/issues/13579)
## 下载
* [B3log](https://b3log.org/siyuan/download.html)
* [GitHub](https://github.com/siyuan-note/siyuan/releases)

View file

@ -19,11 +19,10 @@ win:
- from: "kernel-arm64"
to: "kernel"
requestedExecutionLevel: "asInvoker"
# certificateSubjectName: "Yunnan Liandi Technology Co., Ltd."
signingHashAlgorithms: [ 'sha256' ]
#rfc3161TimeStampServer: "http://sha256timestamp.ws.symantec.com/sha256/timestamp"
#rfc3161TimeStampServer: "http://time.certum.pl"
rfc3161TimeStampServer: "http://timestamp.entrust.net/TSS/RFC3161sha2TS"
signtoolOptions:
#certificateSubjectName: "Yunnan Liandi Technology Co., Ltd."
signingHashAlgorithms: [ 'sha256' ]
rfc3161TimeStampServer: "http://timestamp.entrust.net/TSS/RFC3161sha2TS"
target:
- target: "nsis"
arch: "arm64"

View file

@ -19,11 +19,10 @@ win:
- from: "kernel"
to: "kernel"
requestedExecutionLevel: "asInvoker"
# certificateSubjectName: "Yunnan Liandi Technology Co., Ltd."
signingHashAlgorithms: [ 'sha256' ]
#rfc3161TimeStampServer: "http://sha256timestamp.ws.symantec.com/sha256/timestamp"
#rfc3161TimeStampServer: "http://time.certum.pl"
rfc3161TimeStampServer: "http://timestamp.entrust.net/TSS/RFC3161sha2TS"
signtoolOptions:
#certificateSubjectName: "Yunnan Liandi Technology Co., Ltd."
signingHashAlgorithms: [ 'sha256' ]
rfc3161TimeStampServer: "http://timestamp.entrust.net/TSS/RFC3161sha2TS"
target:
- target: "nsis"
nsis:

View file

@ -6,7 +6,7 @@
"id": "20201204184532-3qm9l8n",
"title": "Template snippet",
"type": "doc",
"updated": "20241213215714"
"updated": "20241224162810"
},
"Children": [
{
@ -57,7 +57,7 @@
"HeadingLevel": 2,
"Properties": {
"id": "20210104091444-jy56z0p",
"updated": "20241213215714"
"updated": "20241224162810"
},
"Children": [
{
@ -215,7 +215,7 @@
"ListData": {},
"Properties": {
"id": "20210104091444-mwbvc9m",
"updated": "20241213215714"
"updated": "20241224162810"
},
"Children": [
{
@ -484,7 +484,7 @@
},
"Properties": {
"id": "20210504093232-vukp34t",
"updated": "20240403151002"
"updated": "20241224162810"
},
"Children": [
{
@ -516,7 +516,7 @@
"IsFencedCodeBlock": true,
"Properties": {
"id": "20241213215606-a1mq6zf",
"updated": "20241213215606"
"updated": "20241224162810"
},
"Children": [
{
@ -528,7 +528,7 @@
},
{
"Type": "NodeCodeBlockCode",
"Data": " .action{querySQL \"SELECT * FROM spans LIMIT ?\" \"3\"}\n"
"Data": " .action{querySpans \"SELECT * FROM spans LIMIT ?\" \"3\"}\n"
},
{
"Type": "NodeCodeBlockFenceCloseMarker",

View file

@ -6,7 +6,7 @@
"id": "20201204181006-7bkppue",
"title": "模板片段",
"type": "doc",
"updated": "20241213215655"
"updated": "20241224162826"
},
"Children": [
{
@ -69,7 +69,7 @@
"HeadingLevel": 2,
"Properties": {
"id": "20210104091309-fhb549c",
"updated": "20241213215655"
"updated": "20241224162826"
},
"Children": [
{
@ -237,7 +237,7 @@
"ListData": {},
"Properties": {
"id": "20210104091309-gjkg3u5",
"updated": "20241213215655"
"updated": "20241224162826"
},
"Children": [
{
@ -506,7 +506,7 @@
},
"Properties": {
"id": "20210504093313-4aoyxd0",
"updated": "20241213215416"
"updated": "20241224162826"
},
"Children": [
{
@ -538,7 +538,7 @@
"IsFencedCodeBlock": true,
"Properties": {
"id": "20241213215337-rhkoc8k",
"updated": "20241213215416"
"updated": "20241224162826"
},
"Children": [
{
@ -550,7 +550,7 @@
},
{
"Type": "NodeCodeBlockCode",
"Data": " .action{querySQL \"SELECT * FROM spans LIMIT ?\" \"3\"}\n"
"Data": " .action{querySpans \"SELECT * FROM spans LIMIT ?\" \"3\"}\n"
},
{
"Type": "NodeCodeBlockFenceCloseMarker",

View file

@ -6,7 +6,7 @@
"id": "20211226123004-dplpw0o",
"title": "範本片段",
"type": "doc",
"updated": "20241213215707"
"updated": "20241224162821"
},
"Children": [
{
@ -53,7 +53,7 @@
"HeadingLevel": 2,
"Properties": {
"id": "20211226123024-eyagqur",
"updated": "20241213215707"
"updated": "20241224162821"
},
"Children": [
{
@ -208,7 +208,7 @@
"ListData": {},
"Properties": {
"id": "20211226123024-pjvw31z",
"updated": "20241213215707"
"updated": "20241224162821"
},
"Children": [
{
@ -477,7 +477,7 @@
},
"Properties": {
"id": "20211226123024-69kddle",
"updated": "20240403150944"
"updated": "20241224162821"
},
"Children": [
{
@ -509,7 +509,7 @@
"IsFencedCodeBlock": true,
"Properties": {
"id": "20241213215524-9an3khb",
"updated": "20241213215524"
"updated": "20241224162821"
},
"Children": [
{
@ -521,7 +521,7 @@
},
{
"Type": "NodeCodeBlockCode",
"Data": " .action{querySQL \"SELECT * FROM spans LIMIT ?\" \"3\"}\n"
"Data": " .action{querySpans \"SELECT * FROM spans LIMIT ?\" \"3\"}\n"
},
{
"Type": "NodeCodeBlockFenceCloseMarker",

View file

@ -7,7 +7,7 @@
"id": "20240530101000-6x9ivi7",
"title": "テンプレートスニペット",
"type": "doc",
"updated": "20241213215720"
"updated": "20241224162728"
},
"Children": [
{
@ -66,7 +66,7 @@
"Properties": {
"ID": "20240530101000-5nvn9ad",
"id": "20240530101000-pi05yzt",
"updated": "20241213215720"
"updated": "20241224162728"
},
"Children": [
{
@ -226,7 +226,7 @@
"ListData": {},
"Properties": {
"id": "20240530101000-by5hqnb",
"updated": "20241213215720"
"updated": "20241224162728"
},
"Children": [
{
@ -495,7 +495,7 @@
},
"Properties": {
"id": "20240530101000-238ctfi",
"updated": "20240530101000"
"updated": "20241224162728"
},
"Children": [
{
@ -527,7 +527,7 @@
"IsFencedCodeBlock": true,
"Properties": {
"id": "20241213215619-gkqs282",
"updated": "20241213215619"
"updated": "20241224162728"
},
"Children": [
{
@ -539,7 +539,7 @@
},
{
"Type": "NodeCodeBlockCode",
"Data": " .action{querySQL \"SELECT * FROM spans LIMIT ?\" \"3\"}\n"
"Data": " .action{querySpans \"SELECT * FROM spans LIMIT ?\" \"3\"}\n"
},
{
"Type": "NodeCodeBlockFenceCloseMarker",

View file

@ -1,6 +1,6 @@
{
"name": "SiYuan",
"version": "3.1.16",
"version": "3.1.17",
"description": "Refactor your thinking",
"homepage": "https://b3log.org/siyuan",
"main": "./electron/main.js",

View file

@ -493,7 +493,8 @@
}
}
.av__views .block__icon {
.av__views .block__icon,
.av__row--footer .av__calc {
opacity: 1;
}

View file

@ -6,4 +6,4 @@ export const img3115 = (imgElement: HTMLElement) => {
} else {
imgElement.removeAttribute("style");
}
}
};

View file

@ -1189,7 +1189,7 @@ export const imgMenu = (protyle: IProtyle, range: Range, assetElement: HTMLEleme
rangeElement.value = "0";
rangeElement.parentElement.setAttribute("aria-label", inputElement.value ? (inputElement.value + "px") : window.siyuan.languages.default);
img3115(assetElement)
img3115(assetElement);
imgElement.parentElement.style.width = inputElement.value ? (inputElement.value + "px") : "";
imgElement.style.height = "";
});
@ -1220,7 +1220,7 @@ export const imgMenu = (protyle: IProtyle, range: Range, assetElement: HTMLEleme
bind(element) {
rangeElement = element.querySelector("input");
rangeElement.addEventListener("input", () => {
img3115(assetElement)
img3115(assetElement);
imgElement.parentElement.style.width = rangeElement.value + "%";
imgElement.style.height = "";
rangeElement.parentElement.setAttribute("aria-label", `${rangeElement.value}%`);
@ -1254,7 +1254,7 @@ export const imgMenu = (protyle: IProtyle, range: Range, assetElement: HTMLEleme
rangeHeightElement.parentElement.setAttribute("aria-label", inputElement.value ? (inputElement.value + "px") : window.siyuan.languages.default);
imgElement.style.height = inputElement.value ? (inputElement.value + "px") : "";
img3115(assetElement)
img3115(assetElement);
imgElement.parentElement.style.width = "";
});
inputElement.addEventListener("blur", () => {
@ -1284,7 +1284,7 @@ export const imgMenu = (protyle: IProtyle, range: Range, assetElement: HTMLEleme
bind(element) {
rangeHeightElement = element.querySelector("input");
rangeHeightElement.addEventListener("input", () => {
img3115(assetElement)
img3115(assetElement);
imgElement.parentElement.style.width = "";
imgElement.style.height = rangeHeightElement.value + "vh";
rangeHeightElement.parentElement.setAttribute("aria-label", `${rangeHeightElement.value}%`);
@ -1825,7 +1825,7 @@ const genImageWidthMenu = (label: string, imgElement: HTMLElement, protyle: IPro
label,
click() {
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
img3115(imgElement.parentElement.parentElement)
img3115(imgElement.parentElement.parentElement);
imgElement.parentElement.style.width = label === window.siyuan.languages.default ? "" : label;
imgElement.style.height = "";
updateTransaction(protyle, id, nodeElement.outerHTML, html);
@ -1841,7 +1841,7 @@ const genImageHeightMenu = (label: string, imgElement: HTMLElement, protyle: IPr
click() {
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
imgElement.style.height = label === window.siyuan.languages.default ? "" : parseInt(label) + "vh";
img3115(imgElement.parentElement.parentElement)
img3115(imgElement.parentElement.parentElement);
imgElement.parentElement.style.width = "";
updateTransaction(protyle, id, nodeElement.outerHTML, html);
focusBlock(nodeElement);

View file

@ -214,7 +214,7 @@ export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLEle
}
const cellType = getTypeByCellElement(target);
// TODO 点击单元格的时候, lineNumber 选中整行
if (cellType === "updated" || cellType === "created" || cellType === "lineNumber" || (cellType === "block" && !target.getAttribute("data-detached"))) {
if (cellType === "updated" || cellType === "created" || cellType === "lineNumber") {
selectRow(rowElement.querySelector(".av__firstcol"), "toggle");
} else {
scrollElement.querySelectorAll(".av__row--select").forEach(item => {
@ -584,18 +584,9 @@ ${window.siyuan.languages.insertRowAfter.replace("${x}", `<span class="fn__space
});
const editAttrSubmenu: IMenu[] = [];
rowElement.parentElement.querySelectorAll(".av__row--header .av__cell").forEach((cellElement: HTMLElement) => {
let hideBlock = false;
const selectElements: HTMLElement[] = Array.from(blockElement.querySelectorAll(`.av__row--select:not(.av__row--header) .av__cell[data-col-id="${cellElement.dataset.colId}"]`));
if (cellElement.dataset.dtype === "block") {
selectElements.find(item => {
if (!item.dataset.detached) {
hideBlock = true;
return true;
}
});
}
const type = cellElement.getAttribute("data-dtype") as TAVCol;
if (!hideBlock && !["updated", "created"].includes(type)) {
if (!["updated", "created"].includes(type)) {
const icon = cellElement.dataset.icon;
editAttrSubmenu.push({
iconHTML: icon ? unicode2Emoji(icon, "b3-menu__icon", true) : `<svg class="b3-menu__icon"><use xlink:href="#${getColIconByType(type)}"></use></svg>`,

View file

@ -61,7 +61,7 @@ export const genAVValueHTML = (value: IAVCellValue) => {
let html = "";
switch (value.type) {
case "block":
html = `<div class="fn__flex-1" placeholder="${window.siyuan.languages.empty}">${value.block.content}</div>`;
html = `<input value="${value.block.content}" type="text" class="b3-text-field b3-text-field--text fn__flex-1" placeholder="${window.siyuan.languages.empty}">`;
break;
case "text":
html = `<textarea style="resize: vertical" rows="${value.text.content.split("\n").length}" class="b3-text-field b3-text-field--text fn__flex-1" placeholder="${window.siyuan.languages.empty}">${value.text.content}</textarea>`;
@ -198,7 +198,7 @@ export const renderAVAttribute = (element: HTMLElement, id: string, protyle: IPr
<div data-av-id="${table.avID}" data-col-id="${item.values[0].keyID}" data-block-id="${item.values[0].blockID}" data-id="${item.values[0].id}" data-type="${item.values[0].type}"
data-options="${item.key?.options ? escapeAttr(JSON.stringify(item.key.options)) : "[]"}"
${["text", "number", "date", "url", "phone", "template", "email"].includes(item.values[0].type) ? "" : `placeholder="${window.siyuan.languages.empty}"`}
class="fn__flex-1 fn__flex${["url", "text", "number", "email", "phone"].includes(item.values[0].type) ? "" : " custom-attr__avvalue"}${["block", "created", "updated"].includes(item.values[0].type) ? " custom-attr__avvalue--readonly" : ""}">${genAVValueHTML(item.values[0])}</div>
class="fn__flex-1 fn__flex${["url", "text", "number", "email", "phone", "block"].includes(item.values[0].type) ? "" : " custom-attr__avvalue"}${["created", "updated"].includes(item.values[0].type) ? " custom-attr__avvalue--readonly" : ""}">${genAVValueHTML(item.values[0])}</div>
</div>`;
});
innerHTML += `<div class="fn__hr"></div>
@ -412,6 +412,14 @@ class="fn__flex-1 fn__flex${["url", "text", "number", "email", "phone"].includes
}
};
}
} else if (type === "block") {
value = {
block: {
content: item.value,
id: item.parentElement.dataset.blockId,
},
isDetached: false
};
}
fetchPost("/api/av/setAttributeViewBlockAttr", {
avID: item.parentElement.dataset.avId,
@ -421,6 +429,8 @@ class="fn__flex-1 fn__flex${["url", "text", "number", "email", "phone"].includes
}, (setResponse) => {
if (type === "number") {
item.parentElement.querySelector(".fn__flex-center").textContent = setResponse.data.value.number.formattedContent;
} else if (type === "block" && !item.value) {
item.value = setResponse.data.value.block.content;
}
});
});

View file

@ -78,6 +78,9 @@ export const genCellValueByElement = (colType: TAVCol, cellElement: HTMLElement)
};
if (colType === "block" && textElement.dataset.id) {
cellValue.block.id = textElement.dataset.id;
if (textElement.previousElementSibling?.classList.contains("b3-menu__avemoji")) {
cellValue.block.icon = textElement.previousElementSibling.getAttribute("data-unicode");
}
}
} else if (colType === "mSelect" || colType === "select") {
const mSelect: IAVCellSelectValue[] = [];
@ -275,7 +278,11 @@ export const genCellValue = (colType: TAVCol, value: string | any) => {
}
}
if (colType === "block") {
cellValue.isDetached = true;
if (typeof value === "object" && value.id) {
cellValue.isDetached = false;
} else {
cellValue.isDetached = true;
}
}
return cellValue;
};
@ -365,9 +372,6 @@ export const popTextCell = (protyle: IProtyle, cellElements: HTMLElement[], type
if (type === "updated" || type === "created" || document.querySelector(".av__mask")) {
return;
}
if (type === "block" && (cellElements.length > 1 || !cellElements[0].getAttribute("data-detached"))) {
return;
}
const blockElement = hasClosestBlock(cellElements[0]);
if (!blockElement) {
return;
@ -391,7 +395,7 @@ export const popTextCell = (protyle: IProtyle, cellElements: HTMLElement[], type
}
if (["text", "email", "phone", "block", "template"].includes(type)) {
html = `<textarea ${style} spellcheck="false" class="b3-text-field">${cellElements[0].firstElementChild.textContent}</textarea>`;
html = `<textarea ${style} spellcheck="false" class="b3-text-field">${cellElements[0].querySelector(".av__celltext").textContent}</textarea>`;
} else if (type === "url") {
html = `<textarea ${style} spellcheck="false" class="b3-text-field">${cellElements[0].firstElementChild.getAttribute("data-href")}</textarea>`;
} else if (type === "number") {
@ -688,6 +692,12 @@ export const updateCellsValue = (protyle: IProtyle, nodeElement: HTMLElement, va
});
newValue = oldValue.mSelect.concat(newMSelectValue);
}
} else if (type === "block" && typeof value === "string" && oldValue.block.id) {
newValue = {
content: value,
id: oldValue.block.id,
icon: oldValue.block.icon
};
}
const cellValue = genCellValue(type, newValue);
cellValue.id = cellId;
@ -703,26 +713,16 @@ export const updateCellsValue = (protyle: IProtyle, nodeElement: HTMLElement, va
if (objEquals(cellValue, oldValue)) {
return;
}
if (type === "block" && !item.dataset.detached) {
const newId = Lute.NewNodeID();
doOperations.push({
action: "unbindAttrViewBlock",
id: rowID,
nextID: newId,
avID,
});
rowElement.dataset.id = newId;
item.dataset.blockId = newId;
} else {
doOperations.push({
action: "updateAttrViewCell",
id: cellId,
avID,
keyID: colId,
rowID,
data: cellValue
});
}
doOperations.push({
action: "updateAttrViewCell",
id: cellId,
avID,
keyID: colId,
rowID,
data: cellValue
});
undoOperations.push({
action: "updateAttrViewCell",
id: cellId,
@ -790,7 +790,7 @@ export const renderCell = (cellValue: IAVCellValue, rowIndex = 0) => {
if (cellValue?.isDetached) {
text = `<span class="av__celltext">${cellValue.block.content || ""}</span><span class="b3-chip b3-chip--info b3-chip--small" data-type="block-more">${window.siyuan.languages.more}</span>`;
} else {
text = `${cellValue.block.icon ? `<span class="b3-menu__avemoji">${unicode2Emoji(cellValue.block.icon)}</span>` : ""}<span data-type="block-ref" data-id="${cellValue.block.id}" data-subtype="s" class="av__celltext av__celltext--ref">${cellValue.block.content || window.siyuan.languages.untitled}</span><span class="b3-chip b3-chip--info b3-chip--small" data-type="block-more">${window.siyuan.languages.update}</span>`;
text = `${cellValue.block.icon ? `<span class="b3-menu__avemoji" data-unicode="${cellValue.block.icon}">${unicode2Emoji(cellValue.block.icon)}</span>` : ""}<span data-type="block-ref" data-id="${cellValue.block.id}" data-subtype="s" class="av__celltext av__celltext--ref">${cellValue.block.content}</span><span class="b3-chip b3-chip--info b3-chip--small" data-type="block-more">${window.siyuan.languages.update}</span>`;
}
} else if (cellValue.type === "number") {
text = `<span class="av__celltext" data-content="${cellValue?.number.isNotEmpty ? cellValue?.number.content : ""}">${cellValue?.number.formattedContent || cellValue?.number.content || ""}</span>`;
@ -878,7 +878,7 @@ const renderRollup = (cellValue: IAVCellValue) => {
if (cellValue?.isDetached) {
text = `<span class="av__celltext" data-id="${cellValue.block?.id}">${cellValue.block?.content || window.siyuan.languages.untitled}</span>`;
} else {
text = `${cellValue.block.icon ? `<span class="b3-menu__avemoji">${unicode2Emoji(cellValue.block.icon)}</span>` : ""}<span data-type="block-ref" data-id="${cellValue.block?.id}" data-subtype="s" class="av__celltext av__celltext--ref">${cellValue.block?.content || window.siyuan.languages.untitled}</span>`;
text = `${cellValue.block.icon ? `<span class="b3-menu__avemoji" data-unicode="${cellValue.block.icon}">${unicode2Emoji(cellValue.block.icon)}</span>` : ""}<span data-type="block-ref" data-id="${cellValue.block?.id}" data-subtype="s" class="av__celltext av__celltext--ref">${cellValue.block?.content || window.siyuan.languages.untitled}</span>`;
}
} else if (cellValue.type === "number") {
text = cellValue?.number.formattedContent || cellValue?.number.content.toString() || "";

View file

@ -1006,7 +1006,7 @@ export const showColMenu = (protyle: IProtyle, blockElement: Element, cellElemen
target = target.parentElement;
}
});
dialog.element.querySelector("button").focus()
dialog.element.querySelector("button").focus();
dialog.element.setAttribute("data-key", Constants.DIALOG_CONFIRM);
return;
}

View file

@ -208,7 +208,7 @@ const processAV = (range: Range, html: string, protyle: IProtyle, blockElement:
if (textJSON.length === 1 && textJSON[0].length === 1) {
updateCellsValue(protyle, blockElement as HTMLElement, text, cellElements, columns, html);
} else {
let currentRowElement:Element
let currentRowElement:Element;
const firstColIndex = cellElements[0].getAttribute("data-col-id");
textJSON.forEach((rowValue, rowIndex) => {
if (!currentRowElement) {
@ -231,7 +231,7 @@ const processAV = (range: Range, html: string, protyle: IProtyle, blockElement:
}
updateCellsValue(protyle, blockElement as HTMLElement, cellValue, [cellElement], columns, html);
});
})
});
}
document.querySelector(".av__panel")?.remove();
} else if (hasClosestByClassName(range.startContainer, "av__title")) {

View file

@ -671,9 +671,9 @@ export class WYSIWYG {
const dragWidth = dragElement.clientWidth;
const dragHeight = dragElement.clientHeight;
const imgElement = dragElement.parentElement.parentElement
const imgElement = dragElement.parentElement.parentElement;
if (dragElement.tagName === "IMG") {
img3115(imgElement)
img3115(imgElement);
}
documentSelf.onmousemove = (moveEvent: MouseEvent) => {
if (dragElement.tagName === "IMG") {

View file

@ -56,7 +56,7 @@ require (
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
github.com/sashabaranov/go-openai v1.29.1
github.com/shirou/gopsutil/v3 v3.24.5
github.com/siyuan-note/dejavu v0.0.0-20241220041421-b6410d912871
github.com/siyuan-note/dejavu v0.0.0-20241224022945-205805f4607e
github.com/siyuan-note/encryption v0.0.0-20231219001248-1e028a4d13b4
github.com/siyuan-note/eventbus v0.0.0-20240627125516-396fdb0f0f97
github.com/siyuan-note/filelock v0.0.0-20241212013445-c66518cdacfa

View file

@ -365,8 +365,8 @@ github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+D
github.com/shurcooL/gofontwoff v0.0.0-20181114050219-180f79e6909d h1:lvCTyBbr36+tqMccdGMwuEU+hjux/zL6xSmf5S9ITaA=
github.com/shurcooL/gofontwoff v0.0.0-20181114050219-180f79e6909d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw=
github.com/simplereach/timeutils v1.2.0/go.mod h1:VVbQDfN/FHRZa1LSqcwo4kNZ62OOyqLLGQKYB3pB0Q8=
github.com/siyuan-note/dejavu v0.0.0-20241220041421-b6410d912871 h1:U65kVBfF0+PYdlJ1btDxhIfuUElmz7iRbtu3yyyIo8w=
github.com/siyuan-note/dejavu v0.0.0-20241220041421-b6410d912871/go.mod h1:YtT05UDgrYO5Cb/aWc2COwqId56n6qHP+jptvITAags=
github.com/siyuan-note/dejavu v0.0.0-20241224022945-205805f4607e h1:JGxds4l/UUyYSmsuJNSjafs0WfcvOziTt5rhZOlXa34=
github.com/siyuan-note/dejavu v0.0.0-20241224022945-205805f4607e/go.mod h1:+gaHpNFsoVagw956l456Cm4eZclB/gXsjkW4YmvWmJM=
github.com/siyuan-note/encryption v0.0.0-20231219001248-1e028a4d13b4 h1:kJaw5L/evyW6LcB9IQT8PR4ppx8JVqOFP9Ix3rfwSrc=
github.com/siyuan-note/encryption v0.0.0-20231219001248-1e028a4d13b4/go.mod h1:UYcCCY+0wh+GmUoDOaO63j1sV5lgy7laLAk1XhEiUis=
github.com/siyuan-note/eventbus v0.0.0-20240627125516-396fdb0f0f97 h1:lM5v8BfNtbOL5jYwhCdMYBcYtr06IYBKjjSLAPMKTM8=

View file

@ -3106,13 +3106,14 @@ func UpdateAttributeViewCell(tx *Transaction, avID, keyID, rowID string, valueDa
unbindBlockAv(tx, avID, oldBoundBlockID)
bindBlockAv(tx, avID, val.BlockID)
} else { // 之前绑定的块和现在绑定的块一样
// 设置静态锚文本 Database-bound block primary key supports setting static anchor text https://github.com/siyuan-note/siyuan/issues/10049
node, tree, getErr := getNodeByBlockID(tx, val.BlockID)
if nil != getErr || nil == node {
return
content := strings.TrimSpace(val.Block.Content)
node, tree, _ := getNodeByBlockID(tx, val.BlockID)
if "" == content {
_, val.Block.Content = getNodeAvBlockText(node)
}
updateBlockValueStaticText(node, tree, avID, strings.TrimSpace(val.Block.Content))
// 设置静态锚文本 Database-bound block primary key supports setting static anchor text https://github.com/siyuan-note/siyuan/issues/10049
updateBlockValueStaticText(tx, node, tree, avID, content)
}
}
}
@ -3281,14 +3282,18 @@ func bindBlockAv0(tx *Transaction, avID string, node *ast.Node, tree *parse.Tree
return
}
func updateBlockValueStaticText(node *ast.Node, tree *parse.Tree, avID, text string) {
func updateBlockValueStaticText(tx *Transaction, node *ast.Node, tree *parse.Tree, avID, text string) {
if nil == node {
return
}
attrs := parse.IAL2Map(node.KramdownIAL)
attrs[av.NodeAttrViewStaticText+"-"+avID] = text
var err error
if nil != tree {
err = setNodeAttrsWithTx(nil, node, tree, attrs)
if nil != tx {
err = setNodeAttrsWithTx(tx, node, tree, attrs)
} else {
err = setNodeAttrs(node, nil, attrs)
err = setNodeAttrs(node, tree, attrs)
}
if err != nil {
logging.LogWarnf("set node [%s] attrs failed: %s", node.ID, err)

View file

@ -281,6 +281,12 @@ func getNodeAvBlockText(node *ast.Node) (icon, content string) {
} else {
content = getNodeRefText0(node, 1024)
}
content = strings.TrimSpace(content)
if "" == content {
content = Conf.language(105)
}
return
}

View file

@ -154,8 +154,6 @@ func ListNotebooks() (ret []*Box, err error) {
sort.Slice(ret, func(i, j int) bool {
return util.PinYinCompare(ret[j].Name, ret[i].Name)
})
case util.SortModeUpdatedASC:
case util.SortModeUpdatedDESC:
case util.SortModeAlphanumASC:
sort.Slice(ret, func(i, j int) bool {
return util.NaturalCompare(ret[i].Name, ret[j].Name)
@ -166,12 +164,10 @@ func ListNotebooks() (ret []*Box, err error) {
})
case util.SortModeCustom:
sort.Slice(ret, func(i, j int) bool { return ret[i].Sort < ret[j].Sort })
case util.SortModeRefCountASC:
case util.SortModeRefCountDESC:
case util.SortModeCreatedASC:
sort.Slice(ret, func(i, j int) bool { return util.NaturalCompare(ret[j].ID, ret[i].ID) })
sort.Slice(ret, func(i, j int) bool { return ret[i].ID < ret[j].ID })
case util.SortModeCreatedDESC:
sort.Slice(ret, func(i, j int) bool { return util.NaturalCompare(ret[j].ID, ret[i].ID) })
sort.Slice(ret, func(i, j int) bool { return ret[i].ID > ret[j].ID })
}
return
}

View file

@ -711,13 +711,12 @@ func ExportMarkdownHTML(id, savePath string, docx, merge bool) (name, dom string
}
}
srcs := []string{"stage/build/export", "stage/build/fonts", "stage/protyle"}
srcs := []string{"stage/build/export", "stage/protyle"}
for _, src := range srcs {
from := filepath.Join(util.WorkingDir, src)
to := filepath.Join(savePath, src)
if err := filelock.Copy(from, to); err != nil {
logging.LogWarnf("copy stage from [%s] to [%s] failed: %s", from, savePath, err)
return
}
}
@ -869,7 +868,7 @@ func ExportHTML(id, savePath string, pdf, image, keepFold, merge bool) (name, do
}
if !pdf && "" != savePath { // 导出 HTML 需要复制静态资源
srcs := []string{"stage/build/export", "stage/build/fonts", "stage/protyle"}
srcs := []string{"stage/build/export", "stage/protyle"}
for _, src := range srcs {
from := filepath.Join(util.WorkingDir, src)
to := filepath.Join(savePath, src)
@ -899,7 +898,6 @@ func ExportHTML(id, savePath string, pdf, image, keepFold, merge bool) (name, do
to := filepath.Join(savePath, "appearance", src)
if err := filelock.Copy(from, to); err != nil {
logging.LogErrorf("copy appearance from [%s] to [%s] failed: %s", from, savePath, err)
return
}
}

View file

@ -48,6 +48,11 @@ var (
// checkIndex 自动校验数据库索引,仅在数据同步执行完成后执行一次。
func checkIndex() {
checkIndexOnce.Do(func() {
if util.ContainerAndroid == util.Container || util.ContainerIOS == util.Container || util.ContainerHarmony == util.Container {
// 移动端不执行校验 https://ld246.com/article/1734939896061
return
}
logging.LogInfof("start checking index...")
removeDuplicateDatabaseIndex()

View file

@ -1288,14 +1288,13 @@ func bootSyncRepo() (err error) {
isBootSyncing.Store(true)
start := time.Now()
waitGroup := sync.WaitGroup{}
var errs []error
waitGroup.Add(1)
go func() {
defer waitGroup.Done()
start := time.Now()
_, _, indexErr := indexRepoBeforeCloudSync(repo)
if indexErr != nil {
errs = append(errs, indexErr)
@ -1311,6 +1310,8 @@ func bootSyncRepo() (err error) {
isBootSyncing.Store(false)
return
}
logging.LogInfof("boot index repo elapsed [%.2fs]", time.Since(start).Seconds())
}()
var fetchedFiles []*entity.File
@ -1318,6 +1319,7 @@ func bootSyncRepo() (err error) {
go func() {
defer waitGroup.Done()
start := time.Now()
syncContext := map[string]interface{}{eventbus.CtxPushMsg: eventbus.CtxPushMsgToStatusBar}
cloudLatest, getErr := repo.GetCloudLatest(syncContext)
if nil != getErr {
@ -1342,29 +1344,14 @@ func bootSyncRepo() (err error) {
isBootSyncing.Store(false)
return
}
logging.LogInfof("boot get sync cloud files elapsed [%.2fs]", time.Since(start).Seconds())
}()
waitGroup.Wait()
if 0 < len(errs) {
err = errs[0]
return
}
syncingFiles = sync.Map{}
syncingStorages.Store(false)
for _, fetchedFile := range fetchedFiles {
name := path.Base(fetchedFile.Path)
if strings.HasSuffix(name, ".sy") {
id := name[:len(name)-3]
syncingFiles.Store(id, true)
continue
}
if strings.HasPrefix(fetchedFile.Path, "/storage/") {
syncingStorages.Store(true)
}
}
elapsed := time.Since(start)
logging.LogInfof("boot get sync cloud files elapsed [%.2fs]", elapsed.Seconds())
if err != nil {
autoSyncErrCount++
planSyncAfter(fixSyncInterval)
@ -1387,6 +1374,20 @@ func bootSyncRepo() (err error) {
return
}
syncingFiles = sync.Map{}
syncingStorages.Store(false)
for _, fetchedFile := range fetchedFiles {
name := path.Base(fetchedFile.Path)
if strings.HasSuffix(name, ".sy") {
id := name[:len(name)-3]
syncingFiles.Store(id, true)
continue
}
if strings.HasPrefix(fetchedFile.Path, "/storage/") {
syncingStorages.Store(true)
}
}
if 0 < len(fetchedFiles) {
go func() {
_, syncErr := syncRepo(false, false)

View file

@ -214,7 +214,6 @@ func CheckAuth(c *gin.Context) {
// 放过 /appearance/
if strings.HasPrefix(c.Request.RequestURI, "/appearance/") ||
strings.HasPrefix(c.Request.RequestURI, "/stage/build/export/") ||
strings.HasPrefix(c.Request.RequestURI, "/stage/build/fonts/") ||
strings.HasPrefix(c.Request.RequestURI, "/stage/protyle/") {
c.Next()
return

View file

@ -44,7 +44,7 @@ import (
var Mode = "prod"
const (
Ver = "3.1.16"
Ver = "3.1.17"
IsInsider = false
)