refactor: unified EditorPanel for notes and files, SaveFileText backend
- Create EditorPanel.svelte: shared editor component for notes + files - Markdown: edit/preview/split modes via MarkdownEditor + MarkdownPreview - Plain text: monospace textarea - Header: title, mode switcher, external open button - Footer: save + close buttons, dirty indicator - Rewrite NoteEditorPanel.svelte as thin wrapper over EditorPanel - FilesTab: browser/editor modes (editor replaces file list, not appended) - Add SaveFileText Wails binding: writes text files atomically (tmp+rename) - Add WriteText to files.Service with SHA256 update - Remove separate TextFileEditor.svelte (replaced by EditorPanel) - Note context: SaveNote API, noteId/title props - File context: SaveFileText API, fileId prop - Linked .md (CheckFileAction=note) → note editor tab - Unlinked .md / text files → EditorPanel in FilesTab - Images/PDF/binary → FilePreviewModal only Co-Authored-By: OWL (Hermes Agent) <hermes@nousresearch.com>
This commit is contained in:
@@ -210,6 +210,46 @@ func (a *App) CheckFileAction(fileID string) (*PreflightFileAction, error) {
|
||||
return &PreflightFileAction{Action: "preview", FileName: fileRec.Filename}, nil
|
||||
}
|
||||
|
||||
// SaveFileText saves text content to a file record.
|
||||
// Only works for vault-contained text files (not binary).
|
||||
func (a *App) SaveFileText(fileID string, content string) error {
|
||||
if err := a.requireVault(); err != nil {
|
||||
return err
|
||||
}
|
||||
fileRec, err := a.files.Get(fileID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("get file: %w", err)
|
||||
}
|
||||
// Safety: only save text-like files
|
||||
name := strings.ToLower(fileRec.Filename)
|
||||
isText := strings.HasPrefix(fileRec.MIME, "text/") ||
|
||||
strings.HasSuffix(name, ".md") ||
|
||||
strings.HasSuffix(name, ".txt") ||
|
||||
strings.HasSuffix(name, ".json") ||
|
||||
strings.HasSuffix(name, ".yaml") ||
|
||||
strings.HasSuffix(name, ".yml") ||
|
||||
strings.HasSuffix(name, ".csv") ||
|
||||
strings.HasSuffix(name, ".xml") ||
|
||||
strings.HasSuffix(name, ".ini") ||
|
||||
strings.HasSuffix(name, ".conf") ||
|
||||
strings.HasSuffix(name, ".sh") ||
|
||||
strings.HasSuffix(name, ".py") ||
|
||||
strings.HasSuffix(name, ".js") ||
|
||||
strings.HasSuffix(name, ".ts") ||
|
||||
strings.HasSuffix(name, ".css") ||
|
||||
strings.HasSuffix(name, ".html") ||
|
||||
strings.HasSuffix(name, ".log")
|
||||
if !isText {
|
||||
return fmt.Errorf("refusing to save binary file: %s", fileRec.Filename)
|
||||
}
|
||||
if err := a.files.WriteText(fileRec, content); err != nil {
|
||||
return fmt.Errorf("write file: %w", err)
|
||||
}
|
||||
// Record activity
|
||||
_ = a.activity.Record(fileRec.NodeID, activity.TargetFile, fileID, "", activity.TypeFileModified, fileRec.Filename, "")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) PreviewImport(sourcePath string) (*files.ImportSummary, error) {
|
||||
if err := a.requireVault(); err != nil {
|
||||
return nil, err
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -19,8 +19,8 @@
|
||||
background: #13131f;
|
||||
}
|
||||
</style>
|
||||
<script type="module" crossorigin src="/assets/main-D23Sgy9Q.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/main-CoirOqGf.css">
|
||||
<script type="module" crossorigin src="/assets/main-B99YW--H.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/main-CtgLvi_n.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
Reference in New Issue
Block a user