Skip to content

Commit

Permalink
Improved overall code quality (#343)
Browse files Browse the repository at this point in the history
* Improved overall code quality

* Format files
  • Loading branch information
hawkkiller committed Jun 28, 2024
1 parent 197a1e0 commit e0bac6a
Show file tree
Hide file tree
Showing 14 changed files with 144 additions and 77 deletions.
3 changes: 1 addition & 2 deletions lib/src/core/database/src/app_database.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import 'package:drift/drift.dart';
import 'package:sizzle_starter/src/core/database/database.dart';
import 'package:sizzle_starter/src/core/database/src/tables/todos_table.dart';

part 'app_database.g.dart';

/// {@template app_database}
/// The drift-managed database configuration
/// {@endtemplate}
@DriftDatabase(tables: [TodosTable])
@DriftDatabase()
class AppDatabase extends _$AppDatabase {
/// {@macro app_database}
AppDatabase([QueryExecutor? executor]) : super(executor ?? createExecutor());
Expand Down
17 changes: 0 additions & 17 deletions lib/src/core/database/src/tables/todos_table.dart

This file was deleted.

32 changes: 20 additions & 12 deletions lib/src/core/utils/app_bloc_observer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import 'package:sizzle_starter/src/core/utils/refined_logger.dart';

/// [BlocObserver] which logs all bloc state changes, errors and events.
class AppBlocObserver extends BlocObserver {
/// [BlocObserver] which logs all bloc state changes, errors and events.
/// Creates an instance of [AppBlocObserver] with the provided [logger].
const AppBlocObserver(this.logger);

/// Logger used to log information during bloc transitions.
Expand All @@ -15,31 +15,39 @@ class AppBlocObserver extends BlocObserver {
Bloc<Object?, Object?> bloc,
Transition<Object?, Object?> transition,
) {
final buffer = StringBuffer()
..write('Bloc: ${bloc.runtimeType} | ')
..writeln('${transition.event.runtimeType}')
..write('Transition: ${transition.currentState.runtimeType}')
..writeln(' => ${transition.nextState.runtimeType}')
final logMessage = StringBuffer()
..writeln('Bloc: ${bloc.runtimeType}')
..writeln('Event: ${transition.event.runtimeType}')
..writeln('Transition: ${transition.currentState.runtimeType} => '
'${transition.nextState.runtimeType}')
..write('New State: ${transition.nextState.toString().limit(100)}');
logger.info(buffer.toString());

logger.info(logMessage.toString());
super.onTransition(bloc, transition);
}

@override
void onEvent(Bloc<Object?, Object?> bloc, Object? event) {
final buffer = StringBuffer()
..writeln('Bloc: ${bloc.runtimeType} | ${event.runtimeType}')
..write('Event: ${event.toString().limit(200)}');
logger.info(buffer.toString());
final logMessage = StringBuffer()
..writeln('Bloc: ${bloc.runtimeType}')
..writeln('Event: ${event.runtimeType}')
..write('Details: ${event.toString().limit(200)}');

logger.info(logMessage.toString());
super.onEvent(bloc, event);
}

@override
void onError(BlocBase<Object?> bloc, Object error, StackTrace stackTrace) {
final logMessage = StringBuffer()
..writeln('Bloc: ${bloc.runtimeType}')
..writeln(error.toString());

logger.error(
'Bloc: ${bloc.runtimeType} | $error',
logMessage.toString(),
error: error,
stackTrace: stackTrace,
printError: false,
);
super.onError(bloc, error, stackTrace);
}
Expand Down
6 changes: 3 additions & 3 deletions lib/src/core/utils/extensions/context_extension.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ extension ContextExtension on BuildContext {
));

/// Maybe inherit specific aspect from [InheritedModel].
T? maybeInheritFrom<A extends Object, T extends InheritedModel<A>>(
T? maybeInheritFrom<A extends Object, T extends InheritedModel<A>>({
A? aspect,
) =>
}) =>
InheritedModel.inheritFrom<T>(this, aspect: aspect);

/// Inherit specific aspect from [InheritedModel].
T inheritFrom<A extends Object, T extends InheritedModel<A>>({A? aspect}) =>
InheritedModel.inheritFrom<T>(this, aspect: aspect) ??
maybeInheritFrom(aspect: aspect) ??
(throw ArgumentError(
'Out of scope, not found inherited model '
'a $T of the exact type',
Expand Down
33 changes: 30 additions & 3 deletions lib/src/core/utils/preferences_dao.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,35 @@ abstract base class PreferencesEntry<T extends Object> {

/// {@template typed_entry}
/// A [PreferencesEntry] that is typed to a specific type [T].
///
/// You can also create subclasses of this class to create adapters for custom
/// types.
///
/// ```dart
/// class CustomTypeEntry extends TypedEntry<CustomType> {
/// CustomTypeEntry({
/// required SharedPreferences sharedPreferences,
/// required String key,
/// }) : super(sharedPreferences: sharedPreferences, key: key);
///
/// @override
/// CustomType? read() {
/// final value = _sharedPreferences.get(key);
///
/// if (value == null) return null;
///
/// return CustomType.fromJson(value);
/// }
///
/// @override
/// Future<void> set(CustomType value) => _sharedPreferences.setString(
/// key,
/// value.toJson(),
/// );
/// }
/// ```
/// {@endtemplate}
final class TypedEntry<T extends Object> extends PreferencesEntry<T> {
base class TypedEntry<T extends Object> extends PreferencesEntry<T> {
/// {@macro typed_entry}
TypedEntry({
required SharedPreferences sharedPreferences,
Expand All @@ -92,7 +119,7 @@ final class TypedEntry<T extends Object> extends PreferencesEntry<T> {

if (value is T) return value;

throw Exception(
throw StateError(
'The value of $key is not of type ${T.runtimeType.toString()}',
);
}
Expand All @@ -107,7 +134,7 @@ final class TypedEntry<T extends Object> extends PreferencesEntry<T> {
key,
value.toList(),
),
_ => throw Exception(
_ => throw StateError(
'$T is not a valid type for a preferences entry value.',
),
};
Expand Down
11 changes: 7 additions & 4 deletions lib/src/core/utils/refined_logger.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'dart:async';

import 'package:clock/clock.dart';
import 'package:flutter/foundation.dart';
import 'package:stack_trace/stack_trace.dart';

/// Logger global instance.
///
Expand Down Expand Up @@ -198,19 +199,21 @@ class DefaultLogger extends RefinedLogger {
final emoji = options.showEmoji ? message.level.emoji : '';
final level = message.level;
final content = message.message;
final stackTrace = message.stackTrace;
final error = message.error;

final buffer = StringBuffer();

buffer.write('$emoji $time [${level.name.toUpperCase()}] $content');

if (message.error != null && wrappedMessage.printError) {
if (error != null && wrappedMessage.printError) {
buffer.writeln();
buffer.write(message.error);
buffer.write(error);
}

if (message.stackTrace != null && wrappedMessage.printStackTrace) {
if (stackTrace != null && wrappedMessage.printStackTrace) {
buffer.writeln();
buffer.write(message.stackTrace);
buffer.write(Trace.from(stackTrace).terse);
}

return buffer.toString();
Expand Down
16 changes: 9 additions & 7 deletions lib/src/feature/app/logic/tracking_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,20 @@ abstract base class ErrorTrackingManagerBase implements ErrorTrackingManager {
@override
Future<void> enableReporting() async {
_subscription ??= _reportLogs.listen((log) async {
if (_shouldReport(log.error)) {
await _report(log);
if (shouldReport(log.error)) {
await report(log);
}
});
}

/// Returns `true` if the error should be reported.
@pragma('vm:prefer-inline')
bool _shouldReport(Object? error) => true;
bool shouldReport(Object? error) => true;

/// Handles the log message.
///
/// This method is called when a log message is received.
Future<void> _report(LogMessage log);
Future<void> report(LogMessage log);
}

/// {@template sentry_tracking_manager}
Expand All @@ -83,7 +83,7 @@ final class SentryTrackingManager extends ErrorTrackingManagerBase {
final String environment;

@override
Future<void> _report(LogMessage log) async {
Future<void> report(LogMessage log) async {
final error = log.error;
final stackTrace = log.stackTrace;
final hint = log.context != null ? Hint.withMap(log.context!) : null;
Expand All @@ -109,10 +109,12 @@ final class SentryTrackingManager extends ErrorTrackingManagerBase {
await SentryFlutter.init((options) {
options.dsn = sentryDsn;

// Set the sample rate to 20% of events.
options.tracesSampleRate = 0.20;
// Set the sample rate to 10% of events.
options.tracesSampleRate = 0.10;
options.debug = kDebugMode;
options.environment = environment;
options.anrEnabled = true;
options.sendDefaultPii = true;
});
await super.enableReporting();
}
Expand Down
6 changes: 4 additions & 2 deletions lib/src/feature/app/widget/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import 'package:sizzle_starter/src/feature/settings/widget/settings_scope.dart';
/// {@template app}
/// [App] is an entry point to the application.
///
/// Scopes that don't depend on widgets returned by [MaterialApp]
/// ([Directionality], [MediaQuery], [Localizations]) should be placed here.
/// If a scope doesn't depend on any inherited widget returned by
/// [MaterialApp] or [WidgetsApp], like [Directionality] or [Theme],
/// and it should be available in the whole application, it can be
/// placed here.
/// {@endtemplate}
class App extends StatelessWidget {
/// {@macro app}
Expand Down
14 changes: 13 additions & 1 deletion lib/src/feature/home/widget/home_screen.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
import 'package:flutter/material.dart';
import 'package:sizzle_starter/src/core/utils/layout/layout.dart';
import 'package:sizzle_starter/src/feature/settings/widget/settings_scope.dart';

/// {@template home_screen}
/// HomeScreen is a simple screen that displays a grid of items.
/// {@endtemplate}
class HomeScreen extends StatelessWidget {
class HomeScreen extends StatefulWidget {
/// {@macro home_screen}
const HomeScreen({super.key});

@override
State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
@override
void initState() {
SettingsScope.of(context, listen: false).setLocale(const Locale('ru'));
super.initState();
}

@override
Widget build(BuildContext context) {
final windowWidth = MediaQuery.sizeOf(context).width;
Expand Down
4 changes: 4 additions & 0 deletions lib/src/feature/initialization/model/environment.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ enum Environment {
/// Development environment.
dev._('DEV'),

/// Staging environment.
staging._('STAGING'),

/// Production environment.
prod._('PROD');

Expand All @@ -16,6 +19,7 @@ enum Environment {
/// Returns the environment from the given [value].
static Environment from(String? value) => switch (value) {
'DEV' => Environment.dev,
'STAGING' => Environment.staging,
'PROD' => Environment.prod,
_ => kReleaseMode ? Environment.prod : Environment.dev,
};
Expand Down
10 changes: 8 additions & 2 deletions lib/src/feature/initialization/widget/dependencies_scope.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@ import 'package:sizzle_starter/src/core/utils/extensions/context_extension.dart'
import 'package:sizzle_starter/src/feature/initialization/model/dependencies.dart';

/// {@template dependencies_scope}
/// A widget which is responsible for providing the dependencies.
/// A scope that provides application dependencies.
///
/// In order to use this in widget tests, you need to wrap your widget with
/// this widget and provide the dependencies. However, you should not
/// always provide the full pack of dependencies, only the ones that are
/// needed for the test. It is possible by creating a new class that extends
/// [Dependencies] and overrides the dependencies that are needed for the test.
/// {@endtemplate}
class DependenciesScope extends InheritedWidget {
/// {@macro dependencies_scope}
Expand All @@ -15,7 +21,7 @@ class DependenciesScope extends InheritedWidget {
super.key,
});

/// The dependencies
/// Container with dependencies.
final Dependencies dependencies;

/// Get the dependencies from the [context].
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:flutter/material.dart';

/// {@template initialization_failed_screen}
/// InitializationFailedScreen widget
/// Screen that is shown when the initialization of the app fails.
/// {@endtemplate}
class InitializationFailedApp extends StatefulWidget {
/// The error that caused the initialization to fail.
Expand Down Expand Up @@ -40,7 +40,7 @@ class _InitializationFailedAppState extends State<InitializationFailedApp> {

Future<void> _retryInitialization() async {
_inProgress.value = true;
await widget.retryInitialization!();
await widget.retryInitialization?.call();
_inProgress.value = false;
}

Expand Down
Loading

0 comments on commit e0bac6a

Please sign in to comment.