full-layout with mobile bottom bar

master
Niko PLP 7 months ago
parent a2f1cf8316
commit 58e7bb85a0
  1. 7
      ng-app/src-tauri/gen/android/app/build.gradle.kts
  2. 190
      ng-app/src/lib/FullLayout.svelte
  3. 183
      ng-app/src/lib/Home.svelte
  4. 12
      ng-app/src/lib/Login.svelte
  5. 23
      ng-app/src/lib/MobileBottomBar.svelte
  6. 32
      ng-app/src/lib/MobileBottomBarItem.svelte
  7. 4
      ng-app/src/lib/NoWallet.svelte
  8. 24
      ng-app/src/routes/WalletCreate.svelte
  9. 317
      ng-app/src/routes/WalletLogin.svelte
  10. 4
      ng-app/src/styles.css
  11. 9
      ng-app/tailwind.config.cjs
  12. 8
      ngaccount/web/src/App.svelte
  13. 2
      ngaccount/web/src/routes/Create.svelte
  14. 8
      ngone/web/src/App.svelte

@ -36,7 +36,8 @@ android {
isDebuggable = true
isJniDebuggable = true
isMinifyEnabled = false
packaging { jniLibs.keepDebugSymbols.add("*/arm64-v8a/*.so")
packaging {
jniLibs.keepDebugSymbols.add("*/arm64-v8a/*.so")
jniLibs.keepDebugSymbols.add("*/armeabi-v7a/*.so")
jniLibs.keepDebugSymbols.add("*/x86/*.so")
jniLibs.keepDebugSymbols.add("*/x86_64/*.so")
@ -45,6 +46,10 @@ android {
getByName("release") {
isMinifyEnabled = true
signingConfig = signingConfigs.getByName("release")
packaging {
jniLibs.excludes.add("*/x86/*.so")
jniLibs.excludes.add("*/x86_64/*.so")
}
proguardFiles(
*fileTree(".") { include("**/*.pro") }
.plus(getDefaultProguardFile("proguard-android-optimize.txt"))

@ -0,0 +1,190 @@
<!--
// Copyright (c) 2022-2023 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
-->
<script lang="ts">
import {
Sidebar,
SidebarGroup,
SidebarItem,
SidebarWrapper,
} from "flowbite-svelte";
import { link, location } from "svelte-spa-router";
import MobileBottomBarItem from "./MobileBottomBarItem.svelte";
import MobileBottomBar from "./MobileBottomBar.svelte";
// @ts-ignore
import Logo from "../assets/nextgraph.svg?component";
// @ts-ignore
import LogoGray from "../assets/nextgraph-gray.svg?component";
import { online } from "../store";
import { onMount, tick } from "svelte";
import {
Home,
Bolt,
MagnifyingGlass,
PlusCircle,
PaperAirplane,
Bell,
User,
} from "svelte-heros-v2";
let width: number;
let breakPoint: number = 662;
let mobile = false;
$: if (width >= breakPoint) {
mobile = false;
} else {
mobile = true;
}
async function scrollToTop() {
await tick();
console.log("scrollToTop");
top.scrollIntoView();
}
onMount(async () => await scrollToTop());
$: activeUrl = "#" + $location;
let top;
let asideClass = "w-48";
let spanClass = "flex-1 ml-3 whitespace-nowrap";
let nonActiveClass =
"flex items-center p-2 text-base font-normal text-gray-900 rounded-lg dark:text-white hover:bg-gray-200 dark:hover:bg-gray-700";
</script>
{#if mobile}
<div class="full-layout">
<main class="pb-14" bind:this={top}>
<slot />
</main>
<MobileBottomBar {activeUrl}>
<MobileBottomBarItem href="#/" icon={Home} on:click={scrollToTop} />
<MobileBottomBarItem href="#/stream" icon={Bolt} on:click={scrollToTop} />
<MobileBottomBarItem
href="#/search"
icon={MagnifyingGlass}
on:click={scrollToTop}
/>
<MobileBottomBarItem href="#/create" icon={PlusCircle} />
<MobileBottomBarItem href="#/site" icon={User} on:click={scrollToTop} />
</MobileBottomBar>
</div>
{:else}
<div class="full-layout">
<Sidebar {activeUrl} {asideClass} {nonActiveClass} class="fixed">
<SidebarWrapper
divClass="bg-gray-60 overflow-y-auto tall:py-4 px-3 rounded dark:bg-gray-800"
>
<SidebarGroup ulClass="space-y-1 tall:space-y-2">
<SidebarItem label="NextGraph" href="#/user" class="mt-1">
<svelte:fragment slot="icon">
{#if $online}
<Logo class="w-7 h-7 tall:w-10 tall:h-10" />
{:else}
<LogoGray class="w-7 h-7 tall:w-10 tall:h-10" />
{/if}
</svelte:fragment>
</SidebarItem>
<SidebarItem
label="Home"
href="#/"
on:click={scrollToTop}
class="py-1 tall:p-2"
>
<svelte:fragment slot="icon">
<Home
tabindex="-1"
class="w-7 h-7 text-black transition duration-75 dark:text-white group-hover:text-gray-900 dark:group-hover:text-white"
/>
</svelte:fragment>
</SidebarItem>
<SidebarItem label="Stream" href="#/stream" class="py-1 tall:p-2">
<svelte:fragment slot="icon">
<Bolt
tabindex="-1"
class="w-7 h-7 text-black transition duration-75 dark:text-white group-hover:text-gray-900 dark:group-hover:text-white"
/>
</svelte:fragment>
</SidebarItem>
<SidebarItem label="Search" href="#/search" class="py-1 tall:p-2">
<svelte:fragment slot="icon">
<MagnifyingGlass
tabindex="-1"
class="w-7 h-7 text-black transition duration-75 dark:text-white group-hover:text-gray-900 dark:group-hover:text-white"
/>
</svelte:fragment>
</SidebarItem>
<SidebarItem label="Create" href="#/create" class="py-1 tall:p-2">
<svelte:fragment slot="icon">
<PlusCircle
tabindex="-1"
class="w-7 h-7 text-black transition duration-75 dark:text-white group-hover:text-gray-900 dark:group-hover:text-white"
/>
</svelte:fragment>
</SidebarItem>
<SidebarItem label="Site" href="#/site" class="py-1 tall:p-2">
<svelte:fragment slot="icon">
<User
tabindex="-1"
class="w-7 h-7 text-black transition duration-75 dark:text-white group-hover:text-gray-900 dark:group-hover:text-white"
/>
</svelte:fragment>
</SidebarItem>
<SidebarItem label="Messages" href="#/messages" class="py-1 tall:p-2">
<svelte:fragment slot="icon">
<PaperAirplane
tabindex="-1"
class="-rotate-45 w-7 h-7 text-black transition duration-75 dark:text-white group-hover:text-gray-900 dark:group-hover:text-white"
/>
<span
class="inline-flex justify-center items-center p-3 mt-1 -ml-3 w-3 h-3 text-sm font-medium text-primary-600 bg-primary-200 rounded-full dark:bg-primary-900 dark:text-primary-200"
>
3
</span>
</svelte:fragment>
</SidebarItem>
<SidebarItem
label="Notifications"
href="#/notifications"
class="mt-1 py-1 tall:p-2"
>
<svelte:fragment slot="icon">
<Bell
tabindex="-1"
class="w-7 h-7 text-black transition duration-75 dark:text-white group-hover:text-gray-900 dark:group-hover:text-white"
/>
<span
class="inline-flex justify-center items-center p-3 mt-1 -ml-3 w-3 h-3 text-sm font-medium text-primary-600 bg-primary-200 rounded-full dark:bg-primary-900 dark:text-primary-200"
>
10
</span>
</svelte:fragment>
</SidebarItem>
</SidebarGroup>
</SidebarWrapper>
</Sidebar>
<main class="ml-48" bind:this={top}>
<slot />
</main>
</div>
{/if}
<svelte:window bind:innerWidth={width} />
<style>
.full-layout {
height: 100vh;
}
</style>

@ -10,156 +10,45 @@
-->
<script lang="ts">
import {
Sidebar,
SidebarGroup,
SidebarItem,
SidebarWrapper,
} from "flowbite-svelte";
import { link, location } from "svelte-spa-router";
// @ts-ignore
import Logo from "../assets/nextgraph.svg?component";
// @ts-ignore
import LogoGray from "../assets/nextgraph-gray.svg?component";
import { close_active_wallet, online } from "../store";
import { onMount } from "svelte";
import {
Home,
Bolt,
MagnifyingGlass,
PlusCircle,
PaperAirplane,
Bell,
User,
ArrowRightOnRectangle,
} from "svelte-heros-v2";
let width: number;
let breakPoint: number = 660;
let mobile = false;
$: if (width >= breakPoint) {
mobile = false;
} else {
mobile = true;
}
$: activeUrl = "#" + $location;
import { ArrowRightOnRectangle } from "svelte-heros-v2";
import FullLayout from "./FullLayout.svelte";
function logout() {
close_active_wallet();
}
let asideClass = "w-48";
let spanClass = "flex-1 ml-3 whitespace-nowrap";
let nonActiveClass =
"flex items-center p-2 text-base font-normal text-gray-900 rounded-lg dark:text-white hover:bg-gray-200 dark:hover:bg-gray-700";
</script>
<div class="full-layout">
<Sidebar {activeUrl} {asideClass} {nonActiveClass} class="fixed">
<SidebarWrapper class="bg-gray-60">
<SidebarGroup>
<SidebarItem label="NextGraph" href="#/user">
<svelte:fragment slot="icon">
{#if $online}
<Logo class="w-10 h-10" />
{:else}
<LogoGray class="w-10 h-10" />
{/if}
</svelte:fragment>
</SidebarItem>
<SidebarItem label="Home" href="#/">
<svelte:fragment slot="icon">
<Home
tabindex="-1"
class="w-7 h-7 text-black transition duration-75 dark:text-white group-hover:text-gray-900 dark:group-hover:text-white"
/>
</svelte:fragment>
</SidebarItem>
<SidebarItem label="Stream" href="#/stream">
<svelte:fragment slot="icon">
<Bolt
tabindex="-1"
class="w-7 h-7 text-black transition duration-75 dark:text-white group-hover:text-gray-900 dark:group-hover:text-white"
/>
</svelte:fragment>
</SidebarItem>
<SidebarItem label="Search" href="#/search">
<svelte:fragment slot="icon">
<MagnifyingGlass
tabindex="-1"
class="w-7 h-7 text-black transition duration-75 dark:text-white group-hover:text-gray-900 dark:group-hover:text-white"
/>
</svelte:fragment>
</SidebarItem>
<SidebarItem label="Create" href="#/create">
<svelte:fragment slot="icon">
<PlusCircle
tabindex="-1"
class="w-7 h-7 text-black transition duration-75 dark:text-white group-hover:text-gray-900 dark:group-hover:text-white"
/>
</svelte:fragment>
</SidebarItem>
<SidebarItem label="Site" href="#/site">
<svelte:fragment slot="icon">
<User
tabindex="-1"
class="w-7 h-7 text-black transition duration-75 dark:text-white group-hover:text-gray-900 dark:group-hover:text-white"
/>
</svelte:fragment>
</SidebarItem>
<SidebarItem label="Messages" href="#/messages">
<svelte:fragment slot="icon">
<PaperAirplane
tabindex="-1"
class="-rotate-45 w-7 h-7 text-black transition duration-75 dark:text-white group-hover:text-gray-900 dark:group-hover:text-white"
/>
<span
class="inline-flex justify-center items-center p-3 mt-1 -ml-3 w-3 h-3 text-sm font-medium text-primary-600 bg-primary-200 rounded-full dark:bg-primary-900 dark:text-primary-200"
>
3
</span>
</svelte:fragment>
</SidebarItem>
<SidebarItem label="Notifications" href="#/notifications">
<svelte:fragment slot="icon">
<Bell
tabindex="-1"
class="w-7 h-7 text-black transition duration-75 dark:text-white group-hover:text-gray-900 dark:group-hover:text-white"
/>
<span
class="inline-flex justify-center items-center p-3 mt-1 -ml-3 w-3 h-3 text-sm font-medium text-primary-600 bg-primary-200 rounded-full dark:bg-primary-900 dark:text-primary-200"
>
10
</span>
</svelte:fragment>
</SidebarItem>
</SidebarGroup>
</SidebarWrapper>
</Sidebar>
<main class="ml-48">
<h1>Welcoe {mobile}</h1>
<div class="row mt-10">
<button
on:click={logout}
class="text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-100/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-100/55 mr-2 mb-2"
>
<ArrowRightOnRectangle tabindex="-1" class="w-8 h-8 mr-2 -ml-1" />
Logout
</button>
</div>
</main>
</div>
<svelte:window bind:innerWidth={width} />
<style>
.full-layout {
height: 100vh;
}
</style>
<FullLayout>
<h1>Welcome</h1>
<h1>Welcome</h1>
<h1>Welcome</h1>
<h1>Welcome</h1>
<h1>Welcome</h1>
<h1>Welcome</h1>
<h1>Welcome</h1>
<h1>Welcome</h1>
<h1>Welcome</h1>
<h1>Welcome</h1>
<h1>Welcome</h1>
<h1>Welcome</h1>
<h1>Welcome</h1>
<h1>Welcome</h1>
<div class="row mt-10">
<button
on:click={logout}
class="text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-100/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-100/55 mr-2 mb-2"
>
<ArrowRightOnRectangle tabindex="-1" class="w-8 h-8 mr-2 -ml-1" />
Logout
</button>
</div>
<h1>Welcome</h1>
<h1>Welcome</h1>
<h1>Welcome</h1>
<h1>Welcome</h1>
<h1>Welcome</h1>
<h1>End</h1>
</FullLayout>

@ -233,7 +233,7 @@
{:else if step == "pazzle"}
<div
class="h-screen aspect-[3/5] pazzleline"
class:min-w-[350px]={mobile}
class:min-w-[310px]={mobile}
class:min-w-[500px]={!mobile}
class:max-w-[360px]={mobile}
class:max-w-[600px]={!mobile}
@ -258,7 +258,7 @@
<!-- console.log(cat_idx, emoji_cat[cat_idx], idx, cat[idx].code); -->
<div
class="h-screen aspect-[3/3] pazzleline"
class:min-w-[350px]={mobile}
class:min-w-[320px]={mobile}
class:min-w-[500px]={!mobile}
class:max-w-[360px]={mobile}
class:max-w-[600px]={!mobile}
@ -293,17 +293,17 @@
{/each}
</div>
{:else if step == "pin"}
<div class=" max-w-6xl lg:px-8 mx-auto px-4">
<div class=" max-w-6xl lg:px-8 mx-auto px-3">
<p class="max-w-xl md:mx-auto lg:max-w-2xl">
<span class="text-xl">Enter your PIN code</span>
</p>
<div class="w-[325px] mx-auto">
<div class="w-[295px] mx-auto">
{#each [0, 1, 2] as row}
<div class="">
{#each shuffle_pin.slice(0 + row * 3, 3 + row * 3) as num}
<button
tabindex="0"
class="m-1 select-none align-bottom text-7xl w-[100px] h-[100px] p-0"
class="m-1 select-none align-bottom text-7xl w-[90px] h-[90px] p-0"
on:click={async () => await pin(num)}
>
<span>{num}</span>
@ -313,7 +313,7 @@
{/each}
<button
tabindex="0"
class="m-1 select-none mx-auto align-bottom text-7xl w-[100px] h-[100px] p-0"
class="m-1 select-none mx-auto align-bottom text-7xl w-[90px] h-[90px] p-0"
on:click={async () => await pin(shuffle_pin[9])}
>
<span>{shuffle_pin[9]}</span>

@ -0,0 +1,23 @@
<script lang="ts">
import { setContext } from "svelte";
import { writable } from "svelte/store";
export let activeUrl: string = "";
const activeUrlStore = writable("");
$: {
activeUrlStore.set(activeUrl);
}
setContext("activeUrl", activeUrlStore);
</script>
<nav
class="border-t border-solid border-gray-200 bg-white dark:bg-gray-900 text-gray-700 dark:text-gray-200 dark:border-gray-700 divide-gray-100 dark:divide-gray-700 px-2 sm:px-4 py-2.5 w-full fixed bottom-0 left-0 z-20"
>
<div
class="mx-auto flex flex-wrap justify-between items-center w-full px-2 xxs:px-8 xs:px-10"
>
<slot />
</div>
</nav>

@ -0,0 +1,32 @@
<script lang="ts">
import { getContext } from "svelte";
import type { ComponentType } from "svelte";
import { Icon } from "svelte-heros-v2";
export let href: string = "";
export let icon: ComponentType;
const activeUrlStore = getContext("activeUrl") as {
subscribe: (callback: (value: string) => void) => void;
};
let sidebarUrl = "";
activeUrlStore.subscribe((value) => {
// console.log('value: ', value)
sidebarUrl = value;
});
// console.log('sidbarUrl: ', sidebarUrl)
// console.log('href: ', href)
$: active = sidebarUrl ? href === sidebarUrl : false;
// console.log('active: ', active)
</script>
<a {href} class="flex items-center" on:click>
<Icon
tabindex="-1"
color="black"
variation={active ? "solid" : "outline"}
class="w-7 h-7 text-black transition duration-75 dark:text-white group-hover:text-gray-900 dark:group-hover:text-white focus:outline-none"
{icon}
/>
</a>

@ -27,7 +27,7 @@
We could not find a wallet saved on this device.<br /> If you already have
a wallet, select "Log in", otherwise, select "Create Wallet" here below
</p>
<div class="row mt-10">
<div class="row mt-5">
<a href="/wallet/create" use:link>
<button
tabindex="-1"
@ -52,7 +52,7 @@
</button>
</a>
</div>
<div class="row mt-10">
<div class="row mt-5">
<a href="/wallet/login" use:link>
<button
tabindex="-1"

@ -245,7 +245,9 @@
cloud_link = "https://nextgraph.one/#/w/" + ready.wallet_name;
}
if (ready.wallet_file.length) {
const blob = new Blob([ready.wallet_file]);
const blob = new Blob([ready.wallet_file], {
type: "application/octet-stream",
});
download_link = URL.createObjectURL(blob);
}
} catch (e) {
@ -1080,7 +1082,7 @@
</button>
</div>
{:else if pin.length < 4}
<div class=" max-w-6xl lg:px-8 mx-auto px-4">
<div class=" max-w-6xl lg:px-8 mx-auto px-3">
{#if registration_success}
<Alert color="green" class="mb-5">
<span class="font-bold text-xl"
@ -1117,13 +1119,13 @@
>{digit}</span
>{/each}
</Alert>
<div class="w-[325px] mx-auto mb-4">
<div class="w-[295px] mx-auto mb-4">
{#each [0, 1, 2] as row}
<div class="">
{#each [1, 2, 3] as num}
<button
tabindex="0"
class="m-1 select-none align-bottom text-7xl w-[100px] h-[100px] p-0"
class="m-1 select-none align-bottom text-7xl w-[90px] h-[90px] p-0"
on:click={async () => sel_pin(num + row * 3)}
>
<span>{num + row * 3}</span>
@ -1133,7 +1135,7 @@
{/each}
<button
tabindex="0"
class="m-1 select-none mx-auto align-bottom text-7xl w-[100px] h-[100px] p-0"
class="m-1 select-none mx-auto align-bottom text-7xl w-[90px] h-[90px] p-0"
on:click={async () => sel_pin(0)}
>
<span>0</span>
@ -1141,9 +1143,9 @@
</div>
</div>
{:else if pin_confirm.length < 4}
<div class=" max-w-6xl lg:px-8 mx-auto px-4">
<div class=" max-w-6xl lg:px-8 mx-auto px-3">
<p class="max-w-xl md:mx-auto lg:max-w-2xl">
<span class="animate-bounce text-xl"
<span class="text-red-800 text-xl"
>Please confirm your PIN code.</span
>
Enter the same PIN again
@ -1153,13 +1155,13 @@
class="font-bold text-xl">{digit}</span
>{/each}
</Alert>
<div class="w-[325px] mx-auto">
<div class="w-[295px] mx-auto">
{#each [0, 1, 2] as row}
<div class="">
{#each [1, 2, 3] as num}
<button
tabindex="0"
class="m-1 select-none align-bottom text-7xl w-[100px] h-[100px] p-0"
class="m-1 select-none align-bottom text-7xl w-[90px] h-[90px] p-0"
on:click={async () => await confirm_pin(num + row * 3)}
>
<span>{num + row * 3}</span>
@ -1169,7 +1171,7 @@
{/each}
<button
tabindex="0"
class="m-1 select-none mx-auto align-bottom text-7xl w-[100px] h-[100px] p-0"
class="m-1 select-none mx-auto align-bottom text-7xl w-[90px] h-[90px] p-0"
on:click={async () => await confirm_pin(0)}
>
<span>0</span>
@ -1311,7 +1313,7 @@
</Dropzone>
<img
bind:this={img_preview}
class="max-w-[300px] h-[300px] mx-auto mb-10"
class="max-w-[250px] h-[250px] mx-auto mb-10"
src={image_url}
/>
{:else}

@ -31,6 +31,7 @@
let step;
let error;
let importing = false;
let top;
let wallets_unsub;
let opened_wallets_unsub;
@ -134,166 +135,99 @@
};
}
}
function scrollToTop() {
top.scrollIntoView();
}
onMount(() => scrollToTop());
</script>
<CenteredLayout>
{#if error}
<div class=" max-w-6xl lg:px-8 mx-auto px-4 text-red-800">
<svg
class="animate-bounce mt-10 h-16 w-16 mx-auto"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z"
/>
</svg>
<p class="max-w-xl md:mx-auto lg:max-w-2xl mb-5">
An error occurred:<br />{error}
</p>
<button
on:click={() => {
importing = false;
error = undefined;
wallet = undefined;
}}
class="text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2"
>
Start over
</button>
</div>
{:else if wallet}
<Login
{wallet}
on:error={gotError}
on:opened={gotWallet}
on:cancel={cancelLogin}
/>
{:else if !$active_wallet && !selected}
<div class="row">
<Logo class="logo block h-40" alt="NextGraph Logo" />
</div>
<h2 class="pb-5 text-xl">Select a wallet to login with</h2>
<div class="flex flex-wrap justify-center gap-5 mb-20">
{#each Object.entries($wallets) as wallet_entry}
<div
class="wallet-box"
role="button"
tabindex="0"
title={wallet_entry[0]}
on:click={() => {
select(wallet_entry[0]);
}}
on:keypress={() => {
select(wallet_entry[0]);
}}
<div bind:this={top}>
<CenteredLayout>
{#if error}
<div class=" max-w-6xl lg:px-8 mx-auto px-4 text-red-800">
<svg
class="animate-bounce mt-10 h-16 w-16 mx-auto"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<span class="securitytxt"
>{wallet_entry[1].wallet.V0.content.security_txt}
</span>
<img
alt={wallet_entry[1].wallet.V0.content.security_txt}
class="securityimg"
src={convert_img_to_url(
wallet_entry[1].wallet.V0.content.security_img
)}
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z"
/>
</div>
{/each}
<div class="wallet-box">
{#if $has_wallets}<p class="mt-1">Log in with another wallet</p>
{:else}<p class="mt-1">Import your wallet</p>
{/if}
<Fileupload
style="display:none;"
id="import_wallet_file"
accept=".ngw, .txt"
on:change={handleWalletUpload}
/>
</svg>
<p class="max-w-xl md:mx-auto lg:max-w-2xl mb-5">
An error occurred:<br />{error}
</p>
<button
class=" mt-1 text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-100/55 mb-2"
on:click={() => {
document.getElementById("import_wallet_file").click();
importing = false;
error = undefined;
wallet = undefined;
}}
class="text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2"
>
<svg
class="w-8 h-8 mr-2 -ml-1"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M9 8.25H7.5a2.25 2.25 0 00-2.25 2.25v9a2.25 2.25 0 002.25 2.25h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25H15M9 12l3 3m0 0l3-3m-3 3V2.25"
/>
</svg>
Import a Wallet File
Start over
</button>
<Button
style="min-width: 250px;justify-content: left;"
disabled
class="disabled mt-1 text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center justify-center dark:focus:ring-primary-100/55 mb-2"
>
<svg
class="w-8 h-8 mr-2 -ml-1"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M3.75 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5A1.125 1.125 0 013.75 9.375v-4.5zM3.75 14.625c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5a1.125 1.125 0 01-1.125-1.125v-4.5zM13.5 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5A1.125 1.125 0 0113.5 9.375v-4.5z"
/>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M6.75 6.75h.75v.75h-.75v-.75zM6.75 16.5h.75v.75h-.75v-.75zM16.5 6.75h.75v.75h-.75v-.75zM13.5 13.5h.75v.75h-.75v-.75zM13.5 19.5h.75v.75h-.75v-.75zM19.5 13.5h.75v.75h-.75v-.75zM19.5 19.5h.75v.75h-.75v-.75zM16.5 16.5h.75v.75h-.75v-.75z"
/>
</svg>
Import with QRcode
</Button>
<Button
style="min-width: 250px;justify-content: left;"
disabled
class="mt-1 text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-100/55 mb-2"
>
<svg
class="w-8 h-8 mr-2 -ml-1"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
</div>
{:else if wallet}
<Login
{wallet}
on:error={gotError}
on:opened={gotWallet}
on:cancel={cancelLogin}
/>
{:else if !$active_wallet && !selected}
<div class="row">
<Logo class="logo block h-40" alt="NextGraph Logo" />
</div>
<h2 class="pb-5 text-xl">Select a wallet to login with</h2>
<div class="flex flex-wrap justify-center gap-5 mb-20">
{#each Object.entries($wallets) as wallet_entry}
<div
class="wallet-box"
role="button"
tabindex="0"
title={wallet_entry[0]}
on:click={() => {
select(wallet_entry[0]);
}}
on:keypress={() => {
select(wallet_entry[0]);
}}
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"
<span class="securitytxt"
>{wallet_entry[1].wallet.V0.content.security_txt}
</span>
<img
alt={wallet_entry[1].wallet.V0.content.security_txt}
class="securityimg"
src={convert_img_to_url(
wallet_entry[1].wallet.V0.content.security_img
)}
/>
</svg>
Enter a Wallet Link
</Button>
<a href="/wallet/create" use:link>
</div>
{/each}
<div class="wallet-box">
{#if $has_wallets}<p class="mt-1">Log in with another wallet</p>
{:else}<p class="mt-1">Import your wallet</p>
{/if}
<Fileupload
style="display:none;"
id="import_wallet_file"
accept="application/octet-stream, .ngw"
on:change={handleWalletUpload}
/>
<button
tabindex="-1"
class="mt-1 text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-100/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2"
class=" mt-1 text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-100/55 mb-2"
on:click={() => {
document.getElementById("import_wallet_file").click();
}}
>
<svg
class="w-8 h-8 mr-2 -ml-1"
@ -307,17 +241,90 @@
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M19 7.5v3m0 0v3m0-3h3m-3 0h-3m-2.25-4.125a3.375 3.375 0 11-6.75 0 3.375 3.375 0 016.75 0zM4 19.235v-.11a6.375 6.375 0 0112.75 0v.109A12.318 12.318 0 0110.374 21c-2.331 0-4.512-.645-6.374-1.766z"
d="M9 8.25H7.5a2.25 2.25 0 00-2.25 2.25v9a2.25 2.25 0 002.25 2.25h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25H15M9 12l3 3m0 0l3-3m-3 3V2.25"
/>
</svg>
Create a new wallet
Import a Wallet File
</button>
</a>
<Button
style="min-width: 250px;justify-content: left;"
disabled
class="disabled mt-1 text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center justify-center dark:focus:ring-primary-100/55 mb-2"
>
<svg
class="w-8 h-8 mr-2 -ml-1"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M3.75 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5A1.125 1.125 0 013.75 9.375v-4.5zM3.75 14.625c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5a1.125 1.125 0 01-1.125-1.125v-4.5zM13.5 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5A1.125 1.125 0 0113.5 9.375v-4.5z"
/>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M6.75 6.75h.75v.75h-.75v-.75zM6.75 16.5h.75v.75h-.75v-.75zM16.5 6.75h.75v.75h-.75v-.75zM13.5 13.5h.75v.75h-.75v-.75zM13.5 19.5h.75v.75h-.75v-.75zM19.5 13.5h.75v.75h-.75v-.75zM19.5 19.5h.75v.75h-.75v-.75zM16.5 16.5h.75v.75h-.75v-.75z"
/>
</svg>
Import with QRcode
</Button>
<Button
style="min-width: 250px;justify-content: left;"
disabled
class="mt-1 text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-100/55 mb-2"
>
<svg
class="w-8 h-8 mr-2 -ml-1"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"
/>
</svg>
Enter a Wallet Link
</Button>
<a href="/wallet/create" use:link>
<button
tabindex="-1"
class="mt-1 text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-100/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2"
>
<svg
class="w-8 h-8 mr-2 -ml-1"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M19 7.5v3m0 0v3m0-3h3m-3 0h-3m-2.25-4.125a3.375 3.375 0 11-6.75 0 3.375 3.375 0 016.75 0zM4 19.235v-.11a6.375 6.375 0 0112.75 0v.109A12.318 12.318 0 0110.374 21c-2.331 0-4.512-.645-6.374-1.766z"
/>
</svg>
Create a new wallet
</button>
</a>
</div>
</div>
</div>
{:else if step == "security"}{:else if step == "qrcode"}{:else if step == "cloud"}{:else if step == "loggedin"}you
are logged in{/if}
</CenteredLayout>
{:else if step == "security"}{:else if step == "qrcode"}{:else if step == "cloud"}{:else if step == "loggedin"}you
are logged in{/if}
</CenteredLayout>
</div>
<style>
.wallet-box {

@ -30,7 +30,7 @@ div[role="alert"] div {
}
.choice-button {
min-width: 340px;
min-width: 320px;
}
.row {
@ -58,7 +58,7 @@ body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-width: 305px;
min-height: 100vh;
}

@ -1,4 +1,5 @@
/** @type {import('tailwindcss').Config}*/
const defaultTheme = require('tailwindcss/defaultTheme')
const config = {
content: [
"./src/**/*.{html,js,svelte,ts}",
@ -9,7 +10,13 @@ const config = {
extend: {
colors: {
primary: { "50": "#eff6ff", "100": "#dbeafe", "200": "#bfdbfe", "300": "#93c5fd", "400": "#60a5fa", "500": "#3b82f6", "600": "#1E88E5", "700": "#4972A5", "800": "#1e40af", "900": "#1e3a8a" }
}
},
},
screens: {
'xxs': '400px',
'xs': '500px',
...defaultTheme.screens,
'tall': { 'raw': '(min-height: 450px)' },
},
},

@ -28,3 +28,11 @@
<main class="">
<Router {routes} />
</main>
<style>
main {
margin: 0 auto;
padding: 0rem;
text-align: center;
}
</style>

@ -307,7 +307,7 @@
<span>
You can delete your account with us at any time by going to the
link <a target="_blank" href="https://account.{domain}/#/delete"
>https://account.{domain}/#/delete</a
>account.{domain}/#/delete</a
> or by entering in your NextGraph application and selecting the
menu, then Accounts, then under broker "delete registration"</span
>

@ -30,3 +30,11 @@
<main class="">
<Router {routes} />
</main>
<style>
main {
margin: 0 auto;
padding: 0rem;
text-align: center;
}
</style>

Loading…
Cancel
Save