diff --git a/example/app.json b/example/app.json index 752d545d..885cfa4f 100644 --- a/example/app.json +++ b/example/app.json @@ -204,6 +204,19 @@ "intervalMinutes": 15, "refresh": true } + }, + { + "id": "android_reactive_weather", + "displayName": "Reactive Weather (Track 4)", + "description": "Hermes-resolved AppIntent parameter — change city from the in-app Reactive Widget screen", + "targetCellWidth": 2, + "targetCellHeight": 2, + "resizeMode": "horizontal|vertical", + "widgetCategory": "home_screen", + "initialStatePath": "./widgets/android/android-reactive-weather-initial.tsx", + "appIntent": { + "parameters": [{ "name": "city", "title": "City", "default": "New York" }] + } } ], "fonts": [ diff --git a/example/app/android-widgets/reactive.tsx b/example/app/android-widgets/reactive.tsx new file mode 100644 index 00000000..94941924 --- /dev/null +++ b/example/app/android-widgets/reactive.tsx @@ -0,0 +1,5 @@ +import AndroidReactiveWidgetScreen from '~/screens/android/AndroidReactiveWidgetScreen' + +export default function AndroidReactiveWidgetIndex() { + return +} diff --git a/example/screens/android/AndroidReactiveWidgetScreen.tsx b/example/screens/android/AndroidReactiveWidgetScreen.tsx new file mode 100644 index 00000000..26aa3381 --- /dev/null +++ b/example/screens/android/AndroidReactiveWidgetScreen.tsx @@ -0,0 +1,112 @@ +import { useRouter } from 'expo-router' +import React, { useState } from 'react' +import { Alert, Platform, StyleSheet, Text, TextInput, View } from 'react-native' +import { setAppIntentParam } from '@use-voltra/android-client' + +import { Button } from '~/components/Button' +import { ScreenLayout } from '~/components/ScreenLayout' + +/** + * Track 4 PoC — in-app stand-in for a future Glance configuration activity. + * Writes the `city` AppIntent parameter into Voltra's DataStore and triggers a + * Glance update; the Hermes resolver substitutes the placeholder at render + * time and the widget re-renders with the new value. + */ +export default function AndroidReactiveWidgetScreen() { + const router = useRouter() + const [city, setCity] = useState('') + const [busy, setBusy] = useState(false) + + const handleSubmit = async () => { + if (Platform.OS !== 'android') { + Alert.alert('Not available', 'This screen demonstrates the Android-only Track 4 PoC.') + return + } + const value = city.trim() + if (!value) { + Alert.alert('Empty input', 'Type a city name before submitting.') + return + } + setBusy(true) + try { + await setAppIntentParam('android_reactive_weather', 'city', value) + Alert.alert( + 'Param updated', + `Wrote city="${value}" to DataStore and triggered the Glance update. The Reactive Weather widget should now show "${value}".` + ) + } catch (e: unknown) { + const message = e instanceof Error ? e.message : String(e) + Alert.alert('Error', `Failed to update param: ${message}`) + } finally { + setBusy(false) + } + } + + return ( + + + City + + Add the "Reactive Weather (Track 4)" widget to your home screen first. + + + +