unfinished compose box

This commit is contained in:
vimaexd 2024-07-04 16:55:57 +01:00
parent 231d29a44b
commit dacabf250c
8 changed files with 241 additions and 5 deletions

132
src/lib/ui/Composer.svelte Normal file
View file

@ -0,0 +1,132 @@
<script>
import { account } from '@cf/store/account';
import Button from '@cf/ui/Button.svelte';
import PostIcon from '@cf/icons/post.svg';
</script>
<div class="composer">
<div class="composer-header-container">
<a href={$account.url} target="_blank" class="composer-avatar-container" on:mouseup|stopPropagation>
<img src={$account.avatar_url} type={$account.avatar_type} alt="" width="48" height="48" class="composer-avatar" loading="lazy" decoding="async">
</a>
<header class="composer-header">
<div class="composer-user-info" on:mouseup|stopPropagation>
{@html $account.rich_name}
<span class="username">{$account.mention}</span>
</div>
<div class="composer-info" on:mouseup|stopPropagation>
</div>
</header>
<div>
<Button centered={true}>
vis
</Button>
</div>
</div>
<input type="text" id="" placeholder="content warning"/>
<textarea placeholder="what's cooking, mae?" class="textbox"></textarea>
<div class="composer-footer">
<div>
<Button centered={true}>
media
</Button>
<Button centered={true}>
poll
</Button>
<Button centered={true}>
cw
</Button>
</div>
<Button filled={true} centered={true} class="postbtn">
<svelte:fragment slot="icon">
<PostIcon/>
</svelte:fragment>
Post
</Button>
</div>
</div>
<style>
.composer {
display: flex;
flex-direction: column;
gap: 16px;
}
.composer-footer {
display: flex;
}
.composer-footer div {
width: 100%;
display: flex;
gap: 16px;
}
.composer-footer div :global(button) {
width: 58px;
}
.composer-footer :global(button) {
width: 30%;
}
input[type="text"], textarea {
box-sizing: border-box;
padding: 8px 8px;
border-radius: 8px;
border-style: none;
font-size: 1em;
width: 100%;
background-color: var(--bg-700);
color: var(--text);
font-family: inherit;
}
.textbox {
resize: none;
height: 160px;
}
.composer-header-container {
width: 100%;
display: flex;
flex-direction: row;
}
.composer-avatar {
border-radius: 8px;
margin-right: 12px;
display: flex;
}
.composer-header {
display: flex;
flex-grow: 1;
flex-direction: row;
}
.composer-info {
margin-left: auto;
}
.composer-user-info {
margin-top: -2px;
display: flex;
flex-direction: column;
justify-content: center;
}
.composer-user-info .name :global(.emoji) {
position: relative;
top: .2em;
height: 1.2em;
}
.composer-user-info .username {
opacity: .8;
font-size: .9em;
}
</style>

88
src/lib/ui/Modal.svelte Normal file
View file

