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

Alpha 0.1 #5

Merged
merged 3 commits into from
Nov 24, 2022
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
47 changes: 39 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,59 @@
# TabNews App

Aplicativo para o [TabNews](https://www.tabnews.com.br) feito em Flutter.
Aplicativo TabNews feito com muito ♥️ e Flutter, pela comunidade para o site [TabNews](https://www.tabnews.com.br).

### Features:
## Instalar e rodar o projeto

- [x] Tema escuro
### Dependências globais

Você precisa ter o Flutter instalado e configurado na sua máquina:

- [Flutter](https://docs.flutter.dev/get-started/install) 3.0 (ou qualquer versão **3** superior)

### Dependências locais

Então após baixar/clonar o repositório, não se esqueça de instalar as dependências locais do projeto:

```bash
flutter pub get
```

### Rodar o projeto

Para rodar o projeto localmente, basta rodar o comando abaixo:

```bash
flutter run
```

Isto irá rodar o projeto no seu emulador/simulador ou dispositivo real conectado.

**Lembrando que as vezes é necessário abrir o emulador/simulador antes de rodar o comando de run.**


## Features:

- [x] Dark mode
- [x] Leitura de conteúdos
- [x] Pull To Refresh
- [x] Infite Scroll
- [ ] Comentários das publicações (Em progresso)
- [ ] Login do usuário (Em progresso)
- [ ] Visualização de Comentários das publicações (Em progresso)
- [x] Login do usuário
- [x] Meus conteúdos
- [ ] Resposta dos conteúdos
- [ ] Postagens de conteúdos
- [ ] Visualização do perfil
- [ ] Favoritos (local database)
- [ ] Opção ler mais taerde (local database)

### Imagens:
## Imagens:

<img src="https://user-images.githubusercontent.com/5226773/203336200-6d56e78d-2abd-4b2b-b93b-84eb605627f9.PNG" width="300px" alt="Home" />
<img src="https://user-images.githubusercontent.com/5226773/203336162-7af83c42-9ec0-4b6c-8be6-e7be32426527.PNG" width="300px" alt="Home - Dark" />
<br />
<img src="https://user-images.githubusercontent.com/5226773/203336407-a25b0d9f-ea7c-4348-895d-d4cf418141e6.PNG" width="300px" alt="Leitura" />
<img src="https://user-images.githubusercontent.com/5226773/203336292-724ab6e6-d3fe-400a-a1ee-12ef5db0a54c.PNG" width="300px" alt="Leitura - Dark" />

<br />
<br />

## Contribuidores

8 changes: 3 additions & 5 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

import 'package:tabnews/src/app.dart';
import 'package:tabnews/src/login_state.dart';
import 'package:tabnews/src/preferences.dart';

void main() async {
WidgetsFlutterBinding.ensureInitialized();

final state = LoginState(await SharedPreferences.getInstance());
state.checkLoggedIn();
await Preferences.init();

runApp(App(loginState: state));
runApp(const App());
}
41 changes: 16 additions & 25 deletions lib/src/app.dart
Original file line number Diff line number Diff line change
@@ -1,42 +1,33 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:tabnews/src/login_state.dart';

import 'package:tabnews/src/routes.dart';
import 'package:tabnews/src/providers/user.dart';
import 'package:tabnews/src/ui/layouts/tab.dart';
import 'package:tabnews/src/ui/pages/login.dart';

class App extends StatelessWidget {
final LoginState loginState;

const App({super.key, required this.loginState});
const App({super.key});

@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(
lazy: false,
create: (_) => loginState,
),
Provider<Routes>(
lazy: false,
create: (context) => Routes(loginState),
create: (_) => UserProvider(),
),
],
child: Builder(
builder: (context) {
final router = Provider.of<Routes>(context, listen: false).router;

return MaterialApp.router(
routeInformationParser: router.routeInformationParser,
routerDelegate: router.routerDelegate,
title: 'TabNews',
debugShowCheckedModeBanner: false,
darkTheme: ThemeData.dark(),
theme: ThemeData(
primaryColor: Colors.black,
),
);
},
child: MaterialApp(
title: 'TabNews',
debugShowCheckedModeBanner: false,
darkTheme: ThemeData.dark(),
theme: ThemeData(
primaryColor: Colors.black,
),
home: Consumer<UserProvider>(
builder: (context, user, _) =>
user.loggedIn ? const TabLayout() : const LoginPage(),
),
),
);
}
Expand Down
23 changes: 8 additions & 15 deletions lib/src/constants.dart
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
import 'package:flutter/material.dart';

const String rootRouteName = 'root';
const String createAccountRouteName = 'create-account';
const String detailsRouteName = 'details';
const String homeRouteName = 'home';
const String loggedInKey = 'LoggedIn';
const String loginRouteName = 'login';
const String moreInfoRouteName = 'moreInfo';
const String personalRouteName = 'personal';
const String profileMoreInfoRouteName = 'profile-moreInfo';
const String profilePersonalRouteName = 'profile-personal';
const String profileRouteName = 'profile';
const String profileSigninInfoRouteName = 'profile-signin';
const String postRouteName = 'post-view';
const String signinInfoRouteName = 'signin';
abstract class AppConstants {
static const String loggedInKey = 'LoggedIn';
static const String authKey = 'AuthLogged';
static const String userKey = 'UserLogged';
}

const Color primaryColor = Color.fromRGBO(36, 41, 47, 1);
abstract class AppColors {
static const Color primaryColor = Color.fromRGBO(36, 41, 47, 1);
}
40 changes: 0 additions & 40 deletions lib/src/login_state.dart

This file was deleted.

49 changes: 49 additions & 0 deletions lib/src/models/user.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
class User {
String? id;
String? username;
String? email;
bool? notifications;
List<String>? features;
int? tabcoins;
int? tabcash;
String? createdAt;
String? updatedAt;

User({
this.id,
this.username,
this.email,
this.notifications,
this.features,
this.tabcoins,
this.tabcash,
this.createdAt,
this.updatedAt,
});

User.fromJson(Map<String, dynamic> json) {
id = json['id'];
username = json['username'];
email = json['email'];
notifications = json['notifications'];
features = json['features'].cast<String>();
tabcoins = json['tabcoins'];
tabcash = json['tabcash'];
createdAt = json['created_at'];
updatedAt = json['updated_at'];
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = {};
data['id'] = id;
data['username'] = username;
data['email'] = email;
data['notifications'] = notifications;
data['features'] = features;
data['tabcoins'] = tabcoins;
data['tabcash'] = tabcash;
data['created_at'] = createdAt;
data['updated_at'] = updatedAt;
return data;
}
}
20 changes: 0 additions & 20 deletions lib/src/pages/error.dart

This file was deleted.

17 changes: 17 additions & 0 deletions lib/src/preferences.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import 'dart:async' show Future;
import 'package:shared_preferences/shared_preferences.dart';

class Preferences {
static late final SharedPreferences _instance;

static Future<SharedPreferences> init() async =>
_instance = await SharedPreferences.getInstance();

static bool? getBool(String key) => _instance.getBool(key);
static Future<bool> setBool(String key, bool value) =>
_instance.setBool(key, value);

static String? getString(String key) => _instance.getString(key);
static Future<bool> setString(String key, String value) =>
_instance.setString(key, value);
}
88 changes: 88 additions & 0 deletions lib/src/providers/user.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import 'dart:convert';

import 'package:flutter/material.dart';

import 'package:tabnews/src/constants.dart';
import 'package:tabnews/src/models/auth.dart';
import 'package:tabnews/src/models/user.dart';
import 'package:tabnews/src/preferences.dart';
import 'package:tabnews/src/services/auth.dart';

class UserProvider extends ChangeNotifier {
static final UserProvider _instance = UserProvider._internal();

final api = ApiAuth();
final String _loggedKey = AppConstants.loggedInKey;
final String _authKey = AppConstants.authKey;
final String _userKey = AppConstants.userKey;

factory UserProvider() {
return _instance;
}

UserProvider._internal() {
_loggedIn = Preferences.getBool(_loggedKey) ?? false;

if (_loggedIn) {
_sessionId = _getSessionId();
_user = _getUser();
}
}

late bool _loggedIn;
bool get loggedIn => _loggedIn;

late String _sessionId;
String get sessionId => _sessionId;

late User _user;
User get user => _user;

void login(String email, String password) async {
var auth = await api.postLogin(email, password);

if (auth.id!.isNotEmpty) {
var user = await api.fetchUser(auth.token!);

Preferences.setString(_authKey, jsonEncode(auth.toJson()));
Preferences.setString(_userKey, jsonEncode(user.toJson()));
Preferences.setBool(_loggedKey, true);
_loggedIn = true;
}

notifyListeners();
}

void logout() {
Preferences.setString(_authKey, '');
Preferences.setString(_userKey, '');
Preferences.setBool(_loggedKey, false);
_loggedIn = false;

notifyListeners();
}

String _getSessionId() {
String pref = Preferences.getString(_authKey) ?? '';

if (pref.isNotEmpty) {
Auth auth = Auth.fromJson(jsonDecode(pref));

return auth.token!;
}

return '';
}

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

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

return user;
}

return User.fromJson({});
}
}
Loading