moved user profile to a widget

This commit is contained in:
shilangyu 2020-08-31 12:05:45 +02:00
parent dd06b79efa
commit 8b738bf5e5
4 changed files with 225 additions and 202 deletions

View File

@ -1,7 +1,11 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:lemmy_api_client/lemmy_api_client.dart';
import 'package:provider/provider.dart';
import 'pages/profile_tab.dart';
import 'stores/config_store.dart';
void main() {
@ -31,7 +35,8 @@ class MyApp extends StatelessWidget {
primarySwatch: ctx.watch<ConfigStore>().accentColor,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
home: UserProfileTab(User.fromJson(jsonDecode(
'''{"id":13917,"name":"shilangyu","preferred_username":null,"password_encrypted":"","email":"xmarcinmarcin@gmail.com","avatar":null,"admin":false,"banned":false,"published":"2020-08-23T07:13:23.229279","updated":"2020-08-29T21:11:11.508707","show_nsfw":true,"theme":"minty","default_sort_type":0,"default_listing_type":1,"lang":"browser","show_avatars":true,"send_notifications_to_email":false,"matrix_user_id":null,"actor_id":"https://dev.lemmy.ml/u/shilangyu","bio":null,"local":true,"private_key":null,"public_key":null,"last_refreshed_at":"2020-08-23T07:13:23.229279","banner":null}'''))),
);
},
);
@ -58,25 +63,25 @@ class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('You have pushed the button this many times:'),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('You have pushed the button this many times:'),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}

View File

@ -1,25 +1,18 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:intl/intl.dart';
import 'package:lemmy_api_client/lemmy_api_client.dart';
import 'package:timeago/timeago.dart' as timeago;
import '../widgets/user_profile.dart';
class UserProfileTab extends HookWidget {
final User user;
final Future<UserView> _userView;
UserProfileTab(this.user)
: _userView = LemmyApi('dev.lemmy.ml')
.v1
.search(q: user.name, type: SearchType.users, sort: SortType.active)
.then((res) => res.users[0]);
UserProfileTab(this.user);
@override
Widget build(BuildContext context) {
var theme = Theme.of(context);
var userViewSnap = useFuture(_userView);
return Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
@ -52,177 +45,7 @@ class UserProfileTab extends HookWidget {
)
],
),
body: Center(
child: Stack(
children: [
Image.network(
'https://c4.wallpaperflare.com/wallpaper/500/442/354/outrun-vaporwave-hd-wallpaper-preview.jpg'), // TODO: should be the banner
SafeArea(
child: Padding(
padding: const EdgeInsets.only(top: 60),
child: SizedBox(
width: double.infinity,
height: double.infinity,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(40)),
color: theme.scaffoldBackgroundColor,
),
),
),
),
),
SafeArea(
child: Column(
children: [
SizedBox(
width: 80,
height: 80,
child: Container(
decoration: BoxDecoration(
boxShadow: [
BoxShadow(blurRadius: 6, color: Colors.black54)
],
color: theme
.backgroundColor, // TODO: add avatar, not color
borderRadius: BorderRadius.all(Radius.circular(15)),
border: Border.all(color: Colors.white, width: 3),
),
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Text(
user.preferredUsername ?? user.name,
style: theme.textTheme.headline6,
),
),
Padding(
padding: const EdgeInsets.only(top: 4.0),
child: Text(
'@${user.name}@', // TODO: add instance host uri
style: theme.textTheme.caption,
),
),
Padding(
padding: const EdgeInsets.only(top: 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_badge(
context: context,
icon: Icons.comment,
text: '''
${NumberFormat.compact().format(userViewSnap.data?.numberOfPosts ?? 0)} Posts''',
loading: !userViewSnap.hasData,
),
Padding(
padding: const EdgeInsets.only(left: 16.0),
child: _badge(
context: context,
icon: Icons.comment,
text: '''
${NumberFormat.compact().format(userViewSnap.data?.numberOfPosts ?? 0)} Comments''',
loading: !userViewSnap.hasData,
),
),
],
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Text(
'Joined ${timeago.format(user.published)}',
style: theme.textTheme.bodyText1,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.cake,
size: 13,
),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text(
DateFormat('MMM dd, yyyy').format(user.published),
style: theme.textTheme.bodyText1,
),
),
],
),
Expanded(child: _tabs())
],
),
),
],
),
),
body: UserProfile(user),
);
}
Widget _badge(
{IconData icon, String text, bool loading, BuildContext context}) =>
Container(
decoration: BoxDecoration(
color: Theme.of(context).accentColor,
borderRadius: BorderRadius.all(Radius.circular(5)),
),
child: Padding(
padding: const EdgeInsets.all(4.0),
child: loading
? CircularProgressIndicator()
: Row(
children: [
Icon(icon, size: 15, color: Colors.white),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text(text, style: TextStyle(color: Colors.white)),
),
],
),
),
);
Widget _tabs() => DefaultTabController(
length: 3,
child: Column(
children: [
TabBar(
labelColor: Colors.black,
tabs: [
Tab(text: 'Posts'),
Tab(text: 'Comments'),
Tab(text: 'About'),
],
),
Expanded(
child: TabBarView(
children: [
Center(
child: Text(
'Posts',
style: const TextStyle(fontSize: 36),
)),
Center(
child: Text(
'Comments',
style: const TextStyle(fontSize: 36),
)),
if (user.bio == null)
Center(
child: Text(
'No bio.',
style: const TextStyle(fontStyle: FontStyle.italic),
),
)
else
Text(user.bio),
],
),
)
],
),
);
}

