@sqlrooms/discuss 0.24.27 → 0.25.0-rc.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/README.md +3 -3
- package/dist/DiscussSlice.d.ts +104 -143
- package/dist/DiscussSlice.d.ts.map +1 -1
- package/dist/DiscussSlice.js +18 -16
- package/dist/DiscussSlice.js.map +1 -1
- package/dist/DiscussionList.js +1 -1
- package/dist/DiscussionList.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -126,7 +126,7 @@ import {useStoreWithDiscussion} from '@sqlrooms/discuss';
|
|
|
126
126
|
function MyComponent() {
|
|
127
127
|
// Get discussions
|
|
128
128
|
const discussions = useStoreWithDiscussion(
|
|
129
|
-
(state) => state.config.
|
|
129
|
+
(state) => state.discuss.config.discussions,
|
|
130
130
|
);
|
|
131
131
|
|
|
132
132
|
// Get actions
|
|
@@ -160,7 +160,7 @@ import {formatTimeRelative} from '@sqlrooms/utils';
|
|
|
160
160
|
|
|
161
161
|
const DiscussionPanel = () => {
|
|
162
162
|
const discussions = useStoreWithDiscussion(
|
|
163
|
-
(state) => state.config.
|
|
163
|
+
(state) => state.discuss.config.discussions,
|
|
164
164
|
);
|
|
165
165
|
|
|
166
166
|
return (
|
|
@@ -226,7 +226,7 @@ function DataVisualization() {
|
|
|
226
226
|
// Highlight related discussion when hovering over data
|
|
227
227
|
const handleDataPointHover = (dataId: string) => {
|
|
228
228
|
const discussions =
|
|
229
|
-
useStoreWithDiscussion.getState().config.
|
|
229
|
+
useStoreWithDiscussion.getState().discuss.config.discussions;
|
|
230
230
|
const relatedDiscussion = discussions.find((d) => d.anchorId === dataId);
|
|
231
231
|
if (relatedDiscussion) {
|
|
232
232
|
setHighlightedDiscussionId(relatedDiscussion.id);
|
package/dist/DiscussSlice.d.ts
CHANGED
|
@@ -118,166 +118,122 @@ export declare const Discussion: z.ZodObject<{
|
|
|
118
118
|
}>;
|
|
119
119
|
export type Discussion = z.infer<typeof Discussion>;
|
|
120
120
|
export declare const DiscussSliceConfig: z.ZodObject<{
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
discussions: z.ZodArray<z.ZodObject<{
|
|
122
|
+
id: z.ZodString;
|
|
123
|
+
anchorId: z.ZodOptional<z.ZodString>;
|
|
124
|
+
rootComment: z.ZodObject<{
|
|
125
|
+
id: z.ZodString;
|
|
126
|
+
userId: z.ZodString;
|
|
127
|
+
text: z.ZodString;
|
|
128
|
+
timestamp: z.ZodDate;
|
|
129
|
+
} & {
|
|
130
|
+
parentId: z.ZodOptional<z.ZodString>;
|
|
131
|
+
}, "strip", z.ZodTypeAny, {
|
|
132
|
+
id: string;
|
|
133
|
+
userId: string;
|
|
134
|
+
text: string;
|
|
135
|
+
timestamp: Date;
|
|
136
|
+
parentId?: string | undefined;
|
|
137
|
+
}, {
|
|
138
|
+
id: string;
|
|
139
|
+
userId: string;
|
|
140
|
+
text: string;
|
|
141
|
+
timestamp: Date;
|
|
142
|
+
parentId?: string | undefined;
|
|
143
|
+
}>;
|
|
144
|
+
comments: z.ZodArray<z.ZodObject<{
|
|
123
145
|
id: z.ZodString;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
timestamp: z.ZodDate;
|
|
130
|
-
} & {
|
|
131
|
-
parentId: z.ZodOptional<z.ZodString>;
|
|
132
|
-
}, "strip", z.ZodTypeAny, {
|
|
133
|
-
id: string;
|
|
134
|
-
userId: string;
|
|
135
|
-
text: string;
|
|
136
|
-
timestamp: Date;
|
|
137
|
-
parentId?: string | undefined;
|
|
138
|
-
}, {
|
|
139
|
-
id: string;
|
|
140
|
-
userId: string;
|
|
141
|
-
text: string;
|
|
142
|
-
timestamp: Date;
|
|
143
|
-
parentId?: string | undefined;
|
|
144
|
-
}>;
|
|
145
|
-
comments: z.ZodArray<z.ZodObject<{
|
|
146
|
-
id: z.ZodString;
|
|
147
|
-
userId: z.ZodString;
|
|
148
|
-
text: z.ZodString;
|
|
149
|
-
timestamp: z.ZodDate;
|
|
150
|
-
} & {
|
|
151
|
-
parentId: z.ZodOptional<z.ZodString>;
|
|
152
|
-
}, "strip", z.ZodTypeAny, {
|
|
153
|
-
id: string;
|
|
154
|
-
userId: string;
|
|
155
|
-
text: string;
|
|
156
|
-
timestamp: Date;
|
|
157
|
-
parentId?: string | undefined;
|
|
158
|
-
}, {
|
|
159
|
-
id: string;
|
|
160
|
-
userId: string;
|
|
161
|
-
text: string;
|
|
162
|
-
timestamp: Date;
|
|
163
|
-
parentId?: string | undefined;
|
|
164
|
-
}>, "many">;
|
|
146
|
+
userId: z.ZodString;
|
|
147
|
+
text: z.ZodString;
|
|
148
|
+
timestamp: z.ZodDate;
|
|
149
|
+
} & {
|
|
150
|
+
parentId: z.ZodOptional<z.ZodString>;
|
|
165
151
|
}, "strip", z.ZodTypeAny, {
|
|
166
152
|
id: string;
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
timestamp: Date;
|
|
172
|
-
parentId?: string | undefined;
|
|
173
|
-
};
|
|
174
|
-
comments: {
|
|
175
|
-
id: string;
|
|
176
|
-
userId: string;
|
|
177
|
-
text: string;
|
|
178
|
-
timestamp: Date;
|
|
179
|
-
parentId?: string | undefined;
|
|
180
|
-
}[];
|
|
181
|
-
anchorId?: string | undefined;
|
|
153
|
+
userId: string;
|
|
154
|
+
text: string;
|
|
155
|
+
timestamp: Date;
|
|
156
|
+
parentId?: string | undefined;
|
|
182
157
|
}, {
|
|
183
158
|
id: string;
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
timestamp: Date;
|
|
189
|
-
parentId?: string | undefined;
|
|
190
|
-
};
|
|
191
|
-
comments: {
|
|
192
|
-
id: string;
|
|
193
|
-
userId: string;
|
|
194
|
-
text: string;
|
|
195
|
-
timestamp: Date;
|
|
196
|
-
parentId?: string | undefined;
|
|
197
|
-
}[];
|
|
198
|
-
anchorId?: string | undefined;
|
|
159
|
+
userId: string;
|
|
160
|
+
text: string;
|
|
161
|
+
timestamp: Date;
|
|
162
|
+
parentId?: string | undefined;
|
|
199
163
|
}>, "many">;
|
|
200
164
|
}, "strip", z.ZodTypeAny, {
|
|
201
|
-
|
|
165
|
+
id: string;
|
|
166
|
+
rootComment: {
|
|
167
|
+
id: string;
|
|
168
|
+
userId: string;
|
|
169
|
+
text: string;
|
|
170
|
+
timestamp: Date;
|
|
171
|
+
parentId?: string | undefined;
|
|
172
|
+
};
|
|
173
|
+
comments: {
|
|
202
174
|
id: string;
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
timestamp: Date;
|
|
208
|
-
parentId?: string | undefined;
|
|
209
|
-
};
|
|
210
|
-
comments: {
|
|
211
|
-
id: string;
|
|
212
|
-
userId: string;
|
|
213
|
-
text: string;
|
|
214
|
-
timestamp: Date;
|
|
215
|
-
parentId?: string | undefined;
|
|
216
|
-
}[];
|
|
217
|
-
anchorId?: string | undefined;
|
|
175
|
+
userId: string;
|
|
176
|
+
text: string;
|
|
177
|
+
timestamp: Date;
|
|
178
|
+
parentId?: string | undefined;
|
|
218
179
|
}[];
|
|
180
|
+
anchorId?: string | undefined;
|
|
219
181
|
}, {
|
|
220
|
-
|
|
182
|
+
id: string;
|
|
183
|
+
rootComment: {
|
|
221
184
|
id: string;
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
timestamp: Date;
|
|
234
|
-
parentId?: string | undefined;
|
|
235
|
-
}[];
|
|
236
|
-
anchorId?: string | undefined;
|
|
185
|
+
userId: string;
|
|
186
|
+
text: string;
|
|
187
|
+
timestamp: Date;
|
|
188
|
+
parentId?: string | undefined;
|
|
189
|
+
};
|
|
190
|
+
comments: {
|
|
191
|
+
id: string;
|
|
192
|
+
userId: string;
|
|
193
|
+
text: string;
|
|
194
|
+
timestamp: Date;
|
|
195
|
+
parentId?: string | undefined;
|
|
237
196
|
}[];
|
|
238
|
-
|
|
197
|
+
anchorId?: string | undefined;
|
|
198
|
+
}>, "many">;
|
|
239
199
|
}, "strip", z.ZodTypeAny, {
|
|
240
|
-
|
|
241
|
-
|
|
200
|
+
discussions: {
|
|
201
|
+
id: string;
|
|
202
|
+
rootComment: {
|
|
203
|
+
id: string;
|
|
204
|
+
userId: string;
|
|
205
|
+
text: string;
|
|
206
|
+
timestamp: Date;
|
|
207
|
+
parentId?: string | undefined;
|
|
208
|
+
};
|
|
209
|
+
comments: {
|
|
242
210
|
id: string;
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
timestamp: Date;
|
|
248
|
-
parentId?: string | undefined;
|
|
249
|
-
};
|
|
250
|
-
comments: {
|
|
251
|
-
id: string;
|
|
252
|
-
userId: string;
|
|
253
|
-
text: string;
|
|
254
|
-
timestamp: Date;
|
|
255
|
-
parentId?: string | undefined;
|
|
256
|
-
}[];
|
|
257
|
-
anchorId?: string | undefined;
|
|
211
|
+
userId: string;
|
|
212
|
+
text: string;
|
|
213
|
+
timestamp: Date;
|
|
214
|
+
parentId?: string | undefined;
|
|
258
215
|
}[];
|
|
259
|
-
|
|
216
|
+
anchorId?: string | undefined;
|
|
217
|
+
}[];
|
|
260
218
|
}, {
|
|
261
|
-
|
|
262
|
-
|
|
219
|
+
discussions: {
|
|
220
|
+
id: string;
|
|
221
|
+
rootComment: {
|
|
222
|
+
id: string;
|
|
223
|
+
userId: string;
|
|
224
|
+
text: string;
|
|
225
|
+
timestamp: Date;
|
|
226
|
+
parentId?: string | undefined;
|
|
227
|
+
};
|
|
228
|
+
comments: {
|
|
263
229
|
id: string;
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
timestamp: Date;
|
|
269
|
-
parentId?: string | undefined;
|
|
270
|
-
};
|
|
271
|
-
comments: {
|
|
272
|
-
id: string;
|
|
273
|
-
userId: string;
|
|
274
|
-
text: string;
|
|
275
|
-
timestamp: Date;
|
|
276
|
-
parentId?: string | undefined;
|
|
277
|
-
}[];
|
|
278
|
-
anchorId?: string | undefined;
|
|
230
|
+
userId: string;
|
|
231
|
+
text: string;
|
|
232
|
+
timestamp: Date;
|
|
233
|
+
parentId?: string | undefined;
|
|
279
234
|
}[];
|
|
280
|
-
|
|
235
|
+
anchorId?: string | undefined;
|
|
236
|
+
}[];
|
|
281
237
|
}>;
|
|
282
238
|
export type DiscussSliceConfig = z.infer<typeof DiscussSliceConfig>;
|
|
283
239
|
export declare function createDefaultDiscussConfig(): DiscussSliceConfig;
|
|
@@ -297,6 +253,7 @@ export type DeleteItem = {
|
|
|
297
253
|
export type DiscussSliceState = {
|
|
298
254
|
discuss: {
|
|
299
255
|
userId: string;
|
|
256
|
+
config: DiscussSliceConfig;
|
|
300
257
|
/**
|
|
301
258
|
* Submit content based on current UI state (add discussion, reply to discussion/comment, or edit).
|
|
302
259
|
* This automatically handles state management and is the preferred way to submit content.
|
|
@@ -346,6 +303,10 @@ export type DiscussSliceState = {
|
|
|
346
303
|
* Should be called after the user confirms deletion in the UI.
|
|
347
304
|
*/
|
|
348
305
|
handleDeleteConfirm: () => void;
|
|
306
|
+
/**
|
|
307
|
+
* Sets the config for the discuss slice.
|
|
308
|
+
*/
|
|
309
|
+
setConfig: (config: DiscussSliceConfig) => void;
|
|
349
310
|
/**
|
|
350
311
|
* Helper function to get the user ID of the entity being replied to.
|
|
351
312
|
* Returns '' if no reply context is set, or the user ID if a valid reply context exists.
|
|
@@ -365,7 +326,7 @@ export type DiscussSliceState = {
|
|
|
365
326
|
};
|
|
366
327
|
};
|
|
367
328
|
export type RoomStateWithDiscussion = RoomShellSliceState<BaseRoomConfig> & DiscussSliceState;
|
|
368
|
-
export declare function createDiscussSlice<PC extends BaseRoomConfig
|
|
329
|
+
export declare function createDiscussSlice<PC extends BaseRoomConfig>({ userId, }: {
|
|
369
330
|
userId: string;
|
|
370
331
|
}): StateCreator<DiscussSliceState>;
|
|
371
332
|
type RoomConfigWithDiscuss = BaseRoomConfig & DiscussSliceConfig;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DiscussSlice.d.ts","sourceRoot":"","sources":["../src/DiscussSlice.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,mBAAmB,EACxB,KAAK,YAAY,EACjB,cAAc,EACf,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAGtB,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;EAKtB,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAGtD,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;EAElB,CAAC;AACH,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,OAAO,CAAC,CAAC;AAG9C,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKrB,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAEpD,eAAO,MAAM,kBAAkB
|
|
1
|
+
{"version":3,"file":"DiscussSlice.d.ts","sourceRoot":"","sources":["../src/DiscussSlice.ts"],"names":[],"mappings":"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"}
|
package/dist/DiscussSlice.js
CHANGED
|
@@ -21,23 +21,25 @@ export const Discussion = z.object({
|
|
|
21
21
|
comments: z.array(Comment),
|
|
22
22
|
});
|
|
23
23
|
export const DiscussSliceConfig = z.object({
|
|
24
|
-
|
|
25
|
-
discussions: z.array(Discussion),
|
|
26
|
-
}),
|
|
24
|
+
discussions: z.array(Discussion),
|
|
27
25
|
});
|
|
28
26
|
export function createDefaultDiscussConfig() {
|
|
29
27
|
return {
|
|
30
|
-
|
|
31
|
-
discussions: [],
|
|
32
|
-
},
|
|
28
|
+
discussions: [],
|
|
33
29
|
};
|
|
34
30
|
}
|
|
35
|
-
export function createDiscussSlice({ userId }) {
|
|
31
|
+
export function createDiscussSlice({ userId, }) {
|
|
36
32
|
return createSlice((set, get) => ({
|
|
37
33
|
discuss: {
|
|
38
34
|
userId,
|
|
35
|
+
config: createDefaultDiscussConfig(),
|
|
39
36
|
// Direct CRUD operations - These are exposed for advanced use cases
|
|
40
37
|
// For normal usage with UI integration, prefer submitEdit
|
|
38
|
+
setConfig: (config) => {
|
|
39
|
+
set((state) => produce(state, (draft) => {
|
|
40
|
+
draft.discuss.config = config;
|
|
41
|
+
}));
|
|
42
|
+
},
|
|
41
43
|
/**
|
|
42
44
|
* Directly adds a new discussion without managing UI state.
|
|
43
45
|
* For UI-integrated usage, prefer submitEdit.
|
|
@@ -57,7 +59,7 @@ export function createDiscussSlice({ userId }) {
|
|
|
57
59
|
comments: [],
|
|
58
60
|
};
|
|
59
61
|
set((state) => produce(state, (draft) => {
|
|
60
|
-
draft.config.
|
|
62
|
+
draft.discuss.config.discussions.push(newDiscussion);
|
|
61
63
|
}));
|
|
62
64
|
},
|
|
63
65
|
/**
|
|
@@ -66,9 +68,9 @@ export function createDiscussSlice({ userId }) {
|
|
|
66
68
|
*/
|
|
67
69
|
removeDiscussion: (id) => {
|
|
68
70
|
set((state) => produce(state, (draft) => {
|
|
69
|
-
const index = draft.config.
|
|
71
|
+
const index = draft.discuss.config.discussions.findIndex((a) => a.id === id);
|
|
70
72
|
if (index !== -1) {
|
|
71
|
-
draft.config.
|
|
73
|
+
draft.discuss.config.discussions.splice(index, 1);
|
|
72
74
|
}
|
|
73
75
|
}));
|
|
74
76
|
},
|
|
@@ -78,7 +80,7 @@ export function createDiscussSlice({ userId }) {
|
|
|
78
80
|
*/
|
|
79
81
|
editDiscussion: (id, text) => {
|
|
80
82
|
set((state) => produce(state, (draft) => {
|
|
81
|
-
const discussion = draft.config.
|
|
83
|
+
const discussion = draft.discuss.config.discussions.find((a) => a.id === id);
|
|
82
84
|
if (discussion) {
|
|
83
85
|
discussion.rootComment.text = text;
|
|
84
86
|
}
|
|
@@ -97,7 +99,7 @@ export function createDiscussSlice({ userId }) {
|
|
|
97
99
|
parentId,
|
|
98
100
|
};
|
|
99
101
|
set((state) => produce(state, (draft) => {
|
|
100
|
-
const discussion = draft.config.
|
|
102
|
+
const discussion = draft.discuss.config.discussions.find((a) => a.id === discussionId);
|
|
101
103
|
if (discussion) {
|
|
102
104
|
discussion.comments.push(newComment);
|
|
103
105
|
}
|
|
@@ -109,7 +111,7 @@ export function createDiscussSlice({ userId }) {
|
|
|
109
111
|
*/
|
|
110
112
|
editComment: (discussionId, commentId, text) => {
|
|
111
113
|
set((state) => produce(state, (draft) => {
|
|
112
|
-
const discussion = draft.config.
|
|
114
|
+
const discussion = draft.discuss.config.discussions.find((a) => a.id === discussionId);
|
|
113
115
|
if (discussion) {
|
|
114
116
|
if (discussion.rootComment.id === commentId) {
|
|
115
117
|
discussion.rootComment.text = text;
|
|
@@ -129,7 +131,7 @@ export function createDiscussSlice({ userId }) {
|
|
|
129
131
|
*/
|
|
130
132
|
removeComment: (discussionId, commentId) => {
|
|
131
133
|
set((state) => produce(state, (draft) => {
|
|
132
|
-
const discussion = draft.config.
|
|
134
|
+
const discussion = draft.discuss.config.discussions.find((a) => a.id === discussionId);
|
|
133
135
|
if (discussion) {
|
|
134
136
|
// Cannot remove the root comment
|
|
135
137
|
if (discussion.rootComment.id !== commentId) {
|
|
@@ -266,7 +268,7 @@ export function createDiscussSlice({ userId }) {
|
|
|
266
268
|
getReplyToUserId: () => {
|
|
267
269
|
const state = get();
|
|
268
270
|
const { replyToItem } = state.discuss;
|
|
269
|
-
const { discussions } = state.config
|
|
271
|
+
const { discussions } = state.discuss.config;
|
|
270
272
|
if (!replyToItem)
|
|
271
273
|
return '';
|
|
272
274
|
const discussion = discussions.find((a) => a.id === replyToItem.discussionId);
|
|
@@ -292,7 +294,7 @@ export function createDiscussSlice({ userId }) {
|
|
|
292
294
|
getEditingItemText: () => {
|
|
293
295
|
const state = get();
|
|
294
296
|
const { editingItem } = state.discuss;
|
|
295
|
-
const { discussions } = state.config
|
|
297
|
+
const { discussions } = state.discuss.config;
|
|
296
298
|
if (!editingItem)
|
|
297
299
|
return '';
|
|
298
300
|
// Look for the discussion
|
package/dist/DiscussSlice.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DiscussSlice.js","sourceRoot":"","sources":["../src/DiscussSlice.ts"],"names":[],"mappings":"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","sourcesContent":["import {createId} from '@paralleldrive/cuid2';\nimport {\n createSlice,\n useBaseRoomShellStore,\n type RoomShellSliceState,\n type StateCreator,\n BaseRoomConfig,\n} from '@sqlrooms/room-shell';\nimport {produce} from 'immer';\nimport {z} from 'zod';\n\n// Base type with common fields\nexport const CommentBase = z.object({\n id: z.string().cuid2(),\n userId: z.string(),\n text: z.string(),\n timestamp: z.coerce.date(),\n});\nexport type CommentBase = z.infer<typeof CommentBase>;\n\n// Comment type extends base with parentId\nexport const Comment = CommentBase.extend({\n parentId: z.string().optional(),\n});\nexport type Comment = z.infer<typeof Comment>;\n\n// Discussion is a container with a rootComment and collection of reply comments\nexport const Discussion = z.object({\n id: z.string().cuid2(),\n anchorId: z.string().optional(),\n rootComment: Comment,\n comments: z.array(Comment),\n});\nexport type Discussion = z.infer<typeof Discussion>;\n\nexport const DiscussSliceConfig = z.object({\n discuss: z.object({\n discussions: z.array(Discussion),\n }),\n});\nexport type DiscussSliceConfig = z.infer<typeof DiscussSliceConfig>;\n\nexport function createDefaultDiscussConfig(): DiscussSliceConfig {\n return {\n discuss: {\n discussions: [],\n },\n };\n}\n\n// UI state for discussions\nexport type ReplyToItem = {\n discussionId: string;\n commentId?: string;\n};\n\nexport type EditingItem = {\n discussionId: string;\n commentId?: string;\n};\n\nexport type DeleteItem = {\n discussionId: string;\n commentId?: string;\n itemType: string;\n};\n\nexport type DiscussSliceState = {\n discuss: {\n userId: string;\n\n // UI-connected actions - preferred API for most use cases\n /**\n * Submit content based on current UI state (add discussion, reply to discussion/comment, or edit).\n * This automatically handles state management and is the preferred way to submit content.\n */\n submitEdit: (text: string) => void;\n\n // UI state management\n /**\n * Current discussion or comment being replied to.\n * Used by the form to determine context when submitting.\n */\n replyToItem: ReplyToItem | undefined;\n /**\n * Sets the discussion or comment being replied to.\n * Will clear editing state if set.\n */\n setReplyToItem: (replyToItem: ReplyToItem | undefined) => void;\n\n /**\n * Current discussion or comment being edited.\n * Used by the form to determine context when submitting.\n */\n editingItem: EditingItem | undefined;\n /**\n * Sets the discussion or comment being edited.\n * Will clear replyTo state if set.\n */\n setEditingItem: (editingItem: EditingItem | undefined) => void;\n\n /**\n * Item currently targeted for deletion.\n * Used by the delete confirmation dialog.\n */\n itemToDelete: DeleteItem | undefined;\n /**\n * Sets the discussion or comment to be deleted.\n * Should be used before showing the confirmation dialog.\n */\n setItemToDelete: (item: DeleteItem | undefined) => void;\n\n /**\n * Currently highlighted discussion.\n * Used to visually highlight a discussion in the UI.\n */\n highlightedDiscussionId: string | undefined;\n /**\n * Sets the highlighted discussion.\n */\n setHighlightedDiscussionId: (discussionId: string | undefined) => void;\n\n // Delete confirmation handler\n /**\n * Handles the confirmation of a delete operation.\n * Should be called after the user confirms deletion in the UI.\n */\n handleDeleteConfirm: () => void;\n\n // Helpers\n /**\n * Helper function to get the user ID of the entity being replied to.\n * Returns '' if no reply context is set, or the user ID if a valid reply context exists.\n */\n getReplyToUserId: () => string;\n\n /**\n * Helper function to get the text of the item being edited.\n * Returns '' if no editing context is set, or the text content if a valid editing context exists.\n */\n getEditingItemText: () => string;\n\n // Direct CRUD operations - use these only for custom integrations\n // that don't use the built-in UI state management\n addDiscussion: (text: string, anchorId?: string) => void;\n editDiscussion: (id: string, text: string) => void;\n removeDiscussion: (id: string) => void;\n addComment: (discussionId: string, text: string, parentId?: string) => void;\n editComment: (\n discussionId: string,\n commentId: string,\n text: string,\n ) => void;\n removeComment: (discussionId: string, commentId: string) => void;\n };\n};\n\nexport type RoomStateWithDiscussion = RoomShellSliceState<BaseRoomConfig> &\n DiscussSliceState;\n\nexport function createDiscussSlice<\n PC extends BaseRoomConfig & DiscussSliceConfig,\n>({userId}: {userId: string}): StateCreator<DiscussSliceState> {\n return createSlice<PC, DiscussSliceState>((set, get) => ({\n discuss: {\n userId,\n\n // Direct CRUD operations - These are exposed for advanced use cases\n // For normal usage with UI integration, prefer submitEdit\n\n /**\n * Directly adds a new discussion without managing UI state.\n * For UI-integrated usage, prefer submitEdit.\n */\n addDiscussion: (text, anchorId) => {\n const id = createId();\n const rootComment: Comment = {\n id: createId(),\n userId,\n text,\n timestamp: new Date(),\n };\n\n const newDiscussion: Discussion = {\n id,\n anchorId,\n rootComment,\n comments: [],\n };\n\n set((state) =>\n produce(state, (draft) => {\n draft.config.discuss.discussions.push(newDiscussion);\n }),\n );\n },\n\n /**\n * Directly removes an discussion without managing UI state.\n * For UI-integrated usage, prefer setting itemToDelete and using handleDeleteConfirm.\n */\n removeDiscussion: (id) => {\n set((state) =>\n produce(state, (draft) => {\n const index = draft.config.discuss.discussions.findIndex(\n (a) => a.id === id,\n );\n if (index !== -1) {\n draft.config.discuss.discussions.splice(index, 1);\n }\n }),\n );\n },\n\n /**\n * Directly edits an discussion without managing UI state.\n * For UI-integrated usage, prefer submitEdit.\n */\n editDiscussion: (id, text) => {\n set((state) =>\n produce(state, (draft) => {\n const discussion = draft.config.discuss.discussions.find(\n (a) => a.id === id,\n );\n if (discussion) {\n discussion.rootComment.text = text;\n }\n }),\n );\n },\n\n /**\n * Directly adds a comment without managing UI state.\n * For UI-integrated usage, prefer submitEdit.\n */\n addComment: (discussionId, text, parentId) => {\n const newComment: Comment = {\n id: createId(),\n userId,\n text,\n timestamp: new Date(),\n parentId,\n };\n\n set((state) =>\n produce(state, (draft) => {\n const discussion = draft.config.discuss.discussions.find(\n (a) => a.id === discussionId,\n );\n if (discussion) {\n discussion.comments.push(newComment);\n }\n }),\n );\n },\n\n /**\n * Directly edits a comment without managing UI state.\n * For UI-integrated usage, prefer submitEdit.\n */\n editComment: (discussionId, commentId, text) => {\n set((state) =>\n produce(state, (draft) => {\n const discussion = draft.config.discuss.discussions.find(\n (a) => a.id === discussionId,\n );\n if (discussion) {\n if (discussion.rootComment.id === commentId) {\n discussion.rootComment.text = text;\n } else {\n const comment = discussion.comments.find(\n (c) => c.id === commentId,\n );\n if (comment) {\n comment.text = text;\n }\n }\n }\n }),\n );\n },\n\n /**\n * Directly removes a comment without managing UI state.\n * For UI-integrated usage, prefer setting itemToDelete and using handleDeleteConfirm.\n */\n removeComment: (discussionId, commentId) => {\n set((state) =>\n produce(state, (draft) => {\n const discussion = draft.config.discuss.discussions.find(\n (a) => a.id === discussionId,\n );\n if (discussion) {\n // Cannot remove the root comment\n if (discussion.rootComment.id !== commentId) {\n const index = discussion.comments.findIndex(\n (c) => c.id === commentId,\n );\n if (index !== -1) {\n discussion.comments.splice(index, 1);\n }\n }\n }\n }),\n );\n },\n\n // UI state management\n /**\n * Current discussion or comment being replied to.\n * Used by the form to determine context when submitting.\n */\n replyToItem: undefined,\n /**\n * Sets the discussion or comment being replied to.\n * Will clear editing state if set.\n */\n setReplyToItem: (replyToItem) => {\n set((state) =>\n produce(state, (draft) => {\n draft.discuss.replyToItem = replyToItem;\n if (replyToItem) {\n draft.discuss.editingItem = undefined;\n }\n }),\n );\n },\n\n /**\n * Current discussion or comment being edited.\n * Used by the form to determine context when submitting.\n */\n editingItem: undefined,\n /**\n * Sets the discussion or comment being edited.\n * Will clear replyTo state if set.\n */\n setEditingItem: (editingItem) => {\n set((state) =>\n produce(state, (draft) => {\n draft.discuss.editingItem = editingItem;\n if (editingItem) {\n draft.discuss.replyToItem = undefined;\n }\n }),\n );\n },\n\n /**\n * Item currently targeted for deletion.\n * Used by the delete confirmation dialog.\n */\n itemToDelete: undefined,\n /**\n * Sets the discussion or comment to be deleted.\n * Should be used before showing the confirmation dialog.\n */\n setItemToDelete: (item) => {\n set((state) =>\n produce(state, (draft) => {\n draft.discuss.itemToDelete = item;\n }),\n );\n },\n\n /**\n * Currently highlighted discussion.\n * Used to visually highlight a discussion in the UI.\n */\n highlightedDiscussionId: undefined,\n /**\n * Sets the highlighted discussion.\n */\n setHighlightedDiscussionId: (discussionId) => {\n set((state) =>\n produce(state, (draft) => {\n draft.discuss.highlightedDiscussionId = discussionId;\n }),\n );\n },\n\n /**\n * Main form submission handler that processes content based on UI state.\n * This is the preferred method to submit discussion/comment content.\n *\n * Will automatically:\n * - Add a new discussion if no context is set\n * - Add a comment as a reply if replyToItem is set\n * - Edit an discussion or comment if editing is set\n * - Clear UI state after submission\n */\n submitEdit: (text) => {\n const state = get();\n const {\n editingItem,\n replyToItem,\n addDiscussion,\n editDiscussion,\n editComment,\n addComment,\n } = state.discuss;\n\n if (editingItem) {\n if (editingItem.commentId) {\n editComment(editingItem.discussionId, editingItem.commentId, text);\n } else {\n editDiscussion(editingItem.discussionId, text);\n }\n state.discuss.setEditingItem(undefined);\n } else if (replyToItem) {\n if (replyToItem.commentId) {\n addComment(replyToItem.discussionId, text, replyToItem.commentId);\n } else {\n addComment(replyToItem.discussionId, text);\n }\n state.discuss.setReplyToItem(undefined);\n } else {\n addDiscussion(text);\n }\n },\n\n /**\n * Handles the confirmation of a delete operation.\n * Should be called after the user confirms deletion in the UI.\n *\n * Will:\n * - Delete the discussion or comment specified in itemToDelete\n * - Clear the itemToDelete state\n */\n handleDeleteConfirm: () => {\n const state = get();\n const {itemToDelete, removeComment, removeDiscussion} = state.discuss;\n\n if (itemToDelete) {\n if (itemToDelete.commentId) {\n removeComment(itemToDelete.discussionId, itemToDelete.commentId);\n } else {\n removeDiscussion(itemToDelete.discussionId);\n }\n state.discuss.setItemToDelete(undefined);\n }\n },\n\n /**\n * Helper function to get the user ID of the entity being replied to.\n * Returns '' if no reply context is set, or the user ID if a valid reply context exists.\n */\n getReplyToUserId: () => {\n const state = get();\n const {replyToItem} = state.discuss;\n const {discussions} = state.config.discuss;\n\n if (!replyToItem) return '';\n\n const discussion = discussions.find(\n (a) => a.id === replyToItem.discussionId,\n );\n\n if (discussion) {\n if (replyToItem.commentId) {\n if (discussion.rootComment.id === replyToItem.commentId) {\n return discussion.rootComment.userId;\n }\n const comment = discussion.comments.find(\n (c) => c.id === replyToItem.commentId,\n );\n if (comment) return comment.userId;\n } else {\n return discussion.rootComment.userId;\n }\n }\n\n return '';\n },\n\n /**\n * Helper function to get the text of the item being edited.\n * Returns '' if no editing context is set, or the text content if a valid editing context exists.\n */\n getEditingItemText: () => {\n const state = get();\n const {editingItem} = state.discuss;\n const {discussions} = state.config.discuss;\n\n if (!editingItem) return '';\n\n // Look for the discussion\n const discussion = discussions.find(\n (a) => a.id === editingItem.discussionId,\n );\n if (!discussion) return '';\n\n // If editing a comment, find the comment\n if (editingItem.commentId) {\n const comment = discussion.comments.find(\n (c) => c.id === editingItem.commentId,\n );\n return comment ? comment.text : '';\n }\n\n // If editing the discussion itself\n return discussion.rootComment.text;\n },\n },\n }));\n}\n\ntype RoomConfigWithDiscuss = BaseRoomConfig & DiscussSliceConfig;\ntype RoomStateWithDiscuss = RoomShellSliceState<RoomConfigWithDiscuss> &\n DiscussSliceState;\n\nexport function useStoreWithDiscussion<T>(\n selector: (state: RoomStateWithDiscuss) => T,\n): T {\n return useBaseRoomShellStore<\n BaseRoomConfig & DiscussSliceConfig,\n RoomStateWithDiscuss,\n T\n >((state) => selector(state as RoomStateWithDiscuss));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"DiscussSlice.js","sourceRoot":"","sources":["../src/DiscussSlice.ts"],"names":[],"mappings":"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","sourcesContent":["import {createId} from '@paralleldrive/cuid2';\nimport {\n createSlice,\n useBaseRoomShellStore,\n type RoomShellSliceState,\n type StateCreator,\n BaseRoomConfig,\n} from '@sqlrooms/room-shell';\nimport {produce} from 'immer';\nimport {z} from 'zod';\n\n// Base type with common fields\nexport const CommentBase = z.object({\n id: z.string().cuid2(),\n userId: z.string(),\n text: z.string(),\n timestamp: z.coerce.date(),\n});\nexport type CommentBase = z.infer<typeof CommentBase>;\n\n// Comment type extends base with parentId\nexport const Comment = CommentBase.extend({\n parentId: z.string().optional(),\n});\nexport type Comment = z.infer<typeof Comment>;\n\n// Discussion is a container with a rootComment and collection of reply comments\nexport const Discussion = z.object({\n id: z.string().cuid2(),\n anchorId: z.string().optional(),\n rootComment: Comment,\n comments: z.array(Comment),\n});\nexport type Discussion = z.infer<typeof Discussion>;\n\nexport const DiscussSliceConfig = z.object({\n discussions: z.array(Discussion),\n});\nexport type DiscussSliceConfig = z.infer<typeof DiscussSliceConfig>;\n\nexport function createDefaultDiscussConfig(): DiscussSliceConfig {\n return {\n discussions: [],\n };\n}\n\n// UI state for discussions\nexport type ReplyToItem = {\n discussionId: string;\n commentId?: string;\n};\n\nexport type EditingItem = {\n discussionId: string;\n commentId?: string;\n};\n\nexport type DeleteItem = {\n discussionId: string;\n commentId?: string;\n itemType: string;\n};\n\nexport type DiscussSliceState = {\n discuss: {\n userId: string;\n config: DiscussSliceConfig;\n\n // UI-connected actions - preferred API for most use cases\n /**\n * Submit content based on current UI state (add discussion, reply to discussion/comment, or edit).\n * This automatically handles state management and is the preferred way to submit content.\n */\n submitEdit: (text: string) => void;\n\n // UI state management\n /**\n * Current discussion or comment being replied to.\n * Used by the form to determine context when submitting.\n */\n replyToItem: ReplyToItem | undefined;\n /**\n * Sets the discussion or comment being replied to.\n * Will clear editing state if set.\n */\n setReplyToItem: (replyToItem: ReplyToItem | undefined) => void;\n\n /**\n * Current discussion or comment being edited.\n * Used by the form to determine context when submitting.\n */\n editingItem: EditingItem | undefined;\n /**\n * Sets the discussion or comment being edited.\n * Will clear replyTo state if set.\n */\n setEditingItem: (editingItem: EditingItem | undefined) => void;\n\n /**\n * Item currently targeted for deletion.\n * Used by the delete confirmation dialog.\n */\n itemToDelete: DeleteItem | undefined;\n /**\n * Sets the discussion or comment to be deleted.\n * Should be used before showing the confirmation dialog.\n */\n setItemToDelete: (item: DeleteItem | undefined) => void;\n\n /**\n * Currently highlighted discussion.\n * Used to visually highlight a discussion in the UI.\n */\n highlightedDiscussionId: string | undefined;\n /**\n * Sets the highlighted discussion.\n */\n setHighlightedDiscussionId: (discussionId: string | undefined) => void;\n\n // Delete confirmation handler\n /**\n * Handles the confirmation of a delete operation.\n * Should be called after the user confirms deletion in the UI.\n */\n handleDeleteConfirm: () => void;\n\n /**\n * Sets the config for the discuss slice.\n */\n setConfig: (config: DiscussSliceConfig) => void;\n\n // Helpers\n /**\n * Helper function to get the user ID of the entity being replied to.\n * Returns '' if no reply context is set, or the user ID if a valid reply context exists.\n */\n getReplyToUserId: () => string;\n\n /**\n * Helper function to get the text of the item being edited.\n * Returns '' if no editing context is set, or the text content if a valid editing context exists.\n */\n getEditingItemText: () => string;\n\n // Direct CRUD operations - use these only for custom integrations\n // that don't use the built-in UI state management\n addDiscussion: (text: string, anchorId?: string) => void;\n editDiscussion: (id: string, text: string) => void;\n removeDiscussion: (id: string) => void;\n addComment: (discussionId: string, text: string, parentId?: string) => void;\n editComment: (\n discussionId: string,\n commentId: string,\n text: string,\n ) => void;\n removeComment: (discussionId: string, commentId: string) => void;\n };\n};\n\nexport type RoomStateWithDiscussion = RoomShellSliceState<BaseRoomConfig> &\n DiscussSliceState;\n\nexport function createDiscussSlice<PC extends BaseRoomConfig>({\n userId,\n}: {\n userId: string;\n}): StateCreator<DiscussSliceState> {\n return createSlice<PC, DiscussSliceState>((set, get) => ({\n discuss: {\n userId,\n config: createDefaultDiscussConfig(),\n // Direct CRUD operations - These are exposed for advanced use cases\n // For normal usage with UI integration, prefer submitEdit\n\n setConfig: (config) => {\n set((state) =>\n produce(state, (draft) => {\n draft.discuss.config = config;\n }),\n );\n },\n\n /**\n * Directly adds a new discussion without managing UI state.\n * For UI-integrated usage, prefer submitEdit.\n */\n addDiscussion: (text, anchorId) => {\n const id = createId();\n const rootComment: Comment = {\n id: createId(),\n userId,\n text,\n timestamp: new Date(),\n };\n\n const newDiscussion: Discussion = {\n id,\n anchorId,\n rootComment,\n comments: [],\n };\n\n set((state) =>\n produce(state, (draft) => {\n draft.discuss.config.discussions.push(newDiscussion);\n }),\n );\n },\n\n /**\n * Directly removes an discussion without managing UI state.\n * For UI-integrated usage, prefer setting itemToDelete and using handleDeleteConfirm.\n */\n removeDiscussion: (id) => {\n set((state) =>\n produce(state, (draft) => {\n const index = draft.discuss.config.discussions.findIndex(\n (a) => a.id === id,\n );\n if (index !== -1) {\n draft.discuss.config.discussions.splice(index, 1);\n }\n }),\n );\n },\n\n /**\n * Directly edits an discussion without managing UI state.\n * For UI-integrated usage, prefer submitEdit.\n */\n editDiscussion: (id, text) => {\n set((state) =>\n produce(state, (draft) => {\n const discussion = draft.discuss.config.discussions.find(\n (a) => a.id === id,\n );\n if (discussion) {\n discussion.rootComment.text = text;\n }\n }),\n );\n },\n\n /**\n * Directly adds a comment without managing UI state.\n * For UI-integrated usage, prefer submitEdit.\n */\n addComment: (discussionId, text, parentId) => {\n const newComment: Comment = {\n id: createId(),\n userId,\n text,\n timestamp: new Date(),\n parentId,\n };\n\n set((state) =>\n produce(state, (draft) => {\n const discussion = draft.discuss.config.discussions.find(\n (a) => a.id === discussionId,\n );\n if (discussion) {\n discussion.comments.push(newComment);\n }\n }),\n );\n },\n\n /**\n * Directly edits a comment without managing UI state.\n * For UI-integrated usage, prefer submitEdit.\n */\n editComment: (discussionId, commentId, text) => {\n set((state) =>\n produce(state, (draft) => {\n const discussion = draft.discuss.config.discussions.find(\n (a) => a.id === discussionId,\n );\n if (discussion) {\n if (discussion.rootComment.id === commentId) {\n discussion.rootComment.text = text;\n } else {\n const comment = discussion.comments.find(\n (c) => c.id === commentId,\n );\n if (comment) {\n comment.text = text;\n }\n }\n }\n }),\n );\n },\n\n /**\n * Directly removes a comment without managing UI state.\n * For UI-integrated usage, prefer setting itemToDelete and using handleDeleteConfirm.\n */\n removeComment: (discussionId, commentId) => {\n set((state) =>\n produce(state, (draft) => {\n const discussion = draft.discuss.config.discussions.find(\n (a) => a.id === discussionId,\n );\n if (discussion) {\n // Cannot remove the root comment\n if (discussion.rootComment.id !== commentId) {\n const index = discussion.comments.findIndex(\n (c) => c.id === commentId,\n );\n if (index !== -1) {\n discussion.comments.splice(index, 1);\n }\n }\n }\n }),\n );\n },\n\n // UI state management\n /**\n * Current discussion or comment being replied to.\n * Used by the form to determine context when submitting.\n */\n replyToItem: undefined,\n /**\n * Sets the discussion or comment being replied to.\n * Will clear editing state if set.\n */\n setReplyToItem: (replyToItem) => {\n set((state) =>\n produce(state, (draft) => {\n draft.discuss.replyToItem = replyToItem;\n if (replyToItem) {\n draft.discuss.editingItem = undefined;\n }\n }),\n );\n },\n\n /**\n * Current discussion or comment being edited.\n * Used by the form to determine context when submitting.\n */\n editingItem: undefined,\n /**\n * Sets the discussion or comment being edited.\n * Will clear replyTo state if set.\n */\n setEditingItem: (editingItem) => {\n set((state) =>\n produce(state, (draft) => {\n draft.discuss.editingItem = editingItem;\n if (editingItem) {\n draft.discuss.replyToItem = undefined;\n }\n }),\n );\n },\n\n /**\n * Item currently targeted for deletion.\n * Used by the delete confirmation dialog.\n */\n itemToDelete: undefined,\n /**\n * Sets the discussion or comment to be deleted.\n * Should be used before showing the confirmation dialog.\n */\n setItemToDelete: (item) => {\n set((state) =>\n produce(state, (draft) => {\n draft.discuss.itemToDelete = item;\n }),\n );\n },\n\n /**\n * Currently highlighted discussion.\n * Used to visually highlight a discussion in the UI.\n */\n highlightedDiscussionId: undefined,\n /**\n * Sets the highlighted discussion.\n */\n setHighlightedDiscussionId: (discussionId) => {\n set((state) =>\n produce(state, (draft) => {\n draft.discuss.highlightedDiscussionId = discussionId;\n }),\n );\n },\n\n /**\n * Main form submission handler that processes content based on UI state.\n * This is the preferred method to submit discussion/comment content.\n *\n * Will automatically:\n * - Add a new discussion if no context is set\n * - Add a comment as a reply if replyToItem is set\n * - Edit an discussion or comment if editing is set\n * - Clear UI state after submission\n */\n submitEdit: (text) => {\n const state = get();\n const {\n editingItem,\n replyToItem,\n addDiscussion,\n editDiscussion,\n editComment,\n addComment,\n } = state.discuss;\n\n if (editingItem) {\n if (editingItem.commentId) {\n editComment(editingItem.discussionId, editingItem.commentId, text);\n } else {\n editDiscussion(editingItem.discussionId, text);\n }\n state.discuss.setEditingItem(undefined);\n } else if (replyToItem) {\n if (replyToItem.commentId) {\n addComment(replyToItem.discussionId, text, replyToItem.commentId);\n } else {\n addComment(replyToItem.discussionId, text);\n }\n state.discuss.setReplyToItem(undefined);\n } else {\n addDiscussion(text);\n }\n },\n\n /**\n * Handles the confirmation of a delete operation.\n * Should be called after the user confirms deletion in the UI.\n *\n * Will:\n * - Delete the discussion or comment specified in itemToDelete\n * - Clear the itemToDelete state\n */\n handleDeleteConfirm: () => {\n const state = get();\n const {itemToDelete, removeComment, removeDiscussion} = state.discuss;\n\n if (itemToDelete) {\n if (itemToDelete.commentId) {\n removeComment(itemToDelete.discussionId, itemToDelete.commentId);\n } else {\n removeDiscussion(itemToDelete.discussionId);\n }\n state.discuss.setItemToDelete(undefined);\n }\n },\n\n /**\n * Helper function to get the user ID of the entity being replied to.\n * Returns '' if no reply context is set, or the user ID if a valid reply context exists.\n */\n getReplyToUserId: () => {\n const state = get();\n const {replyToItem} = state.discuss;\n const {discussions} = state.discuss.config;\n\n if (!replyToItem) return '';\n\n const discussion = discussions.find(\n (a) => a.id === replyToItem.discussionId,\n );\n\n if (discussion) {\n if (replyToItem.commentId) {\n if (discussion.rootComment.id === replyToItem.commentId) {\n return discussion.rootComment.userId;\n }\n const comment = discussion.comments.find(\n (c) => c.id === replyToItem.commentId,\n );\n if (comment) return comment.userId;\n } else {\n return discussion.rootComment.userId;\n }\n }\n\n return '';\n },\n\n /**\n * Helper function to get the text of the item being edited.\n * Returns '' if no editing context is set, or the text content if a valid editing context exists.\n */\n getEditingItemText: () => {\n const state = get();\n const {editingItem} = state.discuss;\n const {discussions} = state.discuss.config;\n\n if (!editingItem) return '';\n\n // Look for the discussion\n const discussion = discussions.find(\n (a) => a.id === editingItem.discussionId,\n );\n if (!discussion) return '';\n\n // If editing a comment, find the comment\n if (editingItem.commentId) {\n const comment = discussion.comments.find(\n (c) => c.id === editingItem.commentId,\n );\n return comment ? comment.text : '';\n }\n\n // If editing the discussion itself\n return discussion.rootComment.text;\n },\n },\n }));\n}\n\ntype RoomConfigWithDiscuss = BaseRoomConfig & DiscussSliceConfig;\ntype RoomStateWithDiscuss = RoomShellSliceState<RoomConfigWithDiscuss> &\n DiscussSliceState;\n\nexport function useStoreWithDiscussion<T>(\n selector: (state: RoomStateWithDiscuss) => T,\n): T {\n return useBaseRoomShellStore<\n BaseRoomConfig & DiscussSliceConfig,\n RoomStateWithDiscuss,\n T\n >((state) => selector(state as RoomStateWithDiscuss));\n}\n"]}
|
package/dist/DiscussionList.js
CHANGED
|
@@ -9,7 +9,7 @@ import { useStoreWithDiscussion } from './DiscussSlice';
|
|
|
9
9
|
const defaultRenderDiscussion = (props) => (_jsx(DiscussionItem, { ...props }));
|
|
10
10
|
export const DiscussionList = forwardRef(({ className, renderComment = defaultRenderComment, renderDiscussion = defaultRenderDiscussion, ...props }, ref) => {
|
|
11
11
|
const highlightedDiscussionId = useStoreWithDiscussion((state) => state.discuss.highlightedDiscussionId);
|
|
12
|
-
const discussions = useStoreWithDiscussion((state) => state.config.
|
|
12
|
+
const discussions = useStoreWithDiscussion((state) => state.discuss.config.discussions);
|
|
13
13
|
const replyToItem = useStoreWithDiscussion((state) => state.discuss.replyToItem);
|
|
14
14
|
const editingItem = useStoreWithDiscussion((state) => state.discuss.editingItem);
|
|
15
15
|
const itemToDelete = useStoreWithDiscussion((state) => state.discuss.itemToDelete);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DiscussionList.js","sourceRoot":"","sources":["../src/DiscussionList.tsx"],"names":[],"mappings":"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","sourcesContent":["import {cn} from '@sqlrooms/ui';\nimport {\n ComponentPropsWithoutRef,\n forwardRef,\n Fragment,\n ReactNode,\n useEffect,\n useRef,\n} from 'react';\nimport {CommentItemProps, defaultRenderComment} from './components/CommentItem';\nimport {DeleteConfirmDialog} from './components/DeleteConfirmDialog';\nimport {DiscussionItem, DiscussionItemProps} from './components/DiscussionItem';\nimport {EditCommentForm} from './components/EditCommentForm';\nimport {useStoreWithDiscussion} from './DiscussSlice';\n\n// Main DiscussionList component\ntype DiscussionListProps = ComponentPropsWithoutRef<'div'> & {\n renderDiscussion?: (props: DiscussionItemProps) => ReactNode;\n renderComment?: (props: CommentItemProps) => ReactNode;\n};\n\nconst defaultRenderDiscussion = (props: DiscussionItemProps) => (\n <DiscussionItem {...props} />\n);\n\nexport const DiscussionList = forwardRef<HTMLDivElement, DiscussionListProps>(\n (\n {\n className,\n renderComment = defaultRenderComment,\n renderDiscussion = defaultRenderDiscussion,\n\n ...props\n },\n ref,\n ) => {\n const highlightedDiscussionId = useStoreWithDiscussion(\n (state) => state.discuss.highlightedDiscussionId,\n );\n const discussions = useStoreWithDiscussion(\n (state) => state.config.discuss.discussions,\n );\n const replyToItem = useStoreWithDiscussion(\n (state) => state.discuss.replyToItem,\n );\n const editingItem = useStoreWithDiscussion(\n (state) => state.discuss.editingItem,\n );\n const itemToDelete = useStoreWithDiscussion(\n (state) => state.discuss.itemToDelete,\n );\n const setReplyToItem = useStoreWithDiscussion(\n (state) => state.discuss.setReplyToItem,\n );\n const setEditingItem = useStoreWithDiscussion(\n (state) => state.discuss.setEditingItem,\n );\n const setItemToDelete = useStoreWithDiscussion(\n (state) => state.discuss.setItemToDelete,\n );\n const submitEdit = useStoreWithDiscussion(\n (state) => state.discuss.submitEdit,\n );\n const handleDeleteConfirm = useStoreWithDiscussion(\n (state) => state.discuss.handleDeleteConfirm,\n );\n const getEditingItemText = useStoreWithDiscussion(\n (state) => state.discuss.getEditingItemText,\n );\n\n // Reference to highlighted discussion\n const highlightedRef = useRef<HTMLDivElement>(null);\n\n // Scroll to highlighted discussion\n useEffect(() => {\n if (highlightedDiscussionId && highlightedRef.current) {\n highlightedRef.current.scrollIntoView({\n behavior: 'smooth',\n block: 'start',\n });\n }\n }, [highlightedDiscussionId]);\n\n // Get the context content (the post being replied to or edited)\n const getContextContent = (): ReactNode => {\n if (editingItem) {\n // When editing, show the original content\n const discussion = discussions.find(\n (d) => d.id === editingItem.discussionId,\n );\n if (!discussion) return null;\n\n if (editingItem.commentId) {\n // Editing a comment\n const comment = discussion.comments.find(\n (c) => c.id === editingItem.commentId,\n );\n if (!comment) return null;\n\n return renderComment({comment, discussion});\n } else {\n // Editing the root discussion\n return renderComment({\n comment: discussion.rootComment,\n discussion,\n });\n }\n }\n\n if (replyToItem) {\n // When replying, show what we're replying to\n const discussion = discussions.find(\n (d) => d.id === replyToItem.discussionId,\n );\n if (!discussion) return null;\n\n if (replyToItem.commentId) {\n // Replying to a comment\n const comment = discussion.comments.find(\n (c) => c.id === replyToItem.commentId,\n );\n if (!comment) return null;\n\n return renderComment({comment, discussion});\n } else {\n // Replying to the root discussion\n return renderComment({\n comment: discussion.rootComment,\n discussion,\n });\n }\n }\n\n return null;\n };\n\n const editingContext = getContextContent();\n\n return (\n <div\n ref={ref}\n className={cn('flex h-full flex-col overflow-hidden', className)}\n {...props}\n >\n {/* Scrollable discussion list */}\n <div className=\"flex-1 overflow-y-auto\">\n <div className=\"flex flex-col gap-4 p-2\">\n {discussions.map((discussion) => (\n <Fragment key={discussion.id}>\n {renderDiscussion({\n discussion,\n renderComment,\n ref:\n highlightedDiscussionId === discussion.id\n ? highlightedRef\n : undefined,\n className: cn(\n 'flex flex-col gap-4 rounded border p-2',\n highlightedDiscussionId === discussion.id &&\n 'border-blue-500 shadow-md transition-all duration-500',\n ),\n })}\n </Fragment>\n ))}\n\n {/* Add padding at the bottom to prevent content from being hidden behind sticky form */}\n <div className=\"h-20\" />\n </div>\n </div>\n\n {/* Sticky form at the bottom */}\n <div className=\"bg-background sticky bottom-0 border-t p-2 shadow-lg\">\n {editingContext ? (\n <div className=\"flex flex-col gap-2 p-1\">\n <div className=\"text-muted-foreground text-xs\">\n {replyToItem ? 'Replying to:' : 'Editing:'}\n </div>\n <div className=\"bg-muted rounded border p-2\">\n {editingContext}\n </div>\n </div>\n ) : null}\n {/* Show editing form when editing */}\n {editingItem && (\n <EditCommentForm\n onSubmit={submitEdit}\n initialText={getEditingItemText()}\n submitLabel=\"Save\"\n onCancel={() => {\n setEditingItem(undefined);\n }}\n />\n )}\n\n {/* Show reply form when replying */}\n {!editingItem && replyToItem && (\n <EditCommentForm\n onSubmit={submitEdit}\n initialText=\"\"\n submitLabel=\"Reply\"\n onCancel={() => {\n setReplyToItem(undefined);\n }}\n />\n )}\n\n {/* Show form for new discussions only when not replying or editing */}\n {!editingItem && !replyToItem && (\n <EditCommentForm\n onSubmit={submitEdit}\n initialText=\"\"\n submitLabel=\"Post\"\n />\n )}\n </div>\n\n <DeleteConfirmDialog\n open={!!itemToDelete}\n onOpenChange={(open) => {\n if (!open) setItemToDelete(undefined);\n }}\n onConfirm={handleDeleteConfirm}\n itemType={itemToDelete?.itemType || 'Item'}\n />\n </div>\n );\n },\n);\nDiscussionList.displayName = 'DiscussionList';\n"]}
|
|
1
|
+
{"version":3,"file":"DiscussionList.js","sourceRoot":"","sources":["../src/DiscussionList.tsx"],"names":[],"mappings":"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","sourcesContent":["import {cn} from '@sqlrooms/ui';\nimport {\n ComponentPropsWithoutRef,\n forwardRef,\n Fragment,\n ReactNode,\n useEffect,\n useRef,\n} from 'react';\nimport {CommentItemProps, defaultRenderComment} from './components/CommentItem';\nimport {DeleteConfirmDialog} from './components/DeleteConfirmDialog';\nimport {DiscussionItem, DiscussionItemProps} from './components/DiscussionItem';\nimport {EditCommentForm} from './components/EditCommentForm';\nimport {useStoreWithDiscussion} from './DiscussSlice';\n\n// Main DiscussionList component\ntype DiscussionListProps = ComponentPropsWithoutRef<'div'> & {\n renderDiscussion?: (props: DiscussionItemProps) => ReactNode;\n renderComment?: (props: CommentItemProps) => ReactNode;\n};\n\nconst defaultRenderDiscussion = (props: DiscussionItemProps) => (\n <DiscussionItem {...props} />\n);\n\nexport const DiscussionList = forwardRef<HTMLDivElement, DiscussionListProps>(\n (\n {\n className,\n renderComment = defaultRenderComment,\n renderDiscussion = defaultRenderDiscussion,\n\n ...props\n },\n ref,\n ) => {\n const highlightedDiscussionId = useStoreWithDiscussion(\n (state) => state.discuss.highlightedDiscussionId,\n );\n const discussions = useStoreWithDiscussion(\n (state) => state.discuss.config.discussions,\n );\n const replyToItem = useStoreWithDiscussion(\n (state) => state.discuss.replyToItem,\n );\n const editingItem = useStoreWithDiscussion(\n (state) => state.discuss.editingItem,\n );\n const itemToDelete = useStoreWithDiscussion(\n (state) => state.discuss.itemToDelete,\n );\n const setReplyToItem = useStoreWithDiscussion(\n (state) => state.discuss.setReplyToItem,\n );\n const setEditingItem = useStoreWithDiscussion(\n (state) => state.discuss.setEditingItem,\n );\n const setItemToDelete = useStoreWithDiscussion(\n (state) => state.discuss.setItemToDelete,\n );\n const submitEdit = useStoreWithDiscussion(\n (state) => state.discuss.submitEdit,\n );\n const handleDeleteConfirm = useStoreWithDiscussion(\n (state) => state.discuss.handleDeleteConfirm,\n );\n const getEditingItemText = useStoreWithDiscussion(\n (state) => state.discuss.getEditingItemText,\n );\n\n // Reference to highlighted discussion\n const highlightedRef = useRef<HTMLDivElement>(null);\n\n // Scroll to highlighted discussion\n useEffect(() => {\n if (highlightedDiscussionId && highlightedRef.current) {\n highlightedRef.current.scrollIntoView({\n behavior: 'smooth',\n block: 'start',\n });\n }\n }, [highlightedDiscussionId]);\n\n // Get the context content (the post being replied to or edited)\n const getContextContent = (): ReactNode => {\n if (editingItem) {\n // When editing, show the original content\n const discussion = discussions.find(\n (d) => d.id === editingItem.discussionId,\n );\n if (!discussion) return null;\n\n if (editingItem.commentId) {\n // Editing a comment\n const comment = discussion.comments.find(\n (c) => c.id === editingItem.commentId,\n );\n if (!comment) return null;\n\n return renderComment({comment, discussion});\n } else {\n // Editing the root discussion\n return renderComment({\n comment: discussion.rootComment,\n discussion,\n });\n }\n }\n\n if (replyToItem) {\n // When replying, show what we're replying to\n const discussion = discussions.find(\n (d) => d.id === replyToItem.discussionId,\n );\n if (!discussion) return null;\n\n if (replyToItem.commentId) {\n // Replying to a comment\n const comment = discussion.comments.find(\n (c) => c.id === replyToItem.commentId,\n );\n if (!comment) return null;\n\n return renderComment({comment, discussion});\n } else {\n // Replying to the root discussion\n return renderComment({\n comment: discussion.rootComment,\n discussion,\n });\n }\n }\n\n return null;\n };\n\n const editingContext = getContextContent();\n\n return (\n <div\n ref={ref}\n className={cn('flex h-full flex-col overflow-hidden', className)}\n {...props}\n >\n {/* Scrollable discussion list */}\n <div className=\"flex-1 overflow-y-auto\">\n <div className=\"flex flex-col gap-4 p-2\">\n {discussions.map((discussion) => (\n <Fragment key={discussion.id}>\n {renderDiscussion({\n discussion,\n renderComment,\n ref:\n highlightedDiscussionId === discussion.id\n ? highlightedRef\n : undefined,\n className: cn(\n 'flex flex-col gap-4 rounded border p-2',\n highlightedDiscussionId === discussion.id &&\n 'border-blue-500 shadow-md transition-all duration-500',\n ),\n })}\n </Fragment>\n ))}\n\n {/* Add padding at the bottom to prevent content from being hidden behind sticky form */}\n <div className=\"h-20\" />\n </div>\n </div>\n\n {/* Sticky form at the bottom */}\n <div className=\"bg-background sticky bottom-0 border-t p-2 shadow-lg\">\n {editingContext ? (\n <div className=\"flex flex-col gap-2 p-1\">\n <div className=\"text-muted-foreground text-xs\">\n {replyToItem ? 'Replying to:' : 'Editing:'}\n </div>\n <div className=\"bg-muted rounded border p-2\">\n {editingContext}\n </div>\n </div>\n ) : null}\n {/* Show editing form when editing */}\n {editingItem && (\n <EditCommentForm\n onSubmit={submitEdit}\n initialText={getEditingItemText()}\n submitLabel=\"Save\"\n onCancel={() => {\n setEditingItem(undefined);\n }}\n />\n )}\n\n {/* Show reply form when replying */}\n {!editingItem && replyToItem && (\n <EditCommentForm\n onSubmit={submitEdit}\n initialText=\"\"\n submitLabel=\"Reply\"\n onCancel={() => {\n setReplyToItem(undefined);\n }}\n />\n )}\n\n {/* Show form for new discussions only when not replying or editing */}\n {!editingItem && !replyToItem && (\n <EditCommentForm\n onSubmit={submitEdit}\n initialText=\"\"\n submitLabel=\"Post\"\n />\n )}\n </div>\n\n <DeleteConfirmDialog\n open={!!itemToDelete}\n onOpenChange={(open) => {\n if (!open) setItemToDelete(undefined);\n }}\n onConfirm={handleDeleteConfirm}\n itemType={itemToDelete?.itemType || 'Item'}\n />\n </div>\n );\n },\n);\nDiscussionList.displayName = 'DiscussionList';\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sqlrooms/discuss",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.25.0-rc.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@paralleldrive/cuid2": "^2.2.2",
|
|
19
|
-
"@sqlrooms/room-shell": "0.
|
|
20
|
-
"@sqlrooms/ui": "0.
|
|
21
|
-
"@sqlrooms/utils": "0.
|
|
19
|
+
"@sqlrooms/room-shell": "0.25.0-rc.0",
|
|
20
|
+
"@sqlrooms/ui": "0.25.0-rc.0",
|
|
21
|
+
"@sqlrooms/utils": "0.25.0-rc.0",
|
|
22
22
|
"immer": "^10.1.1",
|
|
23
23
|
"lucide-react": "^0.474.0",
|
|
24
24
|
"zod": "^3.25.73"
|
|
@@ -33,5 +33,5 @@
|
|
|
33
33
|
"lint": "eslint .",
|
|
34
34
|
"typedoc": "typedoc"
|
|
35
35
|
},
|
|
36
|
-
"gitHead": "
|
|
36
|
+
"gitHead": "063d7608fe608031c690ea3b2e67bb1f4e25a8dd"
|
|
37
37
|
}
|