fix local and remote inconsistency

This commit is contained in:
2025-10-17 23:24:05 +02:00
parent 2b0d8a4a73
commit 76fcc64125
2 changed files with 29 additions and 23 deletions

View File

@@ -1,7 +1,7 @@
import React, { useMemo, useEffect } from 'react'; import React, { useMemo, useEffect } from 'react';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import { getColorIntensity, isToday, formatDate, getWeekdayLabel, getFrozenDays } from '../lib/utils-habit'; import { getColorIntensity, isToday, formatDate, getWeekdayLabel, getFrozenDays } from '../lib/utils-habit';
import { toggleCompletion } from '../lib/datastore'; import { toggleCompletion, getAuthUser } from '../lib/datastore';
const HabitGrid = ({ habit, onUpdate, fullView = false }) => { const HabitGrid = ({ habit, onUpdate, fullView = false }) => {
const frozenDays = getFrozenDays(habit.completions); const frozenDays = getFrozenDays(habit.completions);
@@ -38,19 +38,22 @@ const HabitGrid = ({ habit, onUpdate, fullView = false }) => {
} }
}, []); }, []);
const handleCellClick = (date) => { const handleCellClick = async (date) => {
const dateStr = formatDate(date); const dateStr = formatDate(date);
// Optimistic local update // Only do optimistic localStorage write if logged in (remote-first). In local-only mode, let datastore handle it to avoid double-toggle.
const habits = JSON.parse(localStorage.getItem('habitgrid_data') || '[]'); const user = await getAuthUser();
const idx = habits.findIndex(h => h.id === habit.id); if (user) {
if (idx !== -1) { const habits = JSON.parse(localStorage.getItem('habitgrid_data') || '[]');
const completions = Array.isArray(habits[idx].completions) ? [...habits[idx].completions] : []; const idx = habits.findIndex(h => h.id === habit.id);
const cidx = completions.indexOf(dateStr); if (idx !== -1) {
if (cidx > -1) completions.splice(cidx, 1); else completions.push(dateStr); const completions = Array.isArray(habits[idx].completions) ? [...habits[idx].completions] : [];
habits[idx].completions = completions; const cidx = completions.indexOf(dateStr);
localStorage.setItem('habitgrid_data', JSON.stringify(habits)); if (cidx > -1) completions.splice(cidx, 1); else completions.push(dateStr);
habits[idx].completions = completions;
localStorage.setItem('habitgrid_data', JSON.stringify(habits));
}
} }
toggleCompletion(habit.id, dateStr); // background sync await toggleCompletion(habit.id, dateStr);
onUpdate(); onUpdate();
}; };

View File

@@ -40,7 +40,7 @@ function getFreezeIcon() {
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import { getColorIntensity, isToday, formatDate } from '../lib/utils-habit'; import { getColorIntensity, isToday, formatDate } from '../lib/utils-habit';
import { getFrozenDays } from '../lib/utils-habit'; import { getFrozenDays } from '../lib/utils-habit';
import { toggleCompletion } from '../lib/datastore'; import { toggleCompletion, getAuthUser } from '../lib/datastore';
import { toast } from './ui/use-toast'; import { toast } from './ui/use-toast';
const MiniGrid = ({ habit, onUpdate }) => { const MiniGrid = ({ habit, onUpdate }) => {
@@ -69,17 +69,20 @@ const MiniGrid = ({ habit, onUpdate }) => {
const dateStr = formatDate(date); const dateStr = formatDate(date);
const isTodayCell = isToday(date); const isTodayCell = isToday(date);
const wasCompleted = habit.completions.includes(dateStr); const wasCompleted = habit.completions.includes(dateStr);
// Optimistic local update // Only optimistic write if logged in; in local-only mode, datastore handles it to avoid double-toggle
const habits = JSON.parse(localStorage.getItem('habitgrid_data') || '[]'); const user = await getAuthUser();
const idx = habits.findIndex(h => h.id === habit.id); if (user) {
if (idx !== -1) { const habits = JSON.parse(localStorage.getItem('habitgrid_data') || '[]');
const completions = Array.isArray(habits[idx].completions) ? [...habits[idx].completions] : []; const idx = habits.findIndex(h => h.id === habit.id);
const cidx = completions.indexOf(dateStr); if (idx !== -1) {
if (cidx > -1) completions.splice(cidx, 1); else completions.push(dateStr); const completions = Array.isArray(habits[idx].completions) ? [...habits[idx].completions] : [];
habits[idx].completions = completions; const cidx = completions.indexOf(dateStr);
localStorage.setItem('habitgrid_data', JSON.stringify(habits)); if (cidx > -1) completions.splice(cidx, 1); else completions.push(dateStr);
habits[idx].completions = completions;
localStorage.setItem('habitgrid_data', JSON.stringify(habits));
}
} }
toggleCompletion(habit.id, dateStr); // background sync await toggleCompletion(habit.id, dateStr);
onUpdate(); onUpdate();
// Only show encouragement toast if validating (adding) today's dot // Only show encouragement toast if validating (adding) today's dot
if (isTodayCell && !wasCompleted) { if (isTodayCell && !wasCompleted) {