diff --git a/android/app/build.gradle b/android/app/build.gradle
index 949d735c2e09caad3767de420457f69704a9ffc7..13a35987ea5b3251dbfb11c3cd4691666676675d 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -83,7 +83,9 @@ dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
- implementation 'com.google.firebase:firebase-analytics:17.2.2'
+ implementation 'com.google.firebase:firebase-analytics:'
+ implementation 'com.google.firebase:firebase-messaging:'
+ implementation 'com.google.firebase:firebase-bom:27.0.0'
}
apply plugin: 'com.google.gms.google-services'
\ No newline at end of file
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 1f97511f590b7b1544051a848826375aa519b607..a5e2d872446dcba91f284c1a290bcdf91e5e2376 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -39,6 +39,10 @@
+
+
+
+
@@ -47,5 +51,13 @@
android:value="2" />
+
+
+
+
diff --git a/android/app/src/main/res/mipmap-hdpi/transparent_icon.png b/android/app/src/main/res/mipmap-hdpi/transparent_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..f8fddc349c3a2e79088ca668cc9455ba3f3ae59e
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/transparent_icon.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/transparent_icon.png b/android/app/src/main/res/mipmap-mdpi/transparent_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..f8fddc349c3a2e79088ca668cc9455ba3f3ae59e
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/transparent_icon.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/transparent_icon.png b/android/app/src/main/res/mipmap-xhdpi/transparent_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..f8fddc349c3a2e79088ca668cc9455ba3f3ae59e
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/transparent_icon.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/transparent_icon.png b/android/app/src/main/res/mipmap-xxhdpi/transparent_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..f8fddc349c3a2e79088ca668cc9455ba3f3ae59e
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/transparent_icon.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/transparent_icon.png b/android/app/src/main/res/mipmap-xxxhdpi/transparent_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..f8fddc349c3a2e79088ca668cc9455ba3f3ae59e
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/transparent_icon.png differ
diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml
index 87856b3c9cb06fa2bb9d86addf32a3c87fa2d872..368aefd74099a743712b2993745612fe34bb2c5e 100644
--- a/android/app/src/main/res/values/colors.xml
+++ b/android/app/src/main/res/values/colors.xml
@@ -1,3 +1,4 @@
#3A903A
+ #3A903A
diff --git a/android/fastlane/metadata/android/id/changelogs/changelogs.txt b/android/fastlane/metadata/android/id/changelogs/changelogs.txt
index 659bd954cefc3eb64aba4567f954bb3e78a70e18..ba07351967ac3878978a5ff5011ae77056a734ca 100644
--- a/android/fastlane/metadata/android/id/changelogs/changelogs.txt
+++ b/android/fastlane/metadata/android/id/changelogs/changelogs.txt
@@ -1,20 +1,23 @@
+3.5.0:
+- Pengguna dapat mengganti foto profil
+
+3.4.0:
+- Notifikasi pengguna untuk komentar baru
+
3.3.0:
-- New feature for add kegiatan
-- Fix bugs
+- Kegiatan disabilitas di suatu lokasi
+- Perbaikan bugs
3.2.1:
-- Fix cant update fasilitas
+- Perbaikan masalah update fasilitas
3.2.0:
-- New feature share fasilitas as a link
+- Tersedia fitur membagikan informasi fasilitas/kegiatan disabilitas kepada orang lain
3.1.2:
-- Fix google oauth
+- Perbaikan masuk dengan Google
3.1.1:
-- Add dialog to turn on Location services upon starting the app
-- New feature for layanan search
-- Add feature to upload image for a fasilitas straight from the camera
-- Add default image for facilities
-- Add search history feature
-- Now all fields are required in edit profile
+- Tersedia fitur pencarian layanan
+- Tersedia pilihan kamera ketika menambahkan gambar fasilitas
+- Tersedia fitur riwayat pencarian
diff --git a/lib/bloc/cloud_messaging_bloc.dart b/lib/bloc/cloud_messaging_bloc.dart
new file mode 100644
index 0000000000000000000000000000000000000000..b91d3807ed2b8cfc56b8e8746c6ed3613207d87c
--- /dev/null
+++ b/lib/bloc/cloud_messaging_bloc.dart
@@ -0,0 +1,26 @@
+import 'package:bisaGo/repository/cloud_messaging_repository.dart';
+import 'package:get_it/get_it.dart';
+import 'package:http/http.dart';
+
+class CloudMessagingBloc {
+ CloudMessagingRepository _cloudMessagingRepository;
+
+ CloudMessagingBloc() {
+ _cloudMessagingRepository =
+ GetIt.instance.get();
+ }
+
+ Future sendFCMToken(
+ String fcmToken,
+ String token,
+ ) async {
+ try {
+ return await _cloudMessagingRepository.sendFCMToken(
+ fcmToken,
+ token,
+ );
+ } catch (e) {
+ return Response('Failed to add komentar', 400);
+ }
+ }
+}
diff --git a/lib/bloc/new_user_bloc.dart b/lib/bloc/new_user_bloc.dart
deleted file mode 100644
index 90b1b2dc860f0b618efc1e309ef8baa26401fc7e..0000000000000000000000000000000000000000
--- a/lib/bloc/new_user_bloc.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-import 'dart:async';
-
-import 'package:bisaGo/model/new_user.dart';
-import 'package:bisaGo/network/data/network_model.dart';
-import 'package:bisaGo/repository/user_repository.dart';
-import 'package:get_it/get_it.dart';
-import 'package:http/http.dart';
-
-class NewUserBloc {
- UserRepository _userRepository;
- StreamController _userController;
-
- NewUserBloc() {
- _userController = StreamController>();
- _userRepository = GetIt.instance.get();
- }
-
- Future registerNewUser(NewUser newUser) async {
- try {
- return await _userRepository.createUser(newUser);
- } catch (_) {
- return Response('Failed to register user', 400);
- }
- }
-
- Future updateUser(NewUser newUser) async {
- try {
- return await _userRepository.updateUser(newUser);
- } catch (_) {
- return Response('Failed to update user', 400);
- }
- }
-
- void dispose() {
- _userController?.close();
- }
-}
diff --git a/lib/bloc/user_bloc.dart b/lib/bloc/user_bloc.dart
index b6b155495f76894e5dc4ed6d0d015125b6af78d4..3ff261e757868bb830c20504f0264cc88758ee23 100644
--- a/lib/bloc/user_bloc.dart
+++ b/lib/bloc/user_bloc.dart
@@ -8,39 +8,54 @@ import 'package:get_it/get_it.dart';
class UserBloc {
UserRepository _userRepository;
StreamController _userController;
- List userFromApi;
+ String email;
- StreamSink> get userSink => _userController.sink;
- Stream> get userStream => _userController.stream;
+ StreamSink> get userSink =>
+ _userController.sink;
- UserBloc(String email) {
- _userController = StreamController>();
+ Stream> get userStream =>
+ _userController.stream;
+
+ UserBloc({this.email}) {
+ _userController = StreamController>();
_userRepository = GetIt.instance.get();
- fetchUserDetail(email);
}
- Future fetchUserDetail(String email) async {
+ Future fetchUserDetail() async {
userSink.add(NetworkModel.loading('Getting user'));
+ final response = await getUserDetail(email);
+ if (response is DetailUserModel) {
+ userSink.add(NetworkModel.completed(response));
+ } else {
+ userSink.add(NetworkModel.error('Gagal untuk mendapatkan profile'));
+ }
+ }
+
+ Future getUserDetail(String email) async {
try {
- final userResponse = await _userRepository.fetchUserDetail(email);
- userFromApi = List.from(userResponse.user);
- userSink.add(NetworkModel.completed(userResponse));
+ return await _userRepository.fetchUserDetail(email);
} catch (e) {
- if (!_userController.isClosed) {
- userSink.add(NetworkModel.error(e.toString()));
- }
+ return e;
}
}
- Future fetchUser(String email) async {
+ Future updateUser(UpdateUserModel updateUser) async {
try {
- await fetchUserDetail(email);
- return userFromApi.first;
- } catch (e) {
+ return await _userRepository.updateUser(updateUser, email);
+ } catch (_) {
return null;
}
}
+ Future registerNewUser(RegisterUserModel registerUserModel) async {
+ try {
+ await _userRepository.registerUser(registerUserModel);
+ return true;
+ } catch (_) {
+ return false;
+ }
+ }
+
void dispose() {
_userController?.close();
}
diff --git a/lib/component/bisago_appbar.dart b/lib/component/bisago_appbar.dart
index fdf8b479254dd3e77c502f20b47b654d7706528c..fbd07f49cd6fea0f79f9f1b5c934847493dec912 100644
--- a/lib/component/bisago_appbar.dart
+++ b/lib/component/bisago_appbar.dart
@@ -5,17 +5,24 @@ class BisaGoAppBar extends StatelessWidget implements PreferredSizeWidget {
final String title;
final List 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(
diff --git a/lib/component/bisago_drawer.dart b/lib/component/bisago_drawer.dart
index 7e45592100ef351c75abc7c430f30c47a3a6df6c..05a78c6b2a6802e88b946f9cedbb9a2b89161622 100644
--- a/lib/component/bisago_drawer.dart
+++ b/lib/component/bisago_drawer.dart
@@ -1,3 +1,5 @@
+import 'dart:convert';
+
import 'package:bisaGo/page/informasi/list_sekolah.dart';
import 'package:bisaGo/page/profile/profile.dart';
import 'package:bisaGo/page/tentang_disabilitas/tentang_disabilitas.dart';
@@ -168,7 +170,8 @@ class BisaGoDrawer extends StatelessWidget {
if (sharedPreferences.getString('token') == null) {
return 'Selamat datang ke BisaGo!';
} else {
- return sharedPreferences.getString('email');
+ final userJson = jsonDecode(sharedPreferences.getString('user'));
+ return userJson['email'];
}
}
diff --git a/lib/get_it.dart b/lib/get_it.dart
index aec9e26401134f3efe2a7fb71aa355c296723af8..18eee1bab5e09e5cc8f09d930607bbca50fca5ea 100644
--- a/lib/get_it.dart
+++ b/lib/get_it.dart
@@ -1,3 +1,4 @@
+import 'package:bisaGo/repository/cloud_messaging_repository.dart';
import 'package:bisaGo/repository/kegiatan_repository.dart';
import 'package:bisaGo/repository/kegiatan_terdekat_repository.dart';
import 'package:bisaGo/repository/komentar_posting_kegiatan_repository.dart';
@@ -26,8 +27,8 @@ class AppGetIt {
() => KomentarPostingRepository());
_getIt.registerLazySingleton(
() => KomentarPostingKegiatanRepository());
- _getIt.registerLazySingleton(
- () => LokasiRepository());
+ _getIt
+ .registerLazySingleton(() => LokasiRepository());
_getIt.registerLazySingleton(
() => LayananRepository());
_getIt.registerLazySingleton(
@@ -36,5 +37,7 @@ class AppGetIt {
() => KegiatanTerdekatRepository());
_getIt.registerLazySingleton(
() => DynamicLinksServiceRepository());
+ _getIt.registerLazySingleton(
+ () => CloudMessagingRepository());
}
}
diff --git a/lib/main.dart b/lib/main.dart
index 1d165eef77fee709f6375504b06482b9e8eb1c24..aa484a721f869e7d5b49ed157fad3b804874eac0 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,4 +1,5 @@
-import 'package:bisaGo/get_it.dart';
+import 'package:firebase_core/firebase_core.dart';
+import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:bisaGo/app.dart';
import 'package:intl/date_symbol_data_local.dart';
@@ -6,14 +7,24 @@ import 'package:intl/intl.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'flavor/flavor.dart';
import 'globalnetwork.dart';
+import 'package:bisaGo/get_it.dart';
+
+Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
+ // If you're going to use other Firebase services in the background, such as Firestore,
+ // make sure you call `initializeApp` before using other Firebase services.
+ await Firebase.initializeApp();
+
+ print('Handling a background message: ${message.messageId}');
+}
Future main() async {
AppGetIt().initialize();
await DotEnv().load('.env');
getDioInstance('build');
await initializeDateFormatting('id_ID', null);
+ FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
Intl.defaultLocale = 'id_ID';
dio.options.receiveTimeout = 15000;
- ApiFlavor.flavor = BuildFlavor.production.toString();
+ ApiFlavor.flavor = BuildFlavor.development.toString();
runApp(BisaGo());
}
diff --git a/lib/main_dev.dart b/lib/main_dev.dart
index 564a4551c4cf8d531231ab10c220db35194bc332..aa484a721f869e7d5b49ed157fad3b804874eac0 100644
--- a/lib/main_dev.dart
+++ b/lib/main_dev.dart
@@ -1,3 +1,5 @@
+import 'package:firebase_core/firebase_core.dart';
+import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:bisaGo/app.dart';
import 'package:intl/date_symbol_data_local.dart';
@@ -7,11 +9,20 @@ import 'flavor/flavor.dart';
import 'globalnetwork.dart';
import 'package:bisaGo/get_it.dart';
+Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
+ // If you're going to use other Firebase services in the background, such as Firestore,
+ // make sure you call `initializeApp` before using other Firebase services.
+ await Firebase.initializeApp();
+
+ print('Handling a background message: ${message.messageId}');
+}
+
Future main() async {
AppGetIt().initialize();
await DotEnv().load('.env');
getDioInstance('build');
await initializeDateFormatting('id_ID', null);
+ FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
Intl.defaultLocale = 'id_ID';
dio.options.receiveTimeout = 15000;
ApiFlavor.flavor = BuildFlavor.development.toString();
diff --git a/lib/main_staging.dart b/lib/main_staging.dart
index 564412ca6f2eb6921c61d526856607902958ba8f..aa484a721f869e7d5b49ed157fad3b804874eac0 100644
--- a/lib/main_staging.dart
+++ b/lib/main_staging.dart
@@ -1,3 +1,5 @@
+import 'package:firebase_core/firebase_core.dart';
+import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:bisaGo/app.dart';
import 'package:intl/date_symbol_data_local.dart';
@@ -7,13 +9,22 @@ import 'flavor/flavor.dart';
import 'globalnetwork.dart';
import 'package:bisaGo/get_it.dart';
+Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
+ // If you're going to use other Firebase services in the background, such as Firestore,
+ // make sure you call `initializeApp` before using other Firebase services.
+ await Firebase.initializeApp();
+
+ print('Handling a background message: ${message.messageId}');
+}
+
Future main() async {
AppGetIt().initialize();
await DotEnv().load('.env');
getDioInstance('build');
await initializeDateFormatting('id_ID', null);
+ FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
Intl.defaultLocale = 'id_ID';
dio.options.receiveTimeout = 15000;
- ApiFlavor.flavor = BuildFlavor.staging.toString();
+ ApiFlavor.flavor = BuildFlavor.development.toString();
runApp(BisaGo());
-}
\ No newline at end of file
+}
diff --git a/lib/model/kegiatan.dart b/lib/model/kegiatan.dart
index 6531c58998b7951e5f1c63827f2077150cf0c9dc..eab87fdbff76b8563ff014c7af213ceb4fcd5f5e 100644
--- a/lib/model/kegiatan.dart
+++ b/lib/model/kegiatan.dart
@@ -17,6 +17,8 @@ class KegiatanModel {
String creator;
@JsonKey(name: 'nama_kegiatan')
String namaKegiatan;
+ @JsonKey(name: 'creator_email')
+ String creatorEmail;
String penyelenggara;
String deskripsi;
@JsonKey(name: 'nama_kontak')
@@ -38,6 +40,7 @@ class KegiatanModel {
this.placeId,
this.creator,
this.namaKegiatan,
+ this.creatorEmail,
this.penyelenggara,
this.deskripsi,
this.namaKontak,
@@ -50,6 +53,7 @@ class KegiatanModel {
}
);
- factory KegiatanModel.fromJson(Map json) => _$KegiatanModelFromJson(json);
+ factory KegiatanModel.fromJson(Map json) =>
+ _$KegiatanModelFromJson(json);
Map toJson() => _$KegiatanModelToJson(this);
}
diff --git a/lib/model/kegiatan.g.dart b/lib/model/kegiatan.g.dart
index 90f5b03675b09281b7da1fc4d5865e535482739a..ca5b091e16a313df7783423a74097c86482702ec 100644
--- a/lib/model/kegiatan.g.dart
+++ b/lib/model/kegiatan.g.dart
@@ -27,6 +27,7 @@ KegiatanModel _$KegiatanModelFromJson(Map json) {
placeId: json['place_id'] as String,
creator: json['creator'] as String,
namaKegiatan: json['nama_kegiatan'] as String,
+ creatorEmail: json['creator_email'] as String,
penyelenggara: json['penyelenggara'] as String,
deskripsi: json['deskripsi'] as String,
namaKontak: json['nama_kontak'] as String,
@@ -45,6 +46,7 @@ Map _$KegiatanModelToJson(KegiatanModel instance) =>
'place_id': instance.placeId,
'creator': instance.creator,
'nama_kegiatan': instance.namaKegiatan,
+ 'creator_email': instance.creatorEmail,
'penyelenggara': instance.penyelenggara,
'deskripsi': instance.deskripsi,
'nama_kontak': instance.namaKontak,
diff --git a/lib/model/komentar.dart b/lib/model/komentar.dart
index 3a65b937ef7684aaa124dea0b4c219c3a122e323..68bbeb11479ffb6188cec756b05d60653ddc7047 100644
--- a/lib/model/komentar.dart
+++ b/lib/model/komentar.dart
@@ -1,5 +1,5 @@
+import 'package:intl/intl.dart';
import 'package:json_annotation/json_annotation.dart';
-import 'package:bisaGo/config/custom_serializer.dart';
part 'komentar.g.dart';
@@ -16,7 +16,7 @@ class KomentarModel {
final String namaLokasi;
final String deskripsi;
final String creator;
- @JsonKey(name: 'date_time', fromJson: CustomSerializer.stringToDateTime)
+ @JsonKey(name: 'date_time', fromJson: _stringToDateTime)
final DateTime dateTime;
final String tag;
final List disabilitas;
@@ -25,22 +25,30 @@ class KomentarModel {
final bool isVerified;
final int jumlah;
final int rating;
+ @JsonKey(name: 'creator_email')
+ final String creatorEmail;
- KomentarModel(
- {this.id,
- this.namaLokasi,
- this.deskripsi,
- this.creator,
- this.dateTime,
- this.tag,
- this.disabilitas,
- this.image,
- this.isVerified,
- this.jumlah,
- this.rating});
+ KomentarModel({
+ this.id,
+ this.namaLokasi,
+ this.deskripsi,
+ this.creator,
+ this.dateTime,
+ this.tag,
+ this.disabilitas,
+ this.image,
+ this.isVerified,
+ this.jumlah,
+ this.rating,
+ this.creatorEmail,
+ });
factory KomentarModel.fromJson(Map json) =>
_$KomentarModelFromJson(json);
Map toJson() => _$KomentarModelToJson(this);
}
+
+DateTime _stringToDateTime(String date) {
+ return DateFormat('dd-MM-yyyy hh:mm').parse(date);
+}
diff --git a/lib/model/komentar.g.dart b/lib/model/komentar.g.dart
index 2755f33196eff8652199696fab3f835093960152..85c8277c07b90464571780d033cfa8bb9f3b81b1 100644
--- a/lib/model/komentar.g.dart
+++ b/lib/model/komentar.g.dart
@@ -27,7 +27,7 @@ KomentarModel _$KomentarModelFromJson(Map json) {
namaLokasi: json['nama_lokasi'] as String,
deskripsi: json['deskripsi'] as String,
creator: json['creator'] as String,
- dateTime: CustomSerializer.stringToDateTime(json['date_time'] as String),
+ dateTime: _stringToDateTime(json['date_time'] as String),
tag: json['tag'] as String,
disabilitas:
(json['disabilitas'] as List)?.map((e) => e as String)?.toList(),
@@ -35,6 +35,7 @@ KomentarModel _$KomentarModelFromJson(Map json) {
isVerified: json['is_verified'] as bool,
jumlah: json['jumlah'] as int,
rating: json['rating'] as int,
+ creatorEmail: json['creator_email'] as String,
);
}
@@ -51,4 +52,5 @@ Map _$KomentarModelToJson(KomentarModel instance) =>
'is_verified': instance.isVerified,
'jumlah': instance.jumlah,
'rating': instance.rating,
+ 'creator_email': instance.creatorEmail,
};
diff --git a/lib/model/komentar_posting.dart b/lib/model/komentar_posting.dart
index 04ffea66b0f7e81b692aeb063c34950447605436..fa4e889c3f7c66c078887f6a7582971c8dca4d20 100644
--- a/lib/model/komentar_posting.dart
+++ b/lib/model/komentar_posting.dart
@@ -1,5 +1,5 @@
+import 'package:intl/intl.dart';
import 'package:json_annotation/json_annotation.dart';
-import 'package:bisaGo/config/custom_serializer.dart';
part 'komentar_posting.g.dart';
@@ -14,13 +14,28 @@ class KomentarPostingModel {
final int id;
final String deskripsi;
final String creator;
- @JsonKey(name: 'date_time', fromJson: CustomSerializer.stringToDateTime)
- final DateTime dateTime;
+ @JsonKey(name: 'creator_email')
+ final String creatorEmail;
+ @JsonKey(name: 'creator_picture')
+ final String creatorPicture;
+ @JsonKey(fromJson: _stringToDateTime)
+ final DateTime created;
- KomentarPostingModel({this.id, this.deskripsi, this.creator, this.dateTime});
+ KomentarPostingModel({
+ this.id,
+ this.deskripsi,
+ this.creator,
+ this.creatorEmail,
+ this.creatorPicture,
+ this.created,
+ });
factory KomentarPostingModel.fromJson(Map json) =>
_$KomentarPostingModelFromJson(json);
Map toJson() => _$KomentarPostingModelToJson(this);
}
+
+DateTime _stringToDateTime(String date) {
+ return DateFormat('dd-MM-yyyy hh:mm').parse(date);
+}
diff --git a/lib/model/komentar_posting.g.dart b/lib/model/komentar_posting.g.dart
index 565bcd3708949851186ff00919f57aa4691bedf5..9a6805131ffcba578a385289e40a38b6a228b3f8 100644
--- a/lib/model/komentar_posting.g.dart
+++ b/lib/model/komentar_posting.g.dart
@@ -27,7 +27,9 @@ KomentarPostingModel _$KomentarPostingModelFromJson(Map json) {
id: json['id'] as int,
deskripsi: json['deskripsi'] as String,
creator: json['creator'] as String,
- dateTime: CustomSerializer.stringToDateTime(json['date_time'] as String),
+ creatorEmail: json['creator_email'] as String,
+ creatorPicture: json['creator_picture'] as String,
+ created: _stringToDateTime(json['created'] as String),
);
}
@@ -37,5 +39,7 @@ Map _$KomentarPostingModelToJson(
'id': instance.id,
'deskripsi': instance.deskripsi,
'creator': instance.creator,
- 'date_time': instance.dateTime?.toIso8601String(),
+ 'creator_email': instance.creatorEmail,
+ 'creator_picture': instance.creatorPicture,
+ 'created': instance.created?.toIso8601String(),
};
diff --git a/lib/model/komentar_posting_kegiatan.dart b/lib/model/komentar_posting_kegiatan.dart
index 78e18d736f1dce8e066d0f562a7b6588dd3ab2a7..1057154e1bd739c6dc12d6ab8b45d669e3f79d21 100644
--- a/lib/model/komentar_posting_kegiatan.dart
+++ b/lib/model/komentar_posting_kegiatan.dart
@@ -1,5 +1,5 @@
-import 'package:json_annotation/json_annotation.dart';
import 'package:bisaGo/config/custom_serializer.dart';
+import 'package:json_annotation/json_annotation.dart';
part 'komentar_posting_kegiatan.g.dart';
@@ -13,16 +13,22 @@ class KomentarPostingKegiatanList {
class KomentarPostingKegiatanModel {
final int id;
final String creator;
+ @JsonKey(name: 'creator_email')
+ final String creatorEmail;
+ @JsonKey(name: 'creator_picture')
+ final String creatorPicture;
final String deskripsi;
@JsonKey(name: 'created', fromJson: CustomSerializer.stringToDateTime)
final DateTime created;
- KomentarPostingKegiatanModel(
- {this.id,
- this.creator,
- this.deskripsi,
- this.created}
- );
+ KomentarPostingKegiatanModel({
+ this.id,
+ this.creator,
+ this.deskripsi,
+ this.created,
+ this.creatorEmail,
+ this.creatorPicture,
+ });
factory KomentarPostingKegiatanModel.fromJson(Map json) =>
_$KomentarPostingKegiatanModelFromJson(json);
diff --git a/lib/model/komentar_posting_kegiatan.g.dart b/lib/model/komentar_posting_kegiatan.g.dart
index 3b73f1a6ad4fa7c4a655ef055826935ec7a33754..0a08508d3af3ee216c9e244b32c66b3efb3f25d7 100644
--- a/lib/model/komentar_posting_kegiatan.g.dart
+++ b/lib/model/komentar_posting_kegiatan.g.dart
@@ -30,6 +30,8 @@ KomentarPostingKegiatanModel _$KomentarPostingKegiatanModelFromJson(
creator: json['creator'] as String,
deskripsi: json['deskripsi'] as String,
created: CustomSerializer.stringToDateTime(json['created'] as String),
+ creatorEmail: json['creator_email'] as String,
+ creatorPicture: json['creator_picture'] as String,
);
}
@@ -38,6 +40,8 @@ Map _$KomentarPostingKegiatanModelToJson(
{
'id': instance.id,
'creator': instance.creator,
+ 'creator_email': instance.creatorEmail,
+ 'creator_picture': instance.creatorPicture,
'deskripsi': instance.deskripsi,
'created': instance.created?.toIso8601String(),
};
diff --git a/lib/model/new_user.dart b/lib/model/new_user.dart
deleted file mode 100644
index 34c1a52228652f44096a6cb4e91aa322449c5926..0000000000000000000000000000000000000000
--- a/lib/model/new_user.dart
+++ /dev/null
@@ -1,34 +0,0 @@
-import 'package:json_annotation/json_annotation.dart';
-part 'new_user.g.dart';
-
-@JsonSerializable()
-class NewUser {
- String name;
- String password;
- String email;
- @JsonKey(name: 'tanggal_lahir')
- String tanggalLahir;
- @JsonKey(name: 'jenis_kelamin')
- String jenisKelamin;
- String disabilitas;
- String pekerjaan;
- String alamat;
- @JsonKey(name: 'phone_number')
- String phoneNumber;
-
- NewUser({
- this.name,
- this.password,
- this.email,
- this.tanggalLahir,
- this.jenisKelamin,
- this.disabilitas,
- this.pekerjaan,
- this.alamat,
- this.phoneNumber,
- });
-
- factory NewUser.fromJson(Map json) =>
- _$NewUserFromJson(json);
- Map toJson() => _$NewUserToJson(this);
-}
diff --git a/lib/model/new_user.g.dart b/lib/model/new_user.g.dart
deleted file mode 100644
index 28a0aa445ddfccbbeac2b57a29d76bb798eb178b..0000000000000000000000000000000000000000
--- a/lib/model/new_user.g.dart
+++ /dev/null
@@ -1,33 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'new_user.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-NewUser _$NewUserFromJson(Map json) {
- return NewUser(
- name: json['name'] as String,
- password: json['password'] as String,
- email: json['email'] as String,
- tanggalLahir: json['tanggal_lahir'] as String,
- jenisKelamin: json['jenis_kelamin'] as String,
- disabilitas: json['disabilitas'] as String,
- pekerjaan: json['pekerjaan'] as String,
- alamat: json['alamat'] as String,
- phoneNumber: json['phone_number'] as String,
- );
-}
-
-Map _$NewUserToJson(NewUser instance) => {
- 'name': instance.name,
- 'password': instance.password,
- 'email': instance.email,
- 'tanggal_lahir': instance.tanggalLahir,
- 'jenis_kelamin': instance.jenisKelamin,
- 'disabilitas': instance.disabilitas,
- 'pekerjaan': instance.pekerjaan,
- 'alamat': instance.alamat,
- 'phone_number': instance.phoneNumber,
- };
diff --git a/lib/model/user.dart b/lib/model/user.dart
index 09a6a653c0a57a614f4c014364cfb233ace5f575..ae19bea0a37bae2cb0f690381bbd999f33bef5b3 100644
--- a/lib/model/user.dart
+++ b/lib/model/user.dart
@@ -1,18 +1,11 @@
+import 'dart:ui';
+
import 'package:json_annotation/json_annotation.dart';
-part 'user.g.dart';
-@JsonSerializable()
-class User {
- final List user;
- User(this.user);
-}
+part 'user.g.dart';
-@JsonSerializable()
-class UserModel {
- bool is_login;
- String username;
+abstract class BaseUserModel {
String name;
- String email;
@JsonKey(name: 'tanggal_lahir')
String tanggalLahir;
@JsonKey(name: 'phone_number')
@@ -22,22 +15,144 @@ class UserModel {
String disabilitas;
String pekerjaan;
String alamat;
- String token;
-
- UserModel(
- {this.is_login,
- this.username,
- this.name,
- this.email,
- this.tanggalLahir,
- this.phoneNumber,
- this.jenisKelamin,
- this.disabilitas,
- this.pekerjaan,
- this.alamat,
- this.token});
-
- factory UserModel.fromJson(Map json) =>
- _$UserModelFromJson(json);
- Map toJson() => _$UserModelToJson(this);
+ dynamic foto;
+ @JsonKey(name: 'organisasi_komunitas')
+ String organisasiKomunitas;
+
+ BaseUserModel({
+ this.name,
+ this.tanggalLahir,
+ this.phoneNumber,
+ this.jenisKelamin,
+ this.disabilitas,
+ this.pekerjaan,
+ this.alamat,
+ this.foto,
+ this.organisasiKomunitas,
+ });
+}
+
+@JsonSerializable()
+class RegisterUserModel extends BaseUserModel {
+ String email;
+ String password;
+
+ RegisterUserModel({
+ this.email,
+ this.password,
+ name,
+ tanggalLahir,
+ phoneNumber,
+ jenisKelamin,
+ disabilitas,
+ pekerjaan,
+ alamat,
+ foto,
+ organisasiKomunitas,
+ }) : super(
+ name: name,
+ tanggalLahir: tanggalLahir,
+ phoneNumber: phoneNumber,
+ jenisKelamin: jenisKelamin,
+ disabilitas: disabilitas,
+ pekerjaan: pekerjaan,
+ alamat: alamat,
+ foto: foto,
+ organisasiKomunitas: organisasiKomunitas);
+
+ factory RegisterUserModel.fromJson(Map json) =>
+ _$RegisterUserModelFromJson(json);
+
+ Map toJson() => _$RegisterUserModelToJson(this);
+}
+
+@JsonSerializable()
+class UpdateUserModel extends BaseUserModel {
+ bool seen;
+
+ UpdateUserModel({
+ this.seen,
+ name,
+ tanggalLahir,
+ phoneNumber,
+ jenisKelamin,
+ disabilitas,
+ pekerjaan,
+ alamat,
+ foto,
+ organisasiKomunitas,
+ }) : super(
+ name: name,
+ tanggalLahir: tanggalLahir,
+ phoneNumber: phoneNumber,
+ jenisKelamin: jenisKelamin,
+ disabilitas: disabilitas,
+ pekerjaan: pekerjaan,
+ alamat: alamat,
+ foto: foto,
+ organisasiKomunitas: organisasiKomunitas);
+
+ factory UpdateUserModel.fromJson(Map json) =>
+ _$UpdateUserModelFromJson(json);
+
+ Map toJson() => _$UpdateUserModelToJson(this);
+}
+
+@JsonSerializable()
+class DetailUserModel extends BaseUserModel {
+ String username;
+ String email;
+ bool seen;
+ @JsonKey(name: 'hidden_fields')
+ List hiddenFields;
+ @JsonKey(name: 'hidden_fields_verbose')
+ List hiddenFieldsVerbose;
+ @JsonKey(name: 'can_see_hidden_fields')
+ bool canSeeHiddenFields;
+ @JsonKey(name: 'hidden_fields_color')
+ String hiddenFieldsColor;
+
+ DetailUserModel({
+ this.username,
+ this.email,
+ this.seen,
+ this.hiddenFields,
+ this.hiddenFieldsVerbose,
+ this.canSeeHiddenFields,
+ this.hiddenFieldsColor,
+ name,
+ tanggalLahir,
+ phoneNumber,
+ jenisKelamin,
+ disabilitas,
+ pekerjaan,
+ alamat,
+ foto,
+ organisasiKomunitas,
+ }) : super(
+ name: name,
+ tanggalLahir: tanggalLahir,
+ phoneNumber: phoneNumber,
+ jenisKelamin: jenisKelamin,
+ disabilitas: disabilitas,
+ pekerjaan: pekerjaan,
+ alamat: alamat,
+ foto: foto,
+ organisasiKomunitas: organisasiKomunitas);
+
+ UpdateUserModel toUpdateUserModel() {
+ var thisData = toJson();
+ return UpdateUserModel.fromJson(thisData);
+ }
+
+ Color getHiddenFieldsColor() {
+ final strColor = hiddenFieldsColor.replaceAll('#', '0xff');
+ final hexColor = int.parse(strColor);
+ return Color(hexColor);
+ }
+
+ factory DetailUserModel.fromJson(Map json) =>
+ _$DetailUserModelFromJson(json);
+
+ Map toJson() => _$DetailUserModelToJson(this);
}
diff --git a/lib/model/user.g.dart b/lib/model/user.g.dart
index c3527bc4bf1810c8db88ec791e305a541e5eb3c3..27c2d4b155061f51665f5500008f87e9386a79ce 100644
--- a/lib/model/user.g.dart
+++ b/lib/model/user.g.dart
@@ -6,45 +6,106 @@ part of 'user.dart';
// JsonSerializableGenerator
// **************************************************************************
-User _$UserFromJson(Map json) {
- return User(
- (json['user'] as List)
- ?.map((e) =>
- e == null ? null : UserModel.fromJson(e as Map))
- ?.toList(),
+RegisterUserModel _$RegisterUserModelFromJson(Map json) {
+ return RegisterUserModel(
+ email: json['email'] as String,
+ password: json['password'] as String,
+ name: json['name'],
+ tanggalLahir: json['tanggal_lahir'],
+ phoneNumber: json['phone_number'],
+ jenisKelamin: json['jenis_kelamin'],
+ disabilitas: json['disabilitas'],
+ pekerjaan: json['pekerjaan'],
+ alamat: json['alamat'],
+ foto: json['foto'],
+ organisasiKomunitas: json['organisasi_komunitas'],
);
}
-Map _$UserToJson(User instance) => {
- 'user': instance.user,
+Map _$RegisterUserModelToJson(RegisterUserModel instance) =>
+ {
+ 'name': instance.name,
+ 'tanggal_lahir': instance.tanggalLahir,
+ 'phone_number': instance.phoneNumber,
+ 'jenis_kelamin': instance.jenisKelamin,
+ 'disabilitas': instance.disabilitas,
+ 'pekerjaan': instance.pekerjaan,
+ 'alamat': instance.alamat,
+ 'foto': instance.foto,
+ 'organisasi_komunitas': instance.organisasiKomunitas,
+ 'email': instance.email,
+ 'password': instance.password,
};
-UserModel _$UserModelFromJson(Map json) {
- return UserModel(
- is_login: json['is_login'] as bool,
+UpdateUserModel _$UpdateUserModelFromJson(Map json) {
+ return UpdateUserModel(
+ seen: json['seen'] as bool,
+ name: json['name'],
+ tanggalLahir: json['tanggal_lahir'],
+ phoneNumber: json['phone_number'],
+ jenisKelamin: json['jenis_kelamin'],
+ disabilitas: json['disabilitas'],
+ pekerjaan: json['pekerjaan'],
+ alamat: json['alamat'],
+ foto: json['foto'],
+ organisasiKomunitas: json['organisasi_komunitas'],
+ );
+}
+
+Map _$UpdateUserModelToJson(UpdateUserModel instance) =>
+ {
+ 'name': instance.name,
+ 'tanggal_lahir': instance.tanggalLahir,
+ 'phone_number': instance.phoneNumber,
+ 'jenis_kelamin': instance.jenisKelamin,
+ 'disabilitas': instance.disabilitas,
+ 'pekerjaan': instance.pekerjaan,
+ 'alamat': instance.alamat,
+ 'foto': instance.foto,
+ 'organisasi_komunitas': instance.organisasiKomunitas,
+ 'seen': instance.seen,
+ };
+
+DetailUserModel _$DetailUserModelFromJson(Map json) {
+ return DetailUserModel(
username: json['username'] as String,
- name: json['name'] as String,
email: json['email'] as String,
- tanggalLahir: json['tanggal_lahir'] as String,
- phoneNumber: json['phone_number'] as String,
- jenisKelamin: json['jenis_kelamin'] as String,
- disabilitas: json['disabilitas'] as String,
- pekerjaan: json['pekerjaan'] as String,
- alamat: json['alamat'] as String,
- token: json['token'] as String,
+ seen: json['seen'] as bool,
+ hiddenFields:
+ (json['hidden_fields'] as List)?.map((e) => e as String)?.toList(),
+ hiddenFieldsVerbose: (json['hidden_fields_verbose'] as List)
+ ?.map((e) => e as String)
+ ?.toList(),
+ canSeeHiddenFields: json['can_see_hidden_fields'] as bool,
+ hiddenFieldsColor: json['hidden_fields_color'] as String,
+ name: json['name'],
+ tanggalLahir: json['tanggal_lahir'],
+ phoneNumber: json['phone_number'],
+ jenisKelamin: json['jenis_kelamin'],
+ disabilitas: json['disabilitas'],
+ pekerjaan: json['pekerjaan'],
+ alamat: json['alamat'],
+ foto: json['foto'],
+ organisasiKomunitas: json['organisasi_komunitas'],
);
}
-Map _$UserModelToJson(UserModel instance) => {
- 'is_login': instance.is_login,
- 'username': instance.username,
+Map _$DetailUserModelToJson(DetailUserModel instance) =>
+ {
'name': instance.name,
- 'email': instance.email,
'tanggal_lahir': instance.tanggalLahir,
'phone_number': instance.phoneNumber,
'jenis_kelamin': instance.jenisKelamin,
'disabilitas': instance.disabilitas,
'pekerjaan': instance.pekerjaan,
'alamat': instance.alamat,
- 'token': instance.token,
+ 'foto': instance.foto,
+ 'organisasi_komunitas': instance.organisasiKomunitas,
+ 'username': instance.username,
+ 'email': instance.email,
+ 'seen': instance.seen,
+ 'hidden_fields': instance.hiddenFields,
+ 'hidden_fields_verbose': instance.hiddenFieldsVerbose,
+ 'can_see_hidden_fields': instance.canSeeHiddenFields,
+ 'hidden_fields_color': instance.hiddenFieldsColor,
};
diff --git a/lib/network/network_interface.dart b/lib/network/network_interface.dart
index 4641b1db3322ac1aee24513536d4526d4eb1854e..8bf08982a802e74187a6d2a4b5140115f59b2129 100644
--- a/lib/network/network_interface.dart
+++ b/lib/network/network_interface.dart
@@ -7,6 +7,10 @@ import 'package:bisaGo/flavor/flavor.dart';
import 'package:shared_preferences/shared_preferences.dart';
class NetworkInterface {
+ NetworkInterface() {
+ dio.options.headers['content-type'] = 'application/json';
+ }
+
Future post({
String url,
Map bodyParams,
@@ -15,10 +19,7 @@ class NetworkInterface {
}) async {
var responseJson;
try {
- final sharedPreferences = await SharedPreferences.getInstance();
- dio.options.headers['Authorization'] =
- 'Token ${sharedPreferences.getString('token')}';
- dio.options.headers['content-type'] = 'application/json';
+ await setToken(isLogin);
final response = await dio.post(
'${ApiFlavor.getBaseUrl()}$url',
data: formData ? FormData.fromMap(bodyParams) : json.encode(bodyParams),
@@ -40,12 +41,7 @@ class NetworkInterface {
}) async {
var responseJson;
try {
- if (isLogin) {
- final sharedPreferences = await SharedPreferences.getInstance();
- dio.options.headers['Authorization'] =
- 'Token ${sharedPreferences.getString('token')}';
- }
- dio.options.headers['content-type'] = 'application/json';
+ await setToken(isLogin);
final response = await dio.put(
'${ApiFlavor.getBaseUrl()}$url',
data: formData ? FormData.fromMap(bodyParams) : json.encode(bodyParams),
@@ -67,7 +63,7 @@ class NetworkInterface {
}) async {
var responseJson;
try {
- dio.options.headers['content-type'] = 'application/json';
+ await setToken(isLogin);
final response = await dio.get(
'${ApiFlavor.getBaseUrl()}$url',
);
@@ -80,6 +76,16 @@ class NetworkInterface {
return responseJson;
}
+ Future setToken(bool isLogin) async {
+ if (isLogin) {
+ final sharedPreferences = await SharedPreferences.getInstance();
+ dio.options.headers['Authorization'] =
+ 'Token ${sharedPreferences.getString('token')}';
+ } else {
+ dio.options.headers.remove('Authorization');
+ }
+ }
+
dynamic _response(Response response) {
switch (response.statusCode) {
case 200:
diff --git a/lib/page/dashboard/dashboard.dart b/lib/page/dashboard/dashboard.dart
index 1acec41f29a21ebf97a7cb48269c623a538b9e50..fbc815b6f6f99f9b82e592fe824c80122c6d0a67 100644
--- a/lib/page/dashboard/dashboard.dart
+++ b/lib/page/dashboard/dashboard.dart
@@ -1,3 +1,4 @@
+import 'package:bisaGo/bloc/cloud_messaging_bloc.dart';
import 'package:bisaGo/bloc/lokasi_response_bloc.dart';
import 'package:bisaGo/model/komentar.dart';
import 'package:bisaGo/model/lokasi.dart';
@@ -11,7 +12,10 @@ import 'package:bisaGo/page/filter_fasilitas/postingan/detail_post.dart';
import 'package:bisaGo/repository/komentar_repository.dart';
import 'package:bisaGo/utils/custom_dashboard_location_button.dart';
import 'package:bisaGo/utils/location_turn_on_dialog.dart';
+import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_dynamic_links/firebase_dynamic_links.dart';
+import 'package:firebase_messaging/firebase_messaging.dart';
+import 'package:flushbar/flushbar.dart';
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:geolocator/geolocator.dart';
@@ -21,6 +25,9 @@ import 'package:bisaGo/component/bisago_drawer.dart';
import 'package:bisaGo/config/styles.dart';
import 'package:bisaGo/page/pencarian/pencarian.dart';
import 'package:google_maps_webservice/places.dart';
+import 'package:shared_preferences/shared_preferences.dart';
+
+import '../filter_fasilitas/postingan/detail_post.dart';
class Dashboard extends StatefulWidget {
const Dashboard({Key key}) : super(key: key);
@@ -37,6 +44,13 @@ class DashboardState extends State {
LokasiResponseBloc bloc = LokasiResponseBloc();
KegiatanTerdekatBloc blocKegiatanTerdekat = KegiatanTerdekatBloc();
+ CloudMessagingBloc cloudMessagingBloc = CloudMessagingBloc();
+
+ FirebaseMessaging _firebaseMessaging;
+
+ bool _initialized = false;
+
+ DateTime _lastNotification;
@override
void initState() {
@@ -45,6 +59,71 @@ class DashboardState extends State {
geolocator = Geolocator()..forceAndroidLocationManager;
initDynamicLinks();
setInitialLocation();
+
+ if (!_initialized) {
+ _initialized = true;
+ _setupFirebase();
+ }
+ }
+
+ void _setupFirebase() async {
+ await Firebase.initializeApp();
+ _firebaseMessaging = FirebaseMessaging.instance;
+
+ FirebaseMessaging.onMessage.listen((RemoteMessage message) {
+ final now = DateTime.now();
+
+ if (_lastNotification != null &&
+ _lastNotification.add(Duration(seconds: 10)).isAfter(now)) return;
+
+ _lastNotification = now;
+ final data = message.data;
+ final String msg = data['message'];
+ final String title = data['title'];
+ Flushbar(
+ title: title,
+ message: msg,
+ duration: Duration(seconds: 8),
+ backgroundColor: Color(0xFF003566),
+ onTap: (_) {
+ if (data['type'] == 'fasilitas') {
+ final String placeId = data['place_id'];
+ final id = int.parse(data['id']);
+ _navigateToDetailFasilitasPage(context, placeId, id);
+ } else if (data['type'] == 'kegiatan') {
+ final String placeId = data['place_id'];
+ final id = int.parse(data['id']);
+ _navigateToDetailKegiatanPage(context, placeId, id);
+ }
+ },
+ flushbarStyle: FlushbarStyle.GROUNDED,
+ flushbarPosition: FlushbarPosition.TOP,
+ ).show(context);
+ });
+
+ FirebaseMessaging.onMessageOpenedApp.listen((message) {
+ final data = message.data;
+ if (data['type'] == 'fasilitas') {
+ final String placeId = data['place_id'];
+ final id = int.parse(data['id']);
+ _navigateToDetailFasilitasPage(context, placeId, id);
+ } else if (data['type'] == 'kegiatan') {
+ final String placeId = data['place_id'];
+ final id = int.parse(data['id']);
+ _navigateToDetailKegiatanPage(context, placeId, id);
+ }
+ });
+
+ _requestFCMToken();
+ }
+
+ void _requestFCMToken() async {
+ final fcmToken = await _firebaseMessaging.getToken();
+ final sharedPreferences = await SharedPreferences.getInstance();
+ final token = sharedPreferences.getString('token');
+ if (token != null) {
+ await cloudMessagingBloc.sendFCMToken(fcmToken, token);
+ }
}
void _navigateToPencarianPage(BuildContext context) {
diff --git a/lib/page/filter_fasilitas/kegiatan.dart b/lib/page/filter_fasilitas/kegiatan.dart
index 666c0908de95d88dbe195dfe4e860e93489b209f..ded35a4529d35a33e6e5aca7591387d7463ffe27 100644
--- a/lib/page/filter_fasilitas/kegiatan.dart
+++ b/lib/page/filter_fasilitas/kegiatan.dart
@@ -29,6 +29,7 @@ class _KegiatanState extends State {
id: widget.kegiatan.id,
placeId: widget.kegiatan.placeId,
creator: widget.kegiatan.creator,
+ creatorEmail: widget.kegiatan.creatorEmail,
namaKegiatan: widget.kegiatan.namaKegiatan,
penyelenggara: widget.kegiatan.penyelenggara,
deskripsi: widget.kegiatan.deskripsi,
@@ -150,5 +151,5 @@ class _KegiatanState extends State {
],
),
));
- }
+ }
}
\ No newline at end of file
diff --git a/lib/page/filter_fasilitas/komentar.dart b/lib/page/filter_fasilitas/komentar.dart
index dda5b47d5792cef6a99c83e83467bf2c74443918..216554970c05b6306cddb618ef9e995c37a5cf37 100644
--- a/lib/page/filter_fasilitas/komentar.dart
+++ b/lib/page/filter_fasilitas/komentar.dart
@@ -37,7 +37,7 @@ class _KomentarState extends State {
return InkWell(
key: Key('Fasilitas ${fasilitas[widget.komentar.tag]}'),
onTap: () {
- Navigator.of(context).pushReplacement(MaterialPageRoute(
+ Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => DetailPostPage(
lokasi: widget.lokasi,
komentar: KomentarModel(
@@ -51,6 +51,7 @@ class _KomentarState extends State {
tag: widget.komentar.tag,
disabilitas: widget.komentar.disabilitas,
jumlah: widget.komentar.jumlah,
+ creatorEmail: widget.komentar.creatorEmail,
),
)));
},
diff --git a/lib/page/filter_fasilitas/postingan/detail_post.dart b/lib/page/filter_fasilitas/postingan/detail_post.dart
index 4077643a61b54d62a82cd4774a099b12d2f9f0a4..98e8dd7285c9d948d5f1b1305b79865d8dfb6a22 100644
--- a/lib/page/filter_fasilitas/postingan/detail_post.dart
+++ b/lib/page/filter_fasilitas/postingan/detail_post.dart
@@ -2,7 +2,9 @@ import 'dart:async';
import 'package:bisaGo/config/strings.dart';
import 'package:bisaGo/model/lokasi.dart';
-import 'package:bisaGo/page/filter_fasilitas/fasilitas.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';
@@ -25,9 +27,11 @@ import 'package:shared_preferences/shared_preferences.dart';
class DetailPostPage extends StatefulWidget {
final Lokasi lokasi;
final KomentarModel komentar;
+
const DetailPostPage(
{@required this.komentar, @required this.lokasi, Key key})
: super(key: key);
+
@override
_DetailPostPageState createState() => _DetailPostPageState();
}
@@ -42,6 +46,7 @@ class _DetailPostPageState extends State {
int dislike;
int alreadyLikeFlag;
int alreadyDislikeFlag;
+
@override
void initState() {
alreadyLikeFlag = 0;
@@ -54,196 +59,201 @@ class _DetailPostPageState extends State {
@override
Widget build(BuildContext context) {
var namaLokasi = widget.komentar.namaLokasi ?? 'Invalid Lokasi Name';
- return WillPopScope(
- onWillPop: () => Navigator.of(context).pushReplacement(MaterialPageRoute(
- builder: (BuildContext context) => Fasilitas(
- lokasi: widget.lokasi,
- ))),
- child: Scaffold(
- appBar: BisaGoAppBar(
- title: namaLokasi,
- key: Key('appbar-text-$namaLokasi'),
- actions: [
- InkWell(
- onTap: () async {
- final link = await DynamicLinksServiceRepository()
- .createDynamicLinkForFasilitas(
- widget.komentar.id,
- widget.lokasi.placeId,
- );
- await Share.share(ShareUtils.getFormattedMessageFasilitas(
- widget.komentar, widget.lokasi, link));
- },
- child: const Padding(
- padding: EdgeInsets.all(doubleSpace),
- child: Icon(Icons.share),
- ),
+ return Scaffold(
+ appBar: BisaGoAppBar(
+ title: namaLokasi,
+ key: Key('appbar-text-$namaLokasi'),
+ actions: [
+ InkWell(
+ onTap: () async {
+ final link = await DynamicLinksServiceRepository()
+ .createDynamicLinkForFasilitas(
+ widget.komentar.id,
+ widget.lokasi.placeId,
+ );
+ await Share.share(ShareUtils.getFormattedMessageFasilitas(
+ widget.komentar, widget.lokasi, link));
+ },
+ child: const Padding(
+ padding: EdgeInsets.all(doubleSpace),
+ child: Icon(Icons.share),
),
- ],
- ),
- body: SingleChildScrollView(
- child: Column(
- children: [
- Container(
- key: const Key('Text Jenis Fasilitas'),
- margin: const EdgeInsets.symmetric(
- vertical: 10.0, horizontal: 15.0),
- alignment: Alignment.centerLeft,
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Container(
- width: MediaQuery.of(context).size.width * 0.6,
- child: Text(
- fasilitas[widget.komentar.tag],
- style: const TextStyle(
- fontSize: 28,
- fontWeight: FontWeight.w800,
- letterSpacing: -0.3,
- color: Colors.black,
- fontFamily: 'Comfortaa',
- ),
+ ),
+ ],
+ ),
+ body: SingleChildScrollView(
+ child: Column(
+ children: [
+ Container(
+ key: const Key('Text Jenis Fasilitas'),
+ margin:
+ const EdgeInsets.symmetric(vertical: 10.0, horizontal: 15.0),
+ alignment: Alignment.centerLeft,
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Container(
+ width: MediaQuery.of(context).size.width * 0.6,
+ child: Text(
+ fasilitas[widget.komentar.tag],
+ style: const TextStyle(
+ fontSize: 28,
+ fontWeight: FontWeight.w800,
+ letterSpacing: -0.3,
+ color: Colors.black,
+ fontFamily: 'Comfortaa',
),
),
- PopupMenuButton(
- key: const Key('Button Ubah Informasi'),
- elevation: 4.0,
- offset: const Offset(0.0, 40.0),
- itemBuilder: (BuildContext context) {
- final choices = ['Ubah Informasi'];
- return choices.map((String choice) {
- return PopupMenuItem(
- key: Key(choice),
- child: ElevatedButton(
- style: ButtonStyle(
- padding: MaterialStateProperty.all(
- EdgeInsets.symmetric(
- vertical: 0, horizontal: 0)),
- backgroundColor:
- MaterialStateProperty.all(Colors.white),
- foregroundColor:
- MaterialStateProperty.all(Colors.black),
- elevation: MaterialStateProperty.all(0)),
- onPressed: _updateInformasi,
- child: SizedBox(
- width: double.infinity,
- child: Text(choice),
- ),
+ ),
+ PopupMenuButton(
+ key: const Key('Button Ubah Informasi'),
+ elevation: 4.0,
+ offset: const Offset(0.0, 40.0),
+ itemBuilder: (BuildContext context) {
+ final choices = ['Ubah Informasi'];
+ return choices.map((String choice) {
+ return PopupMenuItem(
+ key: Key(choice),
+ child: ElevatedButton(
+ style: ButtonStyle(
+ padding: MaterialStateProperty.all(
+ EdgeInsets.symmetric(
+ vertical: 0, horizontal: 0)),
+ backgroundColor:
+ MaterialStateProperty.all(Colors.white),
+ foregroundColor:
+ MaterialStateProperty.all(Colors.black),
+ elevation: MaterialStateProperty.all(0)),
+ onPressed: _updateInformasi,
+ child: SizedBox(
+ width: double.infinity,
+ child: Text(choice),
),
- );
- }).toList();
- },
- ),
- ],
- ),
+ ),
+ );
+ }).toList();
+ },
+ ),
+ ],
),
- Container(
- key: const Key('Text Jumlah'),
- width: MediaQuery.of(context).size.width,
- color: red,
- padding: const EdgeInsets.symmetric(
- vertical: regularSpace, horizontal: doubleSpace),
- child: Text(
- 'Tersedia sebanyak ${widget.komentar.jumlah} '
- 'unit fasilitas.',
- style: const TextStyle(
- fontSize: 16,
- color: Colors.white,
- fontFamily: 'Comfortaa',
- ),
- )),
- Container(
- margin: const EdgeInsets.all(doubleSpace),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- SizedBox(
- height: 150,
- child: ImageHolder(
- url: widget.komentar.image,
- fasilitas: widget.komentar.tag)),
- const SizedBox(
- height: 10,
- ),
- // Wrap(
- // alignment: WrapAlignment.start,
- // direction: Axis.horizontal,
- // crossAxisAlignment: WrapCrossAlignment.start,
- // children: widget.komentar.tag
- // .map((tag) =>
- // _createTagContainer(getTag(tag)))
- // .toList(),
- // ),
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ ),
+ Container(
+ key: const Key('Text Jumlah'),
+ width: MediaQuery.of(context).size.width,
+ color: red,
+ padding: const EdgeInsets.symmetric(
+ vertical: regularSpace, horizontal: doubleSpace),
+ child: Text(
+ 'Tersedia sebanyak ${widget.komentar.jumlah} '
+ 'unit fasilitas.',
+ style: const TextStyle(
+ fontSize: 16,
+ color: Colors.white,
+ fontFamily: 'Comfortaa',
+ ),
+ )),
+ Container(
+ margin: const EdgeInsets.all(doubleSpace),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ SizedBox(
+ height: 150,
+ child: ImageHolder(
+ url: widget.komentar.image,
+ fasilitas: widget.komentar.tag)),
+ const SizedBox(
+ height: 10,
+ ),
+ // Wrap(
+ // alignment: WrapAlignment.start,
+ // direction: Axis.horizontal,
+ // crossAxisAlignment: WrapCrossAlignment.start,
+ // children: widget.komentar.tag
+ // .map((tag) =>
+ // _createTagContainer(getTag(tag)))
+ // .toList(),
+ // ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ const Text(
+ 'Dapat digunakan oleh',
+ style: TextStyle(fontSize: 16),
+ textAlign: TextAlign.left,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+ children: [
+ _showIfContains('DF'),
+ _showIfContains('DI'),
+ _showIfContains('DM'),
+ _showIfContains('DS'),
+ ],
+ )
+ ],
+ ),
+ Container(
+ key: const Key('desc'),
+ decoration: BoxDecoration(
+ color: gray,
+ boxShadow: regularShadow,
+ borderRadius: regularBorderRadius),
+ padding: const EdgeInsets.all(doubleSpace),
+ margin: const EdgeInsets.symmetric(vertical: doubleSpace),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
children: [
- const Text(
- 'Dapat digunakan oleh',
- style: TextStyle(fontSize: 16),
- textAlign: TextAlign.left,
- ),
Row(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
- _showIfContains('DF'),
- _showIfContains('DI'),
- _showIfContains('DM'),
- _showIfContains('DS'),
- ],
- )
- ],
- ),
- Container(
- key: const Key('desc'),
- decoration: BoxDecoration(
- color: gray,
- boxShadow: regularShadow,
- borderRadius: regularBorderRadius),
- padding: const EdgeInsets.all(doubleSpace),
- margin: const EdgeInsets.symmetric(vertical: doubleSpace),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Row(
- children: [
- const Expanded(
- child: Text(
- 'Cara menggunakan',
- style: TextStyle(
- fontSize: 20,
- fontWeight: FontWeight.w800),
- ),
+ const Expanded(
+ child: Text(
+ 'Cara menggunakan',
+ style: TextStyle(
+ fontSize: 20, fontWeight: FontWeight.w800),
),
- ],
- ),
- Container(
- margin: const EdgeInsets.symmetric(
- vertical: regularSpace),
- child: Text(
- widget.komentar.deskripsi,
- key: const Key('Text Cara Menggunakan'),
- style: const TextStyle(fontSize: 16),
),
+ ],
+ ),
+ Container(
+ margin: const EdgeInsets.symmetric(
+ vertical: regularSpace),
+ child: Text(
+ widget.komentar.deskripsi,
+ key: const Key('Text Cara Menggunakan'),
+ style: const TextStyle(fontSize: 16),
),
- ],
- ),
+ ),
+ ],
),
- Row(
- mainAxisAlignment: MainAxisAlignment.end,
- children: [
- const Text(
- 'informasi ditambahkan oleh ',
- style: TextStyle(
- fontSize: 12,
- fontStyle: FontStyle.italic,
- fontWeight: FontWeight.w200,
- ),
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ const Text(
+ 'informasi ditambahkan oleh ',
+ style: TextStyle(
+ fontSize: 12,
+ fontStyle: FontStyle.italic,
+ fontWeight: FontWeight.w200,
),
- Container(
- padding: EdgeInsets.zero,
- constraints: BoxConstraints(
- maxWidth:
- MediaQuery.of(context).size.width * 0.3),
+ ),
+ Container(
+ padding: EdgeInsets.zero,
+ constraints: BoxConstraints(
+ maxWidth: MediaQuery.of(context).size.width * 0.3),
+ child: InkWell(
+ onTap: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (_) => Profile(
+ email: widget.komentar.creatorEmail,
+ isPublic: true,
+ ),
+ ),
+ );
+ },
child: Text(
'${widget.komentar.creator} ',
key: Key('creator-${widget.komentar.creator}'),
@@ -255,156 +265,159 @@ class _DetailPostPageState extends State {
),
),
),
- Text(
- '(${DateFormat('dd MMM yyy').format(widget.komentar.dateTime)})',
- key: const Key('timestamp'),
- style: const TextStyle(
- fontSize: 12,
- fontStyle: FontStyle.italic,
- ),
+ ),
+ Text(
+ '(${DateFormat('dd MMM yyy').format(widget.komentar.dateTime)})',
+ key: const Key('timestamp'),
+ style: const TextStyle(
+ fontSize: 12,
+ fontStyle: FontStyle.italic,
),
- ],
- ),
- const SizedBox(
- height: regularSpace,
- ),
- const Divider(
- color: grayPrimary,
- thickness: 1.0,
- ),
- Container(
- key: const Key('Komentar'),
- padding:
- const EdgeInsets.symmetric(vertical: regularSpace),
- child: const Text(
- 'Komentar',
- style: TextStyle(
- fontSize: 20, fontWeight: FontWeight.w800),
- )),
- StreamBuilder(
- stream: _bloc.komentarPostingListStream,
- builder: (context, snapshot) {
- if (snapshot.hasData) {
- switch (snapshot.data.status) {
- case Status.loading:
+ ),
+ ],
+ ),
+ const SizedBox(
+ height: regularSpace,
+ ),
+ const Divider(
+ color: grayPrimary,
+ thickness: 1.0,
+ ),
+ Container(
+ key: const Key('Komentar'),
+ padding:
+ const EdgeInsets.symmetric(vertical: regularSpace),
+ child: const Text(
+ 'Komentar',
+ style: TextStyle(
+ fontSize: 20, fontWeight: FontWeight.w800),
+ )),
+ StreamBuilder(
+ stream: _bloc.komentarPostingListStream,
+ builder: (context, snapshot) {
+ if (snapshot.hasData) {
+ switch (snapshot.data.status) {
+ case Status.loading:
+ return const Center(
+ child: CircularProgressIndicator(
+ valueColor: AlwaysStoppedAnimation(
+ greenPrimary),
+ ),
+ );
+ break;
+ case Status.completed:
+ allKomentarPostingFromApi =
+ snapshot.data.data.allKomentar;
+ if (allKomentarPostingFromApi.isEmpty) {
return const Center(
- child: CircularProgressIndicator(
- valueColor: AlwaysStoppedAnimation(
- greenPrimary),
- ),
- );
- break;
- case Status.completed:
- allKomentarPostingFromApi =
- snapshot.data.data.allKomentar;
- if (allKomentarPostingFromApi.isEmpty) {
- return const Center(
- child: Text('Tidak ada Komentar'));
- } else {
- return Column(
- children: allKomentarPostingFromApi
- .map((k) =>
- komentarPlaceHolder(k.creator,
- k.dateTime, k.deskripsi))
- .toList());
- }
- break;
- case Status.error:
- return Center(
- child: Text(snapshot.data.data.toString()),
- );
- break;
- }
+ child: Text('Tidak ada Komentar'));
+ } else {
+ return Column(
+ children: allKomentarPostingFromApi
+ .map(
+ (k) => komentarPlaceHolder(
+ k.creator,
+ k.created,
+ k.deskripsi,
+ k.creatorEmail,
+ k.creatorPicture,
+ ),
+ )
+ .toList());
+ }
+ break;
+ case Status.error:
+ return Center(
+ child: Text(snapshot.data.data.toString()),
+ );
+ break;
}
- return Container();
- }),
- const SizedBox(height: regularSpace),
- Form(
- key: _formKey,
- child: Column(
- children: [
- TextFormField(
- key: const Key('Text Field Komentar'),
- keyboardType: TextInputType.multiline,
- maxLines: null,
- minLines: 3,
- validator: FieldValidator.validateInfo,
- controller: komentarController,
- style: const TextStyle(
- fontSize: 18,
- ),
- decoration: InputDecoration(
- hintStyle: const TextStyle(
- fontWeight: FontWeight.bold, fontSize: 15),
- hintText: 'Tulis komentar...',
- contentPadding: const EdgeInsets.all(8.0),
- enabledBorder: OutlineInputBorder(
- borderRadius: BorderRadius.circular(10),
- borderSide: BorderSide(
- color: Theme.of(context).primaryColor,
- ),
+ }
+ return Container();
+ }),
+ const SizedBox(height: regularSpace),
+ Form(
+ key: _formKey,
+ child: Column(
+ children: [
+ TextFormField(
+ key: const Key('Text Field Komentar'),
+ keyboardType: TextInputType.multiline,
+ maxLines: null,
+ minLines: 3,
+ validator: FieldValidator.validateInfo,
+ controller: komentarController,
+ style: const TextStyle(
+ fontSize: 18,
+ ),
+ decoration: InputDecoration(
+ hintStyle: const TextStyle(
+ fontWeight: FontWeight.bold, fontSize: 15),
+ hintText: 'Tulis komentar...',
+ contentPadding: const EdgeInsets.all(8.0),
+ enabledBorder: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(10),
+ borderSide: BorderSide(
+ color: Theme.of(context).primaryColor,
),
- border: OutlineInputBorder(
- borderRadius: BorderRadius.circular(10),
- borderSide: BorderSide(
- color: Theme.of(context).primaryColor,
- ),
+ ),
+ border: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(10),
+ borderSide: BorderSide(
+ color: Theme.of(context).primaryColor,
),
),
),
- Container(
- key: const Key('tambah komentar'),
- padding:
- const EdgeInsets.only(top: doubleSpace),
- alignment: Alignment.center,
- child: ButtonTheme(
- minWidth: double.infinity,
- height: 40,
- child: ElevatedButton(
- key: const Key('Button Tambah Komentar'),
- style: ButtonStyle(
- padding: MaterialStateProperty.all(
- EdgeInsets.symmetric(vertical: 13)),
- elevation: MaterialStateProperty.all(0.0),
- backgroundColor:
- MaterialStateProperty.all(
- greenPrimary),
- shape: MaterialStateProperty.all(
- RoundedRectangleBorder(
- borderRadius: BorderRadius.all(
- Radius.circular(10)))),
- ),
- onPressed: () {
- _checkLoginStatus();
- },
- child: Row(
- mainAxisAlignment:
- MainAxisAlignment.center,
- children: [
- const Icon(
- Icons.add,
- size: 30,
- color: Colors.white,
- ),
- const SizedBox(width: 5.0),
- const Text(
- 'Tambah Komentar',
- style: TextStyle(
- fontSize: 20,
- color: Colors.white,
- fontWeight: FontWeight.bold),
- ),
- ],
- ),
+ ),
+ Container(
+ key: const Key('tambah komentar'),
+ padding: const EdgeInsets.only(top: doubleSpace),
+ alignment: Alignment.center,
+ child: ButtonTheme(
+ minWidth: double.infinity,
+ height: 40,
+ child: ElevatedButton(
+ key: const Key('Button Tambah Komentar'),
+ style: ButtonStyle(
+ padding: MaterialStateProperty.all(
+ EdgeInsets.symmetric(vertical: 13)),
+ elevation: MaterialStateProperty.all(0.0),
+ backgroundColor:
+ MaterialStateProperty.all(greenPrimary),
+ shape: MaterialStateProperty.all(
+ RoundedRectangleBorder(
+ borderRadius: BorderRadius.all(
+ Radius.circular(10)))),
),
- )),
- ],
- )),
- ],
- ),
+ onPressed: () {
+ _checkLoginStatus();
+ },
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ const Icon(
+ Icons.add,
+ size: 30,
+ color: Colors.white,
+ ),
+ const SizedBox(width: 5.0),
+ const Text(
+ 'Tambah Komentar',
+ style: TextStyle(
+ fontSize: 20,
+ color: Colors.white,
+ fontWeight: FontWeight.bold),
+ ),
+ ],
+ ),
+ ),
+ )),
+ ],
+ )),
+ ],
),
- ],
- ),
+ ),
+ ],
),
),
);
@@ -440,9 +453,6 @@ class _DetailPostPageState extends State {
newKomentarPostingData, _namaLokasi, widget.komentar.id);
if (response['response'] == 'komentar added') {
successDialog(context);
- Timer(const Duration(seconds: 2), () {
- Navigator.pop(context);
- });
await _bloc.fetchKomentarPostingList(_namaLokasi, widget.komentar.id);
komentarController.clear();
} else {
@@ -474,31 +484,46 @@ class _DetailPostPageState extends State {
});
}
- Widget komentarPlaceHolder(String name, DateTime date, String description) {
+ Widget komentarPlaceHolder(
+ String name,
+ DateTime date,
+ String description,
+ String email,
+ String foto,
+ ) {
+ final user = DetailUserModel()
+ ..email = email
+ ..foto = foto
+ ..name = name;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
- 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(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
- Text(
- name,
- style: const TextStyle(fontSize: 18),
+ InkWell(
+ onTap: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (_) => Profile(
+ email: email,
+ isPublic: true,
+ ),
+ ),
+ );
+ },
+ child: Text(
+ name,
+ style: const TextStyle(fontSize: 18),
+ ),
),
- Text('${DateFormat('dd MMM yyy hh:mm').format(date)}',
+ Text('${DateFormat('dd MMMM yyyy hh:mm').format(date)}',
style: const TextStyle(color: grayPrimary, fontSize: 14))
],
),
@@ -519,16 +544,6 @@ class _DetailPostPageState extends State {
);
}
- 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) {
diff --git a/lib/page/filter_fasilitas/postingan/detail_post_kegiatan.dart b/lib/page/filter_fasilitas/postingan/detail_post_kegiatan.dart
index c8262c01547d518123675fd444f6de3db8597f93..fba26d5cec324cff9fb83b4b67389797d1972b3f 100644
--- a/lib/page/filter_fasilitas/postingan/detail_post_kegiatan.dart
+++ b/lib/page/filter_fasilitas/postingan/detail_post_kegiatan.dart
@@ -2,7 +2,10 @@ import 'dart:async';
import 'package:bisaGo/model/kegiatan.dart';
import 'package:bisaGo/model/lokasi.dart';
+import 'package:bisaGo/model/user.dart';
import 'package:bisaGo/page/filter_fasilitas/kegiatan_list_images.dart';
+import 'package:bisaGo/page/profile/profile.dart';
+import 'package:bisaGo/page/profile/profile_picture.dart';
import 'package:bisaGo/repository/dynamic_links_service_repository.dart';
import 'package:bisaGo/utils/share_utils.dart';
import 'package:bisaGo/utils/validator.dart';
@@ -349,14 +352,24 @@ class _DetailPostKegiatanPageState extends State {
constraints: BoxConstraints(
maxWidth:
MediaQuery.of(context).size.width * 0.3),
- child: Text(
- '${widget.kegiatan.creator}',
- key: Key('creator-${widget.kegiatan.creator}'),
- overflow: TextOverflow.fade,
- softWrap: false,
- style: const TextStyle(
- fontSize: 12,
- fontStyle: FontStyle.italic,
+ child: InkWell(
+ onTap: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (_) => Profile(
+ email: widget.kegiatan.creatorEmail,
+ isPublic: true)));
+ },
+ child: Text(
+ '${widget.kegiatan.creator}',
+ key: Key('creator-${widget.kegiatan.creator}'),
+ overflow: TextOverflow.fade,
+ softWrap: false,
+ style: const TextStyle(
+ fontSize: 12,
+ fontStyle: FontStyle.italic,
+ ),
),
),
),
@@ -411,6 +424,8 @@ class _DetailPostKegiatanPageState extends State {
.map((k) =>
komentarKegiatanPlaceHolder(
k.creator,
+ k.creatorEmail,
+ k.creatorPicture,
k.created,
k.deskripsi))
.toList());
@@ -604,31 +619,40 @@ class _DetailPostKegiatanPageState extends State {
}
Widget komentarKegiatanPlaceHolder(
- String name, DateTime created, String description) {
+ String name, String email, String foto, DateTime created, String description) {
+ final user = DetailUserModel()
+ ..email = email
+ ..foto = foto
+ ..name = name;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
- 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(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
- Text(
- name,
- style: const TextStyle(fontSize: 18),
+ InkWell(
+ onTap: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (_) => Profile(
+ email: email,
+ isPublic: true,
+ ),
+ ),
+ );
+ },
+ child: Text(
+ name,
+ style: const TextStyle(fontSize: 18),
+ ),
),
- Text('${DateFormat('dd MMMM yyy hh:mm').format(created)}',
+ Text('${DateFormat('dd MMMM yyyy hh:mm').format(created)}',
style: const TextStyle(color: grayPrimary, fontSize: 14))
],
),
@@ -649,16 +673,6 @@ class _DetailPostKegiatanPageState extends State {
);
}
- 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;
- }
-
// Future _updateInformasi() async {
// final sharedPreferences = await SharedPreferences.getInstance();
// if (sharedPreferences.getString('token') == null) {
diff --git a/lib/page/login/login.dart b/lib/page/login/login.dart
index 57496777fca5c0688955ad38c1a9cd3d59909428..99462570947b9811fbdd12ee5d26efb9812c3b7f 100644
--- a/lib/page/login/login.dart
+++ b/lib/page/login/login.dart
@@ -1,8 +1,7 @@
import 'dart:async';
import 'dart:convert';
-import 'package:bisaGo/bloc/new_user_bloc.dart';
import 'package:bisaGo/bloc/user_bloc.dart';
-import 'package:bisaGo/model/new_user.dart';
+import 'package:bisaGo/model/user.dart';
import 'package:bisaGo/page/dashboard/dashboard.dart';
import 'package:bisaGo/page/login/pilih_disabilitas.dart';
import 'package:flutter/cupertino.dart';
@@ -35,6 +34,12 @@ class LoginState extends State {
GoogleSignInAccount _currentUser;
SharedPreferences sharedPreferences;
+ UserBloc _userBloc;
+ UpdateUserModel updateUser;
+ String email;
+ TextEditingController emailController = TextEditingController();
+ TextEditingController passwordController = TextEditingController();
+
@override
void initState() {
super.initState();
@@ -159,15 +164,15 @@ class LoginState extends State {
height: 64.0,
child: TextButton(
style: TextButton.styleFrom(
- backgroundColor: Colors.white,
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(5.0),
- side: const BorderSide(color: greenPrimary)),
- padding: const EdgeInsets.symmetric(vertical: 10.0)
- ),
+ backgroundColor: Colors.white,
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(5.0),
+ side: const BorderSide(color: greenPrimary)),
+ padding:
+ const EdgeInsets.symmetric(vertical: 10.0)),
onPressed: () async {
Navigator.of(context).pop(true);
- await _updateUser(newUser);
+ await _updateUser(updateUser);
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
@@ -189,11 +194,11 @@ class LoginState extends State {
height: 64.0,
child: TextButton(
style: TextButton.styleFrom(
- backgroundColor: greenPrimary,
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(5.0)),
- padding: const EdgeInsets.symmetric(vertical: 10.0)
- ),
+ backgroundColor: greenPrimary,
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(5.0)),
+ padding:
+ const EdgeInsets.symmetric(vertical: 10.0)),
onPressed: () {
Navigator.of(context).pop(true);
_navigateToPilihDisabilitas(context);
@@ -219,57 +224,28 @@ class LoginState extends State {
);
}
- Future _getUserDetail() async {
- _userBloc = UserBloc(emailController.text.toString());
- await _userBloc.fetchUserDetail(emailController.text.toString());
- final response = _userBloc.userFromApi.first;
- if (response.disabilitas == '-') {
- newUser = NewUser(
- name: response.name,
- password: '',
- email: emailController.text.toString(),
- phoneNumber: response.phoneNumber,
- tanggalLahir: response.tanggalLahir,
- jenisKelamin: response.jenisKelamin,
- disabilitas: 'Tidak memiliki disabilitas',
- pekerjaan: response.pekerjaan,
- alamat: response.alamat);
- await login(emailController.text.toString(),
- passwordController.text.toString(), '', '', '');
- _popUpDisabilitas();
- } else {
- await login(emailController.text.toString(),
- passwordController.text.toString(), '', '', '');
- }
- }
-
- Future _updateUser(NewUser newUser) async {
- _newUserBloc = NewUserBloc();
- final response = await _newUserBloc.updateUser(newUser);
- if (response.statusCode == 200) {
+ Future _updateUser(UpdateUserModel updateUserModel) async {
+ updateUserModel.foto = '';
+ final updatedUser = await _userBloc.updateUser(updateUserModel);
+ if (updatedUser != null) {
successUserUpdateDialog(context);
} else {
failedUserUpdateDialog(context);
}
- _newUserBloc.dispose();
}
Future _validateLoginInput() async {
final form = _formKey.currentState;
if (_formKey.currentState.validate()) {
form.save();
- await _getUserDetail();
+ await login(emailController.text.toString(),
+ passwordController.text.toString(), '', '', '');
}
}
- NewUserBloc _newUserBloc;
- UserBloc _userBloc;
- NewUser newUser;
- TextEditingController emailController = TextEditingController();
- TextEditingController passwordController = TextEditingController();
-
Future login(String email, String password, String google,
String accessToken, String name) async {
+ _userBloc = UserBloc(email: email);
var data = {};
if (google.isNotEmpty) {
data = {
@@ -287,21 +263,31 @@ class LoginState extends State {
.post('${ApiFlavor.getBaseUrl()}/api-token-auth/', body: data);
if (response.statusCode == 200) {
final tokenMap = jsonDecode(response.body);
+ final loginUser = DetailUserModel.fromJson(tokenMap['user']);
+ this.email = loginUser.email;
+ updateUser = loginUser.toUpdateUserModel();
setState(() {
sharedPreferences
..setString('token', tokenMap['token'])
- ..setString('email', email);
+ ..setString('user', jsonEncode(tokenMap['user']));
});
+
successDialog(context);
+ await Future.delayed(const Duration(seconds: 2));
_navigateToDashboard(context);
+ if (updateUser.disabilitas == '-') {
+ updateUser.disabilitas = 'Tidak memiliki disabilitas';
+ _popUpDisabilitas();
+ }
} else {
failedDialog(context);
}
+ _userBloc.dispose();
}
void _navigateToPilihDisabilitas(BuildContext context) {
- final route =
- MaterialPageRoute(builder: (_) => PilihDisabilitas(newUser: newUser));
+ final route = MaterialPageRoute(
+ builder: (_) => PilihDisabilitas(updateUser: updateUser, email: email));
Navigator.of(context).push(route);
}
@@ -312,7 +298,7 @@ class LoginState extends State {
void _navigateToDashboard(BuildContext context) {
final route = MaterialPageRoute(builder: (_) => const Dashboard());
- Navigator.of(context).push(route);
+ Navigator.of(context).pushReplacement(route);
}
void successDialog(BuildContext context) {
@@ -365,23 +351,13 @@ class LoginState extends State {
}
Future _handleSignIn() async {
- try {
- await _handleSignOut();
- final googleSignInAccount = await _googleSignIn.signIn();
- final googleSignInAuthentication =
- await googleSignInAccount.authentication;
+ await _handleSignOut();
+ final googleSignInAccount = await _googleSignIn.signIn();
+ final googleSignInAuthentication = await googleSignInAccount.authentication;
- final token = googleSignInAuthentication.accessToken;
- await login(
- _currentUser.email, '', 'true', token, _currentUser.displayName);
- sharedPreferences = await SharedPreferences.getInstance();
- successDialog(context);
- Timer(const Duration(seconds: 2), () {
- Navigator.pushNamed(context, '/');
- });
- } catch (error) {
- failedDialog(context);
- }
+ final token = googleSignInAuthentication.accessToken;
+ await login(
+ _currentUser.email, '', 'true', token, _currentUser.displayName);
}
Future _handleSignOut() async {
diff --git a/lib/page/login/pilih_disabilitas.dart b/lib/page/login/pilih_disabilitas.dart
index 758a125ee7d141b902bb15fc93c186d91c977bc1..a117141335449d9fc14b48944e797e9800c5fb7f 100644
--- a/lib/page/login/pilih_disabilitas.dart
+++ b/lib/page/login/pilih_disabilitas.dart
@@ -1,7 +1,7 @@
import 'dart:async';
-import 'package:bisaGo/bloc/new_user_bloc.dart';
-import 'package:bisaGo/model/new_user.dart';
+import 'package:bisaGo/bloc/user_bloc.dart';
+import 'package:bisaGo/model/user.dart';
import 'package:bisaGo/page/dashboard/dashboard.dart';
import 'package:bisaGo/utils/custom_disabilitas_button.dart';
import 'package:flutter/material.dart';
@@ -10,17 +10,18 @@ import 'package:bisaGo/config/styles.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class PilihDisabilitas extends StatefulWidget {
- final NewUser newUser;
+ final UpdateUserModel updateUser;
+ final String email;
- const PilihDisabilitas({Key key, this.newUser}) : super(key: key);
+ const PilihDisabilitas({Key key, this.updateUser, this.email}) : super(key: key);
@override
- _PilihDisabilitasState createState() => _PilihDisabilitasState(newUser);
+ _PilihDisabilitasState createState() => _PilihDisabilitasState();
}
class _PilihDisabilitasState extends State {
- _PilihDisabilitasState(this.newUser);
-
+ UserBloc _userBloc;
String _disabilitas = '';
+
@override
Widget build(BuildContext context) {
return Scaffold(
@@ -116,18 +117,19 @@ class _PilihDisabilitasState extends State {
}
Future _updateUser() async {
- newUser.disabilitas = _disabilitas;
- bloc = NewUserBloc();
- final response = await bloc.updateUser(newUser);
- if (response.statusCode == 200) {
+ var updateUser = widget.updateUser;
+ updateUser.disabilitas = _disabilitas;
+ updateUser.foto = '';
+ _userBloc = UserBloc(email: widget.email);
+ final updatedUser = await _userBloc.updateUser(updateUser);
+ if (updatedUser != null) {
successDialog(context);
- Timer(const Duration(seconds: 2), () {
- _navigateToDashboard(context);
- });
+ await Future.delayed(Duration(seconds: 2));
+ _navigateToDashboard(context);
} else {
failedDialog(context);
}
- bloc.dispose();
+ _userBloc.dispose();
}
void successDialog(BuildContext context) {
@@ -154,9 +156,6 @@ class _PilihDisabilitasState extends State {
});
}
- NewUser newUser;
- NewUserBloc bloc;
-
void _navigateToDashboard(BuildContext context) {
final route = MaterialPageRoute(builder: (_) => const Dashboard());
Navigator.of(context).push(route);
diff --git a/lib/page/profile/edit_profile.dart b/lib/page/profile/edit_profile.dart
index 71d73eb456b3dca92c26cfe739615cb55d6d5c1b..69f4b32caa99041a90a680db8d2557a1a3865a97 100644
--- a/lib/page/profile/edit_profile.dart
+++ b/lib/page/profile/edit_profile.dart
@@ -1,10 +1,14 @@
import 'dart:async';
+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/bloc/new_user_bloc.dart';
import 'package:bisaGo/component/bisago_appbar.dart';
import 'package:bisaGo/config/strings.dart';
import 'package:bisaGo/config/styles.dart';
-import 'package:bisaGo/model/new_user.dart';
import 'package:bisaGo/model/user.dart';
import 'package:bisaGo/page/profile/profile.dart';
import 'package:bisaGo/utils/custom_button.dart';
@@ -14,39 +18,81 @@ import 'package:bisaGo/utils/validator.dart';
import 'package:flutter/material.dart';
import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
-import 'package:intl/intl.dart';
+import 'package:image_picker/image_picker.dart';
class EditProfile extends StatefulWidget {
- final UserModel user;
+ final DetailUserModel user;
const EditProfile({@required this.user, Key key}) : super(key: key);
+
@override
_EditProfileState createState() => _EditProfileState(user);
}
class _EditProfileState extends State {
final GlobalKey _formKey = GlobalKey();
- UserModel user;
- NewUserBloc bloc;
- _EditProfileState(this.user);
+ DetailUserModel detailUserModel;
+ UpdateUserModel updateUserModel;
+ UserBloc _bloc;
+
+ TextEditingController nameController = TextEditingController();
+ TextEditingController phoneController = TextEditingController();
+ TextEditingController emailController = TextEditingController();
+ TextEditingController alamatController = TextEditingController();
+ TextEditingController organisasiController = TextEditingController();
+
+ String jenisKelaminValue;
+ DateTime tanggalLahir;
+ String jenisDisabilitasValue;
+ String pekerjaanValue;
+
+ //UserBloc bloc;
+ final picker = ImagePicker();
+ File _image;
+ String _imageUrl;
+ bool _rahasiakanData;
+
+ Future _getGalleryImage() async {
+ final image = await picker.getImage(source: ImageSource.gallery);
+ return File(image.path);
+ }
+
+ Future _getCameraImage() async {
+ final image =
+ await picker.getImage(source: ImageSource.camera, imageQuality: 50);
+ return File(image.path);
+ }
+
+ Future _clearImage() async {
+ setState(() {
+ _image = null;
+ _imageUrl = null;
+ });
+ }
+
+ _EditProfileState(this.detailUserModel);
@override
void initState() {
super.initState();
- nameController.text = user.name;
- phoneController.text = user.phoneNumber;
- emailController.text = user.email;
- alamatController.text = user.alamat;
- jenisKelaminValue = user.jenisKelamin;
- tanggalLahir = user.tanggalLahir;
- jenisDisabilitasValue = user.disabilitas;
- pekerjaanValue = user.pekerjaan;
+ nameController.text = detailUserModel.name;
+ phoneController.text = detailUserModel.phoneNumber;
+ emailController.text = detailUserModel.email;
+ alamatController.text = detailUserModel.alamat;
+ organisasiController.text = detailUserModel.organisasiKomunitas;
+ jenisKelaminValue = detailUserModel.jenisKelamin;
+ tanggalLahir = (detailUserModel.tanggalLahir == '-'
+ ? DateTime.now()
+ : usDateFormatter.parse(detailUserModel.tanggalLahir));
+ jenisDisabilitasValue = detailUserModel.disabilitas;
+ pekerjaanValue = detailUserModel.pekerjaan;
+ _rahasiakanData = detailUserModel.seen;
+ _imageUrl = detailUserModel.foto;
}
@override
Widget build(BuildContext context) {
- final name = user.name;
return Scaffold(
appBar: PreferredSize(
preferredSize: const Size.fromHeight(55),
@@ -89,30 +135,92 @@ class _EditProfileState extends State {
child: ListBody(
children: [
CircleAvatar(
- key: Key('Avatar ${name.split(' ')[0]}'),
+ key: Key('Avatar ${detailUserModel.name.split(' ')[0]}'),
radius: 50,
- backgroundColor: white,
- child: Text(
- user.name.substring(0, 1),
- style: const TextStyle(
- fontSize: 45,
- fontWeight: FontWeight.w900,
- color: darkGreen,
- fontFamily: 'Comfortaa',
- ),
- ),
+ 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: const EdgeInsets.only(top: doubleSpace),
- child: Text(
- 'Halo, ${name.split(' ')[0]}!',
- style: const TextStyle(
- fontSize: 26,
- fontWeight: FontWeight.w900,
- color: Colors.black,
- fontFamily: 'Comfortaa',
+ padding:
+ const EdgeInsets.symmetric(vertical: doubleSpace),
+ child: InkWell(
+ onTap: () {
+ _showPhotoSelectionDialog();
+ },
+ child: Text(
+ 'Ubah Foto Profil',
+ style: const TextStyle(
+ fontSize: 18,
+ fontWeight: FontWeight.w900,
+ color: Colors.blue,
+ fontFamily: 'Comfortaa',
+ ),
+ textAlign: TextAlign.center,
),
- textAlign: TextAlign.center,
+ ),
+ ),
+ Container(
+ margin: const EdgeInsets.symmetric(vertical: 10),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ 'Rahasiakan data?',
+ key: Key('Rahasiakan data?'),
+ style: const TextStyle(
+ fontSize: 18,
+ color: Colors.black,
+ fontFamily: 'Muli',
+ ),
+ ),
+ Center(
+ child: Text(
+ 'Data yang akan dirahasiakan adalah: ${widget.user.hiddenFieldsVerbose.join(', ')}',
+ style: TextStyle(
+ fontSize: 10.0,
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ Switch(
+ value: !_rahasiakanData,
+ focusColor: Colors.green,
+ hoverColor: Colors.green,
+ activeColor: Colors.green,
+ activeTrackColor: Colors.green,
+ onChanged: (value) {
+ setState(() {
+ _rahasiakanData = !value;
+ });
+ },
+ ),
+ ],
),
),
CustomTextField(
@@ -170,16 +278,15 @@ class _EditProfileState extends State {
),
onPressed: () {
DatePicker.showDatePicker(context,
- currentTime: DateTime.parse(tanggalLahir),
+ currentTime: tanggalLahir,
maxTime: DateTime.now(), onChanged: (date) {
setState(() {
- tanggalLahir =
- '${DateFormat('yyyy-MM-dd').format(date)}';
+ tanggalLahir = date;
});
});
},
child: Text(
- tanggalLahir,
+ idDateFormatter.format(tanggalLahir),
style: const TextStyle(
fontSize: 15.0, color: Colors.white),
),
@@ -218,6 +325,13 @@ class _EditProfileState extends State {
});
},
),
+ CustomTextField(
+ title: 'Organisasi / Komunitas',
+ required: true,
+ key: const Key('Text Field Organisasi'),
+ controller: organisasiController,
+ validator: FieldValidator.validateOrganisasi,
+ ),
Container(
margin: const EdgeInsets.fromLTRB(
0, tripleSpace, 0, regularSpace),
@@ -238,48 +352,69 @@ class _EditProfileState extends State {
);
}
- NewUser newUser;
- TextEditingController nameController = TextEditingController();
- TextEditingController phoneController = TextEditingController();
- TextEditingController emailController = TextEditingController();
- TextEditingController alamatController = TextEditingController();
- String jenisKelaminValue;
- String tanggalLahir;
- String jenisDisabilitasValue;
- String pekerjaanValue;
+ dynamic fotoValidate() {
+ dynamic fotoVal = '';
+ if (_image != null) {
+ final fileName = _image.path.split('/').last;
+ fotoVal = MultipartFile.fromFile(
+ _image.path,
+ filename: fileName,
+ );
+ }
+ return fotoVal;
+ }
Future _validateLoginInput() async {
+ var validatedPhoto = '';
+ if (_image != null) {
+ validatedPhoto = _image.path;
+ } else if (_imageUrl == null) {
+ validatedPhoto = null;
+ }
+
final form = _formKey.currentState;
if (_formKey.currentState.validate()) {
form.save();
- newUser = NewUser(
- name: nameController.text.toString(),
- password: '',
- email: emailController.text.toString(),
- phoneNumber: phoneController.text.toString(),
- tanggalLahir: tanggalLahir,
- jenisKelamin: jenisKelaminValue ?? '-',
- disabilitas: jenisDisabilitasValue,
- pekerjaan: pekerjaanValue ?? '-',
- alamat: alamatController.text.toString());
- await _updateUser(newUser);
+ updateUserModel = UpdateUserModel(
+ name: nameController.text.toString(),
+ phoneNumber: phoneController.text.toString(),
+ tanggalLahir: usDateFormatter.format(tanggalLahir),
+ jenisKelamin: jenisKelaminValue ?? '-',
+ disabilitas: jenisDisabilitasValue,
+ pekerjaan: pekerjaanValue ?? '-',
+ alamat: alamatController.text.toString(),
+ foto: validatedPhoto,
+ seen: _rahasiakanData,
+ organisasiKomunitas: organisasiController.text,
+ );
+ if (_image != null) {
+ final fileName = _image.path.split('/').last;
+ updateUserModel.foto = await MultipartFile.fromFile(
+ _image.path,
+ filename: fileName,
+ );
+ }
+
+ //await updateUser(newUser);
+ await updateUser(updateUserModel, detailUserModel.email);
} else {
failedDialog(context);
}
}
- Future _updateUser(NewUser newUser) async {
- bloc = NewUserBloc();
- final response = await bloc.updateUser(newUser);
- if (response.statusCode == 200) {
+ Future updateUser(UpdateUserModel updateUserModel, String email) async {
+ _bloc = UserBloc(email: email);
+ final updatedUser = await _bloc.updateUser(updateUserModel);
+ if (updatedUser != null) {
successDialog(context);
Timer(const Duration(seconds: 2), () {
- _navigateToProfile(context, newUser);
+ //_navigateToProfile(context, newUser);
+ _navigateToProfile(context, updatedUser.email);
});
} else {
failedDialog(context);
}
- bloc.dispose();
+ _bloc.dispose();
}
void successDialog(BuildContext context) {
@@ -306,21 +441,53 @@ class _EditProfileState extends State {
});
}
- void _navigateToProfile(BuildContext context, NewUser newUser) {
- final userNew = UserModel(
- username: newUser.email,
- name: newUser.name,
- email: newUser.email,
- tanggalLahir: newUser.tanggalLahir,
- phoneNumber: newUser.phoneNumber,
- jenisKelamin: newUser.jenisKelamin,
- disabilitas: newUser.disabilitas,
- pekerjaan: newUser.pekerjaan,
- alamat: newUser.alamat);
- final route =
- MaterialPageRoute(builder: (_) => Profile(email: userNew.email));
+ void _navigateToProfile(BuildContext context, String email) {
+ final route = MaterialPageRoute(builder: (_) => Profile(email: email));
Navigator.of(context).pop(Navigator.pop(context));
Navigator.pop(context);
Navigator.of(context).push(route);
}
+
+ Future _showPhotoSelectionDialog() async {
+ await showDialog(
+ context: context,
+ builder: (_) => SimpleDialog(
+ title: Text('Pilih Foto'),
+ children: [
+ SimpleDialogOption(
+ onPressed: () async {
+ final imageSelected = await _getGalleryImage();
+ setState(() {
+ _image = imageSelected;
+ });
+ Navigator.pop(context);
+ },
+ child: Text('Dari Gallery'),
+ ),
+ SimpleDialogOption(
+ onPressed: () async {
+ final imageSelected = await _getCameraImage();
+ setState(() {
+ _image = imageSelected;
+ });
+ Navigator.pop(context);
+ },
+ child: Text('Dari Kamera'),
+ ),
+ SimpleDialogOption(
+ onPressed: () async {
+ Navigator.pop(context);
+ await _clearImage();
+ },
+ child: Text(
+ 'Hapus Foto',
+ style: TextStyle(
+ color: Colors.red[800],
+ ),
+ ),
+ ),
+ ],
+ ),
+ );
+ }
}
diff --git a/lib/page/profile/full_screen_image.dart b/lib/page/profile/full_screen_image.dart
new file mode 100644
index 0000000000000000000000000000000000000000..f8878ffd71be3fffb63e256d71e7f5dde9d7321b
--- /dev/null
+++ b/lib/page/profile/full_screen_image.dart
@@ -0,0 +1,23 @@
+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(),
+ ),
+ );
+ }
+}
diff --git a/lib/page/profile/profile.dart b/lib/page/profile/profile.dart
index 2f2f74c587f7e02e152050c060b8861eadf3bb68..fe3749a3277542e24a94ef6760c620b14c31ff08 100644
--- a/lib/page/profile/profile.dart
+++ b/lib/page/profile/profile.dart
@@ -2,28 +2,45 @@ import 'package:bisaGo/bloc/user_bloc.dart';
import 'package:bisaGo/component/bisago_appbar.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:bisaGo/utils/profile_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';
class Profile extends StatefulWidget {
final String email;
+ final bool isPublic;
+
+ const Profile({
+ @required this.email,
+ Key key,
+ this.isPublic = false,
+ }) : super(key: key);
- const Profile({@required this.email, Key key}) : super(key: key);
@override
_ProfileState createState() => _ProfileState(email);
}
class _ProfileState extends State {
- UserModel user;
+ DetailUserModel user;
+ DetailUserModel viewUser;
String email;
UserBloc _bloc;
+ bool fetched;
+
_ProfileState(this.email);
@override
void initState() {
super.initState();
- _bloc = UserBloc(email);
+ fetched = false;
+ _bloc = UserBloc(email: email);
+ _bloc.fetchUserDetail();
+ initializeDateFormatting('id_ID');
}
@override
@@ -38,41 +55,53 @@ class _ProfileState extends State {
child: const Icon(Icons.arrow_back_ios),
),
actions: [
- Padding(
- padding: const EdgeInsets.all(doubleSpace),
- child: InkWell(
- key: const Key('Edit User Profile'),
- onTap: () {
- _navigateToEditProfile(context);
- },
- child: const Text(
- 'Edit',
- style: TextStyle(fontSize: 15),
+ if (!widget.isPublic)
+ Padding(
+ padding: const EdgeInsets.all(doubleSpace),
+ child: InkWell(
+ key: const Key('Edit User Profile'),
+ onTap: () {
+ if (user != null) {
+ _navigateToEditProfile(context);
+ }
+ },
+ child: const Text(
+ 'Edit',
+ style: TextStyle(fontSize: 15),
+ ),
),
- ),
- )
+ )
],
),
),
- body: FutureBuilder(
- future: _bloc.fetchUser(email),
- builder: (BuildContext context, AsyncSnapshot snapshot) {
- if (snapshot.hasData) {
- user = snapshot.data;
- return _createProfilePage();
- } else if (!snapshot.hasData) {
- return const Center(
- child: CircularProgressIndicator(
- valueColor: AlwaysStoppedAnimation(greenPrimary),
- ),
- );
+ body: StreamBuilder>(
+ stream: _bloc.userStream,
+ builder: (context, snapshot) {
+ if (snapshot.hasData) {
+ switch (snapshot.data.status) {
+ case Status.completed:
+ user = snapshot.data.data;
+ return _createProfilePage();
+ case Status.loading:
+ return const Center(
+ child: CircularProgressIndicator(
+ valueColor: AlwaysStoppedAnimation(greenPrimary),
+ ),
+ );
+ case Status.error:
+ return Center(
+ child: Text(snapshot.data.message.toString()),
+ );
}
- return Container();
- }),
+ }
+ return Container();
+ },
+ ),
);
}
Widget _createProfilePage() {
+ var tanggalLahir = toIndonesiaLocale(user.tanggalLahir);
return ListView(
children: [
Stack(
@@ -93,38 +122,28 @@ class _ProfileState extends State {
padding: const EdgeInsets.only(
bottom: doubleSpace,
),
- child: CircleAvatar(
- key: Key('Avatar ${user.name.split(' ')[0]}'),
- radius: 50,
- backgroundColor: white,
- child: 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),
),
- Text(
- 'Halo, ${user.name.split(' ')[0]}!',
- style: const TextStyle(
- fontSize: 26,
- fontWeight: FontWeight.w900,
- color: Colors.white,
- fontFamily: 'Comfortaa',
+ if (!widget.isPublic)
+ Text(
+ 'Halo, ${user.name.split(' ')[0]}!',
+ style: TextStyle(
+ fontSize: 26,
+ fontWeight: FontWeight.w900,
+ color:
+ _getFontColor('name', seenColor: Colors.white),
+ fontFamily: 'Muli',
+ ),
+ textAlign: TextAlign.center,
),
- textAlign: TextAlign.center,
- ),
Text(
user.email,
- style: const TextStyle(
- fontSize: 20,
+ style: TextStyle(
+ fontSize: 16,
fontWeight: FontWeight.w500,
- color: Colors.white,
- fontFamily: 'Comfortaa',
+ color: _getFontColor('email', seenColor: Colors.white),
+ fontFamily: 'Muli',
),
textAlign: TextAlign.center,
),
@@ -137,7 +156,9 @@ class _ProfileState extends State {
key: const Key('Card Profile Page'),
alignment: Alignment.topCenter,
padding: EdgeInsets.only(
- top: MediaQuery.of(context).size.height * .32,
+ top: widget.isPublic
+ ? MediaQuery.of(context).size.height * .32 - 30
+ : MediaQuery.of(context).size.height * .32,
left: tripleSpace,
right: tripleSpace,
bottom: tripleSpace),
@@ -163,11 +184,11 @@ class _ProfileState extends State {
),
title: Text(
user.name,
- style: const TextStyle(
+ style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w500,
- color: Colors.black,
- fontFamily: 'Comfortaa',
+ color: _getFontColor('name'),
+ fontFamily: 'Muli',
),
textAlign: TextAlign.left,
),
@@ -179,15 +200,12 @@ class _ProfileState extends State {
color: darkGreen,
),
title: Text(
- user.tanggalLahir == '' ||
- user.tanggalLahir == null
- ? '-'
- : user.tanggalLahir,
- style: const TextStyle(
+ tanggalLahir,
+ style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w500,
- color: Colors.black,
- fontFamily: 'Comfortaa',
+ color: _getFontColor('tanggal_lahir'),
+ fontFamily: 'Muli',
),
textAlign: TextAlign.left,
),
@@ -200,11 +218,11 @@ class _ProfileState extends State {
),
title: Text(
user.phoneNumber,
- style: const TextStyle(
+ style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w500,
- color: Colors.black,
- fontFamily: 'Comfortaa',
+ color: _getFontColor('phone_number'),
+ fontFamily: 'Muli',
),
textAlign: TextAlign.left,
),
@@ -220,11 +238,11 @@ class _ProfileState extends State {
user.jenisKelamin == null
? '-'
: user.jenisKelamin,
- style: const TextStyle(
+ style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w500,
- color: Colors.black,
- fontFamily: 'Comfortaa',
+ color: _getFontColor('jenis_kelamin'),
+ fontFamily: 'Muli',
),
textAlign: TextAlign.left,
),
@@ -239,11 +257,11 @@ class _ProfileState extends State {
user.disabilitas == '' || user.disabilitas == null
? 'Belum memilih'
: user.disabilitas,
- style: const TextStyle(
+ style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w500,
- color: Colors.black,
- fontFamily: 'Comfortaa',
+ color: _getFontColor('disabilitas'),
+ fontFamily: 'Muli',
),
textAlign: TextAlign.left,
),
@@ -258,11 +276,11 @@ class _ProfileState extends State {
user.pekerjaan == '' || user.pekerjaan == null
? '-'
: user.pekerjaan,
- style: const TextStyle(
+ style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w500,
- color: Colors.black,
- fontFamily: 'Comfortaa',
+ color: _getFontColor('pekerjaan'),
+ fontFamily: 'Muli',
),
textAlign: TextAlign.left,
),
@@ -277,11 +295,31 @@ class _ProfileState extends State {
user.alamat == '' || user.alamat == null
? '-'
: user.alamat,
- style: const TextStyle(
+ style: TextStyle(
+ fontSize: 18,
+ fontWeight: FontWeight.w500,
+ color: _getFontColor('alamat'),
+ fontFamily: 'Muli',
+ ),
+ textAlign: TextAlign.left,
+ ),
+ ),
+ ListTile(
+ leading: const Icon(
+ Icons.people,
+ size: 28,
+ color: darkGreen,
+ ),
+ title: Text(
+ user.organisasiKomunitas == '' ||
+ user.organisasiKomunitas == null
+ ? '-'
+ : user.organisasiKomunitas,
+ style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w500,
- color: Colors.black,
- fontFamily: 'Comfortaa',
+ color: _getFontColor('organisasi_komunitas'),
+ fontFamily: 'Muli',
),
textAlign: TextAlign.left,
),
@@ -299,6 +337,15 @@ class _ProfileState extends State {
);
}
+ Color _getFontColor(String fieldName, {Color seenColor = seenColor}) {
+ if (user.canSeeHiddenFields) return seenColor;
+ final hiddenFields = user.hiddenFields;
+ if (hiddenFields.contains(fieldName)) {
+ return user.getHiddenFieldsColor();
+ }
+ return seenColor;
+ }
+
void _navigateToEditProfile(BuildContext context) {
final route = MaterialPageRoute(builder: (_) => EditProfile(user: user));
Navigator.of(context).push(route);
diff --git a/lib/page/profile/profile_picture.dart b/lib/page/profile/profile_picture.dart
new file mode 100644
index 0000000000000000000000000000000000000000..be9efbd8d863efe559d49dbc355e09b8125d203c
--- /dev/null
+++ b/lib/page/profile/profile_picture.dart
@@ -0,0 +1,103 @@
+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(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)));
+}
diff --git a/lib/page/registrasi/registrasi.dart b/lib/page/registrasi/registrasi.dart
index 7c64ecad20cbf6501dc4ba577ea151c2086ac64a..61efcf075c3fb33c03716b6a00b25dcb4f50a339 100644
--- a/lib/page/registrasi/registrasi.dart
+++ b/lib/page/registrasi/registrasi.dart
@@ -1,9 +1,10 @@
import 'dart:async';
-import 'package:bisaGo/bloc/new_user_bloc.dart';
+import 'package:bisaGo/bloc/user_bloc.dart';
import 'package:bisaGo/config/strings.dart';
-import 'package:bisaGo/model/new_user.dart';
+import 'package:bisaGo/model/user.dart';
import 'package:bisaGo/utils/custom_dropdown.dart';
+import 'package:bisaGo/utils/datetime_utils.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
@@ -14,7 +15,6 @@ import 'package:bisaGo/utils/custom_button.dart';
import 'package:bisaGo/utils/custom_text_field.dart';
import 'package:bisaGo/utils/validator.dart';
import 'package:google_sign_in/google_sign_in.dart';
-import 'package:intl/intl.dart';
GoogleSignIn _googleSignIn = GoogleSignIn(scopes: ['email', 'profile']);
@@ -28,7 +28,20 @@ class Registrasi extends StatefulWidget {
class RegistrasiState extends State {
final GlobalKey _formKey = GlobalKey();
- NewUserBloc bloc;
+ RegisterUserModel registerUserModel;
+ TextEditingController nameController = TextEditingController();
+ TextEditingController phoneController = TextEditingController();
+ TextEditingController emailController = TextEditingController();
+ TextEditingController alamatController = TextEditingController();
+ TextEditingController passwordController = TextEditingController();
+ TextEditingController organisasiController = TextEditingController();
+
+ String _jenisKelaminValue;
+ String _pekerjaanValue;
+ String jenisDisabilitas = '-';
+ String tanggalLahir = 'Pilih tanggal lahir';
+
+ UserBloc _bloc;
static GoogleSignInAccount _currentUser;
@@ -165,10 +178,9 @@ class RegistrasiState extends State {
key: const Key('Button Tanggal Lahir'),
onPressed: () {
DatePicker.showDatePicker(context,
- maxTime: DateTime.now(), onChanged: (date) {
+ maxTime: DateTime.now(), onConfirm: (date) {
setState(() {
- tanggalLahir =
- '${DateFormat('yyyy-MM-dd').format(date)}';
+ tanggalLahir = '${idDateFormatter.format(date)}';
});
});
},
@@ -197,6 +209,11 @@ class RegistrasiState extends State {
});
},
),
+ CustomTextField(
+ title: 'Organisasi / Komunitas',
+ key: const Key('Text Field Organisasi'),
+ controller: organisasiController,
+ ),
CustomTextField(
title: 'Password',
required: true,
@@ -257,19 +274,23 @@ class RegistrasiState extends State {
final form = _formKey.currentState;
if (_validateTanggalLahir(context) && _formKey.currentState.validate()) {
form.save();
- newUser = NewUser(
- name: nameController.text.toString(),
- password: passwordController.text.toString(),
- email: emailController.text.toString(),
- phoneNumber: phoneController.text.toString(),
- tanggalLahir: tanggalLahir,
- jenisKelamin: _jenisKelaminValue ?? '-',
- disabilitas: jenisDisabilitas,
- pekerjaan: _pekerjaanValue ?? '-',
- alamat: alamatController.text.toString() == ''
- ? '-'
- : alamatController.text.toString());
- await createUser(newUser);
+ registerUserModel = RegisterUserModel(
+ name: nameController.text.toString(),
+ password: passwordController.text.toString(),
+ email: emailController.text.toString(),
+ phoneNumber: phoneController.text.toString(),
+ tanggalLahir: fromLocaleToLocale(
+ idDateFormatter, registerDateFormatter, tanggalLahir),
+ jenisKelamin: _jenisKelaminValue ?? '-',
+ disabilitas: jenisDisabilitas,
+ pekerjaan: _pekerjaanValue ?? '-',
+ alamat: alamatController.text.toString() == ''
+ ? '-'
+ : alamatController.text.toString(),
+ organisasiKomunitas:
+ organisasiController.text == '' ? '-' : organisasiController.text,
+ );
+ await createUser(registerUserModel);
}
}
@@ -288,29 +309,17 @@ class RegistrasiState extends State {
return true;
}
- NewUser newUser;
- TextEditingController nameController = TextEditingController();
- TextEditingController phoneController = TextEditingController();
- TextEditingController emailController = TextEditingController();
- TextEditingController alamatController = TextEditingController();
- TextEditingController passwordController = TextEditingController();
- String _jenisKelaminValue;
- String _pekerjaanValue;
- String jenisDisabilitas = '-';
- String tanggalLahir = 'Pilih tanggal lahir';
-
- Future createUser(NewUser newUser) async {
- bloc = NewUserBloc();
- final response = await bloc.registerNewUser(newUser);
- if (response.statusCode == 201) {
+ Future createUser(RegisterUserModel registerUserModel) async {
+ _bloc = UserBloc();
+ final response = await _bloc.registerNewUser(registerUserModel);
+ if (response) {
successDialog(context);
- Timer(const Duration(seconds: 2), () {
- _navigateToDashboard(context);
- });
+ await Future.delayed(Duration(seconds: 2));
+ _navigateToDashboard(context);
} else {
failedDialog(context);
}
- bloc.dispose();
+ _bloc.dispose();
}
void successDialog(BuildContext context) {
diff --git a/lib/repository/cloud_messaging_repository.dart b/lib/repository/cloud_messaging_repository.dart
new file mode 100644
index 0000000000000000000000000000000000000000..49ea45c088a72fa18680ff835779f03799b9a453
--- /dev/null
+++ b/lib/repository/cloud_messaging_repository.dart
@@ -0,0 +1,30 @@
+import 'dart:convert';
+
+import 'package:http/http.dart' as http;
+import 'package:bisaGo/flavor/flavor.dart';
+
+abstract class BaseCloudMessagingRepository {
+ Future sendFCMToken(String fcmToken, String token);
+}
+
+class CloudMessagingRepository implements BaseCloudMessagingRepository {
+ @override
+ Future sendFCMToken(String fcmToken, String token) async {
+ try {
+ await http.post(
+ '${ApiFlavor.getBaseUrl()}/notification/',
+ headers: {
+ 'Authorization': 'token $token',
+ 'content-type': 'application/json'
+ },
+ body: json.encode({
+ 'token': fcmToken,
+ 'type': 'android',
+ }),
+ );
+ return true;
+ } catch (_) {
+ return false;
+ }
+ }
+}
diff --git a/lib/repository/kegiatan_repository.dart b/lib/repository/kegiatan_repository.dart
index 5d042a3db4cdc4728db633ac9232fcb4be111eb9..e19f5753c3a136ed67966622c2c6d86bb2c0de6d 100644
--- a/lib/repository/kegiatan_repository.dart
+++ b/lib/repository/kegiatan_repository.dart
@@ -54,10 +54,12 @@ class KegiatanRepository implements BaseKegiatanRepository {
);
return response;
}
-
+
@override
- Future fetchDetailKegiatan(String placeId, int kegiatanId) async {
- final url = '/informasi-fasilitas/lokasi/detail-kegiatan/$placeId/$kegiatanId/';
+ Future fetchDetailKegiatan(
+ String placeId, int kegiatanId) async {
+ final url =
+ '/informasi-fasilitas/lokasi/detail-kegiatan/$placeId/$kegiatanId/';
final response = await _network.get(url: url, isLogin: false);
var kegiatan = KegiatanModel.fromJson(response);
kegiatan.images = await fetchImages(kegiatan.placeId, kegiatan.id);
diff --git a/lib/repository/komentar_repository.dart b/lib/repository/komentar_repository.dart
index cf34a3ee609a0708d6d4990201292a75d30a7002..9d186142ba4f6b98f2c22c27b50c70af19125023 100644
--- a/lib/repository/komentar_repository.dart
+++ b/lib/repository/komentar_repository.dart
@@ -7,8 +7,7 @@ abstract class BaseKomentarRepository {
Map newKomentarData, String namaLokasi);
Future updateKomentar(
Map newKomentarData, String placeId, int id);
- Future fetchDetailFasilitas(
- String placeId, int fasilitasId);
+ Future fetchDetailFasilitas(String placeId, int fasilitasId);
}
class KomentarRepository implements BaseKomentarRepository {
@@ -35,10 +34,11 @@ class KomentarRepository implements BaseKomentarRepository {
}
@override
- Future updateKomentar(Map newKomentarData,
- String placeId, int id) async {
+ Future updateKomentar(
+ Map newKomentarData, String placeId, int id) async {
final response = await _network.put(
- url: '/informasi-fasilitas/lokasi/update-fasilitas/$placeId/${id.toString()}/',
+ url:
+ '/informasi-fasilitas/lokasi/update-fasilitas/$placeId/${id.toString()}/',
bodyParams: newKomentarData,
isLogin: true,
);
@@ -46,8 +46,10 @@ class KomentarRepository implements BaseKomentarRepository {
}
@override
- Future fetchDetailFasilitas(String placeId, int fasilitasId) async {
- final url = '/informasi-fasilitas/lokasi/detail-fasilitas/$placeId/$fasilitasId/';
+ Future fetchDetailFasilitas(
+ String placeId, int fasilitasId) async {
+ final url =
+ '/informasi-fasilitas/lokasi/detail-fasilitas/$placeId/$fasilitasId/';
final response = await _network.get(url: url, isLogin: false);
return KomentarModel.fromJson(response);
}
diff --git a/lib/repository/user_repository.dart b/lib/repository/user_repository.dart
index 4ced6b383e87b1874bfcb2f7d7e5b2757bc39270..a37f83d4dde91906a3783ae03e646058b74eb9d6 100644
--- a/lib/repository/user_repository.dart
+++ b/lib/repository/user_repository.dart
@@ -1,41 +1,41 @@
-import 'package:bisaGo/flavor/flavor.dart';
-import 'package:bisaGo/model/new_user.dart';
import 'package:bisaGo/model/user.dart';
import 'package:bisaGo/network/network_interface.dart';
-import 'package:http/http.dart';
abstract class BaseUserRepository {
- Future fetchUserDetail(String email);
- Future createUser(NewUser newUser);
- Future updateUser(NewUser newUser);
+ Future fetchUserDetail(String email);
+
+ Future registerUser(RegisterUserModel registerUserModel);
+
+ Future updateUser(UpdateUserModel updateUserModel, String email);
}
+
class UserRepository implements BaseUserRepository {
final NetworkInterface _network = NetworkInterface();
@override
- Future fetchUserDetail(String email) async {
+ Future fetchUserDetail(String email) async {
final response =
- await _network.get(url: '/api/user-detail/$email', isLogin: true);
- final data = [response];
- return User(
- data.map((user) => UserModel.fromJson(user)).toList());
+ await _network.get(url: '/api/user/$email/', isLogin: true);
+ return DetailUserModel.fromJson(response);
}
@override
- Future createUser(NewUser newUser) async {
- final response = await post(
- '${ApiFlavor.getBaseUrl()}/api/register/',
- body: newUser.toJson(),
+ Future registerUser(RegisterUserModel registerUserModel) async {
+ return await _network.post(
+ url: '/api/user/register/',
+ isLogin: false,
+ bodyParams: registerUserModel.toJson(),
);
- return response;
}
@override
- Future updateUser(NewUser newUser) async {
- final response = await post(
- '${ApiFlavor.getBaseUrl()}/api/update-user/',
- body: newUser.toJson(),
+ Future updateUser(
+ UpdateUserModel updateUserModel, String email) async {
+ final response = await _network.put(
+ url: '/api/user/$email/',
+ bodyParams: updateUserModel.toJson(),
+ isLogin: true,
);
- return response;
+ return DetailUserModel.fromJson(response);
}
}
diff --git a/lib/utils/datetime_utils.dart b/lib/utils/datetime_utils.dart
new file mode 100644
index 0000000000000000000000000000000000000000..247e779d0e7f6fa617b9d15504d55bda70e86b9b
--- /dev/null
+++ b/lib/utils/datetime_utils.dart
@@ -0,0 +1,27 @@
+import 'package:intl/intl.dart';
+
+const userProfileDateFormat = 'dd MMMM yyyy';
+const userRegisterDateFormat = 'yyyy-MM-dd';
+
+final idDateFormatter = DateFormat(userProfileDateFormat, 'id_ID');
+final usDateFormatter = DateFormat(userProfileDateFormat, 'en_US');
+final registerDateFormatter = DateFormat(userRegisterDateFormat, 'en_US');
+
+String toIndonesiaLocale(String date) {
+ return fromLocaleToLocale(usDateFormatter, idDateFormatter, date);
+}
+
+String toUnitedStatesLocale(String date) {
+ return fromLocaleToLocale(idDateFormatter, usDateFormatter, date);
+}
+
+String fromLocaleToLocale(
+ DateFormat fromLocaleFormatter, DateFormat toLocaleFormatter, String date) {
+ var tempDate;
+ try {
+ tempDate = fromLocaleFormatter.parse(date);
+ } catch (_) {
+ return date;
+ }
+ return toLocaleFormatter.format(tempDate);
+}
diff --git a/lib/utils/profile_utils.dart b/lib/utils/profile_utils.dart
new file mode 100644
index 0000000000000000000000000000000000000000..0899015c56276abe8f01303c2e13619ec2fbe44b
--- /dev/null
+++ b/lib/utils/profile_utils.dart
@@ -0,0 +1,10 @@
+import 'package:flutter/material.dart';
+
+const seenColor = Colors.black;
+
+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;
+}
diff --git a/lib/utils/validator.dart b/lib/utils/validator.dart
index b83b22c6b448151604d79a478758efe82ea8a750..e1d845c39cab7333f82d7be7df9163c37d557038 100644
--- a/lib/utils/validator.dart
+++ b/lib/utils/validator.dart
@@ -34,6 +34,14 @@ class FieldValidator {
}
}
+ static String validateOrganisasi(String value) {
+ if (value.isEmpty) {
+ return '*Wajib diisi';
+ } else {
+ return null;
+ }
+ }
+
static String validateEmail(String value) {
const pattern =
r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
diff --git a/pubspec.yaml b/pubspec.yaml
index 78b485cd46742ba1c02678a248ebdd3be1ca9462..13fba942921fbaad8554267634e10743ccec7d81 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -55,7 +55,9 @@ dependencies:
firebase_core: ^0.7.0
firebase_core_platform_interface: ^3.0.1
firebase_dynamic_links: ^0.7.0+1
+ firebase_messaging: ^8.0.0-dev.15
carousel_slider: ^3.0.0
+ flushbar: ^1.10.4
url_launcher: ^6.0.3
photo_view: ^0.11.1
multi_image_picker: ^4.8.1
diff --git a/test/cloud_messaging_test.dart b/test/cloud_messaging_test.dart
new file mode 100644
index 0000000000000000000000000000000000000000..0f41541f63c9215ec6799f8bb744c81c0501071e
--- /dev/null
+++ b/test/cloud_messaging_test.dart
@@ -0,0 +1,26 @@
+import 'package:bisaGo/repository/cloud_messaging_repository.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:get_it/get_it.dart';
+import 'package:mockito/mockito.dart';
+
+class MockCloudMessagingRepository extends Fake
+ implements CloudMessagingRepository {
+ @override
+ Future sendFCMToken(String fcmToken, String token) async {
+ return Future.value(true);
+ }
+}
+
+void main() {
+ setUpAll(() {
+ final _getIt = GetIt.instance;
+ _getIt.registerLazySingleton(
+ () => MockCloudMessagingRepository());
+ });
+ testWidgets('Generate fcm token', (WidgetTester tester) async {
+ final result =
+ await MockCloudMessagingRepository().sendFCMToken('fcmToken', 'token');
+
+ expect(result, true);
+ });
+}
diff --git a/test/custom_kegiatan_terdekat_button_test.dart b/test/custom_kegiatan_terdekat_button_test.dart
index b59a76e6ddb6c05e04c783a622ac1caae15747bc..c8b5511d1806c21d08d3819e2589d6d3bb86b1ca 100644
--- a/test/custom_kegiatan_terdekat_button_test.dart
+++ b/test/custom_kegiatan_terdekat_button_test.dart
@@ -1,6 +1,7 @@
import 'package:bisaGo/model/kegiatan.dart';
import 'package:bisaGo/model/lokasi.dart';
import 'package:bisaGo/page/dashboard/dashboard.dart';
+import 'package:bisaGo/repository/cloud_messaging_repository.dart';
import 'package:bisaGo/repository/kegiatan_terdekat_repository.dart';
import 'package:bisaGo/repository/lokasi_repository.dart';
import 'package:flutter/material.dart';
@@ -41,6 +42,14 @@ class MockLokasi extends Fake implements LokasiRepository {
}
}
+class MockCloudMessagingRepository extends Fake
+ implements CloudMessagingRepository {
+ @override
+ Future sendFCMToken(String fcmToken, String token) async {
+ return Future.value(true);
+ }
+}
+
void main() {
// final mockLokasi = {
// 'name': 'Margo City',
@@ -68,6 +77,8 @@ void main() {
_getIt.registerLazySingleton(
() => MockKegiatanTerdekat());
_getIt.registerLazySingleton(() => MockLokasi());
+ _getIt.registerLazySingleton(
+ () => MockCloudMessagingRepository());
});
testWidgets('Detail Post Kegiatan Page - Positive Test',
diff --git a/test/detail_post_test.dart b/test/detail_post_test.dart
index 0d6625dfd8f4f5de82c144aae85ad75c065b80aa..7f10f7cce9107484fc19485df8b42599c80f4351 100644
--- a/test/detail_post_test.dart
+++ b/test/detail_post_test.dart
@@ -66,13 +66,23 @@ void main() {
testWidgets('Create a komentar placeholder', (WidgetTester tester) async {
final detailPostState = detailPostPage.createState();
detailPostState.komentarPlaceHolder(
- 'Halo', DateTime(2020, 1, 1), 'This is a test');
+ 'Halo',
+ DateTime(2020, 1, 1),
+ 'This is a test',
+ 'test@email.com',
+ 'test.jpg',
+ );
});
testWidgets('Create a komentar placeholder', (WidgetTester tester) async {
final detailPostState = detailPostPage.createState();
detailPostState.komentarPlaceHolder(
- 'Halo', DateTime(2020, 1, 1), 'This is a test');
+ 'Halo',
+ DateTime(2020, 1, 1),
+ 'This is a test',
+ 'test@email.com',
+ 'test.jpg',
+ );
});
test('Should decrypt tag code', () {
diff --git a/test/login_test.dart b/test/login_test.dart
index dbea2e890f13312a62278d6c6ebd0f8b1ff7aeca..bf03c007308d905a2a816fd91de524fd53ea3019 100644
--- a/test/login_test.dart
+++ b/test/login_test.dart
@@ -1,6 +1,7 @@
import 'dart:io';
import 'package:bisaGo/model/user.dart';
+import 'package:bisaGo/repository/cloud_messaging_repository.dart';
import 'package:bisaGo/repository/user_repository.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
@@ -13,13 +14,21 @@ import 'package:shared_preferences/shared_preferences.dart';
class MockNetwork extends Mock implements NetworkInterface {}
+class MockCloudMessagingRepository extends Fake
+ implements CloudMessagingRepository {
+ @override
+ Future sendFCMToken(String fcmToken, String token) async {
+ return Future.value(true);
+ }
+}
+
class MockUserRepository extends Fake implements UserRepository {
final userData = {
'is_login': true,
'username': 'test@gmail.com',
'name': 'test',
'email': 'test@gmail.com',
- 'tanggal_lahir': '2000-01-01',
+ 'tanggal_lahir': '02 October 2000',
'phone_number': '081234567898',
'jenis_kelamin': 'Laki-Laki',
'disabilitas': '-',
@@ -28,8 +37,8 @@ class MockUserRepository extends Fake implements UserRepository {
};
@override
- Future fetchUserDetail(String email) async {
- return Future.value(User([UserModel.fromJson(userData)]));
+ Future fetchUserDetail(String email) async {
+ return Future.value(DetailUserModel.fromJson(userData));
}
}
@@ -41,6 +50,9 @@ void main() {
.registerLazySingleton(() => MockUserRepository());
SharedPreferences.setMockInitialValues(
{'email': 'test@gmail.com', 'token': 'token'});
+
+ _getIt.registerLazySingleton(
+ () => MockCloudMessagingRepository());
// mockNetwork = MockNetwork();
// when(mockNetwork.get(isLogin: false, url: anyNamed('url')))
// .thenAnswer((_) async {
diff --git a/test/mock_test.dart b/test/mock_test.dart
index 032df7c1fd880109b3b02dcc9b12b37b37c84dca..32c7466c40368ed665c9c7ebce539fc93bd7877b 100644
--- a/test/mock_test.dart
+++ b/test/mock_test.dart
@@ -1,4 +1,5 @@
import 'package:bisaGo/model/kegiatan.dart';
+import 'package:bisaGo/repository/cloud_messaging_repository.dart';
import 'package:bisaGo/repository/kegiatan_terdekat_repository.dart';
import 'package:bisaGo/repository/lokasi_repository.dart';
import 'package:flutter/material.dart';
@@ -45,6 +46,14 @@ class MockKegiatanTerdekatRepository extends Fake
}
}
+class MockCloudMessagingRepository extends Fake
+ implements CloudMessagingRepository {
+ @override
+ Future sendFCMToken(String fcmToken, String token) async {
+ return Future.value(true);
+ }
+}
+
void main() {
group('Dashboard navigation tests', () {
NavigatorObserver mockObserver;
@@ -74,6 +83,8 @@ void main() {
() => MockLokasiRepository());
_getIt.registerLazySingleton(
() => MockKegiatanTerdekatRepository());
+ _getIt.registerLazySingleton(
+ () => MockCloudMessagingRepository());
});
Future _buildDashboardPage(WidgetTester tester) async {
diff --git a/test/model_test.dart b/test/model_test.dart
index 9978873c020ff5cf03c449cebade6f797a08b86b..aad27f1a611725abc6b756f892296a091ded66f2 100644
--- a/test/model_test.dart
+++ b/test/model_test.dart
@@ -1,6 +1,5 @@
import 'package:bisaGo/model/komentar.dart';
import 'package:bisaGo/model/komentar_posting.dart';
-import 'package:bisaGo/model/new_user.dart';
import 'package:bisaGo/model/user.dart';
import 'package:flutter_test/flutter_test.dart';
@@ -9,26 +8,35 @@ void main() {
'id': 1,
'deskripsi': 'This is a test',
'creator': 'Test',
- 'date_time': '2020-11-18 00:13:52.939668'
+ 'creator_email': 'test@email.com',
+ 'creator_picture': 'test.jpg',
+ 'created': '18-11-2020 00:13:52'
};
final returnKomentarPostingData = {
'id': 1,
'deskripsi': 'This is a test',
'creator': 'Test',
- 'date_time': '2020-11-18T00:13:00.000'
+ 'creator_email': 'test@email.com',
+ 'creator_picture': 'test.jpg',
+ 'created': '2020-11-18T00:13:00.000'
};
final userData = {
- 'is_login': true,
- 'username': 'test@gmail.com',
+ 'username': 'test@email.com',
'name': 'test',
- 'email': 'test@gmail.com',
- 'tanggal_lahir': '2000-01-01',
+ 'email': 'test@email.com',
+ 'tanggal_lahir': '02 October 2000',
'phone_number': '081234567898',
'jenis_kelamin': 'Laki-Laki',
'disabilitas': 'Tidak Memiliki Disabilitas',
'pekerjaan': 'Mahasiswa',
'alamat': 'Tidak Tahu',
- 'token': null
+ 'seen': true,
+ 'foto': '',
+ 'hidden_fields': [],
+ 'hidden_fields_verbose': [],
+ 'can_see_hidden_fields': true,
+ 'hidden_fields_color': '#808080',
+ 'organisasi_komunitas': 'Organisasi',
};
final komentarData = {
'id': 1,
@@ -36,13 +44,14 @@ void main() {
'deskripsi':
'Ada toilet khusus disabilitas terletak di lantai 2 dekat kintan',
'creator': '',
- 'date_time': '2020-11-18 00:13:52.939668',
+ 'date_time': '18-11-2020 00:13:52',
'rating': 3,
'tag': 'KR',
'disabilitas': ['DF'],
'jumlah': 1,
'image': 'static/img/2669211407.jpg',
- 'is_verified': false
+ 'is_verified': false,
+ 'creator_email': 'test@email.com'
};
final returnKomentarData = {
'id': 1,
@@ -56,28 +65,32 @@ void main() {
'disabilitas': ['DF'],
'jumlah': 1,
'image': 'static/img/2669211407.jpg',
- 'is_verified': false
+ 'is_verified': false,
+ 'creator_email': 'test@email.com',
};
final newUserData = {
'name': 'test',
- 'email': 'test@gmail.com',
+ 'email': 'test@email.com',
'password': '2139809348143123',
- 'tanggal_lahir': '2000-01-01',
+ 'tanggal_lahir': '02 October 2000',
'phone_number': '081234567898',
'jenis_kelamin': 'Laki-Laki',
'disabilitas': 'Tidak Memiliki Disabilitas',
'pekerjaan': 'Mahasiswa',
'alamat': 'Tidak Tahu',
+ 'hidden_fields': [],
};
test('Komentar Posting fromJson and toJson', () {
final komentarPostingModel =
KomentarPostingModel.fromJson(komentarPostingData);
final komentarPostingWithConstructor = KomentarPostingModel(
- id: 2,
- deskripsi: 'This is a test',
- creator: 'Test',
- dateTime: DateTime.now());
+ id: 2,
+ deskripsi: 'This is a test',
+ creator: 'Test',
+ creatorEmail: 'test@email.com',
+ creatorPicture: 'test.jpg',
+ created: DateTime.now());
expect(komentarPostingModel, isInstanceOf());
expect(
komentarPostingWithConstructor, isInstanceOf());
@@ -93,15 +106,13 @@ void main() {
});
test('User Model fromJson and toJson', () {
- final userModel = [UserModel.fromJson(userData)];
- final user = User(userModel);
- expect(user.user.length, 1);
- expect(userModel.first.toJson(), userData);
+ final userModel = DetailUserModel.fromJson(userData);
+ expect(userModel.toJson(), userData);
});
test('User Model fromJson and toJson', () {
- final newUserModel = NewUser.fromJson(newUserData);
- expect(newUserModel, isInstanceOf());
+ final newUserModel = RegisterUserModel.fromJson(newUserData);
+ expect(newUserModel, isInstanceOf());
});
test('Komentar Model toJson', () {
diff --git a/test/pilih_disabilitas_test.dart b/test/pilih_disabilitas_test.dart
index a149cf3c7926b4788bbc6bc6cba02e8446985a01..c5cf4101d5a38925b0aa8ff835c298faa799fd31 100644
--- a/test/pilih_disabilitas_test.dart
+++ b/test/pilih_disabilitas_test.dart
@@ -1,28 +1,24 @@
-import 'package:bisaGo/model/new_user.dart';
+import 'package:bisaGo/model/user.dart';
import 'package:bisaGo/page/login/pilih_disabilitas.dart';
import 'package:bisaGo/repository/user_repository.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:get_it/get_it.dart';
-import 'package:http/http.dart';
import 'package:mockito/mockito.dart';
class MockUserRepository extends Fake implements UserRepository {
@override
- Future updateUser(NewUser newUser) async {
- final responseBody = {'response': 'User updated'};
- final statusCode = 200;
- return Future.value(Response(responseBody.toString(), statusCode));
+ Future updateUser(UpdateUserModel updateUserModel, String email) async {
+ return Future.value(DetailUserModel());
}
}
void main() {
final userData = {
- 'is_login': true,
'username': 'test@gmail.com',
'name': 'test',
'email': 'test@gmail.com',
- 'tanggal_lahir': '2000-01-01',
+ 'tanggal_lahir': '02 October 2000',
'phone_number': '081234567898',
'jenis_kelamin': 'Laki-Laki',
'disabilitas': 'Tidak memiliki disabilitas',
@@ -96,7 +92,7 @@ void main() {
(WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
home: PilihDisabilitas(
- newUser: NewUser.fromJson(userData),
+ updateUser: UpdateUserModel.fromJson(userData),
)));
final disabilitasIntelektualButton = find.text('Disabilitas Intelektual');
expect(disabilitasIntelektualButton, findsOneWidget);
@@ -105,7 +101,7 @@ void main() {
await tester.pumpWidget(MaterialApp(
home: PilihDisabilitas(
- newUser: NewUser.fromJson(userData),
+ updateUser: UpdateUserModel.fromJson(userData),
)));
final disabilitasSensorikButton = find.text('Disabilitas Sensorik');
expect(disabilitasSensorikButton, findsOneWidget);
@@ -114,7 +110,7 @@ void main() {
await tester.pumpWidget(MaterialApp(
home: PilihDisabilitas(
- newUser: NewUser.fromJson(userData),
+ updateUser: UpdateUserModel.fromJson(userData),
)));
final disabilitasMentalButton = find.text('Disabilitas Mental');
expect(disabilitasMentalButton, findsOneWidget);
@@ -123,7 +119,7 @@ void main() {
await tester.pumpWidget(MaterialApp(
home: PilihDisabilitas(
- newUser: NewUser.fromJson(userData),
+ updateUser: UpdateUserModel.fromJson(userData),
)));
final disabilitasFisikButton = find.text('Disabilitas Fisik');
expect(disabilitasFisikButton, findsOneWidget);
diff --git a/test/profile_test.dart b/test/profile_test.dart
index e1f62408f9d59a3723dd6baea5e48340e0bbfb09..59901d7ded94c53a8a0538d89880a165de010056 100644
--- a/test/profile_test.dart
+++ b/test/profile_test.dart
@@ -1,5 +1,6 @@
+import 'dart:convert';
+
import 'package:bisaGo/component/bisago_drawer.dart';
-import 'package:bisaGo/model/new_user.dart';
import 'package:bisaGo/model/user.dart';
import 'package:bisaGo/page/profile/edit_profile.dart';
import 'package:bisaGo/page/profile/profile.dart';
@@ -7,7 +8,6 @@ import 'package:bisaGo/repository/user_repository.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:get_it/get_it.dart';
-import 'package:http/http.dart';
import 'package:mockito/mockito.dart';
import 'package:shared_preferences/shared_preferences.dart';
@@ -17,31 +17,30 @@ class MockUserRepository extends Fake implements UserRepository {
'username': 'test@gmail.com',
'name': 'test',
'email': 'test@gmail.com',
- 'tanggal_lahir': '2000-01-01',
+ 'tanggal_lahir': '02 October 2000',
'phone_number': '081234567898',
'jenis_kelamin': 'Laki-Laki',
'disabilitas': 'Tidak memiliki disabilitas',
'pekerjaan': 'Pelajar',
- 'alamat': 'Tidak Tahu'
+ 'alamat': 'Tidak Tahu',
+ 'hidden_fields': [],
+ 'hidden_fields_verbose': [],
+ 'can_see_hidden_fields': true,
+ 'hidden_fields_color': '#808080',
+ 'seen': true,
};
@override
- Future fetchUserDetail(String email) async {
- return Future.value(User([UserModel.fromJson(userData)]));
+ Future fetchUserDetail(String email) async {
+ return Future.value(DetailUserModel.fromJson(userData));
}
@override
- Future updateUser(NewUser newUser) async {
- var responseBody;
- var statusCode;
- if (newUser.disabilitas != null) {
- responseBody = {'response': 'User updated'};
- statusCode = 200;
- } else {
- responseBody = {'response': 'Failed to update user'};
- statusCode = 400;
+ Future updateUser(UpdateUserModel updateUserModel, String email) async {
+ if (updateUserModel.disabilitas = null) {
+ return null;
}
- return Future.value(Response(responseBody.toString(), statusCode));
+ return Future.value(DetailUserModel());
}
}
@@ -52,20 +51,17 @@ void main() {
_getIt.registerLazySingleton(
() => MockUserRepository());
SharedPreferences.setMockInitialValues(
- {'email': 'test@gmail.com', 'token': 'token'});
+ {'user':jsonEncode({'email': 'test@gmail.com'}), 'token': 'token'});
});
testWidgets('Dashboard with User', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(home: BisaGoDrawer()));
await tester.pumpAndSettle();
expect(find.text('test@gmail.com'), findsOneWidget);
-
- await tester.tap(find.text('Profile'));
- await tester.pumpAndSettle();
});
testWidgets('Dashboard with no User', (WidgetTester tester) async {
- SharedPreferences.setMockInitialValues({'email': 'test@gmail.com'});
+ SharedPreferences.setMockInitialValues({'user':jsonEncode({'email': 'test@gmail.com'})});
await tester.pumpWidget(MaterialApp(home: BisaGoDrawer()));
await tester.pumpAndSettle();
expect(find.text('test@gmail.com'), findsNothing);
@@ -161,23 +157,33 @@ void main() {
final userData = {
'name': 'test',
'email': 'test@gmail.com',
- 'tanggal_lahir': '2000-01-01',
+ 'tanggal_lahir': '02 October 2000',
'phone_number': '081234567898',
'jenis_kelamin': 'Laki-laki',
'disabilitas': 'Tidak memiliki disabilitas',
'pekerjaan': 'Pelajar',
- 'alamat': 'Tidak Tahu'
+ 'alamat': 'Tidak Tahu',
+ 'seen': true,
+ 'hidden_fields': [],
+ 'hidden_fields_verbose': [],
+ 'can_see_hidden_fields': true,
+ 'hidden_fields_color': '#808080',
};
final userData2 = {
'name': 'test',
'email': '',
- 'tanggal_lahir': '2000-01-01',
+ 'tanggal_lahir': '02 October 2000',
'phone_number': '',
'jenis_kelamin': 'Laki-laki',
'disabilitas': 'Tidak memiliki disabilitas',
'pekerjaan': 'Pelajar',
- 'alamat': ''
+ 'alamat': '',
+ 'seen': true,
+ 'hidden_fields': [],
+ 'hidden_fields_verbose': [],
+ 'can_see_hidden_fields': true,
+ 'hidden_fields_color': '#808080',
};
testWidgets('Edit Profile Page Widget Test -- Positive',
@@ -188,7 +194,7 @@ void main() {
await tester.pumpWidget(MaterialApp(
home: EditProfile(
- user: UserModel.fromJson(userData),
+ user: DetailUserModel.fromJson(userData),
)));
expect(find.byType(EditProfile), findsOneWidget);
expect(find.byKey(headerEditProfilePageKey), findsOneWidget);
@@ -208,7 +214,7 @@ void main() {
await tester.pumpWidget(MaterialApp(
home: EditProfile(
- user: UserModel.fromJson(userData),
+ user: DetailUserModel.fromJson(userData),
)));
expect(find.byType(EditProfile), findsOneWidget);
expect(find.byKey(headerEditProfilePageKey), findsNothing);
@@ -222,14 +228,14 @@ void main() {
testWidgets('New Edit Profile Page Widget Test -- Positive',
(WidgetTester tester) async {
- final userAvatarKey = Key('Avatar test');
+ //final userAvatarKey = Key('Avatar test');
final name = 'test';
await tester.pumpWidget(
- MaterialApp(home: EditProfile(user: UserModel.fromJson(userData))));
+ MaterialApp(home: EditProfile(user: DetailUserModel.fromJson(userData))));
await tester.pumpAndSettle();
expect(find.byType(EditProfile), findsOneWidget);
- expect(find.byKey(userAvatarKey), findsOneWidget);
+ //expect(find.byKey(userAvatarKey), findsOneWidget);
expect(find.text(name), findsOneWidget);
});
@@ -239,7 +245,7 @@ void main() {
final name = 'mantap';
await tester.pumpWidget(
- MaterialApp(home: EditProfile(user: UserModel.fromJson(userData))));
+ MaterialApp(home: EditProfile(user: DetailUserModel.fromJson(userData))));
await tester.pumpAndSettle();
expect(find.byType(Profile), findsNothing);
expect(find.byKey(userAvatarKey), findsNothing);
@@ -253,7 +259,7 @@ void main() {
final pekerjaanKey = find.byKey(Key('Dropdown Pekerjaan'));
await tester.pumpWidget(
- MaterialApp(home: EditProfile(user: UserModel.fromJson(userData))));
+ MaterialApp(home: EditProfile(user: DetailUserModel.fromJson(userData))));
await tester.pumpAndSettle();
expect(find.byType(EditProfile), findsOneWidget);
expect(jenisKelaminKey, findsOneWidget);
@@ -308,7 +314,7 @@ void main() {
userData.update('disabilitas', (value) => null);
await tester.pumpWidget(
- MaterialApp(home: EditProfile(user: UserModel.fromJson(userData2))));
+ MaterialApp(home: EditProfile(user: DetailUserModel.fromJson(userData2))));
await tester.pumpAndSettle();
expect(find.byType(EditProfile), findsOneWidget);
expect(jenisKelaminKey, findsOneWidget);
@@ -354,7 +360,8 @@ void main() {
await tester.tap(find.byKey(Key('Button Simpan')));
await tester.pumpAndSettle();
- expect(find.text('Update profile tidak berhasil!', skipOffstage: false), findsOneWidget);
+ expect(find.text('Update profile tidak berhasil!', skipOffstage: false),
+ findsOneWidget);
});
testWidgets('Require all text fields to be filled -- Positive',
@@ -362,14 +369,16 @@ void main() {
final namaKey = find.byKey(Key('Text Field Nama'));
final nomorTeleponKey = find.byKey(Key('Text Field Nomor Telepon'));
final alamatKey = find.byKey(Key('Text Field Alamat'));
+ final organisasiKey = find.byKey(Key('Text Field Organisasi'));
await tester.pumpWidget(
- MaterialApp(home: EditProfile(user: UserModel.fromJson(userData))));
+ MaterialApp(home: EditProfile(user: DetailUserModel.fromJson(userData))));
await tester.pumpAndSettle();
await tester.enterText(namaKey, 'Ardian');
await tester.enterText(nomorTeleponKey, '085811111111');
await tester.enterText(alamatKey, ' Bekasi');
+ await tester.enterText(organisasiKey, 'Olahraga');
await tester
.ensureVisible(find.byKey(Key('Button Simpan'), skipOffstage: false));
@@ -384,21 +393,37 @@ void main() {
final namaKey = find.byKey(Key('Text Field Nama'));
final nomorTeleponKey = find.byKey(Key('Text Field Nomor Telepon'));
final alamatKey = find.byKey(Key('Text Field Alamat'));
+ final organisasiKey = find.byKey(Key('Text Field Organisasi'));
await tester.pumpWidget(
- MaterialApp(home: EditProfile(user: UserModel.fromJson(userData))));
+ MaterialApp(home: EditProfile(user: DetailUserModel.fromJson(userData))));
await tester.pumpAndSettle();
await tester.enterText(namaKey, '');
await tester.enterText(nomorTeleponKey, '');
await tester.enterText(alamatKey, '');
+ await tester.enterText(organisasiKey, '');
await tester
.ensureVisible(find.byKey(Key('Button Simpan'), skipOffstage: false));
await tester.pumpAndSettle();
await tester.tap(find.byKey(Key('Button Simpan')));
await tester.pumpAndSettle();
- expect(find.text('*Wajib diisi'), findsNWidgets(3));
+ expect(find.text('*Wajib diisi'), findsNWidgets(4));
+ });
+
+ testWidgets('Change Profile Picture Title -- Positive',
+ (WidgetTester tester) async {
+ await tester.pumpWidget(
+ MaterialApp(home: EditProfile(user: DetailUserModel.fromJson(userData))));
+ expect(find.text('Ubah Foto Profil'), findsOneWidget);
+ });
+
+ testWidgets('Change Profile Picture Title -- Negative',
+ (WidgetTester tester) async {
+ await tester.pumpWidget(
+ MaterialApp(home: EditProfile(user: DetailUserModel.fromJson(userData))));
+ expect(find.text('Edit PFP'), findsNothing);
});
});
}
diff --git a/test/registrasi_informasi_layanan_disabilitas_test.dart b/test/registrasi_informasi_layanan_disabilitas_test.dart
index fe308f65cb753ae3adb29db8339062886b6f1bd0..0c65c3f2435833bc235563abcf36f11a927bb38e 100644
--- a/test/registrasi_informasi_layanan_disabilitas_test.dart
+++ b/test/registrasi_informasi_layanan_disabilitas_test.dart
@@ -43,21 +43,21 @@ void main() {
await tester.tap(find.byKey(backButtonKey));
});
- testWidgets('create penyandang method test', (WidgetTester tester) async {
- final registrasiPage = RegistrasiInformasiLayananDisabilitas();
- final registrasiState = registrasiPage.createState();
- var textEditingController = TextEditingController();
- textEditingController.text = 'This is a test';
- registrasiState.namaPenyandangController = textEditingController;
- registrasiState.alamatController = textEditingController;
- registrasiState.ttlController = textEditingController;
- registrasiState.tanggalLahir = '2000-01-01';
- registrasiState.phoneController = textEditingController;
- registrasiState.emailController = textEditingController;
- registrasiState.namaWaliController = textEditingController;
- registrasiState.alamatWaliController = textEditingController;
- registrasiState.phoneNumbOrtuController = textEditingController;
+ // testWidgets('create penyandang method test', (WidgetTester tester) async {
+ // final registrasiPage = RegistrasiInformasiLayananDisabilitas();
+ // final registrasiState = registrasiPage.createState();
+ // var textEditingController = TextEditingController();
+ // textEditingController.text = 'This is a test';
+ // registrasiState.namaPenyandangController = textEditingController;
+ // registrasiState.alamatController = textEditingController;
+ // registrasiState.ttlController = textEditingController;
+ // registrasiState.tanggalLahir = '2000-01-01';
+ // registrasiState.phoneController = textEditingController;
+ // registrasiState.emailController = textEditingController;
+ // registrasiState.namaWaliController = textEditingController;
+ // registrasiState.alamatWaliController = textEditingController;
+ // registrasiState.phoneNumbOrtuController = textEditingController;
- registrasiState.createPenyandang();
- });
+ // registrasiState.createPenyandang();
+ // });
}
diff --git a/test/registrasi_test.dart b/test/registrasi_test.dart
index 9fed8a65172854aa1b3772f81f0bf222ed0f8817..e632c0ff4a8df79e4b17bd2520601637b7470006 100644
--- a/test/registrasi_test.dart
+++ b/test/registrasi_test.dart
@@ -1,26 +1,24 @@
-import 'package:bisaGo/model/new_user.dart';
+import 'package:bisaGo/model/user.dart';
import 'package:bisaGo/repository/user_repository.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:bisaGo/page/registrasi/registrasi.dart';
import 'package:get_it/get_it.dart';
import 'package:mockito/mockito.dart';
-//import 'package:bisaGo/model/user.dart';
-import 'package:http/http.dart';
class MockUserRepository extends Fake implements UserRepository {
@override
- Future createUser(NewUser newUser) async {
- final responseBody = {'response': 'User updated'};
- final statusCode = 200;
- return Future.value(Response(responseBody.toString(), statusCode));
+ Future registerUser(RegisterUserModel registerUserModel) async {
+ final responseBody = {'response': 'User registered'};
+ return Future.value(responseBody);
}
}
void main() {
setUpAll(() {
final _getIt = GetIt.instance;
- _getIt.registerLazySingleton(() => MockUserRepository());
+ _getIt
+ .registerLazySingleton(() => MockUserRepository());
});
testWidgets('Find Name Text Field', (WidgetTester tester) async {
final textFieldKey = Key('Text Field Nama');
@@ -96,7 +94,7 @@ void main() {
final pekerjaanKey = find.byKey(Key('Dropdown Pekerjaan'));
final password = find.byKey(Key('Text Field Password'));
final konfirmasiPassword =
- find.byKey(Key('Text Field Konfirmasi Password'));
+ find.byKey(Key('Text Field Konfirmasi Password'));
await tester.enterText(nama, 'nama');
await tester.enterText(noTelp, '08123456789');
@@ -137,8 +135,6 @@ void main() {
await tester
.ensureVisible(find.byKey(daftarButtonKey, skipOffstage: false));
- await tester.pumpAndSettle(const Duration(seconds: 1));
- await tester.tap(find.byKey(daftarButtonKey));
await tester.pumpAndSettle();
});
diff --git a/test/user_test.dart b/test/user_test.dart
index 4703a5b488a6991bf706ac1497f0825abc4af8c0..0a555d702f8f4f1698763185e8545078420dcd6e 100644
--- a/test/user_test.dart
+++ b/test/user_test.dart
@@ -3,23 +3,26 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
final userData = {
- 'is_login':true,
- 'username':'test@gmail.com',
- 'name':'test',
- 'email':'test@gmail.com',
- 'tanggal_lahir':'2000-01-01',
- 'phone_number':'081234567898',
- 'jenis_kelamin':'Laki-Laki',
- 'disabilitas':'Tidak Memiliki Disabilitas',
- 'pekerjaan':'Mahasiswa',
- 'alamat':'Tidak Tahu',
- 'token':null
+ 'username': 'test@gmail.com',
+ 'name': 'test',
+ 'email': 'test@gmail.com',
+ 'tanggal_lahir': '02 October 2000',
+ 'phone_number': '081234567898',
+ 'jenis_kelamin': 'Laki-Laki',
+ 'disabilitas': 'Tidak Memiliki Disabilitas',
+ 'pekerjaan': 'Mahasiswa',
+ 'alamat': 'Tidak Tahu',
+ 'seen': true,
+ 'foto': '',
+ 'hidden_fields': [],
+ 'hidden_fields_verbose': [],
+ 'can_see_hidden_fields': true,
+ 'hidden_fields_color': '#808080',
+ 'organisasi_komunitas': 'Organisasi',
};
test('User Model', () {
- final userModel = [UserModel.fromJson(userData)];
- final user = User(userModel);
- expect(user.user.length, 1);
- expect(userModel.first.toJson(), userData);
+ final userModel = DetailUserModel.fromJson(userData);
+ expect(userModel.toJson(), userData);
});
-}
\ No newline at end of file
+}
diff --git a/test/widget_test.dart b/test/widget_test.dart
index bac647fc7feb60b7b71c5e090f1f3d194d731782..69c70526ce7c3346e24df51c92fa9352374b3591 100644
--- a/test/widget_test.dart
+++ b/test/widget_test.dart
@@ -2,6 +2,7 @@ import 'package:bisaGo/model/kegiatan.dart';
import 'package:bisaGo/model/komunitas.dart';
import 'package:bisaGo/model/lokasi.dart';
import 'package:bisaGo/model/sekolah.dart';
+import 'package:bisaGo/repository/cloud_messaging_repository.dart';
import 'package:bisaGo/repository/kegiatan_terdekat_repository.dart';
import 'package:bisaGo/repository/komunitas_repository.dart';
import 'package:bisaGo/repository/lokasi_repository.dart';
@@ -88,6 +89,14 @@ class MockKegiatanTerdekatRepository extends Fake
}
}
+class MockCloudMessagingRepository extends Fake
+ implements CloudMessagingRepository {
+ @override
+ Future sendFCMToken(String fcmToken, String token) async {
+ return Future.value(true);
+ }
+}
+
void main() {
setUpAll(() {
final _getIt = GetIt.instance;
@@ -99,6 +108,8 @@ void main() {
() => MockLokasiRepository());
_getIt.registerLazySingleton(
() => MockKegiatanTerdekatRepository());
+ _getIt.registerLazySingleton(
+ () => MockCloudMessagingRepository());
});
testWidgets('finds a text field in dashboard', (WidgetTester tester) async {
final containerTextField = Key('Container Text Field');