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
|
- name: Run with Gradle
|
||||||
uses: gradle/gradle-build-action@v2
|
uses: gradle/gradle-build-action@v2
|
||||||
with:
|
with:
|
||||||
arguments: ktlint
|
arguments: ktlintCheck
|
||||||
|
|
||||||
detekt:
|
detekt:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,6 @@ repositories {
|
||||||
maven { url "https://jitpack.io" }
|
maven { url "https://jitpack.io" }
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations {
|
|
||||||
ktlint
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(include: ['*.jar'], dir: '../common/libs')
|
implementation fileTree(include: ['*.jar'], dir: '../common/libs')
|
||||||
//Networking
|
//Networking
|
||||||
|
|
@ -42,15 +38,15 @@ dependencies {
|
||||||
compileOnly 'javax.annotation:javax.annotation-api:1.3.2'
|
compileOnly 'javax.annotation:javax.annotation-api:1.3.2'
|
||||||
//App Compatibility and Material Design
|
//App Compatibility and Material Design
|
||||||
implementation "androidx.appcompat:appcompat:$appcompat_version"
|
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.recyclerview:recyclerview:$recyclerview_version"
|
||||||
implementation "androidx.preference:preference-ktx:$preferences_version"
|
implementation "androidx.preference:preference-ktx:$preferences_version"
|
||||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
|
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
|
||||||
|
|
||||||
//Desugaring
|
//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
|
// IAP Handling / Verification
|
||||||
implementation "com.android.billingclient:billing-ktx:5.1.0"
|
implementation "com.android.billingclient:billing-ktx:5.1.0"
|
||||||
|
|
@ -62,38 +58,38 @@ dependencies {
|
||||||
implementation "com.amplitude:analytics-android:$amplitude_version"
|
implementation "com.amplitude:analytics-android:$amplitude_version"
|
||||||
|
|
||||||
//Tests
|
//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 'androidx.test:core:1.5.0'
|
||||||
testImplementation 'io.mockk:mockk:1.13.3'
|
testImplementation 'io.mockk:mockk:1.13.4'
|
||||||
testImplementation 'io.mockk:mockk-android:1.13.3'
|
testImplementation 'io.mockk:mockk-android:1.13.4'
|
||||||
testImplementation 'io.kotest:kotest-assertions-core:5.3.0'
|
testImplementation 'io.kotest:kotest-assertions-core:5.5.5'
|
||||||
testImplementation 'io.kotest:kotest-framework-datatest:5.3.0'
|
testImplementation 'io.kotest:kotest-framework-datatest:5.5.5'
|
||||||
androidTestImplementation ('com.kaspersky.android-components:kaspresso:1.4.1') {
|
androidTestImplementation ('com.kaspersky.android-components:kaspresso:1.5.1') {
|
||||||
exclude module: "protobuf-lite"
|
exclude module: "protobuf-lite"
|
||||||
}
|
}
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||||
androidTestImplementation 'androidx.test:runner:1.5.1'
|
androidTestImplementation 'androidx.test:runner:1.5.2'
|
||||||
androidTestImplementation 'androidx.test:rules:1.5.0'
|
androidTestImplementation 'androidx.test:rules:1.5.0'
|
||||||
debugImplementation 'androidx.fragment:fragment-testing:1.5.5'
|
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:core-ktx:1.5.0'
|
||||||
androidTestImplementation 'androidx.test.ext:junit-ktx:1.1.4'
|
androidTestImplementation 'androidx.test.ext:junit-ktx:1.1.5'
|
||||||
androidTestImplementation 'io.mockk:mockk-android:1.13.3'
|
androidTestImplementation 'io.mockk:mockk-android:1.13.4'
|
||||||
androidTestImplementation 'io.kotest:kotest-assertions-core:5.3.0'
|
androidTestImplementation 'io.kotest:kotest-assertions-core:5.5.5'
|
||||||
androidTestUtil("androidx.test:orchestrator:1.4.2")
|
androidTestUtil("androidx.test:orchestrator:1.4.2")
|
||||||
|
|
||||||
implementation 'com.facebook.shimmer:shimmer:0.5.0'
|
implementation 'com.facebook.shimmer:shimmer:0.5.0'
|
||||||
|
|
||||||
//Leak Detection
|
//Leak Detection
|
||||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.9.1'
|
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.10'
|
||||||
//Push Notifications
|
//Push Notifications
|
||||||
implementation platform("com.google.firebase:firebase-bom:$firebase_bom")
|
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-crashlytics-ktx'
|
||||||
implementation 'com.google.firebase:firebase-core'
|
|
||||||
implementation 'com.google.firebase:firebase-messaging-ktx'
|
implementation 'com.google.firebase:firebase-messaging-ktx'
|
||||||
implementation 'com.google.firebase:firebase-config-ktx'
|
implementation 'com.google.firebase:firebase-config-ktx'
|
||||||
implementation 'com.google.firebase:firebase-perf-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.gms:play-services-auth:$play_auth_version"
|
||||||
implementation 'com.google.android.flexbox:flexbox:3.0.0'
|
implementation 'com.google.android.flexbox:flexbox:3.0.0'
|
||||||
implementation "com.google.android.gms:play-services-wearable:$play_wearables_version"
|
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.activity:activity-compose:1.6.1'
|
||||||
implementation "androidx.compose.runtime:runtime-livedata:$compose_version"
|
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.animation:animation:$compose_version"
|
||||||
implementation "androidx.compose.ui:ui-tooling:$compose_version"
|
implementation "androidx.compose.ui:ui-tooling:$compose_version"
|
||||||
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version"
|
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version"
|
||||||
|
|
@ -124,18 +120,12 @@ dependencies {
|
||||||
implementation project(':common')
|
implementation project(':common')
|
||||||
implementation project(':shared')
|
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"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion target_sdk
|
compileSdkVersion target_sdk
|
||||||
buildToolsVersion '30.0.3'
|
buildToolsVersion '33.0.2'
|
||||||
testOptions {
|
testOptions {
|
||||||
unitTests {
|
unitTests {
|
||||||
includeAndroidResources = true
|
includeAndroidResources = true
|
||||||
|
|
@ -169,7 +159,7 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
composeOptions {
|
composeOptions {
|
||||||
kotlinCompilerExtensionVersion = "1.4.0-alpha02"
|
kotlinCompilerExtensionVersion = "1.4.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
|
|
@ -387,24 +377,4 @@ gradle.projectsEvaluated {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'com.google.gms.google-services'
|
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.HabiticaBaseApplication
|
||||||
import com.habitrpg.android.habitica.R
|
import com.habitrpg.android.habitica.R
|
||||||
import com.habitrpg.android.habitica.components.UserComponent
|
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.android.habitica.models.tasks.Task
|
||||||
|
import com.habitrpg.shared.habitica.models.tasks.Frequency
|
||||||
import com.habitrpg.shared.habitica.models.tasks.TaskType
|
import com.habitrpg.shared.habitica.models.tasks.TaskType
|
||||||
import io.github.kakaocup.kakao.common.assertions.BaseAssertions
|
import io.github.kakaocup.kakao.common.assertions.BaseAssertions
|
||||||
import io.github.kakaocup.kakao.common.matchers.ChildCountMatcher
|
import io.github.kakaocup.kakao.common.matchers.ChildCountMatcher
|
||||||
|
|
@ -31,12 +31,12 @@ import io.mockk.mockkObject
|
||||||
import io.mockk.slot
|
import io.mockk.slot
|
||||||
import io.mockk.verify
|
import io.mockk.verify
|
||||||
import io.reactivex.rxjava3.core.Flowable
|
import io.reactivex.rxjava3.core.Flowable
|
||||||
import java.util.Date
|
|
||||||
import java.util.UUID
|
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
|
import java.util.Date
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
class TaskFormScreen : Screen<TaskFormScreen>() {
|
class TaskFormScreen : Screen<TaskFormScreen>() {
|
||||||
val toolbar = KToolbar { withId(R.id.toolbar) }
|
val toolbar = KToolbar { withId(R.id.toolbar) }
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,9 @@ class NavigationDrawerScreen : Screen<NavigationDrawerScreen>() {
|
||||||
val recycler: KRecyclerView = KRecyclerView({
|
val recycler: KRecyclerView = KRecyclerView({
|
||||||
withId(R.id.recyclerView)
|
withId(R.id.recyclerView)
|
||||||
}, itemTypeBuilder = {
|
}, itemTypeBuilder = {
|
||||||
itemType(::SectionHeaderItem)
|
itemType(::SectionHeaderItem)
|
||||||
itemType(::MainItem)
|
itemType(::MainItem)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@LargeTest
|
@LargeTest
|
||||||
|
|
|
||||||
|
|
@ -63,8 +63,8 @@ class ItemScreen : Screen<ItemScreen>() {
|
||||||
val recycler: KRecyclerView = KRecyclerView({
|
val recycler: KRecyclerView = KRecyclerView({
|
||||||
withId(R.id.recyclerView)
|
withId(R.id.recyclerView)
|
||||||
}, itemTypeBuilder = {
|
}, itemTypeBuilder = {
|
||||||
itemType(::ItemItem)
|
itemType(::ItemItem)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ItemRecyclerFragmentTest : FragmentTestCase<ItemRecyclerFragment, FragmentRecyclerviewBinding, ItemScreen>(false) {
|
internal class ItemRecyclerFragmentTest : FragmentTestCase<ItemRecyclerFragment, FragmentRecyclerviewBinding, ItemScreen>(false) {
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ import io.mockk.every
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import io.mockk.mockkObject
|
import io.mockk.mockkObject
|
||||||
import io.mockk.spyk
|
import io.mockk.spyk
|
||||||
import io.mockk.verify
|
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
@ -29,9 +28,9 @@ class PetDetailScreen : Screen<PetDetailScreen>() {
|
||||||
val recycler: KRecyclerView = KRecyclerView({
|
val recycler: KRecyclerView = KRecyclerView({
|
||||||
withId(R.id.recyclerView)
|
withId(R.id.recyclerView)
|
||||||
}, itemTypeBuilder = {
|
}, itemTypeBuilder = {
|
||||||
itemType(::SectionItem)
|
itemType(::SectionItem)
|
||||||
itemType(::PetItem)
|
itemType(::PetItem)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class PetDetailRecyclerFragmentTest :
|
internal class PetDetailRecyclerFragmentTest :
|
||||||
|
|
|
||||||
|
|
@ -33,9 +33,9 @@ class StableScreen : Screen<StableScreen>() {
|
||||||
val recycler: KRecyclerView = KRecyclerView({
|
val recycler: KRecyclerView = KRecyclerView({
|
||||||
withId(R.id.recyclerView)
|
withId(R.id.recyclerView)
|
||||||
}, itemTypeBuilder = {
|
}, itemTypeBuilder = {
|
||||||
itemType(::SectionItem)
|
itemType(::SectionItem)
|
||||||
itemType(::PetItem)
|
itemType(::PetItem)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class StableRecyclerFragmentTest : FragmentTestCase<StableRecyclerFragment, FragmentRecyclerviewBinding, StableScreen>(false) {
|
internal class StableRecyclerFragmentTest : FragmentTestCase<StableRecyclerFragment, FragmentRecyclerviewBinding, StableScreen>(false) {
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@ import com.habitrpg.android.habitica.R
|
||||||
import com.habitrpg.android.habitica.databinding.FragmentRefreshRecyclerviewBinding
|
import com.habitrpg.android.habitica.databinding.FragmentRefreshRecyclerviewBinding
|
||||||
import com.habitrpg.android.habitica.models.tasks.Task
|
import com.habitrpg.android.habitica.models.tasks.Task
|
||||||
import com.habitrpg.android.habitica.models.tasks.TaskList
|
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.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.common.views.KView
|
||||||
import io.github.kakaocup.kakao.recycler.KRecyclerItem
|
import io.github.kakaocup.kakao.recycler.KRecyclerItem
|
||||||
import io.github.kakaocup.kakao.recycler.KRecyclerView
|
import io.github.kakaocup.kakao.recycler.KRecyclerView
|
||||||
|
|
@ -30,8 +30,8 @@ class TaskListScreen : Screen<TaskListScreen>() {
|
||||||
val recycler: KRecyclerView = KRecyclerView({
|
val recycler: KRecyclerView = KRecyclerView({
|
||||||
withId(R.id.recyclerView)
|
withId(R.id.recyclerView)
|
||||||
}, itemTypeBuilder = {
|
}, itemTypeBuilder = {
|
||||||
itemType(::TaskItem)
|
itemType(::TaskItem)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class TaskRecyclerViewFragmentTest : FragmentTestCase<TaskRecyclerViewFragment, FragmentRefreshRecyclerviewBinding, TaskListScreen>(false) {
|
internal class TaskRecyclerViewFragmentTest : FragmentTestCase<TaskRecyclerViewFragment, FragmentRefreshRecyclerviewBinding, TaskListScreen>(false) {
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,6 @@ abstract class HabiticaBaseApplication : Application(), Application.ActivityLife
|
||||||
|
|
||||||
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
|
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
|
||||||
|
|
||||||
|
|
||||||
setupCoil()
|
setupCoil()
|
||||||
|
|
||||||
ExceptionHandler.init(analyticsManager)
|
ExceptionHandler.init(analyticsManager)
|
||||||
|
|
|
||||||
|
|
@ -461,5 +461,5 @@ interface ApiService {
|
||||||
suspend fun getHallMember(@Path("memberID") memberID: String): HabitResponse<Member>
|
suspend fun getHallMember(@Path("memberID") memberID: String): HabitResponse<Member>
|
||||||
|
|
||||||
@POST("tasks/{taskID}/needs-work/{userID}")
|
@POST("tasks/{taskID}/needs-work/{userID}")
|
||||||
suspend fun markTaskNeedsWork(@Path("taskID") taskID: String, @Path("userID") userID: String): HabitResponse<Task>
|
suspend fun markTaskNeedsWork(@Path("taskID") taskID: String, @Path("userID") userID: String): HabitResponse<Task>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,4 +9,4 @@ interface MaintenanceApiService {
|
||||||
|
|
||||||
@GET("deprecation-android.json")
|
@GET("deprecation-android.json")
|
||||||
suspend fun getDepricationStatus(): MaintenanceResponse?
|
suspend fun getDepricationStatus(): MaintenanceResponse?
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import com.habitrpg.android.habitica.models.ContentResult
|
||||||
import com.habitrpg.android.habitica.models.WorldState
|
import com.habitrpg.android.habitica.models.WorldState
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
interface ContentRepository: BaseRepository {
|
interface ContentRepository : BaseRepository {
|
||||||
suspend fun retrieveContent(forced: Boolean = false): ContentResult?
|
suspend fun retrieveContent(forced: Boolean = false): ContentResult?
|
||||||
|
|
||||||
suspend fun retrieveWorldState(forced: Boolean = false): WorldState?
|
suspend fun retrieveWorldState(forced: Boolean = false): WorldState?
|
||||||
|
|
|
||||||
|
|
@ -68,5 +68,4 @@ interface TaskRepository : BaseRepository {
|
||||||
fun getTasksForChallenge(challengeID: String?): Flow<List<Task>>
|
fun getTasksForChallenge(challengeID: String?): Flow<List<Task>>
|
||||||
suspend fun bulkScoreTasks(data: List<Map<String, String>>): BulkTaskScoringData?
|
suspend fun bulkScoreTasks(data: List<Map<String, String>>): BulkTaskScoringData?
|
||||||
suspend fun markTaskNeedsWork(task: Task, userID: String)
|
suspend fun markTaskNeedsWork(task: Task, userID: String)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ class ApiClientImpl(
|
||||||
private val analyticsManager: AnalyticsManager,
|
private val analyticsManager: AnalyticsManager,
|
||||||
private val notificationsManager: NotificationsManager,
|
private val notificationsManager: NotificationsManager,
|
||||||
private val context: Context
|
private val context: Context
|
||||||
): ApiClient {
|
) : ApiClient {
|
||||||
|
|
||||||
private lateinit var retrofitAdapter: Retrofit
|
private lateinit var retrofitAdapter: Retrofit
|
||||||
|
|
||||||
|
|
@ -325,7 +325,7 @@ class ApiClientImpl(
|
||||||
override suspend fun getStatus(): Status? = process { apiService.getStatus() }
|
override suspend fun getStatus(): Status? = process { apiService.getStatus() }
|
||||||
|
|
||||||
override suspend fun getContent(language: String?): ContentResult? {
|
override suspend fun getContent(language: String?): ContentResult? {
|
||||||
return process { apiService.getContent(language ?: this.languageCode) }
|
return process { apiService.getContent(language ?: this.languageCode) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun updateUser(updateDictionary: Map<String, Any>): User? {
|
override suspend fun updateUser(updateDictionary: Map<String, Any>): User? {
|
||||||
|
|
@ -479,11 +479,11 @@ class ApiClientImpl(
|
||||||
|
|
||||||
override suspend fun revive(): User? = process { apiService.revive() }
|
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) }
|
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) }
|
return process { apiService.useSkill(skillName, targetType) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ class ChallengeRepositoryImpl(
|
||||||
return tasksOrder
|
return tasksOrder
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun addChallengeTasks(challenge: Challenge, addedTaskList: List<Task>) {
|
private suspend fun addChallengeTasks(challenge: Challenge, addedTaskList: List<Task>) {
|
||||||
when {
|
when {
|
||||||
addedTaskList.count() == 1 -> apiClient.createChallengeTask(challenge.id ?: "", addedTaskList[0])
|
addedTaskList.count() == 1 -> apiClient.createChallengeTask(challenge.id ?: "", addedTaskList[0])
|
||||||
addedTaskList.count() > 1 -> apiClient.createChallengeTasks(challenge.id ?: "", addedTaskList)
|
addedTaskList.count() > 1 -> apiClient.createChallengeTasks(challenge.id ?: "", addedTaskList)
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ class InventoryRepositoryImpl(
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun retrieveInAppRewards(): List<ShopItem>? {
|
override suspend fun retrieveInAppRewards(): List<ShopItem>? {
|
||||||
val rewards = apiClient.retrieveInAppRewards()
|
val rewards = apiClient.retrieveInAppRewards()
|
||||||
if (rewards != null) {
|
if (rewards != null) {
|
||||||
localRepository.saveInAppRewards(rewards)
|
localRepository.saveInAppRewards(rewards)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -306,17 +306,17 @@ class SocialRepositoryImpl(
|
||||||
|
|
||||||
override suspend fun acceptQuest(user: User?, partyId: String): Void? {
|
override suspend fun acceptQuest(user: User?, partyId: String): Void? {
|
||||||
apiClient.acceptQuest(partyId)
|
apiClient.acceptQuest(partyId)
|
||||||
user?.let {
|
user?.let {
|
||||||
localRepository.updateRSVPNeeded(it, false)
|
localRepository.updateRSVPNeeded(it, false)
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun rejectQuest(user: User?, partyId: String): Void? {
|
override suspend fun rejectQuest(user: User?, partyId: String): Void? {
|
||||||
apiClient.rejectQuest(partyId)
|
apiClient.rejectQuest(partyId)
|
||||||
user?.let {
|
user?.let {
|
||||||
localRepository.updateRSVPNeeded(it, false)
|
localRepository.updateRSVPNeeded(it, false)
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,6 @@ class UserRepositoryImpl(
|
||||||
private var lastSync: Date? = null
|
private var lastSync: Date? = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun getUser(): Flow<User?> = getUser(userID)
|
override fun getUser(): Flow<User?> = getUser(userID)
|
||||||
override fun getUser(userID: String): Flow<User?> = localRepository.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 response = apiClient.useSkill(key, target ?: "", taskId) ?: return null
|
||||||
val user = getLiveUser() ?: return response
|
val user = getLiveUser() ?: return response
|
||||||
response.hpDiff = (response.user?.stats?.hp ?: 0.0) - (user.stats?.hp ?: 0.0)
|
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.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.damage = (response.user?.party?.quest?.progress?.up ?: 0.0f) - (user.party?.quest?.progress?.up ?: 0.0f)
|
||||||
response.user?.let { mergeUser(user, it) }
|
response.user?.let { mergeUser(user, it) }
|
||||||
|
|
@ -137,7 +136,7 @@ class UserRepositoryImpl(
|
||||||
val response = apiClient.useSkill(key, target ?: "") ?: return null
|
val response = apiClient.useSkill(key, target ?: "") ?: return null
|
||||||
val user = getLiveUser() ?: return response
|
val user = getLiveUser() ?: return response
|
||||||
response.hpDiff = (response.user?.stats?.hp ?: 0.0) - (user.stats?.hp ?: 0.0)
|
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.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.damage = (response.user?.party?.quest?.progress?.up ?: 0.0f) - (user.party?.quest?.progress?.up ?: 0.0f)
|
||||||
response.user?.let { mergeUser(user, it) }
|
response.user?.let { mergeUser(user, it) }
|
||||||
|
|
|
||||||
|
|
@ -65,5 +65,4 @@ interface InventoryLocalRepository : ContentLocalRepository {
|
||||||
fun getLiveObject(obj: OwnedItem): OwnedItem?
|
fun getLiveObject(obj: OwnedItem): OwnedItem?
|
||||||
fun getItems(itemClass: Class<out Item>): Flow<List<Item>>
|
fun getItems(itemClass: Class<out Item>): Flow<List<Item>>
|
||||||
fun getItems(itemClass: Class<out Item>, keys: Array<String>): 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 var pendingSaves = mutableListOf<Any>()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <T: RealmModel> copy(realm: Realm, obj: T) {
|
private fun <T : RealmModel> copy(realm: Realm, obj: T) {
|
||||||
try {
|
try {
|
||||||
realm.insertOrUpdate(obj)
|
realm.insertOrUpdate(obj)
|
||||||
} catch (_: java.lang.IllegalArgumentException) {
|
} catch (_: java.lang.IllegalArgumentException) {
|
||||||
|
|
@ -119,9 +119,9 @@ abstract class RealmBaseLocalRepository internal constructor(override var realm:
|
||||||
|
|
||||||
fun queryUser(userID: String): Flow<User?> {
|
fun queryUser(userID: String): Flow<User?> {
|
||||||
return realm.where(User::class.java)
|
return realm.where(User::class.java)
|
||||||
.equalTo("id", userID)
|
.equalTo("id", userID)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { it.isLoaded && it.isValid && !it.isEmpty() }
|
.filter { it.isLoaded && it.isValid && !it.isEmpty() }
|
||||||
.map { it.firstOrNull() }
|
.map { it.firstOrNull() }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,61 +18,61 @@ import kotlinx.coroutines.flow.map
|
||||||
class RealmChallengeLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm), ChallengeLocalRepository {
|
class RealmChallengeLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm), ChallengeLocalRepository {
|
||||||
|
|
||||||
override fun isChallengeMember(userID: String, challengeID: String): Flow<Boolean> = realm.where(ChallengeMembership::class.java)
|
override fun isChallengeMember(userID: String, challengeID: String): Flow<Boolean> = realm.where(ChallengeMembership::class.java)
|
||||||
.equalTo("userID", userID)
|
.equalTo("userID", userID)
|
||||||
.equalTo("challengeID", challengeID)
|
.equalTo("challengeID", challengeID)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { it.isLoaded }
|
.filter { it.isLoaded }
|
||||||
.map { it.count() > 0 }
|
.map { it.count() > 0 }
|
||||||
|
|
||||||
override fun getChallengeMembership(userId: String, id: String) = realm.where(ChallengeMembership::class.java)
|
override fun getChallengeMembership(userId: String, id: String) = realm.where(ChallengeMembership::class.java)
|
||||||
.equalTo("userID", userId)
|
.equalTo("userID", userId)
|
||||||
.equalTo("challengeID", id)
|
.equalTo("challengeID", id)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { it.isLoaded }
|
.filter { it.isLoaded }
|
||||||
.map { it.first() }
|
.map { it.first() }
|
||||||
.filterNotNull()
|
.filterNotNull()
|
||||||
|
|
||||||
override fun getChallengeMemberships(userId: String) = realm.where(ChallengeMembership::class.java)
|
override fun getChallengeMemberships(userId: String) = realm.where(ChallengeMembership::class.java)
|
||||||
.equalTo("userID", userId)
|
.equalTo("userID", userId)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { it.isLoaded }
|
.filter { it.isLoaded }
|
||||||
|
|
||||||
override fun getChallenge(id: String): Flow<Challenge> {
|
override fun getChallenge(id: String): Flow<Challenge> {
|
||||||
return realm.where(Challenge::class.java)
|
return realm.where(Challenge::class.java)
|
||||||
.equalTo("id", id)
|
.equalTo("id", id)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { realmObject -> realmObject.isLoaded && realmObject.isNotEmpty() }
|
.filter { realmObject -> realmObject.isLoaded && realmObject.isNotEmpty() }
|
||||||
.map { it.first() }
|
.map { it.first() }
|
||||||
.filterNotNull()
|
.filterNotNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTasks(challengeID: String): Flow<List<Task>> {
|
override fun getTasks(challengeID: String): Flow<List<Task>> {
|
||||||
return realm.where(Task::class.java)
|
return realm.where(Task::class.java)
|
||||||
.equalTo("userId", challengeID)
|
.equalTo("userId", challengeID)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { realmObject -> realmObject.isLoaded }
|
.filter { realmObject -> realmObject.isLoaded }
|
||||||
}
|
}
|
||||||
|
|
||||||
override val challenges: Flow<List<Challenge>>
|
override val challenges: Flow<List<Challenge>>
|
||||||
get() = realm.where(Challenge::class.java)
|
get() = realm.where(Challenge::class.java)
|
||||||
.isNotNull("name")
|
.isNotNull("name")
|
||||||
.sort("official", Sort.DESCENDING, "createdAt", Sort.DESCENDING)
|
.sort("official", Sort.DESCENDING, "createdAt", Sort.DESCENDING)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { it.isLoaded }
|
.filter { it.isLoaded }
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
override fun getUserChallenges(userId: String): Flow<List<Challenge>> {
|
override fun getUserChallenges(userId: String): Flow<List<Challenge>> {
|
||||||
return realm.where(ChallengeMembership::class.java)
|
return realm.where(ChallengeMembership::class.java)
|
||||||
.equalTo("userID", userId)
|
.equalTo("userID", userId)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { it.isLoaded }
|
.filter { it.isLoaded }
|
||||||
.flatMapLatest { it ->
|
.flatMapLatest { it ->
|
||||||
val ids = it.map {
|
val ids = it.map {
|
||||||
return@map it.challengeID
|
return@map it.challengeID
|
||||||
|
|
|
||||||
|
|
@ -39,10 +39,10 @@ open class RealmContentLocalRepository(realm: Realm) : RealmBaseLocalRepository(
|
||||||
|
|
||||||
override fun getWorldState(): Flow<WorldState> {
|
override fun getWorldState(): Flow<WorldState> {
|
||||||
return realm.where(WorldState::class.java)
|
return realm.where(WorldState::class.java)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { it.isLoaded && it.size > 0 }
|
.filter { it.isLoaded && it.size > 0 }
|
||||||
.map { it.first() }
|
.map { it.first() }
|
||||||
.filterNotNull()
|
.filterNotNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,9 @@ class RealmCustomizationLocalRepository(realm: Realm) : RealmContentLocalReposit
|
||||||
.endGroup()
|
.endGroup()
|
||||||
}
|
}
|
||||||
return query
|
return query
|
||||||
.sort("customizationSet")
|
.sort("customizationSet")
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { it.isLoaded }
|
.filter { it.isLoaded }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,17 +12,17 @@ import kotlinx.coroutines.flow.map
|
||||||
class RealmFAQLocalRepository(realm: Realm) : RealmContentLocalRepository(realm), FAQLocalRepository {
|
class RealmFAQLocalRepository(realm: Realm) : RealmContentLocalRepository(realm), FAQLocalRepository {
|
||||||
override fun getArticle(position: Int): Flow<FAQArticle> {
|
override fun getArticle(position: Int): Flow<FAQArticle> {
|
||||||
return realm.where(FAQArticle::class.java)
|
return realm.where(FAQArticle::class.java)
|
||||||
.equalTo("position", position)
|
.equalTo("position", position)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { it.isLoaded && it.count() > 0 }
|
.filter { it.isLoaded && it.count() > 0 }
|
||||||
.map { it.firstOrNull() }
|
.map { it.firstOrNull() }
|
||||||
.filterNotNull()
|
.filterNotNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
override val articles: Flow<List<FAQArticle>>
|
override val articles: Flow<List<FAQArticle>>
|
||||||
get() = realm.where(FAQArticle::class.java)
|
get() = realm.where(FAQArticle::class.java)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { it.isLoaded }
|
.filter { it.isLoaded }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,8 @@ import java.text.SimpleDateFormat
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
class RealmInventoryLocalRepository(realm: Realm) : RealmContentLocalRepository(realm),
|
class RealmInventoryLocalRepository(realm: Realm) :
|
||||||
|
RealmContentLocalRepository(realm),
|
||||||
InventoryLocalRepository {
|
InventoryLocalRepository {
|
||||||
override fun getQuestContent(keys: List<String>): Flow<List<QuestContent>> {
|
override fun getQuestContent(keys: List<String>): Flow<List<QuestContent>> {
|
||||||
return realm.where(QuestContent::class.java)
|
return realm.where(QuestContent::class.java)
|
||||||
|
|
|
||||||
|
|
@ -21,18 +21,18 @@ import kotlinx.coroutines.flow.map
|
||||||
class RealmSocialLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm), SocialLocalRepository {
|
class RealmSocialLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm), SocialLocalRepository {
|
||||||
|
|
||||||
override fun getGroupMembership(userId: String, id: String) = realm.where(GroupMembership::class.java)
|
override fun getGroupMembership(userId: String, id: String) = realm.where(GroupMembership::class.java)
|
||||||
.equalTo("userID", userId)
|
.equalTo("userID", userId)
|
||||||
.equalTo("groupID", id)
|
.equalTo("groupID", id)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { it.isLoaded && it.isNotEmpty() }
|
.filter { it.isLoaded && it.isNotEmpty() }
|
||||||
.map { it.first() }
|
.map { it.first() }
|
||||||
|
|
||||||
override fun getGroupMemberships(userId: String): Flow<List<GroupMembership>> = realm.where(GroupMembership::class.java)
|
override fun getGroupMemberships(userId: String): Flow<List<GroupMembership>> = realm.where(GroupMembership::class.java)
|
||||||
.equalTo("userID", userId)
|
.equalTo("userID", userId)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { it.isLoaded }
|
.filter { it.isLoaded }
|
||||||
|
|
||||||
override fun updateMembership(userId: String, id: String, isMember: Boolean) {
|
override fun updateMembership(userId: String, id: String, isMember: Boolean) {
|
||||||
if (isMember) {
|
if (isMember) {
|
||||||
|
|
@ -129,19 +129,19 @@ class RealmSocialLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getPublicGuilds() = realm.where(Group::class.java)
|
override fun getPublicGuilds() = realm.where(Group::class.java)
|
||||||
.equalTo("type", "guild")
|
.equalTo("type", "guild")
|
||||||
.equalTo("privacy", "public")
|
.equalTo("privacy", "public")
|
||||||
.notEqualTo("id", Group.TAVERN_ID)
|
.notEqualTo("id", Group.TAVERN_ID)
|
||||||
.sort("memberCount", Sort.DESCENDING)
|
.sort("memberCount", Sort.DESCENDING)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { it.isLoaded }
|
.filter { it.isLoaded }
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
override fun getUserGroups(userID: String, type: String?) = realm.where(GroupMembership::class.java)
|
override fun getUserGroups(userID: String, type: String?) = realm.where(GroupMembership::class.java)
|
||||||
.equalTo("userID", userID)
|
.equalTo("userID", userID)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { it.isLoaded }
|
.filter { it.isLoaded }
|
||||||
.flatMapLatest { memberships ->
|
.flatMapLatest { memberships ->
|
||||||
realm.where(Group::class.java)
|
realm.where(Group::class.java)
|
||||||
|
|
@ -160,10 +160,10 @@ class RealmSocialLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm)
|
||||||
|
|
||||||
override fun getGroups(type: String): Flow<List<Group>> {
|
override fun getGroups(type: String): Flow<List<Group>> {
|
||||||
return realm.where(Group::class.java)
|
return realm.where(Group::class.java)
|
||||||
.equalTo("type", type)
|
.equalTo("type", type)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { it.isLoaded }
|
.filter { it.isLoaded }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getGroup(id: String): Flow<Group?> {
|
override fun getGroup(id: String): Flow<Group?> {
|
||||||
|
|
@ -177,11 +177,11 @@ class RealmSocialLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm)
|
||||||
|
|
||||||
override fun getGroupChat(groupId: String): Flow<List<ChatMessage>> {
|
override fun getGroupChat(groupId: String): Flow<List<ChatMessage>> {
|
||||||
return realm.where(ChatMessage::class.java)
|
return realm.where(ChatMessage::class.java)
|
||||||
.equalTo("groupId", groupId)
|
.equalTo("groupId", groupId)
|
||||||
.sort("timestamp", Sort.DESCENDING)
|
.sort("timestamp", Sort.DESCENDING)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { it.isLoaded }
|
.filter { it.isLoaded }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun deleteMessage(id: String) {
|
override fun deleteMessage(id: String) {
|
||||||
|
|
@ -190,9 +190,9 @@ class RealmSocialLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getPartyMembers(partyId: String) = realm.where(Member::class.java)
|
override fun getPartyMembers(partyId: String) = realm.where(Member::class.java)
|
||||||
.equalTo("party.id", partyId)
|
.equalTo("party.id", partyId)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
|
|
||||||
override fun getGroupMembers(groupID: String) = realm.where(GroupMembership::class.java)
|
override fun getGroupMembers(groupID: String) = realm.where(GroupMembership::class.java)
|
||||||
.equalTo("groupID", groupID)
|
.equalTo("groupID", groupID)
|
||||||
|
|
@ -291,18 +291,18 @@ class RealmSocialLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getInboxMessages(userId: String, replyToUserID: String?) = realm.where(ChatMessage::class.java)
|
override fun getInboxMessages(userId: String, replyToUserID: String?) = realm.where(ChatMessage::class.java)
|
||||||
.equalTo("isInboxMessage", true)
|
.equalTo("isInboxMessage", true)
|
||||||
.equalTo("uuid", replyToUserID)
|
.equalTo("uuid", replyToUserID)
|
||||||
.equalTo("userID", userId)
|
.equalTo("userID", userId)
|
||||||
.sort("timestamp", Sort.DESCENDING)
|
.sort("timestamp", Sort.DESCENDING)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { it.isLoaded }
|
.filter { it.isLoaded }
|
||||||
|
|
||||||
override fun getInboxConversation(userId: String) = realm.where(InboxConversation::class.java)
|
override fun getInboxConversation(userId: String) = realm.where(InboxConversation::class.java)
|
||||||
.equalTo("userID", userId)
|
.equalTo("userID", userId)
|
||||||
.sort("timestamp", Sort.DESCENDING)
|
.sort("timestamp", Sort.DESCENDING)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { it.isLoaded }
|
.filter { it.isLoaded }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,10 +56,10 @@ class RealmTaskLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm),
|
||||||
override fun getTasks(userId: String): Flow<List<Task>> {
|
override fun getTasks(userId: String): Flow<List<Task>> {
|
||||||
if (realm.isClosed) return emptyFlow()
|
if (realm.isClosed) return emptyFlow()
|
||||||
return realm.where(Task::class.java).equalTo("userId", userId)
|
return realm.where(Task::class.java).equalTo("userId", userId)
|
||||||
.sort("position", Sort.ASCENDING, "dateCreated", Sort.DESCENDING)
|
.sort("position", Sort.ASCENDING, "dateCreated", Sort.DESCENDING)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { it.isLoaded }
|
.filter { it.isLoaded }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun saveTasks(ownerID: String, tasksOrder: TasksOrder, tasks: TaskList) {
|
override fun saveTasks(ownerID: String, tasksOrder: TasksOrder, tasks: TaskList) {
|
||||||
|
|
@ -218,10 +218,10 @@ class RealmTaskLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm),
|
||||||
|
|
||||||
override fun getTaskAtPosition(taskType: String, position: Int): Flow<Task> {
|
override fun getTaskAtPosition(taskType: String, position: Int): Flow<Task> {
|
||||||
return realm.where(Task::class.java).equalTo("typeValue", taskType).equalTo("position", position)
|
return realm.where(Task::class.java).equalTo("typeValue", taskType).equalTo("position", position)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { realmObject -> realmObject.isLoaded && realmObject.isNotEmpty() }
|
.filter { realmObject -> realmObject.isLoaded && realmObject.isNotEmpty() }
|
||||||
.map { it.first() }
|
.map { it.first() }
|
||||||
.filterNotNull()
|
.filterNotNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -244,12 +244,12 @@ class RealmTaskLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm),
|
||||||
|
|
||||||
override fun getErroredTasks(userID: String): Flow<List<Task>> {
|
override fun getErroredTasks(userID: String): Flow<List<Task>> {
|
||||||
return realm.where(Task::class.java)
|
return realm.where(Task::class.java)
|
||||||
.equalTo("userId", userID)
|
.equalTo("userId", userID)
|
||||||
.equalTo("hasErrored", true)
|
.equalTo("hasErrored", true)
|
||||||
.sort("position")
|
.sort("position")
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { it.isLoaded }
|
.filter { it.isLoaded }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getUser(userID: String): Flow<User> {
|
override fun getUser(userID: String): Flow<User> {
|
||||||
|
|
@ -264,10 +264,10 @@ class RealmTaskLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm),
|
||||||
|
|
||||||
override fun getTasksForChallenge(challengeID: String?, userID: String?): Flow<List<Task>> {
|
override fun getTasksForChallenge(challengeID: String?, userID: String?): Flow<List<Task>> {
|
||||||
return realm.where(Task::class.java)
|
return realm.where(Task::class.java)
|
||||||
.equalTo("challengeID", challengeID)
|
.equalTo("challengeID", challengeID)
|
||||||
.equalTo("userId", userID)
|
.equalTo("userId", userID)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { it.isLoaded }
|
.filter { it.isLoaded }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,19 +15,19 @@ class RealmTutorialLocalRepository(realm: Realm) : RealmBaseLocalRepository(real
|
||||||
override fun getTutorialStep(key: String): Flow<TutorialStep> {
|
override fun getTutorialStep(key: String): Flow<TutorialStep> {
|
||||||
if (realm.isClosed) return emptyFlow()
|
if (realm.isClosed) return emptyFlow()
|
||||||
return realm.where(TutorialStep::class.java).equalTo("identifier", key)
|
return realm.where(TutorialStep::class.java).equalTo("identifier", key)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { realmObject -> realmObject.isLoaded && realmObject.isValid && realmObject.isNotEmpty() }
|
.filter { realmObject -> realmObject.isLoaded && realmObject.isValid && realmObject.isNotEmpty() }
|
||||||
.map { steps -> steps.first() }
|
.map { steps -> steps.first() }
|
||||||
.filterNotNull()
|
.filterNotNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTutorialSteps(keys: List<String>): Flow<out List<TutorialStep>> {
|
override fun getTutorialSteps(keys: List<String>): Flow<out List<TutorialStep>> {
|
||||||
if (realm.isClosed) return emptyFlow()
|
if (realm.isClosed) return emptyFlow()
|
||||||
return realm.where(TutorialStep::class.java)
|
return realm.where(TutorialStep::class.java)
|
||||||
.`in`("identifier", keys.toTypedArray())
|
.`in`("identifier", keys.toTypedArray())
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { it.isLoaded }
|
.filter { it.isLoaded }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,8 @@ import kotlinx.coroutines.flow.filterNotNull
|
||||||
import kotlinx.coroutines.flow.flatMapLatest
|
import kotlinx.coroutines.flow.flatMapLatest
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
|
|
||||||
class RealmUserLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm),
|
class RealmUserLocalRepository(realm: Realm) :
|
||||||
|
RealmBaseLocalRepository(realm),
|
||||||
UserLocalRepository {
|
UserLocalRepository {
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
override fun getUserQuestStatus(userID: String): Flow<UserQuestStatus> {
|
override fun getUserQuestStatus(userID: String): Flow<UserQuestStatus> {
|
||||||
|
|
@ -30,13 +31,13 @@ class RealmUserLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm),
|
||||||
.map { it.party?.id ?: "" }
|
.map { it.party?.id ?: "" }
|
||||||
.filter { it.isNotBlank() }
|
.filter { it.isNotBlank() }
|
||||||
.flatMapLatest {
|
.flatMapLatest {
|
||||||
realm.where(Group::class.java)
|
realm.where(Group::class.java)
|
||||||
.equalTo("id", it)
|
.equalTo("id", it)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { groups -> groups.size > 0 }
|
.filter { groups -> groups.size > 0 }
|
||||||
.map { it.firstOrNull() }
|
.map { it.firstOrNull() }
|
||||||
.filterNotNull()
|
.filterNotNull()
|
||||||
}
|
}
|
||||||
.map {
|
.map {
|
||||||
when {
|
when {
|
||||||
|
|
@ -127,22 +128,22 @@ class RealmUserLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm),
|
||||||
override fun getTeamPlan(teamID: String): Flow<Group?> {
|
override fun getTeamPlan(teamID: String): Flow<Group?> {
|
||||||
if (realm.isClosed) return emptyFlow()
|
if (realm.isClosed) return emptyFlow()
|
||||||
return realm.where(Group::class.java)
|
return realm.where(Group::class.java)
|
||||||
.equalTo("id", teamID)
|
.equalTo("id", teamID)
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { realmObject -> realmObject.isLoaded && realmObject.isValid }
|
.filter { realmObject -> realmObject.isLoaded && realmObject.isValid }
|
||||||
.map { teams -> teams.firstOrNull() }
|
.map { teams -> teams.firstOrNull() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSkills(user: User): Flow<List<Skill>> {
|
override fun getSkills(user: User): Flow<List<Skill>> {
|
||||||
val habitClass =
|
val habitClass =
|
||||||
if (user.preferences?.disableClasses == true) "none" else user.stats?.habitClass
|
if (user.preferences?.disableClasses == true) "none" else user.stats?.habitClass
|
||||||
return realm.where(Skill::class.java)
|
return realm.where(Skill::class.java)
|
||||||
.equalTo("habitClass", habitClass)
|
.equalTo("habitClass", habitClass)
|
||||||
.sort("lvl")
|
.sort("lvl")
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { it.isLoaded }
|
.filter { it.isLoaded }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSpecialItems(user: User): Flow<List<Skill>> {
|
override fun getSpecialItems(user: User): Flow<List<Skill>> {
|
||||||
|
|
@ -154,9 +155,9 @@ class RealmUserLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return realm.where(Skill::class.java)
|
return realm.where(Skill::class.java)
|
||||||
.`in`("key", ownedItems.toTypedArray())
|
.`in`("key", ownedItems.toTypedArray())
|
||||||
.findAll()
|
.findAll()
|
||||||
.toFlow()
|
.toFlow()
|
||||||
.filter { it.isLoaded }
|
.filter { it.isLoaded }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import com.habitrpg.common.habitica.helpers.AppTestingLevel
|
||||||
import kotlinx.coroutines.MainScope
|
import kotlinx.coroutines.MainScope
|
||||||
import java.util.Date
|
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
|
private var worldState: WorldState? = null
|
||||||
|
|
||||||
|
|
@ -24,8 +24,8 @@ class AppConfigManager(contentRepository: ContentRepository?): com.habitrpg.comm
|
||||||
try {
|
try {
|
||||||
MainScope().launchCatching {
|
MainScope().launchCatching {
|
||||||
contentRepository?.getWorldState()?.collect {
|
contentRepository?.getWorldState()?.collect {
|
||||||
worldState = it
|
worldState = it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (_: java.lang.IllegalStateException) {
|
} catch (_: java.lang.IllegalStateException) {
|
||||||
// pass
|
// pass
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,8 @@ import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import okhttp3.internal.http2.ConnectionShutdownException
|
|
||||||
import okhttp3.internal.http2.StreamResetException
|
|
||||||
import retrofit2.HttpException
|
import retrofit2.HttpException
|
||||||
import java.io.EOFException
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.net.SocketTimeoutException
|
|
||||||
import java.net.UnknownHostException
|
|
||||||
|
|
||||||
class ExceptionHandler {
|
class ExceptionHandler {
|
||||||
private var analyticsManager: AnalyticsManager? = null
|
private var analyticsManager: AnalyticsManager? = null
|
||||||
|
|
@ -52,7 +47,12 @@ class ExceptionHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun CoroutineScope.launchCatching(errorHandler: ((Throwable) -> Unit)? = null, function: suspend CoroutineScope.() -> Unit) {
|
fun CoroutineScope.launchCatching(errorHandler: ((Throwable) -> Unit)? = null, function: suspend CoroutineScope.() -> Unit) {
|
||||||
launch((ExceptionHandler.coroutine {
|
launch(
|
||||||
errorHandler?.invoke(it)
|
(
|
||||||
}), block = function)
|
ExceptionHandler.coroutine {
|
||||||
}
|
errorHandler?.invoke(it)
|
||||||
|
}
|
||||||
|
),
|
||||||
|
block = function
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ object MainNavigationController {
|
||||||
get() { return controllerReference?.get() }
|
get() { return controllerReference?.get() }
|
||||||
|
|
||||||
val isReady: Boolean
|
val isReady: Boolean
|
||||||
get() = controllerReference?.get() != null
|
get() = controllerReference?.get() != null
|
||||||
|
|
||||||
fun setup(navController: NavController) {
|
fun setup(navController: NavController) {
|
||||||
this.controllerReference = WeakReference(navController)
|
this.controllerReference = WeakReference(navController)
|
||||||
|
|
|
||||||
|
|
@ -24,31 +24,31 @@ interface NotificationsManager {
|
||||||
fun dismissTaskNotification(context: Context, task: Task)
|
fun dismissTaskNotification(context: Context, task: Task)
|
||||||
}
|
}
|
||||||
|
|
||||||
class MainNotificationsManager: NotificationsManager {
|
class MainNotificationsManager : NotificationsManager {
|
||||||
|
|
||||||
private val seenNotifications: MutableMap<String, Boolean>
|
private val seenNotifications: MutableMap<String, Boolean>
|
||||||
override var apiClient: WeakReference<ApiClient>? = null
|
override var apiClient: WeakReference<ApiClient>? = null
|
||||||
|
|
||||||
private var lastNotificationHandling: Date? = null
|
private var lastNotificationHandling: Date? = null
|
||||||
val _notifications = MutableStateFlow<List<Notification>?>(null)
|
private val notificationsFlow = MutableStateFlow<List<Notification>?>(null)
|
||||||
val _displaynotificationEvents = Channel<Notification>()
|
private val displayedNotificationEvents = Channel<Notification>()
|
||||||
override val displayNotificationEvents: Flow<Notification> = _displaynotificationEvents.receiveAsFlow().filterNotNull()
|
override val displayNotificationEvents: Flow<Notification> = displayedNotificationEvents.receiveAsFlow().filterNotNull()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
this.seenNotifications = HashMap()
|
this.seenNotifications = HashMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setNotifications(current: List<Notification>) {
|
override fun setNotifications(current: List<Notification>) {
|
||||||
_notifications.value = current
|
notificationsFlow.value = current
|
||||||
this.handlePopupNotifications(current)
|
this.handlePopupNotifications(current)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getNotifications(): Flow<List<Notification>> {
|
override fun getNotifications(): Flow<List<Notification>> {
|
||||||
return _notifications.filterNotNull()
|
return notificationsFlow.filterNotNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getNotification(id: String): Notification? {
|
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) {
|
override fun dismissTaskNotification(context: Context, task: Task) {
|
||||||
|
|
@ -92,7 +92,6 @@ class MainNotificationsManager: NotificationsManager {
|
||||||
Notification.Type.ACHIEVEMENT_FRESHWATER_FRIENDS.type -> true
|
Notification.Type.ACHIEVEMENT_FRESHWATER_FRIENDS.type -> true
|
||||||
Notification.Type.ACHIEVEMENT_GOOD_AS_GOLD.type -> true
|
Notification.Type.ACHIEVEMENT_GOOD_AS_GOLD.type -> true
|
||||||
Notification.Type.ACHIEVEMENT_ALL_THAT_GLITTERS.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_BONE_COLLECTOR.type -> true
|
||||||
Notification.Type.ACHIEVEMENT_SKELETON_CREW.type -> true
|
Notification.Type.ACHIEVEMENT_SKELETON_CREW.type -> true
|
||||||
Notification.Type.ACHIEVEMENT_SEEING_RED.type -> true
|
Notification.Type.ACHIEVEMENT_SEEING_RED.type -> true
|
||||||
|
|
@ -115,7 +114,7 @@ class MainNotificationsManager: NotificationsManager {
|
||||||
|
|
||||||
private fun readNotification(notification: Notification) {
|
private fun readNotification(notification: Notification) {
|
||||||
MainScope().launchCatching {
|
MainScope().launchCatching {
|
||||||
_displaynotificationEvents.send(notification)
|
displayedNotificationEvents.send(notification)
|
||||||
seenNotifications[notification.id] = true
|
seenNotifications[notification.id] = true
|
||||||
apiClient?.get()?.readNotification(notification.id)
|
apiClient?.get()?.readNotification(notification.id)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -121,9 +121,9 @@ class PurchaseHandler(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startListening() {
|
fun startListening() {
|
||||||
if (billingClient.connectionState == BillingClient.ConnectionState.CONNECTING
|
if (billingClient.connectionState == BillingClient.ConnectionState.CONNECTING ||
|
||||||
|| billingClient.connectionState == BillingClient.ConnectionState.CONNECTED
|
billingClient.connectionState == BillingClient.ConnectionState.CONNECTED ||
|
||||||
|| billingClientState == BillingClientState.UNAVAILABLE
|
billingClientState == BillingClientState.UNAVAILABLE
|
||||||
) {
|
) {
|
||||||
// Don't connect again if it's already connected
|
// Don't connect again if it's already connected
|
||||||
return
|
return
|
||||||
|
|
@ -209,9 +209,11 @@ class PurchaseHandler(
|
||||||
}
|
}
|
||||||
billingClientState.canMaybePurchase && billingClient.isReady
|
billingClientState.canMaybePurchase && billingClient.isReady
|
||||||
}
|
}
|
||||||
val params = QueryProductDetailsParams.newBuilder().setProductList(skus.map {
|
val params = QueryProductDetailsParams.newBuilder().setProductList(
|
||||||
Product.newBuilder().setProductId(it).setProductType(type).build()
|
skus.map {
|
||||||
}).build()
|
Product.newBuilder().setProductId(it).setProductType(type).build()
|
||||||
|
}
|
||||||
|
).build()
|
||||||
val skuDetailsResult = withContext(Dispatchers.IO) {
|
val skuDetailsResult = withContext(Dispatchers.IO) {
|
||||||
billingClient.queryProductDetails(params)
|
billingClient.queryProductDetails(params)
|
||||||
}
|
}
|
||||||
|
|
@ -230,12 +232,14 @@ class PurchaseHandler(
|
||||||
addGift(skuDetails.productId, it, recipientUsername ?: it)
|
addGift(skuDetails.productId, it, recipientUsername ?: it)
|
||||||
}
|
}
|
||||||
val flowParams =
|
val flowParams =
|
||||||
BillingFlowParams.newBuilder().setProductDetailsParamsList(listOf(skuDetails).map {
|
BillingFlowParams.newBuilder().setProductDetailsParamsList(
|
||||||
BillingFlowParams.ProductDetailsParams.newBuilder()
|
listOf(skuDetails).map {
|
||||||
.setProductDetails(skuDetails).setOfferToken(
|
BillingFlowParams.ProductDetailsParams.newBuilder()
|
||||||
skuDetails.subscriptionOfferDetails?.first()?.offerToken ?: ""
|
.setProductDetails(skuDetails).setOfferToken(
|
||||||
).build()
|
skuDetails.subscriptionOfferDetails?.first()?.offerToken ?: ""
|
||||||
}).build()
|
).build()
|
||||||
|
}
|
||||||
|
).build()
|
||||||
billingClient.launchBillingFlow(activity, flowParams)
|
billingClient.launchBillingFlow(activity, flowParams)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -555,9 +559,11 @@ class PurchaseHandler(
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun retryUntil(
|
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
|
maxDelay: Long = 1000, // 1 second
|
||||||
factor: Double = 2.0, block: suspend () -> Boolean
|
factor: Double = 2.0,
|
||||||
|
block: suspend () -> Boolean
|
||||||
) {
|
) {
|
||||||
var currentDelay = initialDelay
|
var currentDelay = initialDelay
|
||||||
repeat(times - 1) {
|
repeat(times - 1) {
|
||||||
|
|
|
||||||
|
|
@ -27,4 +27,4 @@ object PurchaseTypes {
|
||||||
Subscription6MonthNoRenew,
|
Subscription6MonthNoRenew,
|
||||||
Subscription12MonthNoRenew
|
Subscription12MonthNoRenew
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,39 +27,39 @@ class SoundFileLoader(private val context: Context) {
|
||||||
@SuppressLint("SetWorldReadable", "ReturnCount")
|
@SuppressLint("SetWorldReadable", "ReturnCount")
|
||||||
suspend fun download(files: List<SoundFile>): List<SoundFile> {
|
suspend fun download(files: List<SoundFile>): List<SoundFile> {
|
||||||
return files.map { audioFile ->
|
return files.map { audioFile ->
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
val file = File(getFullAudioFilePath(audioFile))
|
val file = File(getFullAudioFilePath(audioFile))
|
||||||
if (file.exists() && file.length() > 5000) {
|
if (file.exists() && file.length() > 5000) {
|
||||||
// Important, or else the MediaPlayer can't access this file
|
// Important, or else the MediaPlayer can't access this file
|
||||||
file.setReadable(true, false)
|
|
||||||
audioFile.file = file
|
|
||||||
return@withContext audioFile
|
|
||||||
}
|
|
||||||
val request = Request.Builder().url(audioFile.webUrl).build()
|
|
||||||
|
|
||||||
val response: Response
|
|
||||||
try {
|
|
||||||
response = client.newCall(request).execute()
|
|
||||||
if (!response.isSuccessful) {
|
|
||||||
throw IOException()
|
|
||||||
}
|
|
||||||
} catch (io: IOException) {
|
|
||||||
return@withContext audioFile
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
val sink = file.sink().buffer()
|
|
||||||
sink.writeAll(response.body!!.source())
|
|
||||||
sink.flush()
|
|
||||||
sink.close()
|
|
||||||
} catch (io: IOException) {
|
|
||||||
return@withContext audioFile
|
|
||||||
}
|
|
||||||
|
|
||||||
file.setReadable(true, false)
|
file.setReadable(true, false)
|
||||||
audioFile.file = file
|
audioFile.file = file
|
||||||
return@withContext audioFile
|
return@withContext audioFile
|
||||||
}
|
}
|
||||||
|
val request = Request.Builder().url(audioFile.webUrl).build()
|
||||||
|
|
||||||
|
val response: Response
|
||||||
|
try {
|
||||||
|
response = client.newCall(request).execute()
|
||||||
|
if (!response.isSuccessful) {
|
||||||
|
throw IOException()
|
||||||
|
}
|
||||||
|
} catch (io: IOException) {
|
||||||
|
return@withContext audioFile
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
val sink = file.sink().buffer()
|
||||||
|
sink.writeAll(response.body!!.source())
|
||||||
|
sink.flush()
|
||||||
|
sink.close()
|
||||||
|
} catch (io: IOException) {
|
||||||
|
return@withContext audioFile
|
||||||
|
}
|
||||||
|
|
||||||
|
file.setReadable(true, false)
|
||||||
|
audioFile.file = file
|
||||||
|
return@withContext audioFile
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -99,9 +99,9 @@ class TaskAlarmManager(
|
||||||
private fun setAlarmForRemindersItem(reminderItemTask: Task, remindersItem: RemindersItem?) {
|
private fun setAlarmForRemindersItem(reminderItemTask: Task, remindersItem: RemindersItem?) {
|
||||||
val now = ZonedDateTime.now().withZoneSameLocal(ZoneId.systemDefault())?.toInstant()
|
val now = ZonedDateTime.now().withZoneSameLocal(ZoneId.systemDefault())?.toInstant()
|
||||||
val zonedTime = remindersItem?.getLocalZonedDateTimeInstant()
|
val zonedTime = remindersItem?.getLocalZonedDateTimeInstant()
|
||||||
if (remindersItem == null
|
if (remindersItem == null ||
|
||||||
|| (reminderItemTask.type == TaskType.DAILY && zonedTime?.isBefore(now) == true && reminderItemTask.nextDue?.firstOrNull() != null)
|
(reminderItemTask.type == TaskType.DAILY && zonedTime?.isBefore(now) == true && reminderItemTask.nextDue?.firstOrNull() != null) ||
|
||||||
|| (reminderItemTask.type == TaskType.TODO && zonedTime?.isBefore(now) == true)
|
(reminderItemTask.type == TaskType.TODO && zonedTime?.isBefore(now) == true)
|
||||||
) {
|
) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -226,7 +226,7 @@ class TaskAlarmManager(
|
||||||
try {
|
try {
|
||||||
alarmManager?.setAlarmClock(AlarmClockInfo(time, pendingIntent), pendingIntent)
|
alarmManager?.setAlarmClock(AlarmClockInfo(time, pendingIntent), pendingIntent)
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
when(ex) {
|
when (ex) {
|
||||||
is IllegalStateException, is SecurityException -> {
|
is IllegalStateException, is SecurityException -> {
|
||||||
alarmManager?.setWindow(AlarmManager.RTC_WAKEUP, time, 60000, pendingIntent)
|
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 {
|
task.startDate?.let {
|
||||||
val flags = DateUtils.FORMAT_SHOW_DATE + DateUtils.FORMAT_NO_YEAR
|
val flags = DateUtils.FORMAT_SHOW_DATE + DateUtils.FORMAT_NO_YEAR
|
||||||
DateUtils.formatDateTime(context, it.time, flags)
|
DateUtils.formatDateTime(context, it.time, flags)
|
||||||
} ?: "")
|
} ?: ""
|
||||||
|
)
|
||||||
else -> ""
|
else -> ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ class HabiticaFirebaseMessagingService : FirebaseMessagingService() {
|
||||||
|
|
||||||
if (remoteMessage.data["identifier"]?.contains(PushNotificationManager.WON_CHALLENGE_PUSH_NOTIFICATION_KEY) == true) {
|
if (remoteMessage.data["identifier"]?.contains(PushNotificationManager.WON_CHALLENGE_PUSH_NOTIFICATION_KEY) == true) {
|
||||||
// if (this::userRepository.isInitialized) {
|
// if (this::userRepository.isInitialized) {
|
||||||
// userRepository.retrieveUser(true).subscribe({}, RxErrorHandler.handleEmptyError())
|
// userRepository.retrieveUser(true).subscribe({}, RxErrorHandler.handleEmptyError())
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ class PushNotificationManager(
|
||||||
addRefreshToken()
|
addRefreshToken()
|
||||||
} catch (_: IOException) {
|
} catch (_: IOException) {
|
||||||
// catchy catch-catch
|
// catchy catch-catch
|
||||||
} catch (_: Exception){
|
} catch (_: Exception) {
|
||||||
// catchy catch-catch-cat, I'm out of breath.
|
// catchy catch-catch-cat, I'm out of breath.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -85,7 +85,7 @@ class PushNotificationManager(
|
||||||
if (this.refreshedToken.isEmpty() || !userHasPushDevice()) {
|
if (this.refreshedToken.isEmpty() || !userHasPushDevice()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
apiClient.deletePushDevice(refreshedToken)
|
apiClient.deletePushDevice(refreshedToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun userHasPushDevice(): Boolean {
|
private fun userHasPushDevice(): Boolean {
|
||||||
|
|
@ -133,7 +133,8 @@ class PushNotificationManager(
|
||||||
val remoteMessageIdentifier = remoteMessage.data["identifier"]
|
val remoteMessageIdentifier = remoteMessage.data["identifier"]
|
||||||
|
|
||||||
val notificationFactory = HabiticaLocalNotificationFactory()
|
val notificationFactory = HabiticaLocalNotificationFactory()
|
||||||
val notification = notificationFactory.build(remoteMessageIdentifier,
|
val notification = notificationFactory.build(
|
||||||
|
remoteMessageIdentifier,
|
||||||
context
|
context
|
||||||
)
|
)
|
||||||
if (pushNotificationManager?.userIsSubscribedToNotificationType(remoteMessageIdentifier) != false) {
|
if (pushNotificationManager?.userIsSubscribedToNotificationType(remoteMessageIdentifier) != false) {
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import kotlinx.coroutines.launch
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class DisplayItemDropUseCase @Inject
|
class DisplayItemDropUseCase @Inject
|
||||||
constructor(private val soundManager: SoundManager):
|
constructor(private val soundManager: SoundManager) :
|
||||||
UseCase<DisplayItemDropUseCase.RequestValues, Unit>() {
|
UseCase<DisplayItemDropUseCase.RequestValues, Unit>() {
|
||||||
|
|
||||||
override suspend fun run(requestValues: RequestValues) {
|
override suspend fun run(requestValues: RequestValues) {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,8 @@ import javax.inject.Inject
|
||||||
|
|
||||||
class HatchPetUseCase @Inject
|
class HatchPetUseCase @Inject
|
||||||
constructor(
|
constructor(
|
||||||
private val inventoryRepository: InventoryRepository) : UseCase<HatchPetUseCase.RequestValues, Items?>() {
|
private val inventoryRepository: InventoryRepository
|
||||||
|
) : UseCase<HatchPetUseCase.RequestValues, Items?>() {
|
||||||
override suspend fun run(requestValues: RequestValues): Items? {
|
override suspend fun run(requestValues: RequestValues): Items? {
|
||||||
return inventoryRepository.hatchPet(requestValues.egg, requestValues.potion) {
|
return inventoryRepository.hatchPet(requestValues.egg, requestValues.potion) {
|
||||||
val petWrapper = View.inflate(requestValues.context, R.layout.pet_imageview, null) as? FrameLayout
|
val petWrapper = View.inflate(requestValues.context, R.layout.pet_imageview, null) as? FrameLayout
|
||||||
|
|
|
||||||
|
|
@ -12,4 +12,4 @@ abstract class UseCase<Q : UseCase.RequestValues?, T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface RequestValues
|
interface RequestValues
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,10 +52,10 @@ open class Member : RealmObject(), Avatar, BaseMainObject, Assignable {
|
||||||
} else this.profile?.name ?: ""
|
} else this.profile?.name ?: ""
|
||||||
|
|
||||||
override val identifiableName: String
|
override val identifiableName: String
|
||||||
get() = username ?: ""
|
get() = username ?: ""
|
||||||
|
|
||||||
override val avatar: Avatar
|
override val avatar: Avatar
|
||||||
get() = this
|
get() = this
|
||||||
|
|
||||||
val petsFoundCount: Int
|
val petsFoundCount: Int
|
||||||
get() = this.items?.pets?.size ?: 0
|
get() = this.items?.pets?.size ?: 0
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,8 @@ import io.realm.RealmObject
|
||||||
import io.realm.annotations.RealmClass
|
import io.realm.annotations.RealmClass
|
||||||
|
|
||||||
@RealmClass(embedded = true)
|
@RealmClass(embedded = true)
|
||||||
open class MemberPreferences : RealmObject(),
|
open class MemberPreferences :
|
||||||
|
RealmObject(),
|
||||||
AvatarPreferences {
|
AvatarPreferences {
|
||||||
|
|
||||||
override var hair: Hair? = null
|
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.FragmentSubscriptionBinding
|
||||||
import com.habitrpg.android.habitica.databinding.PurchaseGemViewBinding
|
import com.habitrpg.android.habitica.databinding.PurchaseGemViewBinding
|
||||||
import com.habitrpg.android.habitica.extensions.DateUtils
|
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.helpers.MainNavigationController
|
||||||
import com.habitrpg.android.habitica.ui.fragments.PromoInfoFragment
|
import com.habitrpg.android.habitica.ui.fragments.PromoInfoFragment
|
||||||
import com.habitrpg.android.habitica.ui.fragments.purchases.SubscriptionFragment
|
import com.habitrpg.android.habitica.ui.fragments.purchases.SubscriptionFragment
|
||||||
import com.habitrpg.android.habitica.ui.views.promo.PromoMenuView
|
import com.habitrpg.android.habitica.ui.views.promo.PromoMenuView
|
||||||
|
import com.habitrpg.common.habitica.extensions.isUsingNightModeResources
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
|
||||||
|
|
@ -166,7 +166,7 @@ open class ShopItem : RealmObject(), BaseObject {
|
||||||
item.notes = customization.notes
|
item.notes = customization.notes
|
||||||
item.value = customization.price ?: 0
|
item.value = customization.price ?: 0
|
||||||
item.path = customization.path
|
item.path = customization.path
|
||||||
item.unlockPath = customization.unlockPath
|
item.unlockPath = customization.unlockPath
|
||||||
item.pinType = customization.type
|
item.pinType = customization.type
|
||||||
if (customization.type == "background") {
|
if (customization.type == "background") {
|
||||||
item.purchaseType = "background"
|
item.purchaseType = "background"
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@ import io.realm.annotations.PrimaryKey
|
||||||
open class Group : RealmObject(), BaseMainObject {
|
open class Group : RealmObject(), BaseMainObject {
|
||||||
|
|
||||||
val isGroupPlan: Boolean
|
val isGroupPlan: Boolean
|
||||||
get() {
|
get() {
|
||||||
return purchased?.isActive == true
|
return purchased?.isActive == true
|
||||||
}
|
}
|
||||||
override val realmClass: Class<Group>
|
override val realmClass: Class<Group>
|
||||||
get() = Group::class.java
|
get() = Group::class.java
|
||||||
override val primaryIdentifier: String?
|
override val primaryIdentifier: String?
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import com.habitrpg.android.habitica.R
|
||||||
@io.realm.annotations.RealmClass(embedded = true)
|
@io.realm.annotations.RealmClass(embedded = true)
|
||||||
open class Days() : io.realm.RealmObject(), Parcelable {
|
open class Days() : io.realm.RealmObject(), Parcelable {
|
||||||
val isEveryDay: Boolean
|
val isEveryDay: Boolean
|
||||||
get() = m && t && w && th && f && s && su
|
get() = m && t && w && th && f && s && su
|
||||||
val isOnlyWeekdays: Boolean
|
val isOnlyWeekdays: Boolean
|
||||||
get() = m && t && w && th && f && !s && !su
|
get() = m && t && w && th && f && !s && !su
|
||||||
val isOnlyWeekends: Boolean
|
val isOnlyWeekends: Boolean
|
||||||
|
|
@ -66,4 +66,4 @@ open class Days() : io.realm.RealmObject(), Parcelable {
|
||||||
return arrayOfNulls(size)
|
return arrayOfNulls(size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,6 @@ open class Task : RealmObject, BaseMainObject, Parcelable, BaseTask {
|
||||||
.equals(ZonedDateTime.now().withZoneSameLocal(ZoneId.systemDefault()).toLocalDate())
|
.equals(ZonedDateTime.now().withZoneSameLocal(ZoneId.systemDefault()).toLocalDate())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Needed for offline creating/updating
|
// Needed for offline creating/updating
|
||||||
var isSaving: Boolean = false
|
var isSaving: Boolean = false
|
||||||
var hasErrored: 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 now = ZonedDateTime.now().withZoneSameLocal(ZoneId.systemDefault())?.toInstant()
|
||||||
val nextDate = nextDue?.firstOrNull()
|
val nextDate = nextDue?.firstOrNull()
|
||||||
|
|
||||||
//If task !isDisplayedActive or if isDisplayedActive but reminder passed,
|
// If task !isDisplayedActive or if isDisplayedActive but reminder passed,
|
||||||
//set a updated reminder with nextDate
|
// set a updated reminder with nextDate
|
||||||
return if (nextDate != null && (!isDisplayedActive || remindersItem.getLocalZonedDateTimeInstant()?.isBefore(now) == true)) {
|
return if (nextDate != null && (!isDisplayedActive || remindersItem.getLocalZonedDateTimeInstant()?.isBefore(now) == true)) {
|
||||||
val nextDueCalendar = GregorianCalendar()
|
val nextDueCalendar = GregorianCalendar()
|
||||||
nextDueCalendar.time = nextDate
|
nextDueCalendar.time = nextDate
|
||||||
parse(oldTime)
|
parse(oldTime)
|
||||||
?.withYear(nextDueCalendar.get(Calendar.YEAR))
|
?.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))
|
?.withDayOfMonth(nextDueCalendar.get(Calendar.DAY_OF_MONTH))
|
||||||
} else {
|
} else {
|
||||||
return parse(oldTime)
|
return parse(oldTime)
|
||||||
|
|
@ -392,7 +391,7 @@ open class Task : RealmObject, BaseMainObject, Parcelable, BaseTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isBeingEdited(task: Task): Boolean {
|
fun isBeingEdited(task: Task): Boolean {
|
||||||
|
|
||||||
when {
|
when {
|
||||||
text != task.text -> return true
|
text != task.text -> return true
|
||||||
notes != task.notes -> return true
|
notes != task.notes -> return true
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import io.realm.annotations.RealmClass
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
@RealmClass(embedded = true)
|
@RealmClass(embedded = true)
|
||||||
open class GroupAssignedDetails: RealmObject(), BaseObject {
|
open class GroupAssignedDetails : RealmObject(), BaseObject {
|
||||||
var assignedDate: Date? = null
|
var assignedDate: Date? = null
|
||||||
var assignedUsername: String? = null
|
var assignedUsername: String? = null
|
||||||
var assignedUserID: String? = null
|
var assignedUserID: String? = null
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,4 @@ package com.habitrpg.android.habitica.models.tasks
|
||||||
|
|
||||||
class TaskList {
|
class TaskList {
|
||||||
var tasks: MutableMap<String, Task> = mutableMapOf()
|
var tasks: MutableMap<String, Task> = mutableMapOf()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package com.habitrpg.android.habitica.models.user
|
||||||
import com.habitrpg.android.habitica.models.BaseObject
|
import com.habitrpg.android.habitica.models.BaseObject
|
||||||
import io.realm.RealmObject
|
import io.realm.RealmObject
|
||||||
|
|
||||||
open class Permissions: RealmObject(), BaseObject {
|
open class Permissions : RealmObject(), BaseObject {
|
||||||
var userSupport: Boolean = false
|
var userSupport: Boolean = false
|
||||||
var fullAccess: Boolean = false
|
var fullAccess: Boolean = false
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,17 +56,17 @@ open class SubscriptionPlan : RealmObject(), BaseObject {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
val subMonthCount: Int
|
val subMonthCount: Int
|
||||||
get() {
|
get() {
|
||||||
return when (planId) {
|
return when (planId) {
|
||||||
"basic_earned" -> 1
|
"basic_earned" -> 1
|
||||||
"basic_3mo" -> 3
|
"basic_3mo" -> 3
|
||||||
"basic_6mo" -> 6
|
"basic_6mo" -> 6
|
||||||
"google_6mo" -> 6
|
"google_6mo" -> 6
|
||||||
"basic_12mo" -> 12
|
"basic_12mo" -> 12
|
||||||
"group_plan_auto" -> 1
|
"group_plan_auto" -> 1
|
||||||
else -> 0
|
else -> 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
val monthsUntilNextHourglass: Int
|
val monthsUntilNextHourglass: Int
|
||||||
get() {
|
get() {
|
||||||
|
|
|
||||||
|
|
@ -5,4 +5,4 @@ enum class UserQuestStatus {
|
||||||
QUEST_COLLECT,
|
QUEST_COLLECT,
|
||||||
QUEST_BOSS,
|
QUEST_BOSS,
|
||||||
QUEST_UNKNOWN
|
QUEST_UNKNOWN
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import io.realm.RealmObject
|
||||||
import io.realm.annotations.RealmClass
|
import io.realm.annotations.RealmClass
|
||||||
|
|
||||||
@RealmClass(embedded = true)
|
@RealmClass(embedded = true)
|
||||||
open class UserTaskPreferences: RealmObject(), BaseObject {
|
open class UserTaskPreferences : RealmObject(), BaseObject {
|
||||||
var confirmScoreNotes: Boolean = false
|
var confirmScoreNotes: Boolean = false
|
||||||
var mirrorGroupTasks: RealmList<String> = RealmList()
|
var mirrorGroupTasks: RealmList<String> = RealmList()
|
||||||
var groupByChallenge: Boolean = false
|
var groupByChallenge: Boolean = false
|
||||||
|
|
|
||||||
|
|
@ -47,4 +47,4 @@ class UserModule {
|
||||||
companion object {
|
companion object {
|
||||||
const val NAMED_USER_ID = "userId"
|
const val NAMED_USER_ID = "userId"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,4 +57,4 @@ class DeviceCommunicationService : WearableListenerService() {
|
||||||
"${hostConfig.userID}:${hostConfig.apiKey}".toByteArray()
|
"${hostConfig.userID}:${hostConfig.apiKey}".toByteArray()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import com.habitrpg.android.habitica.databinding.WidgetConfigureAddTaskBinding
|
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.android.habitica.widget.AddTaskWidgetProvider
|
||||||
|
import com.habitrpg.shared.habitica.models.tasks.TaskType
|
||||||
|
|
||||||
class AddTaskWidgetActivity : AppCompatActivity() {
|
class AddTaskWidgetActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,7 @@ class ArmoireActivity : BaseActivity() {
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
binding.titleView.text = "+${value} ${binding.titleView.text}"
|
binding.titleView.text = "+$value ${binding.titleView.text}"
|
||||||
binding.subtitleView.text = getString(R.string.armoireExp)
|
binding.subtitleView.text = getString(R.string.armoireExp)
|
||||||
binding.iconView.setImageResource(R.drawable.armoire_experience)
|
binding.iconView.setImageResource(R.drawable.armoire_experience)
|
||||||
val layoutParams = RelativeLayout.LayoutParams(108.dpToPx(this), 122.dpToPx(this))
|
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.Intent
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.content.res.Resources
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
|
@ -40,7 +38,6 @@ import com.habitrpg.common.habitica.extensions.isUsingNightModeResources
|
||||||
import com.habitrpg.common.habitica.helpers.LanguageHelper
|
import com.habitrpg.common.habitica.helpers.LanguageHelper
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.Locale
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
abstract class BaseActivity : AppCompatActivity() {
|
abstract class BaseActivity : AppCompatActivity() {
|
||||||
|
|
@ -96,12 +93,12 @@ abstract class BaseActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
lifecycleScope.launchCatching {
|
lifecycleScope.launchCatching {
|
||||||
notificationsManager.displayNotificationEvents.collect {
|
notificationsManager.displayNotificationEvents.collect {
|
||||||
if (ShowNotificationInteractor(this@BaseActivity, lifecycleScope).handleNotification(it)) {
|
if (ShowNotificationInteractor(this@BaseActivity, lifecycleScope).handleNotification(it)) {
|
||||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||||
userRepository.retrieveUser(false, true)
|
userRepository.retrieveUser(false, true)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -252,4 +249,4 @@ abstract class BaseActivity : AppCompatActivity() {
|
||||||
overridePendingTransition(R.anim.activity_fade_in, R.anim.activity_fade_out)
|
overridePendingTransition(R.anim.activity_fade_in, R.anim.activity_fade_out)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -198,7 +198,8 @@ class BirthdayActivity : BaseActivity() {
|
||||||
@Composable
|
@Composable
|
||||||
fun BirthdayTitle(text: String) {
|
fun BirthdayTitle(text: String) {
|
||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically, modifier = Modifier
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(top = 20.dp, bottom = 8.dp)
|
.padding(top = 20.dp, bottom = 8.dp)
|
||||||
) {
|
) {
|
||||||
|
|
@ -259,7 +260,8 @@ fun BirthdayActivityView(
|
||||||
scaffoldState = scaffoldState
|
scaffoldState = scaffoldState
|
||||||
) { padding ->
|
) { padding ->
|
||||||
Column(
|
Column(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = Modifier
|
||||||
.background(
|
.background(
|
||||||
Brush.verticalGradient(
|
Brush.verticalGradient(
|
||||||
Pair(0.0f, colorResource(id = R.color.brand_300)),
|
Pair(0.0f, colorResource(id = R.color.brand_300)),
|
||||||
|
|
@ -291,7 +293,8 @@ fun BirthdayActivityView(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Column(
|
Column(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = Modifier
|
||||||
.padding(horizontal = 20.dp)
|
.padding(horizontal = 20.dp)
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
) {
|
) {
|
||||||
|
|
@ -388,16 +391,19 @@ fun BirthdayActivityView(
|
||||||
} else if (isPurchasing) {
|
} else if (isPurchasing) {
|
||||||
CircularProgressIndicator()
|
CircularProgressIndicator()
|
||||||
} else {
|
} else {
|
||||||
Text(buildAnnotatedString {
|
Text(
|
||||||
append("Buy for ")
|
buildAnnotatedString {
|
||||||
withStyle(SpanStyle(fontWeight = FontWeight.Bold)) {
|
append("Buy for ")
|
||||||
append(price)
|
withStyle(SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||||
}
|
append(price)
|
||||||
append(" or ")
|
}
|
||||||
withStyle(SpanStyle(fontWeight = FontWeight.Bold)) {
|
append(" or ")
|
||||||
append("60 Gems")
|
withStyle(SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||||
}
|
append("60 Gems")
|
||||||
}, color = Color.White)
|
}
|
||||||
|
},
|
||||||
|
color = Color.White
|
||||||
|
)
|
||||||
HabiticaButton(
|
HabiticaButton(
|
||||||
Color.White,
|
Color.White,
|
||||||
colorResource(R.color.brand_200),
|
colorResource(R.color.brand_200),
|
||||||
|
|
@ -557,7 +563,8 @@ fun PotionGrid() {
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
model = DataBindingUtils.BASE_IMAGE_URL + DataBindingUtils.getFullFilename(
|
model = DataBindingUtils.BASE_IMAGE_URL + DataBindingUtils.getFullFilename(
|
||||||
"Pet_HatchingPotion_$potion"
|
"Pet_HatchingPotion_$potion"
|
||||||
), null, Modifier.size(68.dp)
|
),
|
||||||
|
null, Modifier.size(68.dp)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -616,11 +623,14 @@ fun HabiticaButton(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
content: @Composable () -> Unit
|
content: @Composable () -> Unit
|
||||||
) {
|
) {
|
||||||
Box(contentAlignment = Alignment.Center, modifier = modifier
|
Box(
|
||||||
.background(background, HabiticaTheme.shapes.medium)
|
contentAlignment = Alignment.Center,
|
||||||
.clickable { onClick() }
|
modifier = modifier
|
||||||
.fillMaxWidth()
|
.background(background, HabiticaTheme.shapes.medium)
|
||||||
.padding(8.dp)) {
|
.clickable { onClick() }
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(8.dp)
|
||||||
|
) {
|
||||||
ProvideTextStyle(
|
ProvideTextStyle(
|
||||||
value = TextStyle(
|
value = TextStyle(
|
||||||
fontSize = 18.sp,
|
fontSize = 18.sp,
|
||||||
|
|
@ -640,4 +650,4 @@ private fun Preview() {
|
||||||
val scaffoldState = rememberScaffoldState()
|
val scaffoldState = rememberScaffoldState()
|
||||||
BirthdayActivityView(scaffoldState, true, false, false, "", Date(), Date(), {
|
BirthdayActivityView(scaffoldState, true, false, false, "", Date(), Date(), {
|
||||||
}, {}) {}
|
}, {}) {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -396,15 +396,15 @@ class ChallengeFormActivity : BaseActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.createChallengeTaskList.addOnItemTouchListener(object :
|
binding.createChallengeTaskList.addOnItemTouchListener(object :
|
||||||
androidx.recyclerview.widget.RecyclerView.SimpleOnItemTouchListener() {
|
androidx.recyclerview.widget.RecyclerView.SimpleOnItemTouchListener() {
|
||||||
override fun onInterceptTouchEvent(
|
override fun onInterceptTouchEvent(
|
||||||
rv: androidx.recyclerview.widget.RecyclerView,
|
rv: androidx.recyclerview.widget.RecyclerView,
|
||||||
e: MotionEvent
|
e: MotionEvent
|
||||||
): Boolean {
|
): Boolean {
|
||||||
// Stop only scrolling.
|
// Stop only scrolling.
|
||||||
return rv.scrollState == androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_DRAGGING
|
return rv.scrollState == androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_DRAGGING
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
binding.createChallengeTaskList.adapter = challengeTasks
|
binding.createChallengeTaskList.adapter = challengeTasks
|
||||||
binding.createChallengeTaskList.layoutManager =
|
binding.createChallengeTaskList.layoutManager =
|
||||||
androidx.recyclerview.widget.LinearLayoutManager(this)
|
androidx.recyclerview.widget.LinearLayoutManager(this)
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import com.plattysoft.leonids.ParticleSystem
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class DeathActivity: BaseActivity() {
|
class DeathActivity : BaseActivity() {
|
||||||
private lateinit var binding: ActivityDeathBinding
|
private lateinit var binding: ActivityDeathBinding
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
|
|
@ -109,12 +109,11 @@ class DeathActivity: BaseActivity() {
|
||||||
.setScaleRange(0.5f, 0.8f)
|
.setScaleRange(0.5f, 0.8f)
|
||||||
.setSpeedRange(0.01f, 0.03f)
|
.setSpeedRange(0.01f, 0.03f)
|
||||||
.setFadeOut(4000, AccelerateInterpolator())
|
.setFadeOut(4000, AccelerateInterpolator())
|
||||||
.setSpeedModuleAndAngleRange(0.01f, 0.03f, startAngle, startAngle+80)
|
.setSpeedModuleAndAngleRange(0.01f, 0.03f, startAngle, startAngle + 80)
|
||||||
.emit(binding.root.width / 2, positionArray[1] + (binding.heartView.height/2), 3, 6000)
|
.emit(binding.root.width / 2, positionArray[1] + (binding.heartView.height / 2), 3, 6000)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
moveTaskToBack(true)
|
moveTaskToBack(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,8 @@ import com.habitrpg.android.habitica.databinding.ActivityFixcharacterBinding
|
||||||
import com.habitrpg.android.habitica.extensions.setTintWith
|
import com.habitrpg.android.habitica.extensions.setTintWith
|
||||||
import com.habitrpg.android.habitica.models.user.Stats
|
import com.habitrpg.android.habitica.models.user.Stats
|
||||||
import com.habitrpg.android.habitica.models.user.User
|
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.viewmodels.MainUserViewModel
|
||||||
|
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class FixCharacterValuesActivity : BaseActivity() {
|
class FixCharacterValuesActivity : BaseActivity() {
|
||||||
|
|
|
||||||
|
|
@ -147,11 +147,11 @@ class FullProfileActivity : BaseActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun refresh() {
|
private suspend fun refresh() {
|
||||||
val member = socialRepository.retrieveMember(userID)
|
val member = socialRepository.retrieveMember(userID)
|
||||||
if (member != null) {
|
if (member != null) {
|
||||||
updateView(member)
|
updateView(member)
|
||||||
}
|
}
|
||||||
this@FullProfileActivity.member.value = member
|
this@FullProfileActivity.member.value = member
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
|
|
@ -174,21 +174,27 @@ class FullProfileActivity : BaseActivity() {
|
||||||
}
|
}
|
||||||
menu.setGroupVisible(R.id.admin_items, isModerator)
|
menu.setGroupVisible(R.id.admin_items, isModerator)
|
||||||
if (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(
|
||||||
R.string.unban_user
|
if (member.value?.authentication?.blocked == true) {
|
||||||
} else {
|
R.string.unban_user
|
||||||
R.string.ban_user
|
} else {
|
||||||
})
|
R.string.ban_user
|
||||||
menu.findItem(R.id.shadow_mute_user)?.title = getString(if (member.value?.flags?.chatShadowMuted == true) {
|
}
|
||||||
R.string.unshadowmute_user
|
)
|
||||||
} else {
|
menu.findItem(R.id.shadow_mute_user)?.title = getString(
|
||||||
R.string.shadow_mute_user
|
if (member.value?.flags?.chatShadowMuted == true) {
|
||||||
})
|
R.string.unshadowmute_user
|
||||||
menu.findItem(R.id.mute_user)?.title = getString(if (member.value?.flags?.chatRevoked == true) {
|
} else {
|
||||||
R.string.unmute_user
|
R.string.shadow_mute_user
|
||||||
} else {
|
}
|
||||||
R.string.mute_user
|
)
|
||||||
})
|
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)
|
return super.onCreateOptionsMenu(menu)
|
||||||
}
|
}
|
||||||
|
|
@ -357,7 +363,7 @@ class FullProfileActivity : BaseActivity() {
|
||||||
if (imageUrl == null || imageUrl.isEmpty()) {
|
if (imageUrl == null || imageUrl.isEmpty()) {
|
||||||
binding.profileImage.visibility = View.GONE
|
binding.profileImage.visibility = View.GONE
|
||||||
} else {
|
} else {
|
||||||
//binding.profileImage.load(imageUrl)
|
// binding.profileImage.load(imageUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
val blurbText = profile.blurb
|
val blurbText = profile.blurb
|
||||||
|
|
|
||||||
|
|
@ -81,10 +81,12 @@ class LoginActivity : BaseActivity() {
|
||||||
showValidationError(R.string.login_validation_error_fieldsmissing)
|
showValidationError(R.string.login_validation_error_fieldsmissing)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
lifecycleScope.launch(ExceptionHandler.coroutine {
|
lifecycleScope.launch(
|
||||||
hideProgress()
|
ExceptionHandler.coroutine {
|
||||||
ExceptionHandler.reportError(it)
|
hideProgress()
|
||||||
}) {
|
ExceptionHandler.reportError(it)
|
||||||
|
}
|
||||||
|
) {
|
||||||
val response = apiClient.connectUser(username, password)
|
val response = apiClient.connectUser(username, password)
|
||||||
if (response != null) {
|
if (response != null) {
|
||||||
handleAuthResponse(response)
|
handleAuthResponse(response)
|
||||||
|
|
@ -112,10 +114,12 @@ class LoginActivity : BaseActivity() {
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
lifecycleScope.launch(ExceptionHandler.coroutine {
|
lifecycleScope.launch(
|
||||||
hideProgress()
|
ExceptionHandler.coroutine {
|
||||||
ExceptionHandler.reportError(it)
|
hideProgress()
|
||||||
}) {
|
ExceptionHandler.reportError(it)
|
||||||
|
}
|
||||||
|
) {
|
||||||
val response = apiClient.registerUser(username, email, password, confirmPassword)
|
val response = apiClient.registerUser(username, email, password, confirmPassword)
|
||||||
if (response != null) {
|
if (response != null) {
|
||||||
handleAuthResponse(response)
|
handleAuthResponse(response)
|
||||||
|
|
|
||||||
|
|
@ -96,9 +96,11 @@ class ReportMessageActivity : BaseActivity() {
|
||||||
}
|
}
|
||||||
isReporting = true
|
isReporting = true
|
||||||
messageID?.let {
|
messageID?.let {
|
||||||
lifecycleScope.launch(ExceptionHandler.coroutine {
|
lifecycleScope.launch(
|
||||||
isReporting = false
|
ExceptionHandler.coroutine {
|
||||||
}) {
|
isReporting = false
|
||||||
|
}
|
||||||
|
) {
|
||||||
socialRepository.flagMessage(messageID ?: "", binding.additionalInfoEdittext.text.toString(), groupID)
|
socialRepository.flagMessage(messageID ?: "", binding.additionalInfoEdittext.text.toString(), groupID)
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -206,7 +206,6 @@ class SetupActivity : BaseActivity(), ViewPager.OnPageChangeListener {
|
||||||
|
|
||||||
override fun onPageScrollStateChanged(state: Int) = Unit
|
override fun onPageScrollStateChanged(state: Int) = Unit
|
||||||
|
|
||||||
|
|
||||||
private var hasCompleted = false
|
private var hasCompleted = false
|
||||||
private fun onUserReceived(user: User?) {
|
private fun onUserReceived(user: User?) {
|
||||||
if (completedSetup && !hasCompleted) {
|
if (completedSetup && !hasCompleted) {
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ class SkillTasksActivity : BaseActivity() {
|
||||||
else -> TaskType.TODO
|
else -> TaskType.TODO
|
||||||
}
|
}
|
||||||
fragment.onTaskSelection = {
|
fragment.onTaskSelection = {
|
||||||
taskSelected(it)
|
taskSelected(it)
|
||||||
}
|
}
|
||||||
viewFragmentsDictionary.put(position, fragment)
|
viewFragmentsDictionary.put(position, fragment)
|
||||||
return fragment
|
return fragment
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ class TaskFormActivity : BaseActivity() {
|
||||||
if (granted) {
|
if (granted) {
|
||||||
pushNotificationManager.addPushDeviceUsingStoredToken()
|
pushNotificationManager.addPushDeviceUsingStoredToken()
|
||||||
} else {
|
} 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)
|
val alert = HabiticaAlertDialog(this)
|
||||||
alert.setTitle(R.string.push_notification_system_settings_title)
|
alert.setTitle(R.string.push_notification_system_settings_title)
|
||||||
alert.setMessage(R.string.push_notification_system_settings_description)
|
alert.setMessage(R.string.push_notification_system_settings_description)
|
||||||
|
|
@ -340,7 +340,8 @@ class TaskFormActivity : BaseActivity() {
|
||||||
HabiticaTheme {
|
HabiticaTheme {
|
||||||
TaskDifficultySelector(
|
TaskDifficultySelector(
|
||||||
viewModel.taskDifficulty.value,
|
viewModel.taskDifficulty.value,
|
||||||
onSelect = { viewModel.taskDifficulty.value = it })
|
onSelect = { viewModel.taskDifficulty.value = it }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -351,32 +352,38 @@ class TaskFormActivity : BaseActivity() {
|
||||||
viewModel.habitScoringPositive.value,
|
viewModel.habitScoringPositive.value,
|
||||||
viewModel.habitScoringNegative.value,
|
viewModel.habitScoringNegative.value,
|
||||||
{ viewModel.habitScoringPositive.value = !viewModel.habitScoringPositive.value },
|
{ viewModel.habitScoringPositive.value = !viewModel.habitScoringPositive.value },
|
||||||
{ viewModel.habitScoringNegative.value = !viewModel.habitScoringNegative.value })
|
{ viewModel.habitScoringNegative.value = !viewModel.habitScoringNegative.value }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.habitResetStreakButtons.setContent {
|
binding.habitResetStreakButtons.setContent {
|
||||||
HabiticaTheme {
|
HabiticaTheme {
|
||||||
TaskFormSelector(
|
TaskFormSelector(
|
||||||
viewModel.habitResetOption.value, listOf(
|
viewModel.habitResetOption.value,
|
||||||
|
listOf(
|
||||||
LabeledValue(getString(R.string.repeat_daily), HabitResetOption.DAILY),
|
LabeledValue(getString(R.string.repeat_daily), HabitResetOption.DAILY),
|
||||||
LabeledValue(getString(R.string.weekly), HabitResetOption.WEEKLY),
|
LabeledValue(getString(R.string.weekly), HabitResetOption.WEEKLY),
|
||||||
LabeledValue(getString(R.string.monthly), HabitResetOption.MONTHLY)
|
LabeledValue(getString(R.string.monthly), HabitResetOption.MONTHLY)
|
||||||
), { viewModel.habitResetOption.value = it }, columnSize = 3
|
),
|
||||||
|
{ viewModel.habitResetOption.value = it }, columnSize = 3
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
binding.statsSelector.setContent {
|
binding.statsSelector.setContent {
|
||||||
HabiticaTheme {
|
HabiticaTheme {
|
||||||
TaskFormSelector(viewModel.selectedAttribute.value, listOf(
|
TaskFormSelector(
|
||||||
LabeledValue(getString(R.string.strength), Attribute.STRENGTH),
|
viewModel.selectedAttribute.value,
|
||||||
LabeledValue(getString(R.string.constitution), Attribute.CONSTITUTION),
|
listOf(
|
||||||
LabeledValue(getString(R.string.intelligence), Attribute.INTELLIGENCE),
|
LabeledValue(getString(R.string.strength), Attribute.STRENGTH),
|
||||||
LabeledValue(getString(R.string.perception), Attribute.PERCEPTION)
|
LabeledValue(getString(R.string.constitution), Attribute.CONSTITUTION),
|
||||||
), { viewModel.selectedAttribute.value = it })
|
LabeledValue(getString(R.string.intelligence), Attribute.INTELLIGENCE),
|
||||||
|
LabeledValue(getString(R.string.perception), Attribute.PERCEPTION)
|
||||||
|
),
|
||||||
|
{ viewModel.selectedAttribute.value = it }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -240,7 +240,8 @@ fun TaskSummaryView(viewModel: TaskSummaryViewModel) {
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
) {
|
) {
|
||||||
Image(HabiticaIconsHelper.imageOfGold().asImageBitmap(), null)
|
Image(HabiticaIconsHelper.imageOfGold().asImageBitmap(), null)
|
||||||
Text("${task?.value}",
|
Text(
|
||||||
|
"${task?.value}",
|
||||||
fontSize = 16.sp,
|
fontSize = 16.sp,
|
||||||
fontWeight = FontWeight.Medium,
|
fontWeight = FontWeight.Medium,
|
||||||
color = darkestColor
|
color = darkestColor
|
||||||
|
|
@ -285,7 +286,8 @@ fun TaskSummaryView(viewModel: TaskSummaryViewModel) {
|
||||||
for (item in task?.group?.assignedUsersDetail ?: emptyList()) {
|
for (item in task?.group?.assignedUsersDetail ?: emptyList()) {
|
||||||
val member = viewModel.getMember(item.assignedUserID).collectAsState(null)
|
val member = viewModel.getMember(item.assignedUserID).collectAsState(null)
|
||||||
UserRow(
|
UserRow(
|
||||||
item.assignedUsername ?: "", member.value, Modifier
|
item.assignedUsername ?: "", member.value,
|
||||||
|
Modifier
|
||||||
.padding(vertical = 4.dp)
|
.padding(vertical = 4.dp)
|
||||||
.background(
|
.background(
|
||||||
HabiticaTheme.colors.windowBackgroundFor(task),
|
HabiticaTheme.colors.windowBackgroundFor(task),
|
||||||
|
|
@ -295,9 +297,11 @@ fun TaskSummaryView(viewModel: TaskSummaryViewModel) {
|
||||||
.heightIn(min = 24.dp)
|
.heightIn(min = 24.dp)
|
||||||
.fillMaxWidth(),
|
.fillMaxWidth(),
|
||||||
color = darkestColor,
|
color = darkestColor,
|
||||||
extraContent = if (item.completed) ({
|
extraContent = if (item.completed) (
|
||||||
CompletedAt(item.completedDate)
|
{
|
||||||
}) else null
|
CompletedAt(item.completedDate)
|
||||||
|
}
|
||||||
|
) else null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
task?.group?.assignedUsersDetail?.find { it.assignedUserID == viewModel.userViewModel.userID }
|
task?.group?.assignedUsersDetail?.find { it.assignedUserID == viewModel.userViewModel.userID }
|
||||||
|
|
@ -339,4 +343,4 @@ private fun String.makeBoldComposable(): AnnotatedString {
|
||||||
@Composable
|
@Composable
|
||||||
private fun TaskSummaryViewPreview() {
|
private fun TaskSummaryViewPreview() {
|
||||||
TaskSummaryView(TaskSummaryViewModel(""))
|
TaskSummaryView(TaskSummaryViewModel(""))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,9 @@ import com.habitrpg.android.habitica.databinding.AchievementSectionHeaderBinding
|
||||||
import com.habitrpg.android.habitica.extensions.inflate
|
import com.habitrpg.android.habitica.extensions.inflate
|
||||||
import com.habitrpg.android.habitica.models.Achievement
|
import com.habitrpg.android.habitica.models.Achievement
|
||||||
import com.habitrpg.android.habitica.models.QuestAchievement
|
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.extensions.loadImage
|
||||||
import com.habitrpg.common.habitica.views.PixelArtView
|
import com.habitrpg.common.habitica.views.PixelArtView
|
||||||
import com.habitrpg.android.habitica.ui.views.dialogs.AchievementDetailDialog
|
|
||||||
|
|
||||||
class AchievementsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
class AchievementsAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,9 @@ class CustomizationEquipmentRecyclerViewAdapter : androidx.recyclerview.widget.R
|
||||||
var equipmentList: MutableList<Equipment> =
|
var equipmentList: MutableList<Equipment> =
|
||||||
ArrayList()
|
ArrayList()
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
var activeEquipment: String? = null
|
var activeEquipment: String? = null
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
|
|
@ -119,7 +119,8 @@ class CustomizationEquipmentRecyclerViewAdapter : androidx.recyclerview.widget.R
|
||||||
priceLabel?.text = itemValue.toString()
|
priceLabel?.text = itemValue.toString()
|
||||||
|
|
||||||
(dialogContent.findViewById<View>(R.id.gem_icon) as? ImageView)?.setImageBitmap(
|
(dialogContent.findViewById<View>(R.id.gem_icon) as? ImageView)?.setImageBitmap(
|
||||||
HabiticaIconsHelper.imageOfGem())
|
HabiticaIconsHelper.imageOfGem()
|
||||||
|
)
|
||||||
|
|
||||||
val dialog = HabiticaAlertDialog(itemView.context)
|
val dialog = HabiticaAlertDialog(itemView.context)
|
||||||
dialog.addButton(R.string.purchase_button, true) { _, _ ->
|
dialog.addButton(R.string.purchase_button, true) { _, _ ->
|
||||||
|
|
@ -153,4 +154,4 @@ class CustomizationEquipmentRecyclerViewAdapter : androidx.recyclerview.widget.R
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -113,9 +113,15 @@ class CustomizationRecyclerViewAdapter() : androidx.recyclerview.widget.Recycler
|
||||||
val isOwned = ownedCustomizations.contains(customization.id)
|
val isOwned = ownedCustomizations.contains(customization.id)
|
||||||
val isUsable = customization.isUsable(isOwned)
|
val isUsable = customization.isUsable(isOwned)
|
||||||
if (customization.availableFrom != null || customization.availableUntil != null) {
|
if (customization.availableFrom != null || customization.availableUntil != null) {
|
||||||
if (((customization.availableFrom?.compareTo(today)
|
if ((
|
||||||
?: 0) > 0 || (customization.availableUntil?.compareTo(today)
|
(
|
||||||
?: 0) < 0) && !isUsable
|
customization.availableFrom?.compareTo(today)
|
||||||
|
?: 0
|
||||||
|
) > 0 || (
|
||||||
|
customization.availableUntil?.compareTo(today)
|
||||||
|
?: 0
|
||||||
|
) < 0
|
||||||
|
) && !isUsable
|
||||||
) {
|
) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -218,7 +224,7 @@ class CustomizationRecyclerViewAdapter() : androidx.recyclerview.widget.Recycler
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (customization?.type == "background"){
|
if (customization?.type == "background") {
|
||||||
val alert = HabiticaAlertDialog(context = itemView.context)
|
val alert = HabiticaAlertDialog(context = itemView.context)
|
||||||
val purchasedCustomizationView: View = LayoutInflater.from(itemView.context).inflate(R.layout.purchased_equip_dialog, null)
|
val purchasedCustomizationView: View = LayoutInflater.from(itemView.context).inflate(R.layout.purchased_equip_dialog, null)
|
||||||
val layerMap = EnumMap<AvatarView.LayerType, String>(AvatarView.LayerType::class.java)
|
val layerMap = EnumMap<AvatarView.LayerType, String>(AvatarView.LayerType::class.java)
|
||||||
|
|
@ -263,12 +269,12 @@ class CustomizationRecyclerViewAdapter() : androidx.recyclerview.widget.Recycler
|
||||||
var additionalSetItems: List<Customization>? = null
|
var additionalSetItems: List<Customization>? = null
|
||||||
|
|
||||||
var buttonWidth: Int
|
var buttonWidth: Int
|
||||||
get() = binding.purchaseSetButton.width
|
get() = binding.purchaseSetButton.width
|
||||||
set(value) {
|
set(value) {
|
||||||
val params = binding.purchaseSetButton.layoutParams
|
val params = binding.purchaseSetButton.layoutParams
|
||||||
params.width = value
|
params.width = value
|
||||||
binding.purchaseSetButton.layoutParams = params
|
binding.purchaseSetButton.layoutParams = params
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
binding.purchaseSetButton.setOnClickListener(this)
|
binding.purchaseSetButton.setOnClickListener(this)
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,6 @@ class NavigationDrawerAdapter(tintColor: Int, backgroundTintColor: Int) : Recycl
|
||||||
|
|
||||||
private fun getItem(position: Int) = items.filter { it.isVisible }[position]
|
private fun getItem(position: Int) = items.filter { it.isVisible }[position]
|
||||||
|
|
||||||
|
|
||||||
override fun getItemCount(): Int = items.count { it.isVisible }
|
override fun getItemCount(): Int = items.count { it.isVisible }
|
||||||
|
|
||||||
override fun getItemViewType(position: Int): Int {
|
override fun getItemViewType(position: Int): Int {
|
||||||
|
|
|
||||||
|
|
@ -99,11 +99,11 @@ class ItemRecyclerAdapter(val context: Context) : BaseRecyclerViewAdapter<OwnedI
|
||||||
binding.ownedTextView.text = ownedItem.numberOwned.toString()
|
binding.ownedTextView.text = ownedItem.numberOwned.toString()
|
||||||
|
|
||||||
val disabled = if (isHatching) {
|
val disabled = if (isHatching) {
|
||||||
!this.canHatch
|
!this.canHatch
|
||||||
} else false
|
} else false
|
||||||
val imageName = if (item != null) {
|
val imageName = if (item != null) {
|
||||||
getImageName(item = item) }
|
getImageName(item = item)
|
||||||
else {
|
} else {
|
||||||
getImageName(ownedItem = ownedItem)
|
getImageName(ownedItem = ownedItem)
|
||||||
}
|
}
|
||||||
binding.imageView.loadImage(imageName)
|
binding.imageView.loadImage(imageName)
|
||||||
|
|
@ -130,7 +130,7 @@ class ItemRecyclerAdapter(val context: Context) : BaseRecyclerViewAdapter<OwnedI
|
||||||
"inventory_quest_scroll_" + item.key
|
"inventory_quest_scroll_" + item.key
|
||||||
}
|
}
|
||||||
is SpecialItem -> {
|
is SpecialItem -> {
|
||||||
//Mystery Item (Inventory Present)
|
// Mystery Item (Inventory Present)
|
||||||
val sdf = SimpleDateFormat("MM", Locale.getDefault())
|
val sdf = SimpleDateFormat("MM", Locale.getDefault())
|
||||||
val month = sdf.format(Date())
|
val month = sdf.format(Date())
|
||||||
"inventory_present_$month"
|
"inventory_present_$month"
|
||||||
|
|
@ -153,8 +153,8 @@ class ItemRecyclerAdapter(val context: Context) : BaseRecyclerViewAdapter<OwnedI
|
||||||
val menu = BottomSheetMenu(context)
|
val menu = BottomSheetMenu(context)
|
||||||
menu.setTitle(item?.text)
|
menu.setTitle(item?.text)
|
||||||
val imageName = if (item != null) {
|
val imageName = if (item != null) {
|
||||||
getImageName(item = item) }
|
getImageName(item = item)
|
||||||
else {
|
} else {
|
||||||
getImageName(ownedItem = ownedItem)
|
getImageName(ownedItem = ownedItem)
|
||||||
}
|
}
|
||||||
menu.setImage(imageName)
|
menu.setImage(imageName)
|
||||||
|
|
|
||||||
|
|
@ -43,14 +43,13 @@ class StableRecyclerAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
field = value
|
field = value
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
var onEquip: ((String) -> Unit)? = null
|
var onEquip: ((String) -> Unit)? = null
|
||||||
private var existingMounts: List<Mount>? = null
|
private var existingMounts: List<Mount>? = null
|
||||||
private var ownedMounts: Map<String, OwnedMount>? = null
|
private var ownedMounts: Map<String, OwnedMount>? = null
|
||||||
private var ownedItems: Map<String, OwnedItem>? = null
|
private var ownedItems: Map<String, OwnedItem>? = null
|
||||||
private var ownsSaddles: Boolean = false
|
private var ownsSaddles: Boolean = false
|
||||||
private var itemList: List<Any> = ArrayList()
|
private var itemList: List<Any> = ArrayList()
|
||||||
|
|
||||||
|
|
||||||
private fun canRaiseToMount(pet: Pet): Boolean {
|
private fun canRaiseToMount(pet: Pet): Boolean {
|
||||||
if (pet.type == "special") return false
|
if (pet.type == "special") return false
|
||||||
for (mount in existingMounts ?: emptyList()) {
|
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.extensions.inflate
|
||||||
import com.habitrpg.android.habitica.models.Achievement
|
import com.habitrpg.android.habitica.models.Achievement
|
||||||
import com.habitrpg.android.habitica.ui.activities.MainActivity
|
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.viewHolders.SectionViewHolder
|
||||||
import com.habitrpg.android.habitica.ui.views.dialogs.AchievementDetailDialog
|
import com.habitrpg.android.habitica.ui.views.dialogs.AchievementDetailDialog
|
||||||
|
import com.habitrpg.common.habitica.extensions.loadImage
|
||||||
|
|
||||||
class AchievementProfileAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
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.fragments.social.challenges.ChallengeFilterOptions
|
||||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||||
import com.habitrpg.common.habitica.helpers.EmojiParser
|
import com.habitrpg.common.habitica.helpers.EmojiParser
|
||||||
|
|
||||||
import io.realm.OrderedRealmCollection
|
import io.realm.OrderedRealmCollection
|
||||||
|
|
||||||
class ChallengesListViewAdapter(
|
class ChallengesListViewAdapter(
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,13 @@ class DailiesRecyclerViewHolder(layoutResource: Int, viewModel: TasksViewModel)
|
||||||
getContentView(parent), { task, direction -> taskScoreEvents?.invoke(task, direction) },
|
getContentView(parent), { task, direction -> taskScoreEvents?.invoke(task, direction) },
|
||||||
{ task, item -> checklistItemScoreEvents?.invoke(task, item) },
|
{ task, item -> checklistItemScoreEvents?.invoke(task, item) },
|
||||||
{
|
{
|
||||||
task ->
|
task ->
|
||||||
taskOpenEvents?.invoke(task.first, task.second)
|
taskOpenEvents?.invoke(task.first, task.second)
|
||||||
}, {
|
}, {
|
||||||
task ->
|
task ->
|
||||||
brokenTaskEvents?.invoke(task)
|
brokenTaskEvents?.invoke(task)
|
||||||
}, viewModel)
|
}, viewModel
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
super.onCreateViewHolder(parent, viewType)
|
super.onCreateViewHolder(parent, viewType)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,13 @@ class HabitsRecyclerViewAdapter(layoutResource: Int, viewModel: TasksViewModel)
|
||||||
HabitViewHolder(
|
HabitViewHolder(
|
||||||
getContentView(parent), { task, direction -> taskScoreEvents?.invoke(task, direction) },
|
getContentView(parent), { task, direction -> taskScoreEvents?.invoke(task, direction) },
|
||||||
{
|
{
|
||||||
task ->
|
task ->
|
||||||
taskOpenEvents?.invoke(task.first, task.second)
|
taskOpenEvents?.invoke(task.first, task.second)
|
||||||
}, {
|
}, {
|
||||||
task ->
|
task ->
|
||||||
brokenTaskEvents?.invoke(task)
|
brokenTaskEvents?.invoke(task)
|
||||||
}, viewModel)
|
}, viewModel
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
super.onCreateViewHolder(parent, viewType)
|
super.onCreateViewHolder(parent, viewType)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -73,9 +73,10 @@ class RewardsRecyclerViewAdapter(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ task -> taskOpenEvents?.invoke(task.first, task.second) }, {
|
{ task -> taskOpenEvents?.invoke(task.first, task.second) }, {
|
||||||
task ->
|
task ->
|
||||||
brokenTaskEvents?.invoke(task)
|
brokenTaskEvents?.invoke(task)
|
||||||
}, viewModel)
|
}, viewModel
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
val viewHolder = ShopItemViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.row_shopitem, parent, false))
|
val viewHolder = ShopItemViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.row_shopitem, parent, false))
|
||||||
viewHolder.purchaseCardAction = { purchaseCardEvents?.invoke(it) }
|
viewHolder.purchaseCardAction = { purchaseCardEvents?.invoke(it) }
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,13 @@ class TodosRecyclerViewAdapter(layoutResource: Int, viewModel: TasksViewModel) :
|
||||||
getContentView(parent), { task, direction -> taskScoreEvents?.invoke(task, direction) },
|
getContentView(parent), { task, direction -> taskScoreEvents?.invoke(task, direction) },
|
||||||
{ task, item -> checklistItemScoreEvents?.invoke(task, item) },
|
{ task, item -> checklistItemScoreEvents?.invoke(task, item) },
|
||||||
{
|
{
|
||||||
task ->
|
task ->
|
||||||
taskOpenEvents?.invoke(task.first, task.second)
|
taskOpenEvents?.invoke(task.first, task.second)
|
||||||
}, {
|
}, {
|
||||||
task ->
|
task ->
|
||||||
brokenTaskEvents?.invoke(task)
|
brokenTaskEvents?.invoke(task)
|
||||||
}, viewModel)
|
}, viewModel
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
super.onCreateViewHolder(parent, viewType)
|
super.onCreateViewHolder(parent, viewType)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -97,9 +97,11 @@ class AchievementsFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding
|
||||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||||
userRepository.getAchievements().combine(userRepository.getQuestAchievements()) { achievements, questAchievements ->
|
userRepository.getAchievements().combine(userRepository.getQuestAchievements()) { achievements, questAchievements ->
|
||||||
return@combine Pair(achievements, questAchievements)
|
return@combine Pair(achievements, questAchievements)
|
||||||
}.combine(userRepository.getQuestAchievements()
|
}.combine(
|
||||||
.map { it.mapNotNull { achievement -> achievement.questKey } }
|
userRepository.getQuestAchievements()
|
||||||
.map { inventoryRepository.getQuestContent(it).firstOrNull() }) { achievements, content ->
|
.map { it.mapNotNull { achievement -> achievement.questKey } }
|
||||||
|
.map { inventoryRepository.getQuestContent(it).firstOrNull() }
|
||||||
|
) { achievements, content ->
|
||||||
Pair(achievements, content)
|
Pair(achievements, content)
|
||||||
}.collect {
|
}.collect {
|
||||||
val achievements = it.first.first
|
val achievements = it.first.first
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ abstract class BaseMainFragment<VB : ViewBinding> : BaseFragment<VB>() {
|
||||||
|
|
||||||
updateTabLayoutVisibility()
|
updateTabLayoutVisibility()
|
||||||
updateToolbarInteractivity()
|
updateToolbarInteractivity()
|
||||||
|
|
||||||
if (hidesToolbar) {
|
if (hidesToolbar) {
|
||||||
hideToolbar()
|
hideToolbar()
|
||||||
disableToolbarScrolling()
|
disableToolbarScrolling()
|
||||||
|
|
|
||||||
|
|
@ -141,14 +141,14 @@ class NavigationDrawerFragment : DialogFragment() {
|
||||||
initializeMenuItems()
|
initializeMenuItems()
|
||||||
|
|
||||||
adapter.itemSelectedEvents = {
|
adapter.itemSelectedEvents = {
|
||||||
setSelection(it.transitionId, it.bundle, true)
|
setSelection(it.transitionId, it.bundle, true)
|
||||||
}
|
}
|
||||||
adapter.promoClosedSubject = {
|
adapter.promoClosedSubject = {
|
||||||
sharedPreferences.edit {
|
sharedPreferences.edit {
|
||||||
putBoolean("hide$it", true)
|
putBoolean("hide$it", true)
|
||||||
}
|
|
||||||
updatePromo()
|
|
||||||
}
|
}
|
||||||
|
updatePromo()
|
||||||
|
}
|
||||||
|
|
||||||
lifecycleScope.launchCatching {
|
lifecycleScope.launchCatching {
|
||||||
contentRepository.getWorldState()
|
contentRepository.getWorldState()
|
||||||
|
|
@ -285,8 +285,10 @@ class NavigationDrawerFragment : DialogFragment() {
|
||||||
if (!user.hasClass && !hasSpecialItems) {
|
if (!user.hasClass && !hasSpecialItems) {
|
||||||
item.isVisible = false
|
item.isVisible = false
|
||||||
} else {
|
} else {
|
||||||
if ((user.stats?.lvl
|
if ((
|
||||||
?: 0) < HabiticaSnackbar.MIN_LEVEL_FOR_SKILLS && (!hasSpecialItems)
|
user.stats?.lvl
|
||||||
|
?: 0
|
||||||
|
) < HabiticaSnackbar.MIN_LEVEL_FOR_SKILLS && (!hasSpecialItems)
|
||||||
) {
|
) {
|
||||||
item.pillText = getString(R.string.unlock_lvl_11)
|
item.pillText = getString(R.string.unlock_lvl_11)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ class NewsFragment : BaseMainFragment<FragmentNewsBinding>() {
|
||||||
if (url?.contains("/static/new-stuff") == true) {
|
if (url?.contains("/static/new-stuff") == true) {
|
||||||
view?.loadUrl(url)
|
view?.loadUrl(url)
|
||||||
} else if (url != null) {
|
} else if (url != null) {
|
||||||
MainNavigationController.navigate(url)
|
MainNavigationController.navigate(url)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -80,22 +80,22 @@ class AvatarCustomizationFragment :
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
showsBackButton = true
|
showsBackButton = true
|
||||||
adapter.onCustomizationSelected = { customization ->
|
adapter.onCustomizationSelected = { customization ->
|
||||||
lifecycleScope.launchCatching {
|
lifecycleScope.launchCatching {
|
||||||
if (customization.identifier?.isNotBlank() != true) {
|
if (customization.identifier?.isNotBlank() != true) {
|
||||||
userRepository.useCustomization(customization.type ?: "", customization.category, activeCustomization ?: "")
|
userRepository.useCustomization(customization.type ?: "", customization.category, activeCustomization ?: "")
|
||||||
} else if (customization.type == "background" && ownedCustomizations.value.firstOrNull { it.key == customization.identifier } == null) {
|
} else if (customization.type == "background" && ownedCustomizations.value.firstOrNull { it.key == customization.identifier } == null) {
|
||||||
userRepository.unlockPath(customization)
|
userRepository.unlockPath(customization)
|
||||||
userRepository.retrieveUser(false, true, true)
|
userRepository.retrieveUser(false, true, true)
|
||||||
} else {
|
} else {
|
||||||
userRepository.useCustomization(
|
userRepository.useCustomization(
|
||||||
customization.type ?: "",
|
customization.type ?: "",
|
||||||
customization.category,
|
customization.category,
|
||||||
customization.identifier ?: ""
|
customization.identifier ?: ""
|
||||||
)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lifecycleScope.launchCatching {
|
lifecycleScope.launchCatching {
|
||||||
inventoryRepository.getInAppRewards()
|
inventoryRepository.getInAppRewards()
|
||||||
|
|
@ -195,31 +195,31 @@ class AvatarCustomizationFragment :
|
||||||
.combine(currentFilter) { customizations, filter -> Pair(customizations, filter) }
|
.combine(currentFilter) { customizations, filter -> Pair(customizations, filter) }
|
||||||
.combine(ownedCustomizations) { pair, ownedCustomizations -> Triple(pair.first, pair.second, ownedCustomizations) }
|
.combine(ownedCustomizations) { pair, ownedCustomizations -> Triple(pair.first, pair.second, ownedCustomizations) }
|
||||||
.collect { (customizations, filter, ownedCustomizations) ->
|
.collect { (customizations, filter, ownedCustomizations) ->
|
||||||
adapter.ownedCustomizations =
|
adapter.ownedCustomizations =
|
||||||
ownedCustomizations.map { it.key + "_" + it.type + "_" + it.category }
|
ownedCustomizations.map { it.key + "_" + it.type + "_" + it.category }
|
||||||
if (filter.isFiltering) {
|
if (filter.isFiltering) {
|
||||||
val displayedCustomizations = mutableListOf<Customization>()
|
val displayedCustomizations = mutableListOf<Customization>()
|
||||||
for (customization in customizations) {
|
for (customization in customizations) {
|
||||||
if (shouldSkip(filter, ownedCustomizations, customization)) continue
|
if (shouldSkip(filter, ownedCustomizations, customization)) continue
|
||||||
displayedCustomizations.add(customization)
|
displayedCustomizations.add(customization)
|
||||||
}
|
|
||||||
adapter.setCustomizations(
|
|
||||||
if (!filter.ascending) {
|
|
||||||
displayedCustomizations.reversed()
|
|
||||||
} else {
|
|
||||||
displayedCustomizations
|
|
||||||
}
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
adapter.setCustomizations(
|
|
||||||
if (!filter.ascending) {
|
|
||||||
customizations.reversed()
|
|
||||||
} else {
|
|
||||||
customizations
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
adapter.setCustomizations(
|
||||||
|
if (!filter.ascending) {
|
||||||
|
displayedCustomizations.reversed()
|
||||||
|
} else {
|
||||||
|
displayedCustomizations
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
adapter.setCustomizations(
|
||||||
|
if (!filter.ascending) {
|
||||||
|
customizations.reversed()
|
||||||
|
} else {
|
||||||
|
customizations
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (type == "hair" && (category == "beard" || category == "mustache")) {
|
if (type == "hair" && (category == "beard" || category == "mustache")) {
|
||||||
val otherCategory = if (category == "mustache") "beard" else "mustache"
|
val otherCategory = if (category == "mustache") "beard" else "mustache"
|
||||||
|
|
|
||||||
|
|
@ -148,4 +148,4 @@ class AvatarEquipmentFragment :
|
||||||
binding?.refreshLayout?.isRefreshing = false
|
binding?.refreshLayout?.isRefreshing = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,8 @@ import com.habitrpg.android.habitica.ui.views.equipment.EquipmentOverviewView
|
||||||
import kotlinx.coroutines.flow.firstOrNull
|
import kotlinx.coroutines.flow.firstOrNull
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
open class AvatarOverviewFragment : BaseMainFragment<FragmentComposeScrollingBinding>(),
|
open class AvatarOverviewFragment :
|
||||||
|
BaseMainFragment<FragmentComposeScrollingBinding>(),
|
||||||
AdapterView.OnItemSelectedListener {
|
AdapterView.OnItemSelectedListener {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
|
|
@ -71,16 +72,18 @@ open class AvatarOverviewFragment : BaseMainFragment<FragmentComposeScrollingBin
|
||||||
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
||||||
setContent {
|
setContent {
|
||||||
HabiticaTheme {
|
HabiticaTheme {
|
||||||
AvatarOverviewView(userViewModel,
|
AvatarOverviewView(
|
||||||
|
userViewModel,
|
||||||
showCustomization, !showCustomization,
|
showCustomization, !showCustomization,
|
||||||
battleGearWeapon.value?.twoHanded == true, costumeWeapon.value?.twoHanded == true,
|
battleGearWeapon.value?.twoHanded == true, costumeWeapon.value?.twoHanded == true,
|
||||||
{ type, category ->
|
{ type, category ->
|
||||||
displayCustomizationFragment(type, category)
|
displayCustomizationFragment(type, category)
|
||||||
}, { type, category ->
|
}, { type, category ->
|
||||||
displayAvatarEquipmentFragment(type, category)
|
displayAvatarEquipmentFragment(type, category)
|
||||||
}, { type, equipped, isCostume ->
|
}, { type, equipped, isCostume ->
|
||||||
displayEquipmentFragment(type, equipped, isCostume)
|
displayEquipmentFragment(type, equipped, isCostume)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -137,7 +140,8 @@ open class AvatarOverviewFragment : BaseMainFragment<FragmentComposeScrollingBin
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AvatarOverviewView(userViewModel: MainUserViewModel,
|
fun AvatarOverviewView(
|
||||||
|
userViewModel: MainUserViewModel,
|
||||||
showCustomization: Boolean = true,
|
showCustomization: Boolean = true,
|
||||||
showEquipment: Boolean = true,
|
showEquipment: Boolean = true,
|
||||||
battleGearTwoHanded: Boolean = false,
|
battleGearTwoHanded: Boolean = false,
|
||||||
|
|
@ -145,12 +149,13 @@ fun AvatarOverviewView(userViewModel: MainUserViewModel,
|
||||||
onCustomizationTap: (String, String?) -> Unit,
|
onCustomizationTap: (String, String?) -> Unit,
|
||||||
onAvatarEquipmentTap: (String, String?) -> Unit,
|
onAvatarEquipmentTap: (String, String?) -> Unit,
|
||||||
onEquipmentTap: (String, String?, Boolean) -> Unit
|
onEquipmentTap: (String, String?, Boolean) -> Unit
|
||||||
) {
|
) {
|
||||||
val user by userViewModel.user.observeAsState()
|
val user by userViewModel.user.observeAsState()
|
||||||
Column(
|
Column(
|
||||||
Modifier
|
Modifier
|
||||||
.padding(horizontal = 8.dp)
|
.padding(horizontal = 8.dp)
|
||||||
.padding(bottom = 16.dp)) {
|
.padding(bottom = 16.dp)
|
||||||
|
) {
|
||||||
if (showCustomization) {
|
if (showCustomization) {
|
||||||
Row(
|
Row(
|
||||||
Modifier.padding(horizontal = 12.dp, vertical = 15.dp),
|
Modifier.padding(horizontal = 12.dp, vertical = 15.dp),
|
||||||
|
|
@ -162,18 +167,21 @@ fun AvatarOverviewView(userViewModel: MainUserViewModel,
|
||||||
color = HabiticaTheme.colors.textSecondary
|
color = HabiticaTheme.colors.textSecondary
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
SegmentedControl(items = listOf(
|
SegmentedControl(
|
||||||
stringResource(R.string.avatar_size_slim), stringResource(
|
items = listOf(
|
||||||
R.string.avatar_size_broad
|
stringResource(R.string.avatar_size_slim),
|
||||||
)
|
stringResource(
|
||||||
),
|
R.string.avatar_size_broad
|
||||||
|
)
|
||||||
|
),
|
||||||
defaultSelectedItemIndex = if (user?.preferences?.size == "slim") 0 else 1,
|
defaultSelectedItemIndex = if (user?.preferences?.size == "slim") 0 else 1,
|
||||||
onItemSelection = {
|
onItemSelection = {
|
||||||
userViewModel.updateUser(
|
userViewModel.updateUser(
|
||||||
"preferences.size",
|
"preferences.size",
|
||||||
if (it == 0) "slim" else "broad"
|
if (it == 0) "slim" else "broad"
|
||||||
)
|
)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
AvatarCustomizationOverviewView(user?.preferences, user?.items?.gear?.equipped, onCustomizationTap, onAvatarEquipmentTap)
|
AvatarCustomizationOverviewView(user?.preferences, user?.items?.gear?.equipped, onCustomizationTap, onAvatarEquipmentTap)
|
||||||
}
|
}
|
||||||
|
|
@ -229,4 +237,4 @@ fun AvatarOverviewView(userViewModel: MainUserViewModel,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,4 @@ class EquipmentOverviewFragment : AvatarOverviewFragment() {
|
||||||
showCustomization = false
|
showCustomization = false
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -269,37 +269,36 @@ class ItemDialogFragment : BaseDialogFragment<FragmentItemsDialogBinding>() {
|
||||||
else -> Egg::class.java
|
else -> Egg::class.java
|
||||||
}
|
}
|
||||||
itemType?.let { type ->
|
itemType?.let { type ->
|
||||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||||
inventoryRepository.getOwnedItems(type)
|
inventoryRepository.getOwnedItems(type)
|
||||||
.onEach { items ->
|
.onEach { items ->
|
||||||
val filteredItems = if (isFeeding) {
|
val filteredItems = if (isFeeding) {
|
||||||
items.filter { it.key != "Saddle" }
|
items.filter { it.key != "Saddle" }
|
||||||
} else {
|
} else {
|
||||||
items
|
items
|
||||||
}
|
|
||||||
adapter?.data = filteredItems
|
|
||||||
}
|
}
|
||||||
.map { items -> items.mapNotNull { it.key } }
|
adapter?.data = filteredItems
|
||||||
.map { inventoryRepository.getItems(itemClass, it.toTypedArray()).firstOrNull() }
|
}
|
||||||
.collect {
|
.map { items -> items.mapNotNull { it.key } }
|
||||||
val itemMap = mutableMapOf<String, Item>()
|
.map { inventoryRepository.getItems(itemClass, it.toTypedArray()).firstOrNull() }
|
||||||
for (item in it ?: emptyList()) {
|
.collect {
|
||||||
itemMap[item.key] = item
|
val itemMap = mutableMapOf<String, Item>()
|
||||||
}
|
for (item in it ?: emptyList()) {
|
||||||
adapter?.items = itemMap
|
itemMap[item.key] = item
|
||||||
}
|
}
|
||||||
|
adapter?.items = itemMap
|
||||||
}
|
}
|
||||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
}
|
||||||
inventoryRepository.getPets().collect { adapter?.setExistingPets(it) }
|
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||||
}
|
inventoryRepository.getPets().collect { adapter?.setExistingPets(it) }
|
||||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
}
|
||||||
inventoryRepository.getOwnedPets().map { ownedPets ->
|
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||||
val petMap = mutableMapOf<String, OwnedPet>()
|
inventoryRepository.getOwnedPets().map { ownedPets ->
|
||||||
ownedPets.forEach { petMap[it.key ?: ""] = it }
|
val petMap = mutableMapOf<String, OwnedPet>()
|
||||||
return@map petMap
|
ownedPets.forEach { petMap[it.key ?: ""] = it }
|
||||||
}.collect { adapter?.setOwnedPets(it) }
|
return@map petMap
|
||||||
}
|
}.collect { adapter?.setOwnedPets(it) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -225,7 +225,7 @@ class ItemRecyclerFragment : BaseFragment<FragmentItemsBinding>(), SwipeRefreshL
|
||||||
alert?.setMessage(R.string.quest_party_required_description)
|
alert?.setMessage(R.string.quest_party_required_description)
|
||||||
alert?.addButton(R.string.create_new_party, true, false) { _, _ ->
|
alert?.addButton(R.string.create_new_party, true, false) { _, _ ->
|
||||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||||
val group = socialRepository.createGroup(
|
socialRepository.createGroup(
|
||||||
getString(R.string.usernames_party, user?.profile?.name),
|
getString(R.string.usernames_party, user?.profile?.name),
|
||||||
"",
|
"",
|
||||||
user?.id,
|
user?.id,
|
||||||
|
|
|
||||||
|
|
@ -276,7 +276,7 @@ open class ShopFragment : BaseMainFragment<FragmentRefreshRecyclerviewBinding>()
|
||||||
lifecycleScope.launchCatching {
|
lifecycleScope.launchCatching {
|
||||||
val shop = inventoryRepository.retrieveMarketGear()
|
val shop = inventoryRepository.retrieveMarketGear()
|
||||||
inventoryRepository.getOwnedEquipment()
|
inventoryRepository.getOwnedEquipment()
|
||||||
.map { equipment -> equipment.map { it.key } }
|
.map { equipment -> equipment.map { it.key } }
|
||||||
.collect { equipment ->
|
.collect { equipment ->
|
||||||
for (category in shop?.categories ?: emptyList()) {
|
for (category in shop?.categories ?: emptyList()) {
|
||||||
val items = category.items.asSequence().filter {
|
val items = category.items.asSequence().filter {
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,7 @@ class MountDetailRecyclerFragment :
|
||||||
if (animalType != null || animalGroup != null) {
|
if (animalType != null || animalGroup != null) {
|
||||||
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
lifecycleScope.launch(ExceptionHandler.coroutine()) {
|
||||||
val mounts = inventoryRepository.getMounts(animalType, animalGroup, animalColor).firstOrNull() ?: emptyList()
|
val mounts = inventoryRepository.getMounts(animalType, animalGroup, animalColor).firstOrNull() ?: emptyList()
|
||||||
inventoryRepository.getOwnedMounts().map { ownedMounts ->
|
inventoryRepository.getOwnedMounts().map { ownedMounts ->
|
||||||
val mountMap = mutableMapOf<String, OwnedMount>()
|
val mountMap = mutableMapOf<String, OwnedMount>()
|
||||||
ownedMounts.forEach { mountMap[it.key ?: ""] = it }
|
ownedMounts.forEach { mountMap[it.key ?: ""] = it }
|
||||||
return@map mountMap
|
return@map mountMap
|
||||||
|
|
|
||||||
|
|
@ -218,7 +218,6 @@ class PetDetailRecyclerFragment :
|
||||||
}
|
}
|
||||||
adapter.setItemList(items)
|
adapter.setItemList(items)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -172,8 +172,6 @@ class StableRecyclerFragment :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val ITEM_TYPE_KEY = "CLASS_TYPE_KEY"
|
private const val ITEM_TYPE_KEY = "CLASS_TYPE_KEY"
|
||||||
private const val HEADER_VIEW_TYPE = 0
|
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.data.ApiClient
|
||||||
import com.habitrpg.android.habitica.extensions.addCancelButton
|
import com.habitrpg.android.habitica.extensions.addCancelButton
|
||||||
import com.habitrpg.android.habitica.extensions.addCloseButton
|
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.ExceptionHandler
|
||||||
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
||||||
import com.habitrpg.android.habitica.helpers.launchCatching
|
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.HabiticaAlertDialog
|
||||||
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaProgressDialog
|
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaProgressDialog
|
||||||
import com.habitrpg.common.habitica.api.HostConfig
|
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 kotlinx.coroutines.launch
|
||||||
import retrofit2.HttpException
|
import retrofit2.HttpException
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
@ -48,7 +48,7 @@ import javax.inject.Inject
|
||||||
class AccountPreferenceFragment :
|
class AccountPreferenceFragment :
|
||||||
BasePreferencesFragment(),
|
BasePreferencesFragment(),
|
||||||
SharedPreferences.OnSharedPreferenceChangeListener,
|
SharedPreferences.OnSharedPreferenceChangeListener,
|
||||||
AccountUpdateConfirmed {
|
AccountUpdateConfirmed {
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var hostConfig: HostConfig
|
lateinit var hostConfig: HostConfig
|
||||||
@Inject
|
@Inject
|
||||||
|
|
@ -334,7 +334,7 @@ class AccountPreferenceFragment :
|
||||||
user?.username ?: "",
|
user?.username ?: "",
|
||||||
email ?: "",
|
email ?: "",
|
||||||
passwordEditText.text ?: "",
|
passwordEditText.text ?: "",
|
||||||
passwordRepeatEditText?.text ?: ""
|
passwordRepeatEditText.text ?: ""
|
||||||
)
|
)
|
||||||
(activity as? SnackbarActivity)?.showSnackbar(
|
(activity as? SnackbarActivity)?.showSnackbar(
|
||||||
content = context.getString(R.string.password_added),
|
content = context.getString(R.string.password_added),
|
||||||
|
|
@ -454,10 +454,10 @@ class AccountPreferenceFragment :
|
||||||
ExceptionHandler.reportError(throwable)
|
ExceptionHandler.reportError(throwable)
|
||||||
}) {
|
}) {
|
||||||
userRepository.deleteAccount(password)
|
userRepository.deleteAccount(password)
|
||||||
dialog?.dismiss()
|
dialog?.dismiss()
|
||||||
accountDialog.dismiss()
|
accountDialog.dismiss()
|
||||||
context?.let { HabiticaBaseApplication.logout(it) }
|
context?.let { HabiticaBaseApplication.logout(it) }
|
||||||
activity?.finish()
|
activity?.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -471,7 +471,6 @@ class AccountPreferenceFragment :
|
||||||
if (habiticaAccountDialog != null) {
|
if (habiticaAccountDialog != null) {
|
||||||
accountDialog = habiticaAccountDialog
|
accountDialog = habiticaAccountDialog
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showConfirmUsernameDialog() {
|
private fun showConfirmUsernameDialog() {
|
||||||
|
|
@ -519,5 +518,4 @@ class AccountPreferenceFragment :
|
||||||
override fun deletionConfirmClicked(confirmationString: String) {
|
override fun deletionConfirmClicked(confirmationString: String) {
|
||||||
deleteAccount(confirmationString)
|
deleteAccount(confirmationString)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ import com.habitrpg.android.habitica.R
|
||||||
import com.habitrpg.android.habitica.databinding.DialogHabiticaAccountBinding
|
import com.habitrpg.android.habitica.databinding.DialogHabiticaAccountBinding
|
||||||
import com.habitrpg.android.habitica.models.user.User
|
import com.habitrpg.android.habitica.models.user.User
|
||||||
|
|
||||||
|
|
||||||
class HabiticaAccountDialog(private var thisContext: Context) : DialogFragment(R.layout.dialog_habitica_account) {
|
class HabiticaAccountDialog(private var thisContext: Context) : DialogFragment(R.layout.dialog_habitica_account) {
|
||||||
private var _binding: DialogHabiticaAccountBinding? = null
|
private var _binding: DialogHabiticaAccountBinding? = null
|
||||||
private val binding get() = _binding!!
|
private val binding get() = _binding!!
|
||||||
|
|
@ -46,7 +45,7 @@ class HabiticaAccountDialog(private var thisContext: Context) : DialogFragment(R
|
||||||
"delete_account" -> setDeleteAccountViews()
|
"delete_account" -> setDeleteAccountViews()
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.backImagebutton.setOnClickListener{dismiss()}
|
binding.backImagebutton.setOnClickListener { dismiss() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setResetAccountViews() {
|
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) {
|
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
|
||||||
if (binding.confirmationInputEdittext.text.toString().isNotEmpty()) {
|
if (binding.confirmationInputEdittext.text.toString().isNotEmpty()) {
|
||||||
if ((user?.authentication?.hasPassword != true && binding.confirmationInputEdittext.text.toString() == context?.getString(R.string.delete_caps)) ||
|
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.setTextColor(ContextCompat.getColor(thisContext, R.color.red_100))
|
||||||
binding.confirmActionTextview.alpha = 1.0f
|
binding.confirmActionTextview.alpha = 1.0f
|
||||||
}
|
}
|
||||||
|
|
@ -127,7 +127,6 @@ class HabiticaAccountDialog(private var thisContext: Context) : DialogFragment(R
|
||||||
accountUpdateConfirmed?.deletionConfirmClicked(confirmationString)
|
accountUpdateConfirmed?.deletionConfirmClicked(confirmationString)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -135,10 +134,8 @@ class HabiticaAccountDialog(private var thisContext: Context) : DialogFragment(R
|
||||||
return R.style.HabiticaAccountDialogTheme
|
return R.style.HabiticaAccountDialogTheme
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
interface AccountUpdateConfirmed {
|
interface AccountUpdateConfirmed {
|
||||||
fun resetConfirmedClicked()
|
fun resetConfirmedClicked()
|
||||||
fun deletionConfirmClicked(confirmationString: String)
|
fun deletionConfirmClicked(confirmationString: String)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue