@fluxy-chat/create-fluxy-chat 0.3.0 → 0.5.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.
@@ -1,10 +1,82 @@
1
- import { useMemo, useState } from "react";
1
+ import { useEffect, useMemo, useState } from "react";
2
2
  import { FluxyChatClient } from "@fluxy-chat/sdk";
3
3
  import { FluxyRealtimeProvider, useChat } from "@fluxy-chat/react";
4
4
 
5
- const workerUrl = import.meta.env.VITE_FLUXYCHAT_WORKER_URL;
6
- const memberJwt = import.meta.env.VITE_FLUXYCHAT_MEMBER_JWT;
7
- const defaultRoomId = import.meta.env.VITE_FLUXYCHAT_ROOM_ID || "demo";
5
+ const workerUrl = import.meta.env.VITE_FLUXYCHAT_WORKER_URL?.trim();
6
+ const memberJwt = import.meta.env.VITE_FLUXYCHAT_MEMBER_JWT?.trim();
7
+ const publicRoomId = import.meta.env.VITE_FLUXYCHAT_PUBLIC_ROOM_ID?.trim();
8
+ const configuredRoomId = import.meta.env.VITE_FLUXYCHAT_ROOM_ID?.trim() || "demo";
9
+
10
+ interface FluxySession {
11
+ client: FluxyChatClient;
12
+ roomId: string;
13
+ mode: "member" | "guest";
14
+ }
15
+
16
+ function useFluxySession(): {
17
+ session: FluxySession | null;
18
+ loading: boolean;
19
+ error: string | null;
20
+ } {
21
+ const [session, setSession] = useState<FluxySession | null>(null);
22
+ const [loading, setLoading] = useState(Boolean(workerUrl));
23
+ const [error, setError] = useState<string | null>(null);
24
+
25
+ useEffect(() => {
26
+ if (!workerUrl) {
27
+ setLoading(false);
28
+ return;
29
+ }
30
+
31
+ if (memberJwt) {
32
+ setSession({
33
+ client: new FluxyChatClient({
34
+ baseUrl: workerUrl,
35
+ userId: "demo-user",
36
+ token: memberJwt,
37
+ }),
38
+ roomId: configuredRoomId,
39
+ mode: "member",
40
+ });
41
+ setLoading(false);
42
+ return;
43
+ }
44
+
45
+ if (publicRoomId) {
46
+ let cancelled = false;
47
+ void FluxyChatClient.joinPublicRoomAsGuest(workerUrl, publicRoomId, {
48
+ displayName: "Guest",
49
+ })
50
+ .then((guest) => {
51
+ if (cancelled) return;
52
+ setSession({
53
+ client: new FluxyChatClient({
54
+ baseUrl: workerUrl,
55
+ userId: guest.userId,
56
+ token: guest.token,
57
+ }),
58
+ roomId: guest.roomId,
59
+ mode: "guest",
60
+ });
61
+ })
62
+ .catch((err) => {
63
+ if (!cancelled) {
64
+ setError(err instanceof Error ? err.message : "Guest session failed");
65
+ }
66
+ })
67
+ .finally(() => {
68
+ if (!cancelled) setLoading(false);
69
+ });
70
+ return () => {
71
+ cancelled = true;
72
+ };
73
+ }
74
+
75
+ setLoading(false);
76
+ }, []);
77
+
78
+ return { session, loading, error };
79
+ }
8
80
 
