changes the area to kecamatan , kelurahan and tps

This commit is contained in:
kicap
2023-11-24 23:16:15 +08:00
parent 6046943a7a
commit 1b2849e6fc
33 changed files with 778 additions and 193 deletions

View File

@ -2,7 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<application <application
android:label="cek_suara_app" android:label="Survei Suara"
android:name="${applicationName}" android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"> android:icon="@mipmap/ic_launcher">
<activity <activity

Binary file not shown.

Before

Width:  |  Height:  |  Size: 544 B

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 442 B

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 721 B

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 87 KiB

View File

@ -11,6 +11,7 @@ import '../ui/views/login_screen/login_screen_view.dart';
import '../ui/views/splash_screen/splash_screen_view.dart'; import '../ui/views/splash_screen/splash_screen_view.dart';
import '../ui/views/tim_survei_index_tracking/first_page/first_page_view.dart'; import '../ui/views/tim_survei_index_tracking/first_page/first_page_view.dart';
import '../ui/views/tim_survei_index_tracking/halaman_history/halaman_history_view.dart'; import '../ui/views/tim_survei_index_tracking/halaman_history/halaman_history_view.dart';
import '../ui/views/tim_survei_index_tracking/halaman_pengaturan/ganti_password_dialog/ganti_password_dialog_view.dart';
import '../ui/views/tim_survei_index_tracking/halaman_pengaturan/halaman_pengaturan_view.dart'; import '../ui/views/tim_survei_index_tracking/halaman_pengaturan/halaman_pengaturan_view.dart';
import '../ui/views/tim_survei_index_tracking/halaman_survei/bottom_sheet_cari_area/bottom_sheet_cari_area_view.dart'; import '../ui/views/tim_survei_index_tracking/halaman_survei/bottom_sheet_cari_area/bottom_sheet_cari_area_view.dart';
@ -32,11 +33,10 @@ import '../ui/views/tim_survei_index_tracking/tim_survei_index_tracking_view.dar
], ],
), ),
], ],
dialogs: [
// dialogs: [ StackedDialog(classType: GantiPasswordDialogView),
// StackedDialog(classType: BottomSheetCariAreaView), // StackedDialog(classType: TambahDetailTimSurveiView)
// // StackedDialog(classType: TambahDetailTimSurveiView) ],
// ],
dependencies: [ dependencies: [
LazySingleton(classType: NavigationService), LazySingleton(classType: NavigationService),
LazySingleton(classType: DialogService), LazySingleton(classType: DialogService),

25
lib/app/app.dialogs.dart Normal file
View File

@ -0,0 +1,25 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// **************************************************************************
// StackedDialogGenerator
// **************************************************************************
import 'package:stacked_services/stacked_services.dart';
import 'app.locator.dart';
import '../ui/views/tim_survei_index_tracking/halaman_pengaturan/ganti_password_dialog/ganti_password_dialog_view.dart';
enum DialogType {
gantiPasswordDialogView,
}
void setupDialogUi() {
final dialogService = locator<DialogService>();
final Map<DialogType, DialogBuilder> builders = {
DialogType.gantiPasswordDialogView: (context, request, completer) =>
GantiPasswordDialogView(request: request, completer: completer),
};
dialogService.registerCustomDialogBuilders(builders);
}

View File

@ -1,5 +1,3 @@
// ignore_for_file: deprecated_member_use
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'app_colors.dart'; import 'app_colors.dart';
@ -17,9 +15,9 @@ ThemeData appTheme = ThemeData(
centerTitle: true, centerTitle: true,
), ),
textTheme: TextTheme( textTheme: TextTheme(
headline1: regularTextStyle.copyWith(fontSize: 32), displayLarge: regularTextStyle.copyWith(fontSize: 32),
headline2: regularTextStyle.copyWith(fontSize: 20), displayMedium: regularTextStyle.copyWith(fontSize: 20),
headline3: regularTextStyle.copyWith(fontSize: 18), displaySmall: regularTextStyle.copyWith(fontSize: 18),
), ),
elevatedButtonTheme: ElevatedButtonThemeData( elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(

View File

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart';
@ -5,12 +7,14 @@ import 'package:stacked_services/stacked_services.dart';
// import 'app/app.bottomsheets.dart'; // import 'app/app.bottomsheets.dart';
import 'app/app.bottomsheets.dart'; import 'app/app.bottomsheets.dart';
import 'app/app.dialogs.dart';
import 'app/app.locator.dart'; import 'app/app.locator.dart';
import 'app/app.router.dart'; import 'app/app.router.dart';
import 'app/themes/app_theme.dart'; import 'app/themes/app_theme.dart';
Future main() async { Future main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
HttpOverrides.global = MyHttpOverrides();
// await Future.wait([ // await Future.wait([
// dotenv.load(fileName: ".env"), // dotenv.load(fileName: ".env"),
// setupLocator(), // setupLocator(),
@ -27,7 +31,7 @@ class MyApp extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
title: 'Cek Suara', title: 'Cek Suara App',
theme: appTheme, theme: appTheme,
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
navigatorKey: StackedService.navigatorKey, navigatorKey: StackedService.navigatorKey,
@ -39,7 +43,16 @@ class MyApp extends StatelessWidget {
Future<void> setupAllLocator() async { Future<void> setupAllLocator() async {
await setupLocator(); await setupLocator();
// setupDialogUi(); setupDialogUi();
setupBottomSheetUi(); setupBottomSheetUi();
// setupSnackbarUi(); // setupSnackbarUi();
} }
class MyHttpOverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext? context) {
return super.createHttpClient(context)
..badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
}
}

View File

@ -1,14 +1,14 @@
class AreaListModel { class KecamatanDetail {
List<AreaModel>? area; List<KecamatanModel>? kecamatan;
int? jumlah; int? jumlah;
AreaListModel({this.area, this.jumlah}); KecamatanDetail({this.kecamatan, this.jumlah});
AreaListModel.fromJson(Map<String, dynamic> json) { KecamatanDetail.fromJson(Map<String, dynamic> json) {
if (json['area'] != null) { if (json['kecamatan'] != null) {
area = <AreaModel>[]; kecamatan = <KecamatanModel>[];
json['area'].forEach((v) { json['kecamatan'].forEach((v) {
area!.add(AreaModel.fromJson(v)); kecamatan!.add(KecamatanModel.fromJson(v));
}); });
} }
jumlah = json['jumlah']; jumlah = json['jumlah'];
@ -16,29 +16,77 @@ class AreaListModel {
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{}; final Map<String, dynamic> data = <String, dynamic>{};
if (area != null) { if (kecamatan != null) {
data['area'] = area!.map((v) => v.toJson()).toList(); data['kecamatan'] = kecamatan!.map((v) => v.toJson()).toList();
} }
data['jumlah'] = jumlah; data['jumlah'] = jumlah;
return data; return data;
} }
} }
class AreaModel { class KecamatanModel {
int? idArea; String? kecamatanId;
String? namaArea; String? name;
AreaModel({this.idArea, this.namaArea}); KecamatanModel({this.kecamatanId, this.name});
AreaModel.fromJson(Map<String, dynamic> json) { KecamatanModel.fromJson(Map<String, dynamic> json) {
idArea = json['id_area']; kecamatanId = json['kecamatan_id'];
namaArea = json['nama_area']; name = json['name'];
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{}; final Map<String, dynamic> data = <String, dynamic>{};
data['id_area'] = idArea; data['kecamatan_id'] = kecamatanId;
data['nama_area'] = namaArea; data['name'] = name;
return data;
}
}
class KelurahanDetail {
List<KelurahanModel>? kelurahan;
int? jumlah;
KelurahanDetail({this.kelurahan, this.jumlah});
KelurahanDetail.fromJson(Map<String, dynamic> json) {
if (json['kelurahan'] != null) {
kelurahan = <KelurahanModel>[];
json['kelurahan'].forEach((v) {
kelurahan!.add(KelurahanModel.fromJson(v));
});
}
jumlah = json['jumlah'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
if (kelurahan != null) {
data['kelurahan'] = kelurahan!.map((v) => v.toJson()).toList();
}
data['jumlah'] = jumlah;
return data;
}
}
class KelurahanModel {
String? kelurahanId;
String? kecamatanId;
String? name;
KelurahanModel({this.kelurahanId, this.kecamatanId, this.name});
KelurahanModel.fromJson(Map<String, dynamic> json) {
kelurahanId = json['kelurahan_id'];
kecamatanId = json['kecamatan_id'];
name = json['name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['kelurahan_id'] = kelurahanId;
data['kecamatan_id'] = kecamatanId;
data['name'] = name;
return data; return data;
} }
} }

View File

@ -1,13 +1,13 @@
import '../app/app.locator.dart'; import '../app/app.locator.dart';
import '../services/other_function.dart'; import '../services/other_function.dart';
class PemilihDetailModel { class PemilihDetail {
List<PemilihModel>? pemilihModel; List<PemilihModel>? pemilihModel;
int? jumlah; int? jumlah;
PemilihDetailModel({this.pemilihModel, this.jumlah}); PemilihDetail({this.pemilihModel, this.jumlah});
PemilihDetailModel.fromJson(Map<String, dynamic> json) { PemilihDetail.fromJson(Map<String, dynamic> json) {
if (json['data'] != null) { if (json['data'] != null) {
pemilihModel = <PemilihModel>[]; pemilihModel = <PemilihModel>[];
json['data'].forEach((v) { json['data'].forEach((v) {
@ -36,7 +36,9 @@ class PemilihModel {
String? nikTimSurvei; String? nikTimSurvei;
String? namaTimSurvei; String? namaTimSurvei;
String? namaCaleg; String? namaCaleg;
String? namaArea; String? kecamatan;
String? kelurahan;
int? tps;
String? createdAt; String? createdAt;
PemilihModel( PemilihModel(
@ -46,7 +48,9 @@ class PemilihModel {
this.nikTimSurvei, this.nikTimSurvei,
this.namaTimSurvei, this.namaTimSurvei,
this.namaCaleg, this.namaCaleg,
this.namaArea, this.kecamatan,
this.kelurahan,
this.tps,
this.createdAt}); this.createdAt});
PemilihModel.fromJson(Map<String, dynamic> json) { PemilihModel.fromJson(Map<String, dynamic> json) {
@ -56,7 +60,9 @@ class PemilihModel {
nikTimSurvei = json['nik_tim_survei']; nikTimSurvei = json['nik_tim_survei'];
namaTimSurvei = json['nama_tim_survei']; namaTimSurvei = json['nama_tim_survei'];
namaCaleg = json['nama_caleg']; namaCaleg = json['nama_caleg'];
namaArea = json['nama_area']; kecamatan = json['kecamatan'];
kelurahan = json['kelurahan'];
tps = json['tps'];
createdAt = myFunction.convertDateTime(json['created_at']); createdAt = myFunction.convertDateTime(json['created_at']);
} }
@ -68,7 +74,9 @@ class PemilihModel {
data['nik_tim_survei'] = nikTimSurvei; data['nik_tim_survei'] = nikTimSurvei;
data['nama_tim_survei'] = namaTimSurvei; data['nama_tim_survei'] = namaTimSurvei;
data['nama_caleg'] = namaCaleg; data['nama_caleg'] = namaCaleg;
data['nama_area'] = namaArea; data['kecamatan'] = kecamatan;
data['kelurahan'] = kelurahan;
data['tps'] = tps;
data['created_at'] = createdAt; data['created_at'] = createdAt;
return data; return data;
} }

View File

@ -1,13 +1,11 @@
// import '../../../app/app.router.dart';
import 'package:cek_suara_app/app/app.router.dart';
import 'package:cek_suara_app/model/my_response.model.dart';
import 'package:cek_suara_app/model/tim_survei_model.dart';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../../app/app.router.dart';
import '../../../app/app.logger.dart'; import '../../../app/app.logger.dart';
import '../../../app/core/custom_base_view_model.dart'; import '../../../app/core/custom_base_view_model.dart';
import '../../../model/my_response.model.dart';
import '../../../model/tim_survei_model.dart';
class LoginScreenViewModel extends CustomBaseViewModel { class LoginScreenViewModel extends CustomBaseViewModel {
final log = getLogger('LoginScreenViewModel'); final log = getLogger('LoginScreenViewModel');
@ -42,6 +40,7 @@ class LoginScreenViewModel extends CustomBaseViewModel {
mySharedPrefs.setString('nama', timSurveiModel.nama!); mySharedPrefs.setString('nama', timSurveiModel.nama!);
mySharedPrefs.setString('id_caleg', timSurveiModel.idCaleg.toString()); mySharedPrefs.setString('id_caleg', timSurveiModel.idCaleg.toString());
mySharedPrefs.setString('level', 'tim_survei'); mySharedPrefs.setString('level', 'tim_survei');
mySharedPrefs.setString('password', passwordController.text);
snackbarService.showSnackbar( snackbarService.showSnackbar(
message: 'Selamat datang kembali ${timSurveiModel.nama}', message: 'Selamat datang kembali ${timSurveiModel.nama}',
title: 'Login Berhasil', title: 'Login Berhasil',

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart'; import 'package:stacked/stacked.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../../../app/themes/app_colors.dart'; import '../../../../app/themes/app_colors.dart';
import '../../../../app/themes/app_text.dart'; import '../../../../app/themes/app_text.dart';
@ -124,11 +125,33 @@ class FirstPageView extends StatelessWidget {
], ],
), ),
), ),
GestureDetector(
onTap: () async {
final url = Uri.parse('https://www.kicap-karan.com');
if (!await launchUrl(url)) {
throw 'Could not launch $url';
}
},
child: Text(
'www.kicap-karan.com',
style: boldTextStyle.copyWith(
color: mainColor,
),
),
),
], ],
), ),
), ),
), ),
), ),
floatingActionButton: FloatingActionButton(
backgroundColor: warningColor,
onPressed: () {
model.gantiPassword();
},
child: const Icon(Icons.settings, color: fontColor),
),
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
); );
}, },
); );

View File

@ -1,3 +1,4 @@
import '../../../../app/app.dialogs.dart';
import '../../../../app/app.logger.dart'; import '../../../../app/app.logger.dart';
import '../../../../app/core/custom_base_view_model.dart'; import '../../../../app/core/custom_base_view_model.dart';
import '../../../../model/my_response.model.dart'; import '../../../../model/my_response.model.dart';
@ -27,4 +28,17 @@ class FirstPageViewModel extends CustomBaseViewModel {
setBusy(false); setBusy(false);
} }
} }
gantiPassword() async {
var res = await dialogService.showCustomDialog(
variant: DialogType.gantiPasswordDialogView,
title: 'Ganti Password',
mainButtonTitle: 'Simpan',
barrierDismissible: false,
);
if (res!.confirmed) {
snackbarService.showSnackbar(message: 'Password berhasil diubah');
}
}
} }

View File

@ -96,6 +96,18 @@ class DetailSuaraPemilihBottomSheetView extends StatelessWidget {
title: 'Tanggal/\nWaktu', title: 'Tanggal/\nWaktu',
value: request.data!.createdAt!, value: request.data!.createdAt!,
), ),
_DetailChildWidget(
title: 'Kecamatan',
value: request.data!.kecamatan!,
),
_DetailChildWidget(
title: 'Kelurahan/\nDesa',
value: request.data!.kelurahan!,
),
_DetailChildWidget(
title: 'TPS',
value: request.data!.tps!.toString(),
),
], ],
), ),
), ),

View File

@ -104,8 +104,26 @@ class HalamanHistoryView extends StatelessWidget {
model.listPemilih[i].namaPemilih!, model.listPemilih[i].namaPemilih!,
style: boldTextStyle, style: boldTextStyle,
), ),
subtitle: Text( subtitle: Column(
model.listPemilih[i].namaArea!, mainAxisSize: MainAxisSize.min,
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.start,
children: [
CardWidget(
title: 'Kec',
value: model
.listPemilih[i].kecamatan!),
CardWidget(
title: 'Kel / Desa',
value: model
.listPemilih[i].kelurahan!),
CardWidget(
title: 'TPS',
value: model.listPemilih[i].tps!
.toString()),
],
), ),
trailing: IconButton( trailing: IconButton(
icon: const Icon( icon: const Icon(
@ -151,3 +169,48 @@ class HalamanHistoryView extends StatelessWidget {
); );
} }
} }
class CardWidget extends StatelessWidget {
const CardWidget({
super.key,
required this.title,
required this.value,
});
final String title;
final String value;
@override
Widget build(BuildContext context) {
return Row(
children: [
Expanded(
flex: 3,
child: Text(
title,
style: italicTextStyle.copyWith(
fontSize: 12,
),
overflow: TextOverflow.ellipsis,
),
),
const Expanded(
flex: 1,
child: Text(
' : ',
),
),
Expanded(
flex: 6,
child: Text(
value,
style: boldTextStyle.copyWith(
fontSize: 12,
),
overflow: TextOverflow.ellipsis,
),
),
],
);
}
}

View File

@ -1,9 +1,8 @@
import 'package:cek_suara_app/model/my_response.model.dart';
import 'package:cek_suara_app/model/pemilih_model.dart';
import '../../../../app/app.bottomsheets.dart'; import '../../../../app/app.bottomsheets.dart';
import '../../../../app/app.logger.dart'; import '../../../../app/app.logger.dart';
import '../../../../app/core/custom_base_view_model.dart'; import '../../../../app/core/custom_base_view_model.dart';
import '../../../../model/my_response.model.dart';
import '../../../../model/pemilih_model.dart';
class HalamanHistoryViewModel extends CustomBaseViewModel { class HalamanHistoryViewModel extends CustomBaseViewModel {
final log = getLogger('HalamanHistoryViewModel'); final log = getLogger('HalamanHistoryViewModel');
@ -13,6 +12,7 @@ class HalamanHistoryViewModel extends CustomBaseViewModel {
String namaCaleg = '...'; String namaCaleg = '...';
Future<void> init() async { Future<void> init() async {
globalVar.backPressed = 'exitApp';
await getData(); await getData();
} }
@ -23,13 +23,13 @@ class HalamanHistoryViewModel extends CustomBaseViewModel {
String? nik = await mySharedPrefs.getString('nik'); String? nik = await mySharedPrefs.getString('nik');
var response = await httpService.get('tim_survei/$nik'); var response = await httpService.get('tim_survei/$nik');
MyResponseModel myResponseModel = MyResponseModel.fromJson(response.data); MyResponseModel myResponseModel = MyResponseModel.fromJson(response.data);
PemilihDetailModel pemilihDetailModel = PemilihDetail pemilihDetail =
PemilihDetailModel.fromJson(myResponseModel.data); PemilihDetail.fromJson(myResponseModel.data);
listPemilih = pemilihDetailModel.pemilihModel!; listPemilih = pemilihDetail.pemilihModel ?? [];
log.i('listPemilih: $listPemilih'); // log.i('listPemilih: $listPemilih');
namaCaleg = listPemilih[0].namaCaleg!; counter = pemilihDetail.jumlah!;
counter = pemilihDetailModel.jumlah!; namaCaleg = counter > 0 ? listPemilih[0].namaCaleg! : '...';
log.i('counter: $counter'); // log.i('counter: $counter');
status = true; status = true;
} catch (e) { } catch (e) {
log.e(e.toString()); log.e(e.toString());

View File

@ -0,0 +1,190 @@
import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart';
import 'package:validatorless/validatorless.dart';
import '../../../../../app/themes/app_colors.dart';
import '../../../../../app/themes/app_text.dart';
import '../../../../widgets/my_textformfield.dart';
import './ganti_password_dialog_view_model.dart';
class GantiPasswordDialogView extends StatelessWidget {
final DialogRequest? request;
final Function(DialogResponse)? completer;
const GantiPasswordDialogView({
Key? key,
this.request,
this.completer,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ViewModelBuilder<GantiPasswordDialogViewModel>.reactive(
viewModelBuilder: () => GantiPasswordDialogViewModel(),
onViewModelReady: (GantiPasswordDialogViewModel model) async {
await model.init();
},
builder: (
BuildContext context,
GantiPasswordDialogViewModel model,
Widget? child,
) {
return Dialog(
child: Container(
padding: const EdgeInsets.all(20),
child: Form(
key: model.globalKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Ganti Password',
style: boldTextStyle.copyWith(fontSize: 18),
),
const SizedBox(height: 20),
MyTextFormField(
labelText: 'Password Lama',
hintText: 'Masukkan password lama',
obscureText: model.isPasswordLamaObscure,
suffixIcon: IconButton(
onPressed: () {
model.isPasswordLamaObscure =
!model.isPasswordLamaObscure;
model.notifyListeners();
},
icon: Icon(
model.isPasswordLamaObscure
? Icons.visibility_off
: Icons.visibility,
),
),
controller: model.passwordLamaController,
validator: Validatorless.multiple(
[
Validatorless.required(
'Password lama tidak boleh kosong'),
Validatorless.min(
8, 'Password lama minimal 8 karakter'),
Validatorless.compare(
model.thePasswordLamaController,
'Password lama tidak sama',
),
],
),
),
const SizedBox(height: 10),
MyTextFormField(
labelText: 'Password Baru',
hintText: 'Masukkan password baru',
obscureText: model.isPasswordBaruObscure,
controller: model.passwordBaruController,
suffixIcon: IconButton(
onPressed: () {
model.isPasswordBaruObscure =
!model.isPasswordBaruObscure;
model.notifyListeners();
},
icon: Icon(
model.isPasswordBaruObscure
? Icons.visibility_off
: Icons.visibility,
),
),
validator: Validatorless.multiple(
[
Validatorless.required(
'Password baru tidak boleh kosong'),
Validatorless.min(
8, 'Password baru minimal 8 karakter'),
],
),
),
const SizedBox(height: 10),
MyTextFormField(
labelText: 'Konfirmasi Password Baru',
hintText: 'Masukkan konfirmasi password baru',
obscureText: model.isKonfirmasiPasswordBaruObscure,
controller: model.konfirmasiPasswordBaruController,
suffixIcon: IconButton(
onPressed: () {
model.isKonfirmasiPasswordBaruObscure =
!model.isKonfirmasiPasswordBaruObscure;
model.notifyListeners();
},
icon: Icon(
model.isKonfirmasiPasswordBaruObscure
? Icons.visibility_off
: Icons.visibility,
),
),
validator: Validatorless.multiple(
[
Validatorless.required(
'Konfirmasi password baru tidak boleh kosong'),
Validatorless.min(
8, 'Konfirmasi password baru minimal 8 karakter'),
Validatorless.compare(
model.passwordBaruController,
'Password baru tidak sama',
),
],
),
),
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () {
if (model.globalKey.currentState!.validate()) {
// remove keyboard
FocusScope.of(context).unfocus();
model.dialogService
.showConfirmationDialog(
title: 'Konfirmasi',
description:
'Apakah anda yakin ingin mengubah password?',
cancelTitle: 'Batal',
confirmationTitle: 'Ya',
)
.then(
(response) async {
if (response!.confirmed) {
// completer!(DialogResponse(confirmed: true));
// model.log.i('Password berhasil diubah');
bool res = await model.gantiPassword();
// model.log.i('res: $res');
if (res) {
completer!(DialogResponse(confirmed: true));
model.log.i('Password berhasil diubah');
}
} else {
model.log.i('Password gagal diubah');
}
},
);
}
},
child: const Text('Simpan'),
),
TextButton(
onPressed: () =>
completer!(DialogResponse(confirmed: false)),
child: const Text(
'Batal',
style: TextStyle(color: dangerColor),
),
),
],
),
],
),
),
),
);
},
);
}
}

View File

@ -0,0 +1,51 @@
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import '../../../../../app/app.logger.dart';
import '../../../../../app/core/custom_base_view_model.dart';
class GantiPasswordDialogViewModel extends CustomBaseViewModel {
final log = getLogger('GantiPasswordDialogViewModel');
// form variable
final globalKey = GlobalKey<FormState>();
TextEditingController passwordLamaController = TextEditingController();
TextEditingController passwordBaruController = TextEditingController();
TextEditingController konfirmasiPasswordBaruController =
TextEditingController();
TextEditingController thePasswordLamaController = TextEditingController();
bool isPasswordLamaObscure = true;
bool isPasswordBaruObscure = true;
bool isKonfirmasiPasswordBaruObscure = true;
// String? passwordLama;
Future<void> init() async {
globalVar.backPressed = 'exitApp';
String? passwordLama = await mySharedPrefs.getString('password');
thePasswordLamaController.text = passwordLama!;
}
Future<bool> gantiPassword() async {
setBusy(true);
try {
String? nik = await mySharedPrefs.getString('nik');
var formData = FormData.fromMap({
'nik': nik,
'password_lama': passwordLamaController.text,
'password_baru': passwordBaruController.text,
});
await httpService.postWithFormData(
'login/ganti_pass_tim_survei', formData);
return true;
} catch (e) {
log.e(e.toString());
return false;
} finally {
setBusy(false);
}
}
}

