tangled
alpha
login
or
join now
moth11.net
/
xcvr
2
fork
atom
frontend for xcvr appview
2
fork
atom
overview
issues
pulls
pipelines
change to diff, probs break things
moth11.net
7 months ago
af459827
abe09cfb
+36
-92
4 changed files
expand all
collapse all
unified
split
package-lock.json
package.json
src
lib
components
AutoGrowTextArea.svelte
Transmitter.svelte
+8
-1
package-lock.json
···
10
10
"dependencies": {
11
11
"@floating-ui/dom": "^1.7.2",
12
12
"@protobuf-ts/runtime": "^2.11.0",
13
13
-
"@rachel-mp4/lrcproto": "^1.0.3"
13
13
+
"@rachel-mp4/lrcproto": "^1.0.3",
14
14
+
"fast-diff": "^1.3.0"
14
15
},
15
16
"devDependencies": {
16
17
"@sveltejs/adapter-auto": "^6.0.0",
···
1131
1132
"dependencies": {
1132
1133
"@jridgewell/sourcemap-codec": "^1.4.15"
1133
1134
}
1135
1135
+
},
1136
1136
+
"node_modules/fast-diff": {
1137
1137
+
"version": "1.3.0",
1138
1138
+
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
1139
1139
+
"integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
1140
1140
+
"license": "Apache-2.0"
1134
1141
},
1135
1142
"node_modules/fdir": {
1136
1143
"version": "6.4.5",
+2
-1
package.json
···
24
24
"dependencies": {
25
25
"@floating-ui/dom": "^1.7.2",
26
26
"@protobuf-ts/runtime": "^2.11.0",
27
27
-
"@rachel-mp4/lrcproto": "^1.0.3"
27
27
+
"@rachel-mp4/lrcproto": "^1.0.3",
28
28
+
"fast-diff": "^1.3.0"
28
29
}
29
30
}
+2
-3
src/lib/components/AutoGrowTextArea.svelte
···
3
3
4
4
interface Props {
5
5
onBeforeInput?: (event: InputEvent) => void;
6
6
-
onInput?: (event: Event) => void;
6
6
+
onInput?: (event: InputEvent) => void;
7
7
placeholder?: string;
8
8
value?: string;
9
9
maxlength?: number;
···
23
23
24
24
let inputEl: HTMLElement;
25
25
function adjust(event: Event) {
26
26
-
onInput?.(event);
26
26
+
onInput?.(event as InputEvent);
27
27
}
28
28
29
29
function adjustHeight() {
···
62
62
border: none;
63
63
}
64
64
</style>
65
65
-
+24
-87
src/lib/components/Transmitter.svelte
···
3
3
import { WSContext } from "$lib/wscontext.svelte";
4
4
import { numToHex } from "$lib/colors";
5
5
import AutoGrowTextArea from "$lib/components/AutoGrowTextArea.svelte";
6
6
+
import diff from "fast-diff";
6
7
import { getPrevCharBoundary, getNextCharBoundary } from "$lib/utils";
7
8
interface Props {
8
9
ctx: WSContext;
···
33
34
});
34
35
35
36
let color = $derived(numToHex(ctx.color));
37
37
+
const diffAndSend = (event: InputEvent) => {
38
38
+
const el = event.target as HTMLInputElement;
39
39
+
const result = diff(message, el.value);
40
40
+
var idx = 0;
41
41
+
result.forEach((d) => {
42
42
+
switch (d[0]) {
43
43
+
case -1:
44
44
+
const idx2 = idx + d[1].length;
45
45
+
ctx.delete(idx, idx2);
46
46
+
break;
47
47
+
case 0:
48
48
+
idx = idx + d[1].length;
49
49
+
break;
50
50
+
case 1:
51
51
+
ctx.insert(idx, d[1]);
52
52
+
idx = idx + d[1].length;
53
53
+
break;
54
54
+
}
55
55
+
});
56
56
+
message = el.value;
57
57
+
};
36
58
37
59
const bi = (event: InputEvent) => {
38
60
const el = event.target as HTMLInputElement;
···
45
67
ctx.insertLineBreak();
46
68
el.value = "";
47
69
event.preventDefault();
48
48
-
return;
49
49
-
}
50
50
-
51
51
-
case "insertText": {
52
52
-
const { selectionStart } = el;
53
53
-
const { selectionEnd } = el;
54
54
-
55
55
-
if (
56
56
-
selectionStart !== selectionEnd &&
57
57
-
selectionEnd !== null &&
58
58
-
selectionStart !== null
59
59
-
) {
60
60
-
ctx.delete(selectionStart, selectionEnd);
61
61
-
}
62
62
-
ctx.insert(selectionStart ?? 0, event.data ?? "");
63
63
-
return;
64
64
-
}
65
65
-
66
66
-
case "insertFromPaste": {
67
67
-
const { selectionStart } = el;
68
68
-
const { selectionEnd } = el;
69
69
-
if (
70
70
-
selectionStart !== selectionEnd &&
71
71
-
selectionEnd !== null &&
72
72
-
selectionStart !== null
73
73
-
) {
74
74
-
ctx.delete(selectionStart, selectionEnd);
75
75
-
}
76
76
-
ctx.insert(selectionStart ?? 0, event.data ?? "");
70
70
+
message = "";
77
71
return;
78
72
}
79
79
-
80
80
-
case "deleteContent": {
81
81
-
const { selectionStart } = el;
82
82
-
const { selectionEnd } = el;
83
83
-
if (
84
84
-
selectionStart !== selectionEnd &&
85
85
-
selectionStart !== null &&
86
86
-
selectionEnd !== null
87
87
-
) {
88
88
-
ctx.delete(selectionStart, selectionEnd);
89
89
-
}
90
90
-
}
91
91
-
92
92
-
case "deleteContentBackward": {
93
93
-
const { selectionStart } = el;
94
94
-
const { selectionEnd } = el;
95
95
-
if (selectionStart !== null && selectionEnd !== null) {
96
96
-
if (selectionStart !== selectionEnd) {
97
97
-
ctx.delete(selectionStart, selectionEnd);
98
98
-
} else if (selectionStart !== 0) {
99
99
-
event.preventDefault();
100
100
-
const realStart = getPrevCharBoundary(
101
101
-
el.value,
102
102
-
selectionStart,
103
103
-
);
104
104
-
ctx.delete(realStart, selectionEnd);
105
105
-
el.value =
106
106
-
el.value.slice(0, realStart) +
107
107
-
el.value.slice(selectionEnd);
108
108
-
el.setSelectionRange(realStart, realStart);
109
109
-
}
110
110
-
}
111
111
-
}
112
112
-
113
113
-
case "deleteContentForward": {
114
114
-
const { selectionStart } = el;
115
115
-
const { selectionEnd } = el;
116
116
-
if (selectionStart !== null && selectionEnd !== null) {
117
117
-
if (selectionStart !== selectionEnd) {
118
118
-
ctx.delete(selectionStart, selectionEnd);
119
119
-
} else if (selectionEnd !== el.value.length) {
120
120
-
event.preventDefault();
121
121
-
const realEnd = getNextCharBoundary(
122
122
-
el.value,
123
123
-
selectionEnd,
124
124
-
);
125
125
-
ctx.delete(selectionStart, realEnd);
126
126
-
el.value =
127
127
-
el.value.slice(0, selectionStart) +
128
128
-
el.value.slice(realEnd);
129
129
-
el.setSelectionRange(selectionStart, selectionStart);
130
130
-
}
131
131
-
}
132
132
-
}
133
133
-
134
134
-
case "historyUndo": {
135
135
-
}
136
73
}
137
74
};
138
75
</script>
···
166
103
/>
167
104
</div>
168
105
<AutoGrowTextArea
169
169
-
bind:value={message}
170
106
placeholder="start typing..."
171
107
onBeforeInput={bi}
108
108
+
onInput={diffAndSend}
172
109
maxlength={65535}
173
110
/>
174
111
</div>