add /edit stub
This commit is contained in:
parent
54cafaa1da
commit
248555f7ad
10 changed files with 175 additions and 36 deletions
2
src/app.d.ts
vendored
2
src/app.d.ts
vendored
|
|
@ -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
35
src/lib/EditPost.svelte
Normal 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>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
<label>
|
||||
<textarea bind:value={content}></textarea>
|
||||
<output><small class="faint">{contentLength} chars</small></output>
|
||||
</label>
|
||||
<EditPost bind:content bind:privacy />
|
||||
|
||||
<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>
|
||||
64
src/routes/edit/[x+3d][id]/+page.svelte
Normal file
64
src/routes/edit/[x+3d][id]/+page.svelte
Normal 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>
|
||||
51
src/routes/edit/[x+3d][id]/+page.ts
Normal file
51
src/routes/edit/[x+3d][id]/+page.ts
Normal 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;
|
||||
}
|
||||
|
|
@ -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) {
|
||||
const { results, query } = event.locals;
|
||||
|
||||
console.log({ results, query });
|
||||
return { results, query };
|
||||
export function load (event) {
|
||||
const { results, query } = event.locals;
|
||||
|
||||
return { results, query };
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
import type { PageProps } from "./$types";
|
||||
|
||||
let { data }: PageProps = $props();
|
||||
console.log(data);
|
||||
let { query, results } = $derived(data);
|
||||
</script>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue