Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#31] [#64] [Integrate] As a logged-in user, I can see the survey list on the Home screen #65

Merged
merged 6 commits into from
Aug 24, 2023
Merged
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
Binary file removed assets/images/dummy_background.png
Binary file not shown.
Binary file added assets/images/placeholder.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ PODS:
- Flutter
- package_info_plus (0.4.5):
- Flutter
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- permission_handler_apple (9.1.1):
- Flutter

Expand All @@ -17,6 +20,7 @@ DEPENDENCIES:
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
- integration_test (from `.symlinks/plugins/integration_test/ios`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)

EXTERNAL SOURCES:
Expand All @@ -30,6 +34,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/integration_test/ios"
package_info_plus:
:path: ".symlinks/plugins/package_info_plus/ios"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin"
permission_handler_apple:
:path: ".symlinks/plugins/permission_handler_apple/ios"

Expand All @@ -39,6 +45,7 @@ SPEC CHECKSUMS:
flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
integration_test: 13825b8a9334a850581300559b8839134b124670
package_info_plus: fd030dabf36271f146f1f3beacd48f564b0f17f7
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6

PODFILE CHECKSUM: 632d6ac0b577d6e268ff7a13a105bbc4f7941989
Expand Down
4 changes: 2 additions & 2 deletions lib/api/data_sources/token_data_source.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ class TokenDataSourceImpl extends TokenDataSource {
return apiToken;
}

return await _secureStorage.getValue(key: SecureStorageKey.apiToken)
as ApiToken;
return await _secureStorage.getValue<ApiToken>(
key: SecureStorageKey.apiToken);
}

@override
Expand Down
7 changes: 4 additions & 3 deletions lib/api/response_decoder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

class ResponseDecoder {
static Map<String, dynamic> decodeData(Map<String, dynamic> json) {
return Japx.decode(json)['data'];
return json.containsKey('data') ? Japx.decode(json)['data'] : json;

Check warning on line 5 in lib/api/response_decoder.dart

View check run for this annotation

Codecov / codecov/patch

lib/api/response_decoder.dart#L5

Added line #L5 was not covered by tests
}

static Map<String, dynamic> decode(Map<String, dynamic> json) =>
Japx.decode(json);
static Map<String, dynamic> decode(Map<String, dynamic> json) {
return Japx.decode(json);

Check warning on line 9 in lib/api/response_decoder.dart

View check run for this annotation

Codecov / codecov/patch

lib/api/response_decoder.dart#L8-L9

Added lines #L8 - L9 were not covered by tests
}
}
3 changes: 2 additions & 1 deletion lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
"noInternetConnectionError": "You seem to be offline.\nPlease try again!",
"genericError": "Something went wrong.\nPlease try again!",
"loginFailAlertTitle": "Unable to log in",
"today": "Today"
"today": "Today",
"errorText": "Error"
}
2 changes: 2 additions & 0 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import 'package:go_router/go_router.dart';
import 'package:survey_flutter/screens/home/home_screen.dart';
import 'package:survey_flutter/screens/login/login_screen.dart';
import 'package:survey_flutter/screens/splash/splash_screen.dart';
import 'package:survey_flutter/storage/survey_storage.dart';
import 'package:survey_flutter/theme/app_theme.dart';

void main() async {
WidgetsFlutterBinding.ensureInitialized();
await FlutterConfig.loadEnvVariables();
await setupHive();
runApp(
ProviderScope(
child: App(),
Expand Down
2 changes: 1 addition & 1 deletion lib/model/response/meta_response.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
});

factory MetaResponse.fromJson(Map<String, dynamic> json) =>
_$MetaResponseFromJson(ResponseDecoder.decode(json));
_$MetaResponseFromJson(ResponseDecoder.decodeData(json));

Check warning on line 22 in lib/model/response/meta_response.dart

View check run for this annotation

Codecov / codecov/patch

lib/model/response/meta_response.dart#L22

Added line #L22 was not covered by tests

static MetaResponse dummy() {
return MetaResponse(
Expand Down
5 changes: 4 additions & 1 deletion lib/model/response/survey_response.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
id: id ?? '',
title: title ?? '',
description: description ?? '',
coverImageUrl: coverImageUrl ?? '',
coverImageUrl: highResolutionCoverImageUrl,

Check warning on line 29 in lib/model/response/survey_response.dart

View check run for this annotation

Codecov / codecov/patch

lib/model/response/survey_response.dart#L29

Added line #L29 was not covered by tests
);

String get highResolutionCoverImageUrl =>
(coverImageUrl != null) ? "${coverImageUrl}l" : "";

Check warning on line 33 in lib/model/response/survey_response.dart

View check run for this annotation

Codecov / codecov/patch

lib/model/response/survey_response.dart#L32-L33

Added lines #L32 - L33 were not covered by tests
}
5 changes: 2 additions & 3 deletions lib/model/response/surveys_container_response.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@
required this.meta,
});

factory SurveysContainerResponse.fromJson(Map<String, dynamic> json) {
return _$SurveysContainerResponseFromJson(ResponseDecoder.decode(json));
}
factory SurveysContainerResponse.fromJson(Map<String, dynamic> json) =>
_$SurveysContainerResponseFromJson(ResponseDecoder.decode(json));

Check warning on line 21 in lib/model/response/surveys_container_response.dart

View check run for this annotation

Codecov / codecov/patch

lib/model/response/surveys_container_response.dart#L20-L21

Added lines #L20 - L21 were not covered by tests

SurveysContainerModel toSurveysContainerModel() => SurveysContainerModel(
surveys:
Expand Down
26 changes: 26 additions & 0 deletions lib/model/survey_model.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
import 'package:equatable/equatable.dart';
import 'package:hive_flutter/hive_flutter.dart';

part 'survey_model.g.dart';

@HiveType(typeId: 0)
class SurveyModel extends Equatable {
@HiveField(0)
final String id;

@HiveField(1)
final String title;

@HiveField(2)
final String description;

@HiveField(3)
final String coverImageUrl;

const SurveyModel({
Expand All @@ -20,4 +31,19 @@
description,
coverImageUrl,
];

SurveyModel toSurveyModel() => SurveyModel(
id: id,
title: title,
description: description,
coverImageUrl: coverImageUrl,
);

const SurveyModel.dummy()
: this(

Check warning on line 43 in lib/model/survey_model.dart

View check run for this annotation

Codecov / codecov/patch

lib/model/survey_model.dart#L43

Added line #L43 was not covered by tests
id: "id",
title: "title",
description: "description",
coverImageUrl: "coverImageUrl",
);
}
20 changes: 14 additions & 6 deletions lib/repositories/survey_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,44 @@
import 'package:survey_flutter/api/exception/network_exceptions.dart';
import 'package:survey_flutter/api/survey_api_service.dart';
import 'package:survey_flutter/di/provider/dio_provider.dart';
import 'package:survey_flutter/model/surveys_container_model.dart';
import 'package:survey_flutter/model/survey_model.dart';
import 'package:survey_flutter/storage/survey_storage.dart';

final surveyRepositoryProvider = Provider<SurveyRepository>((ref) {
final surveyStorage = ref.watch(surveyStorageProvider);

Check warning on line 10 in lib/repositories/survey_repository.dart

View check run for this annotation

Codecov / codecov/patch

lib/repositories/survey_repository.dart#L10

Added line #L10 was not covered by tests
return SurveyRepositoryImpl(
SurveyApiService(DioProvider().getAuthorizedDio(
tokenDataSource: ref.watch(tokenDataSourceProvider),
)),
surveyStorage,
);
});

abstract class SurveyRepository {
Future<SurveysContainerModel> getSurveys({
Future<List<SurveyModel>> getSurveys({
required int pageNumber,
required int pageSize,
});
}

class SurveyRepositoryImpl extends SurveyRepository {
final SurveyApiService _apiService;
final SurveyStorage _surveyStorage;

SurveyRepositoryImpl(this._apiService);
SurveyRepositoryImpl(this._apiService, this._surveyStorage);

@override
Future<SurveysContainerModel> getSurveys({
Future<List<SurveyModel>> getSurveys({
required int pageNumber,
required int pageSize,
}) async {
try {
final result = await _apiService.getSurveys(pageNumber, pageSize);
return result.toSurveysContainerModel();
final response = await _apiService.getSurveys(pageNumber, pageSize);
final surveys = response.data ?? [];
final surveyModels =
surveys.map((item) => (item.toSurveyModel())).toList();
_surveyStorage.saveSurveys(surveyModels);
return surveyModels;
} catch (exception) {
throw NetworkExceptions.fromDioException(exception);
}
Expand Down
17 changes: 9 additions & 8 deletions lib/screens/home/home_footer_widget.dart
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import 'package:flutter/material.dart';
import 'package:survey_flutter/gen/assets.gen.dart';
import 'package:survey_flutter/model/survey_model.dart';
import 'package:survey_flutter/theme/app_constants.dart';
import 'package:survey_flutter/utils/build_context_ext.dart';

const _descriptionOpacity = 0.7;
const _buttonSize = 56.0;

class HomeFooterWidget extends StatelessWidget {
final SurveyModel survey;
final VoidCallback onNextButtonPressed;

const HomeFooterWidget({
Key? key,
required VoidCallback onNextButtonPressed,
required this.survey,
required this.onNextButtonPressed,
}) : super(key: key);

@override
Expand All @@ -28,21 +33,19 @@ class HomeFooterWidget extends StatelessWidget {
}

Widget _buildTitle(BuildContext context) {
// TODO: Replace with survey title
return Text(
"Working from home Check-In",
survey.title,
style: context.textTheme.titleMedium,
maxLines: 2,
);
}

Widget _buildDescription(BuildContext context) {
// TODO: Replace with survey description
return Row(
children: [
Expanded(
child: Text(
"We would like to know how you feel about our work from home...",
survey.description,
style: context.textTheme.bodyMedium?.copyWith(
color: Colors.white.withOpacity(_descriptionOpacity)),
maxLines: 2,
Expand All @@ -63,13 +66,11 @@ class HomeFooterWidget extends StatelessWidget {
backgroundColor: Colors.white,
foregroundColor: Colors.black12,
),
onPressed: onNextButtonPressed,
child: Image.asset(
Assets.images.next.path,
color: Colors.black,
),
onPressed: () {
// TODO: Handle the next button pressed event
},
),
);
}
Expand Down
32 changes: 21 additions & 11 deletions lib/screens/home/home_page_indicator_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,29 @@ const dotIndicatorSize = Size(
);

class HomePageIndicatorWidget extends StatelessWidget {
const HomePageIndicatorWidget({Key? key}) : super(key: key);
final int surveysLength;
final ValueNotifier<int> currentPage;

const HomePageIndicatorWidget({
Key? key,
required this.surveysLength,
required this.currentPage,
}) : super(key: key);

@override
Widget build(BuildContext context) {
// TODO: currentItem and count handled in Integrate
return PageViewDotIndicator(
currentItem: 1,
count: 3,
selectedColor: Colors.white,
unselectedColor: Colors.white.withOpacity(_opacityUnselectedColor),
size: dotIndicatorSize,
unselectedSize: dotIndicatorSize,
alignment: Alignment.bottomLeft,
);
return ValueListenableBuilder(
valueListenable: currentPage,
builder: (_, __, ___) {
return PageViewDotIndicator(
currentItem: currentPage.value,
count: surveysLength,
selectedColor: Colors.white,
unselectedColor: Colors.white.withOpacity(_opacityUnselectedColor),
size: dotIndicatorSize,
unselectedSize: dotIndicatorSize,
alignment: Alignment.bottomLeft,
);
});
}
}
Loading
Loading