@forthtilliath/react-native-kit 0.19.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -15
- package/dist/components/picker/PhotoPicker.d.ts +7 -1
- package/dist/components/picker/PhotoPicker.d.ts.map +1 -1
- package/dist/components/picker/PhotoPicker.js +2 -1
- package/dist/components/picker/QuantityStepper.d.ts +7 -1
- package/dist/components/picker/QuantityStepper.d.ts.map +1 -1
- package/dist/components/picker/QuantityStepper.js +4 -4
- package/dist/components/settings/UpdateSettingsScreen.d.ts +16 -3
- package/dist/components/settings/UpdateSettingsScreen.d.ts.map +1 -1
- package/dist/components/settings/UpdateSettingsScreen.js +24 -9
- package/dist/components/settings/UpdateSettingsScreen.styles.d.ts +13 -1
- package/dist/components/settings/UpdateSettingsScreen.styles.d.ts.map +1 -1
- package/dist/components/settings/UpdateSettingsScreen.styles.js +4 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/useViewShare.d.ts +39 -0
- package/dist/hooks/useViewShare.d.ts.map +1 -0
- package/dist/hooks/useViewShare.js +75 -0
- package/dist/utils/helpers/shareViewAsImage.d.ts +5 -3
- package/dist/utils/helpers/shareViewAsImage.d.ts.map +1 -1
- package/dist/utils/helpers/shareViewAsImage.js +3 -1
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -213,6 +213,7 @@ import { PhotoPicker } from "@forthtilliath/react-native-kit/components/picker/P
|
|
|
213
213
|
|
|
214
214
|
- `renderPreview(photoUri, saving)` replaces the square preview and the "Add a photo" placeholder (e.g. a round avatar with initials and a small camera badge); the press, permission and action sheet stay the same.
|
|
215
215
|
- While `savePhoto` runs, the picker ignores presses (`saving` is `true`, `accessibilityState.busy`).
|
|
216
|
+
- `onOpen()` fires when a press opens the camera/library choice — the place for a haptic tick (`onOpen={tapFeedback}`).
|
|
216
217
|
- A failure (camera, picker or `savePhoto` rejecting) goes to `onError(error)`; without it, an alert says the photo was not saved (`labels.saveErrorTitle` / `saveErrorMessage`).
|
|
217
218
|
|
|
218
219
|
### `<PickerModal visible title items onSelect onClose />`
|
|
@@ -296,6 +297,25 @@ const repeat = usePressRepeat();
|
|
|
296
297
|
/>;
|
|
297
298
|
```
|
|
298
299
|
|
|
300
|
+
### `useViewShare(options?)`
|
|
301
|
+
|
|
302
|
+
Shares as an image a view rendered only for the capture (a scoreboard, a summary card): `share()` sets `capturing` to `true`, waits two frames for the screen to mount and draw the view attached to `ref`, then calls `shareViewAsImage`. A failure shows an alert with the error's message (French or English titles, `errorTitle` / `errorMessage` to override), or goes to `onError(error)`. A second `share()` while one runs is ignored. Takes `shareViewAsImage`'s options (`dialogTitle`…).
|
|
303
|
+
|
|
304
|
+
```tsx
|
|
305
|
+
import { useViewShare } from "@forthtilliath/react-native-kit/hooks/useViewShare";
|
|
306
|
+
|
|
307
|
+
const ranking = useViewShare({ dialogTitle: "Partager le classement" });
|
|
308
|
+
|
|
309
|
+
<Button title="Partager" onPress={() => void ranking.share()} />;
|
|
310
|
+
{
|
|
311
|
+
ranking.capturing ? (
|
|
312
|
+
<View ref={ranking.ref} collapsable={false} style={offScreen}>
|
|
313
|
+
<RankingCard />
|
|
314
|
+
</View>
|
|
315
|
+
) : null;
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
299
319
|
### `confirmDestructive(title, onConfirm, options?)`
|
|
300
320
|
|
|
301
321
|
Generic destructive-action confirmation (title + message + Cancel/Confirm), for anything irreversible (delete, reset...). Ships with French defaults, or English ones with `{ locale: "en" }` (`message`, `cancelLabel`, `confirmLabel` all overridable).
|
|
@@ -382,20 +402,20 @@ const colors = Colors[useResolvedScheme()];
|
|
|
382
402
|
|
|
383
403
|
Every component below has neutral default colors and a `styles` prop whose slots are each merged **after** their default (a partial override keeps the rest of the slot) — pass the app's palette there.
|
|
384
404
|
|
|
385
|
-
| Component | Import path | What it is
|
|
386
|
-
| ----------------------------------------------------------------------- | ----------------------------------- |
|
|
387
|
-
| `<BottomSheet visible onClose bottomInset?>` | `components/overlay/BottomSheet` | Modal sliding up from the bottom, content scrollable past 85 % of the screen. Pass `useSafeAreaInsets().bottom` as `bottomInset` with Android edge-to-edge.
|
|
388
|
-
| `<OptionsModal visible onClose options onSelect>` | `components/picker/OptionsModal` | Centered popup listing `{ value, label }` options; a tap selects and closes.
|
|
389
|
-
| `<SelectField label valueLabel options onSelect>` | `components/picker/SelectField` | Native-looking "select": captioned button + `OptionsModal` (styled through `styles.optionsModal`).
|
|
390
|
-
| `<SegmentedToggle options value onChange label?>` | `components/picker/SegmentedToggle` | Row of equal-width buttons, one active (Calendar / List…), announced as a radio group; each option may carry a smaller `hint` line under its label.
|
|
391
|
-
| `<QuantityStepper value onChange label min? max?>` | `components/picker/QuantityStepper` | Whole-number counter `min…max` (`0…999`, negatives allowed with a negative `min`, `-Infinity`/`Infinity` for no bound): −/+ buttons moving by `step` (1; disabled at the bounds, `longPressStep` to jump on long press, or `repeatOnHold` to repeat faster and faster while held) and a numeric field; `onStep(value)` fires on each −/+ change (e.g. `onStep={tapFeedback}`), not on typing; screen-reader labels in French or English (`a11yLabels` to override). |
|
|
392
|
-
| `<SwitchRow label description? value onChange>` | `components/settings/SwitchRow` | Settings line "label + description + switch", the whole row pressable and read as one switch; `colors` for the track and thumb.
|
|
393
|
-
| `<SettingsCard title icon?>` + `SettingsCardStatus`, `SettingsCardHint` | `components/settings/SettingsCard` | Settings card: icon + title header, then free content — status lines (small icon + text, `iconColor` per state) and a quieter hint.
|
|
394
|
-
| `<CheckboxGroup options values onChange label?>` | `components/picker/CheckboxGroup` | Wrapping chips that each check and uncheck independently (extensions, tags…), each announced as a checkbox.
|
|
395
|
-
| `<MonthDayGrid days selected onToggle>` | `components/picker/MonthDayGrid` | Monday-first month grid whose days toggle on and off (holidays, days off…); `YYYY-MM-DD` days.
|
|
396
|
-
| `<AddButton label onPress>` | `components/list/AddButton` | Dashed "+ Add …" button closing a list.
|
|
397
|
-
| `<DragHandle onPressIn accessibilityLabel>` | `components/list/DragHandle` | "⠿" grip for `react-native-draggable-flatlist` rows (gesture-handler's `Pressable`).
|
|
398
|
-
| `<ErrorFallback error retry>` | `components/feedback/ErrorFallback` | Readable crash screen with a retry button, for Expo Router's `ErrorBoundary`; texts in French or English (`labels` to override).
|
|
405
|
+
| Component | Import path | What it is |
|
|
406
|
+
| ----------------------------------------------------------------------- | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
407
|
+
| `<BottomSheet visible onClose bottomInset?>` | `components/overlay/BottomSheet` | Modal sliding up from the bottom, content scrollable past 85 % of the screen. Pass `useSafeAreaInsets().bottom` as `bottomInset` with Android edge-to-edge. |
|
|
408
|
+
| `<OptionsModal visible onClose options onSelect>` | `components/picker/OptionsModal` | Centered popup listing `{ value, label }` options; a tap selects and closes. |
|
|
409
|
+
| `<SelectField label valueLabel options onSelect>` | `components/picker/SelectField` | Native-looking "select": captioned button + `OptionsModal` (styled through `styles.optionsModal`). |
|
|
410
|
+
| `<SegmentedToggle options value onChange label?>` | `components/picker/SegmentedToggle` | Row of equal-width buttons, one active (Calendar / List…), announced as a radio group; each option may carry a smaller `hint` line under its label. |
|
|
411
|
+
| `<QuantityStepper value onChange label min? max?>` | `components/picker/QuantityStepper` | Whole-number counter `min…max` (`0…999`, negatives allowed with a negative `min`, `-Infinity`/`Infinity` for no bound): −/+ buttons moving by `step` (1; disabled at the bounds, `longPressStep` to jump on long press, or `repeatOnHold` to repeat faster and faster while held) and a numeric field; `onStep(value)` fires on each −/+ change (e.g. `onStep={tapFeedback}`), not on typing; `maxFontSizeMultiplier` caps the system font scaling of −, + and the field; screen-reader labels in French or English (`a11yLabels` to override). |
|
|
412
|
+
| `<SwitchRow label description? value onChange>` | `components/settings/SwitchRow` | Settings line "label + description + switch", the whole row pressable and read as one switch; `colors` for the track and thumb. |
|
|
413
|
+
| `<SettingsCard title icon?>` + `SettingsCardStatus`, `SettingsCardHint` | `components/settings/SettingsCard` | Settings card: icon + title header, then free content — status lines (small icon + text, `iconColor` per state) and a quieter hint. |
|
|
414
|
+
| `<CheckboxGroup options values onChange label?>` | `components/picker/CheckboxGroup` | Wrapping chips that each check and uncheck independently (extensions, tags…), each announced as a checkbox. |
|
|
415
|
+
| `<MonthDayGrid days selected onToggle>` | `components/picker/MonthDayGrid` | Monday-first month grid whose days toggle on and off (holidays, days off…); `YYYY-MM-DD` days. |
|
|
416
|
+
| `<AddButton label onPress>` | `components/list/AddButton` | Dashed "+ Add …" button closing a list. |
|
|
417
|
+
| `<DragHandle onPressIn accessibilityLabel>` | `components/list/DragHandle` | "⠿" grip for `react-native-draggable-flatlist` rows (gesture-handler's `Pressable`). |
|
|
418
|
+
| `<ErrorFallback error retry>` | `components/feedback/ErrorFallback` | Readable crash screen with a retry button, for Expo Router's `ErrorBoundary`; texts in French or English (`labels` to override). |
|
|
399
419
|
|
|
400
420
|
`SwipeableRow` also takes `fullSwipeToDelete`: swiping past half the row deletes right away (the row slides out over a full-width delete band) instead of revealing a button — pair it with an `UndoToast`.
|
|
401
421
|
|
|
@@ -561,6 +581,24 @@ import {
|
|
|
561
581
|
/>;
|
|
562
582
|
```
|
|
563
583
|
|
|
584
|
+
`checkForUpdate` receives `{ includePrereleases }` (`false` by default). Pass `onIncludePrereleasesChange` to show a "Recevoir les versions de test" switch: the app stores the choice, hands it back as `includePrereleases`, and the screen checks again on each change (an older check that answers late is ignored). Hand the value on to `fetchLatestRelease({ …, includePrereleases, requireVerifiedApk: true })`, to `fetchReleaseHistory({ …, includePrereleases })` (the history is fetched again when that function changes), and to the launch check (`UpdateNotifier`) too. Style it with `styles.prereleaseSwitch` / `styles.prereleaseSwitchColors` (`SwitchRow`'s slots).
|
|
585
|
+
|
|
586
|
+
```tsx
|
|
587
|
+
<UpdateSettingsScreen
|
|
588
|
+
checkForUpdate={({ includePrereleases }) =>
|
|
589
|
+
fetchLatestRelease({
|
|
590
|
+
owner,
|
|
591
|
+
repo,
|
|
592
|
+
includePrereleases,
|
|
593
|
+
requireVerifiedApk: true,
|
|
594
|
+
})
|
|
595
|
+
}
|
|
596
|
+
includePrereleases={includePrereleases}
|
|
597
|
+
onIncludePrereleasesChange={setIncludePrereleases}
|
|
598
|
+
{...otherProps}
|
|
599
|
+
/>
|
|
600
|
+
```
|
|
601
|
+
|
|
564
602
|
#### `<BackupSettingsScreen onExport onImport reminder? />`
|
|
565
603
|
|
|
566
604
|
Export/import buttons plus an optional reminder-notification switch. Deliberately just a shell: what actually gets exported/imported is entirely app-specific (your own database tables), so `onExport`/`onImport` are required — this package can't have a sensible default for "how do I export my schema". Import asks for confirmation first (via `confirmDestructive`, from `utils/helpers/`) since it replaces existing data; `onImport` itself doesn't need to.
|
|
@@ -676,7 +714,7 @@ For all 7 components above, styling works the same way as `ChangelogNotes`: an o
|
|
|
676
714
|
- `mergeSlotStyles(defaultStyles, styles)` — merges a component's per-slot `styles` overrides onto its defaults as `[default, override]` style arrays, so overriding one property of a slot keeps the rest of its default. Every component of this package uses it; handy for your own components following the same `styles` convention.
|
|
677
715
|
- `shareFile(uri, { mimeType, dialogTitle?, locale? })` — opens the native share sheet for a local file; throws a user-facing `Error` (French, or English with `locale: "en"`) when the device can't share. Needs `expo-sharing`.
|
|
678
716
|
- `shareTextFile(filename, content, options)` — writes the text to a file in the cache (replacing any previous one), then `shareFile`s it: `.ics`, `.csv`, JSON exports… Needs `expo-file-system` and `expo-sharing`.
|
|
679
|
-
- `shareViewAsImage(ref, { dialogTitle?, locale? })` (`utils/helpers/shareViewAsImage`) — captures a view as a PNG and shares it (scoreboard, schedule…). Needs `react-native-view-shot` and `expo-sharing`; the capture library is loaded on demand, so a binary built without it only fails this call, with a user-facing `Error`.
|
|
717
|
+
- `shareViewAsImage(ref, { dialogTitle?, locale? })` (`utils/helpers/shareViewAsImage`) — captures a view as a PNG and shares it (scoreboard, schedule…); `ref` is a `RefObject<ComponentRef<typeof View> | null>`, as `useRef<ComponentRef<typeof View>>(null)` gives. Needs `react-native-view-shot` and `expo-sharing`; the capture library is loaded on demand, so a binary built without it only fails this call, with a user-facing `Error`.
|
|
680
718
|
- `isNativeModuleAvailable(name)` — whether a native module is compiled into this binary (either architecture): check it before loading a library that crashes on import without its module.
|
|
681
719
|
|
|
682
720
|
### Calendar (`utils/calendar/`)
|
|
@@ -20,6 +20,12 @@ export interface PhotoPickerProps {
|
|
|
20
20
|
* (`labels.saveErrorTitle` / `saveErrorMessage`).
|
|
21
21
|
*/
|
|
22
22
|
onError?: (error: unknown) => void;
|
|
23
|
+
/**
|
|
24
|
+
* Called when a press opens the camera/library choice (not while a photo
|
|
25
|
+
* is being saved). The place for a haptic tick: `onOpen={tapFeedback}`
|
|
26
|
+
* (from `utils/helpers/haptics`).
|
|
27
|
+
*/
|
|
28
|
+
onOpen?: () => void;
|
|
23
29
|
labels?: PhotoPickerLabels;
|
|
24
30
|
/**
|
|
25
31
|
* Language of the built-in labels — French by default, or the nearest
|
|
@@ -28,5 +34,5 @@ export interface PhotoPickerProps {
|
|
|
28
34
|
locale?: KitLocale;
|
|
29
35
|
styles?: PhotoPickerStyles;
|
|
30
36
|
}
|
|
31
|
-
export declare function PhotoPicker({ photoUri, onChange, savePhoto, photoLabel, renderPreview, onError, labels, locale, styles, }: PhotoPickerProps): import("react").JSX.Element;
|
|
37
|
+
export declare function PhotoPicker({ photoUri, onChange, savePhoto, photoLabel, renderPreview, onError, onOpen, labels, locale, styles, }: PhotoPickerProps): import("react").JSX.Element;
|
|
32
38
|
//# sourceMappingURL=PhotoPicker.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PhotoPicker.d.ts","sourceRoot":"","sources":["../../../src/components/picker/PhotoPicker.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAoB,MAAM,OAAO,CAAC;AAKzD,OAAO,EAAE,KAAK,SAAS,EAAgB,MAAM,sBAAsB,CAAC;AAGpE,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACvB,MAAM,yBAAyB,CAAC;AAEjC,YAAY,EACV,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACvC,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,0EAA0E;IAC1E,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,OAAO,KAAK,SAAS,CAAC;IACxE;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AAUD,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,UAAU,EACV,aAAa,EACb,OAAO,EACP,MAAM,EACN,MAAM,EACN,MAAM,GACP,EAAE,gBAAgB,+
|
|
1
|
+
{"version":3,"file":"PhotoPicker.d.ts","sourceRoot":"","sources":["../../../src/components/picker/PhotoPicker.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAoB,MAAM,OAAO,CAAC;AAKzD,OAAO,EAAE,KAAK,SAAS,EAAgB,MAAM,sBAAsB,CAAC;AAGpE,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACvB,MAAM,yBAAyB,CAAC;AAEjC,YAAY,EACV,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACvC,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,0EAA0E;IAC1E,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,OAAO,KAAK,SAAS,CAAC;IACxE;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AAUD,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,UAAU,EACV,aAAa,EACb,OAAO,EACP,MAAM,EACN,MAAM,EACN,MAAM,EACN,MAAM,GACP,EAAE,gBAAgB,+BAoHlB"}
|
|
@@ -13,7 +13,7 @@ const PICKER_OPTIONS = {
|
|
|
13
13
|
aspect: [1, 1],
|
|
14
14
|
};
|
|
15
15
|
// Photo picker (camera or library) with a preview.
|
|
16
|
-
export function PhotoPicker({ photoUri, onChange, savePhoto, photoLabel, renderPreview, onError, labels, locale, styles, }) {
|
|
16
|
+
export function PhotoPicker({ photoUri, onChange, savePhoto, photoLabel, renderPreview, onError, onOpen, labels, locale, styles, }) {
|
|
17
17
|
const mergedStyles = {
|
|
18
18
|
...mergeSlotStyles(defaultStyles, styles),
|
|
19
19
|
iconColor: styles?.iconColor ?? defaultStyles.iconColor,
|
|
@@ -63,6 +63,7 @@ export function PhotoPicker({ photoUri, onChange, savePhoto, photoLabel, renderP
|
|
|
63
63
|
function handlePickPhoto() {
|
|
64
64
|
if (busyRef.current)
|
|
65
65
|
return;
|
|
66
|
+
onOpen?.();
|
|
66
67
|
Alert.alert(t.photoTitle(photoLabel), undefined, [
|
|
67
68
|
{
|
|
68
69
|
text: t.takePhoto,
|
|
@@ -39,6 +39,12 @@ export interface QuantityStepperProps {
|
|
|
39
39
|
* @defaultValue false
|
|
40
40
|
*/
|
|
41
41
|
repeatOnHold?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Caps how much the system font size scales the "−", "+" and the field, so
|
|
44
|
+
* the row keeps fitting at the largest accessibility font sizes (e.g. `1.3`).
|
|
45
|
+
* Unset, they follow the system font size without limit.
|
|
46
|
+
*/
|
|
47
|
+
maxFontSizeMultiplier?: number;
|
|
42
48
|
/**
|
|
43
49
|
* Language of the default screen-reader labels — French by default, or the
|
|
44
50
|
* nearest `KitLocaleProvider`'s.
|
|
@@ -68,5 +74,5 @@ export interface QuantityStepperProps {
|
|
|
68
74
|
* <QuantityStepper value={score} onChange={setScore} label="Points" min={-Infinity} max={Infinity} step={4} repeatOnHold onStep={tapFeedback} />
|
|
69
75
|
* ```
|
|
70
76
|
*/
|
|
71
|
-
export declare function QuantityStepper({ value, onChange, label, min, max, step, onStep, longPressStep, repeatOnHold, locale, a11yLabels, styles, }: QuantityStepperProps): import("react").JSX.Element;
|
|
77
|
+
export declare function QuantityStepper({ value, onChange, label, min, max, step, onStep, longPressStep, repeatOnHold, maxFontSizeMultiplier, locale, a11yLabels, styles, }: QuantityStepperProps): import("react").JSX.Element;
|
|
72
78
|
//# sourceMappingURL=QuantityStepper.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QuantityStepper.d.ts","sourceRoot":"","sources":["../../../src/components/picker/QuantityStepper.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,SAAS,EAAgB,MAAM,sBAAsB,CAAC;AAGpE,OAAO,EAGL,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,EAC3B,MAAM,6BAA6B,CAAC;AAErC,YAAY,EACV,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,6BAA6B,CAAC;AAErC,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,yDAAyD;IACzD,UAAU,CAAC,EAAE,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAChD,oEAAoE;IACpE,MAAM,CAAC,EAAE,qBAAqB,CAAC;CAChC;AAgBD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,QAAQ,EACR,KAAK,EACL,GAAO,EACP,GAAS,EACT,IAAQ,EACR,MAAM,EACN,aAAa,EACb,YAAoB,EACpB,MAAM,EACN,UAAU,EACV,MAAM,GACP,EAAE,oBAAoB,+
|
|
1
|
+
{"version":3,"file":"QuantityStepper.d.ts","sourceRoot":"","sources":["../../../src/components/picker/QuantityStepper.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,SAAS,EAAgB,MAAM,sBAAsB,CAAC;AAGpE,OAAO,EAGL,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,EAC3B,MAAM,6BAA6B,CAAC;AAErC,YAAY,EACV,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,6BAA6B,CAAC;AAErC,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,yDAAyD;IACzD,UAAU,CAAC,EAAE,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAChD,oEAAoE;IACpE,MAAM,CAAC,EAAE,qBAAqB,CAAC;CAChC;AAgBD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,QAAQ,EACR,KAAK,EACL,GAAO,EACP,GAAS,EACT,IAAQ,EACR,MAAM,EACN,aAAa,EACb,YAAoB,EACpB,qBAAqB,EACrB,MAAM,EACN,UAAU,EACV,MAAM,GACP,EAAE,oBAAoB,+BAuJtB"}
|
|
@@ -37,7 +37,7 @@ function lengthOf(bound) {
|
|
|
37
37
|
* <QuantityStepper value={score} onChange={setScore} label="Points" min={-Infinity} max={Infinity} step={4} repeatOnHold onStep={tapFeedback} />
|
|
38
38
|
* ```
|
|
39
39
|
*/
|
|
40
|
-
export function QuantityStepper({ value, onChange, label, min = 0, max = 999, step = 1, onStep, longPressStep, repeatOnHold = false, locale, a11yLabels, styles, }) {
|
|
40
|
+
export function QuantityStepper({ value, onChange, label, min = 0, max = 999, step = 1, onStep, longPressStep, repeatOnHold = false, maxFontSizeMultiplier, locale, a11yLabels, styles, }) {
|
|
41
41
|
const labels = { ...defaultA11yLabels[useKitLocale(locale)], ...a11yLabels };
|
|
42
42
|
const merged = mergeSlotStyles(defaultStyles, styles);
|
|
43
43
|
const atMin = value <= min;
|
|
@@ -97,7 +97,7 @@ export function QuantityStepper({ value, onChange, label, min = 0, max = 999, st
|
|
|
97
97
|
? () => {
|
|
98
98
|
startRepeat(-1);
|
|
99
99
|
}
|
|
100
|
-
: undefined, onPressOut: repeatOnHold ? repeat.stop : undefined, disabled: atMin, hitSlop: 6, accessibilityRole: "button", accessibilityLabel: labels.decrease(label), children: _jsx(Text, { style: merged.buttonText, children: "\u2212" }) }), _jsx(TextInput, { style: merged.input, value: draft ?? String(value), onChangeText: (text) => {
|
|
100
|
+
: undefined, onPressOut: repeatOnHold ? repeat.stop : undefined, disabled: atMin, hitSlop: 6, accessibilityRole: "button", accessibilityLabel: labels.decrease(label), children: _jsx(Text, { style: merged.buttonText, maxFontSizeMultiplier: maxFontSizeMultiplier, children: "\u2212" }) }), _jsx(TextInput, { style: merged.input, value: draft ?? String(value), onChangeText: (text) => {
|
|
101
101
|
const cleaned = sanitize(text, allowsNegative);
|
|
102
102
|
const typed = Number(cleaned);
|
|
103
103
|
if (cleaned === "" || cleaned === "-" || typed < min) {
|
|
@@ -112,7 +112,7 @@ export function QuantityStepper({ value, onChange, label, min = 0, max = 999, st
|
|
|
112
112
|
set(draft === "" || draft === "-" ? 0 : Number(draft));
|
|
113
113
|
},
|
|
114
114
|
// "number-pad" has no "-" key on Android.
|
|
115
|
-
keyboardType: allowsNegative ? "numeric" : "number-pad", selectTextOnFocus: true, maxLength: Math.max(lengthOf(min), lengthOf(max)), accessibilityLabel: labels.input(label) }), _jsx(Pressable, { style: [merged.button, atMax && merged.buttonDisabled], onPress: tapsOnly
|
|
115
|
+
keyboardType: allowsNegative ? "numeric" : "number-pad", selectTextOnFocus: true, maxFontSizeMultiplier: maxFontSizeMultiplier, maxLength: Math.max(lengthOf(min), lengthOf(max)), accessibilityLabel: labels.input(label) }), _jsx(Pressable, { style: [merged.button, atMax && merged.buttonDisabled], onPress: tapsOnly
|
|
116
116
|
? () => {
|
|
117
117
|
tap(step);
|
|
118
118
|
}
|
|
@@ -124,5 +124,5 @@ export function QuantityStepper({ value, onChange, label, min = 0, max = 999, st
|
|
|
124
124
|
? () => {
|
|
125
125
|
startRepeat(1);
|
|
126
126
|
}
|
|
127
|
-
: undefined, onPressOut: repeatOnHold ? repeat.stop : undefined, disabled: atMax, hitSlop: 6, accessibilityRole: "button", accessibilityLabel: labels.increase(label), children: _jsx(Text, { style: merged.buttonText, children: "+" }) })] }));
|
|
127
|
+
: undefined, onPressOut: repeatOnHold ? repeat.stop : undefined, disabled: atMax, hitSlop: 6, accessibilityRole: "button", accessibilityLabel: labels.increase(label), children: _jsx(Text, { style: merged.buttonText, maxFontSizeMultiplier: maxFontSizeMultiplier, children: "+" }) })] }));
|
|
128
128
|
}
|
|
@@ -3,8 +3,14 @@ import type { UpdateSettingsScreenHistoryEntry, UpdateSettingsScreenLabels, Upda
|
|
|
3
3
|
export type { UpdateSettingsScreenHistoryEntry, UpdateSettingsScreenLabels, UpdateSettingsScreenRelease, UpdateSettingsScreenStyles, } from "./UpdateSettingsScreen.styles.js";
|
|
4
4
|
export interface UpdateSettingsScreenProps {
|
|
5
5
|
currentVersion: string;
|
|
6
|
-
/**
|
|
7
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Fetches the latest available release, or `null` if there is none.
|
|
8
|
+
* Receives the current `includePrereleases`, e.g. to pass on to
|
|
9
|
+
* `fetchLatestRelease`.
|
|
10
|
+
*/
|
|
11
|
+
checkForUpdate: (options: {
|
|
12
|
+
includePrereleases: boolean;
|
|
13
|
+
}) => Promise<UpdateSettingsScreenRelease | null>;
|
|
8
14
|
/** Positive when `a` is newer than `b`, e.g. semver comparison. */
|
|
9
15
|
compareVersions: (a: string, b: string) => number;
|
|
10
16
|
/**
|
|
@@ -14,6 +20,13 @@ export interface UpdateSettingsScreenProps {
|
|
|
14
20
|
downloadAndInstallApk: (apkUrl: string, onProgress?: (fraction: number) => void, apkSha256?: string) => Promise<void>;
|
|
15
21
|
/** Omit to not show a version history section at all. */
|
|
16
22
|
fetchReleaseHistory?: () => Promise<UpdateSettingsScreenHistoryEntry[]>;
|
|
23
|
+
/** Whether test versions (alpha, beta…) are offered. Defaults to `false`. */
|
|
24
|
+
includePrereleases?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Shows a "test versions" switch when passed; the app stores the choice and
|
|
27
|
+
* hands it back as `includePrereleases`. Every change triggers a new check.
|
|
28
|
+
*/
|
|
29
|
+
onIncludePrereleasesChange?: (value: boolean) => void;
|
|
17
30
|
/**
|
|
18
31
|
* Locale for formatting each history entry's date. Defaults to the
|
|
19
32
|
* locale's (`"fr-FR"`, or `"en-US"` with `locale="en"`).
|
|
@@ -27,5 +40,5 @@ export interface UpdateSettingsScreenProps {
|
|
|
27
40
|
locale?: KitLocale;
|
|
28
41
|
styles?: UpdateSettingsScreenStyles;
|
|
29
42
|
}
|
|
30
|
-
export declare function UpdateSettingsScreen({ currentVersion, checkForUpdate, compareVersions, downloadAndInstallApk, fetchReleaseHistory, dateLocale: customDateLocale, labels, locale, styles, }: UpdateSettingsScreenProps): import("react").JSX.Element;
|
|
43
|
+
export declare function UpdateSettingsScreen({ currentVersion, checkForUpdate, compareVersions, downloadAndInstallApk, fetchReleaseHistory, includePrereleases, onIncludePrereleasesChange, dateLocale: customDateLocale, labels, locale, styles, }: UpdateSettingsScreenProps): import("react").JSX.Element;
|
|
31
44
|
//# sourceMappingURL=UpdateSettingsScreen.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UpdateSettingsScreen.d.ts","sourceRoot":"","sources":["../../../src/components/settings/UpdateSettingsScreen.tsx"],"names":[],"mappings":"AAKA,OAAO,EAEL,KAAK,SAAS,EAEf,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"UpdateSettingsScreen.d.ts","sourceRoot":"","sources":["../../../src/components/settings/UpdateSettingsScreen.tsx"],"names":[],"mappings":"AAKA,OAAO,EAEL,KAAK,SAAS,EAEf,MAAM,sBAAsB,CAAC;AAI9B,OAAO,KAAK,EACV,gCAAgC,EAChC,0BAA0B,EAC1B,2BAA2B,EAC3B,0BAA0B,EAC3B,MAAM,kCAAkC,CAAC;AAI1C,YAAY,EACV,gCAAgC,EAChC,0BAA0B,EAC1B,2BAA2B,EAC3B,0BAA0B,GAC3B,MAAM,kCAAkC,CAAC;AAU1C,MAAM,WAAW,yBAAyB;IACxC,cAAc,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,cAAc,EAAE,CAAC,OAAO,EAAE;QACxB,kBAAkB,EAAE,OAAO,CAAC;KAC7B,KAAK,OAAO,CAAC,2BAA2B,GAAG,IAAI,CAAC,CAAC;IAClD,mEAAmE;IACnE,eAAe,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAClD;;;OAGG;IACH,qBAAqB,EAAE,CACrB,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,EACvC,SAAS,CAAC,EAAE,MAAM,KACf,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,yDAAyD;IACzD,mBAAmB,CAAC,EAAE,MAAM,OAAO,CAAC,gCAAgC,EAAE,CAAC,CAAC;IACxE,6EAA6E;IAC7E,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;OAGG;IACH,0BAA0B,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACtD;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,0BAA0B,CAAC;IACpC;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,MAAM,CAAC,EAAE,0BAA0B,CAAC;CACrC;AAQD,wBAAgB,oBAAoB,CAAC,EACnC,cAAc,EACd,cAAc,EACd,eAAe,EACf,qBAAqB,EACrB,mBAAmB,EACnB,kBAA0B,EAC1B,0BAA0B,EAC1B,UAAU,EAAE,gBAAgB,EAC5B,MAAM,EACN,MAAM,EACN,MAAM,GACP,EAAE,yBAAyB,+BAsL3B"}
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
3
3
|
import { ActivityIndicator, Pressable, Text, View } from "react-native";
|
|
4
4
|
import { ChangelogNotes } from "@forthtilliath/expo-release-updates-ui";
|
|
5
5
|
import { KIT_LOCALE_TAGS, useKitLocale, } from "../../i18n/locale.js";
|
|
6
6
|
import { mergeSlotStyles } from "../../utils/helpers/mergeSlotStyles.js";
|
|
7
|
+
import { SwitchRow } from "./SwitchRow.js";
|
|
7
8
|
import { defaultLabels, defaultStyles } from "./UpdateSettingsScreen.styles.js";
|
|
8
9
|
import { UpdateSettingsScreenHistory } from "./UpdateSettingsScreenHistory.js";
|
|
9
10
|
// Full "check for update" screen: installed version, a manual check button,
|
|
10
11
|
// the available-update box (with changelog + install button) or an
|
|
11
12
|
// up-to-date/error message, download progress, and — if
|
|
12
13
|
// `fetchReleaseHistory` is passed — a list of past releases. Checks
|
|
13
|
-
// automatically
|
|
14
|
-
//
|
|
15
|
-
export function UpdateSettingsScreen({ currentVersion, checkForUpdate, compareVersions, downloadAndInstallApk, fetchReleaseHistory, dateLocale: customDateLocale, labels, locale, styles, }) {
|
|
14
|
+
// automatically on mount (the caller decided to navigate here, no need to make
|
|
15
|
+
// them tap "check" again) and again whenever `includePrereleases` changes.
|
|
16
|
+
export function UpdateSettingsScreen({ currentVersion, checkForUpdate, compareVersions, downloadAndInstallApk, fetchReleaseHistory, includePrereleases = false, onIncludePrereleasesChange, dateLocale: customDateLocale, labels, locale, styles, }) {
|
|
16
17
|
const resolvedLocale = useKitLocale(locale);
|
|
17
18
|
const dateLocale = customDateLocale ?? KIT_LOCALE_TAGS[resolvedLocale];
|
|
18
19
|
const merged = {
|
|
@@ -34,10 +35,16 @@ export function UpdateSettingsScreen({ currentVersion, checkForUpdate, compareVe
|
|
|
34
35
|
setReleaseHistory([]);
|
|
35
36
|
});
|
|
36
37
|
}, [fetchReleaseHistory]);
|
|
38
|
+
// Only the latest check may update the screen: toggling the switch during a
|
|
39
|
+
// check must not let the older answer land last.
|
|
40
|
+
const latestCheckRef = useRef(0);
|
|
37
41
|
const handleCheckForUpdate = useCallback(async () => {
|
|
42
|
+
const check = ++latestCheckRef.current;
|
|
38
43
|
setUpdateState({ status: "checking" });
|
|
39
44
|
try {
|
|
40
|
-
const release = await checkForUpdate();
|
|
45
|
+
const release = await checkForUpdate({ includePrereleases });
|
|
46
|
+
if (check !== latestCheckRef.current)
|
|
47
|
+
return;
|
|
41
48
|
if (!release || compareVersions(release.version, currentVersion) <= 0) {
|
|
42
49
|
setUpdateState({ status: "up-to-date" });
|
|
43
50
|
return;
|
|
@@ -45,13 +52,21 @@ export function UpdateSettingsScreen({ currentVersion, checkForUpdate, compareVe
|
|
|
45
52
|
setUpdateState({ status: "available", release });
|
|
46
53
|
}
|
|
47
54
|
catch {
|
|
55
|
+
if (check !== latestCheckRef.current)
|
|
56
|
+
return;
|
|
48
57
|
setUpdateState({ status: "error", message: t.checkError });
|
|
49
58
|
}
|
|
50
|
-
}, [
|
|
59
|
+
}, [
|
|
60
|
+
checkForUpdate,
|
|
61
|
+
compareVersions,
|
|
62
|
+
currentVersion,
|
|
63
|
+
includePrereleases,
|
|
64
|
+
t.checkError,
|
|
65
|
+
]);
|
|
51
66
|
useEffect(() => {
|
|
52
67
|
void handleCheckForUpdate();
|
|
53
|
-
// eslint-disable-next-line @eslint-react/exhaustive-deps -- runs
|
|
54
|
-
}, []);
|
|
68
|
+
// eslint-disable-next-line @eslint-react/exhaustive-deps -- runs on mount and when includePrereleases changes by design; the other inputs are expected to be stable enough for the screen's lifetime.
|
|
69
|
+
}, [includePrereleases]);
|
|
55
70
|
async function handleInstall({ apkUrl, apkSha256, }) {
|
|
56
71
|
setUpdateState({ status: "downloading", progress: 0 });
|
|
57
72
|
try {
|
|
@@ -70,7 +85,7 @@ export function UpdateSettingsScreen({ currentVersion, checkForUpdate, compareVe
|
|
|
70
85
|
text: merged.helpText,
|
|
71
86
|
...merged.notes,
|
|
72
87
|
}), [merged.helpText, merged.notes, merged.updateAvailableTitle]);
|
|
73
|
-
return (_jsxs(View, { style: merged.container, children: [_jsxs(View, { style: merged.infoBox, children: [_jsx(Text, { style: merged.infoLabel, children: t.installedVersionLabel }), _jsx(Text, { style: merged.infoValue, children: currentVersion })] }), updateState.status !== "available" &&
|
|
88
|
+
return (_jsxs(View, { style: merged.container, children: [_jsxs(View, { style: merged.infoBox, children: [_jsx(Text, { style: merged.infoLabel, children: t.installedVersionLabel }), _jsx(Text, { style: merged.infoValue, children: currentVersion })] }), onIncludePrereleasesChange && (_jsx(SwitchRow, { label: t.prereleaseLabel, description: t.prereleaseDescription, value: includePrereleases, onChange: onIncludePrereleasesChange, disabled: updateState.status === "downloading", colors: styles?.prereleaseSwitchColors, styles: styles?.prereleaseSwitch })), updateState.status !== "available" &&
|
|
74
89
|
updateState.status !== "downloading" && (_jsx(Pressable, { style: [merged.button, isBusy && merged.buttonDisabled], onPress: () => {
|
|
75
90
|
void handleCheckForUpdate();
|
|
76
91
|
}, disabled: isBusy, accessibilityRole: "button", accessibilityLabel: t.checkButton, children: updateState.status === "checking" ? (_jsx(ActivityIndicator, { color: activityIndicatorColor })) : (_jsx(Text, { style: merged.buttonText, children: t.checkButton })) })), updateState.status === "up-to-date" && (_jsx(Text, { style: merged.helpText, children: t.upToDate })), updateState.status === "error" && (_jsx(Text, { style: merged.errorText, children: updateState.message })), updateState.status === "available" && (_jsxs(View, { style: merged.updateAvailableBox, children: [_jsx(Text, { style: merged.updateAvailableTitle, children: t.availableTitle(updateState.release.version) }), updateState.release.notes ? (_jsx(ChangelogNotes, { notes: updateState.release.notes, styles: merged.notes })) : null, _jsx(Pressable, { style: merged.button, onPress: () => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { StyleProp, TextStyle, ViewStyle } from "react-native";
|
|
2
2
|
import type { ChangelogNotesStyles } from "@forthtilliath/expo-release-updates-ui";
|
|
3
|
+
import type { SwitchRowColors, SwitchRowStyles } from "./SwitchRow.js";
|
|
3
4
|
export interface UpdateSettingsScreenRelease {
|
|
4
5
|
version: string;
|
|
5
6
|
notes: string;
|
|
@@ -24,6 +25,8 @@ export interface UpdateSettingsScreenLabels {
|
|
|
24
25
|
downloadingLabel?: (percent: number) => string;
|
|
25
26
|
downloadingHint?: string;
|
|
26
27
|
historyTitle?: string;
|
|
28
|
+
prereleaseLabel?: string;
|
|
29
|
+
prereleaseDescription?: string;
|
|
27
30
|
}
|
|
28
31
|
export interface UpdateSettingsScreenStyles {
|
|
29
32
|
container?: StyleProp<ViewStyle>;
|
|
@@ -45,6 +48,9 @@ export interface UpdateSettingsScreenStyles {
|
|
|
45
48
|
changelogVersion?: StyleProp<TextStyle>;
|
|
46
49
|
changelogDate?: StyleProp<TextStyle>;
|
|
47
50
|
notes?: ChangelogNotesStyles;
|
|
51
|
+
/** The "test versions" switch row, shown with `onIncludePrereleasesChange`. */
|
|
52
|
+
prereleaseSwitch?: SwitchRowStyles;
|
|
53
|
+
prereleaseSwitchColors?: SwitchRowColors;
|
|
48
54
|
}
|
|
49
55
|
export declare const defaultLabels: {
|
|
50
56
|
fr: {
|
|
@@ -59,6 +65,8 @@ export declare const defaultLabels: {
|
|
|
59
65
|
downloadingLabel: (percent: number) => string;
|
|
60
66
|
downloadingHint: string;
|
|
61
67
|
historyTitle: string;
|
|
68
|
+
prereleaseLabel: string;
|
|
69
|
+
prereleaseDescription: string;
|
|
62
70
|
};
|
|
63
71
|
en: {
|
|
64
72
|
installedVersionLabel: string;
|
|
@@ -72,7 +80,11 @@ export declare const defaultLabels: {
|
|
|
72
80
|
downloadingLabel: (percent: number) => string;
|
|
73
81
|
downloadingHint: string;
|
|
74
82
|
historyTitle: string;
|
|
83
|
+
prereleaseLabel: string;
|
|
84
|
+
prereleaseDescription: string;
|
|
75
85
|
};
|
|
76
86
|
};
|
|
77
|
-
|
|
87
|
+
type LooseStyleKeys = "activityIndicatorColor" | "notes" | "prereleaseSwitch" | "prereleaseSwitchColors";
|
|
88
|
+
export declare const defaultStyles: Required<Omit<UpdateSettingsScreenStyles, LooseStyleKeys>> & Pick<UpdateSettingsScreenStyles, "activityIndicatorColor" | "notes">;
|
|
89
|
+
export {};
|
|
78
90
|
//# sourceMappingURL=UpdateSettingsScreen.styles.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UpdateSettingsScreen.styles.d.ts","sourceRoot":"","sources":["../../../src/components/settings/UpdateSettingsScreen.styles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAInF,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gCAAgC;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,0BAA0B;IACzC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7C,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5C,+BAA+B,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IAC9D,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IAC/C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"UpdateSettingsScreen.styles.d.ts","sourceRoot":"","sources":["../../../src/components/settings/UpdateSettingsScreen.styles.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,8 @@ export const defaultLabels = {
|
|
|
11
11
|
downloadingLabel: (percent) => `Téléchargement… ${String(percent)}%`,
|
|
12
12
|
downloadingHint: "Ton téléphone va ensuite te demander confirmation pour installer la mise à jour.",
|
|
13
13
|
historyTitle: "Historique des versions",
|
|
14
|
+
prereleaseLabel: "Recevoir les versions de test",
|
|
15
|
+
prereleaseDescription: "Versions alpha et bêta, avant leur sortie : elles peuvent contenir des bugs.",
|
|
14
16
|
},
|
|
15
17
|
en: {
|
|
16
18
|
installedVersionLabel: "Installed version",
|
|
@@ -24,6 +26,8 @@ export const defaultLabels = {
|
|
|
24
26
|
downloadingLabel: (percent) => `Downloading… ${String(percent)}%`,
|
|
25
27
|
downloadingHint: "Your phone will then ask you to confirm the install.",
|
|
26
28
|
historyTitle: "Version history",
|
|
29
|
+
prereleaseLabel: "Get test versions",
|
|
30
|
+
prereleaseDescription: "Alpha and beta versions, before their release: they may contain bugs.",
|
|
27
31
|
},
|
|
28
32
|
};
|
|
29
33
|
export const defaultStyles = {
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC"}
|
package/dist/hooks/index.js
CHANGED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type View } from "react-native";
|
|
2
|
+
import { type ShareViewAsImageOptions } from "../utils/helpers/shareViewAsImage.js";
|
|
3
|
+
export interface UseViewShareOptions extends ShareViewAsImageOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Called when the capture or the share fails (capture missing from this
|
|
6
|
+
* binary, no share sheet…). Unset, an alert shows the error's message.
|
|
7
|
+
*/
|
|
8
|
+
onError?: (error: unknown) => void;
|
|
9
|
+
/** Title of the default error alert. */
|
|
10
|
+
errorTitle?: string;
|
|
11
|
+
/** Message of the default error alert, for an error without a message. */
|
|
12
|
+
errorMessage?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Shares as an image a view rendered on demand (a scoreboard, a summary card
|
|
16
|
+
* that isn't on screen): `capturing` is `true` while the capture runs — the
|
|
17
|
+
* screen mounts the view attached to `ref` (off screen, `collapsable={false}`)
|
|
18
|
+
* only meanwhile — and `share()` waits two frames for it to be drawn before
|
|
19
|
+
* capturing it with {@link shareViewAsImage}. A second `share()` while one is
|
|
20
|
+
* running is ignored.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* const ranking = useViewShare({ dialogTitle: "Partager le classement" });
|
|
25
|
+
*
|
|
26
|
+
* <Button title="Partager" onPress={() => void ranking.share()} />
|
|
27
|
+
* {ranking.capturing ? (
|
|
28
|
+
* <View ref={ranking.ref} collapsable={false} style={offScreen}>
|
|
29
|
+
* <RankingCard />
|
|
30
|
+
* </View>
|
|
31
|
+
* ) : null}
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare function useViewShare({ onError, errorTitle, errorMessage, ...options }?: UseViewShareOptions): {
|
|
35
|
+
ref: import("react").RefObject<View | null>;
|
|
36
|
+
capturing: boolean;
|
|
37
|
+
share: () => Promise<void>;
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=useViewShare.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useViewShare.d.ts","sourceRoot":"","sources":["../../src/hooks/useViewShare.ts"],"names":[],"mappings":"AACA,OAAO,EAAS,KAAK,IAAI,EAAE,MAAM,cAAc,CAAC;AAGhD,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,sCAAsC,CAAC;AAE9C,MAAM,WAAW,mBAAoB,SAAQ,uBAAuB;IAClE;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA2BD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,UAAU,EACV,YAAY,EACZ,GAAG,OAAO,EACX,GAAE,mBAAwB;;;;EA+B1B"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { useRef, useState } from "react";
|
|
2
|
+
import { Alert } from "react-native";
|
|
3
|
+
import { useKitLocale } from "../i18n/locale.js";
|
|
4
|
+
import { shareViewAsImage, } from "../utils/helpers/shareViewAsImage.js";
|
|
5
|
+
const defaultErrorLabels = {
|
|
6
|
+
fr: {
|
|
7
|
+
errorTitle: "Partage impossible",
|
|
8
|
+
errorMessage: "L'image n'a pas pu être créée.",
|
|
9
|
+
},
|
|
10
|
+
en: {
|
|
11
|
+
errorTitle: "Couldn't share",
|
|
12
|
+
errorMessage: "The image couldn't be created.",
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
/** Resolves once React has rendered the last state change and native drew it. */
|
|
16
|
+
function nextFrames() {
|
|
17
|
+
return new Promise((resolve) => {
|
|
18
|
+
requestAnimationFrame(() => {
|
|
19
|
+
requestAnimationFrame(() => {
|
|
20
|
+
resolve();
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Shares as an image a view rendered on demand (a scoreboard, a summary card
|
|
27
|
+
* that isn't on screen): `capturing` is `true` while the capture runs — the
|
|
28
|
+
* screen mounts the view attached to `ref` (off screen, `collapsable={false}`)
|
|
29
|
+
* only meanwhile — and `share()` waits two frames for it to be drawn before
|
|
30
|
+
* capturing it with {@link shareViewAsImage}. A second `share()` while one is
|
|
31
|
+
* running is ignored.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```tsx
|
|
35
|
+
* const ranking = useViewShare({ dialogTitle: "Partager le classement" });
|
|
36
|
+
*
|
|
37
|
+
* <Button title="Partager" onPress={() => void ranking.share()} />
|
|
38
|
+
* {ranking.capturing ? (
|
|
39
|
+
* <View ref={ranking.ref} collapsable={false} style={offScreen}>
|
|
40
|
+
* <RankingCard />
|
|
41
|
+
* </View>
|
|
42
|
+
* ) : null}
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export function useViewShare({ onError, errorTitle, errorMessage, ...options } = {}) {
|
|
46
|
+
const ref = useRef(null);
|
|
47
|
+
const [capturing, setCapturing] = useState(false);
|
|
48
|
+
// Ahead of `capturing`, which only changes on the next render.
|
|
49
|
+
const busyRef = useRef(false);
|
|
50
|
+
const locale = useKitLocale(options.locale);
|
|
51
|
+
const defaults = defaultErrorLabels[locale];
|
|
52
|
+
async function share() {
|
|
53
|
+
if (busyRef.current)
|
|
54
|
+
return;
|
|
55
|
+
busyRef.current = true;
|
|
56
|
+
setCapturing(true);
|
|
57
|
+
try {
|
|
58
|
+
await nextFrames();
|
|
59
|
+
await shareViewAsImage(ref, { ...options, locale });
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
if (onError)
|
|
63
|
+
onError(error);
|
|
64
|
+
else
|
|
65
|
+
Alert.alert(errorTitle ?? defaults.errorTitle, error instanceof Error && error.message
|
|
66
|
+
? error.message
|
|
67
|
+
: (errorMessage ?? defaults.errorMessage));
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
busyRef.current = false;
|
|
71
|
+
setCapturing(false);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return { ref, capturing, share };
|
|
75
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RefObject } from "react";
|
|
1
|
+
import type { ComponentRef, RefObject } from "react";
|
|
2
2
|
import type { View } from "react-native";
|
|
3
3
|
import { type ShareFileOptions } from "./shareFile.js";
|
|
4
4
|
export type ShareViewAsImageOptions = Omit<ShareFileOptions, "mimeType"> & {
|
|
@@ -12,10 +12,12 @@ export type ShareViewAsImageOptions = Omit<ShareFileOptions, "mimeType"> & {
|
|
|
12
12
|
* module is known to be there: on a binary built without it, only this
|
|
13
13
|
* feature fails — with a user-facing `Error` — instead of the whole screen.
|
|
14
14
|
*
|
|
15
|
-
* @param view - Ref of the view to capture (`collapsable={false}` on Android)
|
|
15
|
+
* @param view - Ref of the view to capture (`collapsable={false}` on Android),
|
|
16
|
+
* as `useRef<ComponentRef<typeof View>>(null)` gives — `View` is the
|
|
17
|
+
* component, not its instance type.
|
|
16
18
|
* @param options - See {@link ShareViewAsImageOptions} and `shareFile`.
|
|
17
19
|
* @example
|
|
18
20
|
* await shareViewAsImage(rankingRef, { dialogTitle: "Partager le classement" });
|
|
19
21
|
*/
|
|
20
|
-
export declare function shareViewAsImage(view: RefObject<View | null>, { captureUnavailableMessage, ...options }?: ShareViewAsImageOptions): Promise<void>;
|
|
22
|
+
export declare function shareViewAsImage(view: RefObject<ComponentRef<typeof View> | null>, { captureUnavailableMessage, ...options }?: ShareViewAsImageOptions): Promise<void>;
|
|
21
23
|
//# sourceMappingURL=shareViewAsImage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shareViewAsImage.d.ts","sourceRoot":"","sources":["../../../src/utils/helpers/shareViewAsImage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"shareViewAsImage.d.ts","sourceRoot":"","sources":["../../../src/utils/helpers/shareViewAsImage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACrD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAKzC,OAAO,EAAa,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElE,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,GAAG;IACzE,wEAAwE;IACxE,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC,CAAC;AAOF;;;;;;;;;;;;;GAaG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,SAAS,CAAC,YAAY,CAAC,OAAO,IAAI,CAAC,GAAG,IAAI,CAAC,EACjD,EAAE,yBAAyB,EAAE,GAAG,OAAO,EAAE,GAAE,uBAA4B,GACtE,OAAO,CAAC,IAAI,CAAC,CAcf"}
|
|
@@ -12,7 +12,9 @@ const defaultCaptureUnavailableMessages = {
|
|
|
12
12
|
* module is known to be there: on a binary built without it, only this
|
|
13
13
|
* feature fails — with a user-facing `Error` — instead of the whole screen.
|
|
14
14
|
*
|
|
15
|
-
* @param view - Ref of the view to capture (`collapsable={false}` on Android)
|
|
15
|
+
* @param view - Ref of the view to capture (`collapsable={false}` on Android),
|
|
16
|
+
* as `useRef<ComponentRef<typeof View>>(null)` gives — `View` is the
|
|
17
|
+
* component, not its instance type.
|
|
16
18
|
* @param options - See {@link ShareViewAsImageOptions} and `shareFile`.
|
|
17
19
|
* @example
|
|
18
20
|
* await shareViewAsImage(rankingRef, { dialogTitle: "Partager le classement" });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forthtilliath/react-native-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"license": "MIT",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"./*": "./dist/*.js"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@forthtilliath/ts-kit": "^0.
|
|
25
|
+
"@forthtilliath/ts-kit": "^0.15.0"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
28
|
"@expo/vector-icons": ">=15.0.0",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"@size-limit/file": "^14.1.0",
|
|
84
84
|
"@types/react": "^19.2.18",
|
|
85
85
|
"@types/react-test-renderer": "^19.1.0",
|
|
86
|
-
"@vitest/coverage-v8": "5.0.
|
|
86
|
+
"@vitest/coverage-v8": "5.0.5",
|
|
87
87
|
"eslint": "10.7.0",
|
|
88
88
|
"expo-calendar": "~57.0.5",
|
|
89
89
|
"expo-file-system": "~57.0.2",
|
|
@@ -101,16 +101,16 @@
|
|
|
101
101
|
"react-test-renderer": "19.2.3",
|
|
102
102
|
"size-limit": "^14.1.0",
|
|
103
103
|
"typescript": "^5.9.3",
|
|
104
|
-
"vitest": "^5.0.
|
|
105
|
-
"@forthtilliath/
|
|
106
|
-
"@forthtilliath/
|
|
107
|
-
"@forthtilliath/
|
|
104
|
+
"vitest": "^5.0.5",
|
|
105
|
+
"@forthtilliath/eslint-config": "0.10.0",
|
|
106
|
+
"@forthtilliath/expo-release-updates-ui": "^0.5.2",
|
|
107
|
+
"@forthtilliath/typescript-config": "0.1.1"
|
|
108
108
|
},
|
|
109
109
|
"size-limit": [
|
|
110
110
|
{
|
|
111
111
|
"name": "dist (all modules, brotli)",
|
|
112
112
|
"path": "dist/**/*.js",
|
|
113
|
-
"limit": "
|
|
113
|
+
"limit": "48 KB"
|
|
114
114
|
}
|
|
115
115
|
],
|
|
116
116
|
"scripts": {
|