Compare commits

..

97 Commits

Author SHA1 Message Date
c7105d6110 Merge branch 'unity_embed' of https://git.probindo.com/Probindo/FreekakeApp into unity_embed 2025-05-10 23:14:31 +07:00
e15bfc0bef gradle config 2025-05-10 23:14:18 +07:00
442e56294f pubspec 2025-05-10 23:14:18 +07:00
2b7778b152 sebelum unity 2025-05-10 23:14:18 +07:00
d9b5e53e18 pubspec.lock 2025-05-10 23:11:03 +07:00
740f137913 mobile 2025-05-10 23:10:12 +07:00
89dbf1a900 mobile 2025-05-10 22:49:55 +07:00
9899809c18 config gradle unity 2025-05-10 22:38:40 +07:00
4040e8f91a mobile 2025-05-10 22:38:40 +07:00
fe2d68e786 mobile 2025-05-10 22:38:06 +07:00
f7ed9f5035 pubspec.lock 2025-05-10 22:37:32 +07:00
7cea1ea4c5 mobile 2025-05-10 22:36:22 +07:00
501d417b95 mobile 2025-05-10 22:33:16 +07:00
db213c151c config gradle unity 2025-05-10 22:24:42 +07:00
72aa4f9dfe mobile 2025-05-10 22:24:42 +07:00
7946df58d8 mobile 2025-05-10 22:24:22 +07:00
c08aeb999c mobile 2025-05-10 22:17:35 +07:00
206f99b561 main 2025-05-10 22:08:29 +07:00
e7945b1074 updated 2025-05-10 22:08:29 +07:00
dbafded5d2 mobile 2025-05-10 22:08:29 +07:00
fe66f466a2 mobile 2025-05-10 22:08:29 +07:00
06fe0bdd7e config gradle unity 2025-05-10 22:08:29 +07:00
00749179f6 mobile 2025-05-10 22:08:29 +07:00
15e85fc0dd mobile 2025-05-10 22:08:29 +07:00
52df106632 mobile 2025-05-10 22:08:29 +07:00
da4f3f9243 pubspec 2025-05-10 22:08:29 +07:00
5f8305289c updated 2025-05-10 22:08:29 +07:00
ecdad52570 Update README.md 2025-05-10 22:04:54 +07:00
1bd2a67868 Update README.md 2025-05-10 22:04:54 +07:00
fa47208e4e config gradle unity 2025-05-10 22:04:54 +07:00
41e0248b67 mobile 2025-05-10 22:04:54 +07:00
b330c207b7 mobile 2025-05-10 22:04:54 +07:00
17e955e3a9 pubspec.lock 2025-05-10 22:04:54 +07:00
ce76938284 gitignore dan beberapa yang terlewat 2025-05-10 22:04:54 +07:00
316d1937b4 config gradle unity 2025-05-10 22:04:54 +07:00
85a2655457 mobile 2025-05-10 22:04:54 +07:00
d2d45ad685 gradle config 2025-05-09 02:00:18 +07:00
86b1f67dda pubspec 2025-05-09 01:59:25 +07:00
0e985f5453 sebelum unity 2025-05-09 01:42:10 +07:00
2a4f8fc335 Merge branch 'unity_embed' of https://git.probindo.com/Probindo/FreekakeApp into unity_embed 2025-05-08 21:41:45 +07:00
efcfb609d5 main 2025-05-08 20:09:55 +07:00
dba0e9d6cd updated 2025-05-08 20:09:55 +07:00
93d15dd59f mobile 2025-05-08 20:08:04 +07:00
0a8ef32fe4 mobile 2025-05-08 20:03:07 +07:00
0b54a5126d config gradle unity 2025-05-08 19:57:44 +07:00
927f805484 mobile 2025-05-08 19:57:18 +07:00
5230d7dcca mobile 2025-05-08 19:53:37 +07:00
d05d5242db mobile 2025-05-08 19:52:38 +07:00
aa2d7a0194 pubspec 2025-05-08 19:45:50 +07:00
340a66bfb2 updated 2025-05-08 19:45:38 +07:00
467470ce90 Update README.md 2025-05-08 19:42:03 +07:00
3f37619744 Update README.md 2025-05-08 19:42:03 +07:00
f57088b04a config gradle unity 2025-05-08 19:42:03 +07:00
278750083e mobile 2025-05-08 19:42:03 +07:00
854efa1986 mobile 2025-05-08 19:41:44 +07:00
af92616ef7 pubspec.lock 2025-05-08 19:40:46 +07:00
fa9c15f7c8 gitignore dan beberapa yang terlewat 2025-05-08 19:40:46 +07:00
ad3591b042 config gradle unity 2025-05-08 19:40:46 +07:00
c6bcf88caf mobile 2025-05-08 19:37:25 +07:00
4e19c82046 main 2025-05-08 19:22:44 +07:00
0e52ced016 Merge branch 'unity_embed' of https://git.probindo.com/Probindo/FreekakeApp into unity_embed 2025-05-07 13:39:04 +07:00
3ffa70486e pubspec 2025-05-07 13:34:39 +07:00
e6b81acaf3 updated 2025-05-07 13:34:13 +07:00
4fb5cbd567 mobile 2025-05-07 13:28:40 +07:00
8013646d0d mobile 2025-05-07 13:20:46 +07:00
66d72b9b1d Update README.md 2025-05-07 13:18:42 +07:00
17bfc6faee Update README.md 2025-05-07 13:18:42 +07:00
967cd86849 config gradle unity 2025-05-07 13:18:42 +07:00
9ae836b2a1 mobile 2025-05-07 13:18:42 +07:00
8b55983dd6 mobile 2025-05-07 13:17:44 +07:00
ffb4c5876c pubspec.lock 2025-05-07 13:17:44 +07:00
ff68b8b145 gitignore dan beberapa yang terlewat 2025-05-07 13:15:34 +07:00
e15bba626d config gradle unity 2025-05-07 13:15:34 +07:00
42642c2ef3 mobile 2025-05-07 13:15:34 +07:00
35860df873 mobile 2025-05-07 13:15:34 +07:00
47b3e2e15d pubspec 2025-05-07 13:05:40 +07:00
c4c6097828 updated 2025-05-07 13:05:21 +07:00
1fdcc3773d Merge branch 'unity_embed' of https://git.probindo.com/Probindo/FreekakeApp into unity_embed 2025-05-06 23:15:05 +07:00
2e489a97a4 Update README.md 2025-05-06 23:08:40 +07:00
aa06f86854 Update README.md 2025-05-06 23:08:40 +07:00
13e99257b8 config gradle unity 2025-05-06 23:08:12 +07:00
6dbb7f4ca9 mobile 2025-05-06 23:08:12 +07:00
b0d343e6fc mobile 2025-05-06 22:57:59 +07:00
bab3893f8a Merge branch 'unity_embed' of https://git.probindo.com/Probindo/FreekakeApp into unity_embed 2025-05-06 22:39:54 +07:00
e055ef5484 Update README.md 2025-05-06 15:30:47 +00:00
39514dc0f6 Update README.md 2025-04-16 09:02:15 +00:00
0564cab301 pubspec.lock 2025-04-16 08:55:05 +07:00
b5943099ff gitignore dan beberapa yang terlewat 2025-04-16 08:55:05 +07:00
929f2ce729 config gradle unity 2025-04-16 08:54:05 +07:00
75210e29bc mobile 2025-04-16 08:54:05 +07:00
cb1c0a8e05 mobile 2025-04-16 08:45:45 +07:00
0fb3e74cf7 pubspec.lock 2025-04-16 08:33:12 +07:00
26a3940365 gitignore dan beberapa yang terlewat 2025-04-16 08:12:45 +07:00
724b6d47e3 config gradle unity 2025-04-16 08:05:14 +07:00
a858d66653 Merge branch 'unity_embed' of https://git.probindo.com/Probindo/FreekakeApp into unity_embed 2025-04-15 10:14:16 +07:00
6348f74b95 mobile 2025-04-15 09:58:28 +07:00
bf9a57f23b mobile 2025-04-11 13:09:55 +07:00
72 changed files with 1215 additions and 1255 deletions

10
.gitignore vendored
View File

@ -43,4 +43,12 @@ app.*.map.json
/android/app/debug
/android/app/profile
/android/app/release
pubspec.lock
# Place unity project here
/unity
# flutter will place unity Library dependency here
/unityLibrary
# unityLibrary will place build here
/android/unityLibrary

243
README.md
View File

@ -1,16 +1,239 @@
# furibase
# Furikake App
A new Flutter project.
Project ini adalah aplikasi mobile Furikake.
## Getting Started
## Konfiguras dan perubahan android app
This project is a starting point for a Flutter application.
Edit android/app/src/main/kotlin ... /MainActivity.kt
A few resources to get you started if this is your first Flutter project:
```
package com.paj.freekake
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.android.FlutterFragmentActivity;
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
//class MainActivity : FlutterActivity()
class MainActivity: FlutterFragmentActivity() {
}
```
Gunakan konfigurasi ini pada file android/settings.gradle.kts
```
pluginManagement {
val flutterSdkPath = run {
val properties = java.util.Properties()
file("local.properties").inputStream().use { properties.load(it) }
val flutterSdkPath = properties.getProperty("flutter.sdk")
require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
flutterSdkPath
}
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
plugins {
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
id("com.android.application") version "8.9.0" apply false
id("org.jetbrains.kotlin.android") version "1.8.22" apply false
}
include(":app")
include(":unityLibrary")
project(":unityLibrary").projectDir = file("./unityLibrary")
include(":unityLibrary:xrmanifest.androidlib")
//project(":unityLibrary:xrmanifest.androidlib").projectDir = file("unityLibrary/xrmanifest.androidlib")
//include(":unityLibrary:mobilenotifications.androidlib")
//project(":unityLibrary:mobilenotifications.androidlib").projectDir = file("unityLibrary/mobilenotifications.androidlib")
```
Gunakan konfigurasi ini pada android/app/build.gradle.kts
```
plugins {
id("com.android.application")
id("kotlin-android")
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id("dev.flutter.flutter-gradle-plugin")
}
android {
namespace = "com.paj.freekake"
//compileSdk = flutter.compileSdkVersion
compileSdk = 35
//ndkVersion = "27.0.12077973"
//ndkVersion = flutter.ndkVersion
ndkVersion = "23.1.7779620"
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_17.toString()
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "com.paj.freekake"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
//minSdk = flutter.minSdkVersion
//targetSdk = flutter.targetSdkVersion
//minSdk = 24 // Set to 24 or higher
minSdk = 30
targetSdk = 35
versionCode = flutter.versionCode
versionName = flutter.versionName
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig = signingConfigs.getByName("debug")
}
}
}
flutter {
source = "../.."
}
dependencies {
implementation(project(":unityLibrary"))
implementation(project(":flutter_unity_widget"))
}
```
## Konfigurasi UnityLibrary
Gunakan konfigurasi ini pada file android/unityLibrary/build.gradle:
```
apply plugin: 'com.android.library'
dependencies {
implementation(name: 'unity-classes', ext:'jar')
implementation(name: 'arcore_client', ext:'aar')
implementation(name: 'ARPresto', ext:'aar')
implementation(name: 'UnityARCore', ext:'aar')
implementation(name: 'unityandroidpermissions', ext:'aar')
implementation project('xrmanifest.androidlib')
//implementation project('mobilenotifications.androidlib')
}
android {
namespace "com.unity3d.player"
// ndkPath "/Applications/Unity/Hub/Editor/2022.3.60f1/PlaybackEngines/AndroidPlayer/NDK"
compileSdkVersion 35
buildToolsVersion '34.0.0'
ndkVersion "23.1.7779620"
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
defaultConfig {
minSdkVersion 30
targetSdkVersion 35
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
versionCode 1
versionName '1.0.2'
consumerProguardFiles 'proguard-unity.txt'
}
lintOptions {
abortOnError false
}
aaptOptions {
noCompress = ['.unity3d', '.ress', '.resource', '.obb', '.bundle', '.unityexp']
ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:!CVS:!thumbs.db:!picasa.ini:!*~"
}
packagingOptions {
doNotStrip '*/armeabi-v7a/*.so'
doNotStrip '*/arm64-v8a/*.so'
jniLibs {
useLegacyPackaging true
}
}
}
def getSdkDir() {
Properties local = new Properties()
local.load(new FileInputStream("${rootDir}/local.properties"))
return local.getProperty('sdk.dir')
}
def BuildIl2Cpp(String workingDir, String configuration, String architecture, String abi, String[] staticLibraries) {
def commandLineArgs = []
commandLineArgs.add("--compile-cpp")
commandLineArgs.add("--platform=Android")
commandLineArgs.add("--architecture=" + architecture)
commandLineArgs.add("--outputpath=" + workingDir + "/src/main/jniLibs/" + abi + "/libil2cpp.so")
commandLineArgs.add("--baselib-directory=" + workingDir + "/src/main/jniStaticLibs/" + abi)
commandLineArgs.add("--incremental-g-c-time-slice=3")
commandLineArgs.add("--dotnetprofile=unityaot-linux")
commandLineArgs.add("--enable-debugger")
commandLineArgs.add("--profiler-report")
commandLineArgs.add("--profiler-output-file=" + workingDir + "/build/il2cpp_"+ abi + "_" + configuration + "/il2cpp_conv.traceevents")
commandLineArgs.add("--print-command-line")
commandLineArgs.add("--data-folder=" + workingDir + "/src/main/Il2CppOutputProject/Source/il2cppOutput/data")
commandLineArgs.add("--generatedcppdir=" + workingDir + "/src/main/Il2CppOutputProject/Source/il2cppOutput")
commandLineArgs.add("--cachedirectory=" + workingDir + "/build/il2cpp_"+ abi + "_" + configuration + "/il2cpp_cache")
commandLineArgs.add("--tool-chain-path=" + android.ndkDirectory)
staticLibraries.eachWithIndex {fileName, i->
commandLineArgs.add("--additional-libraries=" + workingDir + "/src/main/jniStaticLibs/" + abi + "/" + fileName)
}
def executableExtension = ""
if (org.gradle.internal.os.OperatingSystem.current().isWindows()) {
executableExtension = ".exe"
commandLineArgs = commandLineArgs*.replace('\"', '\\\"')
}
exec {
executable workingDir + "/src/main/Il2CppOutputProject/IL2CPP/build/deploy/il2cpp" + executableExtension
args commandLineArgs
environment "ANDROID_SDK_ROOT", getSdkDir()
}
delete workingDir + "/src/main/jniLibs/" + abi + "/libil2cpp.sym.so"
ant.move(file: workingDir + "/src/main/jniLibs/" + abi + "/libil2cpp.dbg.so", tofile: workingDir + "/symbols/" + abi + "/libil2cpp.so")
}
android {
task BuildIl2CppTask {
doLast {
BuildIl2Cpp(projectDir.toString().replaceAll('\\\\', '/'), 'Debug', 'armv7', 'armeabi-v7a', [ ] as String[]);
BuildIl2Cpp(projectDir.toString().replaceAll('\\\\', '/'), 'Debug', 'arm64', 'arm64-v8a', [ ] as String[]);
}
}
afterEvaluate {
if (project(':unityLibrary').tasks.findByName('mergeDebugJniLibFolders'))
project(':unityLibrary').mergeDebugJniLibFolders.dependsOn BuildIl2CppTask
if (project(':unityLibrary').tasks.findByName('mergeReleaseJniLibFolders'))
project(':unityLibrary').mergeReleaseJniLibFolders.dependsOn BuildIl2CppTask
}
sourceSets {
main {
jni.srcDirs = ["src/main/Il2CppOutputProject"]
}
}
}
```

View File

@ -6,29 +6,31 @@ plugins {
}
android {
namespace = "com.example.furibase"
namespace = "com.paj.freekake"
//compileSdk = flutter.compileSdkVersion
compileSdk = 35
ndkVersion = "27.0.12077973"
//ndkVersion = "27.0.12077973"
//ndkVersion = flutter.ndkVersion
ndkVersion = "23.1.7779620"
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_11.toString()
jvmTarget = JavaVersion.VERSION_17.toString()
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "com.example.furibase"
applicationId = "com.paj.freekake"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
//minSdk = flutter.minSdkVersion
//targetSdk = flutter.targetSdkVersion
minSdk = 24 // Set to 24 or higher
//minSdk = 24 // Set to 24 or higher
minSdk = 30
targetSdk = 35
versionCode = flutter.versionCode
versionName = flutter.versionName
@ -50,3 +52,8 @@ android {
flutter {
source = "../.."
}
dependencies {
implementation(project(":unityLibrary"))
implementation(project(":flutter_unity_widget"))
}

View File

@ -1,9 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:label="furibase"
android:label="freekake"
android:name="${applicationName}"
android:usesCleartextTraffic="true"
android:networkSecurityConfig="@xml/network_security_config"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"

View File

@ -1,5 +0,0 @@
package com.example.furibase
import io.flutter.embedding.android.FlutterActivity
class MainActivity : FlutterActivity()

View File

@ -0,0 +1,8 @@
package com.paj.freekake
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.android.FlutterFragmentActivity;
//class MainActivity : FlutterActivity()
class MainActivity: FlutterFragmentActivity() {
}

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true"/>
</network-security-config>

View File

@ -1,5 +1,11 @@
allprojects {
repositories {
flatDir {
dirs(
file("${project(":unityLibrary").projectDir}/libs")
)
}
google()
mavenCentral()
}
@ -12,6 +18,39 @@ subprojects {
val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
project.layout.buildDirectory.value(newSubprojectBuildDir)
}
subprojects {
afterEvaluate {
if (project.extensions.findByName("android") != null) {
extensions.configure<com.android.build.gradle.BaseExtension>("android") {
if (namespace == null) {
namespace = project.group.toString()
}
}
}
if (plugins.hasPlugin("com.android.application") || plugins.hasPlugin("com.android.library")) {
if (name == "flutter_unity_widget") {
extensions.configure<com.android.build.gradle.BaseExtension>("android") {
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
(this as ExtensionAware).extensions.configure<org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions>("kotlinOptions") {
jvmTarget = "17"
}
if (namespace == null) {
namespace = project.group.toString()
}
compileSdkVersion(35)
}
}
}
}
}
subprojects {
project.evaluationDependsOn(":app")
}

View File

@ -1,3 +1,4 @@
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
# org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError
android.useAndroidX=true
android.enableJetifier=true

View File

@ -1,5 +1,6 @@
#Thu May 08 22:45:23 WIB 2025
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip

View File

@ -18,8 +18,30 @@ pluginManagement {
plugins {
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
id("com.android.application") version "8.7.0" apply false
id("com.android.application") version "8.9.0" apply false
id("org.jetbrains.kotlin.android") version "1.8.22" apply false
}
include(":app")
include(":unityLibrary")
project(":unityLibrary").projectDir = file("./unityLibrary")
include(":unityLibrary:xrmanifest.androidlib")
// project(":unityLibrary:xrmanifest.androidlib").projectDir = file("unityLibrary/xrmanifest.androidlib")
// include(":unityLibrary:mobilenotifications.androidlib")
// project(":unityLibrary:mobilenotifications.androidlib").projectDir = file("unityLibrary/mobilenotifications.androidlib")
include(":unityLibrary")
project(":unityLibrary").projectDir = file("./unityLibrary")
include(":unityLibrary")
project(":unityLibrary").projectDir = file("./unityLibrary")
include(":unityLibrary")
project(":unityLibrary").projectDir = file("./unityLibrary")

View File

@ -0,0 +1,117 @@
apply plugin: 'com.android.library'
dependencies {
implementation(name: 'unity-classes', ext:'jar')
implementation(name: 'arcore_client', ext:'aar')
implementation(name: 'ARPresto', ext:'aar')
implementation(name: 'UnityARCore', ext:'aar')
implementation(name: 'unityandroidpermissions', ext:'aar')
implementation project('xrmanifest.androidlib')
//implementation project('mobilenotifications.androidlib')
}
android {
namespace "com.unity3d.player"
// ndkPath "/Applications/Unity/Hub/Editor/2022.3.60f1/PlaybackEngines/AndroidPlayer/NDK"
compileSdkVersion 35
buildToolsVersion '34.0.0'
ndkVersion "23.1.7779620"
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
defaultConfig {
minSdkVersion 30
targetSdkVersion 35
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
versionCode 1
versionName '1.0.2'
consumerProguardFiles 'proguard-unity.txt'
}
lintOptions {
abortOnError false
}
aaptOptions {
noCompress = ['.unity3d', '.ress', '.resource', '.obb', '.bundle', '.unityexp']
ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:!CVS:!thumbs.db:!picasa.ini:!*~"
}
packagingOptions {
doNotStrip '*/armeabi-v7a/*.so'
doNotStrip '*/arm64-v8a/*.so'
jniLibs {
useLegacyPackaging true
}
}
}
def getSdkDir() {
Properties local = new Properties()
local.load(new FileInputStream("${rootDir}/local.properties"))
return local.getProperty('sdk.dir')
}
def BuildIl2Cpp(String workingDir, String configuration, String architecture, String abi, String[] staticLibraries) {
def commandLineArgs = []
commandLineArgs.add("--compile-cpp")
commandLineArgs.add("--platform=Android")
commandLineArgs.add("--architecture=" + architecture)
commandLineArgs.add("--outputpath=" + workingDir + "/src/main/jniLibs/" + abi + "/libil2cpp.so")
commandLineArgs.add("--baselib-directory=" + workingDir + "/src/main/jniStaticLibs/" + abi)
commandLineArgs.add("--incremental-g-c-time-slice=3")
commandLineArgs.add("--dotnetprofile=unityaot-linux")
commandLineArgs.add("--enable-debugger")
commandLineArgs.add("--profiler-report")
commandLineArgs.add("--profiler-output-file=" + workingDir + "/build/il2cpp_"+ abi + "_" + configuration + "/il2cpp_conv.traceevents")
commandLineArgs.add("--print-command-line")
commandLineArgs.add("--data-folder=" + workingDir + "/src/main/Il2CppOutputProject/Source/il2cppOutput/data")
commandLineArgs.add("--generatedcppdir=" + workingDir + "/src/main/Il2CppOutputProject/Source/il2cppOutput")
commandLineArgs.add("--cachedirectory=" + workingDir + "/build/il2cpp_"+ abi + "_" + configuration + "/il2cpp_cache")
commandLineArgs.add("--tool-chain-path=" + android.ndkDirectory)
staticLibraries.eachWithIndex {fileName, i->
commandLineArgs.add("--additional-libraries=" + workingDir + "/src/main/jniStaticLibs/" + abi + "/" + fileName)
}
def executableExtension = ""
if (org.gradle.internal.os.OperatingSystem.current().isWindows()) {
executableExtension = ".exe"
commandLineArgs = commandLineArgs*.replace('\"', '\\\"')
}
exec {
executable workingDir + "/src/main/Il2CppOutputProject/IL2CPP/build/deploy/il2cpp" + executableExtension
args commandLineArgs
environment "ANDROID_SDK_ROOT", getSdkDir()
}
delete workingDir + "/src/main/jniLibs/" + abi + "/libil2cpp.sym.so"
ant.move(file: workingDir + "/src/main/jniLibs/" + abi + "/libil2cpp.dbg.so", tofile: workingDir + "/symbols/" + abi + "/libil2cpp.so")
}
android {
task BuildIl2CppTask {
doLast {
BuildIl2Cpp(projectDir.toString().replaceAll('\\\\', '/'), 'Debug', 'armv7', 'armeabi-v7a', [ ] as String[]);
BuildIl2Cpp(projectDir.toString().replaceAll('\\\\', '/'), 'Debug', 'arm64', 'arm64-v8a', [ ] as String[]);
}
}
afterEvaluate {
if (project(':unityLibrary').tasks.findByName('mergeDebugJniLibFolders'))
project(':unityLibrary').mergeDebugJniLibFolders.dependsOn BuildIl2CppTask
if (project(':unityLibrary').tasks.findByName('mergeReleaseJniLibFolders'))
project(':unityLibrary').mergeReleaseJniLibFolders.dependsOn BuildIl2CppTask
}
sourceSets {
main {
jni.srcDirs = ["src/main/Il2CppOutputProject"]
}
}
}

View File

@ -1,180 +0,0 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Game Nusantara</title>
<style>
body {
font-family: sans-serif;
margin: 0;
background: #f2f2f2;
}
.container {
max-width: 480px;
margin: auto;
padding: 1rem;
}
h1 {
text-align: center;
font-size: 1.4rem;
}
.grid {
display: grid;
gap: 4px;
margin-top: 1rem;
}
.letter {
background: white;
border-radius: 6px;
padding: 0;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
display: flex;
justify-content: center;
align-items: center;
font-size: 1rem;
font-weight: bold;
text-align: center;
user-select: none;
cursor: pointer;
border: 1px solid #ccc;
aspect-ratio: 1/1;
}
.found {
background-color: #a2f5a2 !important;
}
</style>
</head>
<body>
<div class="container">
<h1 id="game-title">Game Nusantara</h1>
<div id="game-board"></div>
<h3>Kata yang harus ditemukan:</h3>
<ul id="target-words" style="padding-left: 1rem;"></ul>
<p id="penjelasan" style="margin-top: 1rem; font-size: 0.9rem; color: #444;"></p>
</div>
<script>
// Template Find The Word Game (drag to select)
const words = ['TENANG', 'SABAR', 'SYUKUR', 'CINTA', 'GEMBIRA', 'BANGGA'];
const board = document.getElementById('game-board');
const size = 12; // 12x12 grid
let grid = Array(size * size).fill('');
function randomLetter() {
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
return alphabet[Math.floor(Math.random() * alphabet.length)];
}
function placeWord(word) {
const dir = Math.random() < 0.5 ? 'H' : 'V';
let x, y, success = false;
while (!success) {
x = Math.floor(Math.random() * (dir === 'H' ? size - word.length : size));
y = Math.floor(Math.random() * (dir === 'V' ? size - word.length : size));
let fits = true;
for (let i = 0; i < word.length; i++) {
let idx = dir === 'H' ? y * size + (x + i) : (y + i) * size + x;
if (grid[idx] && grid[idx] !== word[i]) {
fits = false;
break;
}
}
if (fits) {
for (let i = 0; i < word.length; i++) {
let idx = dir === 'H' ? y * size + (x + i) : (y + i) * size + x;
grid[idx] = word[i];
}
success = true;
}
}
}
words.forEach(w => placeWord(w));
grid = grid.map(cell => cell || randomLetter());
function renderGrid() {
board.className = 'grid';
board.style.gridTemplateColumns = `repeat(${size}, 1fr)`;
board.innerHTML = '';
grid.forEach((char, i) => {
const div = document.createElement('div');
div.textContent = char;
div.className = 'letter';
div.dataset.index = i;
div.style.aspectRatio = '1/1';
div.style.border = '1px solid #ccc';
div.style.display = 'flex';
div.style.alignItems = 'center';
div.style.justifyContent = 'center';
div.style.fontSize = '1.2rem';
div.style.fontWeight = 'bold';
div.style.userSelect = 'none';
div.style.cursor = 'pointer';
board.appendChild(div);
});
}
renderGrid();
// Daftar kata yang harus ditemukan
// (Daftar kata tidak lagi ditampilkan sebagai list)
let currentSelection = [];
let currentWord = '';
let wordsFound = new Set();
let isMouseDown = false;
board.addEventListener('mousedown', (e) => {
if (!e.target.classList.contains('letter')) return;
isMouseDown = true;
selectCell(e.target);
});
board.addEventListener('mouseover', (e) => {
if (!isMouseDown || !e.target.classList.contains('letter')) return;
selectCell(e.target);
});
document.addEventListener('mouseup', () => {
if (words.includes(currentWord)) {
currentSelection.forEach(c => {
c.style.backgroundColor = '#a2f5a2';
c.classList.add('found');
});
const penjelasanBox = document.getElementById('penjelasan');
const regex = new RegExp(currentWord, 'gi');
penjelasanBox.innerHTML = penjelasanBox.innerHTML.replace(regex, `<span style="color:green; font-weight:bold">${currentWord}</span>`);
wordsFound.add(currentWord);
if (wordsFound.size === words.length) {
alert('Selamat! Kamu telah menemukan semua kata positif. Ingat, berpikir positif setiap hari bisa membuat hidupmu lebih ceria dan penuh semangat 🌈');
}
} else {
currentSelection.forEach(c => c.style.backgroundColor = '');
}
currentSelection = [];
currentWord = '';
isMouseDown = false;
});
function selectCell(cell) {
if (cell.classList.contains('found') || currentSelection.includes(cell)) return;
cell.style.backgroundColor = '#ffeaa7';
currentSelection.push(cell);
currentWord += cell.textContent;
}
// Penjelasan pentingnya emosi positif
const penjelasan = `Di dalam hidup, kita bisa merasa banyak hal. Tapi tahukah kamu? Emosi positif seperti <strong>tenang</strong>, <strong>sabar</strong>, <strong>syukur</strong>, <strong>cinta</strong>, <strong>gembira</strong>, dan <strong>bangga</strong> adalah kunci untuk hidup yang sehat dan bahagia. Yuk, temukan kata-kata positif itu di puzzle, lalu pikirkan kapan terakhir kali kamu merasakannya!`;
document.getElementById('penjelasan').innerHTML = penjelasan;
function includeScript(file) {
const script = document.createElement('script');
script.src = file;
document.body.appendChild(script);
}
</script>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

View File

@ -1,16 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test</title>
<script>
window.onload = function() {
document.body.innerHTML += '<p style="color:green;">✅ JS is working!</p>';
};
window.onload = showAlert;
</script>
</head>
<body>
<h1>Hello WebView</h1>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

View File

@ -224,19 +224,19 @@ figcaption {
<div class="div-grid">
<div class="div-item">
<img src="nori.jpeg" alt="Nori">
<img src="assets/html/furikake/nori.jpeg" alt="Nori">
<p>Nori (Rumput Laut)</p>
</div>
<div class="div-item">
<img src="wijen.jpeg" alt="Biji Wijen">
<img src="assets/html/furikake/wijen.jpeg" alt="Biji Wijen">
<p>Biji Wijen</p>
</div>
<div class="div-item">
<img src="ikankering.jpg" alt="Katsuobushi">
<img src="assets/html/furikake/ikankering.jpg" alt="Katsuobushi">
<p>Katsuobushi (Ikan Kering)</p>
</div>
<div class="div-item">
<img src="gulagaram.jpg" alt="Garam dan Gula">
<img src="assets/html/furikake/gulagaram.jpg" alt="Garam dan Gula">
<p>Garam & Gula</p>
</div>
</div>
@ -259,7 +259,7 @@ figcaption {
</ul>
<figure>
<img src="furikake.jpg" alt="Contoh produk furikake" class="full-width-image">
<img src="assets/html/furikake/furikake.jpg" alt="Contoh produk furikake" class="full-width-image">
<figcaption>Berbagai varian produk furikake yang tersedia di pasaran</figcaption>
</figure>
</section>

View File

@ -177,23 +177,23 @@
<div class="div-grid">
<div class="div-item">
<img src="karbohidrat.png" alt="Karbohidrat" />
<img src="assets/html/karbohidrat.png" alt="Karbohidrat" />
<p><strong>Karbohidrat</strong><br>Sumber energi seperti nasi, roti, dan kentang.</p>
</div>
<div class="div-item">
<img src="protein.png" alt="Protein" />
<img src="assets/html/protein.png" alt="Protein" />
<p><strong>Protein</strong><br>Untuk membangun otot, misalnya ikan, telur, dan tahu.</p>
</div>
<div class="div-item">
<img src="lemak.png" alt="Lemak" />
<img src="assets/html/lemak.png" alt="Lemak" />
<p><strong>Lemak</strong><br>Memberikan tenaga, seperti dari kacang-kacangan dan minyak sehat.</p>
</div>
<div class="div-item">
<img src="vitaminmineral.png" alt="Vitamin dan Mineral" />
<img src="assets/html/vitaminmineral.png" alt="Vitamin dan Mineral" />
<p><strong>Vitamin dan mineral</strong><br>Dari sayur dan buah yang membantu tubuh bekerja dengan baik.</p>
</div>
<div class="div-item">
<img src="seratair.png" alt="Serat dan Air" />
<img src="assets/html/seratair.png" alt="Serat dan Air" />
<p><strong>Serat dan air</strong><br>Membantu pencernaan dan menjaga tubuh tetap segar!</p>
</div>
</div>
@ -209,7 +209,7 @@
<li>🍽️ Seperempat piring: Protein (seperti ayam atau tempe)</li>
<li>🍽️ Sedikit lemak sehat</li>
</ul>
<img src="isipiringku.png" alt="Piring Gizi Seimbang" class="full-width-image">
<img src="assets/html/isipiringku.png" alt="Piring Gizi Seimbang" class="full-width-image">
<figcaption>Isi Piringku</figcaption>
<p>Selain itu, kita tidak boleh makan terlalu banyak atau terlalu sedikit, karena bisa membuat tubuh tidak sehat. Makan berlebihan bisa menyebabkan obesitas, sedangkan makan terlalu sedikit bisa membuat tubuh lemas dan kurang gizi.</p>
</section>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

View File

@ -1,176 +0,0 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Game Nusantara</title>
<link rel="icon" href="data:,">
<style>
body {
font-family: sans-serif;
margin: 0;
background: #f2f2f2;
}
.container {
max-width: 480px;
margin: auto;
padding: 1rem;
}
h1 {
text-align: center;
font-size: 1.4rem;
}
.grid, .drag-area, .drop-area {
display: grid;
gap: 10px;
margin-top: 1rem;
}
.grid {
grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
}
.card, .letter, .drop-zone, .drag-item {
background: white;
border-radius: 6px;
padding: 10px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
display: flex;
justify-content: center;
align-items: center;
font-size: 0.8rem;
text-align: center;
user-select: none;
}
.hidden { background: #ccc; color: transparent; }
.matched { background: #d4edda; }
.drop-zone { height: 80px; background: #eee; border: 2px dashed #bbb; }
.drag-item[draggable="true"] { cursor: grab; }
</style>
</head>
<body>
<div class="container">
<h1 id="game-title">Game Nusantara</h1>
<div id="game-board"></div>
</div>
<script>
const items = [
'pempek.png', 'sumsel.png',
'sopkonro.png', 'sulsel.png',
'rendang.png', 'sumbar.png',
'tinutuan.png', 'sulut.png',
'ayambetutu.png', 'bali.png',
'bikaambon.png', 'sumut.png',
'gudeg.png', 'yogyakarta.png',
'sotobanjar.png', 'kalsel.png',
'ayamtaliwang.png', 'ntb.png'
];
const board = document.getElementById('game-board');
board.className = 'grid';
board.style.gridTemplateColumns = 'repeat(3, 1fr)';
let selectedItems = shuffle([...items]);
let shuffled = shuffle(selectedItems.slice(0, 18));
let selected = [], matched = [];
function shuffle(array) {
return array.sort(() => Math.random() - 0.5);
}
function render() {
board.innerHTML = '';
shuffled.forEach((img, i) => {
const card = document.createElement('div');
card.className = 'card hidden';
card.style.backgroundImage = 'url("../freekake.png")';
card.style.backgroundSize = 'contain';
card.style.backgroundRepeat = 'no-repeat';
card.style.backgroundPosition = 'center';
card.dataset.index = i;
card.style.aspectRatio = '1/1';
card.style.borderRadius = '12px';
card.style.overflow = 'hidden';
card.style.backgroundColor = '#fff';
card.style.display = 'flex';
card.style.flexDirection = 'column';
card.style.alignItems = 'center';
card.style.justifyContent = 'center';
card.style.padding = '8px';
card.style.boxShadow = '0 2px 4px rgba(0,0,0,0.1)';
board.appendChild(card);
});
}
function revealCard(i) {
const el = board.children[i];
el.classList.remove('hidden');
el.style.backgroundImage = 'none';
el.innerHTML = `<img src="${shuffled[i]}" alt="" style="width: 100%; height: auto; object-fit: contain;">`;
}
function hideCard(i) {
const el = board.children[i];
el.classList.add('hidden');
el.style.backgroundImage = 'url("../freekake.png")';
el.style.backgroundSize = 'contain';
el.style.backgroundRepeat = 'no-repeat';
el.style.backgroundPosition = 'center';
el.innerHTML = '';
}
function checkMatch() {
const [a, b] = selected;
const pairs = {
'pempek.png': 'sumsel.png', 'sumsel.png': 'pempek.png',
'sopkonro.png': 'sulsel.png', 'sulsel.png': 'sopkonro.png',
'rendang.png': 'sumbar.png', 'sumbar.png': 'rendang.png',
'tinutuan.png': 'sulut.png', 'sulut.png': 'tinutuan.png',
'ayambetutu.png': 'bali.png', 'bali.png': 'ayambetutu.png',
'bikaambon.png': 'sumut.png', 'sumut.png': 'bikaambon.png',
'gudeg.png': 'yogyakarta.png', 'yogyakarta.png': 'gudeg.png',
'sotobanjar.png': 'kalsel.png', 'kalsel.png': 'sotobanjar.png',
'ayamtaliwang.png': 'ntb.png', 'ntb.png': 'ayamtaliwang.png'
};
if (pairs[shuffled[a]] === shuffled[b]) {
matched.push(a, b);
board.children[a].classList.add('matched');
board.children[a].style.backgroundColor = '#d4edda';
board.children[b].classList.add('matched');
board.children[b].style.backgroundColor = '#d4edda';
} else {
setTimeout(() => {
hideCard(a);
hideCard(b);
}, 800);
}
selected = [];
}
render();
board.addEventListener('click', (e) => {
const index = e.target.closest('.card')?.dataset.index;
if (!index || selected.includes(+index) || matched.includes(+index)) return;
revealCard(index);
selected.push(+index);
if (selected.length === 2) checkMatch();
});
window.render = render;
if (window.flutter_inappwebview) {
window.flutter_inappwebview.callHandler('pageReady', {
boardExists: !!document.getElementById("game-board"),
hasRender: typeof render === "function"
});
}
// Optional helper
function includeScript(file) {
const script = document.createElement('script');
script.src = file;
document.body.appendChild(script);
}
</script>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

View File

@ -1,5 +1,9 @@
import 'package:freekake/components/navbar_shape_3.dart';
import 'package:flutter/material.dart';
import 'package:freekake/components/navbar_container.dart';
import 'package:freekake/components/navbar_shape_1.dart';
import 'package:freekake/components/navbar_shape_2.dart';
import 'package:freekake/components/navbar_shape_3.dart';
import 'package:freekake/components/custom_shape.dart';
class BottomNavbar extends StatefulWidget {
const BottomNavbar({super.key});

View File

@ -53,6 +53,7 @@ class CardList extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 1, width: 5),
Text(
title,
style: const TextStyle(
@ -61,16 +62,16 @@ class CardList extends StatelessWidget {
),
),
const SizedBox(height: 1, width: 5),
Text(
body,
style: const TextStyle(
letterSpacing: 0.2,
fontSize: 14,
fontWeight: FontWeight.normal,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
// Text(
// body,
// style: const TextStyle(
// letterSpacing: 0.2,
// fontSize: 14,
// fontWeight: FontWeight.normal,
// ),
// maxLines: 2,
// overflow: TextOverflow.ellipsis,
// ),
const Spacer(),
Padding(
padding: EdgeInsets.all(0.08),

View File

@ -1,11 +1,11 @@
import 'package:flutter/material.dart';
import 'package:freekake/components/bottom_navbar.dart';
import 'package:freekake/components/menu_button.dart';
import 'package:freekake/providers/menu_selection_provider.dart';
import 'package:freekake/components/scan_button.dart';
import 'package:freekake/screen/Home_screen.dart';
import 'package:freekake/screen/koleksi_screen.dart';
import 'package:freekake/screen/pustaka_screen.dart';
import 'package:freekake/screen/saya/profile_screen.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class MainMenu extends StatefulWidget {
const MainMenu({super.key});

View File

@ -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,
),
),
],

View File

@ -1,7 +1,7 @@
import 'package:freekake/screen/camera_screen.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
// import 'package:freekake/screen/camera_screen.dart';
import 'package:freekake/screen/camera_screen.dart';
class ScanButton extends StatelessWidget {
const ScanButton({super.key});
@ -45,4 +45,4 @@ class ScanButton extends StatelessWidget {
),
);
}
}
}

View File

@ -0,0 +1,14 @@
import 'dart:io';
import 'package:image_picker/image_picker.dart';
class ImagePickerHelper {
Future<dynamic> 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;
}
}
}

View File

@ -0,0 +1,5 @@
class ImagePickerHelper {
Future<void> pickImage() async {
throw UnsupportedError('pickImage is not supported on this platform');
}
}

View File

@ -0,0 +1,35 @@
// import 'package:image_picker_web/image_picker_web.dart';
// import 'dart:typed_data';
// class ImagePickerHelper {
// Future<dynamic> pickImage() async {
// Uint8List? bytesFromPicker = await ImagePickerWeb.getImageAsBytes();
// if (bytesFromPicker != null) {
// return bytesFromPicker;
// }
// }
// }
import 'dart:typed_data';
import 'dart:html' as html;
class ImagePickerHelper {
Future<void> 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;
}
});
});
}
}

