kopia lustrzana https://github.com/elk-zone/elk
				
				
				
			
							rodzic
							
								
									b8cadca717
								
							
						
					
					
						commit
						3b92b27cc8
					
				
							
								
								
									
										31
									
								
								app.vue
								
								
								
								
							
							
						
						
									
										31
									
								
								app.vue
								
								
								
								
							|  | @ -1,21 +1,8 @@ | |||
| <script setup> | ||||
| import { APP_NAME } from './constants' | ||||
| 
 | ||||
| const isDev = process.dev | ||||
| const isPreview = window.location.hostname.includes('deploy-preview') | ||||
| 
 | ||||
| useHead({ | ||||
|   titleTemplate: title => `${title ? `${title} | ` : ''}${APP_NAME}${isDev ? ' (dev)' : isPreview ? ' (preview)' : ''}`, | ||||
|   link: [ | ||||
|     { rel: 'icon', type: 'image/svg+png', href: isDev || isPreview ? '/favicon-dev.png' : '/favicon.png' }, | ||||
|   ], | ||||
| }) | ||||
| usePageHeader() | ||||
| 
 | ||||
| // We want to trigger rerendering the page when account changes | ||||
| const key = computed(() => useMasto().instances.config.url || 'default') | ||||
| 
 | ||||
| // eslint-disable-next-line no-unused-expressions | ||||
| isDark.value | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|  | @ -27,19 +14,3 @@ isDark.value | |||
|     id="teleport-end" | ||||
|   /> | ||||
| </template> | ||||
| 
 | ||||
| <style> | ||||
| html, body , #__nuxt{ | ||||
|   height: 100vh; | ||||
|   margin: 0; | ||||
|   padding: 0; | ||||
| } | ||||
| 
 | ||||
| html.dark { | ||||
|   color-scheme: dark; | ||||
| } | ||||
| 
 | ||||
| html { | ||||
|   --at-apply: bg-base text-base; | ||||
| } | ||||
| </style> | ||||
|  |  | |||
|  | @ -0,0 +1,16 @@ | |||
| import { APP_NAME } from '~/constants' | ||||
| 
 | ||||
| const isDev = process.dev | ||||
| const isPreview = window.location.hostname.includes('deploy-preview') | ||||
| 
 | ||||
| export function usePageHeader() { | ||||
|   useHead({ | ||||
|     titleTemplate: title => `${title ? `${title} | ` : ''}${APP_NAME}${isDev ? ' (dev)' : isPreview ? ' (preview)' : ''}`, | ||||
|     link: [ | ||||
|       { rel: 'icon', type: 'image/svg+png', href: isDev || isPreview ? '/favicon-dev.png' : '/favicon.png' }, | ||||
|     ], | ||||
|   }) | ||||
| 
 | ||||
|   // eslint-disable-next-line no-unused-expressions
 | ||||
|   isDark.value | ||||
| } | ||||
|  | @ -0,0 +1,57 @@ | |||
| <script setup lang="ts"> | ||||
| import type { NuxtError } from '#app' | ||||
| 
 | ||||
| // prevent reactive update when clearing error | ||||
| const { error } = defineProps<{ | ||||
|   error: Partial<NuxtError> | ||||
| }>() | ||||
| 
 | ||||
| usePageHeader() | ||||
| 
 | ||||
| // add more custom status codes messages here | ||||
| const errorCodes: Record<number, string> = { | ||||
|   404: 'Page not found', | ||||
| } | ||||
| 
 | ||||
| const defaultMessage = 'Something went wrong' | ||||
| 
 | ||||
| const message = error.message ?? errorCodes[error.statusCode!] ?? defaultMessage | ||||
| 
 | ||||
