Update dependencies, containerize, add build workflow
All checks were successful
Build / build (push) Successful in 1m14s

This commit is contained in:
Moritz Ruth 2025-03-03 00:35:08 +01:00
parent ae1c71f4c5
commit 88f0632194
Signed by: moritzruth
GPG key ID: C9BBAB79405EE56D
38 changed files with 1139 additions and 829 deletions

View file

@ -0,0 +1,72 @@
<template>
<div class="flex gap-6 p-4">
<section class="w-80">
<div class="font-bold text-2xl pb-2">Raum</div>
<div class="flex flex-col overflow-y-auto bg-dark-900 bg-opacity-50 h-80vh">
<template
v-for="(room, index) in script.roomsById.values()"
:key="room.id"
>
<div v-if="index !== 0" class="w-full h-1px bg-dark-300"/>
<div class="flex-shrink-0 bg-dark-600 flex items-center">
<div class="px-3 py-2 flex-grow">
{{ room.label }}
</div>
<button v-if="game.currentRoomId === room.id" disabled class="bg-green-900 h-full px-3 text-sm cursor-not-allowed">
Aktiv
</button>
<button v-else class="bg-dark-300 h-full px-3 text-sm" @click="game.switchRoom(room.id)">
Aktivieren
</button>
</div>
</template>
</div>
</section>
<section class="flex-grow">
<div class="font-bold text-2xl pb-2">Versteckte Objekte</div>
<div class="grid gap-3 grid-cols-2 flex-grow auto-rows-min p-4 pt-0 relative">
<button
v-for="object in game.allObjectsById.values().filter(o => !game.visibleObjectIds.has(o.id))"
:key="object.id"
class="flex flex-col items-center gap-2 bg-dark-600 rounded-lg p-3"
@click="game.setObjectVisibility(object.id, true)"
>
<ObjectPicture :object-id="object.id"/>
<span class="text-sm text-gray-200 text-center">
{{ object.label }}
</span>
</button>
</div>
</section>
<section class="w-80">
<div class="font-bold text-2xl pb-2">Interaktionen</div>
<transition name="fade" mode="out-in">
<div v-if="game.sortedInteractionQueue.length === 0" class="text-xl text-gray-200">
Keine Interaktionen vorhanden.
</div>
<transition-group v-else tag="div" name="list" class="flex flex-col gap-4 relative h-80vh">
<InteractionQueueItemCard
v-for="(item, index) in game.sortedInteractionQueue"
:key="item.id"
:style="{ zIndex: 1000 - index }"
:item="item"
mode="director"
/>
</transition-group>
</transition>
</section>
</div>
</template>
<style module lang="scss">
</style>
<script setup lang="ts">
import { script } from "../../shared/script"
import { useGame } from "../game"
import ObjectPicture from "../components/ObjectPicture.vue"
import InteractionQueueItemCard from "../components/InteractionQueueItemCard.vue"
const game = useGame()
</script>

View file

@ -0,0 +1,115 @@
<template>
<div class="h-full flex flex-col relative">
<div class="flex-shrink-0 flex order-1">
<ObjectCardDropZone
label="Benutzen"
class="bg-green-800"
:has-floating="useFloatingObjectIds.size > 0"
@object-change="(v, i) => createSetInclusionSetter(useFloatingObjectIds)(v, i)"
@object-drop="onObjectUseDrop"
/>
<ObjectCardDropZone
label="Kombinieren"
class="bg-blue-900"
:has-floating="combineFloatingObjectIds.size > 0"
@object-change="(v, i) => createSetInclusionSetter(combineFloatingObjectIds)(v, i)"
@object-drop="onObjectInteractionDrop"
/>
</div>
<transition-group tag="div" name="list" class="grid gap-3 grid-cols-2 flex-grow auto-rows-min p-4 pt-0 relative">
<ObjectCard
v-for="object in game.visibleObjectsById.values()"
:key="object.id"
:object="object"
:is-over-dropzone="allFloatingObjectIds.has(object.id)"
:marked-for="getMarkedFor(object.id)"
@drag-start="onObjectDragStart"
@drag-end="onObjectDragEnd"
/>
</transition-group>
</div>
</template>
<style module lang="scss">
</style>
<script setup lang="ts">
import ObjectCard from "../components/ObjectCard.vue"
import { useGame } from "../game"
import { computed, reactive, ref } from "vue"
import { useScrollLock } from "@vueuse/core"
import ObjectCardDropZone from "../components/ObjectCardDropZone.vue"
const game = useGame()
const dragCounter = ref(0)
const useFloatingObjectIds = reactive(new Set())
const combineFloatingObjectIds = reactive(new Set())
const allFloatingObjectIds = computed(() => new Set([...useFloatingObjectIds, ...combineFloatingObjectIds]))
const firstCombinationObjectId = ref<null | string>(null)
function createSetInclusionSetter<T>(set: Set<T>) {
return (value: T, isIncluded: boolean) => {
if (isIncluded) set.add(value)
else set.delete(value)
}
}
function getMarkedFor(objectId: string) {
if (firstCombinationObjectId.value !== null) {
if (firstCombinationObjectId.value === objectId) return "combine-first"
} else if (game.currentInteraction !== null) {
switch (game.currentInteraction.type) {
case "use":
if (game.currentInteraction.objectId === objectId) return "use"
break
case "combine":
if (game.currentInteraction.objectIds.has(objectId)) return "combine"
break
}
}
return null
}
function onObjectDragStart() {
dragCounter.value++
}
function onObjectDragEnd() {
dragCounter.value--
if (dragCounter.value <= 0) {
// lock scrolling?
}
}
function onObjectUseDrop(objectId: string) {
game.voteForInteraction({
type: "use",
objectId
})
}
function onObjectInteractionDrop(objectId: string) {
if (firstCombinationObjectId.value === null) {
game.revokeCurrentInteractionVote()
firstCombinationObjectId.value = objectId
} else {
if (firstCombinationObjectId.value === objectId) {
firstCombinationObjectId.value = null
return
}
game.voteForInteraction({
type: "combine",
objectIds: new Set([firstCombinationObjectId.value, objectId])
})
firstCombinationObjectId.value = null
}
}
</script>

View file

@ -0,0 +1,40 @@
<template>
<div class="h-full p-4 pt-0">
<transition name="fade" mode="out-in">
<div v-if="game.sortedInteractionQueue.length === 0" class="h-full flex flex-col justify-center items-center gap-4 p-6">
<div class="text-xl text-center text-gray-200">
Noch keine Interaktionen zum Abstimmen vorhanden.
</div>
<button class="flex items-center gap-2 px-4 py-2 rounded-lg bg-green-800 text-lg" @click="emit('switch-screen', 'interactions')">
<ArrowRightIcon/>
<span class="relative top-1px">Interagieren</span>
</button>
</div>
<transition-group v-else tag="div" name="list" class="flex flex-col gap-4 relative">
<InteractionQueueItemCard
v-for="(item, index) in game.sortedInteractionQueue"
:key="item.id"
:style="{ zIndex: 1000 - index }"
:item="item"
mode="audience"
/>
</transition-group>
</transition>
</div>
</template>
<style scoped lang="scss">
</style>
<script setup lang="ts">
import InteractionQueueItemCard from "../components/InteractionQueueItemCard.vue"
import { useGame } from "../game"
import ArrowRightIcon from "virtual:icons/ph/arrow-right"
const emit = defineEmits<{
"switch-screen": [string]
}>()
const game = useGame()
</script>