some changes

This commit is contained in:
Kicap Karan
2022-11-22 00:32:11 +08:00
parent 94344db9eb
commit 23965005a3
8 changed files with 380 additions and 85 deletions

4
.env
View File

@ -1,2 +1,2 @@
SERVER_URL = http://192.168.189.237/absensi_server/apiuser/
URL=http://192.168.189.237/absensi_server/
SERVER_URL = https://absensi-mamuju-tengah.airlangga-it.com/apiuser/
URL=https://absensi-mamuju-tengah.airlangga-it.com/absensi_server/

View File

@ -1,6 +1,23 @@
package com.example.absensi
import kotlin.random.Random
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
class MainActivity: FlutterActivity() {
}
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "example.com/channel").setMethodCallHandler {
call, result ->
if(call.method == "getRandomNumber") {
val rand = Random.nextInt(100)
result.success(rand)
}
else {
result.notImplemented()
}
}
}
}

View File

@ -3,6 +3,7 @@ import 'dart:io';
import 'dart:ui';
import 'package:absensi_karyawan/src/services/notification_services.dart';
import 'package:background_location/background_location.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@ -10,6 +11,7 @@ import 'package:flutter_background_service/flutter_background_service.dart';
import 'package:flutter_background_service_android/flutter_background_service_android.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:logger/logger.dart';
import 'package:provider/provider.dart';
@ -27,17 +29,46 @@ final dev = Logger();
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
// await GetStorage.init();
// await _startBackgroundLocation();
await dotenv.load(fileName: ".env");
StorageService storage = StorageService();
await storage.init();
// await initializeService();
await _configureLocalTimeZone();
await NotificationServices.init();
// await initializeService();
runApp(const MyApp());
}
Future<void> initializeService() async {
final service = FlutterBackgroundService();
/// OPTIONAL, using custom notification channel id
const AndroidNotificationChannel channel = AndroidNotificationChannel(
'my_foreground', // id
'MY FOREGROUND SERVICE', // title
description:
'This channel is used for important notifications.', // description
importance: Importance.low, // importance must be at low or higher level
);
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
if (Platform.isIOS) {
await flutterLocalNotificationsPlugin.initialize(
const InitializationSettings(
iOS: IOSInitializationSettings(),
),
);
}
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
await service.configure(
androidConfiguration: AndroidConfiguration(
// this will be executed when app is in foreground or background in separated isolate
@ -46,6 +77,11 @@ Future<void> initializeService() async {
// auto start service
autoStart: true,
isForegroundMode: true,
// notificationChannelId: 'my_foreground',
// initialNotificationTitle: 'AWESOME SERVICE',
// initialNotificationContent: 'Initializing',
// foregroundServiceNotificationId: 888,
),
iosConfiguration: IosConfiguration(
// auto start service
@ -58,18 +94,28 @@ Future<void> initializeService() async {
onBackground: onIosBackground,
),
);
service.startService();
}
// to ensure this is executed
// run app from xcode, then from xcode menu, select Simulate Background Fetch
bool onIosBackground(ServiceInstance service) {
@pragma('vm:entry-point')
Future<bool> onIosBackground(ServiceInstance service) async {
WidgetsFlutterBinding.ensureInitialized();
dev.i('FLUTTER BACKGROUND FETCH');
DartPluginRegistrant.ensureInitialized();
// SharedPreferences preferences = await SharedPreferences.getInstance();
// await preferences.reload();
// final log = preferences.getStringList('log') ?? <String>[];
// log.add(DateTime.now().toIso8601String());
// await preferences.setStringList('log', log);
return true;
}
@pragma('vm:entry-point')
void onStart(ServiceInstance service) async {
// Only available for flutter 3.0.0 and later
DartPluginRegistrant.ensureInitialized();
@ -77,6 +123,13 @@ void onStart(ServiceInstance service) async {
// For flutter prior to version 3.0.0
// We have to register the plugin manually
// SharedPreferences preferences = await SharedPreferences.getInstance();
// await preferences.setString("hello", "world");
/// OPTIONAL when use custom notification
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
if (service is AndroidServiceInstance) {
service.on('setAsForeground').listen((event) {
service.setAsForegroundService();
@ -92,24 +145,93 @@ void onStart(ServiceInstance service) async {
});
// bring to foreground
Timer.periodic(const Duration(seconds: 5), (timer) async {
// NotificationServices.showNotification(
// id: 1,
// title: 'Percobaan 2',
// body: "ini message",
// payload: 'Percobaan 2',
// );
// const platform = MethodChannel('example.com/channel');
// int random;
// try {
// random = await platform.invokeMethod('getRandomNumber');
// } on PlatformException catch (e) {
// random = 0;
// }
// BackgroundLocation().getCurrentLocation().then((location) {
// dev.i('Location: ${location.latitude}, ${location.longitude}');
// // NotificationServices.showNotification(
// // id: 1,
// // title: 'Percobaan 2',
// // body: 'Location: ${location.latitude}, ${location.longitude}',
// // payload: 'Percobaan 2',
// // );
// });
// if (service is AndroidServiceInstance) {
// // if (await service.isForegroundService()) {
// /// OPTIONAL for use custom notification
// /// the notification id must be equals with AndroidConfiguration when you call configure() method.
// flutterLocalNotificationsPlugin.show(
// 888,
// 'COOL SERVICE',
// 'Awesome ${DateTime.now()}',
// const NotificationDetails(
// android: AndroidNotificationDetails(
// 'my_foreground',
// 'MY FOREGROUND SERVICE',
// icon: 'ic_bg_service_small',
// ongoing: true,
// ),
// ),
// );
// // if you don't using custom notification, uncomment this
// // service.setForegroundNotificationInfo(
// // title: "My App Service",
// // content: "Updated at ${DateTime.now()}",
// // );
// // }
// }
/// you can see this log in logcat
dev.i('FLUTTER BACKGROUND SERVICE: ${DateTime.now()}');
// test using external plugin
// final deviceInfo = DeviceInfoPlugin();
String? device;
if (Platform.isAndroid) {
// final androidInfo = await deviceInfo.androidInfo;
// device = androidInfo.model;
}
if (Platform.isIOS) {
// final iosInfo = await deviceInfo.iosInfo;
// device = iosInfo.model;
}
service.invoke(
'update',
{
"current_date": DateTime.now().toIso8601String(),
"device": device,
},
);
});
}
Future<void> _startBackgroundLocation() async {
await BackgroundLocation.startLocationService(distanceFilter: 20);
}
Future<void> _configureLocalTimeZone() async {
if (kIsWeb || Platform.isLinux) {
return;
}
tz.initializeTimeZones();
final String timeZoneName = await FlutterNativeTimezone.getLocalTimezone();
tz.setLocalLocation(tz.getLocation(timeZoneName));
try {
final String timeZoneName = await FlutterNativeTimezone.getLocalTimezone();
tz.setLocalLocation(tz.getLocation(timeZoneName));
} catch (e) {
tz.setLocalLocation(tz.getLocation('Asia/Kuala_Lumpur'));
}
// final String timeZoneName = await FlutterNativeTimezone.getLocalTimezone();
// tz.setLocalLocation(tz.getLocation(timeZoneName));
}
class MyApp extends StatelessWidget {

View File

@ -65,20 +65,27 @@ class _AbsensiKaryawanState extends State<AbsensiKaryawan> {
final DateFormat formatter = DateFormat('yyyy-MM-dd');
formatted = formatter.format(now);
String today = DateFormat('EEEE').format(now);
// dev.i(today);
dev.i(today);
if (today == "Sunday" || today == "Saturday") {
setState(() {
String day = (today == "Sunday") ? "Minggu" : "Sabtu";
_statusnya = {'stat': "Libur", 'ket': "Libur Hari $day"};
});
if (mounted) {
setState(() {
String day = (today == "Sunday") ? "Minggu" : "Sabtu";
_statusnya = {'stat': "Libur", 'ket': "Libur Hari $day"};
});
}
} else {
await ApiServices.getTodayLiburAndPerjalanDinas(formatted);
// await Future.delayed(Duration(seconds: 1));
dynamic statusnya = await _storage.read('ada_perjalanan_dinas_libur');
// dev.i(statusnya);
setState(() {
_statusnya = statusnya;
});
if (mounted) {
setState(() {
_statusnya = statusnya;
});
}
// setState(() {
// _statusnya = statusnya;
// });
}
List jadwalDinasList = await _storage.read('jadwalKerja');
@ -93,7 +100,7 @@ class _AbsensiKaryawanState extends State<AbsensiKaryawan> {
}
}
dev.i(_jadwalDinasModel.hari);
// dev.i(_jadwalDinasModel.hari);
// dev.i(_jadwalDinasModel.jamMasuk);
// dev.i(_jadwalDinasModel.jamIstirehat);
// dev.i(_jadwalDinasModel.jamMasukKembali);

View File

@ -5,6 +5,7 @@ import 'package:logger/logger.dart';
import '../../config/theme.dart';
import '../../services/storage_service.dart';
import '../../widget/dumb_widget/my_textformfield.dart';
import '../../widget/smart_widget/bounce_scroller.dart';
class ProfilKaryawanPage extends StatefulWidget {
@ -21,6 +22,18 @@ class _ProfilKaryawanPageState extends State<ProfilKaryawanPage> {
UserDataModel? userDataModel;
static final url = dotenv.env['URL'];
TextEditingController _oldPasswordController = TextEditingController();
TextEditingController _newPasswordController = TextEditingController();
TextEditingController _confirmPasswordController = TextEditingController();
FocusNode _oldPasswordFocusNode = FocusNode();
FocusNode _newPasswordFocusNode = FocusNode();
FocusNode _confirmPasswordFocusNode = FocusNode();
bool _isOldPasswordVisible = false;
bool _isNewPasswordVisible = false;
bool _isConfirmPasswordVisible = false;
@override
void initState() {
super.initState();
@ -37,73 +50,194 @@ class _ProfilKaryawanPageState extends State<ProfilKaryawanPage> {
// dev.i("$url${userDataModel.image}");
}
@override
Widget build(BuildContext context) {
return BounceScrollerWidget(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(
height: 20,
Future<void> _showPasswordEdit() async {
// create dialog box
showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text(
"Ganti Password",
style: TextStyle(
color: Colors.black,
fontSize: 16,
fontWeight: FontWeight.w600,
),
Container(
padding: const EdgeInsets.all(5),
alignment: Alignment.center,
height: 100,
width: 100,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
// borderRadius: BorderRadius.circular(100),
image: DecorationImage(
image: AssetImage('assets/loading.gif'),
fit: BoxFit.fitHeight,
),
boxShadow: [
BoxShadow(
color: ThemeInfo.myGrey2,
blurRadius: 10,
spreadRadius: 5,
),
content: SizedBox(
// height: MediaQuery.of(context).size.height * 0.5,
width: MediaQuery.of(context).size.width * 0.8,
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.min,
children: [
MyTextFormField(
controller: _oldPasswordController,
focusNode: _oldPasswordFocusNode,
labelText: "Password Lama",
hintText: "Password Lama",
suffixIcon: IconButton(
icon: Icon(
_isOldPasswordVisible
? Icons.visibility
: Icons.visibility_off,
),
onPressed: () {
setState(() {
_isOldPasswordVisible = !_isOldPasswordVisible;
});
},
),
),
const SizedBox(
height: 15,
),
MyTextFormField(
controller: _newPasswordController,
focusNode: _newPasswordFocusNode,
labelText: "Password Baru",
hintText: "Password Baru",
suffixIcon: IconButton(
icon: Icon(
_isNewPasswordVisible
? Icons.visibility
: Icons.visibility_off,
),
onPressed: () {
setState(() {
_isNewPasswordVisible = !_isNewPasswordVisible;
});
},
),
),
const SizedBox(
height: 15,
),
MyTextFormField(
controller: _confirmPasswordController,
focusNode: _confirmPasswordFocusNode,
labelText: "Konfirmasi Password",
hintText: "Konfirmasi Password",
suffixIcon: IconButton(
icon: Icon(
_isConfirmPasswordVisible
? Icons.visibility
: Icons.visibility_off,
),
onPressed: () {
setState(() {
_isConfirmPasswordVisible =
!_isConfirmPasswordVisible;
});
},
),
),
],
),
// child: Image.network(
// "$url${userDataModel?.image}",
// errorBuilder: (context, error, stackTrace) {
// return Image.asset(
// 'assets/profile_blank.png',
// fit: BoxFit.cover,
// );
// },
// ),
),
),
actions: <Widget>[
TextButton(
child: const Text('Batalkan'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: const Text('Ganti Password'),
onPressed: () {
// if (_formKey.currentState!.validate()) {
// unfocus all
FocusScope.of(context).unfocus();
child: Center(
child: CircleAvatar(
radius: 100,
backgroundImage:
NetworkImage("$url${userDataModel?.image}", scale: 100),
onBackgroundImageError: (exception, stackTrace) {
return;
},
),
),
// if
},
),
Padding(
padding: const EdgeInsets.all(10),
child: Text(
userDataModel == null ? "loading.." : userDataModel!.nama!,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: ThemeInfo.negroTexto,
),
),
),
_DetailParent(userDataModel: userDataModel),
],
),
],
);
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: BounceScrollerWidget(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(
height: 20,
),
Container(
padding: const EdgeInsets.all(5),
alignment: Alignment.center,
height: 100,
width: 100,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
// borderRadius: BorderRadius.circular(100),
image: DecorationImage(
image: AssetImage('assets/loading.gif'),
fit: BoxFit.fitHeight,
),
boxShadow: [
BoxShadow(
color: ThemeInfo.myGrey2,
blurRadius: 10,
spreadRadius: 5,
),
],
),
// child: Image.network(
// "$url${userDataModel?.image}",
// errorBuilder: (context, error, stackTrace) {
// return Image.asset(
// 'assets/profile_blank.png',
// fit: BoxFit.cover,
// );
// },
// ),
child: Center(
child: CircleAvatar(
radius: 100,
backgroundImage:
NetworkImage("$url${userDataModel?.image}", scale: 100),
onBackgroundImageError: (exception, stackTrace) {
return;
},
),
),
),
Padding(
padding: const EdgeInsets.all(10),
child: Text(
userDataModel == null ? "loading.." : userDataModel!.nama!,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: ThemeInfo.negroTexto,
),
),
),
_DetailParent(userDataModel: userDataModel),
],
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_showPasswordEdit();
},
child: const Icon(Icons.edit),
backgroundColor: ThemeInfo.primary,
),
floatingActionButtonLocation: FloatingActionButtonLocation.startFloat,
);
}
}

View File

@ -1,3 +1,4 @@
import 'package:background_location/background_location.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:logger/logger.dart';
@ -21,6 +22,7 @@ class _SplashScreenPageState extends State<SplashScreenPage> {
@override
void initState() {
super.initState();
getCurrentLocation();
initPlatformState();
// future 3 sec
Future.delayed(const Duration(seconds: 4), () async {
@ -36,6 +38,12 @@ class _SplashScreenPageState extends State<SplashScreenPage> {
});
}
void getCurrentLocation() {
// BackgroundLocation.getLocationUpdates((location) {
// dev.i('location: ${location.latitude}, ${location.longitude}');
// });
}
void goToLogin() {
Navigator.pushReplacementNamed(context, 'login');
}

View File

@ -22,6 +22,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.9.0"
background_location:
dependency: "direct main"
description:
name: background_location
url: "https://pub.dartlang.org"
source: hosted
version: "0.8.1"
boolean_selector:
dependency: transitive
description:

View File

@ -63,7 +63,7 @@ dependencies:
google_maps_flutter:
# geolocator:
# background_location:
background_location:
# background_locator:
# location: ^5.0.0-dev.7