feat(settings,docs): vault subpath becomes the chats folder, panel screenshots in the readme
This commit is contained in:
+15
-6
@@ -230,7 +230,16 @@ export default class BeaverPlugin extends Plugin {
|
||||
}
|
||||
|
||||
async loadSettings(): Promise<void> {
|
||||
this.settings = { ...DEFAULT_SETTINGS, ...(await this.loadData()) };
|
||||
const stored = ((await this.loadData()) ??
|
||||
{}) as Partial<BeaverSettings> & {
|
||||
vaultSubpath?: string;
|
||||
};
|
||||
// The setting used to be called "vault subpath"; carry the value over.
|
||||
const { vaultSubpath, ...rest } = stored;
|
||||
this.settings = { ...DEFAULT_SETTINGS, ...rest };
|
||||
if (vaultSubpath && !rest.chatsFolder) {
|
||||
this.settings.chatsFolder = vaultSubpath;
|
||||
}
|
||||
}
|
||||
|
||||
async saveSettings(): Promise<void> {
|
||||
@@ -431,16 +440,16 @@ export default class BeaverPlugin extends Plugin {
|
||||
}
|
||||
|
||||
private gatewayFilename(file: TFile): string | null {
|
||||
const subpath = this.settings.vaultSubpath;
|
||||
if (!subpath) {
|
||||
const folder = this.settings.chatsFolder;
|
||||
if (!folder) {
|
||||
return file.path;
|
||||
}
|
||||
const prefix = `${subpath}/`;
|
||||
if (file.path === subpath || file.path.startsWith(prefix)) {
|
||||
const prefix = `${folder}/`;
|
||||
if (file.path === folder || file.path.startsWith(prefix)) {
|
||||
return file.path.slice(prefix.length);
|
||||
}
|
||||
new Notice(
|
||||
`Beaver: file ${file.path} is outside the configured vault subpath (${subpath})`,
|
||||
`Beaver: file ${file.path} is outside the chats folder (${folder})`,
|
||||
8000
|
||||
);
|
||||
return null;
|
||||
|
||||
+11
-8
@@ -5,18 +5,20 @@ import type BeaverPlugin from "./main";
|
||||
export interface BeaverSettings {
|
||||
apiBaseUrl: string;
|
||||
baseUrl: string;
|
||||
// Folder in this vault where the deep chats live: the gateway's markdown
|
||||
// frontend reads and writes there, so paths it hands out are relative to it.
|
||||
chatsFolder: string;
|
||||
token: string;
|
||||
vaultSubpath: string;
|
||||
}
|
||||
|
||||
export const DEFAULT_SETTINGS: BeaverSettings = {
|
||||
apiBaseUrl: "",
|
||||
baseUrl: "http://localhost:62993",
|
||||
chatsFolder: "",
|
||||
token: "",
|
||||
vaultSubpath: "",
|
||||
};
|
||||
|
||||
export function normalizeSubpath(raw: string): string {
|
||||
export function normalizeFolder(raw: string): string {
|
||||
return raw.trim().replace(/^\/+|\/+$/g, "");
|
||||
}
|
||||
|
||||
@@ -93,17 +95,18 @@ export class BeaverSettingsTab extends PluginSettingTab {
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Vault subpath")
|
||||
.setName("Chats folder")
|
||||
.setDesc(
|
||||
"Folder in this Obsidian vault that maps to the gateway's vault root. " +
|
||||
"Leave empty if the two vault roots match. Example: `💬 чаты`."
|
||||
"Folder in this vault where the deep chats live - the one the gateway's " +
|
||||
"markdown frontend writes to. Leave empty if the chats sit at the vault root. " +
|
||||
"Example: `💬 чаты`."
|
||||
)
|
||||
.addText((text) =>
|
||||
text
|
||||
.setPlaceholder("")
|
||||
.setValue(this.plugin.settings.vaultSubpath)
|
||||
.setValue(this.plugin.settings.chatsFolder)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.vaultSubpath = normalizeSubpath(value);
|
||||
this.plugin.settings.chatsFolder = normalizeFolder(value);
|
||||
await this.plugin.saveSettings();
|
||||
})
|
||||
);
|
||||
|
||||
+3
-3
@@ -14,14 +14,14 @@
|
||||
|
||||
interface Props {
|
||||
app: ObsidianApp;
|
||||
chatsFolder: () => string;
|
||||
client: ApiClient | null;
|
||||
component: Component;
|
||||
onOpenSettings: () => void;
|
||||
state: PanelState;
|
||||
vaultSubpath: () => string;
|
||||
}
|
||||
|
||||
let { app, client, component, onOpenSettings, state, vaultSubpath }: Props =
|
||||
let { app, client, component, onOpenSettings, state, chatsFolder }: Props =
|
||||
$props();
|
||||
|
||||
// Menus hang off body, not off the view: Obsidian's sidedocks paint above
|
||||
@@ -41,9 +41,9 @@
|
||||
const host = providePanelHost({
|
||||
...obsidianHost({
|
||||
app,
|
||||
chatsFolder,
|
||||
component,
|
||||
sourcePath: () => state.sourcePath,
|
||||
vaultSubpath,
|
||||
}),
|
||||
cache,
|
||||
});
|
||||
|
||||
+5
-4
@@ -4,11 +4,12 @@ import type { PanelHost } from "$lib/panel/host";
|
||||
|
||||
export interface HostOptions {
|
||||
app: App;
|
||||
// Folder in this vault that maps to the gateway's vault root.
|
||||
// Where the deep chats live in this vault; gateway paths are relative to it.
|
||||
chatsFolder: () => string;
|
||||
component: Component;
|
||||
// The note the panel currently follows; link resolution starts from it.
|
||||
sourcePath: () => string;
|
||||
// Folder in this vault that maps to the gateway's vault root.
|
||||
vaultSubpath: () => string;
|
||||
}
|
||||
|
||||
// The Obsidian side of the panel: markdown through the app's own renderer,
|
||||
@@ -47,8 +48,8 @@ export function obsidianHost(options: HostOptions): PanelHost {
|
||||
window.open(target);
|
||||
},
|
||||
openNote(path) {
|
||||
const subpath = options.vaultSubpath();
|
||||
const full = subpath ? `${subpath}/${path}` : path;
|
||||
const folder = options.chatsFolder();
|
||||
const full = folder ? `${folder}/${path}` : path;
|
||||
app.workspace.openLinkText(full, "", false).catch(() => undefined);
|
||||
},
|
||||
touch: Platform.isMobile,
|
||||
|
||||
+1
-1
@@ -231,11 +231,11 @@ export class PanelView extends ItemView {
|
||||
this.root = mount(App, {
|
||||
props: {
|
||||
app: this.app,
|
||||
chatsFolder: () => this.plugin.settings.chatsFolder,
|
||||
client: this.plugin.apiClient(),
|
||||
component: this,
|
||||
onOpenSettings: () => this.plugin.openSettings(),
|
||||
state: this.state,
|
||||
vaultSubpath: () => this.plugin.settings.vaultSubpath,
|
||||
},
|
||||
target: this.contentEl,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user