vzcode 1.17.0 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.html CHANGED
@@ -20,7 +20,7 @@
20
20
  href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap"
21
21
  rel="stylesheet"
22
22
  />
23
- <script type="module" crossorigin src="/assets/index-BQgRA0SD.js"></script>
23
+ <script type="module" crossorigin src="/assets/index-DIcMeAET.js"></script>
24
24
  <link rel="stylesheet" crossorigin href="/assets/index-zzK6rRiK.css">
25
25
  </head>
26
26
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vzcode",
3
- "version": "1.17.0",
3
+ "version": "1.19.0",
4
4
  "description": "Multiplayer code editor system",
5
5
  "main": "src/index.ts",
6
6
  "type": "module",
@@ -142,8 +142,6 @@ export const useShareDB = ({
142
142
  // False for "Saved"
143
143
  const pending = usePending(shareDBDoc);
144
144
 
145
- console.log('pending ', pending);
146
-
147
145
  // A convenience function for mutating the ShareDB document
148
146
  // based submitting OT ops generated by diffing the JSON.
149
147
  const submitOperation =
@@ -8,180 +8,61 @@ export const colorPickerRegex = /#[0-9A-Fa-f]{6}/g;
8
8
  // Works without quotes to support CSS.
9
9
  export const colorPicker = (
10
10
  onInteract?: () => void,
11
- ): InteractRule => {
12
- // Create the color picker element when the page loads
13
- const sel: HTMLInputElement = document.createElement('input');
14
- sel.type = 'color';
15
- sel.style.position = 'fixed';
16
- sel.style.left = '-9999px'; // Initially off-screen
17
- sel.style.top = '-9999px';
18
- document.body.appendChild(sel);
19
-
20
- // Create a close button element to hide the color picker
21
- const closeButton: HTMLButtonElement = document.createElement('button');
22
- closeButton.innerText = 'X';
23
- closeButton.style.position = 'absolute';
24
- closeButton.style.width = '20px';
25
- closeButton.style.height = '20px';
26
- closeButton.style.borderRadius = '50%';
27
- closeButton.style.border = 'none';
28
- closeButton.style.backgroundColor = '#ff4d4f';
29
- closeButton.style.color = 'white';
30
- closeButton.style.fontSize = '12px';
31
- closeButton.style.display = 'none'; // Initially hidden
32
- closeButton.style.cursor = 'pointer';
33
- closeButton.style.top = '-10px'; // Adjust position relative to color picker
34
- closeButton.style.right = '-10px';
35
- sel.parentElement?.appendChild(closeButton); // Add button to the same container
36
-
37
- // Function to hide the color picker and close button
38
- const hideColorPicker = () => {
39
- sel.style.left = '-9999px';
40
- sel.style.top = '-9999px';
41
- closeButton.style.display = 'none';
42
- };
43
-
44
- // Add event listener to the close button to hide color picker
45
- closeButton.addEventListener('click', (event) => {
46
- event.stopPropagation(); // Prevent click event from bubbling to document
47
- hideColorPicker();
48
- });
49
-
50
- // Add event listener for clicks outside the color picker
51
- document.addEventListener('click', (event: MouseEvent) => {
52
- if (event.target !== sel && event.target !== closeButton) {
53
- hideColorPicker();
54
- }
55
- });
56
-
57
- // Function to set the text and color
58
- const setText = (newText: string) => {
59
- console.log('Applying color to the element:', newText);
60
-
61
- // Assuming you're applying the color to a circle element with id 'colorCircle'
62
- const colorCircle = document.getElementById('colorCircle');
63
- if (colorCircle) {
64
- colorCircle.style.backgroundColor = newText;
65
- console.log(`Color applied to colorCircle: ${newText}`);
66
- } else {
67
- console.log('colorCircle element not found');
68
- }
69
-
70
- // If there is any other text element (like an input or div for displaying hex color), update it too.
71
- const hexDisplay = document.getElementById('hexDisplay');
72
- if (hexDisplay) {
73
- hexDisplay.textContent = newText;
74
- console.log(`Hex value applied to hexDisplay: ${newText}`);
75
- } else {
76
- console.log('hexDisplay element not found');
77
- }
78
- };
79
-
80
- return {
81
- regexp: colorPickerRegex,
82
- cursor: 'pointer',
83
-
84
- onClick(
85
- text: string,
86
- setText: (newText: string) => void,
87
- event: MouseEvent
88
- ) {
89
- const startingColor: string = text;
90
-
91
- // Set the initial value of the color picker
92
- console.log('Initial color:', startingColor);
93
- sel.value = startingColor.toLowerCase();
94
- console.log('Color picker initial value set to:', sel.value);
95
-
96
- // Position the color picker near the cursor
97
- const cursorX = event.clientX;
98
- const cursorY = event.clientY;
99
- sel.style.left = cursorX + 'px';
100
- sel.style.top = cursorY + 'px';
101
-
102
- // Show and position the close button
103
- closeButton.style.display = 'block';
104
- closeButton.style.left = `${cursorX + sel.offsetWidth - 15}px`; // Adjust to place in corner
105
- closeButton.style.top = `${cursorY - 15}px`;
106
-
107
- // Update the color selection and setText on change
108
- const updateHex = (e: Event) => {
109
- const el: HTMLInputElement = e.target as HTMLInputElement;
110
- console.log('Hex color value selected:', el.value);
111
-
112
- if (el.value) {
113
- setText(el.value.toUpperCase()); // Use uppercase for consistency
114
- }
115
- if (onInteract) {
116
- console.log('onInteract called');
117
- onInteract();
118
- }
119
-
120
- // Update color display directly (for example, changing the background color of an element)
121
- const colorDisplay = document.getElementById('colorDisplay');
122
- if (colorDisplay) {
123
- colorDisplay.style.backgroundColor = el.value;
124
- console.log(`colorDisplay updated to: ${el.value}`);
125
- } else {
126
- console.log('colorDisplay element not found');
127
- }
128
- };
129
-
130
- // Add input event listener to handle color selection
131
- sel.addEventListener('input', updateHex);
132
-
133
- // Trigger click event on the color picker to display it
11
+ ): InteractRule => ({
12
+ regexp: colorPickerRegex,
13
+ cursor: 'pointer',
14
+ onClick(
15
+ text: string,
16
+ setText: (newText: string) => void,
17
+ event: MouseEvent,
18
+ ) {
19
+ const startingColor: string = text;
20
+
21
+ const sel: HTMLInputElement =
22
+ document.createElement('input');
23
+ sel.type = 'color';
24
+ sel.value = startingColor.toLowerCase();
25
+
26
+ // `valueIsUpper` maintains the style of the user's code.
27
+ // It keeps the case of a-f the same case as the original.
28
+ const valueIsUpper: boolean =
29
+ startingColor.toUpperCase() === startingColor;
30
+
31
+ const updateHex = (e: Event) => {
32
+ const el: HTMLInputElement =
33
+ e.target as HTMLInputElement;
34
+ if (el.value) {
35
+ setText(
36
+ valueIsUpper ? el.value.toUpperCase() : el.value,
37
+ );
38
+ }
39
+ if (onInteract) onInteract();
40
+ };
41
+ sel.addEventListener('input', updateHex);
42
+
43
+ // Position the color input at the mouse cursor
44
+ sel.style.position = 'absolute';
45
+ sel.style.left = `${event.clientX}px`;
46
+ sel.style.top = `${event.clientY}px`;
47
+
48
+ // Make it invisible
49
+ sel.style.opacity = '0';
50
+ sel.style.height = '0';
51
+ sel.style.width = '0';
52
+ sel.style.border = 'none';
53
+ sel.style.padding = '0';
54
+ sel.style.margin = '0';
55
+ document.body.appendChild(sel);
56
+
57
+ // Click the input after a delay, so that
58
+ // it gets the correct position
59
+ setTimeout(() => {
134
60
  sel.click();
135
- },
136
- };
137
- };
138
-
139
-
140
-
141
- // TODO get this working
142
- // rgb color picker
143
- // Inspired by https://github.com/replit/codemirror-interact/blob/master/dev/index.ts#L71
144
- //TODO: create color picker for hsl colors
145
- // {
146
- // regexp: /rgb\(.*\)/g,
147
- // cursor: 'pointer',
148
- // onClick: (text, setText, e) => {
149
- // const res =
150
- // /rgb\((?<r>\d+)\s*,\s*(?<g>\d+)\s*,\s*(?<b>\d+)\)/.exec(
151
- // text,
152
- // );
153
- // const r = Number(res?.groups?.r);
154
- // const g = Number(res?.groups?.g);
155
- // const b = Number(res?.groups?.b);
156
-
157
- // //sel will open the color picker when sel.click is called.
158
- // const sel = document.createElement('input');
159
- // sel.type = 'color';
160
-
161
- // if (!isNaN(r + g + b)) sel.value = rgb2Hex(r, g, b);
162
-
163
- // const updateRGB = (e: Event) => {
164
- // const el = e.target as HTMLInputElement;
165
- // if (onInteract) onInteract();
166
-
167
- // if (el.value) {
168
- // const [r, g, b] = hex2RGB(el.value);
169
- // setText(`rgb(${r}, ${g}, ${b})`);
170
- // }
171
- // sel.removeEventListener('change', updateRGB);
172
- // };
173
-
174
- // sel.addEventListener('change', updateRGB);
175
- // sel.click();
176
- // },
177
- // },
178
-
179
- // // Inspired by https://github.com/replit/codemirror-interact/blob/master/dev/index.ts#L108
180
- // const hex2RGB = (hex: string): [number, number, number] => {
181
- // const v = parseInt(hex.substring(1), 16);
182
- // return [(v >> 16) & 255, (v >> 8) & 255, v & 255];
183
- // };
184
-
185
- // // Inspired by https://github.com/replit/codemirror-interact/blob/master/dev/index.ts#L117
186
- // const rgb2Hex = (r: number, g: number, b: number): string =>
187
- // '#' + r.toString(16) + g.toString(16) + b.toString(16);
61
+ }, 10);
62
+
63
+ // Remove the input after interaction
64
+ sel.addEventListener('blur', () => {
65
+ document.body.removeChild(sel);
66
+ });
67
+ },
68
+ });
@@ -1,3 +1,4 @@
1
+ import { enableLiveKit } from './featureFlags';
1
2
  import { VZKeyboardShortcutsDoc } from './VZKeyboardShortcutsDoc';
2
3
  import { VZSettings } from './VZSettings';
3
4
  import { VZSidebar } from './VZSidebar';
@@ -21,7 +22,7 @@ export const VZLeft = ({ enableUsernameField = true }) => {
21
22
  />
22
23
  <CreateFileModal />
23
24
  <CreateDirModal />
24
- <VoiceChatModal />
25
+ {enableLiveKit && <VoiceChatModal />}
25
26
  </div>
26
27
  );
27
28
  };
@@ -4,7 +4,7 @@ import {
4
4
  useEffect,
5
5
  useMemo,
6
6
  useState,
7
- useRef
7
+ useRef,
8
8
  } from 'react';
9
9
  import {
10
10
  FileId,
@@ -34,6 +34,7 @@ import { Listing } from './Listing';
34
34
  import { Search } from './Search';
35
35
  import './styles.scss';
36
36
  import { useDragAndDrop } from './useDragAndDrop';
37
+ import { enableLiveKit } from '../featureFlags';
37
38
 
38
39
  // TODO turn this UI back on when we are actually detecting
39
40
  // the connection status.
@@ -231,7 +232,12 @@ export const VZSidebar = ({
231
232
  // Handle 'saved' state based on 'pending' transition
232
233
  useEffect(() => {
233
234
  // Check if 'pending' transitioned from true to false
234
- if (previousPendingRef.current && !pending && connected && !isConnecting) {
235
+ if (
236
+ previousPendingRef.current &&
237
+ !pending &&
238
+ connected &&
239
+ !isConnecting
240
+ ) {
235
241
  setSaved(true);
236
242
  const timer = setTimeout(() => {
237
243
  setSaved(false);
@@ -242,7 +248,6 @@ export const VZSidebar = ({
242
248
  previousPendingRef.current = pending;
243
249
  }, [pending, connected, isConnecting]);
244
250
 
245
-
246
251
  return (
247
252
  <div
248
253
  className="vz-sidebar"
@@ -408,25 +413,30 @@ export const VZSidebar = ({
408
413
  </i>
409
414
  </OverlayTrigger>
410
415
  {/* Start Voice Chat */}
411
- <OverlayTrigger
412
- placement="right"
413
- overlay={
414
- <Tooltip id="voice-chat">
415
- {voiceChatToolTipText}
416
- </Tooltip>
417
- }
418
- >
419
- <i
420
- id="mic-icon"
421
- className="icon-button icon-button-dark"
422
- onClick={() => {
423
- console.log('clicking', liveKitConnection);
424
- setVoiceChatModalOpen(true);
425
- }}
416
+ {enableLiveKit && (
417
+ <OverlayTrigger
418
+ placement="right"
419
+ overlay={
420
+ <Tooltip id="voice-chat">
421
+ {voiceChatToolTipText}
422
+ </Tooltip>
423
+ }
426
424
  >
427
- <MicSVG />
428
- </i>
429
- </OverlayTrigger>
425
+ <i
426
+ id="mic-icon"
427
+ className="icon-button icon-button-dark"
428
+ onClick={() => {
429
+ console.log(
430
+ 'clicking',
431
+ liveKitConnection,
432
+ );
433
+ setVoiceChatModalOpen(true);
434
+ }}
435
+ >
436
+ <MicSVG />
437
+ </i>
438
+ </OverlayTrigger>
439
+ )}
430
440
  </div>
431
441
  <div className="files" id="sidebar-view-container">
432
442
  {!isSearchOpen ? (
@@ -472,11 +482,15 @@ export const VZSidebar = ({
472
482
  </div>
473
483
  {enableConnectionStatus && (
474
484
  <div className="connection-status">
475
- {isConnecting ? 'Connecting...' :
476
- !connected ? 'Connection Lost' :
477
- pending ? 'Saving...' :
478
- saved ? 'Saved.' :
479
- 'Connected'}
485
+ {isConnecting
486
+ ? 'Connecting...'
487
+ : !connected
488
+ ? 'Connection Lost'
489
+ : pending
490
+ ? 'Saving...'
491
+ : saved
492
+ ? 'Saved.'
493
+ : 'Connected'}
480
494
  <div className="connection">
481
495
  <div
482
496
  className={`connection-status-indicator ${
@@ -487,7 +501,7 @@ export const VZSidebar = ({
487
501
  : pending
488
502
  ? 'pending'
489
503
  : 'connected'
490
- }`}
504
+ }`}
491
505
  />
492
506
  </div>
493
507
  </div>
@@ -0,0 +1,2 @@
1
+ export const enableLiveKit =
2
+ import.meta.env.VITE_ENABLE_LIVEKIT === 'true';
@@ -7,7 +7,7 @@ export const createToken = async (roomName, username) => {
7
7
  // client joins
8
8
  // Identifier to be used for participant.
9
9
  // It's available as LocalParticipant.identity with livekit-client SDK
10
- console.log(username);
10
+ // console.log(username);
11
11
  const participantName = `${username}`;
12
12
 
13
13
  const at = new AccessToken(
@@ -0,0 +1,10 @@
1
+ /// <reference types="vite/client" />
2
+
3
+ interface ImportMetaEnv {
4
+ readonly VITE_ENABLE_LIVEKIT: string;
5
+ // Add other environment variables here as needed
6
+ }
7
+
8
+ interface ImportMeta {
9
+ readonly env: ImportMetaEnv;
10
+ }