9
81
  function ChatPanel({ roomId }: { roomId: string }) {
10
82
  const { messages, sendMessage, connectionState } = useChat({
@@ -50,31 +122,49 @@ function ChatPanel({ roomId }: { roomId: string }) {
50
122
  }
51
123
 
52
124
  export function App() {
53
- const [roomId, setRoomId] = useState(defaultRoomId);
54
-
55
- const client = useMemo(() => {
56
- if (!workerUrl?.trim() || !memberJwt?.trim()) return null;
57
- return new FluxyChatClient({
58
- baseUrl: workerUrl.trim(),
59
- userId: "demo-user",
60
- token: memberJwt.trim(),
61
- });
62
- }, []);
125
+ const { session, loading, error } = useFluxySession();
126
+ const [roomId, setRoomId] = useState(configuredRoomId);
127
+
128
+ const activeRoomId = useMemo(() => {
129
+ if (session?.mode === "guest") return session.roomId;
130
+ return roomId.trim() || configuredRoomId;
131
+ }, [session, roomId]);
63
132
 
64
- if (!client) {
133
+ if (!workerUrl) {
65
134
  return (
66
135
  <main className="shell">
67
136
  <h1>FluxyChat — chat-only starter</h1>
68
137
  <p>
69
138
  Copy <code>.env.example</code> to <code>.env</code> and set{" "}
70
- <code>VITE_FLUXYCHAT_WORKER_URL</code> and <code>VITE_FLUXYCHAT_MEMBER_JWT</code>.
139
+ <code>VITE_FLUXYCHAT_WORKER_URL</code>.
140
+ </p>
141
+ <p>
142
+ Then either <code>VITE_FLUXYCHAT_MEMBER_JWT</code> (member) or{" "}
143
+ <code>VITE_FLUXYCHAT_PUBLIC_ROOM_ID</code> (guest, ~60s to first message).
71
144
  </p>
145
+ </main>
146
+ );
147
+ }
148
+
149
+ if (loading) {
150
+ return (
151
+ <main className="shell">
152
+ <p>Connecting…</p>
153
+ </main>
154
+ );
155
+ }
156
+
157
+ if (error || !session) {
158
+ return (
159
+ <main className="shell">
160
+ <h1>FluxyChat</h1>
161
+ <p className="error">{error ?? "Set JWT or public room ID in .env"}</p>
72
162
  <p>
73
163
  Get credentials from{" "}
74
164
  <a href="https://fluxychat.com/onboarding" target="_blank" rel="noreferrer">
75
165
  onboarding
76
166
  </a>{" "}
77
- or <code>pnpm run first-message</code> in the monorepo.
167
+ or use a public room ID for guest mode.
78
168
  </p>
79
169
  </main>
80
170
  );
@@ -83,12 +173,15 @@ export function App() {
83
173
  return (
84
174
  <main className="shell">
85
175
  <h1>FluxyChat</h1>
86
- <label className="room-picker">
87
- Room
88
- <input value={roomId} onChange={(e) => setRoomId(e.target.value)} />
89
- </label>
90
- <FluxyRealtimeProvider client={client}>
91
- <ChatPanel roomId={roomId.trim() || defaultRoomId} />
176
+ <p className="mode-badge">{session.mode === "guest" ? "Guest session" : "Member JWT"}</p>
177
+ {session.mode === "member" ? (
178
+ <label className="room-picker">
179
+ Room
180
+ <input value={roomId} onChange={(e) => setRoomId(e.target.value)} />
181
+ </label>
182
+ ) : null}
183
+ <FluxyRealtimeProvider client={session.client}>
184
+ <ChatPanel roomId={activeRoomId} />
92
185
  </FluxyRealtimeProvider>
93
186
  </main>
94
187
  );
@@ -91,6 +91,16 @@ body {
91
91
  cursor: pointer;
92
92
  }
93
93
 
94
+ .mode-badge {
95
+ font-size: 0.75rem;
96
+ color: #64748b;
97
+ margin: 0 0 0.75rem;
98
+ }
99
+
100
+ .error {
101
+ color: #b91c1c;
102
+ }
103
+
94
104
  .room-picker {
95
105
  display: flex;
96
106
  flex-direction: column;
@@ -2,8 +2,9 @@
2
2
 
3
3
  interface ImportMetaEnv {
4
4
  readonly VITE_FLUXYCHAT_WORKER_URL: string;
5
- readonly VITE_FLUXYCHAT_MEMBER_JWT: string;
6
- readonly VITE_FLUXYCHAT_ROOM_ID: string;
5
+ readonly VITE_FLUXYCHAT_MEMBER_JWT?: string;
6
+ readonly VITE_FLUXYCHAT_ROOM_ID?: string;
7
+ readonly VITE_FLUXYCHAT_PUBLIC_ROOM_ID?: string;
7
8
  }
8
9
 
9
10
  interface ImportMeta {