import $ from 'jquery'; import * as JSX from './jsx'; import * as api from './api'; export interface ChatFile { id: string, name: string } export interface UserSettings { uuid: string, nickname: string, site_prefs: { font: string, model?: string }, prompt_data: { system?: string }, chat_files?: { files?: ChatFile[] }, plan: { endTime: number, plan: string } }; export let is_loggedin = false; export let settings: UserSettings = null; let on_prefs_updated: Function = () => {}; export async function onPrefsUpdated( fn: Function ) { on_prefs_updated = fn; } /** * polls settings from the server **/ export async function updatePrefs() { if( !is_loggedin ) { return; } let res = null; try { res = await fetch( `${api.url}/settings`, { method: 'POST', headers: { "Content-Type": "application/json", }, body: JSON.stringify( { token: localStorage.getItem( 'session' ), } ) } ); if( !res.ok ) { try { const json = await res.json(); if( json.status == 'nodata' ) { localStorage.setItem( 'needs-setup', 'true' ); if( window.location.pathname != '/first-landing' ) return JSX.navigate( '/first-landing' ); else { settings = null; localStorage.setItem( 'settings', '{}' ); } } else if( json.status != 'ok' ) { is_loggedin = false; localStorage.clear(); } throw new Error( json.msg ); } catch( e: any ) { throw new Error( "error contacting server" ); } } res = await res.json(); } catch( e: any ) { throw new Error( e.message ); } settings = res.userprefs; localStorage.setItem( 'settings', JSON.stringify( settings ) ); on_prefs_updated(); } /** * saves prefs on the server **/ export async function savePrefs( prefs: any ) { const res = await api.post( `update-settings`, { token: localStorage.getItem( 'session' ), prefs } ); settings = res.userprefs; localStorage.setItem( 'settings', JSON.stringify( settings ) ); } export async function getNotes() { const res = await api.post( `get-notes`, { token: localStorage.getItem( 'session' ) } ); return res.notes; } export async function deleteNote( note_id: string ) { await api.post( `delete-note`, { token: localStorage.getItem( 'session' ), noteId: note_id } ); } export async function deleteAllNotes() { await api.post( `delete-notes`, { token: localStorage.getItem( 'session' ) } ); } export async function getTokens() { const res = await api.post( `get-tokens`, { token: localStorage.getItem( 'session' ) } ); return res.tokens; } export async function createToken() { const res = await api.post( `create-token`, { token: localStorage.getItem( 'session' ) } ); return res.token; } export async function deleteToken( token_id: number ) { await api.post( `delete-token`, { id: token_id, token: localStorage.getItem( 'session' ) } ); } export async function deleteAllTokens() { await api.post( `delete-tokens`, { token: localStorage.getItem( 'session' ) } ); } export async function createChat() { const res = await api.post( `create-chat`, { token: localStorage.getItem( 'session' ) } ); return res; } export async function deleteChat( chatId: string ) { await api.post( `delete-chat`, { chatId, token: localStorage.getItem( 'session' ) } ); } export async function downloadAllData() { let res = await fetch( `${api.url}/getalldata`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify( { token: localStorage.getItem( 'session' ) } ) } ); let contentType = res.headers.get( 'content-type' ); if( contentType && contentType.includes( 'application/zip' ) ) { let blob = await res.blob(); let url = window.URL.createObjectURL( blob ); const a = ; $( 'body' ).append( a ); a.onclick = ( e: Event ) => { e.stopPropagation(); }; a.click(); window.URL.revokeObjectURL( url ); } else { let json = null; try { json = await res.json(); } catch( e: any ) { throw new Error( "Error contacting server" ); } if( json.status != 'ok' ) throw new Error( json.msg ); } } export async function invalidateAllSessions() { const res = await api.post( `invalidate-all-sessions`, { token: localStorage.getItem( 'session' ) } ); localStorage.setItem( 'session', res.session ); } function updateFont() { const style = document.documentElement.style; if( settings.site_prefs && settings.site_prefs.font != null ) style.setProperty( "--site-font", settings.site_prefs.font ); } async function onNavigateAsync() { try { if( is_loggedin ) { if( localStorage.getItem( 'needs-setup' ) && window.location.pathname !== "/first-landing" ) setTimeout( () => JSX.navigate( "/first-landing" ) ); else await updatePrefs(); // update it again in case it changed in prefs updateFont(); } await api.updateModels(); } catch( e: any ) { // todo: display message box w error console.log( e ); } } export function onNavigate() { settings = JSON.parse( localStorage.getItem( 'settings' ) || '{}' ) as UserSettings; api.parseModels(); if( localStorage.getItem( 'session' ) ) is_loggedin = true; if( is_loggedin ) updateFont(); onNavigateAsync(); } /** * returns true on success, error message on failure **/ export async function sendLoginLink( email: string ) { let res = null; try { res = await api.post( `send-login-link`, { email } ); } catch( e: any ) { return e.message; } return true; } export async function onLogin( code: string ) { let json = null; try { const res = await fetch( `${api.url}/login?token=${code}` ); json = await res.json(); } catch( e: any ) { throw new Error( "error contacting server" ); } if( json.status != 'ok' ) throw new Error( json.msg ); localStorage.setItem( 'session', json.session ); is_loggedin = true; try { await updatePrefs(); } catch( e: any ) { throw new Error( e.msg ); } } export async function logout() { if( !is_loggedin ) return; try { await api.post( 'invalidate-session', { token: localStorage.getItem( 'session' ) } ); } catch( e: any ) {} localStorage.clear(); is_loggedin = false; JSX.navigate( '/' ); window.location.reload(); }