Non-official site for The Life Series Minecraft hardcore survival multiplayer series housing every video www.life-series.online
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

format code

Ghustvn c0a1e148 d826b264

+265 -140
+2
.prettierignore
··· 1 + pnpm-lock.yaml 2 + pnpm-workspace.yaml
+5 -4
.prettierrc
··· 1 1 { 2 - "plugins": [ 3 - "prettier-plugin-astro", 4 - "prettier-plugin-tailwindcss" 5 - ], 2 + "tabWidth": 4, 3 + "singleQuote": true, 4 + "printWidth": 100, 5 + "singleAttributePerLine": true, 6 + "plugins": ["prettier-plugin-astro", "prettier-plugin-tailwindcss"], 6 7 "overrides": [ 7 8 { 8 9 "files": "*.astro",
+2 -2
.vscode/extensions.json
··· 1 1 { 2 - "recommendations": ["astro-build.astro-vscode"], 3 - "unwantedRecommendations": [] 2 + "recommendations": ["astro-build.astro-vscode"], 3 + "unwantedRecommendations": [] 4 4 }
+9 -9
.vscode/launch.json
··· 1 1 { 2 - "version": "0.2.0", 3 - "configurations": [ 4 - { 5 - "command": "./node_modules/.bin/astro dev", 6 - "name": "Development server", 7 - "request": "launch", 8 - "type": "node-terminal" 9 - } 10 - ] 2 + "version": "0.2.0", 3 + "configurations": [ 4 + { 5 + "command": "./node_modules/.bin/astro dev", 6 + "name": "Development server", 7 + "request": "launch", 8 + "type": "node-terminal" 9 + } 10 + ] 11 11 }
+3 -3
README.md
··· 33 33 34 34 All commands are run from the root of the project, from a terminal: 35 35 36 - | Command | Action | 37 - | :------------------------ | :----------------------------------------------- | 38 - | `pnpm install` | Installs dependencies | 36 + | Command | Action | 37 + | :--------------------- | :----------------------------------------------- | 38 + | `pnpm install` | Installs dependencies | 39 39 | `pnpm dev` | Starts local dev server at `localhost:4321` | 40 40 | `pnpm build` | Build your production site to `./dist/` | 41 41 | `pnpm preview` | Preview your build locally, before deploying |
-1
astro.config.mjs
··· 16 16 }, 17 17 }, 18 18 }); 19 -
+2 -3
src/content.config.ts
··· 13 13 id: z.string(), 14 14 title: z.string(), 15 15 isMovie: z.boolean().default(false), 16 - }) 17 - ) 16 + }), 17 + ), 18 18 ), 19 19 }), 20 20 }); ··· 31 31 seasons, 32 32 members, 33 33 }; 34 -
-1
src/data/members.json
··· 90 90 "seasons": [6, 5, 4, 3, 2, 1] 91 91 } 92 92 ] 93 -
+1 -2
src/data/seasons.json
··· 3287 3287 "title": "3rd LIFE FINALE! - Massive Battle!" 3288 3288 } 3289 3289 ], 3290 - "ZombieCleo":[ 3290 + "ZombieCleo": [ 3291 3291 { 3292 3292 "id": "3tNCZroHays", 3293 3293 "title": "3rd Life - 01 - TREE.T.S.D" ··· 3328 3328 } 3329 3329 } 3330 3330 ] 3331 -
+13 -3
src/layouts/BaseLayout.astro
··· 12 12 <html lang="en"> 13 13 <Head> 14 14 <meta charset="utf-8" /> 15 - <link rel="icon" type="image/svg+xml" href="/favicon_green.svg" /> 16 - <meta name="viewport" content="width=device-width" /> 17 - <meta name="generator" content={Astro.generator} /> 15 + <link 16 + rel="icon" 17 + type="image/svg+xml" 18 + href="/favicon_green.svg" 19 + /> 20 + <meta 21 + name="viewport" 22 + content="width=device-width" 23 + /> 24 + <meta 25 + name="generator" 26 + content={Astro.generator} 27 + /> 18 28 <title>{title} · Life Series · Non-official site</title> 19 29 </Head> 20 30 <body>
+97 -52
src/layouts/SeasonsLayout.astro
··· 19 19 <html lang="en"> 20 20 <Head> 21 21 <meta charset="utf-8" /> 22 - <link rel="icon" type="image/svg+xml" href="/favicon_green.svg" /> 23 - <meta name="viewport" content="width=device-width" /> 24 - <meta name="generator" content={Astro.generator} /> 22 + <link 23 + rel="icon" 24 + type="image/svg+xml" 25 + href="/favicon_green.svg" 26 + /> 27 + <meta 28 + name="viewport" 29 + content="width=device-width" 30 + /> 31 + <meta 32 + name="generator" 33 + content={Astro.generator} 34 + /> 25 35 <title>{title} · Life Series · Non-official site</title> 26 36 </Head> 27 37 <body> 28 38 <div class="grid min-h-svh grid-cols-[auto_auto_1fr] items-start"> 29 - <div class="sticky top-0 grid h-full max-h-svh overflow-y-auto scrollbar-gutter-stable"> 39 + <div class="scrollbar-gutter-stable sticky top-0 grid h-full max-h-svh overflow-y-auto"> 30 40 <div class="self-center"> 31 - <h2 id="all-seasons-title" class="sr-only">All seasons</h2> 41 + <h2 42 + id="all-seasons-title" 43 + class="sr-only" 44 + > 45 + All seasons 46 + </h2> 32 47 <nav aria-labelledby="all-seasons-title"> 33 - <ol role="list" class="seasons-list grid gap-24 overflow-x-clip px-4 py-16"> 34 - {seasons.map((season) => ( 35 - <li> 36 - <a href={`/seasons/${season.id}`}> 37 - <Image 38 - src={getSeasonImage(season.id)} 39 - width="360" 40 - alt="" 41 - loading="eager" 42 - class="max-w-80" 43 - /> 44 - <span class="sr-only">{season.data.title}</span> 45 - </a> 46 - </li> 47 - ))} 48 + <ol 49 + role="list" 50 + class="seasons-list grid gap-24 overflow-x-clip px-4 py-16" 51 + > 52 + { 53 + seasons.map((season) => ( 54 + <li> 55 + <a href={`/seasons/${season.id}`}> 56 + <Image 57 + src={getSeasonImage(season.id)} 58 + width="360" 59 + alt="" 60 + loading="eager" 61 + class="max-w-80" 62 + /> 63 + <span class="sr-only">{season.data.title}</span> 64 + </a> 65 + </li> 66 + )) 67 + } 48 68 </ol> 49 69 </nav> 50 70 </div> 51 71 </div> 52 - <div class="sticky top-0 grid h-full max-h-svh overflow-y-auto pl-2 scrollbar-gutter-stable"> 72 + <div 73 + class="scrollbar-gutter-stable sticky top-0 grid h-full max-h-svh overflow-y-auto pl-2" 74 + > 53 75 <div class="self-center"> 54 - <h2 id="all-members-title" class="sr-only">All members</h2> 76 + <h2 77 + id="all-members-title" 78 + class="sr-only" 79 + > 80 + All members 81 + </h2> 55 82 <nav aria-labelledby="all-members-title"> 56 - <ul role="list" class="py-16"> 57 - {members.map((member) => { 58 - const notPlaying = !Object.keys(season.data.videos).includes(member.data.name); 83 + <ul 84 + role="list" 85 + class="py-16" 86 + > 87 + { 88 + members.map((member) => { 89 + const notPlaying = !Object.keys(season.data.videos).includes( 90 + member.data.name, 91 + ); 59 92 60 - return ( 61 - <li> 62 - <a 63 - href={`/seasons/${season.id}/${member.data.name}`} 64 - class:list={['w-full py-4', { 'grayscale-75': notPlaying }]} 65 - > 66 - <div class="flex items-center gap-8"> 67 - <Image 68 - src={getMemberImage(member.data.name)} 69 - width="64" 70 - height="64" 71 - alt="" 72 - loading="eager" 73 - class="max-h-32 max-w-32 rounded-full" 74 - /> 75 - <span class:list={[{ 'line-through decoration-2': notPlaying }]}> 76 - {member.data.name} 77 - </span> 78 - {!Object.keys(season.data.videos).includes(member.data.name) && ( 79 - <span class="sr-only">, not playing</span> 80 - )} 81 - </div> 82 - </a> 83 - </li> 84 - ); 85 - })} 93 + return ( 94 + <li> 95 + <a 96 + href={`/seasons/${season.id}/${member.data.name}`} 97 + class:list={[ 98 + 'w-full py-4', 99 + { 100 + 'grayscale-75': notPlaying, 101 + }, 102 + ]} 103 + > 104 + <div class="flex items-center gap-8"> 105 + <Image 106 + src={getMemberImage(member.data.name)} 107 + width="64" 108 + height="64" 109 + alt="" 110 + loading="eager" 111 + class="max-h-32 max-w-32 rounded-full" 112 + /> 113 + <span 114 + class:list={[ 115 + { 116 + 'line-through decoration-2': 117 + notPlaying, 118 + }, 119 + ]} 120 + > 121 + {member.data.name} 122 + </span> 123 + {!Object.keys(season.data.videos).includes( 124 + member.data.name, 125 + ) && <span class="sr-only">, not playing</span>} 126 + </div> 127 + </a> 128 + </li> 129 + ); 130 + }) 131 + } 86 132 </ul> 87 133 </nav> 88 134 </div> ··· 91 137 </div> 92 138 </body> 93 139 </html> 94 -
+22 -15
src/pages/index.astro
··· 11 11 <main class="grid min-h-svh items-center justify-items-center overflow-x-hidden p-32"> 12 12 <h1 class="sr-only">Life Series · Non-official site</h1> 13 13 <nav class="w-full max-w-636"> 14 - <ol role="list" class="seasons-list grid grid-cols-[repeat(auto-fit,minmax(min(180px,100%),1fr))] place-items-center gap-48"> 15 - {seasons.map((season) => ( 16 - <li> 17 - <a href={`/seasons/${season.id}`}> 18 - <Image 19 - src={getSeasonImage(season.id)} 20 - width="360" 21 - alt="" 22 - loading="eager" 23 - class="max-w-180" 24 - /> 25 - <span class="sr-only">{season.data.title} (Season {season.data.seasonNumber})</span> 26 - </a> 27 - </li> 28 - ))} 14 + <ol 15 + role="list" 16 + class="seasons-list grid grid-cols-[repeat(auto-fit,minmax(min(180px,100%),1fr))] place-items-center gap-48" 17 + > 18 + { 19 + seasons.map((season) => ( 20 + <li> 21 + <a href={`/seasons/${season.id}`}> 22 + <Image 23 + src={getSeasonImage(season.id)} 24 + width="360" 25 + alt="" 26 + loading="eager" 27 + class="max-w-180" 28 + /> 29 + <span class="sr-only"> 30 + {season.data.title} (Season {season.data.seasonNumber}) 31 + </span> 32 + </a> 33 + </li> 34 + )) 35 + } 29 36 </ol> 30 37 </nav> 31 38 </main>
+4 -4
src/pages/seasons/[season_id].astro
··· 16 16 const title = `${season.data.title} (S${season.data.seasonNumber})`; 17 17 --- 18 18 19 - <SeasonsLayout title={title} season={season}> 20 - 21 - </SeasonsLayout> 22 - 19 + <SeasonsLayout 20 + title={title} 21 + season={season} 22 + />
+45 -26
src/pages/seasons/[season_id]/[member_name].astro
··· 31 31 const title = `${member.data.name} · ${season.data.title} (S${season.data.seasonNumber})`; 32 32 --- 33 33 34 - <SeasonsLayout title={title} season={season}> 34 + <SeasonsLayout 35 + title={title} 36 + season={season} 37 + > 35 38 <div class="py-80"> 36 - {movie && ( 37 - <h2 class="sr-only">The Movie</h2> 38 - <YouTube 39 - id={movie.id} 40 - title={movie.title} 41 - posterQuality="max" 42 - class="movie-video rounded-lg" 43 - /> 44 - )} 45 - {sessions.length > 0 && ( 46 - <h2 id="session-title" class="sr-only">Sessions</h2> 47 - <ul 48 - role="list" 49 - aria-labelledby="session-title" 50 - class="space-y-64" 51 - > 52 - {sessions.map((session) => ( 53 - <li> 54 - <h3 class="pb-8 text-xl">{session.title}</h3> 55 - <YouTube id={session.id} title={session.title} class="rounded" /> 56 - </li> 57 - ))} 58 - </ul> 59 - )} 39 + { 40 + movie && ( 41 + <> 42 + <h2 class="sr-only">The Movie</h2> 43 + <YouTube 44 + id={movie.id} 45 + title={movie.title} 46 + posterQuality="max" 47 + class="movie-video rounded-lg" 48 + /> 49 + </> 50 + ) 51 + } 52 + { 53 + sessions.length > 0 && ( 54 + <> 55 + <h2 56 + id="session-title" 57 + class="sr-only" 58 + > 59 + Sessions 60 + </h2> 61 + <ul 62 + role="list" 63 + aria-labelledby="session-title" 64 + class="space-y-64" 65 + > 66 + {sessions.map((session) => ( 67 + <li> 68 + <h3 class="pb-8 text-xl">{session.title}</h3> 69 + <YouTube 70 + id={session.id} 71 + title={session.title} 72 + class="rounded" 73 + /> 74 + </li> 75 + ))} 76 + </ul> 77 + </> 78 + ) 79 + } 60 80 </div> 61 81 </SeasonsLayout> 62 -
+54 -12
src/styles/global.css
··· 1 1 @layer base, tw.theme, tw.utilities; 2 2 3 - @import "tailwindcss/theme.css" layer(tw.theme); 4 - @import "tailwindcss/utilities.css" layer(tw.utilities); 3 + @import 'tailwindcss/theme.css' layer(tw.theme); 4 + @import 'tailwindcss/utilities.css' layer(tw.utilities); 5 5 6 6 @theme { 7 7 --spacing: 1px; 8 8 9 9 --spring-transition-duration: 250ms; 10 - --spring-transition-timing-function: linear(0, 0.01 1%, 0.041 2.1%, 0.091 3.2%, 0.163 4.4%, 0.329 6.6%, 0.83 12.5%, 0.955 14.2%, 1.056 15.8%, 1.138 17.4%, 1.2 19%, 1.243 20.6%, 1.268 22.2%, 1.275 24.5%, 1.251 27%, 1.204 29.6%, 1.059 35.8%, 0.999 38.8%, 0.951 42.2%, 0.928 45.6%, 0.931 50.8%, 1 62.5%, 1.019 69%, 1.019 74.7%, 0.996 90%, 1); 10 + --spring-transition-timing-function: linear( 11 + 0, 12 + 0.01 1%, 13 + 0.041 2.1%, 14 + 0.091 3.2%, 15 + 0.163 4.4%, 16 + 0.329 6.6%, 17 + 0.83 12.5%, 18 + 0.955 14.2%, 19 + 1.056 15.8%, 20 + 1.138 17.4%, 21 + 1.2 19%, 22 + 1.243 20.6%, 23 + 1.268 22.2%, 24 + 1.275 24.5%, 25 + 1.251 27%, 26 + 1.204 29.6%, 27 + 1.059 35.8%, 28 + 0.999 38.8%, 29 + 0.951 42.2%, 30 + 0.928 45.6%, 31 + 0.931 50.8%, 32 + 1 62.5%, 33 + 1.019 69%, 34 + 1.019 74.7%, 35 + 0.996 90%, 36 + 1 37 + ); 11 38 } 12 39 13 40 @utility scrollbar-gutter-stable { ··· 89 116 } 90 117 91 118 @media (prefers-reduced-motion: no-preference) { 92 - li:nth-child(1) { --angle: 3deg; } 93 - li:nth-child(2) { --angle: -2deg; } 94 - li:nth-child(3) { --angle: 2deg; } 95 - li:nth-child(4) { --angle: -1deg; } 96 - li:nth-child(5) { --angle: 2deg; } 97 - li:nth-child(6) { --angle: -3deg; } 98 - li:nth-child(7) { --angle: 1deg; } 119 + li:nth-child(1) { 120 + --angle: 3deg; 121 + } 122 + li:nth-child(2) { 123 + --angle: -2deg; 124 + } 125 + li:nth-child(3) { 126 + --angle: 2deg; 127 + } 128 + li:nth-child(4) { 129 + --angle: -1deg; 130 + } 131 + li:nth-child(5) { 132 + --angle: 2deg; 133 + } 134 + li:nth-child(6) { 135 + --angle: -3deg; 136 + } 137 + li:nth-child(7) { 138 + --angle: 1deg; 139 + } 99 140 100 141 a { 101 - transition: scale var(--spring-transition-duration), rotate var(--spring-transition-duration); 142 + transition: 143 + scale var(--spring-transition-duration), 144 + rotate var(--spring-transition-duration); 102 145 transition-timing-function: var(--spring-transition-timing-function); 103 146 } 104 147 ··· 116 159 } 117 160 } 118 161 } 119 -
+6 -3
src/utils/images.ts
··· 1 1 import type { ImageMetadata } from 'astro'; 2 2 3 3 export async function getMemberImage(member: string) { 4 - const memberImages = import.meta.glob<{ default: ImageMetadata }>('/src/assets/images/members/*'); 4 + const memberImages = import.meta.glob<{ default: ImageMetadata }>( 5 + '/src/assets/images/members/*', 6 + ); 5 7 return memberImages[`/src/assets/images/members/${member}.jpg`](); 6 8 } 7 9 8 10 export async function getSeasonImage(season: string) { 9 - const seasonImages = import.meta.glob<{ default: ImageMetadata }>('/src/assets/images/seasons/*'); 11 + const seasonImages = import.meta.glob<{ default: ImageMetadata }>( 12 + '/src/assets/images/seasons/*', 13 + ); 10 14 return seasonImages[`/src/assets/images/seasons/${season}.webp`](); 11 15 } 12 -