kinda finished
This commit is contained in:
		
							parent
							
								
									8a37f14a48
								
							
						
					
					
						commit
						11d9b7a0b4
					
				
					 11 changed files with 2706 additions and 162 deletions
				
			
		
							
								
								
									
										5
									
								
								.dockerignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								.dockerignore
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | |||
| Dockerfile | ||||
| node_modules/ | ||||
| build/ | ||||
| .svelte-kit/ | ||||
| .idea/ | ||||
							
								
								
									
										16
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,16 @@ | |||
| FROM node:23-alpine AS base | ||||
| WORKDIR /app | ||||
| 
 | ||||
| FROM base AS dependencies | ||||
| COPY package*.json /app/ | ||||
| RUN npm ci | ||||
| 
 | ||||
| FROM base AS build | ||||
| COPY --from=dependencies /app/node_modules /app/node_modules | ||||
| COPY . /app | ||||
| RUN npm run build | ||||
| 
 | ||||
| FROM base AS release | ||||
| COPY --from=build /app/build /app/build | ||||
| 
 | ||||
| CMD ["node", "/app/build/index.js"] | ||||
							
								
								
									
										
											BIN
										
									
								
								bun.lockb
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								bun.lockb
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										2501
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										2501
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -14,7 +14,7 @@ | |||
| 	}, | ||||
| 	"devDependencies": { | ||||
| 		"@eslint/compat": "^1.2.3", | ||||
| 		"@sveltejs/adapter-static": "^3.0.6", | ||||
| 		"@sveltejs/adapter-node": "^5.2.11", | ||||
| 		"@sveltejs/kit": "^2.0.0", | ||||
| 		"@sveltejs/vite-plugin-svelte": "^4.0.0", | ||||
| 		"eslint": "^9.7.0", | ||||
|  | @ -28,8 +28,5 @@ | |||
| 		"typescript": "^5.0.0", | ||||
| 		"typescript-eslint": "^8.0.0", | ||||
| 		"vite": "^5.4.11" | ||||
| 	}, | ||||
| 	"dependencies": { | ||||
| 		"svelte-adapter-bun": "^0.5.2" | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ | |||
| 
 | ||||
| <div class="modal"> | ||||
| 	<div class="modal-content"> | ||||
| 		<button class="close" onclick={props.onclose}> X </button> | ||||
| 		<button class="close" onclick={props.onclose}>X</button> | ||||
| 		<video autoplay muted> | ||||
| 			<source src={props.videoUrl} type="video/mp4" /> | ||||
| 			Your browser does not support the video tag. | ||||
|  |  | |||
							
								
								
									
										30
									
								
								src/routes/+layout.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/routes/+layout.svelte
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,30 @@ | |||
| <script lang="ts"> | ||||
| 	let { children } = $props(); | ||||
| </script> | ||||
| <main> | ||||
| 	{@render children()} | ||||
| </main> | ||||
| 
 | ||||
| <style> | ||||
|     :global(body) { | ||||
|         margin: 0; | ||||
|         font-family: 'Arial', sans-serif; | ||||
|         background-color: #f4f4f4; | ||||
|         color: #1c1919; | ||||
|     } | ||||
| 
 | ||||
|     main { | ||||
|         display: flex; | ||||
|         flex-direction: column; | ||||
|         justify-content: center; | ||||
|         align-items: center; | ||||
|         height: 100vh; | ||||
|         width: 100vw; | ||||
|         background-color: #a8571c; | ||||
|         color: white; | ||||
|         text-align: center; | ||||
|         overflow: hidden; | ||||
|         padding: 20px; | ||||
|         box-sizing: border-box; | ||||
|     } | ||||
| </style> | ||||
|  | @ -1,6 +1,7 @@ | |||
| <script lang="ts"> | ||||
| 	import Modal from '$lib/Modal.svelte'; | ||||
| 
 | ||||
| 	import { page } from '$app/state'; | ||||
| 	 | ||||
| 	const difficultyClass = 15; | ||||
| 	const skin = 'winter'; | ||||
| 
 | ||||
|  | @ -23,12 +24,14 @@ | |||
| 	}; | ||||
| 
 | ||||
| 	const handleRoll = async () => { | ||||
| 		if (rollResult) return; | ||||
| 		rollResult = Math.floor(Math.random() * 20) + 1; | ||||
| 		rollVideoUrl = await getVideoUrl(skin, 'd20', rollResult); | ||||
| 		showModal('roll'); | ||||
| 	}; | ||||
| 
 | ||||
| 	const handleGuidance = async () => { | ||||
| 		if (guidanceResult) return; | ||||
| 		guidanceResult = Math.floor(Math.random() * 4) + 1; | ||||
| 		guidanceVideoUrl = await getVideoUrl(skin, 'd4', guidanceResult); | ||||
| 		showModal('guidance'); | ||||
|  | @ -49,182 +52,159 @@ | |||
| 	}; | ||||
| </script> | ||||
| 
 | ||||
| <main> | ||||
| <section> | ||||
| 	<h1>You have received a gift</h1> | ||||
| </section> | ||||
| 
 | ||||
| <section> | ||||
| 	<h2>Investigation</h2> | ||||
| 	<p>Intelligence check</p> | ||||
| </section> | ||||
| 
 | ||||
| <section> | ||||
| 	<h2>Difficulty Class</h2> | ||||
| 	<p>{difficultyClass}</p> | ||||
| </section> | ||||
| 
 | ||||
| 
 | ||||
| {#if !pressedContinue} | ||||
| 	<section> | ||||
| 		<h1>You have received a gift</h1> | ||||
| 		{#if !rollResult} | ||||
| 			<button onclick={handleRoll}>Roll Ability</button> | ||||
| 		{/if} | ||||
| 		{#if rollResult && rollClickedExit} | ||||
| 			<h2>Roll Result</h2> | ||||
| 			<p>{rollResult}</p> | ||||
| 		{/if} | ||||
| 	</section> | ||||
| 
 | ||||
| 	<section> | ||||
| 		<h2>Investigation</h2> | ||||
| 		<p>Intelligence check</p> | ||||
| 	</section> | ||||
| 
 | ||||
| 	<section> | ||||
| 		<h2>Difficulty Class</h2> | ||||
| 		<p>{difficultyClass}</p> | ||||
| 	</section> | ||||
| 
 | ||||
| 
 | ||||
| 	{#if !pressedContinue} | ||||
| 		<section> | ||||
| 			{#if !rollResult} | ||||
| 				<button onclick={handleRoll}>Roll Ability</button> | ||||
| 			{/if} | ||||
| 			{#if rollResult && rollClickedExit} | ||||
| 				<h2>Roll Result</h2> | ||||
| 				<p>{rollResult}</p> | ||||
| 			{/if} | ||||
| 		</section> | ||||
| 
 | ||||
| 		{#if rollModal && rollVideoUrl} | ||||
| 			<Modal onclose={() => { | ||||
| 	{#if rollModal && rollVideoUrl} | ||||
| 		<Modal onclose={() => { | ||||
| 				rollModal = false; | ||||
| 				rollClickedExit = true; | ||||
| 			}} videoUrl={rollVideoUrl} /> | ||||
| 		{/if} | ||||
| 		<section> | ||||
| 			{#if !guidanceResult} | ||||
| 				<button onclick={handleGuidance}>Roll Guidance</button> | ||||
| 			{/if} | ||||
| 			{#if guidanceResult && guidanceClickedExit} | ||||
| 				<h2>Guidance Result</h2> | ||||
| 				<p>{guidanceResult}</p> | ||||
| 			{/if} | ||||
| 		</section> | ||||
| 
 | ||||
| 		{#if guidanceModal && guidanceVideoUrl} | ||||
| 			<Modal onclose={() => { | ||||
| 				guidanceModal = false; | ||||
| 				guidanceClickedExit = true; | ||||
| 			}} videoUrl={guidanceVideoUrl} /> | ||||
| 		{/if} | ||||
| 
 | ||||
| 		{#if rollResult && guidanceResult} | ||||
| 			<button class="continue" onclick={() => {pressedContinue = true}}>Continue</button> | ||||
| 		{/if} | ||||
| 	{/if} | ||||
| 
 | ||||
| 	<section> | ||||
| 		{#if rollResult && guidanceResult && pressedContinue} | ||||
| 			<h2>Final Result</h2> | ||||
| 			<p>{rollResult + guidanceResult}</p> | ||||
| 			{#if rollResult + guidanceResult >= difficultyClass} | ||||
| 				<h2 class="success">Success</h2> | ||||
| 				<a href="/present">Collect your gift!</a> | ||||
| 			{:else} | ||||
| 				<h2 class="failure">Failure</h2> | ||||
| 				<button class="reset" onclick={resetPage}> Reset</button> | ||||
| 			{/if} | ||||
| 		{#if !guidanceResult} | ||||
| 			<button onclick={handleGuidance}>Roll Guidance</button> | ||||
| 		{/if} | ||||
| 		{#if guidanceResult && guidanceClickedExit} | ||||
| 			<h2>Guidance Result</h2> | ||||
| 			<p>{guidanceResult}</p> | ||||
| 		{/if} | ||||
| 	</section> | ||||
| 
 | ||||
| </main> | ||||
| 	{#if guidanceModal && guidanceVideoUrl} | ||||
| 		<Modal onclose={() => { | ||||
| 				guidanceModal = false; | ||||
| 				guidanceClickedExit = true; | ||||
| 			}} videoUrl={guidanceVideoUrl} /> | ||||
| 	{/if} | ||||
| 
 | ||||
| 	{#if rollResult && guidanceResult} | ||||
| 		<button class="continue" onclick={() => {pressedContinue = true}}>Continue</button> | ||||
| 	{/if} | ||||
| {/if} | ||||
| 
 | ||||
| <section> | ||||
| 	{#if rollResult && guidanceResult && pressedContinue} | ||||
| 		<h2>Final Result</h2> | ||||
| 		<p>{rollResult + guidanceResult}</p> | ||||
| 		{#if rollResult + guidanceResult >= difficultyClass} | ||||
| 			<h2 class="success">Success</h2> | ||||
| 			<a href="/present{page.url.search}">Collect your gift!</a> | ||||
| 		{:else} | ||||
| 			<h2 class="failure">Failure</h2> | ||||
| 			<button class="reset" onclick={resetPage}> Reset</button> | ||||
| 		{/if} | ||||
| 	{/if} | ||||
| </section> | ||||
| 
 | ||||
| <style> | ||||
| 		:global(body) { | ||||
|     margin: 0; | ||||
|     font-family: 'Arial', sans-serif; | ||||
|     background-color: #f4f4f4; | ||||
|     color: #1c1919; | ||||
| } | ||||
| 
 | ||||
| main { | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     justify-content: center; | ||||
|     align-items: center; | ||||
|     height: 100vh; | ||||
|     width: 100vw; | ||||
|     background-color: #a8571c; | ||||
|     color: white; | ||||
|     text-align: center; | ||||
|     overflow: hidden; | ||||
|     padding: 20px; | ||||
|     box-sizing: border-box; | ||||
| } | ||||
|     h1, h2 { | ||||
|         font-size: 2rem; | ||||
|         font-weight: bold; | ||||
|         margin: 20px 0; | ||||
|     } | ||||
| 
 | ||||
| h1, h2 { | ||||
|     font-size: 2rem; | ||||
|     font-weight: bold; | ||||
|     margin: 20px 0; | ||||
| } | ||||
|     section { | ||||
|         margin: 15px 0; | ||||
|         width: 100%; | ||||
|         max-width: 400px; | ||||
|     } | ||||
| 
 | ||||
| section { | ||||
|     margin: 15px 0; | ||||
|     width: 100%; | ||||
|     max-width: 400px; | ||||
| } | ||||
|     p { | ||||
|         font-size: 1.2rem; | ||||
|     } | ||||
| 
 | ||||
| p { | ||||
|     font-size: 1.2rem; | ||||
| } | ||||
|     button { | ||||
|         background-color: #1c1919; | ||||
|         color: white; | ||||
|         padding: 12px 25px; | ||||
|         font-size: 1.1rem; | ||||
|         font-weight: bold; | ||||
|         border: none; | ||||
|         border-radius: 5px; | ||||
|         cursor: pointer; | ||||
|         transition: background-color 0.3s ease; | ||||
|         margin-top: 15px; | ||||
|     } | ||||
| 
 | ||||
| button { | ||||
|     background-color: #1c1919; | ||||
|     color: white; | ||||
|     padding: 12px 25px; | ||||
|     font-size: 1.1rem; | ||||
|     font-weight: bold; | ||||
|     border: none; | ||||
|     border-radius: 5px; | ||||
|     cursor: pointer; | ||||
|     transition: background-color 0.3s ease; | ||||
|     margin-top: 15px; | ||||
| } | ||||
|     button:hover { | ||||
|         background-color: #333; | ||||
|     } | ||||
| 
 | ||||
| button:hover { | ||||
|     background-color: #333; | ||||
| } | ||||
|     button:disabled { | ||||
|         background-color: #aaa; | ||||
|         cursor: not-allowed; | ||||
|     } | ||||
| 
 | ||||
| button:disabled { | ||||
|     background-color: #aaa; | ||||
|     cursor: not-allowed; | ||||
| } | ||||
|     a { | ||||
|         color: #fff; | ||||
|         text-decoration: none; | ||||
|         font-weight: bold; | ||||
|         font-size: 1.2rem; | ||||
|         margin-top: 20px; | ||||
|     } | ||||
| 
 | ||||
| a { | ||||
|     color: #fff; | ||||
|     text-decoration: none; | ||||
|     font-weight: bold; | ||||
|     font-size: 1.2rem; | ||||
|     margin-top: 20px; | ||||
| } | ||||
|     a:hover { | ||||
|         text-decoration: underline; | ||||
|     } | ||||
| 
 | ||||
| a:hover { | ||||
|     text-decoration: underline; | ||||
| } | ||||
|     h2 { | ||||
|         color: #ffdf00; | ||||
|     } | ||||
| 
 | ||||
| h2 { | ||||
|     color: #ffdf00; | ||||
| } | ||||
|     h2.success { | ||||
|         color: #4CAF50; | ||||
|     } | ||||
| 
 | ||||
| h2.success { | ||||
|     color: #4CAF50; | ||||
| } | ||||
|     h2.failure { | ||||
|         color: #FF6347; | ||||
|     } | ||||
| 
 | ||||
| h2.failure { | ||||
|     color: #FF6347; | ||||
| } | ||||
|     button.reset { | ||||
|         background-color: #ff6347; | ||||
|         padding: 10px 20px; | ||||
|         font-size: 1.1rem; | ||||
|     } | ||||
| 
 | ||||
| button.reset { | ||||
|     background-color: #ff6347; | ||||
|     padding: 10px 20px; | ||||
|     font-size: 1.1rem; | ||||
| } | ||||
|     button.reset:hover { | ||||
|         background-color: #e55347; | ||||
|     } | ||||
| 
 | ||||
| button.reset:hover { | ||||
|     background-color: #e55347; | ||||
| } | ||||
|     button.continue { | ||||
|         background-color: #4CAF50; | ||||
|         padding: 10px 20px; | ||||
|         font-size: 1.1rem; | ||||
|     } | ||||
| 
 | ||||
| button.continue { | ||||
|     background-color: #4CAF50; | ||||
|     padding: 10px 20px; | ||||
|     font-size: 1.1rem; | ||||
| } | ||||
|     button.continue:hover { | ||||
|         background-color: #45a049; | ||||
|     } | ||||
| 
 | ||||
| button.continue:hover { | ||||
|     background-color: #45a049; | ||||
| } | ||||
| 
 | ||||
| section > button { | ||||
|     margin-top: 20px; | ||||
| }</style> | ||||
|     section > button { | ||||
|         margin-top: 20px; | ||||
|     } | ||||
| </style> | ||||
|  |  | |||
|  | @ -1,8 +1,23 @@ | |||
| <script lang="ts"> | ||||
| 	// Show the gift key that was in ENV during build | ||||
| 	const steamGiftKey = import.meta.env.VITE_STEAM_GIFT_KEY; | ||||
| 	import { page } from '$app/state'; | ||||
| 
 | ||||
| 	let steamGiftKey = $state<string | null>(null); | ||||
| 	let isLegit = $state<boolean>(true); | ||||
| 
 | ||||
| 	$effect(() => { | ||||
| 		const bk = page.url.searchParams.get('bk'); | ||||
| 		if (!bk) { | ||||
| 			isLegit = false; | ||||
| 			return; | ||||
| 		} | ||||
| 		steamGiftKey = atob(bk); | ||||
| 	}); | ||||
| </script> | ||||
| 
 | ||||
| <h1>Congrats!</h1> | ||||
| <h2>Here is your prize <3</h2> | ||||
| <p>{steamGiftKey}</p> | ||||
| {#if isLegit} | ||||
| 	<h1>Congrats!</h1> | ||||
| 	<h2>Enjoy your gift <3</h2> | ||||
| 	<p>{steamGiftKey}</p> | ||||
| {:else} | ||||
| 	<h1>Sorry, this gift is not for you</h1> | ||||
| {/if} | ||||
										
											Binary file not shown.
										
									
								
							|  | @ -1,4 +1,4 @@ | |||
| import adapter from 'svelte-adapter-bun' | ||||
| import adapter from '@sveltejs/adapter-node' | ||||
| import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; | ||||
| 
 | ||||
| /** @type {import('@sveltejs/kit').Config} */ | ||||
|  |  | |||
		Reference in a new issue