@forthtilliath/expo-release-updates-ui 0.2.8 → 0.3.1
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 +2 -0
- package/dist/UpdateAvailableBanner.d.ts +9 -1
- package/dist/UpdateAvailableBanner.d.ts.map +1 -1
- package/dist/UpdateAvailableBanner.js +14 -6
- package/dist/useUpdateCheck.d.ts +8 -7
- package/dist/useUpdateCheck.d.ts.map +1 -1
- package/dist/useUpdateCheck.js +2 -1
- package/package.json +7 -6
package/README.md
CHANGED
|
@@ -129,6 +129,8 @@ import { UpdateAvailableBanner } from "@forthtilliath/expo-release-updates-ui";
|
|
|
129
129
|
}
|
|
130
130
|
```
|
|
131
131
|
|
|
132
|
+
Built-in labels are French by default; pass `locale="en"` for English (e.g. from the app's language on a bilingual app). `labels` still overrides individual strings — `title`, `action`, `dismiss`, `dismissAccessibilityLabel` — whatever the locale.
|
|
133
|
+
|
|
132
134
|
## Scripts
|
|
133
135
|
|
|
134
136
|
```bash
|
|
@@ -10,6 +10,8 @@ export interface UpdateAvailableBannerStyles {
|
|
|
10
10
|
dismissButton?: StyleProp<ViewStyle>;
|
|
11
11
|
dismissButtonText?: StyleProp<TextStyle>;
|
|
12
12
|
}
|
|
13
|
+
/** Languages the banner's built-in labels are available in. */
|
|
14
|
+
export type UpdateBannerLocale = "fr" | "en";
|
|
13
15
|
export interface UpdateAvailableBannerLabels {
|
|
14
16
|
title?: (version: string) => string;
|
|
15
17
|
action?: string;
|
|
@@ -22,8 +24,14 @@ export interface UpdateAvailableBannerProps {
|
|
|
22
24
|
notes: string;
|
|
23
25
|
onPress: () => void;
|
|
24
26
|
onDismiss: () => void;
|
|
27
|
+
/** Overrides individual built-in labels, whatever the `locale`. */
|
|
25
28
|
labels?: UpdateAvailableBannerLabels;
|
|
29
|
+
/**
|
|
30
|
+
* Language of the built-in labels.
|
|
31
|
+
* @defaultValue "fr"
|
|
32
|
+
*/
|
|
33
|
+
locale?: UpdateBannerLocale;
|
|
26
34
|
styles?: UpdateAvailableBannerStyles;
|
|
27
35
|
}
|
|
28
|
-
export declare function UpdateAvailableBanner({ version, notes, onPress, onDismiss, labels, styles, }: UpdateAvailableBannerProps): import("react").JSX.Element;
|
|
36
|
+
export declare function UpdateAvailableBanner({ version, notes, onPress, onDismiss, labels, locale, styles, }: UpdateAvailableBannerProps): import("react").JSX.Element;
|
|
29
37
|
//# sourceMappingURL=UpdateAvailableBanner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UpdateAvailableBanner.d.ts","sourceRoot":"","sources":["../src/UpdateAvailableBanner.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAGhE,MAAM,WAAW,2BAA2B;IAC1C,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,oBAAoB,CAAC;IAC7B,YAAY,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACpC,gBAAgB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACxC,aAAa,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACrC,iBAAiB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,2BAA2B;IAC1C,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,2BAA2B,CAAC;IACrC,MAAM,CAAC,EAAE,2BAA2B,CAAC;CACtC;
|
|
1
|
+
{"version":3,"file":"UpdateAvailableBanner.d.ts","sourceRoot":"","sources":["../src/UpdateAvailableBanner.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAGhE,MAAM,WAAW,2BAA2B;IAC1C,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,oBAAoB,CAAC;IAC7B,YAAY,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACpC,gBAAgB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACxC,aAAa,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACrC,iBAAiB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC1C;AAED,+DAA+D;AAC/D,MAAM,MAAM,kBAAkB,GAAG,IAAI,GAAG,IAAI,CAAC;AAE7C,MAAM,WAAW,2BAA2B;IAC1C,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,mEAAmE;IACnE,MAAM,CAAC,EAAE,2BAA2B,CAAC;IACrC;;;OAGG;IACH,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,MAAM,CAAC,EAAE,2BAA2B,CAAC;CACtC;AAmDD,wBAAgB,qBAAqB,CAAC,EACpC,OAAO,EACP,KAAK,EACL,OAAO,EACP,SAAS,EACT,MAAM,EACN,MAAa,EACb,MAAM,GACP,EAAE,0BAA0B,+BA+C5B"}
|
|
@@ -28,16 +28,24 @@ const defaultStyles = {
|
|
|
28
28
|
dismissButtonText: { fontSize: 13, color: "#6b7280" },
|
|
29
29
|
};
|
|
30
30
|
const defaultLabels = {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
fr: {
|
|
32
|
+
title: (version) => `Version ${version} disponible`,
|
|
33
|
+
action: "Voir",
|
|
34
|
+
dismiss: "Fermer",
|
|
35
|
+
dismissAccessibilityLabel: "Fermer la notification de mise à jour",
|
|
36
|
+
},
|
|
37
|
+
en: {
|
|
38
|
+
title: (version) => `Version ${version} available`,
|
|
39
|
+
action: "View",
|
|
40
|
+
dismiss: "Close",
|
|
41
|
+
dismissAccessibilityLabel: "Dismiss the update notification",
|
|
42
|
+
},
|
|
35
43
|
};
|
|
36
44
|
// Dismissible banner announcing an available update: version, release notes
|
|
37
45
|
// (via `ChangelogNotes`), and an action + dismiss button. Has no opinion on
|
|
38
46
|
// what "action" does (e.g. navigate to an update screen) or on how/whether
|
|
39
47
|
// dismissal is persisted — both are left entirely to the caller.
|
|
40
|
-
export function UpdateAvailableBanner({ version, notes, onPress, onDismiss, labels, styles, }) {
|
|
48
|
+
export function UpdateAvailableBanner({ version, notes, onPress, onDismiss, labels, locale = "fr", styles, }) {
|
|
41
49
|
// Style fields are merged as arrays (default, then override) so a partial
|
|
42
50
|
// override only changes the properties it specifies instead of replacing
|
|
43
51
|
// the whole default style object. `notes` is forwarded as-is to
|
|
@@ -58,6 +66,6 @@ export function UpdateAvailableBanner({ version, notes, onPress, onDismiss, labe
|
|
|
58
66
|
styles?.dismissButtonText,
|
|
59
67
|
],
|
|
60
68
|
};
|
|
61
|
-
const t = { ...defaultLabels, ...labels };
|
|
69
|
+
const t = { ...defaultLabels[locale], ...labels };
|
|
62
70
|
return (_jsxs(View, { style: merged.container, children: [_jsxs(View, { style: merged.header, children: [_jsx(Text, { style: merged.title, children: t.title(version) }), _jsx(Pressable, { style: merged.dismissButton, onPress: onDismiss, accessibilityRole: "button", accessibilityLabel: t.dismissAccessibilityLabel, children: _jsx(Text, { style: merged.dismissButtonText, children: t.dismiss }) })] }), notes ? _jsx(ChangelogNotes, { notes: notes, styles: merged.notes }) : null, _jsx(Pressable, { style: merged.actionButton, onPress: onPress, accessibilityRole: "button", accessibilityLabel: t.action, children: _jsx(Text, { style: merged.actionButtonText, children: t.action }) })] }));
|
|
63
71
|
}
|
package/dist/useUpdateCheck.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
apkUrl: string;
|
|
5
|
-
}
|
|
1
|
+
import type { LatestRelease } from "@forthtilliath/expo-release-updates/githubReleases";
|
|
2
|
+
/** A release as returned by `fetchLatestRelease` (same shape). */
|
|
3
|
+
export type UpdateCheckRelease = LatestRelease;
|
|
6
4
|
export type UpdateCheckState = {
|
|
7
5
|
status: "idle";
|
|
8
6
|
} | {
|
|
@@ -16,8 +14,11 @@ export interface UseUpdateCheckOptions {
|
|
|
16
14
|
currentVersion: string;
|
|
17
15
|
/** Fetches the latest available release, or `null` if there is none. */
|
|
18
16
|
checkForUpdate: () => Promise<UpdateCheckRelease | null>;
|
|
19
|
-
/**
|
|
20
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Positive when `a` is newer than `b`. Defaults to
|
|
19
|
+
* `@forthtilliath/expo-release-updates`'s semver `compareVersions`.
|
|
20
|
+
*/
|
|
21
|
+
compareVersions?: (a: string, b: string) => number;
|
|
21
22
|
/** Read once on mount: when the last check ran, and which version (if any) the user already dismissed. */
|
|
22
23
|
getLastCheck: () => {
|
|
23
24
|
lastCheckedAt: number | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useUpdateCheck.d.ts","sourceRoot":"","sources":["../src/useUpdateCheck.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useUpdateCheck.d.ts","sourceRoot":"","sources":["../src/useUpdateCheck.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oDAAoD,CAAC;AAExF,kEAAkE;AAClE,MAAM,MAAM,kBAAkB,GAAG,aAAa,CAAC;AAE/C,MAAM,MAAM,gBAAgB,GACxB;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAClB;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,kBAAkB,CAAA;CAAE,GACpD;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,CAAC;AAExB,MAAM,WAAW,qBAAqB;IACpC,+EAA+E;IAC/E,cAAc,EAAE,MAAM,CAAC;IACvB,wEAAwE;IACxE,cAAc,EAAE,MAAM,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IACzD;;;OAGG;IACH,eAAe,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACnD,0GAA0G;IAC1G,YAAY,EAAE,MAAM;QAClB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;KACjC,CAAC;IACF,sGAAsG;IACtG,SAAS,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,yDAAyD;IACzD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAUD,wBAAgB,cAAc,CAAC,EAC7B,cAAc,EACd,cAAc,EACd,eAAwC,EACxC,YAAY,EACZ,SAAS,EACT,aAAuC,EACvC,GAAc,GACf,EAAE,qBAAqB,GAAG,gBAAgB,GAAG;IAAE,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,CAyCpE"}
|
package/dist/useUpdateCheck.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useEffect, useState } from "react";
|
|
2
|
+
import { compareVersions as defaultCompareVersions } from "@forthtilliath/expo-release-updates/compareVersions";
|
|
2
3
|
const DEFAULT_MIN_INTERVAL_MS = 12 * 60 * 60 * 1000;
|
|
3
4
|
// Checks once per mount (e.g. app launch) whether a newer release is
|
|
4
5
|
// available, throttled to at most one real network check per `minIntervalMs`
|
|
@@ -6,7 +7,7 @@ const DEFAULT_MIN_INTERVAL_MS = 12 * 60 * 60 * 1000;
|
|
|
6
7
|
// "when did we last check" / "which version did the user dismiss" is left
|
|
7
8
|
// entirely to the caller (`getLastCheck`/`onChecked`, plus its own dismiss
|
|
8
9
|
// handler) — this hook has no opinion on where that lives.
|
|
9
|
-
export function useUpdateCheck({ currentVersion, checkForUpdate, compareVersions, getLastCheck, onChecked, minIntervalMs = DEFAULT_MIN_INTERVAL_MS, now = Date.now, }) {
|
|
10
|
+
export function useUpdateCheck({ currentVersion, checkForUpdate, compareVersions = defaultCompareVersions, getLastCheck, onChecked, minIntervalMs = DEFAULT_MIN_INTERVAL_MS, now = Date.now, }) {
|
|
10
11
|
const [state, setState] = useState({ status: "idle" });
|
|
11
12
|
useEffect(() => {
|
|
12
13
|
const { lastCheckedAt, dismissedVersion } = getLastCheck();
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forthtilliath/expo-release-updates-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"type": "module",
|
|
5
|
+
"sideEffects": false,
|
|
5
6
|
"license": "MIT",
|
|
6
7
|
"publishConfig": {
|
|
7
8
|
"access": "public"
|
|
@@ -21,7 +22,7 @@
|
|
|
21
22
|
"./*": "./dist/*.js"
|
|
22
23
|
},
|
|
23
24
|
"dependencies": {
|
|
24
|
-
"@forthtilliath/expo-release-updates": "0.
|
|
25
|
+
"@forthtilliath/expo-release-updates": "^0.6.0"
|
|
25
26
|
},
|
|
26
27
|
"peerDependencies": {
|
|
27
28
|
"react": ">=19",
|
|
@@ -35,14 +36,14 @@
|
|
|
35
36
|
"react-native": "0.86.0",
|
|
36
37
|
"react-test-renderer": "19.2.3",
|
|
37
38
|
"typescript": "^5.9.3",
|
|
38
|
-
"vitest": "^
|
|
39
|
-
"@forthtilliath/
|
|
40
|
-
"@forthtilliath/
|
|
39
|
+
"vitest": "^5.0.2",
|
|
40
|
+
"@forthtilliath/typescript-config": "0.1.1",
|
|
41
|
+
"@forthtilliath/eslint-config": "0.8.0"
|
|
41
42
|
},
|
|
42
43
|
"scripts": {
|
|
43
44
|
"lint": "eslint . --max-warnings 0",
|
|
44
45
|
"check-types": "tsc --noEmit",
|
|
45
|
-
"clean": "
|
|
46
|
+
"clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
|
|
46
47
|
"dev": "tsc --watch -p tsconfig.build.json",
|
|
47
48
|
"build": "pnpm run clean && tsc -p tsconfig.build.json",
|
|
48
49
|
"test": "vitest run",
|