Compare commits
4 Commits
87195aabf1
...
0.3.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
1ca6b33882
|
|||
|
bd6b5cc652
|
|||
|
6e16a30429
|
|||
|
66fdef78d9
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.gradle/8.9/checksums/checksums.lock
Normal file
BIN
.gradle/8.9/checksums/checksums.lock
Normal file
Binary file not shown.
BIN
.gradle/8.9/checksums/md5-checksums.bin
Normal file
BIN
.gradle/8.9/checksums/md5-checksums.bin
Normal file
Binary file not shown.
BIN
.gradle/8.9/checksums/sha1-checksums.bin
Normal file
BIN
.gradle/8.9/checksums/sha1-checksums.bin
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,769 @@
|
|||||||
|
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 CoilLibraryAccessors laccForCoilLibraryAccessors = new CoilLibraryAccessors(owner);
|
||||||
|
private final KotlinxLibraryAccessors laccForKotlinxLibraryAccessors = new KotlinxLibraryAccessors(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");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependency provider for <b>mpandroidchart</b> with <b>com.github.PhilJay:MPAndroidChart</b> coordinates and
|
||||||
|
* with version <b>v3.1.0</b>
|
||||||
|
* <p>
|
||||||
|
* This dependency was declared in catalog libs.versions.toml
|
||||||
|
*/
|
||||||
|
public Provider<MinimalExternalModuleDependency> getMpandroidchart() {
|
||||||
|
return create("mpandroidchart");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Group of libraries at <b>androidx</b>
|
||||||
|
*/
|
||||||
|
public AndroidxLibraryAccessors getAndroidx() {
|
||||||
|
return laccForAndroidxLibraryAccessors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Group of libraries at <b>coil</b>
|
||||||
|
*/
|
||||||
|
public CoilLibraryAccessors getCoil() {
|
||||||
|
return laccForCoilLibraryAccessors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Group of libraries at <b>kotlinx</b>
|
||||||
|
*/
|
||||||
|
public KotlinxLibraryAccessors getKotlinx() {
|
||||||
|
return laccForKotlinxLibraryAccessors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 AndroidxNavigationLibraryAccessors laccForAndroidxNavigationLibraryAccessors = new AndroidxNavigationLibraryAccessors(owner);
|
||||||
|
private final AndroidxRoomLibraryAccessors laccForAndroidxRoomLibraryAccessors = new AndroidxRoomLibraryAccessors(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.navigation</b>
|
||||||
|
*/
|
||||||
|
public AndroidxNavigationLibraryAccessors getNavigation() {
|
||||||
|
return laccForAndroidxNavigationLibraryAccessors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Group of libraries at <b>androidx.room</b>
|
||||||
|
*/
|
||||||
|
public AndroidxRoomLibraryAccessors getRoom() {
|
||||||
|
return laccForAndroidxRoomLibraryAccessors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
private final AndroidxLifecycleViewmodelLibraryAccessors laccForAndroidxLifecycleViewmodelLibraryAccessors = new AndroidxLifecycleViewmodelLibraryAccessors(owner);
|
||||||
|
|
||||||
|
public AndroidxLifecycleLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Group of libraries at <b>androidx.lifecycle.runtime</b>
|
||||||
|
*/
|
||||||
|
public AndroidxLifecycleRuntimeLibraryAccessors getRuntime() {
|
||||||
|
return laccForAndroidxLifecycleRuntimeLibraryAccessors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Group of libraries at <b>androidx.lifecycle.viewmodel</b>
|
||||||
|
*/
|
||||||
|
public AndroidxLifecycleViewmodelLibraryAccessors getViewmodel() {
|
||||||
|
return laccForAndroidxLifecycleViewmodelLibraryAccessors;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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 AndroidxLifecycleViewmodelLibraryAccessors extends SubDependencyFactory {
|
||||||
|
|
||||||
|
public AndroidxLifecycleViewmodelLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependency provider for <b>compose</b> with <b>androidx.lifecycle:lifecycle-viewmodel-compose</b> coordinates and
|
||||||
|
* with version reference <b>viewmodel</b>
|
||||||
|
* <p>
|
||||||
|
* This dependency was declared in catalog libs.versions.toml
|
||||||
|
*/
|
||||||
|
public Provider<MinimalExternalModuleDependency> getCompose() {
|
||||||
|
return create("androidx.lifecycle.viewmodel.compose");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class AndroidxNavigationLibraryAccessors extends SubDependencyFactory {
|
||||||
|
|
||||||
|
public AndroidxNavigationLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependency provider for <b>compose</b> with <b>androidx.navigation:navigation-compose</b> coordinates and
|
||||||
|
* with version reference <b>navigation</b>
|
||||||
|
* <p>
|
||||||
|
* This dependency was declared in catalog libs.versions.toml
|
||||||
|
*/
|
||||||
|
public Provider<MinimalExternalModuleDependency> getCompose() {
|
||||||
|
return create("androidx.navigation.compose");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class AndroidxRoomLibraryAccessors extends SubDependencyFactory {
|
||||||
|
|
||||||
|
public AndroidxRoomLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependency provider for <b>compiler</b> with <b>androidx.room:room-compiler</b> coordinates and
|
||||||
|
* with version reference <b>room</b>
|
||||||
|
* <p>
|
||||||
|
* This dependency was declared in catalog libs.versions.toml
|
||||||
|
*/
|
||||||
|
public Provider<MinimalExternalModuleDependency> getCompiler() {
|
||||||
|
return create("androidx.room.compiler");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependency provider for <b>ktx</b> with <b>androidx.room:room-ktx</b> coordinates and
|
||||||
|
* with version reference <b>room</b>
|
||||||
|
* <p>
|
||||||
|
* This dependency was declared in catalog libs.versions.toml
|
||||||
|
*/
|
||||||
|
public Provider<MinimalExternalModuleDependency> getKtx() {
|
||||||
|
return create("androidx.room.ktx");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependency provider for <b>runtime</b> with <b>androidx.room:room-runtime</b> coordinates and
|
||||||
|
* with version reference <b>room</b>
|
||||||
|
* <p>
|
||||||
|
* This dependency was declared in catalog libs.versions.toml
|
||||||
|
*/
|
||||||
|
public Provider<MinimalExternalModuleDependency> getRuntime() {
|
||||||
|
return create("androidx.room.runtime");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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 CoilLibraryAccessors extends SubDependencyFactory {
|
||||||
|
|
||||||
|
public CoilLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependency provider for <b>compose</b> with <b>io.coil-kt:coil-compose</b> coordinates and
|
||||||
|
* with version reference <b>coil</b>
|
||||||
|
* <p>
|
||||||
|
* This dependency was declared in catalog libs.versions.toml
|
||||||
|
*/
|
||||||
|
public Provider<MinimalExternalModuleDependency> getCompose() {
|
||||||
|
return create("coil.compose");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class KotlinxLibraryAccessors extends SubDependencyFactory {
|
||||||
|
private final KotlinxCoroutinesLibraryAccessors laccForKotlinxCoroutinesLibraryAccessors = new KotlinxCoroutinesLibraryAccessors(owner);
|
||||||
|
private final KotlinxSerializationLibraryAccessors laccForKotlinxSerializationLibraryAccessors = new KotlinxSerializationLibraryAccessors(owner);
|
||||||
|
|
||||||
|
public KotlinxLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Group of libraries at <b>kotlinx.coroutines</b>
|
||||||
|
*/
|
||||||
|
public KotlinxCoroutinesLibraryAccessors getCoroutines() {
|
||||||
|
return laccForKotlinxCoroutinesLibraryAccessors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Group of libraries at <b>kotlinx.serialization</b>
|
||||||
|
*/
|
||||||
|
public KotlinxSerializationLibraryAccessors getSerialization() {
|
||||||
|
return laccForKotlinxSerializationLibraryAccessors;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class KotlinxCoroutinesLibraryAccessors extends SubDependencyFactory {
|
||||||
|
|
||||||
|
public KotlinxCoroutinesLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependency provider for <b>android</b> with <b>org.jetbrains.kotlinx:kotlinx-coroutines-android</b> coordinates and
|
||||||
|
* with version reference <b>kotlinxCoroutines</b>
|
||||||
|
* <p>
|
||||||
|
* This dependency was declared in catalog libs.versions.toml
|
||||||
|
*/
|
||||||
|
public Provider<MinimalExternalModuleDependency> getAndroid() {
|
||||||
|
return create("kotlinx.coroutines.android");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class KotlinxSerializationLibraryAccessors extends SubDependencyFactory {
|
||||||
|
|
||||||
|
public KotlinxSerializationLibraryAccessors(AbstractExternalDependencyFactory owner) { super(owner); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependency provider for <b>json</b> with <b>org.jetbrains.kotlinx:kotlinx-serialization-json</b> coordinates and
|
||||||
|
* with version reference <b>kotlinxSerialization</b>
|
||||||
|
* <p>
|
||||||
|
* This dependency was declared in catalog libs.versions.toml
|
||||||
|
*/
|
||||||
|
public Provider<MinimalExternalModuleDependency> getJson() {
|
||||||
|
return create("kotlinx.serialization.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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.9.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> getAgp() { return getVersion("agp"); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Version alias <b>coil</b> with value <b>2.7.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> getCoil() { return getVersion("coil"); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Version alias <b>composeBom</b> with value <b>2024.09.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.7.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> 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.3.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> getJunitVersion() { return getVersion("junitVersion"); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Version alias <b>kotlin</b> with value <b>2.0.21</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>kotlinxCoroutines</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> getKotlinxCoroutines() { return getVersion("kotlinxCoroutines"); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Version alias <b>kotlinxSerialization</b> with value <b>1.7.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> getKotlinxSerialization() { return getVersion("kotlinxSerialization"); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Version alias <b>ksp</b> with value <b>2.0.21-1.0.25</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> getKsp() { return getVersion("ksp"); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Version alias <b>lifecycleRuntimeKtx</b> with value <b>2.9.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> getLifecycleRuntimeKtx() { return getVersion("lifecycleRuntimeKtx"); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Version alias <b>navigation</b> with value <b>2.8.4</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> getNavigation() { return getVersion("navigation"); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Version alias <b>room</b> with value <b>2.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> getRoom() { return getVersion("room"); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Version alias <b>viewmodel</b> with value <b>2.9.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> getViewmodel() { return getVersion("viewmodel"); }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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 KotlinPluginAccessors paccForKotlinPluginAccessors = new KotlinPluginAccessors(providers, config);
|
||||||
|
|
||||||
|
public PluginAccessors(ProviderFactory providers, DefaultVersionCatalog config) { super(providers, config); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin provider for <b>ksp</b> with plugin id <b>com.google.devtools.ksp</b> and
|
||||||
|
* with version reference <b>ksp</b>
|
||||||
|
* <p>
|
||||||
|
* This plugin was declared in catalog libs.versions.toml
|
||||||
|
*/
|
||||||
|
public Provider<PluginDependency> getKsp() { return createPlugin("ksp"); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Group of plugins at <b>plugins.android</b>
|
||||||
|
*/
|
||||||
|
public AndroidPluginAccessors getAndroid() {
|
||||||
|
return paccForAndroidPluginAccessors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Group of plugins at <b>plugins.kotlin</b>
|
||||||
|
*/
|
||||||
|
public KotlinPluginAccessors getKotlin() {
|
||||||
|
return paccForKotlinPluginAccessors;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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 KotlinPluginAccessors extends PluginFactory {
|
||||||
|
|
||||||
|
public KotlinPluginAccessors(ProviderFactory providers, DefaultVersionCatalog config) { super(providers, config); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin provider for <b>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("kotlin.android"); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin provider for <b>kotlin.compose</b> with plugin id <b>org.jetbrains.kotlin.plugin.compose</b> and
|
||||||
|
* with version reference <b>kotlin</b>
|
||||||
|
* <p>
|
||||||
|
* This plugin was declared in catalog libs.versions.toml
|
||||||
|
*/
|
||||||
|
public Provider<PluginDependency> getCompose() { return createPlugin("kotlin.compose"); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin provider for <b>kotlin.serialization</b> with plugin id <b>org.jetbrains.kotlin.plugin.serialization</b> and
|
||||||
|
* with version reference <b>kotlin</b>
|
||||||
|
* <p>
|
||||||
|
* This plugin was declared in catalog libs.versions.toml
|
||||||
|
*/
|
||||||
|
public Provider<PluginDependency> getSerialization() { return createPlugin("kotlin.serialization"); }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
0
.gradle/8.9/dependencies-accessors/gc.properties
Normal file
0
.gradle/8.9/dependencies-accessors/gc.properties
Normal file
BIN
.gradle/8.9/fileChanges/last-build.bin
Normal file
BIN
.gradle/8.9/fileChanges/last-build.bin
Normal file
Binary file not shown.
BIN
.gradle/8.9/fileHashes/fileHashes.bin
Normal file
BIN
.gradle/8.9/fileHashes/fileHashes.bin
Normal file
Binary file not shown.
BIN
.gradle/8.9/fileHashes/fileHashes.lock
Normal file
BIN
.gradle/8.9/fileHashes/fileHashes.lock
Normal file
Binary file not shown.
BIN
.gradle/8.9/fileHashes/resourceHashesCache.bin
Normal file
BIN
.gradle/8.9/fileHashes/resourceHashesCache.bin
Normal file
Binary file not shown.
0
.gradle/8.9/gc.properties
Normal file
0
.gradle/8.9/gc.properties
Normal file
Binary file not shown.
@@ -1,2 +1,2 @@
|
|||||||
#Fri Aug 15 12:27:13 MDT 2025
|
#Fri Aug 15 14:37:16 MDT 2025
|
||||||
gradle.version=8.11.1
|
gradle.version=8.11.1
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
3
.idea/gradle.xml
generated
3
.idea/gradle.xml
generated
@@ -1,11 +1,12 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
|
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||||
<component name="GradleSettings">
|
<component name="GradleSettings">
|
||||||
<option name="linkedExternalProjectsSettings">
|
<option name="linkedExternalProjectsSettings">
|
||||||
<GradleProjectSettings>
|
<GradleProjectSettings>
|
||||||
<option name="testRunner" value="CHOOSE_PER_TEST" />
|
<option name="testRunner" value="CHOOSE_PER_TEST" />
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
|
<option name="gradleJvm" value="#JAVA_HOME" />
|
||||||
<option name="modules">
|
<option name="modules">
|
||||||
<set>
|
<set>
|
||||||
<option value="$PROJECT_DIR$" />
|
<option value="$PROJECT_DIR$" />
|
||||||
|
|||||||
7
.idea/misc.xml
generated
7
.idea/misc.xml
generated
@@ -1,10 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="temurin-21" project-jdk-type="JavaSDK" />
|
||||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
|
||||||
</component>
|
|
||||||
<component name="ProjectType">
|
|
||||||
<option name="id" value="Android" />
|
|
||||||
</component>
|
|
||||||
</project>
|
</project>
|
||||||
@@ -14,8 +14,8 @@ android {
|
|||||||
applicationId = "com.atridad.openclimb"
|
applicationId = "com.atridad.openclimb"
|
||||||
minSdk = 31
|
minSdk = 31
|
||||||
targetSdk = 35
|
targetSdk = 35
|
||||||
versionCode = 1
|
versionCode = 3
|
||||||
versionName = "0.1.0"
|
versionName = "0.3.0"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
app/release/app-release.apk
Normal file
BIN
app/release/app-release.apk
Normal file
Binary file not shown.
BIN
app/release/baselineProfiles/0/app-release.dm
Normal file
BIN
app/release/baselineProfiles/0/app-release.dm
Normal file
Binary file not shown.
BIN
app/release/baselineProfiles/1/app-release.dm
Normal file
BIN
app/release/baselineProfiles/1/app-release.dm
Normal file
Binary file not shown.
37
app/release/output-metadata.json
Normal file
37
app/release/output-metadata.json
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"artifactType": {
|
||||||
|
"type": "APK",
|
||||||
|
"kind": "Directory"
|
||||||
|
},
|
||||||
|
"applicationId": "com.atridad.openclimb",
|
||||||
|
"variantName": "release",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"type": "SINGLE",
|
||||||
|
"filters": [],
|
||||||
|
"attributes": [],
|
||||||
|
"versionCode": 3,
|
||||||
|
"versionName": "0.3.0",
|
||||||
|
"outputFile": "app-release.apk"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"elementType": "File",
|
||||||
|
"baselineProfiles": [
|
||||||
|
{
|
||||||
|
"minApi": 28,
|
||||||
|
"maxApi": 30,
|
||||||
|
"baselineProfiles": [
|
||||||
|
"baselineProfiles/1/app-release.dm"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"minApi": 31,
|
||||||
|
"maxApi": 2147483647,
|
||||||
|
"baselineProfiles": [
|
||||||
|
"baselineProfiles/0/app-release.dm"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"minSdkVersionForDexing": 31
|
||||||
|
}
|
||||||
@@ -5,5 +5,13 @@ import kotlinx.serialization.Serializable
|
|||||||
@Serializable
|
@Serializable
|
||||||
enum class ClimbType {
|
enum class ClimbType {
|
||||||
ROPE,
|
ROPE,
|
||||||
BOULDER
|
BOULDER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the display name for the UI
|
||||||
|
*/
|
||||||
|
fun getDisplayName(): String = when (this) {
|
||||||
|
ROPE -> "Rope"
|
||||||
|
BOULDER -> "Bouldering"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,23 +4,68 @@ import kotlinx.serialization.Serializable
|
|||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
enum class DifficultySystem {
|
enum class DifficultySystem {
|
||||||
// Rope climbing systems
|
|
||||||
YDS, // Yosemite Decimal System (5.1 - 5.15d)
|
|
||||||
FRENCH, // French system (3 - 9c+)
|
|
||||||
UIAA, // UIAA system (I - XII+)
|
|
||||||
BRITISH, // British system (Mod - E11)
|
|
||||||
|
|
||||||
// Bouldering systems
|
// Bouldering systems
|
||||||
V_SCALE, // V-Scale (VB - V17)
|
V_SCALE, // V-Scale (VB - V17)
|
||||||
FONT, // Fontainebleau (3 - 9A+)
|
FONT, // Fontainebleau (3 - 8C+)
|
||||||
|
|
||||||
|
// Rope climbing systems
|
||||||
|
YDS, // Yosemite Decimal System (5.0 - 5.15d)
|
||||||
|
|
||||||
// Custom system for gyms that use their own colors/naming
|
// Custom system for gyms that use their own colors/naming
|
||||||
CUSTOM
|
CUSTOM;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the display name for the UI
|
||||||
|
*/
|
||||||
|
fun getDisplayName(): String = when (this) {
|
||||||
|
V_SCALE -> "V Scale"
|
||||||
|
FONT -> "Font Scale"
|
||||||
|
YDS -> "YDS (Yosemite)"
|
||||||
|
CUSTOM -> "Custom"
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if this system is for bouldering
|
||||||
|
*/
|
||||||
|
fun isBoulderingSystem(): Boolean = when (this) {
|
||||||
|
V_SCALE, FONT -> true
|
||||||
|
YDS -> false
|
||||||
|
CUSTOM -> true // Custom is available for all
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if this system is for rope climbing
|
||||||
|
*/
|
||||||
|
fun isRopeSystem(): Boolean = when (this) {
|
||||||
|
YDS -> true
|
||||||
|
V_SCALE, FONT -> false
|
||||||
|
CUSTOM -> true // Custom is available for all
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get available grades for this difficulty system
|
||||||
|
*/
|
||||||
|
fun getAvailableGrades(): List<String> = when (this) {
|
||||||
|
V_SCALE -> listOf("VB", "V0", "V1", "V2", "V3", "V4", "V5", "V6", "V7", "V8", "V9", "V10", "V11", "V12", "V13", "V14", "V15", "V16", "V17")
|
||||||
|
FONT -> listOf("3", "4A", "4B", "4C", "5A", "5B", "5C", "6A", "6A+", "6B", "6B+", "6C", "6C+", "7A", "7A+", "7B", "7B+", "7C", "7C+", "8A", "8A+", "8B", "8B+", "8C", "8C+")
|
||||||
|
YDS -> listOf("5.0", "5.1", "5.2", "5.3", "5.4", "5.5", "5.6", "5.7", "5.8", "5.9", "5.10a", "5.10b", "5.10c", "5.10d", "5.11a", "5.11b", "5.11c", "5.11d", "5.12a", "5.12b", "5.12c", "5.12d", "5.13a", "5.13b", "5.13c", "5.13d", "5.14a", "5.14b", "5.14c", "5.14d", "5.15a", "5.15b", "5.15c", "5.15d")
|
||||||
|
CUSTOM -> emptyList() // Custom allows free text input
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
/**
|
||||||
|
* Get all difficulty systems available for a specific climb type
|
||||||
|
*/
|
||||||
|
fun getSystemsForClimbType(climbType: ClimbType): List<DifficultySystem> = when (climbType) {
|
||||||
|
ClimbType.BOULDER -> entries.filter { it.isBoulderingSystem() }
|
||||||
|
ClimbType.ROPE -> entries.filter { it.isRopeSystem() }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class DifficultyGrade(
|
data class DifficultyGrade(
|
||||||
val system: DifficultySystem,
|
val system: DifficultySystem,
|
||||||
val grade: String,
|
val grade: String,
|
||||||
val numericValue: Int // For comparison and analytics
|
val numericValue: Int
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ fun OpenClimbApp() {
|
|||||||
val navController = rememberNavController()
|
val navController = rememberNavController()
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val currentBackStackEntry by navController.currentBackStackEntryAsState()
|
val currentBackStackEntry by navController.currentBackStackEntryAsState()
|
||||||
val currentDestination = currentBackStackEntry?.destination?.route
|
|
||||||
|
|
||||||
val database = remember { OpenClimbDatabase.getDatabase(context) }
|
val database = remember { OpenClimbDatabase.getDatabase(context) }
|
||||||
val repository = remember { ClimbRepository(database, context) }
|
val repository = remember { ClimbRepository(database, context) }
|
||||||
@@ -247,17 +246,15 @@ fun OpenClimbBottomNavigation(navController: NavHostController) {
|
|||||||
selected = isSelected,
|
selected = isSelected,
|
||||||
onClick = {
|
onClick = {
|
||||||
navController.navigate(item.screen) {
|
navController.navigate(item.screen) {
|
||||||
// Pop up to the start destination of the graph to
|
// Clear the entire back stack and go to the selected tab's root screen
|
||||||
// avoid building up a large stack of destinations
|
popUpTo(0) {
|
||||||
// on the back stack as users select items
|
inclusive = true
|
||||||
popUpTo(Screen.Sessions) {
|
|
||||||
saveState = true
|
|
||||||
}
|
}
|
||||||
// Avoid multiple copies of the same destination when
|
// Avoid multiple copies of the same destination when
|
||||||
// reselecting the same item
|
// reselecting the same item
|
||||||
launchSingleTop = true
|
launchSingleTop = true
|
||||||
// Restore state when reselecting a previously selected item
|
// Don't restore state - always start fresh when switching tabs
|
||||||
restoreState = true
|
restoreState = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -47,6 +47,34 @@ fun AddEditGymScreen(
|
|||||||
|
|
||||||
val isEditing = gymId != null
|
val isEditing = gymId != null
|
||||||
|
|
||||||
|
// Calculate available difficulty systems based on selected climb types
|
||||||
|
val availableDifficultySystems = if (selectedClimbTypes.isEmpty()) {
|
||||||
|
emptyList()
|
||||||
|
} else {
|
||||||
|
selectedClimbTypes.flatMap { climbType ->
|
||||||
|
DifficultySystem.getSystemsForClimbType(climbType)
|
||||||
|
}.distinct()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset selected difficulty systems when available systems change
|
||||||
|
LaunchedEffect(availableDifficultySystems) {
|
||||||
|
selectedDifficultySystems = selectedDifficultySystems.filter { it in availableDifficultySystems }.toSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load existing gym data for editing
|
||||||
|
LaunchedEffect(gymId) {
|
||||||
|
if (gymId != null) {
|
||||||
|
val existingGym = viewModel.getGymById(gymId).first()
|
||||||
|
existingGym?.let { gym ->
|
||||||
|
name = gym.name
|
||||||
|
location = gym.location ?: ""
|
||||||
|
notes = gym.notes ?: ""
|
||||||
|
selectedClimbTypes = gym.supportedClimbTypes.toSet()
|
||||||
|
selectedDifficultySystems = gym.difficultySystems.toSet()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
@@ -59,20 +87,16 @@ fun AddEditGymScreen(
|
|||||||
actions = {
|
actions = {
|
||||||
TextButton(
|
TextButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
val gym = if (isEditing) {
|
val gym = Gym.create(name, location, selectedClimbTypes.toList(), selectedDifficultySystems.toList(), notes = notes)
|
||||||
Gym.create(name, location, selectedClimbTypes.toList(), selectedDifficultySystems.toList(), notes = notes)
|
|
||||||
} else {
|
|
||||||
Gym.create(name, location, selectedClimbTypes.toList(), selectedDifficultySystems.toList(), notes = notes)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isEditing) {
|
if (isEditing) {
|
||||||
viewModel.updateGym(gym)
|
viewModel.updateGym(gym.copy(id = gymId!!))
|
||||||
} else {
|
} else {
|
||||||
viewModel.addGym(gym)
|
viewModel.addGym(gym)
|
||||||
}
|
}
|
||||||
onNavigateBack()
|
onNavigateBack()
|
||||||
},
|
},
|
||||||
enabled = name.isNotBlank() && selectedClimbTypes.isNotEmpty()
|
enabled = name.isNotBlank() && selectedClimbTypes.isNotEmpty() && selectedDifficultySystems.isNotEmpty()
|
||||||
) {
|
) {
|
||||||
Text("Save")
|
Text("Save")
|
||||||
}
|
}
|
||||||
@@ -142,7 +166,7 @@ fun AddEditGymScreen(
|
|||||||
onCheckedChange = null
|
onCheckedChange = null
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.width(8.dp))
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
Text(climbType.name.lowercase().replaceFirstChar { it.uppercase() })
|
Text(climbType.getDisplayName())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -163,29 +187,38 @@ fun AddEditGymScreen(
|
|||||||
|
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
DifficultySystem.entries.forEach { system ->
|
if (selectedClimbTypes.isEmpty()) {
|
||||||
Row(
|
Text(
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
text = "Select climb types first to see available difficulty systems",
|
||||||
modifier = Modifier
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
.fillMaxWidth()
|
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
.selectable(
|
modifier = Modifier.padding(vertical = 8.dp)
|
||||||
selected = system in selectedDifficultySystems,
|
)
|
||||||
onClick = {
|
} else {
|
||||||
selectedDifficultySystems = if (system in selectedDifficultySystems) {
|
availableDifficultySystems.forEach { system ->
|
||||||
selectedDifficultySystems - system
|
Row(
|
||||||
} else {
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
selectedDifficultySystems + system
|
modifier = Modifier
|
||||||
}
|
.fillMaxWidth()
|
||||||
},
|
.selectable(
|
||||||
role = Role.Checkbox
|
selected = system in selectedDifficultySystems,
|
||||||
|
onClick = {
|
||||||
|
selectedDifficultySystems = if (system in selectedDifficultySystems) {
|
||||||
|
selectedDifficultySystems - system
|
||||||
|
} else {
|
||||||
|
selectedDifficultySystems + system
|
||||||
|
}
|
||||||
|
},
|
||||||
|
role = Role.Checkbox
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Checkbox(
|
||||||
|
checked = system in selectedDifficultySystems,
|
||||||
|
onCheckedChange = null
|
||||||
)
|
)
|
||||||
) {
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
Checkbox(
|
Text(system.getDisplayName())
|
||||||
checked = system in selectedDifficultySystems,
|
}
|
||||||
onCheckedChange = null
|
|
||||||
)
|
|
||||||
Spacer(modifier = Modifier.width(8.dp))
|
|
||||||
Text(system.name)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -244,6 +277,8 @@ fun AddEditProblemScreen(
|
|||||||
notes = p.notes ?: ""
|
notes = p.notes ?: ""
|
||||||
isActive = p.isActive
|
isActive = p.isActive
|
||||||
imagePaths = p.imagePaths
|
imagePaths = p.imagePaths
|
||||||
|
// Set the selected gym for the existing problem
|
||||||
|
selectedGym = gyms.find { it.id == p.gymId }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -254,8 +289,39 @@ fun AddEditProblemScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val availableDifficultySystems = selectedGym?.difficultySystems ?: DifficultySystem.entries.toList()
|
|
||||||
val availableClimbTypes = selectedGym?.supportedClimbTypes ?: ClimbType.entries.toList()
|
val availableClimbTypes = selectedGym?.supportedClimbTypes ?: ClimbType.entries.toList()
|
||||||
|
val availableDifficultySystems = DifficultySystem.getSystemsForClimbType(selectedClimbType).filter { system ->
|
||||||
|
selectedGym?.difficultySystems?.contains(system) ?: true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto-select climb type if there's only one available
|
||||||
|
LaunchedEffect(availableClimbTypes) {
|
||||||
|
if (availableClimbTypes.size == 1 && selectedClimbType != availableClimbTypes.first()) {
|
||||||
|
selectedClimbType = availableClimbTypes.first()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto-select or reset difficulty system based on climb type
|
||||||
|
LaunchedEffect(selectedClimbType, availableDifficultySystems) {
|
||||||
|
when {
|
||||||
|
// If current system is not compatible, select the first available one
|
||||||
|
selectedDifficultySystem !in availableDifficultySystems -> {
|
||||||
|
selectedDifficultySystem = availableDifficultySystems.firstOrNull() ?: DifficultySystem.CUSTOM
|
||||||
|
}
|
||||||
|
// If there's only one available system and nothing is selected, auto-select it
|
||||||
|
availableDifficultySystems.size == 1 && selectedDifficultySystem != availableDifficultySystems.first() -> {
|
||||||
|
selectedDifficultySystem = availableDifficultySystems.first()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset grade when difficulty system changes (unless it's a valid grade for the new system)
|
||||||
|
LaunchedEffect(selectedDifficultySystem) {
|
||||||
|
val availableGrades = selectedDifficultySystem.getAvailableGrades()
|
||||||
|
if (availableGrades.isNotEmpty() && difficultyGrade !in availableGrades) {
|
||||||
|
difficultyGrade = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
@@ -437,7 +503,7 @@ fun AddEditProblemScreen(
|
|||||||
availableClimbTypes.forEach { climbType ->
|
availableClimbTypes.forEach { climbType ->
|
||||||
FilterChip(
|
FilterChip(
|
||||||
onClick = { selectedClimbType = climbType },
|
onClick = { selectedClimbType = climbType },
|
||||||
label = { Text(climbType.name.lowercase().replaceFirstChar { it.uppercase() }) },
|
label = { Text(climbType.getDisplayName()) },
|
||||||
selected = selectedClimbType == climbType
|
selected = selectedClimbType == climbType
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -476,7 +542,7 @@ fun AddEditProblemScreen(
|
|||||||
items(availableDifficultySystems) { system ->
|
items(availableDifficultySystems) { system ->
|
||||||
FilterChip(
|
FilterChip(
|
||||||
onClick = { selectedDifficultySystem = system },
|
onClick = { selectedDifficultySystem = system },
|
||||||
label = { Text(system.name) },
|
label = { Text(system.getDisplayName()) },
|
||||||
selected = selectedDifficultySystem == system
|
selected = selectedDifficultySystem == system
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -484,23 +550,51 @@ fun AddEditProblemScreen(
|
|||||||
|
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
OutlinedTextField(
|
if (selectedDifficultySystem == DifficultySystem.CUSTOM) {
|
||||||
value = difficultyGrade,
|
OutlinedTextField(
|
||||||
onValueChange = { difficultyGrade = it },
|
value = difficultyGrade,
|
||||||
label = { Text("Grade *") },
|
onValueChange = { difficultyGrade = it },
|
||||||
modifier = Modifier.fillMaxWidth(),
|
label = { Text("Grade *") },
|
||||||
singleLine = true,
|
modifier = Modifier.fillMaxWidth(),
|
||||||
placeholder = {
|
singleLine = true,
|
||||||
Text(when (selectedDifficultySystem) {
|
placeholder = { Text("Enter custom grade") }
|
||||||
DifficultySystem.V_SCALE -> "e.g., V0, V4, V10"
|
)
|
||||||
DifficultySystem.FONT -> "e.g., 3, 6A+, 8B"
|
} else {
|
||||||
DifficultySystem.YDS -> "e.g., 5.8, 5.12a"
|
var expanded by remember { mutableStateOf(false) }
|
||||||
DifficultySystem.FRENCH -> "e.g., 6a, 7c+"
|
val availableGrades = selectedDifficultySystem.getAvailableGrades()
|
||||||
DifficultySystem.CUSTOM -> "Custom grade"
|
|
||||||
else -> "Enter grade"
|
ExposedDropdownMenuBox(
|
||||||
})
|
expanded = expanded,
|
||||||
|
onExpandedChange = { expanded = !expanded },
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
OutlinedTextField(
|
||||||
|
value = difficultyGrade,
|
||||||
|
onValueChange = { },
|
||||||
|
readOnly = true,
|
||||||
|
label = { Text("Grade *") },
|
||||||
|
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
|
||||||
|
colors = ExposedDropdownMenuDefaults.outlinedTextFieldColors(),
|
||||||
|
modifier = Modifier
|
||||||
|
.menuAnchor()
|
||||||
|
.fillMaxWidth()
|
||||||
|
)
|
||||||
|
ExposedDropdownMenu(
|
||||||
|
expanded = expanded,
|
||||||
|
onDismissRequest = { expanded = false }
|
||||||
|
) {
|
||||||
|
availableGrades.forEach { grade ->
|
||||||
|
DropdownMenuItem(
|
||||||
|
text = { Text(grade) },
|
||||||
|
onClick = {
|
||||||
|
difficultyGrade = grade
|
||||||
|
expanded = false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -617,6 +711,19 @@ fun AddEditSessionScreen(
|
|||||||
var attempts by remember { mutableStateOf(listOf<AttemptInput>()) }
|
var attempts by remember { mutableStateOf(listOf<AttemptInput>()) }
|
||||||
var showAddAttemptDialog by remember { mutableStateOf(false) }
|
var showAddAttemptDialog by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
// Load existing session data for editing
|
||||||
|
LaunchedEffect(sessionId) {
|
||||||
|
if (sessionId != null) {
|
||||||
|
val existingSession = viewModel.getSessionById(sessionId).first()
|
||||||
|
existingSession?.let { session ->
|
||||||
|
selectedGym = gyms.find { it.id == session.gymId }
|
||||||
|
sessionDate = session.date.split("T")[0] // Extract date part
|
||||||
|
duration = session.duration?.toString() ?: ""
|
||||||
|
sessionNotes = session.notes ?: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LaunchedEffect(gymId, gyms) {
|
LaunchedEffect(gymId, gyms) {
|
||||||
if (gymId != null && selectedGym == null) {
|
if (gymId != null && selectedGym == null) {
|
||||||
selectedGym = gyms.find { it.id == gymId }
|
selectedGym = gyms.find { it.id == gymId }
|
||||||
@@ -830,7 +937,7 @@ fun AddEditSessionScreen(
|
|||||||
|
|
||||||
problem?.difficulty?.let { difficulty ->
|
problem?.difficulty?.let { difficulty ->
|
||||||
Text(
|
Text(
|
||||||
text = "${difficulty.system.name}: ${difficulty.grade}",
|
text = "${difficulty.system.getDisplayName()}: ${difficulty.grade}",
|
||||||
style = MaterialTheme.typography.bodySmall,
|
style = MaterialTheme.typography.bodySmall,
|
||||||
color = MaterialTheme.colorScheme.primary
|
color = MaterialTheme.colorScheme.primary
|
||||||
)
|
)
|
||||||
@@ -956,7 +1063,7 @@ fun AddAttemptDialog(
|
|||||||
fontWeight = FontWeight.Medium
|
fontWeight = FontWeight.Medium
|
||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
text = "${problem.difficulty.system.name}: ${problem.difficulty.grade}",
|
text = "${problem.difficulty.system.getDisplayName()}: ${problem.difficulty.grade}",
|
||||||
style = MaterialTheme.typography.bodySmall,
|
style = MaterialTheme.typography.bodySmall,
|
||||||
color = MaterialTheme.colorScheme.primary
|
color = MaterialTheme.colorScheme.primary
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,8 +6,10 @@ import androidx.compose.material3.*
|
|||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.atridad.openclimb.R
|
||||||
import com.atridad.openclimb.ui.viewmodel.ClimbViewModel
|
import com.atridad.openclimb.ui.viewmodel.ClimbViewModel
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -26,11 +28,23 @@ fun AnalyticsScreen(
|
|||||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||||
) {
|
) {
|
||||||
item {
|
item {
|
||||||
Text(
|
Row(
|
||||||
text = "Analytics",
|
modifier = Modifier.fillMaxWidth(),
|
||||||
style = MaterialTheme.typography.headlineMedium,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
fontWeight = FontWeight.Bold
|
horizontalArrangement = Arrangement.spacedBy(12.dp)
|
||||||
)
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(id = R.drawable.ic_mountains),
|
||||||
|
contentDescription = "OpenClimb Logo",
|
||||||
|
modifier = Modifier.size(32.dp),
|
||||||
|
tint = MaterialTheme.colorScheme.primary
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = "Analytics",
|
||||||
|
style = MaterialTheme.typography.headlineMedium,
|
||||||
|
fontWeight = FontWeight.Bold
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overall Stats
|
// Overall Stats
|
||||||
|
|||||||
@@ -481,7 +481,7 @@ fun ProblemDetailScreen(
|
|||||||
Column {
|
Column {
|
||||||
problem?.let { p ->
|
problem?.let { p ->
|
||||||
Text(
|
Text(
|
||||||
text = "${p.difficulty.system.name}: ${p.difficulty.grade}",
|
text = "${p.difficulty.system.getDisplayName()}: ${p.difficulty.grade}",
|
||||||
style = MaterialTheme.typography.titleLarge,
|
style = MaterialTheme.typography.titleLarge,
|
||||||
color = MaterialTheme.colorScheme.primary,
|
color = MaterialTheme.colorScheme.primary,
|
||||||
fontWeight = FontWeight.Bold
|
fontWeight = FontWeight.Bold
|
||||||
@@ -490,7 +490,7 @@ fun ProblemDetailScreen(
|
|||||||
|
|
||||||
problem?.let { p ->
|
problem?.let { p ->
|
||||||
Text(
|
Text(
|
||||||
text = p.climbType.name.lowercase().replaceFirstChar { it.uppercase() },
|
text = p.climbType.getDisplayName(),
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
)
|
)
|
||||||
@@ -1314,7 +1314,7 @@ fun SessionAttemptCard(
|
|||||||
)
|
)
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
text = "${problem.difficulty.system.name}: ${problem.difficulty.grade}",
|
text = "${problem.difficulty.system.getDisplayName()}: ${problem.difficulty.grade}",
|
||||||
style = MaterialTheme.typography.bodySmall,
|
style = MaterialTheme.typography.bodySmall,
|
||||||
color = MaterialTheme.colorScheme.primary
|
color = MaterialTheme.colorScheme.primary
|
||||||
)
|
)
|
||||||
@@ -1406,6 +1406,39 @@ fun EnhancedAddAttemptDialog(
|
|||||||
var selectedClimbType by remember { mutableStateOf(ClimbType.BOULDER) }
|
var selectedClimbType by remember { mutableStateOf(ClimbType.BOULDER) }
|
||||||
var selectedDifficultySystem by remember { mutableStateOf(gym.difficultySystems.firstOrNull() ?: DifficultySystem.V_SCALE) }
|
var selectedDifficultySystem by remember { mutableStateOf(gym.difficultySystems.firstOrNull() ?: DifficultySystem.V_SCALE) }
|
||||||
|
|
||||||
|
// Auto-select climb type if there's only one available
|
||||||
|
LaunchedEffect(gym.supportedClimbTypes) {
|
||||||
|
if (gym.supportedClimbTypes.size == 1 && selectedClimbType != gym.supportedClimbTypes.first()) {
|
||||||
|
selectedClimbType = gym.supportedClimbTypes.first()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto-select difficulty system if there's only one available for the selected climb type
|
||||||
|
LaunchedEffect(selectedClimbType, gym.difficultySystems) {
|
||||||
|
val availableSystems = DifficultySystem.getSystemsForClimbType(selectedClimbType).filter { system ->
|
||||||
|
gym.difficultySystems.contains(system)
|
||||||
|
}
|
||||||
|
|
||||||
|
when {
|
||||||
|
// If current system is not compatible, select the first available one
|
||||||
|
selectedDifficultySystem !in availableSystems -> {
|
||||||
|
selectedDifficultySystem = availableSystems.firstOrNull() ?: gym.difficultySystems.firstOrNull() ?: DifficultySystem.CUSTOM
|
||||||
|
}
|
||||||
|
// If there's only one available system, auto-select it
|
||||||
|
availableSystems.size == 1 && selectedDifficultySystem != availableSystems.first() -> {
|
||||||
|
selectedDifficultySystem = availableSystems.first()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset grade when difficulty system changes
|
||||||
|
LaunchedEffect(selectedDifficultySystem) {
|
||||||
|
val availableGrades = selectedDifficultySystem.getAvailableGrades()
|
||||||
|
if (availableGrades.isNotEmpty() && newProblemGrade !in availableGrades) {
|
||||||
|
newProblemGrade = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Dialog(onDismissRequest = onDismiss) {
|
Dialog(onDismissRequest = onDismiss) {
|
||||||
Card(
|
Card(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@@ -1509,7 +1542,7 @@ fun EnhancedAddAttemptDialog(
|
|||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(4.dp))
|
Spacer(modifier = Modifier.height(4.dp))
|
||||||
Text(
|
Text(
|
||||||
text = "${problem.difficulty.system.name}: ${problem.difficulty.grade}",
|
text = "${problem.difficulty.system.getDisplayName()}: ${problem.difficulty.grade}",
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
color = if (isSelected)
|
color = if (isSelected)
|
||||||
MaterialTheme.colorScheme.onSurface.copy(alpha = 0.8f)
|
MaterialTheme.colorScheme.onSurface.copy(alpha = 0.8f)
|
||||||
@@ -1584,7 +1617,7 @@ fun EnhancedAddAttemptDialog(
|
|||||||
onClick = { selectedClimbType = climbType },
|
onClick = { selectedClimbType = climbType },
|
||||||
label = {
|
label = {
|
||||||
Text(
|
Text(
|
||||||
climbType.name.lowercase().replaceFirstChar { it.uppercase() },
|
climbType.getDisplayName(),
|
||||||
fontWeight = FontWeight.Medium
|
fontWeight = FontWeight.Medium
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@@ -1611,12 +1644,15 @@ fun EnhancedAddAttemptDialog(
|
|||||||
LazyRow(
|
LazyRow(
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||||
) {
|
) {
|
||||||
items(gym.difficultySystems) { system ->
|
val availableSystems = DifficultySystem.getSystemsForClimbType(selectedClimbType).filter { system ->
|
||||||
|
gym.difficultySystems.contains(system)
|
||||||
|
}
|
||||||
|
items(availableSystems) { system ->
|
||||||
FilterChip(
|
FilterChip(
|
||||||
onClick = { selectedDifficultySystem = system },
|
onClick = { selectedDifficultySystem = system },
|
||||||
label = {
|
label = {
|
||||||
Text(
|
Text(
|
||||||
system.name,
|
system.getDisplayName(),
|
||||||
fontWeight = FontWeight.Medium
|
fontWeight = FontWeight.Medium
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@@ -1630,31 +1666,63 @@ fun EnhancedAddAttemptDialog(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OutlinedTextField(
|
if (selectedDifficultySystem == DifficultySystem.CUSTOM) {
|
||||||
value = newProblemGrade,
|
OutlinedTextField(
|
||||||
onValueChange = { newProblemGrade = it },
|
value = newProblemGrade,
|
||||||
label = { Text("Grade *") },
|
onValueChange = { newProblemGrade = it },
|
||||||
placeholder = {
|
label = { Text("Grade *") },
|
||||||
Text(when (selectedDifficultySystem) {
|
placeholder = { Text("Enter custom grade") },
|
||||||
DifficultySystem.V_SCALE -> "e.g., V0, V4, V10"
|
modifier = Modifier.fillMaxWidth(),
|
||||||
DifficultySystem.FONT -> "e.g., 3, 6A+, 8B"
|
singleLine = true,
|
||||||
DifficultySystem.YDS -> "e.g., 5.8, 5.12a"
|
colors = OutlinedTextFieldDefaults.colors(
|
||||||
DifficultySystem.FRENCH -> "e.g., 6a, 7c+"
|
focusedBorderColor = MaterialTheme.colorScheme.primary,
|
||||||
DifficultySystem.CUSTOM -> "Custom grade"
|
unfocusedBorderColor = MaterialTheme.colorScheme.outline
|
||||||
else -> "Enter grade"
|
),
|
||||||
})
|
isError = newProblemGrade.isBlank(),
|
||||||
},
|
supportingText = if (newProblemGrade.isBlank()) {
|
||||||
modifier = Modifier.fillMaxWidth(),
|
{ Text("Grade is required", color = MaterialTheme.colorScheme.error) }
|
||||||
singleLine = true,
|
} else null
|
||||||
colors = OutlinedTextFieldDefaults.colors(
|
)
|
||||||
focusedBorderColor = MaterialTheme.colorScheme.primary,
|
} else {
|
||||||
unfocusedBorderColor = MaterialTheme.colorScheme.outline
|
var expanded by remember { mutableStateOf(false) }
|
||||||
),
|
val availableGrades = selectedDifficultySystem.getAvailableGrades()
|
||||||
isError = newProblemGrade.isBlank(),
|
|
||||||
supportingText = if (newProblemGrade.isBlank()) {
|
ExposedDropdownMenuBox(
|
||||||
{ Text("Grade is required", color = MaterialTheme.colorScheme.error) }
|
expanded = expanded,
|
||||||
} else null
|
onExpandedChange = { expanded = !expanded },
|
||||||
)
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
OutlinedTextField(
|
||||||
|
value = newProblemGrade,
|
||||||
|
onValueChange = { },
|
||||||
|
readOnly = true,
|
||||||
|
label = { Text("Grade *") },
|
||||||
|
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
|
||||||
|
colors = ExposedDropdownMenuDefaults.outlinedTextFieldColors(),
|
||||||
|
modifier = Modifier
|
||||||
|
.menuAnchor()
|
||||||
|
.fillMaxWidth(),
|
||||||
|
isError = newProblemGrade.isBlank(),
|
||||||
|
supportingText = if (newProblemGrade.isBlank()) {
|
||||||
|
{ Text("Grade is required", color = MaterialTheme.colorScheme.error) }
|
||||||
|
} else null
|
||||||
|
)
|
||||||
|
ExposedDropdownMenu(
|
||||||
|
expanded = expanded,
|
||||||
|
onDismissRequest = { expanded = false }
|
||||||
|
) {
|
||||||
|
availableGrades.forEach { grade ->
|
||||||
|
DropdownMenuItem(
|
||||||
|
text = { Text(grade) },
|
||||||
|
onClick = {
|
||||||
|
newProblemGrade = grade
|
||||||
|
expanded = false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,9 +9,11 @@ import androidx.compose.material3.*
|
|||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.atridad.openclimb.R
|
||||||
import com.atridad.openclimb.data.model.Gym
|
import com.atridad.openclimb.data.model.Gym
|
||||||
import com.atridad.openclimb.ui.viewmodel.ClimbViewModel
|
import com.atridad.openclimb.ui.viewmodel.ClimbViewModel
|
||||||
|
|
||||||
@@ -29,11 +31,23 @@ fun GymsScreen(
|
|||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(16.dp)
|
.padding(16.dp)
|
||||||
) {
|
) {
|
||||||
Text(
|
Row(
|
||||||
text = "Climbing Gyms",
|
modifier = Modifier.fillMaxWidth(),
|
||||||
style = MaterialTheme.typography.headlineMedium,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
fontWeight = FontWeight.Bold
|
horizontalArrangement = Arrangement.spacedBy(12.dp)
|
||||||
)
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(id = R.drawable.ic_mountains),
|
||||||
|
contentDescription = "OpenClimb Logo",
|
||||||
|
modifier = Modifier.size(32.dp),
|
||||||
|
tint = MaterialTheme.colorScheme.primary
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = "Climbing Gyms",
|
||||||
|
style = MaterialTheme.typography.headlineMedium,
|
||||||
|
fontWeight = FontWeight.Bold
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
@@ -95,7 +109,7 @@ fun GymCard(
|
|||||||
AssistChip(
|
AssistChip(
|
||||||
onClick = { },
|
onClick = { },
|
||||||
label = {
|
label = {
|
||||||
Text(climbType.name.lowercase().replaceFirstChar { it.uppercase() })
|
Text(climbType.getDisplayName())
|
||||||
},
|
},
|
||||||
modifier = Modifier.padding(end = 4.dp)
|
modifier = Modifier.padding(end = 4.dp)
|
||||||
)
|
)
|
||||||
@@ -105,7 +119,7 @@ fun GymCard(
|
|||||||
if (gym.difficultySystems.isNotEmpty()) {
|
if (gym.difficultySystems.isNotEmpty()) {
|
||||||
Spacer(modifier = Modifier.height(4.dp))
|
Spacer(modifier = Modifier.height(4.dp))
|
||||||
Text(
|
Text(
|
||||||
text = "Systems: ${gym.difficultySystems.joinToString(", ") { it.name }}",
|
text = "Systems: ${gym.difficultySystems.joinToString(", ") { it.getDisplayName() }}",
|
||||||
style = MaterialTheme.typography.bodySmall,
|
style = MaterialTheme.typography.bodySmall,
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.atridad.openclimb.ui.screens
|
|||||||
|
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.LazyRow
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Add
|
import androidx.compose.material.icons.filled.Add
|
||||||
@@ -9,9 +10,13 @@ import androidx.compose.material3.*
|
|||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.atridad.openclimb.R
|
||||||
|
import com.atridad.openclimb.data.model.ClimbType
|
||||||
|
import com.atridad.openclimb.data.model.Gym
|
||||||
import com.atridad.openclimb.data.model.Problem
|
import com.atridad.openclimb.data.model.Problem
|
||||||
import com.atridad.openclimb.ui.components.FullscreenImageViewer
|
import com.atridad.openclimb.ui.components.FullscreenImageViewer
|
||||||
import com.atridad.openclimb.ui.components.ImageDisplay
|
import com.atridad.openclimb.ui.components.ImageDisplay
|
||||||
@@ -30,29 +35,149 @@ fun ProblemsScreen(
|
|||||||
var selectedImagePaths by remember { mutableStateOf<List<String>>(emptyList()) }
|
var selectedImagePaths by remember { mutableStateOf<List<String>>(emptyList()) }
|
||||||
var selectedImageIndex by remember { mutableStateOf(0) }
|
var selectedImageIndex by remember { mutableStateOf(0) }
|
||||||
|
|
||||||
|
// Filter state
|
||||||
|
var selectedClimbType by remember { mutableStateOf<ClimbType?>(null) }
|
||||||
|
var selectedGym by remember { mutableStateOf<Gym?>(null) }
|
||||||
|
|
||||||
|
// Apply filters
|
||||||
|
val filteredProblems = problems.filter { problem ->
|
||||||
|
val climbTypeMatch = selectedClimbType?.let { it == problem.climbType } ?: true
|
||||||
|
val gymMatch = selectedGym?.let { it.id == problem.gymId } ?: true
|
||||||
|
climbTypeMatch && gymMatch
|
||||||
|
}
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(16.dp)
|
.padding(16.dp)
|
||||||
) {
|
) {
|
||||||
Text(
|
Row(
|
||||||
text = "Problems & Routes",
|
modifier = Modifier.fillMaxWidth(),
|
||||||
style = MaterialTheme.typography.headlineMedium,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
fontWeight = FontWeight.Bold
|
horizontalArrangement = Arrangement.spacedBy(12.dp)
|
||||||
)
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(id = R.drawable.ic_mountains),
|
||||||
|
contentDescription = "OpenClimb Logo",
|
||||||
|
modifier = Modifier.size(32.dp),
|
||||||
|
tint = MaterialTheme.colorScheme.primary
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = "Problems & Routes",
|
||||||
|
style = MaterialTheme.typography.headlineMedium,
|
||||||
|
fontWeight = FontWeight.Bold
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
if (problems.isEmpty()) {
|
// Filters Section
|
||||||
|
if (problems.isNotEmpty()) {
|
||||||
|
Card(
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.padding(16.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "Filters",
|
||||||
|
style = MaterialTheme.typography.titleMedium,
|
||||||
|
fontWeight = FontWeight.Bold
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(12.dp))
|
||||||
|
|
||||||
|
// Climb Type Filter
|
||||||
|
Text(
|
||||||
|
text = "Climb Type",
|
||||||
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
|
fontWeight = FontWeight.Medium
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
|
LazyRow(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||||
|
) {
|
||||||
|
item {
|
||||||
|
FilterChip(
|
||||||
|
onClick = { selectedClimbType = null },
|
||||||
|
label = { Text("All Types") },
|
||||||
|
selected = selectedClimbType == null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
items(ClimbType.entries) { climbType ->
|
||||||
|
FilterChip(
|
||||||
|
onClick = { selectedClimbType = climbType },
|
||||||
|
label = { Text(climbType.getDisplayName()) },
|
||||||
|
selected = selectedClimbType == climbType
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(12.dp))
|
||||||
|
|
||||||
|
// Gym Filter
|
||||||
|
Text(
|
||||||
|
text = "Gym",
|
||||||
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
|
fontWeight = FontWeight.Medium
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
|
LazyRow(
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||||
|
) {
|
||||||
|
item {
|
||||||
|
FilterChip(
|
||||||
|
onClick = { selectedGym = null },
|
||||||
|
label = { Text("All Gyms") },
|
||||||
|
selected = selectedGym == null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
items(gyms) { gym ->
|
||||||
|
FilterChip(
|
||||||
|
onClick = { selectedGym = gym },
|
||||||
|
label = { Text(gym.name) },
|
||||||
|
selected = selectedGym?.id == gym.id
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter result count
|
||||||
|
if (selectedClimbType != null || selectedGym != null) {
|
||||||
|
Spacer(modifier = Modifier.height(12.dp))
|
||||||
|
Text(
|
||||||
|
text = "Showing ${filteredProblems.size} of ${problems.size} problems",
|
||||||
|
style = MaterialTheme.typography.bodySmall,
|
||||||
|
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filteredProblems.isEmpty()) {
|
||||||
EmptyStateMessage(
|
EmptyStateMessage(
|
||||||
title = if (gyms.isEmpty()) "No Gyms Available" else "No Problems Yet",
|
title = if (problems.isEmpty()) {
|
||||||
message = if (gyms.isEmpty()) "Add a gym first to start tracking problems and routes!" else "Start tracking your favorite problems and routes!",
|
if (gyms.isEmpty()) "No Gyms Available" else "No Problems Yet"
|
||||||
|
} else {
|
||||||
|
"No Problems Match Filters"
|
||||||
|
},
|
||||||
|
message = if (problems.isEmpty()) {
|
||||||
|
if (gyms.isEmpty()) "Add a gym first to start tracking problems and routes!" else "Start tracking your favorite problems and routes!"
|
||||||
|
} else {
|
||||||
|
"Try adjusting your filters to see more problems."
|
||||||
|
},
|
||||||
onActionClick = { },
|
onActionClick = { },
|
||||||
actionText = ""
|
actionText = ""
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
LazyColumn {
|
LazyColumn {
|
||||||
items(problems) { problem ->
|
items(filteredProblems) { problem ->
|
||||||
ProblemCard(
|
ProblemCard(
|
||||||
problem = problem,
|
problem = problem,
|
||||||
gymName = gyms.find { it.id == problem.gymId }?.name ?: "Unknown Gym",
|
gymName = gyms.find { it.id == problem.gymId }?.name ?: "Unknown Gym",
|
||||||
@@ -124,7 +249,7 @@ fun ProblemCard(
|
|||||||
)
|
)
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
text = problem.climbType.name.lowercase().replaceFirstChar { it.uppercase() },
|
text = problem.climbType.getDisplayName(),
|
||||||
style = MaterialTheme.typography.bodySmall,
|
style = MaterialTheme.typography.bodySmall,
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -10,9 +10,11 @@ import androidx.compose.runtime.*
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.atridad.openclimb.R
|
||||||
import com.atridad.openclimb.data.model.ClimbSession
|
import com.atridad.openclimb.data.model.ClimbSession
|
||||||
import com.atridad.openclimb.data.model.SessionStatus
|
import com.atridad.openclimb.data.model.SessionStatus
|
||||||
import com.atridad.openclimb.ui.components.ActiveSessionBanner
|
import com.atridad.openclimb.ui.components.ActiveSessionBanner
|
||||||
@@ -45,16 +47,20 @@ fun SessionsScreen(
|
|||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
verticalAlignment = Alignment.CenterVertically
|
horizontalArrangement = Arrangement.spacedBy(12.dp)
|
||||||
) {
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(id = R.drawable.ic_mountains),
|
||||||
|
contentDescription = "OpenClimb Logo",
|
||||||
|
modifier = Modifier.size(32.dp),
|
||||||
|
tint = MaterialTheme.colorScheme.primary
|
||||||
|
)
|
||||||
Text(
|
Text(
|
||||||
text = "Climbing Sessions",
|
text = "Climbing Sessions",
|
||||||
style = MaterialTheme.typography.headlineMedium,
|
style = MaterialTheme.typography.headlineMedium,
|
||||||
fontWeight = FontWeight.Bold
|
fontWeight = FontWeight.Bold
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|||||||
@@ -13,8 +13,10 @@ import androidx.compose.runtime.*
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.atridad.openclimb.R
|
||||||
import com.atridad.openclimb.ui.viewmodel.ClimbViewModel
|
import com.atridad.openclimb.ui.viewmodel.ClimbViewModel
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@@ -94,11 +96,23 @@ fun SettingsScreen(
|
|||||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||||
) {
|
) {
|
||||||
item {
|
item {
|
||||||
Text(
|
Row(
|
||||||
text = "Settings",
|
modifier = Modifier.fillMaxWidth(),
|
||||||
style = MaterialTheme.typography.headlineMedium,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
fontWeight = FontWeight.Bold
|
horizontalArrangement = Arrangement.spacedBy(12.dp)
|
||||||
)
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(id = R.drawable.ic_mountains),
|
||||||
|
contentDescription = "OpenClimb Logo",
|
||||||
|
modifier = Modifier.size(32.dp),
|
||||||
|
tint = MaterialTheme.colorScheme.primary
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = "Settings",
|
||||||
|
style = MaterialTheme.typography.headlineMedium,
|
||||||
|
fontWeight = FontWeight.Bold
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Data Management Section
|
// Data Management Section
|
||||||
@@ -256,9 +270,22 @@ fun SettingsScreen(
|
|||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
ListItem(
|
ListItem(
|
||||||
headlineContent = { Text("Version") },
|
headlineContent = {
|
||||||
supportingContent = { Text(appVersion ?: "Unknown") },
|
Row(
|
||||||
leadingContent = { Icon(Icons.Default.Info, contentDescription = null) }
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(id = R.drawable.ic_mountains),
|
||||||
|
contentDescription = "OpenClimb Logo",
|
||||||
|
modifier = Modifier.size(24.dp),
|
||||||
|
tint = MaterialTheme.colorScheme.primary
|
||||||
|
)
|
||||||
|
Text("OpenClimb")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
supportingContent = { Text("Track your climbing progress") },
|
||||||
|
leadingContent = { }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,8 +298,8 @@ fun SettingsScreen(
|
|||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
ListItem(
|
ListItem(
|
||||||
headlineContent = { Text("About") },
|
headlineContent = { Text("Version") },
|
||||||
supportingContent = { Text("OpenClimb - Track your climbing progress") },
|
supportingContent = { Text(appVersion ?: "Unknown") },
|
||||||
leadingContent = { Icon(Icons.Default.Info, contentDescription = null) }
|
leadingContent = { Icon(Icons.Default.Info, contentDescription = null) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,167 +4,8 @@
|
|||||||
android:height="108dp"
|
android:height="108dp"
|
||||||
android:viewportWidth="108"
|
android:viewportWidth="108"
|
||||||
android:viewportHeight="108">
|
android:viewportHeight="108">
|
||||||
<path
|
|
||||||
android:fillColor="#3DDC84"
|
<!-- Clean white background -->
|
||||||
android:pathData="M0,0h108v108h-108z" />
|
<path android:fillColor="#FFFFFF"
|
||||||
<path
|
android:pathData="M0,0h108v108h-108z"/>
|
||||||
android:fillColor="#00000000"
|
</vector>
|
||||||
android:pathData="M9,0L9,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,0L19,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M29,0L29,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M39,0L39,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M49,0L49,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M59,0L59,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M69,0L69,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M79,0L79,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M89,0L89,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M99,0L99,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,9L108,9"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,19L108,19"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,29L108,29"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,39L108,39"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,49L108,49"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,59L108,59"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,69L108,69"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,79L108,79"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,89L108,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,99L108,99"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,29L89,29"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,39L89,39"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,49L89,49"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,59L89,59"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,69L89,69"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,79L89,79"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M29,19L29,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M39,19L39,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M49,19L49,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M59,19L59,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M69,19L69,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M79,19L79,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
</vector>
|
|
||||||
@@ -1,30 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:aapt="http://schemas.android.com/aapt"
|
|
||||||
android:width="108dp"
|
android:width="108dp"
|
||||||
android:height="108dp"
|
android:height="108dp"
|
||||||
android:viewportWidth="108"
|
android:viewportWidth="108"
|
||||||
android:viewportHeight="108">
|
android:viewportHeight="108">
|
||||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
|
||||||
<aapt:attr name="android:fillColor">
|
<group
|
||||||
<gradient
|
android:scaleX="0.7"
|
||||||
android:endX="85.84757"
|
android:scaleY="0.7"
|
||||||
android:endY="92.4963"
|
android:translateX="16.2"
|
||||||
android:startX="42.9492"
|
android:translateY="20">
|
||||||
android:startY="49.59793"
|
|
||||||
android:type="linear">
|
<!-- Left mountain (yellow/amber) -->
|
||||||
<item
|
<path
|
||||||
android:color="#44000000"
|
android:fillColor="#FFC107"
|
||||||
android:offset="0.0" />
|
android:strokeColor="#1C1C1C"
|
||||||
<item
|
android:strokeWidth="3"
|
||||||
android:color="#00000000"
|
android:strokeLineJoin="round"
|
||||||
android:offset="1.0" />
|
android:pathData="M15,70 L35,25 L55,70 Z" />
|
||||||
</gradient>
|
|
||||||
</aapt:attr>
|
<!-- Right mountain (red) -->
|
||||||
</path>
|
<path
|
||||||
<path
|
android:fillColor="#F44336"
|
||||||
android:fillColor="#FFFFFF"
|
android:strokeColor="#1C1C1C"
|
||||||
android:fillType="nonZero"
|
android:strokeWidth="3"
|
||||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
android:strokeLineJoin="round"
|
||||||
android:strokeWidth="1"
|
android:pathData="M40,70 L65,15 L90,70 Z" />
|
||||||
android:strokeColor="#00000000" />
|
</group>
|
||||||
</vector>
|
</vector>
|
||||||
32
app/src/main/res/drawable/ic_mountains.xml
Normal file
32
app/src/main/res/drawable/ic_mountains.xml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
|
||||||
|
<!-- Left mountain (yellow/amber) -->
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFC107"
|
||||||
|
android:pathData="M3,18 L8,9 L13,18 Z" />
|
||||||
|
|
||||||
|
<!-- Right mountain (red) -->
|
||||||
|
<path
|
||||||
|
android:fillColor="#F44336"
|
||||||
|
android:pathData="M11,18 L16,7 L21,18 Z" />
|
||||||
|
|
||||||
|
<!-- Black outlines -->
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/transparent"
|
||||||
|
android:strokeColor="#1C1C1C"
|
||||||
|
android:strokeWidth="1"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:pathData="M3,18 L8,9 L13,18" />
|
||||||
|
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/transparent"
|
||||||
|
android:strokeColor="#1C1C1C"
|
||||||
|
android:strokeWidth="1"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:pathData="M11,18 L16,7 L21,18" />
|
||||||
|
</vector>
|
||||||
Reference in New Issue
Block a user