Fakultas Ilmu Komputer UI

Verified Commit 55a97b04 authored by Muhammad Ariq Basyar's avatar Muhammad Ariq Basyar
Browse files

[GREEN] implemented new komentar model and finalize PBI 10

- new attribute on komentar model 'creator_picture'
- implemented viewable profile picture at profile and komentar
parent 34f55800
Pipeline #81203 passed with stages
in 14 minutes and 15 seconds
......@@ -27,7 +27,7 @@ class UserBloc {
if (response is DetailUserModel) {
userSink.add(NetworkModel.completed(response));
} else {
userSink.add(NetworkModel.error(response.toString()));
userSink.add(NetworkModel.error('Gagal untuk mendapatkan profile'));
}
}
......
......@@ -5,17 +5,24 @@ class BisaGoAppBar extends StatelessWidget implements PreferredSizeWidget {
final String title;
final List<Widget> actions;
final Widget leading;
final backgroundColor;
const BisaGoAppBar(
{this.title = 'bisaGo', this.actions = const [], this.leading, Key key})
{this.title = 'bisaGo',
this.actions = const [],
this.backgroundColor = greenPrimary,
this.leading,
Key key})
: super(key: key);
@override
final Size preferredSize = const Size.fromHeight(55);
@override
Widget build(BuildContext context) {
return AppBar(
elevation: 15,
centerTitle: true,
backgroundColor: greenPrimary,
backgroundColor: backgroundColor,
automaticallyImplyLeading: leading == null,
leading: leading,
title: Row(
......
......@@ -16,6 +16,8 @@ class KomentarPostingModel {
final String creator;
@JsonKey(name: 'creator_email')
final String creatorEmail;
@JsonKey(name: 'creator_picture')
final String creatorPicture;
@JsonKey(fromJson: CustomSerializer.stringToDateTime)
final DateTime created;
......@@ -24,6 +26,7 @@ class KomentarPostingModel {
this.deskripsi,
this.creator,
this.creatorEmail,
this.creatorPicture,
this.created,
});
......
......@@ -28,6 +28,7 @@ KomentarPostingModel _$KomentarPostingModelFromJson(Map<String, dynamic> json) {
deskripsi: json['deskripsi'] as String,
creator: json['creator'] as String,
creatorEmail: json['creator_email'] as String,
creatorPicture: json['creator_picture'] as String,
created: CustomSerializer.stringToDateTime(json['created'] as String),
);
}
......@@ -39,5 +40,6 @@ Map<String, dynamic> _$KomentarPostingModelToJson(
'deskripsi': instance.deskripsi,
'creator': instance.creator,
'creator_email': instance.creatorEmail,
'creator_picture': instance.creatorPicture,
'created': instance.created?.toIso8601String(),
};
......@@ -15,6 +15,8 @@ class KomentarPostingKegiatanModel {
final String creator;
@JsonKey(name: 'creator_email')
final String creatorEmail;
@JsonKey(name: 'creator_picture')
final String creatorPicture;
final String deskripsi;
@JsonKey(name: 'created', fromJson: _stringToDateTime)
final DateTime created;
......@@ -25,6 +27,7 @@ class KomentarPostingKegiatanModel {
this.deskripsi,
this.created,
this.creatorEmail,
this.creatorPicture,
});
factory KomentarPostingKegiatanModel.fromJson(Map<String, dynamic> json) =>
......
......@@ -31,6 +31,7 @@ KomentarPostingKegiatanModel _$KomentarPostingKegiatanModelFromJson(
deskripsi: json['deskripsi'] as String,
created: _stringToDateTime(json['created'] as String),
creatorEmail: json['creator_email'] as String,
creatorPicture: json['creator_picture'] as String,
);
}
......@@ -40,6 +41,7 @@ Map<String, dynamic> _$KomentarPostingKegiatanModelToJson(
'id': instance.id,
'creator': instance.creator,
'creator_email': instance.creatorEmail,
'creator_picture': instance.creatorPicture,
'deskripsi': instance.deskripsi,
'created': instance.created?.toIso8601String(),
};
......@@ -2,7 +2,9 @@ import 'dart:async';
import 'package:bisaGo/config/strings.dart';
import 'package:bisaGo/model/lokasi.dart';
import 'package:bisaGo/model/user.dart';
import 'package:bisaGo/page/profile/profile.dart';
import 'package:bisaGo/page/profile/profile_picture.dart';
import 'package:bisaGo/page/updateInformasi/update_informasi.dart';
import 'package:bisaGo/repository/dynamic_links_service_repository.dart';
import 'package:bisaGo/utils/share_utils.dart';
......@@ -318,6 +320,7 @@ class _DetailPostPageState extends State<DetailPostPage> {
k.created,
k.deskripsi,
k.creatorEmail,
k.creatorPicture,
),
)
.toList());
......@@ -486,34 +489,18 @@ class _DetailPostPageState extends State<DetailPostPage> {
DateTime date,
String description,
String email,
String foto,
) {
final user = DetailUserModel()
..email = email
..foto = foto
..name = name;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
children: <Widget>[
InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => Profile(
email: email,
isPublic: true,
),
),
);
},
child: CircleAvatar(
backgroundColor: greenPrimary,
child: Text(
_creatorInitials(name),
style: const TextStyle(
color: Colors.white,
),
),
),
),
ProfilePicture(user, redirectToDetailProfile: true),
Padding(
padding: const EdgeInsets.all(regularSpace),
child: Column(
......@@ -557,16 +544,6 @@ class _DetailPostPageState extends State<DetailPostPage> {
);
}
String _creatorInitials(String name) {
if (name.isEmpty) return '';
var initials = '';
for (final i in name.split(' ')) {
initials += '${i[0].toUpperCase()}';
}
if (initials.length > 2) return initials.substring(0, 2);
return initials;
}
Widget _showIfContains(String disabilitas) {
String imageUrl;
switch (disabilitas) {
......
......@@ -3,6 +3,7 @@ import 'dart:io';
import 'package:bisaGo/bloc/user_bloc.dart';
import 'package:bisaGo/component/image_holder.dart';
import 'package:bisaGo/utils/datetime_utils.dart';
import 'package:bisaGo/utils/profile_utils.dart';
import 'package:dio/dio.dart';
import 'package:bisaGo/component/bisago_appbar.dart';
......@@ -136,30 +137,28 @@ class _EditProfileState extends State<EditProfile> {
CircleAvatar(
key: Key('Avatar ${detailUserModel.name.split(' ')[0]}'),
radius: 50,
backgroundColor: white,
child: ClipOval(
child: (_image != null)
? SizedBox(
width: 100,
height: 100,
child: Image.file(_image, fit: BoxFit.cover),
)
: ((_imageUrl) == null
? Text(detailUserModel.name.substring(0, 1),
style: const TextStyle(
fontSize: 45,
fontWeight: FontWeight.w900,
color: darkGreen,
fontFamily: 'Comfortaa',
))
: SizedBox(
width: 100,
height: 100,
child: ImageHolder(
url: _imageUrl,
),
)),
),
backgroundColor: greenPrimary,
child: (_image != null)
? ClipOval(
child: AspectRatio(
aspectRatio: 1,
child: Image.file(_image, fit: BoxFit.cover),
))
: ((_imageUrl) == null
? Text(getNameInitials(detailUserModel.name),
style: const TextStyle(
fontSize: 45,
fontWeight: FontWeight.w900,
color: Colors.white,
fontFamily: 'Comfortaa',
))
: ClipOval(
child: AspectRatio(
aspectRatio: 1,
child: ImageHolder(
url: _imageUrl,
),
))),
),
Padding(
padding:
......@@ -404,7 +403,7 @@ class _EditProfileState extends State<EditProfile> {
}
Future<void> updateUser(UpdateUserModel updateUserModel, String email) async {
_bloc = UserBloc(email:email);
_bloc = UserBloc(email: email);
final updatedUser = await _bloc.updateUser(updateUserModel);
if (updatedUser != null) {
successDialog(context);
......
import 'package:bisaGo/component/bisago_appbar.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class FullScreenImage extends StatelessWidget {
final Widget body;
FullScreenImage({Key key, this.body}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
appBar: BisaGoAppBar(
title: '',
backgroundColor: Colors.transparent,
),
body: Center(
child: body ?? Container(),
),
);
}
}
import 'package:bisaGo/bloc/user_bloc.dart';
import 'package:bisaGo/component/bisago_appbar.dart';
import 'package:bisaGo/component/image_holder.dart';
import 'package:bisaGo/config/styles.dart';
import 'package:bisaGo/model/user.dart';
import 'package:bisaGo/network/data/network_model.dart';
import 'package:bisaGo/page/profile/edit_profile.dart';
import 'package:bisaGo/page/profile/profile_picture.dart';
import 'package:bisaGo/utils/datetime_utils.dart';
import 'package:flutter/material.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
const rahasia = Color(0xFF585858);
class Profile extends StatefulWidget {
final String email;
final bool isPublic;
......@@ -88,7 +90,7 @@ class _ProfileState extends State<Profile> {
);
case Status.error:
return Center(
child: Text(snapshot.data.toString()),
child: Text(snapshot.data.message.toString()),
);
}
}
......@@ -120,28 +122,8 @@ class _ProfileState extends State<Profile> {
padding: const EdgeInsets.only(
bottom: doubleSpace,
),
child: CircleAvatar(
key: Key('Avatar ${user.name.split(' ')[0]}'),
radius: 50,
backgroundColor: white,
child: ClipOval(
child: (user.foto != null)
? SizedBox(
width: 100,
height: 100,
child: ImageHolder(
url: user.foto,
),
)
: Text(user.name.substring(0, 1),
style: const TextStyle(
fontSize: 45,
fontWeight: FontWeight.w900,
color: darkGreen,
fontFamily: 'Comfortaa',
)),
),
),
child: ProfilePicture(user,
radius: 50, fontSize: 50 * 0.7, previewAble: true),
),
if (!widget.isPublic)
Text(
......@@ -159,7 +141,7 @@ class _ProfileState extends State<Profile> {
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Colors.white,
color: rahasia,
fontFamily: 'Comfortaa',
),
textAlign: TextAlign.center,
......@@ -216,11 +198,12 @@ class _ProfileState extends State<Profile> {
size: 28,
color: darkGreen,
),
title: Text(tanggalLahir,
title: Text(
tanggalLahir,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w500,
color: Colors.black,
color: rahasia,
fontFamily: 'Comfortaa',
),
textAlign: TextAlign.left,
......@@ -237,7 +220,7 @@ class _ProfileState extends State<Profile> {
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w500,
color: Colors.black,
color: rahasia,
fontFamily: 'Comfortaa',
),
textAlign: TextAlign.left,
......@@ -314,7 +297,7 @@ class _ProfileState extends State<Profile> {
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w500,
color: Colors.black,
color: rahasia,
fontFamily: 'Comfortaa',
),
textAlign: TextAlign.left,
......
import 'dart:math';
import 'package:bisaGo/component/image_holder.dart';
import 'package:bisaGo/config/styles.dart';
import 'package:bisaGo/model/user.dart';
import 'package:bisaGo/page/profile/full_screen_image.dart';
import 'package:bisaGo/page/profile/profile.dart';
import 'package:bisaGo/utils/profile_utils.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:photo_view/photo_view.dart';
class ProfilePicture extends StatelessWidget {
final DetailUserModel user;
final bool redirectToDetailProfile;
final bool previewAble;
final double radius;
final double fontSize;
final Color color;
final Color backgroundColor;
final String fontFamily;
final FontWeight fontWeight;
ProfilePicture(this.user,
{Key key,
this.redirectToDetailProfile = false,
this.previewAble = false,
this.radius = 20,
this.fontSize = 14,
this.color = Colors.white,
this.backgroundColor = greenPrimary,
this.fontFamily = 'Comfortaa',
this.fontWeight = FontWeight.w900})
: super(key: key);
@override
Widget build(BuildContext context) {
return InkWell(
onTap: () {
if (redirectToDetailProfile) {
_toDetailProfile(context);
} else if (previewAble) {
_toPreviewImage(context);
}
},
child: _makeAvatar(),
);
}
Widget _makeAvatar({double radius, double fontSize}) {
return CircleAvatar(
key: Key('Avatar ${user.name.split(' ')[0]}'),
radius: radius ?? this.radius,
backgroundColor: user.foto != null ? Colors.white : backgroundColor,
child: (user.foto != null)
? ClipOval(
child: AspectRatio(
aspectRatio: 1,
child: ImageHolder(
url: user.foto,
),
),
)
: Text(getNameInitials(user.name),
style: TextStyle(
fontSize: fontSize ?? this.fontSize,
fontWeight: fontWeight,
color: color,
fontFamily: fontFamily,
)),
);
}
Widget _getFullPicture(BuildContext context) {
if (user.foto != null) {
return PhotoView(
imageProvider: NetworkImage(user.foto),
loadingBuilder: (context, event) => const Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(greenPrimary),
)),
);
}
var width = MediaQuery.of(context).size.width;
var height = MediaQuery.of(context).size.height;
var minWidthHeight = min(width, height);
return _makeAvatar(radius: minWidthHeight, fontSize: minWidthHeight * 0.5);
}
void _toDetailProfile(BuildContext context) =>
_toSomewhere(context, (_) => Profile(email: user.email, isPublic: true));
void _toPreviewImage(BuildContext context) => _toSomewhere(
context,
(_) => FullScreenImage(
body: _getFullPicture(context),
));
void _toSomewhere(
BuildContext context, Function(BuildContext context) builder) =>
Navigator.push(
context, MaterialPageRoute(builder: (context) => builder(context)));
}
String getNameInitials(String name) {
if (name.isEmpty) return '';
final initials = name.split(' ').map((e) => e[0]).join().toUpperCase();
if (initials.length > 2) return initials.substring(0, 2);
return initials;
}
......@@ -58,6 +58,7 @@ dependencies:
firebase_messaging: ^8.0.0-dev.15
carousel_slider: ^3.0.0
flushbar: ^1.10.4
photo_view: ^0.11.1
dev_dependencies:
flutter_test:
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment