[READ-ONLY] Mirror of https://github.com/flo-bit/atmo-tools. atmo.tools
0

Configure Feed

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

update login modal

Florian (May 17, 2025, 12:58 PM +0200) 92b389d2 e257366f

+183 -4
+1 -1
src/routes/+page.svelte
··· 1 1 <script lang="ts"> 2 2 import { client, login } from '$lib/oauth'; 3 - import { BlueskyLogin } from '@fuxui/social'; 3 + import { BlueskyLogin } from '$lib/bluesky-login'; 4 4 import Search from './Search.svelte'; 5 5 import { Heading } from '@fuxui/base'; 6 6 </script>
+23
src/lib/bluesky-login/BlueskyLogin.svelte
··· 1 + <script lang="ts"> 2 + import { Button } from '@fuxui/base'; 3 + import { BlueskyLoginModal, blueskyLoginModalState, type BlueskyLoginProps } from '.'; 4 + 5 + let { login, formAction, formMethod }: BlueskyLoginProps = $props(); 6 + </script> 7 + 8 + <Button onclick={() => blueskyLoginModalState.show()}> 9 + <svg 10 + fill="currentColor" 11 + xmlns="http://www.w3.org/2000/svg" 12 + viewBox="-40 -40 680 620" 13 + version="1.1" 14 + aria-hidden="true" 15 + > 16 + <path 17 + d="m135.72 44.03c66.496 49.921 138.02 151.14 164.28 205.46 26.262-54.316 97.782-155.54 164.28-205.46 47.98-36.021 125.72-63.892 125.72 24.795 0 17.712-10.155 148.79-16.111 170.07-20.703 73.984-96.144 92.854-163.25 81.433 117.3 19.964 147.14 86.092 82.697 152.22-122.39 125.59-175.91-31.511-189.63-71.766-2.514-7.3797-3.6904-10.832-3.7077-7.8964-0.0174-2.9357-1.1937 0.51669-3.7077 7.8964-13.714 40.255-67.233 197.36-189.63 71.766-64.444-66.128-34.605-132.26 82.697-152.22-67.108 11.421-142.55-7.4491-163.25-81.433-5.9562-21.282-16.111-152.36-16.111-170.07 0-88.687 77.742-60.816 125.72-24.795z" 18 + /> 19 + </svg> 20 + Login 21 + </Button> 22 + 23 + <BlueskyLoginModal {login} {formAction} {formMethod} />
+147
src/lib/bluesky-login/BlueskyLoginModal.svelte
··· 1 + <script lang="ts" module> 2 + export const blueskyLoginModalState = $state({ 3 + open: false, 4 + show: () => (blueskyLoginModalState.open = true), 5 + hide: () => (blueskyLoginModalState.open = false) 6 + }); 7 + </script> 8 + 9 + <script lang="ts"> 10 + import { Button, Modal, Subheading, Label, Input, Avatar } from '@fuxui/base'; 11 + import type { BlueskyLoginProps } from '.'; 12 + 13 + let value = $state(''); 14 + let error: string | null = $state(null); 15 + let loading = $state(false); 16 + 17 + let { login, formAction, formMethod = 'get' }: BlueskyLoginProps = $props(); 18 + 19 + async function onLogin(handle: string) { 20 + if (loading || !login) return; 21 + 22 + loading = true; 23 + error = null; 24 + 25 + try { 26 + const hide = await login(handle); 27 + 28 + if (hide) { 29 + blueskyLoginModalState.hide(); 30 + value = ''; 31 + } 32 + } catch (err) { 33 + error = err instanceof Error ? err.message : String(err); 34 + } finally { 35 + loading = false; 36 + } 37 + } 38 + 39 + async function onSubmit(evt: Event) { 40 + if (formAction || !login) return; 41 + evt.preventDefault(); 42 + 43 + await onLogin(value); 44 + } 45 + 46 + let input: HTMLInputElement | null = $state(null); 47 + 48 + let lastLogin: { handle: string; avatar: string } | null = $state(null); 49 + 50 + $effect(() => { 51 + let lastLoginDid = localStorage.getItem('last-login'); 52 + 53 + if (lastLoginDid) { 54 + let profile = localStorage.getItem(`profile-${lastLoginDid}`); 55 + 56 + if (profile) { 57 + lastLogin = { 58 + ...JSON.parse(profile), 59 + handle: 60 + 'bhvgsfabjkdvsbgfhdjnewjfvshbgsjdrndefgbgjfnkredfjgbhfdnksmfjgbhfdnrsfgjbnndksmefjgbvjn' 61 + }; 62 + } 63 + } 64 + }); 65 + 66 + $inspect(lastLogin); 67 + </script> 68 + 69 + <Modal 70 + bind:open={blueskyLoginModalState.open} 71 + class="max-w-sm gap-2 p-4 sm:p-6" 72 + onOpenAutoFocus={(e: Event) => { 73 + e.preventDefault(); 74 + input?.focus(); 75 + }} 76 + > 77 + <form onsubmit={onSubmit} action={formAction} method={formMethod} class="flex flex-col gap-2"> 78 + <Subheading class="mb-1 inline-flex items-center gap-2 text-xl font-bold"> 79 + <svg 80 + fill="currentColor" 81 + xmlns="http://www.w3.org/2000/svg" 82 + viewBox="-40 -40 680 620" 83 + version="1.1" 84 + class={['text-accent-600 dark:text-accent-400 size-6']} 85 + aria-hidden="true" 86 + > 87 + <path 88 + d="m135.72 44.03c66.496 49.921 138.02 151.14 164.28 205.46 26.262-54.316 97.782-155.54 164.28-205.46 47.98-36.021 125.72-63.892 125.72 24.795 0 17.712-10.155 148.79-16.111 170.07-20.703 73.984-96.144 92.854-163.25 81.433 117.3 19.964 147.14 86.092 82.697 152.22-122.39 125.59-175.91-31.511-189.63-71.766-2.514-7.3797-3.6904-10.832-3.7077-7.8964-0.0174-2.9357-1.1937 0.51669-3.7077 7.8964-13.714 40.255-67.233 197.36-189.63 71.766-64.444-66.128-34.605-132.26 82.697-152.22-67.108 11.421-142.55-7.4491-163.25-81.433-5.9562-21.282-16.111-152.36-16.111-170.07 0-88.687 77.742-60.816 125.72-24.795z" 89 + /> 90 + </svg> 91 + Login with Bluesky</Subheading 92 + > 93 + 94 + <div class="text-base-600 dark:text-base-400 text-xs leading-5"> 95 + Don't have an account? 96 + <br /> 97 + <a 98 + href="https://bsky.app" 99 + target="_blank" 100 + class="text-accent-600 dark:text-accent-400 dark:hover:text-accent-500 hover:text-accent-500 font-medium transition-colors" 101 + > 102 + Sign up on bluesky 103 + </a>, then come back here. 104 + </div> 105 + 106 + {#if lastLogin} 107 + <Label for="bluesky-handle" class="mt-4 text-sm">Recent login:</Label> 108 + <Button 109 + class="max-w-xs overflow-x-hidden justify-start truncate" 110 + variant="primary" 111 + onclick={() => onLogin(lastLogin?.handle ?? '')} 112 + disabled={loading} 113 + > 114 + <Avatar src={lastLogin.avatar} class="size-6" /> 115 + 116 + <div 117 + class="text-accent-600 dark:text-accent-400 text-md max-w-full truncate overflow-x-hidden font-semibold" 118 + > 119 + <p>{loading ? 'Loading...' : lastLogin.handle}</p> 120 + </div> 121 + </Button> 122 + {/if} 123 + 124 + <div class="mt-4 w-full"> 125 + <Label for="bluesky-handle" class="text-sm">Your handle</Label> 126 + <div class="mt-2"> 127 + <Input 128 + bind:ref={input} 129 + type="text" 130 + name="bluesky-handle" 131 + id="bluesky-handle" 132 + placeholder="yourname.bsky.social" 133 + class="w-full" 134 + bind:value 135 + /> 136 + </div> 137 + </div> 138 + 139 + {#if error} 140 + <p class="text-accent-500 mt-2 text-sm font-medium">{error}</p> 141 + {/if} 142 + 143 + <Button type="submit" class="mt-2 ml-auto w-full md:w-auto" disabled={loading} 144 + >{loading ? 'Loading...' : 'Login'}</Button 145 + > 146 + </form> 147 + </Modal>
+9
src/lib/bluesky-login/index.ts
··· 1 + export { default as BlueskyLoginModal } from './BlueskyLoginModal.svelte'; 2 + export { blueskyLoginModalState } from './BlueskyLoginModal.svelte'; 3 + export { default as BlueskyLogin } from './BlueskyLogin.svelte'; 4 + 5 + export type BlueskyLoginProps = { 6 + login?: (handle: string) => Promise<boolean | undefined>; 7 + formAction?: string; 8 + formMethod?: 'dialog' | 'get' | 'post' | 'DIALOG' | 'GET' | 'POST' | null; 9 + };
+3 -3
src/lib/oauth/auth.svelte.ts
··· 79 79 export async function logout() { 80 80 const currentAgent = client.agent; 81 81 if (currentAgent) { 82 - const did = currentAgent.session.info.sub; 82 + //const did = currentAgent.session.info.sub; 83 83 84 - localStorage.removeItem('last-login'); 85 - localStorage.removeItem(`profile-${did}`); 84 + //localStorage.removeItem('last-login'); 85 + //localStorage.removeItem(`profile-${did}`); 86 86 87 87 await currentAgent.signOut(); 88 88 client.session = null;