View File

@ -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';

View File

@ -1,5 +1,5 @@
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';
@ -9,12 +9,12 @@ import 'package:provider/provider.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
// SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
await SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
// await SystemChrome.setPreferredOrientations([
// DeviceOrientation.portraitUp,
// DeviceOrientation.portraitDown, // bisa dihapus jika hanya ingin satu arah
// ]);
runApp(const MyApp());
}
@ -32,7 +32,7 @@ class MyApp extends StatelessWidget {
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'AR Character App',
title: 'Freekake',
theme: ThemeData.dark(),
home:
// DrawScreen(),

View File

@ -1,31 +0,0 @@
class Users {
int id;
// String nama;
// String tgl;
// String? alamat;
Users({
required this.id,
// required this.nama, this.alamat, required this.tgl
});
Map<String, dynamic> toMap() {
return {
"id": id,
// "nama": nama, "alamat": this.alamat, "tgl": this.tgl
};
}
factory Users.fromJson(Map<String, dynamic> map) {
return Users(
id: map['id'],
// nama: map['nama'],
// alamat: map['alamat'],
// tgl: map['tanggal'],
);
}
String toString() {
return 'Users{id:$id,}';
}
}

View File

@ -5,6 +5,7 @@ import 'package:freekake/components/buildcard_info.dart';
import 'package:freekake/components/main_menu.dart';
import 'package:freekake/components/menu_item.dart';
import 'package:freekake/components/scan_button.dart';
import 'package:flutter_unity_widget/flutter_unity_widget.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@ -16,6 +17,7 @@ class HomeScreen extends StatefulWidget {
class _HomeScreenState extends State<HomeScreen> {
final String username = "luffy01";
// Image image
late UnityWidgetController _unityWidgetController;
@override
Widget build(BuildContext context) {
@ -49,89 +51,98 @@ class _HomeScreenState extends State<HomeScreen> {
return Stack(
children: <Widget>[
Positioned.fill(
child: RepaintBoundary(
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/background.jpeg"),
fit: BoxFit.cover,
),
),
),
child: UnityWidget(
onUnityCreated: onUnityCreated,
//isARScene: true,
onUnityMessage: onUnityMessage,
//onUnitySceneLoaded: onUnitySceneLoaded,
fullscreen: false,
),
),
// Positioned.fill(
// child: RepaintBoundary(
// child: Container(
// decoration: const BoxDecoration(
// image: DecorationImage(
// image: AssetImage("assets/images/background.jpeg"),
// fit: BoxFit.cover,
// ),
// ),
// ),
// ),
// ),
Positioned(
right: 0,
top: 100,
child: Padding(
padding: EdgeInsets.only(right: 20),
child: Container(
width: 40,
height: 40,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(1),
color: Color.fromARGB(1, 209, 174, 174).withAlpha(0),
),
child: Center(
child: DropdownButtonHideUnderline(
child: DropdownButton2(
customButton: Container(
height: 100,
width: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
image: const DecorationImage(
image: AssetImage('assets/images/cepot-u.png'),
fit: BoxFit.cover,
),
),
),
openWithLongPress: false,
items: [
..._MenuItems.firstItems.map(
(item) => DropdownMenuItem<MenuItem>(
value: item,
child: _MenuItems.buildItem(item),
),
),
],
onChanged: (value) {
if (value != null) {
_MenuItems.onChanged(context, value);
} else {
print("null");
}
},
buttonStyleData: ButtonStyleData(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(40),
),
),
dropdownStyleData: DropdownStyleData(
width: 140,
padding: EdgeInsets.zero,
maxHeight: 150,
// padding: const EdgeInsets.symmetric(vertical: 6),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
color: Color.fromRGBO(2, 104, 17, 1).withAlpha(50),
),
offset: const Offset(40, -4),
),
menuItemStyleData: MenuItemStyleData(
height: 35,
padding: EdgeInsets.symmetric(horizontal: 10),
),
// menuItemStyleData: const MenuItemStyleData(
// padding: EdgeInsets.only(left: 16, right: 16),
// ),
),
),
),
),
),
),
// Positioned(
// right: 0,
// top: 100,
// child: Padding(
// padding: EdgeInsets.only(right: 20),
// child: Container(
// width: 40,
// height: 40,
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(1),
// color: Color.fromARGB(1, 209, 174, 174).withAlpha(0),
// ),
// child: Center(
// child: DropdownButtonHideUnderline(
// child: DropdownButton2(
// customButton: Container(
// height: 50,
// width: 50,
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(10),
// image: const DecorationImage(
// image: AssetImage('assets/images/cepot-u.png'),
// fit: BoxFit.cover,
// ),
// ),
// ),
// openWithLongPress: false,
// items: [
// ..._MenuItems.firstItems.map(
// (item) => DropdownMenuItem<MenuItem>(
// value: item,
// child: _MenuItems.buildItem(item),
// ),
// ),
// ],
// onChanged: (value) {
// if (value != null) {
// _MenuItems.onChanged(context, value);
// } else {
// print("null");
// }
// },
// buttonStyleData: ButtonStyleData(
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(40),
// ),
// ),
// dropdownStyleData: DropdownStyleData(
// width: 140,
// padding: EdgeInsets.zero,
// maxHeight: 150,
// // padding: const EdgeInsets.symmetric(vertical: 6),
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(4),
// color: Color.fromRGBO(2, 104, 17, 1).withAlpha(50),
// ),
// offset: const Offset(40, -4),
// ),
// menuItemStyleData: MenuItemStyleData(
// height: 35,
// padding: EdgeInsets.symmetric(horizontal: 10),
// ),
// // menuItemStyleData: const MenuItemStyleData(
// // padding: EdgeInsets.only(left: 16, right: 16),
// // ),
// ),
// ),
// ),
// ),
// ),
// ),
Positioned(
top: 10,
left: 10,
@ -154,39 +165,39 @@ class _HomeScreenState extends State<HomeScreen> {
],
),
),
Positioned(
bottom: 150,
left: 0,
right: 0,
child: Column(
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
decoration: BoxDecoration(
color: Color.fromARGB(255, 247, 224, 236),
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Color.fromARGB(255, 214, 213, 121),
blurRadius: 5,
spreadRadius: 2,
),
],
),
// child: Text(
// "Halo....Jotaslim",
// style: TextStyle(
// fontSize: 12,
// fontWeight: FontWeight.bold,
// color: Color(0xFF000000),
// ),
// ),
),
SizedBox(height: 10),
setHomeImage("assets/images/cepott.png", 300),
],
),
),
// Positioned(
// bottom: 150,
// left: 0,
// right: 0,
// child: Column(
// children: [
// Container(
// padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
// decoration: BoxDecoration(
// color: Color.fromARGB(255, 247, 224, 236),
// borderRadius: BorderRadius.circular(10),
// boxShadow: [
// BoxShadow(
// color: Color.fromARGB(255, 214, 213, 121),
// blurRadius: 5,
// spreadRadius: 2,
// ),
// ],
// ),
// child: Text(
// "Halo....Jotaslim",
// style: TextStyle(
// fontSize: 12,
// fontWeight: FontWeight.bold,
// color: Color(0xFF000000),
// ),
// ),
// ),
// SizedBox(height: 10),
// //setHomeImage("assets/images/cepott.png", 300),
// ],
// ),
// ),
// BG MEnu
Stack(
children: [
@ -218,6 +229,14 @@ class _HomeScreenState extends State<HomeScreen> {
Widget setHomeImage(String src, double size) {
return Image.asset(src, width: size);
}
void onUnityCreated(controller) {
_unityWidgetController = controller;
}
void onUnityMessage(message) {
print('Received message from unity: ${message.toString()}');
}
}
class _MenuItems {

View File

@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:freekake/components/collection_container.dart';
import 'package:freekake/screen/collection/character_view.dart';
class CollectionCaraterScreen extends StatefulWidget {
const CollectionCaraterScreen({super.key});
@ -23,13 +22,7 @@ class _CollectionCaraterScreenState extends State<CollectionCaraterScreen> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Favorite",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
Text("Favorit", style: TextStyle(color: Colors.black)),
Divider(height: 20, color: Colors.transparent),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
@ -55,13 +48,7 @@ class _CollectionCaraterScreenState extends State<CollectionCaraterScreen> {
charSex: "Laki-laki",
charOrigin: "Jawa Barat",
content:
"""Cepot adalah sosok yang begitu menarik—aneh, ceria, dan penuh kejutan!
Ia muncul seperti tokoh dari dongeng lama yang lupa pulang ke rumah, dengan wajah merah seperti apel matang,
hidung besar yang tampak siap mencium rahasia, dan mata bulat yang selalu bersinar penuh rasa ingin tahu. Ia suka tertawa keras,
suka bermain-main dengan kata-kata, dan sangat pandai membuat siapa pun merasa nyaman di dekatnya. \nMeski kadang terlihat konyol,
Cepot sebenarnya sangat cerdikia tahu kapan harus berbicara, kapan harus diam, dan yang paling penting, ia tahu bagaimana menghibur
orang-orang yang sedang sedih. \nAnak-anak menyukainya, orang tua menghormatinya, dan tak jarang hewan-hewan kecil pun tampak betah
duduk di dekatnya saat ia bercerita.
"""Cepot adalah sosok yang begitu menarik—aneh, ceria, dan penuh kejutan! Ia muncul seperti tokoh dari dongeng lama yang lupa pulang ke rumah, dengan wajah merah seperti apel matang, hidung besar yang tampak siap mencium rahasia, dan mata bulat yang selalu bersinar penuh rasa ingin tahu. Ia suka tertawa keras, suka bermain-main dengan kata-kata, dan sangat pandai membuat siapa pun merasa nyaman di dekatnya. \nMeski kadang terlihat konyol, Cepot sebenarnya sangat cerdik—ia tahu kapan harus berbicara, kapan harus diam, dan yang paling penting, ia tahu bagaimana menghibur orang-orang yang sedang sedih. \nAnak-anak menyukainya, orang tua menghormatinya, dan tak jarang hewan-hewan kecil pun tampak betah duduk di dekatnya saat ia bercerita.
""",
),
),
@ -83,13 +70,7 @@ class _CollectionCaraterScreenState extends State<CollectionCaraterScreen> {
),
),
Divider(height: 20, color: Colors.transparent),
Text(
"All",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
Text("Semua", style: TextStyle(color: Colors.black)),
Divider(height: 20, color: Colors.transparent),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
@ -125,20 +106,8 @@ class _CollectionCaraterScreenState extends State<CollectionCaraterScreen> {
charName: "Cepot",
charSex: "Laki-laki",
charOrigin: "Jawa Barat",
content: """
Cepot adalah sosok yang begitu menarikaneh,
ceria, dan penuh kejutan! Ia muncul seperti
tokoh dari dongeng lama yang lupa pulang ke rumah,
dengan wajah merah seperti apel matang,
hidung besar yang tampak siap
mencium rahasia, dan mata bulat
yang selalu bersinar penuh rasa ingin
tahu. Ia suka tertawa keras, suka bermain-main dengan kata-kata, dan sangat
pandai membuat siapa pun merasa nyaman di dekatnya. \nMeski kadang terlihat konyol,
Cepot sebenarnya sangat cerdikia tahu kapan harus berbicara, kapan harus diam, dan
yang paling penting, ia tahu bagaimana menghibur orang-orang yang sedang sedih. \nAnak-anak
menyukainya, orang tua menghormatinya, dan tak jarang hewan-hewan kecil pun tampak betah duduk
di dekatnya saat ia bercerita.
content:
"""Cepot adalah sosok yang begitu menarik—aneh, ceria, dan penuh kejutan! Ia muncul seperti tokoh dari dongeng lama yang lupa pulang ke rumah, dengan wajah merah seperti apel matang, hidung besar yang tampak siap mencium rahasia, dan mata bulat yang selalu bersinar penuh rasa ingin tahu. Ia suka tertawa keras, suka bermain-main dengan kata-kata, dan sangat pandai membuat siapa pun merasa nyaman di dekatnya. \nMeski kadang terlihat konyol, Cepot sebenarnya sangat cerdik—ia tahu kapan harus berbicara, kapan harus diam, dan yang paling penting, ia tahu bagaimana menghibur orang-orang yang sedang sedih. \nAnak-anak menyukainya, orang tua menghormatinya, dan tak jarang hewan-hewan kecil pun tampak betah duduk di dekatnya saat ia bercerita.
""",
),
),

View File

@ -1,7 +1,5 @@
import 'package:flutter/material.dart';
import 'package:freekake/components/collection_container.dart';
import 'package:freekake/screen/collection/character_view.dart';
import 'package:freekake/screen/collection/skin_view.dart';
class CollectionSkinScreen extends StatefulWidget {
const CollectionSkinScreen({super.key});

View File

@ -1,105 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:webview_flutter/webview_flutter.dart';
class _ListDetailScreen extends StatefulWidget {
final String title;
final String? filepath;
const _ListDetailScreen({super.key, required this.title, this.filepath});
@override
State<_ListDetailScreen> createState() => _ListDetailScreenState();
}
class _ListDetailScreenState extends State<_ListDetailScreen> {
List<bool> checklist = [];
late WebViewController _controller;
late String? fPath = widget.filepath;
@override
void initState() {
super.initState();
_controller =
WebViewController()..setJavaScriptMode(JavaScriptMode.unrestricted);
checklist = List.generate(paragraphs.length, (index) => false);
if (fPath != null && fPath!.isNotEmpty) {
_loadContent(fPath!); // <- ini penting
}
}
final List<String> paragraphs = [
"Paragraf pertama tentang ${"widget.title"}.",
"Paragraf kedua dengan informasi tambahan.",
"Paragraf ketiga yang menjelaskan detail lebih lanjut.",
"Paragraf keempat yang melengkapi pembahasan.",
];
void _loadContent(String path) async {
try {
if (path.startsWith('http')) {
_controller.loadRequest(Uri.parse(path));
} else {
String fileHtml = await rootBundle.loadString(path);
_controller.loadHtmlString(fileHtml);
}
} catch (e) {
debugPrint("Error loading HTML: $e");
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(title: Text(widget.title)),
body:
(fPath != null && fPath!.isNotEmpty)
? WebViewWidget(controller: _controller)
: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.asset(
'assets/images/default.png',
width: 100,
height: 100,
fit: BoxFit.cover,
),
const SizedBox(width: 16),
Expanded(
child: Text(
"Ini adalah detail dari ${widget.title}.",
style: const TextStyle(fontSize: 18),
),
),
],
),
const SizedBox(height: 20),
Expanded(
child: ListView.builder(
itemCount: paragraphs.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(paragraphs[index]),
trailing: Checkbox(
value: checklist[index],
onChanged: (bool? value) {
setState(() {
checklist[index] = value!;
});
},
),
);
},
),
),
],
),
),
);
}
}

View File

@ -1,7 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'dart:convert';
import 'package:webview_flutter/webview_flutter.dart';
class ListDetailScreen extends StatefulWidget {
final String title;
@ -14,120 +13,89 @@ class ListDetailScreen extends StatefulWidget {
}
class _ListDetailScreenState extends State<ListDetailScreen> {
late InAppWebViewController _webViewController;
List<bool> checklist = [];
late WebViewController _controller;
late String? fPath = widget.filepath;
@override
void initState() {
super.initState();
checklist = List.generate(paragraphs.length, (index) => false);
}
final List<String> paragraphs = [
"Paragraf pertama tentang ${"widget.title"}.",
"Paragraf kedua dengan informasi tambahan.",
"Paragraf ketiga yang menjelaskan detail lebih lanjut.",
"Paragraf keempat yang melengkapi pembahasan.",
];
void _loadContent(String path) async {
if (path.startsWith('http')) {
// Load dari Internet
_controller.loadRequest(Uri.parse(path));
} else {
// Load dari assets lokal
String fileHtml = await rootBundle.loadString(path);
_controller.loadHtmlString(fileHtml);
}
}
@override
Widget build(BuildContext context) {
String _getMimeType(String path) {
if (path.endsWith('.png')) return 'image/png';
if (path.endsWith('.jpg') || path.endsWith('.jpeg')) return 'image/jpeg';
if (path.endsWith('.svg')) return 'image/svg+xml';
if (path.endsWith('.html')) return 'text/html';
if (path.endsWith('.css')) return 'text/css';
if (path.endsWith('.js')) return 'application/javascript';
return 'application/octet-stream';
}
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(title: Text(widget.title)),
body:
widget.filepath != null
? InAppWebView(
initialUrlRequest: URLRequest(url: WebUri("about:blank")),
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
javaScriptEnabled: true,
allowFileAccessFromFileURLs: true,
allowUniversalAccessFromFileURLs: true,
),
(fPath != null && fPath!.isNotEmpty)
? WebViewWidget(controller: _controller)
: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
// Gambar di kiri atas dengan teks di kanan
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.asset(
'assets/images/default.png', // Ganti dengan gambar yang sesuai
width: 100,
height: 100,
fit: BoxFit.cover,
),
const SizedBox(width: 16),
Expanded(
child: Text(
"Ini adalah detail dari ${widget.title}.",
style: const TextStyle(fontSize: 18),
),
),
],
),
const SizedBox(height: 20),
// Paragraf dengan checklist
Expanded(
child: ListView.builder(
itemCount: paragraphs.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(paragraphs[index]),
trailing: Checkbox(
value: checklist[index],
onChanged: (bool? value) {
setState(() {
checklist[index] = value!;
});
},
),
);
},
),
),
],
),
onWebViewCreated: (controller) async {
_webViewController = controller;
final html = await rootBundle.loadString(widget.filepath!);
final base = widget.filepath!.substring(
0,
widget.filepath!.lastIndexOf('/') + 1,
);
await controller.loadData(
data: html,
baseUrl: WebUri(
"file:///android_asset/flutter_assets/$base",
), // agar path relatif seperti img1/* jalan
mimeType: 'text/html',
encoding: 'utf-8',
);
debugPrint("http://localhost/$base");
debugPrint("file:///android_asset/flutter_assets/$base");
},
onLoadStop: (controller, url) async {
debugPrint("🚀 onLoadStop called. URL: $url");
var result = await controller.evaluateJavascript(
source: """
(() => {
const board = document.getElementById('game-board');
const hasRender = typeof renderGrid === 'function';
return { hasRender, boardExists: board !== null };
})();
""",
);
debugPrint("📊 Evaluated JS result: $result");
final jsCheck = await controller.evaluateJavascript(
source: """
typeof renderGrid === 'function' &&
document.querySelector('#game-board') !== null
""",
);
debugPrint(
"Apakah renderGrid tersedia dan board muncul? => $jsCheck",
);
final imageLoaded = await controller.evaluateJavascript(
source: """
Array.from(document.images).every(img => img.complete)
""",
);
debugPrint("Semua gambar berhasil dimuat? => $imageLoaded");
},
// (Opsional) tangkap log dari JS
onConsoleMessage: (controller, consoleMessage) {
debugPrint("📢 JS Console: ${consoleMessage.message}");
},
shouldInterceptRequest: (controller, request) async {
final url = request.url;
if (url == null || url.host != 'localhost') return null;
try {
// Strip "http://localhost/" from the path
final path = url.path.replaceFirst('/', '');
final asset = await rootBundle.load(path);
final mimeType = _getMimeType(path);
return WebResourceResponse(
contentType: mimeType,
data: asset.buffer.asUint8List(),
statusCode: 200,
reasonPhrase: 'OK',
);
} catch (e) {
print("⚠️ Asset not found: ${url.path} -> $e");
return WebResourceResponse(
contentType: 'text/plain',
data: Uint8List.fromList(utf8.encode('404 Not Found')),
statusCode: 404,
reasonPhrase: 'Not Found',
);
}
},
)
: const Center(child: Text("Tidak ada file HTML")),
),
);
}
}

