refactor: pwa prompt modal
This commit is contained in:
@@ -1,13 +1,14 @@
|
|||||||
// import React from "react";
|
// import React from "react";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import Modal from "../Modal";
|
import Modal from "../Modal";
|
||||||
|
import IconClose from "../../../assets/icons/close.svg";
|
||||||
import Button from "../../component/styled/Button";
|
import Button from "../../component/styled/Button";
|
||||||
|
|
||||||
const Styled = styled.div`
|
const Styled = styled.div`
|
||||||
|
position: relative;
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
width: 300px;
|
width: 406px;
|
||||||
padding: 16px 32px;
|
padding: 16px;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
box-shadow: 0px 25px 50px rgba(31, 41, 55, 0.25);
|
box-shadow: 0px 25px 50px rgba(31, 41, 55, 0.25);
|
||||||
@@ -15,42 +16,52 @@ const Styled = styled.div`
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
.tip {
|
.tip {
|
||||||
line-height: 1.4;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 5px;
|
gap: 16px;
|
||||||
color: #333;
|
color: #344054;
|
||||||
.title {
|
.title {
|
||||||
font-size: 18px;
|
font-weight: 600;
|
||||||
font-weight: bold;
|
font-size: 16px;
|
||||||
|
line-height: 24px;
|
||||||
}
|
}
|
||||||
.desc {
|
.desc {
|
||||||
font-size: 12px;
|
font-weight: 400;
|
||||||
color: #666;
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.btns {
|
.btns {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
gap: 12px;
|
gap: 16px;
|
||||||
|
}
|
||||||
|
.close {
|
||||||
|
cursor: pointer;
|
||||||
|
position: absolute;
|
||||||
|
top: 16px;
|
||||||
|
right: 16px;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
export default function Prompt({ handleInstall, closePrompt }) {
|
export default function Prompt({ handleInstall, closePrompt }) {
|
||||||
return (
|
return (
|
||||||
<Modal mask={false}>
|
<Modal mask={false}>
|
||||||
<Styled>
|
<Styled>
|
||||||
|
<IconClose className="close" onClick={closePrompt} />
|
||||||
<div className="tip">
|
<div className="tip">
|
||||||
<h2 className="title">Add this Web APP</h2>
|
<h2 className="title">Install web app on desktop?</h2>
|
||||||
<p className="desc">Add to your PC and open like native APP</p>
|
<p className="desc">
|
||||||
|
Put it on your desktop for quick access to apps.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="btns">
|
<div className="btns">
|
||||||
|
<Button className="ghost cancel small" onClick={closePrompt}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
<Button className="main small" onClick={handleInstall}>
|
<Button className="main small" onClick={handleInstall}>
|
||||||
Install
|
Install
|
||||||
</Button>
|
</Button>
|
||||||
<Button className="ghost small" onClick={closePrompt}>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</Styled>
|
</Styled>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ import { useEffect, useState, useRef } from "react";
|
|||||||
// import { useGetServerQuery } from "../../../app/services/server";
|
// import { useGetServerQuery } from "../../../app/services/server";
|
||||||
// import manifest from "./manifest.json";
|
// import manifest from "./manifest.json";
|
||||||
import Prompt from "./Prompt";
|
import Prompt from "./Prompt";
|
||||||
|
import usePrompt from "./usePrompt";
|
||||||
|
|
||||||
export default function Manifest() {
|
export default function Manifest() {
|
||||||
|
const { setCanneled } = usePrompt();
|
||||||
const deferredPromptRef = useRef(null);
|
const deferredPromptRef = useRef(null);
|
||||||
const [popup, setPopup] = useState(false);
|
const [popup, setPopup] = useState(false);
|
||||||
// const { data, isSuccess } = useGetServerQuery();
|
// const { data, isSuccess } = useGetServerQuery();
|
||||||
@@ -56,6 +59,7 @@ export default function Manifest() {
|
|||||||
deferredPromptRef.current = null;
|
deferredPromptRef.current = null;
|
||||||
};
|
};
|
||||||
const handleClose = async () => {
|
const handleClose = async () => {
|
||||||
|
setCanneled();
|
||||||
setPopup(false);
|
setPopup(false);
|
||||||
};
|
};
|
||||||
if (!popup) return null;
|
if (!popup) return null;
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
// import React from "react";
|
||||||
|
const Key = `RUSTCHAT_PWA_PROMPT`;
|
||||||
|
export default function usePrompt() {
|
||||||
|
const resetPrompt = () => {
|
||||||
|
localStorage.removeItem(Key);
|
||||||
|
};
|
||||||
|
const setPrompt = () => {
|
||||||
|
localStorage.setItem(Key, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
setCanneled: setPrompt,
|
||||||
|
prompted: !!localStorage.getItem(Key),
|
||||||
|
resetPrompt,
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -23,7 +23,6 @@ import SettingPage from "./setting";
|
|||||||
import SettingChannelPage from "./settingChannel";
|
import SettingChannelPage from "./settingChannel";
|
||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
import ResourceManagement from "./resources";
|
import ResourceManagement from "./resources";
|
||||||
import Manifest from "../common/component/Manifest";
|
|
||||||
|
|
||||||
const PageRoutes = () => {
|
const PageRoutes = () => {
|
||||||
const {
|
const {
|
||||||
@@ -129,7 +128,6 @@ export default function ReduxRoutes() {
|
|||||||
// };
|
// };
|
||||||
return (
|
return (
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<Manifest />
|
|
||||||
<Meta />
|
<Meta />
|
||||||
<PageRoutes />
|
<PageRoutes />
|
||||||
</Provider>
|
</Provider>
|
||||||
|
|||||||
Reference in New Issue
Block a user