-
Notifications
You must be signed in to change notification settings - Fork 24
/
Copy pathApp.tsx
83 lines (70 loc) · 2.28 KB
/
App.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import { useEffect, useState } from 'react';
import { createClient, type ActorHandle } from 'actor-core/client';
import { type CursorRoom } from './cursor-room';
import CursorList from './components/CursorList';
import type { ActorCoreApp } from 'actor-core';
type App = ActorCoreApp<{
"cursor-room": typeof CursorRoom;
}>;
function App() {
const [cursorRoom, setCursorRoom] = useState<ActorHandle<typeof CursorRoom> | null>(null);
const [username] = useState(() => `User ${Math.floor(Math.random() * 10000)}`);
const [userId] = useState(() => crypto.randomUUID());
useEffect(() => {
let mounted = true;
async function connect() {
try {
// Use local development URL
const client = createClient<App>('http://localhost:8788/actors');
const room = await client["cursor-room"].get();
if (!mounted) return;
setCursorRoom(room);
} catch (error) {
console.error("Failed to connect:", error);
}
}
connect();
return () => {
mounted = false;
};
}, []);
useEffect(() => {
if (!cursorRoom) return;
const throttledMouseMove = throttle((event: MouseEvent) => {
cursorRoom.updateCursor(userId, event.clientX, event.clientY, username);
}, 50);
window.addEventListener('mousemove', throttledMouseMove);
return () => {
window.removeEventListener('mousemove', throttledMouseMove);
};
}, [cursorRoom, username, userId]);
return (
<div className="min-h-screen bg-gray-100 p-8">
<div className="max-w-4xl mx-auto">
<h1 className="text-4xl font-bold mb-8">Live Cursors Demo</h1>
<p className="text-lg mb-4">
Move your cursor around to see it sync with other users in real-time.
</p>
<div className="text-sm text-gray-600">
Connected as: {username}
</div>
</div>
<CursorList />
</div>
);
}
// Utility function to throttle function calls
function throttle<T extends (...args: any[]) => void>(
func: T,
limit: number
): (...args: Parameters<T>) => void {
let inThrottle: boolean;
return function(this: any, ...args: Parameters<T>) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => (inThrottle = false), limit);
}
};
}
export default App;