Skip to content
Draft
Show file tree
Hide file tree
Changes from 19 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/svelte.dev/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
"@supabase/supabase-js": "^2.43.4",
"@sveltejs/adapter-vercel": "^5.10.2",
"@sveltejs/enhanced-img": "^0.8.1",
"@sveltejs/kit": "^2.44.0",
"@sveltejs/kit": "^2.48.3",
"@sveltejs/site-kit": "workspace:*",
"@sveltejs/vite-plugin-svelte": "^6.1.3",
"@types/cookie": "^0.6.0",
Expand All @@ -74,7 +74,7 @@
"satori": "^0.10.13",
"satori-html": "^0.3.2",
"sv": "^0.9.2",
"svelte": "^5.40.0",
"svelte": "^5.43.1",
"svelte-check": "^4.3.1",
"svelte-preprocess": "^6.0.3",
"tiny-glob": "^0.2.9",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,12 @@

body {
--border-radius: 4px;
--font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell,
--font:
-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell,
'Open Sans', 'Helvetica Neue', sans-serif;
--font-mono: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas,
'DejaVu Sans Mono', monospace;
--font-mono:
ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, 'DejaVu Sans Mono',
monospace;
background: var(--bg-1);
color: var(--fg-1);
font-family: var(--font);
Expand Down
7 changes: 7 additions & 0 deletions apps/svelte.dev/src/lib/remote/auth.remote.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { getRequestEvent, query } from '$app/server';
import * as session from '$lib/db/session';

export const get_user = query(() => {
const { request } = getRequestEvent();
return session.from_cookie(request.headers.get('cookie'));
});
13 changes: 0 additions & 13 deletions apps/svelte.dev/src/routes/(authed)/+layout.server.js
Original file line number Diff line number Diff line change
@@ -1,14 +1 @@
import * as session from '$lib/db/session';

export const prerender = false;

/** @type {import('@sveltejs/adapter-vercel').Config} */
export const config = {
runtime: 'nodejs20.x' // see https://github.com/sveltejs/svelte/pull/9136
};

export async function load({ request }) {
return {
user: await session.from_cookie(request.headers.get('cookie'))
};
}
20 changes: 0 additions & 20 deletions apps/svelte.dev/src/routes/(authed)/apps/+page.server.js

This file was deleted.

40 changes: 25 additions & 15 deletions apps/svelte.dev/src/routes/(authed)/apps/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
import { ago } from '$lib/time';
import { goto, invalidateAll } from '$app/navigation';
import { get_app_context } from '../app-context.js';

let { data } = $props();
import { get_user } from '$lib/remote/auth.remote.js';
import { get_gists } from './data.remote.js';
import { page } from '$app/state';

const { login, logout } = get_app_context();

Expand All @@ -14,6 +15,17 @@
let selected: string[] = $state([]);
const selecting = $derived(selected.length > 0);

const user = $derived(await get_user());

const search = page.url.searchParams.get('search') ?? '';

const { gists, next } = $derived(
await get_gists({
search,
offset: parseInt(page.url.searchParams.get('offset') ?? '0')
})
);

async function destroy_selected() {
const confirmed = confirm(
`Are you sure you want to delete ${selected.length} ${
Expand Down Expand Up @@ -54,17 +66,17 @@
</svelte:head>

<div class="apps">
{#if data.user}
{#if user}
<header>
<h1>Your apps</h1>
<div class="user">
<img
class="avatar"
alt="{data.user.github_name || data.user.github_login} avatar"
src={data.user.github_avatar_url}
alt="{user.github_name || user.github_login} avatar"
src={user.github_avatar_url}
/>
<span>
{data.user.github_name || data.user.github_login}
{user.github_name || user.github_login}
(<a onclick={(e) => (e.preventDefault(), logout())} href="/auth/logout">log out</a>)
</span>
</div>
Expand Down Expand Up @@ -92,15 +104,15 @@
placeholder="Search"
aria-label="Search"
name="search"
value={data.search}
value={page.url.searchParams.get('search')}
/>
</form>
{/if}
</div>

{#if data.gists.length > 0}
{#if gists.length > 0}
<ul class:selecting>
{#each data.gists as gist}
{#each gists as gist}
<li class:selected={selected.includes(gist.id)}>
<a href={selecting ? undefined : `/playground/${gist.id}`}>
<h2>{gist.name}</h2>
Expand All @@ -121,12 +133,10 @@

<div class="pagination">
<!-- TODO more sophisticated pagination -->
{#if data.next !== null && !selecting}
<a
href="/apps?offset={data.next}{data.search
? `&search=${encodeURIComponent(data.search)}`
: ''}">Next page...</a
>
{#if next !== null && !selecting}
<a href="/apps?offset={next}{search ? `&search=${encodeURIComponent(search)}` : ''}">
Next page...
</a>
{/if}
</div>
{:else}
Expand Down
20 changes: 20 additions & 0 deletions apps/svelte.dev/src/routes/(authed)/apps/data.remote.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { query } from '$app/server';
import * as gist from '$lib/db/gist';
import { get_user } from '$lib/remote/auth.remote';
import * as v from 'valibot';

export const get_gists = query(
v.object({
search: v.string(),
offset: v.optional(v.number())
}),
async ({ search, offset = 0 }) => {
const user = await get_user();

if (!user) {
return { gists: [], next: null };
}

return gist.list(user, { offset, search });
}
);
5 changes: 3 additions & 2 deletions apps/svelte.dev/src/routes/(authed)/apps/destroy/+server.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import * as session from '$lib/db/session';
import * as gist from '$lib/db/gist';
import { get_user } from '$lib/remote/auth.remote.js';

// TODO this should be a `form` or `command`
export async function POST({ request }) {
const user = await session.from_cookie(request.headers.get('cookie'));
const user = await get_user();
if (!user) return new Response(undefined, { status: 401 });

const body = await request.json();
Expand Down
18 changes: 0 additions & 18 deletions apps/svelte.dev/src/routes/(authed)/playground/[id]/+page.js

This file was deleted.

This file was deleted.

39 changes: 26 additions & 13 deletions apps/svelte.dev/src/routes/(authed)/playground/[id]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,26 @@
import { compress_and_encode_text, decode_and_decompress_text } from './gzip.js';
import { page } from '$app/state';
import type { File } from '@sveltejs/repl/workspace';
import { get_example, get_example_index, get_gist } from '../data.remote.js';
import { get_user } from '$lib/remote/auth.remote.js';

let { data } = $props();
let { data, params } = $props();

// TODO dewaterfall
const examples = await get_example_index();
const slugs = examples
.map((section) => section.examples)
.flat()
.map((example) => example.slug);

const gist = $derived(
slugs.includes(params.id) ? await get_example(params.id) : await get_gist(params.id)
);

const STORAGE_KEY = 'svelte:playground';

let repl = $state() as ReturnType<typeof Repl>;
let name = $state(data.gist.name);
let name = $state(gist.name);
let modified = $state(false);
let setting_hash: any = null;

Expand All @@ -28,7 +41,7 @@
const can_escape = browser && !page.url.hash;

afterNavigate(() => {
name = data.gist.name;
name = gist.name;
set_files();
});

Expand All @@ -52,7 +65,7 @@
if (!hash && !saved) {
repl?.set({
// TODO make this munging unnecessary (using JSON instead of structuredClone for better browser compat)
files: JSON.parse(JSON.stringify(data.gist.components)).map(munge),
files: JSON.parse(JSON.stringify(gist.components)).map(munge),
tailwind: false // TODO
});

Expand Down Expand Up @@ -162,22 +175,22 @@
if (
!was_modified &&
modified &&
name === data.gist.name &&
data.examples.some((section) =>
section.examples.some((example) => example.slug === data.gist.id)
)
name === gist.name &&
examples.some((section) => section.examples.some((example) => example.slug === gist.id))
) {
name = `${name} (edited)`;
}
}

const relaxed = $derived(data.gist.relaxed || (data.user && data.user.id === data.gist.owner));
const user = $derived(await get_user());

const relaxed = $derived(gist.relaxed || (user && user.id === gist.owner));
</script>

<svelte:head>
<title>{name} • Playground • Svelte</title>

<meta name="twitter:title" content="{data.gist.name} • Playground • Svelte" />
<meta name="twitter:title" content="{gist.name} • Playground • Svelte" />
<meta name="twitter:description" content="Web development for the rest of us" />
<meta name="description" content="Interactive Svelte playground" />
</svelte:head>
Expand All @@ -203,9 +216,9 @@

<div class="repl-outer">
<AppControls
examples={data.examples}
user={data.user}
gist={data.gist}
{examples}
{user}
{gist}
forked={handle_fork}
saved={handle_save}
{repl}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
import SecondaryNav from '$lib/components/SecondaryNav.svelte';
import type { File } from '@sveltejs/repl/workspace';
import type { Repl } from '@sveltejs/repl';
import { get_user } from '$lib/remote/auth.remote';

interface Props {
examples: Array<{ title: string; examples: any[] }>;
user: User | null;
repl: ReturnType<typeof Repl>;
gist: Gist;
name: string;
Expand All @@ -25,7 +25,6 @@
let {
name = $bindable(),
modified = $bindable(),
user,
repl,
gist,
examples,
Expand All @@ -44,6 +43,8 @@
return new Promise((f) => setTimeout(f, ms));
}

const user = $derived(await get_user());

const canSave = $derived(user && gist && gist.owner === user.id);

function handleKeydown(event: KeyboardEvent) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import { page } from '$app/state';
import { decode_and_decompress_text } from '../gzip.js';
import type { File } from '@sveltejs/repl/workspace';
import { get_user } from '$lib/remote/auth.remote.js';

let { data } = $props();

Expand Down Expand Up @@ -51,7 +52,9 @@
set_files();
});

const relaxed = $derived(data.gist.relaxed || (data.user && data.user.id === data.gist.owner));
const user = $derived(await get_user());

const relaxed = $derived(data.gist.relaxed || (user && user.id === data.gist.owner));
</script>

<svelte:head>
Expand Down
Loading
Loading