@vetc-miniapp/ui-react 0.0.11 → 0.0.13
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 +85 -8
- package/package.json +1 -1
- package/src/dist/ui-react/index.js +1 -1
- package/src/dist/ui-react/index.js.LICENSE.txt +2 -0
- package/src/ui-react/hooks/use-app-pause.js +35 -0
- package/src/ui-react/hooks/use-app-pause.ts +33 -0
- package/src/ui-react/hooks/use-app-resume.js +38 -0
- package/src/ui-react/hooks/use-app-resume.ts +32 -0
- package/src/ui-react/hooks/use-did-hide.js +25 -0
- package/src/ui-react/hooks/use-did-hide.ts +34 -0
- package/src/ui-react/hooks/use-did-show.js +25 -0
- package/src/ui-react/hooks/use-did-show.ts +34 -0
- package/src/ui-react/index.js +4 -0
- package/src/ui-react/index.ts +4 -0
package/README.md
CHANGED
|
@@ -5,21 +5,98 @@ SDK giúp Mini App giao tiếp với Super App host thông qua JS Bridge.
|
|
|
5
5
|
## Cài đặt
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install @
|
|
8
|
+
npm install @vetc-miniapp/ui-react
|
|
9
9
|
```
|
|
10
10
|
## Sử dụng
|
|
11
|
+
# useNavigate – Điều hướng Mini App qua Native (Flutter)
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
`useNavigate` là hook dùng trong **mini app React** để điều hướng **thông qua host app (Flutter)**, thay vì tự điều hướng nội bộ bằng `react-router-dom`.
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
Hook này giúp:
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
- Mini app **không phụ thuộc URL thực**
|
|
18
|
+
- Toàn bộ navigation được **native kiểm soát**
|
|
19
|
+
- **Đồng bộ header, back stack, animation** giữa mini app & app chính
|
|
17
20
|
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 📦 Import
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { useNavigate } from '@vetc-miniapp/ui-react';
|
|
27
|
+
|
|
28
|
+
const navigate = useNavigate();
|
|
29
|
+
|
|
30
|
+
navigate(
|
|
31
|
+
path: string,
|
|
32
|
+
title: string,
|
|
33
|
+
params?: Record<string, any>,
|
|
34
|
+
options?: {
|
|
35
|
+
replace?: boolean;
|
|
36
|
+
popTo?: string;
|
|
37
|
+
}
|
|
38
|
+
): void
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## 🚀 Cách sử dụng cơ bản
|
|
43
|
+
# Điều hướng sang page khác
|
|
44
|
+
```ts
|
|
45
|
+
const navigate = useNavigate();
|
|
46
|
+
|
|
47
|
+
<button onClick={() => navigate('/about', { title: "About", params: {}})}>
|
|
48
|
+
Go to About
|
|
49
|
+
</button>
|
|
50
|
+
|
|
51
|
+
Truyền params
|
|
52
|
+
navigate('/vehicle-detail', {
|
|
53
|
+
title: "About",
|
|
54
|
+
params: {
|
|
55
|
+
id: 'abc123',
|
|
56
|
+
source: 'homepage',
|
|
57
|
+
}
|
|
20
58
|
});
|
|
59
|
+
```
|
|
21
60
|
|
|
22
|
-
|
|
23
|
-
npm publish --access public
|
|
61
|
+
# ➡ Flutter sẽ nhận được URL dạng:
|
|
24
62
|
|
|
63
|
+
/miniapp/vehicle-detail?id=abc123&source=homepage
|
|
25
64
|
|
|
65
|
+
## 🔁 Replace route (không giữ back stack)
|
|
66
|
+
```
|
|
67
|
+
navigate('/login', { mode: 'replace' });
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
navigate('/home', { popTo: '/home' });
|
|
71
|
+
```
|
|
72
|
+
## 🧩 Ví dụ đầy đủ trong Component
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
import { useNavigate } from '@vetc-miniapp/ui-react';
|
|
76
|
+
|
|
77
|
+
function VehicleItem({ vehicle }) {
|
|
78
|
+
const navigate = useNavigate();
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<div onClick={() => navigate('/vehicle-detail', { title: "Chi tiết xe"}, { mode: "replace" })}>
|
|
82
|
+
{vehicle.name}
|
|
83
|
+
</div>
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## ⚠️ Lưu ý quan trọng
|
|
89
|
+
# ❌ Không dùng react-router-dom
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
// KHÔNG dùng
|
|
93
|
+
import { useNavigate } from 'react-router-dom';
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
Mini app không quản lý history nội bộ.
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
# ❌ Không dùng window.location
|
|
100
|
+
```
|
|
101
|
+
window.location.href = '/about'; // ❌
|
|
102
|
+
```
|
package/package.json
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! For license information please see index.js.LICENSE.txt */
|
|
2
|
-
!function(e,
|
|
2
|
+
!function(e,n){"object"==typeof exports&&"object"==typeof module?module.exports=n(require("react")):"function"==typeof define&&define.amd?define(["react"],n):"object"==typeof exports?exports["vetc-miniapp/ui-react"]=n(require("react")):e["vetc-miniapp/ui-react"]=n(e.react)}(this,e=>(()=>{"use strict";var n={155(n){n.exports=e},698(e,n){var r=Symbol.for("react.transitional.element"),t=Symbol.for("react.fragment");function o(e,n,t){var o=null;if(void 0!==t&&(o=""+t),void 0!==n.key&&(o=""+n.key),"key"in n)for(var i in t={},n)"key"!==i&&(t[i]=n[i]);else t=n;return n=t.ref,{$$typeof:r,type:e,key:o,ref:void 0!==n?n:null,props:t}}n.Fragment=t,n.jsx=o,n.jsxs=o},848(e,n,r){e.exports=r(698)}},r={};function t(e){var o=r[e];if(void 0!==o)return o.exports;var i=r[e]={exports:{}};return n[e](i,i.exports,t),i.exports}t.n=e=>{var n=e&&e.__esModule?()=>e.default:()=>e;return t.d(n,{a:n}),n},t.d=(e,n)=>{for(var r in n)t.o(n,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:n[r]})},t.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n),t.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var o={};t.r(o),t.d(o,{App:()=>O,appConfig:()=>m,getCurrentPage:()=>S,initRouter:()=>M,setCurrentPath:()=>x,useAppPause:()=>a,useAppResume:()=>c,useDidHide:()=>p,useDidShow:()=>f,useNavigate:()=>g});var i=t(155),u=t.n(i);function a(e){var n=(0,i.useRef)(e);(0,i.useEffect)(function(){n.current=e},[e]),(0,i.useEffect)(function(){if("undefined"!=typeof window&&window.MiniApp){var e=function(){try{n.current&&n.current()}catch(e){console.error("[useAppPause error]",e)}};return window.MiniApp.on("appPause",e),function(){window.MiniApp.off("appPause",e)}}},[])}function c(e){var n=(0,i.useRef)(e);(0,i.useEffect)(function(){n.current=e},[e]),(0,i.useEffect)(function(){if(console.warn("MiniApp: useAppResume"),console.warn(window.MiniApp),"undefined"!=typeof window&&window.MiniApp){var e=function(){try{n.current&&n.current()}catch(e){console.error("[useAppResume error]",e)}};return window.MiniApp.on("appResume",e),function(){window.MiniApp.off("appResume",e)}}},[])}function f(e,n){var r=(0,i.useRef)(n);(0,i.useEffect)(function(){r.current=n},[n]),(0,i.useEffect)(function(){if(window.MiniApp){var n=function(n){var t;(null==n?void 0:n.pathname)===e&&(null===(t=r.current)||void 0===t||t.call(r,n))};return window.MiniApp.on("didShow",n),function(){window.MiniApp.off("didShow",n)}}},[e])}function p(e,n){var r=(0,i.useRef)(n);(0,i.useEffect)(function(){r.current=n},[n]),(0,i.useEffect)(function(){if(window.MiniApp){var n=function(n){var t;(null==n?void 0:n.pathname)===e&&(null===(t=r.current)||void 0===t||t.call(r,n))};return window.MiniApp.on("didHide",n),function(){window.MiniApp.off("didHide",n)}}},[e])}function l(){var e,n,r="function"==typeof Symbol?Symbol:{},t=r.iterator||"@@iterator",o=r.toStringTag||"@@toStringTag";function i(r,t,o,i){var c=t&&t.prototype instanceof a?t:a,f=Object.create(c.prototype);return s(f,"_invoke",function(r,t,o){var i,a,c,f=0,p=o||[],l=!1,s={p:0,n:0,v:e,a:d,f:d.bind(e,4),d:function(n,r){return i=n,a=0,c=e,s.n=r,u}};function d(r,t){for(a=r,c=t,n=0;!l&&f&&!o&&n<p.length;n++){var o,i=p[n],d=s.p,v=i[2];r>3?(o=v===t)&&(c=i[(a=i[4])?5:(a=3,3)],i[4]=i[5]=e):i[0]<=d&&((o=r<2&&d<i[1])?(a=0,s.v=t,s.n=i[1]):d<v&&(o=r<3||i[0]>t||t>v)&&(i[4]=r,i[5]=t,s.n=v,a=0))}if(o||r>1)return u;throw l=!0,t}return function(o,p,v){if(f>1)throw TypeError("Generator is already running");for(l&&1===p&&d(p,v),a=p,c=v;(n=a<2?e:c)||!l;){i||(a?a<3?(a>1&&(s.n=-1),d(a,c)):s.n=c:s.v=c);try{if(f=2,i){if(a||(o="next"),n=i[o]){if(!(n=n.call(i,c)))throw TypeError("iterator result is not an object");if(!n.done)return n;c=n.value,a<2&&(a=0)}else 1===a&&(n=i.return)&&n.call(i),a<2&&(c=TypeError("The iterator does not provide a '"+o+"' method"),a=1);i=e}else if((n=(l=s.n<0)?c:r.call(t,s))!==u)break}catch(n){i=e,a=1,c=n}finally{f=1}}return{value:n,done:l}}}(r,o,i),!0),f}var u={};function a(){}function c(){}function f(){}n=Object.getPrototypeOf;var p=[][t]?n(n([][t]())):(s(n={},t,function(){return this}),n),d=f.prototype=a.prototype=Object.create(p);function v(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,f):(e.__proto__=f,s(e,o,"GeneratorFunction")),e.prototype=Object.create(d),e}return c.prototype=f,s(d,"constructor",f),s(f,"constructor",c),c.displayName="GeneratorFunction",s(f,o,"GeneratorFunction"),s(d),s(d,o,"Generator"),s(d,t,function(){return this}),s(d,"toString",function(){return"[object Generator]"}),(l=function(){return{w:i,m:v}})()}function s(e,n,r,t){var o=Object.defineProperty;try{o({},"",{})}catch(e){o=0}s=function(e,n,r,t){function i(n,r){s(e,n,function(e){return this._invoke(n,r,e)})}n?o?o(e,n,{value:r,enumerable:!t,configurable:!t,writable:!t}):e[n]=r:(i("next",0),i("throw",1),i("return",2))},s(e,n,r,t)}function d(e,n,r,t,o,i,u){try{var a=e[i](u),c=a.value}catch(e){return void r(e)}a.done?n(c):Promise.resolve(c).then(t,o)}var v="undefined"!=typeof window,y=function(){return v&&window.flutter_inappwebview?window.flutter_inappwebview:null},w=function(){var e,n=(e=l().m(function e(n){var r,t,o,i,u=arguments;return l().w(function(e){for(;;)switch(e.p=e.n){case 0:if(r=u.length>1&&void 0!==u[1]?u[1]:{},t=y()){e.n=1;break}return e.a(2,Promise.reject(new Error("MiniApp bridge not available")));case 1:return e.p=1,e.n=2,t.callHandler("MiniAppBridge",{action:n,payload:r});case 2:return o=e.v,e.a(2,o);case 3:throw e.p=3,i=e.v,console.error("Bridge error:",i),i;case 4:return e.a(2)}},e,null,[[1,3]])}),function(){var n=this,r=arguments;return new Promise(function(t,o){var i=e.apply(n,r);function u(e){d(i,t,o,u,a,"next",e)}function a(e){d(i,t,o,u,a,"throw",e)}u(void 0)})});return function(e){return n.apply(this,arguments)}}();function g(){return function(e){w("navigate",{type:"native",route:e,params:arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},options:arguments.length>2&&void 0!==arguments[2]?arguments[2]:{}})}}var m={locale:"vi",theme:"light",pages:[]},h=t(848);function b(e,n){(null==n||n>e.length)&&(n=e.length);for(var r=0,t=Array(n);r<n;r++)t[r]=e[r];return t}var A=new Map,j="/";function M(e){console.log(e),A=new Map(e.pages.map(function(e){return[e.path,e]})),console.log(A)}function S(){return A.get(j)}function x(e){j=e}function O(e){var n,r,t=e.config,o=e.children,u=(n=(0,i.useState)(null),r=2,function(e){if(Array.isArray(e))return e}(n)||function(e,n){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var t,o,i,u,a=[],c=!0,f=!1;try{if(i=(r=r.call(e)).next,0===n){if(Object(r)!==r)return;c=!1}else for(;!(c=(t=i.call(r)).done)&&(a.push(t.value),a.length!==n);c=!0);}catch(e){f=!0,o=e}finally{try{if(!c&&null!=r.return&&(u=r.return(),Object(u)!==u))return}finally{if(f)throw o}}return a}}(n,r)||function(e,n){if(e){if("string"==typeof e)return b(e,n);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?b(e,n):void 0}}(n,r)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),a=u[0],c=u[1];if((0,i.useEffect)(function(){var e;if(null!=t&&null!==(e=t.pages)&&void 0!==e&&e.length){M(t);var n=window.location.pathname||"/",r=n.replace("/miniapp","")||"/";console.log(n),x(r);var o=S();console.warn(o),o||(x("/"),o=S()),c(o),w("registerAppConfig",{config:t})}},[t]),!a||!a.Component)return console.warn("MiniApp: Page not found for current route"),(0,h.jsx)(h.Fragment,{children:(0,h.jsx)("div",{})});var f=a.Component||(0,h.jsx)("div",{});return(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(f,{}),o]})}return console.log("SDK React object:",u()),o})());
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* useAppPause
|
|
5
|
+
*
|
|
6
|
+
* Trigger khi Native App đi vào background.
|
|
7
|
+
*/
|
|
8
|
+
export function useAppPause(callback) {
|
|
9
|
+
const savedCallback = useRef(callback);
|
|
10
|
+
|
|
11
|
+
// Luôn giữ callback mới nhất
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
savedCallback.current = callback;
|
|
14
|
+
}, [callback]);
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (typeof window === "undefined" || !window.MiniApp) return;
|
|
18
|
+
|
|
19
|
+
const handler = () => {
|
|
20
|
+
try {
|
|
21
|
+
if (savedCallback.current) {
|
|
22
|
+
savedCallback.current();
|
|
23
|
+
}
|
|
24
|
+
} catch (err) {
|
|
25
|
+
console.error("[useAppPause error]", err);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
window.MiniApp.on("appPause", handler);
|
|
30
|
+
|
|
31
|
+
return () => {
|
|
32
|
+
window.MiniApp.off("appPause", handler);
|
|
33
|
+
};
|
|
34
|
+
}, []);
|
|
35
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* useAppPause
|
|
5
|
+
*
|
|
6
|
+
* Trigger khi Native App đi vào background.
|
|
7
|
+
*/
|
|
8
|
+
export function useAppPause(callback: () => void) {
|
|
9
|
+
const savedCallback = useRef(callback);
|
|
10
|
+
|
|
11
|
+
// giữ callback luôn mới nhất
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
savedCallback.current = callback;
|
|
14
|
+
}, [callback]);
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (typeof window === "undefined" || !window.MiniApp) return;
|
|
18
|
+
|
|
19
|
+
const handler = () => {
|
|
20
|
+
try {
|
|
21
|
+
savedCallback.current?.();
|
|
22
|
+
} catch (err) {
|
|
23
|
+
console.error("[useAppPause error]", err);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
window.MiniApp.on("appPause", handler);
|
|
28
|
+
|
|
29
|
+
return () => {
|
|
30
|
+
window.MiniApp.off("appPause", handler);
|
|
31
|
+
};
|
|
32
|
+
}, []);
|
|
33
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* useAppResume
|
|
5
|
+
*
|
|
6
|
+
* Trigger khi Native App quay lại foreground.
|
|
7
|
+
*/
|
|
8
|
+
export function useAppResume(callback) {
|
|
9
|
+
const savedCallback = useRef(callback);
|
|
10
|
+
|
|
11
|
+
// Cập nhật callback mới nhất
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
savedCallback.current = callback;
|
|
14
|
+
}, [callback]);
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
console.warn("MiniApp: useAppResume");
|
|
18
|
+
console.warn(window.MiniApp);
|
|
19
|
+
|
|
20
|
+
if (typeof window === "undefined" || !window.MiniApp) return;
|
|
21
|
+
|
|
22
|
+
const handler = () => {
|
|
23
|
+
try {
|
|
24
|
+
if (savedCallback.current) {
|
|
25
|
+
savedCallback.current();
|
|
26
|
+
}
|
|
27
|
+
} catch (err) {
|
|
28
|
+
console.error("[useAppResume error]", err);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
window.MiniApp.on("appResume", handler);
|
|
33
|
+
|
|
34
|
+
return () => {
|
|
35
|
+
window.MiniApp.off("appResume", handler);
|
|
36
|
+
};
|
|
37
|
+
}, []);
|
|
38
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* useAppResume
|
|
5
|
+
*
|
|
6
|
+
* Trigger khi Native App quay lại foreground.
|
|
7
|
+
*/
|
|
8
|
+
export function useAppResume(callback: () => void) {
|
|
9
|
+
const savedCallback = useRef(callback);
|
|
10
|
+
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
savedCallback.current = callback;
|
|
13
|
+
}, [callback]);
|
|
14
|
+
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
if (typeof window === "undefined" || !window.MiniApp) return;
|
|
17
|
+
|
|
18
|
+
const handler = () => {
|
|
19
|
+
try {
|
|
20
|
+
savedCallback.current?.();
|
|
21
|
+
} catch (err) {
|
|
22
|
+
console.error("[useAppResume error]", err);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
window.MiniApp.on("appResume", handler);
|
|
27
|
+
|
|
28
|
+
return () => {
|
|
29
|
+
window.MiniApp.off("appResume", handler);
|
|
30
|
+
};
|
|
31
|
+
}, []);
|
|
32
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
2
|
+
|
|
3
|
+
export function useDidHide(pathname, callback) {
|
|
4
|
+
const saved = useRef(callback);
|
|
5
|
+
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
saved.current = callback;
|
|
8
|
+
}, [callback]);
|
|
9
|
+
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
if (!window.MiniApp) return;
|
|
12
|
+
|
|
13
|
+
const handler = (data) => {
|
|
14
|
+
if (data?.pathname === pathname) {
|
|
15
|
+
saved.current?.(data);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
window.MiniApp.on("didHide", handler);
|
|
20
|
+
|
|
21
|
+
return () => {
|
|
22
|
+
window.MiniApp.off("didHide", handler);
|
|
23
|
+
};
|
|
24
|
+
}, [pathname]);
|
|
25
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
2
|
+
|
|
3
|
+
type DidHidePayload = {
|
|
4
|
+
pathname?: string;
|
|
5
|
+
[key: string]: any;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export function useDidHide(
|
|
9
|
+
pathname: string,
|
|
10
|
+
callback: (data?: DidHidePayload) => void
|
|
11
|
+
): void {
|
|
12
|
+
const saved = useRef(callback);
|
|
13
|
+
|
|
14
|
+
// luôn giữ callback mới nhất
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
saved.current = callback;
|
|
17
|
+
}, [callback]);
|
|
18
|
+
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (typeof window === "undefined" || !window.MiniApp) return;
|
|
21
|
+
|
|
22
|
+
const handler = (data?: DidHidePayload) => {
|
|
23
|
+
if (data?.pathname === pathname) {
|
|
24
|
+
saved.current?.(data);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
window.MiniApp.on("didHide", handler);
|
|
29
|
+
|
|
30
|
+
return () => {
|
|
31
|
+
window.MiniApp.off("didHide", handler);
|
|
32
|
+
};
|
|
33
|
+
}, [pathname]);
|
|
34
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
2
|
+
|
|
3
|
+
export function useDidShow(pathname, callback) {
|
|
4
|
+
const saved = useRef(callback);
|
|
5
|
+
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
saved.current = callback;
|
|
8
|
+
}, [callback]);
|
|
9
|
+
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
if (!window.MiniApp) return;
|
|
12
|
+
|
|
13
|
+
const handler = (data) => {
|
|
14
|
+
if (data?.pathname === pathname) {
|
|
15
|
+
saved.current?.(data);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
window.MiniApp.on("didShow", handler);
|
|
20
|
+
|
|
21
|
+
return () => {
|
|
22
|
+
window.MiniApp.off("didShow", handler);
|
|
23
|
+
};
|
|
24
|
+
}, [pathname]);
|
|
25
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
2
|
+
|
|
3
|
+
type DidShowPayload = {
|
|
4
|
+
pathname?: string;
|
|
5
|
+
[key: string]: any;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export function useDidShow(
|
|
9
|
+
pathname: string,
|
|
10
|
+
callback: (data?: DidShowPayload) => void
|
|
11
|
+
): void {
|
|
12
|
+
const saved = useRef(callback);
|
|
13
|
+
|
|
14
|
+
// luôn giữ callback mới nhất
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
saved.current = callback;
|
|
17
|
+
}, [callback]);
|
|
18
|
+
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (typeof window === "undefined" || !window.MiniApp) return;
|
|
21
|
+
|
|
22
|
+
const handler = (data?: DidShowPayload) => {
|
|
23
|
+
if (data?.pathname === pathname) {
|
|
24
|
+
saved.current?.(data);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
window.MiniApp.on("didShow", handler);
|
|
29
|
+
|
|
30
|
+
return () => {
|
|
31
|
+
window.MiniApp.off("didShow", handler);
|
|
32
|
+
};
|
|
33
|
+
}, [pathname]);
|
|
34
|
+
}
|
package/src/ui-react/index.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
export * from './hooks/use-app-pause.js';
|
|
2
|
+
export * from './hooks/use-app-resume.js';
|
|
3
|
+
export * from './hooks/use-did-show.js';
|
|
4
|
+
export * from './hooks/use-did-hide.js';
|
|
1
5
|
export * from './hooks/use-navigate.js';
|
|
2
6
|
export * from './hooks/use-app-state.js';
|
|
3
7
|
export * from './components/app.jsx';
|
package/src/ui-react/index.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
export * from './hooks/use-app-resume';
|
|
2
|
+
export * from './hooks/use-app-pause';
|
|
3
|
+
export * from './hooks/use-did-show';
|
|
4
|
+
export * from './hooks/use-did-hide';
|
|
1
5
|
export * from './hooks/use-navigate';
|
|
2
6
|
export * from './hooks/use-app-state';
|
|
3
7
|
// export * from './components/app';
|