Skip to content

Commit

Permalink
feat(validations): BREAKING CHANGE: Removido provider, e usando um no…
Browse files Browse the repository at this point in the history
…vo jeito para ter os retornos da api
  • Loading branch information
avuenja committed Nov 30, 2022
1 parent b0f806e commit 7b13a1d
Show file tree
Hide file tree
Showing 29 changed files with 913 additions and 701 deletions.
58 changes: 19 additions & 39 deletions lib/src/app.dart
Original file line number Diff line number Diff line change
@@ -1,57 +1,37 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

import 'package:tabnews/src/constants.dart';
import 'package:tabnews/src/providers/content.dart';
import 'package:tabnews/src/providers/favorites.dart';
import 'package:tabnews/src/providers/user.dart';
import 'package:tabnews/src/ui/layouts/tab.dart';

class App extends StatelessWidget {
const App({super.key});

@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(
lazy: false,
create: (_) => UserProvider(),
return MaterialApp(
title: 'TabNews',
debugShowCheckedModeBanner: false,
darkTheme: ThemeData.dark().copyWith(
primaryColor: Colors.white,
colorScheme: const ColorScheme.light(
primary: Colors.white60,
secondary: Colors.white60,
),
ChangeNotifierProvider(
lazy: false,
create: (_) => ContentProvider(),
textSelectionTheme: TextSelectionThemeData(
selectionColor: Colors.grey.shade700,
),
ChangeNotifierProvider(
lazy: false,
create: (_) => FavoritesProvider(),
),
],
child: MaterialApp(
title: 'TabNews',
debugShowCheckedModeBanner: false,
darkTheme: ThemeData.dark().copyWith(
primaryColor: Colors.white,
colorScheme: const ColorScheme.light(
primary: Colors.white60,
secondary: Colors.white60,
),
textSelectionTheme: TextSelectionThemeData(
selectionColor: Colors.grey.shade700,
),
),
theme: ThemeData(
primaryColor: Colors.black,
colorScheme: const ColorScheme.light(
primary: AppColors.primaryColor,
secondary: AppColors.primaryColor,
),
theme: ThemeData(
primaryColor: Colors.black,
colorScheme: const ColorScheme.light(
primary: AppColors.primaryColor,
secondary: AppColors.primaryColor,
),
textSelectionTheme: TextSelectionThemeData(
selectionColor: Colors.grey.shade300,
),
textSelectionTheme: TextSelectionThemeData(
selectionColor: Colors.grey.shade300,
),
home: const TabLayout(),
),
home: const TabLayout(),
);
}
}
42 changes: 42 additions & 0 deletions lib/src/controllers/app.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:tabnews/src/constants.dart';
import 'package:tabnews/src/models/user.dart';
import 'package:tabnews/src/preferences.dart';

class AppController {
static final AppController _singleton = AppController._internal();

factory AppController() {
return _singleton;
}

AppController._internal();

static const String _loggedKey = AppConstants.loggedInKey;
static const String _authKey = AppConstants.authKey;
static const String _userKey = AppConstants.userKey;

static ValueNotifier<bool> isLoggedIn = ValueNotifier(
Preferences.getBool(AppController._loggedKey) ?? false,
);
static ValueNotifier<String> auth = ValueNotifier(
Preferences.getString(AppController._authKey) ?? '',
);
static ValueNotifier<User> user = ValueNotifier(
AppController._getLoggedUser(),
);

static User _getLoggedUser() {
String pref = Preferences.getString(_userKey) ?? '';

if (pref.isNotEmpty) {
User user = User.fromJson(jsonDecode(pref));

return user;
}

return User.fromJson({});
}
}
111 changes: 111 additions & 0 deletions lib/src/controllers/auth.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import 'dart:convert';

import 'package:flutter/material.dart';

import 'package:tabnews/src/constants.dart';
import 'package:tabnews/src/controllers/app.dart';
import 'package:tabnews/src/interfaces/view_action.dart';
import 'package:tabnews/src/models/user.dart';
import 'package:tabnews/src/preferences.dart';
import 'package:tabnews/src/services/auth.dart';
import 'package:tabnews/src/services/http_response.dart';

class AuthController {
final ViewAction _view;
final AuthService _authService = AuthService();

final String _loggedKey = AppConstants.loggedInKey;
final String _authKey = AppConstants.authKey;
final String _userKey = AppConstants.userKey;

final ValueNotifier<bool> _isLoading = ValueNotifier(false);
ValueNotifier<bool> get isLoading => _isLoading;

final ValueNotifier<bool> _isRegister = ValueNotifier(false);
ValueNotifier<bool> get isRegister => _isRegister;

AuthController(this._view);

void login(String email, String password) async {
if (email.isEmpty || password.isEmpty) {
_view.onError(message: 'É necessário preencher todos os campos!');

return;
}

_setLoading(true);
final HttpResponse auth = await _authService.postLogin(email, password);

if (auth.ok) {
var user = await _authService.fetchUser(auth.data['token']);

Preferences.setString(_authKey, auth.data['token']);
Preferences.setString(_userKey, jsonEncode(user.data));
Preferences.setBool(_loggedKey, true);

_setLoggedIn(true);
_setToken(auth.data['token']);
_setUser(User.fromJson(user.data));

_view.onSuccess();
} else {
_view.onError(message: auth.message);
}

_setLoading(false);
}

void logout() {
Preferences.setString(_authKey, '');
Preferences.setString(_userKey, '');
Preferences.setBool(_loggedKey, false);
_setLoggedIn(false);
_setToken('');
_setUser(User());
}

void register(String username, String email, String password) async {
if (username.isEmpty || email.isEmpty || password.isEmpty) {
_view.onError(message: 'É necessário preencher todos os campos!');

return;
}

_setLoading(true);
final HttpResponse register = await _authService.postRegister(
username,
email,
password,
);

if (register.ok) {
_setRegister(true);

_view.onSuccess();
} else {
_view.onError(message: register.message);
}

_setLoading(false);
}

void _setLoading(bool value) {
_isLoading.value = value;
}

void _setRegister(bool value) {
_isRegister.value = value;
}

void _setLoggedIn(bool value) {
AppController.isLoggedIn.value = value;
}

void _setToken(String value) {
AppController.auth.value = value;
}

void _setUser(User value) {
AppController.user.value = value;
}
}
44 changes: 44 additions & 0 deletions lib/src/controllers/content.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import 'package:flutter/material.dart';

import 'package:tabnews/src/controllers/app.dart';
import 'package:tabnews/src/interfaces/view_action.dart';
import 'package:tabnews/src/services/content.dart';
import 'package:tabnews/src/services/http_response.dart';

class ContentController {
final ViewAction _view;
final ContentService _contentService = ContentService();

final ValueNotifier<bool> _isLoading = ValueNotifier(false);
ValueNotifier<bool> get isLoading => _isLoading;

ContentController(this._view);

void create(String title, String body, String source) async {
if (title.isEmpty || body.isEmpty) {
_view.onError(message: 'É necessário preencher os campos obrigatórios!');

return;
}

_setLoading(true);
final HttpResponse content = await _contentService.postContent(
AppController.auth.value,
title,
body,
source,
);

if (content.ok) {
_view.onSuccess();
} else {
_view.onError(message: content.message);
}

_setLoading(false);
}

void _setLoading(bool value) {
_isLoading.value = value;
}
}
64 changes: 64 additions & 0 deletions lib/src/controllers/favorites.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import 'dart:convert';

import 'package:flutter/material.dart';

import 'package:tabnews/src/models/content.dart';
import 'package:tabnews/src/preferences.dart';

class FavoritesController {
static final FavoritesController _singleton = FavoritesController._internal();

factory FavoritesController() {
return _singleton;
}

FavoritesController._internal();

final ValueNotifier<bool> _isLoading = ValueNotifier(false);
ValueNotifier<bool> get isLoading => _isLoading;

final ValueNotifier<List<Content>> _favorites = ValueNotifier(
FavoritesController._getSavedFavorites(),
);
ValueNotifier<List<Content>> get favorites => _favorites;

static List<Content> _getSavedFavorites() {
String pref = Preferences.getString('favorites') ?? '';

if (pref.isNotEmpty) {
List<dynamic> contents = jsonDecode(pref);

return contents.map<Content>((e) => Content.fromJson(e)).toList();
}

return [];
}

void toggle(Content content) async {
_setLoading(true);
Content copyContent = content;

if (_favorites.value.isNotEmpty) {
if (_favorites.value
.where((element) => element.id == content.id)
.isNotEmpty) {
_favorites.value = List.from(_favorites.value)
..removeWhere((element) => element.id == content.id);
} else {
copyContent.body = null;
_favorites.value = List.from(_favorites.value)..add(copyContent);
}
} else {
copyContent.body = null;
_favorites.value = List.from(_favorites.value)..add(copyContent);
}

Preferences.setString('favorites', jsonEncode(_favorites.value));

_setLoading(false);
}

void _setLoading(bool value) {
_isLoading.value = value;
}
}
Loading

0 comments on commit 7b13a1d

Please sign in to comment.