Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expanded cell creation #22

Merged
merged 3 commits into from
Feb 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 20 additions & 8 deletions src-tauri/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

use serde_json::json;
use tokio::sync::Mutex;

use std::collections::HashMap;
Expand Down Expand Up @@ -94,20 +95,26 @@ impl AppState {
}

// Return cell_id
async fn create_cell(&self, window_id: &str) -> Option<String> {
async fn create_cell(&self, window: Window, cell_type: Option<&str>) -> Option<String> {
let window_id = window.label();
debug!("Creating a new cell in window with ID: {}", window_id);

let cell_type = cell_type.unwrap_or("code");
let mut notebooks = self.notebooks.lock().await;
if let Some(notebook) = notebooks.get_mut(window_id) {
let new_cell = notebook.add_code_cell("");
let new_cell = match cell_type {
"markdown" => notebook.add_markdown_cell(""),
_ => notebook.add_code_cell(""),
};
Some(new_cell.id().to_string())
} else {
None
}
}

// Update a specific cell within the specified notebook
async fn update_cell(&self, window_id: &str, cell_id: &str, new_content: &str) -> bool {
async fn update_cell(&self, window: Window, cell_id: &str, new_content: &str) -> bool {
let window_id = window.label();
debug!(
"Updating cell with ID: {} in window with ID: {} with new content: {}",
cell_id, window_id, new_content
Expand All @@ -117,6 +124,13 @@ impl AppState {
if let Some(notebook) = notebooks.get_mut(window_id) {
if let Some(cell) = notebook.get_mut_cell(cell_id) {
cell.set_source(new_content);

window.emit(
format!("cell-{}", cell_id).as_str(),
Some(json!({
"source": new_content
}))
).unwrap();
}
true
} else {
Expand All @@ -126,9 +140,8 @@ impl AppState {
}

#[tauri::command]
async fn create_cell(state: State<'_, AppState>, window: Window) -> Result<Option<String>, String> {
let window_id = window.label(); // Use the window label as a unique identifier
Ok(state.create_cell(window_id).await)
async fn create_cell(state: State<'_, AppState>, window: Window, cell_type: &str) -> Result<Option<String>, String> {
Ok(state.create_cell(window, Some(cell_type)).await)
}

#[tauri::command]
Expand All @@ -147,8 +160,7 @@ async fn update_cell(
cell_id: &str,
new_content: &str,
) -> Result<bool, String> {
let window_id = window.label(); // Use the window label as a unique identifier
Ok(state.update_cell(window_id, cell_id, new_content).await)
Ok(state.update_cell(window, cell_id, new_content).await)
}

// The main entry point for the Tauri application
Expand Down
25 changes: 17 additions & 8 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
import Cell from "@/components/Cell";

import { Button} from "@/components/ui/button";
import { Button } from "@/components/ui/button";
import { useNotebook } from '@/hooks/useNotebook';

import { MarkdownCell } from "@/components/markdown-cell"
import { CodeCell } from '@/components/code-cell'

function App() {
const { cells, createCell } = useNotebook();
const { cells, createCodeCell, createMarkdownCell } = useNotebook();
return (
<div>
{cells.map((cellId: string) => (
<Cell cellId={cellId} key={cellId}/>
))}
<Button onClick={createCell}>New Cell</Button>
{cells.map((cellInfo) => {
switch (cellInfo.cellType) {
case "code":
return <CodeCell cellId={cellInfo.id} key={cellInfo.id} />
case "markdown":
return <MarkdownCell cellId={cellInfo.id} key={cellInfo.id} />
default:
return "Unknown cell type"
}
})}
<Button onClick={createCodeCell}>New Code Cell</Button>
<Button onClick={createMarkdownCell}>New Markdown Cell</Button>
</div>
);
}
Expand Down
9 changes: 0 additions & 9 deletions src/components/Cell.tsx

This file was deleted.

4 changes: 2 additions & 2 deletions src/components/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { lightTheme } from "@/codemirror-themes";

import { StateField } from "@codemirror/state";
import { EditorView, keymap } from "@codemirror/view";
import { useCodeCell } from "@/hooks/useCell";
import { useCell } from "@/hooks/useCell";

import { invoke } from "@tauri-apps/api/tauri";

Expand Down Expand Up @@ -82,7 +82,7 @@ const baseExtensions = [
export const Editor = ({ cellId, className, language }: { cellId: string, className?: string, language: string }) => {
const ref = useRef<HTMLDivElement>(null);

const { content, updateCell } = useCodeCell(cellId);
const { content, updateCell } = useCell(cellId);

// We need to compute a derived extensions state based on the language of the editor
const extensions = useMemo(() => {
Expand Down
10 changes: 10 additions & 0 deletions src/components/markdown-cell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { useRemark } from "react-remark";

import { useMarkdownCell } from "@/hooks/useCell";

import { Editor } from "@/components//Editor";

export const MarkdownCell = ({ cellId }: { cellId: string }) => {
const { content } = useMarkdownCell(cellId);

Expand All @@ -12,13 +14,21 @@ export const MarkdownCell = ({ cellId }: { cellId: string }) => {
setMarkdownSource(content);
}, [content]);

console.log(content)


return (
<div className="flex items-start">
<div className="w-14 h-full pt-1 pb-1 m-0">
{/* placeholder */}
</div>

<Editor
cellId={cellId}
className="mr-2 pt-0 pb-0 text-sm"
language="markdown"
/>

<div className="prose">{reactContent}</div>
</div>
);
Expand Down
44 changes: 30 additions & 14 deletions src/hooks/useCell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,43 @@ function cellReducer(state: CellState, action: Action) {
}
}

export function useMarkdownCell(cellId: string) {
export function useCell(cellId: string) {
const [content, setContent] = useState<string>("");

const updateCell = useCallback(async (newContent: string) => {
try {
await invoke("update_cell", { cellId, newContent });
setContent(newContent);
await invoke("update_cell", { cellId, newContent });
} catch (error) {
console.error(error);
// Handle error
}
}, [cellId]);
}, [cellId]);


useEffect(() => {
const setupListener = async () => {
const unlisten = await listen(`cell-${cellId}`, (event) => {
const cellUpdate = event.payload as any;

setContent(cellUpdate.source)
});

return () => {
unlisten();
};
};

setupListener();
}, [cellId]);



return { content, setContent, updateCell }
}

export function useMarkdownCell(cellId: string) {
const { content, updateCell } = useCell(cellId);

// TODO: Push/pull this from cell metadata
const metadata = { };
Expand All @@ -55,7 +80,8 @@ export function useMarkdownCell(cellId: string) {
}

export function useCodeCell(cellId: string) {
const [content, setContent] = useState<string>("");
const { content, updateCell } = useCell(cellId);

const [state, dispatch] = useReducer(cellReducer, initialState);

const executeCell = useCallback(async () => {
Expand All @@ -69,16 +95,6 @@ export function useCodeCell(cellId: string) {
dispatch({ type: 'reset' });
}, [cellId]);

const updateCell = useCallback(async (newContent: string) => {
try {
await invoke("update_cell", { cellId, newContent });
setContent(newContent);
} catch (error) {
console.error(error);
// Handle error
}
}, [cellId]);

useEffect(() => {
const setupListener = async () => {
const unlisten = await listen(`cell-outputs-${cellId}`, (event) => {
Expand Down
22 changes: 14 additions & 8 deletions src/hooks/useNotebook.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import { useState } from 'react';
import { useState, useCallback } from 'react';
import { invoke } from "@tauri-apps/api/tauri";

type CellInfo = {
id: string,
cellType: "code" | "markdown"
}

export function useNotebook() {
const [cells, setCells] = useState<string[]>([]);
const [cells, setCells] = useState<CellInfo[]>([]);

async function createCell() {
const id = (await invoke("create_cell")) as string;
setCells(oldCells => [...oldCells, id]);
}
const createCell = useCallback(async (cellType: "code" | "markdown") => {
const id = (await invoke("create_cell", { cellType })) as string;
setCells(oldCells => [...oldCells, { id, cellType }]);
}, []);

// TODO(kyle): Listen to events from the backend to update the cell list
const createCodeCell = useCallback(() => createCell("code"), [createCell]);
const createMarkdownCell = useCallback(() => createCell("markdown"), [createCell]);

return { cells, createCell };
return { cells, createCell, createCodeCell, createMarkdownCell};
}
Loading