doc(arch): add fully featured example
This commit is contained in:
+52
@@ -0,0 +1,52 @@
|
||||
// Copyright (C) 2022 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'package:architecture_example/core/constants/hive_boxes.dart';
|
||||
import 'package:architecture_example/domain/data_sources/local/favorite_local_data_source.dart';
|
||||
import 'package:architecture_example/domain/entities/photo.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
|
||||
class FavoriteHiveDataSource extends FavoriteLocalDataSource {
|
||||
@override
|
||||
Future<void> addPhotoToFavorites(Photo photo) async {
|
||||
final box = await Hive.openBox<bool>(HiveBoxes.favorites);
|
||||
if (box.containsKey(photo.id)) {
|
||||
throw Exception('Photo already in favorites');
|
||||
}
|
||||
await box.put(photo.id, true);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> checkIfPhotoIsInFavorites(int id) async {
|
||||
final box = await Hive.openBox<bool>(HiveBoxes.favorites);
|
||||
return box.containsKey(id);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> deletePhotoFromFavorites(int id) async {
|
||||
final box = await Hive.openBox<bool>(HiveBoxes.favorites);
|
||||
if (!box.containsKey(id)) {
|
||||
throw Exception('Unknown photo');
|
||||
}
|
||||
await box.delete(id);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<int>> getAllPhotosFromFavorites() async {
|
||||
final box = await Hive.openBox<bool>(HiveBoxes.favorites);
|
||||
return box.keys.cast<int>().toList();
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
// Copyright (C) 2022 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'package:architecture_example/data/models/photo_model.dart';
|
||||
import 'package:architecture_example/domain/data_sources/local/favorite_local_data_source.dart';
|
||||
import 'package:architecture_example/domain/entities/photo.dart';
|
||||
|
||||
class FavoriteMockDataSource extends FavoriteLocalDataSource {
|
||||
final Map<int, Photo> _mock = {
|
||||
2: const PhotoModel(
|
||||
albumId: 1,
|
||||
id: 2,
|
||||
title: 'Photo 2',
|
||||
url: 'https://via.placeholder.com/600/771796',
|
||||
thumbnailUrl: 'https://via.placeholder.com/150/771796',
|
||||
),
|
||||
};
|
||||
|
||||
@override
|
||||
Future<void> addPhotoToFavorites(Photo photo) async {
|
||||
if (_mock.containsKey(photo.id)) {
|
||||
throw Exception('Photo already in favorites');
|
||||
}
|
||||
_mock.putIfAbsent(photo.id, () => photo);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> checkIfPhotoIsInFavorites(int id) async => _mock.containsKey(id);
|
||||
|
||||
@override
|
||||
Future<void> deletePhotoFromFavorites(int id) async {
|
||||
if (!_mock.containsKey(id)) {
|
||||
throw Exception('Unknown photo');
|
||||
}
|
||||
_mock.remove(id);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<int>> getAllPhotosFromFavorites() async {
|
||||
final result = _mock.keys;
|
||||
return result.toList();
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
// Copyright (C) 2022 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:architecture_example/data/models/album_model.dart';
|
||||
import 'package:architecture_example/data/models/list_album_model.dart';
|
||||
import 'package:architecture_example/domain/data_sources/remote/album_remote_data_source.dart';
|
||||
import 'package:architecture_example/domain/entities/album.dart';
|
||||
import 'package:wyatt_http_client/wyatt_http_client.dart';
|
||||
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
|
||||
|
||||
class AlbumApiDataSourceImpl extends AlbumRemoteDataSource {
|
||||
final MiddlewareClient _client;
|
||||
|
||||
AlbumApiDataSourceImpl(this._client);
|
||||
|
||||
@override
|
||||
Future<Album> getAlbum(int id) async {
|
||||
final response = await _client.get(Uri.parse('/albums/$id'));
|
||||
final album =
|
||||
AlbumModel.fromJson(jsonDecode(response.body) as Map<String, Object?>);
|
||||
return album;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<Album>> getAllAlbums({int? start, int? limit}) async {
|
||||
final startQuery = start.isNotNull ? '_start=$start' : '';
|
||||
final limitQuery = limit.isNotNull ? '_limit=$limit' : '';
|
||||
final delimiter1 =
|
||||
(startQuery.isNotEmpty || limitQuery.isNotEmpty) ? '?' : '';
|
||||
final delimiter2 =
|
||||
(startQuery.isNotEmpty && limitQuery.isNotEmpty) ? '&' : '';
|
||||
final url = '/albums$delimiter1$startQuery$delimiter2$limitQuery';
|
||||
final response = await _client.get(Uri.parse(url));
|
||||
final albums =
|
||||
ListAlbumModel.fromJson({'albums': jsonDecode(response.body)});
|
||||
return albums.albums;
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
// Copyright (C) 2022 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'package:architecture_example/data/models/album_model.dart';
|
||||
import 'package:architecture_example/domain/data_sources/remote/album_remote_data_source.dart';
|
||||
import 'package:architecture_example/domain/entities/album.dart';
|
||||
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
|
||||
|
||||
class AlbumMockDataSourceImpl extends AlbumRemoteDataSource {
|
||||
final Map<int, Album> _mock = {
|
||||
1: const AlbumModel(
|
||||
id: 1,
|
||||
userId: 1,
|
||||
title: 'Album 1',
|
||||
)
|
||||
};
|
||||
|
||||
@override
|
||||
Future<Album> getAlbum(int id) async {
|
||||
final response = _mock[id];
|
||||
if (response.isNull) {
|
||||
throw Exception('Unknown album');
|
||||
}
|
||||
return response!;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<Album>> getAllAlbums({int? start, int? limit}) async {
|
||||
final response = _mock.values;
|
||||
final nullableEnd = (limit != null) ? start ?? 0 + limit : null;
|
||||
return response.toList().sublist(start ?? 0, nullableEnd);
|
||||
}
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
// Copyright (C) 2022 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:architecture_example/data/models/list_photo_model.dart';
|
||||
import 'package:architecture_example/data/models/photo_model.dart';
|
||||
import 'package:architecture_example/domain/data_sources/remote/photo_remote_data_source.dart';
|
||||
import 'package:architecture_example/domain/entities/photo.dart';
|
||||
import 'package:wyatt_http_client/wyatt_http_client.dart';
|
||||
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
|
||||
|
||||
class PhotoApiDataSourceImpl extends PhotoRemoteDataSource {
|
||||
final MiddlewareClient _client;
|
||||
|
||||
PhotoApiDataSourceImpl(this._client);
|
||||
|
||||
@override
|
||||
Future<Photo> getPhoto(int id) async {
|
||||
final response = await _client.get(Uri.parse('/photos/$id'));
|
||||
final photo =
|
||||
PhotoModel.fromJson(jsonDecode(response.body) as Map<String, Object?>);
|
||||
return photo;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<Photo>> getAllPhotos({int? start, int? limit}) async {
|
||||
final startQuery = start.isNotNull ? '_start=$start' : '';
|
||||
final limitQuery = limit.isNotNull ? '_limit=$limit' : '';
|
||||
final delimiter1 =
|
||||
(startQuery.isNotEmpty || limitQuery.isNotEmpty) ? '?' : '';
|
||||
final delimiter2 =
|
||||
(startQuery.isNotEmpty && limitQuery.isNotEmpty) ? '&' : '';
|
||||
final url = '/photos$delimiter1$startQuery$delimiter2$limitQuery';
|
||||
final response = await _client.get(Uri.parse(url));
|
||||
final photos =
|
||||
ListPhotoModel.fromJson({'photos': jsonDecode(response.body)});
|
||||
return photos.photos;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<Photo>> getPhotosFromAlbum(
|
||||
int albumId, {
|
||||
int? start,
|
||||
int? limit,
|
||||
}) async {
|
||||
final startQuery = start.isNotNull ? '_start=$start' : '';
|
||||
final limitQuery = limit.isNotNull ? '_limit=$limit' : '';
|
||||
final delimiter =
|
||||
(startQuery.isNotEmpty && limitQuery.isNotEmpty) ? '&' : '';
|
||||
final url = '/photos?albumId=$albumId&$startQuery$delimiter$limitQuery';
|
||||
final response = await _client.get(Uri.parse(url));
|
||||
final photos =
|
||||
ListPhotoModel.fromJson({'photos': jsonDecode(response.body)});
|
||||
return photos.photos;
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
// Copyright (C) 2022 WYATT GROUP
|
||||
// Please see the AUTHORS file for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'package:architecture_example/data/models/photo_model.dart';
|
||||
import 'package:architecture_example/domain/data_sources/remote/photo_remote_data_source.dart';
|
||||
import 'package:architecture_example/domain/entities/photo.dart';
|
||||
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
|
||||
|
||||
class PhotoMockDataSourceImpl extends PhotoRemoteDataSource {
|
||||
final Map<int, Photo> _mock = {
|
||||
1: const PhotoModel(
|
||||
albumId: 1,
|
||||
id: 1,
|
||||
title: 'Photo 1',
|
||||
url: 'https://via.placeholder.com/600/92c952',
|
||||
thumbnailUrl: 'https://via.placeholder.com/150/92c952',
|
||||
),
|
||||
2: const PhotoModel(
|
||||
albumId: 1,
|
||||
id: 2,
|
||||
title: 'Photo 2',
|
||||
url: 'https://via.placeholder.com/600/771796',
|
||||
thumbnailUrl: 'https://via.placeholder.com/150/771796',
|
||||
),
|
||||
};
|
||||
|
||||
@override
|
||||
Future<Photo> getPhoto(int id) async {
|
||||
final response = _mock[id];
|
||||
if (response.isNull) {
|
||||
throw Exception('Unknown photo');
|
||||
}
|
||||
return response!;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<Photo>> getAllPhotos({int? start, int? limit}) async {
|
||||
final response = _mock.values;
|
||||
final nullableEnd = (limit != null) ? start ?? 0 + limit : null;
|
||||
return response.toList().sublist(start ?? 0, nullableEnd);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<Photo>> getPhotosFromAlbum(
|
||||
int albumId, {
|
||||
int? start,
|
||||
int? limit,
|
||||
}) async {
|
||||
// TODO(hpcl): use start and limit
|
||||
final response = _mock.values
|
||||
..where((element) => element.albumId == albumId);
|
||||
return response.toList();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user