Skip to content
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
18 changes: 18 additions & 0 deletions packages/backend/src/api/file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import * as fs from "fs";

import { type SDK } from "caido:plugin";

import type { API } from "../index";
import type { BackendEvents } from "../types/events";

export function getFileContent(
_sdk: SDK<API, BackendEvents>,
filePath: string,
): string {
try {
const content = fs.readFileSync(filePath, "utf-8");
return content;
} catch (error) {
return `Error reading file: ${error}`;
}
}
2 changes: 2 additions & 0 deletions packages/backend/src/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { getFileContent } from "./file";
import { createFolder, deleteFolder } from "./folder";
import { getLegacyNotes, migrateNote } from "./migration";
import {
Expand All @@ -24,4 +25,5 @@ export {
getCurrentProjectId,
getLegacyNotes,
migrateNote,
getFileContent,
};
3 changes: 3 additions & 0 deletions packages/backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
deleteFolder,
deleteNote,
getCurrentProjectId,
getFileContent,
getLegacyNotes,
getNote,
getTree,
Expand All @@ -31,6 +32,7 @@ export type API = DefineAPI<{
getCurrentProjectId: typeof getCurrentProjectId;
getLegacyNotes: typeof getLegacyNotes;
migrateNote: typeof migrateNote;
getFileContent: typeof getFileContent;
}>;

export function init(sdk: SDK<API, BackendEvents>) {
Expand All @@ -46,6 +48,7 @@ export function init(sdk: SDK<API, BackendEvents>) {
sdk.api.register("getCurrentProjectId", getCurrentProjectId);
sdk.api.register("getLegacyNotes", getLegacyNotes);
sdk.api.register("migrateNote", migrateNote);
sdk.api.register("getFileContent", getFileContent);

sdk.events.onProjectChange((sdk, project) => {
sdk.api.send("notes++:projectChange", project?.getId());
Expand Down
9 changes: 9 additions & 0 deletions packages/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@
},
"dependencies": {
"@caido/primevue": "0.1.13",
"@codemirror/lang-css": "^6.3.1",
"@codemirror/lang-html": "^6.4.11",
"@codemirror/lang-javascript": "^6.2.4",
"@codemirror/lang-json": "^6.0.2",
"@codemirror/lang-markdown": "^6.5.0",
"@codemirror/language": "^6.11.3",
"@codemirror/state": "^6.5.2",
"@codemirror/view": "^6.39.3",
"@lezer/highlight": "^1.2.3",
"@tiptap/core": "^2.12.0",
"@tiptap/extension-image": "^2.12.0",
"@tiptap/extension-mention": "^2.12.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
<script setup lang="ts">
import { Image as ImageExtension } from "@tiptap/extension-image";
import { Placeholder } from "@tiptap/extension-placeholder";
import Table from "@tiptap/extension-table";

Check warning on line 17 in packages/frontend/src/components/content/editor/NoteEditor.vue

View workflow job for this annotation

GitHub Actions / validate

Using exported name 'Table' as identifier for default import
import TableCell from "@tiptap/extension-table-cell";

Check warning on line 18 in packages/frontend/src/components/content/editor/NoteEditor.vue

View workflow job for this annotation

GitHub Actions / validate

Using exported name 'TableCell' as identifier for default import
import TableHeader from "@tiptap/extension-table-header";

Check warning on line 19 in packages/frontend/src/components/content/editor/NoteEditor.vue

View workflow job for this annotation

GitHub Actions / validate

Using exported name 'TableHeader' as identifier for default import
import TableRow from "@tiptap/extension-table-row";

Check warning on line 20 in packages/frontend/src/components/content/editor/NoteEditor.vue

View workflow job for this annotation

GitHub Actions / validate

Using exported name 'TableRow' as identifier for default import
import { type Slice } from "@tiptap/pm/model";
import { type EditorView } from "@tiptap/pm/view";
import { StarterKit } from "@tiptap/starter-kit";
Expand All @@ -30,6 +30,7 @@
import { ArrowKeysFix } from "./extensions/arrows-fix";
import { MarkdownHeading } from "./extensions/markdown-heading";
import MarkdownStyling from "./extensions/markdown-styling";
import { createFileMention } from "./extensions/mentions/mention-file";
import { createSessionMention } from "./extensions/mentions/mention-request";
import createSuggestion from "./extensions/mentions/suggestion";
import { Search } from "./extensions/search";
Expand All @@ -46,6 +47,7 @@
const notesStore = useNotesStore();
const suggestion = createSuggestion(sdk);
const SessionMention = createSessionMention(sdk);
const FileMention = createFileMention(sdk);

const MAX_IMAGE_SIZE_MB = 30;
const ALLOWED_IMAGE_TYPES = ["image/jpeg", "image/png", "image/gif"];
Expand Down Expand Up @@ -185,7 +187,8 @@
TableRow,
TableHeader,
TableCell,
SlashCommands,
FileMention,
SlashCommands.configure({ sdk }),
],
editorProps: {
attributes: {
Expand Down Expand Up @@ -255,7 +258,6 @@
watch(
() => notesStore.currentNote,
(newNote, oldNote) => {
// Save cursor position of the previous note before switching
if (previousNotePath && editor.value) {
const { from, to } = editor.value.state.selection;
cursorPositions.set(previousNotePath, { from, to });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ const props = defineProps<{

const shouldShowMenu = () => {
if (!props.editor.isActive("table")) return false;
const { from, to } = props.editor.state.selection;
if (from === to) return false;
return (
props.editor.isActive("tableCell") || props.editor.isActive("tableHeader")
);
Expand Down Expand Up @@ -50,7 +52,9 @@ const deleteTable = () => {
>
<button title="Add column left" @click="addColumnBefore">+Col</button>
<button title="Add column right" @click="addColumnAfter">Col+</button>
<button title="Delete column" class="del" @click="deleteColumn">−Col</button>
<button title="Delete column" class="del" @click="deleteColumn">
−Col
</button>
<span class="sep"></span>
<button title="Add row above" @click="addRowBefore">+Row</button>
<button title="Add row below" @click="addRowAfter">Row+</button>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<template>
<div
class="dropdown-menu bg-surface-800 rounded-sm shadow-md border border-surface-700 p-0.5 max-h-52 overflow-y-auto w-64"
>
<div class="p-1 text-xs font-medium text-surface-300">
Select a hosted file
</div>
<div class="h-px bg-surface-700 mb-1"></div>
<template v-if="items.length">
<button
v-for="(item, index) in items"
:key="index"
class="w-full text-left px-2 py-1.5 text-sm hover:bg-surface-700 rounded-sm transition-colors text-surface-200 flex items-center gap-2"
:class="{ 'bg-surface-600 text-surface-100': index === selectedIndex }"
@click="selectItem(index)"
>
<i class="fas fa-file text-primary-500 text-xs"></i>
<div class="flex-1 overflow-hidden">
<div class="truncate">{{ item.name }}</div>
<div class="text-xs text-surface-400">
{{ formatSize(item.size) }}
</div>
</div>
</button>
</template>
<div v-else class="px-2 py-2 text-sm text-surface-400 text-center">
No files found
</div>
</div>
</template>

<script>
export default {
props: {
items: {
type: Array,
required: true,
},
command: {
type: Function,
required: true,
},
},

data() {
return {
selectedIndex: 0,
};
},

watch: {
items() {
this.selectedIndex = 0;
},
},

methods: {
formatSize(bytes) {
if (bytes === 0) return "0 B";
const k = 1024;
const sizes = ["B", "KB", "MB", "GB"];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + " " + sizes[i];
},

onKeyDown({ event }) {
if (event.key === "ArrowUp") {
this.upHandler();
return true;
}

if (event.key === "ArrowDown") {
this.downHandler();
return true;
}

if (event.key === "Enter") {
this.enterHandler();
return true;
}

return false;
},

upHandler() {
this.selectedIndex =
(this.selectedIndex + this.items.length - 1) % this.items.length;
},

downHandler() {
this.selectedIndex = (this.selectedIndex + 1) % this.items.length;
},

enterHandler() {
this.selectItem(this.selectedIndex);
},

selectItem(index) {
const item = this.items[index];
if (item) {
this.command(item);
}
},
},
};
</script>
Loading