@@ -18,7 +18,8 @@ import {
1818 IconHeadphones ,
1919 IconDots ,
2020 IconLogout ,
21- IconX
21+ IconX ,
22+ IconDownload
2223} from "@tabler/icons-react"
2324import { cn } from "@utils/cn"
2425import { motion , AnimatePresence } from "framer-motion"
@@ -69,11 +70,40 @@ const SidebarContent = ({
6970 const pathname = usePathname ( )
7071 const [ userDetails , setUserDetails ] = useState ( null )
7172 const [ isHelpModalOpen , setHelpModalOpen ] = useState ( false )
73+ const [ installPrompt , setInstallPrompt ] = useState ( null )
7274 const [ isUserMenuOpen , setUserMenuOpen ] = useState ( false )
7375 const userMenuRef = useRef ( null )
7476
7577 useClickOutside ( userMenuRef , ( ) => setUserMenuOpen ( false ) )
7678
79+ useEffect ( ( ) => {
80+ const handleBeforeInstallPrompt = ( e ) => {
81+ // Prevent the mini-infobar from appearing on mobile
82+ e . preventDefault ( )
83+ // Stash the event so it can be triggered later.
84+ setInstallPrompt ( e )
85+ }
86+
87+ window . addEventListener (
88+ "beforeinstallprompt" ,
89+ handleBeforeInstallPrompt
90+ )
91+
92+ return ( ) => {
93+ window . removeEventListener (
94+ "beforeinstallprompt" ,
95+ handleBeforeInstallPrompt
96+ )
97+ }
98+ } , [ ] )
99+
100+ const handleInstallClick = async ( ) => {
101+ if ( ! installPrompt ) return
102+ const result = await installPrompt . prompt ( )
103+ console . log ( `Install prompt was: ${ result . outcome } ` )
104+ setInstallPrompt ( null )
105+ }
106+
77107 useEffect ( ( ) => {
78108 fetch ( "/api/user/profile" )
79109 . then ( ( res ) => ( res . ok ? res . json ( ) : null ) )
@@ -225,6 +255,22 @@ const SidebarContent = ({
225255
226256 { /* Footer */ }
227257 < div className = "flex flex-col gap-2" >
258+ { installPrompt && (
259+ < button
260+ onClick = { handleInstallClick }
261+ className = { cn (
262+ "w-full flex items-center gap-3 bg-green-600/20 border border-green-500/50 text-green-300 rounded-lg p-2 text-left text-sm hover:bg-green-600/40 transition-colors" ,
263+ isCollapsed && "justify-center"
264+ ) }
265+ >
266+ < IconDownload size = { 20 } className = "flex-shrink-0" />
267+ { ! isCollapsed && (
268+ < span className = "font-medium whitespace-nowrap" >
269+ Install App
270+ </ span >
271+ ) }
272+ </ button >
273+ ) }
228274 { isMobile ? (
229275 < button
230276 onClick = { onMobileClose }
0 commit comments