diff --git a/package.json b/package.json index cff924e..c76c277 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "keimeno", - "version": "0.9.0", + "version": "1.0.0-rc.0", "private": true, "scripts": { "dev": "next dev", diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index a90c81f..cd47efa 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -5,10 +5,14 @@ import Head from "next/head"; export default function App({ Component, pageProps }: AppProps) { return ( <> - - Keímeno - - - + + Keímeno + + + + ); } diff --git a/src/pages/_document.tsx b/src/pages/_document.tsx index 8bd2c9c..712e44b 100644 --- a/src/pages/_document.tsx +++ b/src/pages/_document.tsx @@ -5,10 +5,6 @@ export default function Document() { -
diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 76133ea..c38d3e5 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -6,9 +6,12 @@ const inter = Inter({ subsets: ["latin"] }); export default function Home() { const [wordCount, setWordCount] = useState(0); + const [showShortcuts, setShowShortcuts] = useState(false); useEffect(() => { - const editableArea = document.getElementById("editableArea"); + const editableArea = document.getElementById( + "editableArea" + ) as HTMLDivElement; const savedText = localStorage.getItem("savedText"); const savedWordCount = localStorage.getItem("savedWordCount"); if (savedText && editableArea) { @@ -48,6 +51,65 @@ export default function Home() { if (event.shiftKey && event.key === "F") { toggleFocusMode(); } + if (event.ctrlKey && event.key === "b") { + event.preventDefault(); + makeTextBold(); + } + if (event.ctrlKey && event.key === "i") { + event.preventDefault(); + makeTextItalic(); + } + if (event.ctrlKey && event.key === "s") { + event.preventDefault(); + const editableArea = document.getElementById( + "editableArea" + ) as HTMLDivElement; + const content = editableArea.innerText; + const words = content.trim().split(/\s+/); + const blob = new Blob([content], { type: "text/plain" }); + const url = URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = `keimeno-${words.length}-words.txt`; + a.click(); + URL.revokeObjectURL(url); + } + if (event.ctrlKey && event.key === "o") { + event.preventDefault(); + const input = document.createElement("input"); + input.type = "file"; + input.accept = ".txt"; + input.onchange = async (event) => { + const file = (event.target as HTMLInputElement).files?.[0]; + if (file) { + const text = await file.text(); + const editableArea = document.getElementById( + "editableArea" + ) as HTMLDivElement; + editableArea.innerText = text; + handleWordCount(); + } + }; + input.click(); + } + if (event.ctrlKey && event.key === "d") { + event.preventDefault(); + const editableArea = document.getElementById( + "editableArea" + ) as HTMLDivElement; + const selection = window.getSelection(); + const range = selection?.getRangeAt(0); + const span = document.createElement("span"); + span.style.textDecoration = "line-through"; + if (range) { + range.surroundContents(span); + selection?.removeAllRanges(); + selection?.addRange(range); + } + } + if (event.key === "Escape") { + setShowShortcuts(false); + } }; document.addEventListener("keydown", handleKeyDown); @@ -63,6 +125,40 @@ export default function Home() { setFocusMode(!focusMode); }; + const makeTextBold = () => { + const editableArea = document.getElementById( + "editableArea" + ) as HTMLDivElement; + const selection = window.getSelection(); + const range = selection?.getRangeAt(0); + const span = document.createElement("span"); + span.style.fontWeight = "bold"; + if (range) { + range.surroundContents(span); + selection?.removeAllRanges(); + selection?.addRange(range); + } + }; + + const makeTextItalic = () => { + const editableArea = document.getElementById( + "editableArea" + ) as HTMLDivElement; + const selection = window.getSelection(); + const range = selection?.getRangeAt(0); + const span = document.createElement("span"); + span.style.fontStyle = "italic"; + if (range) { + range.surroundContents(span); + selection?.removeAllRanges(); + selection?.addRange(range); + } + }; + + const toggleShortcuts = () => { + setShowShortcuts(!showShortcuts); + }; + return (
Focus +

Just Text. Just Notes. Save. Secure.

-

v0.8.0 "Lumina"

+

v1.0.0-rc.0 "Prut"

Made with ❤️ by{" "} @@ -124,6 +227,63 @@ export default function Home() {

+ {showShortcuts && ( +
+
+

Keyboard Shortcuts

+
    +
  • + + Shift + C + {" "} + : Clear text +
  • +
  • + + Shift + F + {" "} + : Toggle Focus Mode +
  • +
  • + + Ctrl + B + {" "} + : Make text bold +
  • +
  • + + Ctrl + I + {" "} + : Make text italic +
  • +
  • + + Ctrl + S + {" "} + : Save text as file +
  • +
  • + + Ctrl + O + {" "} + : Open text file +
  • +
  • + + Ctrl + D + {" "} + : Strikethrough text +
  • +
+ +
+
+ )}
); } diff --git a/tailwind.config.ts b/tailwind.config.ts index 8a74b32..d201045 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -17,6 +17,8 @@ const config: Config = { extend: { backgroundImage: { wip: "repeating-linear-gradient( -45deg, #000, #000 30px, #ffdd00 30px, #ffdd00 50px )", + stable1: "repeating-linear-gradient( -45deg, #04724D, #04724D 30px, #F06449 30px, #F06449 50px )", + stable: "repeating-linear-gradient(45deg, #DEBA6F, #DEBA6F 20px, #823038 20px, #823038 40px)", }, colors: { "black-soft": "#222222",