Skip to content

Commit 4110617

Browse files
committed
feat(Modal): Show file changes before performing sync.
1 parent 4462cfd commit 4110617

File tree

4 files changed

+115
-4
lines changed

4 files changed

+115
-4
lines changed

src/loadingModal.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { App, Modal } from "obsidian";
2+
import type InvioPlugin from "./main"; // unavoidable
3+
import type { TransItemType } from "./i18n";
4+
import svg from './utils/svg';
5+
6+
export class LoadingModal extends Modal {
7+
readonly plugin: InvioPlugin;
8+
constructor(app: App, plugin: InvioPlugin) {
9+
super(app);
10+
this.plugin = plugin;
11+
}
12+
13+
onOpen() {
14+
let { contentEl } = this;
15+
const t = (x: TransItemType, vars?: any) => {
16+
return this.plugin.i18n.t(x, vars);
17+
};
18+
19+
contentEl.createEl("h2", {
20+
text: 'Checking Sync Files'
21+
});
22+
23+
const loadingContainer = contentEl.createDiv('loading-container');
24+
25+
const loadingSVG = `<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
26+
width="36px" height="45px" viewBox="0 0 24 30" style="enable-background:new 0 0 50 50;" xml:space="preserve">
27+
<rect x="0" y="13" width="4" height="5" fill="currentColor">
28+
<animate attributeName="height" attributeType="XML"
29+
values="5;21;5"
30+
begin="0s" dur="0.6s" repeatCount="indefinite" />
31+
<animate attributeName="y" attributeType="XML"
32+
values="13; 5; 13"
33+
begin="0s" dur="0.6s" repeatCount="indefinite" />
34+
</rect>
35+
<rect x="10" y="13" width="4" height="5" fill="currentColor">
36+
<animate attributeName="height" attributeType="XML"
37+
values="5;21;5"
38+
begin="0.15s" dur="0.6s" repeatCount="indefinite" />
39+
<animate attributeName="y" attributeType="XML"
40+
values="13; 5; 13"
41+
begin="0.15s" dur="0.6s" repeatCount="indefinite" />
42+
</rect>
43+
<rect x="20" y="13" width="4" height="5" fill="currentColor">
44+
<animate attributeName="height" attributeType="XML"
45+
values="5;21;5"
46+
begin="0.3s" dur="0.6s" repeatCount="indefinite" />
47+
<animate attributeName="y" attributeType="XML"
48+
values="13; 5; 13"
49+
begin="0.3s" dur="0.6s" repeatCount="indefinite" />
50+
</rect>
51+
</svg>`;
52+
let content = loadingSVG;
53+
content = content.replace(/(\r\n|\n|\r)/gm, '');
54+
content = content.replace(/>\s+</gm, '><');
55+
content = svg.extract(content);
56+
content = svg.setFontSize(content, 28);
57+
58+
loadingContainer.innerHTML = content;
59+
}
60+
61+
onClose() {
62+
let { contentEl } = this;
63+
contentEl.empty();
64+
}
65+
}

src/main.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import type { LangType, LangTypeAndAuto, TransItemType } from "./i18n";
4747
import { DeletionOnRemote, MetadataOnRemote } from "./metadataOnRemote";
4848
import { SyncAlgoV2Modal } from "./syncAlgoV2Notice";
4949
import { TouchedPlanModel } from './touchedPlanModel';
50+
import { LoadingModal } from './loadingModal';
5051

5152
import { applyLogWriterInplace, log } from "./moreOnLog";
5253
import AggregateError from "aggregate-error";
@@ -183,6 +184,11 @@ export default class InvioPlugin extends Plugin {
183184
maxSteps: `${MAX_STEPS}`,
184185
})
185186
);
187+
188+
189+
const loading = new LoadingModal(this.app, this);
190+
loading.open();
191+
186192
this.syncStatus = "getting_remote_files_list";
187193
const self = this;
188194
const client = new RemoteClient(
@@ -285,6 +291,8 @@ export default class InvioPlugin extends Plugin {
285291
log.info('plan.mixedStates: ', plan.mixedStates, touchedFileMap); // for debugging
286292

287293
try {
294+
loading.close();
295+
288296
await new Promise((resolve, reject) => {
289297
const touchedPlanModel = new TouchedPlanModel(this.app, this, touchedFileMap, (pub: boolean) => {
290298
log.info('user confirmed: ', pub);

src/touchedPlanModel.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import { App, Modal, Notice, PluginSettingTab, Setting } from "obsidian";
22
import type InvioPlugin from "./main"; // unavoidable
33
import type { TransItemType } from "./i18n";
4+
import { createElement, FilePlus2, Trash } from "lucide";
45

56
import { log } from "./moreOnLog";
67
import { FileOrFolderMixedState } from "./baseTypes";
78

89
export class TouchedPlanModel extends Modal {
910
agree: boolean;
1011
readonly plugin: InvioPlugin;
11-
hook: (agree: boolean) => void;
1212
readonly files: Record<string, FileOrFolderMixedState>;
13+
hook: (agree: boolean) => void;
1314
constructor(app: App, plugin: InvioPlugin, fileMap: Record<string, FileOrFolderMixedState>, cb: (agree: boolean) => void) {
1415
super(app);
1516
this.plugin = plugin;
@@ -51,17 +52,28 @@ export class TouchedPlanModel extends Modal {
5152
});
5253

5354
new Setting(contentEl)
54-
.setDesc('在做同步操作之前,请检查文件变更列表,确认所有变更是否符合预期')
55+
.setDesc('Please check the file changes list to confirm that all changes are as expected.')
5556

5657
if (toRemoteFiles?.length > 0) {
5758
contentEl.createEl("h4", {
5859
text: 'Remote files to be modifed'
5960
});
6061
const ulRemote = contentEl.createEl("ul");
6162
toRemoteFiles.forEach((val) => {
62-
ulRemote.createEl("li", {
63-
text: val.key + ' - ' + (val.decision === 'uploadLocalToRemote' ? '➕' : '➖'),
63+
const li = ulRemote.createEl("li", {
64+
text: val.key,
65+
cls: 'file-item-action'
6466
});
67+
if (val.decision === 'uploadLocalToRemote') {
68+
const iconSvgSyncPending = createElement(FilePlus2);
69+
iconSvgSyncPending.addClass('file-item-action-icon')
70+
li.appendChild(iconSvgSyncPending)
71+
} else {
72+
Trash
73+
const iconSvgTrash = createElement(Trash);
74+
iconSvgTrash.addClass('file-item-action-icon')
75+
li.appendChild(iconSvgTrash)
76+
}
6577
});
6678
}
6779

styles.css

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,30 @@
122122
.settings-pub-header {
123123
display: block;
124124
margin-bottom: 15px;
125+
}
126+
127+
.loading-container {
128+
display: flex;
129+
justify-content: center;
130+
align-items: center;
131+
height: 68px;
132+
width: 100%;
133+
}
134+
135+
.hide-loading-container {
136+
display: none;
137+
}
138+
139+
.file-item-action {
140+
margin: 8px auto;
141+
display: flex;
142+
justify-content: flex-start;
143+
align-items: center;
144+
}
145+
146+
.file-item-action-icon {
147+
font-size: var(--font-text-size);
148+
width: var(--font-text-size);
149+
height: var(--font-text-size);
150+
margin: 0 8px;
125151
}

0 commit comments

Comments
 (0)