Skip to content

Commit

Permalink
feat: create app install popup
Browse files Browse the repository at this point in the history
  • Loading branch information
AlejandroAkbal committed Feb 6, 2024
1 parent 39c4114 commit e21a9c3
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 2 deletions.
97 changes: 97 additions & 0 deletions components/layout/DialogManager.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<script lang="ts" setup>
import { watchOnce } from '@vueuse/core'
const open = ref(false)
const dialogs = [
{
condition: () => {
const { timesTheAppHasBeenOpened, promptInstallPwa } = useAppStatistics()
if (promptInstallPwa.value) {
return false
}
if (timesTheAppHasBeenOpened.value < 1) {
return false
}
if (window.matchMedia('(display-mode: standalone)').matches) {
return false
}
return true
},
component: resolveComponent('PWA')
}
]
const dialog = computed(() => {
return dialogs.find((dialog) => dialog.condition())?.component
})
watchOnce(
dialog,
() => {
if (dialog.value) {
// Show after X seconds
setTimeout(() => {
open.value = true
}, 1000 * 1.33)
}
},
{
immediate: true
}
)
</script>

<template>
<HeadlessTransitionRoot
:show="open"
as="template"
>
<HeadlessDialog
as="div"
class="relative z-10"
@close="open = false"
>
<!-- Background -->
<HeadlessTransitionChild
as="template"
enter="ease-out duration-300"
enter-from="opacity-0"
enter-to="opacity-100"
leave="ease-in duration-200"
leave-from="opacity-100"
leave-to="opacity-0"
>
<div class="fixed inset-0 bg-base-1000/80 backdrop-blur transition-opacity" />
</HeadlessTransitionChild>

<!-- Body -->
<div class="fixed inset-0 z-10 w-screen overflow-y-auto">
<div class="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
<HeadlessTransitionChild
as="template"
enter="ease-out duration-300"
enter-from="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
enter-to="opacity-100 translate-y-0 sm:scale-100"
leave="ease-in duration-200"
leave-from="opacity-100 translate-y-0 sm:scale-100"
leave-to="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
>
<HeadlessDialogPanel
class="relative transform overflow-hidden rounded-lg bg-base-1000 px-4 pb-4 pt-5 text-left shadow-xl ring-1 ring-base-0/10 transition-all sm:my-8 sm:w-full sm:max-w-lg sm:p-6"
>
<component
:is="dialog"
v-model="open"
/>
</HeadlessDialogPanel>
</HeadlessTransitionChild>
</div>
</div>
</HeadlessDialog>
</HeadlessTransitionRoot>
</template>
63 changes: 63 additions & 0 deletions components/layout/modal/PWA.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<script lang="ts" setup>
import { HomeIcon } from '@heroicons/vue/24/outline'
const open = defineModel<boolean>()
onMounted(() => {
const { promptInstallPwa } = useAppStatistics()
promptInstallPwa.value = true
})
</script>

<template>
<!-- Header -->
<div>
<div class="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-green-100">
<HomeIcon
aria-hidden="true"
class="h-6 w-6 text-green-600"
/>
</div>

<div class="mt-3 text-center sm:mt-5">
<HeadlessDialogTitle
as="h3"
class="text-base font-semibold leading-6 text-base-content-highlight"
>
Install the App?
</HeadlessDialogTitle>

<div class="mt-2">
<p class="text-sm">
<!-- TODO: Mention times visited? -->
Add it to your home screen for quick and easy access,
<!-- -->
it doesn't take any storage!
</p>
</div>
</div>
</div>

<!-- Body -->
<iframe
border="0"
cellspacing="0"
class="mt-5 h-screen max-h-[60vh] w-full rounded-md sm:mt-6"
loading="eager"
onload="this.style.visibility='visible';"
src="https://www.installpwa.com/from/r34.app/embed?theme=dark"
style="visibility: hidden"
/>

<!-- Actions -->
<div class="mt-5 sm:mt-6">
<button
class="focus-visible:focus-outline-util hover:hover-bg-util hover:hover-text-util inline-flex w-full justify-center rounded-md px-3 py-2 text-sm font-semibold shadow-sm ring-1 ring-inset ring-base-0/20"
type="button"
@click="open = false"
>
Dismiss
</button>
</div>
</template>
11 changes: 9 additions & 2 deletions composables/useAppStatistics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ let tutorialLongClickTag = ref<boolean>(false)
let tutorialPostSave = ref<boolean>(false)
let tutorialPostSource = ref<boolean>(false)

let promptInstallPwa = ref<boolean>(false)

if (process.client) {
timesTheAppHasBeenOpened = useStorage('statistics-appOpenedCount', 0, localStorage, {
writeDefaults: false
Expand All @@ -19,10 +21,13 @@ if (process.client) {
tutorialPostSave = useStorage('tutorial-postSave', false, localStorage, {
writeDefaults: false
})

tutorialPostSource = useStorage('tutorial-postSource', false, localStorage, {
writeDefaults: false
})

promptInstallPwa = useStorage('prompt-installPwa', false, localStorage, {
writeDefaults: false
})
}

timesTheAppHasBeenOpened.value++
Expand All @@ -33,6 +38,8 @@ export function useAppStatistics() {

tutorialLongClickTag,
tutorialPostSave,
tutorialPostSource
tutorialPostSource,

promptInstallPwa
}
}
2 changes: 2 additions & 0 deletions layouts/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
position="top-center"
theme="dark"
/>

<DialogManager />
</ClientOnly>

<SidebarWrapper>
Expand Down

0 comments on commit e21a9c3

Please sign in to comment.