mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-04-14 11:46:32 +00:00
fix formatting
This commit is contained in:
parent
c9fea5872a
commit
afb2b234d9
329 changed files with 1782 additions and 1622 deletions
2
.github/workflows/android.yml
vendored
2
.github/workflows/android.yml
vendored
|
|
@ -87,7 +87,7 @@ jobs:
|
|||
- name: Run with Gradle
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
arguments: ktlint
|
||||
arguments: ktlintCheck
|
||||
|
||||
detekt:
|
||||
runs-on: ubuntu-latest
|
||||
|
|
|
|||
|
|
@ -21,10 +21,6 @@ repositories {
|
|||
maven { url "https://jitpack.io" }
|
||||
}
|
||||
|
||||
configurations {
|
||||
ktlint
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(include: ['*.jar'], dir: '../common/libs')
|
||||
//Networking
|
||||
|
|
@ -42,15 +38,15 @@ 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.7.0'
|
||||
implementation 'com.google.android.material:material:1.8.0'
|
||||
implementation "androidx.recyclerview:recyclerview:$recyclerview_version"
|
||||
implementation "androidx.preference:preference-ktx:$preferences_version"
|
||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
|
||||
|
||||
//Desugaring
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.6'
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.2'
|
||||
|
||||
implementation('com.jaredrummler:android-device-names:2.1.0')
|
||||
implementation('com.jaredrummler:android-device-names:2.1.1')
|
||||
|
||||
// IAP Handling / Verification
|
||||
implementation "com.android.billingclient:billing-ktx:5.1.0"
|
||||
|
|
@ -62,38 +58,38 @@ dependencies {
|
|||
implementation "com.amplitude:analytics-android:$amplitude_version"
|
||||
|
||||
//Tests
|
||||
testImplementation 'io.kotest:kotest-runner-junit5:5.3.0'
|
||||
testImplementation 'io.kotest:kotest-runner-junit5:5.5.5'
|
||||
testImplementation 'androidx.test:core:1.5.0'
|
||||
testImplementation 'io.mockk:mockk:1.13.3'
|
||||
testImplementation 'io.mockk:mockk-android:1.13.3'
|
||||
testImplementation 'io.kotest:kotest-assertions-core:5.3.0'
|
||||
testImplementation 'io.kotest:kotest-framework-datatest:5.3.0'
|
||||
androidTestImplementation ('com.kaspersky.android-components:kaspresso:1.4.1') {
|
||||
testImplementation 'io.mockk:mockk:1.13.4'
|
||||
testImplementation 'io.mockk:mockk-android:1.13.4'
|
||||
testImplementation 'io.kotest:kotest-assertions-core:5.5.5'
|
||||
testImplementation 'io.kotest:kotest-framework-datatest:5.5.5'
|
||||
androidTestImplementation ('com.kaspersky.android-components:kaspresso:1.5.1') {
|
||||
exclude module: "protobuf-lite"
|
||||
}
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0'
|
||||
androidTestImplementation 'androidx.test:runner:1.5.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||
androidTestImplementation 'androidx.test:runner:1.5.2'
|
||||
androidTestImplementation 'androidx.test:rules:1.5.0'
|
||||
debugImplementation 'androidx.fragment:fragment-testing:1.5.5'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.4'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
androidTestImplementation 'androidx.test:core-ktx:1.5.0'
|
||||
androidTestImplementation 'androidx.test.ext:junit-ktx:1.1.4'
|
||||
androidTestImplementation 'io.mockk:mockk-android:1.13.3'
|
||||
androidTestImplementation 'io.kotest:kotest-assertions-core:5.3.0'
|
||||
androidTestImplementation 'androidx.test.ext:junit-ktx:1.1.5'
|
||||
androidTestImplementation 'io.mockk:mockk-android:1.13.4'
|
||||
androidTestImplementation 'io.kotest:kotest-assertions-core:5.5.5'
|
||||
androidTestUtil("androidx.test:orchestrator:1.4.2")
|
||||
|
||||
implementation 'com.facebook.shimmer:shimmer:0.5.0'
|
||||
|
||||
//Leak Detection
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.9.1'
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.10'
|
||||
//Push Notifications
|
||||
implementation platform("com.google.firebase:firebase-bom:$firebase_bom")
|
||||
implementation 'com.google.firebase:firebase-analytics-ktx'
|
||||
implementation 'com.google.firebase:firebase-crashlytics-ktx'
|
||||
implementation 'com.google.firebase:firebase-core'
|
||||
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.4.0'
|
||||
implementation 'com.google.android.gms:play-services-ads:21.5.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"
|
||||
|
|
@ -114,7 +110,7 @@ dependencies {
|
|||
|
||||
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.material:material:1.3.1"
|
||||
implementation "androidx.compose.animation:animation:$compose_version"
|
||||
implementation "androidx.compose.ui:ui-tooling:$compose_version"
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version"
|
||||
|
|
@ -124,18 +120,12 @@ dependencies {
|
|||
implementation project(':common')
|
||||
implementation project(':shared')
|
||||
|
||||
ktlint('com.pinterest:ktlint:0.45.2') {
|
||||
attributes {
|
||||
attribute(Bundling.BUNDLING_ATTRIBUTE, getObjects().named(Bundling, Bundling.EXTERNAL))
|
||||
}
|
||||
}
|
||||
androidTestImplementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion target_sdk
|
||||
buildToolsVersion '30.0.3'
|
||||
buildToolsVersion '33.0.2'
|
||||
testOptions {
|
||||
unitTests {
|
||||
includeAndroidResources = true
|
||||
|
|
@ -169,7 +159,7 @@ android {
|
|||
}
|
||||
|
||||
composeOptions {
|
||||
kotlinCompilerExtensionVersion = "1.4.0-alpha02"
|
||||
kotlinCompilerExtensionVersion = "1.4.2"
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
|
|
@ -388,23 +378,3 @@ gradle.projectsEvaluated {
|
|||
}
|
||||
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
|
||||
task ktlint(type: JavaExec, group: "verification") {
|
||||
description = "Check Kotlin code style."
|
||||
classpath = configurations.ktlint
|
||||
mainClass.set("com.pinterest.ktlint.Main")
|
||||
args "--disabled_rules=max-line-length", "--android", "--reporter=plain?group_by_file", "src/**/*.kt"
|
||||
// to generate report in checkstyle format prepend following args:
|
||||
// "--reporter=plain", "--reporter=checkstyle,output=${buildDir}/ktlint.xml"
|
||||
// to add a baseline to check against prepend following args:
|
||||
// "--baseline=ktlint-baseline.xml"
|
||||
// see https://github.com/pinterest/ktlint#usage for more
|
||||
}
|
||||
check.dependsOn ktlint
|
||||
|
||||
task ktlintFormat(type: JavaExec, group: "formatting") {
|
||||
description = "Fix Kotlin code style deviations."
|
||||
classpath = configurations.ktlint
|
||||
mainClass.set("com.pinterest.ktlint.Main")
|
||||
args "--disabled_rules=max-lint-length", "--android", "-F", "src/**/*.kt"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ import androidx.test.filters.LargeTest
|
|||
import com.habitrpg.android.habitica.HabiticaBaseApplication
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.shared.habitica.models.tasks.Frequency
|
||||
import com.habitrpg.android.habitica.models.tasks.Task
|
||||
import com.habitrpg.shared.habitica.models.tasks.Frequency
|
||||
import com.habitrpg.shared.habitica.models.tasks.TaskType
|
||||
import io.github.kakaocup.kakao.common.assertions.BaseAssertions
|
||||
import io.github.kakaocup.kakao.common.matchers.ChildCountMatcher
|
||||
|
|
@ -31,12 +31,12 @@ import io.mockk.mockkObject
|
|||
import io.mockk.slot
|
||||
import io.mockk.verify
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import java.util.Date
|
||||
import java.util.UUID
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import java.util.Date
|
||||
import java.util.UUID
|
||||
|
||||
class TaskFormScreen : Screen<TaskFormScreen>() {
|
||||
val toolbar = KToolbar { withId(R.id.toolbar) }
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import io.mockk.every
|
|||
import io.mockk.mockk
|
||||
import io.mockk.mockkObject
|
||||
import io.mockk.spyk
|
||||
import io.mockk.verify
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import org.junit.Test
|
||||
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import com.habitrpg.android.habitica.R
|
|||
import com.habitrpg.android.habitica.databinding.FragmentRefreshRecyclerviewBinding
|
||||
import com.habitrpg.android.habitica.models.tasks.Task
|
||||
import com.habitrpg.android.habitica.models.tasks.TaskList
|
||||
import com.habitrpg.shared.habitica.models.tasks.TaskType
|
||||
import com.habitrpg.android.habitica.ui.fragments.FragmentTestCase
|
||||
import com.habitrpg.shared.habitica.models.tasks.TaskType
|
||||
import io.github.kakaocup.kakao.common.views.KView
|
||||
import io.github.kakaocup.kakao.recycler.KRecyclerItem
|
||||
import io.github.kakaocup.kakao.recycler.KRecyclerView
|
||||
|
|
|
|||
|
|
@ -81,7 +81,6 @@ abstract class HabiticaBaseApplication : Application(), Application.ActivityLife
|
|||
|
||||
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
|
||||
|
||||
|
||||
setupCoil()
|
||||
|
||||
ExceptionHandler.init(analyticsManager)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import com.habitrpg.android.habitica.models.ContentResult
|
|||
import com.habitrpg.android.habitica.models.WorldState
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface ContentRepository: BaseRepository {
|
||||
interface ContentRepository : BaseRepository {
|
||||
suspend fun retrieveContent(forced: Boolean = false): ContentResult?
|
||||
|
||||
suspend fun retrieveWorldState(forced: Boolean = false): WorldState?
|
||||
|
|
|
|||
|
|
@ -68,5 +68,4 @@ interface TaskRepository : BaseRepository {
|
|||
fun getTasksForChallenge(challengeID: String?): Flow<List<Task>>
|
||||
suspend fun bulkScoreTasks(data: List<Map<String, String>>): BulkTaskScoringData?
|
||||
suspend fun markTaskNeedsWork(task: Task, userID: String)
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ class ApiClientImpl(
|
|||
private val analyticsManager: AnalyticsManager,
|
||||
private val notificationsManager: NotificationsManager,
|
||||
private val context: Context
|
||||
): ApiClient {
|
||||
) : ApiClient {
|
||||
|
||||
private lateinit var retrofitAdapter: Retrofit
|
||||
|
||||
|
|
@ -479,11 +479,11 @@ class ApiClientImpl(
|
|||
|
||||
override suspend fun revive(): User? = process { apiService.revive() }
|
||||
|
||||
suspend override fun useSkill(skillName: String, targetType: String, targetId: String): SkillResponse? {
|
||||
override suspend fun useSkill(skillName: String, targetType: String, targetId: String): SkillResponse? {
|
||||
return process { apiService.useSkill(skillName, targetType, targetId) }
|
||||
}
|
||||
|
||||
suspend override fun useSkill(skillName: String, targetType: String): SkillResponse? {
|
||||
override suspend fun useSkill(skillName: String, targetType: String): SkillResponse? {
|
||||
return process { apiService.useSkill(skillName, targetType) }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ class UserRepositoryImpl(
|
|||
private var lastSync: Date? = null
|
||||
}
|
||||
|
||||
|
||||
override fun getUser(): Flow<User?> = getUser(userID)
|
||||
override fun getUser(userID: String): Flow<User?> = localRepository.getUser(userID)
|
||||
|
||||
|
|
@ -126,7 +125,7 @@ class UserRepositoryImpl(
|
|||
val response = apiClient.useSkill(key, target ?: "", taskId) ?: return null
|
||||
val user = getLiveUser() ?: return response
|
||||
response.hpDiff = (response.user?.stats?.hp ?: 0.0) - (user.stats?.hp ?: 0.0)
|
||||
response.expDiff =(response.user?.stats?.exp ?: 0.0) - (user.stats?.exp ?: 0.0)
|
||||
response.expDiff = (response.user?.stats?.exp ?: 0.0) - (user.stats?.exp ?: 0.0)
|
||||
response.goldDiff = (response.user?.stats?.gp ?: 0.0) - (user.stats?.gp ?: 0.0)
|
||||
response.damage = (response.user?.party?.quest?.progress?.up ?: 0.0f) - (user.party?.quest?.progress?.up ?: 0.0f)
|
||||
response.user?.let { mergeUser(user, it) }
|
||||
|
|
@ -137,7 +136,7 @@ class UserRepositoryImpl(
|
|||
val response = apiClient.useSkill(key, target ?: "") ?: return null
|
||||
val user = getLiveUser() ?: return response
|
||||
response.hpDiff = (response.user?.stats?.hp ?: 0.0) - (user.stats?.hp ?: 0.0)
|
||||
response.expDiff =(response.user?.stats?.exp ?: 0.0) - (user.stats?.exp ?: 0.0)
|
||||
response.expDiff = (response.user?.stats?.exp ?: 0.0) - (user.stats?.exp ?: 0.0)
|
||||
response.goldDiff = (response.user?.stats?.gp ?: 0.0) - (user.stats?.gp ?: 0.0)
|
||||
response.damage = (response.user?.party?.quest?.progress?.up ?: 0.0f) - (user.party?.quest?.progress?.up ?: 0.0f)
|
||||
response.user?.let { mergeUser(user, it) }
|
||||
|
|
|
|||
|
|
@ -65,5 +65,4 @@ interface InventoryLocalRepository : ContentLocalRepository {
|
|||
fun getLiveObject(obj: OwnedItem): OwnedItem?
|
||||
fun getItems(itemClass: Class<out Item>): Flow<List<Item>>
|
||||
fun getItems(itemClass: Class<out Item>, keys: Array<String>): Flow<List<Item>>
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ abstract class RealmBaseLocalRepository internal constructor(override var realm:
|
|||
private var pendingSaves = mutableListOf<Any>()
|
||||
}
|
||||
|
||||
private fun <T: RealmModel> copy(realm: Realm, obj: T) {
|
||||
private fun <T : RealmModel> copy(realm: Realm, obj: T) {
|
||||
try {
|
||||
realm.insertOrUpdate(obj)
|
||||
} catch (_: java.lang.IllegalArgumentException) {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ import java.text.SimpleDateFormat
|
|||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
class RealmInventoryLocalRepository(realm: Realm) : RealmContentLocalRepository(realm),
|
||||
class RealmInventoryLocalRepository(realm: Realm) :
|
||||
RealmContentLocalRepository(realm),
|
||||
InventoryLocalRepository {
|
||||
override fun getQuestContent(keys: List<String>): Flow<List<QuestContent>> {
|
||||
return realm.where(QuestContent::class.java)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ import kotlinx.coroutines.flow.filterNotNull
|
|||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
class RealmUserLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm),
|
||||
class RealmUserLocalRepository(realm: Realm) :
|
||||
RealmBaseLocalRepository(realm),
|
||||
UserLocalRepository {
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
override fun getUserQuestStatus(userID: String): Flow<UserQuestStatus> {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import com.habitrpg.common.habitica.helpers.AppTestingLevel
|
|||
import kotlinx.coroutines.MainScope
|
||||
import java.util.Date
|
||||
|
||||
class AppConfigManager(contentRepository: ContentRepository?): com.habitrpg.common.habitica.helpers.AppConfigManager() {
|
||||
class AppConfigManager(contentRepository: ContentRepository?) : com.habitrpg.common.habitica.helpers.AppConfigManager() {
|
||||
|
||||
private var worldState: WorldState? = null
|
||||
|
||||
|
|
|
|||
|
|
@ -7,13 +7,8 @@ import kotlinx.coroutines.CancellationException
|
|||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import okhttp3.internal.http2.ConnectionShutdownException
|
||||
import okhttp3.internal.http2.StreamResetException
|
||||
import retrofit2.HttpException
|
||||
import java.io.EOFException
|
||||
import java.io.IOException
|
||||
import java.net.SocketTimeoutException
|
||||
import java.net.UnknownHostException
|
||||
|
||||
class ExceptionHandler {
|
||||
private var analyticsManager: AnalyticsManager? = null
|
||||
|
|
@ -52,7 +47,12 @@ class ExceptionHandler {
|
|||
}
|
||||
|
||||
fun CoroutineScope.launchCatching(errorHandler: ((Throwable) -> Unit)? = null, function: suspend CoroutineScope.() -> Unit) {
|
||||
launch((ExceptionHandler.coroutine {
|
||||
launch(
|
||||
(
|
||||
ExceptionHandler.coroutine {
|
||||
errorHandler?.invoke(it)
|
||||
}), block = function)
|
||||
}
|
||||
),
|
||||
block = function
|
||||
)
|
||||
}
|
||||
|
|
@ -24,31 +24,31 @@ interface NotificationsManager {
|
|||
fun dismissTaskNotification(context: Context, task: Task)
|
||||
}
|
||||
|
||||
class MainNotificationsManager: NotificationsManager {
|
||||
class MainNotificationsManager : NotificationsManager {
|
||||
|
||||
private val seenNotifications: MutableMap<String, Boolean>
|
||||
override var apiClient: WeakReference<ApiClient>? = null
|
||||
|
||||
private var lastNotificationHandling: Date? = null
|
||||
val _notifications = MutableStateFlow<List<Notification>?>(null)
|
||||
val _displaynotificationEvents = Channel<Notification>()
|
||||
override val displayNotificationEvents: Flow<Notification> = _displaynotificationEvents.receiveAsFlow().filterNotNull()
|
||||
private val notificationsFlow = MutableStateFlow<List<Notification>?>(null)
|
||||
private val displayedNotificationEvents = Channel<Notification>()
|
||||
override val displayNotificationEvents: Flow<Notification> = displayedNotificationEvents.receiveAsFlow().filterNotNull()
|
||||
|
||||
init {
|
||||
this.seenNotifications = HashMap()
|
||||
}
|
||||
|
||||
override fun setNotifications(current: List<Notification>) {
|
||||
_notifications.value = current
|
||||
notificationsFlow.value = current
|
||||
this.handlePopupNotifications(current)
|
||||
}
|
||||
|
||||
override fun getNotifications(): Flow<List<Notification>> {
|
||||
return _notifications.filterNotNull()
|
||||
return notificationsFlow.filterNotNull()
|
||||
}
|
||||
|
||||
override fun getNotification(id: String): Notification? {
|
||||
return _notifications.value?.find { it.id == id }
|
||||
return notificationsFlow.value?.find { it.id == id }
|
||||
}
|
||||
|
||||
override fun dismissTaskNotification(context: Context, task: Task) {
|
||||
|
|
@ -92,7 +92,6 @@ class MainNotificationsManager: NotificationsManager {
|
|||
Notification.Type.ACHIEVEMENT_FRESHWATER_FRIENDS.type -> true
|
||||
Notification.Type.ACHIEVEMENT_GOOD_AS_GOLD.type -> true
|
||||
Notification.Type.ACHIEVEMENT_ALL_THAT_GLITTERS.type -> true
|
||||
Notification.Type.ACHIEVEMENT_GOOD_AS_GOLD.type -> true
|
||||
Notification.Type.ACHIEVEMENT_BONE_COLLECTOR.type -> true
|
||||
Notification.Type.ACHIEVEMENT_SKELETON_CREW.type -> true
|
||||
Notification.Type.ACHIEVEMENT_SEEING_RED.type -> true
|
||||
|
|
@ -115,7 +114,7 @@ class MainNotificationsManager: NotificationsManager {
|
|||
|
||||
private fun readNotification(notification: Notification) {
|
||||
MainScope().launchCatching {
|
||||
_displaynotificationEvents.send(notification)
|
||||
displayedNotificationEvents.send(notification)
|
||||
seenNotifications[notification.id] = true
|
||||
apiClient?.get()?.readNotification(notification.id)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,9 +121,9 @@ class PurchaseHandler(
|
|||
}
|
||||
|
||||
fun startListening() {
|
||||
if (billingClient.connectionState == BillingClient.ConnectionState.CONNECTING
|
||||
|| billingClient.connectionState == BillingClient.ConnectionState.CONNECTED
|
||||
|| billingClientState == BillingClientState.UNAVAILABLE
|
||||
if (billingClient.connectionState == BillingClient.ConnectionState.CONNECTING ||
|
||||
billingClient.connectionState == BillingClient.ConnectionState.CONNECTED ||
|
||||
billingClientState == BillingClientState.UNAVAILABLE
|
||||
) {
|
||||
// Don't connect again if it's already connected
|
||||
return
|
||||
|
|
@ -209,9 +209,11 @@ class PurchaseHandler(
|
|||
}
|
||||
billingClientState.canMaybePurchase && billingClient.isReady
|
||||
}
|
||||
val params = QueryProductDetailsParams.newBuilder().setProductList(skus.map {
|
||||
val params = QueryProductDetailsParams.newBuilder().setProductList(
|
||||
skus.map {
|
||||
Product.newBuilder().setProductId(it).setProductType(type).build()
|
||||
}).build()
|
||||
}
|
||||
).build()
|
||||
val skuDetailsResult = withContext(Dispatchers.IO) {
|
||||
billingClient.queryProductDetails(params)
|
||||
}
|
||||
|
|
@ -230,12 +232,14 @@ class PurchaseHandler(
|
|||
addGift(skuDetails.productId, it, recipientUsername ?: it)
|
||||
}
|
||||
val flowParams =
|
||||
BillingFlowParams.newBuilder().setProductDetailsParamsList(listOf(skuDetails).map {
|
||||
BillingFlowParams.newBuilder().setProductDetailsParamsList(
|
||||
listOf(skuDetails).map {
|
||||
BillingFlowParams.ProductDetailsParams.newBuilder()
|
||||
.setProductDetails(skuDetails).setOfferToken(
|
||||
skuDetails.subscriptionOfferDetails?.first()?.offerToken ?: ""
|
||||
).build()
|
||||
}).build()
|
||||
}
|
||||
).build()
|
||||
billingClient.launchBillingFlow(activity, flowParams)
|
||||
}
|
||||
|
||||
|
|
@ -555,9 +559,11 @@ class PurchaseHandler(
|
|||
}
|
||||
|
||||
suspend fun retryUntil(
|
||||
times: Int = Int.MAX_VALUE, initialDelay: Long = 100, // 0.1 second
|
||||
times: Int = Int.MAX_VALUE,
|
||||
initialDelay: Long = 100, // 0.1 second
|
||||
maxDelay: Long = 1000, // 1 second
|
||||
factor: Double = 2.0, block: suspend () -> Boolean
|
||||
factor: Double = 2.0,
|
||||
block: suspend () -> Boolean
|
||||
) {
|
||||
var currentDelay = initialDelay
|
||||
repeat(times - 1) {
|
||||
|
|
|
|||
|
|
@ -99,9 +99,9 @@ class TaskAlarmManager(
|
|||
private fun setAlarmForRemindersItem(reminderItemTask: Task, remindersItem: RemindersItem?) {
|
||||
val now = ZonedDateTime.now().withZoneSameLocal(ZoneId.systemDefault())?.toInstant()
|
||||
val zonedTime = remindersItem?.getLocalZonedDateTimeInstant()
|
||||
if (remindersItem == null
|
||||
|| (reminderItemTask.type == TaskType.DAILY && zonedTime?.isBefore(now) == true && reminderItemTask.nextDue?.firstOrNull() != null)
|
||||
|| (reminderItemTask.type == TaskType.TODO && zonedTime?.isBefore(now) == true)
|
||||
if (remindersItem == null ||
|
||||
(reminderItemTask.type == TaskType.DAILY && zonedTime?.isBefore(now) == true && reminderItemTask.nextDue?.firstOrNull() != null) ||
|
||||
(reminderItemTask.type == TaskType.TODO && zonedTime?.isBefore(now) == true)
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
|
@ -226,7 +226,7 @@ class TaskAlarmManager(
|
|||
try {
|
||||
alarmManager?.setAlarmClock(AlarmClockInfo(time, pendingIntent), pendingIntent)
|
||||
} catch (ex: Exception) {
|
||||
when(ex) {
|
||||
when (ex) {
|
||||
is IllegalStateException, is SecurityException -> {
|
||||
alarmManager?.setWindow(AlarmManager.RTC_WAKEUP, time, 60000, pendingIntent)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,11 +94,13 @@ class TaskDescriptionBuilder(private val context: Context) {
|
|||
""
|
||||
}
|
||||
}
|
||||
Frequency.YEARLY -> " " + context.getString(R.string.on_x,
|
||||
Frequency.YEARLY -> " " + context.getString(
|
||||
R.string.on_x,
|
||||
task.startDate?.let {
|
||||
val flags = DateUtils.FORMAT_SHOW_DATE + DateUtils.FORMAT_NO_YEAR
|
||||
DateUtils.formatDateTime(context, it.time, flags)
|
||||
} ?: "")
|
||||
} ?: ""
|
||||
)
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ class PushNotificationManager(
|
|||
addRefreshToken()
|
||||
} catch (_: IOException) {
|
||||
// catchy catch-catch
|
||||
} catch (_: Exception){
|
||||
} catch (_: Exception) {
|
||||
// catchy catch-catch-cat, I'm out of breath.
|
||||
}
|
||||
}
|
||||
|
|
@ -133,7 +133,8 @@ class PushNotificationManager(
|
|||
val remoteMessageIdentifier = remoteMessage.data["identifier"]
|
||||
|
||||
val notificationFactory = HabiticaLocalNotificationFactory()
|
||||
val notification = notificationFactory.build(remoteMessageIdentifier,
|
||||
val notification = notificationFactory.build(
|
||||
remoteMessageIdentifier,
|
||||
context
|
||||
)
|
||||
if (pushNotificationManager?.userIsSubscribedToNotificationType(remoteMessageIdentifier) != false) {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import kotlinx.coroutines.launch
|
|||
import javax.inject.Inject
|
||||
|
||||
class DisplayItemDropUseCase @Inject
|
||||
constructor(private val soundManager: SoundManager):
|
||||
constructor(private val soundManager: SoundManager) :
|
||||
UseCase<DisplayItemDropUseCase.RequestValues, Unit>() {
|
||||
|
||||
override suspend fun run(requestValues: RequestValues) {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,8 @@ import javax.inject.Inject
|
|||
|
||||
class HatchPetUseCase @Inject
|
||||
constructor(
|
||||
private val inventoryRepository: InventoryRepository) : UseCase<HatchPetUseCase.RequestValues, Items?>() {
|
||||
private val inventoryRepository: InventoryRepository
|
||||
) : UseCase<HatchPetUseCase.RequestValues, Items?>() {
|
||||
override suspend fun run(requestValues: RequestValues): Items? {
|
||||
return inventoryRepository.hatchPet(requestValues.egg, requestValues.potion) {
|
||||
val petWrapper = View.inflate(requestValues.context, R.layout.pet_imageview, null) as? FrameLayout
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ import io.realm.RealmObject
|
|||
import io.realm.annotations.RealmClass
|
||||
|
||||
@RealmClass(embedded = true)
|
||||
open class MemberPreferences : RealmObject(),
|
||||
open class MemberPreferences :
|
||||
RealmObject(),
|
||||
AvatarPreferences {
|
||||
|
||||
override var hair: Hair? = null
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ import com.habitrpg.android.habitica.databinding.FragmentGemPurchaseBinding
|
|||
import com.habitrpg.android.habitica.databinding.FragmentSubscriptionBinding
|
||||
import com.habitrpg.android.habitica.databinding.PurchaseGemViewBinding
|
||||
import com.habitrpg.android.habitica.extensions.DateUtils
|
||||
import com.habitrpg.common.habitica.extensions.isUsingNightModeResources
|
||||
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
||||
import com.habitrpg.android.habitica.ui.fragments.PromoInfoFragment
|
||||
import com.habitrpg.android.habitica.ui.fragments.purchases.SubscriptionFragment
|
||||
import com.habitrpg.android.habitica.ui.views.promo.PromoMenuView
|
||||
import com.habitrpg.common.habitica.extensions.isUsingNightModeResources
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
|
|
|||
|
|
@ -96,7 +96,6 @@ open class Task : RealmObject, BaseMainObject, Parcelable, BaseTask {
|
|||
.equals(ZonedDateTime.now().withZoneSameLocal(ZoneId.systemDefault()).toLocalDate())
|
||||
}
|
||||
|
||||
|
||||
// Needed for offline creating/updating
|
||||
var isSaving: Boolean = false
|
||||
var hasErrored: Boolean = false
|
||||
|
|
@ -307,14 +306,14 @@ open class Task : RealmObject, BaseMainObject, Parcelable, BaseTask {
|
|||
val now = ZonedDateTime.now().withZoneSameLocal(ZoneId.systemDefault())?.toInstant()
|
||||
val nextDate = nextDue?.firstOrNull()
|
||||
|
||||
//If task !isDisplayedActive or if isDisplayedActive but reminder passed,
|
||||
//set a updated reminder with nextDate
|
||||
// If task !isDisplayedActive or if isDisplayedActive but reminder passed,
|
||||
// set a updated reminder with nextDate
|
||||
return if (nextDate != null && (!isDisplayedActive || remindersItem.getLocalZonedDateTimeInstant()?.isBefore(now) == true)) {
|
||||
val nextDueCalendar = GregorianCalendar()
|
||||
nextDueCalendar.time = nextDate
|
||||
parse(oldTime)
|
||||
?.withYear(nextDueCalendar.get(Calendar.YEAR))
|
||||
?.withMonth(nextDueCalendar.get(Calendar.MONTH) + 1) //+1 to handle Gregorian Calendar month range from 0-11
|
||||
?.withMonth(nextDueCalendar.get(Calendar.MONTH) + 1) // +1 to handle Gregorian Calendar month range from 0-11
|
||||
?.withDayOfMonth(nextDueCalendar.get(Calendar.DAY_OF_MONTH))
|
||||
} else {
|
||||
return parse(oldTime)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import io.realm.annotations.RealmClass
|
|||
import java.util.Date
|
||||
|
||||
@RealmClass(embedded = true)
|
||||
open class GroupAssignedDetails: RealmObject(), BaseObject {
|
||||
open class GroupAssignedDetails : RealmObject(), BaseObject {
|
||||
var assignedDate: Date? = null
|
||||
var assignedUsername: String? = null
|
||||
var assignedUserID: String? = null
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package com.habitrpg.android.habitica.models.user
|
|||
import com.habitrpg.android.habitica.models.BaseObject
|
||||
import io.realm.RealmObject
|
||||
|
||||
open class Permissions: RealmObject(), BaseObject {
|
||||
open class Permissions : RealmObject(), BaseObject {
|
||||
var userSupport: Boolean = false
|
||||
var fullAccess: Boolean = false
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import io.realm.RealmObject
|
|||
import io.realm.annotations.RealmClass
|
||||
|
||||
@RealmClass(embedded = true)
|
||||
open class UserTaskPreferences: RealmObject(), BaseObject {
|
||||
open class UserTaskPreferences : RealmObject(), BaseObject {
|
||||
var confirmScoreNotes: Boolean = false
|
||||
var mirrorGroupTasks: RealmList<String> = RealmList()
|
||||
var groupByChallenge: Boolean = false
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import androidx.appcompat.app.AppCompatActivity
|
|||
import androidx.core.content.edit
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.habitrpg.android.habitica.databinding.WidgetConfigureAddTaskBinding
|
||||
import com.habitrpg.shared.habitica.models.tasks.TaskType
|
||||
import com.habitrpg.android.habitica.widget.AddTaskWidgetProvider
|
||||
import com.habitrpg.shared.habitica.models.tasks.TaskType
|
||||
|
||||
class AddTaskWidgetActivity : AppCompatActivity() {
|
||||
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ class ArmoireActivity : BaseActivity() {
|
|||
}
|
||||
else -> {
|
||||
@SuppressLint("SetTextI18n")
|
||||
binding.titleView.text = "+${value} ${binding.titleView.text}"
|
||||
binding.titleView.text = "+$value ${binding.titleView.text}"
|
||||
binding.subtitleView.text = getString(R.string.armoireExp)
|
||||
binding.iconView.setImageResource(R.drawable.armoire_experience)
|
||||
val layoutParams = RelativeLayout.LayoutParams(108.dpToPx(this), 122.dpToPx(this))
|
||||
|
|
|
|||
|
|
@ -4,10 +4,8 @@ import android.content.Context
|
|||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.content.res.Configuration
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.provider.MediaStore
|
||||
import android.view.LayoutInflater
|
||||
|
|
@ -40,7 +38,6 @@ import com.habitrpg.common.habitica.extensions.isUsingNightModeResources
|
|||
import com.habitrpg.common.habitica.helpers.LanguageHelper
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
|
||||
abstract class BaseActivity : AppCompatActivity() {
|
||||
|
|
|
|||
|
|
@ -198,7 +198,8 @@ class BirthdayActivity : BaseActivity() {
|
|||
@Composable
|
||||
fun BirthdayTitle(text: String) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically, modifier = Modifier
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 20.dp, bottom = 8.dp)
|
||||
) {
|
||||
|
|
@ -259,7 +260,8 @@ fun BirthdayActivityView(
|
|||
scaffoldState = scaffoldState
|
||||
) { padding ->
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier
|
||||
.background(
|
||||
Brush.verticalGradient(
|
||||
Pair(0.0f, colorResource(id = R.color.brand_300)),
|
||||
|
|
@ -291,7 +293,8 @@ fun BirthdayActivityView(
|
|||
)
|
||||
}
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 20.dp)
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
|
|
@ -388,7 +391,8 @@ fun BirthdayActivityView(
|
|||
} else if (isPurchasing) {
|
||||
CircularProgressIndicator()
|
||||
} else {
|
||||
Text(buildAnnotatedString {
|
||||
Text(
|
||||
buildAnnotatedString {
|
||||
append("Buy for ")
|
||||
withStyle(SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||
append(price)
|
||||
|
|
@ -397,7 +401,9 @@ fun BirthdayActivityView(
|
|||
withStyle(SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||
append("60 Gems")
|
||||
}
|
||||
}, color = Color.White)
|
||||
},
|
||||
color = Color.White
|
||||
)
|
||||
HabiticaButton(
|
||||
Color.White,
|
||||
colorResource(R.color.brand_200),
|
||||
|
|
@ -557,7 +563,8 @@ fun PotionGrid() {
|
|||
AsyncImage(
|
||||
model = DataBindingUtils.BASE_IMAGE_URL + DataBindingUtils.getFullFilename(
|
||||
"Pet_HatchingPotion_$potion"
|
||||
), null, Modifier.size(68.dp)
|
||||
),
|
||||
null, Modifier.size(68.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -616,11 +623,14 @@ fun HabiticaButton(
|
|||
modifier: Modifier = Modifier,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
Box(contentAlignment = Alignment.Center, modifier = modifier
|
||||
Box(
|
||||
contentAlignment = Alignment.Center,
|
||||
modifier = modifier
|
||||
.background(background, HabiticaTheme.shapes.medium)
|
||||
.clickable { onClick() }
|
||||
.fillMaxWidth()
|
||||
.padding(8.dp)) {
|
||||
.padding(8.dp)
|
||||
) {
|
||||
ProvideTextStyle(
|
||||
value = TextStyle(
|
||||
fontSize = 18.sp,
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import com.plattysoft.leonids.ParticleSystem
|
|||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
class DeathActivity: BaseActivity() {
|
||||
class DeathActivity : BaseActivity() {
|
||||
private lateinit var binding: ActivityDeathBinding
|
||||
|
||||
@Inject
|
||||
|
|
@ -109,9 +109,8 @@ class DeathActivity: BaseActivity() {
|
|||
.setScaleRange(0.5f, 0.8f)
|
||||
.setSpeedRange(0.01f, 0.03f)
|
||||
.setFadeOut(4000, AccelerateInterpolator())
|
||||
.setSpeedModuleAndAngleRange(0.01f, 0.03f, startAngle, startAngle+80)
|
||||
.emit(binding.root.width / 2, positionArray[1] + (binding.heartView.height/2), 3, 6000)
|
||||
|
||||
.setSpeedModuleAndAngleRange(0.01f, 0.03f, startAngle, startAngle + 80)
|
||||
.emit(binding.root.width / 2, positionArray[1] + (binding.heartView.height / 2), 3, 6000)
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
|
|
|
|||
|
|
@ -13,9 +13,8 @@ import com.habitrpg.android.habitica.databinding.ActivityFixcharacterBinding
|
|||
import com.habitrpg.android.habitica.extensions.setTintWith
|
||||
import com.habitrpg.android.habitica.models.user.Stats
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
|
||||
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
import javax.inject.Inject
|
||||
|
||||
class FixCharacterValuesActivity : BaseActivity() {
|
||||
|
|
|
|||
|
|
@ -174,21 +174,27 @@ class FullProfileActivity : BaseActivity() {
|
|||
}
|
||||
menu.setGroupVisible(R.id.admin_items, isModerator)
|
||||
if (isModerator) {
|
||||
menu.findItem(R.id.ban_user)?.title = getString(if (member.value?.authentication?.blocked == true) {
|
||||
menu.findItem(R.id.ban_user)?.title = getString(
|
||||
if (member.value?.authentication?.blocked == true) {
|
||||
R.string.unban_user
|
||||
} else {
|
||||
R.string.ban_user
|
||||
})
|
||||
menu.findItem(R.id.shadow_mute_user)?.title = getString(if (member.value?.flags?.chatShadowMuted == true) {
|
||||
}
|
||||
)
|
||||
menu.findItem(R.id.shadow_mute_user)?.title = getString(
|
||||
if (member.value?.flags?.chatShadowMuted == true) {
|
||||
R.string.unshadowmute_user
|
||||
} else {
|
||||
R.string.shadow_mute_user
|
||||
})
|
||||
menu.findItem(R.id.mute_user)?.title = getString(if (member.value?.flags?.chatRevoked == true) {
|
||||
}
|
||||
)
|
||||
menu.findItem(R.id.mute_user)?.title = getString(
|
||||
if (member.value?.flags?.chatRevoked == true) {
|
||||
R.string.unmute_user
|
||||
} else {
|
||||
R.string.mute_user
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
return super.onCreateOptionsMenu(menu)
|
||||
}
|
||||
|
|
@ -357,7 +363,7 @@ class FullProfileActivity : BaseActivity() {
|
|||
if (imageUrl == null || imageUrl.isEmpty()) {
|
||||
binding.profileImage.visibility = View.GONE
|
||||
} else {
|
||||
//binding.profileImage.load(imageUrl)
|
||||
// binding.profileImage.load(imageUrl)
|
||||
}
|
||||
|
||||
val blurbText = profile.blurb
|
||||
|
|
|
|||
|
|
@ -81,10 +81,12 @@ class LoginActivity : BaseActivity() {
|
|||
showValidationError(R.string.login_validation_error_fieldsmissing)
|
||||
return
|
||||
}
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine {
|
||||
lifecycleScope.launch(
|
||||
ExceptionHandler.coroutine {
|
||||
hideProgress()
|
||||
ExceptionHandler.reportError(it)
|
||||
}) {
|
||||
}
|
||||
) {
|
||||
val response = apiClient.connectUser(username, password)
|
||||
if (response != null) {
|
||||
handleAuthResponse(response)
|
||||
|
|
@ -112,10 +114,12 @@ class LoginActivity : BaseActivity() {
|
|||
)
|
||||
return
|
||||
}
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine {
|
||||
lifecycleScope.launch(
|
||||
ExceptionHandler.coroutine {
|
||||
hideProgress()
|
||||
ExceptionHandler.reportError(it)
|
||||
}) {
|
||||
}
|
||||
) {
|
||||
val response = apiClient.registerUser(username, email, password, confirmPassword)
|
||||
if (response != null) {
|
||||
handleAuthResponse(response)
|
||||
|
|
|
|||
|
|
@ -96,9 +96,11 @@ class ReportMessageActivity : BaseActivity() {
|
|||
}
|
||||
isReporting = true
|
||||
messageID?.let {
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine {
|
||||
lifecycleScope.launch(
|
||||
ExceptionHandler.coroutine {
|
||||
isReporting = false
|
||||
}) {
|
||||
}
|
||||
) {
|
||||
socialRepository.flagMessage(messageID ?: "", binding.additionalInfoEdittext.text.toString(), groupID)
|
||||
finish()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -206,7 +206,6 @@ class SetupActivity : BaseActivity(), ViewPager.OnPageChangeListener {
|
|||
|
||||
override fun onPageScrollStateChanged(state: Int) = Unit
|
||||
|
||||
|
||||
private var hasCompleted = false
|
||||
private fun onUserReceived(user: User?) {
|
||||
if (completedSetup && !hasCompleted) {
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ class TaskFormActivity : BaseActivity() {
|
|||
if (granted) {
|
||||
pushNotificationManager.addPushDeviceUsingStoredToken()
|
||||
} else {
|
||||
//If user denies notification settings originally - they must manually enable it through notification settings.
|
||||
// If user denies notification settings originally - they must manually enable it through notification settings.
|
||||
val alert = HabiticaAlertDialog(this)
|
||||
alert.setTitle(R.string.push_notification_system_settings_title)
|
||||
alert.setMessage(R.string.push_notification_system_settings_description)
|
||||
|
|
@ -340,7 +340,8 @@ class TaskFormActivity : BaseActivity() {
|
|||
HabiticaTheme {
|
||||
TaskDifficultySelector(
|
||||
viewModel.taskDifficulty.value,
|
||||
onSelect = { viewModel.taskDifficulty.value = it })
|
||||
onSelect = { viewModel.taskDifficulty.value = it }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -351,32 +352,38 @@ class TaskFormActivity : BaseActivity() {
|
|||
viewModel.habitScoringPositive.value,
|
||||
viewModel.habitScoringNegative.value,
|
||||
{ viewModel.habitScoringPositive.value = !viewModel.habitScoringPositive.value },
|
||||
{ viewModel.habitScoringNegative.value = !viewModel.habitScoringNegative.value })
|
||||
{ viewModel.habitScoringNegative.value = !viewModel.habitScoringNegative.value }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
binding.habitResetStreakButtons.setContent {
|
||||
HabiticaTheme {
|
||||
TaskFormSelector(
|
||||
viewModel.habitResetOption.value, listOf(
|
||||
viewModel.habitResetOption.value,
|
||||
listOf(
|
||||
LabeledValue(getString(R.string.repeat_daily), HabitResetOption.DAILY),
|
||||
LabeledValue(getString(R.string.weekly), HabitResetOption.WEEKLY),
|
||||
LabeledValue(getString(R.string.monthly), HabitResetOption.MONTHLY)
|
||||
), { viewModel.habitResetOption.value = it }, columnSize = 3
|
||||
),
|
||||
{ viewModel.habitResetOption.value = it }, columnSize = 3
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
binding.statsSelector.setContent {
|
||||
HabiticaTheme {
|
||||
TaskFormSelector(viewModel.selectedAttribute.value, listOf(
|
||||
TaskFormSelector(
|
||||
viewModel.selectedAttribute.value,
|
||||
listOf(
|
||||
LabeledValue(getString(R.string.strength), Attribute.STRENGTH),
|
||||
LabeledValue(getString(R.string.constitution), Attribute.CONSTITUTION),
|
||||
LabeledValue(getString(R.string.intelligence), Attribute.INTELLIGENCE),
|
||||
LabeledValue(getString(R.string.perception), Attribute.PERCEPTION)
|
||||
), { viewModel.selectedAttribute.value = it })
|
||||
),
|
||||
{ viewModel.selectedAttribute.value = it }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -240,7 +240,8 @@ fun TaskSummaryView(viewModel: TaskSummaryViewModel) {
|
|||
.fillMaxWidth()
|
||||
) {
|
||||
Image(HabiticaIconsHelper.imageOfGold().asImageBitmap(), null)
|
||||
Text("${task?.value}",
|
||||
Text(
|
||||
"${task?.value}",
|
||||
fontSize = 16.sp,
|
||||
fontWeight = FontWeight.Medium,
|
||||
color = darkestColor
|
||||
|
|
@ -285,7 +286,8 @@ fun TaskSummaryView(viewModel: TaskSummaryViewModel) {
|
|||
for (item in task?.group?.assignedUsersDetail ?: emptyList()) {
|
||||
val member = viewModel.getMember(item.assignedUserID).collectAsState(null)
|
||||
UserRow(
|
||||
item.assignedUsername ?: "", member.value, Modifier
|
||||
item.assignedUsername ?: "", member.value,
|
||||
Modifier
|
||||
.padding(vertical = 4.dp)
|
||||
.background(
|
||||
HabiticaTheme.colors.windowBackgroundFor(task),
|
||||
|
|
@ -295,9 +297,11 @@ fun TaskSummaryView(viewModel: TaskSummaryViewModel) {
|
|||
.heightIn(min = 24.dp)
|
||||
.fillMaxWidth(),
|
||||
color = darkestColor,
|
||||
extraContent = if (item.completed) ({
|
||||
extraContent = if (item.completed) (
|
||||
{
|
||||
CompletedAt(item.completedDate)
|
||||
}) else null
|
||||
}
|
||||
) else null
|
||||
)
|
||||
}
|
||||
task?.group?.assignedUsersDetail?.find { it.assignedUserID == viewModel.userViewModel.userID }
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ import com.habitrpg.android.habitica.databinding.AchievementSectionHeaderBinding
|
|||
import com.habitrpg.android.habitica.extensions.inflate
|
||||
import com.habitrpg.android.habitica.models.Achievement
|
||||
import com.habitrpg.android.habitica.models.QuestAchievement
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.AchievementDetailDialog
|
||||
import com.habitrpg.common.habitica.extensions.loadImage
|
||||
import com.habitrpg.common.habitica.views.PixelArtView
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.AchievementDetailDialog
|
||||
|
||||
class AchievementsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
|
||||
|
|
|
|||
|
|
@ -119,7 +119,8 @@ class CustomizationEquipmentRecyclerViewAdapter : androidx.recyclerview.widget.R
|
|||
priceLabel?.text = itemValue.toString()
|
||||
|
||||
(dialogContent.findViewById<View>(R.id.gem_icon) as? ImageView)?.setImageBitmap(
|
||||
HabiticaIconsHelper.imageOfGem())
|
||||
HabiticaIconsHelper.imageOfGem()
|
||||
)
|
||||
|
||||
val dialog = HabiticaAlertDialog(itemView.context)
|
||||
dialog.addButton(R.string.purchase_button, true) { _, _ ->
|
||||
|
|
|
|||
|
|
@ -113,9 +113,15 @@ class CustomizationRecyclerViewAdapter() : androidx.recyclerview.widget.Recycler
|
|||
val isOwned = ownedCustomizations.contains(customization.id)
|
||||
val isUsable = customization.isUsable(isOwned)
|
||||
if (customization.availableFrom != null || customization.availableUntil != null) {
|
||||
if (((customization.availableFrom?.compareTo(today)
|
||||
?: 0) > 0 || (customization.availableUntil?.compareTo(today)
|
||||
?: 0) < 0) && !isUsable
|
||||
if ((
|
||||
(
|
||||
customization.availableFrom?.compareTo(today)
|
||||
?: 0
|
||||
) > 0 || (
|
||||
customization.availableUntil?.compareTo(today)
|
||||
?: 0
|
||||
) < 0
|
||||
) && !isUsable
|
||||
) {
|
||||
continue
|
||||
}
|
||||
|
|
@ -218,7 +224,7 @@ class CustomizationRecyclerViewAdapter() : androidx.recyclerview.widget.Recycler
|
|||
return
|
||||
}
|
||||
|
||||
if (customization?.type == "background"){
|
||||
if (customization?.type == "background") {
|
||||
val alert = HabiticaAlertDialog(context = itemView.context)
|
||||
val purchasedCustomizationView: View = LayoutInflater.from(itemView.context).inflate(R.layout.purchased_equip_dialog, null)
|
||||
val layerMap = EnumMap<AvatarView.LayerType, String>(AvatarView.LayerType::class.java)
|
||||
|
|
|
|||
|
|
@ -111,7 +111,6 @@ class NavigationDrawerAdapter(tintColor: Int, backgroundTintColor: Int) : Recycl
|
|||
|
||||
private fun getItem(position: Int) = items.filter { it.isVisible }[position]
|
||||
|
||||
|
||||
override fun getItemCount(): Int = items.count { it.isVisible }
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
|
|
|
|||
|
|
@ -102,8 +102,8 @@ class ItemRecyclerAdapter(val context: Context) : BaseRecyclerViewAdapter<OwnedI
|
|||
!this.canHatch
|
||||
} else false
|
||||
val imageName = if (item != null) {
|
||||
getImageName(item = item) }
|
||||
else {
|
||||
getImageName(item = item)
|
||||
} else {
|
||||
getImageName(ownedItem = ownedItem)
|
||||
}
|
||||
binding.imageView.loadImage(imageName)
|
||||
|
|
@ -130,7 +130,7 @@ class ItemRecyclerAdapter(val context: Context) : BaseRecyclerViewAdapter<OwnedI
|
|||
"inventory_quest_scroll_" + item.key
|
||||
}
|
||||
is SpecialItem -> {
|
||||
//Mystery Item (Inventory Present)
|
||||
// Mystery Item (Inventory Present)
|
||||
val sdf = SimpleDateFormat("MM", Locale.getDefault())
|
||||
val month = sdf.format(Date())
|
||||
"inventory_present_$month"
|
||||
|
|
@ -153,8 +153,8 @@ class ItemRecyclerAdapter(val context: Context) : BaseRecyclerViewAdapter<OwnedI
|
|||
val menu = BottomSheetMenu(context)
|
||||
menu.setTitle(item?.text)
|
||||
val imageName = if (item != null) {
|
||||
getImageName(item = item) }
|
||||
else {
|
||||
getImageName(item = item)
|
||||
} else {
|
||||
getImageName(ownedItem = ownedItem)
|
||||
}
|
||||
menu.setImage(imageName)
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@ class StableRecyclerAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
|||
private var ownsSaddles: Boolean = false
|
||||
private var itemList: List<Any> = ArrayList()
|
||||
|
||||
|
||||
private fun canRaiseToMount(pet: Pet): Boolean {
|
||||
if (pet.type == "special") return false
|
||||
for (mount in existingMounts ?: emptyList()) {
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ import com.habitrpg.android.habitica.databinding.ProfileAchievementItemBinding
|
|||
import com.habitrpg.android.habitica.extensions.inflate
|
||||
import com.habitrpg.android.habitica.models.Achievement
|
||||
import com.habitrpg.android.habitica.ui.activities.MainActivity
|
||||
import com.habitrpg.common.habitica.extensions.loadImage
|
||||
import com.habitrpg.android.habitica.ui.viewHolders.SectionViewHolder
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.AchievementDetailDialog
|
||||
import com.habitrpg.common.habitica.extensions.loadImage
|
||||
|
||||
class AchievementProfileAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import com.habitrpg.android.habitica.ui.adapter.BaseRecyclerViewAdapter
|
|||
import com.habitrpg.android.habitica.ui.fragments.social.challenges.ChallengeFilterOptions
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
import com.habitrpg.common.habitica.helpers.EmojiParser
|
||||
|
||||
import io.realm.OrderedRealmCollection
|
||||
|
||||
class ChallengesListViewAdapter(
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ class DailiesRecyclerViewHolder(layoutResource: Int, viewModel: TasksViewModel)
|
|||
}, {
|
||||
task ->
|
||||
brokenTaskEvents?.invoke(task)
|
||||
}, viewModel)
|
||||
}, viewModel
|
||||
)
|
||||
} else {
|
||||
super.onCreateViewHolder(parent, viewType)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ class HabitsRecyclerViewAdapter(layoutResource: Int, viewModel: TasksViewModel)
|
|||
}, {
|
||||
task ->
|
||||
brokenTaskEvents?.invoke(task)
|
||||
}, viewModel)
|
||||
}, viewModel
|
||||
)
|
||||
} else {
|
||||
super.onCreateViewHolder(parent, viewType)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,7 +75,8 @@ class RewardsRecyclerViewAdapter(
|
|||
{ task -> taskOpenEvents?.invoke(task.first, task.second) }, {
|
||||
task ->
|
||||
brokenTaskEvents?.invoke(task)
|
||||
}, viewModel)
|
||||
}, viewModel
|
||||
)
|
||||
} else {
|
||||
val viewHolder = ShopItemViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.row_shopitem, parent, false))
|
||||
viewHolder.purchaseCardAction = { purchaseCardEvents?.invoke(it) }
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ class TodosRecyclerViewAdapter(layoutResource: Int, viewModel: TasksViewModel) :
|
|||
}, {
|
||||
task ->
|
||||
brokenTaskEvents?.invoke(task)
|
||||
}, viewModel)
|
||||
}, viewModel
|
||||
)
|
||||
} else {
|
||||
super.onCreateViewHolder(parent, viewType)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,9 +97,11 @@ class AchievementsFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding
|
|||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.getAchievements().combine(userRepository.getQuestAchievements()) { achievements, questAchievements ->
|
||||
return@combine Pair(achievements, questAchievements)
|
||||
}.combine(userRepository.getQuestAchievements()
|
||||
}.combine(
|
||||
userRepository.getQuestAchievements()
|
||||
.map { it.mapNotNull { achievement -> achievement.questKey } }
|
||||
.map { inventoryRepository.getQuestContent(it).firstOrNull() }) { achievements, content ->
|
||||
.map { inventoryRepository.getQuestContent(it).firstOrNull() }
|
||||
) { achievements, content ->
|
||||
Pair(achievements, content)
|
||||
}.collect {
|
||||
val achievements = it.first.first
|
||||
|
|
|
|||
|
|
@ -285,8 +285,10 @@ class NavigationDrawerFragment : DialogFragment() {
|
|||
if (!user.hasClass && !hasSpecialItems) {
|
||||
item.isVisible = false
|
||||
} else {
|
||||
if ((user.stats?.lvl
|
||||
?: 0) < HabiticaSnackbar.MIN_LEVEL_FOR_SKILLS && (!hasSpecialItems)
|
||||
if ((
|
||||
user.stats?.lvl
|
||||
?: 0
|
||||
) < HabiticaSnackbar.MIN_LEVEL_FOR_SKILLS && (!hasSpecialItems)
|
||||
) {
|
||||
item.pillText = getString(R.string.unlock_lvl_11)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ import com.habitrpg.android.habitica.ui.views.equipment.EquipmentOverviewView
|
|||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import javax.inject.Inject
|
||||
|
||||
open class AvatarOverviewFragment : BaseMainFragment<FragmentComposeScrollingBinding>(),
|
||||
open class AvatarOverviewFragment :
|
||||
BaseMainFragment<FragmentComposeScrollingBinding>(),
|
||||
AdapterView.OnItemSelectedListener {
|
||||
|
||||
@Inject
|
||||
|
|
@ -71,7 +72,8 @@ open class AvatarOverviewFragment : BaseMainFragment<FragmentComposeScrollingBin
|
|||
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
||||
setContent {
|
||||
HabiticaTheme {
|
||||
AvatarOverviewView(userViewModel,
|
||||
AvatarOverviewView(
|
||||
userViewModel,
|
||||
showCustomization, !showCustomization,
|
||||
battleGearWeapon.value?.twoHanded == true, costumeWeapon.value?.twoHanded == true,
|
||||
{ type, category ->
|
||||
|
|
@ -80,7 +82,8 @@ open class AvatarOverviewFragment : BaseMainFragment<FragmentComposeScrollingBin
|
|||
displayAvatarEquipmentFragment(type, category)
|
||||
}, { type, equipped, isCostume ->
|
||||
displayEquipmentFragment(type, equipped, isCostume)
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -137,7 +140,8 @@ open class AvatarOverviewFragment : BaseMainFragment<FragmentComposeScrollingBin
|
|||
}
|
||||
|
||||
@Composable
|
||||
fun AvatarOverviewView(userViewModel: MainUserViewModel,
|
||||
fun AvatarOverviewView(
|
||||
userViewModel: MainUserViewModel,
|
||||
showCustomization: Boolean = true,
|
||||
showEquipment: Boolean = true,
|
||||
battleGearTwoHanded: Boolean = false,
|
||||
|
|
@ -145,12 +149,13 @@ fun AvatarOverviewView(userViewModel: MainUserViewModel,
|
|||
onCustomizationTap: (String, String?) -> Unit,
|
||||
onAvatarEquipmentTap: (String, String?) -> Unit,
|
||||
onEquipmentTap: (String, String?, Boolean) -> Unit
|
||||
) {
|
||||
) {
|
||||
val user by userViewModel.user.observeAsState()
|
||||
Column(
|
||||
Modifier
|
||||
.padding(horizontal = 8.dp)
|
||||
.padding(bottom = 16.dp)) {
|
||||
.padding(bottom = 16.dp)
|
||||
) {
|
||||
if (showCustomization) {
|
||||
Row(
|
||||
Modifier.padding(horizontal = 12.dp, vertical = 15.dp),
|
||||
|
|
@ -162,8 +167,10 @@ fun AvatarOverviewView(userViewModel: MainUserViewModel,
|
|||
color = HabiticaTheme.colors.textSecondary
|
||||
)
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
SegmentedControl(items = listOf(
|
||||
stringResource(R.string.avatar_size_slim), stringResource(
|
||||
SegmentedControl(
|
||||
items = listOf(
|
||||
stringResource(R.string.avatar_size_slim),
|
||||
stringResource(
|
||||
R.string.avatar_size_broad
|
||||
)
|
||||
),
|
||||
|
|
@ -173,7 +180,8 @@ fun AvatarOverviewView(userViewModel: MainUserViewModel,
|
|||
"preferences.size",
|
||||
if (it == 0) "slim" else "broad"
|
||||
)
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
AvatarCustomizationOverviewView(user?.preferences, user?.items?.gear?.equipped, onCustomizationTap, onAvatarEquipmentTap)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -288,7 +288,6 @@ class ItemDialogFragment : BaseDialogFragment<FragmentItemsDialogBinding>() {
|
|||
}
|
||||
adapter?.items = itemMap
|
||||
}
|
||||
|
||||
}
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
inventoryRepository.getPets().collect { adapter?.setExistingPets(it) }
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ class ItemRecyclerFragment : BaseFragment<FragmentItemsBinding>(), SwipeRefreshL
|
|||
alert?.setMessage(R.string.quest_party_required_description)
|
||||
alert?.addButton(R.string.create_new_party, true, false) { _, _ ->
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
val group = socialRepository.createGroup(
|
||||
socialRepository.createGroup(
|
||||
getString(R.string.usernames_party, user?.profile?.name),
|
||||
"",
|
||||
user?.id,
|
||||
|
|
|
|||
|
|
@ -218,7 +218,6 @@ class PetDetailRecyclerFragment :
|
|||
}
|
||||
adapter.setItemList(items)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -172,8 +172,6 @@ class StableRecyclerFragment :
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
companion object {
|
||||
private const val ITEM_TYPE_KEY = "CLASS_TYPE_KEY"
|
||||
private const val HEADER_VIEW_TYPE = 0
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@ import com.habitrpg.android.habitica.R
|
|||
import com.habitrpg.android.habitica.data.ApiClient
|
||||
import com.habitrpg.android.habitica.extensions.addCancelButton
|
||||
import com.habitrpg.android.habitica.extensions.addCloseButton
|
||||
import com.habitrpg.common.habitica.extensions.dpToPx
|
||||
import com.habitrpg.common.habitica.extensions.layoutInflater
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
||||
import com.habitrpg.android.habitica.helpers.launchCatching
|
||||
|
|
@ -41,6 +39,8 @@ import com.habitrpg.android.habitica.ui.views.ValidatingEditText
|
|||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaProgressDialog
|
||||
import com.habitrpg.common.habitica.api.HostConfig
|
||||
import com.habitrpg.common.habitica.extensions.dpToPx
|
||||
import com.habitrpg.common.habitica.extensions.layoutInflater
|
||||
import kotlinx.coroutines.launch
|
||||
import retrofit2.HttpException
|
||||
import javax.inject.Inject
|
||||
|
|
@ -334,7 +334,7 @@ class AccountPreferenceFragment :
|
|||
user?.username ?: "",
|
||||
email ?: "",
|
||||
passwordEditText.text ?: "",
|
||||
passwordRepeatEditText?.text ?: ""
|
||||
passwordRepeatEditText.text ?: ""
|
||||
)
|
||||
(activity as? SnackbarActivity)?.showSnackbar(
|
||||
content = context.getString(R.string.password_added),
|
||||
|
|
@ -471,7 +471,6 @@ class AccountPreferenceFragment :
|
|||
if (habiticaAccountDialog != null) {
|
||||
accountDialog = habiticaAccountDialog
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun showConfirmUsernameDialog() {
|
||||
|
|
@ -519,5 +518,4 @@ class AccountPreferenceFragment :
|
|||
override fun deletionConfirmClicked(confirmationString: String) {
|
||||
deleteAccount(confirmationString)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import com.habitrpg.android.habitica.R
|
|||
import com.habitrpg.android.habitica.databinding.DialogHabiticaAccountBinding
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
|
||||
|
||||
class HabiticaAccountDialog(private var thisContext: Context) : DialogFragment(R.layout.dialog_habitica_account) {
|
||||
private var _binding: DialogHabiticaAccountBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
|
@ -46,7 +45,7 @@ class HabiticaAccountDialog(private var thisContext: Context) : DialogFragment(R
|
|||
"delete_account" -> setDeleteAccountViews()
|
||||
}
|
||||
|
||||
binding.backImagebutton.setOnClickListener{dismiss()}
|
||||
binding.backImagebutton.setOnClickListener { dismiss() }
|
||||
}
|
||||
|
||||
private fun setResetAccountViews() {
|
||||
|
|
@ -103,7 +102,8 @@ class HabiticaAccountDialog(private var thisContext: Context) : DialogFragment(R
|
|||
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
|
||||
if (binding.confirmationInputEdittext.text.toString().isNotEmpty()) {
|
||||
if ((user?.authentication?.hasPassword != true && binding.confirmationInputEdittext.text.toString() == context?.getString(R.string.delete_caps)) ||
|
||||
user?.authentication?.hasPassword == true) {
|
||||
user?.authentication?.hasPassword == true
|
||||
) {
|
||||
binding.confirmActionTextview.setTextColor(ContextCompat.getColor(thisContext, R.color.red_100))
|
||||
binding.confirmActionTextview.alpha = 1.0f
|
||||
}
|
||||
|
|
@ -127,7 +127,6 @@ class HabiticaAccountDialog(private var thisContext: Context) : DialogFragment(R
|
|||
accountUpdateConfirmed?.deletionConfirmClicked(confirmationString)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -135,10 +134,8 @@ class HabiticaAccountDialog(private var thisContext: Context) : DialogFragment(R
|
|||
return R.style.HabiticaAccountDialogTheme
|
||||
}
|
||||
|
||||
|
||||
interface AccountUpdateConfirmed {
|
||||
fun resetConfirmedClicked()
|
||||
fun deletionConfirmClicked(confirmationString: String)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,16 +9,23 @@ import android.provider.Settings
|
|||
import android.view.View
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.preference.*
|
||||
import androidx.preference.CheckBoxPreference
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceCategory
|
||||
import androidx.preference.PreferenceScreen
|
||||
import com.habitrpg.android.habitica.BuildConfig
|
||||
import com.habitrpg.android.habitica.HabiticaBaseApplication
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.data.ApiClient
|
||||
import com.habitrpg.android.habitica.data.ContentRepository
|
||||
import com.habitrpg.android.habitica.extensions.addCancelButton
|
||||
import com.habitrpg.android.habitica.helpers.*
|
||||
import com.habitrpg.android.habitica.helpers.AppConfigManager
|
||||
import com.habitrpg.android.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.android.habitica.helpers.SoundManager
|
||||
import com.habitrpg.android.habitica.helpers.TaskAlarmManager
|
||||
import com.habitrpg.android.habitica.helpers.launchCatching
|
||||
import com.habitrpg.android.habitica.helpers.notifications.PushNotificationManager
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.prefs.TimePreference
|
||||
|
|
@ -33,7 +40,7 @@ import com.habitrpg.common.habitica.helpers.AppTestingLevel
|
|||
import com.habitrpg.common.habitica.helpers.LanguageHelper
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.*
|
||||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
|
||||
class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
|
@ -195,7 +202,7 @@ class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnShare
|
|||
usePushPreference?.isChecked = true
|
||||
pushNotificationManager.addPushDeviceUsingStoredToken()
|
||||
} else {
|
||||
//If user denies notification settings originally - they must manually enable it through notification settings.
|
||||
// If user denies notification settings originally - they must manually enable it through notification settings.
|
||||
val alert = context?.let { HabiticaAlertDialog(it) }
|
||||
alert?.setTitle(R.string.push_notification_system_settings_title)
|
||||
alert?.setMessage(R.string.push_notification_system_settings_description)
|
||||
|
|
|
|||
|
|
@ -103,8 +103,11 @@ class GemsPurchaseFragment : BaseFragment<FragmentGemPurchaseBinding>() {
|
|||
if (birthdayEventEnd != null) {
|
||||
binding?.promoComposeView?.setContent {
|
||||
HabiticaTheme {
|
||||
BirthdayBanner(endDate = birthdayEventEnd, Modifier.padding(horizontal = 20.dp).clip(HabiticaTheme.shapes.medium)
|
||||
.padding(bottom = 20.dp))
|
||||
BirthdayBanner(
|
||||
endDate = birthdayEventEnd,
|
||||
Modifier.padding(horizontal = 20.dp).clip(HabiticaTheme.shapes.medium)
|
||||
.padding(bottom = 20.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
binding?.promoComposeView?.isVisible = true
|
||||
|
|
|
|||
|
|
@ -104,8 +104,11 @@ class SubscriptionFragment : BaseFragment<FragmentSubscriptionBinding>() {
|
|||
if (birthdayEventEnd != null) {
|
||||
binding?.promoComposeView?.setContent {
|
||||
HabiticaTheme {
|
||||
BirthdayBanner(endDate = birthdayEventEnd, Modifier.padding(horizontal = 20.dp).clip(HabiticaTheme.shapes.medium)
|
||||
.padding(bottom = 10.dp))
|
||||
BirthdayBanner(
|
||||
endDate = birthdayEventEnd,
|
||||
Modifier.padding(horizontal = 20.dp).clip(HabiticaTheme.shapes.medium)
|
||||
.padding(bottom = 10.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
binding?.promoComposeView?.isVisible = true
|
||||
|
|
|
|||
|
|
@ -10,14 +10,14 @@ import com.habitrpg.android.habitica.R
|
|||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.databinding.FragmentSetupTasksBinding
|
||||
import com.habitrpg.android.habitica.models.tasks.Days
|
||||
import com.habitrpg.shared.habitica.models.tasks.Frequency
|
||||
import com.habitrpg.android.habitica.models.tasks.Task
|
||||
import com.habitrpg.shared.habitica.models.tasks.TaskType
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.ui.activities.SetupActivity
|
||||
import com.habitrpg.android.habitica.ui.adapter.setup.TaskSetupAdapter
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseFragment
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
import com.habitrpg.shared.habitica.models.tasks.Frequency
|
||||
import com.habitrpg.shared.habitica.models.tasks.TaskType
|
||||
import java.util.Date
|
||||
|
||||
class TaskSetupFragment : BaseFragment<FragmentSetupTasksBinding>() {
|
||||
|
|
|
|||
|
|
@ -117,7 +117,6 @@ class InboxMessageListFragment : BaseMainFragment<FragmentInboxMessageListBindin
|
|||
chatAdapter?.submitList(it)
|
||||
}
|
||||
|
||||
|
||||
binding?.chatBarView?.sendAction = { sendMessage(it) }
|
||||
binding?.chatBarView?.maxChatLength = configManager.maxChatLength()
|
||||
|
||||
|
|
@ -183,7 +182,8 @@ class InboxMessageListFragment : BaseMainFragment<FragmentInboxMessageListBindin
|
|||
|
||||
private fun sendMessage(chatText: String) {
|
||||
viewModel.memberID?.let { userID ->
|
||||
lifecycleScope.launch(ExceptionHandler.coroutine { error ->
|
||||
lifecycleScope.launch(
|
||||
ExceptionHandler.coroutine { error ->
|
||||
ExceptionHandler.reportError(error)
|
||||
binding?.let {
|
||||
val alert = HabiticaAlertDialog(it.chatBarView.context)
|
||||
|
|
@ -193,7 +193,8 @@ class InboxMessageListFragment : BaseMainFragment<FragmentInboxMessageListBindin
|
|||
alert.show()
|
||||
}
|
||||
binding?.chatBarView?.message = chatText
|
||||
}) {
|
||||
}
|
||||
) {
|
||||
socialRepository.postPrivateMessage(userID, chatText)
|
||||
delay(200.toDuration(DurationUnit.MILLISECONDS))
|
||||
viewModel.invalidateDataSource()
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ package com.habitrpg.android.habitica.ui.fragments.social.challenges
|
|||
|
||||
import com.habitrpg.android.habitica.models.social.Group
|
||||
|
||||
data class ChallengeFilterOptions(var showByGroups: List<Group>,
|
||||
data class ChallengeFilterOptions(
|
||||
var showByGroups: List<Group>,
|
||||
var showOwned: Boolean = false,
|
||||
var notOwned: Boolean = false
|
||||
)
|
||||
|
|
@ -27,7 +27,8 @@ import kotlinx.coroutines.launch
|
|||
import javax.inject.Inject
|
||||
import javax.inject.Named
|
||||
|
||||
class ChallengeListFragment : BaseFragment<FragmentRefreshRecyclerviewBinding>(),
|
||||
class ChallengeListFragment :
|
||||
BaseFragment<FragmentRefreshRecyclerviewBinding>(),
|
||||
androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener {
|
||||
|
||||
@Inject
|
||||
|
|
|
|||
|
|
@ -21,8 +21,10 @@ import com.habitrpg.common.habitica.helpers.EmptyItem
|
|||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
class GuildListFragment : BaseFragment<FragmentRefreshRecyclerviewBinding>(),
|
||||
SearchView.OnQueryTextListener, SearchView.OnCloseListener,
|
||||
class GuildListFragment :
|
||||
BaseFragment<FragmentRefreshRecyclerviewBinding>(),
|
||||
SearchView.OnQueryTextListener,
|
||||
SearchView.OnCloseListener,
|
||||
SwipeRefreshLayout.OnRefreshListener {
|
||||
|
||||
@Inject
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ class PartyDetailFragment : BaseFragment<FragmentPartyDetailBinding>() {
|
|||
} else {
|
||||
context?.let { context ->
|
||||
DataBindingUtils.loadImage(context, "quest_" + questContent.key) {
|
||||
if (binding?.questImageView?.drawable?.constantState != it.constantState || binding?.questImageView?.drawable == null){
|
||||
if (binding?.questImageView?.drawable?.constantState != it.constantState || binding?.questImageView?.drawable == null) {
|
||||
binding?.questImageView?.setImageDrawable(it)
|
||||
}
|
||||
val params = binding?.questImageView?.layoutParams ?: return@loadImage
|
||||
|
|
|
|||
|
|
@ -46,19 +46,26 @@ class FAQOverviewFragment : BaseMainFragment<FragmentFaqOverviewBinding>() {
|
|||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
binding?.healthSection?.findViewById<ImageView>(R.id.icon_view)?.setImageBitmap(
|
||||
HabiticaIconsHelper.imageOfHeartLarge())
|
||||
HabiticaIconsHelper.imageOfHeartLarge()
|
||||
)
|
||||
binding?.experienceSection?.findViewById<ImageView>(R.id.icon_view)?.setImageBitmap(
|
||||
HabiticaIconsHelper.imageOfExperienceReward())
|
||||
HabiticaIconsHelper.imageOfExperienceReward()
|
||||
)
|
||||
binding?.manaSection?.findViewById<ImageView>(R.id.icon_view)?.setImageBitmap(
|
||||
HabiticaIconsHelper.imageOfMagicLarge())
|
||||
HabiticaIconsHelper.imageOfMagicLarge()
|
||||
)
|
||||
binding?.goldSection?.findViewById<ImageView>(R.id.icon_view)?.setImageBitmap(
|
||||
HabiticaIconsHelper.imageOfGoldReward())
|
||||
HabiticaIconsHelper.imageOfGoldReward()
|
||||
)
|
||||
binding?.gemsSection?.findViewById<ImageView>(R.id.icon_view)?.setImageBitmap(
|
||||
HabiticaIconsHelper.imageOfGem())
|
||||
HabiticaIconsHelper.imageOfGem()
|
||||
)
|
||||
binding?.hourglassesSection?.findViewById<ImageView>(R.id.icon_view)?.setImageBitmap(
|
||||
HabiticaIconsHelper.imageOfHourglassLarge())
|
||||
HabiticaIconsHelper.imageOfHourglassLarge()
|
||||
)
|
||||
binding?.statsSection?.findViewById<ImageView>(R.id.icon_view)?.setImageBitmap(
|
||||
HabiticaIconsHelper.imageOfStats())
|
||||
HabiticaIconsHelper.imageOfStats()
|
||||
)
|
||||
|
||||
binding?.moreHelpTextView?.setMarkdown(context?.getString(R.string.need_help_header_description, "[Habitica Help Guild](https://habitica.com/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a)"))
|
||||
binding?.moreHelpTextView?.setOnClickListener { MainNavigationController.navigate(R.id.guildFragment, bundleOf("groupID" to "5481ccf3-5d2d-48a9-a871-70a7380cee5a")) }
|
||||
|
|
|
|||
|
|
@ -64,7 +64,6 @@ class SupportMainFragment : BaseMainFragment<FragmentSupportMainBinding>() {
|
|||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||
userRepository.resetTutorial()
|
||||
activity?.showSnackbar(null, null, getString(R.string.tutorial_reset_confirmation), displayType = HabiticaSnackbar.SnackbarDisplayType.SUCCESS)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,8 @@ import kotlinx.coroutines.withContext
|
|||
import java.util.Date
|
||||
import javax.inject.Inject
|
||||
|
||||
open class TaskRecyclerViewFragment : BaseFragment<FragmentRefreshRecyclerviewBinding>(),
|
||||
open class TaskRecyclerViewFragment :
|
||||
BaseFragment<FragmentRefreshRecyclerviewBinding>(),
|
||||
androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener {
|
||||
private var taskFlowJob: Job? = null
|
||||
val viewModel: TasksViewModel by viewModels({ requireParentFragment() })
|
||||
|
|
@ -274,8 +275,10 @@ open class TaskRecyclerViewFragment : BaseFragment<FragmentRefreshRecyclerviewBi
|
|||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder
|
||||
): Int {
|
||||
return if ((recyclerAdapter?.getItemViewType(viewHolder.bindingAdapterPosition)
|
||||
?: 0) != 0
|
||||
return if ((
|
||||
recyclerAdapter?.getItemViewType(viewHolder.bindingAdapterPosition)
|
||||
?: 0
|
||||
) != 0
|
||||
) {
|
||||
makeFlag(ItemTouchHelper.ACTION_STATE_IDLE, 0)
|
||||
} else {
|
||||
|
|
@ -316,11 +319,13 @@ open class TaskRecyclerViewFragment : BaseFragment<FragmentRefreshRecyclerviewBi
|
|||
newPosition = if ((newPosition + 1) >= (recyclerAdapter?.data?.size ?: 0)) {
|
||||
recyclerAdapter?.data?.get(newPosition - 1)?.position ?: newPosition
|
||||
} else {
|
||||
(recyclerAdapter?.data?.get(newPosition + 1)?.position
|
||||
?: newPosition) - 1
|
||||
(
|
||||
recyclerAdapter?.data?.get(newPosition + 1)?.position
|
||||
?: newPosition
|
||||
) - 1
|
||||
}
|
||||
}
|
||||
//Factor in if adventure guide is shown.
|
||||
// Factor in if adventure guide is shown.
|
||||
if (recyclerAdapter?.showAdventureGuide == true) {
|
||||
newPosition = newPosition - 1
|
||||
}
|
||||
|
|
@ -556,8 +561,10 @@ open class TaskRecyclerViewFragment : BaseFragment<FragmentRefreshRecyclerviewBi
|
|||
}
|
||||
|
||||
private fun openTaskForm(task: Task) {
|
||||
if (Date().time - (TasksFragment.lastTaskFormOpen?.time
|
||||
?: 0) < 2000 || !task.isValid
|
||||
if (Date().time - (
|
||||
TasksFragment.lastTaskFormOpen?.time
|
||||
?: 0
|
||||
) < 2000 || !task.isValid
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ import com.habitrpg.common.habitica.helpers.RecyclerViewState
|
|||
import com.habitrpg.common.habitica.helpers.RecyclerViewStateAdapter
|
||||
|
||||
class RecyclerViewEmptySupport @JvmOverloads constructor(
|
||||
context: Context, attrs: AttributeSet? = null
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null
|
||||
) : RecyclerView(context, attrs) {
|
||||
var onRefresh: (() -> Unit)?
|
||||
get() = emptyAdapter.onRefresh
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class BottomSheetMenu(context: Context) : HabiticaBottomSheetDialog(context), Vi
|
|||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
binding.menuItems.children.forEachIndexed { index, view ->
|
||||
val anim = TranslateAnimation(0f, 0f, 10f.dpToPx(context) + (5f.dpToPx(context)*index), 0f)
|
||||
val anim = TranslateAnimation(0f, 0f, 10f.dpToPx(context) + (5f.dpToPx(context) * index), 0f)
|
||||
anim.startOffset = 300 + (20 * index).toLong()
|
||||
anim.fillBefore = true
|
||||
anim.fillAfter = true
|
||||
|
|
|
|||
|
|
@ -94,11 +94,11 @@ fun HabiticaTheme(
|
|||
val Typography.caption1
|
||||
get() = caption
|
||||
val Typography.caption2
|
||||
get() = TextStyle(
|
||||
get() = TextStyle(
|
||||
fontWeight = FontWeight.Medium,
|
||||
fontSize = 12.sp,
|
||||
letterSpacing = 0.4.sp
|
||||
)
|
||||
)
|
||||
val Typography.caption3
|
||||
get() = TextStyle(
|
||||
fontWeight = FontWeight.Medium,
|
||||
|
|
@ -123,7 +123,6 @@ object HabiticaTheme {
|
|||
@Composable
|
||||
get() = MaterialTheme.typography
|
||||
|
||||
|
||||
val shapes: Shapes
|
||||
@Composable
|
||||
get() = MaterialTheme.shapes
|
||||
|
|
|
|||
|
|
@ -3,5 +3,4 @@ package com.habitrpg.android.habitica.ui.viewHolders
|
|||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
||||
class ComposableViewHolder(view: ComposeView) : RecyclerView.ViewHolder(view) {
|
||||
}
|
||||
class ComposableViewHolder(view: ComposeView) : RecyclerView.ViewHolder(view)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package com.habitrpg.android.habitica.ui.viewHolders.tasks
|
|||
|
||||
import android.content.Context
|
||||
import android.graphics.PorterDuff
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
|
|
|||
|
|
@ -55,7 +55,8 @@ class RewardViewHolder(
|
|||
binding.priceLabel.setCompoundDrawablesWithIntrinsicBounds(
|
||||
HabiticaIconsHelper.imageOfLocked(
|
||||
ContextCompat.getColor(context, R.color.gray_1_30), 10, 12
|
||||
).toDrawable(context.resources), null, null, null
|
||||
).toDrawable(context.resources),
|
||||
null, null, null
|
||||
)
|
||||
binding.priceLabel.compoundDrawablePadding = 2.dpToPx(context)
|
||||
} else {
|
||||
|
|
@ -83,7 +84,8 @@ class RewardViewHolder(
|
|||
ContextCompat.getColor(
|
||||
context,
|
||||
R.color.offset_background
|
||||
), 127
|
||||
),
|
||||
127
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,11 +116,13 @@ open class GroupViewModel(initializeComponent: Boolean) : BaseViewModel(initiali
|
|||
|
||||
fun retrieveGroup(function: (() -> Unit)?) {
|
||||
if (groupID?.isNotEmpty() == true) {
|
||||
viewModelScope.launch(ExceptionHandler.coroutine {
|
||||
viewModelScope.launch(
|
||||
ExceptionHandler.coroutine {
|
||||
if (it is HttpException && it.code() == 404) {
|
||||
MainNavigationController.navigateBack()
|
||||
}
|
||||
}) {
|
||||
}
|
||||
) {
|
||||
val group = socialRepository.retrieveGroup(groupID ?: "")
|
||||
if (groupViewType == GroupViewType.PARTY) {
|
||||
socialRepository.retrievePartyMembers(group?.id ?: "", true)
|
||||
|
|
@ -161,7 +163,6 @@ open class GroupViewModel(initializeComponent: Boolean) : BaseViewModel(initiali
|
|||
fun leaveGroup(
|
||||
groupChallenges: List<Challenge>,
|
||||
keepChallenges: Boolean = true,
|
||||
function: (() -> Unit)? = null
|
||||
) {
|
||||
if (!keepChallenges) {
|
||||
viewModelScope.launchCatching {
|
||||
|
|
@ -222,21 +223,25 @@ open class GroupViewModel(initializeComponent: Boolean) : BaseViewModel(initiali
|
|||
val list = _chatMessages.value?.toMutableList()
|
||||
list?.remove(chatMessage)
|
||||
_chatMessages.postValue(list)
|
||||
viewModelScope.launch(ExceptionHandler.coroutine {
|
||||
viewModelScope.launch(
|
||||
ExceptionHandler.coroutine {
|
||||
list?.add(oldIndex, chatMessage)
|
||||
_chatMessages.postValue(list)
|
||||
ExceptionHandler.reportError(it)
|
||||
}) {
|
||||
}
|
||||
) {
|
||||
socialRepository.deleteMessage(chatMessage)
|
||||
}
|
||||
}
|
||||
|
||||
fun postGroupChat(chatText: String, onComplete: () -> Unit, onError: () -> Unit) {
|
||||
groupID?.let { groupID ->
|
||||
viewModelScope.launch(ExceptionHandler.coroutine {
|
||||
viewModelScope.launch(
|
||||
ExceptionHandler.coroutine {
|
||||
ExceptionHandler.reportError(it)
|
||||
onError()
|
||||
}) {
|
||||
}
|
||||
) {
|
||||
val response = socialRepository.postGroupChat(groupID, chatText)
|
||||
val list = _chatMessages.value?.toMutableList()
|
||||
if (response != null) {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class InboxViewModel(recipientID: String?, recipientUsername: String?) : BaseVie
|
|||
@Inject
|
||||
lateinit var socialRepository: SocialRepository
|
||||
|
||||
protected var memberIDFlow = MutableStateFlow<String?>(null)
|
||||
private var memberIDFlow = MutableStateFlow<String?>(null)
|
||||
val memberIDState: StateFlow<String?> = memberIDFlow
|
||||
|
||||
private val config = PagedList.Config.Builder()
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package com.habitrpg.android.habitica.ui.viewmodels
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Build
|
||||
import androidx.core.content.edit
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import kotlinx.coroutines.flow.map
|
|||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
class StableViewModel(private val application: Application?, private val itemType: String?): BaseViewModel() {
|
||||
class StableViewModel(private val application: Application?, private val itemType: String?) : BaseViewModel() {
|
||||
|
||||
@Inject
|
||||
lateinit var inventoryRepository: InventoryRepository
|
||||
|
|
@ -35,7 +35,6 @@ class StableViewModel(private val application: Application?, private val itemTyp
|
|||
component.inject(this)
|
||||
}
|
||||
|
||||
|
||||
private val _items: MutableLiveData<List<Any>> = MutableLiveData()
|
||||
val items: LiveData<List<Any>> = _items
|
||||
val eggs: LiveData<Map<String, Egg>> = inventoryRepository.getItems(Egg::class.java)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import com.habitrpg.shared.habitica.models.tasks.Attribute
|
|||
import com.habitrpg.shared.habitica.models.tasks.HabitResetOption
|
||||
import com.habitrpg.shared.habitica.models.tasks.TaskDifficulty
|
||||
|
||||
class TaskFormViewModel: BaseViewModel() {
|
||||
class TaskFormViewModel : BaseViewModel() {
|
||||
override fun inject(component: UserComponent) {
|
||||
component.inject(this)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -282,11 +282,13 @@ class TasksViewModel : BaseViewModel(), GroupPlanInfoProvider {
|
|||
} else {
|
||||
query.equalTo("completed", false)
|
||||
}
|
||||
Task.FILTER_GRAY -> query =
|
||||
Task.FILTER_GRAY ->
|
||||
query =
|
||||
query.equalTo("completed", true).or().equalTo("isDue", false)
|
||||
Task.FILTER_WEAK -> query = query.lessThan("value", 1.0)
|
||||
Task.FILTER_STRONG -> query = query.greaterThanOrEqualTo("value", 1.0)
|
||||
Task.FILTER_DATED -> query =
|
||||
Task.FILTER_DATED ->
|
||||
query =
|
||||
query.isNotNull("dueDate").equalTo("completed", false).sort("dueDate")
|
||||
Task.FILTER_COMPLETED -> query = query.equalTo("completed", true)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,7 +162,8 @@ fun AppHeaderView(
|
|||
visible = teamPlan != null,
|
||||
enter = slideInHorizontally { animWidth } + fadeIn(),
|
||||
exit = slideOutHorizontally { animWidth } + fadeOut(),
|
||||
modifier = Modifier.align(Alignment.TopEnd)) {
|
||||
modifier = Modifier.align(Alignment.TopEnd)
|
||||
) {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
|
|
@ -181,8 +182,12 @@ fun AppHeaderView(
|
|||
)
|
||||
}
|
||||
) {
|
||||
Image(painterResource(R.drawable.icon_chat), null, colorFilter = ColorFilter.tint(
|
||||
colorResource(R.color.text_ternary)))
|
||||
Image(
|
||||
painterResource(R.drawable.icon_chat), null,
|
||||
colorFilter = ColorFilter.tint(
|
||||
colorResource(R.color.text_ternary)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
val animHeight = with(LocalDensity.current) { 40.dp.roundToPx() }
|
||||
|
|
@ -190,7 +195,8 @@ fun AppHeaderView(
|
|||
visible = teamPlan != null,
|
||||
enter = slideInVertically { animHeight } + fadeIn(),
|
||||
exit = slideOutVertically { animHeight } + fadeOut(),
|
||||
modifier = Modifier.align(Alignment.BottomCenter)) {
|
||||
modifier = Modifier.align(Alignment.BottomCenter)
|
||||
) {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp, Alignment.CenterHorizontally),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
|
|
@ -208,10 +214,12 @@ fun AppHeaderView(
|
|||
}
|
||||
) {
|
||||
for (member in teamPlanMembers?.filter { it.id != user?.id }?.sortedByDescending { it.authentication?.timestamps?.lastLoggedIn }?.take(6) ?: emptyList()) {
|
||||
Box(modifier = Modifier
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.clip(CircleShape)
|
||||
.size(26.dp)
|
||||
.padding(end = 6.dp, top = 4.dp)) {
|
||||
.padding(end = 6.dp, top = 4.dp)
|
||||
) {
|
||||
ComposableAvatarView(
|
||||
avatar = member,
|
||||
Modifier
|
||||
|
|
@ -237,7 +245,8 @@ fun AppHeaderView(
|
|||
.padding(end = 12.dp)
|
||||
.clickable {
|
||||
MainNavigationController.navigate(R.id.subscriptionPurchaseActivity)
|
||||
}, decimals = 0
|
||||
},
|
||||
decimals = 0
|
||||
)
|
||||
}
|
||||
CurrencyText(
|
||||
|
|
@ -288,6 +297,5 @@ private class UserProvider : PreviewParameterProvider<User> {
|
|||
@Preview
|
||||
private fun Preview(@PreviewParameter(UserProvider::class) user: User) {
|
||||
AppHeaderView(user) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
package com.habitrpg.android.habitica.ui.views
|
||||
|
||||
import android.app.Activity
|
||||
import android.util.Log
|
||||
import android.view.ViewGroup
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.foundation.background
|
||||
|
|
@ -71,7 +70,6 @@ private fun BottomSheetWrapper(
|
|||
composeView: ComposeView,
|
||||
content: @Composable (() -> Unit) -> Unit
|
||||
) {
|
||||
val TAG = parent::class.java.simpleName
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val modalBottomSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
|
||||
var isSheetOpened by remember { mutableStateOf(false) }
|
||||
|
|
@ -143,7 +141,6 @@ private fun BottomSheetWrapper(
|
|||
}
|
||||
}
|
||||
else -> {
|
||||
Log.i(TAG, "Bottom sheet ${modalBottomSheetState.currentValue} state")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,11 +30,15 @@ fun CompletedAt(
|
|||
modifier = Modifier.padding(top = 4.dp)
|
||||
) {
|
||||
Image(painterResource(R.drawable.completed), null)
|
||||
Text(stringResource(R.string.completed_at,
|
||||
Text(
|
||||
stringResource(
|
||||
R.string.completed_at,
|
||||
completedAt?.let { if (completedToday) completedTimeFormatToday.format(it) else completedTimeFormat.format(it) }
|
||||
?: ""),
|
||||
?: ""
|
||||
),
|
||||
fontSize = 14.sp,
|
||||
color = if (completedToday) colorResource(R.color.green_10) else colorResource(R.color.text_secondary),
|
||||
modifier = Modifier.padding(start = 4.dp))
|
||||
modifier = Modifier.padding(start = 4.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -5,8 +5,8 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.layout.Layout
|
||||
import androidx.compose.ui.layout.MeasurePolicy
|
||||
|
||||
fun flowLayoutMeasurePolicy(spacing: Int = 0) = MeasurePolicy{ measurables,constraints ->
|
||||
layout(constraints.maxWidth,constraints.maxHeight){
|
||||
fun flowLayoutMeasurePolicy(spacing: Int = 0) = MeasurePolicy { measurables, constraints ->
|
||||
layout(constraints.maxWidth, constraints.maxHeight) {
|
||||
val placeables = measurables.map { measurable ->
|
||||
measurable.measure(constraints)
|
||||
}
|
||||
|
|
@ -41,9 +41,11 @@ fun FlowLayout(
|
|||
modifier: Modifier = Modifier,
|
||||
spacing: Int = 0,
|
||||
content: @Composable () -> Unit,
|
||||
){
|
||||
) {
|
||||
val measurePolicy = flowLayoutMeasurePolicy(spacing)
|
||||
Layout(measurePolicy = measurePolicy,
|
||||
Layout(
|
||||
measurePolicy = measurePolicy,
|
||||
content = content,
|
||||
modifier = modifier )
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
|
|
@ -40,9 +40,7 @@ import kotlin.random.Random
|
|||
fun GroupPlanMemberList(
|
||||
members: List<Member>?,
|
||||
group: Group?,
|
||||
onMemberClicked: (String) -> Unit,
|
||||
onMoreClicked: (Member) -> Unit
|
||||
) {
|
||||
onMemberClicked: (String) -> Unit) {
|
||||
LazyColumn {
|
||||
item {
|
||||
Text(
|
||||
|
|
@ -56,8 +54,10 @@ fun GroupPlanMemberList(
|
|||
.padding(bottom = 20.dp)
|
||||
)
|
||||
}
|
||||
for (member in members?.sortedByDescending { it.authentication?.timestamps?.lastLoggedIn }
|
||||
?: emptyList()) {
|
||||
for (
|
||||
member in members?.sortedByDescending { it.authentication?.timestamps?.lastLoggedIn }
|
||||
?: emptyList()
|
||||
) {
|
||||
item {
|
||||
val role = if (group?.isLeader(member.id ?: "") == true) {
|
||||
stringResource(R.string.owner)
|
||||
|
|
@ -98,7 +98,8 @@ fun MemberItem(
|
|||
modifier = Modifier.padding(8.dp)
|
||||
) {
|
||||
ComposableAvatarView(
|
||||
avatar = member, modifier = Modifier
|
||||
avatar = member,
|
||||
modifier = Modifier
|
||||
.padding(6.dp)
|
||||
.size(94.dp, 98.dp)
|
||||
)
|
||||
|
|
@ -196,7 +197,7 @@ private class MemberProvider : PreviewParameterProvider<Member> {
|
|||
member.profile?.name = "User $x"
|
||||
member.authentication = Authentication()
|
||||
member.authentication?.localAuthentication = LocalAuthentication()
|
||||
member.authentication?.localAuthentication?.username = "user${x}"
|
||||
member.authentication?.localAuthentication?.username = "user$x"
|
||||
member.stats = Stats()
|
||||
member.stats?.hp = Random.nextDouble()
|
||||
member.stats?.maxHealth = 50
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@ class HabiticaListPreference : ListPreference {
|
|||
override fun onClick() {
|
||||
val subtitleText = TextView(context)
|
||||
subtitleText.setText(R.string.cds_subtitle)
|
||||
val builder = AlertDialog.Builder(context).setSingleChoiceItems(entries, getValueIndex()+1) { dialog, index ->
|
||||
if (callChangeListener(entryValues[index-1].toString())) {
|
||||
setValueIndex(index-1)
|
||||
val builder = AlertDialog.Builder(context).setSingleChoiceItems(entries, getValueIndex() + 1) { dialog, index ->
|
||||
if (callChangeListener(entryValues[index - 1].toString())) {
|
||||
setValueIndex(index - 1)
|
||||
}
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,9 +67,11 @@ fun LabeledBar(
|
|||
modifier = modifier.alpha(if (disabled) 0.5f else 1.0f)
|
||||
) {
|
||||
icon?.let {
|
||||
AnimatedVisibility(visible = !displayCompact,
|
||||
AnimatedVisibility(
|
||||
visible = !displayCompact,
|
||||
enter = slideInHorizontally { -18 },
|
||||
exit = slideOutHorizontally { -18 }) {
|
||||
exit = slideOutHorizontally { -18 }
|
||||
) {
|
||||
Image(
|
||||
it.asImageBitmap(), null, modifier = Modifier.padding(end = 8.dp)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ fun SegmentedControl(
|
|||
defaultSelectedItemIndex: Int = 0,
|
||||
useFixedWidth: Boolean = false,
|
||||
itemWidth: Dp = 120.dp,
|
||||
cornerRadius : Int = 10,
|
||||
cornerRadius: Int = 10,
|
||||
onItemSelection: (selectedItemIndex: Int) -> Unit
|
||||
) {
|
||||
val selectedIndex = remember { mutableStateOf(defaultSelectedItemIndex) }
|
||||
|
|
@ -104,7 +104,8 @@ fun SegmentedControl(
|
|||
)
|
||||
},
|
||||
border = BorderStroke(
|
||||
1.dp, if (selectedIndex.value == index) {
|
||||
1.dp,
|
||||
if (selectedIndex.value == index) {
|
||||
color
|
||||
} else {
|
||||
color.copy(alpha = 0.75f)
|
||||
|
|
|
|||
|
|
@ -32,11 +32,13 @@ fun UserRow(
|
|||
color: Color? = null
|
||||
) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically, modifier = modifier.fillMaxWidth()) {
|
||||
Box(modifier = Modifier
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(end = 12.dp)
|
||||
.clip(CircleShape)
|
||||
.size(40.dp)
|
||||
.padding(end = 12.dp, top = if (avatar?.currentMount?.isNotBlank() == true) 24.dp else 12.dp)) {
|
||||
.padding(end = 12.dp, top = if (avatar?.currentMount?.isNotBlank() == true) 24.dp else 12.dp)
|
||||
) {
|
||||
if (avatar != null) {
|
||||
ComposableAvatarView(
|
||||
avatar = avatar,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ import com.habitrpg.common.habitica.R
|
|||
import com.habitrpg.common.habitica.models.PlayerTier
|
||||
|
||||
class UsernameLabel @JvmOverloads constructor(
|
||||
context: Context, attrs: AttributeSet? = null
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null
|
||||
) : LinearLayout(context, attrs) {
|
||||
|
||||
private val textView = TextView(context)
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ import com.habitrpg.android.habitica.R
|
|||
import com.habitrpg.android.habitica.databinding.AdButtonBinding
|
||||
import com.habitrpg.android.habitica.extensions.getMinuteOrSeconds
|
||||
import com.habitrpg.android.habitica.extensions.getShortRemainingString
|
||||
import com.habitrpg.common.habitica.extensions.layoutInflater
|
||||
import com.habitrpg.android.habitica.helpers.AdHandler
|
||||
import com.habitrpg.android.habitica.helpers.AdType
|
||||
import com.habitrpg.common.habitica.extensions.layoutInflater
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@ import android.widget.TextView
|
|||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.databinding.DialogAchievementDetailBinding
|
||||
import com.habitrpg.android.habitica.extensions.fromHtml
|
||||
import com.habitrpg.common.habitica.extensions.layoutInflater
|
||||
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
||||
import com.habitrpg.common.habitica.models.Notification
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.common.habitica.extensions.layoutInflater
|
||||
import com.habitrpg.common.habitica.extensions.loadImage
|
||||
import com.habitrpg.common.habitica.models.Notification
|
||||
|
||||
class AchievementDialog(context: Context) : HabiticaAlertDialog(context) {
|
||||
var isLastOnboardingAchievement: Boolean = false
|
||||
|
|
|
|||
|
|
@ -12,11 +12,11 @@ import android.widget.TextView
|
|||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.databinding.DialogCompletedQuestContentBinding
|
||||
import com.habitrpg.android.habitica.extensions.fromHtml
|
||||
import com.habitrpg.common.habitica.extensions.layoutInflater
|
||||
import com.habitrpg.android.habitica.models.inventory.QuestContent
|
||||
import com.habitrpg.android.habitica.models.inventory.QuestDropItem
|
||||
import com.habitrpg.common.habitica.extensions.loadImage
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
import com.habitrpg.common.habitica.extensions.layoutInflater
|
||||
import com.habitrpg.common.habitica.extensions.loadImage
|
||||
import com.habitrpg.common.habitica.views.PixelArtView
|
||||
|
||||
class QuestCompletedDialogContent : LinearLayout {
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import android.widget.ImageView
|
|||
import android.widget.TextView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.extensions.fromHtml
|
||||
import com.habitrpg.common.habitica.models.notifications.ChallengeWonData
|
||||
import com.habitrpg.common.habitica.extensions.loadImage
|
||||
import com.habitrpg.common.habitica.models.notifications.ChallengeWonData
|
||||
import com.habitrpg.common.habitica.views.PixelArtView
|
||||
|
||||
class WonChallengeDialog(context: Context) : HabiticaAlertDialog(context) {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue