Skip to content

Commit

Permalink
сделал дата слой + правки
Browse files Browse the repository at this point in the history
  • Loading branch information
Isaykin Vasily authored and Isaykin Vasily committed Jun 23, 2023
1 parent 3c33fcf commit 64660e3
Show file tree
Hide file tree
Showing 26 changed files with 468 additions and 76 deletions.
2 changes: 1 addition & 1 deletion android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ android {
applicationId "com.example.todo"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion flutter.minSdkVersion
minSdkVersion 24
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
Expand Down
3 changes: 3 additions & 0 deletions lib/application/app.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:todo/application/di/di.dart';
import 'package:todo/application/exceptions/handle_exceptions.dart';
import 'package:todo/application/routes.dart';
import 'package:todo/generated/l10n.dart';
import 'package:todo/presentation/blocs/todos_bloc/todos_bloc.dart';
Expand All @@ -21,10 +22,12 @@ class App extends StatelessWidget {
L10n.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: L10n.delegate.supportedLocales,
routes: routes,
initialRoute: Routes.main.path,
scaffoldMessengerKey: messengerKey,
),
);
}
Expand Down
26 changes: 18 additions & 8 deletions lib/application/di/di.dart
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
import 'dart:io';

import 'package:device_info_plus/device_info_plus.dart';
import 'package:dio/dio.dart';
import 'package:get_it/get_it.dart';
import 'package:injectable/injectable.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:intl/intl.dart';
import 'package:intl/intl_standalone.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:todo/data/services/dio.dart';

import 'di.config.dart';

final getIt = GetIt.instance;

@InjectableInit()
Future<void> configureDependencies() async {
getIt.init();
Intl.systemLocale = await findSystemLocale();
await initializeDateFormatting();
await getIt.init();
// Intl.systemLocale = await findSystemLocale();
// await initializeDateFormatting();
}

@module
abstract class RegisterModule {
@lazySingleton
Dio get dio => createYandexClient();

@preResolve
Future<SharedPreferences> get prefs => SharedPreferences.getInstance();

DeviceInfoPlugin get device => DeviceInfoPlugin();
}
9 changes: 9 additions & 0 deletions lib/application/env/env.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import 'package:envied/envied.dart';

part 'env.g.dart';

@Envied(path: '.env')
abstract class Env {
@EnviedField(varName: 'TOKEN')
static const String token = _Env.token;
}
26 changes: 26 additions & 0 deletions lib/application/exceptions/handle_exceptions.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import 'package:bloc/bloc.dart';
import 'package:flutter/material.dart';
import 'package:todo/uikit/theme.dart';

void handleExceptions() {
Bloc.observer = _BlocErrorHandler();
}

final messengerKey = GlobalKey<ScaffoldMessengerState>();
ScaffoldMessengerState? get _messenger => messengerKey.currentState;

class _BlocErrorHandler extends BlocObserver {
@override
void onError(BlocBase bloc, Object error, StackTrace stackTrace) {
_messenger?.showSnackBar(ErrorSnackBar(error));
super.onError(bloc, error, stackTrace);
}
}

class ErrorSnackBar extends SnackBar {
ErrorSnackBar(Object error, {super.key})
: super(
content: Text(error.toString()),
backgroundColor: ColorsUI.red,
);
}
24 changes: 24 additions & 0 deletions lib/data/dtos/todo_dto/todo_dto.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:todo/domain/models/todo.dart';

part 'todo_dto.freezed.dart';

part 'todo_dto.g.dart';

@freezed
class TodoDto with _$TodoDto {
const factory TodoDto({
Id? id,
required String text,
required String importance,
int? deadline,
required bool done,
String? color,
@JsonKey(name: "created_at") int? createdAt,
@JsonKey(name: "changed_at") int? changedAt,
@JsonKey(name: "last_updated_by") String? lastUpdatedBy,
}) = _TodoDto;

factory TodoDto.fromJson(Map<String, dynamic> json) =>
_$TodoDtoFromJson(json);
}
38 changes: 38 additions & 0 deletions lib/data/mappers/todo_mapper.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import 'package:injectable/injectable.dart';
import 'package:todo/data/dtos/todo_dto/todo_dto.dart';
import 'package:todo/domain/models/todo.dart';

@singleton
class TodoMapper {
Todo fromDto(TodoDto dto) {
return Todo(
id: dto.id,
todo: dto.text,
completed: dto.done,
deadline: dto.deadline != null
? DateTime.fromMillisecondsSinceEpoch(dto.deadline!)
: null,
priority: _importanceFromDto[dto.importance]!,
);
}

TodoDto toDto(Todo todo) {
return TodoDto(
id: todo.id,
text: todo.todo,
done: todo.completed,
importance: _importanceToDto[todo.priority]!,
deadline: todo.deadline?.millisecondsSinceEpoch,
);
}
}

const _importanceFromDto = {
'low': Priority.low,
'basic': Priority.none,
'important': Priority.high,
};

final _importanceToDto = _importanceFromDto.map(
(key, value) => MapEntry(value, key),
);
22 changes: 22 additions & 0 deletions lib/data/repositories/device_repository.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import 'dart:io';

import 'package:device_info_plus/device_info_plus.dart';
import 'package:injectable/injectable.dart';

@singleton
class DeviceRepository {
final DeviceInfoPlugin _device;

DeviceRepository(this._device);

Future<String?> getId() async {
if (Platform.isIOS) {
final iosDeviceInfo = await _device.iosInfo;
return iosDeviceInfo.identifierForVendor; // unique ID on iOS
} else if (Platform.isAndroid) {
final androidDeviceInfo = await _device.androidInfo;
return androidDeviceInfo.id; // unique ID on Android
}
return null;
}
}
16 changes: 9 additions & 7 deletions lib/data/repositories/todo_repository_memory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import 'package:injectable/injectable.dart';
import 'package:todo/application/global.dart';
import 'package:todo/domain/models/todo.dart';
import 'package:todo/domain/repositories/todo_repository.dart';
import 'package:uuid/uuid.dart';

typedef Id = int;

@Singleton(as: TodoRepository)
// @Singleton(as: TodoRepository)
class TodoRepositoryMemory implements TodoRepository {
static const uuid = Uuid();

final Map<Id, Todo> todos = SplayTreeMap.fromIterables(
_stub.map((e) => e.id!),
_stub,
Expand All @@ -34,8 +35,8 @@ class TodoRepositoryMemory implements TodoRepository {
}

@override
Future<Todo?> delete(int id) async {
logger.d('$id');
Future<Todo?> delete(Id id) async {
logger.d(id);

return todos.remove(id);
}
Expand All @@ -45,7 +46,7 @@ class TodoRepositoryMemory implements TodoRepository {
return todos.values.toList();
}

int genId() => todos.keys.last + 1;
Id genId() => uuid.v1();
}

final _stub = () {
Expand Down Expand Up @@ -89,8 +90,9 @@ final _stub = () {
deadline: DateTime.now(),
),
];
const uuid = Uuid();
return [
for (var i = 0; i < stub.length; i++) //
stub[i].copyWith(id: i),
stub[i].copyWith(id: uuid.v1()),
];
}();
55 changes: 55 additions & 0 deletions lib/data/repositories/todo_repository_remote.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import 'package:injectable/injectable.dart';
import 'package:todo/data/mappers/todo_mapper.dart';
import 'package:todo/data/repositories/device_repository.dart';
import 'package:todo/data/services/todo_service/todo_service.dart';
import 'package:todo/domain/models/todo.dart';
import 'package:todo/domain/repositories/todo_repository.dart';
import 'package:uuid/uuid.dart';

@Singleton(as: TodoRepository)
class TodoRepositoryRemote implements TodoRepository {
final TodoService service;
final TodoMapper mapper;
final DeviceRepository device;

static const uuid = Uuid();

TodoRepositoryRemote(this.service, this.mapper, this.device);

@override
Future<void> add(Todo todo) async {
final id = uuid.v1();
final dto = mapper.toDto(todo.copyWith(id: id));
await service.createTodo(
dto.copyWith(
createdAt: DateTime.now().millisecondsSinceEpoch,
changedAt: DateTime.now().millisecondsSinceEpoch,
lastUpdatedBy: (await device.getId())!,
),
);
}

@override
Future<Todo?> delete(Id id) async {
final dto = await service.deleteTodo(id);
return mapper.fromDto(dto);
}

@override
Future<List<Todo>> getAll() async {
final dtos = await service.getTodos();
return dtos.map(mapper.fromDto).toList();
}

@override
Future<void> update(Todo todo) async {
await service.updateTodo(
todo.id!,
mapper.toDto(todo).copyWith(
createdAt: DateTime.now().millisecondsSinceEpoch,
changedAt: DateTime.now().millisecondsSinceEpoch,
lastUpdatedBy: (await device.getId())!,
),
);
}
}
27 changes: 27 additions & 0 deletions lib/data/services/dio.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import 'dart:io';

import 'package:dio/dio.dart';
import 'package:todo/application/env/env.dart';

Dio createYandexClient() {
final dio = Dio(
BaseOptions(
baseUrl: 'https://beta.mrdekk.ru/todobackend',
headers: {
'Authorization': 'Bearer ${Env.token}',
},
),
);

HttpOverrides.global = _HttpPassAllCerts();

return dio;
}

class _HttpPassAllCerts extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext? context) {
return super.createHttpClient(context)
..badCertificateCallback = (_, __, ___) => true;
}
}
Loading

0 comments on commit 64660e3

Please sign in to comment.