Merge branch 'master' of git.silversoft.se:Imbus/FrostByte

This commit is contained in:
Imbus 2024-03-05 07:05:18 +01:00
commit fb42380f9c
7 changed files with 312 additions and 263 deletions

View file

@ -8,7 +8,8 @@
"build": "tsc && vite build", "build": "tsc && vite build",
"preview": "vite preview", "preview": "vite preview",
"format": "prettier --config .prettierrc '**/*.ts' '**/*.tsx' '**/*.js' '**/*.json' --write", "format": "prettier --config .prettierrc '**/*.ts' '**/*.tsx' '**/*.js' '**/*.json' --write",
"fmt": "prettier --config .prettierrc 'src/**/*.ts' 'src/**/*.tsx' --write && npx eslint --fix 'src/**/*.ts' 'src/**/*.tsx'" "fmt": "prettier --config .prettierrc 'src/**/*.ts' 'src/**/*.tsx' --write && npx eslint --fix 'src/**/*.ts' 'src/**/*.tsx'",
"lint": "eslint --ext .ts,.tsx src"
}, },
"dependencies": { "dependencies": {
"@solidjs/router": "^0.9.1", "@solidjs/router": "^0.9.1",

View file

@ -1,18 +1,29 @@
import { useParams } from "@solidjs/router"; import { useParams } from "@solidjs/router";
import { JSXElement, Show, Suspense, createResource } from "solid-js"; import { For, JSXElement, Show, Suspense, createResource } from "solid-js";
import { loadSpinner } from "../Util/Icons"; import { loadSpinner } from "../Util/Icons";
import { getPost } from "../Util/api"; import { getComments, getPost } from "../Util/api";
import { PostSegment } from "./Posts"; import { PostSegment } from "./Posts";
export function SinglePost(): JSXElement { export function SinglePost(): JSXElement {
const params = useParams(); const params = useParams();
const [post] = createResource(params.postid, getPost); const [post] = createResource(params.postid, getPost);
const [comments] = createResource(params.postid, () =>
getComments(params.postid, 0, 10)
);
return ( return (
<Suspense fallback={loadSpinner()}> <Suspense fallback={loadSpinner()}>
<Show when={post()}> <Show when={post()}>
<PostSegment post={post()!} /> <PostSegment post={post()!} />
<For each={comments()!}>
{(comment) => (
// TODO: This should be a separate component
<div class="comment">
<p>{comment.content}</p>
</div>
)}
</For>
</Show> </Show>
</Suspense> </Suspense>
); );

View file

@ -1,4 +1,4 @@
import { JSXElement, Show, onCleanup, useContext } from "solid-js"; import { JSXElement, Show, onCleanup, splitProps, useContext } from "solid-js";
import { LoginForm } from "../Components/Login"; import { LoginForm } from "../Components/Login";
import { RegisterForm } from "../Components/Register"; import { RegisterForm } from "../Components/Register";
@ -61,10 +61,11 @@ export function LoginModal(): JSXElement {
} }
// Local wrapper component for the login and register forms // Local wrapper component for the login and register forms
function FormContainer({ children }: { children: JSXElement }): JSXElement { function FormContainer(props: { children: JSXElement }): JSXElement {
const [local] = splitProps(props, ["children"]);
return ( return (
<div class="tab-content rounded-box border-base-300 bg-base-100 p-2 md:p-10"> <div class="tab-content rounded-box border-base-300 bg-base-100 p-2 md:p-10">
<span class="label-text">{children}</span> <span class="label-text">{local.children}</span>
</div> </div>
); );
} }

View file

@ -22,6 +22,18 @@ export interface AuthResponse {
token: string; token: string;
} }
// This is what a public comment looks like, as it arrives from the server
export interface PublicComment {
id: number;
parent_post_id: number;
parent_comment_id: number | null;
upvotes: number;
downvotes: number;
content: string;
created_at: string;
updated_at: string;
}
export async function getPosts(): Promise<Post[]> { export async function getPosts(): Promise<Post[]> {
const res = await fetch("/api/posts"); const res = await fetch("/api/posts");
const data = await res.json(); const data = await res.json();
@ -44,6 +56,19 @@ export async function createPost(post: NewPost): Promise<void> {
}); });
} }
// Gets the comments for a specific post
export async function getComments(
postId: string,
limit: number,
offset: number
): Promise<PublicComment[]> {
const res = await fetch(
`/api/comments?post_id=${postId}&limit=${limit}&offset=${offset}`
);
const data = await res.json();
return data;
}
// Send the registration request to the server // Send the registration request to the server
export async function submitRegistration( export async function submitRegistration(
username: string, username: string,

View file

@ -0,0 +1,31 @@
# This composefile is not yet ready for use.
# This is because the application assumes the database to be migrated, which happens manually.
version: "3.8"
services:
frostbyte:
build:
context: ..
dockerfile: ./container/Containerfile
container_name: fb-server
environment:
DATABASE_URL: "postgres://CHANGEME:CHANGEME@fb-database:5432/frostbyte"
networks:
- fb_network
depends_on:
- postgres
postgres:
image: docker.io/postgres:16.1-alpine
container_name: fb-database
environment:
POSTGRES_DB: CHANGEME
POSTGRES_USER: CHANGEME
POSTGRES_PASSWORD: CHANGEME
networks:
- fb_network
networks:
fb_network:
driver: bridge

488
server/Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -42,9 +42,9 @@ async fn main() -> std::io::Result<()> {
.allowed_methods(vec!["GET", "POST"]) .allowed_methods(vec!["GET", "POST"])
.max_age(3600); .max_age(3600);
// In debug mode, allow localhost // In debug mode, allow any origin
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
let cors = cors.allowed_origin("http://localhost:8080"); let cors = cors.allow_any_origin();
App::new() App::new()
.wrap(cors) .wrap(cors)