Skip to content

Commit

Permalink
Add view source feature, add gloss for brandt 03-1
Browse files Browse the repository at this point in the history
  • Loading branch information
justinsilvestre committed Feb 26, 2024
1 parent 7131abb commit 9c02cda
Show file tree
Hide file tree
Showing 17 changed files with 770 additions and 497 deletions.
31 changes: 31 additions & 0 deletions src/app/Result.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
export type Result<T> =
| {
ok: true;
value: T;
}
| {
ok: false;
error: any;
message: string;
};

export const success = <T>(value: T): Result<T> => ({
ok: true,
value,
});

export const failure = (error: any): Result<never> => ({
ok: false,
error,
get message() {
return error instanceof Error ? error.message : String(error);
},
});

export const attempt = <T>(fn: () => T): Result<T> => {
try {
return success(fn());
} catch (error) {
return failure(error);
}
};
104 changes: 91 additions & 13 deletions src/app/contribute/ContributePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,40 @@
import { useEffect, useRef, useState } from "react";
import TextPage from "../texts/[textId]/TextPage";
import { Passage, PassageVocab, parsePassage } from "../texts/Passage";
import {
PassageDisplayOptionsForm,
useDisplayOptions,
} from "../texts/[textId]/PassageDisplayOptionsForm";
import { PassageBody } from "../texts/[textId]/PassageBody";
import { PassageFrontmatter } from "../texts/[textId]/PassageFrontmatter";
import Link from "next/link";

export function ContributePage({ lexicon }: { lexicon: PassageVocab }) {
const [passage, setPassage] = useState<Passage>({
frontmatter: {
title: "",
description: "",
},
lines: [],
notes: {},
export function ContributePage({
passageId,
initialText = "",
lexicon,
}: {
passageId?: string;
initialText?: string;
lexicon: PassageVocab;
}) {
const storageKey = `contribute-${passageId || "NEW"}`;
const [passage, setPassage] = useState<Passage>(() => {
try {
return parsePassage(initialText);
} catch (err) {
return {
frontmatter: {
title: "",
description: "",
},
lines: [],
notes: {},
};
}
});

const [text, setText] = useState("");
const [text, setText] = useState(initialText);
function updateTextAndParse(newText: string) {
setText(newText);
try {
Expand All @@ -34,13 +56,13 @@ export function ContributePage({ lexicon }: { lexicon: PassageVocab }) {
const initialized = useRef(false);
useEffect(() => {
if (!initialized.current) {
const text = localStorage.getItem("text");
const text = localStorage.getItem(storageKey);
if (text) {
updateTextAndParse(text);
}
initialized.current = true;
} else {
localStorage.setItem("text", text);
localStorage.setItem(storageKey, text);
}
}, [text]);

Expand All @@ -50,6 +72,7 @@ export function ContributePage({ lexicon }: { lexicon: PassageVocab }) {
) => {
updateTextAndParse(e.target.value);
};
const [displayOptions, setDisplayOptions] = useDisplayOptions();

return (
<div className="flex flex-row p-4 gap-4 max-h-[calc(100vh-5rem)]">
Expand All @@ -64,14 +87,69 @@ export function ContributePage({ lexicon }: { lexicon: PassageVocab }) {
<textarea
name="text"
id="text"
className="w-full h-full text-black"
className={`w-full h-full ${
initialText === text ? "text-gray-500" : "text-black"
}`}
value={text}
onChange={handleTextChange}
placeholder="Enter text here"
></textarea>
{passageId && (
<div className="flex flex-row justify-between">
<Link
className="p-1 bg-indigo-100 border-indigo-300 rounded border-1 border text-black"
href={`/texts/${passageId}`}
>
hide source
</Link>
<button
className="p-1 bg-indigo-100 border-indigo-300 rounded border-1 border text-black"
onClick={() => {
if (confirm("Are you sure you want to reset?")) {
setText(initialText);
}
}}
>
reset
</button>
<button
className="p-1 bg-indigo-100 border-indigo-300 rounded border-1 border text-black"
onClick={() => {
// copy text to clipboard
navigator.clipboard.writeText(text).then(
() => {
console.log("Text copied to clipboard");
alert("Text copied to clipboard");
},
(err) => {
console.error("Error copying text to clipboard", err);
alert("Error copying text to clipboard");
}
);
}}
>
copy edits to clipboard
</button>
</div>
)}
</form>
<div className="basis-1/2 overflow-auto max-h-screen">
<TextPage text={passage} vocab={lexicon} />
<main className="flex min-h-screen flex-col max-w-xl m-auto p-4">
<PassageFrontmatter
text={passage}
vocab={lexicon}
displayOptions={displayOptions}
/>
<PassageDisplayOptionsForm
displayOptions={displayOptions}
setDisplayOptions={setDisplayOptions}
/>
<PassageBody
passage={passage}
vocab={lexicon}
displayOptions={displayOptions}
/>
</main>
</div>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion src/app/texts/[textId]/ChineseWithPopover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const LATEST_DISPLAY_OPTIONS_VERSION = 1;

export type DisplayOptions = {
ruby: null | VocabEntryPronunciationKey;
translation: "gloss" | "idiomatic";
translation: null | "gloss" | "idiomatic";
version: number;
};

Expand Down
27 changes: 27 additions & 0 deletions src/app/texts/[textId]/NotesChinese.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"use client";
import { PassageVocab } from "../Passage";
import { ChineseWithPopover, DisplayOptions } from "./ChineseWithPopover";
import { GlossDocument } from "@/app/glossUtils";

export function NotesChinese({
children,
vocab,
displayOptions,
gloss,
}: {
children: string;
vocab: PassageVocab;
displayOptions: DisplayOptions;
gloss: GlossDocument | null;
}) {
return (
<span className="text-3xl">
<ChineseWithPopover
text={children}
vocab={vocab}
displayOptions={displayOptions}
gloss={gloss}
/>
</span>
);
}
Loading

0 comments on commit 9c02cda

Please sign in to comment.