mirror of
https://github.com/Steffo99/todocolors.git
synced 2024-11-22 08:14:18 +00:00
Make some frontend progress
This commit is contained in:
parent
88b3ab1674
commit
3c6b9ba36e
19 changed files with 473 additions and 111 deletions
|
@ -17,6 +17,7 @@
|
|||
"@types/node": "20.4.5",
|
||||
"@types/react": "18.2.17",
|
||||
"@types/react-dom": "18.2.7",
|
||||
"classnames": "^2.3.2",
|
||||
"next": "13.4.12",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
|
|
38
todoblue/src/app/CreatePrivateBoard.tsx
Normal file
38
todoblue/src/app/CreatePrivateBoard.tsx
Normal file
|
@ -0,0 +1,38 @@
|
|||
"use client";
|
||||
|
||||
import {useBoardCreator} from "@/app/useBoardCreator"
|
||||
import {faKey} from "@fortawesome/free-solid-svg-icons"
|
||||
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"
|
||||
import {default as React} from "react"
|
||||
|
||||
export function CreatePrivateBoard() {
|
||||
const {createBoard} = useBoardCreator();
|
||||
|
||||
return (
|
||||
<form
|
||||
className={"panel box form-flex"}
|
||||
onSubmit={e => {
|
||||
e.preventDefault();
|
||||
createBoard(crypto.randomUUID().toString());
|
||||
}}
|
||||
>
|
||||
<h3>
|
||||
<FontAwesomeIcon icon={faKey} size={"1x"}/>
|
||||
{" "}
|
||||
Privato
|
||||
</h3>
|
||||
<p>
|
||||
Crea un nuovo tabellone privato utilizzando un codice segreto autogenerato!
|
||||
<br/>
|
||||
<small>Esso sarà accessibile solo da chi ne conosce il link.</small>
|
||||
</p>
|
||||
<label className={"float-bottom"}>
|
||||
<span/>
|
||||
<button>
|
||||
Crea
|
||||
</button>
|
||||
<span/>
|
||||
</label>
|
||||
</form>
|
||||
)
|
||||
}
|
57
todoblue/src/app/CreatePublicBoard.tsx
Normal file
57
todoblue/src/app/CreatePublicBoard.tsx
Normal file
|
@ -0,0 +1,57 @@
|
|||
"use client"
|
||||
|
||||
import {useBoardCreator} from "@/app/useBoardCreator"
|
||||
import {useLowerKebabState} from "@/app/useKebabState"
|
||||
import {faGlobe} from "@fortawesome/free-solid-svg-icons"
|
||||
import {default as React} from "react"
|
||||
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"
|
||||
|
||||
|
||||
export function CreatePublicBoard() {
|
||||
const [code, setCode] = useLowerKebabState("")
|
||||
const {createBoard} = useBoardCreator();
|
||||
|
||||
return (
|
||||
<form
|
||||
className={"panel box form-flex"}
|
||||
onSubmit={e => {
|
||||
e.preventDefault();
|
||||
createBoard(code);
|
||||
}}
|
||||
>
|
||||
<h3>
|
||||
<FontAwesomeIcon icon={faGlobe}/>
|
||||
{" "}
|
||||
Pubblico
|
||||
</h3>
|
||||
<p>
|
||||
Crea un nuovo tabellone pubblico, con un codice personalizzato!
|
||||
<br/>
|
||||
<small>Se un tabellone con quel codice esiste già, sarai reindirizzato ad esso.</small>
|
||||
</p>
|
||||
<label className={"float-bottom"}>
|
||||
<span>
|
||||
Codice
|
||||
</span>
|
||||
<input
|
||||
type={"text"}
|
||||
placeholder={"garasauto-planning-2023"}
|
||||
value={code}
|
||||
onChange={(
|
||||
e => setCode(e.target.value)
|
||||
)}
|
||||
/>
|
||||
<span/>
|
||||
</label>
|
||||
<label>
|
||||
<span/>
|
||||
<button
|
||||
onClick={_ => createBoard(code)}
|
||||
>
|
||||
Crea
|
||||
</button>
|
||||
<span/>
|
||||
</label>
|
||||
</form>
|
||||
)
|
||||
}
|
65
todoblue/src/app/board/[board]/page.module.css
Normal file
65
todoblue/src/app/board/[board]/page.module.css
Normal file
|
@ -0,0 +1,65 @@
|
|||
.boardHeader {
|
||||
display: grid;
|
||||
align-items: center;
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 450px) {
|
||||
.boardHeader {
|
||||
grid-template-areas:
|
||||
"left right"
|
||||
"title title"
|
||||
;
|
||||
grid-template-columns: auto auto;
|
||||
grid-template-rows: auto auto;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 451px) {
|
||||
.boardHeader {
|
||||
grid-template-areas:
|
||||
"left title right"
|
||||
;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
grid-template-rows: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.boardButtons {
|
||||
width: auto;
|
||||
min-width: unset;
|
||||
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.boardButtonsLeft {
|
||||
grid-area: left;
|
||||
justify-self: start;
|
||||
}
|
||||
|
||||
.boardButtonsRight {
|
||||
grid-area: right;
|
||||
justify-self: end;
|
||||
}
|
||||
|
||||
.boardTitle {
|
||||
grid-area: title;
|
||||
}
|
||||
|
||||
.boardButtons button {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
background-color: hsla(
|
||||
var(--bhsl-background-hue),
|
||||
var(--bhsl-background-saturation),
|
||||
var(--bhsl-background-lightness),
|
||||
100%
|
||||
);
|
||||
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
|
@ -1,15 +1,73 @@
|
|||
'use client';
|
||||
import {default as React} from "react";
|
||||
import {useBoard} from "@/app/board/[board]/useBoard"
|
||||
"use client";
|
||||
|
||||
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"
|
||||
import {useEffect} from "react"
|
||||
import {useBoardWebSocket} from "@/app/board/[board]/useBoardWebSocket"
|
||||
import style from "./page.module.css";
|
||||
import classNames from "classnames"
|
||||
import {faHouse, faPencil, faTableColumns, faArrowDownWideShort} from "@fortawesome/free-solid-svg-icons"
|
||||
|
||||
|
||||
export default function Page({params: {board}}: {params: {board: string}}) {
|
||||
const wsUrl = React.useMemo(() => `ws://127.0.0.1:8080/board/${board}/ws`, [board])
|
||||
useBoard(wsUrl);
|
||||
const {tasks, title, pushEvent, readyState} = useBoardWebSocket(board);
|
||||
|
||||
return (
|
||||
<p>
|
||||
TODO
|
||||
</p>
|
||||
)
|
||||
useEffect(() => {
|
||||
console.debug("[Page] Current events: ", tasks)
|
||||
}, [tasks])
|
||||
|
||||
return <>
|
||||
<header className={style.boardHeader}>
|
||||
<div className={classNames(style.boardButtons, style.boardButtonsLeft)}>
|
||||
<button title={"Home"}>
|
||||
<FontAwesomeIcon icon={faHouse}/>
|
||||
</button>
|
||||
<button title={"Modifica titolo"}>
|
||||
<FontAwesomeIcon icon={faPencil}/>
|
||||
</button>
|
||||
</div>
|
||||
<h1 className={style.boardTitle}>
|
||||
{title}
|
||||
</h1>
|
||||
<div className={classNames(style.boardButtons, style.boardButtonsRight)}>
|
||||
<button title={"Cambia raggruppamento orizzontale"}>
|
||||
<FontAwesomeIcon icon={faTableColumns}/>
|
||||
</button>
|
||||
<button title={"Cambia ordinamento verticale"}>
|
||||
<FontAwesomeIcon icon={faArrowDownWideShort}/>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
<main>
|
||||
<div className={"chapter-5"}>
|
||||
<div>
|
||||
<h2>
|
||||
Gruppo A
|
||||
</h2>
|
||||
</div>
|
||||
<div>
|
||||
<h2>
|
||||
Gruppo B
|
||||
</h2>
|
||||
</div>
|
||||
<div>
|
||||
<h2>
|
||||
Gruppo C
|
||||
</h2>
|
||||
</div>
|
||||
<div>
|
||||
<h2>
|
||||
Gruppo D
|
||||
</h2>
|
||||
</div>
|
||||
<div>
|
||||
<h2>
|
||||
Gruppo E
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<footer>
|
||||
sos
|
||||
</footer>
|
||||
</>
|
||||
}
|
||||
|
|
62
todoblue/src/app/board/[board]/types.ts
Normal file
62
todoblue/src/app/board/[board]/types.ts
Normal file
|
@ -0,0 +1,62 @@
|
|||
export type TaskIcon =
|
||||
"User" &
|
||||
"Image" &
|
||||
"Envelope" &
|
||||
"Star" &
|
||||
"Heart" &
|
||||
"Comment" &
|
||||
"FaceSmile" &
|
||||
"File" &
|
||||
"Bell" &
|
||||
"Bookmark" &
|
||||
"Eye" &
|
||||
"Hand" &
|
||||
"PaperPlane" &
|
||||
"Handshake" &
|
||||
"Sun" &
|
||||
"Clock" &
|
||||
"Circle" &
|
||||
"Square" &
|
||||
"Building" &
|
||||
"Flag" &
|
||||
"Moon";
|
||||
|
||||
export type TaskImportance =
|
||||
"Highest" &
|
||||
"High" &
|
||||
"Normal" &
|
||||
"Low" &
|
||||
"Lowest";
|
||||
|
||||
export type TaskPriority =
|
||||
"Highest" &
|
||||
"High" &
|
||||
"Normal" &
|
||||
"Low" &
|
||||
"Lowest";
|
||||
|
||||
export type TaskStatus =
|
||||
"Unfinished" &
|
||||
"InProgress" &
|
||||
"Complete"
|
||||
|
||||
export type Task = {
|
||||
text: string,
|
||||
icon: TaskIcon,
|
||||
importance: TaskImportance,
|
||||
priority: TaskPriority,
|
||||
status: TaskStatus,
|
||||
}
|
||||
|
||||
export type TitleBoardAction = {
|
||||
"Title": string,
|
||||
}
|
||||
|
||||
export type TaskBoardAction = {
|
||||
"Task": [
|
||||
string,
|
||||
Task,
|
||||
]
|
||||
}
|
||||
|
||||
export type BoardAction = TitleBoardAction & TaskBoardAction;
|
|
@ -1,18 +0,0 @@
|
|||
'use client';
|
||||
|
||||
import {default as React} from "react";
|
||||
import {useWs} from "@/app/board/[board]/useWs"
|
||||
|
||||
|
||||
export function useBoard(url: string) {
|
||||
const socket = useWs(url, {
|
||||
onopen: React.useCallback((sock: WebSocket, event: Event) => {
|
||||
console.debug("[useBoard] Connected to the server!");
|
||||
sock.send('{"Title": "sus"}')
|
||||
}, []),
|
||||
onmessage: React.useCallback((sock: WebSocket, event: MessageEvent) => {
|
||||
const data = JSON.parse(event.data);
|
||||
console.debug("[useBoard] Received ServerOperation: ", data);
|
||||
}, [])
|
||||
});
|
||||
}
|
57
todoblue/src/app/board/[board]/useBoardWebSocket.ts
Normal file
57
todoblue/src/app/board/[board]/useBoardWebSocket.ts
Normal file
|
@ -0,0 +1,57 @@
|
|||
'use client';
|
||||
|
||||
import {BoardAction, Task} from "@/app/board/[board]/types"
|
||||
import {useMemo, useCallback, useState} from "react"
|
||||
import {useWebSocket} from "@/app/board/[board]/useWebSocket"
|
||||
|
||||
|
||||
export function useBoardWebSocket(board: string) {
|
||||
const url = useMemo(() => `ws://127.0.0.1:8080/board/${board}/ws`, [board]);
|
||||
const [title, setTitle] = useState<string>("Nuovo tabellone");
|
||||
const [tasks, setTasks] = useState<{[key: string]: Task}>(() => ({}));
|
||||
|
||||
const onopen = useCallback((sock: WebSocket, event: Event) => {
|
||||
setTasks(() => ({}))
|
||||
console.debug("[useBoardWebSocket] Connected to the websocket of board:", board);
|
||||
}, [])
|
||||
|
||||
const onmessage = useCallback((sock: WebSocket, event: MessageEvent) => {
|
||||
const data: BoardAction = JSON.parse(event.data);
|
||||
console.debug("[useBoardWebSocket] Received:", data);
|
||||
if(data["Title"] !== undefined) {
|
||||
setTitle(data["Title"]);
|
||||
}
|
||||
else if(data["Task"] !== undefined) {
|
||||
const id = data["Task"][0]
|
||||
const task = data["Task"][1]
|
||||
setTasks((prevTasks) => {
|
||||
const tasks = {...prevTasks}
|
||||
if(task === null) {
|
||||
delete tasks[id]
|
||||
}
|
||||
else {
|
||||
tasks[id] = task
|
||||
}
|
||||
return tasks
|
||||
})
|
||||
}
|
||||
}, [])
|
||||
|
||||
const {websocket} = useWebSocket(url, {onopen, onmessage});
|
||||
const readyState = websocket?.readyState;
|
||||
|
||||
const pushEvent = useCallback((data: any) => {
|
||||
if(!websocket) {
|
||||
console.warn("[useBoardWebSocket] Socket does not exist yet, cannot send:", data)
|
||||
return;
|
||||
}
|
||||
if(readyState != 1) {
|
||||
console.warn("[useBoardWebSocket] Socket isn't ready yet, cannot send:", data);
|
||||
return;
|
||||
}
|
||||
console.debug("[useBoardWebSocket] Sending:", data);
|
||||
websocket.send(JSON.stringify(data));
|
||||
}, [websocket, readyState])
|
||||
|
||||
return {title, tasks, pushEvent, readyState}
|
||||
}
|
43
todoblue/src/app/board/[board]/useWebSocket.ts
Normal file
43
todoblue/src/app/board/[board]/useWebSocket.ts
Normal file
|
@ -0,0 +1,43 @@
|
|||
'use client';
|
||||
|
||||
import {useState, useEffect, useCallback} from "react"
|
||||
|
||||
export interface WebSocketHandlers {
|
||||
onclose?: (sock: WebSocket, event: CloseEvent) => void,
|
||||
onerror?: (sock: WebSocket, event: Event) => void,
|
||||
onmessage?: (sock: WebSocket, event: MessageEvent) => void,
|
||||
onopen?: (sock: WebSocket, event: Event) => void,
|
||||
}
|
||||
|
||||
export function useWebSocket(url: string, {onclose, onerror, onmessage, onopen}: WebSocketHandlers) {
|
||||
const [websocket, setWebsocket] = useState<WebSocket | null>(null)
|
||||
const [readyState, setReadyState] = useState<number>(0);
|
||||
|
||||
useEffect(() => {
|
||||
console.debug("[useWebSocket] Creating websocket...");
|
||||
const sock = new WebSocket(url);
|
||||
setWebsocket(sock);
|
||||
sock.onopen = (ev) => {
|
||||
setReadyState(sock.readyState);
|
||||
onopen?.(sock, ev);
|
||||
}
|
||||
sock.onclose = (ev) => {
|
||||
setReadyState(sock.readyState);
|
||||
onclose?.(sock, ev);
|
||||
}
|
||||
sock.onerror = (ev) => {
|
||||
setReadyState(sock.readyState);
|
||||
onerror?.(sock, ev);
|
||||
}
|
||||
sock.onmessage = (ev) => {
|
||||
onmessage?.(sock, ev);
|
||||
}
|
||||
return () => {
|
||||
console.debug("[useWebSocket] Closing websocket...");
|
||||
sock.close();
|
||||
setWebsocket(null);
|
||||
}
|
||||
}, [url, onclose, onerror, onmessage, onopen])
|
||||
|
||||
return {websocket, readyState}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
'use client';
|
||||
import {default as React} from "react";
|
||||
|
||||
|
||||
export interface UseWsHandlers {
|
||||
onclose?: (sock: WebSocket, event: CloseEvent) => void,
|
||||
onerror?: (sock: WebSocket, event: Event) => void,
|
||||
onmessage?: (sock: WebSocket, event: MessageEvent) => void,
|
||||
onopen?: (sock: WebSocket, event: Event) => void,
|
||||
}
|
||||
|
||||
|
||||
export function useWs(url: string, {onclose, onerror, onmessage, onopen}: UseWsHandlers) {
|
||||
const [websocket, setWebsocket] = React.useState<WebSocket | null>(null)
|
||||
|
||||
React.useEffect(() => {
|
||||
const sock = new WebSocket(url);
|
||||
sock.onclose = onclose ? (ev) => onclose(sock, ev) : null;
|
||||
sock.onerror = onerror ? (ev) => onerror(sock, ev) : null;
|
||||
sock.onmessage = onmessage ? (ev) => onmessage(sock, ev) : null;
|
||||
sock.onopen = onopen ? (ev) => onopen(sock, ev) : null;
|
||||
setWebsocket(sock);
|
||||
return () => {
|
||||
sock.close();
|
||||
setWebsocket(null);
|
||||
}
|
||||
}, [url, onclose, onerror, onmessage, onopen])
|
||||
|
||||
return websocket
|
||||
}
|
|
@ -6,9 +6,13 @@ import "@steffo/bluelib/dist/glass.root.css"
|
|||
import "@steffo/bluelib/dist/layouts-center.root.css"
|
||||
import "@steffo/bluelib/dist/colors-royalblue.root.css"
|
||||
import "@steffo/bluelib/dist/fonts-fira-ghpages.root.css"
|
||||
import '@fortawesome/fontawesome-svg-core/styles.css';
|
||||
|
||||
import { config } from '@fortawesome/fontawesome-svg-core';
|
||||
config.autoAddCss = false; /* eslint-disable import/first */
|
||||
|
||||
import type {Metadata as NextMetadata} from "next"
|
||||
import {ReactNode} from "react"
|
||||
import {default as React, ReactNode} from "react"
|
||||
|
||||
|
||||
export const metadata: NextMetadata = {
|
||||
|
@ -21,6 +25,13 @@ export default function RootLayout({children}: { children: ReactNode }) {
|
|||
<html lang="en">
|
||||
<body className={"theme-bluelib layout-center"}>
|
||||
{children}
|
||||
<footer>
|
||||
<p>
|
||||
© <a href="https://steffo.eu">Stefano Pigozzi</a> -
|
||||
<a href="https://www.gnu.org/licenses/agpl-3.0.en.html">AGPL 3.0</a> -
|
||||
<a href="https://github.com/Steffo99/todocolors">GitHub</a>
|
||||
</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import {CreatePrivateBoard} from "@/app/CreatePrivateBoard"
|
||||
import {CreatePublicBoard} from "@/app/CreatePublicBoard"
|
||||
import {default as React} from "react";
|
||||
|
||||
export default function Page() {
|
||||
|
@ -12,55 +14,9 @@ export default function Page() {
|
|||
<h2>
|
||||
Crea un nuovo tabellone
|
||||
</h2>
|
||||
<form className={"panel box form-flex"}>
|
||||
<h3>
|
||||
Pubblico
|
||||
</h3>
|
||||
<p>
|
||||
Crea un nuovo tabellone pubblico, con un codice personalizzato!
|
||||
<br/>
|
||||
<small>Se un tabellone con quel codice esiste già, sarai reindirizzato ad esso.</small>
|
||||
</p>
|
||||
<label className={"float-bottom"}>
|
||||
<span>
|
||||
Codice
|
||||
</span>
|
||||
<input type={"text"} placeholder={"garas-auto-planning-2023"}/>
|
||||
<span/>
|
||||
</label>
|
||||
<label>
|
||||
<span/>
|
||||
<button>
|
||||
Crea
|
||||
</button>
|
||||
<span/>
|
||||
</label>
|
||||
</form>
|
||||
<div className={"panel box form-flex"}>
|
||||
<h3>
|
||||
Privato
|
||||
</h3>
|
||||
<p>
|
||||
Crea un nuovo tabellone privato utilizzando un codice segreto autogenerato!
|
||||
<br/>
|
||||
<small>Esso sarà accessibile solo da chi ne conosce il link.</small>
|
||||
</p>
|
||||
<label className={"float-bottom"}>
|
||||
<span/>
|
||||
<button>
|
||||
Crea
|
||||
</button>
|
||||
<span/>
|
||||
</label>
|
||||
</div>
|
||||
<CreatePublicBoard/>
|
||||
<CreatePrivateBoard/>
|
||||
</div>
|
||||
</main>
|
||||
<footer>
|
||||
<p>
|
||||
© <a href="https://steffo.eu">Stefano Pigozzi</a> -
|
||||
<a href="https://www.gnu.org/licenses/agpl-3.0.en.html">AGPL 3.0</a> -
|
||||
<a href="https://github.com/Steffo99/todocolors">GitHub</a>
|
||||
</p>
|
||||
</footer>
|
||||
</>
|
||||
}
|
||||
|
|
13
todoblue/src/app/useBoardCreator.ts
Normal file
13
todoblue/src/app/useBoardCreator.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
"use client";
|
||||
import {useCallback} from "react"
|
||||
import {useRouter} from "next/navigation"
|
||||
|
||||
export function useBoardCreator() {
|
||||
const router = useRouter();
|
||||
|
||||
const createBoard = useCallback((board: String) => {
|
||||
router.push(`/board/${board}`);
|
||||
}, [])
|
||||
|
||||
return {createBoard}
|
||||
}
|
38
todoblue/src/app/useKebabState.ts
Normal file
38
todoblue/src/app/useKebabState.ts
Normal file
|
@ -0,0 +1,38 @@
|
|||
"use client";
|
||||
|
||||
import {useCallback, useState} from "react"
|
||||
|
||||
const KEBABIFIER = /[^a-zA-Z0-9-]/g
|
||||
|
||||
export function useAnyKebabState(initial: string): [string, (inputString: string) => void] {
|
||||
const [state, setInnerState] = useState<string>(initial);
|
||||
|
||||
const setState = useCallback((inputString: string) => {
|
||||
const kebabifiedString = inputString.replaceAll(KEBABIFIER, "-");
|
||||
setInnerState(kebabifiedString);
|
||||
}, [])
|
||||
|
||||
return [state, setState]
|
||||
}
|
||||
|
||||
export function useLowerKebabState(initial: string): [string, (inputString: string) => void] {
|
||||
const [state, setInnerState] = useState<string>(initial);
|
||||
|
||||
const setState = useCallback((inputString: string) => {
|
||||
const kebabifiedString = inputString.toLowerCase().replaceAll(KEBABIFIER, "-");
|
||||
setInnerState(kebabifiedString);
|
||||
}, [])
|
||||
|
||||
return [state, setState]
|
||||
}
|
||||
|
||||
export function useUpperKebabState(initial: string): [string, (inputString: string) => void] {
|
||||
const [state, setInnerState] = useState<string>(initial);
|
||||
|
||||
const setState = useCallback((inputString: string) => {
|
||||
const kebabifiedString = inputString.toUpperCase().replaceAll(KEBABIFIER, "-");
|
||||
setInnerState(kebabifiedString);
|
||||
}, [])
|
||||
|
||||
return [state, setState]
|
||||
}
|
|
@ -2,10 +2,7 @@
|
|||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/node_modules" />
|
||||
</content>
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
|
|
|
@ -140,6 +140,11 @@ caniuse-lite@^1.0.30001406:
|
|||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001517.tgz#90fabae294215c3495807eb24fc809e11dc2f0a8"
|
||||
integrity sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA==
|
||||
|
||||
classnames@^2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924"
|
||||
integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==
|
||||
|
||||
client-only@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1"
|
||||
|
|
2
todored/Cargo.lock
generated
2
todored/Cargo.lock
generated
|
@ -1071,11 +1071,13 @@ dependencies = [
|
|||
"axum",
|
||||
"deadqueue",
|
||||
"futures-util",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"micronfig",
|
||||
"pkg-version",
|
||||
"pretty_env_logger",
|
||||
"redis",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
|
|
|
@ -9,11 +9,13 @@ edition = "2021"
|
|||
axum = { version = "0.6.19", features = ["ws"] }
|
||||
deadqueue = "0.2.4"
|
||||
futures-util = "0.3.28"
|
||||
lazy_static = "1.4.0"
|
||||
log = "0.4.19"
|
||||
micronfig = "0.2.0"
|
||||
pkg-version = "1.0.0"
|
||||
pretty_env_logger = "0.5.0"
|
||||
redis = { version = "0.23.1", features = ["r2d2", "ahash", "cluster", "tokio-comp", "connection-manager"] }
|
||||
regex = "1.9.1"
|
||||
serde = { version = "1.0.178", features = ["derive"] }
|
||||
serde_json = "1.0.104"
|
||||
tokio = { version = "1.29.1", features = ["macros", "rt-multi-thread"] }
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
use axum::Extension;
|
||||
use axum::extract::{Path, WebSocketUpgrade};
|
||||
use uuid::Uuid;
|
||||
use crate::kebab::Skewer;
|
||||
use crate::routes::board::structs::{BoardAction, BoardRequest};
|
||||
use crate::task::{Task, TaskIcon, TaskImportance, TaskPriority, TaskStatus};
|
||||
use super::ws;
|
||||
|
||||
pub(crate) async fn handler(
|
||||
|
@ -12,6 +15,8 @@ pub(crate) async fn handler(
|
|||
let board = board.to_kebab_lowercase();
|
||||
log::trace!("Kebabified board name to: {board:?}");
|
||||
|
||||
log::info!("{}", serde_json::ser::to_string(&BoardAction::Task(Some(Uuid::new_v4()), Some(Task { text: "Hello world".to_string(), icon: TaskIcon::Bell, importance: TaskImportance::High, priority: TaskPriority::Highest, status: TaskStatus::Complete }))).unwrap());
|
||||
|
||||
log::trace!("Received websocket request, upgrading...");
|
||||
upgrade_request.on_upgrade(|websocket| ws::handler(board, rclient, websocket))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue