From 82b501e753af6737c03f2881722bb7e84b403a65 Mon Sep 17 00:00:00 2001 From: escouade-bot Date: Tue, 31 Mar 2026 00:01:14 -0400 Subject: [PATCH] fix: force widget refresh via requestWidgetUpdate after click actions (#32) The Android ListView caches its items, so visual-only changes (like toggling a subtask checkbox) were not reflected without calling requestWidgetUpdate() to invalidate the cache. Added forceWidgetRefresh() helper that calls requestWidgetUpdate() for all 3 widget sizes after TOGGLE_SUBTASK, TOGGLE_COMPLETE, and TOGGLE_EXPAND handlers. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/widgets/widgetTaskHandler.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/widgets/widgetTaskHandler.ts b/src/widgets/widgetTaskHandler.ts index 90c33f8..757de46 100644 --- a/src/widgets/widgetTaskHandler.ts +++ b/src/widgets/widgetTaskHandler.ts @@ -1,8 +1,11 @@ import type { WidgetTaskHandlerProps } from 'react-native-android-widget'; +import { requestWidgetUpdate } from 'react-native-android-widget'; import { TaskListWidget } from './TaskListWidget'; import { getWidgetState, setWidgetState, type WidgetTask } from '../services/widgetSync'; import { isValidUUID } from '../lib/validation'; +const WIDGET_NAMES = ['SimplListeSmall', 'SimplListeMedium', 'SimplListeLarge']; + const EXPAND_DEBOUNCE_MS = 2000; const lastExpandTimes = new Map(); @@ -24,6 +27,25 @@ function renderWithState( ); } +async function forceWidgetRefresh( + tasks: WidgetTask[], + isDark: boolean, + expandedTaskIds: string[], +): Promise { + for (const widgetName of WIDGET_NAMES) { + try { + await requestWidgetUpdate({ + widgetName, + renderWidget: (props) => + TaskListWidget({ ...props, widgetName, tasks, isDark, expandedTaskIds }), + widgetNotFound: () => {}, + }); + } catch { + // Widget not placed on home screen + } + } +} + export async function widgetTaskHandler( props: WidgetTaskHandlerProps ): Promise { @@ -51,6 +73,7 @@ export async function widgetTaskHandler( await setWidgetState(state); renderWithState(renderWidget, widgetInfo, state.tasks, state.isDark, state.expandedTaskIds); + await forceWidgetRefresh(state.tasks, state.isDark, state.expandedTaskIds); try { const { toggleComplete } = await import('../db/repository/tasks'); @@ -82,6 +105,7 @@ export async function widgetTaskHandler( await setWidgetState(state); renderWithState(renderWidget, widgetInfo, state.tasks, state.isDark, state.expandedTaskIds); + await forceWidgetRefresh(state.tasks, state.isDark, state.expandedTaskIds); } if (props.clickAction === 'TOGGLE_SUBTASK') { @@ -103,6 +127,7 @@ export async function widgetTaskHandler( await setWidgetState(state); renderWithState(renderWidget, widgetInfo, state.tasks, state.isDark, state.expandedTaskIds); + await forceWidgetRefresh(state.tasks, state.isDark, state.expandedTaskIds); try { const { toggleComplete } = await import('../db/repository/tasks');