refactor: usePWAInstallPrompt

This commit is contained in:
Tristan Yang
2022-07-21 22:27:59 +08:00
parent 21dd975145
commit 6427af90ef
5 changed files with 63 additions and 44 deletions
-6
View File
@@ -189,11 +189,6 @@ export const serverApi = createApi({
body: data
})
}),
getInitialized: builder.query<boolean, void>({
query: () => ({
url: `/admin/system/initialized`
})
}),
getLicense: builder.query<LicenseResponse, void>({
query: () => ({
url: `/license`
@@ -244,7 +239,6 @@ export const {
useGetThirdPartySecretQuery,
useUpdateThirdPartySecretMutation,
useCreateAdminMutation,
useGetInitializedQuery,
useUpsertLicenseMutation,
useCheckLicenseMutation,
useGetLicenseQuery
+7 -5
View File
@@ -1,6 +1,6 @@
import { FC, useState } from "react";
import styled from "styled-components";
import { NavLink } from "react-router-dom";
// import { NavLink } from "react-router-dom";
import ChannelModal from "./ChannelModal";
import InviteModal from "./InviteModal";
import IconChat from "../../assets/icons/placeholder.chat.svg";
@@ -8,6 +8,7 @@ import IconAsk from "../../assets/icons/placeholder.question.svg";
import IconInvite from "../../assets/icons/placeholder.invite.svg";
import IconDownload from "../../assets/icons/placeholder.download.svg";
import UsersModal from "./UsersModal";
import usePWAInstallPrompt from "../hook/usePWAInstallPrompt";
import { useAppSelector } from "../../app/store";
const Styled = styled.div`
@@ -72,6 +73,7 @@ interface Props {
}
const BlankPlaceholder: FC<Props> = ({ type = "chat" }) => {
const { showPrompt } = usePWAInstallPrompt();
const server = useAppSelector((store) => store.server);
const [inviteModalVisible, setInviteModalVisible] = useState(false);
const [createChannelVisible, setCreateChannelVisible] = useState(false);
@@ -108,14 +110,14 @@ const BlankPlaceholder: FC<Props> = ({ type = "chat" }) => {
<IconChat className="icon" />
<div className="txt">{chatTip}</div>
</div>
<a className="box" href="#">
<button className="box" onClick={showPrompt}>
<IconDownload className="icon" />
<div className="txt">Download PC and Mobile apps</div>
</a>
<NavLink to={"#"} className="box">
</button>
<a href={"https://voce.chat"} target={"_blank"} rel="noreferrer" className="box">
<IconAsk className="icon" />
<div className="txt">Got questions? Visit our help center </div>
</NavLink>
</a>
</div>
</Styled>
{createChannelVisible && (
+7 -16
View File
@@ -1,25 +1,24 @@
import { useEffect, useState, useRef, FC } from "react";
import { BeforeInstallPromptEvent } from "../../../types/global";
import { useEffect, useState, FC } from "react";
import Prompt from "./Prompt";
import usePrompt from "./usePrompt";
import usePWAInstallPrompt from "../../hook/usePWAInstallPrompt";
import { BeforeInstallPromptEvent } from "../../../types/global";
interface IProps {}
const Manifest: FC<IProps> = () => {
const { setCanceled: setCanceled, prompted } = usePrompt();
const deferredPromptRef = useRef<null | BeforeInstallPromptEvent>(null);
const { setCanceled, prompted, setDeferredPrompt, showPrompt } = usePWAInstallPrompt();
const [popup, setPopup] = useState(false);
useEffect(() => {
const handleInstallPromotion = (e: BeforeInstallPromptEvent) => {
// Prevent the mini-infobar from appearing on mobile
e.preventDefault();
// Stash the event so it can be triggered later.
deferredPromptRef.current = e;
setDeferredPrompt(e);
// Update UI notify the user they can install the PWA
setPopup(true);
// Optionally, send analytics event that PWA install promo was shown.
console.log(`'beforeinstallprompt' event was fired.`);
};
const handleInstalled = () => {
deferredPromptRef.current = null;
setDeferredPrompt(null);
setPopup(false);
};
window.addEventListener("beforeinstallprompt", handleInstallPromotion, true);
@@ -32,15 +31,7 @@ const Manifest: FC<IProps> = () => {
const handleInstall = async () => {
// Hide the app provided install promotion
setPopup(false);
if (!deferredPromptRef.current) return;
// Show the install prompt
deferredPromptRef.current.prompt();
// Wait for the user to respond to the prompt
const { outcome } = await deferredPromptRef.current.userChoice;
// Optionally, send analytics event with outcome of user choice
console.log(`User response to the install prompt: ${outcome}`);
// We've used the prompt, and can't use it again, throw it away
deferredPromptRef.current = null;
await showPrompt();
};
const handleClose = async () => {
setCanceled();
@@ -1,17 +0,0 @@
// import React from "react";
import { KEY_PWA_INSTALLED } from "../../../app/config";
export default function usePrompt() {
const resetPrompt = () => {
localStorage.removeItem(KEY_PWA_INSTALLED);
};
const setPrompt = () => {
localStorage.setItem(KEY_PWA_INSTALLED, "true");
};
return {
setCanceled: setPrompt,
prompted: !!localStorage.getItem(KEY_PWA_INSTALLED),
resetPrompt
};
}
+49
View File
@@ -0,0 +1,49 @@
import { useRef, useEffect } from "react";
import { KEY_PWA_INSTALLED } from "../../app/config";
import { BeforeInstallPromptEvent } from "../../types/global";
export default function usePWAInstallPrompt() {
const deferredPromptRef = useRef<null | BeforeInstallPromptEvent>(null);
const resetPrompt = () => {
localStorage.removeItem(KEY_PWA_INSTALLED);
deferredPromptRef.current = null;
};
const setPrompt = () => {
localStorage.setItem(KEY_PWA_INSTALLED, "true");
};
const setDeferredPrompt = (p: BeforeInstallPromptEvent | null) => {
deferredPromptRef.current = p;
};
const showPrompt = async () => {
if (!deferredPromptRef.current) return;
// Show the install prompt
deferredPromptRef.current.prompt();
// Wait for the user to respond to the prompt
const { outcome } = await deferredPromptRef.current.userChoice;
// Optionally, send analytics event with outcome of user choice
console.log(`User response to the install prompt: ${outcome}`);
// We've used the prompt, and can't use it again, throw it away
setDeferredPrompt(null);
};
useEffect(() => {
const handleInstallPromotion = (e: BeforeInstallPromptEvent) => {
// Prevent the mini-infobar from appearing on mobile
e.preventDefault();
// Stash the event so it can be triggered later.
setDeferredPrompt(e);
};
window.addEventListener("beforeinstallprompt", handleInstallPromotion, true);
return () => {
window.removeEventListener("beforeinstallprompt", handleInstallPromotion, true);
};
}, []);
return {
setCanceled: setPrompt,
prompted: !!localStorage.getItem(KEY_PWA_INSTALLED),
resetPrompt,
deferredPrompt: deferredPromptRef.current,
setDeferredPrompt,
showPrompt
};
}