/
main.ts
130 lines (113 loc) · 3.28 KB
/
main.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import {
App,
Plugin,
PluginSettingTab,
Setting,
normalizePath,
WorkspaceLeaf,
} from "obsidian";
import {
DEFAULT_SETTINGS,
HEADING_TITLE_PROP_NAME,
PLUGIN_ICON_NAME,
PLUGIN_TITLE,
PLUGIN_VIEW_ID,
} from "src/constants";
import { PluginContext } from "src/context";
import { PluginSettings } from "src/types";
import { getRelativeFileByName } from "src/utils/obsidian";
import HierarchyView from "src/view";
export default class HierarchyViewPlugin extends Plugin {
ctx: PluginContext;
override async onload() {
const settings: PluginSettings = Object.assign(
{},
DEFAULT_SETTINGS,
await this.loadData(),
);
this.ctx = new PluginContext(this, settings);
this.registerView(
PLUGIN_VIEW_ID,
(leaf) => new HierarchyView(leaf, this.ctx),
);
this.addRibbonIcon(PLUGIN_ICON_NAME, PLUGIN_TITLE, () => {
this.activateView();
});
this.addSettingTab(new SettingTab(this.app, this));
}
async activateView() {
const { workspace } = this.app;
let leaf: WorkspaceLeaf | null = null;
const leaves = workspace.getLeavesOfType(PLUGIN_VIEW_ID);
if (leaves.length > 0) {
leaf = leaves[0]!;
} else {
leaf = workspace.getLeftLeaf(false);
await leaf.setViewState({ type: PLUGIN_VIEW_ID, active: true });
}
workspace.revealLeaf(leaf);
}
}
class SettingTab extends PluginSettingTab {
plugin: HierarchyViewPlugin;
constructor(app: App, plugin: HierarchyViewPlugin) {
super(app, plugin);
this.plugin = plugin;
}
display(): void {
const { containerEl } = this;
containerEl.empty();
new Setting(containerEl)
.setName("Parent property name")
.setDesc(
"Required. A property indicating the parent of the note. This will be used to build a hierarchy. To apply the changes correctly, it requires restarting the plugin or app after the change.",
)
.addText((text) =>
text
.setValue(this.plugin.ctx.settings.get("parentPropName"))
.onChange(async (value) => {
this.plugin.ctx.settings.set(
"parentPropName",
value || DEFAULT_SETTINGS.parentPropName,
);
}),
);
new Setting(containerEl)
.setName("Title source")
.setDesc(
`Specify the properties whose first value will be used as the file title.You can specify "${HEADING_TITLE_PROP_NAME}" to use the first-level heading from the file. You can specify multiple values in order of priority by separating them with commas. If none are found or the field is empty, the file name will be used.`,
)
.addText((text) => {
text.setValue(
this.plugin.ctx.settings.get("titlePropNames")?.join(", "),
).onChange(async (value) => {
this.plugin.ctx.settings.set(
"titlePropNames",
value.split(",").map((v) => v.trim()),
);
});
});
new Setting(containerEl)
.setName("Home file path")
.setDesc(
"Optional. A home note for which a quick access button will be created. Enter path relative to vault root.",
)
.addText((text) =>
text
.setValue(
this.plugin.ctx.settings.get("homeFilePath") ?? "",
)
.onChange(async (value) => {
const finalValue = getRelativeFileByName(
this.app,
normalizePath(value),
"",
);
this.plugin.ctx.settings.set(
"homeFilePath",
finalValue?.path || DEFAULT_SETTINGS.homeFilePath,
);
}),
);
}
}