View File

@ -2,21 +2,16 @@ import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:freekake/components/buildcard_info.dart';
import 'package:freekake/components/card_list.dart';
import 'package:freekake/components/collection_container%20copy.dart';
import 'package:freekake/components/main_menu.dart';
import 'package:freekake/components/topbar_container.dart';
import 'package:freekake/screen/pustaka/pustaka_detail_screen.dart';
import 'package:freekake/helpers/color_helper.dart';
import 'package:freekake/models/users.dart';
import 'package:freekake/screen/pustaka/list_detail_screen.dart';
import 'package:freekake/util/api_client.dart';
import 'package:list_detail_extension/list_detail_extension.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:dio/dio.dart';
class ListEducation extends StatefulWidget {
final String? selectedCategory;
const ListEducation({super.key, this.selectedCategory});
const ListEducation({super.key});
@override
State<ListEducation> createState() => _ListEducationState();
@ -27,14 +22,9 @@ class _ListEducationState extends State<ListEducation> {
late final WebViewController _controller;
late String urlOrAssetPath;
bool _shouldShowWebView = false;
String? selectedCategory;
final listDetailExtension = ListDetailExtension();
// Data fetch
final ApiClient _apiClient = ApiClient();
List<Users> _posts = [];
bool _isLoading = true;
String _error = '';
// load extension
final listDetailExtension = ListDetailExtension();
Future<void> _initExtension() async {
await listDetailExtension.load();
@ -79,55 +69,18 @@ class _ListEducationState extends State<ListEducation> {
""",
"file": "assets/html/index.html",
},
{
"title": "Memori Game",
"image": "assets/html/freekake.png",
"color": "#cef1da",
"category": "Gizi",
"type": "Materi",
"point": "100",
"coint": "20",
"body":
"""Game untuk melatih daya ingat siswa, sehingga bisa diharapkan bisa
menemukan cara sendiri untuk mengingat sesuatu
""",
"file": "assets/html/memory/memory.html",
},
{
"title": "Find Words",
"image": "assets/html/freekake.png",
"color": "#cef1da",
"category": "Kesehatan",
"type": "Materi",
"point": "100",
"coint": "20",
"body": """
No Descripptions
""",
"file": "assets/html/findwords/findwords.html",
},
];
List<Map<String, dynamic>> filteredItems = [];
@override
void initState() {
super.initState();
selectedCategory = widget.selectedCategory;
print(selectedCategory);
if (selectedCategory != null && selectedCategory!.isNotEmpty) {
filteredItems =
_listContent
.where((item) => item["category"] == selectedCategory)
.toList();
} else {
filteredItems = List.from(_listContent);
}
filteredItems = List.from(_listContent);
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) {
_shouldShowWebView = true;
_controller =
WebViewController()..setJavaScriptMode(JavaScriptMode.unrestricted);
urlOrAssetPath = "assets/html/index.html";
urlOrAssetPath = "assets/makanan_bergizi/index.html";
_loadContent(urlOrAssetPath);
_initExtension();
}
@ -139,20 +92,18 @@ class _ListEducationState extends State<ListEducation> {
// Load dari Internet
_controller.loadRequest(Uri.parse(path));
} else {
try {
await rootBundle.load(path);
await _controller.loadFlutterAsset(path);
} catch (e) {
print("Gagal memuat file HTML: $path\nError: $e");
}
_controller.loadFlutterAsset(path);
// Load dari assets lokal
// String fileHtml = await rootBundle.loadString(path);
String fileHtml = await DefaultAssetBundle.of(
context,
).loadString('assets/html/index.html');
_controller.loadHtmlString(fileHtml);
}
}
}
void filterSearch(String query) {
setState(() {
selectedCategory = null;
if (query.isEmpty) {
filteredItems = List.from(_listContent);
} else {
@ -166,7 +117,6 @@ class _ListEducationState extends State<ListEducation> {
void filterByCategory(String category) {
setState(() {
selectedCategory = category;
filteredItems =
_listContent.where((item) {
return item["category"].toLowerCase() == category.toLowerCase();
@ -174,43 +124,9 @@ class _ListEducationState extends State<ListEducation> {
});
}
Future<void> _fetchPosts() async {
try {
setState(() {
_isLoading = true;
_error = '';
});
// Melakukan permintaan GET ke endpoint
final Response response = await _apiClient.dio.get('auth/users');
if (response.statusCode == 200) {
// Konversi data JSON ke List
List<dynamic> postJson = response.data;
_posts = postJson.map((json) => Users.fromJson(json)).toList();
} else {
_error = 'Gagal memuat data: ${response.statusCode}';
}
} on DioException catch (e) {
if (e.response != null) {
_error =
'Server Error: ${e.response?.statusCode} - ${e.response?.statusMessage}';
} else {
_error = 'Network Error: ${e.message}';
}
print('DioError: $e');
} catch (e) {
_error = 'Terjadi kesalahan tidak terduga: $e';
print('General Error: $e');
} finally {
setState(() {
_isLoading = false;
});
}
}
@override
Widget build(BuildContext context) {
String searchQuery = "";
final List<Map<String, dynamic>> collections = [
{
"label": "Kesehatan",
@ -242,8 +158,7 @@ class _ListEducationState extends State<ListEducation> {
collections
.where(
(item) => item["label"].toLowerCase().contains(
// searchQuery.toLowerCase(),
searchController.text.toLowerCase(),
searchQuery.toLowerCase(),
),
)
.toList();
@ -261,7 +176,7 @@ class _ListEducationState extends State<ListEducation> {
body: Column(
children: [
// Header Section
headerContainer(context, collections),
headerContainer(context, filteredCollections),
// Collection Items dengan Filter
SizedBox(height: 20),
Expanded(child: contentContainer(context)),
@ -340,7 +255,6 @@ class _ListEducationState extends State<ListEducation> {
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children:
filteredCollections.map((item) {
final isSelected = selectedCategory == item["category"];
return CollectionContainer(
label: item["label"]!,
imageSvg: item["image"]!,
@ -348,16 +262,9 @@ class _ListEducationState extends State<ListEducation> {
iconh: 20,
width: 70,
height: 70,
textColor:
isSelected
? const Color.fromARGB(255, 230, 48, 160)
: Colors.black,
lblSize: 10,
// colorContiner: ColorHelper.hexToColor(item["color"]),
colorContiner:
isSelected
? const Color.fromARGB(255, 84, 3, 224)
: ColorHelper.hexToColor(item["color"]),
textColor: Colors.black,
lblSize: 8,
colorContiner: ColorHelper.hexToColor(item["color"]),
onTapAc:
() => {
searchController.clear(),
@ -440,41 +347,36 @@ class _ListEducationState extends State<ListEducation> {
GridView _generateList() {
return GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
crossAxisCount: 1, // 2 Kolom
crossAxisSpacing: 10,
mainAxisSpacing: 10,
childAspectRatio: 2.5,
),
itemCount: filteredItems.length,
itemCount: _listContent.length,
itemBuilder: (context, index) {
return GestureDetector(
child: CardList(
title: filteredItems[index]["title"] ?? "",
body: filteredItems[index]["body"] ?? "",
gambar: filteredItems[index]['image'],
point: filteredItems[index]['point'],
coint: filteredItems[index]['coint'],
tipe: filteredItems[index]['type'],
title: _listContent[index]["title"] ?? "",
body: _listContent[index]["body"] ?? "",
gambar: _listContent[index]['image'],
point: _listContent[index]['coint'],
coint: _listContent[index]['point'],
tipe: _listContent[index]['tipe'],
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder:
// (context) => listDetailExtension.buildPage({
// 'title': filteredItems[index]['category'],
// 'imagePath': filteredItems[index]['image'],
// 'filepath': filteredItems[index]['file'],
// 'paragraphs':
// """
// """
// "<h1> ${filteredItems[index]["title"]} </h1> <p> ${filteredItems[index]["body"]}",
// }),
(context) => ListDetailScreen(
title: filteredItems[index]['category'],
// 'imagePath': filteredItems[index]['image'],
filepath: filteredItems[index]['file'],
),
(context) => listDetailExtension.buildPage({
'title': filteredItems[index]['category'],
'imagePath': filteredItems[index]['image'],
'filepath': filteredItems[index]['file'],
'paragraphs':
"""
"""
"<h1> ${_listContent[index]["title"]} </h1> <p> ${_listContent[index]["body"]}",
}),
),
);
},

View File

@ -74,11 +74,106 @@ class _ListDetailScreenState extends State<ListPustakaDetailScreen> {
),
),
),
// Padding(
// padding: const EdgeInsets.all(20.0),
// child: Row(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Image.asset(
// widget.imagePath,
// width: 100,
// height: 100,
// fit: BoxFit.cover,
// ),
// const SizedBox(width: 16),
// Expanded(
// child: Center(
// child: Text(
// widget.title,
// style: const TextStyle(
// fontSize: 22,
// fontWeight: FontWeight.bold,
// color: Colors.black,
// ),
// ),
// ),
// ),
// ],
// ),
// ),
const SizedBox(height: 0),
Expanded(
child: SingleChildScrollView(
padding: const EdgeInsets.only(left: 18.0, right: 18, bottom: 18),
child: htmlBody(),
child:
// ListView.builder(
// itemCount: widget.paragraphs.length,
// itemBuilder: (context, index) {
// return
// Padding(
// padding: const EdgeInsets.only(bottom: 16.0),
// child: Row(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Expanded(
// child:
// // Text(
// // widget.paragraphs[index] +
// // style: TextStyle(color: Colors.black),
// Html(
// // style: {
// // "body": Style(
// // color: const Color.fromRGBO(0, 0, 0, 1),
// // ),
// // },
// data:
// widget.paragraphs +
// """
// <html>
// <!-- Text between angle brackets is an HTML tag and is not displayed.
// Most tags, such as the HTML and /HTML tags that surround the contents of
// a page, come in pairs; some tags, like HR, for a horizontal rule, stand
// alone. Comments, such as the text you're reading, are not displayed when
// the Web page is shown. The information between the HEAD and /HEAD tags is
// not displayed. The information between the BODY and /BODY tags is displayed.-->
// <head>
// <title>Enter a title, displayed at the top of the window.</title>
// </head>
// <!-- The information between the BODY and /BODY tags is displayed.-->
// <body>
// <h1>Enter the main heading, usually the same as the title.</h1>
// <p>Be <b>bold</b> in stating your key points. Put them in a list: </p>
// <ul>
// <li>The first item in your list</li>
// <li>The second item; <i>italicize</i> key words</li>
// </ul>
// <p>Improve your image by including an image. </p>
// <p><img src="http://www.mygifs.com/CoverImage.gif" alt="A Great HTML Resource"></p>
// <p>Add a link to your favorite <a href="https://www.dummies.com/">Web site</a>.
// Break up your page with a horizontal rule or two. </p>
// <hr>
// <p>Finally, link to <a href="page2.html">another page</a> in your own Web site.</p>
// <!-- And add a copyright notice.-->
// <p>© Wiley Publishing, 2011</p>
// </body>
// </html>
// """,
// ),
// ),
// // ),
// // Checkbox(
// // value: _readStatus[index],
// // onChanged: (bool? value) {
// // _toggleReadStatus(index);
// // },
// // ),
// ],
// ),
// );
// },
// ),
htmlBody(),
),
),
],

View File

@ -108,7 +108,7 @@ class _PustakaScreenState extends State<PustakaScreen> {
children: [
CollectionContainer(
label: "Luffy",
imagesrc: 'images/luffy.png',
imagesrc: 'assets/images/luffy.png',
width: 100,
height: 100,
onTapAc:

View File

@ -108,7 +108,7 @@ class _PustakaScreenState extends State<PustakaScreen> {
children: [
CollectionContainer(
label: "Luffy",
imagesrc: 'images/luffy.png',
imagesrc: 'assets/images/luffy.png',
width: 100,
height: 100,
onTapAc:

View File

@ -44,32 +44,6 @@ class _PustakaScreenState extends State<PustakaScreen> {
},
];
final List<Map<String, dynamic>> _genres = [
{
"label": "Game",
"type": "game",
"image": "assets/icons/healthy.svg",
"color": "#cdd0ee",
},
{
"label": "Novel",
"image": "assets/icons/Nutrition.svg",
"color": "#e8e29a",
},
{
"label": "TTS",
"type": "puzzle",
"image": "assets/icons/Education.svg",
"color": "#efd8c6",
},
{
"label": "Pazzle",
"type": "puzzle",
"image": "assets/icons/Safety.svg",
"color": "#cef1da",
},
];
void _onMenuTapped(int index) {
setState(() {
_selectedIndex = index;
@ -86,23 +60,14 @@ class _PustakaScreenState extends State<PustakaScreen> {
final screenWidth = MediaQuery.of(context).size.width;
final buttonScanSize = screenWidth * 0.20;
final double bottomPadding = (9000 / screenWidth).clamp(0, 0.2);
List<Map<String, dynamic>> filterCollections(
List<Map<String, dynamic>> collections,
String query,
) {
return collections
.where(
(item) =>
item["label"]!.toLowerCase().contains(query.toLowerCase()),
)
.toList();
}
List<Map<String, dynamic>> filteredCollections = filterCollections(
_collections,
_searchQuery,
);
List<Map<String, dynamic>> filteredCollections =
_collections
.where(
(item) => item["label"]!.toLowerCase().contains(
_searchQuery.toLowerCase(),
),
)
.toList();
return Scaffold(
backgroundColor: const Color.fromARGB(255, 255, 255, 255),
@ -156,6 +121,16 @@ class _PustakaScreenState extends State<PustakaScreen> {
],
),
),
// // Date Display
// Padding(
// padding: const EdgeInsets.symmetric(vertical: 10),
// child: Text(
// DateTime.now().toString(),
// style: const TextStyle(color: Colors.white),
// ),
// ),
// Search Bar
Padding(
padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 10),
@ -223,10 +198,7 @@ class _PustakaScreenState extends State<PustakaScreen> {
Navigator.push(
context,
MaterialPageRoute(
builder:
(_) => ListEducation(
selectedCategory: item["label"],
),
builder: (_) => const ListEducation(),
),
);
},
@ -259,61 +231,61 @@ class _PustakaScreenState extends State<PustakaScreen> {
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children:
_genres.map((genre) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 8.0,
),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
elevation: 5,
color: ColorHelper.hexToColor("#efd8c6"),
// color: const Color.fromARGB(140, 255, 255, 255),
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(15),
// ),
child: GestureDetector(
onTap:
() => {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ListEducation(),
),
),
},
child: Container(
width: 80,
padding: const EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.book,
size: 50,
color: Colors.blueAccent,
),
Text(
genre['label'],
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Color.fromARGB(255, 0, 0, 0),
),
),
],
children: List.generate(
10,
(index) => Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
elevation: 5,
color: ColorHelper.hexToColor("#efd8c6"),
// color: const Color.fromARGB(140, 255, 255, 255),
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(15),
// ),
child: GestureDetector(
onTap:
() => {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ListEducation(),
),
),
),
},
child: Container(
width: 80,
padding: const EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.book,
size: 50,
color: Colors.blueAccent,
),
Text(
'Topic ${index + 1}',
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Color.fromARGB(255, 0, 0, 0),
),
),
],
),
),
);
}).toList(),
),
),
),
),
),
),
),
),
// Bottom Navigation
// MainMenu(),
],
),
// BG MEnu
@ -328,17 +300,13 @@ class _PustakaScreenState extends State<PustakaScreen> {
Positioned(bottom: 0, left: 0, right: 0, child: MainMenu()),
],
),
Stack(
children: [
Positioned(
bottom: bottomPadding * 98,
left: (screenWidth - buttonScanSize) / 2,
child: Transform.translate(
offset: Offset(0, -20),
child: ScanButton(),
),
),
],
Positioned(
bottom: bottomPadding * 98,
left: (screenWidth - buttonScanSize) / 2,
child: Transform.translate(
offset: Offset(0, -20),
child: ScanButton(),
),
),
],
);

