summaryrefslogtreecommitdiffhomepage
path: root/src/settings-modal.ts
blob: 4fb089f5c1fa2a0ea407bddade0cb4208c93a9df (plain)
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
import { Modal, Setting } from "obsidian";
import type AIOrganizer from "./main";

export class SettingsModal extends Modal {
	private plugin: AIOrganizer;

	constructor(plugin: AIOrganizer) {
		super(plugin.app);
		this.plugin = plugin;
	}

	onOpen(): void {
		const { contentEl } = this;
		contentEl.empty();
		contentEl.addClass("ai-organizer-settings-modal");

		this.setTitle("AI Settings");

		// Ollama URL setting
		new Setting(contentEl)
			.setName("Ollama URL")
			.setDesc("Base URL of the Ollama server.")
			.addText((text) =>
				text
					.setValue(this.plugin.settings.ollamaUrl)
					.onChange(async (value) => {
						this.plugin.settings.ollamaUrl = value;
						await this.plugin.saveSettings();
					}),
			);

		// Model dropdown
		let modelDropdownSelectEl: HTMLSelectElement | null = null;

		const modelSetting = new Setting(contentEl)
			.setName("Model")
			.setDesc("Select the model to use.")
			.addDropdown((dropdown) => {
				this.populateModelDropdown(dropdown.selectEl);
				dropdown.onChange(async (value) => {
					this.plugin.settings.model = value;
					await this.plugin.saveSettings();
				});
				modelDropdownSelectEl = dropdown.selectEl;
			});

		// Connect button
		const connectSetting = new Setting(contentEl)
			.setName("Connect")
			.setDesc(this.plugin.connectionMessage);

		connectSetting.addButton((button) =>
			button.setButtonText("Connect").onClick(async () => {
				const descEl = connectSetting.descEl;
				descEl.setText("Connecting...");

				await this.plugin.connect();

				descEl.setText(this.plugin.connectionMessage);

				if (modelDropdownSelectEl !== null) {
					this.populateModelDropdown(modelDropdownSelectEl);
				}
			}),
		);

		// Move connect above model in the DOM
		contentEl.insertBefore(connectSetting.settingEl, modelSetting.settingEl);
	}

	onClose(): void {
		this.contentEl.empty();
	}

	private populateModelDropdown(selectEl: HTMLSelectElement): void {
		const models = this.plugin.availableModels;

		selectEl.empty();

		if (models.length === 0) {
			const placeholderOpt = selectEl.createEl("option", {
				text: "Connect first",
				attr: { value: "" },
			});
			placeholderOpt.value = "";
			selectEl.disabled = true;
			return;
		}

		const placeholderOpt = selectEl.createEl("option", {
			text: "Select a model...",
			attr: { value: "" },
		});
		placeholderOpt.value = "";

		for (const modelName of models) {
			const opt = selectEl.createEl("option", {
				text: modelName,
				attr: { value: modelName },
			});
			opt.value = modelName;
		}

		if (
			this.plugin.settings.model !== "" &&
			models.includes(this.plugin.settings.model)
		) {
			selectEl.value = this.plugin.settings.model;
		}

		selectEl.disabled = false;
	}
}