chore: Add hybrid rendering, CSP fixes, memory config
This commit is contained in:
parent
524fb74df5
commit
2268f0c38c
|
|
@ -2,6 +2,7 @@
|
||||||
FROM node:22-alpine AS build
|
FROM node:22-alpine AS build
|
||||||
ARG PASSWORD
|
ARG PASSWORD
|
||||||
ENV PASSWORD=${PASSWORD}
|
ENV PASSWORD=${PASSWORD}
|
||||||
|
ENV NODE_OPTIONS="--max-old-space-size=4096"
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY package*.json ./
|
COPY package*.json ./
|
||||||
RUN npm install
|
RUN npm install
|
||||||
|
|
|
||||||
|
|
@ -29,26 +29,38 @@
|
||||||
</div>
|
</div>
|
||||||
<slot /> <!-- required here only -->
|
<slot /> <!-- required here only -->
|
||||||
<div class="fixed bottom-0 bg-white p-2 w-full flex justify-center z-20">
|
<div class="fixed bottom-0 bg-white p-2 w-full flex justify-center z-20">
|
||||||
|
<ClientOnly>
|
||||||
<iframe width="400rem" height="20px" scrolling="no" frameborder="no" allow="autoplay" v-if="audioPlayerStore.soundcloud_trackid !== 'undefined'"
|
<iframe width="400rem" height="20px" scrolling="no" frameborder="no" allow="autoplay" v-if="audioPlayerStore.soundcloud_trackid !== 'undefined'"
|
||||||
: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>
|
: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>
|
||||||
|
</ClientOnly>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Modal v-model="modalStore.isOpen" :maxHeight="modalStore.type === 'image' && modalStore.soundcloudUrl ? 'calc(85vh + 60px)' : '85vh'">
|
<Modal v-model="modalStore.isOpen" :maxHeight="modalStore.type === 'image' && modalStore.soundcloudUrl ? 'calc(85vh + 60px)' : '85vh'">
|
||||||
<ModalBody :class="modalStore.aspect">
|
<ModalBody :class="modalStore.aspect">
|
||||||
<ImageSlider v-if="modalStore.type === 'image'" :bucket="modalStore.bucket" :gallery="modalStore.gallery"></ImageSlider>
|
<ImageSlider v-if="modalStore.type === 'image'" :bucket="modalStore.bucket" :gallery="modalStore.gallery"></ImageSlider>
|
||||||
<div v-if="modalStore.type === 'image' && modalStore.soundcloudUrl" class="flex justify-center mt-2">
|
<div v-if="modalStore.type === 'image' && modalStore.soundcloudUrl" class="flex justify-center mt-2">
|
||||||
|
<ClientOnly>
|
||||||
<iframe :src="modalStore.soundcloudUrl" width="400rem" height="20px" scrolling="no" frameborder="no" allow="autoplay"></iframe>
|
<iframe :src="modalStore.soundcloudUrl" width="400rem" height="20px" scrolling="no" frameborder="no" allow="autoplay"></iframe>
|
||||||
|
</ClientOnly>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="modalStore.type === 'video'" :class="modalStore.aspect" class="w-full h-full flex items-center justify-center p-4">
|
<div v-if="modalStore.type === 'video'" :class="modalStore.aspect" class="w-full h-full flex items-center justify-center p-4">
|
||||||
|
<ClientOnly>
|
||||||
<iframe :src="'https://player.vimeo.com/video/' + modalStore.vimeo_trackid" width="100%" height="100%" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen class="max-w-full max-h-full"></iframe>
|
<iframe :src="'https://player.vimeo.com/video/' + modalStore.vimeo_trackid" width="100%" height="100%" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen class="max-w-full max-h-full"></iframe>
|
||||||
|
</ClientOnly>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="modalStore.type === 'document'" class="w-full h-full">
|
<div v-if="modalStore.type === 'document'" class="w-full h-full">
|
||||||
|
<ClientOnly>
|
||||||
<iframe :src="modalStore.iframeUrl" width="100%" height="100%" frameborder="0"></iframe>
|
<iframe :src="modalStore.iframeUrl" width="100%" height="100%" frameborder="0"></iframe>
|
||||||
|
</ClientOnly>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="modalStore.type === 'pdf'" class="flex flex-col h-full">
|
<div v-if="modalStore.type === 'pdf'" class="flex flex-col h-full">
|
||||||
|
<ClientOnly>
|
||||||
<iframe :src="modalStore.pdfUrl + '#toolbar=1&navpanes=0&sidebar=0'" width="100%" height="100%" frameborder="0" :class="[modalStore.soundcloudUrl ? 'max-h-[calc(85vh-60px)]' : 'max-h-[calc(85vh-2rem)]', 'flex-grow']"></iframe>
|
<iframe :src="modalStore.pdfUrl + '#toolbar=1&navpanes=0&sidebar=0'" width="100%" height="100%" frameborder="0" :class="[modalStore.soundcloudUrl ? 'max-h-[calc(85vh-60px)]' : 'max-h-[calc(85vh-2rem)]', 'flex-grow']"></iframe>
|
||||||
|
</ClientOnly>
|
||||||
<div v-if="modalStore.soundcloudUrl" class="flex justify-center mt-2">
|
<div v-if="modalStore.soundcloudUrl" class="flex justify-center mt-2">
|
||||||
|
<ClientOnly>
|
||||||
<iframe :src="modalStore.soundcloudUrl" width="400rem" height="20px" scrolling="no" frameborder="no" allow="autoplay"></iframe>
|
<iframe :src="modalStore.soundcloudUrl" width="400rem" height="20px" scrolling="no" frameborder="no" allow="autoplay"></iframe>
|
||||||
|
</ClientOnly>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="modalStore.type === 'pdf' || modalStore.type === 'image' || modalStore.type === 'document'" class="absolute bottom-2 right-2 z-10">
|
<div v-if="modalStore.type === 'pdf' || modalStore.type === 'image' || modalStore.type === 'document'" class="absolute bottom-2 right-2 z-10">
|
||||||
|
|
@ -63,24 +75,28 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useAudioPlayerStore } from "@/stores/AudioPlayerStore"
|
import { useAudioPlayerStore } from "@/stores/AudioPlayerStore"
|
||||||
import { useModalStore } from "@/stores/ModalStore"
|
import { useModalStore } from "@/stores/ModalStore"
|
||||||
|
import { onMounted } from "vue"
|
||||||
|
|
||||||
const audioPlayerStore = useAudioPlayerStore()
|
const audioPlayerStore = useAudioPlayerStore()
|
||||||
const modalStore = useModalStore()
|
const modalStore = useModalStore()
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
if(process.client && route.params.files == 'scores') {
|
onMounted(() => {
|
||||||
const { data: works } = await useFetch('/api/works', {
|
if(route.params.files == 'scores') {
|
||||||
|
useFetch('/api/works', {
|
||||||
transform: (works) => {
|
transform: (works) => {
|
||||||
return works.find(w => w.score === route.params.filename)
|
return works.find(w => w.score === route.params.filename)
|
||||||
}
|
}
|
||||||
})
|
}).then(({ data }) => {
|
||||||
if(works.value?.soundcloud_trackid){
|
if(data.value?.soundcloud_trackid){
|
||||||
audioPlayerStore.setSoundCloudTrackID(works.value.soundcloud_trackid)
|
audioPlayerStore.setSoundCloudTrackID(data.value.soundcloud_trackid)
|
||||||
} else {
|
} else {
|
||||||
audioPlayerStore.clearSoundCloudTrackID()
|
audioPlayerStore.clearSoundCloudTrackID()
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const { data: upcoming_events } = await useFetch('/api/events', {
|
const { data: upcoming_events } = await useFetch('/api/events', {
|
||||||
transform: (events) => {
|
transform: (events) => {
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,13 @@ export default defineNuxtConfig({
|
||||||
},
|
},
|
||||||
routeRules: {
|
routeRules: {
|
||||||
'/hdp': { redirect: '/a_history_of_the_domino_problem' },
|
'/hdp': { redirect: '/a_history_of_the_domino_problem' },
|
||||||
|
|
||||||
|
// Default: prerender all routes (static HTML)
|
||||||
|
'/**': { prerender: true },
|
||||||
|
|
||||||
|
// Exceptions: admin needs SSR (dynamic), API needs CORS
|
||||||
|
'/admin': { ssr: true },
|
||||||
|
'/api/**': { cors: true },
|
||||||
},
|
},
|
||||||
nitro: {
|
nitro: {
|
||||||
prerender: { crawlLinks: true}
|
prerender: { crawlLinks: true}
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<IconButton :visible=item.entryTags.howpublished type="document" :link="item.entryTags.howpublished" class="inline-flex p-1 mt-[-6px]"></IconButton>
|
<IconButton :visible=item.entryTags.howpublished type="document" :link=item.entryTags.howpublished class="inline-flex p-1 mt-[-6px]"></IconButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -89,11 +89,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const { data: images } = await useFetch('/api/images')
|
const { data: images } = await useFetch('/api/images', { key: 'images' })
|
||||||
|
|
||||||
const { data: works } = await useFetch('/api/works', {
|
const { data: works } = await useFetch('/api/works', {
|
||||||
|
key: 'works',
|
||||||
transform: (works) => {
|
transform: (works) => {
|
||||||
for (const work of works) {
|
const cloned = JSON.parse(JSON.stringify(works))
|
||||||
|
for (const work of cloned) {
|
||||||
if(work.score){
|
if(work.score){
|
||||||
work.score = "/scores/" + work.score
|
work.score = "/scores/" + work.score
|
||||||
}
|
}
|
||||||
|
|
@ -107,7 +109,7 @@
|
||||||
work.gallery = gallery
|
work.gallery = gallery
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let priorityGroups = groupBy(works, work => work.priority)
|
let priorityGroups = groupBy(cloned, work => work.priority)
|
||||||
let groups = groupBy(priorityGroups["1"], work => new Date(work.date).getFullYear())
|
let groups = groupBy(priorityGroups["1"], work => new Date(work.date).getFullYear())
|
||||||
groups = Object.keys(groups).map((year) => {
|
groups = Object.keys(groups).map((year) => {
|
||||||
return {
|
return {
|
||||||
|
|
@ -124,19 +126,23 @@
|
||||||
})
|
})
|
||||||
|
|
||||||
const { data: pubs } = await useFetch('/api/publications', {
|
const { data: pubs } = await useFetch('/api/publications', {
|
||||||
|
key: 'publications',
|
||||||
transform: (pubs) => {
|
transform: (pubs) => {
|
||||||
for (const pub of pubs) {
|
const cloned = JSON.parse(JSON.stringify(pubs))
|
||||||
|
for (const pub of cloned) {
|
||||||
if(pub.entryTags && pub.entryTags.howpublished && !(isValidUrl(pub.entryTags.howpublished))){
|
if(pub.entryTags && pub.entryTags.howpublished && !(isValidUrl(pub.entryTags.howpublished))){
|
||||||
pub.entryTags.howpublished = "/pubs/" + pub.entryTags.howpublished
|
pub.entryTags.howpublished = "/pubs/" + pub.entryTags.howpublished
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pubs.sort((a,b) => (a.citationKey > b.citationKey) ? -1 : ((b.citationKey > a.citationKey) ? 1 : 0))
|
return cloned.sort((a,b) => (a.citationKey > b.citationKey) ? -1 : ((b.citationKey > a.citationKey) ? 1 : 0))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const { data: releases } = await useFetch('/api/releases', {
|
const { data: releases } = await useFetch('/api/releases', {
|
||||||
|
key: 'releases',
|
||||||
transform: (releases) => {
|
transform: (releases) => {
|
||||||
return releases.sort((a,b) => {
|
const cloned = JSON.parse(JSON.stringify(releases))
|
||||||
|
return cloned.sort((a,b) => {
|
||||||
const dateA = parseInt(a.date) || 0
|
const dateA = parseInt(a.date) || 0
|
||||||
const dateB = parseInt(b.date) || 0
|
const dateB = parseInt(b.date) || 0
|
||||||
return dateB - dateA
|
return dateB - dateA
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue