Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 339801f

Browse files
committedFeb 5, 2024
support sync state to multiComponent when use same instance
1 parent fc2c226 commit 339801f

File tree

11 files changed

+173
-34
lines changed

11 files changed

+173
-34
lines changed
 

‎packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"description": "@git-diff-view/core",
44
"author": "MrWangJustToDo",
55
"license": "MIT",
6-
"version": "0.0.2",
6+
"version": "0.0.3",
77
"main": "index.js",
88
"types": "index.d.ts",
99
"files": [

‎packages/core/src/diff-file.ts

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ export class DiffFile {
102102

103103
#unifiedLastStartIndex?: number;
104104

105-
#listeners: (() => void)[] = [];
105+
#listeners: ((() => void) & { isSyncExternal?: boolean })[] = [];
106106

107107
#hasInitRaw: boolean = false;
108108

@@ -132,6 +132,8 @@ export class DiffFile {
132132

133133
#id: string = "";
134134

135+
#clonedInstance = new Map<DiffFile, () => void>();
136+
135137
static createInstance(
136138
data: {
137139
oldFile?: { fileName?: string | null; fileLang?: string | null; content?: string | null };
@@ -786,26 +788,40 @@ export class DiffFile {
786788
return this.#newFileSyntaxLines?.[lineNumber];
787789
};
788790

789-
subscribe = (listener: () => void) => {
791+
subscribe = (listener: (() => void) & { isSyncExternal?: boolean }) => {
790792
this.#listeners.push(listener);
791793

792794
return () => {
793795
this.#listeners.filter((i) => i !== listener);
794796
};
795797
};
796798

797-
notifyAll = () => {
799+
notifyAll = (skipSyncExternal?: boolean) => {
798800
this.#updateCount++;
799-
this.#listeners.forEach((f) => f());
801+
this.#listeners.forEach((f) => {
802+
if (skipSyncExternal && f.isSyncExternal) {
803+
return;
804+
}
805+
f();
806+
});
800807
};
801808

802809
getUpdateCount = () => this.#updateCount;
803810

804811
getNeedShowExpandAll = (mode: "split" | "unified") => {
805812
if (mode === "split") {
806-
return this.#splitLastStartIndex && Number.isFinite(this.#splitLastStartIndex);
813+
return (
814+
this.#splitLastStartIndex &&
815+
Number.isFinite(this.#splitLastStartIndex) &&
816+
(this.getSplitLeftLine(this.splitLineLength - 1)?.isHidden ||
817+
this.getSplitRightLine(this.splitLineLength - 1)?.isHidden)
818+
);
807819
} else {
808-
return this.#unifiedLastStartIndex && Number.isFinite(this.#unifiedLastStartIndex);
820+
return (
821+
this.#unifiedLastStartIndex &&
822+
Number.isFinite(this.#unifiedLastStartIndex) &&
823+
this.getUnifiedLine(this.unifiedLineLength - 1)?.isHidden
824+
);
809825
}
810826
};
811827

@@ -891,6 +907,34 @@ export class DiffFile {
891907
this.notifyAll();
892908
};
893909

910+
_addClonedInstance = (instance: DiffFile) => {
911+
const updateFunc = () => {
912+
this._notifyOthers(instance);
913+
};
914+
915+
updateFunc.isSyncExternal = true;
916+
917+
const unsubscribe = instance.subscribe(updateFunc);
918+
919+
this.#clonedInstance.set(instance, unsubscribe);
920+
};
921+
922+
_notifyOthers = (instance: DiffFile) => {
923+
this.#clonedInstance.forEach((_, i) => {
924+
if (i !== instance) {
925+
i.notifyAll(true);
926+
}
927+
});
928+
};
929+
930+
_delClonedInstance = (instance: DiffFile) => {
931+
const unsubscribe = this.#clonedInstance.get(instance);
932+
933+
unsubscribe && unsubscribe();
934+
935+
this.#clonedInstance.delete(instance);
936+
};
937+
894938
_getFullBundle = () => {
895939
const bundle = this.getBundle();
896940
const oldFileResult = this.#oldFileResult;
@@ -914,4 +958,11 @@ export class DiffFile {
914958
this.#diffLines = data.diffLines;
915959
this.#diffListResults = data.diffListResults;
916960
};
961+
962+
_destroy = () => {
963+
this.clearId();
964+
this.#listeners.splice(0, this.#listeners.length);
965+
this.#clonedInstance.forEach((v) => v());
966+
this.#clonedInstance.clear();
967+
};
917968
}

‎packages/react/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"description": "@git-diff-view/react",
44
"author": "MrWangJustToDo",
55
"license": "MIT",
6-
"version": "0.0.2",
6+
"version": "0.0.3",
77
"main": "index.js",
88
"types": "index.d.ts",
99
"files": [

‎packages/react/src/components/DiffView.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,6 @@ const _InternalDiffView = <T extends unknown>(
235235
onAddWidgetClick,
236236
]);
237237

238-
useUnmount(() => diffFile.clearId(), [diffFile]);
239-
240238
const value = useMemo(() => ({ useDiffContext }), [useDiffContext]);
241239

242240
return (
@@ -305,6 +303,17 @@ export const DiffView = <T extends unknown>(props: DiffViewProps<T>) => {
305303
}
306304
}, [diffFile, props.diffViewHighlight, autoDetectLang, registerHighlighter]);
307305

306+
useEffect(() => {
307+
if (_diffFile && diffFile) {
308+
_diffFile._addClonedInstance(diffFile);
309+
return () => {
310+
_diffFile._delClonedInstance(diffFile);
311+
};
312+
}
313+
}, [diffFile, _diffFile]);
314+
315+
useUnmount(() => diffFile._destroy(), [diffFile]);
316+
308317
if (!diffFile) return null;
309318

310319
return (

‎packages/vue/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"description": "@git-diff-view/vue",
44
"author": "MrWangJustToDo",
55
"license": "MIT",
6-
"version": "0.0.2",
6+
"version": "0.0.3",
77
"main": "index.js",
88
"type": "module",
99
"types": "index.d.ts",

‎packages/vue/src/components/DiffSplitHunkLineNormal.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,32 +83,36 @@ export const DiffSplitHunkLine = defineComponent(
8383
{enableExpand.value ? (
8484
currentIsFirstLine.value ? (
8585
<button
86-
class="w-full hover:bg-blue-300 flex justify-center items-center py-[6px] cursor-pointer rounded-[2px]"
86+
class="w-full diff-widget-tooltip hover:bg-blue-300 flex justify-center items-center py-[6px] cursor-pointer rounded-[2px]"
8787
title="Expand Up"
88+
data-title="Expand Up"
8889
onClick={() => props.diffFile.onSplitHunkExpand("up", props.index)}
8990
>
9091
<ExpandUp className="fill-current" />
9192
</button>
9293
) : currentShowExpandAll.value ? (
9394
<button
94-
class="w-full hover:bg-blue-300 flex justify-center items-center py-[6px] cursor-pointer rounded-[2px]"
95+
class="w-full diff-widget-tooltip hover:bg-blue-300 flex justify-center items-center py-[6px] cursor-pointer rounded-[2px]"
9596
title="Expand All"
97+
data-title="Expand All"
9698
onClick={() => props.diffFile.onSplitHunkExpand("all", props.index)}
9799
>
98100
<ExpandAll className="fill-current" />
99101
</button>
100102
) : (
101103
<>
102104
<button
103-
class="w-full hover:bg-blue-300 flex justify-center items-center py-[2px] cursor-pointer rounded-[2px]"
105+
class="w-full diff-widget-tooltip hover:bg-blue-300 flex justify-center items-center py-[2px] cursor-pointer rounded-[2px]"
104106
title="Expand Down"
107+
data-title="Expand Down"
105108
onClick={() => props.diffFile.onSplitHunkExpand("down", props.index)}
106109
>
107110
<ExpandDown className="fill-current" />
108111
</button>
109112
<button
110-
class="w-full hover:bg-blue-300 flex justify-center items-center py-[2px] cursor-pointer rounded-[2px]"
113+
class="w-full diff-widget-tooltip hover:bg-blue-300 flex justify-center items-center py-[2px] cursor-pointer rounded-[2px]"
111114
title="Expand Up"
115+
data-title="Expand Up"
112116
onClick={() => props.diffFile.onSplitHunkExpand("up", props.index)}
113117
>
114118
<ExpandUp className="fill-current" />
@@ -187,8 +191,9 @@ export const DiffSplitLastHunkLine = defineComponent(
187191
}}
188192
>
189193
<button
190-
class="w-full hover:bg-blue-300 flex justify-center items-center py-[6px] cursor-pointer rounded-[2px]"
194+
class="w-full diff-widget-tooltip hover:bg-blue-300 flex justify-center items-center py-[6px] cursor-pointer rounded-[2px]"
191195
title="Expand Down"
196+
data-title="Expand Down"
192197
onClick={() => props.diffFile.onSplitLastExpand()}
193198
>
194199
<ExpandDown className="fill-current" />

‎packages/vue/src/components/DiffSplitHunkLineWrap.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,32 +59,36 @@ export const DiffSplitHunkLine = defineComponent(
5959
{enableExpand.value &&
6060
(currentIsFirstLine.value ? (
6161
<button
62-
class="w-full hover:bg-blue-300 flex justify-center items-center py-[6px] cursor-pointer rounded-[2px]"
62+
class="w-full diff-widget-tooltip hover:bg-blue-300 flex justify-center items-center py-[6px] cursor-pointer rounded-[2px]"
6363
title="Expand Up"
64+
data-title="Expand Up"
6465
onClick={() => props.diffFile.onSplitHunkExpand("up", props.index)}
6566
>
6667
<ExpandUp className="fill-current" />
6768
</button>
6869
) : currentShowExpandAll.value ? (
6970
<button
70-
class="w-full hover:bg-blue-300 flex justify-center items-center py-[6px] cursor-pointer rounded-[2px]"
71+
class="w-full diff-widget-tooltip hover:bg-blue-300 flex justify-center items-center py-[6px] cursor-pointer rounded-[2px]"
7172
title="Expand All"
73+
data-title="Expand All"
7274
onClick={() => props.diffFile.onSplitHunkExpand("all", props.index)}
7375
>
7476
<ExpandAll className="fill-current" />
7577
</button>
7678
) : (
7779
<>
7880
<button
79-
class="w-full hover:bg-blue-300 flex justify-center items-center py-[2px] cursor-pointer rounded-[2px]"
81+
class="w-full diff-widget-tooltip hover:bg-blue-300 flex justify-center items-center py-[2px] cursor-pointer rounded-[2px]"
8082
title="Expand Down"
83+
data-title="Expand Down"
8184
onClick={() => props.diffFile.onSplitHunkExpand("down", props.index)}
8285
>
8386
<ExpandDown className="fill-current" />
8487
</button>
8588
<button
86-
class="w-full hover:bg-blue-300 flex justify-center items-center py-[2px] cursor-pointer rounded-[2px]"
89+
class="w-full diff-widget-tooltip hover:bg-blue-300 flex justify-center items-center py-[2px] cursor-pointer rounded-[2px]"
8790
title="Expand Up"
91+
data-title="Expand Up"
8892
onClick={() => props.diffFile.onSplitHunkExpand("up", props.index)}
8993
>
9094
<ExpandUp className="fill-current" />
@@ -135,8 +139,9 @@ export const DiffSplitLastHunkLine = defineComponent(
135139
}}
136140
>
137141
<button
138-
class="w-full hover:bg-blue-300 flex justify-center items-center py-[6px] cursor-pointer rounded-[2px]"
142+
class="w-full diff-widget-tooltip hover:bg-blue-300 flex justify-center items-center py-[6px] cursor-pointer rounded-[2px]"
139143
title="Expand Down"
144+
data-title="Expand Down"
140145
onClick={() => props.diffFile.onSplitLastExpand()}
141146
>
142147
<ExpandDown className="fill-current" />

‎packages/vue/src/components/DiffUnifiedHunkLine.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,32 +64,36 @@ export const DiffUnifiedHunkLine = defineComponent(
6464
{enableExpand.value ? (
6565
currentIsFirstLine.value ? (
6666
<button
67-
class="w-full hover:bg-blue-300 flex justify-center items-center py-[6px] cursor-pointer rounded-[2px]"
67+
class="w-full diff-widget-tooltip hover:bg-blue-300 flex justify-center items-center py-[6px] cursor-pointer rounded-[2px]"
6868
title="Expand Up"
69+
data-title="Expand Up"
6970
onClick={() => props.diffFile.onUnifiedHunkExpand("up", props.index)}
7071
>
7172
<ExpandUp className="fill-current" />
7273
</button>
7374
) : currentIsEnableAll.value ? (
7475
<button
75-
class="w-full hover:bg-blue-300 flex justify-center items-center py-[6px] cursor-pointer rounded-[2px]"
76+
class="w-full diff-widget-tooltip hover:bg-blue-300 flex justify-center items-center py-[6px] cursor-pointer rounded-[2px]"
7677
title="Expand All"
78+
data-title="Expand All"
7779
onClick={() => props.diffFile.onUnifiedHunkExpand("all", props.index)}
7880
>
7981
<ExpandAll className="fill-current" />
8082
</button>
8183
) : (
8284
<>
8385
<button
84-
class="w-full hover:bg-blue-300 flex justify-center items-center py-[2px] cursor-pointer rounded-[2px]"
86+
class="w-full diff-widget-tooltip hover:bg-blue-300 flex justify-center items-center py-[2px] cursor-pointer rounded-[2px]"
8587
title="Expand Down"
88+
data-title="Expand Down"
8689
onClick={() => props.diffFile.onUnifiedHunkExpand("down", props.index)}
8790
>
8891
<ExpandDown className="fill-current" />
8992
</button>
9093
<button
91-
class="w-full hover:bg-blue-300 flex justify-center items-center py-[2px] cursor-pointer rounded-[2px]"
94+
class="w-full diff-widget-tooltip hover:bg-blue-300 flex justify-center items-center py-[2px] cursor-pointer rounded-[2px]"
9295
title="Expand Up"
96+
data-title="Expand Up"
9397
onClick={() => props.diffFile.onUnifiedHunkExpand("up", props.index)}
9498
>
9599
<ExpandUp className="fill-current" />
@@ -145,8 +149,9 @@ export const DiffUnifiedLastHunkLine = defineComponent(
145149
}}
146150
>
147151
<button
148-
class="w-full hover:bg-blue-300 flex justify-center items-center py-[6px] cursor-pointer rounded-[2px]"
152+
class="w-full diff-widget-tooltip hover:bg-blue-300 flex justify-center items-center py-[6px] cursor-pointer rounded-[2px]"
149153
title="Expand Down"
154+
data-title="Expand Down"
150155
onClick={() => props.diffFile.onUnifiedLastExpand()}
151156
>
152157
<ExpandDown className="fill-current" />

‎packages/vue/src/components/DiffView.tsx

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { DiffFile } from "@git-diff-view/core";
2-
import { defineComponent, provide, ref, watch, watchEffect, computed } from "vue";
2+
import { defineComponent, provide, ref, watch, watchEffect, computed, onUnmounted } from "vue";
33

44
import {
55
idSymbol,
@@ -98,13 +98,20 @@ export const DiffView = defineComponent<
9898

9999
watch(
100100
() => props.diffFile,
101-
() => (diffFile.value = getInstance())
101+
() => {
102+
diffFile.value._destroy?.();
103+
diffFile.value = getInstance();
104+
},
105+
{ immediate: true }
102106
);
103107

104108
watch(
105109
() => props.data,
106-
() => (diffFile.value = getInstance()),
107-
{ deep: true }
110+
() => {
111+
diffFile.value._destroy?.();
112+
diffFile.value = getInstance();
113+
},
114+
{ immediate: true, deep: true }
108115
);
109116

110117
watch(
@@ -114,6 +121,13 @@ export const DiffView = defineComponent<
114121

115122
const isMounted = useIsMounted();
116123

124+
const initSubscribe = (onClean: (cb: () => void) => void) => {
125+
if (!isMounted.value || !diffFile.value || !props.diffFile) return;
126+
const instance = diffFile.value as DiffFile;
127+
props.diffFile._addClonedInstance(instance);
128+
onClean(() => props.diffFile._delClonedInstance(instance));
129+
};
130+
117131
const initDiff = () => {
118132
if (!isMounted.value || !diffFile.value) return;
119133
const instance = diffFile.value;
@@ -131,8 +145,9 @@ export const DiffView = defineComponent<
131145

132146
const initId = (onClean: (cb: () => void) => void) => {
133147
if (!diffFile.value) return;
134-
id.value = diffFile.value.getId();
135-
onClean(() => diffFile.value.clearId());
148+
const instance = diffFile.value;
149+
id.value = instance.getId();
150+
onClean(() => instance.clearId());
136151
};
137152

138153
watchEffect(() => initDiff());
@@ -141,6 +156,8 @@ export const DiffView = defineComponent<
141156

142157
watchEffect((onClean) => initId(onClean));
143158

159+
watchEffect((onClean) => initSubscribe(onClean));
160+
144161
provide(idSymbol, id);
145162

146163
provide(slotsSymbol, options.slots);
@@ -163,6 +180,8 @@ export const DiffView = defineComponent<
163180

164181
useProvide(props, "extendData", extendDataSymbol, true);
165182

183+
onUnmounted(() => diffFile.value._destroy?.());
184+
166185
return () => {
167186
if (!diffFile.value) return null;
168187

There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Please sign in to comment.