View File

@ -1,7 +1,7 @@
import 'package:cek_suara_app/ui/views/tim_survei_index_tracking/first_page/first_page_view.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart'; import 'package:stacked/stacked.dart';
import '../first_page/first_page_view.dart';
import './halaman_pengaturan_view_model.dart'; import './halaman_pengaturan_view_model.dart';
class HalamanPengaturanView extends StatelessWidget { class HalamanPengaturanView extends StatelessWidget {

View File

@ -1,8 +1,8 @@
import 'package:cek_suara_app/ui/widgets/my_textformfield.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart'; import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart'; import 'package:stacked_services/stacked_services.dart';
import '../../../../widgets/my_textformfield.dart';
import './bottom_sheet_cari_area_view_model.dart'; import './bottom_sheet_cari_area_view_model.dart';
class BottomSheetCariAreaView extends StatelessWidget { class BottomSheetCariAreaView extends StatelessWidget {

View File

@ -120,11 +120,11 @@ class HalamanSurveiView extends StatelessWidget {
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
const Text( const Text(
' Pilih Area', ' Pilih Kecamatan',
), ),
if (model.isBusy) if (model.isBusy)
const Center(child: CircularProgressIndicator()), const Center(child: CircularProgressIndicator()),
if (!model.isBusy && model.selectedArea != null) if (!model.isBusy && model.selectedKecamatan != null)
Container( Container(
width: double.infinity, width: double.infinity,
height: 60, height: 60,
@ -135,46 +135,97 @@ class HalamanSurveiView extends StatelessWidget {
color: sixthGrey, color: sixthGrey,
), ),
), ),
child: Row(
children: [
// icon search
IconButton(
onPressed: () async =>
await model.searchArea(),
icon: const Icon(
Icons.search,
color: sixthGrey,
),
),
const SizedBox(width: 10),
Expanded(
child: DropdownButtonHideUnderline( child: DropdownButtonHideUnderline(
child: DropdownButton<String>( child: DropdownButton<String>(
isExpanded: true, isExpanded: true,
value: model.selectedArea!, value: model.selectedKecamatan!,
icon: const Icon(Icons.arrow_drop_down), icon: const Icon(Icons.arrow_drop_down),
iconSize: 24, iconSize: 24,
elevation: 16, elevation: 16,
style: const TextStyle( style: const TextStyle(color: Colors.black),
color: Colors.black),
onChanged: (String? newValue) { onChanged: (String? newValue) {
model.log.i(newValue); model.log.i(newValue);
model.selectedArea = newValue!; model.selectedKecamatan = newValue!;
String kecamatanId = model
.listKecamatanModel[model
.listKecamatanString
.indexOf(newValue)]
.kecamatanId!;
model.getKelurahan(kecamatanId);
// model.changeArea(newValue); // model.changeArea(newValue);
model.notifyListeners(); model.notifyListeners();
}, },
items: model.listAreaString items: model.listKecamatanString
.map<DropdownMenuItem<String>>( .map<DropdownMenuItem<String>>(
(String value) { (String value) {
return DropdownMenuItem<String>( return DropdownMenuItem<String>(
value: value, value: value,
child: Text(value, child: Text(value,
overflow: overflow: TextOverflow.ellipsis),
TextOverflow.ellipsis),
); );
}).toList()), }).toList()),
), ),
), ),
const SizedBox(height: 20),
const Text(
' Pilih Kelurahan / Desa',
),
if (model.isBusy)
const Center(child: CircularProgressIndicator()),
if (!model.isBusy && model.selectedKelurahan != null)
Container(
width: double.infinity,
height: 60,
padding: const EdgeInsets.symmetric(horizontal: 10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25),
border: Border.all(
color: sixthGrey,
),
),
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
isExpanded: true,
value: model.selectedKelurahan!,
icon: const Icon(Icons.arrow_drop_down),
iconSize: 24,
elevation: 16,
style: const TextStyle(color: Colors.black),
onChanged: (String? newValue) {
model.log.i(newValue);
model.selectedKelurahan = newValue!;
// model.changeArea(newValue);
model.notifyListeners();
},
items: model.listKelurahanString
.map<DropdownMenuItem<String>>(
(String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value,
overflow: TextOverflow.ellipsis),
);
}).toList()),
),
),
const SizedBox(height: 20),
MyTextFormField(
hintText: 'Masukkan No TPS',
labelText: 'Nomor TPS',
maxLength: 2,
suffixIcon: const Icon(Icons.account_balance),
controller: model.noTPScontroller,
keyboardType: TextInputType.number,
validator: Validatorless.multiple(
[
Validatorless.required(
'Nomor TPS tidak boleh kosong'),
Validatorless.number('Nomor TPS harus angka'),
Validatorless.min(1, 'Nomor TPS minimal 1 digit'),
Validatorless.max(
2, 'Nomor TPS maksimal 2 digit'),
], ],
), ),
), ),

