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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

On finish callback #268

Merged
merged 2 commits into from
Aug 14, 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
5 changes: 4 additions & 1 deletion core/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ class MyHomePage extends StatelessWidget {
),
// Add Survey to your widget tree with filePath parameter that accepts
// a json file with parsed survey data
body: const Survey(filePath: 'assets/questions.json'),
body: const Survey(
filePath: 'assets/questions.json',
onFinish: print,
),
);
}
}
9 changes: 6 additions & 3 deletions core/lib/src/presentation/survey/survey.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import 'package:survey_sdk/src/presentation/survey/survey_cubit.dart';
import 'package:survey_sdk/src/presentation/survey/survey_state.dart';
import 'package:survey_sdk/src/presentation/survey_error/survey_error.dart';
import 'package:survey_sdk/src/presentation/utils/callback_type.dart';
import 'package:survey_sdk/src/presentation/utils/on_finish_callback.dart';
import 'package:survey_sdk/src/presentation/utils/utils.dart';

// TODO(dev): Maybe create two classes, where one is for filePath and the other
Expand Down Expand Up @@ -44,13 +45,17 @@ class Survey extends StatefulWidget {
/// Whether the survey should save user selected answers.
final bool saveAnswer;

/// Called after the survey is finished.
final OnFinishCallback? onFinish;

/// Either [filePath] or [surveyData] must pe provided. The [controller]
/// parameter is optional and can be used to provide a custom survey
/// controller.
const Survey({
this.filePath,
this.surveyData,
this.controller,
this.onFinish,
this.saveAnswer = true,
super.key,
}) : assert(
Expand Down Expand Up @@ -107,6 +112,7 @@ class _SurveyState extends State<Survey> {
index,
answer,
callbackType,
onFinish: widget.onFinish,
saveAnswer: widget.saveAnswer,
);
}
Expand Down Expand Up @@ -177,9 +183,6 @@ class _SurveyState extends State<Survey> {
onGoNext: _surveyController.onNext,
),
),
DataToWidgetUtil.createEndPage(
data: data.endPage,
),
],
),
),
Expand Down
19 changes: 17 additions & 2 deletions core/lib/src/presentation/survey/survey_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:survey_sdk/src/domain/entities/question_answer.dart';
import 'package:survey_sdk/src/domain/repository_interfaces/survey_data_repository.dart';
import 'package:survey_sdk/src/presentation/survey/survey_state.dart';
import 'package:survey_sdk/src/presentation/utils/on_finish_callback.dart';
import 'package:survey_sdk/src/presentation/utils/survey_button_callback.dart';

import 'package:survey_sdk/survey_sdk.dart';
Expand Down Expand Up @@ -29,6 +30,7 @@ class SurveyCubit extends Cubit<SurveyState> {
QuestionAnswer? answer,
CallbackType callbackType, {
required bool saveAnswer,
OnFinishCallback? onFinish,
}) {
if (state is SurveyLoadedState) {
final loadedState = state as SurveyLoadedState;
Expand All @@ -41,10 +43,16 @@ class SurveyCubit extends Cubit<SurveyState> {
callback: callback,
callbackType: callbackType,
surveyController: surveyController,
onFinish: onFinish,
answers: loadedState.answers,
questions: loadedState.surveyData.questions,
saveAnswer: () => answer == null || !saveAnswer
? null
: _saveAnswer(index: questionIndex, answer: answer),
: _saveAnswer(
index: questionIndex,
answer: answer,
onFinish: onFinish,
),
).callbackFromType();
}
}
Expand Down Expand Up @@ -72,11 +80,18 @@ class SurveyCubit extends Cubit<SurveyState> {
}

/// Saves the provided [answer] for the question at the specified [index].
void _saveAnswer({required int index, required QuestionAnswer answer}) {
void _saveAnswer({
required int index,
required QuestionAnswer answer,
OnFinishCallback? onFinish,
}) {
final currentState = state;
if (currentState is SurveyLoadedState) {
final newAnswers = Map<int, QuestionAnswer>.of(currentState.answers);
newAnswers[index] = answer;
if (index == currentState.surveyData.questions.length) {
onFinish?.call(newAnswers);
}
emit(currentState.copyWith(answers: newAnswers));
}
}
Expand Down
3 changes: 3 additions & 0 deletions core/lib/src/presentation/utils/on_finish_callback.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import 'package:survey_sdk/src/domain/entities/question_answer.dart';

typedef OnFinishCallback = void Function(Map<int, QuestionAnswer> answers);
13 changes: 11 additions & 2 deletions core/lib/src/presentation/utils/survey_button_callback.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,33 @@ import 'package:survey_sdk/src/domain/entities/actions/go_next_action.dart';
import 'package:survey_sdk/src/domain/entities/actions/go_to_action.dart';
import 'package:survey_sdk/src/domain/entities/actions/skip_question_action.dart';
import 'package:survey_sdk/src/domain/entities/actions/survey_action.dart';
import 'package:survey_sdk/src/domain/entities/question_answer.dart';
import 'package:survey_sdk/src/domain/entities/question_types/question_data.dart';
import 'package:survey_sdk/src/presentation/survey/survey_controller.dart';
import 'package:survey_sdk/src/presentation/utils/callback_type.dart';
import 'package:survey_sdk/src/presentation/utils/on_finish_callback.dart';

class SurveyButtonCallback {
final SurveyAction? callback;
final VoidCallback? saveAnswer;
final SurveyController surveyController;
final List<QuestionData> questions;
final OnFinishCallback? onFinish;
final CallbackType callbackType;
final Map<int, QuestionAnswer>? answers;

SurveyButtonCallback({
required this.callback,
required this.saveAnswer,
required this.surveyController,
required this.questions,
required this.callbackType,
});
this.answers,
this.onFinish,
}) : assert(
onFinish != null && answers != null || onFinish == null,
'If onFinish != null answers should not be null either',
);

void callbackFromType() => switch (callback.runtimeType) {
GoToAction => goToCallback(),
Expand All @@ -33,7 +42,6 @@ class SurveyButtonCallback {
_ => defaultSurveyCallback(),
};


@visibleForTesting
void goToCallback() {
saveAnswer?.call();
Expand All @@ -43,6 +51,7 @@ class SurveyButtonCallback {
@visibleForTesting
void finishSurveyCallback() {
saveAnswer?.call();
onFinish?.call(answers!);
surveyController.animateTo(questions.length);
}

Expand Down