Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions app/appearance/langs/ar_SA.json
Original file line number Diff line number Diff line change
Expand Up @@ -1335,6 +1335,10 @@
"uploadError": "خطأ في الرفع",
"uploading": "يتم الرفع...",
"wysiwyg": "‫ما تراه هو ما تحصل عليه (WYSIWYG)‬",
"recentViewed": "تم عرضها مؤخراً",
"recentOpened": "تم فتحها مؤخراً",
"recentClosed": "تم إغلاقها مؤخراً",
"recentModified": "تم تعديلها مؤخراً",
"_label": "العربية",
"_time": {
"albl": "من قبل",
Expand Down
4 changes: 4 additions & 0 deletions app/appearance/langs/de_DE.json
Original file line number Diff line number Diff line change
Expand Up @@ -1335,6 +1335,10 @@
"uploadError": "Upload-Fehler",
"uploading": "Hochladen...",
"wysiwyg": "WYSIWYG",
"recentViewed": "Zuletzt angesehen",
"recentOpened": "Zuletzt geöffnet",
"recentClosed": "Zuletzt geschlossen",
"recentModified": "Zuletzt geändert",
"_label": "Deutsch",
"_time": {
"albl": "vor",
Expand Down
4 changes: 4 additions & 0 deletions app/appearance/langs/en_US.json
Original file line number Diff line number Diff line change
Expand Up @@ -1335,6 +1335,10 @@
"uploadError": "upload error",
"uploading": "Uploading...",
"wysiwyg": "WYSIWYG",
"recentViewed": "Recently Viewed",
"recentOpened": "Recently Opened",
"recentClosed": "Recently Closed",
"recentModified": "Recently Modified",
"_label": "English",
"_time": {
"albl": "ago",
Expand Down
4 changes: 4 additions & 0 deletions app/appearance/langs/es_ES.json
Original file line number Diff line number Diff line change
Expand Up @@ -1335,6 +1335,10 @@
"uploadError": "error de subida",
"uploading": "Subiendo...",
"wysiwyg": "WYSIWYG",
"recentViewed": "Visto recientemente",
"recentOpened": "Abierto recientemente",
"recentClosed": "Cerrado recientemente",
"recentModified": "Modificado recientemente",
"_label": "Español",
"_time": {
"albl": "hace",
Expand Down
4 changes: 4 additions & 0 deletions app/appearance/langs/fr_FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -1335,6 +1335,10 @@
"uploadError": "erreur de transfert",
"uploading": "Transfert en cours",
"wysiwyg": "WYSIWYG",
"recentViewed": "Récemment consulté",
"recentOpened": "Récemment ouvert",
"recentClosed": "Récemment fermé",
"recentModified": "Récemment modifié",
"_label": "Français",
"_time": {
"albl": "Précédemment",
Expand Down
4 changes: 4 additions & 0 deletions app/appearance/langs/he_IL.json
Original file line number Diff line number Diff line change
Expand Up @@ -1335,6 +1335,10 @@
"uploadError": "שגיאת העלאה",
"uploading": "מעלה...",
"wysiwyg": "WYSIWYG",
"recentViewed": "נצפה לאחרונה",
"recentOpened": "נפתח לאחרונה",
"recentClosed": "נסגר לאחרונה",
"recentModified": "שונה לאחרונה",
"_label": "עברית",
"_time": {
"albl": "לפני",
Expand Down
4 changes: 4 additions & 0 deletions app/appearance/langs/it_IT.json
Original file line number Diff line number Diff line change
Expand Up @@ -1335,6 +1335,10 @@
"uploadError": "Errore di caricamento",
"uploading": "Caricamento in corso.",
"wysiwyg": "WYSIWYG",
"recentViewed": "Visualizzato di recente",
"recentOpened": "Aperto di recente",
"recentClosed": "Chiuso di recente",
"recentModified": "Modificato di recente",
"_label": "Italiano",
"_time": {
"albl": "fa",
Expand Down
4 changes: 4 additions & 0 deletions app/appearance/langs/ja_JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -1335,6 +1335,10 @@
"uploadError": "アップロードエラー",
"uploading": "アップロード中...",
"wysiwyg": "WYSIWYG",
"recentViewed": "最近閲覧",
"recentOpened": "最近開いた",
"recentClosed": "最近閉じる",
"recentModified": "最近更新",
"_label": "日本語",
"_time": {
"albl": "前",
Expand Down
4 changes: 4 additions & 0 deletions app/appearance/langs/pl_PL.json
Original file line number Diff line number Diff line change
Expand Up @@ -1335,6 +1335,10 @@
"uploadError": "błąd przesyłania",
"uploading": "Przesyłanie...",
"wysiwyg": "WYSIWYG",
"recentViewed": "Ostatnio przeglądane",
"recentOpened": "Ostatnio otwarte",
"recentClosed": "Ostatnio zamknięte",
"recentModified": "Ostatnio modyfikowane",
"_label": "Polski",
"_time": {
"albl": "temu",
Expand Down
4 changes: 4 additions & 0 deletions app/appearance/langs/pt_BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -1335,6 +1335,10 @@
"uploadError": "erro de upload",
"uploading": "Enviando...",
"wysiwyg": "WYSIWYG",
"recentViewed": "Visualizado recentemente",
"recentOpened": "Aberto recentemente",
"recentClosed": "Fechado recentemente",
"recentModified": "Modificado recentemente",
"_label": "Português (Brasil)",
"_time": {
"albl": "atrás",
Expand Down
4 changes: 4 additions & 0 deletions app/appearance/langs/ru_RU.json
Original file line number Diff line number Diff line change
Expand Up @@ -1335,6 +1335,10 @@
"uploadError": "Ошибка загрузки",
"uploading": "Загрузка...",
"wysiwyg": "WYSIWYG",
"recentViewed": "Недавно просмотренные",
"recentOpened": "Недавно открытые",
"recentClosed": "Недавно закрытые",
"recentModified": "Недавно измененные",
"_label": "Русский",
"_time": {
"albl": "назад",
Expand Down
4 changes: 4 additions & 0 deletions app/appearance/langs/zh_CHT.json
Original file line number Diff line number Diff line change
Expand Up @@ -1335,6 +1335,10 @@
"uploadError": "上傳錯誤",
"uploading": "上傳中...",
"wysiwyg": "所見即所得",
"recentViewed": "最近瀏覽",
"recentOpened": "最近開啟",
"recentClosed": "最近關閉",
"recentModified": "最近更新",
"_label": "繁體中文",
"_time": {
"albl": "前",
Expand Down
4 changes: 4 additions & 0 deletions app/appearance/langs/zh_CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -1335,6 +1335,10 @@
"uploadError": "上传错误",
"uploading": "上传中...",
"wysiwyg": "所见即所得",
"recentViewed": "最近浏览",
"recentOpened": "最近打开",
"recentClosed": "最近关闭",
"recentModified": "最近修改",
"_label": "简体中文",
"_time": {
"albl": "前",
Expand Down
13 changes: 13 additions & 0 deletions app/src/boot/globalEvent/keydown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1528,6 +1528,19 @@ export const windowKeyDown = (app: App, event: KeyboardEvent) => {
return;
}

if (matchHotKey("⇧⌘T", event)) {
if ((window as any).siyuan.closedTabs && (window as any).siyuan.closedTabs.length > 0) {
const closedTab = (window as any).siyuan.closedTabs.pop();
openFileById({
app,
id: closedTab.id,
action: [Constants.CB_GET_FOCUS, Constants.CB_GET_SCROLL]
});
}
event.preventDefault();
return;
}

if (matchHotKey(window.siyuan.config.keymap.general.goToTab1.custom, event) && !event.repeat) {
switchTabByIndex(0);
event.preventDefault();
Expand Down
65 changes: 60 additions & 5 deletions app/src/business/openRecentDocs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,18 @@ import {focusByRange} from "../protyle/util/selection";
import {hasClosestByClassName} from "../protyle/util/hasClosest";
import {hideElements} from "../protyle/ui/hideElements";

const getHTML = async (data: { rootID: string, icon: string, title: string }[], element: Element, key?: string) => {
const getHTML = async (data: { rootID: string, icon: string, title: string, viewedAt?: number, closedAt?: number, openAt?: number, updated?: number }[], element: Element, key?: string, sortBy: "viewedAt" | "closedAt" | "openAt" | "updated" = "viewedAt") => {
let tabHtml = "";
let index = 0;
data.forEach((item) => {

// 根据排序字段对数据进行排序
const sortedData = [...data].sort((a, b) => {
const aValue = a[sortBy] || 0;
const bValue = b[sortBy] || 0;
return bValue - aValue; // 降序排序
});

sortedData.forEach((item) => {
if (!key || item.title.toLowerCase().includes(key.toLowerCase())) {
tabHtml += `<li data-index="${index}" data-node-id="${item.rootID}" class="b3-list-item${index === 0 ? " b3-list-item--focus" : ""}">
${unicode2Emoji(item.icon || window.siyuan.storage[Constants.LOCAL_IMAGES].file, "b3-list-item__graphic", true)}
Expand Down Expand Up @@ -77,7 +85,7 @@ export const openRecentDocs = () => {
hideElements(["dialog"]);
return;
}
fetchPost("/api/storage/getRecentDocs", {}, (response) => {
fetchPost("/api/storage/getRecentDocs", {sortBy: "viewedAt"}, (response) => {
let range: Range;
if (getSelection().rangeCount > 0) {
range = getSelection().getRangeAt(0);
Expand All @@ -91,6 +99,14 @@ export const openRecentDocs = () => {
<svg class="b3-form__icon-icon"><use xlink:href="#iconSearch"></use></svg>
<input placeholder="${window.siyuan.languages.search}" class="b3-text-field fn__block b3-form__icon-input">
</div>
<div class="fn__flex-center fn__ml8">
<select class="b3-select fn__size200" id="recentDocsSort">
<option value="viewedAt">${window.siyuan.languages.recentViewed}</option>
<option value="updated">${window.siyuan.languages.recentModified}</option>
<option value="openAt">${window.siyuan.languages.recentOpened}</option>
<option value="closedAt">${window.siyuan.languages.recentClosed}</option>
</select>
</div>
</div>`,
content: `<div class="fn__flex-column switch-doc">
<div class="fn__flex fn__flex-1" style="overflow:auto;"></div>
Expand All @@ -106,13 +122,13 @@ export const openRecentDocs = () => {
const searchElement = dialog.element.querySelector("input");
searchElement.focus();
searchElement.addEventListener("compositionend", () => {
getHTML(response.data, dialog.element, searchElement.value);
getHTML(response.data, dialog.element, searchElement.value, sortSelect.value as "viewedAt" | "closedAt" | "openAt" | "updated");
});
searchElement.addEventListener("input", (event: InputEvent) => {
if (event.isComposing) {
return;
}
getHTML(response.data, dialog.element, searchElement.value);
getHTML(response.data, dialog.element, searchElement.value, sortSelect.value as "viewedAt" | "closedAt" | "openAt" | "updated");
});
dialog.element.setAttribute("data-key", Constants.DIALOG_RECENTDOCS);
dialog.element.addEventListener("click", (event) => {
Expand All @@ -125,6 +141,45 @@ export const openRecentDocs = () => {
event.preventDefault();
}
});

// 添加排序下拉框事件监听
const sortSelect = dialog.element.querySelector("#recentDocsSort") as HTMLSelectElement;
sortSelect.addEventListener("change", () => {
// 重新调用API获取排序后的数据
if (sortSelect.value === "updated") {
// 使用SQL查询获取最近修改的文档
const data = {
stmt: "SELECT * FROM blocks WHERE type = 'd' ORDER BY updated DESC LIMIT 33"
};
fetchSyncPost("/api/query/sql", data).then((sqlResponse) => {
if (sqlResponse.data && sqlResponse.data.length > 0) {
// 转换SQL查询结果格式
const recentModifiedDocs = sqlResponse.data.map((block: any) => {
// 从ial中解析icon
let icon = "";
if (block.ial) {
const iconMatch = block.ial.match(/icon="([^"]*)"/);
if (iconMatch) {
icon = iconMatch[1];
}
}
return {
rootID: block.id,
icon: icon,
title: block.content,
updated: block.updated
};
});
getHTML(recentModifiedDocs, dialog.element, searchElement.value, "updated");
}
});
} else {
fetchPost("/api/storage/getRecentDocs", {sortBy: sortSelect.value}, (newResponse) => {
getHTML(newResponse.data, dialog.element, searchElement.value, sortSelect.value as "viewedAt" | "closedAt" | "openAt");
});
}
});

getHTML(response.data, dialog.element);
});
};
8 changes: 4 additions & 4 deletions app/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -509,10 +509,10 @@ export abstract class Constants {
checkToggle: {default: "⌘↩", custom: "⌘↩"},
},
table: {
insertRowAbove: {default: "⇧⌘T", custom: "⇧⌘T"},
insertRowBelow: {default: "⇧⌘D", custom: "⇧⌘D"},
insertColumnLeft: {default: "⇧⌘L", custom: "⇧⌘L"},
insertColumnRight: {default: "⇧⌘R", custom: "⇧⌘R"},
insertRowAbove: {default: "", custom: ""},
insertRowBelow: {default: "", custom: ""},
insertColumnLeft: {default: "", custom: ""},
insertColumnRight: {default: "", custom: ""},
moveToUp: {default: "⌥⌘T", custom: "⌥⌘T"},
moveToDown: {default: "⌥⌘B", custom: "⌥⌘B"},
moveToLeft: {default: "⌥⌘L", custom: "⌥⌘L"},
Expand Down
4 changes: 4 additions & 0 deletions app/src/editor/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ export const openFileById = async (options: {
showMessage(response.msg);
return;
}

// 更新文档浏览时间
fetchPost("/api/storage/updateRecentDocViewTime", {rootID: response.data.rootID});

return openFile({
app: options.app,
fileName: response.data.rootTitle,
Expand Down
18 changes: 18 additions & 0 deletions app/src/layout/Wnd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {Search} from "../search";
import {showMessage} from "../dialog/message";
import {openFileById, updatePanelByEditor} from "../editor/util";
import {scrollCenter} from "../util/highlightById";
import {fetchPost} from "../util/fetch";
import {getAllModels} from "./getAll";
import {clearCounter} from "./status";
import {saveScroll} from "../protyle/scroll/saveScroll";
Expand Down Expand Up @@ -555,6 +556,9 @@ export class Wnd {
}
// focusin 触发前,layout__wnd--active 和 tab 已设置,需在调用里面更新
if (update) {
// 更新文档浏览时间
fetchPost("/api/storage/updateRecentDocViewTime", {rootID: currentTab.model.editor.protyle.block.rootID});

updatePanelByEditor({
protyle: currentTab.model.editor.protyle,
focus: true,
Expand Down Expand Up @@ -632,6 +636,12 @@ export class Wnd {
if (tab.callback) {
tab.callback(tab);
}

// 当文档第一次加载到页签时更新 openAt 时间
if (tab.model instanceof Editor && tab.model.editor?.protyle?.block?.rootID) {
fetchPost("/api/storage/updateRecentDocOpenTime", {rootID: tab.model.editor.protyle.block.rootID});
}

// 移除 centerLayout 中的 empty
if (this.parent.type === "center" && this.children.length === 2 && !this.children[0].headElement) {
this.removeTab(this.children[0].id);
Expand Down Expand Up @@ -781,6 +791,14 @@ export class Wnd {
}
if (item.model instanceof Editor) {
saveScroll(item.model.editor.protyle);
// 更新文档关闭时间
fetchPost("/api/storage/updateRecentDocCloseTime", {rootID: item.model.editor.protyle.block.rootID});
if (!(window as any).siyuan.closedTabs) {
(window as any).siyuan.closedTabs = [];
}
(window as any).siyuan.closedTabs.push({
id: item.model.editor.protyle.block.rootID
});
}
if (this.children.length === 1) {
this.destroyModel(this.children[0].model);
Expand Down
3 changes: 3 additions & 0 deletions app/src/mobile/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ export const openMobileFileById = (app: App, id: string, action: TProtyleAction[
showMessage(data.msg);
return;
}

// 更新文档浏览时间
fetchPost("/api/storage/updateRecentDocViewTime", {rootID: data.data.rootID});
const protyleOptions: IProtyleOptions = {
blockId: id,
rootId: data.data.rootID,
Expand Down
2 changes: 1 addition & 1 deletion app/src/mobile/menu/getRecentDocs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {openMobileFileById} from "../editor";
import {App} from "../../index";

export const getRecentDocs = (app: App) => {
fetchPost("/api/storage/getRecentDocs", {}, (response) => {
fetchPost("/api/storage/getRecentDocs", {sortBy: "viewedAt"}, (response) => {
let html = "";
response.data.forEach((item: any, index: number) => {
html += `<li data-index="${index}" data-node-id="${item.rootID}" class="b3-list-item${index === 0 ? " b3-list-item--focus" : ""}">
Expand Down
5 changes: 4 additions & 1 deletion kernel/api/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,10 @@ func ServeAPI(ginServer *gin.Engine) {
ginServer.Handle("POST", "/api/storage/getCriteria", model.CheckAuth, getCriteria)
ginServer.Handle("POST", "/api/storage/removeCriterion", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeCriterion)
ginServer.Handle("POST", "/api/storage/getRecentDocs", model.CheckAuth, getRecentDocs)

ginServer.Handle("POST", "/api/storage/updateRecentDocViewTime", model.CheckAuth, updateRecentDocViewTime)
ginServer.Handle("POST", "/api/storage/updateRecentDocCloseTime", model.CheckAuth, updateRecentDocCloseTime)
ginServer.Handle("POST", "/api/storage/updateRecentDocOpenTime", model.CheckAuth, updateRecentDocOpenTime)

ginServer.Handle("POST", "/api/account/login", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, login)
ginServer.Handle("POST", "/api/account/checkActivationcode", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, checkActivationcode)
ginServer.Handle("POST", "/api/account/useActivationcode", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, useActivationcode)
Expand Down
Loading