View File

@ -0,0 +1,211 @@
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:freekake/components/bottom_navbar.dart';
import 'package:freekake/components/main_menu.dart';
import 'package:freekake/components/scan_button.dart';
import 'package:freekake/helpers/pick_image.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
class AkunSaya extends StatefulWidget {
@override
_AkunSayaState createState() => _AkunSayaState();
}
class _AkunSayaState extends State<AkunSaya> {
dynamic _profileImage;
dynamic _headerImage;
//final ImagePicker _picker = ImagePicker();
Future<void> _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: () {},
);
}
}

View File

@ -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 {

View File

@ -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 {

View File

@ -1,36 +0,0 @@
import 'package:dio/dio.dart';
class ApiClient {
final Dio _dio = Dio();
final String _baseUrl = 'https://api.freekake.com/';
ApiClient() {
_dio.options.baseUrl = _baseUrl;
_dio.options.connectTimeout = const Duration(seconds: 5);
_dio.options.receiveTimeout = const Duration(seconds: 3);
_dio.interceptors.add(
InterceptorsWrapper(
onRequest: (options, handler) {
print('REQUEST[${options.method}] => PATH: ${options.path}');
// options.headers['Authorization'] = 'Bearer your_token_here';
return handler.next(options);
},
onResponse: (response, handler) {
print(
'RESPONSE[${response.statusCode}] => PATH: ${response.requestOptions.path}',
);
return handler.next(response);
},
onError: (DioException e, handler) {
print(
'ERROR[${e.response?.statusCode}] => PATH: ${e.requestOptions.path}',
);
return handler.next(e);
},
),
);
}
Dio get dio => _dio;
}

View File

@ -7,7 +7,6 @@ import Foundation
import desktop_webview_window
import file_selector_macos
import flutter_inappwebview_macos
import shared_preferences_foundation
import url_launcher_macos
import webview_flutter_wkwebview
@ -15,7 +14,6 @@ import webview_flutter_wkwebview
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
DesktopWebviewWindowPlugin.register(with: registry.registrar(forPlugin: "DesktopWebviewWindowPlugin"))
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
WebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "WebViewFlutterPlugin"))

View File

@ -129,22 +129,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.2.3"
dio:
dependency: "direct main"
description:
name: dio
sha256: "253a18bbd4851fecba42f7343a1df3a9a4c1d31a2c1b37e221086b4fa8c8dbc9"
url: "https://pub.dev"
source: hosted
version: "5.8.0+1"
dio_web_adapter:
dependency: transitive
description:
name: dio_web_adapter
sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
dropdown_button2:
dependency: "direct main"
description:
@ -222,70 +206,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.0-beta.2"
flutter_inappwebview:
dependency: "direct main"
description:
name: flutter_inappwebview
sha256: "80092d13d3e29b6227e25b67973c67c7210bd5e35c4b747ca908e31eb71a46d5"
url: "https://pub.dev"
source: hosted
version: "6.1.5"
flutter_inappwebview_android:
dependency: transitive
description:
name: flutter_inappwebview_android
sha256: "62557c15a5c2db5d195cb3892aab74fcaec266d7b86d59a6f0027abd672cddba"
url: "https://pub.dev"
source: hosted
version: "1.1.3"
flutter_inappwebview_internal_annotations:
dependency: transitive
description:
name: flutter_inappwebview_internal_annotations
sha256: "787171d43f8af67864740b6f04166c13190aa74a1468a1f1f1e9ee5b90c359cd"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
flutter_inappwebview_ios:
dependency: transitive
description:
name: flutter_inappwebview_ios
sha256: "5818cf9b26cf0cbb0f62ff50772217d41ea8d3d9cc00279c45f8aabaa1b4025d"
url: "https://pub.dev"
source: hosted
version: "1.1.2"
flutter_inappwebview_macos:
dependency: transitive
description:
name: flutter_inappwebview_macos
sha256: c1fbb86af1a3738e3541364d7d1866315ffb0468a1a77e34198c9be571287da1
url: "https://pub.dev"
source: hosted
version: "1.1.2"
flutter_inappwebview_platform_interface:
dependency: transitive
description:
name: flutter_inappwebview_platform_interface
sha256: cf5323e194096b6ede7a1ca808c3e0a078e4b33cc3f6338977d75b4024ba2500
url: "https://pub.dev"
source: hosted
version: "1.3.0+1"
flutter_inappwebview_web:
dependency: transitive
description:
name: flutter_inappwebview_web
sha256: "55f89c83b0a0d3b7893306b3bb545ba4770a4df018204917148ebb42dc14a598"
url: "https://pub.dev"
source: hosted
version: "1.1.2"
flutter_inappwebview_windows:
dependency: transitive
description:
name: flutter_inappwebview_windows
sha256: "8b4d3a46078a2cdc636c4a3d10d10f2a16882f6be607962dbfff8874d1642055"
url: "https://pub.dev"
source: hosted
version: "0.6.0"
flutter_lints:
dependency: "direct dev"
description:
@ -315,6 +235,15 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_unity_widget:
dependency: "direct main"
description:
path: "."
ref: "flutter_3.24_android_hotfix"
resolved-ref: d2f6dc853d5b5054668ea9d79bb138d2d072696c
url: "https://github.com/juicycleff/flutter-unity-view-widget.git"
source: git
version: "2022.2.1"
flutter_web_plugins:
dependency: transitive
description: flutter
@ -893,7 +822,23 @@ packages:
sha256: "18b1640839cf6546784a524c72aded5b6e86b23e7167dc2311cc96f7658b64bd"
url: "https://pub.dev"
source: hosted
version: "2.11.0"
version: "2.10.0"
webview_flutter_web:
dependency: transitive
description:
name: webview_flutter_web
sha256: "18a7ccc1c31dd9a5c759a1b7217a2a1e04bd8f65712714a4070bfac19a23ca9e"
url: "https://pub.dev"
source: hosted
version: "0.2.3+4"
webview_flutter_wkwebview:
dependency: transitive
description:
name: webview_flutter_web
sha256: "18a7ccc1c31dd9a5c759a1b7217a2a1e04bd8f65712714a4070bfac19a23ca9e"
url: "https://pub.dev"
source: hosted
version: "0.2.3+4"
webview_flutter_wkwebview:
dependency: "direct main"
description:

View File

@ -54,13 +54,16 @@ dependencies:
url: https://github.com/fhauze/list_detail_screen.git
ref: main
desktop_webview_window: ^0.2.3
flutter_inappwebview: ^6.0.0
dio: ^5.0.0
# arcore_flutter_plugin: ^0.2.0-alpha
# flutter_unity_widget: ^2022.2.1
# 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:
@ -87,57 +90,13 @@ flutter:
# To add assets to your application, add an assets section, like this:
assets:
- assets/images/
- assets/images/Artboard 15@4x.png
- assets/images/Artboard 16@4x.png
- assets/images/background.jpeg
- assets/images/cepott.png
- assets/images/ft_cepot.png
- assets/images/ft_luffy.png
- assets/images/klipartz.png
- assets/images/luffy-kimono.png
- assets/images/luffy-king.png
- assets/images/luffy-u.png
- assets/images/luffy.gif
- assets/images/luffy.png
# SVG files
- assets/icons/E-furrybuddy.svg
- assets/icons/E-furrybuddy1.svg
- assets/icons/Education.svg
- assets/icons/furrybuddy.svg
- assets/icons/healthy.svg
- assets/icons/Koleksi.svg
- assets/icons/Nutrition.svg
- assets/icons/Pustaka.svg
- assets/icons/Safety.svg
- assets/icons/Saya.svg
- assets/icons/Scan.svg
- assets/icons/
#HTML File
- assets/html/
- assets/html/index.html
- assets/html/furikake/index.html
- assets/html/furikake/
# HTML Images
- assets/html/isipiringku.png
- assets/html/karbohidrat.png
- assets/html/lemak.png
- assets/html/protein.png
- assets/html/seratair.png
- assets/html/vitaminmineral.png
#drag and drop
- assets/html/findwords/
- assets/html/findwords/test.html
- assets/html/findwords/findwords.html
- assets/html/freekake.png
- assets/html/memory/
- assets/html/memory/memory.html
#assets puzzle memory
- assets/html/memory/freekake.png
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/to/resolution-aware-images

View File

@ -8,7 +8,6 @@
#include <desktop_webview_window/desktop_webview_window_plugin.h>
#include <file_selector_windows/file_selector_windows.h>
#include <flutter_inappwebview_windows/flutter_inappwebview_windows_plugin_c_api.h>
#include <permission_handler_windows/permission_handler_windows_plugin.h>
#include <url_launcher_windows/url_launcher_windows.h>
@ -17,8 +16,6 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("DesktopWebviewWindowPlugin"));
FileSelectorWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FileSelectorWindows"));
FlutterInappwebviewWindowsPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FlutterInappwebviewWindowsPluginCApi"));
PermissionHandlerWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
UrlLauncherWindowsRegisterWithRegistrar(

View File

@ -5,7 +5,6 @@
list(APPEND FLUTTER_PLUGIN_LIST
desktop_webview_window
file_selector_windows
flutter_inappwebview_windows
permission_handler_windows
url_launcher_windows
)