aboutsummaryrefslogtreecommitdiffstats
path: root/src/routes/+layout.svelte
blob: 7653e05aebc7868f02e80d1e8235e61acc96c8a2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
<script>
  import { run } from "svelte/legacy";
  import { browser } from "$app/environment";
  import { PUBLIC_DOMAIN } from "$env/static/public";
  import "../app.css";
  import { loading, t } from "$lib/translations";
  import { onMount } from "svelte";
  import { installPrompt, theme as themeStore } from "$lib/store";


const map = { light: 'lofi', dark: 'black', system: 'system' };

  let { data, children } = $props();
  let { pathname, theme } = $state(data);
  $effect(() => ($themeStore = data.theme));
  $effect(() => (theme = $themeStore));
$effect(() => {
  const v = map[theme] ?? theme;
  if (!v || v === 'system') {
    document.documentElement.removeAttribute('data-theme');
  } else {
    document.documentElement.setAttribute('data-theme', v);
  }
});

  let host = PUBLIC_DOMAIN.includes("localhost")
    ? `http://${PUBLIC_DOMAIN}`
    : `https://${PUBLIC_DOMAIN}`;

  function clearBadge() {
    if ("clearAppBadge" in navigator) {
      navigator.clearAppBadge().catch(() => {});
    }
  }

  onMount(() => {
    if (!browser) return;

    // Handle install prompt
    window.addEventListener("beforeinstallprompt", (event) => {
      event.preventDefault();
      $installPrompt = event;
    });

    clearBadge(); // first load
    document.addEventListener("visibilitychange", () => {
      if (document.visibilityState === "visible") clearBadge();
    });

    let hasNotch = typeof window.AndroidNotch !== "undefined";
    if (hasNotch) {
      window.AndroidNotch.getInsetTop(
        (px) => {
          document.documentElement.style.setProperty(
            "--safe-area-inset-top",
            Math.round(px) + "px",
          );
        },
        (err) => {
          console.error("Failed to get notch inset:", err);
        },
      );

      window.AndroidNotch.getInsetBottom(
        (px) => {
          document.documentElement.style.setProperty(
            "--safe-area-inset-bottom",
            24 + "px",
          );
        },
        (err) => {
          console.error("Failed to get bottom inset:", err);
        },
      );
    }
  });
</script>

<svelte:head>
  <title>coinos</title>
  <meta property="og:title" content="coinos" />
  <meta name="twitter:title" content="coinos" />

  <meta property="og:image" content={`${host}/images/logo.webp`} />
  <meta property="og:type" content="website" />
  <meta property="og:description" content="An easy to use bitcoin web wallet" />
  <meta name="description" content="An easy to use bitcoin web wallet" />

  <meta name="keywords" content="coinos easy bitcoin web wallet" />
  <meta name="twitter:image" content={`${host}/images/logo.webp`} />
  <meta name="twitter:card" content="summary_large_image" />
  <meta property="og:url" content={host + pathname} />
  <meta name="twitter:site" content="@coinoswallet" />
  <meta name="twitter:creator" content="@coinoswallet" />
</svelte:head>

{#if !$loading}
  <main>
    {@render children?.()}
  </main>
{/if}

<style global>
  :root {
    --toastContainerTop: auto;
    --toastContainerRight: auto;
    --toastContainerBottom: 8rem;
    --toastContainerLeft: calc(50vw - 8rem);
    --toastBackground: #292929;

    --safe-area-inset-top: 0px;
    --safe-area-inset-bottom: 0px;
  }

  main {
    padding-top: var(--safe-area-inset-top);
    padding-bottom: var(--safe-area-inset-bottom);
  }
</style>