Skip to content

Commit

Permalink
Merge pull request #26 from avuenja/14-adicionar-publicar-novo-conteúdo
Browse files Browse the repository at this point in the history
feat(content): criação de conteúdo pelo app
  • Loading branch information
avuenja authored Nov 26, 2022
2 parents c7916d8 + 63a9841 commit aac7933
Show file tree
Hide file tree
Showing 9 changed files with 282 additions and 22 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Isto irá rodar o projeto no seu emulador/simulador ou dispositivo real conectad
- [x] Gerencimaneto de conta
- [x] Criação de conta pelo App
- [ ] Resposta dos conteúdos
- [ ] Postagens de conteúdos
- [x] Postagens de conteúdos
- [ ] Visualização do perfil de outros usuários
- [ ] Favoritos (local database)
- [ ] Opção ler mais tarde (local database)
Expand Down
13 changes: 13 additions & 0 deletions lib/src/app.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
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/user.dart';
import 'package:tabnews/src/ui/layouts/tab.dart';
import 'package:tabnews/src/ui/pages/login.dart';
Expand All @@ -16,13 +18,24 @@ class App extends StatelessWidget {
lazy: false,
create: (_) => UserProvider(),
),
ChangeNotifierProvider(
lazy: false,
create: (_) => ContentProvider(),
),
],
child: MaterialApp(
title: 'TabNews',
debugShowCheckedModeBanner: false,
darkTheme: ThemeData.dark(),
theme: ThemeData(
primaryColor: Colors.black,
colorScheme: const ColorScheme.light(
primary: AppColors.primaryColor,
secondary: AppColors.primaryColor,
),
textSelectionTheme: TextSelectionThemeData(
selectionColor: Colors.grey.shade300,
),
),
home: Consumer<UserProvider>(
builder: (context, user, _) =>
Expand Down
48 changes: 48 additions & 0 deletions lib/src/providers/content.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import 'package:flutter/material.dart';

import 'package:tabnews/src/providers/user.dart';
import 'package:tabnews/src/services/api.dart';

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

final api = Api();

factory ContentProvider() {
return _instance;
}

ContentProvider._internal() {
_isLoading = false;
_isCreated = false;
}

late bool _isLoading;
bool get isLoading => _isLoading;

late bool _isCreated;
bool get isCreated => _isCreated;

void _loading(bool value) {
_isLoading = value;
notifyListeners();
}

void create(String title, String body, String source) async {
_loading(true);

var content = await api.postContent(
UserProvider().sessionId,
title,
body,
source,
);

if (content.id!.isNotEmpty) {
_isCreated = true;
}

_isLoading = false;
notifyListeners();
}
}
28 changes: 28 additions & 0 deletions lib/src/services/api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,32 @@ class Api {
throw Exception('Failed to load my contents');
}
}

Future<Content> postContent(
String token,
String title,
String body,
String source,
) async {
final response = await http.post(
Uri.parse(apiUrl),
headers: {
'Set-Cookie': 'session_id=$token',
'Cookie': 'session_id=$token',
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode({
'title': title,
'body': body,
'status': 'published',
source.isNotEmpty ? 'source_url' : source: null,
}),
);

if (response.statusCode == 201) {
return Content.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to create a new content');
}
}
}
163 changes: 163 additions & 0 deletions lib/src/ui/pages/new_content.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import 'package:flutter/material.dart';
import 'package:markdown_editable_textinput/format_markdown.dart';
import 'package:markdown_editable_textinput/markdown_text_input.dart';
import 'package:provider/provider.dart';

import 'package:tabnews/src/constants.dart';
import 'package:tabnews/src/providers/content.dart';
import 'package:tabnews/src/ui/layouts/page.dart';
import 'package:tabnews/src/ui/pages/my_contents.dart';
import 'package:tabnews/src/ui/widgets/markdown.dart';
import 'package:tabnews/src/utils/navigation.dart';

class NewContentPage extends StatefulWidget {
const NewContentPage({super.key});

@override
State<NewContentPage> createState() => _NewContentPageState();
}

class _NewContentPageState extends State<NewContentPage> {
TextEditingController titleTextController = TextEditingController();
TextEditingController bodyTextController = TextEditingController();
TextEditingController sourceTextController = TextEditingController();
final _formKey = GlobalKey<FormState>();

bool isViewMarkdown = false;

@override
void dispose() {
titleTextController.dispose();
bodyTextController.dispose();
sourceTextController.dispose();

super.dispose();
}

@override
Widget build(BuildContext context) {
return PageLayout(
onRefresh: () async {},
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
TextFormField(
cursorColor: AppColors.primaryColor,
decoration: const InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: AppColors.primaryColor,
width: 2.0,
),
),
hintText: 'Título',
),
controller: titleTextController,
),
const SizedBox(height: 15.0),
isViewMarkdown
? SizedBox(
height: 420.0,
child: MarkedownReader(body: bodyTextController.text),
)
: MarkdownTextInput(
maxLines: 20,
label: 'Conteúdo',
controller: bodyTextController,
actions: MarkdownType.values,
(value) {},
bodyTextController.text,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () {
setState(() {
isViewMarkdown = !isViewMarkdown;
});
},
child: Text(isViewMarkdown ? 'Escrever' : 'Visualizar'),
),
],
),
const SizedBox(height: 15.0),
TextFormField(
cursorColor: AppColors.primaryColor,
decoration: const InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: AppColors.primaryColor,
width: 2.0,
),
),
hintText: 'Fonte (opcional)',
),
controller: sourceTextController,
),
const SizedBox(height: 30.0),
Consumer<ContentProvider>(
builder: (context, provider, _) => ElevatedButton(
style: ButtonStyle(
elevation: MaterialStateProperty.all<double>(0.0),
backgroundColor: MaterialStateProperty.all<Color>(
AppColors.primaryColor.withOpacity(
provider.isLoading ? 0.5 : 1.0,
),
),
foregroundColor: MaterialStateProperty.all<Color>(
Colors.white,
),
shape: MaterialStateProperty.all<OutlinedBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4.0),
),
),
),
onPressed: provider.isLoading
? null
: () {
if (titleTextController.text.isEmpty ||
bodyTextController.text.isEmpty) {
return;
}

provider.create(
titleTextController.text,
bodyTextController.text,
sourceTextController.text,
);

ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text(
'Conteúdo publicado com sucesso!',
),
),
);

Navigation.pop(context);
Navigation.push(context, const MyContentsPage());
},
child: Text(
provider.isLoading ? 'Aguarde...' : 'Publicar',
style: const TextStyle().copyWith(
fontSize: 16.0,
),
),
),
),
],
),
),
),
),
);
}
}
7 changes: 4 additions & 3 deletions lib/src/ui/pages/profile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:provider/provider.dart';

import 'package:tabnews/src/providers/user.dart';
import 'package:tabnews/src/ui/pages/my_contents.dart';
import 'package:tabnews/src/ui/pages/new_content.dart';
import 'package:tabnews/src/ui/pages/profile_edit.dart';
import 'package:tabnews/src/utils/navigation.dart';

Expand Down Expand Up @@ -37,9 +38,9 @@ class _ProfilePageState extends State<ProfilePage> {
title: const Text('Meu conteúdo'),
),
const Divider(color: Colors.grey),
const ListTile(
onTap: null,
title: Text('Publicar novo conteúdo'),
ListTile(
onTap: () => Navigation.push(context, const NewContentPage()),
title: const Text('Publicar novo conteúdo'),
),
ListTile(
onTap: () => Navigation.push(context, ProfileEditPage()),
Expand Down
4 changes: 2 additions & 2 deletions lib/src/ui/widgets/markdown.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import 'package:markdown/markdown.dart' as md;

class MarkedownReader extends StatelessWidget {
final String body;
final ScrollController controller;
final ScrollController? controller;

const MarkedownReader({
super.key,
required this.body,
required this.controller,
this.controller,
});

@override
Expand Down
37 changes: 22 additions & 15 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.5"
effective_dart:
dependency: transitive
description:
name: effective_dart
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.2"
expandable:
dependency: transitive
description:
name: expandable
url: "https://pub.dartlang.org"
source: hosted
version: "5.0.1"
fake_async:
dependency: transitive
description:
Expand Down Expand Up @@ -107,13 +121,6 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
go_router:
dependency: "direct main"
description:
name: go_router
url: "https://pub.dartlang.org"
source: hosted
version: "5.2.0"
http:
dependency: "direct main"
description:
Expand Down Expand Up @@ -156,20 +163,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
logging:
dependency: transitive
description:
name: logging
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
markdown:
dependency: "direct main"
description:
name: markdown
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.1"
markdown_editable_textinput:
dependency: "direct main"
description:
name: markdown_editable_textinput
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
matcher:
dependency: transitive
description:
Expand Down Expand Up @@ -429,4 +436,4 @@ packages:
version: "6.1.0"
sdks:
dart: ">=2.18.4 <3.0.0"
flutter: ">=3.3.0"
flutter: ">=3.0.0"
Loading

0 comments on commit aac7933

Please sign in to comment.