11import 'dart:async' ;
22import 'package:flutter/material.dart' ;
3+ import 'package:owlistic/utils/document_builder.dart' ;
34import 'package:owlistic/viewmodel/notes_viewmodel.dart' ;
45import 'package:owlistic/models/note.dart' ;
56import 'package:owlistic/services/note_service.dart' ;
@@ -10,6 +11,7 @@ import 'package:owlistic/utils/websocket_message_parser.dart';
1011import 'package:owlistic/utils/logger.dart' ;
1112import 'package:owlistic/services/block_service.dart' ;
1213import 'package:owlistic/services/app_state_service.dart' ;
14+ import 'package:super_editor_markdown/super_editor_markdown.dart' ;
1315
1416class NotesProvider with ChangeNotifier implements NotesViewModel {
1517 final Logger _logger = Logger ('NotesProvider' );
@@ -526,4 +528,104 @@ class NotesProvider with ChangeNotifier implements NotesViewModel {
526528 notifyListeners ();
527529 }
528530 }
531+
532+ @override
533+ Future <Note ?> importMarkdownFile (String content, String fileName, String notebookId) async {
534+ try {
535+ _logger.info ('Importing markdown file: $fileName to notebook: $notebookId ' );
536+
537+ if (notebookId.isEmpty) {
538+ throw Exception ("Notebook ID is required to import a note" );
539+ }
540+
541+ // Extract title from filename (remove .md extension if present)
542+ String title = fileName;
543+ if (title.toLowerCase ().endsWith ('.md' )) {
544+ title = title.substring (0 , title.length - 3 );
545+ }
546+
547+ // Create the note first
548+ final note = await _noteService.createNote (notebookId, title);
549+ _logger.debug ('Created note: ${note .id } for markdown import' );
550+
551+ final documentBuilder = DocumentBuilder ();
552+
553+ // Create blocks for each node
554+ final document = documentBuilder.deserializeMarkdownContent (content);
555+
556+ // Create blocks for each node
557+ int order = 0 ;
558+ for (final node in document) {
559+ try {
560+ final blockContent = documentBuilder.buildBlockContent (node);
561+
562+ final blockType = blockContent['type' ];
563+ final payload = {
564+ "metadata" : blockContent['metadata' ],
565+ "content" : blockContent['content' ],
566+ };
567+
568+ // Create block through BlockService
569+ await _blockService.createBlock (
570+ note.id,
571+ payload,
572+ blockType,
573+ (order + 1 ) * 1000.0 // Use increasing order with gaps
574+ );
575+
576+ order++ ;
577+ } catch (e) {
578+ _logger.error ('Error creating block for imported markdown: $e ' );
579+ }
580+ }
581+
582+ // Add note to local state
583+ _notesMap[note.id] = note;
584+ _updateCount++ ;
585+ notifyListeners ();
586+
587+ return note;
588+ } catch (error) {
589+ _logger.error ('Error importing markdown file' , error);
590+ _errorMessage = 'Failed to import markdown: ${error .toString ()}' ;
591+ notifyListeners ();
592+ return null ;
593+ }
594+ }
595+
596+ @override
597+ Future <String > exportNoteToMarkdown (String noteId) async {
598+ try {
599+ _logger.info ('Exporting note $noteId to markdown' );
600+
601+ // Fetch note if not already in memory
602+ Note ? note = _notesMap[noteId];
603+ note = await fetchNoteById (noteId);
604+
605+ if (note == null ) {
606+ throw Exception ("Note not found" );
607+ }
608+
609+ // Fetch all blocks for the note to ensure we have the latest data
610+ final blocks = await _blockService.fetchBlocksForNote (noteId);
611+
612+ // Create a document from the blocks
613+ final documentBuilder = DocumentBuilder ();
614+
615+ // Convert blocks to document nodes
616+ documentBuilder.populateDocumentFromBlocks (blocks);
617+
618+ // Serialize document to markdown
619+ final markdown = serializeDocumentToMarkdown (
620+ documentBuilder.document,
621+ syntax: MarkdownSyntax .normal
622+ );
623+
624+ _logger.debug ('Note exported to markdown successfully' );
625+ return markdown;
626+ } catch (error) {
627+ _logger.error ('Error exporting note to markdown' , error);
628+ throw Exception ('Failed to export note: ${error .toString ()}' );
629+ }
630+ }
529631}
0 commit comments