Compare commits

..

No commits in common. "80d5f76840b3af898ce534ad512ce4324bb0155a" and "06daa25c5a8da6bf3534ab6e39fdd3f81f713d6b" have entirely different histories.

43 changed files with 274 additions and 605 deletions

BIN
bun.lockb

Binary file not shown.

Binary file not shown.

View File

@ -1,138 +0,0 @@
import React, { useState, useEffect } from 'react';
import Card from '@mui/material/Card';
import Button from '@mui/material/Button';
import {
Bold,
Italic,
List,
ListOrdered,
Heading1,
Heading2,
Quote,
MoreVertical,
X
} from 'lucide-react';
const NoteEditor = () => {
const [content, setContent] = useState('');
const [isToolbarOpen, setIsToolbarOpen] = useState(false);
const [viewportHeight, setViewportHeight] = useState('100vh');
// Handle viewport resize when keyboard appears
useEffect(() => {
const handleResize = () => {
const visualViewport = window.visualViewport;
if (visualViewport) {
setViewportHeight(`${visualViewport.height}px`);
}
};
window.visualViewport?.addEventListener('resize', handleResize);
window.visualViewport?.addEventListener('scroll', handleResize);
return () => {
window.visualViewport?.removeEventListener('resize', handleResize);
window.visualViewport?.removeEventListener('scroll', handleResize);
};
}, []);
const execCommand = (command, value = false) => {
document.execCommand(command, false, value);
};
const ToolbarButton = ({ icon: Icon, command, value, label }) => (
<Button
variant="ghost"
size="lg"
className="p-4 h-auto flex flex-col items-center gap-1"
onClick={() => {
execCommand(command, value);
// Don't close toolbar for formatting commands
if (command === 'save') setIsToolbarOpen(false);
}}
>
<Icon className="w-6 h-6" />
<span className="text-xs">{label}</span>
</Button>
);
return (
<div
className="fixed inset-0 flex flex-col"
style={{ height: viewportHeight }}
>
{/* Main toolbar button */}
<Button
variant="outline"
size="icon"
className="fixed top-2 right-2 z-20"
onClick={() => setIsToolbarOpen(!isToolbarOpen)}
>
{isToolbarOpen ? <X className="w-4 h-4" /> : <MoreVertical className="w-4 h-4" />}
</Button>
{/* Expandable toolbar */}
{isToolbarOpen && (
<Card className="absolute top-12 right-2 z-10 p-2 shadow-lg">
<div className="grid grid-cols-3 gap-2">
<ToolbarButton
icon={Bold}
command="bold"
label="Bold"
/>
<ToolbarButton
icon={Italic}
command="italic"
label="Italic"
/>
<ToolbarButton
icon={List}
command="insertUnorderedList"
label="Bullet List"
/>
<ToolbarButton
icon={ListOrdered}
command="insertOrderedList"
label="Numbered List"
/>
<ToolbarButton
icon={Heading1}
command="formatBlock"
value="<h1>"
label="Heading 1"
/>
<ToolbarButton
icon={Heading2}
command="formatBlock"
value="<h2>"
label="Heading 2"
/>
<ToolbarButton
icon={Quote}
command="formatBlock"
value="<blockquote>"
label="Quote"
/>
</div>
</Card>
)}
{/* Editor area */}
<div className="flex-1 overflow-auto">
<div
className="min-h-full p-4 focus:outline-none"
contentEditable={true}
onInput={(e) => setContent(e.currentTarget.innerHTML)}
suppressContentEditableWarning={true}
style={{
WebkitUserSelect: 'text',
WebkitTouchCallout: 'none',
overflowY: 'auto',
}}
/>
</div>
</div>
);
};
export default NoteEditor;

View File

@ -1,32 +0,0 @@
import { invoke } from "@tauri-apps/api/core";
import { createRoot } from 'react-dom/client';
import React, { useState, useEffect } from 'react';
import NoteEditor from "./claude-generated-code";
const domElem = document.getElementById("editor");
console.log(domElem);
const root = createRoot(domElem);
root.render(<NoteEditor/>);
let greetInputEl: HTMLInputElement | null;
let greetMsgEl: HTMLElement | null;
async function greet() {
if (greetMsgEl && greetInputEl) {
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
greetMsgEl.textContent = await invoke("greet", {
name: greetInputEl.value,
});
}
}
window.addEventListener("DOMContentLoaded", () => {
greetInputEl = document.querySelector("#greet-input");
greetMsgEl = document.querySelector("#greet-msg");
document.querySelector("#greet-form")?.addEventListener("submit", (e) => {
e.preventDefault();
greet();
});
});

View File

@ -1 +0,0 @@
{ "dependencies": { "lucide-react": "^0.460.0", "react-dom": "^18.3.1" } }

BIN
scribe/bun.lockb Executable file

Binary file not shown.

View File

@ -4,8 +4,9 @@
<meta charset="UTF-8" />
<link rel="stylesheet" href="/src/styles.css" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Notes</title>
<script type="module" src="/src/main.tsx" defer></script>
<title>Tauri App</title>
<script type="module" src="/src/main.ts" defer></script>
<script type="module" src="/src/prosemirror.ts" defer></script>
</head>
<body>
@ -32,7 +33,6 @@
</a>
</div>
<p>Click on the Tauri logo to learn more about the framework</p>
<div id="editor"></div>
<form class="row" id="greet-form">
<input id="greet-input" placeholder="Enter a name..." />
@ -41,5 +41,7 @@
<p id="greet-msg"></p>
</main>
<div id="editor"></div>
<div id="content">test</div>
</body>
</html>

View File

@ -1,5 +1,5 @@
{
"name": "notes",
"name": "scribe",
"private": true,
"version": "0.1.0",
"type": "module",
@ -10,11 +10,13 @@
"tauri": "tauri"
},
"dependencies": {
"@emotion/react": "^11.13.3",
"@emotion/styled": "^11.13.0",
"@mui/material": "^6.1.7",
"@tauri-apps/api": "^2",
"@tauri-apps/plugin-shell": "^2"
"@tauri-apps/plugin-shell": "^2",
"prosemirror-example-setup": "^1.2.3",
"prosemirror-schema-basic": "^1.2.3",
"prosemirror-schema-list": "^1.4.1",
"prosemirror-state": "^1.4.3",
"prosemirror-view": "^1.34.3"
},
"devDependencies": {
"@tauri-apps/cli": "^2",

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
[package]
name = "notes"
name = "scribe"
version = "0.1.0"
description = "A Tauri App"
authors = ["you"]
@ -11,7 +11,7 @@ edition = "2021"
# The `_lib` suffix may seem redundant but it is necessary
# to make the lib name unique and wouldn't conflict with the bin name.
# This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519
name = "notes_lib"
name = "scribe_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
[build-dependencies]

View File

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

Before

Width:  |  Height:  |  Size: 974 B

After

Width:  |  Height:  |  Size: 974 B

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

Before

Width:  |  Height:  |  Size: 903 B

After

Width:  |  Height:  |  Size: 903 B

View File

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 85 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -2,5 +2,5 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
fn main() {
notes_lib::run()
scribe_lib::run()
}

View File

@ -1,8 +1,8 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "notes",
"productName": "scribe",
"version": "0.1.0",
"identifier": "com.notes.app",
"identifier": "com.scribe.app",
"build": {
"beforeDevCommand": "bun run dev",
"devUrl": "http://localhost:1420",
@ -13,7 +13,7 @@
"withGlobalTauri": true,
"windows": [
{
"title": "notes",
"title": "scribe",
"width": 800,
"height": 600
}

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

44
scribe/src/main.ts Normal file
View File

@ -0,0 +1,44 @@
import { invoke } from "@tauri-apps/api/core";
import {EditorState} from "prosemirror-state"
import {EditorView} from "prosemirror-view"
import {Schema, DOMParser} from "prosemirror-model"
import {schema} from "prosemirror-schema-basic"
import {addListNodes} from "prosemirror-schema-list"
import {exampleSetup} from "prosemirror-example-setup"
// Mix the nodes from prosemirror-schema-list into the basic schema to
// create a schema with list support.
const mySchema = new Schema({
nodes: addListNodes(schema.spec.nodes, "paragraph block*", "block"),
marks: schema.spec.marks
})
window.view = new EditorView(document.querySelector("#editor"), {
state: EditorState.create({
doc: DOMParser.fromSchema(mySchema).parse(document.querySelector("#content")),
plugins: exampleSetup({schema: mySchema})
})
})
let greetInputEl: HTMLInputElement | null;
let greetMsgEl: HTMLElement | null;
async function greet() {
if (greetMsgEl && greetInputEl) {
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
greetMsgEl.textContent = await invoke("greet", {
name: greetInputEl.value,
});
}
}
window.addEventListener("DOMContentLoaded", () => {
greetInputEl = document.querySelector("#greet-input");
greetMsgEl = document.querySelector("#greet-msg");
document.querySelector("#greet-form")?.addEventListener("submit", (e) => {
e.preventDefault();
greet();
});
});

21
scribe/src/prosemirror.ts Normal file
View File

@ -0,0 +1,21 @@
import {EditorState} from "prosemirror-state"
import {EditorView} from "prosemirror-view"
import {Schema, DOMParser} from "prosemirror-model"
import {schema} from "prosemirror-schema-basic"
import {addListNodes} from "prosemirror-schema-list"
import {exampleSetup} from "prosemirror-example-setup"
// Mix the nodes from prosemirror-schema-list into the basic schema to
// create a schema with list support.
const mySchema = new Schema({
nodes: addListNodes(schema.spec.nodes, "paragraph block*", "block"),
marks: schema.spec.marks
})
window.view = new EditorView(document.querySelector("#editor"), {
state: EditorState.create({
doc: DOMParser.fromSchema(mySchema).parse(document.querySelector("#content")),
plugins: exampleSetup({schema: mySchema})
})
})