first commit
This commit is contained in:
72
lib/main.dart
Normal file
72
lib/main.dart
Normal file
@ -0,0 +1,72 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_native_timezone/flutter_native_timezone.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tanah_longsor_app/src/provider/maps_provider.dart';
|
||||
import 'package:tanah_longsor_app/src/service/notification_api.dart';
|
||||
import 'package:tanah_longsor_app/src/service/socket_io.dart';
|
||||
// import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:timezone/data/latest_all.dart' as tz;
|
||||
import 'package:timezone/timezone.dart' as tz;
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
|
||||
import 'src/config/routes.dart';
|
||||
|
||||
Future<void> main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
MySocketIO socket = MySocketIO();
|
||||
await socket.init();
|
||||
await _configureLocalTimeZone();
|
||||
await dotenv.load(fileName: ".env");
|
||||
HttpOverrides.global = MyHttpOverrides();
|
||||
// if (defaultTargetPlatform == TargetPlatform.android) {
|
||||
// AndroidGoogleMapsFlutter.useAndroidViewSurface = true;
|
||||
// }
|
||||
|
||||
NotificationApi.init(initScheduled: true);
|
||||
runApp(
|
||||
MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider(create: (_) => MapsProvider()),
|
||||
],
|
||||
child: const MyApp(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
const MyApp({Key? key}) : super(key: key);
|
||||
|
||||
// This widget is the root of your application.
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: 'Flutter Demo',
|
||||
theme: ThemeData(
|
||||
primarySwatch: Colors.blue,
|
||||
),
|
||||
routes: MyRoutes.getRoutes(),
|
||||
initialRoute: '/',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MyHttpOverrides extends HttpOverrides {
|
||||
@override
|
||||
HttpClient createHttpClient(SecurityContext? context) {
|
||||
return super.createHttpClient(context)
|
||||
..badCertificateCallback =
|
||||
(X509Certificate cert, String host, int port) => true;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _configureLocalTimeZone() async {
|
||||
if (kIsWeb || Platform.isLinux) {
|
||||
return;
|
||||
}
|
||||
tz.initializeTimeZones();
|
||||
final String timeZoneName = await FlutterNativeTimezone.getLocalTimezone();
|
||||
tz.setLocalLocation(tz.getLocation(timeZoneName));
|
||||
}
|
||||
11
lib/src/config/routes.dart
Normal file
11
lib/src/config/routes.dart
Normal file
@ -0,0 +1,11 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../page/index.dart';
|
||||
|
||||
class MyRoutes {
|
||||
static getRoutes() {
|
||||
return {
|
||||
'/': (BuildContext context) => const IndexPage(),
|
||||
};
|
||||
}
|
||||
}
|
||||
34
lib/src/model/base_response.dart
Normal file
34
lib/src/model/base_response.dart
Normal file
@ -0,0 +1,34 @@
|
||||
// To parse this JSON data, do
|
||||
//
|
||||
// final baseResponse = baseResponseFromJson(jsonString);
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
BaseResponse baseResponseFromJson(String str) =>
|
||||
BaseResponse.fromJson(json.decode(str));
|
||||
|
||||
String baseResponseToJson(BaseResponse data) => json.encode(data.toJson());
|
||||
|
||||
class BaseResponse {
|
||||
BaseResponse({
|
||||
required this.status,
|
||||
required this.message,
|
||||
this.data,
|
||||
});
|
||||
|
||||
bool status;
|
||||
String message;
|
||||
dynamic data;
|
||||
|
||||
factory BaseResponse.fromJson(Map<String, dynamic> json) => BaseResponse(
|
||||
status: json["status"],
|
||||
message: json["message"],
|
||||
data: json["data"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"status": status,
|
||||
"message": message,
|
||||
"data": data,
|
||||
};
|
||||
}
|
||||
40
lib/src/model/marker_model.dart
Normal file
40
lib/src/model/marker_model.dart
Normal file
@ -0,0 +1,40 @@
|
||||
class MarkerModel {
|
||||
String? sId;
|
||||
String? lat;
|
||||
String? lng;
|
||||
String? status;
|
||||
String? createdAt;
|
||||
String? updatedAt;
|
||||
int? iV;
|
||||
|
||||
MarkerModel(
|
||||
{this.sId,
|
||||
this.lat,
|
||||
this.lng,
|
||||
this.status,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.iV});
|
||||
|
||||
MarkerModel.fromJson(Map<String, dynamic> json) {
|
||||
sId = json['_id'];
|
||||
lat = json['lat'];
|
||||
lng = json['lng'];
|
||||
status = json['status'];
|
||||
createdAt = json['created_at'];
|
||||
updatedAt = json['updated_at'];
|
||||
iV = json['__v'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
data['_id'] = sId;
|
||||
data['lat'] = lat;
|
||||
data['lng'] = lng;
|
||||
data['status'] = status;
|
||||
data['created_at'] = createdAt;
|
||||
data['updated_at'] = updatedAt;
|
||||
data['__v'] = iV;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
104
lib/src/page/index.dart
Normal file
104
lib/src/page/index.dart
Normal file
@ -0,0 +1,104 @@
|
||||
// ignore_for_file: unnecessary_const
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:logger/logger.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../provider/maps_provider.dart';
|
||||
import '../service/notification_api.dart';
|
||||
import '../service/socket_io.dart';
|
||||
import 'list.dart';
|
||||
import 'maps2.dart';
|
||||
|
||||
class IndexPage extends StatefulWidget {
|
||||
const IndexPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<IndexPage> createState() => _IndexPageState();
|
||||
}
|
||||
|
||||
class _IndexPageState extends State<IndexPage> {
|
||||
// final logger = Logger();
|
||||
int currentIndex = 0;
|
||||
final socketIO = MySocketIO();
|
||||
final logger = Logger();
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
// context.read<MapsProvider>().getMarkers();
|
||||
socketIO.on('notif_to_phone', (data) {
|
||||
logger.i(data);
|
||||
context.read<MapsProvider>().changeMarkerStyle(
|
||||
data['id'], data['status'], data['lat'], data['lng']);
|
||||
|
||||
if (data['status'] != 'Normal') {
|
||||
NotificationApi.showNotification(
|
||||
id: 1,
|
||||
title: 'Info',
|
||||
body: data['message'],
|
||||
payload: "Info Kemungkinan Bencana Tanah Longsor",
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
socketIO.on('reload_calibation', (data) {
|
||||
logger.i(data);
|
||||
context.watch<MapsProvider>().getMarkers();
|
||||
|
||||
// if (data['status'] != 'Normal') {
|
||||
NotificationApi.showNotification(
|
||||
id: 2,
|
||||
title: 'Info',
|
||||
body: "Alat Baru Berhasil Di Calibrasi",
|
||||
payload: "Alat Baru Berhasil Di Calibrasi",
|
||||
);
|
||||
// }
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
socketIO.disconnect();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: myWidget(context),
|
||||
),
|
||||
bottomNavigationBar: BottomNavigationBar(
|
||||
backgroundColor: const Color.fromARGB(255, 234, 230, 230),
|
||||
items: const <BottomNavigationBarItem>[
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(Icons.location_on),
|
||||
label: 'Home',
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(Icons.map_outlined),
|
||||
label: 'List Lokasi',
|
||||
),
|
||||
],
|
||||
currentIndex: currentIndex,
|
||||
selectedItemColor: Colors.blue,
|
||||
onTap: (int index) {
|
||||
// logger.i('index: $index');
|
||||
setState(() {
|
||||
currentIndex = index;
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
myWidget(BuildContext context) {
|
||||
switch (currentIndex) {
|
||||
case 0:
|
||||
// return const MapPage();
|
||||
return const Map2Page();
|
||||
case 1:
|
||||
return const ListAlatPage();
|
||||
}
|
||||
}
|
||||
}
|
||||
71
lib/src/page/list.dart
Normal file
71
lib/src/page/list.dart
Normal file
@ -0,0 +1,71 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tanah_longsor_app/src/provider/maps_provider.dart';
|
||||
|
||||
class ListAlatPage extends StatefulWidget {
|
||||
const ListAlatPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<ListAlatPage> createState() => _ListAlatPageState();
|
||||
}
|
||||
|
||||
class _ListAlatPageState extends State<ListAlatPage> {
|
||||
late MapsProvider mapsProvider;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
mapsProvider = Provider.of<MapsProvider>(context, listen: false);
|
||||
mapsProvider.getMarkers();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
const Align(
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
'List Alat',
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
// Text('List Alat'),
|
||||
if (mapsProvider.isLoading == false) const Text("Error Loading"),
|
||||
if (mapsProvider.isLoading == true)
|
||||
if (mapsProvider.markerModels.isEmpty)
|
||||
const Text('Tidak ada alat yang tersedia'),
|
||||
if (mapsProvider.isLoading == true)
|
||||
if (mapsProvider.markerModels.isNotEmpty)
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: mapsProvider.markerModels.length,
|
||||
itemBuilder: (context, index) {
|
||||
return Card(
|
||||
elevation: 5,
|
||||
child: ListTile(
|
||||
title: Text(
|
||||
"ID : ${mapsProvider.markerModels[index].sId ?? ''}",
|
||||
),
|
||||
subtitle: Text(
|
||||
"Status : ${mapsProvider.markerModels[index].status ?? ''}",
|
||||
),
|
||||
onTap: () {},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
93
lib/src/page/maps.dart
Normal file
93
lib/src/page/maps.dart
Normal file
@ -0,0 +1,93 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:logger/logger.dart';
|
||||
|
||||
import '../model/base_response.dart';
|
||||
import '../model/marker_model.dart';
|
||||
import '../service/api.dart';
|
||||
import '../service/socket_io.dart';
|
||||
|
||||
class MapPage extends StatefulWidget {
|
||||
const MapPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<MapPage> createState() => _MapPageState();
|
||||
}
|
||||
|
||||
class _MapPageState extends State<MapPage> {
|
||||
final logger = Logger();
|
||||
final socket = MySocketIO();
|
||||
static const _initialCameraPosition = CameraPosition(
|
||||
target: LatLng(-4.006971153905515, 119.63025053884449),
|
||||
zoom: 11,
|
||||
);
|
||||
|
||||
final Set<Marker> _markers = HashSet<Marker>();
|
||||
final Set<Circle> _circles = HashSet<Circle>();
|
||||
|
||||
void _getMarkers(BuildContext context) async {
|
||||
BaseResponse baseResponse = await ApiService.getAllMarker();
|
||||
// logger.i(baseResponse.data);
|
||||
if (baseResponse.status) {
|
||||
if (mounted) {
|
||||
baseResponse.data.forEach((element) {
|
||||
MarkerModel markerModel = MarkerModel.fromJson(element);
|
||||
late double icon;
|
||||
switch (markerModel.status) {
|
||||
case "Normal":
|
||||
icon = BitmapDescriptor.hueBlue;
|
||||
break;
|
||||
case "Warning":
|
||||
icon = BitmapDescriptor.hueYellow;
|
||||
break;
|
||||
case "Danger":
|
||||
icon = BitmapDescriptor.hueOrange;
|
||||
break;
|
||||
case "Danger Area":
|
||||
icon = BitmapDescriptor.hueRed;
|
||||
break;
|
||||
}
|
||||
setState(() {
|
||||
_markers.add(
|
||||
Marker(
|
||||
icon: BitmapDescriptor.defaultMarkerWithHue(icon),
|
||||
markerId: MarkerId(markerModel.sId!),
|
||||
position: LatLng(double.parse(markerModel.lat!),
|
||||
double.parse(markerModel.lng!)),
|
||||
infoWindow: InfoWindow(
|
||||
title: markerModel.sId,
|
||||
snippet: markerModel.status,
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
} else {
|
||||
logger.e(baseResponse.message);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_getMarkers(context);
|
||||
// socket.on('hehe', (data) {
|
||||
// logger.i(data);
|
||||
// });
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GoogleMap(
|
||||
initialCameraPosition: _initialCameraPosition,
|
||||
onMapCreated: _onMapCreated,
|
||||
markers: _markers,
|
||||
circles: _circles,
|
||||
);
|
||||
}
|
||||
|
||||
void _onMapCreated(GoogleMapController controller) {}
|
||||
}
|
||||
19
lib/src/page/maps2.dart
Normal file
19
lib/src/page/maps2.dart
Normal file
@ -0,0 +1,19 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tanah_longsor_app/src/provider/maps_provider.dart';
|
||||
|
||||
class Map2Page extends StatelessWidget {
|
||||
const Map2Page({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GoogleMap(
|
||||
initialCameraPosition:
|
||||
context.watch<MapsProvider>().initialCameraPosition,
|
||||
onMapCreated: context.watch<MapsProvider>().onMapCreated,
|
||||
markers: context.watch<MapsProvider>().markers,
|
||||
circles: context.watch<MapsProvider>().circles,
|
||||
);
|
||||
}
|
||||
}
|
||||
134
lib/src/provider/maps_provider.dart
Normal file
134
lib/src/provider/maps_provider.dart
Normal file
@ -0,0 +1,134 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:logger/logger.dart';
|
||||
import 'package:tanah_longsor_app/src/service/socket_io.dart';
|
||||
|
||||
import '../model/base_response.dart';
|
||||
import '../model/marker_model.dart';
|
||||
import '../service/api.dart';
|
||||
|
||||
class MapsProvider extends ChangeNotifier {
|
||||
MapsProvider() {
|
||||
// socketIO.on('notif_to_phone', (data) {
|
||||
// // logger.i(data);
|
||||
// changeMarkerStyle(data['id']);
|
||||
// });
|
||||
getMarkers();
|
||||
// notifyListeners();
|
||||
}
|
||||
|
||||
final socketIO = MySocketIO();
|
||||
final logger = Logger();
|
||||
|
||||
final _initialCameraPosition = const CameraPosition(
|
||||
target: LatLng(-4.006971153905515, 119.63025053884449),
|
||||
zoom: 11,
|
||||
);
|
||||
|
||||
get initialCameraPosition => _initialCameraPosition;
|
||||
|
||||
final Set<Marker> _markers = HashSet<Marker>();
|
||||
final Set<Circle> _circles = HashSet<Circle>();
|
||||
|
||||
bool _isLoading = false;
|
||||
bool get isLoading => _isLoading;
|
||||
|
||||
final List<MarkerModel> _markerModels = [];
|
||||
List<MarkerModel> get markerModels => _markerModels;
|
||||
|
||||
Set<Marker> get markers => _markers;
|
||||
Set<Circle> get circles => _circles;
|
||||
|
||||
void getMarkers() async {
|
||||
BaseResponse baseResponse = await ApiService.getAllMarker();
|
||||
logger.i(baseResponse.data);
|
||||
_markerModels.clear();
|
||||
_markers.clear();
|
||||
if (baseResponse.status) {
|
||||
// _markers
|
||||
// .removeWhere((element) => element.markerId.value == '8C3C4CBD9E7C');
|
||||
baseResponse.data.forEach((element) {
|
||||
_markerModels.add(MarkerModel.fromJson(element));
|
||||
MarkerModel markerModel = MarkerModel.fromJson(element);
|
||||
late double icon;
|
||||
switch (markerModel.status) {
|
||||
case "Normal":
|
||||
icon = BitmapDescriptor.hueBlue;
|
||||
break;
|
||||
case "Warning":
|
||||
icon = BitmapDescriptor.hueYellow;
|
||||
break;
|
||||
case "Danger":
|
||||
icon = BitmapDescriptor.hueOrange;
|
||||
break;
|
||||
case "Danger Area":
|
||||
icon = BitmapDescriptor.hueRed;
|
||||
break;
|
||||
case "calibration":
|
||||
icon = BitmapDescriptor.hueBlue;
|
||||
break;
|
||||
}
|
||||
|
||||
_markers.add(
|
||||
Marker(
|
||||
icon: BitmapDescriptor.defaultMarkerWithHue(icon),
|
||||
markerId: MarkerId(markerModel.sId!),
|
||||
position: LatLng(
|
||||
double.parse(markerModel.lat!), double.parse(markerModel.lng!)),
|
||||
infoWindow: InfoWindow(
|
||||
title: markerModel.sId,
|
||||
snippet: markerModel.status,
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
_isLoading = true;
|
||||
logger.i(_markers);
|
||||
} else {
|
||||
logger.e(baseResponse.message);
|
||||
_isLoading = false;
|
||||
}
|
||||
// notifyListeners();merah hitam coklat ungu
|
||||
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void changeMarkerStyle(
|
||||
String id, String status, String lat, String lng) async {
|
||||
logger.i("ini berlaku");
|
||||
late double icon;
|
||||
switch (status) {
|
||||
case "Normal":
|
||||
icon = BitmapDescriptor.hueBlue;
|
||||
break;
|
||||
case "Warning":
|
||||
icon = BitmapDescriptor.hueYellow;
|
||||
break;
|
||||
case "Danger":
|
||||
icon = BitmapDescriptor.hueOrange;
|
||||
break;
|
||||
case "Danger Area":
|
||||
icon = BitmapDescriptor.hueRed;
|
||||
break;
|
||||
}
|
||||
// search in _markers with markerId= '8C3C4CBD9E7C' and delete it
|
||||
_markers.removeWhere((element) => element.markerId.value == id);
|
||||
_markers.add(
|
||||
Marker(
|
||||
icon: BitmapDescriptor.defaultMarkerWithHue(icon),
|
||||
markerId: MarkerId(id),
|
||||
position: LatLng(double.parse(lat), double.parse(lng)),
|
||||
infoWindow: InfoWindow(
|
||||
title: id,
|
||||
snippet: status,
|
||||
),
|
||||
),
|
||||
);
|
||||
logger.i(_markers);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void onMapCreated(GoogleMapController controller) {}
|
||||
}
|
||||
41
lib/src/service/api.dart
Normal file
41
lib/src/service/api.dart
Normal file
@ -0,0 +1,41 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:logger/logger.dart';
|
||||
|
||||
import '../model/base_response.dart';
|
||||
|
||||
class ApiService {
|
||||
static final log = Logger();
|
||||
static final url = dotenv.env['DEV_URL'];
|
||||
|
||||
static final options = BaseOptions(
|
||||
baseUrl: url!,
|
||||
connectTimeout: 5000,
|
||||
receiveTimeout: 3000,
|
||||
);
|
||||
|
||||
static Dio dio = Dio(options);
|
||||
|
||||
static Future<BaseResponse> getAllMarker() async {
|
||||
// log.i(url);
|
||||
try {
|
||||
String endpoint = 'device_list';
|
||||
var response = await dio.get(endpoint);
|
||||
var data = response.data;
|
||||
|
||||
return BaseResponse.fromJson(data);
|
||||
} on DioError catch (e) {
|
||||
log.e(e.toString());
|
||||
return BaseResponse(
|
||||
status: false,
|
||||
message: e.message,
|
||||
);
|
||||
} catch (e) {
|
||||
log.e(e.toString());
|
||||
return BaseResponse(
|
||||
status: false,
|
||||
message: e.toString(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
95
lib/src/service/notification_api.dart
Normal file
95
lib/src/service/notification_api.dart
Normal file
@ -0,0 +1,95 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||
import 'package:flutter_native_timezone/flutter_native_timezone.dart';
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
import 'package:timezone/timezone.dart' as tz;
|
||||
// import 'package:timezone/tzdata.dart' as tz;
|
||||
|
||||
// ignore: avoid_classes_with_only_static_members
|
||||
class NotificationApi {
|
||||
// Below is the code for initializing the plugin using var _notificationPlugin
|
||||
static final _notifications = FlutterLocalNotificationsPlugin();
|
||||
static final onNotifications = BehaviorSubject<String?>();
|
||||
|
||||
static Future showNotification({
|
||||
required int id,
|
||||
String? title,
|
||||
String? body,
|
||||
String? payload,
|
||||
}) async =>
|
||||
_notifications.show(
|
||||
id,
|
||||
title,
|
||||
body,
|
||||
await _notificanDetails(),
|
||||
payload: payload,
|
||||
);
|
||||
|
||||
// static Future showScheduleNotification() async =>
|
||||
// _notifications.zonedSchedule(
|
||||
// 0,
|
||||
// 'Cek Laporan',
|
||||
// "Laporan Baru Mungkin Ada, Sila Cek Di Aplikasi",
|
||||
// // tz.TZDateTime.from(scheduledDate, tz.local),
|
||||
// _scheduleDaily(const Time(18)),
|
||||
// await _notificanDetails(),
|
||||
// payload: "Laporan Baru Mungkin Ada, Sila Cek Di Aplikasi",
|
||||
// androidAllowWhileIdle: true,
|
||||
// uiLocalNotificationDateInterpretation:
|
||||
// UILocalNotificationDateInterpretation.absoluteTime,
|
||||
// matchDateTimeComponents: DateTimeComponents.time,
|
||||
// );
|
||||
|
||||
static Future _notificanDetails() async {
|
||||
const AndroidNotificationDetails androidPlatformChannelSpecifics =
|
||||
AndroidNotificationDetails(
|
||||
'your channel id',
|
||||
'your channel name',
|
||||
channelDescription: 'your channel description',
|
||||
importance: Importance.max,
|
||||
// priority: Priority.high,
|
||||
// ticker: 'ticker',
|
||||
);
|
||||
return const NotificationDetails(
|
||||
android: androidPlatformChannelSpecifics,
|
||||
iOS: IOSNotificationDetails(),
|
||||
);
|
||||
}
|
||||
|
||||
static Future init(
|
||||
{bool initScheduled = false, BuildContext? context}) async {
|
||||
const android = AndroidInitializationSettings('@mipmap/ic_launcher');
|
||||
// const android = AndroidInitializationSettings('app_icon');
|
||||
const iOS = IOSInitializationSettings();
|
||||
const settings = InitializationSettings(android: android, iOS: iOS);
|
||||
|
||||
final details = await _notifications.getNotificationAppLaunchDetails();
|
||||
if (details != null && details.didNotificationLaunchApp) {
|
||||
onNotifications.add(details.payload);
|
||||
}
|
||||
|
||||
await _notifications.initialize(
|
||||
settings,
|
||||
onSelectNotification: (payload) async {
|
||||
onNotifications.add(payload);
|
||||
},
|
||||
);
|
||||
|
||||
if (initScheduled) {
|
||||
final locationName = await FlutterNativeTimezone.getLocalTimezone();
|
||||
tz.setLocalLocation(tz.getLocation(locationName));
|
||||
}
|
||||
}
|
||||
|
||||
// static tz.TZDateTime _scheduleDaily(Time time) {
|
||||
// final tz.TZDateTime now = tz.TZDateTime.now(tz.local);
|
||||
// final scheduledDate = tz.TZDateTime(tz.local, now.year, now.month, now.day,
|
||||
// time.hour, time.minute, time.second);
|
||||
// // if (scheduledDate.isBefore(now)) {
|
||||
// // scheduledDate = scheduledDate.add(const Duration(days: 1));
|
||||
// // }
|
||||
// return scheduledDate.isBefore(now)
|
||||
// ? scheduledDate.add(const Duration(days: 1))
|
||||
// : scheduledDate;
|
||||
// }
|
||||
}
|
||||
47
lib/src/service/socket_io.dart
Normal file
47
lib/src/service/socket_io.dart
Normal file
@ -0,0 +1,47 @@
|
||||
import 'package:logger/logger.dart';
|
||||
import 'package:socket_io_client/socket_io_client.dart';
|
||||
|
||||
class MySocketIO {
|
||||
static final dev = Logger();
|
||||
static final MySocketIO _singleton = MySocketIO._internal();
|
||||
factory MySocketIO() {
|
||||
return _singleton;
|
||||
}
|
||||
MySocketIO._internal();
|
||||
|
||||
late Socket _socket;
|
||||
// static const String _url = 'http://192.168.43.125:3004';
|
||||
static const String _url = 'https://tanah-longosor-be.herokuapp.com';
|
||||
|
||||
init() {
|
||||
_socket = io(_url, <String, dynamic>{
|
||||
'transports': ['websocket'],
|
||||
'autoConnect': true,
|
||||
});
|
||||
|
||||
_socket.on('connect', (_) {
|
||||
dev.i('connect : ${_socket.id}');
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> emit(String event, dynamic data) async {
|
||||
_socket.emit(event, data);
|
||||
}
|
||||
|
||||
Future<void> on(String event, Function(dynamic) callback) async {
|
||||
_socket.on(event, callback);
|
||||
}
|
||||
|
||||
Future<void> off(String event) async {
|
||||
_socket.off(event);
|
||||
}
|
||||
|
||||
Future<void> disconnect() async {
|
||||
_socket.disconnect();
|
||||
}
|
||||
|
||||
Future<void> connect() async {
|
||||
dev.i('connect : ${_socket.id}');
|
||||
_socket.connect();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user