@ -0,0 +1,88 @@
<script>
export let visible = true;
export let centered = false;
// disable scrolling hack: this has to be on body
$: if(visible) {
document.body.style.overflowY = "hidden";
} else {
document.body.style.overflowY = "scroll";
}
</script>
{#if visible}
<div class="overlay" on:click={() => visible = !visible}></div>
<div class="container">
<div class="modal" class:modal-top={!centered} class:modal-center={centered}>
<slot/>
</div>
</div>
{/if}
<style>
.container {
z-index: 101;
display: flex;
justify-content: center;
position: absolute;
width: 100vw;
height: 100vh;
pointer-events: none;
}
.modal {
background-color: var(--bg-800);
z-index: 101;
padding: 16px;
width: 732px;
border-radius: 8px;
box-shadow: 0px 16px 64px 4px rgba(0,0,0,0.5);
animation: modal_pop_up .15s cubic-bezier(0.22, 1, 0.36, 1);
height: fit-content;
}
.overlay {
width: 100vw;
height: 100vw;
position: absolute;
top: 0;
left: 0;
z-index: 100;
background-color: rgba(0,0,0,0.2);
backdrop-filter: blur(32px) saturate(1.25);
user-select: none;
animation: modal_bg .15s cubic-bezier(0.22, 1, 0.36, 1);
}
.modal-top {
margin-top: 8em;
}
.modal-center {
align-items: center;
}
@keyframes modal_bg {
from {
background-color: rgba(0,0,0,0);
backdrop-filter: blur(0px) saturate(1.0);
}
to {
background-color: rgba(0,0,0,0.2);
backdrop-filter: blur(32px) saturate(1.25);
}
}
@keyframes modal_pop_up {
from {
transform: translateY(16px) scale(0.95);
}
to {
transform: translateY(0px) scale(1);
}
}
</style>

View file

@ -6,6 +6,7 @@
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import { page } from '$app/stores'; import { page } from '$app/stores';
import { get } from 'svelte/store'; import { get } from 'svelte/store';
import { createEventDispatcher } from 'svelte';
import { unread_notif_count, last_read_notif_id } from '$lib/notifications.js'; import { unread_notif_count, last_read_notif_id } from '$lib/notifications.js';
import Logo from '$lib/../img/campfire-logo.svg'; import Logo from '$lib/../img/campfire-logo.svg';
@ -26,6 +27,8 @@
const VERSION = APP_VERSION; const VERSION = APP_VERSION;
const dispatch = createEventDispatcher();
function handle_btn(name) { function handle_btn(name) {
if (!get(logged_in)) return; if (!get(logged_in)) return;
let route; let route;
@ -122,7 +125,7 @@
</Button> </Button>
</div> </div>
<Button filled label="Post" disabled> <Button filled label="Post" disabled on:click={() => dispatch("compose")}>
<svelte:fragment slot="icon"> <svelte:fragment slot="icon">
<PostIcon/> <PostIcon/>
</svelte:fragment> </svelte:fragment>

View file

@ -9,8 +9,12 @@
import { get } from 'svelte/store'; import { get } from 'svelte/store';
import Navigation from '$lib/ui/Navigation.svelte'; import Navigation from '$lib/ui/Navigation.svelte';
import Modal from '@cf/ui/Modal.svelte';
import Composer from '@cf/ui/Composer.svelte';
import Widgets from '$lib/ui/Widgets.svelte'; import Widgets from '$lib/ui/Widgets.svelte';
let show_composer = false;
async function init() { async function init() {
if (!get(app) || !get(app).token) { if (!get(app) || !get(app).token) {
account.set(false); account.set(false);
@ -40,9 +44,8 @@
</script> </script>
<div id="app"> <div id="app">
<header> <header>
<Navigation /> <Navigation on:compose={() => show_composer = true} />
</header> </header>
<main> <main>
@ -59,6 +62,9 @@
<Widgets /> <Widgets />
</div> </div>
<Modal bind:visible={show_composer}>
<Composer/>
</Modal>
</div> </div>
<style> <style>

View file

@ -6,6 +6,7 @@
import LoginForm from '$lib/ui/LoginForm.svelte'; import LoginForm from '$lib/ui/LoginForm.svelte';
import Feed from '$lib/ui/Feed.svelte'; import Feed from '$lib/ui/Feed.svelte';
import Modal from '../lib/ui/Modal.svelte';
logged_in.subscribe(logged_in => { logged_in.subscribe(logged_in => {
if (logged_in) getTimeline(); if (logged_in) getTimeline();

View file

@ -113,6 +113,7 @@
margin-right: 8px; margin-right: 8px;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center;
gap: 8px; gap: 8px;
} }

View file

@ -17,6 +17,11 @@ const config = {
}), }),
version: { version: {
name: child_process.execSync('git rev-parse HEAD').toString().trim() name: child_process.execSync('git rev-parse HEAD').toString().trim()
},
alias: {
'@cf/ui/*': "./src/lib/ui",
'@cf/icons/*': "./src/img/icons",
'@cf/store/*': "./src/lib/stores"
} }
}, },
}; };