fix bugs
This commit is contained in:
@@ -208,7 +208,7 @@
|
|||||||
<span class="msg-author" style="color:{colorOf(msg)}">{msg.authorName}</span>
|
<span class="msg-author" style="color:{colorOf(msg)}">{msg.authorName}</span>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="bubble" style="background:{colorOf(msg) + '33'}; color:{colorOf(msg)}">
|
<div class="bubble" style="background:{colorOf(msg) + '33'}; color:{colorOf(msg)}">
|
||||||
{#each renderContent(msg.content) as seg (msg.id + ':' + seg.text)}
|
{#each renderContent(msg.content) as seg, i (msg.id + ':' + i)}
|
||||||
{#if seg.mention}
|
{#if seg.mention}
|
||||||
<button class="mention" onclick={() => insertMention(seg.text.slice(1))}
|
<button class="mention" onclick={() => insertMention(seg.text.slice(1))}
|
||||||
>{seg.text}</button
|
>{seg.text}</button
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import type { Snippet } from 'svelte';
|
||||||
let {
|
let {
|
||||||
announcement = '',
|
announcement = '',
|
||||||
role = '',
|
role = '',
|
||||||
seasons = [],
|
seasons = [],
|
||||||
connected = true,
|
connected = true,
|
||||||
children,
|
children,
|
||||||
|
left
|
||||||
}: {
|
}: {
|
||||||
announcement?: string
|
announcement?: string
|
||||||
role?: string
|
role?: string
|
||||||
seasons?: { id: string; name: string; color: string; active: boolean }[]
|
seasons?: { id: string; name: string; color: string; active: boolean }[]
|
||||||
connected?: boolean
|
connected?: boolean
|
||||||
children?: any
|
children?: any
|
||||||
|
left?: Snippet
|
||||||
} = $props();
|
} = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -19,6 +22,7 @@
|
|||||||
{#if role}
|
{#if role}
|
||||||
<span class="role-pill {role}">{role}</span>
|
<span class="role-pill {role}">{role}</span>
|
||||||
{/if}
|
{/if}
|
||||||
|
{@render left?.()}
|
||||||
<span
|
<span
|
||||||
class="conn-dot"
|
class="conn-dot"
|
||||||
class:up={connected}
|
class:up={connected}
|
||||||
|
|||||||
@@ -55,14 +55,13 @@ export async function toggle(pb: any, famId: string, memberId: string, body: { a
|
|||||||
const chore = choreList?.[0];
|
const chore = choreList?.[0];
|
||||||
const isTodo = chore?.isTodo;
|
const isTodo = chore?.isTodo;
|
||||||
const isShared = chore?.shared === true || !chore?.memberId;
|
const isShared = chore?.shared === true || !chore?.memberId;
|
||||||
|
// Only one-off shared todos are claimed (winner takes it). Recurring
|
||||||
|
// shared chores stay unassigned so every member completes independently
|
||||||
|
// each period — claiming them permanently hides the chore from siblings.
|
||||||
|
const isClaimable = isShared && !!isTodo;
|
||||||
|
|
||||||
let filter: string;
|
let filter: string;
|
||||||
if (isShared && !isTodo) {
|
if (isTodo) {
|
||||||
// Shared non-todo: any completion in the period = already claimed
|
|
||||||
const { payday, tz } = await famMetaSU(famId);
|
|
||||||
const { from, to } = periodWindow(chore?.frequency, payday, tz);
|
|
||||||
filter = `assignedChoreId = '${assignedChoreId}' && date >= '${from}' && date < '${to}'`;
|
|
||||||
} else if (isTodo) {
|
|
||||||
filter = `assignedChoreId = '${assignedChoreId}' && memberId = '${memberId}'`;
|
filter = `assignedChoreId = '${assignedChoreId}' && memberId = '${memberId}'`;
|
||||||
} else {
|
} else {
|
||||||
const { payday, tz } = await famMetaSU(famId);
|
const { payday, tz } = await famMetaSU(famId);
|
||||||
@@ -78,8 +77,8 @@ export async function toggle(pb: any, famId: string, memberId: string, body: { a
|
|||||||
if (isTodo && existing[0].rewardId) {
|
if (isTodo && existing[0].rewardId) {
|
||||||
await pb.collection('rewards').delete(existing[0].rewardId).catch(() => {});
|
await pb.collection('rewards').delete(existing[0].rewardId).catch(() => {});
|
||||||
}
|
}
|
||||||
// If this was a shared chore claimed by this member, un-share it
|
// If this was a claimed one-off todo, release it back to shared.
|
||||||
if (isShared && existing[0].memberId === memberId) {
|
if (isClaimable && existing[0].memberId === memberId) {
|
||||||
await claimChore(assignedChoreId, famId, '');
|
await claimChore(assignedChoreId, famId, '');
|
||||||
}
|
}
|
||||||
evaluateFam(pb, famId).catch(() => {});
|
evaluateFam(pb, famId).catch(() => {});
|
||||||
@@ -107,8 +106,9 @@ export async function toggle(pb: any, famId: string, memberId: string, body: { a
|
|||||||
completedAt: new Date().toISOString(),
|
completedAt: new Date().toISOString(),
|
||||||
...(rewardId ? { rewardId } : {})
|
...(rewardId ? { rewardId } : {})
|
||||||
});
|
});
|
||||||
// Claim the shared chore by setting memberId
|
// Claim a shared one-off todo by setting memberId (recurring shared
|
||||||
if (isShared) {
|
// chores stay unassigned — see isClaimable above).
|
||||||
|
if (isClaimable) {
|
||||||
await claimChore(assignedChoreId, famId, memberId);
|
await claimChore(assignedChoreId, famId, memberId);
|
||||||
}
|
}
|
||||||
evaluateFam(pb, famId).catch(() => {});
|
evaluateFam(pb, famId).catch(() => {});
|
||||||
|
|||||||
@@ -306,6 +306,18 @@
|
|||||||
announcement={disabled && !activating ? accessMessage(accessReason, isParent) : ''}
|
announcement={disabled && !activating ? accessMessage(accessReason, isParent) : ''}
|
||||||
connected={!famStore.connectionDown}
|
connected={!famStore.connectionDown}
|
||||||
>
|
>
|
||||||
|
{#snippet left()}
|
||||||
|
<button
|
||||||
|
class="shared-toggle"
|
||||||
|
class:on={sharedOn}
|
||||||
|
onclick={toggleShared}
|
||||||
|
aria-label="Toggle shared computer mode"
|
||||||
|
aria-pressed={sharedOn}
|
||||||
|
title={sharedOn ? 'Shared computer mode is ON' : 'Mark this as a shared computer'}
|
||||||
|
>
|
||||||
|
{@html monitorIcon}
|
||||||
|
</button>
|
||||||
|
{/snippet}
|
||||||
<button class="chat-toggle" onclick={() => chatStore.toggle()} aria-label="Open chat">
|
<button class="chat-toggle" onclick={() => chatStore.toggle()} aria-label="Open chat">
|
||||||
{@html chatIcon}
|
{@html chatIcon}
|
||||||
{#if chatStore.unread > 0}
|
{#if chatStore.unread > 0}
|
||||||
@@ -323,16 +335,6 @@
|
|||||||
></span>
|
></span>
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
<button
|
|
||||||
class="shared-toggle"
|
|
||||||
class:on={sharedOn}
|
|
||||||
onclick={toggleShared}
|
|
||||||
aria-label="Toggle shared computer mode"
|
|
||||||
aria-pressed={sharedOn}
|
|
||||||
title={sharedOn ? 'Shared computer mode is ON' : 'Mark this as a shared computer'}
|
|
||||||
>
|
|
||||||
{@html monitorIcon}
|
|
||||||
</button>
|
|
||||||
</TopNav>
|
</TopNav>
|
||||||
<main class="app-main" class:join-page={page.url.pathname.split('/')[2] === 'join'}>
|
<main class="app-main" class:join-page={page.url.pathname.split('/')[2] === 'join'}>
|
||||||
<div class="page-wrap">
|
<div class="page-wrap">
|
||||||
|
|||||||
@@ -550,9 +550,10 @@
|
|||||||
const name = bonusConfigs.find((b: BonusConfig) => b.id === r.bonusConfigId)?.name || r.label;
|
const name = bonusConfigs.find((b: BonusConfig) => b.id === r.bonusConfigId)?.name || r.label;
|
||||||
map.set(name, (map.get(name) || 0) + 1);
|
map.set(name, (map.get(name) || 0) + 1);
|
||||||
}
|
}
|
||||||
// Only badge recurring/multiple bonuses — a single occurrence (×1) is
|
// Badge every bonus earned this week — including a single occurrence
|
||||||
// already obvious from the wallet, so it just adds noise here.
|
// (×1): the hero is the child's only at-a-glance signal, so nothing
|
||||||
return [...map.entries()].map(([name, count]) => ({ name, count })).filter((t) => t.count > 1);
|
// earned should stay invisible here.
|
||||||
|
return [...map.entries()].map(([name, count]) => ({ name, count }));
|
||||||
});
|
});
|
||||||
let anyWeekBonuses = $derived(weekRewards.length > 0);
|
let anyWeekBonuses = $derived(weekRewards.length > 0);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user