fixed issues namely reveloved around chat
This commit is contained in:
@@ -14,6 +14,14 @@
|
||||
|
||||
const isOwn = (msg: any) => msg.authorId === chatStore.actorId;
|
||||
|
||||
// Colour comes from the sender's user record (loaded with the family on
|
||||
// page load) — no per-message snapshot, no live colour tracking. Falls back
|
||||
// to the stored authorColor for any message sent before this change.
|
||||
function colorOf(msg: any): string {
|
||||
if (msg.authorId === chatStore.actorId) return chatStore.actorColor || '#6366f1';
|
||||
return msg.authorColor || '#6366f1';
|
||||
}
|
||||
|
||||
function scrollToBottom(instant = false) {
|
||||
if (!container) return;
|
||||
container.scrollTo({
|
||||
@@ -107,15 +115,18 @@
|
||||
{#each chatStore.messages as msg (msg.id)}
|
||||
<div class="msg-row" class:own={isOwn(msg)}>
|
||||
{#if !isOwn(msg)}
|
||||
<span class="avatar" style="background:{msg.authorColor || '#6366f1'}">
|
||||
<span class="avatar" style="background:{colorOf(msg)}">
|
||||
{msg.authorName?.charAt(0).toUpperCase()}
|
||||
</span>
|
||||
{/if}
|
||||
<div class="bubble-wrap">
|
||||
{#if !isOwn(msg)}
|
||||
<span class="msg-author">{msg.authorName}</span>
|
||||
<span class="msg-author" style="color:{colorOf(msg)}">{msg.authorName}</span>
|
||||
{/if}
|
||||
<div class="bubble">
|
||||
<div
|
||||
class="bubble"
|
||||
style="background:{colorOf(msg) + '33'}; color:{colorOf(msg)}"
|
||||
>
|
||||
{#each renderContent(msg.content) as seg (msg.id + ':' + seg.text)}
|
||||
{#if seg.mention}
|
||||
<button class="mention" onclick={() => insertMention(seg.text.slice(1))}
|
||||
@@ -274,8 +285,6 @@
|
||||
position: relative;
|
||||
}
|
||||
.msg-row.own .bubble {
|
||||
background: #6366f1;
|
||||
color: #fff;
|
||||
border-bottom-left-radius: 14px;
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
@@ -288,7 +297,7 @@
|
||||
text-transform: capitalize;
|
||||
}
|
||||
.msg-row.own .msg-time {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
color: rgba(17, 24, 39, 0.45);
|
||||
}
|
||||
.mention {
|
||||
background: #ede9fe;
|
||||
|
||||
@@ -106,27 +106,30 @@ async function ensureUsers(ids: Record<string, string>): Promise<void> {
|
||||
changed = true;
|
||||
}
|
||||
|
||||
const listRule = "famId = @request.auth.famId";
|
||||
const parentWrite = "famId = @request.auth.famId && @request.auth.role = 'parent'";
|
||||
if (usersCol.listRule !== listRule || usersCol.viewRule !== listRule ||
|
||||
usersCol.updateRule !== parentWrite || usersCol.deleteRule !== parentWrite) {
|
||||
changed = true;
|
||||
}
|
||||
const listRule = "famId = @request.auth.famId";
|
||||
const parentWrite = "famId = @request.auth.famId && @request.auth.role = 'parent'";
|
||||
// Members can edit their own record (name/colour); parents can edit any
|
||||
// family member. Delete stays parent-only.
|
||||
const selfOrParentWrite = "@request.auth.id = id || (famId = @request.auth.famId && @request.auth.role = 'parent')";
|
||||
if (usersCol.listRule !== listRule || usersCol.viewRule !== listRule ||
|
||||
usersCol.updateRule !== selfOrParentWrite || usersCol.deleteRule !== parentWrite) {
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
await updateCollection(usersCol.id, {
|
||||
name: "users",
|
||||
type: "auth",
|
||||
listRule,
|
||||
viewRule: listRule,
|
||||
createRule: usersCol.createRule || "",
|
||||
updateRule: parentWrite,
|
||||
deleteRule: parentWrite,
|
||||
fields: usersCol.fields,
|
||||
indexes,
|
||||
passwordAuth: { enabled: true, identityFields },
|
||||
});
|
||||
}
|
||||
if (changed) {
|
||||
await updateCollection(usersCol.id, {
|
||||
name: "users",
|
||||
type: "auth",
|
||||
listRule,
|
||||
viewRule: listRule,
|
||||
createRule: usersCol.createRule || "",
|
||||
updateRule: selfOrParentWrite,
|
||||
deleteRule: parentWrite,
|
||||
fields: usersCol.fields,
|
||||
indexes,
|
||||
passwordAuth: { enabled: true, identityFields },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Superuser-only OTP store for the child join gate. Holds the rotating code and
|
||||
|
||||
@@ -50,21 +50,38 @@ class ChatStore {
|
||||
});
|
||||
|
||||
async init(opts: ChatInit) {
|
||||
// Re-initialize whenever the family OR the actor changes (e.g. switching
|
||||
// between parent and child in the same browser session). The store is a
|
||||
// module singleton — keeping the previous actor's identity/subscription
|
||||
// would make one direction's realtime silently dead.
|
||||
const sameIdentity =
|
||||
this.initialized &&
|
||||
this.famId === opts.famId &&
|
||||
this.actorId === opts.actorId &&
|
||||
this.actorType === opts.actorType;
|
||||
if (sameIdentity) return;
|
||||
if (this.initPromise) {
|
||||
await this.initPromise;
|
||||
if (
|
||||
this.initialized &&
|
||||
this.famId === opts.famId &&
|
||||
this.actorId === opts.actorId &&
|
||||
this.actorType === opts.actorType
|
||||
)
|
||||
return;
|
||||
}
|
||||
|
||||
this.cleanup();
|
||||
this.destroyed = false;
|
||||
this.famId = opts.famId;
|
||||
this.actorId = opts.actorId;
|
||||
this.actorType = opts.actorType;
|
||||
this.actorName = opts.actorName;
|
||||
this.actorColor = opts.actorColor;
|
||||
this.pbToken = opts.pbToken || '';
|
||||
|
||||
if (this.initialized && this.famId === opts.famId) return;
|
||||
if (this.initPromise) {
|
||||
await this.initPromise;
|
||||
if (this.initialized && this.famId === opts.famId) return;
|
||||
}
|
||||
|
||||
this.cleanup();
|
||||
this.destroyed = false;
|
||||
this.messages = [];
|
||||
this.typing = {};
|
||||
this.unread = 0;
|
||||
this.lastSeenAt = Date.now();
|
||||
|
||||
this.initPromise = (async () => {
|
||||
|
||||
Reference in New Issue
Block a user