UNPKG

one

Version:

One is a React framework for web, iOS, and Android apps.

109 lines (98 loc) • 4.24 kB
import { NativeEventEmitter, NativeModules, Platform } from 'react-native' import type { ReactNode } from 'react' import { encodeActivityView, encodeWidgetView, type ActivityView } from './view' import { LiveActivities as unavailableLiveActivities } from './unavailable' export { WidgetUI, type WidgetStyle, type ActivityView } from './view' export type WidgetData = { title: string; value: string; subtitle: string } export type LiveActivityState = { status: string; value: string } export type PushTokenEvent = { id: string; token: string } interface WidgetsBridge { writeWidget(title: string, value: string, subtitle: string): Promise<void> writeView(layout: string): Promise<void> start(title: string, status: string, value: string, push: boolean): Promise<string> startView(title: string, layout: string, push: boolean): Promise<string> update(id: string, status: string, value: string): Promise<void> updateView(id: string, layout: string): Promise<void> end(id: string): Promise<void> pushToken(id: string): Promise<string | null> addListener(event: string): void removeListeners(count: number): void } function bridge(): WidgetsBridge { const native = NativeModules.OneWidgetsBridge as WidgetsBridge | undefined if (!native) throw new Error('iOS widgets require native.app.ios.widgets and a new iOS build') return native } const nativeWidgets = Object.freeze({ write(data: WidgetData): Promise<void> { return bridge().writeWidget(data.title, data.value, data.subtitle) }, writeView(view: ReactNode): Promise<void> { return bridge().writeView(encodeWidgetView(view)) }, }) const nativeLiveActivities = Object.freeze({ start(title: string, state: LiveActivityState, push = false): Promise<string> { return bridge().start(title, state.status, state.value, push) }, startView(title: string, view: ActivityView, push = false): Promise<string> { return bridge().startView(title, encodeActivityView(view), push) }, update(id: string, state: LiveActivityState): Promise<void> { return bridge().update(id, state.status, state.value) }, updateView(id: string, view: ActivityView): Promise<void> { return bridge().updateView(id, encodeActivityView(view)) }, end(id: string): Promise<void> { return bridge().end(id) }, pushToken(id: string): Promise<string | null> { return bridge().pushToken(id) }, onPushToken(listener: (event: PushTokenEvent) => void): () => void { const subscription = new NativeEventEmitter(bridge()).addListener( 'oneLiveActivityPushToken', listener ) return () => subscription.remove() }, }) function androidLimit(operation: string): Error { return new Error(`${operation} requires an iOS native build`) } const androidWidgets = Object.freeze({ write(_data: WidgetData): Promise<void> { return Promise.reject(androidLimit('Widgets.write')) }, writeView(_view: ReactNode): Promise<void> { return Promise.reject(androidLimit('Widgets.writeView')) }, }) const androidLiveActivities = Object.freeze({ ...unavailableLiveActivities, start(_title: string, _state: LiveActivityState, _push = false): Promise<string> { return Promise.reject(androidLimit('LiveActivities.start')) }, startView(_title: string, _view: ActivityView, _push = false): Promise<string> { return Promise.reject(androidLimit('LiveActivities.startView')) }, update(_id: string, _state: LiveActivityState): Promise<void> { return Promise.reject(androidLimit('LiveActivities.update')) }, updateView(_id: string, _view: ActivityView): Promise<void> { return Promise.reject(androidLimit('LiveActivities.updateView')) }, end(_id: string): Promise<void> { return Promise.reject(androidLimit('LiveActivities.end')) }, onPushToken(_listener: (event: PushTokenEvent) => void): () => void { throw androidLimit('LiveActivities.onPushToken') }, }) // widgetkit and activitykit are iOS only; Android action methods report that limit. export const Widgets: typeof nativeWidgets = Platform.OS === 'android' ? androidWidgets : nativeWidgets export const LiveActivities: typeof nativeLiveActivities = Platform.OS === 'android' ? androidLiveActivities : nativeLiveActivities