mirror of
https://github.com/kou029w/quot.git
synced 2025-03-10 00:15:20 +00:00
Compare commits
4 commits
86afc69f56
...
87c5021a80
Author | SHA1 | Date | |
---|---|---|---|
87c5021a80 | |||
031553612f | |||
6b942ef288 | |||
60c86f146e |
10 changed files with 94 additions and 19 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
:root {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
max-inline-size: 80rem;
|
||||||
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -7,3 +15,7 @@ header {
|
||||||
a[href^="/"] {
|
a[href^="/"] {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
main * {
|
||||||
|
line-height: 2;
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import "./app.css";
|
||||||
import { createSignal } from "solid-js";
|
import { createSignal } from "solid-js";
|
||||||
import Index from "./pages/index";
|
import Index from "./pages/index";
|
||||||
import Page from "./pages/page";
|
import Page from "./pages/page";
|
||||||
|
import random from "./helpers/random";
|
||||||
|
|
||||||
const routes = {
|
const routes = {
|
||||||
"/": Index,
|
"/": Index,
|
||||||
|
@ -36,7 +37,9 @@ export default () => {
|
||||||
</h1>
|
</h1>
|
||||||
<a href="/new">📄</a>
|
<a href="/new">📄</a>
|
||||||
</header>
|
</header>
|
||||||
{routes[pathname()] ?? <Page id={Number(pathname().slice(1))} />}
|
{routes[pathname()] ?? (
|
||||||
|
<Page id={Number(pathname().slice(1)) || random()} />
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
22
app/src/components/card.css
Normal file
22
app/src/components/card.css
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
.card {
|
||||||
|
margin: unset;
|
||||||
|
padding: 1rem;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: var(--nc-bg-2);
|
||||||
|
color: var(--nc-tx-2);
|
||||||
|
border-width: 0.75rem;
|
||||||
|
border-top-style: solid;
|
||||||
|
border-top-color: var(--nc-bg-3);
|
||||||
|
box-shadow: 0 1px var(--nc-bg-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card h2 {
|
||||||
|
padding: unset;
|
||||||
|
font-size: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card p {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
10
app/src/components/card.tsx
Normal file
10
app/src/components/card.tsx
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import "./card.css";
|
||||||
|
|
||||||
|
export default (props: { id: number; title: string; text: string }) => {
|
||||||
|
return (
|
||||||
|
<article class="card">
|
||||||
|
<h2>{props.title}</h2>
|
||||||
|
<p>{props.text.slice(props.title.length + 1)}</p>
|
||||||
|
</article>
|
||||||
|
);
|
||||||
|
};
|
5
app/src/components/cards.css
Normal file
5
app/src/components/cards.css
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
.cards {
|
||||||
|
display: grid;
|
||||||
|
gap: 1rem;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
|
||||||
|
}
|
6
app/src/components/cards.tsx
Normal file
6
app/src/components/cards.tsx
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import type { JSX } from "solid-js";
|
||||||
|
import "./cards.css";
|
||||||
|
|
||||||
|
export default (props: { children: JSX.Element }) => (
|
||||||
|
<div class="cards">{props.children}</div>
|
||||||
|
);
|
|
@ -4,18 +4,16 @@ import "./editor.css";
|
||||||
export default (props: {
|
export default (props: {
|
||||||
id: number;
|
id: number;
|
||||||
onUpdatePage: (content: Pages.RequestContentPage) => void;
|
onUpdatePage: (content: Pages.RequestContentPage) => void;
|
||||||
}) => {
|
}) => (
|
||||||
return (
|
<textarea
|
||||||
<textarea
|
id={String(props.id)}
|
||||||
id={String(props.id)}
|
class="editor"
|
||||||
class="editor"
|
autofocus
|
||||||
autofocus
|
onInput={(e) => {
|
||||||
onInput={(e) => {
|
const text = e.currentTarget.value;
|
||||||
const text = e.currentTarget.value;
|
const lines = text.split("\n");
|
||||||
const lines = text.split("\n");
|
props.onUpdatePage({ id: props.id, title: lines[0] ?? "", text });
|
||||||
props.onUpdatePage({ id: props.id, title: lines[0] ?? "", text });
|
e.currentTarget.setAttribute("rows", String(Math.max(2, lines.length)));
|
||||||
e.currentTarget.setAttribute("rows", String(Math.max(2, lines.length)));
|
}}
|
||||||
}}
|
></textarea>
|
||||||
></textarea>
|
);
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
5
app/src/helpers/random.ts
Normal file
5
app/src/helpers/random.ts
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
function random(): number {
|
||||||
|
return window.crypto.getRandomValues(new Uint16Array(1))[0]!;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default random;
|
|
@ -1,5 +1,7 @@
|
||||||
import { createResource } from "solid-js";
|
import { createResource, For } from "solid-js";
|
||||||
import type Pages from "../protocol/pages";
|
import type Pages from "../protocol/pages";
|
||||||
|
import Cards from "../components/cards";
|
||||||
|
import Card from "../components/card";
|
||||||
|
|
||||||
async function fetchPages(): Promise<Pages.Response> {
|
async function fetchPages(): Promise<Pages.Response> {
|
||||||
const res = await fetch(
|
const res = await fetch(
|
||||||
|
@ -14,7 +16,17 @@ export default () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main>
|
<main>
|
||||||
<pre>{() => JSON.stringify(pages(), null, " ")}</pre>
|
{() => (
|
||||||
|
<Cards>
|
||||||
|
<For each={pages()}>
|
||||||
|
{(page) => (
|
||||||
|
<a href={`/${page.id}`}>
|
||||||
|
<Card {...page} />
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
</Cards>
|
||||||
|
)}
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { createResource } from "solid-js";
|
import { createResource } from "solid-js";
|
||||||
import type Pages from "../protocol/pages";
|
import type Pages from "../protocol/pages";
|
||||||
import Editor from "../components/editor";
|
import Editor from "../components/editor";
|
||||||
|
import Card from "../components/card";
|
||||||
import beforeunload from "../helpers/beforeunload";
|
import beforeunload from "../helpers/beforeunload";
|
||||||
import throttle from "../helpers/throttle";
|
import throttle from "../helpers/throttle";
|
||||||
|
|
||||||
|
@ -37,6 +38,7 @@ export default (props: { id: number }) => {
|
||||||
if (await updatePage(id, content)) {
|
if (await updatePage(id, content)) {
|
||||||
unblock();
|
unblock();
|
||||||
refetch();
|
refetch();
|
||||||
|
window.history.replaceState({}, "", `/${id}`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
intervalMs
|
intervalMs
|
||||||
|
@ -50,7 +52,7 @@ export default (props: { id: number }) => {
|
||||||
return (
|
return (
|
||||||
<main>
|
<main>
|
||||||
<Editor id={props.id} onUpdatePage={onUpdatePage} />
|
<Editor id={props.id} onUpdatePage={onUpdatePage} />
|
||||||
<pre>{() => JSON.stringify(page(), null, " ")}</pre>
|
{() => <Card id={props.id} title="" text="" {...page()} />}
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue