Skip to content

Commit a868ca9

Browse files
committed
refactor: migrate to svelte 5, manual fixes
1 parent 938ff8c commit a868ca9

12 files changed

+165
-141
lines changed

esbuild.config.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ const context = await esbuild.context({
4444
treeShaking: true,
4545
platform: "browser",
4646
minify: prod,
47+
conditions: [prod ? "production" : "development"], // https://www.npmjs.com/package/esm-env
4748
plugins: [
4849
esbuildSvelte({
4950
compilerOptions: {

src/ui/history/components/logComponent.svelte

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,18 @@
1414
plugin: ObsidianGit;
1515
}
1616
17-
let {
18-
log,
19-
view,
20-
showTree,
21-
plugin
22-
}: Props = $props();
17+
let { log, view, showTree, plugin }: Props = $props();
2318
let logsHierarchy = $derived({
2419
title: "",
2520
path: "",
2621
vaultPath: "",
2722
children: plugin.gitManager.getTreeStructure(log.diff.files),
2823
});
2924
30-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
31-
let side = $derived((view.leaf.getRoot() as any).side == "left" ? "right" : "left");
25+
let side = $derived(
26+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
27+
(view.leaf.getRoot() as any).side == "left" ? "right" : "left"
28+
);
3229
let isCollapsed = $state(true);
3330
3431
function authorToString(log: LogEntry) {

src/ui/history/components/logFileComponent.svelte

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
<script lang="ts">
2-
import { stopPropagation, createBubbler } from 'svelte/legacy';
3-
4-
const bubble = createBubbler();
52
import { setIcon, TFile } from "obsidian";
63
import type { DiffFile } from "src/types";
74
import {
@@ -20,15 +17,18 @@
2017
let { diff, view }: Props = $props();
2118
let buttons: HTMLElement[] = $state([]);
2219
23-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
24-
let side = $derived((view.leaf.getRoot() as any).side == "left" ? "right" : "left");
20+
let side = $derived(
21+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
22+
(view.leaf.getRoot() as any).side == "left" ? "right" : "left"
23+
);
2524
2625
window.setTimeout(
2726
() => buttons.forEach((b) => setIcon(b, b.getAttr("data-icon")!)),
2827
0
2928
);
3029
3130
function mainClick(event: MouseEvent) {
31+
event.stopPropagation();
3232
if (fileIsBinary(diff.path)) {
3333
open(event);
3434
} else {
@@ -37,6 +37,7 @@
3737
}
3838
3939
function open(event: MouseEvent) {
40+
event.stopPropagation();
4041
const file = view.app.vault.getAbstractFileByPath(diff.vaultPath);
4142
4243
if (file instanceof TFile) {
@@ -61,8 +62,9 @@
6162
<!-- svelte-ignore a11y_no_static_element_interactions -->
6263
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
6364
<main
64-
onclick={stopPropagation(mainClick)}
65-
onauxclick={stopPropagation((event) => {
65+
onclick={mainClick}
66+
onauxclick={(event) => {
67+
event.stopPropagation();
6668
if (event.button == 2)
6769
mayTriggerFileMenu(
6870
view.app,
@@ -72,8 +74,7 @@
7274
"git-history"
7375
);
7476
else mainClick(event);
75-
})}
76-
onfocus={bubble('focus')}
77+
}}
7778
class="tree-item nav-file"
7879
>
7980
<div
@@ -92,10 +93,10 @@
9293
data-icon="go-to-file"
9394
aria-label="Open File"
9495
bind:this={buttons[0]}
95-
onauxclick={stopPropagation(open)}
96-
onclick={stopPropagation(open)}
96+
onauxclick={open}
97+
onclick={open}
9798
class="clickable-icon"
98-
></div>
99+
></div>
99100
{/if}
100101
</div>
101102
<span class="type" data-type={diff.status}>{diff.status}</span>

src/ui/history/components/logTreeComponent.svelte

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,26 @@
11
<!-- tslint:disable ts(2345) -->
22
<script lang="ts">
3-
import LogTreeComponent from './logTreeComponent.svelte';
3+
import LogTreeComponent from "./logTreeComponent.svelte";
44
import type ObsidianGit from "src/main";
55
import type { HistoryRootTreeItem, TreeItem } from "src/types";
66
import { slide } from "svelte/transition";
77
import type HistoryView from "../historyView";
88
import LogFileComponent from "./logFileComponent.svelte";
9+
910
interface Props {
1011
hierarchy: HistoryRootTreeItem;
1112
plugin: ObsidianGit;
1213
view: HistoryView;
1314
topLevel?: boolean;
1415
}
1516
16-
let {
17-
hierarchy,
18-
plugin,
19-
view,
20-
topLevel = false
21-
}: Props = $props();
17+
let { hierarchy, plugin, view, topLevel = false }: Props = $props();
2218
const closed: Record<string, boolean> = $state({});
2319
24-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
25-
let side = $derived((view.leaf.getRoot() as any).side == "left" ? "right" : "left");
20+
let side = $derived(
21+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
22+
(view.leaf.getRoot() as any).side == "left" ? "right" : "left"
23+
);
2624
2725
function fold(item: TreeItem) {
2826
closed[item.title] = !closed[item.title];
@@ -51,7 +49,7 @@
5149
<div
5250
data-icon="folder"
5351
style="padding-right: 5px; display: flex; "
54-
></div>
52+
></div>
5553
<div
5654
class="tree-item-icon nav-folder-collapse-indicator collapse-icon"
5755
class:is-collapsed={closed[entity.title]}
@@ -80,7 +78,11 @@
8078
class="tree-item-children nav-folder-children"
8179
transition:slide|local={{ duration: 150 }}
8280
>
83-
<LogTreeComponent hierarchy={entity} {plugin} {view} />
81+
<LogTreeComponent
82+
hierarchy={entity as HistoryRootTreeItem}
83+
{plugin}
84+
{view}
85+
/>
8486
</div>
8587
{/if}
8688
</div>

src/ui/history/historyView.svelte

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
<script lang="ts">
2-
import { run } from 'svelte/legacy';
3-
42
import { setIcon, type EventRef } from "obsidian";
53
import { SimpleGit } from "src/gitManager/simpleGit";
64
import type ObsidianGit from "src/main";
@@ -15,14 +13,14 @@
1513
}
1614
1715
let { plugin = $bindable(), view }: Props = $props();
18-
let loading: boolean = $state();
16+
let loading: boolean = $state(false);
1917
let buttons: HTMLElement[] = $state([]);
2018
let logs: LogEntry[] | undefined = $state();
2119
let showTree: boolean = $state(plugin.settings.treeStructure);
2220
let refreshRef: EventRef;
2321
24-
let layoutBtn: HTMLElement = $state();
25-
run(() => {
22+
let layoutBtn: HTMLElement | undefined = $state();
23+
$effect(() => {
2624
if (layoutBtn) {
2725
layoutBtn.empty();
2826
setIcon(layoutBtn, showTree ? "list" : "folder");
@@ -38,7 +36,7 @@
3836
plugin.app.workspace.onLayoutReady(() => {
3937
window.setTimeout(() => {
4038
buttons.forEach((btn) => setIcon(btn, btn.getAttr("data-icon")!));
41-
setIcon(layoutBtn, showTree ? "list" : "folder");
39+
setIcon(layoutBtn!, showTree ? "list" : "folder");
4240
}, 0);
4341
});
4442
onDestroy(() => {
@@ -80,7 +78,7 @@
8078
plugin.settings.treeStructure = showTree;
8179
void plugin.saveSettings();
8280
}}
83-
></div>
81+
></div>
8482
<div
8583
id="refresh"
8684
class="clickable-icon nav-action-button"
@@ -90,7 +88,7 @@
9088
style="margin: 1px;"
9189
bind:this={buttons[6]}
9290
onclick={triggerRefresh}
93-
></div>
91+
></div>
9492
</div>
9593
</div>
9694

src/ui/history/historyView.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ import { ItemView } from "obsidian";
33
import { HISTORY_VIEW_CONFIG } from "src/constants";
44
import type ObsidianGit from "src/main";
55
import HistoryViewComponent from "./historyView.svelte";
6-
import { mount } from "svelte";
6+
import { mount, unmount } from "svelte";
77

88
export default class HistoryView extends ItemView implements HoverParent {
99
plugin: ObsidianGit;
10-
private _view: HistoryViewComponent | undefined;
10+
private _view: Record<string, any> | undefined;
1111
hoverPopover: HoverPopover | null;
1212

1313
constructor(leaf: WorkspaceLeaf, plugin: ObsidianGit) {
@@ -29,19 +29,25 @@ export default class HistoryView extends ItemView implements HoverParent {
2929
}
3030

3131
onClose(): Promise<void> {
32-
this._view?.$destroy();
32+
if (this._view) {
33+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
34+
unmount(this._view);
35+
}
3336
return super.onClose();
3437
}
3538

3639
reload(): void {
37-
this._view?.$destroy();
40+
if (this._view) {
41+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
42+
unmount(this._view);
43+
}
3844
this._view = mount(HistoryViewComponent, {
39-
target: this.contentEl,
40-
props: {
41-
plugin: this.plugin,
42-
view: this,
43-
},
44-
});
45+
target: this.contentEl,
46+
props: {
47+
plugin: this.plugin,
48+
view: this,
49+
},
50+
});
4551
}
4652

4753
onOpen(): Promise<void> {

src/ui/sourceControl/components/fileComponent.svelte

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
<script lang="ts">
2-
import { stopPropagation, createBubbler } from 'svelte/legacy';
3-
4-
const bubble = createBubbler();
52
import { setIcon, TFile } from "obsidian";
63
import { hoverPreview } from "obsidian-community-lib";
74
import type { GitManager } from "src/gitManager/gitManager";
@@ -24,15 +21,18 @@
2421
let { change, view, manager }: Props = $props();
2522
let buttons: HTMLElement[] = $state([]);
2623
27-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
28-
let side = $derived((view.leaf.getRoot() as any).side == "left" ? "right" : "left");
24+
let side = $derived(
25+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
26+
(view.leaf.getRoot() as any).side == "left" ? "right" : "left"
27+
);
2928
3029
window.setTimeout(
3130
() => buttons.forEach((b) => setIcon(b, b.getAttr("data-icon")!)),
3231
0
3332
);
3433
3534
function mainClick(event: MouseEvent) {
35+
event.stopPropagation();
3636
if (fileIsBinary(change.path)) {
3737
open(event);
3838
} else {
@@ -48,6 +48,7 @@
4848
}
4949
5050
function open(event: MouseEvent) {
51+
event.stopPropagation();
5152
const file = view.app.vault.getAbstractFileByPath(change.vaultPath);
5253
5354
if (file instanceof TFile) {
@@ -57,7 +58,8 @@
5758
}
5859
}
5960
60-
function stage() {
61+
function stage(event: MouseEvent) {
62+
event.stopPropagation();
6163
manager
6264
.stage(change.path, false)
6365
.catch((e) => view.plugin.displayError(e))
@@ -67,14 +69,16 @@
6769
}
6870
6971
function showDiff(event: MouseEvent) {
72+
event.stopPropagation();
7073
view.plugin.tools.openDiff({
7174
aFile: change.path,
7275
aRef: "",
7376
event,
7477
});
7578
}
7679
77-
function discard() {
80+
function discard(event: MouseEvent) {
81+
event.stopPropagation();
7882
const deleteFile = change.workingDir == "U";
7983
new DiscardModal(view.app, deleteFile, change.vaultPath).myOpen().then(
8084
(shouldDiscard) => {
@@ -104,10 +108,12 @@
104108
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
105109
<!-- svelte-ignore a11y_no_static_element_interactions -->
106110
<!-- svelte-ignore a11y_unknown_aria_attribute -->
111+
<!-- svelte-ignore a11y_mouse_events_have_key_events -->
107112
<main
108113
onmouseover={hover}
109-
onclick={stopPropagation(mainClick)}
110-
onauxclick={stopPropagation((event) => {
114+
onclick={mainClick}
115+
onauxclick={(event) => {
116+
event.stopPropagation();
111117
if (event.button == 2)
112118
mayTriggerFileMenu(
113119
view.app,
@@ -117,8 +123,7 @@
117123
"git-source-control"
118124
);
119125
else mainClick(event);
120-
})}
121-
onfocus={bubble('focus')}
126+
}}
122127
class="tree-item nav-file"
123128
>
124129
<div
@@ -142,25 +147,25 @@
142147
data-icon="go-to-file"
143148
aria-label="Open File"
144149
bind:this={buttons[1]}
145-
onauxclick={stopPropagation(open)}
146-
onclick={stopPropagation(open)}
150+
onauxclick={open}
151+
onclick={open}
147152
class="clickable-icon"
148-
></div>
153+
></div>
149154
{/if}
150155
<div
151156
data-icon="undo"
152157
aria-label="Discard"
153158
bind:this={buttons[0]}
154-
onclick={stopPropagation(discard)}
159+
onclick={discard}
155160
class="clickable-icon"
156-
></div>
161+
></div>
157162
<div
158163
data-icon="plus"
159164
aria-label="Stage"
160165
bind:this={buttons[2]}
161-
onclick={stopPropagation(stage)}
166+
onclick={stage}
162167
class="clickable-icon"
163-
></div>
168+
></div>
164169
</div>
165170
<div class="type" data-type={change.workingDir}>
166171
{change.workingDir}

0 commit comments

Comments
 (0)