add theme example, did -> handle resolution, more info on state

This commit is contained in:
Badtz 2025-04-02 18:13:50 -07:00
parent aeee9019ab
commit 59107f0eef
6 changed files with 67 additions and 38 deletions

View file

@ -3,13 +3,4 @@
scale: 2; scale: 2;
} }
html, @custom-variant dark (&:where(.dark, .dark *));
body {
height: 100%;
margin: 0;
overflow: hidden; /* Prevent scrolling */
}
#svelte {
height: 100%;
}

View file

@ -5,8 +5,16 @@ export const userState = $state<{
rpc: XRPC | undefined; rpc: XRPC | undefined;
agent: OAuthUserAgent | undefined; agent: OAuthUserAgent | undefined;
did: string | undefined; did: string | undefined;
handle: string | undefined;
}>({ }>({
rpc: undefined, rpc: undefined,
agent: undefined, agent: undefined,
did: undefined did: undefined,
handle: undefined
});
export const style = $state<{
theme: 'light' | 'dark';
}>({
theme: 'light'
}); });

View file

@ -28,15 +28,21 @@ async function resolvePDS(did: string) {
return pds; return pds;
} }
export async function resolveHandle(handle: string) { export async function resolveDID(handle: string) {
if (!handle.includes('.')) { if (!handle.includes('.')) {
throw new Error(`Invalid DID: ${handle}`); throw new Error(`Invalid DID: ${handle}`);
} }
return await handleResolver.resolve(handle as `${string}.${string}`); return await handleResolver.resolve(handle as `${string}.${string}`);
} }
export async function resolveHandle(did: string) {
const data = await didDocumentResolver.resolve(did as `did:plc:${string}` | `did:web:${string}`);
return await (data.alsoKnownAs?.[0] ?? null);
}
export async function createRPC(did: string) { export async function createRPC(did: string) {
if (!did.startsWith('did:')) did = await resolveHandle(did); if (!did.startsWith('did:')) did = await resolveDID(did);
const pds = await resolvePDS(did); const pds = await resolvePDS(did);
if (!pds) { if (!pds) {

View file

@ -10,7 +10,7 @@
resolveFromIdentity resolveFromIdentity
} from '@atcute/oauth-browser-client'; } from '@atcute/oauth-browser-client';
import { userState } from '$lib/state.svelte'; import { style, userState } from '$lib/state.svelte';
import { config } from '$lib/util'; import { config } from '$lib/util';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
@ -51,6 +51,15 @@
userState.did = undefined; userState.did = undefined;
} }
async function toggleTheme() {
if (style.theme === 'dark') {
style.theme = 'light';
} else {
style.theme = 'dark';
}
document.getElementById('theme')?.setAttribute('class', style.theme);
}
onMount(async () => { onMount(async () => {
console.log('mounted'); console.log('mounted');
config(); config();
@ -71,27 +80,43 @@
// } else { // } else {
// console.log('userState.rpc is undefined'); // console.log('userState.rpc is undefined');
// } // }
console.log(userState);
}); });
</script> </script>
<ul class="flex space-x-4 bg-gray-800 p-4 text-white"> <nav
<li><a href="/" aria-label="home" class="icon-[mynaui--home] text-gray-300"></a></li> aria-label="nav"
<li> class="text-grey-300 sticky top-0 z-10 flex flex-row place-content-between bg-gray-800 p-4 text-gray-300"
<a href="/landing" aria-label="landing" class="icon-[mynaui--external-link] text-gray-300"></a> >
</li> <ul class="flex flex-row space-x-4">
<li><a href="/search" aria-label="search" class="icon-[mynaui--search] text-gray-300"></a></li> <li><a href="/" aria-label="home" class="icon-[mynaui--home]"></a></li>
<li> <li>
<a href="/user/m.woach.me/" aria-label="user" class="icon-[mynaui--user] text-gray-300"></a> <a href="/landing" aria-label="landing" class="icon-[mynaui--external-link]"></a>
</li> </li>
{#if userState.rpc} <li><a href="/search" aria-label="search" class="icon-[mynaui--search]"></a></li>
<div>{userState.did}</div>
<button onclick={() => logout()}>logout</button>
{:else}
<button onclick={() => login('m.woach.me')}>login</button>
{/if}
</ul>
<div class="h-screen overflow-hidden bg-gray-300"> {#if userState.rpc}
{@render children()} <li>
<a
href="/user/{userState.handle?.split('at://')[1]}"
aria-label="user"
class="icon-[mynaui--user]"
></a>
</li>
{/if}
</ul>
<div class="flex flex-row items-center space-x-4">
<button class="icon-[mynaui--paint]" onclick={() => toggleTheme()} aria-label="theme"></button>
{#if userState.rpc}
<p class="">{userState.handle}</p>
<button onclick={() => logout()}>logout</button>
{:else}
<button onclick={() => login('m.woach.me')}>login</button>
{/if}
</div>
</nav>
<div id="theme" class={style.theme}>
<div class="bg-grey-300 dark:bg-gray-500">
{@render children()}
</div>
</div> </div>

View file

@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import { userState } from '$lib/state.svelte'; import { userState } from '$lib/state.svelte';
import { config } from '$lib/util'; import { config, resolveHandle } from '$lib/util';
import { XRPC } from '@atcute/client'; import { XRPC } from '@atcute/client';
import { OAuthUserAgent, finalizeAuthorization } from '@atcute/oauth-browser-client'; import { OAuthUserAgent, finalizeAuthorization } from '@atcute/oauth-browser-client';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
@ -13,12 +13,11 @@
history.replaceState(null, '', location.pathname + location.search); history.replaceState(null, '', location.pathname + location.search);
const session = await finalizeAuthorization(params); const session = await finalizeAuthorization(params);
const agentItem = new OAuthUserAgent(session); const agentItem = new OAuthUserAgent(session);
const rpcItem = new XRPC({ handler: agentItem }); const rpcItem = new XRPC({ handler: agentItem });
userState.did = (await agentItem?.getSession())?.info.sub ?? ''; userState.did = (await agentItem?.getSession())?.info.sub ?? '';
userState.handle = (await resolveHandle(userState.did)) ?? userState.did;
userState.rpc = rpcItem; userState.rpc = rpcItem;
userState.agent = agentItem; userState.agent = agentItem;

View file

@ -3,7 +3,7 @@ import {
getActivity, getActivity,
getProgress, getProgress,
getSessions, getSessions,
resolveHandle, resolveDID,
resolveMedia, resolveMedia,
resolveSession resolveSession
} from '$lib/util'; } from '$lib/util';
@ -16,7 +16,7 @@ import type {
import type { PageLoad } from './$types'; import type { PageLoad } from './$types';
export const load: PageLoad = async ({ params }) => { export const load: PageLoad = async ({ params }) => {
const did = await resolveHandle(params.handle); const did = await resolveDID(params.handle);
const rpc = await createRPC(did); const rpc = await createRPC(did);
const sessions: { const sessions: {