diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png index 00e83fc..81a6e4f 100644 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png index e3943e9..cd5a92a 100644 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png index 15f7dc9..f90fa82 100644 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index ef0c289..b3f2841 100644 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index 787e5c2..0ec02ab 100644 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/assets/icon.png b/assets/icon.png index 8531422..99250c2 100644 Binary files a/assets/icon.png and b/assets/icon.png differ diff --git a/lib/app.dart b/lib/app.dart index 5b8672c..7a7b4e3 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -3,6 +3,8 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_quill/flutter_quill.dart'; import 'package:notas/data/app_database.dart'; import 'package:notas/data/api_client.dart'; import 'package:notas/data/local_vault_service.dart'; @@ -1094,6 +1096,12 @@ class _NotesAppState extends State title: 'Mis Notas', debugShowCheckedModeBanner: false, scaffoldMessengerKey: _scaffoldMessengerKey, + localizationsDelegates: const >[ + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + FlutterQuillLocalizations.delegate, + ], theme: _lightTheme ?? AppTheme.theme( diff --git a/lib/data/note_body.dart b/lib/data/note_body.dart new file mode 100644 index 0000000..2e6234e --- /dev/null +++ b/lib/data/note_body.dart @@ -0,0 +1,38 @@ +import 'dart:convert'; + +import 'package:flutter_quill/flutter_quill.dart'; + +Document noteBodyToDocument(String storedBody) { + final String trimmedBody = storedBody.trimLeft(); + + if (trimmedBody.startsWith('[')) { + try { + final dynamic decoded = jsonDecode(storedBody); + if (decoded is List) { + return Document.fromJson(decoded); + } + } catch (_) { + // Fall back to plain text for legacy notes or malformed JSON. + } + } + + if (storedBody.isEmpty) { + return Document(); + } + + final String plainText = storedBody.endsWith('\n') + ? storedBody + : '$storedBody\n'; + + return Document.fromJson([ + {'insert': plainText}, + ]); +} + +String noteBodyToPlainText(String storedBody) { + return noteBodyToDocument(storedBody).toPlainText(); +} + +String noteDocumentToStorageJson(Document document) { + return jsonEncode(document.toDelta().toJson()); +} diff --git a/lib/screens/home_screen.dart b/lib/screens/home_screen.dart index 93ba2a0..d249a76 100644 --- a/lib/screens/home_screen.dart +++ b/lib/screens/home_screen.dart @@ -5,6 +5,7 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; +import 'package:notas/data/note_body.dart'; import 'package:notas/data/note_repository.dart'; import 'package:notas/models/note.dart'; import 'package:notas/screens/note_editor_screen.dart'; @@ -290,7 +291,7 @@ class _HomeScreenState extends State { .where( (Note note) => note.title.toLowerCase().contains(query) || - note.body.toLowerCase().contains(query), + noteBodyToPlainText(note.body).toLowerCase().contains(query), ) .toList(); } @@ -713,7 +714,7 @@ class _DraggableNote extends StatelessWidget { ), const SizedBox(height: 8), Text( - note.body, + noteBodyToPlainText(note.body), style: TextStyle(color: palette.textSecondary, fontSize: 14), maxLines: 20, overflow: TextOverflow.clip, diff --git a/lib/screens/note_editor_screen.dart b/lib/screens/note_editor_screen.dart index 44c77ea..fea79da 100644 --- a/lib/screens/note_editor_screen.dart +++ b/lib/screens/note_editor_screen.dart @@ -2,8 +2,10 @@ import 'dart:async'; import 'dart:math' as math; import 'package:flutter/material.dart'; +import 'package:flutter_quill/flutter_quill.dart' hide Text; import 'package:intl/intl.dart'; +import 'package:notas/data/note_body.dart'; import 'package:notas/models/category.dart'; import 'package:notas/models/note.dart'; import 'package:notas/platform/app_platform.dart'; @@ -110,7 +112,9 @@ class NoteEditorScreen extends StatefulWidget { class _NoteEditorScreenState extends State { late TextEditingController _titleController; - late TextEditingController _bodyController; + late QuillController _bodyController; + late FocusNode _bodyFocusNode; + late ScrollController _bodyScrollController; late Note _currentNote; late bool _isNewNote; String? _selectedCategoryId; @@ -147,13 +151,20 @@ class _NoteEditorScreenState extends State { _selectedCategoryId = _currentNote.categoryId ?? widget.categoryId; _titleController = TextEditingController(text: _currentNote.title); - _bodyController = TextEditingController(text: _currentNote.body); + _bodyController = QuillController( + document: noteBodyToDocument(_currentNote.body), + selection: const TextSelection.collapsed(offset: 0), + ); + _bodyFocusNode = FocusNode(); + _bodyScrollController = ScrollController(); } @override void dispose() { _closeCategoryMenu(); _titleController.dispose(); + _bodyFocusNode.dispose(); + _bodyScrollController.dispose(); _bodyController.dispose(); super.dispose(); } @@ -182,17 +193,17 @@ class _NoteEditorScreenState extends State { void _saveNote() { final String title = _titleController.text.trim(); - final String body = _bodyController.text.trim(); + final String bodyPlainText = _bodyController.document.toPlainText().trim(); final bool categoryChanged = _selectedCategoryId != _currentNote.categoryId; - if (title.isEmpty && body.isEmpty && !categoryChanged) { + if (title.isEmpty && bodyPlainText.isEmpty && !categoryChanged) { _complete(null); return; } final Note updatedNote = _currentNote.copyWith( title: title.isEmpty ? 'Sin título' : title, - body: body, + body: noteDocumentToStorageJson(_bodyController.document), categoryId: _selectedCategoryId, updatedAt: DateTime.now(), isDirty: true, @@ -646,21 +657,20 @@ class _NoteEditorScreenState extends State { ), SizedBox(height: titleSpacing), Expanded( - child: TextField( - controller: _bodyController, - keyboardType: TextInputType.multiline, - maxLines: null, - expands: true, - style: TextStyle( - color: palette.textPrimary, - fontSize: 16, - height: 1.6, - ), - decoration: InputDecoration( - hintText: 'Escribe tu nota...', - hintStyle: TextStyle(color: palette.textHint), - border: InputBorder.none, - contentPadding: EdgeInsets.zero, + child: Padding( + padding: const EdgeInsets.only(top: 4), + child: QuillEditor.basic( + controller: _bodyController, + focusNode: _bodyFocusNode, + scrollController: _bodyScrollController, + config: QuillEditorConfig( + scrollable: true, + padding: EdgeInsets.zero, + autoFocus: false, + expands: true, + placeholder: 'Escribe tu nota...', + keyboardAppearance: Theme.of(context).brightness, + ), ), ), ), @@ -673,21 +683,67 @@ class _NoteEditorScreenState extends State { decoration: BoxDecoration( border: Border(top: BorderSide(color: palette.border, width: 1)), ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + child: Column( + mainAxisSize: MainAxisSize.min, children: [ - if (!_isNewNote) - IconButton( - onPressed: _deleteNote, - icon: Icon( - Icons.delete_outline, - color: palette.destructiveAccent, + QuillSimpleToolbar( + controller: _bodyController, + config: const QuillSimpleToolbarConfig( + color: Colors.transparent, + showBoldButton: true, + showItalicButton: true, + showUnderLineButton: true, + showStrikeThrough: false, + showInlineCode: false, + showColorButton: false, + showBackgroundColorButton: false, + showClearFormat: false, + showAlignmentButtons: false, + showHeaderStyle: false, + showListNumbers: true, + showListBullets: true, + showListCheck: true, + showCodeBlock: false, + showQuote: false, + showIndent: false, + showLink: false, + showUndo: false, + showRedo: false, + showDividers: false, + showFontFamily: false, + showFontSize: false, + showDirection: false, + showSearchButton: false, + showSubscript: false, + showSuperscript: false, + multiRowsDisplay: false, + showClipboardCut: false, + showClipboardCopy: false, + showClipboardPaste: false, + axis: Axis.horizontal, + ), + ), + const SizedBox(height: 8), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + if (!_isNewNote) + IconButton( + onPressed: _deleteNote, + icon: Icon( + Icons.delete_outline, + color: palette.destructiveAccent, + ), + tooltip: 'Eliminar nota', + ) + else + const SizedBox(width: 48), + FilledButton( + onPressed: _saveNote, + child: const Text('Guardar'), ), - tooltip: 'Eliminar nota', - ) - else - const SizedBox(width: 48), - FilledButton(onPressed: _saveNote, child: const Text('Guardar')), + ], + ), ], ), ), diff --git a/lib/widgets/note_card.dart b/lib/widgets/note_card.dart index 6f22d90..74362c2 100644 --- a/lib/widgets/note_card.dart +++ b/lib/widgets/note_card.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:notas/data/note_body.dart'; import 'package:notas/models/note.dart'; import 'package:notas/theme/app_palette.dart'; @@ -77,26 +78,27 @@ class _NoteCardState extends State { // running the expensive TextPainter layout. This heuristic counts // newline characters and estimates wrapped lines based on an // average characters-per-line to handle many short lines well. - final List rawLines = widget.note.body.split('\n'); + final String bodyText = noteBodyToPlainText(widget.note.body); + final List rawLines = bodyText.split('\n'); const int avgCharsPerLine = 40; int estimatedLines = 0; for (final String line in rawLines) { estimatedLines += (line.trim().length ~/ avgCharsPerLine) + 1; } - final bool needsPreciseMeasurement = estimatedLines > 20; + final bool needsPreciseMeasurement = estimatedLines > 15; final bool isBodyTruncated; if (needsPreciseMeasurement) { final TextPainter textPainter = TextPainter( text: TextSpan( - text: widget.note.body, + text: bodyText, style: TextStyle( color: palette.textSecondary, fontSize: 14, ), ), - maxLines: 20, + maxLines: 15, textDirection: TextDirection.ltr, )..layout(maxWidth: constraints.maxWidth); @@ -121,12 +123,12 @@ class _NoteCardState extends State { ), const SizedBox(height: 8), Text( - widget.note.body, + bodyText, style: TextStyle( color: palette.textSecondary, fontSize: 14, ), - maxLines: 20, + maxLines: 15, overflow: TextOverflow.clip, ), if (isBodyTruncated) ...[ diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 1bf5c50..bc9d47b 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -8,6 +8,7 @@ #include #include +#include #include void fl_register_plugins(FlPluginRegistry* registry) { @@ -17,6 +18,9 @@ void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) screen_retriever_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverLinuxPlugin"); screen_retriever_linux_plugin_register_with_registrar(screen_retriever_linux_registrar); + g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); + url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); g_autoptr(FlPluginRegistrar) window_manager_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "WindowManagerPlugin"); window_manager_plugin_register_with_registrar(window_manager_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index ae20184..79de9a7 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -5,6 +5,7 @@ list(APPEND FLUTTER_PLUGIN_LIST flutter_secure_storage_linux screen_retriever_linux + url_launcher_linux window_manager ) diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 68b382f..64e3d31 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -7,14 +7,18 @@ import Foundation import flutter_secure_storage_darwin import local_auth_darwin +import quill_native_bridge_macos import screen_retriever_macos import shared_preferences_foundation +import url_launcher_macos import window_manager func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FlutterSecureStorageDarwinPlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStorageDarwinPlugin")) LocalAuthPlugin.register(with: registry.registrar(forPlugin: "LocalAuthPlugin")) + QuillNativeBridgePlugin.register(with: registry.registrar(forPlugin: "QuillNativeBridgePlugin")) ScreenRetrieverMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverMacosPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) + UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin")) } diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png index 1bb69be..93af73e 100644 Binary files a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png index d175d6c..1b0b9b0 100644 Binary files a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png index 98fc656..349279b 100644 Binary files a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png index a8ded16..51ae3c0 100644 Binary files a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png index 31faa26..0fae58a 100644 Binary files a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png index 3a4bb09..3f5a885 100644 Binary files a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png index cbdf4c8..2c9b633 100644 Binary files a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/pubspec.lock b/pubspec.lock index 4a12a00..8c0f5d0 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -161,6 +161,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.2" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: "28bb3ae56f117b5aec029d702a90f57d285cd975c3c5c281eaca38dbc47c5937" + url: "https://pub.dev" + source: hosted + version: "0.3.5+2" crypto: dependency: "direct main" description: @@ -177,6 +185,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.9.0" + csslib: + dependency: transitive + description: + name: csslib + sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" + url: "https://pub.dev" + source: hosted + version: "1.0.2" cupertino_icons: dependency: "direct main" description: @@ -185,6 +201,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.9" + dart_quill_delta: + dependency: transitive + description: + name: dart_quill_delta + sha256: bddb0b2948bd5b5a328f1651764486d162c59a8ccffd4c63e8b2c5e44be1dac4 + url: "https://pub.dev" + source: hosted + version: "10.8.3" dart_style: dependency: transitive description: @@ -193,6 +217,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.8" + diff_match_patch: + dependency: transitive + description: + name: diff_match_patch + sha256: "2efc9e6e8f449d0abe15be240e2c2a3bcd977c8d126cfd70598aee60af35c0a4" + url: "https://pub.dev" + source: hosted + version: "0.4.1" drift: dependency: "direct main" description: @@ -225,14 +257,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.0" - ffi_leak_tracker: - dependency: transitive - description: - name: ffi_leak_tracker - sha256: "4093d4ef9ca06ffe2786e73bfb25e22aa92112b9bb4ec941f11e3e6b61489a97" - url: "https://pub.dev" - source: hosted - version: "0.1.2" file: dependency: transitive description: @@ -241,6 +265,22 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.1" + file_selector_platform_interface: + dependency: transitive + description: + name: file_selector_platform_interface + sha256: "35e0bd61ebcdb91a3505813b055b09b79dfdc7d0aee9c09a7ba59ae4bb13dc85" + url: "https://pub.dev" + source: hosted + version: "2.7.0" + file_selector_windows: + dependency: transitive + description: + name: file_selector_windows + sha256: "62197474ae75893a62df75939c777763d39c2bc5f73ce5b88497208bc269abfd" + url: "https://pub.dev" + source: hosted + version: "0.9.3+5" fixnum: dependency: transitive description: @@ -254,6 +294,54 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_colorpicker: + dependency: transitive + description: + name: flutter_colorpicker + sha256: "969de5f6f9e2a570ac660fb7b501551451ea2a1ab9e2097e89475f60e07816ea" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + flutter_keyboard_visibility_linux: + dependency: transitive + description: + name: flutter_keyboard_visibility_linux + sha256: "6fba7cd9bb033b6ddd8c2beb4c99ad02d728f1e6e6d9b9446667398b2ac39f08" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + flutter_keyboard_visibility_macos: + dependency: transitive + description: + name: flutter_keyboard_visibility_macos + sha256: c5c49b16fff453dfdafdc16f26bdd8fb8d55812a1d50b0ce25fc8d9f2e53d086 + url: "https://pub.dev" + source: hosted + version: "1.0.0" + flutter_keyboard_visibility_platform_interface: + dependency: transitive + description: + name: flutter_keyboard_visibility_platform_interface + sha256: e43a89845873f7be10cb3884345ceb9aebf00a659f479d1c8f4293fcb37022a4 + url: "https://pub.dev" + source: hosted + version: "2.0.0" + flutter_keyboard_visibility_temp_fork: + dependency: transitive + description: + name: flutter_keyboard_visibility_temp_fork + sha256: e3d02900640fbc1129245540db16944a0898b8be81694f4bf04b6c985bed9048 + url: "https://pub.dev" + source: hosted + version: "0.1.5" + flutter_keyboard_visibility_windows: + dependency: transitive + description: + name: flutter_keyboard_visibility_windows + sha256: fc4b0f0b6be9b93ae527f3d527fb56ee2d918cd88bbca438c478af7bcfd0ef73 + url: "https://pub.dev" + source: hosted + version: "1.0.0" flutter_launcher_icons: dependency: "direct dev" description: @@ -270,6 +358,11 @@ packages: url: "https://pub.dev" source: hosted version: "6.0.0" + flutter_localizations: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -278,6 +371,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.34" + flutter_quill: + dependency: "direct main" + description: + name: flutter_quill + sha256: "3ee7125b2dd3f3bce3ebdaac722a72f0c8aff3db9aa19053a9d777db12d71c98" + url: "https://pub.dev" + source: hosted + version: "11.5.1" + flutter_quill_delta_from_html: + dependency: transitive + description: + name: flutter_quill_delta_from_html + sha256: "0eb801ea8dd498cadc057507af5da794d4c9599ce58b2569cb3d4bb53ba8bed2" + url: "https://pub.dev" + source: hosted + version: "1.5.3" flutter_secure_storage: dependency: "direct main" description: @@ -322,10 +431,10 @@ packages: dependency: transitive description: name: flutter_secure_storage_windows - sha256: "8f42f359f187a94dce7a3ab2ec5903d013dddfc7127078ebab19fa244c3840e8" + sha256: "3b7c8e068875dfd46719ff57c90d8c459c87f2302ed6b00ff006b3c9fcad1613" url: "https://pub.dev" source: hosted - version: "4.2.1" + version: "4.1.0" flutter_staggered_grid_view: dependency: "direct main" description: @@ -368,6 +477,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.3" + html: + dependency: transitive + description: + name: html + sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602" + url: "https://pub.dev" + source: hosted + version: "0.15.6" http: dependency: "direct main" description: @@ -520,6 +637,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.0" + markdown: + dependency: transitive + description: + name: markdown + sha256: ee85086ad7698b42522c6ad42fe195f1b9898e4d974a1af4576c1a3a176cada9 + url: "https://pub.dev" + source: hosted + version: "7.3.1" matcher: dependency: transitive description: @@ -688,6 +813,70 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.0" + quill_native_bridge: + dependency: transitive + description: + name: quill_native_bridge + sha256: "76a16512e398e84216f3f659f7cb18a89ec1e141ea908e954652b4ce6cf15b18" + url: "https://pub.dev" + source: hosted + version: "11.1.0" + quill_native_bridge_android: + dependency: transitive + description: + name: quill_native_bridge_android + sha256: b75c7e6ede362a7007f545118e756b1f19053994144ec9eda932ce5e54a57569 + url: "https://pub.dev" + source: hosted + version: "0.0.1+2" + quill_native_bridge_ios: + dependency: transitive + description: + name: quill_native_bridge_ios + sha256: d23de3cd7724d482fe2b514617f8eedc8f296e120fb297368917ac3b59d8099f + url: "https://pub.dev" + source: hosted + version: "0.0.1" + quill_native_bridge_macos: + dependency: transitive + description: + name: quill_native_bridge_macos + sha256: "1c0631bd1e2eee765a8b06017c5286a4e829778f4585736e048eb67c97af8a77" + url: "https://pub.dev" + source: hosted + version: "0.0.1" + quill_native_bridge_platform_interface: + dependency: transitive + description: + name: quill_native_bridge_platform_interface + sha256: "8264a2bdb8a294c31377a27b46c0f8717fa9f968cf113f7dc52d332ed9c84526" + url: "https://pub.dev" + source: hosted + version: "0.0.2+1" + quill_native_bridge_web: + dependency: transitive + description: + name: quill_native_bridge_web + sha256: "7c723f6824b0250d7f33e8b6c23f2f8eb0103fe48ee7ebf47ab6786b64d5c05d" + url: "https://pub.dev" + source: hosted + version: "0.0.2" + quill_native_bridge_windows: + dependency: transitive + description: + name: quill_native_bridge_windows + sha256: "3f96ced19e3206ddf4f6f7dde3eb16bdd05e10294964009ea3a806d995aa7caa" + url: "https://pub.dev" + source: hosted + version: "0.0.2" + quiver: + dependency: transitive + description: + name: quiver + sha256: ea0b925899e64ecdfbf9c7becb60d5b50e706ade44a85b2363be2a22d88117d2 + url: "https://pub.dev" + source: hosted + version: "3.2.2" recase: dependency: transitive description: @@ -909,6 +1098,70 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" + url_launcher: + dependency: transitive + description: + name: url_launcher + sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8 + url: "https://pub.dev" + source: hosted + version: "6.3.2" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + sha256: "17bc677f0b301615530dd1d67e0a9828cafa2d0b6b6eae4cd3679b7eac4a273c" + url: "https://pub.dev" + source: hosted + version: "6.3.30" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + sha256: "580fe5dfb51671ae38191d316e027f6b76272b026370708c2d898799750a02b0" + url: "https://pub.dev" + source: hosted + version: "6.4.1" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a + url: "https://pub.dev" + source: hosted + version: "3.2.2" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18" + url: "https://pub.dev" + source: hosted + version: "3.2.5" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + sha256: "85c81589622fbc87c1c683aaea164d3604a7777495a79d91e39ffcdec39ddb34" + url: "https://pub.dev" + source: hosted + version: "2.4.3" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f" + url: "https://pub.dev" + source: hosted + version: "3.1.5" uuid: dependency: "direct main" description: @@ -969,10 +1222,10 @@ packages: dependency: transitive description: name: win32 - sha256: a1fc9eb9248baa05dfc12ed5b66e377b3e23f095eec078e0371622b9033810d9 + sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e url: "https://pub.dev" source: hosted - version: "6.2.0" + version: "5.15.0" window_manager: dependency: "direct main" description: @@ -1006,5 +1259,5 @@ packages: source: hosted version: "3.1.3" sdks: - dart: ">=3.11.5 <4.0.0" - flutter: ">=3.38.4" + dart: ">=3.12.0 <4.0.0" + flutter: ">=3.44.0" diff --git a/pubspec.yaml b/pubspec.yaml index 4f18275..03a9f45 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: notas description: "A new Flutter project." # The following line prevents the package from being accidentally published to # pub.dev using `flutter pub publish`. This is preferred for private packages. -publish_to: 'none' # Remove this line if you wish to publish to pub.dev +publish_to: "none" # Remove this line if you wish to publish to pub.dev # The following defines the version and build number for your application. # A version number is three numbers separated by dots, like 1.2.43 @@ -48,6 +48,7 @@ dependencies: crypto: ^3.0.6 cryptography: ^2.7.0 uuid: ^4.0.0 + flutter_quill: ^11.5.1 dev_dependencies: flutter_test: @@ -68,7 +69,6 @@ dev_dependencies: # The following section is specific to Flutter packages. flutter: - # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class. @@ -113,27 +113,26 @@ hooks: # For details regarding fonts from package dependencies, # see https://flutter.dev/to/font-from-package - flutter_launcher_icons: # Configuración general y móvil image_path: "assets/icon.png" android: true ios: false - + # Configuración para Windows windows: generate: true image_path: "assets/icon.png" icon_size: 256 # Tamaño máximo requerido por Windows - + # Configuración para Web (Opcional, pero recomendado) web: generate: false image_path: "assets/icon.png" background_color: "#FFFFFF" # Cambia esto al color de fondo de tu app theme_color: "#FFFFFF" - + # Configuración para macOS (Por si en el futuro compilas para Mac) macos: generate: true - image_path: "assets/icon.png" \ No newline at end of file + image_path: "assets/icon.png" diff --git a/test/note_editor_screen_test.dart b/test/note_editor_screen_test.dart index 8e0279d..3e67f53 100644 --- a/test/note_editor_screen_test.dart +++ b/test/note_editor_screen_test.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:flutter_quill/flutter_quill.dart'; import 'package:notas/models/category.dart'; import 'package:notas/models/note.dart'; @@ -13,6 +15,12 @@ void main() { await tester.pumpWidget( MaterialApp( + localizationsDelegates: const >[ + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + FlutterQuillLocalizations.delegate, + ], home: Scaffold( body: NoteEditorScreen( note: null, @@ -55,6 +63,12 @@ void main() { await tester.pumpWidget( MaterialApp( + localizationsDelegates: const >[ + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + FlutterQuillLocalizations.delegate, + ], home: Scaffold( body: NoteEditorScreen( note: null, @@ -78,4 +92,4 @@ void main() { expect(completionCount, 1); }); -} \ No newline at end of file +} diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index d25cfff..cb72c3d 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -6,18 +6,24 @@ #include "generated_plugin_registrant.h" +#include #include #include #include +#include #include void RegisterPlugins(flutter::PluginRegistry* registry) { + FileSelectorWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FileSelectorWindows")); FlutterSecureStorageWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin")); LocalAuthPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("LocalAuthPlugin")); ScreenRetrieverWindowsPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("ScreenRetrieverWindowsPluginCApi")); + UrlLauncherWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("UrlLauncherWindows")); WindowManagerPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("WindowManagerPlugin")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index b2fc4ee..0167b5c 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -3,9 +3,11 @@ # list(APPEND FLUTTER_PLUGIN_LIST + file_selector_windows flutter_secure_storage_windows local_auth_windows screen_retriever_windows + url_launcher_windows window_manager ) diff --git a/windows/runner/resources/app_icon.ico b/windows/runner/resources/app_icon.ico index a83eb75..43f9ad0 100644 Binary files a/windows/runner/resources/app_icon.ico and b/windows/runner/resources/app_icon.ico differ