View File

@ -0,0 +1,195 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:intl/intl.dart';
import 'package:lemmy_api_client/lemmy_api_client.dart';
import 'package:timeago/timeago.dart' as timeago;
class UserProfile extends HookWidget {
final User user;
final Future<UserView> _userView;
UserProfile(this.user)
: _userView = LemmyApi('dev.lemmy.ml')
.v1
.search(q: user.name, type: SearchType.users, sort: SortType.active)
.then((res) => res.users[0]);
@override
Widget build(BuildContext context) {
var theme = Theme.of(context);
var userViewSnap = useFuture(_userView);
return Center(
child: Stack(
children: [
Image.network(
'https://c4.wallpaperflare.com/wallpaper/500/442/354/outrun-vaporwave-hd-wallpaper-preview.jpg'), // TODO: should be the banner
SafeArea(
child: Padding(
padding: const EdgeInsets.only(top: 60),
child: SizedBox(
width: double.infinity,
height: double.infinity,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(40)),
color: theme.scaffoldBackgroundColor,
),
),
),
),
),
SafeArea(
child: Column(
children: [
SizedBox(
width: 80,
height: 80,
child: Container(
decoration: BoxDecoration(
boxShadow: [
BoxShadow(blurRadius: 6, color: Colors.black54)
],
color:
theme.backgroundColor, // TODO: add avatar, not color
borderRadius: BorderRadius.all(Radius.circular(15)),
border: Border.all(color: Colors.white, width: 3),
),
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Text(
user.preferredUsername ?? user.name,
style: theme.textTheme.headline6,
),
),
Padding(
padding: const EdgeInsets.only(top: 4.0),
child: Text(
'@${user.name}@', // TODO: add instance host uri
style: theme.textTheme.caption,
),
),
Padding(
padding: const EdgeInsets.only(top: 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_badge(
context: context,
icon: Icons.comment,
text: '''
${NumberFormat.compact().format(userViewSnap.data?.numberOfPosts ?? 0)} Posts''',
loading: !userViewSnap.hasData,
),
Padding(
padding: const EdgeInsets.only(left: 16.0),
child: _badge(
context: context,
icon: Icons.comment,
text: '''
${NumberFormat.compact().format(userViewSnap.data?.numberOfPosts ?? 0)} Comments''',
loading: !userViewSnap.hasData,
),
),
],
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Text(
'Joined ${timeago.format(user.published)}',
style: theme.textTheme.bodyText1,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.cake,
size: 13,
),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text(
DateFormat('MMM dd, yyyy').format(user.published),
style: theme.textTheme.bodyText1,
),
),
],
),
Expanded(child: _tabs())
],
),
),
],
),
);
}
Widget _badge(
{IconData icon, String text, bool loading, BuildContext context}) =>
Container(
decoration: BoxDecoration(
color: Theme.of(context).accentColor,
borderRadius: BorderRadius.all(Radius.circular(5)),
),
child: Padding(
padding: const EdgeInsets.all(4.0),
child: loading
? CircularProgressIndicator()
: Row(
children: [
Icon(icon, size: 15, color: Colors.white),
Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Text(text, style: TextStyle(color: Colors.white)),
),
],
),
),
);
Widget _tabs() => DefaultTabController(
length: 3,
child: Column(
children: [
TabBar(
labelColor: Colors.black,
tabs: [
Tab(text: 'Posts'),
Tab(text: 'Comments'),
Tab(text: 'About'),
],
),
Expanded(
child: TabBarView(
children: [
Center(
child: Text(
'Posts',
style: const TextStyle(fontSize: 36),
)),
Center(
child: Text(
'Comments',
style: const TextStyle(fontSize: 36),
)),
if (user.bio == null)
Center(
child: Text(
'No bio.',
style: const TextStyle(fontStyle: FontStyle.italic),
),
)
else
Text(user.bio),
],
),
)
],
),
);
}