web_lib

Common web application libraries
git clone https://radroots.dev/git/web_lib.git
Log | Files | Refs | LICENSE

web.ts (4200B)


      1 import { IResultList } from "@radroots/types-bindings";
      2 import { err_msg, handle_err, type ResolveError, type ResolveStatus } from "@radroots/utils";
      3 import { cl_notifications_error } from "./error.js";
      4 import type {
      5     IClientNotifications,
      6     IClientNotificationsAlertResolve,
      7     IClientNotificationsConfig,
      8     IClientNotificationsConfirmResolve,
      9     IClientNotificationsDialogConfirmOpts,
     10     IClientNotificationsNotifyInitResolve,
     11     IClientNotificationsNotifySendOptions,
     12     IClientNotificationsNotifySendResolve
     13 } from "./types.js";
     14 
     15 export interface IWebNotifications extends IClientNotifications { }
     16 
     17 export class WebNotifications implements IWebNotifications {
     18     private _config: IClientNotificationsConfig;
     19 
     20     constructor(config: IClientNotificationsConfig = { app_name: "Radroots" }) {
     21         this._config = config;
     22     }
     23     public async alert(opts: string, title?: string, kind?: ResolveStatus): Promise<IClientNotificationsAlertResolve> {
     24         try {
     25             const msg = title ? `${title}\n\n${opts}` : opts;
     26             window.alert(msg);
     27             return true;
     28         } catch (e) {
     29             handle_err(e);
     30             return false;
     31         }
     32     }
     33 
     34     public async confirm(opts: IClientNotificationsDialogConfirmOpts): Promise<IClientNotificationsConfirmResolve> {
     35         try {
     36             const msg = typeof opts === 'string' ? opts : opts.message
     37             return window.confirm(msg);
     38         } catch (e) {
     39             handle_err(e);
     40             return false;
     41         }
     42     }
     43 
     44     public async notify_init(): Promise<IClientNotificationsNotifyInitResolve> {
     45         try {
     46             if (!("Notification" in window)) return "unavailable";
     47             if (Notification.permission === 'granted') return "granted";
     48             return await Notification.requestPermission();
     49         } catch (e) {
     50             return handle_err(e);
     51         }
     52     }
     53 
     54     public async notify_send(opts: string | IClientNotificationsNotifySendOptions): Promise<IClientNotificationsNotifySendResolve> {
     55         try {
     56             if (!("Notification" in window)) return err_msg(cl_notifications_error.unavailable);
     57             if (Notification.permission !== "granted") {
     58                 const permission = await this.notify_init();
     59                 if (permission !== "granted") return err_msg(cl_notifications_error.unavailable);
     60             }
     61             if (typeof opts === "string") return new Notification(this._config.app_name, { body: opts });
     62             else return new Notification(opts.title || this._config.app_name, { body: opts.body });
     63         } catch (e) {
     64             return handle_err(e);
     65         }
     66     }
     67 
     68     private async read_photo_data(file: File): Promise<string> {
     69         return await new Promise<string>((resolve, reject) => {
     70             const reader = new FileReader();
     71             reader.onload = () => {
     72                 if (typeof reader.result === "string") return resolve(reader.result);
     73                 return reject(new Error(cl_notifications_error.read_failure));
     74             };
     75             reader.onerror = () => {
     76                 if (reader.error) return reject(reader.error);
     77                 return reject(new Error(cl_notifications_error.read_failure));
     78             };
     79             reader.readAsDataURL(file);
     80         });
     81     }
     82 
     83     public async open_photos(): Promise<ResolveError<IResultList<string> | undefined>> {
     84         try {
     85             const files = await new Promise<FileList | null>((resolve) => {
     86                 const input = document.createElement('input');
     87                 input.type = 'file';
     88                 input.multiple = true;
     89                 input.accept = 'image/png,image/jpg';
     90                 input.onchange = () => resolve(input.files);
     91                 input.click();
     92             });
     93             if (!files) return;
     94             const results: string[] = [];
     95             for (let i = 0; i < files.length; i++) {
     96                 const file = files.item(i);
     97                 if (!file) continue;
     98                 const data_url = await this.read_photo_data(file);
     99                 results.push(data_url);
    100             }
    101             return { results };
    102         } catch (e) {
    103             return handle_err(e);
    104         }
    105     }
    106 }