@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/bootCsr.mjs ADDED
@@ -0,0 +1,138 @@
1
+ "use client";
2
+ import { device, initAuth, storage } from "@akanjs/client";
3
+ import {
4
+ csrContext,
5
+ DEFAULT_BOTTOM_INSET,
6
+ DEFAULT_TOP_INSET,
7
+ defaultPageState
8
+ } from "@akanjs/client";
9
+ import { Logger } from "@akanjs/common";
10
+ import React from "react";
11
+ import * as ReactDOM from "react-dom/client";
12
+ import { useCsrValues } from "./useCsrValues";
13
+ const supportLanguages = ["en", "ko"];
14
+ const bootCsr = async (context, rootPath, entryPath = "/route") => {
15
+ const [, jwt] = await Promise.all([device.init({ supportLanguages }), storage.getItem("jwt")]);
16
+ if (jwt)
17
+ initAuth({ jwt });
18
+ Logger.verbose(`Set default language: ${device.lang}`);
19
+ const pages = {};
20
+ await Promise.all(
21
+ Object.entries(context).map(async ([key, value]) => {
22
+ pages[key] = await value();
23
+ })
24
+ );
25
+ const getPageState = (csrConfig) => {
26
+ const { transition, safeArea, topInset, bottomInset, gesture, cache } = csrConfig ?? {};
27
+ const pageState = {
28
+ transition: transition ?? "none",
29
+ topSafeArea: safeArea === false ? 0 : device.topSafeArea,
30
+ bottomSafeArea: safeArea === false ? 0 : device.bottomSafeArea,
31
+ // topSafeArea: safeArea === false || device.info.platform === "android" ? 0 : device.topSafeArea,
32
+ // bottomSafeArea: safeArea === false || device.info.platform === "android" ? 0 : device.bottomSafeArea,
33
+ topInset: topInset === true ? DEFAULT_TOP_INSET : topInset === false ? 0 : topInset ?? 0,
34
+ bottomInset: bottomInset === true ? DEFAULT_BOTTOM_INSET : bottomInset === false ? 0 : bottomInset ?? 0,
35
+ gesture: gesture ?? true,
36
+ cache: cache ?? false
37
+ };
38
+ return pageState;
39
+ };
40
+ const routeMap = /* @__PURE__ */ new Map();
41
+ routeMap.set("/", { path: "/", children: /* @__PURE__ */ new Map() });
42
+ for (const filePath of Object.keys(pages)) {
43
+ const fileName = /\.\/(.*)\.tsx$/.exec(filePath)?.[1];
44
+ if (!fileName)
45
+ continue;
46
+ const fileType = fileName.endsWith("page") ? "page" : fileName.endsWith("layout") ? "layout" : null;
47
+ if (!fileType)
48
+ continue;
49
+ const pathSegments = [
50
+ "/",
51
+ ...fileName.split("/").slice(0, -1).map((segment) => `/${segment.replace(/\[(.*?)\]/g, ":$1")}`)
52
+ ];
53
+ const targetRouteMap = pathSegments.slice(0, -1).reduce((rMap, path) => {
54
+ if (!rMap.has(path))
55
+ rMap.set(path, { path, children: /* @__PURE__ */ new Map() });
56
+ return rMap.get(path)?.children;
57
+ }, routeMap);
58
+ if (!targetRouteMap)
59
+ continue;
60
+ const targetPath = pathSegments[pathSegments.length - 1];
61
+ targetRouteMap.set(targetPath, {
62
+ // action: pages[path]?.action,
63
+ // ErrorBoundary: pages[path]?.ErrorBoundary,
64
+ ...targetRouteMap.get(targetPath) ?? { path: targetPath, children: /* @__PURE__ */ new Map() },
65
+ ...fileType === "layout" ? { Layout: pages[filePath].default } : {
66
+ Page: pages[filePath].default,
67
+ pageState: getPageState(pages[filePath].default.csrConfig),
68
+ csrConfig: pages[filePath].default.csrConfig
69
+ }
70
+ });
71
+ }
72
+ const pathname = window.location.pathname;
73
+ const initialPath = device.lang + entryPath;
74
+ window.document.body.style.overflow = "hidden";
75
+ const getPathRoutes = (route, parentRootLayouts = [], parentLayouts = [], parentPaths = []) => {
76
+ const parentPath = parentPaths.filter((path2) => path2 !== "/").join("");
77
+ const currentPathSegment = /^\/\(.*\)$/.test(route.path) ? "" : route.path;
78
+ const isRoot = ["/", "/:lang"].includes(parentPath + currentPathSegment) && parentRootLayouts.length < 2;
79
+ const path = parentPath + currentPathSegment;
80
+ const pathSegments = [...parentPaths, ...currentPathSegment ? [currentPathSegment] : []];
81
+ const RootLayouts = [...parentRootLayouts, ...isRoot && route.Layout ? [route.Layout] : []];
82
+ const Layouts = [...parentLayouts, ...!isRoot && route.Layout ? [route.Layout] : []];
83
+ return [
84
+ ...route.Page ? [
85
+ {
86
+ path,
87
+ pathSegments,
88
+ Page: route.Page,
89
+ RootLayouts,
90
+ Layouts,
91
+ pageState: route.pageState ?? defaultPageState
92
+ }
93
+ ] : [],
94
+ ...route.children.size ? [...route.children.values()].flatMap((child) => getPathRoutes(child, RootLayouts, Layouts, pathSegments)) : []
95
+ ];
96
+ };
97
+ const rootRoute = routeMap.get("/");
98
+ if (!rootRoute)
99
+ throw new Error("No root route");
100
+ const pathRoutes = getPathRoutes(rootRoute);
101
+ const routeGuide = { pathSegment: "/", children: {} };
102
+ pathRoutes.forEach((pathRoute) => {
103
+ const pathSegments = pathRoute.pathSegments.slice(1);
104
+ pathSegments.reduce((routeGuide2, pathSegment, index) => {
105
+ const child = routeGuide2.children[pathSegment];
106
+ routeGuide2.children[pathSegment] = {
107
+ ...child ?? {},
108
+ pathSegment,
109
+ ...index === pathSegments.length - 1 ? { pathRoute } : {},
110
+ children: child?.children ?? {}
111
+ };
112
+ return routeGuide2.children[pathSegment];
113
+ }, routeGuide);
114
+ });
115
+ const RouterProvider = () => {
116
+ const csrValues = useCsrValues(routeGuide, pathRoutes);
117
+ const { location } = csrValues;
118
+ return /* @__PURE__ */ React.createElement(csrContext.Provider, { value: csrValues }, location.pathRoute.RootLayouts.reduceRight(
119
+ (children, Layout) => {
120
+ return /* @__PURE__ */ React.createElement(Layout, { params: location.params, searchParams: location.searchParams }, children);
121
+ },
122
+ /* @__PURE__ */ React.createElement(React.Fragment, null)
123
+ ));
124
+ };
125
+ if (pathname !== `/${initialPath}`) {
126
+ window.location.replace(initialPath);
127
+ return;
128
+ } else {
129
+ const el = document.getElementById("root");
130
+ if (!el)
131
+ throw new Error("No root element");
132
+ const root = ReactDOM.createRoot(el);
133
+ root.render(/* @__PURE__ */ React.createElement(RouterProvider, null));
134
+ }
135
+ };
136
+ export {
137
+ bootCsr
138
+ };
@@ -0,0 +1,49 @@
1
+ import { logo } from "@akanjs/base";
2
+ import { Logger } from "@akanjs/common";
3
+ import { match as matchLocale } from "@formatjs/intl-localematcher";
4
+ import Negotiator from "negotiator";
5
+ import { NextResponse } from "next/server";
6
+ const i18n = { defaultLocale: "en", locales: ["en", "ko"] };
7
+ const basePaths = process.env.basePaths ? process.env.basePaths.split(",") : [];
8
+ function getLocale(request) {
9
+ if (!request.headers.get("accept-language"))
10
+ return i18n.defaultLocale;
11
+ const negotiatorHeaders = {};
12
+ request.headers.forEach((value, key) => negotiatorHeaders[key] = value);
13
+ try {
14
+ const languages = new Negotiator({ headers: negotiatorHeaders }).languages();
15
+ return matchLocale(languages, i18n.locales, i18n.defaultLocale);
16
+ } catch (e) {
17
+ return i18n.defaultLocale;
18
+ }
19
+ }
20
+ const createNextMiddleware = () => {
21
+ Logger.rawLog(logo, "console");
22
+ const middleware = (request) => {
23
+ const pathname = request.nextUrl.pathname;
24
+ const pathnameIsMissingLocale = i18n.locales.every(
25
+ (locale2) => !pathname.startsWith(`/${locale2}/`) && pathname !== `/${locale2}`
26
+ );
27
+ if (pathnameIsMissingLocale)
28
+ return NextResponse.redirect(
29
+ new URL(`/${getLocale(request)}/${request.nextUrl.href.split("/").slice(3).join("/")}`, request.url)
30
+ );
31
+ const splits = pathname.split("/");
32
+ const locale = splits[1];
33
+ const basePath = basePaths.includes(splits[2]) ? splits[2] : null;
34
+ const headers = new Headers(request.headers);
35
+ const searchParams = new URLSearchParams(request.nextUrl.search);
36
+ const searchParamJwt = searchParams.get("jwt");
37
+ headers.set("x-locale", locale);
38
+ headers.set("x-path", "/" + splits.slice(2).join("/"));
39
+ if (basePath)
40
+ headers.set("x-base-path", basePath);
41
+ if (searchParamJwt)
42
+ headers.set("jwt", searchParamJwt);
43
+ return NextResponse.next({ request: { headers } });
44
+ };
45
+ return middleware;
46
+ };
47
+ export {
48
+ createNextMiddleware
49
+ };
@@ -0,0 +1,15 @@
1
+ const createRobotPage = (clientHttpUri, config) => {
2
+ return {
3
+ ...config ?? {},
4
+ rules: {
5
+ userAgent: "*",
6
+ allow: "/",
7
+ disallow: "/admin/",
8
+ ...config?.rules ?? {}
9
+ },
10
+ sitemap: `${clientHttpUri}/sitemap.xml`
11
+ };
12
+ };
13
+ export {
14
+ createRobotPage
15
+ };
@@ -0,0 +1,7 @@
1
+ const lastModified = /* @__PURE__ */ new Date();
2
+ const createSitemapPage = (clientHttpUri, paths) => {
3
+ return paths.map((path) => ({ url: `${clientHttpUri}${path}`, lastModified }));
4
+ };
5
+ export {
6
+ createSitemapPage
7
+ };
package/index.js CHANGED
@@ -1,41 +1,60 @@
1
- import { useFetch } from "./useFetch";
2
- import { lazy } from "./lazy";
3
- import { makePageProto } from "./makePageProto";
4
- import { useDebounce } from "./useDebounce";
5
- import { useInterval } from "./useInterval";
6
- import { bootCsr } from "./bootCsr";
7
- import { useCamera } from "./useCamera";
8
- import { useContact } from "./useContact";
9
- import { usePushNoti } from "./usePushNoti";
10
- import { useGeoLocation } from "./useGeoLocation";
11
- import { useCodepush } from "./useCodepush";
12
- import { usePurchase } from "./usePurchase";
13
- import { useCsrValues } from "./useCsrValues";
14
- import { createRobotPage } from "./createRobotPage";
15
- import { createSitemapPage } from "./createSitemapPage";
16
- import { createNextMiddleware } from "./createNextMiddleware";
17
- //! PageAgent csr에서 말썽 일으킨다
18
- import { useThrottle } from "./useThrottle";
19
- import { useHistory } from "./useHistory";
20
- import { useLocation } from "./useLocation";
21
- export {
22
- bootCsr,
23
- createNextMiddleware,
24
- createRobotPage,
25
- createSitemapPage,
26
- lazy,
27
- makePageProto,
28
- useCamera,
29
- useCodepush,
30
- useContact,
31
- useCsrValues,
32
- useDebounce,
33
- useFetch,
34
- useGeoLocation,
35
- useHistory,
36
- useInterval,
37
- useLocation,
38
- usePurchase,
39
- usePushNoti,
40
- useThrottle
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
41
16
  };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var next_exports = {};
