mirror of
https://github.com/Qortal/qortal-mobile.git
synced 2025-04-24 20:07:52 +00:00
updated pwa
This commit is contained in:
parent
299a42ca99
commit
2c006c12f9
@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
|
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.ico" />
|
<link rel="icon" type="image/svg+xml" href="/favicon.ico" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, interactive-widget=resizes-content">
|
||||||
|
|
||||||
|
|
||||||
<title>Qortal Go</title>
|
<title>Qortal Go</title>
|
||||||
|
@ -147,6 +147,7 @@ import { useBlockedAddresses } from "./components/Chat/useBlockUsers";
|
|||||||
import { UserLookup } from "./components/UserLookup.tsx/UserLookup";
|
import { UserLookup } from "./components/UserLookup.tsx/UserLookup";
|
||||||
import { RegisterName } from "./components/RegisterName";
|
import { RegisterName } from "./components/RegisterName";
|
||||||
import { BuyQortInformation } from "./components/BuyQortInformation";
|
import { BuyQortInformation } from "./components/BuyQortInformation";
|
||||||
|
import { InstallPWA } from "./components/InstallPWA";
|
||||||
|
|
||||||
|
|
||||||
type extStates =
|
type extStates =
|
||||||
@ -1839,6 +1840,13 @@ function App() {
|
|||||||
backgroundRepeat: desktopViewMode === "apps" && "no-repeat",
|
backgroundRepeat: desktopViewMode === "apps" && "no-repeat",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
||||||
|
<div style={{
|
||||||
|
display: !isNative && extState === "not-authenticated" ? 'block' : 'none'
|
||||||
|
}}>
|
||||||
|
<InstallPWA />
|
||||||
|
</div>
|
||||||
|
|
||||||
<GlobalContext.Provider value={{
|
<GlobalContext.Provider value={{
|
||||||
showTutorial,
|
showTutorial,
|
||||||
openTutorialModal,
|
openTutorialModal,
|
||||||
|
@ -114,22 +114,31 @@ import { LocalNotifications } from '@capacitor/local-notifications';
|
|||||||
import { executeEvent } from "./utils/events";
|
import { executeEvent } from "./utils/events";
|
||||||
import TradeBotRespondRequest from "./transactions/TradeBotRespondRequest";
|
import TradeBotRespondRequest from "./transactions/TradeBotRespondRequest";
|
||||||
|
|
||||||
|
|
||||||
|
export const isNative = Capacitor.isNativePlatform();
|
||||||
|
|
||||||
|
|
||||||
const uid = new ShortUniqueId({ length: 9, dictionary: 'number' });
|
const uid = new ShortUniqueId({ length: 9, dictionary: 'number' });
|
||||||
|
|
||||||
const generateId = ()=> {
|
const generateId = ()=> {
|
||||||
return parseInt(uid.rnd())
|
return parseInt(uid.rnd())
|
||||||
}
|
}
|
||||||
LocalNotifications.requestPermissions().then(permission => {
|
|
||||||
if (permission.display === 'granted') {
|
|
||||||
console.log("Notifications enabled");
|
|
||||||
}
|
|
||||||
}).catch((error)=> console.error(error));
|
|
||||||
|
|
||||||
FilePicker.requestPermissions().then(permission => {
|
if(isNative){
|
||||||
if (permission?.publicStorage === 'granted') {
|
|
||||||
console.log("File access permission granted");
|
LocalNotifications.requestPermissions().then(permission => {
|
||||||
}
|
if (permission.display === 'granted') {
|
||||||
}).catch((error)=> console.error(error));;
|
console.log("Notifications enabled");
|
||||||
|
}
|
||||||
|
}).catch((error)=> console.error(error));
|
||||||
|
|
||||||
|
FilePicker.requestPermissions().then(permission => {
|
||||||
|
if (permission?.publicStorage === 'granted') {
|
||||||
|
console.log("File access permission granted");
|
||||||
|
}
|
||||||
|
}).catch((error)=> console.error(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export let groupSecretkeys = {}
|
export let groupSecretkeys = {}
|
||||||
@ -435,7 +444,6 @@ export async function performPowTaskWeb(chatBytes, difficulty) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function performPowTask(chatBytes, difficulty) {
|
export async function performPowTask(chatBytes, difficulty) {
|
||||||
const isNative = Capacitor.isNativePlatform();
|
|
||||||
const chatBytesArray = Uint8Array.from(Object.values(chatBytes));
|
const chatBytesArray = Uint8Array.from(Object.values(chatBytes));
|
||||||
const result = isNative ? await NativePOW.computeProofOfWork({ chatBytes, difficulty }) : await performPowTaskWeb(chatBytes, difficulty);
|
const result = isNative ? await NativePOW.computeProofOfWork({ chatBytes, difficulty }) : await performPowTaskWeb(chatBytes, difficulty);
|
||||||
return {nonce: result.nonce, chatBytesArray}
|
return {nonce: result.nonce, chatBytesArray}
|
||||||
@ -3375,7 +3383,9 @@ export const checkThreads = async (bringBack) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Configure Background Fetch
|
if(isNative){
|
||||||
|
|
||||||
|
// Configure Background Fetch
|
||||||
BackgroundFetch.configure({
|
BackgroundFetch.configure({
|
||||||
minimumFetchInterval: 15, // Minimum 15-minute interval
|
minimumFetchInterval: 15, // Minimum 15-minute interval
|
||||||
enableHeadless: true, // Enable headless mode for Android
|
enableHeadless: true, // Enable headless mode for Android
|
||||||
@ -3400,7 +3410,9 @@ BackgroundFetch.configure({
|
|||||||
BackgroundFetch.finish(taskId);
|
BackgroundFetch.finish(taskId);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isNative){
|
||||||
|
|
||||||
LocalNotifications.addListener('localNotificationActionPerformed', async (event) => {
|
LocalNotifications.addListener('localNotificationActionPerformed', async (event) => {
|
||||||
|
|
||||||
@ -3430,6 +3442,9 @@ LocalNotifications.addListener('localNotificationActionPerformed', async (event)
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const initializeBackButton = () => {
|
const initializeBackButton = () => {
|
||||||
|
|
||||||
@ -3443,5 +3458,6 @@ const initializeBackButton = () => {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Call this function on app startup
|
if(isNative){
|
||||||
initializeBackButton();
|
initializeBackButton();
|
||||||
|
}
|
||||||
|
64
src/components/InstallPWA.tsx
Normal file
64
src/components/InstallPWA.tsx
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import { Button } from '@mui/material';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
export const InstallPWA = () => {
|
||||||
|
const [deferredPrompt, setDeferredPrompt] = useState(null);
|
||||||
|
const [showInstallButton, setShowInstallButton] = useState(false);
|
||||||
|
const [isStandalone, setIsStandalone] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Check if app is already installed
|
||||||
|
if (window.matchMedia("(display-mode: standalone)").matches || window.navigator.standalone) {
|
||||||
|
setIsStandalone(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore install prompt if previously stored
|
||||||
|
const wasPromptAvailable = localStorage.getItem("pwaPromptAvailable");
|
||||||
|
if (wasPromptAvailable === "true") {
|
||||||
|
setShowInstallButton(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen for beforeinstallprompt event
|
||||||
|
const handleBeforeInstallPrompt = (e) => {
|
||||||
|
e.preventDefault(); // Prevent automatic prompt
|
||||||
|
setDeferredPrompt(e);
|
||||||
|
setShowInstallButton(true);
|
||||||
|
localStorage.setItem("pwaPromptAvailable", "true"); // Remember install prompt was available
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener("beforeinstallprompt", handleBeforeInstallPrompt);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener("beforeinstallprompt", handleBeforeInstallPrompt);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
const handleInstallClick = () => {
|
||||||
|
if (deferredPrompt) {
|
||||||
|
deferredPrompt.prompt();
|
||||||
|
deferredPrompt.userChoice.then((choiceResult) => {
|
||||||
|
if (choiceResult.outcome === "accepted") {
|
||||||
|
console.log("User accepted the install prompt");
|
||||||
|
localStorage.removeItem("pwaPromptAvailable"); // Remove stored prompt
|
||||||
|
setShowInstallButton(false);
|
||||||
|
} else {
|
||||||
|
console.log("User dismissed the install prompt");
|
||||||
|
setShowInstallButton(true); // Keep showing button
|
||||||
|
}
|
||||||
|
setDeferredPrompt(null);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{!isStandalone && showInstallButton && (
|
||||||
|
<Button size="small" sx={{
|
||||||
|
position: 'fixed',
|
||||||
|
top: '10px',
|
||||||
|
left: '10px'
|
||||||
|
}} variant="contained" onClick={handleInstallClick}>Install App</Button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -12,15 +12,17 @@ export default defineConfig({
|
|||||||
|
|
||||||
assetsInclude: ['**/*.wasm'],
|
assetsInclude: ['**/*.wasm'],
|
||||||
plugins: [react(), wasm(), topLevelAwait(), VitePWA({
|
plugins: [react(), wasm(), topLevelAwait(), VitePWA({
|
||||||
registerType: 'prompt',
|
registerType: "autoUpdate",
|
||||||
|
|
||||||
manifest: {
|
manifest: {
|
||||||
name: 'Qortal Go',
|
name: 'Qortal Go',
|
||||||
short_name: 'Go',
|
short_name: 'Go',
|
||||||
description: 'Your easy access to the Qortal blockchain',
|
description: 'Your easy access to the Qortal blockchain',
|
||||||
start_url: '/',
|
start_url: '/',
|
||||||
display: 'standalone',
|
display: 'standalone',
|
||||||
theme_color: '#ffffff',
|
|
||||||
background_color: '#ffffff',
|
theme_color: '#1f2023',
|
||||||
|
background_color: '#1f2023',
|
||||||
icons: [
|
icons: [
|
||||||
{
|
{
|
||||||
src: '/qortal192.png',
|
src: '/qortal192.png',
|
||||||
@ -37,6 +39,8 @@ export default defineConfig({
|
|||||||
workbox: {
|
workbox: {
|
||||||
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024, // 5MB limit
|
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024, // 5MB limit
|
||||||
disableDevLogs: true, // Suppresses logs in development
|
disableDevLogs: true, // Suppresses logs in development
|
||||||
|
skipWaiting: true, // Forces the new version to activate immediately
|
||||||
|
clientsClaim: true // Makes the new service worker take control
|
||||||
},
|
},
|
||||||
})],
|
})],
|
||||||
build: {
|
build: {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user