Add reMarkable browser modal with import and conversion options

The browser modal allows users to navigate their reMarkable file structure, view documents and folders, and perform
actions on individual files. Users can either import documents directly or convert handwriting to Markdown during
import.

The implementation includes:
- New ribbon icon and command to open the browser
- Modal UI with navigation controls (up/refresh)
- Document listing with folder traversal
- Per-file actions: Import and Handwriting to Markdown
- Proper error handling and user feedback
- Comprehensive tests for the new functionality

The downloader was also enhanced to support the new conversion options through a more flexible interface.
This commit is contained in:
2026-05-31 17:41:40 +02:00
parent 2f14e8c1fa
commit 07f4c27d58
9 changed files with 372 additions and 29 deletions
+75
View File
@@ -42,6 +42,50 @@ export class PluginSettingTab {
}
}
export class Modal {
app: any;
contentEl = createElement();
constructor(app: any) {
this.app = app;
}
open(): void {
this.onOpen();
}
close(): void {
this.onClose();
}
onOpen(): void {}
onClose(): void {}
}
export class ButtonComponent {
static instances: ButtonComponent[] = [];
buttonEl = createElement();
private callback: (() => void | Promise<void>) | null = null;
constructor(_containerEl: any) {
ButtonComponent.instances.push(this);
}
setButtonText(text: string): this {
this.buttonEl.text = text;
return this;
}
onClick(callback: () => void | Promise<void>): this {
this.callback = callback;
return this;
}
click(): void | Promise<void> {
return this.callback?.();
}
}
export class Setting {
constructor(_containerEl: any) {}
@@ -72,6 +116,37 @@ export class Setting {
}
}
function createElement(): any {
const element: any = {
children: [],
text: "",
empty: () => {
element.children = [];
},
createEl: (_tag: string, options: any = {}) => {
const child = createElement();
child.text = options.text || "";
child.cls = options.cls || "";
element.children.push(child);
return child;
},
createDiv: (options: any = {}) => {
const child = createElement();
child.cls = options.cls || "";
element.children.push(child);
return child;
},
createSpan: (options: any = {}) => {
const child = createElement();
child.text = options.text || "";
child.cls = options.cls || "";
element.children.push(child);
return child;
},
};
return element;
}
function createControl(): any {
const control: any = {
inputEl: {},