19
+ __export(next_exports, {
20
+ bootCsr: () => import_bootCsr.bootCsr,
21
+ createNextMiddleware: () => import_createNextMiddleware.createNextMiddleware,
22
+ createRobotPage: () => import_createRobotPage.createRobotPage,
23
+ createSitemapPage: () => import_createSitemapPage.createSitemapPage,
24
+ lazy: () => import_lazy.lazy,
25
+ makePageProto: () => import_makePageProto.makePageProto,
26
+ useCamera: () => import_useCamera.useCamera,
27
+ useCodepush: () => import_useCodepush.useCodepush,
28
+ useContact: () => import_useContact.useContact,
29
+ useCsrValues: () => import_useCsrValues.useCsrValues,
30
+ useDebounce: () => import_useDebounce.useDebounce,
31
+ useFetch: () => import_useFetch.useFetch,
32
+ useGeoLocation: () => import_useGeoLocation.useGeoLocation,
33
+ useHistory: () => import_useHistory.useHistory,
34
+ useInterval: () => import_useInterval.useInterval,
35
+ useLocation: () => import_useLocation.useLocation,
36
+ usePurchase: () => import_usePurchase.usePurchase,
37
+ usePushNoti: () => import_usePushNoti.usePushNoti,
38
+ useThrottle: () => import_useThrottle.useThrottle
39
+ });
40
+ module.exports = __toCommonJS(next_exports);
41
+ var import_useFetch = require("./useFetch");
42
+ var import_lazy = require("./lazy");
43
+ var import_makePageProto = require("./makePageProto");
44
+ var import_useDebounce = require("./useDebounce");
45
+ var import_useInterval = require("./useInterval");
46
+ var import_bootCsr = require("./bootCsr");
47
+ var import_useCamera = require("./useCamera");
48
+ var import_useContact = require("./useContact");
49
+ var import_usePushNoti = require("./usePushNoti");
50
+ var import_useGeoLocation = require("./useGeoLocation");
51
+ var import_useCodepush = require("./useCodepush");
52
+ var import_usePurchase = require("./usePurchase");
53
+ var import_useCsrValues = require("./useCsrValues");
54
+ var import_createRobotPage = require("./createRobotPage");
55
+ var import_createSitemapPage = require("./createSitemapPage");
56
+ var import_createNextMiddleware = require("./createNextMiddleware");
57
+ var import_useThrottle = require("./useThrottle");
58
+ var import_useHistory = require("./useHistory");
59
+ var import_useLocation = require("./useLocation");
60
+ //! PageAgent csr에서 말썽 일으킨다
package/index.mjs ADDED
@@ -0,0 +1,41 @@
1
+ import { useFetch } from "./useFetch";
2
+ import { lazy } from "./lazy";
3
+ import { makePageProto } from "./makePageProto";
4
+ import { useDebounce } from "./useDebounce";
5
+ import { useInterval } from "./useInterval";
6
+ import { bootCsr } from "./bootCsr";
7
+ import { useCamera } from "./useCamera";
8
+ import { useContact } from "./useContact";
9
+ import { usePushNoti } from "./usePushNoti";
10
+ import { useGeoLocation } from "./useGeoLocation";
11
+ import { useCodepush } from "./useCodepush";
12
+ import { usePurchase } from "./usePurchase";
13
+ import { useCsrValues } from "./useCsrValues";
14
+ import { createRobotPage } from "./createRobotPage";
15
+ import { createSitemapPage } from "./createSitemapPage";
16
+ import { createNextMiddleware } from "./createNextMiddleware";
17
+ //! PageAgent csr에서 말썽 일으킨다
18
+ import { useThrottle } from "./useThrottle";
19
+ import { useHistory } from "./useHistory";
20
+ import { useLocation } from "./useLocation";
21
+ export {
22
+ bootCsr,
23
+ createNextMiddleware,
24
+ createRobotPage,
25
+ createSitemapPage,
26
+ lazy,
27
+ makePageProto,
28
+ useCamera,
29
+ useCodepush,
30
+ useContact,
31
+ useCsrValues,
32
+ useDebounce,
33
+ useFetch,
34
+ useGeoLocation,
35
+ useHistory,
36
+ useInterval,
37
+ useLocation,
38
+ usePurchase,
39
+ usePushNoti,
40
+ useThrottle
41
+ };
package/lazy.js CHANGED
@@ -32,4 +32,4 @@ __export(lazy_exports, {
32
32
  module.exports = __toCommonJS(lazy_exports);
33
33
  var import_dynamic = __toESM(require("next/dynamic"));
34
34
  //! next build를 위해서 lint 무시
35
- const lazy = (loader, option) => (0, import_dynamic.default)(loader, option ?? {});
35
+ const lazy = (loader, option) => (0, import_dynamic.default)(loader, { ...option ?? {} });
package/lazy.mjs ADDED
@@ -0,0 +1,6 @@
1
+ //! next build를 위해서 lint 무시
2
+ import dynamic from "next/dynamic";
3
+ const lazy = (loader, option) => dynamic(loader, { ...option ?? {} });
4
+ export {
5
+ lazy
6
+ };
@@ -0,0 +1,114 @@
1
+ import { baseClientEnv } from "@akanjs/base";
2
+ import { getHeader } from "@akanjs/client";
3
+ import { Logger, pathGet } from "@akanjs/common";
4
+ const getPageInfo = () => {
5
+ if (baseClientEnv.side !== "server") {
6
+ return {
7
+ locale: window.location.pathname.split("/")[1] ?? "en",
8
+ path: "/" + window.location.pathname.split("/").slice(2).join("/")
9
+ };
10
+ }
11
+ const locale = getHeader("x-locale") ?? "en";
12
+ const path = getHeader("x-path") ?? "/";
13
+ return { locale, path };
14
+ };
15
+ const langIdx = { en: 0, ko: 1, zhChs: 2, zhCht: 3 };
16
+ const dictionary = {};
17
+ const translator = (lang, key, param) => {
18
+ const idx = langIdx[lang];
19
+ try {
20
+ const msg = pathGet(key, dictionary)?.[idx];
21
+ if (!msg) {
22
+ Logger.error(`No translation for ${key}`);
23
+ return key;
24
+ }
25
+ return param ? msg.replace(/{([^}]+)}/g, (_, key2) => param[key2]) : msg;
26
+ } catch (e) {
27
+ return key;
28
+ }
29
+ };
30
+ translator.rich = (lang, key, param) => {
31
+ const idx = langIdx[lang];
32
+ const msg = pathGet(key, dictionary)?.[idx];
33
+ if (!msg) {
34
+ Logger.error(`No translation for ${key}`);
35
+ return key;
36
+ }
37
+ return param ? msg.replace(/{([^}]+)}/g, (_, key2) => param[key2]) : msg;
38
+ };
39
+ const makePageProto = (locales) => {
40
+ locales.forEach((locale) => {
41
+ Object.keys(locale).forEach((key) => dictionary[key] = Object.assign(dictionary[key] ?? {}, locale[key]));
42
+ });
43
+ return () => {
44
+ const { locale, path } = getPageInfo();
45
+ const lang = locale;
46
+ const l = (key, param) => translator(lang, key, param);
47
+ l.rich = (key, param) => /* @__PURE__ */ React.createElement(
48
+ "span",
49
+ {
50
+ dangerouslySetInnerHTML: {
51
+ __html: translator.rich(lang, key, {
52
+ ...param,
53
+ // strong: (chunks: string) => `<b>${chunks}</b>`,
54
+ // "bg-primary": (chunks: string) => `<span className="bg-primary text-base-100">${chunks}</span>`,
55
+ // primary: (chunks: string) => `<span className="bg-base-100 text-primary">${chunks}</span>`,
56
+ br: `<br />`
57
+ })
58
+ }
59
+ }
60
+ );
61
+ l.field = (model, field) => {
62
+ const key = `${model}.${field}`;
63
+ return l(key);
64
+ };
65
+ l.desc = (model, field) => {
66
+ const key = `${model}.desc-${field}`;
67
+ return l(key);
68
+ };
69
+ l.enum = (model, field, value) => {
70
+ const key = `${model}.enum-${field}-${value}`;
71
+ return l(key);
72
+ };
73
+ l.enumdesc = (model, field, value) => {
74
+ const key = `${model}.enumdesc-${field}-${value}`;
75
+ return l(key);
76
+ };
77
+ l.api = (model, endpoint) => {
78
+ const key = `${model}.api-${endpoint}`;
79
+ return l(key);
80
+ };
81
+ l.apidesc = (model, endpoint) => {
82
+ const key = `${model}.apidesc-${endpoint}`;
83
+ return l(key);
84
+ };
85
+ l.arg = (model, endpoint, arg) => {
86
+ const key = `${model}.arg-${endpoint}-${arg}`;
87
+ return l(key);
88
+ };
89
+ l.argdesc = (model, endpoint, arg) => {
90
+ const key = `${model}.argdesc-${endpoint}-${arg}`;
91
+ return l(key);
92
+ };
93
+ l.qry = (model, queryKey) => {
94
+ const key = `${model}.qry-${queryKey}`;
95
+ return l(key);
96
+ };
97
+ l.qrydesc = (model, queryKey) => {
98
+ const key = `${model}.qrydesc-${queryKey}`;
99
+ return l(key);
100
+ };
101
+ l.qarg = (model, queryKey, arg) => {
102
+ const key = `${model}.qarg-${queryKey}-${arg}`;
103
+ return l(key);
104
+ };
105
+ l.qargdesc = (model, queryKey, arg) => {
106
+ const key = `${model}.qargdesc-${queryKey}-${arg}`;
107
+ return l(key);
108
+ };
109
+ return { path, l, lang };
110
+ };
111
+ };
112
+ export {
113
+ makePageProto
114
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akanjs/next",
3
- "version": "0.0.53",
3
+ "version": "0.0.55",
4
4
  "type": "commonjs",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -32,5 +32,11 @@
32
32
  "next": "^15.3.2",
33
33
  "react": "^18.3.1",
34
34
  "react-dom": "^18.3.1"
35
+ },
36
+ "exports": {
37
+ ".": {
38
+ "require": "./index.js",
39
+ "import": "./index.mjs"
40
+ }
35
41
  }
36
42
  }
package/types.mjs ADDED
File without changes
package/useCamera.mjs ADDED
@@ -0,0 +1,77 @@
1
+ "use client";
2
+ import { device } from "@akanjs/client";
3
+ import { Camera, CameraResultType, CameraSource } from "@capacitor/camera";
4
+ import { useEffect, useState } from "react";
5
+ const useCamera = () => {
6
+ const [permissions, setPermissions] = useState({ camera: "prompt", photos: "prompt" });
7
+ const checkPermission = async (type) => {
8
+ try {
9
+ if (type === "photos") {
10
+ if (permissions.photos === "prompt") {
11
+ const { photos } = await Camera.requestPermissions();
12
+ setPermissions((prev) => ({ ...prev, photos }));
13
+ } else if (permissions.photos === "denied") {
14
+ location.assign("app-settings:");
15
+ return;
16
+ }
17
+ } else if (type === "camera") {
18
+ if (permissions.camera === "prompt") {
19
+ const { camera } = await Camera.requestPermissions();
20
+ setPermissions((prev) => ({ ...prev, camera }));
21
+ } else if (permissions.camera === "denied") {
22
+ location.assign("app-settings:");
23
+ return;
24
+ }
25
+ } else {
26
+ if (permissions.camera === "prompt" || permissions.photos === "prompt") {
27
+ const permissions2 = await Camera.requestPermissions();
28
+ setPermissions(permissions2);
29
+ } else if (permissions.camera === "denied" || permissions.photos === "denied") {
30
+ location.assign("app-settings:");
31
+ return;
32
+ }
33
+ }
34
+ } catch (e) {
35
+ }
36
+ };
37
+ const getPhoto = async (src = "prompt") => {
38
+ const source = device.info.platform !== "web" ? src === "prompt" ? CameraSource.Prompt : src === "camera" ? CameraSource.Camera : CameraSource.Photos : CameraSource.Photos;
39
+ const permission = src === "prompt" ? "all" : src === "camera" ? "camera" : "photos";
40
+ void checkPermission(permission);
41
+ try {
42
+ const photo = await Camera.getPhoto({
43
+ quality: 100,
44
+ source,
45
+ allowEditing: false,
46
+ resultType: CameraResultType.DataUrl,
47
+ promptLabelHeader: "\uD504\uB85C\uD544 \uC0AC\uC9C4\uC744 \uC62C\uB824\uC8FC\uC138\uC694",
48
+ promptLabelPhoto: "\uC568\uBC94\uC5D0\uC11C \uC120\uD0DD\uD558\uAE30",
49
+ promptLabelPicture: "\uC0AC\uC9C4 \uCC0D\uAE30",
50
+ promptLabelCancel: "\uCDE8\uC18C"
51
+ });
52
+ return photo;
53
+ } catch (e) {
54
+ if (e === "User cancelled photos app")
55
+ return;
56
+ }
57
+ };
58
+ const pickImage = async () => {
59
+ void checkPermission("photos");
60
+ const photo = await Camera.pickImages({
61
+ quality: 90
62
+ });
63
+ return photo;
64
+ };
65
+ useEffect(() => {
66
+ void (async () => {
67
+ if (device.info.platform !== "web") {
68
+ const permissions2 = await Camera.checkPermissions();
69
+ setPermissions(permissions2);
70
+ }
71
+ })();
72
+ }, []);
73
+ return { permissions, getPhoto, pickImage, checkPermission };
74
+ };
75
+ export {
76
+ useCamera
77
+ };
@@ -0,0 +1,74 @@
1
+ "use client";
2
+ import { mergeVersion, splitVersion } from "@akanjs/common";
3
+ import { App } from "@capacitor/app";
4
+ import { Device } from "@capacitor/device";
5
+ import { CapacitorUpdater } from "@capgo/capacitor-updater";
6
+ import axios from "axios";
7
+ import { useState } from "react";
8
+ const useCodepush = ({ serverUrl, branch }) => {
9
+ const [update, setUpdate] = useState(false);
10
+ const [version, setVersion] = useState("");
11
+ const initialize = async () => {
12
+ await CapacitorUpdater.notifyAppReady();
13
+ };
14
+ const checkNewRelease = async () => {
15
+ const info = await Device.getInfo();
16
+ const app = await App.getInfo();
17
+ const pluginVersion = await CapacitorUpdater.getPluginVersion();
18
+ const { deviceId } = await CapacitorUpdater.getDeviceId();
19
+ const { bundle: version2, native } = await CapacitorUpdater.current();
20
+ const builtInversion = await CapacitorUpdater.getBuiltinVersion();
21
+ const appId = app.id;
22
+ const platform = info.platform;
23
+ window.alert(
24
+ `getBuildinVersion:${builtInversion.version}
25
+ current.bundle:${version2.version}
26
+ currennt.native:${native}`
27
+ );
28
+ const { major, minor, patch } = splitVersion(version2.version === "builtin" ? app.version : version2.version);
29
+ const appName = process.env.NEXT_PUBLIC_APP_NAME ?? "";
30
+ const appInfo = {
31
+ appId,
32
+ appName,
33
+ deviceId,
34
+ platform,
35
+ branch,
36
+ isEmulator: info.isVirtual,
37
+ major: parseInt(major),
38
+ minor: parseInt(minor),
39
+ patch: parseInt(patch),
40
+ buildNum: app.build,
41
+ //앱내 빌드시 버전 횟수 모르면 고한테 물어보기
42
+ versionOs: info.osVersion
43
+ };
44
+ const url = serverUrl.replace("lu", "akasys");
45
+ const release = (await axios.post(`${url}/release/codepush`, {
46
+ data: { ...appInfo }
47
+ })).data;
48
+ if (!release)
49
+ return;
50
+ const file = (await axios.get(`${url}/file/file/${release.appBuild}`)).data;
51
+ return { release, bundleFile: file };
52
+ };
53
+ const codepush = async () => {
54
+ const isNewRelease = await checkNewRelease();
55
+ if (!isNewRelease)
56
+ return;
57
+ const { release, bundleFile } = isNewRelease;
58
+ setUpdate(true);
59
+ const bundle = await CapacitorUpdater.download({
60
+ url: bundleFile.url,
61
+ version: mergeVersion(release.major, release.minor, release.patch)
62
+ });
63
+ await CapacitorUpdater.set(bundle);
64
+ };
65
+ const getVersion = async () => {
66
+ return await CapacitorUpdater.getBuiltinVersion();
67
+ };
68
+ const statManager = async () => {
69
+ };
70
+ return { update, version, initialize, checkNewRelease, codepush, statManager };
71
+ };
72
+ export {
73
+ useCodepush
74
+ };