@akanjs/next 0.0.53 → 0.0.55

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/useHistory.mjs ADDED
@@ -0,0 +1,46 @@
1
+ "use client";
2
+ import { useCallback, useRef } from "react";
3
+ const useHistory = (locations = []) => {
4
+ const history = useRef({
5
+ type: "initial",
6
+ locations,
7
+ scrollMap: /* @__PURE__ */ new Map([[window.location.pathname, 0]]),
8
+ idxMap: /* @__PURE__ */ new Map([[window.location.pathname, 0]]),
9
+ cachedLocationMap: /* @__PURE__ */ new Map(),
10
+ idx: 0
11
+ });
12
+ const setHistoryForward = useCallback(({ type, location, scrollTop = 0 }) => {
13
+ history.current.type = "forward";
14
+ history.current.scrollMap.set(location.pathname, scrollTop);
15
+ history.current.idxMap.set(location.pathname, history.current.idx);
16
+ if (type === "push")
17
+ history.current.locations = [...history.current.locations.slice(0, history.current.idx + 1), location];
18
+ else if (type === "replace")
19
+ history.current.locations = [...history.current.locations.slice(0, history.current.idx), location];
20
+ if (location.pathRoute.pageState.cache)
21
+ history.current.cachedLocationMap.set(location.pathRoute.path, location);
22
+ if (type === "push" || type === "popForward")
23
+ history.current.idx++;
24
+ }, []);
25
+ const setHistoryBack = useCallback(({ location, scrollTop = 0 }) => {
26
+ history.current.type = "back";
27
+ history.current.scrollMap.set(location.pathname, scrollTop);
28
+ history.current.idxMap.set(location.pathname, history.current.idx);
29
+ if (location.pathRoute.pageState.cache)
30
+ history.current.cachedLocationMap.set(location.pathRoute.path, location);
31
+ history.current.idx--;
32
+ }, []);
33
+ const getCurrentLocation = useCallback(() => {
34
+ return history.current.locations[history.current.idx];
35
+ }, []);
36
+ const getPrevLocation = useCallback(() => {
37
+ return history.current.locations[history.current.idx - 1] ?? null;
38
+ }, []);
39
+ const getScrollTop = useCallback((pathname = history.current.locations[history.current.idx]?.pathname ?? "/") => {
40
+ return history.current.scrollMap.get(pathname) ?? 0;
41
+ }, []);
42
+ return { history, setHistoryForward, setHistoryBack, getCurrentLocation, getPrevLocation, getScrollTop };
43
+ };
44
+ export {
45
+ useHistory
46
+ };
@@ -0,0 +1,21 @@
1
+ "use client";
2
+ import { useEffect, useRef } from "react";
3
+ const useInterval = (callback, delay) => {
4
+ const savedCallback = useRef(null);
5
+ useEffect(() => {
6
+ savedCallback.current = callback;
7
+ }, [callback]);
8
+ useEffect(() => {
9
+ const tick = () => {
10
+ void savedCallback.current?.();
11
+ };
12
+ const id = setInterval(tick, delay);
13
+ return () => {
14
+ clearInterval(id);
15
+ };
16
+ }, [delay]);
17
+ return savedCallback;
18
+ };
19
+ export {
20
+ useInterval
21
+ };
@@ -0,0 +1,59 @@
1
+ "use client";
2
+ import { useCallback } from "react";
3
+ const useLocation = ({ rootRouteGuide }) => {
4
+ const getLocation = useCallback((href) => {
5
+ const getPathSegments = (pathname2) => {
6
+ return [
7
+ ...pathname2.split("/").filter((pathSegment) => !!pathSegment).map((pathSegment) => `/${pathSegment}`)
8
+ ];
9
+ };
10
+ const getPathRoute = (pathname2) => {
11
+ const pathSegments = getPathSegments(pathname2);
12
+ const getTargetRouteGuide = (pathSegments2, routeGuide) => {
13
+ const pathSegment = pathSegments2.shift();
14
+ if (!pathSegment)
15
+ return routeGuide;
16
+ const childrenSegments = Object.keys(routeGuide.children);
17
+ const matchingPathSegment = childrenSegments.find((segment) => segment === pathSegment);
18
+ const paramSegment = childrenSegments.find((segment) => segment.startsWith("/:"));
19
+ const childRouteGuide = matchingPathSegment ? routeGuide.children[pathSegment] : paramSegment ? routeGuide.children[paramSegment] : null;
20
+ if (!childRouteGuide)
21
+ throw new Error("404");
22
+ return getTargetRouteGuide(pathSegments2, childRouteGuide);
23
+ };
24
+ const targetRouteGuide = getTargetRouteGuide(pathSegments, rootRouteGuide);
25
+ const pathRoute2 = targetRouteGuide.pathRoute;
26
+ if (!pathRoute2) {
27
+ window.location.assign("/404");
28
+ throw new Error("404");
29
+ }
30
+ return pathRoute2;
31
+ };
32
+ const getParams = (pathname2, pathRoute2) => {
33
+ const pathSegments = getPathSegments(pathname2);
34
+ return pathRoute2.pathSegments.reduce((params2, pathSegment, idx) => {
35
+ if (pathSegment.startsWith("/:"))
36
+ params2[pathSegment.slice(2)] = pathSegments[idx - 1].slice(1);
37
+ return params2;
38
+ }, {});
39
+ };
40
+ const getSearchParams = (search2) => {
41
+ return [...new URLSearchParams(search2).entries()].reduce(
42
+ (params2, [key, value]) => {
43
+ params2[key] = params2[key] ? [...Array.isArray(params2[key]) ? params2[key] : [params2[key]], value] : value;
44
+ return params2;
45
+ },
46
+ {}
47
+ );
48
+ };
49
+ const [pathname, search] = href.split("?");
50
+ const pathRoute = getPathRoute(pathname);
51
+ const params = getParams(pathname, pathRoute);
52
+ const searchParams = getSearchParams(search);
53
+ return { pathname, search, params, searchParams, pathRoute };
54
+ }, []);
55
+ return { getLocation };
56
+ };
57
+ export {
58
+ useLocation
59
+ };
@@ -0,0 +1,120 @@
1
+ "use client";
2
+ import "cordova-plugin-purchase/www/store";
3
+ import { App } from "@capacitor/app";
4
+ import { useEffect, useRef, useState } from "react";
5
+ const usePurchase = ({
6
+ platform,
7
+ productInfo,
8
+ url,
9
+ onPay,
10
+ onSubscribe
11
+ }) => {
12
+ const [isLoading, setIsLoading] = useState(true);
13
+ const billingRef = useRef();
14
+ useEffect(() => {
15
+ const init = async () => {
16
+ if (CdvPurchase.store.isReady) {
17
+ setIsLoading(false);
18
+ return;
19
+ }
20
+ const app = await App.getInfo();
21
+ if (platform === "all")
22
+ CdvPurchase.store.register([
23
+ ...productInfo.map((prouct) => ({
24
+ id: prouct.id,
25
+ platform: CdvPurchase.Platform.GOOGLE_PLAY,
26
+ type: CdvPurchase.ProductType[prouct.type]
27
+ })),
28
+ ...productInfo.map((prouct) => ({
29
+ id: prouct.id,
30
+ platform: CdvPurchase.Platform.APPLE_APPSTORE,
31
+ type: CdvPurchase.ProductType[prouct.type]
32
+ }))
33
+ ]);
34
+ else
35
+ CdvPurchase.store.register(
36
+ productInfo.map((product) => ({
37
+ id: product.id,
38
+ platform: platform === "android" ? CdvPurchase.Platform.GOOGLE_PLAY : CdvPurchase.Platform.APPLE_APPSTORE,
39
+ type: CdvPurchase.ProductType[product.type]
40
+ }))
41
+ );
42
+ await CdvPurchase.store.initialize([
43
+ { platform: CdvPurchase.Platform.APPLE_APPSTORE, options: { needAppReceipt: false } },
44
+ { platform: CdvPurchase.Platform.GOOGLE_PLAY }
45
+ ]);
46
+ await CdvPurchase.store.update();
47
+ await CdvPurchase.store.restorePurchases();
48
+ CdvPurchase.store.validator = async (request, callback) => {
49
+ const transactionId = request.transaction.id;
50
+ const transactions = CdvPurchase.store.localTransactions;
51
+ const verifingTransaction = transactions.find((transaction) => transaction.transactionId === transactionId);
52
+ if (verifingTransaction?.state !== "approved")
53
+ return;
54
+ const billing = await fetch(`${url}/billing/verifyBilling`, {
55
+ method: "POST",
56
+ headers: {
57
+ "Content-Type": "application/json"
58
+ },
59
+ body: JSON.stringify({
60
+ data: {
61
+ platform: verifingTransaction.platform === CdvPurchase.Platform.GOOGLE_PLAY ? "google" : "apple",
62
+ packageName: app.id,
63
+ productId: verifingTransaction.products[0].id,
64
+ receipt: verifingTransaction.platform === CdvPurchase.Platform.GOOGLE_PLAY ? request.transaction.purchaseToken : request.transaction.appStoreReceipt,
65
+ transactionId: verifingTransaction.transactionId
66
+ }
67
+ })
68
+ });
69
+ billingRef.current = billing.json();
70
+ callback({
71
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
72
+ ok: billing ? true : false,
73
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
74
+ data: { id: request.id, latest_receipt: true, transaction: request.transaction }
75
+ });
76
+ };
77
+ if (CdvPurchase.store.localReceipts.length > 0) {
78
+ CdvPurchase.store.localReceipts.forEach((receipt) => {
79
+ if (receipt.platform === CdvPurchase.Platform.GOOGLE_PLAY)
80
+ if (receipt.transactions[0].state === CdvPurchase.TransactionState.APPROVED)
81
+ void receipt.transactions[0].verify();
82
+ else
83
+ void receipt.transactions[0].finish();
84
+ });
85
+ }
86
+ CdvPurchase.store.when().approved((transaction) => {
87
+ void transaction.verify();
88
+ }).verified((receipt) => {
89
+ void receipt.finish();
90
+ }).finished((transaction) => {
91
+ void inAppPurchase(transaction);
92
+ });
93
+ setIsLoading(false);
94
+ };
95
+ void init();
96
+ }, []);
97
+ const purchaseProduct = async (product) => {
98
+ await product.getOffer()?.order();
99
+ };
100
+ const restorePurchases = async () => {
101
+ await CdvPurchase.store.restorePurchases();
102
+ };
103
+ const inAppPurchase = async (transaction) => {
104
+ const product = CdvPurchase.store.get(transaction.products[0].id);
105
+ if (product?.type === "consumable")
106
+ await onPay?.(transaction);
107
+ else
108
+ await onSubscribe?.(transaction);
109
+ await transaction.finish();
110
+ };
111
+ return {
112
+ isLoading,
113
+ products: CdvPurchase.store.products,
114
+ purchaseProduct,
115
+ restorePurchases
116
+ };
117
+ };
118
+ export {
119
+ usePurchase
120
+ };
@@ -0,0 +1,42 @@
1
+ "use client";
2
+ import { Device } from "@capacitor/device";
3
+ import { PushNotifications } from "@capacitor/push-notifications";
4
+ import { FCM } from "@capacitor-community/fcm";
5
+ const usePushNoti = () => {
6
+ const init = async () => {
7
+ const device = await Device.getInfo();
8
+ if (device.platform === "web")
9
+ return;
10
+ void FCM.setAutoInit({ enabled: true });
11
+ void PushNotifications.requestPermissions().then(async (result) => {
12
+ if (result.receive === "granted") {
13
+ await PushNotifications.register();
14
+ }
15
+ });
16
+ };
17
+ const checkPermission = async () => {
18
+ const { receive } = await PushNotifications.checkPermissions();
19
+ return receive === "granted";
20
+ };
21
+ const register = async () => {
22
+ const device = await Device.getInfo();
23
+ if (device.platform === "web")
24
+ return;
25
+ const { receive } = await PushNotifications.checkPermissions();
26
+ if (receive === "denied")
27
+ location.assign("app-settings:");
28
+ else
29
+ await PushNotifications.register();
30
+ };
31
+ const getToken = async () => {
32
+ const device = await Device.getInfo();
33
+ if (device.platform === "web")
34
+ return;
35
+ const { token } = await FCM.getToken();
36
+ return token;
37
+ };
38
+ return { init, checkPermission, register, getToken };
39
+ };
40
+ export {
41
+ usePushNoti
42
+ };
@@ -0,0 +1,20 @@
1
+ "use client";
2
+ import { useCallback, useRef } from "react";
3
+ const useThrottle = (func, delay = 200, deps = []) => {
4
+ const throttleSeed = useRef(null);
5
+ const throttleFunction = useCallback(
6
+ (...args) => {
7
+ if (throttleSeed.current)
8
+ return;
9
+ func(...args);
10
+ throttleSeed.current = setTimeout(() => {
11
+ throttleSeed.current = null;
12
+ }, delay);
13
+ },
14
+ [func, delay, ...deps]
15
+ );
16
+ return throttleFunction;
17
+ };
18
+ export {
19
+ useThrottle
20
+ };