Skip to content

Commit

Permalink
refactor(monaco-editor): 调整文件资源管理器图标与提示文本 | Adjust the icon and promp…
Browse files Browse the repository at this point in the history
…t text of the file explorer.
  • Loading branch information
Zuoqiu-Yingyi committed Jul 22, 2023
1 parent 1481c23 commit 32fff26
Show file tree
Hide file tree
Showing 9 changed files with 217 additions and 43 deletions.
3 changes: 3 additions & 0 deletions public/i18n/en_US.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@
"toggle": {
"ariaLabel": "Collapse/Expand"
},
"tooltips": {
"siyuanDoc": "SiYuan Document File"
},
"unfold": {
"ariaLabel": "Expand"
},
Expand Down
3 changes: 3 additions & 0 deletions public/i18n/zh_CHT.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@
"toggle": {
"ariaLabel": "摺疊/展開"
},
"tooltips": {
"siyuanDoc": "思源文件檔案"
},
"unfold": {
"ariaLabel": "展開"
},
Expand Down
3 changes: 3 additions & 0 deletions public/i18n/zh_CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@
"toggle": {
"ariaLabel": "折叠/展开"
},
"tooltips": {
"siyuanDoc": "思源文档文件"
},
"unfold": {
"ariaLabel": "展开"
},
Expand Down
3 changes: 2 additions & 1 deletion src/components/ExplorerDock.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import type MonacoEditorPlugin from "@/index";
import { Explorer } from "@/explorer";
import type { ITree } from '@workspace/components/siyuan/tree/file';
import { Icon } from '@/explorer/icon';
export let plugin: InstanceType<typeof MonacoEditorPlugin>; // 插件对象
export let workspace: string; // 工作空间目录
Expand All @@ -37,7 +38,7 @@
/* 标题栏配置 */
const bar: IBar = {
logo: Explorer.ICONS.filetree,
logo: Icon.ICONS.filetree,
title: plugin.i18n.explorer.title,
icons: [
{
Expand Down
65 changes: 65 additions & 0 deletions src/explorer/icon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* Copyright (C) 2023 Zuoqiu Yingyi
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import { FileTreeNodeType, type IFileTreeNode, type IFileTreeNodeStores } from "@workspace/components/siyuan/tree/file";
import { parse } from "@workspace/utils/path/browserify";
import { get } from "svelte/store";

/* 图标管理 */
export class Icon {
public static ICONS = {
file: "#iconFile",
filetree: "#icon-monaco-editor-file-tree",
folder_closed: "#icon-monaco-editor-folder-closed",
folder_opend: "#icon-monaco-editor-folder-opend",
siyuan: "#iconSiYuan",
workspace: "#iconWorkspace",
} as const;

/* 展开节点 */
public static expand(node: IFileTreeNodeStores) {
if (get(node.type) === FileTreeNodeType.Folder) {
node.icon.set(Icon.ICONS.folder_opend);
}
}

/* 收缩节点 */
public static collapse(node: IFileTreeNodeStores) {
if (get(node.type) === FileTreeNodeType.Folder) {
node.icon.set(Icon.ICONS.folder_closed);
}
}

/* 根据节点信息生成图标 ID */
public static make(type: FileTreeNodeType, path: string): string {
switch (type) {
case FileTreeNodeType.Root:
return Icon.ICONS.workspace;
case FileTreeNodeType.Folder:
return Icon.ICONS.folder_closed;
case FileTreeNodeType.File: {
const info = parse(path); // 节点路径信息
switch (true) {
case info.ext === ".sy": // 思源文件
return Icon.ICONS.siyuan;
default:
return Icon.ICONS.file;
}
}
}
}
}
74 changes: 39 additions & 35 deletions src/explorer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ import { isBinaryExt } from "@workspace/utils/file/binary";
import { fn__code, ft__primary } from "@workspace/utils/siyuan/text/span";

import type MonacoEditorPlugin from "@/index";
import { Select } from "./select";
import { Icon } from "./icon";
import { Tooltip } from "./tooltip";

/* 资源 */
export interface IItem {
Expand Down Expand Up @@ -71,17 +74,16 @@ export type DefaultNodeProps = Required<Pick<

/* 文件资源管理器 */
export class Explorer implements ITree {
public static ICONS = {
filetree: "#icon-monaco-editor-file-tree",
workspace: "#iconWorkspace",
folder_opend: "#icon-monaco-editor-folder-opend",
folder_closed: "#icon-monaco-editor-folder-closed",
} as const;
/* 树节点集合 */
protected readonly tooltip: InstanceType<typeof Tooltip>; // 提示文本管理

/* 树节点集合 */
protected readonly set: Set<IFileTreeNodeStores>;
protected readonly set = new Set<IFileTreeNodeStores>();
/* 路径->节点 */
protected readonly map: Map<IFileTreeNode["path"], IFileTreeNodeStores>;
protected readonly map = new Map<IFileTreeNode["path"], IFileTreeNodeStores>();
/* 节点选中状态 */
protected readonly select = new Select();

/* 根节点列表 */
protected roots: IFileTreeRootNode[];

Expand Down Expand Up @@ -125,8 +127,7 @@ export class Explorer implements ITree {
countAriaLabel: plugin.i18n.explorer.count.ariaLabel,
},
) {
this.map = new Map();
this.set = new Set();
this.tooltip = new Tooltip(this.plugin);
}

public path2node(path: string): IFileTreeNodeStores | undefined {
Expand All @@ -149,8 +150,8 @@ export class Explorer implements ITree {

title: this.workspace,

icon: Explorer.ICONS.workspace,
iconAriaLabel: this.plugin.i18n.explorer.workspace.name,
icon: Icon.make(FileTreeNodeType.Root, "./"),
iconAriaLabel: this.tooltip.make(FileTreeNodeType.Root, "./"),

text: this.plugin.i18n.explorer.workspace.name,
textAriaLabel: "./",
Expand Down Expand Up @@ -194,42 +195,44 @@ export class Explorer implements ITree {
/* 打开事件 */
public readonly open = (e: ComponentEvents<Node>["open"]) => {
// plugin.logger.debug(e);
const props = e.detail.props;
const node = e.detail.props;
this.select.one(node);

switch (get(props.type)) {
switch (get(node.type)) {
case FileTreeNodeType.File: { // 打开文件
const filename = get(props.name);
const path = get(props.relative);
const ext = extname(filename); // 文件扩展名
const path = get(node.relative);
const icon = get(node.icon);
const ext = extname(path); // 文件扩展名
if (isBinaryExt(ext)) {
this.plugin.siyuan.confirm(
fn__code(filename), // 标题
fn__code(path), // 标题
[
this.plugin.i18n.message.binaryError,
"",
ft__primary(this.plugin.i18n.message.openAnyway),
].join("<br />"), // 文本
async () => {
this.plugin.openWorkspaceFile(path);
this.plugin.openWorkspaceFile(path, icon);
}, // 确认按钮回调
);
}
else {
this.plugin.openWorkspaceFile(path);
this.plugin.openWorkspaceFile(path, icon);
}
break;
}
case FileTreeNodeType.Root:
case FileTreeNodeType.Folder:
default: // 切换文件夹折叠状态
switch (get(props.folded)) {
switch (get(node.folded)) {
case true:
props.folded.set(false);
props.icon.set(Explorer.ICONS.folder_opend);
node.folded.set(false);
Icon.expand(node);
break;
case false:
default:
props.folded.set(true);
props.icon.set(Explorer.ICONS.folder_closed);
node.folded.set(true);
Icon.collapse(node);
break;
}
break;
Expand Down Expand Up @@ -261,6 +264,10 @@ export class Explorer implements ITree {
}
}

/**
* 动态生成文件图标
*/

/**
* 列出指定目录下的资源
* @param relative: 相对于工作空间目录的路径
Expand Down Expand Up @@ -329,8 +336,8 @@ export class Explorer implements ITree {

title: item.path,

icon: Explorer.ICONS.folder_closed,
iconAriaLabel: this.plugin.i18n.explorer.folder.ariaLabel,
icon: Icon.make(FileTreeNodeType.Folder, item.relative),
iconAriaLabel: this.tooltip.make(FileTreeNodeType.Folder, item.relative),

text: item.name,
textAriaLabel: item.relative,
Expand All @@ -351,8 +358,8 @@ export class Explorer implements ITree {
title: item.path,
symlink: item.isSymlink,

icon: "#iconFile",
iconAriaLabel: this.plugin.i18n.explorer.file.ariaLabel,
icon: Icon.make(FileTreeNodeType.File, item.relative),
iconAriaLabel: this.tooltip.make(FileTreeNodeType.File, item.relative),

text: item.name,
textAriaLabel: item.relative,
Expand Down Expand Up @@ -382,9 +389,7 @@ export class Explorer implements ITree {

/* 展开并更新图标 */
node.folded.set(false);
if (get(node.type) === FileTreeNodeType.Folder) {
node.icon.set(Explorer.ICONS.folder_opend);
}
Icon.expand(node);
}

/**
Expand All @@ -399,10 +404,9 @@ export class Explorer implements ITree {
this.call(
node,
node => {
/* 折叠节点并更新图标 */
node.folded.set(true);
if (get(node.type) === FileTreeNodeType.Folder) {
node.icon.set(Explorer.ICONS.folder_closed);
}
Icon.collapse(node);
},
recursive,
);
Expand Down
36 changes: 36 additions & 0 deletions src/explorer/select.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Copyright (C) 2023 Zuoqiu Yingyi
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import type { IFileTreeNodeStores } from "@workspace/components/siyuan/tree/file";

/* 管理节点的选中 */
export class Select {
/* 选中的节点集合 */
protected readonly selected: Set<IFileTreeNodeStores> = new Set();

/**
* 仅选中一个节点
* 取消其他所有节点的选中状态
*/
public one(node: IFileTreeNodeStores) {
node.focus.set(true);
this.selected.delete(node);
this.selected.forEach(node => node.focus.set(false));
this.selected.clear();
this.selected.add(node);
}
}
50 changes: 50 additions & 0 deletions src/explorer/tooltip.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* Copyright (C) 2023 Zuoqiu Yingyi
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import type MonacoEditorPlugin from "@/index";
import { FileTreeNodeType } from "@workspace/components/siyuan/tree/file";
import { parse } from "@workspace/utils/path/browserify";
import { Icon } from "./icon";

/* 提示信息管理 */
export class Tooltip {
protected readonly i18n: MonacoEditorPlugin["i18n"];
constructor(
public readonly plugin: InstanceType<typeof MonacoEditorPlugin>, // 插件对象
) {
this.i18n = this.plugin.i18n;
}

/* 根据节点信息生成提示信息 */
public make(type: FileTreeNodeType, path: string): string {
switch (type) {
case FileTreeNodeType.Root:
return this.i18n.explorer.workspace.name;
case FileTreeNodeType.Folder:
return this.i18n.explorer.folder.ariaLabel;
case FileTreeNodeType.File: {
const info = parse(path); // 节点路径信息
switch (true) {
case info.ext === ".sy": // 思源文件
return this.i18n.explorer.tooltips.siyuanDoc;
default:
return this.i18n.explorer.file.ariaLabel;
}
}
}
}
}
Loading

0 comments on commit 32fff26

Please sign in to comment.