Skip to content

Commit

Permalink
feat: Added the delete badge and import saved badge functionality. (#…
Browse files Browse the repository at this point in the history
…1047)

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Loading branch information
Jhalakupadhyay and dependabot[bot] authored Oct 20, 2024
1 parent 56aee1b commit 221308b
Show file tree
Hide file tree
Showing 9 changed files with 313 additions and 10 deletions.
24 changes: 24 additions & 0 deletions assets/icons/empty_badge.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
63 changes: 63 additions & 0 deletions lib/bademagic_module/utils/file_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import 'package:badgemagic/bademagic_module/models/data.dart';
import 'package:badgemagic/bademagic_module/utils/byte_array_utils.dart';
import 'package:badgemagic/bademagic_module/utils/image_utils.dart';
import 'package:badgemagic/providers/imageprovider.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get_it/get_it.dart';
import 'package:path_provider/path_provider.dart';
Expand Down Expand Up @@ -277,4 +279,65 @@ class FileHelper {
logger.i('Error sharing file: $e');
}
}

Future<void> deleteFile(String filename) async {
try {
final directory = await getApplicationDocumentsDirectory();
final filePath = '${directory.path}/$filename';

File file = File(filePath);
if (await file.exists()) {
await file.delete();
logger.i('File deleted: $filePath');
} else {
logger.i('File not found: $filePath');
}
} catch (e) {
logger.i('Error deleting file: $e');
}
}

Future<bool> importBadgeData(context) async {
try {
// Open file picker to select a JSON file
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['json'], // Only allow JSON files
);

if (result != null && result.files.isNotEmpty) {
// Get the selected file
File file = File(result.files.single.path!);

// Read the content of the file
String jsonContent = await file.readAsString();

// Parse the JSON data
Map<String, dynamic> importedBadge = jsonDecode(jsonContent);
logger.d('Imported badge: $importedBadge');
// Validate the structure of the JSON if necessary
if (importedBadge.containsKey('messages')) {
// Save the imported badge file to your application's directory
final directory = await getApplicationDocumentsDirectory();
final filePath = '${directory.path}/${result.files.single.name}';
logger.d('Importing badge to: $filePath');
File newFile = File(filePath);
await newFile.writeAsString(jsonContent);
return true;
} else {
throw Exception("Invalid Badge Data");
}
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('No file selected')),
);
return false;
}
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error importing badge: $e')),
);
return false;
}
}
}
71 changes: 65 additions & 6 deletions lib/view/save_badge_screen.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import 'package:badgemagic/bademagic_module/utils/byte_array_utils.dart';
import 'package:badgemagic/bademagic_module/utils/file_helper.dart';
import 'package:badgemagic/bademagic_module/utils/toast_utils.dart';
import 'package:badgemagic/constants.dart';
import 'package:badgemagic/providers/badgeview_provider.dart';
import 'package:badgemagic/view/widgets/common_scaffold_widget.dart';
import 'package:badgemagic/view/widgets/saved_badge_listview.dart';
import 'package:badgemagic/virtualbadge/view/saved_badge_view.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get_it/get_it.dart';

class SaveBadgeScreen extends StatefulWidget {
const SaveBadgeScreen({super.key});
Expand All @@ -14,43 +21,95 @@ class SaveBadgeScreen extends StatefulWidget {

class _SaveBadgeScreenState extends State<SaveBadgeScreen> {
List<MapEntry<String, Map<String, dynamic>>> badgeData = [];
DrawBadgeProvider drawBadgeProvider = GetIt.instance<DrawBadgeProvider>();
ToastUtils toastUtils = ToastUtils();
FileHelper fileHelper = FileHelper();

@override
void initState() {
super.initState();
loadSavedBadges();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
DeviceOrientation.landscapeLeft,
DeviceOrientation.landscapeRight,
]);
// Set a new 2D array to store the badge data with all false
drawBadgeProvider.setNewGrid(
List.generate(11, (index) => List.generate(44, (index) => false)),
true);
}

void loadSavedBadges() async {
// Method to load saved badges and refresh the list
Future<void> loadSavedBadges() async {
var data = await fileHelper.getBadgeDataFiles();
setState(() {
badgeData = data;
});
}

FileHelper fileHelper = FileHelper();
@override
Widget build(BuildContext context) {
return CommonScaffold(
actions: [
TextButton(
onPressed: () {},
onPressed: () {
fileHelper.importBadgeData(context).then((value) {
if (value) {
logger.d('value: $value');
toastUtils.showToast('Badge imported successfully');
loadSavedBadges();
}
});
},
child: const Text(
'Import',
style: TextStyle(color: Colors.white),
))
],
body: badgeData.isEmpty
? const Text("No data Available")
? Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.only(left: 50.0.w),
child: SvgPicture.asset(
'assets/icons/empty_badge.svg',
height: 200.h,
),
),
SizedBox(
height: 20.h,
),
Text(
'No saved badges !',
style: TextStyle(
color: Colors.black,
fontSize: 20.sp,
),
),
Text(
'Looks like there are no saved badges yet.',
style: TextStyle(
color: Colors.black,
fontSize: 14.sp,
),
),
],
),
)
: Column(
children: [
SavedBadgeView(),
BadgeListView(
futureBadges: fileHelper.getBadgeDataFiles(), // Fetch badges
futureBadges: Future.value(badgeData),
refreshBadgesCallback: loadSavedBadges, // Pass the callback
),
],
),
title: 'Bade Magic',
title: 'Badge Magic',
key: const Key(drawBadgeScreen),
);
}
Expand Down
21 changes: 21 additions & 0 deletions lib/view/saved_clipart.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import 'package:badgemagic/view/widgets/common_scaffold_widget.dart';
import 'package:flutter/material.dart';

class SavedClipart extends StatefulWidget {
const SavedClipart({super.key});

@override
State<SavedClipart> createState() => _SavedClipartState();
}

class _SavedClipartState extends State<SavedClipart> {
@override
Widget build(BuildContext context) {
return CommonScaffold(
body: Column(
children: [],
),
title: '',
);
}
}
88 changes: 88 additions & 0 deletions lib/view/widgets/badge_delete_dialog.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';

class DeleteBadgeDialog extends StatelessWidget {
const DeleteBadgeDialog({
super.key,
});

@override
Widget build(BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.r),
),
child: Container(
height: 110.h,
width: 300.w,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5.r),
),
child: Column(
children: [
SizedBox(
height: 10.h,
),
Row(
children: [
SizedBox(
width: 20,
),
Icon(Icons.delete, color: Colors.black),
SizedBox(
width: 10,
),
Text(
'Delete',
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w500,
),
),
],
),
SizedBox(
height: 7.h,
),
Row(
children: [
SizedBox(
width: 20,
),
Text('Are you sure want to delete this badge?',
style: TextStyle(fontSize: 14.sp)),
],
),
SizedBox(
height: 10.h,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () {
Navigator.of(context).pop(false);
},
child: const Text(
'Cancel',
style: TextStyle(color: Colors.red),
),
),
TextButton(
onPressed: () {
Navigator.of(context).pop(true);
},
child: const Text(
'OK',
style: TextStyle(color: Colors.red),
),
),
],
),
],
),
),
);
}
}
25 changes: 24 additions & 1 deletion lib/view/widgets/save_badge_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,21 @@ import 'package:badgemagic/providers/badge_message_provider.dart';
import 'package:badgemagic/providers/badgeview_provider.dart';
import 'package:badgemagic/providers/cardsprovider.dart';
import 'package:badgemagic/view/draw_badge_screen.dart';
import 'package:badgemagic/view/widgets/badge_delete_dialog.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:provider/provider.dart';

class SaveBadgeCard extends StatelessWidget {
final MapEntry<String, Map<String, dynamic>> badgeData;
final Future<void> Function() refreshBadgesCallback;
final FileHelper file = FileHelper();
final Converters converters = Converters();

SaveBadgeCard({
super.key,
required this.badgeData,
required this.refreshBadgesCallback,
});

@override
Expand Down Expand Up @@ -126,7 +130,17 @@ class SaveBadgeCard extends StatelessWidget {
Icons.delete,
color: Colors.black,
),
onPressed: () {},
onPressed: () async {
// file.deleteFile(badgeData.key);
// refreshBadgesCallback();
//add a dialog for confirmation before deleting
await _showDeleteDialog(context).then((value) async {
if (value == true) {
file.deleteFile(badgeData.key);
await refreshBadgesCallback();
}
});
},
),
],
),
Expand Down Expand Up @@ -272,4 +286,13 @@ class SaveBadgeCard extends StatelessWidget {
),
);
}

Future<bool> _showDeleteDialog(BuildContext context) async {
return await showDialog(
context: context,
builder: (BuildContext context) {
return DeleteBadgeDialog();
},
);
}
}
Loading

0 comments on commit 221308b

Please sign in to comment.