This commit is contained in:
Ibnu Naz'm Ar-rosyid
2025-07-18 20:05:17 +07:00
commit bea44c1b7c
234 changed files with 5681 additions and 0 deletions

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1 @@
<EFBFBD>axfnd7xox5e4ton7ncyqiattau<EFBFBD><02>classesP=+<2B>7<EFBFBD><37>7<EFBFBD><37>7~n<>`<60><>sourcesI<>iH<69><EFBFBD>H{<7B><>&<26>

View File

@ -0,0 +1,501 @@
package org.gradle.accessors.dm;
import org.gradle.api.NonNullApi;
import org.gradle.api.artifacts.MinimalExternalModuleDependency;
import org.gradle.plugin.use.PluginDependency;
import org.gradle.api.artifacts.ExternalModuleDependencyBundle;
import org.gradle.api.artifacts.MutableVersionConstraint;
import org.gradle.api.provider.Provider;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.provider.ProviderFactory;
import org.gradle.api.internal.catalog.AbstractExternalDependencyFactory;
import org.gradle.api.internal.catalog.DefaultVersionCatalog;
import java.util.Map;
import org.gradle.api.internal.attributes.ImmutableAttributesFactory;
import org.gradle.api.internal.artifacts.dsl.CapabilityNotationParser;
import javax.inject.Inject;
/**
* A catalog of dependencies accessible via the {@code libs} extension.
*/
@NonNullApi
public class LibrariesForLibs extends AbstractExternalDependencyFactory {
private final AbstractExternalDependencyFactory owner = this;
private final AndroidxLibraryAccessors laccForAndroidxLibraryAccessors = new AndroidxLibraryAccessors(owner);
private final VersionAccessors vaccForVersionAccessors = new VersionAccessors(providers, config);
private final BundleAccessors baccForBundleAccessors = new BundleAccessors(objects, providers, config, attributesFactory, capabilityNotationParser);
private final PluginAccessors paccForPluginAccessors = new PluginAccessors(providers, config);
@Inject
public LibrariesForLibs(DefaultVersionCatalog config, ProviderFactory providers, ObjectFactory objects, ImmutableAttributesFactory attributesFactory, CapabilityNotationParser capabilityNotationParser) {
super(config, providers, objects, attributesFactory, capabilityNotationParser);
}
/**
* Dependency provider for <b>junit</b> with <b>junit:junit</b> coordinates and
* with version reference <b>junit</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*/
public Provider<MinimalExternalModuleDependency> getJunit() {
return create("junit");
}
/**
* Group of libraries at <b>androidx</b>
*/
public AndroidxLibraryAccessors getAndroidx() {
return laccForAndroidxLibraryAccessors;
}
/**
* Group of versions at <b>versions</b>
*/
public VersionAccessors getVersions() {
return vaccForVersionAccessors;
}
/**
* Group of bundles at <b>bundles</b>
*/
public BundleAccessors getBundles() {
return baccForBundleAccessors;
}
/**
* Group of plugins at <b>plugins</b>
*/
public PluginAccessors getPlugins() {
return paccForPluginAccessors;
}
public static class AndroidxLibraryAccessors extends SubDependencyFactory {
private final AndroidxActivityLibraryAccessors laccForAndroidxActivityLibraryAccessors = new AndroidxActivityLibraryAccessors(owner);
private final AndroidxComposeLibraryAccessors laccForAndroidxComposeLibraryAccessors = new AndroidxComposeLibraryAccessors(owner);
private final AndroidxCoreLibraryAccessors laccForAndroidxCoreLibraryAccessors = new AndroidxCoreLibraryAccessors(owner);
private final AndroidxEspressoLibraryAccessors laccForAndroidxEspressoLibraryAccessors = new AndroidxEspressoLibraryAccessors(owner);
private final AndroidxLifecycleLibraryAccessors laccForAndroidxLifecycleLibraryAccessors = new AndroidxLifecycleLibraryAccessors(owner);
private final AndroidxUiLibraryAccessors laccForAndroidxUiLibraryAccessors = new AndroidxUiLibraryAccessors(owner);
public AndroidxLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
/**
* Dependency provider for <b>junit</b> with <b>androidx.test.ext:junit</b> coordinates and
* with version reference <b>junitVersion</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*/
public Provider<MinimalExternalModuleDependency> getJunit() {
return create("androidx.junit");
}
/**
* Dependency provider for <b>material3</b> with <b>androidx.compose.material3:material3</b> coordinates and
* with <b>no version specified</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*/
public Provider<MinimalExternalModuleDependency> getMaterial3() {
return create("androidx.material3");
}
/**
* Group of libraries at <b>androidx.activity</b>
*/
public AndroidxActivityLibraryAccessors getActivity() {
return laccForAndroidxActivityLibraryAccessors;
}
/**
* Group of libraries at <b>androidx.compose</b>
*/
public AndroidxComposeLibraryAccessors getCompose() {
return laccForAndroidxComposeLibraryAccessors;
}
/**
* Group of libraries at <b>androidx.core</b>
*/
public AndroidxCoreLibraryAccessors getCore() {
return laccForAndroidxCoreLibraryAccessors;
}
/**
* Group of libraries at <b>androidx.espresso</b>
*/
public AndroidxEspressoLibraryAccessors getEspresso() {
return laccForAndroidxEspressoLibraryAccessors;
}
/**
* Group of libraries at <b>androidx.lifecycle</b>
*/
public AndroidxLifecycleLibraryAccessors getLifecycle() {
return laccForAndroidxLifecycleLibraryAccessors;
}
/**
* Group of libraries at <b>androidx.ui</b>
*/
public AndroidxUiLibraryAccessors getUi() {
return laccForAndroidxUiLibraryAccessors;
}
}
public static class AndroidxActivityLibraryAccessors extends SubDependencyFactory {
public AndroidxActivityLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
/**
* Dependency provider for <b>compose</b> with <b>androidx.activity:activity-compose</b> coordinates and
* with version reference <b>activityCompose</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*/
public Provider<MinimalExternalModuleDependency> getCompose() {
return create("androidx.activity.compose");
}
}
public static class AndroidxComposeLibraryAccessors extends SubDependencyFactory {
public AndroidxComposeLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
/**
* Dependency provider for <b>bom</b> with <b>androidx.compose:compose-bom</b> coordinates and
* with version reference <b>composeBom</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*/
public Provider<MinimalExternalModuleDependency> getBom() {
return create("androidx.compose.bom");
}
}
public static class AndroidxCoreLibraryAccessors extends SubDependencyFactory {
public AndroidxCoreLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
/**
* Dependency provider for <b>ktx</b> with <b>androidx.core:core-ktx</b> coordinates and
* with version reference <b>coreKtx</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*/
public Provider<MinimalExternalModuleDependency> getKtx() {
return create("androidx.core.ktx");
}
}
public static class AndroidxEspressoLibraryAccessors extends SubDependencyFactory {
public AndroidxEspressoLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
/**
* Dependency provider for <b>core</b> with <b>androidx.test.espresso:espresso-core</b> coordinates and
* with version reference <b>espressoCore</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*/
public Provider<MinimalExternalModuleDependency> getCore() {
return create("androidx.espresso.core");
}
}
public static class AndroidxLifecycleLibraryAccessors extends SubDependencyFactory {
private final AndroidxLifecycleRuntimeLibraryAccessors laccForAndroidxLifecycleRuntimeLibraryAccessors = new AndroidxLifecycleRuntimeLibraryAccessors(owner);
public AndroidxLifecycleLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
/**
* Group of libraries at <b>androidx.lifecycle.runtime</b>
*/
public AndroidxLifecycleRuntimeLibraryAccessors getRuntime() {
return laccForAndroidxLifecycleRuntimeLibraryAccessors;
}
}
public static class AndroidxLifecycleRuntimeLibraryAccessors extends SubDependencyFactory {
public AndroidxLifecycleRuntimeLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
/**
* Dependency provider for <b>ktx</b> with <b>androidx.lifecycle:lifecycle-runtime-ktx</b> coordinates and
* with version reference <b>lifecycleRuntimeKtx</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*/
public Provider<MinimalExternalModuleDependency> getKtx() {
return create("androidx.lifecycle.runtime.ktx");
}
}
public static class AndroidxUiLibraryAccessors extends SubDependencyFactory implements DependencyNotationSupplier {
private final AndroidxUiTestLibraryAccessors laccForAndroidxUiTestLibraryAccessors = new AndroidxUiTestLibraryAccessors(owner);
private final AndroidxUiToolingLibraryAccessors laccForAndroidxUiToolingLibraryAccessors = new AndroidxUiToolingLibraryAccessors(owner);
public AndroidxUiLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
/**
* Dependency provider for <b>ui</b> with <b>androidx.compose.ui:ui</b> coordinates and
* with <b>no version specified</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*/
public Provider<MinimalExternalModuleDependency> asProvider() {
return create("androidx.ui");
}
/**
* Dependency provider for <b>graphics</b> with <b>androidx.compose.ui:ui-graphics</b> coordinates and
* with <b>no version specified</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*/
public Provider<MinimalExternalModuleDependency> getGraphics() {
return create("androidx.ui.graphics");
}
/**
* Group of libraries at <b>androidx.ui.test</b>
*/
public AndroidxUiTestLibraryAccessors getTest() {
return laccForAndroidxUiTestLibraryAccessors;
}
/**
* Group of libraries at <b>androidx.ui.tooling</b>
*/
public AndroidxUiToolingLibraryAccessors getTooling() {
return laccForAndroidxUiToolingLibraryAccessors;
}
}
public static class AndroidxUiTestLibraryAccessors extends SubDependencyFactory {
public AndroidxUiTestLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
/**
* Dependency provider for <b>junit4</b> with <b>androidx.compose.ui:ui-test-junit4</b> coordinates and
* with <b>no version specified</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*/
public Provider<MinimalExternalModuleDependency> getJunit4() {
return create("androidx.ui.test.junit4");
}
/**
* Dependency provider for <b>manifest</b> with <b>androidx.compose.ui:ui-test-manifest</b> coordinates and
* with <b>no version specified</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*/
public Provider<MinimalExternalModuleDependency> getManifest() {
return create("androidx.ui.test.manifest");
}
}
public static class AndroidxUiToolingLibraryAccessors extends SubDependencyFactory implements DependencyNotationSupplier {
public AndroidxUiToolingLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
/**
* Dependency provider for <b>tooling</b> with <b>androidx.compose.ui:ui-tooling</b> coordinates and
* with <b>no version specified</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*/
public Provider<MinimalExternalModuleDependency> asProvider() {
return create("androidx.ui.tooling");
}
/**
* Dependency provider for <b>preview</b> with <b>androidx.compose.ui:ui-tooling-preview</b> coordinates and
* with <b>no version specified</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*/
public Provider<MinimalExternalModuleDependency> getPreview() {
return create("androidx.ui.tooling.preview");
}
}
public static class VersionAccessors extends VersionFactory {
public VersionAccessors(ProviderFactory providers, DefaultVersionCatalog config) { super(providers, config); }
/**
* Version alias <b>activityCompose</b> with value <b>1.10.1</b>
* <p>
* If the version is a rich version and cannot be represented as a
* single version string, an empty string is returned.
* <p>
* This version was declared in catalog libs.versions.toml
*/
public Provider<String> getActivityCompose() { return getVersion("activityCompose"); }
/**
* Version alias <b>agp</b> with value <b>8.4.0</b>
* <p>
* If the version is a rich version and cannot be represented as a
* single version string, an empty string is returned.
* <p>
* This version was declared in catalog libs.versions.toml
*/
public Provider<String> getAgp() { return getVersion("agp"); }
/**
* Version alias <b>composeBom</b> with value <b>2023.08.00</b>
* <p>
* If the version is a rich version and cannot be represented as a
* single version string, an empty string is returned.
* <p>
* This version was declared in catalog libs.versions.toml
*/
public Provider<String> getComposeBom() { return getVersion("composeBom"); }
/**
* Version alias <b>coreKtx</b> with value <b>1.15.0</b>
* <p>
* If the version is a rich version and cannot be represented as a
* single version string, an empty string is returned.
* <p>
* This version was declared in catalog libs.versions.toml
*/
public Provider<String> getCoreKtx() { return getVersion("coreKtx"); }
/**
* Version alias <b>espressoCore</b> with value <b>3.6.1</b>
* <p>
* If the version is a rich version and cannot be represented as a
* single version string, an empty string is returned.
* <p>
* This version was declared in catalog libs.versions.toml
*/
public Provider<String> getEspressoCore() { return getVersion("espressoCore"); }
/**
* Version alias <b>junit</b> with value <b>4.13.2</b>
* <p>
* If the version is a rich version and cannot be represented as a
* single version string, an empty string is returned.
* <p>
* This version was declared in catalog libs.versions.toml
*/
public Provider<String> getJunit() { return getVersion("junit"); }
/**
* Version alias <b>junitVersion</b> with value <b>1.2.1</b>
* <p>
* If the version is a rich version and cannot be represented as a
* single version string, an empty string is returned.
* <p>
* This version was declared in catalog libs.versions.toml
*/
public Provider<String> getJunitVersion() { return getVersion("junitVersion"); }
/**
* Version alias <b>kotlin</b> with value <b>1.9.0</b>
* <p>
* If the version is a rich version and cannot be represented as a
* single version string, an empty string is returned.
* <p>
* This version was declared in catalog libs.versions.toml
*/
public Provider<String> getKotlin() { return getVersion("kotlin"); }
/**
* Version alias <b>lifecycleRuntimeKtx</b> with value <b>2.8.7</b>
* <p>
* If the version is a rich version and cannot be represented as a
* single version string, an empty string is returned.
* <p>
* This version was declared in catalog libs.versions.toml
*/
public Provider<String> getLifecycleRuntimeKtx() { return getVersion("lifecycleRuntimeKtx"); }
}
public static class BundleAccessors extends BundleFactory {
public BundleAccessors(ObjectFactory objects, ProviderFactory providers, DefaultVersionCatalog config, ImmutableAttributesFactory attributesFactory, CapabilityNotationParser capabilityNotationParser) { super(objects, providers, config, attributesFactory, capabilityNotationParser); }
}
public static class PluginAccessors extends PluginFactory {
private final AndroidPluginAccessors paccForAndroidPluginAccessors = new AndroidPluginAccessors(providers, config);
private final JetbrainsPluginAccessors paccForJetbrainsPluginAccessors = new JetbrainsPluginAccessors(providers, config);
public PluginAccessors(ProviderFactory providers, DefaultVersionCatalog config) { super(providers, config); }
/**
* Group of plugins at <b>plugins.android</b>
*/
public AndroidPluginAccessors getAndroid() {
return paccForAndroidPluginAccessors;
}
/**
* Group of plugins at <b>plugins.jetbrains</b>
*/
public JetbrainsPluginAccessors getJetbrains() {
return paccForJetbrainsPluginAccessors;
}
}
public static class AndroidPluginAccessors extends PluginFactory {
public AndroidPluginAccessors(ProviderFactory providers, DefaultVersionCatalog config) { super(providers, config); }
/**
* Plugin provider for <b>android.application</b> with plugin id <b>com.android.application</b> and
* with version reference <b>agp</b>
* <p>
* This plugin was declared in catalog libs.versions.toml
*/
public Provider<PluginDependency> getApplication() { return createPlugin("android.application"); }
}
public static class JetbrainsPluginAccessors extends PluginFactory {
private final JetbrainsKotlinPluginAccessors paccForJetbrainsKotlinPluginAccessors = new JetbrainsKotlinPluginAccessors(providers, config);
public JetbrainsPluginAccessors(ProviderFactory providers, DefaultVersionCatalog config) { super(providers, config); }
/**
* Group of plugins at <b>plugins.jetbrains.kotlin</b>
*/
public JetbrainsKotlinPluginAccessors getKotlin() {
return paccForJetbrainsKotlinPluginAccessors;
}
}
public static class JetbrainsKotlinPluginAccessors extends PluginFactory {
public JetbrainsKotlinPluginAccessors(ProviderFactory providers, DefaultVersionCatalog config) { super(providers, config); }
/**
* Plugin provider for <b>jetbrains.kotlin.android</b> with plugin id <b>org.jetbrains.kotlin.android</b> and
* with version reference <b>kotlin</b>
* <p>
* This plugin was declared in catalog libs.versions.toml
*/
public Provider<PluginDependency> getAndroid() { return createPlugin("jetbrains.kotlin.android"); }
}
}

View File

@ -0,0 +1,645 @@
package org.gradle.accessors.dm;
import org.gradle.api.NonNullApi;
import org.gradle.api.artifacts.MinimalExternalModuleDependency;
import org.gradle.plugin.use.PluginDependency;
import org.gradle.api.artifacts.ExternalModuleDependencyBundle;
import org.gradle.api.artifacts.MutableVersionConstraint;
import org.gradle.api.provider.Provider;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.provider.ProviderFactory;
import org.gradle.api.internal.catalog.AbstractExternalDependencyFactory;
import org.gradle.api.internal.catalog.DefaultVersionCatalog;
import java.util.Map;
import org.gradle.api.internal.attributes.ImmutableAttributesFactory;
import org.gradle.api.internal.artifacts.dsl.CapabilityNotationParser;
import javax.inject.Inject;
/**
* A catalog of dependencies accessible via the {@code libs} extension.
*/
@NonNullApi
public class LibrariesForLibsInPluginsBlock extends AbstractExternalDependencyFactory {
private final AbstractExternalDependencyFactory owner = this;
private final AndroidxLibraryAccessors laccForAndroidxLibraryAccessors = new AndroidxLibraryAccessors(owner);
private final VersionAccessors vaccForVersionAccessors = new VersionAccessors(providers, config);
private final BundleAccessors baccForBundleAccessors = new BundleAccessors(objects, providers, config, attributesFactory, capabilityNotationParser);
private final PluginAccessors paccForPluginAccessors = new PluginAccessors(providers, config);
@Inject
public LibrariesForLibsInPluginsBlock(DefaultVersionCatalog config, ProviderFactory providers, ObjectFactory objects, ImmutableAttributesFactory attributesFactory, CapabilityNotationParser capabilityNotationParser) {
super(config, providers, objects, attributesFactory, capabilityNotationParser);
}
/**
* Dependency provider for <b>junit</b> with <b>junit:junit</b> coordinates and
* with version reference <b>junit</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public Provider<MinimalExternalModuleDependency> getJunit() {
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
return create("junit");
}
/**
* Group of libraries at <b>androidx</b>
*
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public AndroidxLibraryAccessors getAndroidx() {
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
return laccForAndroidxLibraryAccessors;
}
/**
* Group of versions at <b>versions</b>
*/
public VersionAccessors getVersions() {
return vaccForVersionAccessors;
}
/**
* Group of bundles at <b>bundles</b>
*
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public BundleAccessors getBundles() {
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
return baccForBundleAccessors;
}
/**
* Group of plugins at <b>plugins</b>
*/
public PluginAccessors getPlugins() {
return paccForPluginAccessors;
}
/**
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public static class AndroidxLibraryAccessors extends SubDependencyFactory {
private final AndroidxActivityLibraryAccessors laccForAndroidxActivityLibraryAccessors = new AndroidxActivityLibraryAccessors(owner);
private final AndroidxComposeLibraryAccessors laccForAndroidxComposeLibraryAccessors = new AndroidxComposeLibraryAccessors(owner);
private final AndroidxCoreLibraryAccessors laccForAndroidxCoreLibraryAccessors = new AndroidxCoreLibraryAccessors(owner);
private final AndroidxEspressoLibraryAccessors laccForAndroidxEspressoLibraryAccessors = new AndroidxEspressoLibraryAccessors(owner);
private final AndroidxLifecycleLibraryAccessors laccForAndroidxLifecycleLibraryAccessors = new AndroidxLifecycleLibraryAccessors(owner);
private final AndroidxUiLibraryAccessors laccForAndroidxUiLibraryAccessors = new AndroidxUiLibraryAccessors(owner);
public AndroidxLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
/**
* Dependency provider for <b>junit</b> with <b>androidx.test.ext:junit</b> coordinates and
* with version reference <b>junitVersion</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public Provider<MinimalExternalModuleDependency> getJunit() {
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
return create("androidx.junit");
}
/**
* Dependency provider for <b>material3</b> with <b>androidx.compose.material3:material3</b> coordinates and
* with <b>no version specified</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public Provider<MinimalExternalModuleDependency> getMaterial3() {
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
return create("androidx.material3");
}
/**
* Group of libraries at <b>androidx.activity</b>
*
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public AndroidxActivityLibraryAccessors getActivity() {
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
return laccForAndroidxActivityLibraryAccessors;
}
/**
* Group of libraries at <b>androidx.compose</b>
*
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public AndroidxComposeLibraryAccessors getCompose() {
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
return laccForAndroidxComposeLibraryAccessors;
}
/**
* Group of libraries at <b>androidx.core</b>
*
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public AndroidxCoreLibraryAccessors getCore() {
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
return laccForAndroidxCoreLibraryAccessors;
}
/**
* Group of libraries at <b>androidx.espresso</b>
*
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public AndroidxEspressoLibraryAccessors getEspresso() {
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
return laccForAndroidxEspressoLibraryAccessors;
}
/**
* Group of libraries at <b>androidx.lifecycle</b>
*
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public AndroidxLifecycleLibraryAccessors getLifecycle() {
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
return laccForAndroidxLifecycleLibraryAccessors;
}
/**
* Group of libraries at <b>androidx.ui</b>
*
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public AndroidxUiLibraryAccessors getUi() {
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
return laccForAndroidxUiLibraryAccessors;
}
}
/**
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public static class AndroidxActivityLibraryAccessors extends SubDependencyFactory {
public AndroidxActivityLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
/**
* Dependency provider for <b>compose</b> with <b>androidx.activity:activity-compose</b> coordinates and
* with version reference <b>activityCompose</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public Provider<MinimalExternalModuleDependency> getCompose() {
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
return create("androidx.activity.compose");
}
}
/**
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public static class AndroidxComposeLibraryAccessors extends SubDependencyFactory {
public AndroidxComposeLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
/**
* Dependency provider for <b>bom</b> with <b>androidx.compose:compose-bom</b> coordinates and
* with version reference <b>composeBom</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public Provider<MinimalExternalModuleDependency> getBom() {
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
return create("androidx.compose.bom");
}
}
/**
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public static class AndroidxCoreLibraryAccessors extends SubDependencyFactory {
public AndroidxCoreLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
/**
* Dependency provider for <b>ktx</b> with <b>androidx.core:core-ktx</b> coordinates and
* with version reference <b>coreKtx</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public Provider<MinimalExternalModuleDependency> getKtx() {
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
return create("androidx.core.ktx");
}
}
/**
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public static class AndroidxEspressoLibraryAccessors extends SubDependencyFactory {
public AndroidxEspressoLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
/**
* Dependency provider for <b>core</b> with <b>androidx.test.espresso:espresso-core</b> coordinates and
* with version reference <b>espressoCore</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public Provider<MinimalExternalModuleDependency> getCore() {
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
return create("androidx.espresso.core");
}
}
/**
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public static class AndroidxLifecycleLibraryAccessors extends SubDependencyFactory {
private final AndroidxLifecycleRuntimeLibraryAccessors laccForAndroidxLifecycleRuntimeLibraryAccessors = new AndroidxLifecycleRuntimeLibraryAccessors(owner);
public AndroidxLifecycleLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
/**
* Group of libraries at <b>androidx.lifecycle.runtime</b>
*
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public AndroidxLifecycleRuntimeLibraryAccessors getRuntime() {
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
return laccForAndroidxLifecycleRuntimeLibraryAccessors;
}
}
/**
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public static class AndroidxLifecycleRuntimeLibraryAccessors extends SubDependencyFactory {
public AndroidxLifecycleRuntimeLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
/**
* Dependency provider for <b>ktx</b> with <b>androidx.lifecycle:lifecycle-runtime-ktx</b> coordinates and
* with version reference <b>lifecycleRuntimeKtx</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public Provider<MinimalExternalModuleDependency> getKtx() {
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
return create("androidx.lifecycle.runtime.ktx");
}
}
/**
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public static class AndroidxUiLibraryAccessors extends SubDependencyFactory implements DependencyNotationSupplier {
private final AndroidxUiTestLibraryAccessors laccForAndroidxUiTestLibraryAccessors = new AndroidxUiTestLibraryAccessors(owner);
private final AndroidxUiToolingLibraryAccessors laccForAndroidxUiToolingLibraryAccessors = new AndroidxUiToolingLibraryAccessors(owner);
public AndroidxUiLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
/**
* Dependency provider for <b>ui</b> with <b>androidx.compose.ui:ui</b> coordinates and
* with <b>no version specified</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public Provider<MinimalExternalModuleDependency> asProvider() {
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
return create("androidx.ui");
}
/**
* Dependency provider for <b>graphics</b> with <b>androidx.compose.ui:ui-graphics</b> coordinates and
* with <b>no version specified</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public Provider<MinimalExternalModuleDependency> getGraphics() {
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
return create("androidx.ui.graphics");
}
/**
* Group of libraries at <b>androidx.ui.test</b>
*
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public AndroidxUiTestLibraryAccessors getTest() {
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
return laccForAndroidxUiTestLibraryAccessors;
}
/**
* Group of libraries at <b>androidx.ui.tooling</b>
*
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public AndroidxUiToolingLibraryAccessors getTooling() {
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
return laccForAndroidxUiToolingLibraryAccessors;
}
}
/**
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public static class AndroidxUiTestLibraryAccessors extends SubDependencyFactory {
public AndroidxUiTestLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
/**
* Dependency provider for <b>junit4</b> with <b>androidx.compose.ui:ui-test-junit4</b> coordinates and
* with <b>no version specified</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public Provider<MinimalExternalModuleDependency> getJunit4() {
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
return create("androidx.ui.test.junit4");
}
/**
* Dependency provider for <b>manifest</b> with <b>androidx.compose.ui:ui-test-manifest</b> coordinates and
* with <b>no version specified</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public Provider<MinimalExternalModuleDependency> getManifest() {
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
return create("androidx.ui.test.manifest");
}
}
/**
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public static class AndroidxUiToolingLibraryAccessors extends SubDependencyFactory implements DependencyNotationSupplier {
public AndroidxUiToolingLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
/**
* Dependency provider for <b>tooling</b> with <b>androidx.compose.ui:ui-tooling</b> coordinates and
* with <b>no version specified</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public Provider<MinimalExternalModuleDependency> asProvider() {
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
return create("androidx.ui.tooling");
}
/**
* Dependency provider for <b>preview</b> with <b>androidx.compose.ui:ui-tooling-preview</b> coordinates and
* with <b>no version specified</b>
* <p>
* This dependency was declared in catalog libs.versions.toml
*
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public Provider<MinimalExternalModuleDependency> getPreview() {
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
return create("androidx.ui.tooling.preview");
}
}
public static class VersionAccessors extends VersionFactory {
public VersionAccessors(ProviderFactory providers, DefaultVersionCatalog config) { super(providers, config); }
/**
* Version alias <b>activityCompose</b> with value <b>1.10.1</b>
* <p>
* If the version is a rich version and cannot be represented as a
* single version string, an empty string is returned.
* <p>
* This version was declared in catalog libs.versions.toml
*/
public Provider<String> getActivityCompose() { return getVersion("activityCompose"); }
/**
* Version alias <b>agp</b> with value <b>8.4.0</b>
* <p>
* If the version is a rich version and cannot be represented as a
* single version string, an empty string is returned.
* <p>
* This version was declared in catalog libs.versions.toml
*/
public Provider<String> getAgp() { return getVersion("agp"); }
/**
* Version alias <b>composeBom</b> with value <b>2023.08.00</b>
* <p>
* If the version is a rich version and cannot be represented as a
* single version string, an empty string is returned.
* <p>
* This version was declared in catalog libs.versions.toml
*/
public Provider<String> getComposeBom() { return getVersion("composeBom"); }
/**
* Version alias <b>coreKtx</b> with value <b>1.15.0</b>
* <p>
* If the version is a rich version and cannot be represented as a
* single version string, an empty string is returned.
* <p>
* This version was declared in catalog libs.versions.toml
*/
public Provider<String> getCoreKtx() { return getVersion("coreKtx"); }
/**
* Version alias <b>espressoCore</b> with value <b>3.6.1</b>
* <p>
* If the version is a rich version and cannot be represented as a
* single version string, an empty string is returned.
* <p>
* This version was declared in catalog libs.versions.toml
*/
public Provider<String> getEspressoCore() { return getVersion("espressoCore"); }
/**
* Version alias <b>junit</b> with value <b>4.13.2</b>
* <p>
* If the version is a rich version and cannot be represented as a
* single version string, an empty string is returned.
* <p>
* This version was declared in catalog libs.versions.toml
*/
public Provider<String> getJunit() { return getVersion("junit"); }
/**
* Version alias <b>junitVersion</b> with value <b>1.2.1</b>
* <p>
* If the version is a rich version and cannot be represented as a
* single version string, an empty string is returned.
* <p>
* This version was declared in catalog libs.versions.toml
*/
public Provider<String> getJunitVersion() { return getVersion("junitVersion"); }
/**
* Version alias <b>kotlin</b> with value <b>1.9.0</b>
* <p>
* If the version is a rich version and cannot be represented as a
* single version string, an empty string is returned.
* <p>
* This version was declared in catalog libs.versions.toml
*/
public Provider<String> getKotlin() { return getVersion("kotlin"); }
/**
* Version alias <b>lifecycleRuntimeKtx</b> with value <b>2.8.7</b>
* <p>
* If the version is a rich version and cannot be represented as a
* single version string, an empty string is returned.
* <p>
* This version was declared in catalog libs.versions.toml
*/
public Provider<String> getLifecycleRuntimeKtx() { return getVersion("lifecycleRuntimeKtx"); }
}
/**
* @deprecated Will be removed in Gradle 9.0.
*/
@Deprecated
public static class BundleAccessors extends BundleFactory {
public BundleAccessors(ObjectFactory objects, ProviderFactory providers, DefaultVersionCatalog config, ImmutableAttributesFactory attributesFactory, CapabilityNotationParser capabilityNotationParser) { super(objects, providers, config, attributesFactory, capabilityNotationParser); }
}
public static class PluginAccessors extends PluginFactory {
private final AndroidPluginAccessors paccForAndroidPluginAccessors = new AndroidPluginAccessors(providers, config);
private final JetbrainsPluginAccessors paccForJetbrainsPluginAccessors = new JetbrainsPluginAccessors(providers, config);
public PluginAccessors(ProviderFactory providers, DefaultVersionCatalog config) { super(providers, config); }
/**
* Group of plugins at <b>plugins.android</b>
*/
public AndroidPluginAccessors getAndroid() {
return paccForAndroidPluginAccessors;
}
/**
* Group of plugins at <b>plugins.jetbrains</b>
*/
public JetbrainsPluginAccessors getJetbrains() {
return paccForJetbrainsPluginAccessors;
}
}
public static class AndroidPluginAccessors extends PluginFactory {
public AndroidPluginAccessors(ProviderFactory providers, DefaultVersionCatalog config) { super(providers, config); }
/**
* Plugin provider for <b>android.application</b> with plugin id <b>com.android.application</b> and
* with version reference <b>agp</b>
* <p>
* This plugin was declared in catalog libs.versions.toml
*/
public Provider<PluginDependency> getApplication() { return createPlugin("android.application"); }
}
public static class JetbrainsPluginAccessors extends PluginFactory {
private final JetbrainsKotlinPluginAccessors paccForJetbrainsKotlinPluginAccessors = new JetbrainsKotlinPluginAccessors(providers, config);
public JetbrainsPluginAccessors(ProviderFactory providers, DefaultVersionCatalog config) { super(providers, config); }
/**
* Group of plugins at <b>plugins.jetbrains.kotlin</b>
*/
public JetbrainsKotlinPluginAccessors getKotlin() {
return paccForJetbrainsKotlinPluginAccessors;
}
}
public static class JetbrainsKotlinPluginAccessors extends PluginFactory {
public JetbrainsKotlinPluginAccessors(ProviderFactory providers, DefaultVersionCatalog config) { super(providers, config); }
/**
* Plugin provider for <b>jetbrains.kotlin.android</b> with plugin id <b>org.jetbrains.kotlin.android</b> and
* with version reference <b>kotlin</b>
* <p>
* This plugin was declared in catalog libs.versions.toml
*/
public Provider<PluginDependency> getAndroid() { return createPlugin("jetbrains.kotlin.android"); }
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

View File

@ -0,0 +1,2 @@
#Wed Mar 12 13:52:02 WIB 2025
gradle.version=8.6

View File

@ -0,0 +1,2 @@
#Wed Mar 12 13:51:48 WIB 2025
java.home=C\:\\Program Files\\Android\\Android Studio\\jbr

Binary file not shown.

3
TomatoLeafCare/.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

1
TomatoLeafCare/.idea/.name generated Normal file
View File

@ -0,0 +1 @@
Tomato Leaf Care

View File

@ -0,0 +1,291 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="WizardSettings">
<option name="children">
<map>
<entry key="imageWizard">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="imageAssetPanel">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="actionbar">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="clipArt">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
<entry key="imagePath" value="C:\Users\Lenovo\AppData\Local\Temp\ic_android_black_24dp.xml" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="text">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="textAsset">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="launcher">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="foregroundClipArt">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="imagePath" value="C:\Users\Lenovo\AppData\Local\Temp\ic_android_black_24dp.xml" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="foregroundImage">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
<entry key="imagePath" value="C:\Users\Lenovo\Downloads\Aplikasi\TomatoLeafCare\app\src\main\res\drawable\icon.png" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="foregroundText">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="foregroundTextAsset">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="launcherLegacy">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="clipArt">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
<entry key="imagePath" value="C:\Users\Lenovo\AppData\Local\Temp\ic_android_black_24dp.xml" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="text">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="textAsset">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="notification">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="clipArt">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
<entry key="imagePath" value="C:\Users\Lenovo\AppData\Local\Temp\ic_android_black_24dp.xml" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="text">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="textAsset">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="tvBanner">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="foregroundText">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="tvChannel">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="foregroundClipArt">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="imagePath" value="C:\Users\Lenovo\AppData\Local\Temp\ic_android_black_24dp.xml" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="foregroundImage">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="foregroundText">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="foregroundTextAsset">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="color" value="000000" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</component>
</project>

6
TomatoLeafCare/.idea/compiler.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="17" />
</component>
</project>

View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetSelector">
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2025-07-08T04:54:33.007111300Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=aeb992bf" />
</handle>
</Target>
</DropdownSelection>
<DialogSelection>
<targets>
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=aeb992bf" />
</handle>
</Target>
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\Lenovo\.android\avd\Pixel_4_API_27.avd" />
</handle>
</Target>
</targets>
</DialogSelection>
</SelectionState>
<SelectionState runConfigName="SplashActivity">
<option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2025-04-11T11:21:00.168098900Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\Lenovo\.android\avd\Pixel_4_API_31.avd" />
</handle>
</Target>
</DropdownSelection>
<DialogSelection>
<targets>
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=aeb992bf" />
</handle>
</Target>
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\Lenovo\.android\avd\Pixel_4_API_31.avd" />
</handle>
</Target>
</targets>
</DialogSelection>
</SelectionState>
</selectionStates>
</component>
</project>

19
TomatoLeafCare/.idea/gradle.xml generated Normal file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveExternalAnnotations" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

View File

@ -0,0 +1,41 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewApiLevelMustBeValid" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewFontScaleMustBeGreaterThanZero" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewMultipleParameterProviders" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewPickerAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
</profile>
</component>

6
TomatoLeafCare/.idea/kotlinc.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="1.9.0" />
</component>
</project>

10
TomatoLeafCare/.idea/migrations.xml generated Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectMigrations">
<option name="MigrateToGradleLocalJavaHome">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</component>
</project>

9
TomatoLeafCare/.idea/misc.xml generated Normal file
View File

@ -0,0 +1,9 @@
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

6
TomatoLeafCare/.idea/other.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ScreenshotViewer">
<option name="frameScreenshot" value="true" />
</component>
</project>

6
TomatoLeafCare/.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 513 KiB

1
TomatoLeafCare/app/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

View File

@ -0,0 +1,100 @@
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android)
id("kotlin-parcelize")
}
android {
namespace = "com.example.tomatoleafcare"
compileSdk = 35
defaultConfig {
applicationId = "com.example.tomatoleafcare"
minSdk = 24
targetSdk = 35
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
aaptOptions {
noCompress += "tflite"
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.1"
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
buildFeatures {
viewBinding = true
dataBinding = true
}
}
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.ui)
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
implementation("androidx.cardview:cardview:1.0.0")
implementation("androidx.recyclerview:recyclerview:1.2.1")
implementation("androidx.navigation:navigation-fragment-ktx:2.7.2")
implementation("androidx.navigation:navigation-ui-ktx:2.7.2")
implementation("androidx.camera:camera-core:1.3.0")
implementation("androidx.camera:camera-camera2:1.3.0")
implementation("androidx.camera:camera-lifecycle:1.3.0")
implementation("androidx.camera:camera-view:1.3.0")
implementation("com.google.android.material:material:1.9.0")
implementation ("org.tensorflow:tensorflow-lite:2.13.0")
implementation ("org.tensorflow:tensorflow-lite-support:0.3.1")
implementation ("com.squareup.okhttp3:okhttp:4.12.0")
implementation ("com.squareup.picasso:picasso:2.8")
implementation ("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2")
implementation ("androidx.lifecycle:lifecycle-livedata-ktx:2.6.2")
}

21
TomatoLeafCare/app/proguard-rules.pro vendored Normal file
View File

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@ -0,0 +1,24 @@
package com.example.tomatoleafcare
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.example.tomatoleafcare", appContext.packageName)
}
}

View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.TomatoLeafCare"
tools:targetApi="31"
android:networkSecurityConfig="@xml/network_security_config"
android:usesCleartextTraffic="true">
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
<activity
android:name=".ui.splash.SplashActivity"
android:screenOrientation="portrait"
android:exported="true"
android:theme="@style/Theme.TomatoLeafCare.Splash">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name=".ui.home.MainActivity"
android:screenOrientation="portrait"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.TomatoLeafCare.Splash"/>
<activity android:name=".DiseaseDetailFragment" />
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -0,0 +1,48 @@
package com.example.tomatoleafcare.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.tomatoleafcare.R
import com.example.tomatoleafcare.model.Disease
class DiseaseAdapter(
private val diseases: List<Disease>,
private val listener: OnItemClickListener
) : RecyclerView.Adapter<DiseaseAdapter.DiseaseViewHolder>() {
interface OnItemClickListener {
fun onItemClick(disease: Disease)
}
inner class DiseaseViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val diseaseName: TextView = itemView.findViewById(R.id.diseaseName)
private val diseaseImage: ImageView = itemView.findViewById(R.id.diseaseImage)
private val diseaseDescription: TextView = itemView.findViewById((R.id.diseaseDescription))
fun bind(disease: Disease) {
diseaseName.text = disease.name
diseaseImage.setImageResource(disease.imageResId)
diseaseDescription.text = disease.description
itemView.setOnClickListener {
listener.onItemClick(disease)
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DiseaseViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.disease_item, parent, false)
return DiseaseViewHolder(view)
}
override fun onBindViewHolder(holder: DiseaseViewHolder, position: Int) {
holder.bind(diseases[position])
}
override fun getItemCount(): Int = diseases.size
}

View File

@ -0,0 +1,59 @@
package com.example.tomatoleafcare.ui.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.*
import androidx.recyclerview.widget.RecyclerView
import com.example.tomatoleafcare.R
import com.example.tomatoleafcare.model.History
import com.squareup.picasso.Picasso
class HistoryAdapter(
private val context: Context,
private var historyList: List<History>,
private val onItemClick: (History) -> Unit,
private val onDeleteClick: (History) -> Unit
) : RecyclerView.Adapter<HistoryAdapter.HistoryViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HistoryViewHolder {
val view = LayoutInflater.from(context).inflate(R.layout.history_item, parent, false)
return HistoryViewHolder(view)
}
override fun onBindViewHolder(holder: HistoryViewHolder, position: Int) {
val history = historyList[position]
holder.bind(history)
holder.itemView.setOnClickListener {
onItemClick(history)
}
holder.btnDelete.setOnClickListener {
onDeleteClick(history)
}
}
override fun getItemCount(): Int = historyList.size
fun updateData(newList: List<History>) {
historyList = newList
notifyDataSetChanged()
}
inner class HistoryViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val diseaseName: TextView = itemView.findViewById(R.id.txtDiseaseName)
private val date: TextView = itemView.findViewById(R.id.txtDate)
private val image: ImageView = itemView.findViewById(R.id.imageHistory)
val btnDelete: ImageButton = itemView.findViewById(R.id.btnDelete)
fun bind(history: History) {
diseaseName.text = history.diseaseName
date.text = history.date
Picasso.get().load(history.imagePath)
.placeholder(R.drawable.placeholder)
.into(image)
}
}
}

View File

@ -0,0 +1,18 @@
package com.example.tomatoleafcare.adapter
import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.example.tomatoleafcare.ui.home.CardSlide1Fragment
import com.example.tomatoleafcare.ui.home.CardSlide2Fragment
class SliderAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) {
override fun getItemCount(): Int = 2
override fun createFragment(position: Int): Fragment {
return when (position) {
0 -> CardSlide1Fragment()
1 -> CardSlide2Fragment()
else -> CardSlide1Fragment()
}
}
}

View File

@ -0,0 +1,66 @@
package com.example.tomatoleafcare.helper
import android.content.ContentValues
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import com.example.tomatoleafcare.model.History
class HistoryDatabaseHelper(context: Context) :
SQLiteOpenHelper(context, "history.db", null, 1) {
override fun onCreate(db: SQLiteDatabase) {
val createTable = """
CREATE TABLE history (
id INTEGER PRIMARY KEY AUTOINCREMENT,
diseaseName TEXT,
date TEXT,
imagePath TEXT
)
""".trimIndent()
db.execSQL(createTable)
}
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
db.execSQL("DROP TABLE IF EXISTS history")
onCreate(db)
}
fun insertHistory(item: History): Long {
val db = writableDatabase
val values = ContentValues().apply {
put("diseaseName", item.diseaseName)
put("date", item.date)
put("imagePath", item.imagePath)
}
return db.insert("history", null, values)
}
fun getAllHistory(): List<History> {
val db = readableDatabase
val cursor = db.rawQuery("SELECT * FROM history ORDER BY id DESC", null)
val items = mutableListOf<History>()
while (cursor.moveToNext()) {
items.add(
History(
id = cursor.getLong(cursor.getColumnIndexOrThrow("id")),
diseaseName = cursor.getString(cursor.getColumnIndexOrThrow("diseaseName")),
date = cursor.getString(cursor.getColumnIndexOrThrow("date")),
imagePath = cursor.getString(cursor.getColumnIndexOrThrow("imagePath"))
)
)
}
cursor.close()
return items
}
fun deleteHistory(id: Long): Boolean {
val db = this.writableDatabase
val result = db.delete("history", "id=?", arrayOf(id.toString()))
db.close()
return result > 0
}
}

View File

@ -0,0 +1,15 @@
package com.example.tomatoleafcare.model
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
data class Disease(
val name: String,
val description: String,
val cause: String,
val symptoms: String,
val impact: String,
val solution: String,
val imageResId: Int
): Parcelable

View File

@ -0,0 +1,11 @@
package com.example.tomatoleafcare.model
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
data class History(
val id: Long = 0,
val diseaseName: String,
val date: String,
val imagePath: String
) : Parcelable

View File

@ -0,0 +1,99 @@
package com.example.tomatoleafcare.repository
import com.example.tomatoleafcare.R
import com.example.tomatoleafcare.model.Disease
object DiseaseRepository {
val classList = listOf(
Disease(
"Bercak Daun Septoria",
"Menyebabkan bercak coklat pada daun, pencegahan dengan fungisida dan sirkulasi udara yang baik.",
"Jamur Septoria lycopersici, jamur ini sering ditemukan di tanah yang basah dan menyebar melalui percikan air.",
"Bercak-bercak kecil berwarna coklat tua atau hitam pada daun yang dimulai dari bagian bawah dan dapat membesar.",
"Daun menguning dan rontok., mengurangi produktivitas buah, dan membuat tanaman rentan terhadap penyakit lain.",
"Penggunaan fungisida, memastikan sirkulasi udara yang baik, dan menghindari penyiraman berlebihan.",
R.drawable.bercakdaunseptoria
),
Disease(
"Virus Mozaik",
"Menyebabkan daun terdistorsi dan mosaik, cegah dengan benih sehat dan menghapus tanaman terinfeksi.",
"Tomato Mosaic Virus (ToMV) yang menyebar melalui kontak tanaman terinfeksi, alat pertanian, dan serangga.",
"Pola mosaik bercak hijau muda dan gelap pada daun, daun menjadi keriput atau terdistorsi",
"Menghambat fotosintesis, menyebabkan pertumbuhan yang tidak optimal, serta menurunkan kualitas dan kuantitas buah.",
"Menggunakan benih sehat, menjaga kebersihan alat, dan menghilangkan tanaman yang terinfeksi.",
R.drawable.virusmozaik
),
Disease(
"Jamur Daun",
"Menyebabkan bercak kuning dan lapisan beludru di bawah daun, cegah dengan kelembapan rendah dan fungisida.",
"Jamur Cladosporium fulvum yang berkembang di lingkungan lembap dan sirkulasi udara buruk.",
"Bercak kuning pada bagian atas daun dan lapisan beludru hijau atau coklat pada bagian bawah daun",
"Mengurangi kemampuan fotosintesis, dapat menyebabkan daun mengering dan rontok.",
"Menjaga kelembapan rendah, meningkatkan sirkulasi udara, menghindari penyiraman langsung pada daun, dan menggunakan fungisida.",
R.drawable.jamurdaun
),
Disease(
"Virus Keriting Daun",
"Menyebabkan daun keriting dan menguning, cegah dengan insektisida dan penghapusan tanaman terinfeksi.",
"Virus yang ditularkan oleh kutu kebul (Bemisia tabaci).",
"Daun menjadi keriting, tebal, dan berubah warna menjadi kuning.",
"Menghambat pertumbuhan tanaman, menurunkan kualitas dan kuantitas buah.",
"Menggunakan insektisida, dan segera hapus tanaman yang terinfeksi.",
R.drawable.viruskeriting
),
Disease(
"Hawar Daun",
"Menyebabkan bercak hitam, pembusukan buah, cegah dengan fungisida dan rotasi tanaman.",
"Jamur Phytophthora infestans, yang menyebar cepat dalam kondisi lembap dan dingin.",
"Bercak coklat gelap atau hitam menyebar cepat pada daun, dengan lapisan putih pada bagian bawah daun.",
"Bisa dengan cepat menghancurkan seluruh tanaman jika tidak segera diatasi, buah juga bisa membusuk.",
"Gunakan fungisida terutama saat musim hujan, dan lakukan rotasi tanaman untuk mencegah infeksi ulang",
R.drawable.lateblight
),
Disease(
"Bercak Bakteri",
"Menyebabkan bercak hitam pada daun dan buah, cegah dengan benih sehat dan sanitasi.",
"Bakteri Xanthomonas campestris pv. vesicatoria, yang menyebar melalui air, angin, dan alat pertanian.",
"Bercak hitam kecil muncul pada daun, batang, dan buah.",
"Merusak jaringan daun, Menghambat fotositesis dan Menurunkan kualitas buah,",
"Gunakan benih sehat, jaga sanitasi, dan gunakan bakterisida.",
R.drawable.bercakbakteri
),
Disease(
"Tanaman Sehat",
"Tidak ditemukan penyakit pada daun ini.",
"tidak ada",
"tidak ada",
"tidak ada",
"tidak ada",
R.drawable.sehat
)
)
fun getData(): List<Disease> {
return classList
}
fun findDiseaseByName(name: String): Disease? {
return classList.find { it.name.equals(name, ignoreCase = true) }
}
}
object DiseaseMatcher {
fun matchDisease(className: String): Disease? {
return when (className) {
"bacterial_spot" -> DiseaseRepository.classList.find { it.name.contains("Bercak Bakteri", ignoreCase = true) }
"healthy" -> DiseaseRepository.classList.find { it.name.contains("Tanaman Sehat", ignoreCase = true) }
"late_blight" -> DiseaseRepository.classList.find { it.name.contains("Hawar Daun", ignoreCase = true) }
"leaf_curl_virus" -> DiseaseRepository.classList.find { it.name.contains("Virus Keriting Daun", ignoreCase = true) }
"leaf_mold" -> DiseaseRepository.classList.find { it.name.contains("Jamur Daun", ignoreCase = true) }
"mosaic_virus" -> DiseaseRepository.classList.find { it.name.contains("Virus Mozaik", ignoreCase = true) }
"septoria_leaf_spot" -> DiseaseRepository.classList.find { it.name.contains("Bercak Daun Septoria", ignoreCase = true) }
else -> null
}
}
}

View File

@ -0,0 +1,431 @@
package com.example.tomatoleafcare.ui.camera
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.os.Debug
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.FileProvider
import androidx.fragment.app.Fragment
import com.example.tomatoleafcare.DiseaseDetailFragment
import com.example.tomatoleafcare.R
import com.example.tomatoleafcare.repository.DiseaseMatcher
import com.example.tomatoleafcare.model.History
import com.example.tomatoleafcare.databinding.CameraFragmentBinding
import com.example.tomatoleafcare.helper.HistoryDatabaseHelper
import okhttp3.*
import org.json.JSONObject
import java.io.*
import java.nio.channels.FileChannel
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import android.os.Handler
import android.os.Looper
import androidx.core.content.ContextCompat
import android.util.Base64
import android.util.Log
import okhttp3.RequestBody.Companion.toRequestBody
import org.tensorflow.lite.Interpreter
import java.nio.MappedByteBuffer
import kotlin.math.roundToInt
class CameraFragment : Fragment() {
private var _binding: CameraFragmentBinding? = null
private val binding get() = _binding ?: throw IllegalStateException("Binding belum diinisialisasi")
private lateinit var imageUri: Uri
private lateinit var photoFile: File
private val classLabels = arrayOf(
"bacterial_spot",
"healthy",
"late_blight",
"leaf_curl_virus",
"leaf_mold",
"mosaic_virus",
"septoria_leaf_spot"
)
private val labelKelas = arrayOf(
"Bercak Bakteri",
"Daun Sehat",
"Hawar Daun",
"Virus Keriting",
"Jamur Daun",
"Virus Mozaik",
"Bercak Daun Septoria"
)
private var apiAvailable = false
private val credentials = "rahasia:tomat"
private val basicAuth = "Basic " + Base64.encodeToString(credentials.toByteArray(), Base64.NO_WRAP)
private val galleryLauncher = registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
uri?.let {
try {
val inputStream = requireContext().contentResolver.openInputStream(it)
val tempFile = File.createTempFile("gallery_", ".jpg", requireContext().cacheDir)
val outputStream = FileOutputStream(tempFile)
inputStream?.copyTo(outputStream)
inputStream?.close()
outputStream.close()
imageUri = Uri.fromFile(tempFile)
binding.imageView.setImageURI(imageUri)
} catch (e: Exception) {
e.printStackTrace()
Toast.makeText(requireContext(), "Gagal memuat gambar dari galeri", Toast.LENGTH_SHORT).show()
}
}
}
private val cameraLauncher = registerForActivityResult(ActivityResultContracts.TakePicture()) { success ->
if (success) {
binding.imageView.setImageURI(imageUri)
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
_binding = CameraFragmentBinding.inflate(inflater, container, false)
binding.btnKamera.setOnClickListener {
requestCameraPermissionLauncher.launch(android.Manifest.permission.CAMERA)
}
binding.btnGaleri.setOnClickListener {
openGallery()
}
binding.btnPindai.setOnClickListener {
if (::imageUri.isInitialized) {
if (apiAvailable) {
sendImageToApi(imageUri)
} else {
runLocalModel(imageUri, requireContext())
}
} else {
Toast.makeText(requireContext(), "Silakan pilih gambar terlebih dahulu", Toast.LENGTH_SHORT).show()
}
}
handler.post(updateNetworkStatusRunnable)
return binding.root
}
private fun openGallery() {
galleryLauncher.launch("image/*")
}
private fun openCamera() {
try {
photoFile = File.createTempFile("photo_", ".jpg", requireContext().cacheDir)
imageUri = FileProvider.getUriForFile(requireContext(), "${requireContext().packageName}.fileprovider", photoFile)
cameraLauncher.launch(imageUri)
} catch (e: IOException) {
Toast.makeText(requireContext(), "Gagal membuat file foto", Toast.LENGTH_SHORT).show()
e.printStackTrace()
}
}
private val requestCameraPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted ->
if (isGranted) {
openCamera()
} else {
Toast.makeText(requireContext(), "Izin kamera diperlukan untuk fitur ini", Toast.LENGTH_SHORT).show()
}
}
private fun runLocalModel(uri: Uri, context: Context) {
// val startTime = System.currentTimeMillis()
// val beforeMemory = Debug.getNativeHeapAllocatedSize() / 1024.0
val model = Interpreter(loadModelFile("ResNet-50_tomato-leaf-disease.tflite", context))
val inputStream = context.contentResolver.openInputStream(uri)
val bitmap = BitmapFactory.decodeStream(inputStream)
val resizedBitmap = Bitmap.createScaledBitmap(bitmap, 224, 224, true)
val input = Array(1) { Array(224) { Array(224) { FloatArray(3) } } }
for (y in 0 until 224) {
for (x in 0 until 224) {
val pixel = resizedBitmap.getPixel(x, y)
input[0][y][x][0] = Color.red(pixel).toFloat()
input[0][y][x][1] = Color.green(pixel).toFloat()
input[0][y][x][2] = Color.blue(pixel).toFloat()
}
}
val output = Array(1) { FloatArray(classLabels.size) }
model.run(input, output)
val probabilities = output[0]
// Softmax normalization (optional, if model doesn't do it)
val expValues = probabilities.map { Math.exp(it.toDouble()) }
val sumExp = expValues.sum()
val softmax = expValues.map { (it / sumExp).toFloat() }
val predictedIndex = probabilities.indices.maxByOrNull { probabilities[it] } ?: -1
val prediction = classLabels[predictedIndex]
val resultBuilder = StringBuilder()
resultBuilder.append("Confidence:\n")
for (i in labelKelas.indices) {
val label = labelKelas[i]
val confidence = softmax[i] * 100
resultBuilder.append("$label: ${"%.2f".format(confidence)}%\n")
}
// val endTime = System.currentTimeMillis()
// val afterMemory = Debug.getNativeHeapAllocatedSize() / 1024.0
// val duration = endTime - startTime
// val memoryUsed = (afterMemory - beforeMemory).roundToInt()
// Log.d("MODEL_RESULT", resultBuilder.toString())
val confidenceText = resultBuilder.toString()
//Toast.makeText(context, "Local: $prediction\nTime: $duration ms\nMemory: $memoryUsed KB", Toast.LENGTH_LONG).show()
// Toast.makeText(context, "Local: $prediction", Toast.LENGTH_LONG).show()
// Log.d("MODEL_METRICS", "Local - Time: $duration ms, Memory: $memoryUsed KB")
navigateToNoteFragment(prediction, uri, confidenceText)
}
private fun loadModelFile(modelName: String, context: Context): MappedByteBuffer {
val fileDescriptor = context.assets.openFd(modelName)
val inputStream = FileInputStream(fileDescriptor.fileDescriptor)
val fileChannel = inputStream.channel
val startOffset = fileDescriptor.startOffset
val declaredLength = fileDescriptor.declaredLength
return fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength)
}
private fun sendImageToApi(uri: Uri) {
// val startTime = System.currentTimeMillis()
// val beforeMemory = Debug.getNativeHeapAllocatedSize() / 1024.0
val contentResolver = requireContext().contentResolver
val inputStream = contentResolver.openInputStream(uri) ?: return
val imageBytes = inputStream.readBytes()
val requestBody = imageBytes.toRequestBody("image/*".toMediaTypeOrNull(), 0)
val body = MultipartBody.Part.createFormData("image", "image.jpg", requestBody)
val requestBodyMultipart = MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addPart(body)
.build()
val client = OkHttpClient()
val request = Request.Builder()
.url("http://robotika.upnvj.ac.id:8000/tomatoleafcare/classify")
// .url("http://api.simdoks.web.id:5000/tomatoleafcare/classify")
.post(requestBodyMultipart)
.addHeader("Authorization", basicAuth)
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
requireActivity().runOnUiThread {
Toast.makeText(requireContext(), "Gagal terhubung ke server", Toast.LENGTH_SHORT).show()
}
}
override fun onResponse(call: Call, response: Response) {
val responseBody = response.body?.string()
if (!response.isSuccessful || responseBody == null) {
requireActivity().runOnUiThread {
Toast.makeText(requireContext(), "Respons tidak valid dari server", Toast.LENGTH_SHORT).show()
}
return
}
try {
val jsonObject = JSONObject(responseBody)
val predictedClassObj = jsonObject.getJSONObject("predictedClass")
val prediction = predictedClassObj.getString("class")
val confidencesArray = predictedClassObj.getJSONArray("confidences")
val confidenceTextBuilder = StringBuilder()
confidenceTextBuilder.append("\nConfidence:\n")
for (i in 0 until confidencesArray.length()) {
val item = confidencesArray.getJSONObject(i)
val className = item.getString("class")
val confidence = item.getDouble("confidence")
confidenceTextBuilder.append("$className: ${"%.2f".format(confidence)}%\n")
}
val confidenceText = confidenceTextBuilder.toString()
// val endTime = System.currentTimeMillis()
// val duration = endTime - startTime
// val afterMemory = Debug.getNativeHeapAllocatedSize() / 1024.0
// val memoryUsed = (afterMemory - beforeMemory).roundToInt()
requireActivity().runOnUiThread {
// Toast.makeText(requireContext(), "Online: $prediction\nTime: $duration ms\nMemory: $memoryUsed KB", Toast.LENGTH_LONG).show()
// Toast.makeText(requireContext(), "Online: $prediction", Toast.LENGTH_LONG).show()
// Log.d("MODEL_METRICS", "Online - Time: $duration ms, Memory: $memoryUsed KB")
navigateToNoteFragment(prediction, uri, confidenceText)
}
} catch (e: Exception) {
Log.e("PARSE_ERROR", e.message ?: "Unknown error")
Log.e("RAW_JSON", responseBody ?: "No body")
e.printStackTrace()
requireActivity().runOnUiThread {
Toast.makeText(requireContext(), "Gagal parsing data", Toast.LENGTH_SHORT).show()
}
}
}
})
}
private val handler = Handler(Looper.getMainLooper())
private val updateInterval: Long = 1000
private val updateNetworkStatusRunnable = object : Runnable {
override fun run() {
checkApiAvailability()
handler.postDelayed(this, updateInterval)
}
}
private fun checkApiAvailability() {
val client = OkHttpClient()
val request = Request.Builder()
.url("http://robotika.upnvj.ac.id:8000/tomatoleafcare/check")
// .url("http://api.simdoks.web.id:5000/tomatoleafcare/check")
.get()
.addHeader("Authorization", basicAuth)
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
apiAvailable = false
updateApiStatus()
Log.e("API_RESPONSE", "Request failed: ${e.message}")
}
override fun onResponse(call: Call, response: Response) {
apiAvailable = response.isSuccessful
updateApiStatus()
}
})
}
private fun updateApiStatus() {
if (_binding == null || !isAdded) return
requireActivity().runOnUiThread {
_binding?.let { binding ->
if (apiAvailable) {
binding.textStatus.text = getString(R.string.online)
binding.textStatus.setTextColor(ContextCompat.getColor(requireContext(), R.color.green))
binding.ledStatus.setBackgroundResource(R.drawable.bg_led_online)
} else {
binding.textStatus.text = getString(R.string.offline)
binding.textStatus.setTextColor(ContextCompat.getColor(requireContext(), R.color.blue))
binding.ledStatus.setBackgroundResource(R.drawable.bg_led_offline)
}
}
}
}
private fun navigateToNoteFragment(
className: String,
imageUri: Uri,
confidenceText: String
) {
confidenceText.lines().forEachIndexed { index, line ->
Log.d("CONFIDENCE_LINE", "[$index] $line")
}
val maxConfidence = confidenceText.lines()
.mapNotNull { line ->
Regex("[a-zA-Z_]+:\\s*([\\d.,]+)%").find(line)
?.groupValues?.get(1)
?.replace(",", ".")
?.toFloatOrNull()
}
.maxOrNull() ?: 0f
val isConfident = maxConfidence >= 70f
Log.d("ParsedConfidence", "confidence: $confidenceText")
Log.d("ParsedConfidence", "Max confidence: $maxConfidence")
// matchedDisease hanya dipakai jika confidence cukup
val matchedDisease = if (isConfident) DiseaseMatcher.matchDisease(className) else null
// Simpan ke database hanya jika confidence >= 70%
if (isConfident) {
val dbHelper = HistoryDatabaseHelper(requireContext())
val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault())
val now = formatter.format(Date())
val historyItem = History(
diseaseName = matchedDisease?.name ?: "Unknown",
date = now,
imagePath = imageUri.toString()
)
dbHelper.insertHistory(historyItem)
}
// Siapkan Bundle untuk dikirim ke DiseaseDetailFragment
val bundle = Bundle().apply {
if (isConfident) {
putString("disease_name", matchedDisease?.name)
putString("disease_description", matchedDisease?.description)
putString("disease_symptoms", matchedDisease?.symptoms)
putString("disease_causes", matchedDisease?.cause)
putString("disease_impact", matchedDisease?.impact)
putString("disease_solution", matchedDisease?.solution)
} else {
putString("disease_name", "Penyakit daun tidak terdeteksi")
putString("disease_description", "-")
putString("disease_symptoms", "-")
putString("disease_causes", "-")
putString("disease_impact", "-")
putString("disease_solution", "-")
}
putString("image_uri", imageUri.toString())
putString("confidence_text", confidenceText)
}
// Navigasi ke DiseaseDetailFragment
val noteFragment = DiseaseDetailFragment().apply {
arguments = bundle
}
requireActivity().supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, noteFragment)
.addToBackStack(null)
.commit()
}
override fun onDestroyView() {
super.onDestroyView()
handler.removeCallbacks(updateNetworkStatusRunnable)
_binding = null
}
}

View File

@ -0,0 +1,73 @@
package com.example.tomatoleafcare.ui.history
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.fragment.app.Fragment
import com.example.tomatoleafcare.R
import com.example.tomatoleafcare.repository.DiseaseRepository
import com.example.tomatoleafcare.model.History
import com.example.tomatoleafcare.ui.home.MainActivity
import com.squareup.picasso.Picasso
class HistoryDetailFragment : Fragment() {
private var history: History? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.history_detail_fragment, container, false)
(activity as? MainActivity)?.showBottomNav(false)
val btnBack = view.findViewById<ImageView>(R.id.btnBack)
btnBack.setOnClickListener {
requireActivity().onBackPressedDispatcher.onBackPressed()
}
history = arguments?.getParcelable<History>("history") as? History
history?.let {
showDetails(view, it)
}
return view
}
private fun showDetails(view: View, history: History) {
val detailDiseaseName = view.findViewById<TextView>(R.id.detailDiseaseName)
val detailDiseaseCauses = view.findViewById<TextView>(R.id.detailDiseaseCauses)
val detailDiseaseSymptoms = view.findViewById<TextView>(R.id.detailDiseaseSymptoms)
val detailDiseaseImpact = view.findViewById<TextView>(R.id.detailDiseaseImpact)
val detailDiseaseSolution = view.findViewById<TextView>(R.id.detailDiseaseSolution)
val detailDiseaseImage = view.findViewById<ImageView>(R.id.detailDiseaseImage)
Picasso.get().load(history.imagePath).into(detailDiseaseImage)
detailDiseaseName.text = history.diseaseName
val matchedDisease = DiseaseRepository.findDiseaseByName(history.diseaseName)
matchedDisease?.let {
detailDiseaseCauses.text = it.cause
detailDiseaseSymptoms.text = it.symptoms
detailDiseaseImpact.text = it.impact
detailDiseaseSolution.text = it.solution
} ?: run {
detailDiseaseCauses.text = "-"
detailDiseaseSymptoms.text = "-"
detailDiseaseImpact.text = "-"
detailDiseaseSolution.text = "-"
}
}
override fun onDestroyView() {
super.onDestroyView()
(activity as? MainActivity)?.showBottomNav(true)
}
}

View File

@ -0,0 +1,64 @@
package com.example.tomatoleafcare.ui.history
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.tomatoleafcare.R
import com.example.tomatoleafcare.ui.adapter.HistoryAdapter
import com.example.tomatoleafcare.viewmodel.HistoryViewModel
class HistoryFragment : Fragment() {
private lateinit var recyclerView: RecyclerView
private lateinit var historyAdapter: HistoryAdapter
private val viewModel: HistoryViewModel by viewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.history_fragment, container, false)
recyclerView = view.findViewById(R.id.recyclerViewHistory)
recyclerView.layoutManager = LinearLayoutManager(requireContext())
historyAdapter = HistoryAdapter(
context = requireContext(),
historyList = listOf(),
onItemClick = { history ->
val bundle = Bundle()
bundle.putParcelable("history", history)
val detailFragment = HistoryDetailFragment().apply {
arguments = bundle
}
requireActivity().supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, detailFragment)
.addToBackStack(null)
.commit()
},
onDeleteClick = { item ->
viewModel.deleteHistoryById(item.id.toInt())
}
)
recyclerView.adapter = historyAdapter
observeViewModel()
return view
}
private fun observeViewModel() {
viewModel.historyList.observe(viewLifecycleOwner, Observer { list ->
historyAdapter.updateData(list)
})
}
}

View File

@ -0,0 +1,14 @@
package com.example.tomatoleafcare.ui.home
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.example.tomatoleafcare.R
class CardSlide1Fragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.card_slide_1, container, false)
}
}

View File

@ -0,0 +1,14 @@
package com.example.tomatoleafcare.ui.home
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.example.tomatoleafcare.R
class CardSlide2Fragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.card_slide_2, container, false)
}
}

View File

@ -0,0 +1,123 @@
package com.example.tomatoleafcare.ui.home
import android.graphics.Paint
import android.graphics.Rect
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import com.example.tomatoleafcare.DiseaseDetailFragment
import com.example.tomatoleafcare.R
import com.example.tomatoleafcare.adapter.DiseaseAdapter
import com.example.tomatoleafcare.adapter.SliderAdapter
import com.example.tomatoleafcare.model.Disease
import com.example.tomatoleafcare.repository.DiseaseRepository
import com.example.tomatoleafcare.ui.note.NoteFragment
import com.google.android.material.bottomnavigation.BottomNavigationView
class HomeFragment : Fragment() {
private lateinit var recyclerView: RecyclerView
private lateinit var adapter: DiseaseAdapter
private lateinit var viewPager: ViewPager2
private val sliderHandler = Handler(Looper.getMainLooper())
private val sliderRunnable = object : Runnable {
override fun run() {
val itemCount = viewPager.adapter?.itemCount ?: 0
if (itemCount > 0) {
val nextItem = (viewPager.currentItem + 1) % itemCount
viewPager.setCurrentItem(nextItem, true)
sliderHandler.postDelayed(this, 10000)
}
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.home_fragment, container, false)
val classList = DiseaseRepository.classList.filter { it.name != "Tanaman Sehat" }
val topThreeDiseases = classList.take(3)
viewPager = view.findViewById(R.id.viewPager)
viewPager.adapter = SliderAdapter(this)
val space = resources.getDimensionPixelSize(R.dimen.slider_gap)
viewPager.addItemDecoration(SliderItemDecoration(space))
recyclerView = view.findViewById(R.id.recyclerView)
recyclerView.layoutManager = LinearLayoutManager(requireContext())
val seeMoreText: TextView = view.findViewById(R.id.seeMoreText)
seeMoreText.paintFlags = seeMoreText.paintFlags or Paint.UNDERLINE_TEXT_FLAG
seeMoreText.setOnClickListener {
val noteFragment = NoteFragment()
requireActivity().supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, noteFragment)
.addToBackStack(null)
.commit()
val bottomNavigationView = requireActivity().findViewById<BottomNavigationView>(R.id.bottomNavigationView)
bottomNavigationView.selectedItemId = R.id.navigation_note
}
adapter = DiseaseAdapter(topThreeDiseases, object : DiseaseAdapter.OnItemClickListener {
override fun onItemClick(disease: Disease) {
val detailFragment = DiseaseDetailFragment().apply {
arguments = Bundle().apply {
putString("disease_name", disease.name)
putString("disease_description", disease.description)
putString("disease_symptoms", disease.symptoms)
putString("disease_causes", disease.cause)
putString("disease_impact", disease.impact)
putString("disease_solution", disease.solution)
putInt("disease_image", disease.imageResId)
}
}
requireActivity().supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, detailFragment)
.addToBackStack(null)
.commit()
}
})
recyclerView.adapter = adapter
return view
}
override fun onResume() {
super.onResume()
sliderHandler.postDelayed(sliderRunnable, 1000)
}
override fun onPause() {
super.onPause()
sliderHandler.removeCallbacks(sliderRunnable)
}
class SliderItemDecoration(private val space: Int) : RecyclerView.ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
super.getItemOffsets(outRect, view, parent, state)
outRect.left = space
outRect.right = space
}
}
}

View File

@ -0,0 +1,49 @@
package com.example.tomatoleafcare.ui.home
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import com.example.tomatoleafcare.R
import com.example.tomatoleafcare.databinding.ActivityMainBinding
import com.example.tomatoleafcare.ui.note.NoteFragment
import com.example.tomatoleafcare.ui.camera.CameraFragment
import com.example.tomatoleafcare.ui.history.HistoryFragment
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
if (savedInstanceState == null) {
replaceFragment(HomeFragment())
}
binding.bottomNavigationView.setOnItemSelectedListener { item ->
when (item.itemId) {
R.id.navigation_home -> replaceFragment(HomeFragment())
R.id.navigation_camera -> replaceFragment(CameraFragment())
R.id.navigation_note -> replaceFragment(NoteFragment())
R.id.navigation_history -> replaceFragment(HistoryFragment())
}
true
}
}
fun showBottomNav(show: Boolean) {
val bottomNav = findViewById<View>(R.id.bottomNavigationView)
bottomNav.visibility = if (show) View.VISIBLE else View.GONE
}
private fun replaceFragment(fragment: Fragment) {
supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, fragment)
.commit()
}
}

View File

@ -0,0 +1,104 @@
package com.example.tomatoleafcare
import android.app.AlertDialog
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageButton
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Observer
import com.example.tomatoleafcare.ui.home.MainActivity
import com.example.tomatoleafcare.viewmodel.DiseaseViewModel
import com.google.android.material.imageview.ShapeableImageView
class DiseaseDetailFragment : Fragment() {
private val diseaseViewModel: DiseaseViewModel by activityViewModels()
private lateinit var imageView: ShapeableImageView
private lateinit var nameTextView: TextView
private lateinit var causesTextView: TextView
private lateinit var symptomsTextView: TextView
private lateinit var impactTextView: TextView
private lateinit var solutionTextView: TextView
private lateinit var backButton: ImageButton
private lateinit var infoConfidenceButton: ImageButton
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.disease_detail_fragment, container, false)
(activity as? MainActivity)?.showBottomNav(false)
imageView = view.findViewById(R.id.detailDiseaseImage)
nameTextView = view.findViewById(R.id.detailDiseaseName)
causesTextView = view.findViewById(R.id.detailDiseaseCauses)
symptomsTextView = view.findViewById(R.id.detailDiseaseSymptoms)
impactTextView = view.findViewById(R.id.detailDiseaseImpact)
solutionTextView = view.findViewById(R.id.detailDiseaseSolution)
backButton = view.findViewById(R.id.btnBack)
infoConfidenceButton = view.findViewById(R.id.infoConfidenceButton)
val diseaseName = arguments?.getString("disease_name")
val imageUriString = arguments?.getString("image_uri")
val confidenceText = arguments?.getString("confidence_text")
if (!imageUriString.isNullOrEmpty()) {
val imageUri = Uri.parse(imageUriString)
imageView.setImageURI(imageUri)
}
if (diseaseName?.trim()?.lowercase() == "penyakit daun tidak terdeteksi") {
// Jangan load data dari ViewModel
nameTextView.text = "Tidak terdeteksi"
causesTextView.text = "-"
symptomsTextView.text = "-"
impactTextView.text = "-"
solutionTextView.text = "-"
} else {
// Load dan tampilkan data penyakit
diseaseViewModel.loadDiseaseByName(diseaseName ?: "")
diseaseViewModel.disease.observe(viewLifecycleOwner, Observer { disease ->
if (disease != null) {
nameTextView.text = disease.name
causesTextView.text = disease.cause
symptomsTextView.text = disease.symptoms
impactTextView.text = disease.impact
solutionTextView.text = disease.solution
if (imageUriString.isNullOrEmpty()) {
imageView.setImageResource(disease.imageResId)
}
}
})
}
infoConfidenceButton.setOnClickListener {
AlertDialog.Builder(requireContext())
.setTitle("Confidence per Label")
.setMessage(confidenceText ?: "Confidence tidak tersedia.")
.show()
}
backButton.setOnClickListener {
requireActivity().supportFragmentManager.popBackStack()
}
return view
}
override fun onDestroyView() {
super.onDestroyView()
(activity as? MainActivity)?.showBottomNav(true)
diseaseViewModel.clearDisease()
}
}

View File

@ -0,0 +1,50 @@
package com.example.tomatoleafcare.ui.note
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.tomatoleafcare.DiseaseDetailFragment
import com.example.tomatoleafcare.R
import com.example.tomatoleafcare.adapter.DiseaseAdapter
import com.example.tomatoleafcare.repository.DiseaseRepository
import com.example.tomatoleafcare.model.Disease
import com.example.tomatoleafcare.viewmodel.DiseaseViewModel
class NoteFragment : Fragment() {
private lateinit var recyclerView: RecyclerView
private lateinit var adapter: DiseaseAdapter
private val viewModel: DiseaseViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.note_fragment, container, false)
val classList = DiseaseRepository.classList.filter { it.name != "Tanaman Sehat" }
recyclerView = view.findViewById(R.id.recyclerViewNote)
recyclerView.layoutManager = LinearLayoutManager(requireContext())
adapter = DiseaseAdapter(classList, object : DiseaseAdapter.OnItemClickListener {
override fun onItemClick(disease: Disease) {
viewModel.loadDiseaseByName(disease.name)
requireActivity().supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, DiseaseDetailFragment())
.addToBackStack(null)
.commit()
}
})
recyclerView.adapter = adapter
return view
}
}

View File

@ -0,0 +1,21 @@
package com.example.tomatoleafcare.ui.splash
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import androidx.appcompat.app.AppCompatActivity
import com.example.tomatoleafcare.R
import com.example.tomatoleafcare.ui.home.MainActivity
class SplashActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.splash_screen)
Handler(Looper.getMainLooper()).postDelayed({
startActivity(Intent(this, MainActivity::class.java))
finish()
}, 2000)
}
}

View File

@ -0,0 +1,11 @@
package com.example.tomatoleafcare.ui.theme
import androidx.compose.ui.graphics.Color
val Purple80 = Color(0xFFD0BCFF)
val PurpleGrey80 = Color(0xFFCCC2DC)
val Pink80 = Color(0xFFEFB8C8)
val Purple40 = Color(0xFF6650a4)
val PurpleGrey40 = Color(0xFF625b71)
val Pink40 = Color(0xFF7D5260)

View File

@ -0,0 +1,58 @@
package com.example.tomatoleafcare.ui.theme
import android.app.Activity
import android.os.Build
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
private val DarkColorScheme = darkColorScheme(
primary = Purple80,
secondary = PurpleGrey80,
tertiary = Pink80
)
private val LightColorScheme = lightColorScheme(
primary = Purple40,
secondary = PurpleGrey40,
tertiary = Pink40
/* Other default colors to override
background = Color(0xFFFFFBFE),
surface = Color(0xFFFFFBFE),
onPrimary = Color.White,
onSecondary = Color.White,
onTertiary = Color.White,
onBackground = Color(0xFF1C1B1F),
onSurface = Color(0xFF1C1B1F),
*/
)
@Composable
fun TomatoLeafCareTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
// Dynamic color is available on Android 12+
dynamicColor: Boolean = true,
content: @Composable () -> Unit
) {
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
}
darkTheme -> DarkColorScheme
else -> LightColorScheme
}
MaterialTheme(
colorScheme = colorScheme,
typography = Typography,
content = content
)
}

View File

@ -0,0 +1,34 @@
package com.example.tomatoleafcare.ui.theme
import androidx.compose.material3.Typography
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp
// Set of Material typography styles to start with
val Typography = Typography(
bodyLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontSize = 16.sp,
lineHeight = 24.sp,
letterSpacing = 0.5.sp
)
/* Other default text styles to override
titleLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontSize = 22.sp,
lineHeight = 28.sp,
letterSpacing = 0.sp
),
labelSmall = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Medium,
fontSize = 11.sp,
lineHeight = 16.sp,
letterSpacing = 0.5.sp
)
*/
)

View File

@ -0,0 +1,25 @@
package com.example.tomatoleafcare.viewmodel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.example.tomatoleafcare.model.Disease
import com.example.tomatoleafcare.repository.DiseaseRepository
class DiseaseViewModel : ViewModel() {
private val _disease = MutableLiveData<Disease?>()
val disease: MutableLiveData<Disease?> get() = _disease
fun loadDiseaseByName(name: String) {
val result = DiseaseRepository.findDiseaseByName(name)
result?.let {
_disease.value = it
}
}
fun clearDisease() {
_disease.value = null
}
}

View File

@ -0,0 +1,37 @@
package com.example.tomatoleafcare.viewmodel
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.example.tomatoleafcare.helper.HistoryDatabaseHelper
import com.example.tomatoleafcare.model.History
class HistoryViewModel(application: Application) : AndroidViewModel(application) {
private val dbHelper = HistoryDatabaseHelper(application)
private val _historyList = MutableLiveData<List<History>>()
val historyList: LiveData<List<History>> get() = _historyList
init {
loadAllHistory()
}
fun loadAllHistory() {
val allHistory = dbHelper.getAllHistory()
_historyList.postValue(allHistory)
}
fun deleteHistoryById(id: Int) {
val success = dbHelper.deleteHistory(id.toLong())
if (success) {
loadAllHistory()
}
}
fun insertHistory(item: History) {
dbHelper.insertHistory(item)
loadAllHistory()
}
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/active_color" android:state_checked="true"/>
<item android:color="@color/inactive_color"/>
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

View File

@ -0,0 +1,4 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
<solid android:color="#0000FF"/> <!-- Biru -->
<size android:width="16dp" android:height="16dp"/>
</shape>

Some files were not shown because too many files have changed in this diff Show More