| const state = ref<'error' | 'reloading'>('error') | ||||
| const reload = async () => { | ||||
|   state.value = 'reloading' | ||||
|   try { | ||||
|     if (!useMasto()) | ||||
|       await loginTo(currentUser.value) | ||||
|     clearError({ redirect: currentUser.value ? '/home' : '/public' }) | ||||
|   } | ||||
|   catch { | ||||
|     state.value = 'error' | ||||
|   } | ||||
| } | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|   <NuxtLoadingIndicator color="repeating-linear-gradient(to right,var(--c-primary) 0%,var(--c-primary-active) 100%)" /> | ||||
|   <NuxtLayout> | ||||
|     <MainContent> | ||||
|       <template #title> | ||||
|         <span text-lg font-bold>Error</span> | ||||
|       </template> | ||||
|       <slot> | ||||
|         <form p5 grid gap-y-4 @submit="reload"> | ||||
|           <div text-lg> | ||||
|             Something went wrong | ||||
|           </div> | ||||
|           <div text-secondary> | ||||
|             {{ message }} | ||||
|           </div> | ||||
|           <button flex items-center gap-2 justify-center btn-solid text-center :disabled="state === 'reloading'"> | ||||
|             <span v-if="state === 'reloading'" i-ri:loader-2-fill animate-spin inline-block /> | ||||
|             {{ state === 'reloading' ? 'Reloading' : 'Reload' }} | ||||
|           </button> | ||||
|         </form> | ||||
|       </slot> | ||||
|     </MainContent> | ||||
|   </NuxtLayout> | ||||
| </template> | ||||
|  | @ -55,6 +55,12 @@ export default defineNuxtConfig({ | |||
|       translateApi: '', | ||||
|     }, | ||||
|   }, | ||||
|   nitro: { | ||||
|     prerender: { | ||||
|       crawlLinks: false, | ||||
|       routes: ['/200.html'], | ||||
|     }, | ||||
|   }, | ||||
|   app: { | ||||
|     keepalive: true, | ||||
|   }, | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ import type { MastoClient } from 'masto' | |||
| import { currentUser } from '../composables/users' | ||||
| 
 | ||||
| export default defineNuxtPlugin(async () => { | ||||
|   let masto!: MastoClient | ||||
|   try { | ||||
|     const { query } = useRoute() | ||||
|     const user = typeof query.server === 'string' && typeof query.token === 'string' | ||||
|  | @ -9,23 +10,22 @@ export default defineNuxtPlugin(async () => { | |||
|       : currentUser.value | ||||
| 
 | ||||
|     // TODO: improve upstream to make this synchronous (delayed auth)
 | ||||
|     const masto = await loginTo(user) as MastoClient | ||||
| 
 | ||||
|     return { | ||||
|       provide: { | ||||
|         masto: shallowReactive({ | ||||
|           replace(api: MastoClient) { this.api = api }, | ||||
|           api: masto, | ||||
|         }), | ||||
|       }, | ||||
|     } | ||||
|     masto = await loginTo(user) | ||||
|   } | ||||
|   catch { | ||||
|     // TODO: handle error
 | ||||
|     // Show error page when Mastodon server is down
 | ||||
|     throw createError({ | ||||
|     showError({ | ||||
|       fatal: true, | ||||
|       statusMessage: 'Could not log into account.', | ||||
|     }) | ||||
|   } | ||||
| 
 | ||||
|   return { | ||||
|     provide: { | ||||
|       masto: shallowReactive({ | ||||
|         replace(api: MastoClient) { this.api = api }, | ||||
|         api: masto, | ||||
|       }), | ||||
|     }, | ||||
|   } | ||||
| }) | ||||
|  |  | |||
|  | @ -103,3 +103,17 @@ html { | |||
|     background-position: 0 50% | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| html, body , #__nuxt{ | ||||
|   height: 100vh; | ||||
|   margin: 0; | ||||
|   padding: 0; | ||||
| } | ||||
| 
 | ||||
| html.dark { | ||||
|   color-scheme: dark; | ||||
| } | ||||
| 
 | ||||
| html { | ||||
|   --at-apply: bg-base text-base; | ||||
| } | ||||
|  |  | |||
		Ładowanie…
	
		Reference in New Issue
	
	 Joaquín Sánchez
						Joaquín Sánchez