Skip to content

Commit c5cee5e

Browse files
committed
feat: add IP validation with regex pattern and visual feedback
Fixes #18
1 parent 1104467 commit c5cee5e

File tree

1 file changed

+108
-92
lines changed

1 file changed

+108
-92
lines changed

src/settings.ts

Lines changed: 108 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,111 +1,127 @@
1-
import SupernotePlugin from "./main";
2-
import { App, PluginSettingTab, Setting } from 'obsidian';
1+
import SupernotePlugin from "./main";
2+
import { App, ExtraButtonComponent, PluginSettingTab, Setting } from 'obsidian';
3+
4+
const IP_VALIDATION_PATTERN = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/;
35

46

57
export interface SupernotePluginSettings {
6-
directConnectIP: string;
7-
invertColorsWhenDark: boolean;
8-
showTOC: boolean;
9-
showExportButtons: boolean;
10-
collapseRecognizedText: boolean,
11-
noteImageMaxDim: number;
8+
directConnectIP: string;
9+
invertColorsWhenDark: boolean;
10+
showTOC: boolean;
11+
showExportButtons: boolean;
12+
collapseRecognizedText: boolean,
13+
noteImageMaxDim: number;
1214
}
1315

1416
export const DEFAULT_SETTINGS: SupernotePluginSettings = {
15-
directConnectIP: '',
16-
invertColorsWhenDark: true,
17-
showTOC: true,
18-
showExportButtons: true,
19-
collapseRecognizedText: false,
20-
noteImageMaxDim: 800, // Sensible default for Nomad pages to be legible but not too big. Unit: px
17+
directConnectIP: '',
18+
invertColorsWhenDark: true,
19+
showTOC: true,
20+
showExportButtons: true,
21+
collapseRecognizedText: false,
22+
noteImageMaxDim: 800, // Sensible default for Nomad pages to be legible but not too big. Unit: px
2123
}
2224

2325
export class SupernoteSettingTab extends PluginSettingTab {
24-
plugin: SupernotePlugin;
26+
plugin: SupernotePlugin;
2527

26-
constructor(app: App, plugin: SupernotePlugin) {
27-
super(app, plugin);
28-
this.plugin = plugin;
29-
}
28+
constructor(app: App, plugin: SupernotePlugin) {
29+
super(app, plugin);
30+
this.plugin = plugin;
31+
}
3032

31-
display(): void {
32-
const { containerEl } = this;
33+
display(): void {
34+
const { containerEl } = this;
3335

34-
containerEl.empty();
36+
containerEl.empty();
37+
let alert: ExtraButtonComponent;
3538

36-
new Setting(containerEl)
37-
.setName('Supernote IP address')
38-
.setDesc('See Supernote "Screen Mirroring" and "Browse & Access" documentation for how to enable')
39-
.addText(text => text
40-
.setPlaceholder('IP only e.g. 192.168.1.2')
41-
.setValue(this.plugin.settings.directConnectIP)
42-
.onChange(async (value) => {
43-
this.plugin.settings.directConnectIP = value;
44-
await this.plugin.saveSettings();
45-
})
46-
);
39+
new Setting(containerEl)
40+
.setName('Supernote IP address')
41+
.setDesc('(Optional) When using the Supernote "Browse and Access" for document upload/download or "Screen Mirroring" screenshot attachment this is the IP of the Supernote device')
42+
.addText(text => text
43+
.setPlaceholder('IP only e.g. 192.168.1.2')
44+
.setValue(this.plugin.settings.directConnectIP)
45+
.onChange(async (value) => {
46+
if (IP_VALIDATION_PATTERN.test(value) || value === '') {
47+
this.plugin.settings.directConnectIP = value;
48+
alert.extraSettingsEl.style.display = 'none';
49+
await this.plugin.saveSettings();
50+
} else {
51+
alert.extraSettingsEl.style.display = 'inline';
52+
}
53+
})
54+
.inputEl.setAttribute('pattern', IP_VALIDATION_PATTERN.source)
55+
)
56+
.addExtraButton(btn => {
57+
btn.setIcon('alert-triangle')
58+
.setTooltip('Invalid IP format: must be xxx.xxx.xxx.xxx');
59+
btn.extraSettingsEl.style.display = 'none';
60+
alert = btn
61+
return btn;
62+
});
4763

48-
new Setting(containerEl)
49-
.setName('Invert colors in "Dark mode"')
50-
.setDesc('When Obsidian is in "Dark mode" increase image visibility by inverting colors of images')
51-
.addToggle(text => text
52-
.setValue(this.plugin.settings.invertColorsWhenDark)
53-
.onChange(async (value) => {
54-
this.plugin.settings.invertColorsWhenDark = value;
55-
await this.plugin.saveSettings();
56-
})
57-
);
64+
new Setting(containerEl)
65+
.setName('Invert colors in "Dark mode"')
66+
.setDesc('When Obsidian is in "Dark mode" increase image visibility by inverting colors of images')
67+
.addToggle(text => text
68+
.setValue(this.plugin.settings.invertColorsWhenDark)
69+
.onChange(async (value) => {
70+
this.plugin.settings.invertColorsWhenDark = value;
71+
await this.plugin.saveSettings();
72+
})
73+
);
5874

59-
new Setting(containerEl)
60-
.setName('Show table of contents and page headings')
61-
.setDesc(
62-
'When viewing .note files, show a table of contents and page number headings',
63-
)
64-
.addToggle((text) =>
65-
text
66-
.setValue(this.plugin.settings.showTOC)
67-
.onChange(async (value) => {
68-
this.plugin.settings.showTOC = value;
69-
await this.plugin.saveSettings();
70-
}),
71-
);
75+
new Setting(containerEl)
76+
.setName('Show table of contents and page headings')
77+
.setDesc(
78+
'When viewing .note files, show a table of contents and page number headings',
79+
)
80+
.addToggle((text) =>
81+
text
82+
.setValue(this.plugin.settings.showTOC)
83+
.onChange(async (value) => {
84+
this.plugin.settings.showTOC = value;
85+
await this.plugin.saveSettings();
86+
}),
87+
);
7288

73-
new Setting(containerEl)
74-
.setName('Show export buttons')
75-
.setDesc(
76-
'When viewing .note files, show buttons for exporting images and/or markdown files to vault. These features can still be accessed via the command pallete.',
77-
)
78-
.addToggle((text) =>
79-
text
80-
.setValue(this.plugin.settings.showExportButtons)
81-
.onChange(async (value) => {
82-
this.plugin.settings.showExportButtons = value;
83-
await this.plugin.saveSettings();
84-
}),
85-
);
89+
new Setting(containerEl)
90+
.setName('Show export buttons')
91+
.setDesc(
92+
'When viewing .note files, show buttons for exporting images and/or markdown files to vault. These features can still be accessed via the command pallete.',
93+
)
94+
.addToggle((text) =>
95+
text
96+
.setValue(this.plugin.settings.showExportButtons)
97+
.onChange(async (value) => {
98+
this.plugin.settings.showExportButtons = value;
99+
await this.plugin.saveSettings();
100+
}),
101+
);
86102

87-
new Setting(containerEl)
88-
.setName('Collapse recognized text')
89-
.setDesc('When viewing .note files, hide recognized text in a collapsible element. This does not affect exported markdown.')
90-
.addToggle(text => text
91-
.setValue(this.plugin.settings.collapseRecognizedText)
92-
.onChange(async (value) => {
93-
this.plugin.settings.collapseRecognizedText = value;
94-
await this.plugin.saveSettings();
95-
})
96-
);
103+
new Setting(containerEl)
104+
.setName('Collapse recognized text')
105+
.setDesc('When viewing .note files, hide recognized text in a collapsible element. This does not affect exported markdown.')
106+
.addToggle(text => text
107+
.setValue(this.plugin.settings.collapseRecognizedText)
108+
.onChange(async (value) => {
109+
this.plugin.settings.collapseRecognizedText = value;
110+
await this.plugin.saveSettings();
111+
})
112+
);
97113

98-
new Setting(containerEl)
99-
.setName('Max image side length in .note files')
100-
.setDesc('Maximum width and height (in pixels) of the note image when viewing .note files. Does not affect exported images and markdown.')
101-
.addSlider(text => text
102-
.setLimits(200, 1900, 100) // Resolution of an A5X/A6X2/Nomad page is 1404 x 1872 px (with no upscaling)
103-
.setDynamicTooltip()
104-
.setValue(this.plugin.settings.noteImageMaxDim)
105-
.onChange(async (value) => {
106-
this.plugin.settings.noteImageMaxDim = value;
107-
await this.plugin.saveSettings();
108-
})
109-
);
110-
}
114+
new Setting(containerEl)
115+
.setName('Max image side length in .note files')
116+
.setDesc('Maximum width and height (in pixels) of the note image when viewing .note files. Does not affect exported images and markdown.')
117+
.addSlider(text => text
118+
.setLimits(200, 1900, 100) // Resolution of an A5X/A6X2/Nomad page is 1404 x 1872 px (with no upscaling)
119+
.setDynamicTooltip()
120+
.setValue(this.plugin.settings.noteImageMaxDim)
121+
.onChange(async (value) => {
122+
this.plugin.settings.noteImageMaxDim = value;
123+
await this.plugin.saveSettings();
124+
})
125+
);
126+
}
111127
}

0 commit comments

Comments
 (0)