import * as React from 'react'; import { AppRegistry } from 'react-native'; import { AndroidWidget } from '../AndroidWidget'; import { buildWidgetTree } from './build-widget-tree'; import type { WidgetInfo, WidgetRepresentation } from './types'; const HEADLESS_TASK_KEY = 'RNWidgetBackgroundTask'; interface NativeTaskInfo extends WidgetInfo { widgetAction: | 'WIDGET_ADDED' | 'WIDGET_UPDATE' | 'WIDGET_RESIZED' | 'WIDGET_DELETED' | 'WIDGET_CLICK'; clickAction?: string; clickActionData?: Record; } export interface WidgetTaskHandlerProps { /** * Information about the widget being handled. */ widgetInfo: WidgetInfo; /** * What kind of action is being handled */ widgetAction: | 'WIDGET_ADDED' | 'WIDGET_UPDATE' | 'WIDGET_RESIZED' | 'WIDGET_DELETED' | 'WIDGET_CLICK'; /** * Click action if widgetAction was WIDGET_CLICK */ clickAction?: string; /** * Additional click action data if widgetAction was `WIDGET_CLICK` */ clickActionData?: Record; /** * Function that needs to be called with the Widget JSX to render */ renderWidget: (widgetComponent: WidgetRepresentation) => void; } export type WidgetTaskHandler = ( props: WidgetTaskHandlerProps ) => Promise; /** * Register a task handler that will handle widget actions * * @param handler {@link WidgetTaskHandler} */ export function registerWidgetTaskHandler(handler: WidgetTaskHandler): void { async function taskProvider({ widgetAction, clickAction, clickActionData, ...widgetInfo }: NativeTaskInfo) { function renderWidget(widgetComponent: WidgetRepresentation) { if (widgetAction === 'WIDGET_DELETED') return; const lightWidget = 'light' in widgetComponent ? buildWidgetTree(widgetComponent.light) : buildWidgetTree(widgetComponent); const darkWidget = 'dark' in widgetComponent ? buildWidgetTree(widgetComponent.dark as React.JSX.Element) : null; const config = { light: lightWidget, dark: darkWidget, }; AndroidWidget.drawWidgetById( config, widgetInfo.widgetName, widgetInfo.widgetId ); } await handler({ widgetInfo, widgetAction, clickAction, clickActionData: clickActionData ? JSON.parse(clickActionData as unknown as string) : {}, renderWidget, }); } AppRegistry.registerHeadlessTask(HEADLESS_TASK_KEY, () => taskProvider); }