@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.
- package/CHANGELOG.md +16 -0
- package/dist/index.js +105 -29
- package/package.json +4 -3
- package/readme.md +22 -16
- package/templates/full/.env.example +10 -0
- package/templates/full/README.md +66 -0
- package/templates/full/index.html +12 -0
- package/templates/full/package.json +29 -0
- package/templates/full/scripts/fluxy-dev.mjs +169 -0
- package/templates/full/scripts/fluxy-doctor.mjs +122 -0
- package/templates/full/scripts/fluxy-setup.mjs +323 -0
- package/templates/full/src/App.tsx +223 -0
- package/templates/full/src/index.css +242 -0
- package/templates/full/src/main.tsx +10 -0
- package/templates/full/src/vite-env.d.ts +16 -0
- package/templates/full/tsconfig.json +21 -0
- package/templates/full/vite.config.ts +7 -0
- package/templates/hr-feedback/.env.example +9 -0
- package/templates/hr-feedback/README.md +45 -0
- package/templates/hr-feedback/package.json +19 -0
- package/templates/hr-feedback/src/feedback.ts +71 -0
- package/templates/hr-feedback/src/index.ts +22 -0
- package/templates/hr-feedback/tsconfig.json +18 -0
- package/templates/hr-feedback/wrangler.toml +7 -0
- package/templates/minimal/README.md +1 -1
- package/templates/react/.env.example +4 -3
- package/templates/react/README.md +17 -7
- package/templates/react/src/App.tsx +116 -23
- package/templates/react/src/index.css +10 -0
- package/templates/react/src/vite-env.d.ts +3 -2
|
@@ -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
|
|
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
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
return
|
|
58
|
-
|
|
59
|
-
|
|
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 (!
|
|
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
|
|
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
|
|
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
|
-
<
|
|
87
|
-
|
|
88
|
-
<
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
);
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
interface ImportMetaEnv {
|
|
4
4
|
readonly VITE_FLUXYCHAT_WORKER_URL: string;
|
|
5
|
-
readonly VITE_FLUXYCHAT_MEMBER_JWT
|
|
6
|
-
readonly VITE_FLUXYCHAT_ROOM_ID
|
|
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 {
|