Skip to content

Commit 440946f

Browse files
committed
Implement pages
1 parent f9f50c4 commit 440946f

File tree

3 files changed

+253
-99
lines changed

3 files changed

+253
-99
lines changed

thread_app/lib/main.dart

Lines changed: 39 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,53 @@
11
import 'package:flutter/material.dart';
2+
import 'package:flutter_bloc/flutter_bloc.dart';
3+
import 'package:thread_app/pages/home_page.dart';
4+
import 'package:thread_app/pages/login_page.dart';
5+
import 'package:flutter/rendering.dart' show debugPaintSizeEnabled;
6+
import 'package:thread_app/pages/register_page.dart';
7+
import 'package:thread_app/services/user_service.dart';
8+
9+
import 'bloc/user_bloc/user_bloc.dart';
10+
import 'bloc/user_bloc/user_event.dart';
11+
import 'bloc/user_bloc/user_state.dart';
212

313
void main() {
4-
runApp(MyApp());
14+
debugPaintSizeEnabled = false;
15+
runApp(BlocProvider<UserBloc>(
16+
create: (context) {
17+
final authService = AuthService();
18+
return UserBloc(authenticationService: authService)
19+
..add(AuthenticationInit());
20+
},
21+
child: MyApp()
22+
));
523
}
624

725
class MyApp extends StatelessWidget {
8-
// This widget is the root of your application.
26+
927
@override
1028
Widget build(BuildContext context) {
1129
return MaterialApp(
12-
title: 'Flutter Demo',
13-
theme: ThemeData(
14-
// This is the theme of your application.
15-
//
16-
// Try running your application with "flutter run". You'll see the
17-
// application has a blue toolbar. Then, without quitting the app, try
18-
// changing the primarySwatch below to Colors.green and then invoke
19-
// "hot reload" (press "r" in the console where you ran "flutter run",
20-
// or simply save your changes to "hot reload" in a Flutter IDE).
21-
// Notice that the counter didn't reset back to zero; the application
22-
// is not restarted.
23-
primarySwatch: Colors.blue,
24-
),
25-
home: MyHomePage(title: 'Flutter Demo Home Page'),
26-
);
27-
}
28-
}
29-
30-
class MyHomePage extends StatefulWidget {
31-
MyHomePage({Key key, this.title}) : super(key: key);
32-
33-
// This widget is the home page of your application. It is stateful, meaning
34-
// that it has a State object (defined below) that contains fields that affect
35-
// how it looks.
36-
37-
// This class is the configuration for the state. It holds the values (in this
38-
// case the title) provided by the parent (in this case the App widget) and
39-
// used by the build method of the State. Fields in a Widget subclass are
40-
// always marked "final".
41-
42-
final String title;
43-
44-
@override
45-
_MyHomePageState createState() => _MyHomePageState();
46-
}
47-
48-
class _MyHomePageState extends State<MyHomePage> {
49-
int _counter = 0;
50-
51-
void _incrementCounter() {
52-
setState(() {
53-
// This call to setState tells the Flutter framework that something has
54-
// changed in this State, which causes it to rerun the build method below
55-
// so that the display can reflect the updated values. If we changed
56-
// _counter without calling setState(), then the build method would not be
57-
// called again, and so nothing would appear to happen.
58-
_counter++;
59-
});
60-
}
61-
62-
@override
63-
Widget build(BuildContext context) {
64-
// This method is rerun every time setState is called, for instance as done
65-
// by the _incrementCounter method above.
66-
//
67-
// The Flutter framework has been optimized to make rerunning build methods
68-
// fast, so that you can just rebuild anything that needs updating rather
69-
// than having to individually change instances of widgets.
70-
return Scaffold(
71-
appBar: AppBar(
72-
// Here we take the value from the MyHomePage object that was created by
73-
// the App.build method, and use it to set our appbar title.
74-
title: Text(widget.title),
75-
),
76-
body: Center(
77-
// Center is a layout widget. It takes a single child and positions it
78-
// in the middle of the parent.
79-
child: Column(
80-
// Column is also a layout widget. It takes a list of children and
81-
// arranges them vertically. By default, it sizes itself to fit its
82-
// children horizontally, and tries to be as tall as its parent.
83-
//
84-
// Invoke "debug painting" (press "p" in the console, choose the
85-
// "Toggle Debug Paint" action from the Flutter Inspector in Android
86-
// Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
87-
// to see the wireframe for each widget.
88-
//
89-
// Column has various properties to control how it sizes itself and
90-
// how it positions its children. Here we use mainAxisAlignment to
91-
// center the children vertically; the main axis here is the vertical
92-
// axis because Columns are vertical (the cross axis would be
93-
// horizontal).
94-
mainAxisAlignment: MainAxisAlignment.center,
95-
children: <Widget>[
96-
Text(
97-
'You have pushed the button this many times:',
98-
),
99-
Text(
100-
'$_counter',
101-
style: Theme.of(context).textTheme.headline4,
30+
title: 'Flutter Thread',
31+
home: BlocBuilder<UserBloc, UserState>(
32+
builder: (context, state) {
33+
if (state is AuthSuccess) {
34+
return HomePage();
35+
}
36+
if (state is LoginInitial || state is AuthBreak) {
37+
return LoginPage();
38+
}
39+
if (state is RegisterInitial) {
40+
return RegisterPage();
41+
}
42+
return Scaffold(
43+
body: Container(
44+
child: Center(
45+
child: CircularProgressIndicator()
46+
),
10247
),
103-
],
104-
),
48+
);
49+
},
10550
),
106-
floatingActionButton: FloatingActionButton(
107-
onPressed: _incrementCounter,
108-
tooltip: 'Increment',
109-
child: Icon(Icons.add),
110-
), // This trailing comma makes auto-formatting nicer for build methods.
11151
);
11252
}
11353
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:flutter_bloc/flutter_bloc.dart';
3+
import 'package:thread_app/bloc/comment_bloc/comment_bloc.dart';
4+
import 'package:thread_app/bloc/comment_bloc/comment_event.dart';
5+
import 'package:thread_app/services/comment_service.dart';
6+
import 'package:thread_app/widgets/comment_list.dart';
7+
import 'package:thread_app/widgets/components/comment_field.dart';
8+
import 'package:thread_app/widgets/components/post.dart';
9+
10+
class DetailsPage extends StatelessWidget {
11+
12+
final post;
13+
final currentUserId;
14+
15+
DetailsPage({this.post, this.currentUserId}): assert(post != null, currentUserId != null);
16+
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
17+
18+
@override
19+
Widget build(BuildContext context) {
20+
return BlocProvider<CommentBloc>(
21+
create: (context) {
22+
final commentService = CommentService();
23+
return CommentBloc(commentService: commentService)
24+
..add(CommentFetchEvent(
25+
userId: currentUserId,
26+
postId: post.id
27+
)
28+
);
29+
},
30+
child: Scaffold(
31+
key: _scaffoldKey,
32+
appBar: AppBar(
33+
title: Text('Post details'),
34+
),
35+
body: SingleChildScrollView(
36+
scrollDirection: Axis.vertical,
37+
physics: AlwaysScrollableScrollPhysics(),
38+
child: Column(
39+
mainAxisAlignment: MainAxisAlignment.start,
40+
children: <Widget>[
41+
Post(
42+
post: post,
43+
detailsDisable: 'true',
44+
),
45+
SizedBox(
46+
height: 10.0,
47+
),
48+
Container(
49+
alignment: Alignment.centerLeft,
50+
margin: EdgeInsets.only(
51+
left: 15.0
52+
),
53+
child: Text(
54+
'Comments',
55+
style: TextStyle(
56+
fontSize: 18.0,
57+
),
58+
),
59+
),
60+
Divider(),
61+
CommentList(
62+
currentUserId: currentUserId,
63+
),
64+
CommentField(
65+
postId: post.id,
66+
),
67+
],
68+
),
69+
),
70+
),
71+
);
72+
}
73+
}
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:flutter_bloc/flutter_bloc.dart';
3+
4+
import 'package:thread_app/bloc/post_bloc/post_bloc.dart';
5+
import 'package:thread_app/bloc/post_bloc/post_event.dart';
6+
import 'package:thread_app/bloc/post_bloc/post_state.dart';
7+
import 'package:thread_app/bloc/user_bloc/user_bloc.dart';
8+
import 'package:thread_app/bloc/user_bloc/user_event.dart';
9+
import 'package:thread_app/bloc/user_bloc/user_state.dart';
10+
import 'package:thread_app/helpers/image_helper.dart';
11+
import 'package:thread_app/pages/details_page.dart';
12+
import 'package:thread_app/services/post_service.dart';
13+
import 'package:thread_app/widgets/components/post_field.dart';
14+
import 'package:thread_app/widgets/components/switch.dart';
15+
import 'package:thread_app/widgets/post_list.dart';
16+
17+
class HomePage extends StatelessWidget {
18+
final postService = PostService();
19+
20+
@override
21+
Widget build(BuildContext context) {
22+
final UserState userState = BlocProvider.of<UserBloc>(context).state;
23+
return BlocProvider<PostBloc>(
24+
create: (context) {
25+
final postService = PostService();
26+
return PostBloc(postService: postService)
27+
..add(PostFetchEvent(
28+
userId: (userState as AuthSuccess).user.id
29+
)
30+
);
31+
},
32+
child: BlocListener<PostBloc, PostState>(
33+
listener: (context, state) async {
34+
if (state is PostDetailsState) {
35+
await Navigator.of(context).push(MaterialPageRoute(
36+
builder: (_) {
37+
return BlocProvider.value(
38+
value: context.read<PostBloc>(),
39+
child: DetailsPage(
40+
post: state.post,
41+
currentUserId: (userState as AuthSuccess).user.id,
42+
),
43+
);
44+
}
45+
)
46+
);
47+
BlocProvider.of<PostBloc>(context)
48+
.add(PostFetchEvent(
49+
userId: (userState as AuthSuccess).user.id
50+
));
51+
}
52+
},
53+
child: Scaffold(
54+
appBar: AppBar(
55+
leading: Padding(
56+
padding: const EdgeInsets.only(left: 15.0),
57+
child: CircleAvatar(
58+
backgroundImage: NetworkImage(
59+
getUserImgLink((userState as AuthSuccess).user.avatar)
60+
),
61+
),
62+
),
63+
title: Column(
64+
mainAxisAlignment: MainAxisAlignment.center,
65+
crossAxisAlignment: CrossAxisAlignment.start,
66+
children: [
67+
Text(
68+
(userState as AuthSuccess).user.username ?? '',
69+
style: TextStyle(
70+
color: Colors.white,
71+
fontSize: 18.0
72+
),
73+
),
74+
Text(
75+
(userState as AuthSuccess).user.userStatus ?? '',
76+
style: TextStyle(
77+
color: Colors.white,
78+
fontSize: 14.0
79+
),
80+
)
81+
],
82+
),
83+
actions: <Widget>[
84+
IconButton(
85+
visualDensity: VisualDensity(horizontal: -4.0, vertical: -4.0),
86+
padding: EdgeInsets.zero,
87+
icon: Icon(
88+
Icons.account_circle,
89+
color: Colors.white,
90+
),
91+
onPressed: () {
92+
93+
},
94+
),
95+
IconButton(
96+
icon: Icon(
97+
Icons.exit_to_app ,
98+
color: Colors.white,
99+
),
100+
onPressed: () {
101+
BlocProvider.of<UserBloc>(context)..add(UserLoggedOut());
102+
},
103+
),
104+
],
105+
),
106+
body: SingleChildScrollView(
107+
scrollDirection: Axis.vertical,
108+
physics: AlwaysScrollableScrollPhysics(),
109+
child: Column(
110+
crossAxisAlignment: CrossAxisAlignment.center,
111+
children: <Widget>[
112+
PostField(),
113+
SwitchElement(
114+
fieldName: 'Sort posts by date',
115+
type: 'date'
116+
),
117+
SwitchElement(
118+
fieldName: 'Sort posts by like count',
119+
type: 'likeCount'
120+
),
121+
SwitchElement(
122+
fieldName: 'Sort posts by dislike count',
123+
type: 'dislikeCount'
124+
),
125+
SwitchElement(
126+
fieldName: 'Filter posts by user',
127+
type: 'user'
128+
),
129+
Container (
130+
child: PostList(
131+
currentUserId: (userState as AuthSuccess).user.id,
132+
),
133+
),
134+
],
135+
),
136+
),
137+
),
138+
),
139+
);
140+
}
141+
}

0 commit comments

Comments
 (0)