View File

@ -4,7 +4,6 @@ import 'package:dio/dio.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:http_parser/http_parser.dart'; import 'package:http_parser/http_parser.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import '../../../../app/app.bottomsheets.dart';
import '../../../../app/app.logger.dart'; import '../../../../app/app.logger.dart';
import '../../../../app/core/custom_base_view_model.dart'; import '../../../../app/core/custom_base_view_model.dart';
import '../../../../model/area_model.dart'; import '../../../../model/area_model.dart';
@ -17,6 +16,7 @@ class HalamanSurveiViewModel extends CustomBaseViewModel {
final formKey = GlobalKey<FormState>(); final formKey = GlobalKey<FormState>();
TextEditingController ktpController = TextEditingController(); TextEditingController ktpController = TextEditingController();
TextEditingController namaController = TextEditingController(); TextEditingController namaController = TextEditingController();
TextEditingController noTPScontroller = TextEditingController();
// image picker // image picker
String? _imagePath; String? _imagePath;
@ -25,11 +25,14 @@ class HalamanSurveiViewModel extends CustomBaseViewModel {
Uint8List? imageBytes; Uint8List? imageBytes;
// area // area
List<AreaModel> listAreaModel = []; List<KecamatanModel> listKecamatanModel = [];
List<String> listAreaString = []; List<String> listKecamatanString = [];
List<AreaModel> allListAreaModel = []; List<KelurahanModel> listKelurahanModel = [];
String? selectedArea; List<String> listKelurahanString = [];
int areaIndex = 0; // List<AreaModel> allListKecamatanModel = [];
String? selectedKecamatan;
String? selectedKelurahan;
// int areaIndex = 0;
// // caleg // // caleg
// List<CalegModel> listCalegModel = []; // List<CalegModel> listCalegModel = [];
@ -59,17 +62,31 @@ class HalamanSurveiViewModel extends CustomBaseViewModel {
// String? nik = await mySharedPrefs.getString('nik'); // String? nik = await mySharedPrefs.getString('nik');
var response = await httpService.get('area/cek_area/$nik'); var response = await httpService.get('area/cek_area/$nik');
log.i(response.data); // log.i(response.data);
MyResponseModel myResponseModel = MyResponseModel.fromJson(response.data); MyResponseModel myResponseModel = MyResponseModel.fromJson(response.data);
AreaListModel areaListModel = KecamatanDetail kecamatanDetail =
AreaListModel.fromJson(myResponseModel.data); KecamatanDetail.fromJson(myResponseModel.data);
listAreaModel = areaListModel.area!;
allListAreaModel = areaListModel.area!; listKecamatanModel = kecamatanDetail.kecamatan!;
for (var element in listAreaModel) { selectedKecamatan = listKecamatanModel[0].name!;
listAreaString.add(element.namaArea!); for (var element in listKecamatanModel) {
listKecamatanString.add(element.name!);
} }
selectedArea = listAreaString[0];
// int idArea = listAreaModel[0].idArea!; // log.i('kecamatanDetail: ${kecamatanDetail.kecamatan}');
String idKecamatan = listKecamatanModel[0].kecamatanId!;
await getKelurahan(idKecamatan);
// AreaListModel areaListModel =
// AreaListModel.fromJson(myResponseModel.data);
// listKecamatanModel = areaListModel.area!;
// allListKecamatanModel = areaListModel.area!;
// for (var element in listKecamatanModel) {
// listKecamatanString.add(element.namaArea!);
// }
// selectedKecamatan = listKecamatanString[0];
// // int idArea = listKecamatanModel[0].idArea!;
// await getCaleg(idArea); // await getCaleg(idArea);
// getCaleg() // getCaleg()
@ -81,40 +98,30 @@ class HalamanSurveiViewModel extends CustomBaseViewModel {
} }
} }
// getCaleg(int idArea) async { getKelurahan(String idKecamatan) async {
// log.i('getCaleg'); log.i('getKelurahan');
// log.i('idArea: $idArea'); listKelurahanModel = [];
// selectedCaleg = null; listKelurahanString = [];
// listCalegModel = []; selectedKelurahan = null;
// listCalegString = []; setBusy(true);
// setBusy(true); try {
// try { var response = await httpService.get('area/kelurahan/$idKecamatan');
// var response = await httpService.get('caleg/area/$idArea');
// log.i(response.data); // log.i(response.data);
// MyResponseModel myResponseModel = MyResponseModel.fromJson(response.data); MyResponseModel myResponseModel = MyResponseModel.fromJson(response.data);
// // log.i(myResponseModel.data); KelurahanDetail kelurahanDetail =
// CalegListModel calegListModel = KelurahanDetail.fromJson(myResponseModel.data);
// CalegListModel.fromJson(myResponseModel.data); // log.i('kelurahanDetail: ${kelurahanDetail.kelurahan}');
// listCalegModel = calegListModel.caleg!; listKelurahanModel = kelurahanDetail.kelurahan!;
// for (var element in listCalegModel) { for (var element in listKelurahanModel) {
// listCalegString.add(element.namaCaleg!); listKelurahanString.add(element.name!);
// } }
// selectedCaleg = listCalegString[0]; selectedKelurahan = listKelurahanString[0];
// // log.i('listCalegModel: $listCalegModel'); } catch (e) {
// // log.i('listCalegString: $listCalegString'); log.e(e);
// // log.i('selectedCaleg: $selectedCaleg'); } finally {
// } catch (e) { setBusy(false);
// log.e(e); }
// } finally { }
// setBusy(false);
// }
// }
// changeArea(String? value) async {
// int idArea = listAreaModel[listAreaString.indexOf(value!)].idArea!;
// // log.i('idArea: $idArea');
// await getCaleg(idArea);
// }
void addImage() async { void addImage() async {
try { try {
@ -132,47 +139,19 @@ class HalamanSurveiViewModel extends CustomBaseViewModel {
} }
} }
searchArea() async {
var res = await bottomSheetService.showCustomSheet(
variant: BottomSheetType.bottomSheetCariAreaView,
ignoreSafeArea: false,
isScrollControlled: true,
);
if (res!.confirmed) {
log.i('res.data: ${res.data}');
String area = res.data;
if (area == '') {
listAreaModel = allListAreaModel;
} else {
listAreaModel = [];
for (var element in allListAreaModel) {
if (element.namaArea!.toLowerCase().contains(area.toLowerCase())) {
listAreaModel.add(element);
}
}
}
listAreaString = [];
for (var element in listAreaModel) {
listAreaString.add(element.namaArea!);
}
selectedArea = listAreaString[0];
// int idArea = listAreaModel[0].idArea!;
// await getCaleg(idArea);
notifyListeners();
}
}
uploadData() async { uploadData() async {
log.i('uploadData'); log.i('uploadData');
setBusy(true); setBusy(true);
easyLoading.customLoading('Uploading data...'); easyLoading.customLoading('Uploading data...');
globalVar.backPressed = 'cantBack'; globalVar.backPressed = 'cantBack';
try { try {
String idArea = listAreaModel[listAreaString.indexOf(selectedArea!)] String idKecamatan =
.idArea listKecamatanModel[listKecamatanString.indexOf(selectedKecamatan!)]
.kecamatanId
.toString();
String idKelurahan =
listKelurahanModel[listKelurahanString.indexOf(selectedKelurahan!)]
.kelurahanId
.toString(); .toString();
var fomData = FormData.fromMap( var fomData = FormData.fromMap(
{ {
@ -184,8 +163,10 @@ class HalamanSurveiViewModel extends CustomBaseViewModel {
filename: imageFile!.name, filename: imageFile!.name,
contentType: MediaType('image', 'jpg'), contentType: MediaType('image', 'jpg'),
), ),
'idArea': idArea, 'idKecamatan': idKecamatan,
'idKelurahan': idKelurahan,
'nik': nik, 'nik': nik,
'noTPS': noTPScontroller.text,
}, },
); );
await httpService.postWithFormData('tim_survei', fomData); await httpService.postWithFormData('tim_survei', fomData);
@ -200,6 +181,7 @@ class HalamanSurveiViewModel extends CustomBaseViewModel {
_imagePath = null; _imagePath = null;
imageFile = null; imageFile = null;
imageBytes = null; imageBytes = null;
noTPScontroller.clear();
notifyListeners(); notifyListeners();
} catch (e) { } catch (e) {
log.e(e); log.e(e);

View File

@ -26,6 +26,26 @@ class TimSurveiIndexTrackingView extends StatelessWidget {
) { ) {
return SafeArea( return SafeArea(
child: Scaffold( child: Scaffold(
appBar: AppBar(
title: Text(
model.header,
style: const TextStyle(
color: fontColor,
fontSize: 20,
),
),
backgroundColor: warningColor,
elevation: 0,
automaticallyImplyLeading: false,
actions: [
IconButton(
onPressed: () {
model.logout();
},
icon: const Icon(Icons.logout, color: fontColor),
),
],
),
extendBody: false, extendBody: false,
body: ExtendedNavigator( body: ExtendedNavigator(
router: TimSurveiIndexTrackingViewRouter(), router: TimSurveiIndexTrackingViewRouter(),

View File

@ -14,6 +14,7 @@ class TimSurveiIndexTrackingViewModel extends IndexTrackingViewModel {
final navigationService = locator<NavigationService>(); final navigationService = locator<NavigationService>();
final snackbarService = locator<SnackbarService>(); final snackbarService = locator<SnackbarService>();
final globalVar = locator<GlobalVar>(); final globalVar = locator<GlobalVar>();
final dialogService = locator<DialogService>();
final _bottomNavBarList = [ final _bottomNavBarList = [
{ {
@ -68,4 +69,20 @@ class TimSurveiIndexTrackingViewModel extends IndexTrackingViewModel {
id: 5, id: 5,
); );
} }
logout() async {
dialogService
.showConfirmationDialog(
title: 'Konfirmasi',
description: 'Apakah anda yakin ingin keluar?',
cancelTitle: 'Batal',
confirmationTitle: 'Keluar',
)
.then((value) async {
if (value!.confirmed) {
await mySharedPrefs.clear();
navigationService.clearStackAndShow(Routes.loginScreenView);
}
});
}
} }

View File

@ -7,9 +7,13 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <file_selector_linux/file_selector_plugin.h> #include <file_selector_linux/file_selector_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) { void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar = g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
file_selector_plugin_register_with_registrar(file_selector_linux_registrar); file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
} }

View File

@ -4,6 +4,7 @@
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
file_selector_linux file_selector_linux
url_launcher_linux
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST

View File

@ -8,9 +8,11 @@ import Foundation
import file_selector_macos import file_selector_macos
import path_provider_foundation import path_provider_foundation
import shared_preferences_foundation import shared_preferences_foundation
import url_launcher_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
} }

View File

@ -877,6 +877,70 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.2" version: "2.2.2"
url_launcher:
dependency: "direct main"
description:
name: url_launcher
sha256: "47e208a6711459d813ba18af120d9663c20bdf6985d6ad39fe165d2538378d27"
url: "https://pub.dev"
source: hosted
version: "6.1.14"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
sha256: "31222ffb0063171b526d3e569079cf1f8b294075ba323443fdc690842bfd4def"
url: "https://pub.dev"
source: hosted
version: "6.2.0"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
sha256: "4ac97281cf60e2e8c5cc703b2b28528f9b50c8f7cebc71df6bdf0845f647268a"
url: "https://pub.dev"
source: hosted
version: "6.2.0"
url_launcher_linux:
dependency: transitive
description:
name: url_launcher_linux
sha256: "9f2d390e096fdbe1e6e6256f97851e51afc2d9c423d3432f1d6a02a8a9a8b9fd"
url: "https://pub.dev"
source: hosted
version: "3.1.0"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
sha256: b7244901ea3cf489c5335bdacda07264a6e960b1c1b1a9f91e4bc371d9e68234
url: "https://pub.dev"
source: hosted
version: "3.1.0"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
sha256: "980e8d9af422f477be6948bdfb68df8433be71f5743a188968b0c1b887807e50"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
sha256: ba140138558fcc3eead51a1c42e92a9fb074a1b1149ed3c73e66035b2ccd94f2
url: "https://pub.dev"
source: hosted
version: "2.0.19"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
sha256: "7754a1ad30ee896b265f8d14078b0513a4dba28d358eabb9d5f339886f4a1adc"
url: "https://pub.dev"
source: hosted
version: "3.1.0"
validatorless: validatorless:
dependency: "direct main" dependency: "direct main"
description: description:
@ -935,4 +999,4 @@ packages:
version: "3.1.2" version: "3.1.2"
sdks: sdks:
dart: ">=3.1.0-163.1.beta <4.0.0" dart: ">=3.1.0-163.1.beta <4.0.0"
flutter: ">=3.7.0" flutter: ">=3.10.0"

View File

@ -42,17 +42,13 @@ dependencies:
path_provider: ^2.0.9 path_provider: ^2.0.9
dio: dio:
flutter_easyloading: flutter_easyloading:
# location: ^4.4.0
# flutter_inappwebview:
# webview_flutter: ^3.0.4
# google_fonts:
# flutter_svg:
stylish_bottom_bar: stylish_bottom_bar:
validatorless: ^1.2.3 validatorless: ^1.2.3
http_parser: http_parser:
intl: intl:
shared_preferences: shared_preferences:
easy_image_viewer: easy_image_viewer:
url_launcher:
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

View File

@ -7,8 +7,11 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <file_selector_windows/file_selector_windows.h> #include <file_selector_windows/file_selector_windows.h>
#include <url_launcher_windows/url_launcher_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
FileSelectorWindowsRegisterWithRegistrar( FileSelectorWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FileSelectorWindows")); registry->GetRegistrarForPlugin("FileSelectorWindows"));
UrlLauncherWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
} }

View File

@ -4,6 +4,7 @@
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
file_selector_windows file_selector_windows
url_launcher_windows
) )
list(APPEND FLUTTER_FFI_PLUGIN_LIST list(APPEND FLUTTER_FFI_PLUGIN_LIST