Skip to content

Commit b28067f

Browse files
committed
📺 Add a Homepage!
1 parent b11d97c commit b28067f

22 files changed

+550
-39
lines changed

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,8 @@
3636
"unplugin-icons": "^0.19.0",
3737
"vite": "^5.0.3"
3838
},
39-
"type": "module"
39+
"type": "module",
40+
"dependencies": {
41+
"svelte-youtube-embed": "^0.3.0"
42+
}
4043
}

src/app.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/// <reference types="@svelteness/kit-docs/globals" />
2+
import type { CompositionEventHandler } from 'svelte/elements';
23

34
// See https://kit.svelte.dev/docs/types#app
45
// for information about these interfaces
@@ -10,6 +11,13 @@ declare global {
1011
// interface PageState {}
1112
// interface Platform {}
1213
}
14+
15+
declare namespace svelteHTML {
16+
interface HTMLProps<T> {
17+
'on:enter'?: CompositionEventHandler<T>;
18+
'on:exit'?: CompositionEventHandler<T>;
19+
}
20+
}
1321
}
1422

1523
export {};

src/app.html

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,19 @@
44
<meta charset="utf-8" />
55
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
66
<meta name="viewport" content="width=device-width, initial-scale=1" />
7-
8-
<script>
9-
const key = 'svelteness::color-scheme';
10-
const scheme = localStorage[key];
11-
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
12-
if (scheme === 'dark' || (scheme !== 'light' && prefersDark)) {
13-
document.documentElement.classList.add('dark');
14-
} else {
15-
document.documentElement.classList.remove('dark');
16-
}
17-
</script>
18-
19-
%sveltekit.head%
7+
8+
<script>
9+
const key = 'svelteness::color-scheme';
10+
const scheme = localStorage[key];
11+
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
12+
if (scheme === 'dark' || (scheme !== 'light' && prefersDark)) {
13+
document.documentElement.classList.add('dark');
14+
} else {
15+
document.documentElement.classList.remove('dark');
16+
}
17+
</script>
18+
19+
%sveltekit.head%
2020
</head>
2121
<body data-sveltekit-preload-data="hover">
2222
<div style="display: contents">%sveltekit.body%</div>

src/components/VideoCarousel.svelte

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<script lang="ts" context="module">
2+
import { Button } from '@svelteness/kit-docs';
3+
</script>
4+
5+
<script lang="ts">
6+
import Youtube from 'svelte-youtube-embed';
7+
import { writable } from 'svelte/store';
8+
9+
let index = writable(0);
10+
11+
const VIDEOS = [
12+
'fthlphRmsjY',
13+
'dd7pqAPd-p0',
14+
'M2R3zgvbZ30',
15+
'0UCrI7NJ5KI',
16+
'0xPyRA-he5c',
17+
'CO2kYUMpYPk',
18+
'fs0NUGmsa10',
19+
'4VlwyI0EHo4'
20+
];
21+
22+
async function getYoutubeVideoTitle(id: string) {
23+
const res = await fetch(
24+
`//www.youtube.com/oembed?url=https://www.youtube.com/watch?v=${id}&format=json`
25+
);
26+
const videoInfo = await res.json();
27+
28+
return videoInfo?.title;
29+
}
30+
</script>
31+
32+
<div class="container">
33+
<Youtube id={VIDEOS[$index]} animations={false} />
34+
<div class="grid">
35+
{#each VIDEOS as id}
36+
<!-- svelte-ignore a11y-click-events-have-key-events -->
37+
<!-- svelte-ignore a11y-no-static-element-interactions -->
38+
<div
39+
class="thumbnail-container"
40+
on:click={(e) => {
41+
index.set(VIDEOS.indexOf(id));
42+
}}
43+
>
44+
<Button class="thumbnail-button">
45+
<div
46+
class="thumbnail-image"
47+
style={`background-image: url(https://img.youtube.com/vi/${id}/0.jpg);`}
48+
></div>
49+
{#await getYoutubeVideoTitle(id)}
50+
<p>Loading...</p>
51+
{:then title}
52+
<p>{title}</p>
53+
{:catch error}
54+
<!-- -->
55+
{/await}
56+
</Button>
57+
</div>
58+
{/each}
59+
</div>
60+
</div>
61+
62+
<style>
63+
.container {
64+
display: flex;
65+
flex-direction: column;
66+
justify-content: center;
67+
align-items: stretch;
68+
}
69+
.grid {
70+
width: 100%;
71+
display: grid;
72+
grid-template-columns: repeat(auto-fill, minmax(256px, 1fr));
73+
margin-top: 2rem;
74+
}
75+
p {
76+
text-align: center;
77+
text-transform: capitalize;
78+
}
79+
.thumbnail-container {
80+
display: flex;
81+
flex-direction: column;
82+
align-items: center;
83+
}
84+
.thumbnail-image {
85+
min-height: 148px;
86+
aspect-ratio: 16 / 9;
87+
background-size: cover;
88+
background-position: center;
89+
border-radius: 8px;
90+
box-shadow: 2px 2px 8px -4px black;
91+
}
92+
:global(.you__tube) {
93+
border-radius: 16px;
94+
box-shadow: 2px 2px 8px -4px black;
95+
}
96+
:global(.v__title) {
97+
text-align: left;
98+
font-size: 1.5rem;
99+
backdrop-filter: blur(4px);
100+
background: rgba(var(--kd-color-elevate) / 0.5) !important;
101+
padding-bottom: 0.25rem;
102+
text-transform: capitalize;
103+
}
104+
</style>

src/kit-docs/CodeFence.svelte

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
55
import clsx from 'clsx';
66
7-
// @ts-expect-error
87
import CopyFileIcon from '~icons/ri/file-copy-line';
98
109
export let lang: string | null = null;

src/kit-docs/custom/Admonition.svelte

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
11
<script lang="ts">
22
import clsx from 'clsx';
33
4-
// @ts-expect-error
54
import NoteIcon from '~icons/ri/sticky-note-fill';
6-
// @ts-expect-error
75
import HeroiconsSolidCode from '~icons/heroicons-solid/code';
8-
// @ts-expect-error
96
import TipIcon from '~icons/ri/lightbulb-flash-fill';
10-
// @ts-expect-error
117
import WarningIcon from '~icons/ri/error-warning-fill';
12-
// @ts-expect-error
138
import DangerIcon from '~icons/ri/skull-2-fill';
14-
// @ts-expect-error
159
import ExperimentalIcon from '~icons/ri/test-tube-fill';
10+
1611
import { getI18nContext } from '@svelteness/kit-docs';
1712
1813
export let type: 'note' | 'info' | 'tip' | 'warning' | 'danger' | 'experimental';

src/lib/inView.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
interface ISetObserverOptions {
2+
root?: HTMLElement;
3+
top?: number;
4+
bottom?: number;
5+
}
6+
7+
export default function inView(node: HTMLElement, options: ISetObserverOptions = {}) {
8+
let observer: IntersectionObserver;
9+
10+
const handleIntersect: IntersectionObserverCallback = (e) => {
11+
const v = e[0].isIntersecting ? 'enter' : 'exit';
12+
node.dispatchEvent(new CustomEvent(v));
13+
};
14+
15+
const setObserver = ({ root, top, bottom }: ISetObserverOptions) => {
16+
const marginTop = top ? top * -1 : 0;
17+
const marginBottom = bottom ? bottom * -1 : 0;
18+
const rootMargin = `${marginTop}px 0px ${marginBottom}px 0px`;
19+
const options = { root, rootMargin };
20+
if (observer) observer.disconnect();
21+
observer = new IntersectionObserver(handleIntersect, options);
22+
observer.observe(node);
23+
};
24+
25+
setObserver(options);
26+
27+
return {
28+
update(args: ISetObserverOptions) {
29+
setObserver(args);
30+
},
31+
32+
destroy() {
33+
if (observer) observer.disconnect();
34+
}
35+
};
36+
}

src/lib/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
// place files you want to import through the `$lib` alias in this folder.
2+
export { default as inView } from './inView';

src/routes/+layout.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export const prerender = true;
55
/** @type {import('./$types').LayoutLoad} */
66
export const load = createKitDocsLoader({
77
sidebar: {
8-
'/': null,
8+
'/home': '/home',
99
'/docs': '/docs'
1010
}
1111
});

src/routes/+layout.svelte

Lines changed: 64 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,40 @@
1-
<script>
1+
<script lang="ts">
22
import '@svelteness/kit-docs/client/polyfills/index.js';
33
import '@svelteness/kit-docs/client/styles/normalize.css';
44
import '@svelteness/kit-docs/client/styles/fonts.css';
55
import '@svelteness/kit-docs/client/styles/theme.css';
66
import '$lib/styles/kit-docs.css';
77
88
import { page } from '$app/stores';
9-
import AnimatedJavaBanner from '$img/Animated Java 2024 Banner.svg?raw';
9+
10+
import DiscordIcon from '~icons/ri/discord-fill';
11+
import GithubIcon from '~icons/ri/github-fill';
1012
1113
import {
1214
Button,
1315
KitDocs,
1416
KitDocsLayout,
1517
SocialLink,
16-
createSidebarContext
18+
createSidebarContext,
19+
type NavbarConfig
1720
} from '@svelteness/kit-docs';
21+
import type { LayoutData } from './$types';
1822
19-
/** @type {import('./$types').LayoutData} */
20-
export let data;
23+
export let data: LayoutData;
2124
2225
$: ({ meta, sidebar } = data);
2326
24-
/** @type {import('@svelteness/kit-docs').NavbarConfig} */
25-
const navbar = {
26-
links: [{ title: 'Documentation', slug: '/docs', match: /\/docs/ }]
27+
const navbar: NavbarConfig = {
28+
links: [
29+
{ title: 'Home', slug: '/home', match: /\/home/ },
30+
{ title: 'Documentation', slug: '/docs', match: /\/docs/ }
31+
]
2732
};
2833
2934
const { activeCategory } = createSidebarContext(sidebar);
3035
3136
$: category = $activeCategory ? `${$activeCategory}: ` : '';
32-
$: title = meta ? `${category}${meta.title} | KitDocs` : null;
37+
$: title = meta ? `${category}${meta.title} | Animated Java` : 'Animated Java';
3338
$: description = meta?.description;
3439
</script>
3540

@@ -48,20 +53,31 @@
4853
<KitDocsLayout {navbar} {sidebar}>
4954
<div class="logo" slot="navbar-left">
5055
<Button href="/">
51-
{@html AnimatedJavaBanner}
56+
<div class="header-container">
57+
<!-- svelte-ignore a11y-missing-attribute -->
58+
<img src="/img/animated_java_icon.svg" />
59+
<div>
60+
<h1>Animated Java</h1>
61+
</div>
62+
</div>
5263
</Button>
5364
</div>
5465

5566
<slot />
56-
<div class="header" slot="main-top">
57-
<div class="header-wip-warning">
67+
68+
<div class="footer" slot="main-bottom">
69+
<div class="header-wip-warning" style="margin-top: 16px;">
5870
⚠️ This website is a work in progress. Some pages may be incomplete or missing. ⚠️
5971
</div>
60-
</div>
61-
<div class="footer" slot="main-bottom">
6272
<div class="footer-social">
63-
<SocialLink type="discord" href="https://discord.com/invite/jFgY4PXZfp" />
64-
<SocialLink type="gitHub" href="https://github.com/Animated-Java/animated-java" />
73+
<div class="social-container">
74+
<Button title="Join our Discord Server!">
75+
<svelte:component this={DiscordIcon} class="social-icon" />
76+
</Button>
77+
<Button title="Check out our Source Code!">
78+
<svelte:component this={GithubIcon} class="social-icon" />
79+
</Button>
80+
</div>
6581
</div>
6682
</div>
6783
</KitDocsLayout>
@@ -103,4 +119,36 @@
103119
justify-content: center;
104120
margin-bottom: 2rem;
105121
}
122+
123+
.header-container {
124+
display: flex;
125+
align-items: center;
126+
margin-bottom: 2rem;
127+
position: relative;
128+
top: 16px;
129+
}
130+
.header-container div {
131+
display: flex;
132+
flex-direction: column;
133+
justify-content: center;
134+
margin-left: 1rem;
135+
}
136+
.header-container img {
137+
width: 48px;
138+
border-radius: 8px;
139+
box-shadow: 2px 2px 4px -2px black;
140+
}
141+
.header-container h1 {
142+
font-size: 1.5rem;
143+
}
144+
145+
.social-container {
146+
display: flex;
147+
flex-direction: row;
148+
justify-content: center;
149+
}
150+
151+
.social-container > :global(button) {
152+
font-size: 2rem;
153+
}
106154
</style>

src/routes/+page.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ export const prerender = true;
44

55
/** @type {import('./$types').PageLoad} */
66
export function load() {
7-
throw redirect(307, '/docs/introduction/what-is-animated-java');
7+
throw redirect(307, '/home');
88
}

0 commit comments

Comments
 (0)