|
| 1 | +import 'dart:convert'; |
| 2 | +import 'dart:io'; |
| 3 | + |
| 4 | +import 'package:injectable/injectable.dart'; |
| 5 | +import 'package:mibook/layers/data/api/custom_errors.dart'; |
| 6 | +import 'package:mibook/layers/data/models/reading_data.dart'; |
| 7 | +import 'package:path_provider/path_provider.dart'; |
| 8 | + |
| 9 | +abstract class IStorageClient { |
| 10 | + Future<void> saveReading(ReadingData readingData); |
| 11 | + Future<List<ReadingData>> getReadingList(); |
| 12 | +} |
| 13 | + |
| 14 | +@Singleton(as: IStorageClient) |
| 15 | +class StorageClient implements IStorageClient { |
| 16 | + Future<File> _getLocalFile(String fileName) async { |
| 17 | + final directory = await getApplicationDocumentsDirectory(); |
| 18 | + return File('${directory.path}/$fileName.json'); |
| 19 | + } |
| 20 | + |
| 21 | + @override |
| 22 | + Future<void> saveReading(ReadingData readingData) async { |
| 23 | + final file = await _getLocalFile('reading_list'); |
| 24 | + List<ReadingData> currentList = await getReadingList(); |
| 25 | + |
| 26 | + if (currentList.any((item) => item.bookId == readingData.bookId)) { |
| 27 | + throw DuplicatedReadingError(); |
| 28 | + } |
| 29 | + currentList.add(readingData); |
| 30 | + final jsonString = jsonEncode(currentList.map((e) => e.toJson()).toList()); |
| 31 | + await file.writeAsString(jsonString); |
| 32 | + } |
| 33 | + |
| 34 | + @override |
| 35 | + Future<List<ReadingData>> getReadingList() async { |
| 36 | + final file = await _getLocalFile('reading_list'); |
| 37 | + |
| 38 | + if (!await file.exists()) { |
| 39 | + return []; |
| 40 | + } |
| 41 | + |
| 42 | + final jsonString = await file.readAsString(); |
| 43 | + |
| 44 | + if (jsonString.isEmpty) { |
| 45 | + return []; |
| 46 | + } |
| 47 | + |
| 48 | + final List<dynamic> decoded = jsonDecode(jsonString); |
| 49 | + return decoded.map((e) => ReadingData.fromJson(e)).toList(); |
| 50 | + } |
| 51 | +} |
0 commit comments