web


git clone https://radroots.dev/git/web.git
Log | Files | Refs | Submodules | README | LICENSE

+layout.svelte (4347B)


      1 <script lang="ts">
      2     import { dev, version as kit_version } from "$app/environment";
      3     import { resolve } from "$app/paths";
      4     import { page } from "$app/state";
      5     import { app_init } from "$lib/utils/app";
      6     import { app_cfg } from "$lib/utils/app/config";
      7     import {
      8         lc_color_mode,
      9         lc_geocode,
     10         lc_geop_current,
     11         lc_gui_alert,
     12         lc_gui_confirm,
     13         lc_img_bin,
     14         lc_photos_add,
     15         lc_photos_upload,
     16     } from "$lib/utils/app/handlers";
     17     import { locale, ls } from "$lib/utils/i18n";
     18     import {
     19         set_context,
     20         theme_key,
     21         theme_mode,
     22         theme_set,
     23         win_h,
     24     } from "@radroots/apps-lib";
     25     import { Css, LayoutWindow } from "@radroots/apps-lib-pwa";
     26     import { app_lo } from "@radroots/apps-lib-pwa/stores/app";
     27     import type { LibContext } from "@radroots/apps-lib-pwa/types/context";
     28     import { CFG_APP } from "@radroots/apps-lib-pwa/utils/app";
     29     import { parse_theme_key, parse_theme_mode } from "@radroots/themes";
     30     import { RADROOTS_ASSET_CACHE_NAME, str_cap_words } from "@radroots/utils";
     31     import "css-paint-polyfill";
     32     import { onMount } from "svelte";
     33     import "../app.css";
     34     import type { LayoutProps } from "./$types";
     35 
     36     type MetaTag = {
     37         name: string;
     38         content: string;
     39     };
     40 
     41 
     42     const HEAD_META_TAGS: MetaTag[] = [
     43         {
     44             name: "app_version",
     45             content: app_cfg.version,
     46         },
     47         {
     48             name: "app_backup_version",
     49             content: app_cfg.backup.version,
     50         },
     51         {
     52             name: "app_build_id",
     53             content: kit_version,
     54         },
     55         {
     56             name: "app_build_mode",
     57             content: dev ? "development" : "production",
     58         },
     59     ];
     60 
     61     let { children }: LayoutProps = $props();
     62 
     63     const LIB_CONTEXT: LibContext = {
     64         ls,
     65         locale,
     66         lc_color_mode,
     67         lc_gui_alert,
     68         lc_gui_confirm,
     69         lc_geocode,
     70         lc_geop_current,
     71         lc_img_bin,
     72         lc_photos_add,
     73         lc_photos_upload,
     74     };
     75 
     76     set_context("lib", LIB_CONTEXT);
     77 
     78     theme_mode.subscribe((_theme_mode) =>
     79         theme_set(parse_theme_key($theme_key), parse_theme_mode(_theme_mode)),
     80     );
     81 
     82     theme_key.subscribe((_theme_key) =>
     83         theme_set(parse_theme_key(_theme_key), parse_theme_mode($theme_mode)),
     84     );
     85 
     86     win_h.subscribe((_win_h) => {
     87         if (_win_h > CFG_APP.layout.ios1.h) {
     88             app_lo.set("ios1");
     89         } else {
     90             app_lo.set("ios0");
     91         }
     92     });
     93 
     94     const register_service_worker = async (): Promise<void> => {
     95         if (dev) return;
     96         if (!("serviceWorker" in navigator)) return;
     97         const service_worker_root = resolve("/");
     98         const service_worker_path = service_worker_root.endsWith("/")
     99             ? `${service_worker_root}service-worker.js`
    100             : `${service_worker_root}/service-worker.js`;
    101         try {
    102             await navigator.serviceWorker.register(service_worker_path);
    103             await navigator.serviceWorker.ready;
    104         } catch {
    105             return;
    106         }
    107     };
    108 
    109     const unregister_service_workers = async (): Promise<void> => {
    110         if (!("serviceWorker" in navigator)) return;
    111         const registrations = await navigator.serviceWorker.getRegistrations();
    112         await Promise.all(registrations.map((registration) => registration.unregister()));
    113         if (!("caches" in globalThis)) return;
    114         const cache_names = await caches.keys();
    115         const stale_cache_names = cache_names.filter((name) => name !== RADROOTS_ASSET_CACHE_NAME);
    116         await Promise.all(stale_cache_names.map((name) => caches.delete(name)));
    117     };
    118 
    119     onMount(async () => {
    120         if (dev) await unregister_service_workers();
    121         await app_init();
    122         await register_service_worker();
    123     });
    124 
    125     const format_title = (title: string): string => {
    126         return str_cap_words(title.replaceAll(`/`, ` `));
    127     };
    128 
    129     const head_title = $derived(format_title(page.url.pathname));
    130 </script>
    131 
    132 <svelte:head>
    133     <title>{`${head_title || "Home"} | Rad Roots`}</title>
    134     {#each HEAD_META_TAGS as meta_tag (meta_tag.name)}
    135         <meta name={meta_tag.name} content={meta_tag.content} />
    136     {/each}
    137 </svelte:head>
    138 
    139 <LayoutWindow>
    140     {@render children()}
    141 </LayoutWindow>
    142 <Css />