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,
|
site: ServerHealth | null,
|
||||||
me: UserEntry | null,
|
me: UserEntry | null,
|
||||||
results?: object[],
|
results?: object[],
|
||||||
query?: string
|
query?: string,
|
||||||
}
|
}
|
||||||
// interface PageState {}
|
// interface PageState {}
|
||||||
// interface Platform {}
|
// 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>
|
<li><a href="/report/post/{id}"><RiFlagLine/> Report</a></li>
|
||||||
{/if}
|
{/if}
|
||||||
{#if me && me.id === post.author?.id }
|
{#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}
|
{/if}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<script lang="ts">
|
<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 { activePostCount } from "./globals.svelte";
|
||||||
import type { UserEntry } from "./backend";
|
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><a href="/@{user.username}">@{user.username}</a></span>
|
||||||
<span>{user.karma || 0} karma</span>
|
<span>{user.karma || 0} karma</span>
|
||||||
</div>
|
</div>
|
||||||
|
<a class="mobileonly" href="/@{user.username}">
|
||||||
|
<RiUserLine />
|
||||||
|
</a>
|
||||||
</li>
|
</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>
|
<li><a href="/logout" aria-label="Log out" title="Log out"><RiLogoutBoxLine /></a></li>
|
||||||
{:else}
|
{:else}
|
||||||
<li><a href="/login" aria-label="Log in" title="Log in"><RiLoginBoxLine /></a></li>
|
<li><a href="/login" aria-label="Log in" title="Log in"><RiLoginBoxLine /></a></li>
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,9 @@ export type PostEntry = {
|
||||||
title: string,
|
title: string,
|
||||||
created_at: string,
|
created_at: string,
|
||||||
author?: UserEntry | null,
|
author?: UserEntry | null,
|
||||||
content?: string | null,
|
content?: string,
|
||||||
to: UserEntry | GuildEntry
|
to: UserEntry | GuildEntry ,
|
||||||
|
privacy?: number
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ServerHealth = {
|
export type ServerHealth = {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Centered from "$lib/Centered.svelte";
|
import Centered from "$lib/Centered.svelte";
|
||||||
|
import EditPost from "$lib/EditPost.svelte";
|
||||||
import { getMe } from "$lib/globals.svelte";
|
import { getMe } from "$lib/globals.svelte";
|
||||||
import GuildSelect from "$lib/GuildSelect.svelte";
|
import GuildSelect from "$lib/GuildSelect.svelte";
|
||||||
import PrivacySelect from "$lib/PrivacySelect.svelte";
|
|
||||||
import SLayout from "$lib/SLayout.svelte";
|
import SLayout from "$lib/SLayout.svelte";
|
||||||
import { RiErrorWarningLine } from "svelte-remixicon";
|
import { RiErrorWarningLine } from "svelte-remixicon";
|
||||||
|
|
||||||
|
|
@ -11,7 +11,6 @@
|
||||||
let content = $state("");
|
let content = $state("");
|
||||||
let privacy = $state(0);
|
let privacy = $state(0);
|
||||||
|
|
||||||
let contentLength = $derived(content.length);
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
@ -22,20 +21,12 @@
|
||||||
<p>Posting as <strong>@{me.username}</strong></p>
|
<p>Posting as <strong>@{me.username}</strong></p>
|
||||||
|
|
||||||
<label>
|
<label>
|
||||||
Post to: <!-- TODO autocomplete! -->
|
Post to:
|
||||||
<GuildSelect />
|
<GuildSelect />
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label>
|
<EditPost bind:content bind:privacy />
|
||||||
<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} />
|
|
||||||
{#if privacy === 0}
|
{#if privacy === 0}
|
||||||
<span class="warning"><RiErrorWarningLine /> Your post will be PUBLIC!</span>
|
<span class="warning"><RiErrorWarningLine /> Your post will be PUBLIC!</span>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
@ -60,22 +51,10 @@
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
||||||
textarea {
|
|
||||||
width: 100%;
|
|
||||||
background-color: inherit;
|
|
||||||
color: var(--text-primary);
|
|
||||||
min-height: 10em;
|
|
||||||
margin-top: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
form {
|
form {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[name="title"] {
|
|
||||||
width: 100%;
|
|
||||||
margin: 6px 0;
|
|
||||||
font-size: 1.25em;
|
|
||||||
}
|
|
||||||
</style>
|
</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.results = results;
|
||||||
event.locals.query = query;
|
event.locals.query = query;
|
||||||
console.log(event.locals);
|
console.log(event.locals);
|
||||||
return
|
|
||||||
}
|
}
|
||||||
} satisfies Actions;
|
} satisfies Actions;
|
||||||
|
|
||||||
export async function load (event) {
|
export function load (event) {
|
||||||
const { results, query } = event.locals;
|
const { results, query } = event.locals;
|
||||||
|
|
||||||
console.log({ results, query });
|
return { results, query };
|
||||||
return { results, query };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
import type { PageProps } from "./$types";
|
import type { PageProps } from "./$types";
|
||||||
|
|
||||||
let { data }: PageProps = $props();
|
let { data }: PageProps = $props();
|
||||||
|
console.log(data);
|
||||||
let { query, results } = $derived(data);
|
let { query, results } = $derived(data);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue