Skip to content
Open
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
5 changes: 2 additions & 3 deletions lib/bademagic_module/models/speed.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ enum Speed {

// Static method to get int value of speed from the Enum Speed
static int getIntValue(Speed speed) {
String hexValue = speed.hexValue.substring(2, 3);
int intValue = int.parse(hexValue, radix: 10);
return intValue;
// Map Speed.one (index 0) -> 1, Speed.two (index 1) -> 2, etc.
return speed.index + 1;
}

// Static method to get Speed from hex value
Expand Down
109 changes: 109 additions & 0 deletions lib/bademagic_module/utils/badge_text_storage.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import 'dart:convert';
import 'dart:io';

import 'package:badgemagic/bademagic_module/utils/byte_array_utils.dart';
import 'package:path_provider/path_provider.dart';

/// A utility class to store and retrieve the original text of badges
class BadgeTextStorage {
static const String TEXT_STORAGE_FILENAME = 'badge_original_texts.json';

/// Save the original text for a badge
static Future<void> saveOriginalText(
String badgeFilename, String originalText) async {
try {
// Get the existing text storage or create a new one
Map<String, String> textStorage = await _getTextStorage();

// Store the original text with the badge filename as the key
textStorage[badgeFilename] = originalText;

// Save the updated storage
await _saveTextStorage(textStorage);

logger.d('Saved original text for badge: $badgeFilename');
} catch (e) {
logger.e('Error saving original text: $e');
}
}

/// Get the original text for a badge
static Future<String> getOriginalText(String badgeFilename) async {
try {
// Get the existing text storage
Map<String, String> textStorage = await _getTextStorage();

// Return the original text if it exists, otherwise return empty string
return textStorage[badgeFilename] ?? '';
} catch (e) {
logger.e('Error getting original text: $e');
return '';
}
}

/// Delete the original text for a badge
static Future<void> deleteOriginalText(String badgeFilename) async {
try {
// Get the existing text storage
Map<String, String> textStorage = await _getTextStorage();

// Remove the entry for the badge
textStorage.remove(badgeFilename);

// Save the updated storage
await _saveTextStorage(textStorage);

logger.d('Deleted original text for badge: $badgeFilename');
} catch (e) {
logger.e('Error deleting original text: $e');
}
}

/// Get the text storage file
static Future<Map<String, String>> _getTextStorage() async {
try {
final directory = await getApplicationDocumentsDirectory();
final file = File('${directory.path}/$TEXT_STORAGE_FILENAME');

// Create the file if it doesn't exist
if (!await file.exists()) {
await file.create();
await file.writeAsString('{}');
return {};
}

// Read the file and parse the JSON
final jsonString = await file.readAsString();
if (jsonString.isEmpty) {
return {};
}

final Map<String, dynamic> jsonData = jsonDecode(jsonString);

// Convert dynamic values to String
final Map<String, String> textStorage = {};
jsonData.forEach((key, value) {
textStorage[key] = value.toString();
});

return textStorage;
} catch (e) {
logger.e('Error getting text storage: $e');
return {};
}
}

/// Save the text storage to file
static Future<void> _saveTextStorage(Map<String, String> textStorage) async {
try {
final directory = await getApplicationDocumentsDirectory();
final file = File('${directory.path}/$TEXT_STORAGE_FILENAME');

// Convert the map to JSON and save it
final jsonString = jsonEncode(textStorage);
await file.writeAsString(jsonString);
} catch (e) {
logger.e('Error saving text storage: $e');
}
}
}
51 changes: 46 additions & 5 deletions lib/bademagic_module/utils/file_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,22 @@ class FileHelper {
// Save JSON string to the file
File file = File(filePath);
await file.writeAsString(jsonString);
imageCacheProvider.savedBadgeCache
.add(MapEntry("$filename.json", jsonData));

// Update the cache properly - check if the badge already exists in the cache
final cacheKey = "$filename.json";
final cache = imageCacheProvider.savedBadgeCache;
final existingIndex = cache.indexWhere((entry) => entry.key == cacheKey);

if (existingIndex >= 0) {
// Replace the existing entry in the cache
logger.i('Updating existing badge in cache: $cacheKey');
cache[existingIndex] = MapEntry(cacheKey, jsonData);
} else {
// Add as a new entry if it doesn't exist
logger.i('Adding new badge to cache: $cacheKey');
cache.add(MapEntry(cacheKey, jsonData));
}

logger.i('Data saved to $filePath');
} catch (e) {
logger.i('Error saving data: $e');
Expand Down Expand Up @@ -315,9 +329,36 @@ class FileHelper {

//function that takes JsonSData and returns the Data object
Data jsonToData(Map<String, dynamic> jsonData) {
// Convert JSON data to Data object
Data data = Data.fromJson(jsonData);
return data;
try {
// Convert JSON data to Data object
Data data = Data.fromJson(jsonData);
return data;
} catch (e) {
// If there's an error with the 'messages' key missing, add it with default values
if (e.toString().contains("Missing \"messages\" key")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Fragile error message string matching in jsonToData

Instead of matching error strings, check if 'messages' exists in jsonData before calling Data.fromJson, or catch a more specific exception if possible.

logger.w('Fixing missing "messages" key in badge data');

// Create a default message structure if missing
Comment on lines +332 to +341
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): jsonToData may mask data issues by auto-fixing missing keys.

Log a warning or error when default values are used, and notify the UI or user about potentially incomplete badge data.

Map<String, dynamic> fixedJsonData =
Map<String, dynamic>.from(jsonData);
fixedJsonData['messages'] = [
{
'text': jsonData['text'] ?? ['00'],
'flash': jsonData['flash'] ?? false,
'marquee': jsonData['marquee'] ?? false,
'speed': jsonData['speed'] ?? '0x70', // Default to Speed.one
'mode': jsonData['mode'] ?? '0x00', // Default to Mode.left
'invert': jsonData['invert'] ?? false
}
];

return Data.fromJson(fixedJsonData);
} else {
// For other errors, rethrow
logger.e('Error parsing badge data: $e');
rethrow;
}
}
}

Future<void> shareBadgeData(String filename) async {
Expand Down
Loading