design improvement and consistency
This commit is contained in:
parent
6ee0809661
commit
f70f4c4518
12 changed files with 135 additions and 110 deletions
|
@ -63,31 +63,6 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: var(--spacing-md);
|
padding: var(--spacing-md);
|
||||||
|
|
||||||
> :global(.title) {
|
|
||||||
position: fixed;
|
|
||||||
display: flex;
|
|
||||||
width: calc(100% + 2 * var(--spacing-md));
|
|
||||||
margin: calc(var(--spacing-md) * -1);
|
|
||||||
padding: var(--spacing-md);
|
|
||||||
background: color-mix(in oklab, black 50%, var(--accent));
|
|
||||||
z-index: 99999;
|
|
||||||
|
|
||||||
> :global(.close-button) {
|
|
||||||
position: absolute;
|
|
||||||
top: var(--spacing-md);
|
|
||||||
right: calc(
|
|
||||||
var(--spacing-md) * 2 + 1.5rem
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(& + *) {
|
|
||||||
margin-top: calc(
|
|
||||||
1.5rem +
|
|
||||||
var(--spacing-md) * 3
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> :global(*:not(:last-child)) {
|
> :global(*:not(:last-child)) {
|
||||||
margin-bottom: var(--spacing-sm);
|
margin-bottom: var(--spacing-sm);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
bind:open={isAddingFolder}
|
bind:open={isAddingFolder}
|
||||||
onClose={newFolderDialogClosed}
|
onClose={newFolderDialogClosed}
|
||||||
>
|
>
|
||||||
<div class="title">
|
<div class="section-title">
|
||||||
<h3>Create Folder</h3>
|
<h3>Create Folder</h3>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-secondary">Please enter a name for the new folder:</p>
|
<p class="text-secondary">Please enter a name for the new folder:</p>
|
||||||
|
@ -63,7 +63,7 @@
|
||||||
<hr />
|
<hr />
|
||||||
{/if}
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
<IconButton icon="eos-icons:plus" onclick={() => isAddingFolder = true} text="Add Folder" />
|
<IconButton icon="pajamas:folder-new" onclick={() => isAddingFolder = true} text="Add Folder" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { activeUser, ndk } from '$lib/stores.svelte';
|
import { activeUser, ndk, pageIcon, pageTitle } from '$lib/stores.svelte';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { browser } from '$app/environment';
|
import { browser } from '$app/environment';
|
||||||
import { NDKNip07Signer, NDKPrivateKeySigner } from '@nostr-dev-kit/ndk';
|
import { NDKNip07Signer, NDKPrivateKeySigner } from '@nostr-dev-kit/ndk';
|
||||||
|
@ -71,6 +71,8 @@
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if ($ndk.activeUser)
|
if ($ndk.activeUser)
|
||||||
activeUser.set($ndk.activeUser);
|
activeUser.set($ndk.activeUser);
|
||||||
|
$pageTitle = 'Login';
|
||||||
|
$pageIcon = 'line-md:login';
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -7,12 +7,12 @@
|
||||||
import Select from './Select.svelte';
|
import Select from './Select.svelte';
|
||||||
import type { Letter } from '$lib/letter';
|
import type { Letter } from '$lib/letter';
|
||||||
import { slide } from 'svelte/transition';
|
import { slide } from 'svelte/transition';
|
||||||
import IconButton from './IconButton.svelte';
|
|
||||||
|
|
||||||
let {
|
let {
|
||||||
letters,
|
letters,
|
||||||
foldersList = $bindable<{ id: string; name: string; icon: string }[]>(),
|
foldersList = $bindable<{ id: string; name: string; icon: string }[]>(),
|
||||||
folder = $bindable<{ id: string; name: string; icon: string }>()
|
folder = $bindable<{ id: string; name: string; icon: string }>(),
|
||||||
|
moveFolderDialogOpen = $bindable<boolean>()
|
||||||
} = $props();
|
} = $props();
|
||||||
|
|
||||||
function formatRange(start, end) {
|
function formatRange(start, end) {
|
||||||
|
@ -83,7 +83,6 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
let selectedLetters = $state<string[]>([]);
|
let selectedLetters = $state<string[]>([]);
|
||||||
let moveFolderDialogOpen = $state(false);
|
|
||||||
let moveFolderName = $state('');
|
let moveFolderName = $state('');
|
||||||
|
|
||||||
function clickedLetter(letter: Letter) {
|
function clickedLetter(letter: Letter) {
|
||||||
|
@ -125,7 +124,7 @@
|
||||||
</div>
|
</div>
|
||||||
{#if letter.stamps}
|
{#if letter.stamps}
|
||||||
<div class="stamps-count">
|
<div class="stamps-count">
|
||||||
<Icon icon="emojione-v1:stamped-envelope" />
|
<Icon icon="fxemoji:stampedenvelope" />
|
||||||
{letter.stamps} sats
|
{letter.stamps} sats
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -140,10 +139,10 @@
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="letter-meta">
|
<div class="letter-meta">
|
||||||
<Icon icon="mdi:calendar" />
|
<Icon icon="ph:calendar-duotone" />
|
||||||
{getReadableDate(letter.date)}
|
{getReadableDate(letter.date)}
|
||||||
|
|
||||||
<Icon icon="mdi:clock-outline" />
|
<Icon icon="ph:clock-duotone" />
|
||||||
{getReadableTime(letter.date)}
|
{getReadableTime(letter.date)}
|
||||||
</div>
|
</div>
|
||||||
<div class="letter-preview">{letter.preview}</div>
|
<div class="letter-preview">{letter.preview}</div>
|
||||||
|
@ -156,7 +155,7 @@
|
||||||
<Dialog
|
<Dialog
|
||||||
bind:open={moveFolderDialogOpen}
|
bind:open={moveFolderDialogOpen}
|
||||||
>
|
>
|
||||||
<div class="title">
|
<div class="section-title">
|
||||||
<h3>Move Letters to Folder</h3>
|
<h3>Move Letters to Folder</h3>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-secondary">Select a folder to move the selected letters to:</p>
|
<p class="text-secondary">Select a folder to move the selected letters to:</p>
|
||||||
|
@ -181,7 +180,7 @@
|
||||||
</div>
|
</div>
|
||||||
{#if letter.stamps}
|
{#if letter.stamps}
|
||||||
<div class="stamps-count">
|
<div class="stamps-count">
|
||||||
<Icon icon="emojione-v1:stamped-envelope" />
|
<Icon icon="fxemoji:stampedenvelope" />
|
||||||
{letter.stamps} sats
|
{letter.stamps} sats
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -201,14 +200,6 @@
|
||||||
</div>
|
</div>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
||||||
<h2 id="page-title">
|
|
||||||
{folder.name}
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<div class="actions">
|
|
||||||
<IconButton icon="mdi:folder-move-outline" onclick={() => moveFolderDialogOpen = true} text="Move Letters" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<main class="letter-list">
|
<main class="letter-list">
|
||||||
{#if $groupByStamps}
|
{#if $groupByStamps}
|
||||||
{#each groupedInbox as [range, letters]}
|
{#each groupedInbox as [range, letters]}
|
||||||
|
@ -317,12 +308,5 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: var(--spacing-sm);
|
|
||||||
margin-bottom: var(--spacing-sm);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -33,6 +33,6 @@
|
||||||
<div class="notification-message">{@render children?.()}</div>
|
<div class="notification-message">{@render children?.()}</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="close-button" onclick={hide}>
|
<button class="close-button" onclick={hide}>
|
||||||
<Icon icon="mdi:close" />
|
<Icon icon="si:close-circle-duotone" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
|
@ -49,16 +49,18 @@
|
||||||
--glass-border: color-mix(in srgb, white 12%, transparent);
|
--glass-border: color-mix(in srgb, white 12%, transparent);
|
||||||
--glass-shadow: rgb(0 0 0 / 0.1);
|
--glass-shadow: rgb(0 0 0 / 0.1);
|
||||||
--glass-glow: oklch(67% 0.2 var(--base-hue) / 0.15);
|
--glass-glow: oklch(67% 0.2 var(--base-hue) / 0.15);
|
||||||
--depth-shadow: 0 8px 32px -8px rgb(0 0 0 / 0.3);
|
--depth-shadow: 0 10px 30px -10px hsl(var(--base-hue) 30% 5% / 0.3),
|
||||||
|
0 4px 6px -4px hsl(var(--base-hue) 30% 5% / 0.2);
|
||||||
--noise-filter: url("data:image/svg+xml,%3Csvg width='1000' height='1000' viewBox='0 0 1000 1000' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='4' stitchTiles='stitch' seed='2' result='noise'/%3E%3CfeColorMatrix type='saturate' values='0' in='noise' result='desaturatedNoise'/%3E%3CfeBlend in='SourceGraphic' in2='desaturatedNoise' mode='overlay' result='blend'/%3E%3CfeComposite operator='in' in2='SourceGraphic'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E#noiseFilter");
|
--noise-filter: url("data:image/svg+xml,%3Csvg width='1000' height='1000' viewBox='0 0 1000 1000' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='4' stitchTiles='stitch' seed='2' result='noise'/%3E%3CfeColorMatrix type='saturate' values='0' in='noise' result='desaturatedNoise'/%3E%3CfeBlend in='SourceGraphic' in2='desaturatedNoise' mode='overlay' result='blend'/%3E%3CfeComposite operator='in' in2='SourceGraphic'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E#noiseFilter");
|
||||||
--gradient-shine: linear-gradient(
|
--gradient-shine: linear-gradient(
|
||||||
135deg,
|
135deg,
|
||||||
transparent 25%,
|
transparent 20%,
|
||||||
rgb(255 255 255 / 0.1) 50%,
|
hsl(var(--base-hue) 100% 100% / 0.1) 40%,
|
||||||
transparent 75%
|
transparent 60%
|
||||||
);
|
);
|
||||||
--base-hue: 200;
|
--base-hue: 200;
|
||||||
--accent: oklch(67% 0.2 var(--base-hue));
|
--accent: oklch(67% 0.2 var(--base-hue));
|
||||||
|
--ternary: oklch(25% 0.3 var(--base-hue));
|
||||||
--accent-light: oklch(75% 0.2 var(--base-hue));
|
--accent-light: oklch(75% 0.2 var(--base-hue));
|
||||||
--text-primary: oklch(100% 0 0);
|
--text-primary: oklch(100% 0 0);
|
||||||
--text-secondary: oklch(100% 0 0 / 0.7);
|
--text-secondary: oklch(100% 0 0 / 0.7);
|
||||||
|
@ -478,3 +480,33 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
position: fixed;
|
||||||
|
display: flex;
|
||||||
|
width: calc(100%);
|
||||||
|
margin: calc(var(--spacing-md) * -1);
|
||||||
|
padding: var(--spacing-md);
|
||||||
|
background: var(--ternary);
|
||||||
|
border: 1px solid var(--accent);
|
||||||
|
z-index: 99999;
|
||||||
|
border-top-left-radius: 16px;
|
||||||
|
border-top-right-radius: 16px;
|
||||||
|
place-content: center;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--spacing-xs);
|
||||||
|
|
||||||
|
> .close-button {
|
||||||
|
position: absolute;
|
||||||
|
top: var(--spacing-md);
|
||||||
|
right: calc(
|
||||||
|
var(--spacing-md) * 2 + 1.5rem
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
& + * {
|
||||||
|
margin-top: calc(
|
||||||
|
1.5rem +
|
||||||
|
var(--spacing-md) * 3
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -46,6 +46,9 @@ export const timeFormat = writable(
|
||||||
browser ? localStorage.getItem('timeFormat') || 'h:m:s' : 'h:m:s'
|
browser ? localStorage.getItem('timeFormat') || 'h:m:s' : 'h:m:s'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export let pageTitle = writable('loading');
|
||||||
|
export let pageIcon = writable('');
|
||||||
|
|
||||||
if (browser) {
|
if (browser) {
|
||||||
baseHue.subscribe((value) => {
|
baseHue.subscribe((value) => {
|
||||||
document.documentElement.style.setProperty('--base-hue', value.toString());
|
document.documentElement.style.setProperty('--base-hue', value.toString());
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { activeUser, baseHue, ndk } from '$lib/stores.svelte';
|
import { activeUser, baseHue, ndk, pageIcon, pageTitle } from '$lib/stores.svelte';
|
||||||
import LoginWithNostr from '../components/LoginWithNostr.svelte';
|
import LoginWithNostr from '../components/LoginWithNostr.svelte';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { NDKNip07Signer } from '@nostr-dev-kit/ndk';
|
import { NDKNip07Signer } from '@nostr-dev-kit/ndk';
|
||||||
import IconButton from '../components/IconButton.svelte';
|
import IconButton from '../components/IconButton.svelte';
|
||||||
|
import Icon from '@iconify/svelte';
|
||||||
|
|
||||||
|
let { children } = $props();
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
if (localStorage.getItem('useNip07')) {
|
if (localStorage.getItem('useNip07')) {
|
||||||
|
@ -35,8 +38,15 @@
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
|
<div class="section-title">
|
||||||
|
{#if $pageIcon}
|
||||||
|
<Icon width="1.5em" icon={$pageIcon} />
|
||||||
|
{/if}
|
||||||
|
<h3>{$pageTitle}</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
{#if $activeUser}
|
{#if $activeUser}
|
||||||
<slot></slot>
|
{@render children?.()}
|
||||||
{:else}
|
{:else}
|
||||||
<LoginWithNostr />
|
<LoginWithNostr />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { ndk } from '$lib/stores.svelte';
|
import { ndk, pageIcon, pageTitle } from '$lib/stores.svelte';
|
||||||
import Icon from '@iconify/svelte';
|
import Icon from '@iconify/svelte';
|
||||||
import MailboxFolderItems from '../components/MailboxFolderItems.svelte';
|
import MailboxFolderItems from '../components/MailboxFolderItems.svelte';
|
||||||
import { decryptSealedMessageIntoReadableType } from '$lib/utils.svelte';
|
import { decryptSealedMessageIntoReadableType } from '$lib/utils.svelte';
|
||||||
|
@ -9,6 +9,7 @@
|
||||||
import { LetterToFolderMapping } from '$lib/letterToFolderMapping';
|
import { LetterToFolderMapping } from '$lib/letterToFolderMapping';
|
||||||
import IconButton from '../components/IconButton.svelte';
|
import IconButton from '../components/IconButton.svelte';
|
||||||
import FoldersListSidebar from '../components/FoldersListSidebar.svelte';
|
import FoldersListSidebar from '../components/FoldersListSidebar.svelte';
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
|
||||||
let sidebarOpen = $state(false);
|
let sidebarOpen = $state(false);
|
||||||
|
|
||||||
|
@ -78,13 +79,25 @@
|
||||||
function changeFolder(newFolder: string) {
|
function changeFolder(newFolder: string) {
|
||||||
letters = [];
|
letters = [];
|
||||||
activeFolder = newFolder;
|
activeFolder = newFolder;
|
||||||
|
$pageTitle = folders.find(f => f.id === newFolder)!.name;
|
||||||
|
$pageIcon = folders.find(f => f.id === newFolder)!.icon;
|
||||||
decryptMessages($messages);
|
decryptMessages($messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let moveFolderDialogOpen = $state(false);
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
$pageTitle = 'Inbox';
|
||||||
|
$pageIcon = 'solar:inbox-bold-duotone';
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<IconButton icon="mynaui:sidebar-solid" onclick={() => sidebarOpen = !sidebarOpen} text="Sidebar" />
|
<div class="actions">
|
||||||
|
<IconButton icon="mynaui:sidebar-solid" onclick={() => sidebarOpen = !sidebarOpen} text="Sidebar" />
|
||||||
|
<IconButton icon="mdi:folder-move-outline" onclick={() => moveFolderDialogOpen = true} text="Move Letters" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="content">
|
<div class="content" class:sidebar-open={sidebarOpen}>
|
||||||
<FoldersListSidebar bind:folders bind:sidebarOpen {changeFolder} />
|
<FoldersListSidebar bind:folders bind:sidebarOpen {changeFolder} />
|
||||||
|
|
||||||
<div class="folder-view">
|
<div class="folder-view">
|
||||||
|
@ -95,7 +108,8 @@
|
||||||
If you have letters, they will appear here, please wait...
|
If you have letters, they will appear here, please wait...
|
||||||
</p>
|
</p>
|
||||||
{:else}
|
{:else}
|
||||||
<MailboxFolderItems foldersList={folders} folder={folders.find(f => f.id === activeFolder)} {letters} />
|
<MailboxFolderItems bind:moveFolderDialogOpen foldersList={folders}
|
||||||
|
folder={folders.find(f => f.id === activeFolder)} {letters} />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -103,10 +117,21 @@
|
||||||
<style>
|
<style>
|
||||||
.content {
|
.content {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
gap: 0;
|
||||||
|
transition: gap 0.3s ease;
|
||||||
|
|
||||||
|
&.sidebar-open {
|
||||||
gap: var(--spacing-sm);
|
gap: var(--spacing-sm);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.folder-view {
|
.folder-view {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
display: flex;
|
||||||
|
gap: var(--spacing-sm);
|
||||||
|
margin-bottom: var(--spacing-sm);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
|
@ -1,7 +1,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import RecipientChip from '../../components/RecipientChip.svelte';
|
import RecipientChip from '../../components/RecipientChip.svelte';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { ndk } from '$lib/stores.svelte';
|
import { ndk, pageIcon, pageTitle } from '$lib/stores.svelte';
|
||||||
import Notification from '../../components/Notification.svelte';
|
import Notification from '../../components/Notification.svelte';
|
||||||
import { createCarbonCopyLetter, createSealedLetter } from '$lib/utils.svelte';
|
import { createCarbonCopyLetter, createSealedLetter } from '$lib/utils.svelte';
|
||||||
import type { NDKUser } from '@nostr-dev-kit/ndk';
|
import type { NDKUser } from '@nostr-dev-kit/ndk';
|
||||||
|
@ -19,6 +19,11 @@
|
||||||
let tokenInfo = $state<TokenInfoWithMailSubscriptionDuration>();
|
let tokenInfo = $state<TokenInfoWithMailSubscriptionDuration>();
|
||||||
let tokenInfoError = $state('');
|
let tokenInfoError = $state('');
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
if (isSending) $pageTitle = 'Sending...';
|
||||||
|
else $pageTitle = 'New Letter';
|
||||||
|
});
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
try {
|
try {
|
||||||
tokenInfo = new TokenInfoWithMailSubscriptionDuration(stamp);
|
tokenInfo = new TokenInfoWithMailSubscriptionDuration(stamp);
|
||||||
|
@ -111,6 +116,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
|
$pageTitle = 'New Letter';
|
||||||
|
$pageIcon = 'proicons:compose';
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
if (urlParams.has('replyTo'))
|
if (urlParams.has('replyTo'))
|
||||||
replyTo = urlParams.get('replyTo');
|
replyTo = urlParams.get('replyTo');
|
||||||
|
@ -129,19 +136,8 @@
|
||||||
</Notification>
|
</Notification>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if isSending}
|
{#if !isSending}
|
||||||
<div class="compose-container">
|
<div class="compose-container">
|
||||||
<div class="compose-header">
|
|
||||||
<div id="page-title">Sending Letter...</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{:else}
|
|
||||||
<div class="compose-container">
|
|
||||||
<div class="compose-header">
|
|
||||||
<div id="page-title">New Message</div>
|
|
||||||
<button class="button">Close</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="compose-fields">
|
<div class="compose-fields">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>To:</label>
|
<label>To:</label>
|
||||||
|
@ -152,7 +148,6 @@
|
||||||
{/each}
|
{/each}
|
||||||
<input
|
<input
|
||||||
bind:value={toField}
|
bind:value={toField}
|
||||||
class="input"
|
|
||||||
onkeyup={recepientInput}
|
onkeyup={recepientInput}
|
||||||
placeholder="Enter npub or nip05..."
|
placeholder="Enter npub or nip05..."
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -175,9 +170,9 @@
|
||||||
<p class="error">
|
<p class="error">
|
||||||
{tokenInfoError}
|
{tokenInfoError}
|
||||||
</p>
|
</p>
|
||||||
{:else if tokenInfo}
|
{:else if tokenInfo && stamp.length > 0}
|
||||||
<p class="stamp-count">
|
<p class="stamp-count">
|
||||||
<Icon icon="emojione-v1:stamped-envelope" /> {tokenInfo.amount} sats
|
<Icon icon="fxemoji:stampedenvelope" /> {tokenInfo.amount} sats
|
||||||
</p>
|
</p>
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -200,14 +195,6 @@
|
||||||
gap: var(--spacing-md);
|
gap: var(--spacing-md);
|
||||||
}
|
}
|
||||||
|
|
||||||
.compose-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding-bottom: var(--spacing-md);
|
|
||||||
border-bottom: 1px solid var(--glass-border);
|
|
||||||
}
|
|
||||||
|
|
||||||
.compose-fields {
|
.compose-fields {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: var(--spacing-sm);
|
gap: var(--spacing-sm);
|
||||||
|
@ -216,7 +203,12 @@
|
||||||
position: relative;
|
position: relative;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 80px 1fr;
|
grid-template-columns: 80px 1fr;
|
||||||
|
place-items: end;
|
||||||
|
align-items: center;
|
||||||
gap: var(--spacing-sm);
|
gap: var(--spacing-sm);
|
||||||
|
background: var(--glass-bg);
|
||||||
|
border: 1px solid var(--glass-border);
|
||||||
|
padding: var(--spacing-md);
|
||||||
|
|
||||||
& .to {
|
& .to {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -227,6 +219,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
& label {
|
& label {
|
||||||
|
font-weight: bolder;
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,20 +260,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@layer components {
|
@layer components {
|
||||||
.input {
|
input {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
background: transparent;
|
|
||||||
border: 1px solid var(--input-border);
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 0.5rem;
|
|
||||||
color: var(--text-primary);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
border-color: var(--accent);
|
|
||||||
box-shadow: 0 0 0 3px var(--input-focus);
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.send-button {
|
.send-button {
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
</div>
|
</div>
|
||||||
{:else if error}
|
{:else if error}
|
||||||
<div class="error-state">
|
<div class="error-state">
|
||||||
<Icon icon="eos-icons:close" width="5em" />
|
<Icon icon="si:close-circle-duotone" width="5em" />
|
||||||
<span>{error}</span>
|
<span>{error}</span>
|
||||||
</div>
|
</div>
|
||||||
{:else if letter}
|
{:else if letter}
|
||||||
|
@ -63,7 +63,11 @@
|
||||||
<div class="header-main">
|
<div class="header-main">
|
||||||
<div class="header-info">
|
<div class="header-info">
|
||||||
<div class="subject">
|
<div class="subject">
|
||||||
<Icon icon="mdi:letter-outline" />
|
{#if letter.emailAddress}
|
||||||
|
<Icon icon="mdi:email-lock" width="32" />
|
||||||
|
{:else}
|
||||||
|
<img src="/nostr-lock.svg" width="32" />
|
||||||
|
{/if}
|
||||||
<h1>{letter.subject}</h1>
|
<h1>{letter.subject}</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -86,7 +90,7 @@
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
{#if letter.stamp}
|
{#if letter.stamp}
|
||||||
<div onclick={() => stampDialogOpen = true} class="stamp-count button">
|
<div onclick={() => stampDialogOpen = true} class="stamp-count button">
|
||||||
<Icon icon="emojione-v1:stamped-envelope" />
|
<Icon icon="fxemoji:stampedenvelope" />
|
||||||
<span>{letter.stamp.amount} sats</span>
|
<span>{letter.stamp.amount} sats</span>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -100,10 +104,10 @@
|
||||||
|
|
||||||
<div class="metadata">
|
<div class="metadata">
|
||||||
<div class="timestamp">
|
<div class="timestamp">
|
||||||
<Icon icon="mdi:calendar" />
|
<Icon icon="ph:calendar-duotone" />
|
||||||
<span>{getReadableDate(letter.date)}</span>
|
<span>{getReadableDate(letter.date)}</span>
|
||||||
<div class="separator" />
|
<div class="separator" />
|
||||||
<Icon icon="mdi:clock-outline" />
|
<Icon icon="ph:clock-duotone" />
|
||||||
<span>{getReadableTime(letter.date)}</span>
|
<span>{getReadableTime(letter.date)}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -114,7 +118,7 @@
|
||||||
|
|
||||||
<Dialog bind:open={stampDialogOpen}>
|
<Dialog bind:open={stampDialogOpen}>
|
||||||
{#if letter && letter.stamp}
|
{#if letter && letter.stamp}
|
||||||
<div class="title">
|
<div class="section-title">
|
||||||
<h3>Bitcoin Stamp</h3>
|
<h3>Bitcoin Stamp</h3>
|
||||||
<button class="close-button" onclick={() => stampDialogOpen = false}>Close</button>
|
<button class="close-button" onclick={() => stampDialogOpen = false}>Close</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -127,7 +131,7 @@
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<div class="stamp-count">
|
<div class="stamp-count">
|
||||||
<Icon icon="emojione-v1:stamped-envelope" />
|
<Icon icon="fxemoji:stampedenvelope" />
|
||||||
<span>{letter.stamp.amount} sats</span>
|
<span>{letter.stamp.amount} sats</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,14 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { activeUser, baseHue, groupByStamps, ndk, sortBy, validSortOptions } from '$lib/stores.svelte';
|
import {
|
||||||
|
activeUser,
|
||||||
|
baseHue,
|
||||||
|
groupByStamps,
|
||||||
|
ndk,
|
||||||
|
pageIcon,
|
||||||
|
pageTitle,
|
||||||
|
sortBy,
|
||||||
|
validSortOptions
|
||||||
|
} from '$lib/stores.svelte';
|
||||||
import ColorPicker from '../../components/ColorPicker.svelte';
|
import ColorPicker from '../../components/ColorPicker.svelte';
|
||||||
import SettingsLine from '../../components/SettingsLine.svelte';
|
import SettingsLine from '../../components/SettingsLine.svelte';
|
||||||
import Checkbox from '../../components/Checkbox.svelte';
|
import Checkbox from '../../components/Checkbox.svelte';
|
||||||
|
@ -166,13 +175,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
|
$pageTitle = 'Settings';
|
||||||
|
$pageIcon = 'si:settings-cute-line';
|
||||||
await reloadAliases();
|
await reloadAliases();
|
||||||
await reloadSubscriptionStatus();
|
await reloadSubscriptionStatus();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<h2 id="page-title">Settings</h2>
|
|
||||||
|
|
||||||
<SettingsLine title="Your Nostr Public Key">
|
<SettingsLine title="Your Nostr Public Key">
|
||||||
<code>{$activeUser?.npub}</code>
|
<code>{$activeUser?.npub}</code>
|
||||||
</SettingsLine>
|
</SettingsLine>
|
||||||
|
|
Loading…
Add table
Reference in a new issue