-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAddToAppButton.tsx
More file actions
117 lines (104 loc) · 3.23 KB
/
AddToAppButton.tsx
File metadata and controls
117 lines (104 loc) · 3.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import React, { useState, useEffect } from 'react'
import { Box, Button, Snackbar, Alert, IconButton } from '@mui/material'
import { GetApp, Close, PhoneIphone, LaptopMac } from '@mui/icons-material'
interface BeforeInstallPromptEvent extends Event {
prompt(): Promise<void>
userChoice: Promise<{ outcome: 'accepted' | 'dismissed' }>
}
export function AddToAppButton() {
const [deferredPrompt, setDeferredPrompt] = useState<BeforeInstallPromptEvent | null>(null)
const [showIOSInstructions, setShowIOSInstructions] = useState(false)
const [isInstallable, setIsInstallable] = useState(false)
useEffect(() => {
const handleBeforeInstallPrompt = (e: Event) => {
// Prevent the mini-infobar from appearing on mobile
e.preventDefault()
setDeferredPrompt(e as BeforeInstallPromptEvent)
setIsInstallable(true)
}
const handleAppInstalled = () => {
setIsInstallable(false)
setDeferredPrompt(null)
}
window.addEventListener('beforeinstallprompt', handleBeforeInstallPrompt)
window.addEventListener('appinstalled', handleAppInstalled)
return () => {
window.removeEventListener('beforeinstallprompt', handleBeforeInstallPrompt)
window.removeEventListener('appinstalled', handleAppInstalled)
}
}, [])
const isIOS = () => {
return /iPad|iPhone|iPod/.test(navigator.userAgent)
}
const isInStandaloneMode = () => {
return window.matchMedia('(display-mode: standalone)').matches ||
(window.navigator as any).standalone === true
}
const handleInstallClick = async () => {
if (isIOS()) {
setShowIOSInstructions(true)
return
}
if (deferredPrompt) {
deferredPrompt.prompt()
const { outcome } = await deferredPrompt.userChoice
if (outcome === 'accepted') {
setDeferredPrompt(null)
setIsInstallable(false)
}
}
}
// Don't show the button if already installed or not installable
if (isInStandaloneMode() || (!isInstallable && !isIOS())) {
return null
}
return (
<>
<Box
sx={{
display: 'flex',
justifyContent: 'center',
mt: 2,
mb: 1,
}}
>
<Button
variant="outlined"
startIcon={isIOS() ? <PhoneIphone /> : <LaptopMac />}
onClick={handleInstallClick}
sx={{
borderRadius: 2,
textTransform: 'none',
px: 3,
py: 1,
}}
>
Add to {isIOS() ? 'Home Screen' : 'Desktop'}
</Button>
</Box>
{/* iOS Installation Instructions */}
<Snackbar
open={showIOSInstructions}
onClose={() => setShowIOSInstructions(false)}
anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
autoHideDuration={8000}
>
<Alert
severity="info"
sx={{ maxWidth: '90vw' }}
action={
<IconButton
size="small"
color="inherit"
onClick={() => setShowIOSInstructions(false)}
>
<Close fontSize="small" />
</IconButton>
}
>
To install: tap the Share button in Safari, then tap "Add to Home Screen"
</Alert>
</Snackbar>
</>
)
}