This commit is contained in:
Jonathan Staab 2022-11-24 11:47:03 -08:00
parent c2eee552b4
commit 586b7853ac
14 changed files with 111 additions and 49 deletions

10
README.md Normal file
View File

@ -0,0 +1,10 @@
Bugs
- [ ] Remove hack for re-rendering rooms on url change
- [ ] Memoize room list, every time the user switches chat rooms it pulls the full list
Features
- [ ] Threads/social
- [ ] Server discovery
- [ ] Favorite chat rooms

View File

@ -13,8 +13,10 @@
import Profile from "src/routes/Profile.svelte"
import RelayList from "src/routes/RelayList.svelte"
import UserDetail from "src/routes/UserDetail.svelte"
import Explore from "src/routes/Explore.svelte"
import Messages from "src/routes/Messages.svelte"
import Chat from "src/routes/Chat.svelte"
import ChatCreate from "src/routes/ChatCreate.svelte"
import ChatRoom from "src/routes/ChatRoom.svelte"
import ChatEdit from "src/routes/ChatEdit.svelte"
const menuIsOpen = writable(false)
const toggleMenu = () => menuIsOpen.update(x => !x)
@ -44,80 +46,82 @@
</script>
<Router {url}>
<div use:links>
<div class="py-20 p-4 text-white">
<div use:links class="h-full">
<div class="pt-16 text-white h-full">
<Route path="/" component={Feed} />
<Route path="/login" component={Login} />
<Route path="/relays" component={RelayList} />
<Route path="/chat" component={Chat} />
<Route path="/chat/new" component={ChatCreate} />
<Route path="/chat/:room" component={ChatRoom} />
<Route path="/chat/:room/edit" component={ChatEdit} />
<Route path="/user/:pubkey" component={UserDetail} />
<Route path="/explore" component={Explore} />
<Route path="/messages" component={Messages} />
<Route path="/settings/profile" component={Profile} />
</div>
<ul
class="py-20 w-48 bg-dark fixed top-0 bottom-0 left-0 transition-all shadow-xl
border-r border-light text-white"
class:-ml-48={!$menuIsOpen}
class="py-20 w-56 bg-dark fixed top-0 bottom-0 left-0 transition-all shadow-xl
border-r border-medium text-white overflow-hidden"
class:-ml-56={!$menuIsOpen}
>
{#if $user}
<li class="flex gap-2 px-4 py-2 pb-8 items-center">
<div
class="overflow-hidden w-6 h-6 rounded-full bg-cover bg-center shrink-0"
class="overflow-hidden w-6 h-6 rounded-full bg-cover bg-center shrink-0 border border-solid border-white"
style="background-image: url({$user.picture})" />
<span class="text-lg font-bold">{$user.name}</span>
</li>
<li class="cursor-pointer">
<a class="block pl-6 px-4 py-2 hover:bg-accent transition-all" href="/user/{$user.pubkey}">
<a class="block px-4 py-2 hover:bg-accent transition-all" href="/user/{$user.pubkey}">
<i class="fa-solid fa-user-astronaut mr-2" /> Profile
</a>
</li>
{:else}
<li class="cursor-pointer">
<a class="block pl-6 px-4 py-2 hover:bg-accent transition-all" href="/login">
<i class="fa-solid fa-right-to-bracket mr-2" /> Login
</a>
</li>
{/if}
<li class="cursor-pointer">
<a class="block pl-6 px-4 py-2 hover:bg-accent transition-all" href="/relays">
<a class="block px-4 py-2 hover:bg-accent transition-all" href="/">
<i class="fa-solid fa-home mr-2" /> Home
</a>
</li>
<li class="cursor-pointer">
<a class="block px-4 py-2 hover:bg-accent transition-all" href="/relays">
<i class="fa-solid fa-server mr-2" /> Relays
</a>
</li>
<li class="cursor-pointer">
<a class="block px-4 py-2 hover:bg-accent transition-all" href="/chat">
<i class="fa-solid fa-message mr-2" /> Chat
</a>
</li>
{#if $user}
<li class="cursor-pointer">
<a class="block pl-6 px-4 py-2 hover:bg-accent transition-all" on:click={logout}>
<a class="block px-4 py-2 hover:bg-accent transition-all" on:click={logout}>
<i class="fa-solid fa-right-from-bracket mr-2" /> Logout
</a>
</li>
{:else}
<li class="cursor-pointer">
<a class="block px-4 py-2 hover:bg-accent transition-all" href="/login">
<i class="fa-solid fa-right-to-bracket mr-2" /> Login
</a>
</li>
{/if}
</ul>
<div
class="fixed top-0 bg-dark flex justify-between items-center text-white w-full p-4
border-b border-light"
border-b border-medium"
>
<i class="fa-solid fa-bars fa-2xl cursor-pointer" bind:this={menuIcon} on:click={toggleMenu} />
<h1 class="staatliches text-3xl">Coracle</h1>
</div>
<div
class="fixed bottom-0 bg-dark flex justify-between items-center text-white w-full
border-t border-light px-8 p-6"
>
<a href="/"><i class="fa-solid fa-home fa-xl" /></a>
<i class="cursor-pointer fa-solid fa-search fa-xl" on:click={toggleSearch} />
<a href="/explore"><i class="fa-solid fa-compass fa-xl" /></a>
<a href="/messages"><i class="fa-solid fa-envelope fa-xl" /></a>
</div>
{#if $toast}
<div
class="fixed bottom-0 left-0 right-0 pointer-events-none"
transition:fly={{y: 50, duration: 300}}
>
<div
class="rounded bg-accent shadow-xl mb-14 m-2 p-4 text-white text-center border border-dark"
class="rounded bg-accent shadow-xl m-4 p-4 text-white text-center border border-dark"
>
{$toast.message}
</div>

View File

@ -41,6 +41,10 @@
:root {
font-family: Montserrat;
background-color: #252422;
background-color: #0f0f0e;
color: white;
}
html, body, #app, #app > div {
height: 100%;
}

View File

@ -6,17 +6,21 @@
const className = cx(
$$props.class,
"rounded bg-light shadow-inset py-2 px-4 pr-10 text-black w-full text-dark",
"rounded bg-light shadow-inset py-2 px-4 pr-10 text-black w-full placeholder:text-medium",
{"pl-10": $$slots.before, "pr-10": $$slots.after},
)
</script>
<div class={cx(wrapperClass, "relative")}>
<input {...$$props} class={className} bind:value />
{#if $$slots.before}
<div class="absolute top-0 left-0 pt-3 px-3 text-dark flex gap-2">
<slot name="before" />
</div>
{/if}
{#if $$slots.after}
<div class="absolute top-0 right-0 pt-3 px-3 text-dark flex gap-2 bg-light">
<slot name="after" />
</div>
{/if}
</div>

13
src/routes/Chat.svelte Normal file
View File

@ -0,0 +1,13 @@
<script>
import RoomList from "src/partials/chat/RoomList.svelte"
</script>
<div class="flex gap-4 h-full">
<div class="sm:ml-56 w-full">
<div class="max-w-sm m-auto pt-24 text-center">
Select a room to join the conversation!
</div>
</div>
<RoomList />
</div>

View File

@ -1 +0,0 @@
Explore

View File

@ -18,7 +18,7 @@
{#if $relays && $relays.length > 0}
feed
<div class="fixed bottom-0 right-0 pb-24 pr-8">
<div class="fixed bottom-0 right-0 p-8">
<div
class="rounded-full bg-accent color-white w-16 h-16 flex justify-center
items-center border border-dark shadow-2xl cursor-pointer"
@ -29,7 +29,7 @@
</div>
{:else if $relays}
<div class="flex w-full justify-center items-center py-16">
<div class="text-center max-w-2xl">
<div class="text-center max-w-md">
You aren't yet connected to any relays. Please click <Anchor href="/relays"
>here</Anchor
> to get started.

View File

@ -31,7 +31,7 @@
}
</script>
<div class="flex justify-center pt-12">
<div class="flex justify-center p-12">
<div class="flex flex-col gap-4 max-w-2xl">
<div class="flex justify-center items-center flex-col mb-4">
<h1 class="staatliches text-6xl">Welcome!</h1>

View File

@ -1 +0,0 @@
Messages

View File

@ -49,7 +49,7 @@
}
</script>
<form on:submit={submit} class="flex justify-center py-12" in:fly={{y: 20}}>
<form on:submit={submit} class="flex justify-center py-8 px-4" in:fly={{y: 20}}>
<div class="flex flex-col gap-4 max-w-2xl">
<div class="flex justify-center items-center flex-col mb-4">
<h1 class="staatliches text-6xl">About You</h1>

View File

@ -10,7 +10,7 @@
import {nostr, relays} from "src/state/nostr"
let q = ""
let search = () => []
let search
const knownRelays = liveQuery(() => db.relays.toArray())
@ -21,7 +21,7 @@
}
</script>
<div class="flex justify-center py-12" in:fly={{y: 20}}>
<div class="flex justify-center py-8 px-4" in:fly={{y: 20}}>
<div class="flex flex-col gap-8 max-w-2xl w-full">
<div class="flex justify-center items-center flex-col mb-4">
<h1 class="staatliches text-6xl">Get Connected</h1>
@ -38,12 +38,14 @@
</div>
<div class="flex flex-col gap-6 overflow-auto flex-grow -mx-6 px-6">
{#each search(q) as relay}
<div class="flex gap-2 justify-between cursor-pointer">
<div class="flex gap-2 justify-between">
<div>
<strong>{relay.name || relay.url}</strong>
<p class="text-light">{relay.description || ''}</p>
</div>
<a class="underline" on:click={() => toggle(relay.url, !$relays.includes(relay.url))}>
<a
class="underline cursor-pointer"
on:click={() => toggle(relay.url, !$relays.includes(relay.url))}>
{$relays.includes(relay.url) ? "Leave" : "Join"}
</a>
</div>

View File

@ -42,11 +42,11 @@
</script>
{#if userData}
<div class="max-w-2xl m-auto flex flex-col gap-4 py-4">
<div class="max-w-2xl m-auto flex flex-col gap-4 py-8 px-4">
<div class="flex flex-col gap-4" in:fly={{y: 20}}>
<div class="flex gap-4">
<div
class="overflow-hidden w-12 h-12 rounded-full bg-cover bg-center shrink-0"
class="overflow-hidden w-12 h-12 rounded-full bg-cover bg-center shrink-0 border border-solid border-white"
style="background-image: url({userData.picture})" />
<div class="flex-grow">
<div class="flex justify-between items-center">
@ -57,11 +57,11 @@
</a>
{/if}
</div>
<p>{userData.about}</p>
<p>{userData.about || ''}</p>
</div>
</div>
</div>
<div class="h-px bg-light" in:fly={{y: 20, delay: 200}} />
<div class="h-px bg-medium" in:fly={{y: 20, delay: 200}} />
<div class="flex flex-col gap-4" in:fly={{y: 20, delay: 400}}>
{#each reverse(notes) as note}
<div>

View File

@ -42,3 +42,29 @@ dispatch.addMethod("relay/join", (topic, url) => {
dispatch.addMethod("relay/leave", (topic, url) => {
relays.update(r => without([url], r))
})
dispatch.addMethod("room/create", async (topic, room) => {
const event = nostr.event(40, JSON.stringify(room))
await nostr.publish(event)
return event
})
dispatch.addMethod("room/update", async (topic, {id, ...room}) => {
const [relay] = get(relays)
const event = nostr.event(41, JSON.stringify(room), [["e", id, relay]])
await nostr.publish(event)
return event
})
dispatch.addMethod("message/create", async (topic, roomId, content, type = "root") => {
const [relay] = get(relays)
const event = nostr.event(42, content, [["e", roomId, relay, type]])
await nostr.publish(event)
return event
})

View File

@ -8,11 +8,12 @@ module.exports = {
extend: {},
colors: {
transparent: "transparent",
black: "#252422",
black: "#0f0f0e",
white: "#FFFCF2",
accent: "#EB5E28",
light: "#CCC5B9",
dark: "#403D39",
medium: "#403D39",
dark: "#252422",
},
},
plugins: [],