From 85a265545743decf34f4ae3da5b5c9a5329b0104 Mon Sep 17 00:00:00 2001 From: Irwan Cahyono Date: Fri, 11 Apr 2025 13:09:55 +0700 Subject: [PATCH] mobile --- .gitignore | 9 ++ lib/components/menu_button.dart | 5 +- lib/helpers/image_picker_mobile.dart | 14 ++ lib/helpers/image_picker_stub.dart | 5 + lib/helpers/image_picker_web.dart | 35 +++++ lib/helpers/pick_image.dart | 3 + lib/main.dart | 1 + lib/screen/Home_screen.dart | 50 +++++- lib/screen/pustaka_screen copy 2.dart | 2 +- lib/screen/pustaka_screen copy.dart | 2 +- lib/screen/pustaka_screen.dart | 6 +- lib/screen/saya/akun_saya copy.dart | 211 ++++++++++++++++++++++++++ lib/screen/saya/akun_saya.dart | 1 - lib/screen/saya/profile_screen.dart | 1 - pubspec.yaml | 5 + 15 files changed, 341 insertions(+), 9 deletions(-) create mode 100644 lib/helpers/image_picker_mobile.dart create mode 100644 lib/helpers/image_picker_stub.dart create mode 100644 lib/helpers/image_picker_web.dart create mode 100644 lib/helpers/pick_image.dart create mode 100644 lib/screen/saya/akun_saya copy.dart diff --git a/.gitignore b/.gitignore index 79c113f..c837fb1 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,12 @@ app.*.map.json /android/app/debug /android/app/profile /android/app/release + +# Place unity project here +/unity + +# flutter will place unity Library dependency here +/unityLibrary + +# unityLibrary will place build here +/android/unityLibrary \ No newline at end of file diff --git a/lib/components/menu_button.dart b/lib/components/menu_button.dart index 66f5ef0..61592b9 100644 --- a/lib/components/menu_button.dart +++ b/lib/components/menu_button.dart @@ -28,8 +28,8 @@ class MenuButton extends StatelessWidget { IconButton( icon: SvgPicture.asset( icon ?? '', - width: w ?? 28, - height: h ?? 28, + width: w ?? 24, + height: h ?? 24, // allowDrawingOutsideViewBox: true, colorFilter: ColorFilter.mode( (isSelected ?? false) @@ -48,6 +48,7 @@ class MenuButton extends StatelessWidget { ? Color.fromARGB(255, 216, 182, 10) : Color.fromARGB(255, 239, 224, 232), fontWeight: FontWeight.bold, + fontSize: 10, ), ), ], diff --git a/lib/helpers/image_picker_mobile.dart b/lib/helpers/image_picker_mobile.dart new file mode 100644 index 0000000..bf49f5b --- /dev/null +++ b/lib/helpers/image_picker_mobile.dart @@ -0,0 +1,14 @@ +import 'dart:io'; +import 'package:image_picker/image_picker.dart'; + +class ImagePickerHelper { + Future pickImage() async { + final ImagePicker picker = ImagePicker(); + final XFile? pickedFile = await picker.pickImage(source: ImageSource.gallery); + + if (pickedFile != null) { + File imageFile = File(pickedFile.path); + return imageFile; + } + } +} \ No newline at end of file diff --git a/lib/helpers/image_picker_stub.dart b/lib/helpers/image_picker_stub.dart new file mode 100644 index 0000000..0f4d0d2 --- /dev/null +++ b/lib/helpers/image_picker_stub.dart @@ -0,0 +1,5 @@ +class ImagePickerHelper { + Future pickImage() async { + throw UnsupportedError('pickImage is not supported on this platform'); + } +} \ No newline at end of file diff --git a/lib/helpers/image_picker_web.dart b/lib/helpers/image_picker_web.dart new file mode 100644 index 0000000..86be7f0 --- /dev/null +++ b/lib/helpers/image_picker_web.dart @@ -0,0 +1,35 @@ +// import 'package:image_picker_web/image_picker_web.dart'; +// import 'dart:typed_data'; + +// class ImagePickerHelper { +// Future pickImage() async { +// Uint8List? bytesFromPicker = await ImagePickerWeb.getImageAsBytes(); +// if (bytesFromPicker != null) { +// return bytesFromPicker; +// } +// } +// } + +import 'dart:typed_data'; +import 'dart:html' as html; + +class ImagePickerHelper { + Future pickImage() async { + html.FileUploadInputElement uploadInput = html.FileUploadInputElement(); + uploadInput.accept = 'image/*'; + uploadInput.click(); + + uploadInput.onChange.listen((event) async { + final file = uploadInput.files!.first; + final reader = html.FileReader(); + + reader.readAsArrayBuffer(file); + reader.onLoadEnd.listen((event) { + Uint8List imageBytes = reader.result as Uint8List; + if (imageBytes != null) { + return imageBytes; + } + }); + }); + } +} \ No newline at end of file diff --git a/lib/helpers/pick_image.dart b/lib/helpers/pick_image.dart new file mode 100644 index 0000000..e01473f --- /dev/null +++ b/lib/helpers/pick_image.dart @@ -0,0 +1,3 @@ +export 'image_picker_stub.dart' + if (dart.library.html) 'image_picker_web.dart' + if (dart.library.io) 'image_picker_mobile.dart'; \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index 83003bf..b6feff6 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:freekake/components/navbar_container.dart'; import 'package:freekake/providers/character_provider.dart'; import 'package:freekake/providers/menu_selection_provider.dart'; import 'package:freekake/providers/point_provider.dart'; diff --git a/lib/screen/Home_screen.dart b/lib/screen/Home_screen.dart index df55393..42713e3 100644 --- a/lib/screen/Home_screen.dart +++ b/lib/screen/Home_screen.dart @@ -16,6 +16,7 @@ class HomeScreen extends StatefulWidget { class _HomeScreenState extends State { final String username = "luffy01"; // Image image + late UnityWidgetController _unityWidgetController; @override Widget build(BuildContext context) { @@ -215,8 +216,55 @@ class _HomeScreenState extends State { ); } + // Widget _menuButton(String label, Widget icon) { + // return Expanded( + // child: Column( + // children: [ + // IconButton( + // // icon: Icon(icon, color: Color.fromARGB(255, 179, 161, 170)), + // icon: icon, + // onPressed: () {}, + // ), + // Text( + // label, + // style: TextStyle( + // color: Color.fromARGB(255, 239, 224, 232), + // fontWeight: FontWeight.bold, + // ), + // ), + // ], + // ), + // ); + // } + + // Widget _scanButton() { + // return Expanded( + // child: Container( + // decoration: BoxDecoration(shape: BoxShape.circle, color: transparent), + // padding: EdgeInsets.all(10), + // child: IconButton( + // icon: SvgPicture.asset( + // 'icons/Scan.svg', + // width: 60, + // height: 60, + // colorFilter: ColorFilter.mode(Color(0xFFFFFFFF), BlendMode.srcIn), + // ), + // onPressed: () {}, + // ), + // ), + // ); + // } + Widget setHomeImage(String src, double size) { - return Image.asset(src, width: size); + return Image.asset("assets/" + src, width: size); + } + + void onUnityCreated(controller) { + _unityWidgetController = controller; + } + + void onUnityMessage(message) { + print('Received message from unity: ${message.toString()}'); } } diff --git a/lib/screen/pustaka_screen copy 2.dart b/lib/screen/pustaka_screen copy 2.dart index a41f270..db63090 100644 --- a/lib/screen/pustaka_screen copy 2.dart +++ b/lib/screen/pustaka_screen copy 2.dart @@ -108,7 +108,7 @@ class _PustakaScreenState extends State { children: [ CollectionContainer( label: "Luffy", - imagesrc: 'images/luffy.png', + imagesrc: 'assets/images/luffy.png', width: 100, height: 100, onTapAc: diff --git a/lib/screen/pustaka_screen copy.dart b/lib/screen/pustaka_screen copy.dart index a41f270..db63090 100644 --- a/lib/screen/pustaka_screen copy.dart +++ b/lib/screen/pustaka_screen copy.dart @@ -108,7 +108,7 @@ class _PustakaScreenState extends State { children: [ CollectionContainer( label: "Luffy", - imagesrc: 'images/luffy.png', + imagesrc: 'assets/images/luffy.png', width: 100, height: 100, onTapAc: diff --git a/lib/screen/pustaka_screen.dart b/lib/screen/pustaka_screen.dart index b33d1b5..cd2a69e 100644 --- a/lib/screen/pustaka_screen.dart +++ b/lib/screen/pustaka_screen.dart @@ -159,7 +159,7 @@ class _PustakaScreenState extends State { ), decoration: const InputDecoration( border: InputBorder.none, - hintText: 'Search...', + hintText: 'Cari konten...', hintStyle: TextStyle(color: Colors.grey), ), ), @@ -188,6 +188,7 @@ class _PustakaScreenState extends State { final item = filteredCollections[index]; return CollectionContainer( label: item["label"]!, + lblSize: 11, imageSvg: item["image"]!, width: 30, height: 80, @@ -267,9 +268,10 @@ class _PustakaScreenState extends State { color: Colors.blueAccent, ), Text( - 'Topic ${index + 1}', + 'Topik ${index + 1}', style: const TextStyle( fontWeight: FontWeight.bold, + fontSize: 11, color: Color.fromARGB(255, 0, 0, 0), ), ), diff --git a/lib/screen/saya/akun_saya copy.dart b/lib/screen/saya/akun_saya copy.dart new file mode 100644 index 0000000..95388a0 --- /dev/null +++ b/lib/screen/saya/akun_saya copy.dart @@ -0,0 +1,211 @@ +import 'dart:typed_data'; + +import 'package:flutter/material.dart'; +import 'package:furibase/components/bottom_navbar.dart'; +import 'package:furibase/components/main_menu.dart'; +import 'package:furibase/components/scan_button.dart'; +import 'package:furibase/helpers/pick_image.dart'; +import 'package:flutter/foundation.dart' show kIsWeb; + +class AkunSaya extends StatefulWidget { + @override + _AkunSayaState createState() => _AkunSayaState(); +} + +class _AkunSayaState extends State { + dynamic _profileImage; + dynamic _headerImage; + //final ImagePicker _picker = ImagePicker(); + + Future _pickImage(bool isProfile) async { + final imagePicker = ImagePickerHelper(); + dynamic pic = await imagePicker.pickImage(); + + if (pic != null) { + setState(() { + if (isProfile) { + _profileImage = pic; + } else { + _headerImage = pic; + } + }); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text("Saya"), + backgroundColor: Color.fromARGB(225, 79, 76, 182), + ), + backgroundColor: const Color.fromARGB(255, 255, 255, 255), + body: Stack( + children: [ + Positioned( + bottom: 0, + left: 0, + right: 0, + child: Padding( + padding: const EdgeInsets.only(top: 20.0, left: 20, right: 20), + child: Container( + height: MediaQuery.of(context).size.height * 0.7, + width: MediaQuery.of(context).size.width, + decoration: BoxDecoration( + color: const Color.fromARGB(255, 205, 202, 189), + borderRadius: BorderRadius.only( + topLeft: Radius.circular(20), + topRight: Radius.circular(20), + ), + ), + ), + ), + ), + Column( + children: [ + // Header image (bisa diubah) + SizedBox( + height: 80, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(40), + bottomRight: Radius.circular(40), + ), + color: Color.fromARGB(225, 79, 76, 182), + ), + ), + ), + SizedBox(height: 40), + Expanded( + child: Padding( + padding: EdgeInsets.all(20), + child: ListView( + padding: EdgeInsets.symmetric(horizontal: 20, vertical: 40), + children: [ + TextFormField( + initialValue: "Cepot", + decoration: const InputDecoration( + border: UnderlineInputBorder(), + labelText: 'Nama', + labelStyle: TextStyle(color: Colors.black), + ), + style: TextStyle(color: Colors.black), + ), + TextFormField( + initialValue: "cpt09", + decoration: const InputDecoration( + border: UnderlineInputBorder(), + labelText: 'Nama Pengguna', + labelStyle: TextStyle(color: Colors.black), + ), + style: TextStyle(color: Colors.black), + ), + + TextFormField( + initialValue: "Jl. Sentosa jaya", + decoration: const InputDecoration( + border: UnderlineInputBorder(), + labelText: 'Alamat', + labelStyle: TextStyle(color: Colors.black), + ), + style: TextStyle(color: Colors.black), + ), + + TextFormField( + initialValue: "******", + decoration: const InputDecoration( + border: UnderlineInputBorder(), + labelText: 'Kata Sandi', + labelStyle: TextStyle(color: Colors.black), + ), + style: TextStyle(color: Colors.black), + ), + TextFormField( + initialValue: "+62923", + decoration: const InputDecoration( + border: UnderlineInputBorder(), + labelText: 'No. HP', + labelStyle: TextStyle(color: Colors.black), + ), + style: TextStyle(color: Colors.black), + ), + ], + ), + ), + ), + ], + ), + // Profile Picture (bisa diubah) + Positioned( + top: 25, + left: MediaQuery.of(context).size.width / 2 - 50, + child: GestureDetector( + onTap: () => _pickImage(true), + child: Stack( + alignment: Alignment.bottomRight, + children: [ + CircleAvatar( + radius: 50, + backgroundColor: Colors.grey[300], + backgroundImage: + _profileImage != null + ? (kIsWeb + ? MemoryImage(_profileImage) as ImageProvider + : FileImage(_profileImage) as ImageProvider) + : null, + child: + _profileImage == null + ? Icon(Icons.person, size: 50, color: Colors.white) + : null, + ), + CircleAvatar( + radius: 15, + backgroundColor: Colors.blue, + child: Icon(Icons.edit, color: Colors.white, size: 15), + ), + ], + ), + ), + ), + + Positioned( + top: 130, + left: MediaQuery.of(context).size.width / 2 - 50, + child: GestureDetector( + onTap: () => _pickImage(true), + child: Stack( + alignment: Alignment.bottomRight, + children: [ + Text( + "Nama Akun", + style: TextStyle( + color: Colors.deepPurple, + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + ), + ], + ), + ); + } + + Widget _buildListItem(IconData icon, String label, {bool isLogout = false}) { + return ListTile( + leading: Icon( + icon, + color: + isLogout + ? const Color.fromARGB(255, 181, 47, 47) + : const Color.fromARGB(255, 255, 255, 255), + ), + title: Text(label, style: TextStyle(fontSize: 16, color: Colors.black)), + trailing: Icon(Icons.arrow_forward_ios, size: 16), + onTap: () {}, + ); + } +} diff --git a/lib/screen/saya/akun_saya.dart b/lib/screen/saya/akun_saya.dart index 9b414fc..d16bfa9 100644 --- a/lib/screen/saya/akun_saya.dart +++ b/lib/screen/saya/akun_saya.dart @@ -7,7 +7,6 @@ import 'package:freekake/components/scan_button.dart'; import 'package:image_picker/image_picker.dart'; import 'dart:io'; -// import 'package:image_picker_web/image_picker_web.dart'; import 'package:flutter/foundation.dart' show kIsWeb; class AkunSaya extends StatefulWidget { diff --git a/lib/screen/saya/profile_screen.dart b/lib/screen/saya/profile_screen.dart index 8d659a6..98a2eca 100644 --- a/lib/screen/saya/profile_screen.dart +++ b/lib/screen/saya/profile_screen.dart @@ -12,7 +12,6 @@ import 'package:freekake/screen/saya/point_saya.dart'; import 'package:image_picker/image_picker.dart'; import 'dart:io'; -// import 'package:image_picker_web/image_picker_web.dart'; import 'package:flutter/foundation.dart' show kIsWeb; class ProfileScreen extends StatefulWidget { diff --git a/pubspec.yaml b/pubspec.yaml index 2fd55a3..309b8c8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -59,6 +59,11 @@ dependencies: # arcore_flutter_plugin: # git: # url: https://github.com/giandifra/arcore_flutter_plugin.git + flutter_unity_widget: ^2022.2.1 + # flutter_unity_widget: + # git: + # url: https://github.com/juicycleff/flutter-unity-view-widget.git + # ref: flutter_3.24_android_hotfix dev_dependencies: flutter_test: