feat: Optimize note encryption and decryption processes with parallel execution

This commit is contained in:
2026-05-19 10:09:20 +02:00
parent 9769087fd8
commit 2a898111fa
3 changed files with 316 additions and 74 deletions
+45 -23
View File
@@ -1,13 +1,12 @@
import 'package:notas/models/note.dart';
import 'package:notas/models/category.dart';
import 'dart:convert';
// DTOs para sincronización con el servidor
class SyncRequest {
SyncRequest({
DateTime? lastSyncAt,
required this.changes,
}) : lastSyncAt = lastSyncAt ?? DateTime.utc(1970, 1, 1);
SyncRequest({DateTime? lastSyncAt, required this.changes})
: lastSyncAt = lastSyncAt ?? DateTime.utc(1970, 1, 1);
final DateTime lastSyncAt;
final SyncChanges changes;
@@ -21,10 +20,7 @@ class SyncRequest {
}
class SyncChanges {
const SyncChanges({
this.categories = const [],
this.notes = const [],
});
const SyncChanges({this.categories = const [], this.notes = const []});
final List<SyncCategoryPayload> categories;
final List<SyncNotePayload> notes;
@@ -33,8 +29,7 @@ class SyncChanges {
return {
if (categories.isNotEmpty)
'categories': categories.map((c) => c.toJson()).toList(),
if (notes.isNotEmpty)
'notes': notes.map((n) => n.toJson()).toList(),
if (notes.isNotEmpty) 'notes': notes.map((n) => n.toJson()).toList(),
};
}
}
@@ -49,7 +44,8 @@ class SyncChangesResponse {
final List<SyncNoteResponse> notes;
factory SyncChangesResponse.fromJson(Map<String, dynamic> json) {
final List<dynamic> categoriesJson = json['categories'] as List<dynamic>? ?? [];
final List<dynamic> categoriesJson =
json['categories'] as List<dynamic>? ?? [];
final List<dynamic> notesJson = json['notes'] as List<dynamic>? ?? [];
return SyncChangesResponse(
@@ -62,6 +58,30 @@ class SyncChangesResponse {
);
}
}
String _readStringValue(dynamic value) {
if (value is String) {
return value;
}
if (value == null) {
throw FormatException('Expected String value but found null');
}
return jsonEncode(value);
}
int _readIntValue(dynamic value) {
if (value is int) {
return value;
}
if (value is String) {
final int? parsed = int.tryParse(value);
if (parsed != null) {
return parsed;
}
}
throw FormatException('Expected int value but found $value');
}
class SyncCategoryPayload {
const SyncCategoryPayload({
required this.id,
@@ -163,11 +183,11 @@ class SyncResponse {
factory SyncResponse.fromJson(Map<String, dynamic> json) {
return SyncResponse(
serverTimestamp:
DateTime.parse(json['serverTimestamp'] as String),
serverTimestamp: DateTime.parse(json['serverTimestamp'] as String),
synced: json['synced'] as bool? ?? false,
changes: SyncChangesResponse.fromJson(
json['changes'] as Map<String, dynamic>? ?? {}),
changes: SyncChangesResponse.fromJson(
json['changes'] as Map<String, dynamic>? ?? {},
),
);
}
}
@@ -189,9 +209,9 @@ class SyncCategoryResponse {
factory SyncCategoryResponse.fromJson(Map<String, dynamic> json) {
return SyncCategoryResponse(
id: json['id'] as String,
encryptedName: json['encrypted_name'] as String,
serverVersion: json['serverVersion'] as int,
id: _readStringValue(json['id']),
encryptedName: _readStringValue(json['encrypted_name']),
serverVersion: _readIntValue(json['serverVersion']),
isDeleted: json['isDeleted'] as bool? ?? false,
updatedAt: DateTime.parse(json['updatedAt'] as String),
);
@@ -231,11 +251,13 @@ class SyncNoteResponse {
factory SyncNoteResponse.fromJson(Map<String, dynamic> json) {
return SyncNoteResponse(
id: json['id'] as String,
categoryId: json['categoryId'] as String?,
encryptedTitle: json['encrypted_title'] as String,
encryptedBody: json['encrypted_body'] as String,
serverVersion: json['serverVersion'] as int,
id: _readStringValue(json['id']),
categoryId: json['categoryId'] == null
? null
: _readStringValue(json['categoryId']),
encryptedTitle: _readStringValue(json['encrypted_title']),
encryptedBody: _readStringValue(json['encrypted_body']),
serverVersion: _readIntValue(json['serverVersion']),
position: json['position'] as int? ?? 0,
isDeleted: json['isDeleted'] as bool? ?? false,
updatedAt: DateTime.parse(json['updatedAt'] as String),