add /edit stub

This commit is contained in:
Yusur 2025-10-23 09:59:18 +02:00
parent 54cafaa1da
commit 248555f7ad
10 changed files with 175 additions and 36 deletions

2
src/app.d.ts vendored
View file

@ -14,7 +14,7 @@ declare global {
site: ServerHealth | null,
me: UserEntry | null,
results?: object[],
query?: string
query?: string,
}
// interface PageState {}
// interface Platform {}

35
src/lib/EditPost.svelte Normal file
View file

@ -0,0 +1,35 @@
<script lang="ts">
import PrivacySelect from "./PrivacySelect.svelte";
let { content = $bindable(""), privacy = $bindable(0) } = $props();
let contentLength = $derived(content.length);
</script>
<label>
<input type="text" name="title" maxlength=256 placeholder="An interesting title"/>
</label>
<label>
<textarea bind:value={content}></textarea>
<output><small class="faint">{contentLength} chars</small></output>
</label>
<PrivacySelect bind:value={privacy} />
<style>
textarea {
width: 100%;
background-color: inherit;
color: var(--text-primary);
min-height: 10em;
margin-top: 4px;
}
input[name="title"] {
width: 100%;
margin: 6px 0;
font-size: 1.25em;
}
</style>

View file

@ -43,7 +43,7 @@ let { title, created_at, id, content = '', to } = post;
<li><a href="/report/post/{id}"><RiFlagLine/> Report</a></li>
{/if}
{#if me && me.id === post.author?.id }
<li><a href="/edit/post/{id}"><RiEditLine/> Edit</a></li>
<li><a href="/edit/={id}"><RiEditLine/> Edit</a></li>
{/if}
</ul>
</div>

View file

@ -1,6 +1,6 @@
<script lang="ts">
import { RiLoginBoxLine, RiLogoutBoxLine, RiSearch2Line, RiSearchLine, RiSettings3Line } from "svelte-remixicon";
import { RiLoginBoxLine, RiLogoutBoxLine, RiSearch2Line, RiSearchLine, RiSettings3Line, RiShieldStarLine, RiUserLine } from "svelte-remixicon";
import { activePostCount } from "./globals.svelte";
import type { UserEntry } from "./backend";
@ -35,7 +35,17 @@ let enable_search = $derived(user !== null);
<span><a href="/@{user.username}">@{user.username}</a></span>
<span>{user.karma || 0} karma</span>
</div>
<a class="mobileonly" href="/@{user.username}">
<RiUserLine />
</a>
</li>
{#if user.badges && user.badges.indexOf("administrator") >= 0}
<li>
<a href="/admin/">
<RiShieldStarLine />
</a>
</li>
{/if}
<li><a href="/logout" aria-label="Log out" title="Log out"><RiLogoutBoxLine /></a></li>
{:else}
<li><a href="/login" aria-label="Log in" title="Log in"><RiLoginBoxLine /></a></li>

View file

@ -29,8 +29,9 @@ export type PostEntry = {
title: string,
created_at: string,
author?: UserEntry | null,
content?: string | null,
to: UserEntry | GuildEntry
content?: string,
to: UserEntry | GuildEntry ,
privacy?: number
};
export type ServerHealth = {

View file

@ -1,8 +1,8 @@
<script lang="ts">
import Centered from "$lib/Centered.svelte";
import EditPost from "$lib/EditPost.svelte";
import { getMe } from "$lib/globals.svelte";
import GuildSelect from "$lib/GuildSelect.svelte";
import PrivacySelect from "$lib/PrivacySelect.svelte";
import SLayout from "$lib/SLayout.svelte";
import { RiErrorWarningLine } from "svelte-remixicon";
@ -11,7 +11,6 @@
let content = $state("");
let privacy = $state(0);
let contentLength = $derived(content.length);
</script>
@ -22,20 +21,12 @@
<p>Posting as <strong>@{me.username}</strong></p>
<label>
Post to: <!-- TODO autocomplete! -->
Post to:
<GuildSelect />
</label>
<label>
<input type="text" name="title" maxlength=256 placeholder="An interesting title"/>
</label>
<EditPost bind:content bind:privacy />
<label>
<textarea bind:value={content}></textarea>
<output><small class="faint">{contentLength} chars</small></output>
</label>
<PrivacySelect bind:value={privacy} />
{#if privacy === 0}
<span class="warning"><RiErrorWarningLine /> Your post will be PUBLIC!</span>
{/if}
@ -60,22 +51,10 @@
<style>
textarea {
width: 100%;
background-color: inherit;
color: var(--text-primary);
min-height: 10em;
margin-top: 4px;
}
form {
display: flex;
flex-direction: column;
}
input[name="title"] {
width: 100%;
margin: 6px 0;
font-size: 1.25em;
}
</style>

View file

@ -0,0 +1,64 @@
<script lang="ts">
import type { PostEntry } from "$lib/backend";
import Centered from "$lib/Centered.svelte";
import EditPost from "$lib/EditPost.svelte";
import { getMe } from "$lib/globals.svelte";
import GuildSelect from "$lib/GuildSelect.svelte";
import SLayout from "$lib/SLayout.svelte";
import { RiErrorWarningLine } from "svelte-remixicon";
let me = getMe();
let { data }: { data: PostEntry } = $props();
let post = $state(data) ;
let { content = "", privacy } = $derived(post);
</script>
{#if me?.id === post.author?.id}
<SLayout title="New post">
<form method="POST" class="card">
<p>Posting as <strong>@{me?.username}</strong></p>
<label>
Post to:
<GuildSelect />
</label>
<EditPost bind:content bind:privacy />
{#if privacy === 0}
<span class="warning"><RiErrorWarningLine /> Your post will be PUBLIC!</span>
{/if}
<button class="card primary" disabled>Create</button>
</form>
{#snippet left()}
...
{/snippet}
{#snippet right()}
...
{/snippet}
</SLayout>
{:else if me}
You can't edit posts that are not your own.
{:else}
<Centered>
You must be <a href="login">logged in</a> in order to edit your own posts.
</Centered>
{/if}
<style>
form {
display: flex;
flex-direction: column;
}
</style>

View file

@ -0,0 +1,51 @@
import { backend, type GuildEntry } from '$lib/backend.js';
import { getMe } from '$lib/globals.svelte';
import { error, isHttpError, redirect } from '@sveltejs/kit';
export async function load(event) {
const { params } = event;
const { id } = params;
const resp = await backend.withEvent(event).fetch('post/' + encodeURIComponent(id));
if(resp.status === 404) {
error(404);
}
let post;
try{
const respJ = await resp.json();
let { posts } = respJ;
post = posts[id];
let me = getMe();
if (!me) {
redirect(303, "/login?next=" + encodeURIComponent(event.url.pathname));
}
if ( post.author.id !== me?.id) {
error(403);
}
if (post?.to && post.to.type === 'guild') {
const guild: GuildEntry = post.to;
const guildResp = await backend.withEvent(event).fetch('guild/' + encodeURIComponent(guild.id));
const guildJson = await guildResp.json();
const guildInfo = guildJson?.guilds?.[guild.id];
guildInfo.type = 'guild';
post.to = guildInfo || guild;
console.log(post.to);
}
} catch (e) {
if (isHttpError(e)) throw e;
console.error(e);
error(502);
}
return post;
}

View file

@ -32,14 +32,12 @@ export const actions = {
event.locals.results = results;
event.locals.query = query;
console.log(event.locals);
return
}
} satisfies Actions;
export async function load (event) {
export function load (event) {
const { results, query } = event.locals;
console.log({ results, query });
return { results, query };
}

View file

@ -6,6 +6,7 @@
import type { PageProps } from "./$types";
let { data }: PageProps = $props();
console.log(data);
let { query, results } = $derived(data);
</script>