@hook-sdk/template 0.11.0 → 0.12.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/dist/index.cjs CHANGED
@@ -2070,6 +2070,8 @@ function FallbackPaywall() {
2070
2070
  // src/hooks/usePush.ts
2071
2071
  var import_react12 = require("react");
2072
2072
  var import_sdk5 = require("@hook-sdk/sdk");
2073
+ var DISMISS_STORAGE_KEY = "push:dismissed-until";
2074
+ var DISMISS_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
2073
2075
  function detectIosNeedsInstall() {
2074
2076
  if (typeof navigator === "undefined" || typeof window === "undefined") return false;
2075
2077
  const ua = navigator.userAgent || "";
@@ -2080,6 +2082,21 @@ function detectIosNeedsInstall() {
2080
2082
  const legacyStandalone = typeof navigator.standalone === "boolean" ? navigator.standalone : false;
2081
2083
  return !(standalone || legacyStandalone);
2082
2084
  }
2085
+ function readDismissedUntil() {
2086
+ if (typeof localStorage === "undefined") return null;
2087
+ try {
2088
+ const raw = localStorage.getItem(DISMISS_STORAGE_KEY);
2089
+ if (raw === null) return null;
2090
+ const n = Number.parseInt(raw, 10);
2091
+ return Number.isFinite(n) ? n : null;
2092
+ } catch {
2093
+ return null;
2094
+ }
2095
+ }
2096
+ function isDismissedNow() {
2097
+ const until = readDismissedUntil();
2098
+ return until !== null && until > Date.now();
2099
+ }
2083
2100
  function deriveState(push) {
2084
2101
  if (!push.isAvailable()) {
2085
2102
  if (detectIosNeedsInstall()) return { kind: "ios_needs_install" };
@@ -2092,6 +2109,7 @@ function deriveState(push) {
2092
2109
  if (detectIosNeedsInstall()) return { kind: "ios_needs_install" };
2093
2110
  return { kind: "unsupported" };
2094
2111
  }
2112
+ if (isDismissedNow()) return { kind: "dismissed" };
2095
2113
  return { kind: "prompt" };
2096
2114
  }
2097
2115
  function usePush() {
@@ -2121,14 +2139,41 @@ function usePush() {
2121
2139
  throw e;
2122
2140
  }
2123
2141
  }, [push]);
2124
- return { state, subscribe, unsubscribe };
2142
+ const dismiss = (0, import_react12.useCallback)(() => {
2143
+ if (typeof localStorage !== "undefined") {
2144
+ try {
2145
+ localStorage.setItem(DISMISS_STORAGE_KEY, String(Date.now() + DISMISS_TTL_MS));
2146
+ } catch {
2147
+ }
2148
+ }
2149
+ setState({ kind: "dismissed" });
2150
+ }, []);
2151
+ return { state, subscribe, unsubscribe, dismiss };
2125
2152
  }
2126
2153
 
2127
2154
  // src/components/PushPrompt.tsx
2128
2155
  var import_jsx_runtime19 = require("react/jsx-runtime");
2156
+ function platformRecoveryCopy(texts) {
2157
+ if (typeof navigator === "undefined") return null;
2158
+ const ua = navigator.userAgent || "";
2159
+ const platform = detectPlatform(ua);
2160
+ switch (platform) {
2161
+ case "ios-safari":
2162
+ case "ios-other":
2163
+ return texts.deniedRecoveryIos ?? null;
2164
+ case "android":
2165
+ return texts.deniedRecoveryAndroid ?? null;
2166
+ case "desktop":
2167
+ return texts.deniedRecoveryDesktop ?? null;
2168
+ case "in-app":
2169
+ return texts.deniedRecoveryInApp ?? null;
2170
+ default:
2171
+ return null;
2172
+ }
2173
+ }
2129
2174
  function PushPrompt2({ texts, onSubscribed, onDeclined, onInstallRequested, className }) {
2130
2175
  const { state, subscribe } = usePush();
2131
- if (state.kind === "subscribed") return null;
2176
+ if (state.kind === "subscribed" || state.kind === "dismissed") return null;
2132
2177
  if (state.kind === "ios_needs_install") {
2133
2178
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className, role: "region", "aria-label": texts.iosInstallTitle, children: [
2134
2179
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h3", { children: texts.iosInstallTitle }),
@@ -2137,9 +2182,11 @@ function PushPrompt2({ texts, onSubscribed, onDeclined, onInstallRequested, clas
2137
2182
  ] });
2138
2183
  }
2139
2184
  if (state.kind === "denied") {
2185
+ const recovery = platformRecoveryCopy(texts);
2140
2186
  return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className, role: "region", "aria-label": texts.deniedTitle, children: [
2141
2187
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h3", { children: texts.deniedTitle }),
2142
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { children: texts.deniedBody })
2188
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { children: texts.deniedBody }),
2189
+ recovery && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { "data-testid": "denied-recovery", children: recovery })
2143
2190
  ] });
2144
2191
  }
2145
2192
  if (state.kind === "unsupported") {