Fakultas Ilmu Komputer UI

Commit cc34d637 authored by jovi_013's avatar jovi_013
Browse files

[WIP] Multi image picker

parent 58357fe7
Pipeline #80318 failed with stages
in 2 minutes and 44 seconds
......@@ -3,7 +3,6 @@ import 'dart:io';
import 'package:bisaGo/bloc/kegiatan_bloc.dart';
import 'package:bisaGo/component/bisago_appbar.dart';
import 'package:bisaGo/component/image_preview_holder.dart';
// import 'package:bisaGo/config/strings.dart';
import 'package:bisaGo/config/styles.dart';
import 'package:bisaGo/model/kegiatan.dart';
......@@ -11,6 +10,7 @@ import 'package:bisaGo/utils/custom_button.dart';
// import 'package:bisaGo/utils/custom_dropdown.dart';
import 'package:bisaGo/utils/custom_text_field.dart';
import 'package:bisaGo/utils/validator.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
......@@ -18,6 +18,8 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:image_picker/image_picker.dart';
import 'package:intl/intl.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'package:multi_image_picker/multi_image_picker.dart';
import 'package:permission_handler/permission_handler.dart';
class AddKegiatan extends StatefulWidget {
AddKegiatan({
......@@ -45,6 +47,8 @@ class _AddKegiatanState extends State<AddKegiatan> {
String tanggalKegiatan =
'${DateFormat('yyyy-MM-ddTHH:mm').format(DateTime.now())}';
List<Asset> images = <Asset>[];
@override
Widget build(BuildContext context) {
......@@ -95,6 +99,127 @@ class _AddKegiatanState extends State<AddKegiatan> {
);
}
Future<void> _submitData() async {
final form = _formKey.currentState;
if (_formKey.currentState.validate()) {
form.save();
final fileName = _image.path.split('/').last;
final _imageFile = await MultipartFile.fromFile(
_image.path,
filename: fileName,
);
final newKegiatan = KegiatanModel(
namaKegiatan: namaKegiatanController.text,
penyelenggara: penyelenggaraController.text,
deskripsi: deskripsiController.text,
namaKontak: namaKontakController.text,
nomorKontak: nomorKontakController.text,
links: linkController.text,
timeStart: DateTime.parse(tanggalKegiatan),
timeEnd: DateTime.parse(tanggalKegiatan).add(
Duration(days: 1),
),
);
final newKegiatanData = newKegiatan.toJson();
newKegiatanData['images'] = _imageFile;
final _bloc = KegiatanBloc(widget.placeId);
await _bloc.addNewKegiatan(
newKegiatanData,
widget.placeId,
);
successDialog(context);
Timer(const Duration(seconds: 2), () {
Navigator.pop(context);
Navigator.pop(context);
});
} else {
failedDialog(context, '');
}
}
void successDialog(BuildContext context) {
const alertDialog = AlertDialog(
title: Text('Tambah informasi berhasil'),
content: Icon(FontAwesomeIcons.checkCircle),
);
showDialog(
context: context,
builder: (BuildContext context) {
return alertDialog;
});
}
void failedDialog(BuildContext context, String message) {
var newMessage = message;
if (message == 'default') {
newMessage = 'Gagal menambahkan informasi';
}
final alertDialog = AlertDialog(
title: Text(newMessage),
content: const Icon(
FontAwesomeIcons.exclamationCircle,
),
);
showDialog(
context: context,
builder: (BuildContext context) {
return alertDialog;
});
}
final picker = ImagePicker();
File _image;
Future _getCameraImage() async {
final image =
await picker.getImage(source: ImageSource.camera, imageQuality: 50);
return File(image.path);
}
Future<void> pickImages() async {
var resultList = <Asset>[];
// var status = await Permission.camera.status;
try {
// if (status.isGranted) {
// }
resultList = await MultiImagePicker.pickImages(
maxImages: 300,
enableCamera: true,
selectedAssets: images,
materialOptions: MaterialOptions(
actionBarTitle: widget.nama,
actionBarColor: '#ff3A903A',
useDetailsView: true,
),
);
} on Exception catch (e) {
print(e);
}
setState(() {
images = resultList;
});
}
// Future<bool> checkAndRequestCameraPermissions() async {
// PermissionStatus permission =
// await PermissionHandler().checkPermissionStatus(PermissionGroup.camera);
// if (permission != PermissionStatus.granted) {
// Map<PermissionGroup, PermissionStatus> permissions =
// await PermissionHandler().requestPermissions([PermissionGroup.camera]);
// return permissions[PermissionGroup.camera] == PermissionStatus.granted;
// } else {
// return true;
// }
// }
Widget namaLokasi() {
return Padding(
padding: const EdgeInsets.only(bottom: doubleSpace),
......@@ -276,196 +401,163 @@ class _AddKegiatanState extends State<AddKegiatan> {
}
Widget fotoField() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'Foto',
style: TextStyle(fontSize: 18),
textAlign: TextAlign.left,
),
TextButton(
key: const Key('Button Input Foto Gallery'),
style: TextButton.styleFrom(padding: EdgeInsets.zero),
onPressed: () async {
final imageSelected = await _getImage();
setState(() {
_image = imageSelected;
});
},
child: Container(
width: MediaQuery.of(context).size.width * 0.35,
padding: const EdgeInsets.all(9.0),
alignment: Alignment.centerLeft,
decoration: BoxDecoration(
boxShadow: regularShadow,
borderRadius: BorderRadius.circular(10.0),
color: greenPrimary),
child: Row(
children: [
const Icon(
MdiIcons.imagePlus,
color: Colors.white,
size: 14.0,
),
const SizedBox(width: regularSpace),
const Text(
'Dari Gallery',
style: TextStyle(
color: Colors.white, fontSize: 14.0),
),
],
),
return Padding(
padding: const EdgeInsets.only(bottom: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'Foto',
style: TextStyle(fontSize: 18),
textAlign: TextAlign.left,
),
),
TextButton(
key: const Key('Button Input Foto Camera'),
style: TextButton.styleFrom(padding: EdgeInsets.zero),
onPressed: () async {
final imageSelected = await _getCameraImage();
setState(() {
_image = imageSelected;
});
},
child: Container(
width: MediaQuery.of(context).size.width * 0.35,
padding: const EdgeInsets.all(9.0),
alignment: Alignment.centerLeft,
decoration: BoxDecoration(
boxShadow: regularShadow,
borderRadius: BorderRadius.circular(10.0),
color: greenPrimary),
child: Row(
children: [
const Icon(
MdiIcons.imagePlus,
color: Colors.white,
size: 14.0,
),
const SizedBox(width: regularSpace),
const Text(
'Dari Kamera',
style: TextStyle(
color: Colors.white, fontSize: 14.0),
),
],
TextButton(
key: const Key('Button Input Foto Gallery'),
style: TextButton.styleFrom(padding: EdgeInsets.zero),
onPressed: () async {
await pickImages();
},
child: Container(
width: MediaQuery.of(context).size.width * 0.35,
padding: const EdgeInsets.all(9.0),
alignment: Alignment.centerLeft,
decoration: BoxDecoration(
boxShadow: regularShadow,
borderRadius: BorderRadius.circular(10.0),
color: greenPrimary),
child: Row(
children: [
const Icon(
MdiIcons.imagePlus,
color: Colors.white,
size: 14.0,
),
const SizedBox(width: regularSpace),
const Text(
'Dari Gallery',
style: TextStyle(
color: Colors.white, fontSize: 14.0),
),
],
),
),
),
)
],
TextButton(
key: const Key('Button Input Foto Camera'),
style: TextButton.styleFrom(padding: EdgeInsets.zero),
onPressed: () async {
final imageSelected = await _getCameraImage();
setState(() {
_image = imageSelected;
});
},
child: Container(
width: MediaQuery.of(context).size.width * 0.35,
padding: const EdgeInsets.all(9.0),
alignment: Alignment.centerLeft,
decoration: BoxDecoration(
boxShadow: regularShadow,
borderRadius: BorderRadius.circular(10.0),
color: greenPrimary),
child: Row(
children: [
const Icon(
MdiIcons.imagePlus,
color: Colors.white,
size: 14.0,
),
const SizedBox(width: regularSpace),
const Text(
'Dari Kamera',
style: TextStyle(
color: Colors.white, fontSize: 14.0),
),
],
),
),
)
],
),
);
}
Widget simpanButton() {
return Container(
margin: const EdgeInsets.only(top: tripleSpace),
margin: const EdgeInsets.only(top: doubleSpace),
alignment: Alignment.center,
child: ButtonTheme(
key: const Key('Button Simpan'),
minWidth: double.infinity,
height: 40,
child: submitButton('Simpan', _validateLoginInput),
child: submitButton('Simpan', _submitData),
)
);
}
Future<void> _validateLoginInput() async {
final form = _formKey.currentState;
if (_formKey.currentState.validate()) {
form.save();
final fileName = _image.path.split('/').last;
final _imageFile = await MultipartFile.fromFile(
_image.path,
filename: fileName,
);
final newKegiatan = KegiatanModel(
namaKegiatan: namaKegiatanController.text,
penyelenggara: penyelenggaraController.text,
deskripsi: deskripsiController.text,
namaKontak: namaKontakController.text,
nomorKontak: nomorKontakController.text,
links: linkController.text,
timeStart: DateTime.parse(tanggalKegiatan),
timeEnd: DateTime.parse(tanggalKegiatan).add(
Duration(days: 1),
),
);
final newKegiatanData = newKegiatan.toJson();
newKegiatanData['images'] = _imageFile;
final _bloc = KegiatanBloc(widget.placeId);
await _bloc.addNewKegiatan(
newKegiatanData,
widget.placeId,
);
successDialog(context);
Timer(const Duration(seconds: 2), () {
Navigator.pop(context);
Navigator.pop(context);
});
} else {
failedDialog(context, '');
}
}
Widget _showImagePreview() {
return _image == null
return images.isEmpty
? const SizedBox(height: 0)
: ImagePreviewHolder(
image: Image.file(_image),
onPressed: () async {
setState(() {
_image = null;
});
},
);
}
void successDialog(BuildContext context) {
const alertDialog = AlertDialog(
title: Text('Tambah informasi berhasil'),
content: Icon(FontAwesomeIcons.checkCircle),
);
showDialog(
context: context,
builder: (BuildContext context) {
return alertDialog;
});
: carousel();
}
void failedDialog(BuildContext context, String message) {
var newMessage = message;
if (message == 'default') {
newMessage = 'Gagal menambahkan informasi';
}
final alertDialog = AlertDialog(
title: Text(newMessage),
content: const Icon(
FontAwesomeIcons.exclamationCircle,
),
Widget carousel() {
return 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: images.map((item) => Container(
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(20)),
child: Stack(
children: <Widget>[
AssetThumb(
asset: item,
width: MediaQuery.of(context).size.height.toInt(),
height: MediaQuery.of(context).size.width.toInt(),
),
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(
'#${images.indexOf(item) + 1}',
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
),
),
),
],
)
),
),
).toList()),
);
showDialog(
context: context,
builder: (BuildContext context) {
return alertDialog;
});
}
final picker = ImagePicker();
File _image;
Future _getImage() 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);
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment