mirror of
https://github.com/coracle-social/flotilla.git
synced 2025-12-10 10:57:04 +00:00
Work on add space modal
This commit is contained in:
41
package-lock.json
generated
41
package-lock.json
generated
@@ -9,10 +9,11 @@
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"@poppanator/sveltekit-svg": "^4.2.1",
|
||||
"@welshman/lib": "^0.0.12",
|
||||
"@welshman/net": "^0.0.16",
|
||||
"@welshman/lib": "^0.0.13",
|
||||
"@welshman/net": "^0.0.17",
|
||||
"@welshman/signer": "^0.0.2",
|
||||
"@welshman/store": "^0.0.1",
|
||||
"@welshman/util": "^0.0.23",
|
||||
"@welshman/util": "^0.0.24",
|
||||
"daisyui": "^4.12.10",
|
||||
"nostr-login": "^1.5.2",
|
||||
"prettier-plugin-tailwindcss": "^0.6.5"
|
||||
@@ -1394,9 +1395,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@welshman/lib": {
|
||||
"version": "0.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@welshman/lib/-/lib-0.0.12.tgz",
|
||||
"integrity": "sha512-865dbPRbXdpZXNkAXz0KDgW0Yq6krC9Pz59cycfe6k75fDO1w4jA30UlW4E1mJuGQycmBtyi9sAkUPP9LG4Srw==",
|
||||
"version": "0.0.13",
|
||||
"resolved": "https://registry.npmjs.org/@welshman/lib/-/lib-0.0.13.tgz",
|
||||
"integrity": "sha512-tp5+KAiUwoid04Pap47uqkz3MWDqA1iy+JklX7qu5WppClehMgkYfePtCbKOQ8LS9psl88xnZM1oR8NtDhVqnA==",
|
||||
"dependencies": {
|
||||
"@scure/base": "^1.1.6",
|
||||
"@types/events": "^3.0.3",
|
||||
@@ -1406,16 +1407,26 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@welshman/net": {
|
||||
"version": "0.0.16",
|
||||
"resolved": "https://registry.npmjs.org/@welshman/net/-/net-0.0.16.tgz",
|
||||
"integrity": "sha512-9NoNKs3BxMs7biyfhLtQFs0rJP5e8raMMjCXYL0+WaHTSPi1VaKBzXGlsikF713pJ0xm5kigAxa6wquonsWHtg==",
|
||||
"version": "0.0.17",
|
||||
"resolved": "https://registry.npmjs.org/@welshman/net/-/net-0.0.17.tgz",
|
||||
"integrity": "sha512-m2hvpb3AdHPmmhtfc16oy03523TG+6ggM9bt7vOLfKZl67qg9ki5VHFRxd7VPRuKosvNabeIErWBsXIxtKWdJg==",
|
||||
"dependencies": {
|
||||
"@welshman/lib": "0.0.12",
|
||||
"@welshman/util": "0.0.23",
|
||||
"@welshman/lib": "0.0.13",
|
||||
"@welshman/util": "0.0.24",
|
||||
"isomorphic-ws": "^5.0.0",
|
||||
"ws": "^8.16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@welshman/signer": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@welshman/signer/-/signer-0.0.2.tgz",
|
||||
"integrity": "sha512-24K8A5Xnfsijq108+CQI+rvFhbhr+L14YitC/gA69VKnhSSEJTeaIvnKs9YSrHVX0BAYD3/kUNVpeYF3kp7YfA==",
|
||||
"dependencies": {
|
||||
"@welshman/lib": "^0.0.13",
|
||||
"@welshman/net": "^0.0.17",
|
||||
"@welshman/util": "^0.0.24"
|
||||
}
|
||||
},
|
||||
"node_modules/@welshman/store": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@welshman/store/-/store-0.0.1.tgz",
|
||||
@@ -1425,11 +1436,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@welshman/util": {
|
||||
"version": "0.0.23",
|
||||
"resolved": "https://registry.npmjs.org/@welshman/util/-/util-0.0.23.tgz",
|
||||
"integrity": "sha512-xV9RnPvO3XZ163TD/5ga/vCnLtejMpkIu9JlfiO/iyHJ1DdObq9WkyuHTgVDNxkrPBf74KuoF9gnub9rLMCj/w==",
|
||||
"version": "0.0.24",
|
||||
"resolved": "https://registry.npmjs.org/@welshman/util/-/util-0.0.24.tgz",
|
||||
"integrity": "sha512-Qpe0J5VCYpqhpGB4f966d4FAw65L3JE2xYSqhBGbbfdMXnteqW6nHClP0YVbX9pMSYGRPn3ZXWkWf33yqImbGQ==",
|
||||
"dependencies": {
|
||||
"@welshman/lib": "0.0.12",
|
||||
"@welshman/lib": "0.0.13",
|
||||
"nostr-tools": "^2.3.2"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -35,10 +35,11 @@
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@poppanator/sveltekit-svg": "^4.2.1",
|
||||
"@welshman/lib": "^0.0.12",
|
||||
"@welshman/net": "^0.0.16",
|
||||
"@welshman/lib": "^0.0.13",
|
||||
"@welshman/net": "^0.0.17",
|
||||
"@welshman/signer": "^0.0.2",
|
||||
"@welshman/store": "^0.0.1",
|
||||
"@welshman/util": "^0.0.23",
|
||||
"@welshman/util": "^0.0.24",
|
||||
"daisyui": "^4.12.10",
|
||||
"nostr-login": "^1.5.2",
|
||||
"prettier-plugin-tailwindcss": "^0.6.5"
|
||||
|
||||
35
src/app.css
35
src/app.css
@@ -42,23 +42,6 @@
|
||||
font-family: Lato;
|
||||
}
|
||||
|
||||
.button {
|
||||
padding: 12px 16px;
|
||||
display: flex;
|
||||
border-radius: var(--rounded-btn, 0.5rem);
|
||||
cursor: pointer;
|
||||
animation: button-pop 200ms ease-out;
|
||||
transition-property: all;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transition-duration: 150ms;
|
||||
}
|
||||
|
||||
.button:active:hover,
|
||||
.button:active:focus {
|
||||
animation: button-pop 0s ease-out;
|
||||
transform: scale(var(--btn-focus-scale, 0.97));
|
||||
}
|
||||
|
||||
[data-theme="dark"] {
|
||||
--stark: #111;
|
||||
--stark-content: #eee;
|
||||
@@ -88,3 +71,21 @@
|
||||
.hover\:bg-stark-content:hover {
|
||||
background-color: var(--stark-content);
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 1rem;
|
||||
background-color: oklch(var(--b2) / 1);
|
||||
border-radius: var(--rounded-box, 1rem);
|
||||
}
|
||||
|
||||
.column {
|
||||
@apply flex flex-col;
|
||||
}
|
||||
|
||||
.heading {
|
||||
@apply text-2xl text-stark-content text-center;
|
||||
}
|
||||
|
||||
.subheading {
|
||||
@apply text-xl text-stark-content text-center;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import {batch, postJson} from "@welshman/lib"
|
||||
import {normalizeRelayUrl} from "@welshman/util"
|
||||
import {relayInfo} from "app/state"
|
||||
import {DUFFLEPUD_URL} from "@app/base"
|
||||
import {relayInfo} from "@app/state"
|
||||
|
||||
export const loadRelay = batch(1000, async (urls: string[]) => {
|
||||
const data = await postJson(`${DUFFLEPUD_URL}/relay/info`, {urls})
|
||||
|
||||
@@ -8,8 +8,12 @@
|
||||
<script lang="ts">
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import PrimaryNavItem from "@lib/components/PrimaryNavItem.svelte"
|
||||
import SpaceAdd from '@app/components/SpaceAdd.svelte'
|
||||
import {getGroupName, getGroupPicture, makeGroupId} from "@app/domain"
|
||||
import {userGroupRelaysByNom, groupsById} from "@app/state"
|
||||
import {pushModal} from "@app/modal"
|
||||
|
||||
export const addSpace = () => pushModal(SpaceAdd)
|
||||
</script>
|
||||
|
||||
<div class="relative w-14 bg-base-100">
|
||||
@@ -32,7 +36,7 @@
|
||||
</div>
|
||||
</PrimaryNavItem>
|
||||
{/each}
|
||||
<PrimaryNavItem title="Add Space">
|
||||
<PrimaryNavItem title="Add Space" on:click={addSpace}>
|
||||
<div class="!flex w-10 items-center justify-center">
|
||||
<Icon size={7} icon="add-circle" />
|
||||
</div>
|
||||
|
||||
21
src/app/components/SpaceAdd.svelte
Normal file
21
src/app/components/SpaceAdd.svelte
Normal file
@@ -0,0 +1,21 @@
|
||||
<script lang="ts">
|
||||
import CardButton from '@lib/components/CardButton.svelte'
|
||||
import SpaceCreate from '@app/components/SpaceCreate.svelte'
|
||||
import {pushModal} from '@app/modal'
|
||||
|
||||
const startCreate = () => pushModal(SpaceCreate)
|
||||
</script>
|
||||
|
||||
<div class="column gap-4">
|
||||
<h1 class="heading">Add a Space</h1>
|
||||
<p class="text-center">Spaces are places where communities come together to work, play, and hang out.</p>
|
||||
<CardButton icon="add-circle" title="Get started" on:click={startCreate}>
|
||||
Just a few questions and you'll be on your way.
|
||||
</CardButton>
|
||||
<div class="card column gap-4">
|
||||
<h2 class="subheading">Have an invite?</h2>
|
||||
<button class="btn btn-primary">
|
||||
Join a Space
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
27
src/app/components/SpaceCreate.svelte
Normal file
27
src/app/components/SpaceCreate.svelte
Normal file
@@ -0,0 +1,27 @@
|
||||
<script lang="ts">
|
||||
import Field from '@lib/components/Field.svelte'
|
||||
import Icon from '@lib/components/Icon.svelte'
|
||||
|
||||
const back = () => history.back()
|
||||
</script>
|
||||
|
||||
<div class="column gap-4">
|
||||
<h1 class="heading">Customize your Space</h1>
|
||||
<p class="text-center">
|
||||
Give people a few details to go. You can always change this later.
|
||||
</p>
|
||||
<Field>
|
||||
<p slot="label">Give your space a name:</p>
|
||||
<input slot="input" type="text" class="input input-bordered w-full max-w-xs" />
|
||||
</Field>
|
||||
<div class="flex flex-row justify-between items-center gap-4">
|
||||
<button class="btn btn-link" on:click={back}>
|
||||
<Icon icon="alt-arrow-left" />
|
||||
Go back
|
||||
</button>
|
||||
<button class="btn btn-primary" on:click={back}>
|
||||
Next
|
||||
<Icon icon="alt-arrow-right" class="!bg-base-300" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -4,7 +4,7 @@ import {pushState} from "$app/navigation"
|
||||
|
||||
export const modals = new Map()
|
||||
|
||||
export const pushModal = (component: ComponentType, props: Record<string, any>) => {
|
||||
export const pushModal = (component: ComponentType, props: Record<string, any> = {}) => {
|
||||
const id = randomId()
|
||||
|
||||
// TODO: fix memory leak here by listening to history somehow
|
||||
|
||||
3
src/assets/icons/Alt Arrow Left.svg
Normal file
3
src/assets/icons/Alt Arrow Left.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M15 5L9 12L15 19" stroke="#1C274C" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 215 B |
18
src/lib/components/CardButton.svelte
Normal file
18
src/lib/components/CardButton.svelte
Normal file
@@ -0,0 +1,18 @@
|
||||
<script lang="ts">
|
||||
import cx from 'classnames'
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
|
||||
export let icon
|
||||
export let title
|
||||
</script>
|
||||
|
||||
<button on:click class={cx($$props.class, "btn btn-neutral btn-lg text-left h-24")}>
|
||||
<div class="flex gap-6 py-4 flex-grow items-center">
|
||||
<Icon class="bg-accent" size={7} {icon} />
|
||||
<div class="flex flex-col gap-1 flex-grow">
|
||||
<p class="text-stark-content">{title}</p>
|
||||
<p class="text-xs"><slot /></p>
|
||||
</div>
|
||||
<Icon size={7} icon="alt-arrow-right" />
|
||||
</div>
|
||||
</button>
|
||||
9
src/lib/components/Field.svelte
Normal file
9
src/lib/components/Field.svelte
Normal file
@@ -0,0 +1,9 @@
|
||||
<div class="flex flex-col gap-2">
|
||||
<label class="flex items-center gap-2 font-bold">
|
||||
<slot name="label" />
|
||||
</label>
|
||||
<slot name="input" />
|
||||
<p class="text-sm text-neutral-200">
|
||||
<slot name="info" />
|
||||
</p>
|
||||
</div>
|
||||
@@ -11,6 +11,7 @@
|
||||
import AddSquare from "@assets/icons/Add Square.svg?dataurl"
|
||||
import AddCircle from "@assets/icons/Add Circle.svg?dataurl"
|
||||
import AltArrowRight from "@assets/icons/Alt Arrow Right.svg?dataurl"
|
||||
import AltArrowLeft from "@assets/icons/Alt Arrow Left.svg?dataurl"
|
||||
import ClipboardText from "@assets/icons/Clipboard Text.svg?dataurl"
|
||||
import Compass from "@assets/icons/Compass.svg?dataurl"
|
||||
import CompassBig from "@assets/icons/Compass Big.svg?dataurl"
|
||||
@@ -30,6 +31,7 @@
|
||||
"add-square": AddSquare,
|
||||
"add-circle": AddCircle,
|
||||
"alt-arrow-right": AltArrowRight,
|
||||
"alt-arrow-left": AltArrowLeft,
|
||||
"clipboard-text": ClipboardText,
|
||||
compass: Compass,
|
||||
"compass-big": CompassBig,
|
||||
|
||||
32
src/lib/components/ModalBox.svelte
Normal file
32
src/lib/components/ModalBox.svelte
Normal file
@@ -0,0 +1,32 @@
|
||||
<script context="module" lang="ts">
|
||||
const modalHeight = tweened(0, {
|
||||
duration: 700,
|
||||
easing: quintOut
|
||||
})
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import {onMount} from 'svelte'
|
||||
import {slide} from 'svelte/transition'
|
||||
import {quintOut} from 'svelte/easing'
|
||||
import {tweened} from 'svelte/motion'
|
||||
import {last} from '@welshman/lib'
|
||||
|
||||
export let component
|
||||
export let props
|
||||
|
||||
let box: HTMLElement
|
||||
let content: HTMLElement
|
||||
let naturalHeight = 0
|
||||
|
||||
onMount(() => {
|
||||
naturalHeight = content.clientHeight + 48
|
||||
$modalHeight = naturalHeight
|
||||
})
|
||||
</script>
|
||||
|
||||
<div class="modal-box" bind:this={box} style={`height: ${$modalHeight}px`} class:overflow-hidden={$modalHeight !== naturalHeight}>
|
||||
<div bind:this={content}>
|
||||
<svelte:component this={component} {...props} />
|
||||
</div>
|
||||
</div>
|
||||
@@ -2,10 +2,10 @@
|
||||
export let title
|
||||
</script>
|
||||
|
||||
<div class="relative z-nav-item flex h-14 w-14 items-center justify-center">
|
||||
<button on:click class="relative z-nav-item flex h-14 w-14 items-center justify-center">
|
||||
<div
|
||||
class="avatar tooltip tooltip-right cursor-pointer rounded-full bg-base-300 p-1"
|
||||
data-tip={title}>
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
@@ -8,10 +8,29 @@
|
||||
|
||||
<a
|
||||
{href}
|
||||
class="button group justify-start border-none transition-all hover:bg-base-100"
|
||||
class="group justify-start border-none transition-all hover:bg-base-100"
|
||||
class:text-stark-content={active}
|
||||
class:bg-base-100={active}>
|
||||
<div class="flex items-center gap-3">
|
||||
<slot />
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<style>
|
||||
a {
|
||||
padding: 12px 16px;
|
||||
display: flex;
|
||||
border-radius: var(--rounded-btn, 0.5rem);
|
||||
cursor: pointer;
|
||||
animation: nav-button-pop 200ms ease-out;
|
||||
transition-property: all;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transition-duration: 150ms;
|
||||
}
|
||||
|
||||
a:active:hover,
|
||||
a:active:focus {
|
||||
animation: button-pop 0s ease-out;
|
||||
transform: scale(var(--btn-focus-scale, 0.97));
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import {fly} from "@lib/transition"
|
||||
import {toast} from "@app/toast"
|
||||
import {modals} from "@app/modal"
|
||||
import ModalBox from "@lib/components/ModalBox.svelte"
|
||||
import PrimaryNav from "@app/components/PrimaryNav.svelte"
|
||||
import SecondaryNav from "@app/components/SecondaryNav.svelte"
|
||||
|
||||
@@ -34,32 +35,31 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex h-screen" data-theme="dark">
|
||||
<PrimaryNav />
|
||||
<SecondaryNav />
|
||||
<div class="flex-grow bg-base-200">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<dialog bind:this={modal} class="modal modal-bottom sm:modal-middle">
|
||||
<div class="modal-box">
|
||||
{#if $page.state.modal}
|
||||
{@const {component, props} = modals.get($page.state.modal)}
|
||||
<svelte:component this={component} {...props} />
|
||||
{/if}
|
||||
</div>
|
||||
<form method="dialog" class="modal-backdrop">
|
||||
<button />
|
||||
</form>
|
||||
</dialog>
|
||||
|
||||
{#if $toast}
|
||||
{#key $toast.id}
|
||||
<div transition:fly class="toast">
|
||||
<div class="alert">
|
||||
<span>{$toast.message}</span>
|
||||
</div>
|
||||
<div data-theme="dark">
|
||||
<div class="flex h-screen">
|
||||
<PrimaryNav />
|
||||
<SecondaryNav />
|
||||
<div class="flex-grow bg-base-200">
|
||||
<slot />
|
||||
</div>
|
||||
{/key}
|
||||
{/if}
|
||||
</div>
|
||||
<dialog bind:this={modal} class="modal modal-bottom sm:modal-middle">
|
||||
{#if $page.state.modal}
|
||||
{#key $page.state.modal}
|
||||
<ModalBox {...modals.get($page.state.modal)} />
|
||||
{/key}
|
||||
{/if}
|
||||
<form method="dialog" class="modal-backdrop">
|
||||
<button />
|
||||
</form>
|
||||
</dialog>
|
||||
{#if $toast}
|
||||
{#key $toast.id}
|
||||
<div transition:fly class="toast">
|
||||
<div class="alert">
|
||||
<span>{$toast.message}</span>
|
||||
</div>
|
||||
</div>
|
||||
{/key}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import CardButton from "@lib/components/CardButton.svelte"
|
||||
</script>
|
||||
|
||||
<div class="hero min-h-screen bg-base-200">
|
||||
@@ -7,43 +7,19 @@
|
||||
<div class="flex max-w-xl flex-col gap-4">
|
||||
<h1 class="text-stark-content text-center text-5xl">Welcome to</h1>
|
||||
<h1 class="text-stark-content mb-4 text-center text-5xl font-bold uppercase">Flotilla</h1>
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<div class="button flex items-center gap-4 bg-base-100 hover:bg-base-200">
|
||||
<Icon class="bg-accent" size={7} icon="add-circle" />
|
||||
<div class="flex flex-col gap-1">
|
||||
<p class="text-stark-content">Create a group</p>
|
||||
<p class="text-xs">Invite all your friends, do life together.</p>
|
||||
<p></p>
|
||||
</div>
|
||||
<Icon size={7} icon="alt-arrow-right" />
|
||||
</div>
|
||||
<div class="button flex items-center gap-4 bg-base-100 hover:bg-base-200">
|
||||
<Icon class="bg-accent" size={7} icon="compass" />
|
||||
<div class="flex flex-col gap-1">
|
||||
<p class="text-stark-content">Discover groups</p>
|
||||
<p class="text-xs">Find a community based on your hobbies or interests.</p>
|
||||
<p></p>
|
||||
</div>
|
||||
<Icon size={7} icon="alt-arrow-right" />
|
||||
</div>
|
||||
<div class="button flex items-center gap-4 bg-base-100 hover:bg-base-200">
|
||||
<Icon class="bg-accent" size={7} icon="plain" />
|
||||
<div class="flex flex-col gap-1">
|
||||
<p class="text-stark-content">Leave feedback</p>
|
||||
<p class="text-xs">Let us know how we can improve by giving us feedback.</p>
|
||||
<p></p>
|
||||
</div>
|
||||
<Icon size={7} icon="alt-arrow-right" />
|
||||
</div>
|
||||
<div class="button flex items-center gap-4 bg-base-100 hover:bg-base-200">
|
||||
<Icon class="bg-accent" size={7} icon="hand-pills" />
|
||||
<div class="flex flex-col gap-1">
|
||||
<p class="text-stark-content">Donate to Flotilla</p>
|
||||
<p class="text-xs">Support the project by donating to the developer.</p>
|
||||
<p></p>
|
||||
</div>
|
||||
<Icon size={7} icon="alt-arrow-right" />
|
||||
</div>
|
||||
<div class="grid lg:grid-cols-2 gap-3">
|
||||
<CardButton icon="add-circle" title="Create a group" class="h-24">
|
||||
Invite all your friends, do life together.
|
||||
</CardButton>
|
||||
<CardButton icon="compass" title="Discover groups" class="h-24">
|
||||
Find a community based on your hobbies or interests.
|
||||
</CardButton>
|
||||
<CardButton icon="plain" title="Leave feedback" class="h-24">
|
||||
Let us know how we can improve by giving us feedback.
|
||||
</CardButton>
|
||||
<CardButton icon="hand-pills" title="Donate to Flotilla" class="h-24">
|
||||
Support the project by donating to the developer.
|
||||
</CardButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user