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 7e0e18fb45ff626a6fc56cfea115918375278066..ea7ae76cd2a169db2a144e3e9eb4badb211784af 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -33,6 +33,10 @@
+
+
+
+
@@ -41,5 +45,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..62642395e589bde6ebeb5ad92577e10f4b0287b8 100644
--- a/android/fastlane/metadata/android/id/changelogs/changelogs.txt
+++ b/android/fastlane/metadata/android/id/changelogs/changelogs.txt
@@ -1,20 +1,20 @@
+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/config/custom_serializer.dart b/lib/config/custom_serializer.dart
index 00ed551485c6ffcbb5d0b4b99156a5d29c1d383b..458c5a40085be5818e9619941d34b67cc150f7da 100644
--- a/lib/config/custom_serializer.dart
+++ b/lib/config/custom_serializer.dart
@@ -2,6 +2,6 @@ import 'package:intl/intl.dart';
class CustomSerializer {
static DateTime stringToDateTime(String date) {
- return DateFormat('yyyy-MM-dd hh:mm').parse(date);
+ return DateFormat('dd-MM-yyyy hh:mm').parse(date);
}
}
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/komentar_posting.dart b/lib/model/komentar_posting.dart
index 04ffea66b0f7e81b692aeb063c34950447605436..465d0691b5f2d76f3325ed7e36af878d9473bc63 100644
--- a/lib/model/komentar_posting.dart
+++ b/lib/model/komentar_posting.dart
@@ -14,10 +14,15 @@ class KomentarPostingModel {
final int id;
final String deskripsi;
final String creator;
- @JsonKey(name: 'date_time', fromJson: CustomSerializer.stringToDateTime)
- final DateTime dateTime;
+ @JsonKey(fromJson: CustomSerializer.stringToDateTime)
+ final DateTime created;
- KomentarPostingModel({this.id, this.deskripsi, this.creator, this.dateTime});
+ KomentarPostingModel({
+ this.id,
+ this.deskripsi,
+ this.creator,
+ this.created,
+ });
factory KomentarPostingModel.fromJson(Map json) =>
_$KomentarPostingModelFromJson(json);
diff --git a/lib/model/komentar_posting.g.dart b/lib/model/komentar_posting.g.dart
index 565bcd3708949851186ff00919f57aa4691bedf5..0670572063c1797746975910dbcc6828422dff10 100644
--- a/lib/model/komentar_posting.g.dart
+++ b/lib/model/komentar_posting.g.dart
@@ -27,7 +27,7 @@ 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),
+ created: CustomSerializer.stringToDateTime(json['created'] as String),
);
}
@@ -37,5 +37,5 @@ Map _$KomentarPostingModelToJson(
'id': instance.id,
'deskripsi': instance.deskripsi,
'creator': instance.creator,
- 'date_time': instance.dateTime?.toIso8601String(),
+ 'created': instance.created?.toIso8601String(),
};
diff --git a/lib/model/komentar_posting_kegiatan.dart b/lib/model/komentar_posting_kegiatan.dart
index 78e18d736f1dce8e066d0f562a7b6588dd3ab2a7..4f668c1b42c5e5259644469eef0d122e332b7df4 100644
--- a/lib/model/komentar_posting_kegiatan.dart
+++ b/lib/model/komentar_posting_kegiatan.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_kegiatan.g.dart';
@@ -14,18 +14,18 @@ class KomentarPostingKegiatanModel {
final int id;
final String creator;
final String deskripsi;
- @JsonKey(name: 'created', fromJson: CustomSerializer.stringToDateTime)
+ @JsonKey(name: 'created', fromJson: _stringToDateTime)
final DateTime created;
KomentarPostingKegiatanModel(
- {this.id,
- this.creator,
- this.deskripsi,
- this.created}
- );
+ {this.id, this.creator, this.deskripsi, this.created});
factory KomentarPostingKegiatanModel.fromJson(Map json) =>
_$KomentarPostingKegiatanModelFromJson(json);
Map toJson() => _$KomentarPostingKegiatanModelToJson(this);
}
+
+DateTime _stringToDateTime(String date) {
+ return DateFormat('yyy-MM-dd hh:mm').parse(date);
+}
diff --git a/lib/model/komentar_posting_kegiatan.g.dart b/lib/model/komentar_posting_kegiatan.g.dart
index 3b73f1a6ad4fa7c4a655ef055826935ec7a33754..49596213e4df2955e63cdc26d289aab9d0e37af3 100644
--- a/lib/model/komentar_posting_kegiatan.g.dart
+++ b/lib/model/komentar_posting_kegiatan.g.dart
@@ -29,7 +29,7 @@ KomentarPostingKegiatanModel _$KomentarPostingKegiatanModelFromJson(
id: json['id'] as int,
creator: json['creator'] as String,
deskripsi: json['deskripsi'] as String,
- created: CustomSerializer.stringToDateTime(json['created'] as String),
+ created: _stringToDateTime(json['created'] as String),
);
}
diff --git a/lib/page/dashboard/dashboard.dart b/lib/page/dashboard/dashboard.dart
index 8e70ad4b6701d65f787ae760644f32541446f775..f6915b4dd5290abd37f74c2d49b7e62340fe2fa0 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) {
@@ -368,20 +447,20 @@ class DashboardState extends State {
..name = namaLokasi;
final fasilitasRoute = MaterialPageRoute(
builder: (BuildContext context) => DetailPostKegiatanPage(
- lokasi: lokasi,
- kegiatan: KegiatanModel(
- id: kegiatan.id,
- placeId: lokasi.placeId,
- creator: kegiatan.creator,
- namaKegiatan: kegiatan.namaKegiatan,
- penyelenggara: kegiatan.penyelenggara,
- narahubung: kegiatan.narahubung,
- deskripsi: kegiatan.deskripsi,
- timeStart: kegiatan.timeStart,
- timeEnd: kegiatan.timeEnd,
- image: kegiatan.image,
- ),
- ));
+ lokasi: lokasi,
+ kegiatan: KegiatanModel(
+ id: kegiatan.id,
+ placeId: lokasi.placeId,
+ creator: kegiatan.creator,
+ namaKegiatan: kegiatan.namaKegiatan,
+ penyelenggara: kegiatan.penyelenggara,
+ narahubung: kegiatan.narahubung,
+ deskripsi: kegiatan.deskripsi,
+ timeStart: kegiatan.timeStart,
+ timeEnd: kegiatan.timeEnd,
+ image: kegiatan.image,
+ ),
+ ));
await Navigator.of(context).push(fasilitasRoute);
}
diff --git a/lib/page/filter_fasilitas/kegiatan.dart b/lib/page/filter_fasilitas/kegiatan.dart
index d66844303731fed78a616cb41ff20511a7cc3121..ef3c723ed8d307f91a464bec41ae8596ef5c1fce 100644
--- a/lib/page/filter_fasilitas/kegiatan.dart
+++ b/lib/page/filter_fasilitas/kegiatan.dart
@@ -17,29 +17,27 @@ class Kegiatan extends StatefulWidget {
}
class _KegiatanState extends State {
-
@override
Widget build(BuildContext context) {
return InkWell(
key: Key(widget.kegiatan.namaKegiatan),
onTap: () {
- Navigator.of(context).pushReplacement(MaterialPageRoute(
+ Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => DetailPostKegiatanPage(
- lokasi: widget.lokasi,
- kegiatan: KegiatanModel(
- id: widget.kegiatan.id,
- placeId: widget.kegiatan.placeId,
- creator: widget.kegiatan.creator,
- namaKegiatan: widget.kegiatan.namaKegiatan,
- penyelenggara: widget.kegiatan.penyelenggara,
- narahubung: widget.kegiatan.narahubung,
- deskripsi: widget.kegiatan.deskripsi,
- timeStart: widget.kegiatan.timeStart,
- timeEnd: widget.kegiatan.timeEnd,
- image: widget.kegiatan.image,
- ),
- )
- ));
+ lokasi: widget.lokasi,
+ kegiatan: KegiatanModel(
+ id: widget.kegiatan.id,
+ placeId: widget.kegiatan.placeId,
+ creator: widget.kegiatan.creator,
+ namaKegiatan: widget.kegiatan.namaKegiatan,
+ penyelenggara: widget.kegiatan.penyelenggara,
+ narahubung: widget.kegiatan.narahubung,
+ deskripsi: widget.kegiatan.deskripsi,
+ timeStart: widget.kegiatan.timeStart,
+ timeEnd: widget.kegiatan.timeEnd,
+ image: widget.kegiatan.image,
+ ),
+ )));
},
child: Container(
margin: const EdgeInsets.only(bottom: regularSpace),
@@ -72,59 +70,68 @@ class _KegiatanState extends State {
),
),
Container(
- margin: const EdgeInsets.only(bottom: regularSpace),
- child: SizedBox(
- width: MediaQuery.of(context).size.width,
- height: 160,
- child: CarouselSlider(
- options: CarouselOptions(
- aspectRatio: 1.0,
- enlargeCenterPage: true,
- enableInfiniteScroll: false,
- initialPage: 0,
- autoPlay: true,
- ),
- items: widget.kegiatan.image.map((item) => Container(
- child: Container(
- child: ClipRRect(
- borderRadius: BorderRadius.all(Radius.circular(20)),
- child: Stack(
- children: [
- Image.network(item, fit: BoxFit.cover, width: 1000.0),
- Positioned(
- bottom: 0.0,
- left: 0.0,
- right: 0.0,
+ margin: const EdgeInsets.only(bottom: regularSpace),
+ child: SizedBox(
+ width: MediaQuery.of(context).size.width,
+ height: 160,
+ child: CarouselSlider(
+ options: CarouselOptions(
+ aspectRatio: 1.0,
+ enlargeCenterPage: true,
+ enableInfiniteScroll: false,
+ initialPage: 0,
+ autoPlay: true,
+ ),
+ items: widget.kegiatan.image
+ .map((item) => Container(
child: Container(
- decoration: BoxDecoration(
- gradient: LinearGradient(
- colors: [
- Color.fromARGB(200, 0, 0, 0),
- Color.fromARGB(0, 0, 0, 0)
- ],
- begin: Alignment.bottomCenter,
- end: Alignment.topCenter,
- ),
- ),
- padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
- child: Text(
- '#${widget.kegiatan.image.indexOf(item)+1}',
- style: TextStyle(
- color: Colors.white,
- fontSize: 20.0,
- fontWeight: FontWeight.bold,
- ),
- ),
+ child: ClipRRect(
+ borderRadius: BorderRadius.all(
+ Radius.circular(20)),
+ child: Stack(
+ children: [
+ Image.network(item,
+ fit: BoxFit.cover,
+ width: 1000.0),
+ Positioned(
+ bottom: 0.0,
+ left: 0.0,
+ right: 0.0,
+ child: Container(
+ decoration: BoxDecoration(
+ gradient: LinearGradient(
+ colors: [
+ Color.fromARGB(
+ 200, 0, 0, 0),
+ Color.fromARGB(
+ 0, 0, 0, 0)
+ ],
+ begin: Alignment
+ .bottomCenter,
+ end: Alignment.topCenter,
+ ),
+ ),
+ padding: EdgeInsets.symmetric(
+ vertical: 10.0,
+ horizontal: 20.0),
+ child: Text(
+ '#${widget.kegiatan.image.indexOf(item) + 1}',
+ style: TextStyle(
+ color: Colors.white,
+ fontSize: 20.0,
+ fontWeight:
+ FontWeight.bold,
+ ),
+ ),
+ ),
+ ),
+ ],
+ )),
),
- ),
- ],
- )
- ),
- ),
- )).toList(),
- ),
- )
- ),
+ ))
+ .toList(),
+ ),
+ )),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.end,
@@ -148,5 +155,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..d7c53f2b905f61fb21f2d74e2b6fe9f430e37524 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(
diff --git a/lib/page/filter_fasilitas/postingan/detail_post.dart b/lib/page/filter_fasilitas/postingan/detail_post.dart
index af1d54df43a22cda93b3b70940ed03bd93f8eec6..c8abdb50b5d317bb103f02c43cf47885772e5156 100644
--- a/lib/page/filter_fasilitas/postingan/detail_post.dart
+++ b/lib/page/filter_fasilitas/postingan/detail_post.dart
@@ -2,7 +2,6 @@ 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/page/updateInformasi/update_informasi.dart';
import 'package:bisaGo/repository/dynamic_links_service_repository.dart';
import 'package:bisaGo/utils/share_utils.dart';
@@ -54,357 +53,345 @@ 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),
),
- ),
- ],
- ),
- ),
- 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),
+ margin: const EdgeInsets.symmetric(
+ vertical: regularSpace),
child: Text(
- '${widget.komentar.creator} ',
- key: Key('creator-${widget.komentar.creator}'),
- overflow: TextOverflow.fade,
- softWrap: false,
- style: const TextStyle(
- fontSize: 12,
- fontStyle: FontStyle.italic,
- ),
+ widget.komentar.deskripsi,
+ key: const Key('Text Cara Menggunakan'),
+ style: const TextStyle(fontSize: 16),
),
),
- Text(
- '(${DateFormat('dd MMM yyy').format(widget.komentar.dateTime)})',
- key: const Key('timestamp'),
+ ],
+ ),
+ ),
+ 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),
+ child: Text(
+ '${widget.komentar.creator} ',
+ key: Key('creator-${widget.komentar.creator}'),
+ overflow: TextOverflow.fade,
+ softWrap: false,
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:
+ ),
+ 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:
+ 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))
+ .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 +427,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 {
@@ -498,7 +482,7 @@ class _DetailPostPageState extends State {
name,
style: const TextStyle(fontSize: 18),
),
- Text('${DateFormat('dd MMMM yyy hh:mm').format(date)}',
+ Text('${DateFormat('dd MMMM yyyy hh:mm').format(date)}',
style: const TextStyle(color: grayPrimary, fontSize: 14))
],
),
diff --git a/lib/page/filter_fasilitas/postingan/detail_post_kegiatan.dart b/lib/page/filter_fasilitas/postingan/detail_post_kegiatan.dart
index fbc07c0cc10c94679c0adace288298a43bc3babc..2054000f53e0d4c3670db062138143d13ca3e917 100644
--- a/lib/page/filter_fasilitas/postingan/detail_post_kegiatan.dart
+++ b/lib/page/filter_fasilitas/postingan/detail_post_kegiatan.dart
@@ -19,8 +19,6 @@ import 'package:bisaGo/page/login/login.dart';
import 'package:share/share.dart';
import 'package:shared_preferences/shared_preferences.dart';
-import '../fasilitas.dart';
-
class DetailPostKegiatanPage extends StatefulWidget {
final Lokasi lokasi;
final KegiatanModel kegiatan; // ganti model x // sudah
@@ -48,436 +46,422 @@ class _DetailPostKegiatanPageState extends State {
@override
Widget build(BuildContext context) {
- return WillPopScope(
- onWillPop: () => Navigator.of(context).pushReplacement(MaterialPageRoute(
- builder: (BuildContext context) => Fasilitas(
- lokasi: widget.lokasi,
- ))),
- child: Scaffold(
- appBar: BisaGoAppBar(
- title: widget.lokasi.name,
- key: Key('appbar-text-${widget.kegiatan.placeId}'),
- actions: [
- InkWell(
- onTap: () async {
- final link = await DynamicLinksServiceRepository()
- .createDynamicLinkForKegiatan(
- widget.kegiatan.id,
- widget.lokasi.placeId,
- );
- await Share.share(ShareUtils.getFormattedMessageKegiatan(
- widget.kegiatan, widget.lokasi, link));
- },
- child: const Padding(
- padding: EdgeInsets.all(doubleSpace),
- child: Icon(Icons.share),
- ),
+ return Scaffold(
+ appBar: BisaGoAppBar(
+ title: widget.lokasi.name,
+ key: Key('appbar-text-${widget.kegiatan.placeId}'),
+ actions: [
+ InkWell(
+ onTap: () async {
+ final link = await DynamicLinksServiceRepository()
+ .createDynamicLinkForKegiatan(
+ widget.kegiatan.id,
+ widget.lokasi.placeId,
+ );
+ await Share.share(ShareUtils.getFormattedMessageKegiatan(
+ widget.kegiatan, widget.lokasi, link));
+ },
+ child: const Padding(
+ padding: EdgeInsets.all(doubleSpace),
+ child: Icon(Icons.share),
),
- ],
- ),
- body: SingleChildScrollView(
- child: Column(
- children: [
- Container(
- key: const Key('Text Judul Kegiatan'),
- 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,
- // ganti alias tambahan
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- SizedBox(height: regularSpace),
- Text(
- widget.kegiatan
- .namaKegiatan, // ganti nama kegiatan // sudah
- style: const TextStyle(
- fontSize: 30,
- fontWeight: FontWeight.w800,
- letterSpacing: 0.3,
- fontFamily: 'Muli',
- // color: Colors.black,
- // fontFamily: 'Comfortaa',
- ),
+ ),
+ ],
+ ),
+ body: SingleChildScrollView(
+ child: Column(
+ children: [
+ Container(
+ key: const Key('Text Judul Kegiatan'),
+ 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,
+ // ganti alias tambahan
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ SizedBox(height: regularSpace),
+ Text(
+ widget.kegiatan
+ .namaKegiatan, // ganti nama kegiatan // sudah
+ style: const TextStyle(
+ fontSize: 30,
+ fontWeight: FontWeight.w800,
+ letterSpacing: 0.3,
+ fontFamily: 'Muli',
+ // color: Colors.black,
+ // fontFamily: 'Comfortaa',
),
- Text(
- 'oleh ${widget.kegiatan.penyelenggara}', // ganti format ${nama penyelenggara} // sudah
- style: TextStyle(fontSize: 16),
- textAlign: TextAlign.left,
- )
- ],
- ),
+ ),
+ Text(
+ 'oleh ${widget.kegiatan.penyelenggara}', // ganti format ${nama penyelenggara} // sudah
+ style: TextStyle(fontSize: 16),
+ textAlign: TextAlign.left,
+ )
+ ],
),
- // 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();
- // },
- // ),
- ],
- ),
+ ),
+ // 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();
+ // },
+ // ),
+ ],
),
- Container(
- margin: const EdgeInsets.all(doubleSpace),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- SizedBox(
- width: MediaQuery.of(context).size.width,
- height: 160,
- child: CarouselSlider(
- options: CarouselOptions(
- aspectRatio: 1.0,
- enlargeCenterPage: true,
- enableInfiniteScroll: false,
- initialPage: 0,
- autoPlay: true,
- ),
- items: widget.kegiatan.image
- .map((item) => Container(
- child: Container(
- child: ClipRRect(
- borderRadius: BorderRadius.all(
- Radius.circular(20)),
- child: Stack(
- children: [
- Image.network(item,
- fit: BoxFit.cover,
- width: 1000.0),
- Positioned(
- bottom: 0.0,
- left: 0.0,
- right: 0.0,
- child: Container(
- decoration: BoxDecoration(
- gradient: LinearGradient(
- colors: [
- Color.fromARGB(
- 200, 0, 0, 0),
- Color.fromARGB(0, 0, 0, 0)
- ],
- begin:
- Alignment.bottomCenter,
- end: Alignment.topCenter,
- ),
+ ),
+ Container(
+ margin: const EdgeInsets.all(doubleSpace),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ SizedBox(
+ width: MediaQuery.of(context).size.width,
+ height: 160,
+ child: CarouselSlider(
+ options: CarouselOptions(
+ aspectRatio: 1.0,
+ enlargeCenterPage: true,
+ enableInfiniteScroll: false,
+ initialPage: 0,
+ autoPlay: true,
+ ),
+ items: widget.kegiatan.image
+ .map((item) => Container(
+ child: Container(
+ child: ClipRRect(
+ borderRadius:
+ BorderRadius.all(Radius.circular(20)),
+ child: Stack(
+ children: [
+ Image.network(item,
+ fit: BoxFit.cover, width: 1000.0),
+ Positioned(
+ bottom: 0.0,
+ left: 0.0,
+ right: 0.0,
+ child: Container(
+ decoration: BoxDecoration(
+ gradient: LinearGradient(
+ colors: [
+ Color.fromARGB(
+ 200, 0, 0, 0),
+ Color.fromARGB(0, 0, 0, 0)
+ ],
+ begin: Alignment.bottomCenter,
+ end: Alignment.topCenter,
),
- padding: EdgeInsets.symmetric(
- vertical: 10.0,
- horizontal: 20.0),
- child: Text(
- '#${widget.kegiatan.image.indexOf(item) + 1}',
- style: TextStyle(
- color: Colors.white,
- fontSize: 20.0,
- fontWeight: FontWeight.bold,
- ),
+ ),
+ padding: EdgeInsets.symmetric(
+ vertical: 10.0,
+ horizontal: 20.0),
+ child: Text(
+ '#${widget.kegiatan.image.indexOf(item) + 1}',
+ style: TextStyle(
+ color: Colors.white,
+ fontSize: 20.0,
+ fontWeight: FontWeight.bold,
),
),
),
- ],
- )),
- ),
- ))
- .toList(),
- ),
- ),
- const SizedBox(
- height: 10,
- ),
- 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),
- // ),
- // ),
- // ],
- // ),
- // Container(
- // margin: const EdgeInsets.symmetric(
- // vertical: regularSpace
- // ),
- // ganti alias tambahan
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Row(
- // mainAxisAlignment:
- // MainAxisAlignment.center,
- children: [
- const Icon(
- Icons.access_time,
- size: 20,
- color: Colors.green,
- ),
- const SizedBox(width: 7.0),
- const Text(
- 'Senin, 3 Mei 2021', // ganti format widget.x.tanggalpelaksanaan
- style: TextStyle(fontSize: 16),
- key: Key('Text Waktu Pelaksanaan'),
- ),
- ],
- ),
- SizedBox(height: 40),
- Text(
- widget.kegiatan
- .deskripsi, // ganti format widget.x.deskripsi kegiatan // sudah
- style: const TextStyle(fontSize: 16),
- key: const Key('Text Deskripsi Kegiatan'),
- ),
- SizedBox(height: 40),
- Row(
- // mainAxisAlignment:
- // MainAxisAlignment.center,
- children: [
- const Icon(
- Icons.call,
- size: 20,
- color: Colors.green,
- ),
- const SizedBox(width: 7.0),
- Text(
- widget.kegiatan
- .narahubung, // ganti format narahubung // sudah
- style: TextStyle(fontSize: 16),
- key: Key('Text Narahubung'),
- ),
- ],
- ),
- ],
- ),
- // ),
- // ],
- // ),
+ ),
+ ],
+ )),
+ ),
+ ))
+ .toList(),
),
- 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),
- child: Text(
- widget.kegiatan
- .creator, // ganti format ${widget.x.creator} // sudah
- key: Key(
- 'Creator info kegiatan'), // ganti format key creator-${widget.x.creator}
- overflow: TextOverflow.fade,
- softWrap: false,
- style: const TextStyle(
- fontSize: 12,
- fontStyle: FontStyle.italic,
+ ),
+ const SizedBox(
+ height: 10,
+ ),
+ 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),
+ // ),
+ // ),
+ // ],
+ // ),
+ // Container(
+ // margin: const EdgeInsets.symmetric(
+ // vertical: regularSpace
+ // ),
+ // ganti alias tambahan
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ // mainAxisAlignment:
+ // MainAxisAlignment.center,
+ children: [
+ const Icon(
+ Icons.access_time,
+ size: 20,
+ color: Colors.green,
),
- ),
+ const SizedBox(width: 7.0),
+ const Text(
+ 'Senin, 3 Mei 2021', // ganti format widget.x.tanggalpelaksanaan
+ style: TextStyle(fontSize: 16),
+ key: Key('Text Waktu Pelaksanaan'),
+ ),
+ ],
),
+ SizedBox(height: 40),
Text(
- '22 April 2021',
- // '(${DateFormat('dd MMM yyy').format(widget.kegiatan.dateTime)})', // ganti format (${DateFormat('dd MMM yyy').format(widget.x.dateTime)})
- key: const Key('timestamp'),
+ widget.kegiatan
+ .deskripsi, // ganti format widget.x.deskripsi kegiatan // sudah
+ style: const TextStyle(fontSize: 16),
+ key: const Key('Text Deskripsi Kegiatan'),
+ ),
+ SizedBox(height: 40),
+ Row(
+ // mainAxisAlignment:
+ // MainAxisAlignment.center,
+ children: [
+ const Icon(
+ Icons.call,
+ size: 20,
+ color: Colors.green,
+ ),
+ const SizedBox(width: 7.0),
+ Text(
+ widget.kegiatan
+ .narahubung, // ganti format narahubung // sudah
+ style: TextStyle(fontSize: 16),
+ key: Key('Text Narahubung'),
+ ),
+ ],
+ ),
+ ],
+ ),
+ // ),
+ // ],
+ // ),
+ ),
+ 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),
+ child: Text(
+ widget.kegiatan
+ .creator, // ganti format ${widget.x.creator} // sudah
+ key: Key(
+ 'Creator info kegiatan'), // ganti format key creator-${widget.x.creator}
+ overflow: TextOverflow.fade,
+ softWrap: false,
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),
),
+ Text(
+ '22 April 2021',
+ // '(${DateFormat('dd MMM yyy').format(widget.kegiatan.dateTime)})', // ganti format (${DateFormat('dd MMM yyy').format(widget.x.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.komentarPostingKegiatanListStream,
- builder: (context, snapshot) {
- if (snapshot.hasData) {
- switch (snapshot.data.status) {
- case Status.loading:
+ ),
+ StreamBuilder(
+ stream: _bloc.komentarPostingKegiatanListStream,
+ 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:
+ allKomentarPositngKegiatanFromApi = snapshot
+ .data
+ .data
+ .allKomentarKegiatan; // kalo error, brarti allKegiatan
+ if (allKomentarPositngKegiatanFromApi.isEmpty) {
return const Center(
- child: CircularProgressIndicator(
- valueColor: AlwaysStoppedAnimation(
- greenPrimary),
- ),
- );
- break;
- case Status.completed:
- allKomentarPositngKegiatanFromApi = snapshot
- .data
- .data
- .allKomentarKegiatan; // kalo error, brarti allKegiatan
- if (allKomentarPositngKegiatanFromApi.isEmpty) {
- return const Center(
- child: Text('Tidak ada komentar'));
- } else {
- return Column(
- children:
- allKomentarPositngKegiatanFromApi
- .map((k) =>
- komentarKegiatanPlaceHolder(
- k.creator,
- k.created,
- 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: allKomentarPositngKegiatanFromApi
+ .map((k) =>
+ komentarKegiatanPlaceHolder(
+ k.creator,
+ k.created,
+ k.deskripsi))
+ .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: komentarKegiatanController,
- 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: komentarKegiatanController,
+ 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),
+ ),
+ ],
+ ),
+ ),
+ )),
+ ],
+ )),
+ ],
),
- ],
- ),
+ ),
+ ],
),
),
);
@@ -513,9 +497,6 @@ class _DetailPostKegiatanPageState extends State {
if (response['response'] == 'komentar kegiatan added') {
successDialog(context);
- Timer(const Duration(seconds: 2), () {
- Navigator.pop(context);
- });
await _bloc.fetchKomentarPostingKegiatanList(
_placeId, widget.kegiatan.id); // ganti widget.x.id // sudah
komentarKegiatanController.clear();
diff --git a/lib/page/login/login.dart b/lib/page/login/login.dart
index 57496777fca5c0688955ad38c1a9cd3d59909428..67aaa2e980ca1d42832abc94dc95d84899e26ea8 100644
--- a/lib/page/login/login.dart
+++ b/lib/page/login/login.dart
@@ -1,10 +1,13 @@
import 'dart:async';
import 'dart:convert';
+import 'package:bisaGo/bloc/cloud_messaging_bloc.dart';
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/page/dashboard/dashboard.dart';
import 'package:bisaGo/page/login/pilih_disabilitas.dart';
+import 'package:firebase_core/firebase_core.dart';
+import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
@@ -35,6 +38,10 @@ class LoginState extends State {
GoogleSignInAccount _currentUser;
SharedPreferences sharedPreferences;
+ FirebaseMessaging _firebaseMessaging;
+
+ CloudMessagingBloc cloudMessagingBloc = CloudMessagingBloc();
+
@override
void initState() {
super.initState();
@@ -159,12 +166,12 @@ 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);
@@ -189,11 +196,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);
@@ -292,6 +299,8 @@ class LoginState extends State {
..setString('token', tokenMap['token'])
..setString('email', email);
});
+ await _requestFCMToken();
+
successDialog(context);
_navigateToDashboard(context);
} else {
@@ -384,6 +393,19 @@ class LoginState extends State {
}
}
+ Future _requestFCMToken() async {
+ await Firebase.initializeApp();
+
+ _firebaseMessaging = FirebaseMessaging.instance;
+
+ final fcmToken = await _firebaseMessaging.getToken();
+ final sharedPreferences = await SharedPreferences.getInstance();
+ final token = sharedPreferences.getString('token');
+ if (token != null) {
+ await cloudMessagingBloc.sendFCMToken(fcmToken, token);
+ }
+ }
+
Future _handleSignOut() async {
await _googleSignIn.signOut();
}
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 e8fdb53b8e26f78aca55f1d35bd76f11e30d7f0e..b1f969ac6488ffd7c84c331106fe6cf519abfed3 100644
--- a/lib/repository/kegiatan_repository.dart
+++ b/lib/repository/kegiatan_repository.dart
@@ -55,10 +55,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.image = await fetchImages(kegiatan.placeId, kegiatan.id);
diff --git a/lib/repository/user_repository.dart b/lib/repository/user_repository.dart
index 4ced6b383e87b1874bfcb2f7d7e5b2757bc39270..dd7caf0331ae1e354aeaf8a7c858dcf1da0e0a4c 100644
--- a/lib/repository/user_repository.dart
+++ b/lib/repository/user_repository.dart
@@ -9,13 +9,14 @@ abstract class BaseUserRepository {
Future createUser(NewUser newUser);
Future updateUser(NewUser newUser);
}
+
class UserRepository implements BaseUserRepository {
final NetworkInterface _network = NetworkInterface();
@override
Future fetchUserDetail(String email) async {
final response =
- await _network.get(url: '/api/user-detail/$email', isLogin: true);
+ await _network.get(url: '/api/user/$email/', isLogin: true);
final data = [response];
return User(
data.map((user) => UserModel.fromJson(user)).toList());
diff --git a/pubspec.yaml b/pubspec.yaml
index 59f1b2ba4576ab45e87141c318a48e53234659c3..14d76cf29aa08394cbe0c21b3489b74b438129b7 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
dev_dependencies:
flutter_test:
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/login_test.dart b/test/login_test.dart
index dbea2e890f13312a62278d6c6ebd0f8b1ff7aeca..2573a52272127c220f0064b2cdad3c9bd1c2be90 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,6 +14,14 @@ 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,
@@ -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..cece1d5f14ee3f674c967fefd1a81701d772245d 100644
--- a/test/model_test.dart
+++ b/test/model_test.dart
@@ -9,13 +9,13 @@ void main() {
'id': 1,
'deskripsi': 'This is a test',
'creator': 'Test',
- 'date_time': '2020-11-18 00:13:52.939668'
+ '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'
+ 'created': '2020-11-18T00:13:00.000'
};
final userData = {
'is_login': true,
@@ -36,7 +36,7 @@ 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'],
@@ -77,7 +77,7 @@ void main() {
id: 2,
deskripsi: 'This is a test',
creator: 'Test',
- dateTime: DateTime.now());
+ created: DateTime.now());
expect(komentarPostingModel, isInstanceOf());
expect(
komentarPostingWithConstructor, isInstanceOf());
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');