restructure for sveltekit
This commit is contained in:
		
							parent
							
								
									7deea47857
								
							
						
					
					
						commit
						9ef27fd2a2
					
				
					 73 changed files with 469 additions and 28 deletions
				
			
		
							
								
								
									
										14
									
								
								src/app.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/app.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
|     <head> | ||||
|         <meta charset="UTF-8"> | ||||
|         <link rel="icon" type="image/png" href="/favicon.png"> | ||||
|         <meta name="viewport" content="width=device-width, initial-scale=1"> | ||||
|         <title>space social</title> | ||||
|         %sveltekit.head% | ||||
|     </head> | ||||
|     <body data-sveltekit-preload-data="hover"> | ||||
|         <div style="display: contents">%sveltekit.body%</div> | ||||
|         <noscript>you need to enable javascript to use this app! :(</noscript> | ||||
|     </body> | ||||
| </html> | ||||
|  | @ -1,4 +1,3 @@ | |||
| import { version as APP_VERSION } from '../../package.json'; | ||||
| import { Instance, server_types } from './instance.js'; | ||||
| import * as api from './api.js'; | ||||
| import { get, writable } from 'svelte/store'; | ||||
|  | @ -25,7 +24,8 @@ export class Client { | |||
|     static get() { | ||||
|         if (get(client)) return client; | ||||
|         let new_client = new Client(); | ||||
|         window.peekie = new_client; | ||||
|         if (typeof window !== typeof undefined) | ||||
|             window.peekie = new_client; | ||||
|         new_client.load(); | ||||
|         client.set(new_client); | ||||
|         return client; | ||||
|  | @ -157,6 +157,7 @@ export class Client { | |||
|     } | ||||
| 
 | ||||
|     save() { | ||||
|         if (typeof localStorage === typeof undefined) return; | ||||
|         localStorage.setItem(save_name, JSON.stringify({ | ||||
|             version: APP_VERSION, | ||||
|             instance: { | ||||
|  | @ -168,6 +169,7 @@ export class Client { | |||
|     } | ||||
| 
 | ||||
|     load() { | ||||
|         if (typeof localStorage === typeof undefined) return; | ||||
|         let json = localStorage.getItem(save_name); | ||||
|         if (!json) return false; | ||||
|         let saved = JSON.parse(json); | ||||
|  | @ -1,8 +1,12 @@ | |||
| const sounds = { | ||||
|     "default": new Audio("/sound/log.ogg"), | ||||
|     "post": new Audio("/sound/success.ogg"), | ||||
|     "boost": new Audio("/sound/hello.ogg"), | ||||
| }; | ||||
| let sounds; | ||||
| 
 | ||||
| if (typeof Audio !== typeof undefined) { | ||||
|     sounds = { | ||||
|         "default": new Audio("/sound/log.ogg"), | ||||
|         "post": new Audio("/sound/success.ogg"), | ||||
|         "boost": new Audio("/sound/hello.ogg"), | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| export function play_sound(name) { | ||||
|     if (name === false) return; | ||||
|  | @ -1,6 +1,5 @@ | |||
| <script> | ||||
|     import { version as APP_VERSION } from '../../package.json'; | ||||
|     import Logo from '../img/spacesocial-logo.svg'; | ||||
|     import Logo from '../../img/spacesocial-logo.svg'; | ||||
|     import Button from './Button.svelte'; | ||||
|     import Feed from './Feed.svelte'; | ||||
|     import { Client } from '../client/client.js'; | ||||
							
								
								
									
										224
									
								
								src/routes/+page.svelte
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								src/routes/+page.svelte
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,224 @@ | |||
| <script> | ||||
|     import '$lib/app.css'; | ||||
|     import Navigation from '$lib/ui/Navigation.svelte'; | ||||
|     import Widgets from '$lib/ui/Widgets.svelte'; | ||||
|     import Feed from '$lib/ui/Feed.svelte'; | ||||
|     import { Client } from '$lib/client/client.js'; | ||||
|     import Button from '$lib/ui/Button.svelte'; | ||||
|     import { get } from 'svelte/store'; | ||||
| 
 | ||||
|     let client = get(Client.get()); | ||||
|     let ready = client.app && client.app.token; | ||||
|     let instance_url_error = false; | ||||
|     let logging_in = false; | ||||
| 
 | ||||
|     if (typeof location !== typeof undefined) { | ||||
|         let auth_code = new URLSearchParams(location.search).get("code"); | ||||
|         if (auth_code) { | ||||
|             client.getToken(auth_code).then(() => { | ||||
|                 client.save(); | ||||
|                 location = location.origin; | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (client.app && client.app.token) { | ||||
|         // this triggers the client actually getting the authenticated user's data. | ||||
|         client.verifyCredentials().then(res => { | ||||
|             if (res) { | ||||
|                 console.log(`Logged in as @${client.user.username}@${client.user.host}`); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     function log_in(event) { | ||||
|         logging_in = true; | ||||
|         event.preventDefault(); | ||||
|         const host = event.target.host.value; | ||||
| 
 | ||||
|         client.init(host).then(res => { | ||||
|             logging_in = false; | ||||
|             if (!res) return; | ||||
|             if (res.constructor === String) { | ||||
|                 instance_url_error = res; | ||||
|                 return; | ||||
|             }; | ||||
|             let oauth_url = client.getOAuthUrl(); | ||||
|             location = oauth_url; | ||||
|         }); | ||||
|     } | ||||
| </script> | ||||
| 
 | ||||
| <div id="spacesocial-app"> | ||||
| 
 | ||||
|     <header> | ||||
|         <Navigation /> | ||||
|     </header> | ||||
| 
 | ||||
|     <main> | ||||
|         {#if ready} | ||||
|             <Feed /> | ||||
|         {:else} | ||||
|             <div> | ||||
|                 <form on:submit={log_in} id="login"> | ||||
|                     <h1>Space Social</h1> | ||||
|                     <p>Welcome, fediverse user!</p> | ||||
|                     <p>Please enter your instance domain to log in.</p> | ||||
|                     <div class="input-wrapper"> | ||||
|                         <input type="text" id="host" aria-label="instance domain" class={logging_in ? "throb" : ""}> | ||||
|                         {#if instance_url_error} | ||||
|                             <p class="error">{instance_url_error}</p> | ||||
|                         {/if} | ||||
|                     </div> | ||||
|                     <br> | ||||
|                     <button type="submit" id="login" class={logging_in ? "disabled" : ""}>Log in</button> | ||||
|                     <p><small> | ||||
|                         Please note this is | ||||
|                         <strong><em>extremely experimental software</em></strong>; | ||||
|                         things are likely to break! | ||||
|                         <br> | ||||
|                         If that's all cool with you, welcome aboard! | ||||
|                     </small></p> | ||||
| 
 | ||||
|                     <p class="form-footer">made with ❤️ by <a href="https://arimelody.me">ari melody</a>, 2024</p> | ||||
|                 </form> | ||||
|             </div> | ||||
|         {/if} | ||||
|     </main> | ||||
| 
 | ||||
|     <div id="widgets"> | ||||
|         <Widgets /> | ||||
|     </div> | ||||
| 
 | ||||
| </div> | ||||
| 
 | ||||
| <style> | ||||
|     #spacesocial-app { | ||||
|         margin: auto 0; | ||||
|         padding: 0 16px; | ||||
|         display: flex; | ||||
|         flex-direction: row; | ||||
|         justify-content: center; | ||||
|         gap: 16px; | ||||
|     } | ||||
| 
 | ||||
|     header, #widgets { | ||||
|         width: 300px; | ||||
|     } | ||||
| 
 | ||||
|     main { | ||||
|         width: 732px; | ||||
|     } | ||||
| 
 | ||||
|     div.pane { | ||||
|         margin-top: 16px; | ||||
|         padding: 20px 32px; | ||||
|         border: 1px solid #8884; | ||||
|         border-radius: 16px; | ||||
|         background-color: var(--bg1); | ||||
|     } | ||||
| 
 | ||||
|     form#login { | ||||
|         margin: 25vh 0 32px 0; | ||||
|         text-align: center; | ||||
|     } | ||||
| 
 | ||||
|     a { | ||||
|         color: var(--accent); | ||||
|         text-decoration: none; | ||||
|     } | ||||
| 
 | ||||
|     a:hover { | ||||
|         text-decoration: underline; | ||||
|     } | ||||
| 
 | ||||
|     .input-wrapper { | ||||
|         width: 360px; | ||||
|         margin: 0 auto; | ||||
|         display: flex; | ||||
|         flex-direction: column; | ||||
|         align-items: center; | ||||
|     } | ||||
| 
 | ||||
|     input[type=text] { | ||||
|         width: 100%; | ||||
|         padding: 12px; | ||||
|         display: block; | ||||
|         border-radius: 8px; | ||||
|         border: 1px solid var(--accent); | ||||
|         background-color: var(--bg-800); | ||||
| 
 | ||||
|         font-family: inherit; | ||||
|         font-weight: bold; | ||||
|         font-size: inherit; | ||||
|         color: var(--text); | ||||
| 
 | ||||
|         transition: box-shadow .2s; | ||||
|     } | ||||
| 
 | ||||
|     input[type=text]::placeholder { | ||||
|         opacity: .8; | ||||
|     } | ||||
| 
 | ||||
|     input[type=text]:focus { | ||||
|         outline: none; | ||||
|         box-shadow: 0 0 16px color-mix(in srgb, transparent, var(--accent) 25%); | ||||
|     } | ||||
| 
 | ||||
|     .error { | ||||
|         margin: 6px; | ||||
|         font-style: italic; | ||||
|         font-size: .9em; | ||||
|         color: red; | ||||
|         opacity: .7; | ||||
|     } | ||||
| 
 | ||||
|     button#login { | ||||
|         margin: -8px auto 0 auto; | ||||
|         padding: 12px 24px; | ||||
|         display: flex; | ||||
|         flex-direction: row; | ||||
|         justify-content: space-between; | ||||
|         align-items: center; | ||||
| 
 | ||||
|         font-family: inherit; | ||||
|         font-size: 1rem; | ||||
|         font-weight: 600; | ||||
|         text-align: left; | ||||
| 
 | ||||
|         border-radius: 8px; | ||||
|         border-width: 2px; | ||||
|         border-style: solid; | ||||
| 
 | ||||
|         background-color: var(--bg-700); | ||||
|         color: var(--text); | ||||
|         border-color: transparent; | ||||
| 
 | ||||
|         transition-property: border-color, background-color, color; | ||||
|         transition-timing-function: ease-out; | ||||
|         transition-duration: .1s; | ||||
| 
 | ||||
|         cursor: pointer; | ||||
|         text-align: center; | ||||
|         justify-content: center; | ||||
|     } | ||||
| 
 | ||||
|     button#login:hover { | ||||
|         background-color: color-mix(in srgb, var(--bg-700), var(--accent) 10%); | ||||
|         border-color: color-mix(in srgb, var(--bg-700), var(--accent) 20%); | ||||
|     } | ||||
| 
 | ||||
|     button#login:active { | ||||
|         background-color: color-mix(in srgb, var(--bg-700), var(--bg-800) 50%); | ||||
|         border-color: color-mix(in srgb, var(--bg-700), var(--bg-800) 10%); | ||||
|     } | ||||
| 
 | ||||
|     button#login.disabled { | ||||
|         opacity: .5; | ||||
|         cursor: initial; | ||||
|     } | ||||
| 
 | ||||
|     .form-footer { | ||||
|         opacity: .7; | ||||
|     } | ||||
| </style> | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue