modal with vimeo player

main
mwinter 1 year ago
parent 0511ab89cd
commit bd6efb24b6

@ -5,3 +5,15 @@
</NuxtLayout> </NuxtLayout>
</div> </div>
</template> </template>
<style>
.page-enter-active,
.page-leave-active {
transition: all 0.2s;
}
.page-enter-from,
.page-leave-to {
opacity: 0;
filter: blur(1rem);
}
</style>

@ -0,0 +1,3 @@
<template>
<div class="fixed inset-0 bg-black/50 z-5 transition duration-300" />
</template>

@ -0,0 +1,110 @@
<script setup lang="ts">
import { ref } from 'vue'
import {
Dialog,
DialogPanel,
TransitionChild,
TransitionRoot,
} from '@headlessui/vue'
const props = withDefaults(
defineProps<{
modelValue?: boolean
persistent?: boolean
fullscreen?: boolean
}>(),
{
modelValue: false,
persistent: false,
fullscreen: false,
},
)
const emit = defineEmits<{
(e: 'update:modelValue', value: boolean): void
}>()
const { modelValue } = toRefs(props)
const isOpen = ref(modelValue.value)
watch(modelValue, (value) => {
isOpen.value = value
})
function closeModal() {
isOpen.value = false
}
function openModal() {
isOpen.value = true
}
function onModalClose() {
if (!props.persistent)
closeModal()
}
watch(isOpen, (value) => {
emit('update:modelValue', value)
})
const api = {
isOpen,
open: openModal,
close: closeModal,
}
provide('modal', api)
</script>
<template>
<ClientOnly>
<slot name="activator" :open="openModal" :on="{ click: openModal }" />
<TransitionRoot appear :show="isOpen" as="template">
<Dialog as="div" class="relative z-10" @close="onModalClose">
<TransitionChild
as="template"
enter="duration-300 ease-out"
enter-from="opacity-0"
enter-to="opacity-100"
leave="duration-200 ease-in"
leave-from="opacity-100"
leave-to="opacity-0"
>
<div class="fixed inset-0 bg-black bg-opacity-25" />
</TransitionChild>
<div class="fixed inset-0 overflow-y-auto">
<div
class="flex min-h-full items-center justify-center text-center"
:class="{
'p-4': !fullscreen,
}"
>
<TransitionChild
as="template"
enter="duration-300 ease-out"
enter-from="opacity-0 scale-95"
enter-to="opacity-100 scale-100"
leave="duration-200 ease-in"
leave-from="opacity-100 scale-100"
leave-to="opacity-0 scale-95"
>
<DialogPanel
class="w-full transform overflow-hidden bg-white text-left align-middle shadow-xl transition-all"
:class="{
'h-screen': fullscreen,
'max-w-[85%] rounded-lg': !fullscreen,
}"
>
<slot />
</DialogPanel>
</TransitionChild>
</div>
</div>
</Dialog>
</TransitionRoot>
</ClientOnly>
</template>

@ -0,0 +1,9 @@
<script setup lang="ts">
import { DialogDescription } from '@headlessui/vue'
</script>
<template>
<DialogDescription class="px-4 py-3 text-sm text-gray-800">
<slot />
</DialogDescription>
</template>

@ -0,0 +1,9 @@
<script setup lang="ts">
// import { ref } from 'vue'
</script>
<template>
<div class="px-4 py-3">
<slot />
</div>
</template>

@ -0,0 +1,34 @@
<script setup lang="ts">
import { DialogTitle } from '@headlessui/vue'
interface Props {
dismissable?: boolean
titleClass?: string
}
defineProps<Props>()
const api = inject('modal')
</script>
<template>
<DialogTitle
as="div"
class="flex gap-2 justify-between items-center px-4 pt-3"
>
<h3
class="text-lg font-medium leading-6 text-gray-900"
:class="titleClass"
>
<slot />
</h3>
<slot v-if="dismissable" name="dismissable">
<button
class="text-2xl text-gray-500 appearance-none px-2 -mr-2"
@click="api.close"
>
&times;
</button>
</slot>
</DialogTitle>
</template>

@ -1,18 +1,30 @@
<template> <template>
<div class="p-1"> <div class="p-1">
<div v-show="visible" class="inline-flex bg-black rounded-full text-xs" > <div v-show="visible" class="inline-flex bg-black rounded-full text-xs" >
<NuxtLink v-if="type === 'document'" class="inline-flex p-1" :to="'/scores/' + work.score" target="_blank">
<NuxtLink v-if="type === 'document'" class="inline-flex p-1" :to="'/scores/' + work.score">
<Icon name="ion:book-outline" color="white" /> <Icon name="ion:book-outline" color="white" />
</NuxtLink> </NuxtLink>
<button @click="audioPlayerStore.setSoundCloudTrackID(work.soundcloud_trackid)" v-else-if="type === 'audio'" class="inline-flex p-1"> <button @click="audioPlayerStore.setSoundCloudTrackID(work.soundcloud_trackid)" v-else-if="type === 'audio'" class="inline-flex p-1">
<Icon name="wpf:speaker" color="white" /> <Icon name="wpf:speaker" color="white" />
</button> </button>
<button v-else-if="type === 'video'" class="inline-flex p-1">
<button @click="isOpen = true" v-else-if="type === 'video'" class="inline-flex p-1">
<Icon name="fluent:video-48-filled" color="white" /> <Icon name="fluent:video-48-filled" color="white" />
<Modal v-model="isOpen">
<ModalBody class="aspect-video">
<iframe :src="'https://player.vimeo.com/video/' + work.vimeo_trackid" width="100%" height="100%" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</ModalBody>
</Modal>
</button> </button>
<button v-else="type === 'image'" class="inline-flex p-1"> <button v-else="type === 'image'" class="inline-flex p-1">
<Icon name="mdi:camera" color="white" /> <Icon name="mdi:camera" color="white" />
</button> </button>
</div> </div>
</div> </div>
</template> </template>
@ -20,6 +32,8 @@
<script setup> <script setup>
import { useAudioPlayerStore } from "@/stores/AudioPlayerStore" import { useAudioPlayerStore } from "@/stores/AudioPlayerStore"
const audioPlayerStore = useAudioPlayerStore() const audioPlayerStore = useAudioPlayerStore()
const isOpen = ref(false)
</script> </script>
<script> <script>

@ -11,7 +11,7 @@
<slot /> <!-- required here only --> <slot /> <!-- required here only -->
<div class="sticky bottom-0 bg-white p-2 flex justify-center"> <div class="sticky bottom-0 bg-white p-2 flex justify-center">
<iframe width="400rem" height="20" scrolling="no" frameborder="no" allow="autoplay" <iframe width="400rem" height="20" scrolling="no" frameborder="no" allow="autoplay"
:src="'https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/' + audioPlayerStore.soundcloud_trackid + '&color=%23ff5500&inverse=false&auto_play=true&show_user=true'"></iframe> :src="'https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/' + audioPlayerStore.soundcloud_trackid + '&inverse=false&auto_play=true&show_user=false'"></iframe>
</div> </div>
</template> </template>

@ -3,5 +3,8 @@ export default defineNuxtConfig({
modules: ['@nuxtjs/tailwindcss', '@nuxt/image', 'nuxt-icon', '@pinia/nuxt'], modules: ['@nuxtjs/tailwindcss', '@nuxt/image', 'nuxt-icon', '@pinia/nuxt'],
image: { image: {
domains: ['unboundedpress.org'] domains: ['unboundedpress.org']
},
app: {
pageTransition: { name: 'page', mode: 'out-in' }
} }
}) })

File diff suppressed because it is too large Load Diff

@ -16,6 +16,7 @@
"nuxt-icon": "^0.4.1" "nuxt-icon": "^0.4.1"
}, },
"dependencies": { "dependencies": {
"@headlessui/vue": "^1.7.14",
"@pinia/nuxt": "^0.4.11", "@pinia/nuxt": "^0.4.11",
"pinia": "^2.1.3" "pinia": "^2.1.3"
} }

@ -1,6 +1,6 @@
<template> <template>
<div> <div class="flex min-h-full items-center justify-center text-center">
<embed :src="'https://unboundedpress.org/api/scores.files/' + metadata._id.$oid + '/binary'" width="100%" height="900px" /> <embed :src="'https://unboundedpress.org/api/scores.files/' + metadata._id.$oid + '/binary'" class="w-[85%] h-[88vh]" />
</div> </div>
</template> </template>

@ -1,5 +1,5 @@
<template> <template>
<div class="bg-gray-100 rounded-lg m-5 grid grid-cols-3 gap-10 bg-white divide-x divide-solid divide-black p-4"> <div class="bg-zinc-100 rounded-lg m-5 grid grid-cols-3 gap-10 bg-white divide-x divide-solid divide-black p-4">
<div class="px-5"> <div class="px-5">
<p class="text-lg">pieces</p> <p class="text-lg">pieces</p>
<div class="py-2 ml-3" v-for="item in works"> <div class="py-2 ml-3" v-for="item in works">
@ -9,7 +9,7 @@
<p class="italic text-sm">{{ work.title }}</p> <p class="italic text-sm">{{ work.title }}</p>
<div class="grid grid-cols-4"> <div class="grid grid-cols-4">
<Button :visible="work.score" type="document" :work="work" :link="'/scores/' + work.score"></Button> <Button :visible="work.score" type="document" :work="work"></Button>
<Button :visible="work.soundcloud_trackid" type="audio" :work="work"></Button> <Button :visible="work.soundcloud_trackid" type="audio" :work="work"></Button>
@ -25,6 +25,7 @@
<div class="px-5"> <div class="px-5">
<p class="text-lg">writings</p> <p class="text-lg">writings</p>
<div class="leading-tight py-2 ml-3 text-sm" v-for="item in pubs"> <div class="leading-tight py-2 ml-3 text-sm" v-for="item in pubs">
{{ item.entryTags.title }} {{ item.entryTags.title }}
</div> </div>

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save