Skip to content

Commit

Permalink
refactor: introduce datasource abstraction layer
Browse files Browse the repository at this point in the history
  • Loading branch information
Ascenio committed May 7, 2024
1 parent fc7c5d4 commit 0b246fe
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 63 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import 'package:nasa_potday/features/picture_of_the_day/domain/entities/pictures_page_entity.dart';

abstract interface class NasaDataSource {
Future<PicturesPageEntity> loadPictureOfTheDay({
required DateTime startDate,
});

Future<PicturesPageEntity> loadNextPage({
required DateTime currentStartDate,
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import 'dart:convert';

import 'package:flutter/foundation.dart';
import 'package:http/http.dart';
import 'package:nasa_potday/features/picture_of_the_day/data/datasources/nasa_datasource.dart';
import 'package:nasa_potday/features/picture_of_the_day/data/models/load_picture_of_the_day_request_model.dart';
import 'package:nasa_potday/features/picture_of_the_day/data/models/picture_model.dart';
import 'package:nasa_potday/features/picture_of_the_day/domain/entities/pictures_page_entity.dart';

final class RemoteNasaDataSource implements NasaDataSource {
const RemoteNasaDataSource({
required this.baseUrl,
required this.apiKey,
});

final String baseUrl;
final String apiKey;

@override
Future<PicturesPageEntity> loadPictureOfTheDay({
required DateTime startDate,
}) async {
try {
final pictures = await _request(
LoadPictureOfTheDayRequestModel(
apiKey: apiKey,
startDate: startDate,
),
);
return PicturesPageEntity(
pictures: pictures,
startDate: startDate,
);
} catch (error) {
debugPrint('Could not load picture of the day: $error');
}
return PicturesPageEntity(
pictures: [],
startDate: startDate,
);
}

@override
Future<PicturesPageEntity> loadNextPage({
required DateTime currentStartDate,
}) async {
final newStartDate = currentStartDate.subtract(const Duration(days: 7));
try {
final pictures = await _request(
LoadPictureOfTheDayRequestModel(
apiKey: apiKey,
startDate: newStartDate,
endDate: currentStartDate.subtract(const Duration(days: 1)),
),
);
return PicturesPageEntity(pictures: pictures, startDate: newStartDate);
} catch (error) {
debugPrint('Could not load picture of the day: $error');
}
return PicturesPageEntity(
pictures: [],
startDate: newStartDate,
);
}

Future<List<PictureModel>> _request(
LoadPictureOfTheDayRequestModel request) async {
final uri = Uri.parse(baseUrl).replace(
queryParameters: request.toJson(),
);
final response = await get(uri);
return (jsonDecode(response.body) as List)
.cast<Map<String, dynamic>>()
.map(PictureModel.fromJson)
.toList()
.reversed
.toList();
}
}
Original file line number Diff line number Diff line change
@@ -1,79 +1,25 @@
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:nasa_potday/features/picture_of_the_day/data/models/load_picture_of_the_day_request_model.dart';
import 'package:nasa_potday/features/picture_of_the_day/data/models/picture_model.dart';
import 'package:nasa_potday/features/picture_of_the_day/data/datasources/remote_nasa_datasource.dart';
import 'package:nasa_potday/features/picture_of_the_day/domain/entities/pictures_page_entity.dart';
import 'package:nasa_potday/features/picture_of_the_day/domain/repositories/nasa_repository.dart';

class RemoteNasaRepository implements NasaRepository {
RemoteNasaRepository({
required this.baseUrl,
required this.apiKey,
required this.remoteDatasource,
});

final String baseUrl;
final String apiKey;
final RemoteNasaDataSource remoteDatasource;

@override
Future<PicturesPageEntity> loadPictureOfTheDay({
required DateTime startDate,
}) async {
try {
final pictures = await _request(
LoadPictureOfTheDayRequestModel(
apiKey: apiKey,
startDate: startDate,
),
);
return PicturesPageEntity(
pictures: pictures,
startDate: startDate,
);
} catch (error) {
debugPrint('Could not load picture of the day: $error');
}
return PicturesPageEntity(
pictures: [],
startDate: startDate,
);
}) {
return remoteDatasource.loadPictureOfTheDay(startDate: startDate);
}

@override
Future<PicturesPageEntity> loadNextPage({
required DateTime currentStartDate,
}) async {
final newStartDate = currentStartDate.subtract(const Duration(days: 7));
try {
final pictures = await _request(
LoadPictureOfTheDayRequestModel(
apiKey: apiKey,
startDate: newStartDate,
endDate: currentStartDate.subtract(const Duration(days: 1)),
),
);
return PicturesPageEntity(pictures: pictures, startDate: newStartDate);
} catch (error) {
debugPrint('Could not load picture of the day: $error');
}
return PicturesPageEntity(
pictures: [],
startDate: newStartDate,
);
}

Future<List<PictureModel>> _request(
LoadPictureOfTheDayRequestModel request) async {
final uri = Uri.parse(baseUrl).replace(
queryParameters: request.toJson(),
);
final response = await get(uri);
return (jsonDecode(response.body) as List)
.cast<Map<String, dynamic>>()
.map(PictureModel.fromJson)
.toList()
.reversed
.toList();
}) {
return remoteDatasource.loadNextPage(currentStartDate: currentStartDate);
}
}
7 changes: 5 additions & 2 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:nasa_potday/features/picture_of_the_day/data/datasources/remote_nasa_datasource.dart';
import 'package:nasa_potday/features/picture_of_the_day/data/repositories/remote_nasa_repository.dart';
import 'package:nasa_potday/features/picture_of_the_day/presentation/cubits/picture_of_the_day/picture_of_the_day_cubit.dart';
import 'package:nasa_potday/features/picture_of_the_day/presentation/pages/picture_of_the_day_page.dart';
Expand All @@ -22,8 +23,10 @@ class _MainAppState extends State<MainApp> {
home: BlocProvider(
create: (_) => PictureOfTheDayCubit(
nasaRepository: RemoteNasaRepository(
baseUrl: const String.fromEnvironment('BASE_URL'),
apiKey: const String.fromEnvironment('API_KEY'),
remoteDatasource: const RemoteNasaDataSource(
baseUrl: String.fromEnvironment('BASE_URL'),
apiKey: String.fromEnvironment('API_KEY'),
),
),
),
child: const PictureOfTheDayPage(),
Expand Down

0 comments on commit 0b246fe

Please sign in to comment.