first attempt at stream sidebar, tasks, and events
This commit is contained in:
@@ -33,6 +33,31 @@ import type {
|
||||
|
||||
// --- Converter ---
|
||||
|
||||
// Firestore stores timestamps as `Timestamp`; zod expects `Date`. Coerce the
|
||||
// per-type property fields that carry timestamps.
|
||||
function coerceLeafPropertyDates(
|
||||
type: ParticleType,
|
||||
properties: DocumentData | undefined,
|
||||
): DocumentData | undefined {
|
||||
if (!properties) return properties;
|
||||
if (type === 'text' && properties.edited_at) {
|
||||
return {
|
||||
...properties,
|
||||
edited_at: (properties.edited_at as Timestamp).toDate(),
|
||||
};
|
||||
}
|
||||
if (type === 'event') {
|
||||
return {
|
||||
...properties,
|
||||
start_at: (properties.start_at as Timestamp).toDate(),
|
||||
end_at: properties.end_at
|
||||
? (properties.end_at as Timestamp).toDate()
|
||||
: undefined,
|
||||
};
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
const particleConverter: FirestoreDataConverter<Particle> = {
|
||||
toFirestore(particle: Particle): DocumentData {
|
||||
const { id: _id, created_at, updated_at, ...rest } = particle;
|
||||
@@ -79,7 +104,6 @@ const particleConverter: FirestoreDataConverter<Particle> = {
|
||||
: undefined,
|
||||
huddle_active_participants:
|
||||
raw.huddle_active_participants ?? undefined,
|
||||
status: raw.status ?? undefined,
|
||||
});
|
||||
case 'folder':
|
||||
return ParticleSchema.parse({
|
||||
@@ -96,17 +120,10 @@ const particleConverter: FirestoreDataConverter<Particle> = {
|
||||
case 'media':
|
||||
case 'file':
|
||||
case 'text':
|
||||
case 'quest':
|
||||
case 'task':
|
||||
case 'event':
|
||||
case 'paper': {
|
||||
// Firestore stores timestamps as `Timestamp`; zod expects `Date`. Text
|
||||
// particles carry `properties.edited_at`, so coerce it if present.
|
||||
const properties =
|
||||
type === 'text' && raw.properties?.edited_at
|
||||
? {
|
||||
...raw.properties,
|
||||
edited_at: (raw.properties.edited_at as Timestamp).toDate(),
|
||||
}
|
||||
: raw.properties;
|
||||
const properties = coerceLeafPropertyDates(type, raw.properties);
|
||||
return ParticleSchema.parse({
|
||||
id: snap.id,
|
||||
type: raw.type,
|
||||
@@ -308,7 +325,6 @@ export async function createStreamParticle(
|
||||
created_at: new Date(),
|
||||
created_by_human_id: createdByHumanId,
|
||||
visible_to: visibleTo,
|
||||
status: 'open',
|
||||
});
|
||||
const ref = await addDoc(typedCollection(collectionPath), particle);
|
||||
return ref.id;
|
||||
@@ -382,14 +398,6 @@ export async function updateParticle(
|
||||
});
|
||||
}
|
||||
|
||||
export async function updateStreamStatus(
|
||||
docPath: string,
|
||||
status: 'open' | 'closed',
|
||||
): Promise<void> {
|
||||
const particleRef = typedDoc(docPath);
|
||||
await updateDoc(particleRef, { status, updated_at: serverTimestamp() });
|
||||
}
|
||||
|
||||
/**
|
||||
* Soft-delete (tombstone) a non-container particle. The Firestore doc stays
|
||||
* in place so concurrent viewers see the deletion inline rather than being
|
||||
|
||||
Reference in New Issue
Block a user