From f93f45e69261c5e0e7a10b7b48a44a7b507c5af4 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Mon, 31 Oct 2022 15:12:55 +0100 Subject: [PATCH] fix colrs --- Habitica/build.gradle | 12 +- Habitica/res/values/styles.xml | 1 + .../ui/adapter/NavigationDrawerAdapter.kt | 31 +--- .../customization/AvatarOverviewFragment.kt | 9 +- .../habitica/ui/views/AppHeaderView.kt | 7 +- .../habitica/ui/views/SegmentedControl.kt | 139 ++++++++++++++++++ build.gradle | 8 +- 7 files changed, 164 insertions(+), 43 deletions(-) create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/SegmentedControl.kt diff --git a/Habitica/build.gradle b/Habitica/build.gradle index 74c19431c..34fa27a2b 100644 --- a/Habitica/build.gradle +++ b/Habitica/build.gradle @@ -43,7 +43,7 @@ dependencies { compileOnly 'javax.annotation:javax.annotation-api:1.3.2' //App Compatibility and Material Design implementation "androidx.appcompat:appcompat:$appcompat_version" - implementation 'com.google.android.material:material:1.6.1' + implementation 'com.google.android.material:material:1.7.0' implementation "androidx.recyclerview:recyclerview:$recyclerview_version" implementation "androidx.preference:preference-ktx:$preferences_version" implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" @@ -79,7 +79,7 @@ dependencies { androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' androidTestImplementation 'androidx.test:runner:1.4.0' androidTestImplementation 'androidx.test:rules:1.4.0' - debugImplementation 'androidx.fragment:fragment-testing:1.5.3' + debugImplementation 'androidx.fragment:fragment-testing:1.5.4' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test:core-ktx:1.4.0' androidTestImplementation 'androidx.test.ext:junit-ktx:1.1.3' @@ -98,7 +98,7 @@ dependencies { implementation 'com.google.firebase:firebase-messaging-ktx' implementation 'com.google.firebase:firebase-config-ktx' implementation 'com.google.firebase:firebase-perf-ktx' - implementation 'com.google.android.gms:play-services-ads:21.2.0' + implementation 'com.google.android.gms:play-services-ads:21.3.0' implementation "com.google.android.gms:play-services-auth:$play_auth_version" implementation 'com.google.android.flexbox:flexbox:3.0.0' implementation "com.google.android.gms:play-services-wearable:$play_wearables_version" @@ -109,13 +109,13 @@ dependencies { implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version" implementation "androidx.navigation:navigation-fragment-ktx:$navigation_version" implementation "androidx.navigation:navigation-ui-ktx:$navigation_version" - implementation "androidx.fragment:fragment-ktx:1.5.3" + implementation "androidx.fragment:fragment-ktx:1.5.4" implementation "androidx.paging:paging-runtime-ktx:3.1.1" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version" - implementation "com.google.android.material:compose-theme-adapter:1.1.19" + implementation "com.google.android.material:compose-theme-adapter:1.1.21" - implementation 'androidx.activity:activity-compose:1.6.0' + implementation 'androidx.activity:activity-compose:1.6.1' implementation "androidx.compose.runtime:runtime-livedata:$compose_version" implementation "androidx.compose.material:material:$compose_version" implementation "androidx.compose.animation:animation:$compose_version" diff --git a/Habitica/res/values/styles.xml b/Habitica/res/values/styles.xml index 48e23d006..72e59c4da 100644 --- a/Habitica/res/values/styles.xml +++ b/Habitica/res/values/styles.xml @@ -26,6 +26,7 @@ @color/brand_500 @color/brand_400 @color/brand_300 + @color/brand @color/text_primary @color/text_secondary diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/NavigationDrawerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/NavigationDrawerAdapter.kt index f961d9f07..23e19efff 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/NavigationDrawerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/NavigationDrawerAdapter.kt @@ -4,19 +4,16 @@ import android.view.View import android.view.ViewGroup import android.widget.TextView import androidx.core.content.ContextCompat -import androidx.core.os.bundleOf import androidx.recyclerview.widget.RecyclerView import com.habitrpg.android.habitica.R -import com.habitrpg.common.habitica.extensions.dpToPx import com.habitrpg.android.habitica.extensions.inflate -import com.habitrpg.android.habitica.models.TeamPlan import com.habitrpg.android.habitica.models.promotions.HabiticaPromotion -import com.habitrpg.android.habitica.ui.fragments.NavigationDrawerFragment import com.habitrpg.android.habitica.ui.menu.HabiticaDrawerItem import com.habitrpg.android.habitica.ui.views.promo.PromoMenuView import com.habitrpg.android.habitica.ui.views.promo.PromoMenuViewHolder import com.habitrpg.android.habitica.ui.views.promo.SubscriptionBuyGemsPromoView import com.habitrpg.android.habitica.ui.views.promo.SubscriptionBuyGemsPromoViewHolder +import com.habitrpg.common.habitica.extensions.dpToPx import io.reactivex.rxjava3.core.BackpressureStrategy import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.subjects.PublishSubject @@ -77,32 +74,6 @@ class NavigationDrawerAdapter(tintColor: Int, backgroundTintColor: Int) : Recycl notifyDataSetChanged() } - fun setTeams(teams: List) { - var teamHeaderIndex = -1 - var nextHeaderIndex = -1 - for ((index, item) in items.withIndex()) { - if (teamHeaderIndex != -1 && item.isHeader) { - nextHeaderIndex = index - break - } else if (item.identifier == NavigationDrawerFragment.SIDEBAR_TEAMS) { - teamHeaderIndex = index - } - } - if (teamHeaderIndex != -1 && nextHeaderIndex != -1) { - for (x in nextHeaderIndex - 1 downTo teamHeaderIndex + 1) { - items.removeAt(x) - notifyItemRemoved(x) - } - for ((index, team) in teams.withIndex()) { - val item = HabiticaDrawerItem(R.id.tasksFragment, team.id, team.summary) - item.bundle = bundleOf(Pair("ownerID", team.id)) - val newIndex = teamHeaderIndex + index + 1 - items.add(newIndex, item) - notifyItemInserted(newIndex) - } - } - } - override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { val drawerItem = getItem(position) when { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarOverviewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarOverviewFragment.kt index 98d2a4619..0b0e62358 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarOverviewFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarOverviewFragment.kt @@ -30,6 +30,7 @@ import com.habitrpg.android.habitica.ui.theme.HabiticaTheme import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import com.habitrpg.android.habitica.ui.views.AvatarCustomizationOverviewView import com.habitrpg.android.habitica.ui.views.EquipmentOverviewView +import com.habitrpg.android.habitica.ui.views.SegmentedControl import javax.inject.Inject class AvatarOverviewFragment : BaseMainFragment(), @@ -108,11 +109,17 @@ fun AvatarOverviewView(userViewModel: MainUserViewModel, Modifier .padding(horizontal = 8.dp) .padding(bottom = 16.dp)) { - Row(Modifier.padding(horizontal = 12.dp, vertical = 15.dp)) { + Row(Modifier.padding(horizontal = 12.dp, vertical = 15.dp), + verticalAlignment = Alignment.CenterVertically) { Text( stringResource(R.string.avatar_size), style = HabiticaTheme.typography.subtitle2 ) + Spacer(modifier = Modifier.weight(1f)) + SegmentedControl(items = listOf(stringResource(R.string.avatar_size_slim), stringResource(R.string.avatar_size_broad + )), defaultSelectedItemIndex = if (user?.preferences?.size == "slim") 0 else 1, onItemSelection = { + userViewModel.updateUser("preferences.size", if (it == 0) "slim" else "broad") + }) } AvatarCustomizationOverviewView(user?.preferences, onCustomizationTap) Row( diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/AppHeaderView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/AppHeaderView.kt index 6d7a86ca8..a604a4bf2 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/AppHeaderView.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/AppHeaderView.kt @@ -52,6 +52,7 @@ import com.habitrpg.android.habitica.helpers.MainNavigationController import com.habitrpg.android.habitica.models.user.User import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import com.habitrpg.common.habitica.helpers.NumberAbbreviator +import java.lang.Double.max import java.math.RoundingMode import java.text.NumberFormat @@ -261,6 +262,8 @@ fun LabeledBar( formatter.roundingMode = RoundingMode.UP formatter.isGroupingUsed = true + val cleanedMaxVlaue = max(1.0, maxValue) + val animatedValue = animateFloatAsState( targetValue = value.toFloat(), animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec, @@ -274,7 +277,7 @@ fun LabeledBar( } Column(modifier = Modifier.weight(1f)) { LinearProgressIndicator( - progress = (animatedValue / maxValue).toFloat(), + progress = (animatedValue / cleanedMaxVlaue).toFloat(), Modifier .fillMaxWidth() .clip(CircleShape) @@ -288,7 +291,7 @@ fun LabeledBar( modifier = Modifier.padding(top = 2.dp) ) { Text( - "${formatter.format(animatedValue)} / ${formatter.format(maxValue)}", + "${formatter.format(animatedValue)} / ${formatter.format(cleanedMaxVlaue)}", fontSize = 12.sp, color = colorResource(R.color.text_ternary) ) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/SegmentedControl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/SegmentedControl.kt new file mode 100644 index 000000000..c13f53773 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/SegmentedControl.kt @@ -0,0 +1,139 @@ +package com.habitrpg.android.habitica.ui.views + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.ButtonDefaults +import androidx.compose.material.MaterialTheme +import androidx.compose.material.OutlinedButton +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import androidx.compose.ui.zIndex + +/** + * items : list of items to be render + * defaultSelectedItemIndex : to highlight item by default (Optional) + * useFixedWidth : set true if you want to set fix width to item (Optional) + * itemWidth : Provide item width if useFixedWidth is set to true (Optional) + * cornerRadius : To make control as rounded (Optional) + * color : Set color to control (Optional) + * onItemSelection : Get selected item index + */ +@Composable +fun SegmentedControl( + items: List, + defaultSelectedItemIndex: Int = 0, + useFixedWidth: Boolean = false, + itemWidth: Dp = 120.dp, + cornerRadius : Int = 10, + onItemSelection: (selectedItemIndex: Int) -> Unit +) { + val selectedIndex = remember { mutableStateOf(defaultSelectedItemIndex) } + val color = MaterialTheme.colors.primary + Row( + modifier = Modifier + ) { + items.forEachIndexed { index, item -> + OutlinedButton( + modifier = when (index) { + 0 -> { + if (useFixedWidth) { + Modifier + .width(itemWidth) + .offset(0.dp, 0.dp) + .zIndex(if (selectedIndex.value == 0) 1f else 0f) + } else { + Modifier + .wrapContentSize() + .offset(0.dp, 0.dp) + .zIndex(if (selectedIndex.value == 0) 1f else 0f) + } + } else -> { + if (useFixedWidth) + Modifier + .width(itemWidth) + .offset((-1 * index).dp, 0.dp) + .zIndex(if (selectedIndex.value == index) 1f else 0f) + else Modifier + .wrapContentSize() + .offset((-1 * index).dp, 0.dp) + .zIndex(if (selectedIndex.value == index) 1f else 0f) + } + }, + onClick = { + selectedIndex.value = index + onItemSelection(selectedIndex.value) + }, + shape = when (index) { + /** + * left outer button + */ + 0 -> RoundedCornerShape( + topStartPercent = cornerRadius, + topEndPercent = 0, + bottomStartPercent = cornerRadius, + bottomEndPercent = 0 + ) + /** + * right outer button + */ + items.size - 1 -> RoundedCornerShape( + topStartPercent = 0, + topEndPercent = cornerRadius, + bottomStartPercent = 0, + bottomEndPercent = cornerRadius + ) + /** + * middle button + */ + else -> RoundedCornerShape( + topStartPercent = 0, + topEndPercent = 0, + bottomStartPercent = 0, + bottomEndPercent = 0 + ) + }, + border = BorderStroke( + 1.dp, if (selectedIndex.value == index) { + color + } else { + color.copy(alpha = 0.75f) + } + ), + colors = if (selectedIndex.value == index) { + /** + * selected colors + */ + ButtonDefaults.outlinedButtonColors( + backgroundColor = color + ) + } else { + /** + * not selected colors + */ + ButtonDefaults.outlinedButtonColors(backgroundColor = Color.Transparent) + }, + ) { + Text( + text = item, + fontWeight = FontWeight.Normal, + color = if (selectedIndex.value == index) { + Color.White + } else { + color.copy(alpha = 0.9f) + }, + ) + } + } + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 75d747444..2df4a4e19 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ buildscript { amplitude_version = '3.35.1' appcompat_version = '1.5.1' coil_version = '2.1.0' - compose_version = '1.2.1' + compose_version = '1.3.0' core_ktx_version = '1.9.0' coroutines_version = '1.6.4' daggerhilt_version = '2.42' @@ -19,7 +19,7 @@ buildscript { lifecycle_version = '2.5.1' markwon_version = '4.6.2' moshi_version = '1.13.0' - navigation_version = '2.5.2' + navigation_version = '2.5.3' okhttp_version = '4.9.3' play_wearables_version = '18.0.0' play_auth_version = '20.3.0' @@ -35,7 +35,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.3.0' + classpath 'com.android.tools.build:gradle:7.3.1' classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' classpath 'com.google.gms:google-services:4.3.14' classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.2' @@ -44,7 +44,7 @@ buildscript { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.19.0" classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$navigation_version" - classpath 'com.google.firebase:perf-plugin:1.4.1' + classpath 'com.google.firebase:perf-plugin:1.4.2' classpath "com.google.dagger:hilt-android-gradle-plugin:$daggerhilt_version" } }