cq

Distributed social media platform
git clone git://git.finwo.net/app/cq
Log | Files | Refs

screen-account-select.tsx (2731B)


      1 import { Vnode } from 'mithril';
      2 import { AccountCreateScreen } from './screen-account-create.tsx';
      3 
      4 import TrashIcon from 'lucide/dist/esm/icons/trash-2.js';
      5 
      6 import { getDirectoryHandle, getFileHandle } from '../util/opfs';
      7 import {HomeScreen} from './screen-home.js';
      8 
      9 type _Vnode = Vnode<{}, typeof AccountSelectScreen>;
     10 
     11 export const AccountSelectScreen = {
     12   routePath: '/account/select',
     13 
     14   accounts: [] as Array<{id:string,displayName:string}>,
     15 
     16   handler: {
     17     selectAccount: (account: {id:string}) => () => {
     18       localStorage.selectedAccount = account.id;
     19       document.location.href = `#!${HomeScreen.routePath}`;
     20     },
     21     loadAccounts: async (vnode: _Vnode, redraw: boolean = false) => {
     22       vnode.state.accounts = [];
     23 
     24       const accountsHandle = await getDirectoryHandle('/local/accounts');
     25       for await (const accountId of accountsHandle.keys()) {
     26         try {
     27           const accountConfigHandle = await getFileHandle(`/local/accounts/${accountId}/config.json`)
     28           const accountConfig       = JSON.parse(Buffer.from(await (await accountConfigHandle.getFile()).arrayBuffer()));
     29           vnode.state.accounts.push({
     30             ...accountConfig,
     31             id: accountId,
     32           });
     33         } catch {
     34           // Intentionally empty
     35         }
     36       }
     37       if (!vnode.state.accounts.length) {
     38         document.location.href = `#!${AccountCreateScreen.routePath}`;
     39         return;
     40       }
     41       if (redraw) m.redraw();
     42     },
     43     deleteAccount: async (vnode: _Vnode, account:{id:string,displayName:string}) => {
     44       if (!confirm(`Delete account ${account.displayName}?`)) return false;
     45       const accountsHandle = await getDirectoryHandle(`/local/accounts`)
     46       await accountsHandle.removeEntry(account.id, { recursive: true })
     47       vnode.state.handler.loadAccounts(vnode, true);
     48     }
     49   },
     50 
     51   async oninit(vnode: _Vnode) {
     52     await vnode.state.handler.loadAccounts(vnode, true);
     53   },
     54 
     55   view(vnode: _Vnode) {
     56     return (
     57       <div class="main">
     58         <h3>Select account</h3>
     59         <div id="accountSelectList" class="entry-list">
     60           {vnode.state.accounts.map(account => (
     61             <a style="display:block;padding:1em" onclick={vnode.state.handler.selectAccount(account)}>
     62               <label>{account.displayName}</label>
     63               <svg ns="http://www.w3.org/2000/svg" fill="transparent" class="icon accountListDeleteButton" onclick={()=>{vnode.state.handler.deleteAccount(vnode, account);return false;}}>
     64                 {TrashIcon.map(el => m(...el))}
     65               </svg>
     66             </a>
     67           ))}
     68         </div>
     69         <center>
     70           <a href={`#!${AccountCreateScreen.routePath}`}>Create new account</a>
     71         </center>
     72       </div>
     73     );
     74   },
     75 };