Skip to content
Open
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: 5 additions & 0 deletions lib/core/app/app.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:sqflite_migration_service/sqflite_migration_service.dart';
import 'package:stacked/stacked_annotations.dart';
import 'package:stacked_services/stacked_services.dart';
import 'package:stacked_themes/stacked_themes.dart';

import '../../features/advice/advice_view.dart';
import '../../features/advices/advices_view.dart';
Expand Down Expand Up @@ -64,6 +65,10 @@ import '../stores/slip_store.dart';
classType: AdviceSlipServiceImpl,
asType: AdviceSlipService,
),
LazySingleton(
classType: ThemeService,
resolveUsing: ThemeService.getInstance,
)
],
logger: StackedLogger(),
)
Expand Down
2 changes: 2 additions & 0 deletions lib/core/app/app.locator.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 35 additions & 20 deletions lib/core/stores/slip_store.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,48 @@ class SlipStore {
}

Future<void> addAdvice({Slip? slip}) async {
_log.i('adding slip: ${slip?.id}');
await _databaseService.database!.insert(_slipTable, slip!.toJson());
try {
_log.i('adding slip: ${slip?.id}');
await _databaseService.database!.insert(_slipTable, slip!.toJson());
} catch (e) {
_log.e('error adding slip');
return;
}
}

Future<void> removeAdvice({Slip? slip}) async {
_log.i('removing slip: ${slip?.id}');
await _databaseService.database!
.delete(_slipTable, where: "id = ?", whereArgs: [slip?.id]);
try {
_log.i('removing slip: ${slip?.id}');
await _databaseService.database!
.delete(_slipTable, where: "id = ?", whereArgs: [slip?.id]);
} catch (e) {
_log.e('error deleting slip');
return;
}
}

Future<bool> isSaved({int? slipId}) async {
_log.i('checking saved state for $slipId');
bool status = false;
var records = await _databaseService.database!.query(
_slipTable,
where: "id = ?",
whereArgs: [slipId],
);
var data = records.map((e) => Slip.fromJson(e)).toList();
if (data.isEmpty) {
status = false;
_log.i('status: $status');
} else {
status = true;
_log.i('status: $status');
try {
_log.i('checking saved state for $slipId');
bool status = false;
var records = await _databaseService.database!.query(
_slipTable,
where: "id = ?",
whereArgs: [slipId],
);
var data = records.map((e) => Slip.fromJson(e)).toList();
if (data.isEmpty) {
status = false;
_log.i('status: $status');
} else {
status = true;
_log.i('status: $status');
}
return status;
} catch (e) {
_log.e('error checking state');
return false;
}
return status;
}

Stream<bool> isStreamedSaved({String? slipId}) async* {
Expand Down
16 changes: 7 additions & 9 deletions lib/features/advice/advice_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,16 @@ class AdviceView extends StatelessWidget {
style: theme.textTheme.bodyLarge,
),
),
SizedBox(
height: SizeMg.height(30),
),
IconButton(
onPressed: () {
model.actionSaveAdvice(slip: slip);
},
icon: const Icon(Icons.save),
),
],
),
),
floatingActionButton: FloatingActionButton(
tooltip: 'Save Advice',
onPressed: () {
model.actionconfirmSave(slip: slip);
},
child: const Icon(Icons.save),
),
);
},
);
Expand Down
42 changes: 32 additions & 10 deletions lib/features/advice/view_model/advice_viewmodel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,34 @@ import '../../../core/stores/slip_store.dart';

class AdviceViewModel extends BaseViewModel {
final _snackbarService = locator<SnackbarService>();
final _dialogService = locator<DialogService>();
final _slipStore = locator<SlipStore>();
final _log = getLogger('AdviceViewModel');

void actionSaveAdvice({Slip? slip}) async {
_log.i('adding advice');
if (await _slipStore.isSaved(slipId: slip?.id)) {
void _actionSaveAdvice({Slip? slip}) async {
try {
_log.i('adding advice');
if (await _slipStore.isSaved(slipId: slip?.id)) {
return _handleSnackbar(
title: 'Error',
message: 'An advice with the ID: ${slip?.id} has already been saved.',
variant: SnackBarType.error,
);
}
await _slipStore.addAdvice(slip: slip);
return _handleSnackbar(
title: 'Info',
message: 'An advice with an ID: ${slip?.id} has been saved.',
variant: SnackBarType.info,
);
} catch (e) {
_log.e('well once in awhile, things do break.');
return _handleSnackbar(
title: 'Error',
message: 'An advice with the ID: ${slip?.id} has already been saved.',
message: 'Opps! something went wrong',
variant: SnackBarType.error,
);
}
await _slipStore.addAdvice(slip: slip);
return _handleSnackbar(
title: 'Info',
message: 'An advice with an ID: ${slip?.id} has been saved.',
variant: SnackBarType.info,
);
}

void _handleSnackbar({
Expand All @@ -40,4 +50,16 @@ class AdviceViewModel extends BaseViewModel {
variant: variant,
);
}

void actionconfirmSave({Slip? slip}) async {
final DialogResponse? response = await _dialogService.showDialog(
title: 'Save Advice',
description: 'Are you sure you want to save this advice?',
buttonTitle: 'Yes',
cancelTitle: 'No',
);
if (response?.confirmed ?? false) {
_actionSaveAdvice(slip: slip);
}
}
}
2 changes: 1 addition & 1 deletion lib/features/advices/advices_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class AdvicesView extends StatelessWidget {
trailing: IconButton(
color: Colors.redAccent,
onPressed: () {
model.actionDeleteAdvice(slip: slip);
model.actionconfirmDelete(slip: slip);
},
icon: const Icon(Icons.delete),
),
Expand Down
15 changes: 14 additions & 1 deletion lib/features/advices/view_model/advices_viewmodel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import '../../../core/stores/slip_store.dart';
class AdvicesViewModel extends StreamViewModel<List<Slip>> {
final _slipStore = locator<SlipStore>();
final _snackbarService = locator<SnackbarService>();
final _dialogService = locator<DialogService>();
final _log = getLogger('AdvicesViewModel');

void actionDeleteAdvice({Slip? slip}) async {
void _actionDeleteAdvice({Slip? slip}) async {
_log.i('deleting advice');
await _slipStore.removeAdvice(slip: slip);
_snackbarService.showCustomSnackBar(
Expand All @@ -24,6 +25,18 @@ class AdvicesViewModel extends StreamViewModel<List<Slip>> {
initialise();
}

void actionconfirmDelete({Slip? slip}) async {
final DialogResponse? response = await _dialogService.showDialog(
title: 'Delete Advice',
description: 'Are you sure you want to delete this advice?',
buttonTitle: 'Yes',
cancelTitle: 'No',
);
if (response?.confirmed ?? false) {
_actionDeleteAdvice(slip: slip);
}
}

@override
Stream<List<Slip>> get stream => _slipStore.getStreamAdvice();
}
8 changes: 7 additions & 1 deletion lib/features/home/home_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,15 @@ class HomeView extends StatelessWidget {
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
leading: Switch.adaptive(
value: model.isDark,
onChanged: (value) {
model.actionSwitchTheme();
},
),
actions: [
IconButton(
color: Colors.black,
color: theme.iconTheme.color,
onPressed: () {
model.actionRouteAdvices();
},
Expand Down
8 changes: 8 additions & 0 deletions lib/features/home/view_model/home_viewmodel.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:dio/dio.dart';
import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart';
import 'package:stacked_themes/stacked_themes.dart';

import '../../../core/app/app.locator.dart';
import '../../../core/app/app.logger.dart';
Expand All @@ -15,8 +16,15 @@ class HomeViewModel extends StreamViewModel<bool> {
final _navigationService = locator<NavigationService>();
final _adviceSlipService = locator<AdviceSlipService>();
final _connectivityService = locator<ConnectivityService>();
final _themeService = locator<ThemeService>();
final _log = getLogger('HomeViewModel');

bool get isDark => _themeService.isDarkMode;

void actionSwitchTheme() {
_themeService.toggleDarkLightTheme();
}

void actionRouteAdvices() {
_navigationService.navigateToAdvicesView();
}
Expand Down
36 changes: 0 additions & 36 deletions lib/features/home/widgets/action_button.dart

This file was deleted.

10 changes: 7 additions & 3 deletions lib/features/home/widgets/contents.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import 'package:stacked/stacked.dart';
import '../../../core/shared_widgets/info_card.dart';
import '../../../core/utils/size_manager.dart';
import '../view_model/home_viewmodel.dart';
import 'action_button.dart';

class Contents extends ViewModelWidget<HomeViewModel> {
const Contents({Key? key}) : super(key: key, reactive: false);

@override
Widget build(BuildContext context, HomeViewModel viewModel) {
SizeMg.init(context);
var theme = Theme.of(context);
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expand All @@ -22,10 +22,14 @@ class Contents extends ViewModelWidget<HomeViewModel> {
SizedBox(
height: SizeMg.height(50),
),
ActionButton(
onTap: () {
ElevatedButton(
onPressed: () {
viewModel.actionGetAdviceSlip();
},
child: Text(
'Get Advice',
style: theme.textTheme.button,
),
),
],
);
Expand Down
35 changes: 17 additions & 18 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:stacked_services/stacked_services.dart';
import 'package:stacked_themes/stacked_themes.dart';

import 'core/app/app.locator.dart';
import 'core/app/app.router.dart';
Expand All @@ -8,6 +9,7 @@ import 'core/utils/setup_snackbar_ui.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized;
await setupLocator();
await ThemeManager.initialise();
setupSnackbarUi();
runApp(const MyApp());
}
Expand All @@ -18,24 +20,21 @@ class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Advice App',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
navigatorKey: StackedService.navigatorKey,
initialRoute: Routes.splashView,
onGenerateRoute: StackedRouter().onGenerateRoute,
navigatorObservers: [StackedService.routeObserver],
return ThemeBuilder(
lightTheme: ThemeData.light(useMaterial3: true),
darkTheme: ThemeData.dark(useMaterial3: true),
builder: (context, lightTheme, darkTheme, themeMode) {
return MaterialApp(
title: 'Advice App',
theme: lightTheme,
darkTheme: darkTheme,
themeMode: themeMode,
navigatorKey: StackedService.navigatorKey,
initialRoute: Routes.splashView,
onGenerateRoute: StackedRouter().onGenerateRoute,
navigatorObservers: [StackedService.routeObserver],
);
},
);
}
}
Loading