formatting fixes

This commit is contained in:
Phillip Thelen 2025-01-14 12:29:01 +01:00
parent c112c4d416
commit d91be2d7fe
526 changed files with 11518 additions and 11538 deletions

View file

@ -106,7 +106,7 @@ open class HabiticaTestCase : TestCase() {
internal fun <T> loadJsonFile( internal fun <T> loadJsonFile(
s: String, s: String,
type: Type, type: Type
): T { ): T {
val userStream = javaClass.classLoader?.getResourceAsStream("$s.json") val userStream = javaClass.classLoader?.getResourceAsStream("$s.json")
return gson.fromJson(gson.newJsonReader(InputStreamReader(userStream)), type) return gson.fromJson(gson.newJsonReader(InputStreamReader(userStream)), type)
@ -138,7 +138,7 @@ open class HabiticaTestCase : TestCase() {
private fun <P, C> assign( private fun <P, C> assign(
it: KCallable<*>, it: KCallable<*>,
obj: C, obj: C,
value: P, value: P
) { ) {
if ((it as KMutableProperty1<C, P>).javaField!!.get(obj) == null) { if ((it as KMutableProperty1<C, P>).javaField!!.get(obj) == null) {
it.set(obj, value) it.set(obj, value)

View file

@ -296,7 +296,7 @@ class TaskFormActivityTest : ActivityTestCase() {
} }
KSpinner( KSpinner(
builder = { withId(R.id.repeats_every_spinner) }, builder = { withId(R.id.repeats_every_spinner) },
itemTypeBuilder = { itemType(::KSpinnerItem) }, itemTypeBuilder = { itemType(::KSpinnerItem) }
) perform { ) perform {
open() open()
childAt<KSpinnerItem>(1) { childAt<KSpinnerItem>(1) {

View file

@ -9,7 +9,7 @@ import io.github.kakaocup.kakao.screen.Screen
import org.junit.Before import org.junit.Before
abstract class FragmentTestCase<F : Fragment, VB : ViewBinding, S : Screen<S>>( abstract class FragmentTestCase<F : Fragment, VB : ViewBinding, S : Screen<S>>(
val shouldLaunchFragment: Boolean = true, val shouldLaunchFragment: Boolean = true
) : HabiticaTestCase() { ) : HabiticaTestCase() {
lateinit var scenario: FragmentScenario<F> lateinit var scenario: FragmentScenario<F>
lateinit var fragment: F lateinit var fragment: F

View file

@ -27,9 +27,9 @@ class NavigationDrawerScreen : Screen<NavigationDrawerScreen>() {
KRecyclerView({ KRecyclerView({
withId(R.id.recyclerView) withId(R.id.recyclerView)
}, itemTypeBuilder = { }, itemTypeBuilder = {
itemType(::SectionHeaderItem) itemType(::SectionHeaderItem)
itemType(::MainItem) itemType(::MainItem)
}) })
} }
@LargeTest @LargeTest

View file

@ -46,14 +46,14 @@ private val KTextView.text: CharSequence?
override fun perform( override fun perform(
uiController: UiController?, uiController: UiController?,
view: View?, view: View?
) { ) {
val tv = view as TextView val tv = view as TextView
string = tv.text string = tv.text
} }
}, }
)
) )
)
return string return string
} }
@ -67,8 +67,8 @@ class ItemScreen : Screen<ItemScreen>() {
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) {

View file

@ -25,9 +25,9 @@ class PetDetailScreen : Screen<PetDetailScreen>() {
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 :
@ -43,9 +43,9 @@ internal class PetDetailRecyclerFragmentTest :
mapOf( mapOf(
Pair( Pair(
"Saddle-food", "Saddle-food",
saddle, saddle
), )
), )
) )
fragment = spyk() fragment = spyk()
@ -69,18 +69,18 @@ internal class PetDetailRecyclerFragmentTest :
inventoryRepository.getPets( inventoryRepository.getPets(
any(), any(),
any(), any(),
any(), any()
) )
} returns flowOf(content.pets.filter { it.animal == "Cactus" }) } returns flowOf(content.pets.filter { it.animal == "Cactus" })
every { every {
inventoryRepository.getMounts( inventoryRepository.getMounts(
any(), any(),
any(), any(),
any(), any()
) )
} returns flowOf(content.mounts.filter { it.animal == "Cactus" }) } returns flowOf(content.mounts.filter { it.animal == "Cactus" })
launchFragment( launchFragment(
PetDetailRecyclerFragmentArgs.Builder("cactus", "drop", "").build().toBundle(), PetDetailRecyclerFragmentArgs.Builder("cactus", "drop", "").build().toBundle()
) )
screen { screen {
recycler { recycler {
@ -102,14 +102,14 @@ internal class PetDetailRecyclerFragmentTest :
inventoryRepository.getPets( inventoryRepository.getPets(
any(), any(),
any(), any(),
any(), any()
) )
} returns flowOf(content.pets.filter { it.animal == "Fox" }) } returns flowOf(content.pets.filter { it.animal == "Fox" })
every { every {
inventoryRepository.getMounts( inventoryRepository.getMounts(
any(), any(),
any(), any(),
any(), any()
) )
} returns flowOf(content.mounts.filter { it.animal == "Fox" }) } returns flowOf(content.mounts.filter { it.animal == "Fox" })
launchFragment(PetDetailRecyclerFragmentArgs.Builder("fox", "drop", "").build().toBundle()) launchFragment(PetDetailRecyclerFragmentArgs.Builder("fox", "drop", "").build().toBundle())

View file

@ -34,9 +34,9 @@ class StableScreen : Screen<StableScreen>() {
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) {

View file

@ -32,8 +32,8 @@ class TaskListScreen : Screen<TaskListScreen>() {
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) {

View file

@ -14,7 +14,6 @@ import android.database.sqlite.SQLiteDatabase
import android.os.Build import android.os.Build
import android.os.Build.VERSION.SDK_INT import android.os.Build.VERSION.SDK_INT
import android.os.Bundle import android.os.Bundle
import android.provider.Settings
import android.util.Log import android.util.Log
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.core.content.edit import androidx.core.content.edit
@ -39,7 +38,6 @@ import com.habitrpg.android.habitica.modules.AuthenticationHandler
import com.habitrpg.android.habitica.ui.activities.BaseActivity import com.habitrpg.android.habitica.ui.activities.BaseActivity
import com.habitrpg.android.habitica.ui.activities.LoginActivity import com.habitrpg.android.habitica.ui.activities.LoginActivity
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
import com.habitrpg.common.habitica.extensions.DataBindingUtils
import com.habitrpg.common.habitica.extensions.setupCoil import com.habitrpg.common.habitica.extensions.setupCoil
import com.habitrpg.common.habitica.helpers.ExceptionHandler import com.habitrpg.common.habitica.helpers.ExceptionHandler
import com.habitrpg.common.habitica.helpers.LanguageHelper import com.habitrpg.common.habitica.helpers.LanguageHelper
@ -161,8 +159,8 @@ abstract class HabiticaBaseApplication : Application(), Application.ActivityLife
val configuration: Configuration = resources.configuration val configuration: Configuration = resources.configuration
val languageHelper = LanguageHelper(sharedPrefs.getString("language", "en")) val languageHelper = LanguageHelper(sharedPrefs.getString("language", "en"))
if (if (SDK_INT >= Build.VERSION_CODES.N) { if (if (SDK_INT >= Build.VERSION_CODES.N) {
configuration.locales.isEmpty || configuration.locales[0] != languageHelper.locale configuration.locales.isEmpty || configuration.locales[0] != languageHelper.locale
} else { } else {
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
configuration.locale != languageHelper.locale configuration.locale != languageHelper.locale
} }
@ -216,7 +214,7 @@ abstract class HabiticaBaseApplication : Application(), Application.ActivityLife
override fun openOrCreateDatabase( override fun openOrCreateDatabase(
name: String, name: String,
mode: Int, mode: Int,
factory: SQLiteDatabase.CursorFactory?, factory: SQLiteDatabase.CursorFactory?
): SQLiteDatabase { ): SQLiteDatabase {
return super.openOrCreateDatabase(getDatabasePath(name).absolutePath, mode, factory) return super.openOrCreateDatabase(getDatabasePath(name).absolutePath, mode, factory)
} }
@ -225,13 +223,13 @@ abstract class HabiticaBaseApplication : Application(), Application.ActivityLife
name: String, name: String,
mode: Int, mode: Int,
factory: SQLiteDatabase.CursorFactory?, factory: SQLiteDatabase.CursorFactory?,
errorHandler: DatabaseErrorHandler?, errorHandler: DatabaseErrorHandler?
): SQLiteDatabase { ): SQLiteDatabase {
return super.openOrCreateDatabase( return super.openOrCreateDatabase(
getDatabasePath(name).absolutePath, getDatabasePath(name).absolutePath,
mode, mode,
factory, factory,
errorHandler, errorHandler
) )
} }
@ -299,7 +297,7 @@ abstract class HabiticaBaseApplication : Application(), Application.ActivityLife
override fun onActivityCreated( override fun onActivityCreated(
p0: Activity, p0: Activity,
p1: Bundle?, p1: Bundle?
) { ) {
} }
@ -308,7 +306,7 @@ abstract class HabiticaBaseApplication : Application(), Application.ActivityLife
override fun onActivitySaveInstanceState( override fun onActivitySaveInstanceState(
p0: Activity, p0: Activity,
p1: Bundle, p1: Bundle
) { ) {
} }
@ -350,7 +348,7 @@ abstract class HabiticaBaseApplication : Application(), Application.ActivityLife
private fun startActivity( private fun startActivity(
activityClass: Class<*>, activityClass: Class<*>,
context: Context, context: Context
) { ) {
val intent = Intent(context, activityClass) val intent = Intent(context, activityClass)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)

View file

@ -63,7 +63,7 @@ interface ApiService {
@GET("inbox/messages") @GET("inbox/messages")
suspend fun getInboxMessages( suspend fun getInboxMessages(
@Query("conversation") uuid: String, @Query("conversation") uuid: String,
@Query("page") page: Int, @Query("page") page: Int
): HabitResponse<List<ChatMessage>> ): HabitResponse<List<ChatMessage>>
@GET("inbox/conversations") @GET("inbox/conversations")
@ -77,17 +77,17 @@ interface ApiService {
@GET("content") @GET("content")
suspend fun getContent( suspend fun getContent(
@Query("language") language: String?, @Query("language") language: String?
): HabitResponse<ContentResult> ): HabitResponse<ContentResult>
@PUT("user/") @PUT("user/")
suspend fun updateUser( suspend fun updateUser(
@Body updateDictionary: Map<String, Any?>, @Body updateDictionary: Map<String, Any?>
): HabitResponse<User> ): HabitResponse<User>
@PUT("user/") @PUT("user/")
suspend fun registrationLanguage( suspend fun registrationLanguage(
@Header("Accept-Language") registrationLanguage: String, @Header("Accept-Language") registrationLanguage: String
): HabitResponse<User> ): HabitResponse<User>
@GET("user/in-app-rewards") @GET("user/in-app-rewards")
@ -96,171 +96,171 @@ interface ApiService {
@POST("user/equip/{type}/{key}") @POST("user/equip/{type}/{key}")
suspend fun equipItem( suspend fun equipItem(
@Path("type") type: String, @Path("type") type: String,
@Path("key") itemKey: String, @Path("key") itemKey: String
): HabitResponse<Items> ): HabitResponse<Items>
@POST("user/buy/{key}") @POST("user/buy/{key}")
suspend fun buyItem( suspend fun buyItem(
@Path("key") itemKey: String, @Path("key") itemKey: String,
@Body quantity: Map<String, Int>, @Body quantity: Map<String, Int>
): HabitResponse<BuyResponse> ): HabitResponse<BuyResponse>
@POST("user/purchase/{type}/{key}") @POST("user/purchase/{type}/{key}")
suspend fun purchaseItem( suspend fun purchaseItem(
@Path("type") type: String, @Path("type") type: String,
@Path("key") itemKey: String, @Path("key") itemKey: String,
@Body quantity: Map<String, Int>, @Body quantity: Map<String, Int>
): HabitResponse<Void> ): HabitResponse<Void>
@POST("user/purchase-hourglass/{type}/{key}") @POST("user/purchase-hourglass/{type}/{key}")
suspend fun purchaseHourglassItem( suspend fun purchaseHourglassItem(
@Path("type") type: String, @Path("type") type: String,
@Path("key") itemKey: String, @Path("key") itemKey: String
): HabitResponse<Void> ): HabitResponse<Void>
@POST("user/buy-mystery-set/{key}") @POST("user/buy-mystery-set/{key}")
suspend fun purchaseMysterySet( suspend fun purchaseMysterySet(
@Path("key") itemKey: String, @Path("key") itemKey: String
): HabitResponse<Void> ): HabitResponse<Void>
@POST("user/buy-quest/{key}") @POST("user/buy-quest/{key}")
suspend fun purchaseQuest( suspend fun purchaseQuest(
@Path("key") key: String, @Path("key") key: String
): HabitResponse<Void> ): HabitResponse<Void>
@POST("user/buy-special-spell/{key}") @POST("user/buy-special-spell/{key}")
suspend fun purchaseSpecialSpell( suspend fun purchaseSpecialSpell(
@Path("key") key: String, @Path("key") key: String
): HabitResponse<Void> ): HabitResponse<Void>
@POST("user/sell/{type}/{key}") @POST("user/sell/{type}/{key}")
suspend fun sellItem( suspend fun sellItem(
@Path("type") itemType: String, @Path("type") itemType: String,
@Path("key") itemKey: String, @Path("key") itemKey: String
): HabitResponse<User> ): HabitResponse<User>
@POST("user/feed/{pet}/{food}") @POST("user/feed/{pet}/{food}")
suspend fun feedPet( suspend fun feedPet(
@Path("pet") petKey: String, @Path("pet") petKey: String,
@Path("food") foodKey: String, @Path("food") foodKey: String
): HabitResponse<FeedResponse> ): HabitResponse<FeedResponse>
@POST("user/hatch/{egg}/{hatchingPotion}") @POST("user/hatch/{egg}/{hatchingPotion}")
suspend fun hatchPet( suspend fun hatchPet(
@Path("egg") eggKey: String, @Path("egg") eggKey: String,
@Path("hatchingPotion") hatchingPotionKey: String, @Path("hatchingPotion") hatchingPotionKey: String
): HabitResponse<Items> ): HabitResponse<Items>
@GET("tasks/user") @GET("tasks/user")
suspend fun getTasks( suspend fun getTasks(
@Query("type") type: String, @Query("type") type: String
): HabitResponse<TaskList> ): HabitResponse<TaskList>
@GET("tasks/user") @GET("tasks/user")
suspend fun getTasks( suspend fun getTasks(
@Query("type") type: String, @Query("type") type: String,
@Query("dueDate") dueDate: String, @Query("dueDate") dueDate: String
): HabitResponse<TaskList> ): HabitResponse<TaskList>
@POST("user/unlock") @POST("user/unlock")
suspend fun unlockPath( suspend fun unlockPath(
@Query("path") path: String, @Query("path") path: String
): HabitResponse<UnlockResponse> ): HabitResponse<UnlockResponse>
@GET("tasks/{id}") @GET("tasks/{id}")
suspend fun getTask( suspend fun getTask(
@Path("id") id: String, @Path("id") id: String
): HabitResponse<Task> ): HabitResponse<Task>
@POST("tasks/{id}/score/{direction}") @POST("tasks/{id}/score/{direction}")
suspend fun postTaskDirection( suspend fun postTaskDirection(
@Path("id") id: String, @Path("id") id: String,
@Path("direction") direction: String, @Path("direction") direction: String
): HabitResponse<TaskDirectionData> ): HabitResponse<TaskDirectionData>
@POST("tasks/bulk-score") @POST("tasks/bulk-score")
suspend fun bulkScoreTasks( suspend fun bulkScoreTasks(
@Body data: List<Map<String, String>>, @Body data: List<Map<String, String>>
): HabitResponse<BulkTaskScoringData> ): HabitResponse<BulkTaskScoringData>
@POST("tasks/{id}/move/to/{position}") @POST("tasks/{id}/move/to/{position}")
suspend fun postTaskNewPosition( suspend fun postTaskNewPosition(
@Path("id") id: String, @Path("id") id: String,
@Path("position") position: Int, @Path("position") position: Int
): HabitResponse<List<String>> ): HabitResponse<List<String>>
@POST("tasks/{taskId}/checklist/{itemId}/score") @POST("tasks/{taskId}/checklist/{itemId}/score")
suspend fun scoreChecklistItem( suspend fun scoreChecklistItem(
@Path("taskId") taskId: String, @Path("taskId") taskId: String,
@Path("itemId") itemId: String, @Path("itemId") itemId: String
): HabitResponse<Task> ): HabitResponse<Task>
@POST("tasks/user") @POST("tasks/user")
suspend fun createTask( suspend fun createTask(
@Body item: Task, @Body item: Task
): HabitResponse<Task> ): HabitResponse<Task>
@POST("tasks/group/{groupId}") @POST("tasks/group/{groupId}")
suspend fun createGroupTask( suspend fun createGroupTask(
@Path("groupId") groupId: String, @Path("groupId") groupId: String,
@Body item: Task, @Body item: Task
): HabitResponse<Task> ): HabitResponse<Task>
@POST("tasks/user") @POST("tasks/user")
suspend fun createTasks( suspend fun createTasks(
@Body tasks: List<Task>, @Body tasks: List<Task>
): HabitResponse<List<Task>> ): HabitResponse<List<Task>>
@PUT("tasks/{id}") @PUT("tasks/{id}")
suspend fun updateTask( suspend fun updateTask(
@Path("id") id: String, @Path("id") id: String,
@Body item: Task, @Body item: Task
): HabitResponse<Task> ): HabitResponse<Task>
@DELETE("tasks/{id}") @DELETE("tasks/{id}")
suspend fun deleteTask( suspend fun deleteTask(
@Path("id") id: String, @Path("id") id: String
): HabitResponse<Void> ): HabitResponse<Void>
@POST("tags") @POST("tags")
suspend fun createTag( suspend fun createTag(
@Body tag: Tag, @Body tag: Tag
): HabitResponse<Tag> ): HabitResponse<Tag>
@PUT("tags/{id}") @PUT("tags/{id}")
suspend fun updateTag( suspend fun updateTag(
@Path("id") id: String, @Path("id") id: String,
@Body tag: Tag, @Body tag: Tag
): HabitResponse<Tag> ): HabitResponse<Tag>
@DELETE("tags/{id}") @DELETE("tags/{id}")
suspend fun deleteTag( suspend fun deleteTag(
@Path("id") id: String, @Path("id") id: String
): HabitResponse<Void> ): HabitResponse<Void>
@POST("user/auth/local/register") @POST("user/auth/local/register")
suspend fun registerUser( suspend fun registerUser(
@Body auth: UserAuth, @Body auth: UserAuth
): HabitResponse<UserAuthResponse> ): HabitResponse<UserAuthResponse>
@POST("user/auth/local/login") @POST("user/auth/local/login")
suspend fun connectLocal( suspend fun connectLocal(
@Body auth: UserAuth, @Body auth: UserAuth
): HabitResponse<UserAuthResponse> ): HabitResponse<UserAuthResponse>
@POST("user/auth/social") @POST("user/auth/social")
suspend fun connectSocial( suspend fun connectSocial(
@Body auth: UserAuthSocial, @Body auth: UserAuthSocial
): HabitResponse<UserAuthResponse> ): HabitResponse<UserAuthResponse>
@DELETE("user/auth/social/{network}") @DELETE("user/auth/social/{network}")
suspend fun disconnectSocial( suspend fun disconnectSocial(
@Path("network") network: String, @Path("network") network: String
): HabitResponse<Void> ): HabitResponse<Void>
@POST("user/auth/apple") @POST("user/auth/apple")
suspend fun loginApple( suspend fun loginApple(
@Body auth: Map<String, Any>, @Body auth: Map<String, Any>
): HabitResponse<UserAuthResponse> ): HabitResponse<UserAuthResponse>
@POST("user/sleep") @POST("user/sleep")
@ -273,13 +273,13 @@ interface ApiService {
suspend fun useSkill( suspend fun useSkill(
@Path("skill") skillName: String, @Path("skill") skillName: String,
@Query("targetType") targetType: String, @Query("targetType") targetType: String,
@Query("targetId") targetId: String, @Query("targetId") targetId: String
): HabitResponse<SkillResponse> ): HabitResponse<SkillResponse>
@POST("user/class/cast/{skill}") @POST("user/class/cast/{skill}")
suspend fun useSkill( suspend fun useSkill(
@Path("skill") skillName: String, @Path("skill") skillName: String,
@Query("targetType") targetType: String, @Query("targetType") targetType: String
): HabitResponse<SkillResponse> ): HabitResponse<SkillResponse>
@POST("user/change-class") @POST("user/change-class")
@ -287,7 +287,7 @@ interface ApiService {
@POST("user/change-class") @POST("user/change-class")
suspend fun changeClass( suspend fun changeClass(
@Query("class") className: String, @Query("class") className: String
): HabitResponse<User> ): HabitResponse<User>
@POST("user/disable-classes") @POST("user/disable-classes")
@ -300,164 +300,164 @@ interface ApiService {
@GET("groups") @GET("groups")
suspend fun listGroups( suspend fun listGroups(
@Query("type") type: String, @Query("type") type: String
): HabitResponse<List<Group>> ): HabitResponse<List<Group>>
@GET("groups/{gid}") @GET("groups/{gid}")
suspend fun getGroup( suspend fun getGroup(
@Path("gid") groupId: String, @Path("gid") groupId: String
): HabitResponse<Group> ): HabitResponse<Group>
@POST("groups") @POST("groups")
suspend fun createGroup( suspend fun createGroup(
@Body item: Group, @Body item: Group
): HabitResponse<Group> ): HabitResponse<Group>
@PUT("groups/{id}") @PUT("groups/{id}")
suspend fun updateGroup( suspend fun updateGroup(
@Path("id") id: String, @Path("id") id: String,
@Body item: Group, @Body item: Group
): HabitResponse<Group> ): HabitResponse<Group>
@POST("groups/{groupID}/removeMember/{userID}") @POST("groups/{groupID}/removeMember/{userID}")
suspend fun removeMemberFromGroup( suspend fun removeMemberFromGroup(
@Path("groupID") groupID: String, @Path("groupID") groupID: String,
@Path("userID") userID: String, @Path("userID") userID: String
): HabitResponse<Void> ): HabitResponse<Void>
@GET("groups/{gid}/chat") @GET("groups/{gid}/chat")
suspend fun listGroupChat( suspend fun listGroupChat(
@Path("gid") groupId: String, @Path("gid") groupId: String
): HabitResponse<List<ChatMessage>> ): HabitResponse<List<ChatMessage>>
@POST("groups/{gid}/join") @POST("groups/{gid}/join")
suspend fun joinGroup( suspend fun joinGroup(
@Path("gid") groupId: String, @Path("gid") groupId: String
): HabitResponse<Group> ): HabitResponse<Group>
@POST("groups/{gid}/leave") @POST("groups/{gid}/leave")
suspend fun leaveGroup( suspend fun leaveGroup(
@Path("gid") groupId: String, @Path("gid") groupId: String,
@Query("keepChallenges") keepChallenges: String, @Query("keepChallenges") keepChallenges: String
): HabitResponse<Void> ): HabitResponse<Void>
@POST("groups/{gid}/chat") @POST("groups/{gid}/chat")
suspend fun postGroupChat( suspend fun postGroupChat(
@Path("gid") groupId: String, @Path("gid") groupId: String,
@Body message: Map<String, String>, @Body message: Map<String, String>
): HabitResponse<PostChatMessageResult> ): HabitResponse<PostChatMessageResult>
@DELETE("groups/{gid}/chat/{messageId}") @DELETE("groups/{gid}/chat/{messageId}")
suspend fun deleteMessage( suspend fun deleteMessage(
@Path("gid") groupId: String, @Path("gid") groupId: String,
@Path("messageId") messageId: String, @Path("messageId") messageId: String
): HabitResponse<Void> ): HabitResponse<Void>
@DELETE("inbox/messages/{messageId}") @DELETE("inbox/messages/{messageId}")
suspend fun deleteInboxMessage( suspend fun deleteInboxMessage(
@Path("messageId") messageId: String, @Path("messageId") messageId: String
): HabitResponse<Void> ): HabitResponse<Void>
@GET("groups/{gid}/members") @GET("groups/{gid}/members")
suspend fun getGroupMembers( suspend fun getGroupMembers(
@Path("gid") groupId: String, @Path("gid") groupId: String,
@Query("includeAllPublicFields") includeAllPublicFields: Boolean?, @Query("includeAllPublicFields") includeAllPublicFields: Boolean?
): HabitResponse<List<Member>> ): HabitResponse<List<Member>>
@GET("groups/{gid}/members") @GET("groups/{gid}/members")
suspend fun getGroupMembers( suspend fun getGroupMembers(
@Path("gid") groupId: String, @Path("gid") groupId: String,
@Query("includeAllPublicFields") includeAllPublicFields: Boolean?, @Query("includeAllPublicFields") includeAllPublicFields: Boolean?,
@Query("lastId") lastId: String, @Query("lastId") lastId: String
): HabitResponse<List<Member>> ): HabitResponse<List<Member>>
// Like returns the full chat list // Like returns the full chat list
@POST("groups/{gid}/chat/{mid}/like") @POST("groups/{gid}/chat/{mid}/like")
suspend fun likeMessage( suspend fun likeMessage(
@Path("gid") groupId: String, @Path("gid") groupId: String,
@Path("mid") mid: String, @Path("mid") mid: String
): HabitResponse<ChatMessage> ): HabitResponse<ChatMessage>
@POST("groups/{gid}/chat/{mid}/flag") @POST("groups/{gid}/chat/{mid}/flag")
suspend fun flagMessage( suspend fun flagMessage(
@Path("gid") groupId: String, @Path("gid") groupId: String,
@Path("mid") mid: String, @Path("mid") mid: String,
@Body data: Map<String, String>, @Body data: Map<String, String>
): HabitResponse<Void> ): HabitResponse<Void>
@POST("members/{mid}/flag") @POST("members/{mid}/flag")
suspend fun reportMember( suspend fun reportMember(
@Path("mid") mid: String, @Path("mid") mid: String,
@Body data: Map<String, String>, @Body data: Map<String, String>
): HabitResponse<Void> ): HabitResponse<Void>
@POST("groups/{gid}/chat/seen") @POST("groups/{gid}/chat/seen")
suspend fun seenMessages( suspend fun seenMessages(
@Path("gid") groupId: String, @Path("gid") groupId: String
): HabitResponse<Void> ): HabitResponse<Void>
@POST("groups/{gid}/invite") @POST("groups/{gid}/invite")
suspend fun inviteToGroup( suspend fun inviteToGroup(
@Path("gid") groupId: String, @Path("gid") groupId: String,
@Body inviteData: Map<String, Any>, @Body inviteData: Map<String, Any>
): HabitResponse<List<InviteResponse>> ): HabitResponse<List<InviteResponse>>
@POST("groups/{gid}/reject-invite") @POST("groups/{gid}/reject-invite")
suspend fun rejectGroupInvite( suspend fun rejectGroupInvite(
@Path("gid") groupId: String, @Path("gid") groupId: String
): HabitResponse<Void> ): HabitResponse<Void>
@POST("groups/{gid}/quests/accept") @POST("groups/{gid}/quests/accept")
suspend fun acceptQuest( suspend fun acceptQuest(
@Path("gid") groupId: String, @Path("gid") groupId: String
): HabitResponse<Void> ): HabitResponse<Void>
@POST("groups/{gid}/quests/reject") @POST("groups/{gid}/quests/reject")
suspend fun rejectQuest( suspend fun rejectQuest(
@Path("gid") groupId: String, @Path("gid") groupId: String
): HabitResponse<Void> ): HabitResponse<Void>
@POST("groups/{gid}/quests/cancel") @POST("groups/{gid}/quests/cancel")
suspend fun cancelQuest( suspend fun cancelQuest(
@Path("gid") groupId: String, @Path("gid") groupId: String
): HabitResponse<Void> ): HabitResponse<Void>
@POST("groups/{gid}/quests/force-start") @POST("groups/{gid}/quests/force-start")
suspend fun forceStartQuest( suspend fun forceStartQuest(
@Path("gid") groupId: String, @Path("gid") groupId: String,
@Body group: Group, @Body group: Group
): HabitResponse<Quest> ): HabitResponse<Quest>
@POST("groups/{gid}/quests/invite/{questKey}") @POST("groups/{gid}/quests/invite/{questKey}")
suspend fun inviteToQuest( suspend fun inviteToQuest(
@Path("gid") groupId: String, @Path("gid") groupId: String,
@Path("questKey") questKey: String, @Path("questKey") questKey: String
): HabitResponse<Quest> ): HabitResponse<Quest>
@GET("groups/{gid}/invites") @GET("groups/{gid}/invites")
suspend fun getGroupInvites( suspend fun getGroupInvites(
@Path("gid") groupId: String, @Path("gid") groupId: String,
@Query("includeAllPublicFields") includeAllPublicFields: Boolean?, @Query("includeAllPublicFields") includeAllPublicFields: Boolean?
): HabitResponse<List<Member>> ): HabitResponse<List<Member>>
@POST("groups/{gid}/quests/abort") @POST("groups/{gid}/quests/abort")
suspend fun abortQuest( suspend fun abortQuest(
@Path("gid") groupId: String, @Path("gid") groupId: String
): HabitResponse<Quest> ): HabitResponse<Quest>
@POST("groups/{gid}/quests/leave") @POST("groups/{gid}/quests/leave")
suspend fun leaveQuest( suspend fun leaveQuest(
@Path("gid") groupId: String, @Path("gid") groupId: String
): HabitResponse<Void> ): HabitResponse<Void>
@POST("/iap/android/verify") @POST("/iap/android/verify")
suspend fun validatePurchase( suspend fun validatePurchase(
@Body request: PurchaseValidationRequest, @Body request: PurchaseValidationRequest
): HabitResponse<PurchaseValidationResult> ): HabitResponse<PurchaseValidationResult>
@POST("/iap/android/subscribe") @POST("/iap/android/subscribe")
suspend fun validateSubscription( suspend fun validateSubscription(
@Body request: PurchaseValidationRequest, @Body request: PurchaseValidationRequest
): HabitResponse<Void> ): HabitResponse<Void>
@GET("/iap/android/subscribe/cancel") @GET("/iap/android/subscribe/cancel")
@ -465,69 +465,69 @@ interface ApiService {
@POST("/iap/android/norenew-subscribe") @POST("/iap/android/norenew-subscribe")
suspend fun validateNoRenewSubscription( suspend fun validateNoRenewSubscription(
@Body request: PurchaseValidationRequest, @Body request: PurchaseValidationRequest
): HabitResponse<Void> ): HabitResponse<Void>
@POST("user/custom-day-start") @POST("user/custom-day-start")
suspend fun changeCustomDayStart( suspend fun changeCustomDayStart(
@Body updateObject: Map<String, Any>, @Body updateObject: Map<String, Any>
): HabitResponse<Void> ): HabitResponse<Void>
// Members URL // Members URL
@GET("members/{mid}") @GET("members/{mid}")
suspend fun getMember( suspend fun getMember(
@Path("mid") memberId: String, @Path("mid") memberId: String
): HabitResponse<Member> ): HabitResponse<Member>
@GET("members/username/{username}") @GET("members/username/{username}")
suspend fun getMemberWithUsername( suspend fun getMemberWithUsername(
@Path("username") username: String, @Path("username") username: String
): HabitResponse<Member> ): HabitResponse<Member>
@GET("members/{mid}/achievements") @GET("members/{mid}/achievements")
suspend fun getMemberAchievements( suspend fun getMemberAchievements(
@Path("mid") memberId: String, @Path("mid") memberId: String,
@Query("lang") language: String?, @Query("lang") language: String?
): HabitResponse<List<Achievement>> ): HabitResponse<List<Achievement>>
@POST("members/send-private-message") @POST("members/send-private-message")
suspend fun postPrivateMessage( suspend fun postPrivateMessage(
@Body messageDetails: Map<String, String>, @Body messageDetails: Map<String, String>
): HabitResponse<PostChatMessageResult> ): HabitResponse<PostChatMessageResult>
@GET("members/find/{username}") @GET("members/find/{username}")
suspend fun findUsernames( suspend fun findUsernames(
@Path("username") username: String, @Path("username") username: String,
@Query("context") context: String?, @Query("context") context: String?,
@Query("id") id: String?, @Query("id") id: String?
): HabitResponse<List<FindUsernameResult>> ): HabitResponse<List<FindUsernameResult>>
@POST("members/flag-private-message/{mid}") @POST("members/flag-private-message/{mid}")
suspend fun flagInboxMessage( suspend fun flagInboxMessage(
@Path("mid") mid: String, @Path("mid") mid: String,
@Body data: Map<String, String>, @Body data: Map<String, String>
): HabitResponse<Void> ): HabitResponse<Void>
@GET("shops/{identifier}") @GET("shops/{identifier}")
suspend fun retrieveShopInventory( suspend fun retrieveShopInventory(
@Path("identifier") identifier: String, @Path("identifier") identifier: String,
@Query("lang") language: String?, @Query("lang") language: String?
): HabitResponse<Shop> ): HabitResponse<Shop>
@GET("shops/market-gear") @GET("shops/market-gear")
suspend fun retrieveMarketGear( suspend fun retrieveMarketGear(
@Query("lang") language: String?, @Query("lang") language: String?
): HabitResponse<Shop> ): HabitResponse<Shop>
// Push notifications // Push notifications
@POST("user/push-devices") @POST("user/push-devices")
suspend fun addPushDevice( suspend fun addPushDevice(
@Body pushDeviceData: Map<String, String>, @Body pushDeviceData: Map<String, String>
): HabitResponse<List<Void>> ): HabitResponse<List<Void>>
@DELETE("user/push-devices/{regId}") @DELETE("user/push-devices/{regId}")
suspend fun deletePushDevice( suspend fun deletePushDevice(
@Path("regId") regId: String, @Path("regId") regId: String
): HabitResponse<List<Void>> ): HabitResponse<List<Void>>
// challenges api // challenges api
@ -535,61 +535,61 @@ interface ApiService {
@GET("challenges/user") @GET("challenges/user")
suspend fun getUserChallenges( suspend fun getUserChallenges(
@Query("page") page: Int?, @Query("page") page: Int?,
@Query("member") memberOnly: Boolean, @Query("member") memberOnly: Boolean
): HabitResponse<List<Challenge>> ): HabitResponse<List<Challenge>>
@GET("challenges/user") @GET("challenges/user")
suspend fun getUserChallenges( suspend fun getUserChallenges(
@Query("page") page: Int?, @Query("page") page: Int?
): HabitResponse<List<Challenge>> ): HabitResponse<List<Challenge>>
@GET("tasks/challenge/{challengeId}") @GET("tasks/challenge/{challengeId}")
suspend fun getChallengeTasks( suspend fun getChallengeTasks(
@Path("challengeId") challengeId: String, @Path("challengeId") challengeId: String
): HabitResponse<TaskList> ): HabitResponse<TaskList>
@GET("challenges/{challengeId}") @GET("challenges/{challengeId}")
suspend fun getChallenge( suspend fun getChallenge(
@Path("challengeId") challengeId: String, @Path("challengeId") challengeId: String
): HabitResponse<Challenge> ): HabitResponse<Challenge>
@POST("challenges/{challengeId}/join") @POST("challenges/{challengeId}/join")
suspend fun joinChallenge( suspend fun joinChallenge(
@Path("challengeId") challengeId: String, @Path("challengeId") challengeId: String
): HabitResponse<Challenge> ): HabitResponse<Challenge>
@POST("challenges/{challengeId}/leave") @POST("challenges/{challengeId}/leave")
suspend fun leaveChallenge( suspend fun leaveChallenge(
@Path("challengeId") challengeId: String, @Path("challengeId") challengeId: String,
@Body body: LeaveChallengeBody, @Body body: LeaveChallengeBody
): HabitResponse<Void> ): HabitResponse<Void>
@POST("challenges") @POST("challenges")
suspend fun createChallenge( suspend fun createChallenge(
@Body challenge: Challenge, @Body challenge: Challenge
): HabitResponse<Challenge> ): HabitResponse<Challenge>
@POST("tasks/challenge/{challengeId}") @POST("tasks/challenge/{challengeId}")
suspend fun createChallengeTasks( suspend fun createChallengeTasks(
@Path("challengeId") challengeId: String, @Path("challengeId") challengeId: String,
@Body tasks: List<Task>, @Body tasks: List<Task>
): HabitResponse<List<Task>> ): HabitResponse<List<Task>>
@POST("tasks/challenge/{challengeId}") @POST("tasks/challenge/{challengeId}")
suspend fun createChallengeTask( suspend fun createChallengeTask(
@Path("challengeId") challengeId: String, @Path("challengeId") challengeId: String,
@Body task: Task, @Body task: Task
): HabitResponse<Task> ): HabitResponse<Task>
@PUT("challenges/{challengeId}") @PUT("challenges/{challengeId}")
suspend fun updateChallenge( suspend fun updateChallenge(
@Path("challengeId") challengeId: String, @Path("challengeId") challengeId: String,
@Body challenge: Challenge, @Body challenge: Challenge
): HabitResponse<Challenge> ): HabitResponse<Challenge>
@DELETE("challenges/{challengeId}") @DELETE("challenges/{challengeId}")
suspend fun deleteChallenge( suspend fun deleteChallenge(
@Path("challengeId") challengeId: String, @Path("challengeId") challengeId: String
): HabitResponse<Void> ): HabitResponse<Void>
// DEBUG: These calls only work on a local development server // DEBUG: These calls only work on a local development server
@ -603,17 +603,17 @@ interface ApiService {
// Notifications // Notifications
@POST("notifications/{notificationId}/read") @POST("notifications/{notificationId}/read")
suspend fun readNotification( suspend fun readNotification(
@Path("notificationId") notificationId: String, @Path("notificationId") notificationId: String
): HabitResponse<List<Any>> ): HabitResponse<List<Any>>
@POST("notifications/read") @POST("notifications/read")
suspend fun readNotifications( suspend fun readNotifications(
@Body notificationIds: Map<String, List<String>>, @Body notificationIds: Map<String, List<String>>
): HabitResponse<List<Any>> ): HabitResponse<List<Any>>
@POST("notifications/see") @POST("notifications/see")
suspend fun seeNotifications( suspend fun seeNotifications(
@Body notificationIds: Map<String, List<String>>, @Body notificationIds: Map<String, List<String>>
): HabitResponse<List<Any>> ): HabitResponse<List<Any>>
@POST("user/open-mystery-item") @POST("user/open-mystery-item")
@ -624,69 +624,69 @@ interface ApiService {
@POST("user/reset") @POST("user/reset")
suspend fun resetAccount( suspend fun resetAccount(
@Body body: Map<String, String>, @Body body: Map<String, String>
): HabitResponse<Void> ): HabitResponse<Void>
@HTTP(method = "DELETE", path = "user", hasBody = true) @HTTP(method = "DELETE", path = "user", hasBody = true)
suspend fun deleteAccount( suspend fun deleteAccount(
@Body body: Map<String, String>, @Body body: Map<String, String>
): HabitResponse<Void> ): HabitResponse<Void>
@GET("user/toggle-pinned-item/{pinType}/{path}") @GET("user/toggle-pinned-item/{pinType}/{path}")
suspend fun togglePinnedItem( suspend fun togglePinnedItem(
@Path("pinType") pinType: String, @Path("pinType") pinType: String,
@Path("path") path: String, @Path("path") path: String
): HabitResponse<Void> ): HabitResponse<Void>
@POST("user/reset-password") @POST("user/reset-password")
suspend fun sendPasswordResetEmail( suspend fun sendPasswordResetEmail(
@Body data: Map<String, String>, @Body data: Map<String, String>
): HabitResponse<Void> ): HabitResponse<Void>
@PUT("user/auth/update-username") @PUT("user/auth/update-username")
suspend fun updateLoginName( suspend fun updateLoginName(
@Body data: Map<String, String>, @Body data: Map<String, String>
): HabitResponse<Void> ): HabitResponse<Void>
@POST("user/auth/verify-username") @POST("user/auth/verify-username")
suspend fun verifyUsername( suspend fun verifyUsername(
@Body data: Map<String, String>, @Body data: Map<String, String>
): HabitResponse<VerifyUsernameResponse> ): HabitResponse<VerifyUsernameResponse>
@PUT("user/auth/update-email") @PUT("user/auth/update-email")
suspend fun updateEmail( suspend fun updateEmail(
@Body data: Map<String, String>, @Body data: Map<String, String>
): HabitResponse<Void> ): HabitResponse<Void>
@PUT("user/auth/update-password") @PUT("user/auth/update-password")
suspend fun updatePassword( suspend fun updatePassword(
@Body data: Map<String, String>, @Body data: Map<String, String>
): HabitResponse<Void> ): HabitResponse<Void>
@POST("user/allocate") @POST("user/allocate")
suspend fun allocatePoint( suspend fun allocatePoint(
@Query("stat") stat: String, @Query("stat") stat: String
): HabitResponse<Stats> ): HabitResponse<Stats>
@POST("user/allocate-bulk") @POST("user/allocate-bulk")
suspend fun bulkAllocatePoints( suspend fun bulkAllocatePoints(
@Body stats: Map<String, Map<String, Int>>, @Body stats: Map<String, Map<String, Int>>
): HabitResponse<Stats> ): HabitResponse<Stats>
@POST("members/transfer-gems") @POST("members/transfer-gems")
suspend fun transferGems( suspend fun transferGems(
@Body data: Map<String, Any>, @Body data: Map<String, Any>
): HabitResponse<Void> ): HabitResponse<Void>
@POST("tasks/unlink-all/{challengeID}") @POST("tasks/unlink-all/{challengeID}")
suspend fun unlinkAllTasks( suspend fun unlinkAllTasks(
@Path("challengeID") challengeID: String?, @Path("challengeID") challengeID: String?,
@Query("keep") keepOption: String, @Query("keep") keepOption: String
): HabitResponse<Void> ): HabitResponse<Void>
@POST("user/block/{userID}") @POST("user/block/{userID}")
suspend fun blockMember( suspend fun blockMember(
@Path("userID") userID: String, @Path("userID") userID: String
): HabitResponse<List<String>> ): HabitResponse<List<String>>
@POST("user/reroll") @POST("user/reroll")
@ -699,46 +699,46 @@ interface ApiService {
@GET("tasks/group/{groupID}") @GET("tasks/group/{groupID}")
suspend fun getTeamPlanTasks( suspend fun getTeamPlanTasks(
@Path("groupID") groupId: String, @Path("groupID") groupId: String
): HabitResponse<TaskList> ): HabitResponse<TaskList>
@POST("tasks/{taskID}/assign") @POST("tasks/{taskID}/assign")
suspend fun assignToTask( suspend fun assignToTask(
@Path("taskID") taskId: String?, @Path("taskID") taskId: String?,
@Body ids: List<String>, @Body ids: List<String>
): HabitResponse<Task> ): HabitResponse<Task>
@POST("tasks/{taskID}/unassign/{userID}") @POST("tasks/{taskID}/unassign/{userID}")
suspend fun unassignFromTask( suspend fun unassignFromTask(
@Path("taskID") taskID: String, @Path("taskID") taskID: String,
@Path("userID") userID: String, @Path("userID") userID: String
): HabitResponse<Task> ): HabitResponse<Task>
@PUT("hall/heroes/{memberID}") @PUT("hall/heroes/{memberID}")
suspend fun updateUser( suspend fun updateUser(
@Path("memberID") memberID: String, @Path("memberID") memberID: String,
@Body updateData: Map<String, Map<String, Boolean>>, @Body updateData: Map<String, Map<String, Boolean>>
): HabitResponse<Member> ): HabitResponse<Member>
@GET("hall/heroes/{memberID}") @GET("hall/heroes/{memberID}")
suspend fun getHallMember( suspend fun getHallMember(
@Path("memberID") memberID: String, @Path("memberID") memberID: String
): HabitResponse<Member> ): HabitResponse<Member>
@POST("tasks/{taskID}/needs-work/{userID}") @POST("tasks/{taskID}/needs-work/{userID}")
suspend fun markTaskNeedsWork( suspend fun markTaskNeedsWork(
@Path("taskID") taskID: String, @Path("taskID") taskID: String,
@Path("userID") userID: String, @Path("userID") userID: String
): HabitResponse<Task> ): HabitResponse<Task>
@GET("looking-for-party") @GET("looking-for-party")
suspend fun retrievePartySeekingUsers( suspend fun retrievePartySeekingUsers(
@Query("page") page: Int, @Query("page") page: Int
): HabitResponse<List<Member>> ): HabitResponse<List<Member>>
@POST("challenges/{challengeId}/flag") @POST("challenges/{challengeId}/flag")
suspend fun reportChallenge( suspend fun reportChallenge(
@Path("challengeId") challengeid: String, @Path("challengeId") challengeid: String,
@Body updateData: Map<String, String>, @Body updateData: Map<String, String>
): HabitResponse<Void> ): HabitResponse<Void>
} }

View file

@ -51,7 +51,7 @@ interface ApiClient {
suspend fun getUserChallenges( suspend fun getUserChallenges(
page: Int, page: Int,
memberOnly: Boolean, memberOnly: Boolean
): List<Challenge>? ): List<Challenge>?
suspend fun getWorldState(): WorldState? suspend fun getWorldState(): WorldState?
@ -68,23 +68,23 @@ interface ApiClient {
suspend fun equipItem( suspend fun equipItem(
type: String, type: String,
itemKey: String, itemKey: String
): Items? ): Items?
suspend fun buyItem( suspend fun buyItem(
itemKey: String, itemKey: String,
purchaseQuantity: Int, purchaseQuantity: Int
): BuyResponse? ): BuyResponse?
suspend fun purchaseItem( suspend fun purchaseItem(
type: String, type: String,
itemKey: String, itemKey: String,
purchaseQuantity: Int, purchaseQuantity: Int
): Void? ): Void?
suspend fun purchaseHourglassItem( suspend fun purchaseHourglassItem(
type: String, type: String,
itemKey: String, itemKey: String
): Void? ): Void?
suspend fun purchaseMysterySet(itemKey: String): Void? suspend fun purchaseMysterySet(itemKey: String): Void?
@ -101,24 +101,24 @@ interface ApiClient {
suspend fun sellItem( suspend fun sellItem(
itemType: String, itemType: String,
itemKey: String, itemKey: String
): User? ): User?
suspend fun feedPet( suspend fun feedPet(
petKey: String, petKey: String,
foodKey: String, foodKey: String
): FeedResponse? ): FeedResponse?
suspend fun hatchPet( suspend fun hatchPet(
eggKey: String, eggKey: String,
hatchingPotionKey: String, hatchingPotionKey: String
): Items? ): Items?
suspend fun getTasks(type: String): TaskList? suspend fun getTasks(type: String): TaskList?
suspend fun getTasks( suspend fun getTasks(
type: String, type: String,
dueDate: String, dueDate: String
): TaskList? ): TaskList?
suspend fun unlockPath(path: String): UnlockResponse? suspend fun unlockPath(path: String): UnlockResponse?
@ -127,33 +127,33 @@ interface ApiClient {
suspend fun postTaskDirection( suspend fun postTaskDirection(
id: String, id: String,
direction: String, direction: String
): TaskDirectionData? ): TaskDirectionData?
suspend fun bulkScoreTasks(data: List<Map<String, String>>): BulkTaskScoringData? suspend fun bulkScoreTasks(data: List<Map<String, String>>): BulkTaskScoringData?
suspend fun postTaskNewPosition( suspend fun postTaskNewPosition(
id: String, id: String,
position: Int, position: Int
): List<String>? ): List<String>?
suspend fun scoreChecklistItem( suspend fun scoreChecklistItem(
taskId: String, taskId: String,
itemId: String, itemId: String
): Task? ): Task?
suspend fun createTask(item: Task): Task? suspend fun createTask(item: Task): Task?
suspend fun createGroupTask( suspend fun createGroupTask(
groupId: String, groupId: String,
item: Task, item: Task
): Task? ): Task?
suspend fun createTasks(tasks: List<Task>): List<Task>? suspend fun createTasks(tasks: List<Task>): List<Task>?
suspend fun updateTask( suspend fun updateTask(
id: String, id: String,
item: Task, item: Task
): Task? ): Task?
suspend fun deleteTask(id: String): Void? suspend fun deleteTask(id: String): Void?
@ -162,7 +162,7 @@ interface ApiClient {
suspend fun updateTag( suspend fun updateTag(
id: String, id: String,
tag: Tag, tag: Tag
): Tag? ): Tag?
suspend fun deleteTag(id: String): Void? suspend fun deleteTag(id: String): Void?
@ -171,18 +171,18 @@ interface ApiClient {
username: String, username: String,
email: String, email: String,
password: String, password: String,
confirmPassword: String, confirmPassword: String
): UserAuthResponse? ): UserAuthResponse?
suspend fun connectUser( suspend fun connectUser(
username: String, username: String,
password: String, password: String
): UserAuthResponse? ): UserAuthResponse?
suspend fun connectSocial( suspend fun connectSocial(
network: String, network: String,
userId: String, userId: String,
accessToken: String, accessToken: String
): UserAuthResponse? ): UserAuthResponse?
suspend fun disconnectSocial(network: String): Void? suspend fun disconnectSocial(network: String): Void?
@ -196,12 +196,12 @@ interface ApiClient {
suspend fun useSkill( suspend fun useSkill(
skillName: String, skillName: String,
targetType: String, targetType: String,
targetId: String, targetId: String
): SkillResponse? ): SkillResponse?
suspend fun useSkill( suspend fun useSkill(
skillName: String, skillName: String,
targetType: String, targetType: String
): SkillResponse? ): SkillResponse?
suspend fun changeClass(className: String?): User? suspend fun changeClass(className: String?): User?
@ -220,12 +220,12 @@ interface ApiClient {
suspend fun updateGroup( suspend fun updateGroup(
id: String, id: String,
item: Group, item: Group
): Group? ): Group?
suspend fun removeMemberFromGroup( suspend fun removeMemberFromGroup(
groupID: String, groupID: String,
userID: String, userID: String
): Void? ): Void?
suspend fun listGroupChat(groupId: String): List<ChatMessage>? suspend fun listGroupChat(groupId: String): List<ChatMessage>?
@ -234,59 +234,59 @@ interface ApiClient {
suspend fun leaveGroup( suspend fun leaveGroup(
groupId: String, groupId: String,
keepChallenges: String, keepChallenges: String
): Void? ): Void?
suspend fun postGroupChat( suspend fun postGroupChat(
groupId: String, groupId: String,
message: Map<String, String>, message: Map<String, String>
): PostChatMessageResult? ): PostChatMessageResult?
suspend fun deleteMessage( suspend fun deleteMessage(
groupId: String, groupId: String,
messageId: String, messageId: String
): Void? ): Void?
suspend fun deleteInboxMessage(id: String): Void? suspend fun deleteInboxMessage(id: String): Void?
suspend fun getGroupMembers( suspend fun getGroupMembers(
groupId: String, groupId: String,
includeAllPublicFields: Boolean?, includeAllPublicFields: Boolean?
): List<Member>? ): List<Member>?
suspend fun getGroupMembers( suspend fun getGroupMembers(
groupId: String, groupId: String,
includeAllPublicFields: Boolean?, includeAllPublicFields: Boolean?,
lastId: String, lastId: String
): List<Member>? ): List<Member>?
// Like returns the full chat list // Like returns the full chat list
suspend fun likeMessage( suspend fun likeMessage(
groupId: String, groupId: String,
mid: String, mid: String
): ChatMessage? ): ChatMessage?
suspend fun flagMessage( suspend fun flagMessage(
groupId: String, groupId: String,
mid: String, mid: String,
data: MutableMap<String, String>, data: MutableMap<String, String>
): Void? ): Void?
suspend fun flagInboxMessage( suspend fun flagInboxMessage(
mid: String, mid: String,
data: MutableMap<String, String>, data: MutableMap<String, String>
): Void? ): Void?
suspend fun reportMember( suspend fun reportMember(
mid: String, mid: String,
data: Map<String, String>, data: Map<String, String>
): Void? ): Void?
suspend fun seenMessages(groupId: String): Void? suspend fun seenMessages(groupId: String): Void?
suspend fun inviteToGroup( suspend fun inviteToGroup(
groupId: String, groupId: String,
inviteData: Map<String, Any>, inviteData: Map<String, Any>
): List<InviteResponse>? ): List<InviteResponse>?
suspend fun rejectGroupInvite(groupId: String): Void? suspend fun rejectGroupInvite(groupId: String): Void?
@ -299,12 +299,12 @@ interface ApiClient {
suspend fun forceStartQuest( suspend fun forceStartQuest(
groupId: String, groupId: String,
group: Group, group: Group
): Quest? ): Quest?
suspend fun inviteToQuest( suspend fun inviteToQuest(
groupId: String, groupId: String,
questKey: String, questKey: String
): Quest? ): Quest?
suspend fun abortQuest(groupId: String): Quest? suspend fun abortQuest(groupId: String): Quest?
@ -339,19 +339,19 @@ interface ApiClient {
suspend fun leaveChallenge( suspend fun leaveChallenge(
challengeId: String, challengeId: String,
body: LeaveChallengeBody, body: LeaveChallengeBody
): Void? ): Void?
suspend fun createChallenge(challenge: Challenge): Challenge? suspend fun createChallenge(challenge: Challenge): Challenge?
suspend fun createChallengeTasks( suspend fun createChallengeTasks(
challengeId: String, challengeId: String,
tasks: List<Task>, tasks: List<Task>
): List<Task>? ): List<Task>?
suspend fun createChallengeTask( suspend fun createChallengeTask(
challengeId: String, challengeId: String,
task: Task, task: Task
): Task? ): Task?
suspend fun updateChallenge(challenge: Challenge): Challenge? suspend fun updateChallenge(challenge: Challenge): Challenge?
@ -375,7 +375,7 @@ interface ApiClient {
fun updateAuthenticationCredentials( fun updateAuthenticationCredentials(
userID: String?, userID: String?,
apiToken: String?, apiToken: String?
) )
fun hasAuthenticationKeys(): Boolean fun hasAuthenticationKeys(): Boolean
@ -384,7 +384,7 @@ interface ApiClient {
suspend fun retrieveInboxMessages( suspend fun retrieveInboxMessages(
uuid: String, uuid: String,
page: Int, page: Int
): List<ChatMessage>? ): List<ChatMessage>?
suspend fun retrieveInboxConversations(): List<InboxConversation>? suspend fun retrieveInboxConversations(): List<InboxConversation>?
@ -401,27 +401,27 @@ interface ApiClient {
suspend fun togglePinnedItem( suspend fun togglePinnedItem(
pinType: String, pinType: String,
path: String, path: String
): Void? ): Void?
suspend fun sendPasswordResetEmail(email: String): Void? suspend fun sendPasswordResetEmail(email: String): Void?
suspend fun updateLoginName( suspend fun updateLoginName(
newLoginName: String, newLoginName: String,
password: String, password: String
): Void? ): Void?
suspend fun updateUsername(newLoginName: String): Void? suspend fun updateUsername(newLoginName: String): Void?
suspend fun updateEmail( suspend fun updateEmail(
newEmail: String, newEmail: String,
password: String, password: String
): Void? ): Void?
suspend fun updatePassword( suspend fun updatePassword(
oldPassword: String, oldPassword: String,
newPassword: String, newPassword: String,
newPasswordConfirmation: String, newPasswordConfirmation: String
): Void? ): Void?
suspend fun allocatePoint(stat: String): Stats? suspend fun allocatePoint(stat: String): Stats?
@ -430,7 +430,7 @@ interface ApiClient {
strength: Int, strength: Int,
intelligence: Int, intelligence: Int,
constitution: Int, constitution: Int,
perception: Int, perception: Int
): Stats? ): Stats?
suspend fun retrieveMarketGear(): Shop? suspend fun retrieveMarketGear(): Shop?
@ -442,17 +442,17 @@ interface ApiClient {
suspend fun findUsernames( suspend fun findUsernames(
username: String, username: String,
context: String?, context: String?,
id: String?, id: String?
): List<FindUsernameResult>? ): List<FindUsernameResult>?
suspend fun transferGems( suspend fun transferGems(
giftedID: String, giftedID: String,
amount: Int, amount: Int
): Void? ): Void?
suspend fun unlinkAllTasks( suspend fun unlinkAllTasks(
challengeID: String?, challengeID: String?,
keepOption: String, keepOption: String
): Void? ): Void?
suspend fun blockMember(userID: String): List<String>? suspend fun blockMember(userID: String): List<String>?
@ -463,37 +463,37 @@ interface ApiClient {
suspend fun assignToTask( suspend fun assignToTask(
taskId: String, taskId: String,
ids: List<String>, ids: List<String>
): Task? ): Task?
suspend fun unassignFromTask( suspend fun unassignFromTask(
taskId: String, taskId: String,
userID: String, userID: String
): Task? ): Task?
suspend fun updateMember( suspend fun updateMember(
memberID: String, memberID: String,
updateData: Map<String, Map<String, Boolean>>, updateData: Map<String, Map<String, Boolean>>
): Member? ): Member?
suspend fun getHallMember(userId: String): Member? suspend fun getHallMember(userId: String): Member?
suspend fun markTaskNeedsWork( suspend fun markTaskNeedsWork(
taskID: String, taskID: String,
userID: String, userID: String
): Task? ): Task?
suspend fun retrievePartySeekingUsers(page: Int): List<Member>? suspend fun retrievePartySeekingUsers(page: Int): List<Member>?
suspend fun getGroupInvites( suspend fun getGroupInvites(
groupId: String, groupId: String,
includeAllPublicFields: Boolean?, includeAllPublicFields: Boolean?
): List<Member>? ): List<Member>?
suspend fun syncUserStats(): User? suspend fun syncUserStats(): User?
suspend fun reportChallenge( suspend fun reportChallenge(
challengeid: String, challengeid: String,
updateData: Map<String, String>, updateData: Map<String, String>
): Void? ): Void?
} }

View file

@ -9,7 +9,7 @@ import kotlinx.coroutines.flow.Flow
interface ChallengeRepository : BaseRepository { interface ChallengeRepository : BaseRepository {
suspend fun retrieveChallenges( suspend fun retrieveChallenges(
page: Int = 0, page: Int = 0,
memberOnly: Boolean, memberOnly: Boolean
): List<Challenge>? ): List<Challenge>?
fun getChallenges(): Flow<List<Challenge>> fun getChallenges(): Flow<List<Challenge>>
@ -24,7 +24,7 @@ interface ChallengeRepository : BaseRepository {
suspend fun createChallenge( suspend fun createChallenge(
challenge: Challenge, challenge: Challenge,
taskList: List<Task>, taskList: List<Task>
): Challenge? ): Challenge?
/** /**
@ -41,7 +41,7 @@ interface ChallengeRepository : BaseRepository {
fullTaskList: List<Task>, fullTaskList: List<Task>,
addedTaskList: List<Task>, addedTaskList: List<Task>,
updatedTaskList: List<Task>, updatedTaskList: List<Task>,
removedTaskList: List<String>, removedTaskList: List<String>
): Challenge? ): Challenge?
suspend fun deleteChallenge(challengeId: String): Void? suspend fun deleteChallenge(challengeId: String): Void?
@ -50,7 +50,7 @@ interface ChallengeRepository : BaseRepository {
suspend fun leaveChallenge( suspend fun leaveChallenge(
challenge: Challenge, challenge: Challenge,
keepTasks: String, keepTasks: String
): Void? ): Void?
suspend fun joinChallenge(challenge: Challenge): Challenge? suspend fun joinChallenge(challenge: Challenge): Challenge?
@ -63,6 +63,6 @@ interface ChallengeRepository : BaseRepository {
suspend fun reportChallenge( suspend fun reportChallenge(
challengeid: String, challengeid: String,
updateData: Map<String, String>, updateData: Map<String, String>
): Void? ): Void?
} }

View file

@ -7,6 +7,6 @@ interface CustomizationRepository : BaseRepository {
fun getCustomizations( fun getCustomizations(
type: String, type: String,
category: String?, category: String?,
onlyAvailable: Boolean, onlyAvailable: Boolean
): Flow<List<Customization>> ): Flow<List<Customization>>
} }

View file

@ -50,12 +50,12 @@ interface InventoryRepository : BaseRepository {
fun getEquipmentType( fun getEquipmentType(
type: String, type: String,
set: String, set: String
): Flow<List<Equipment>> ): Flow<List<Equipment>>
fun getOwnedItems( fun getOwnedItems(
itemType: String, itemType: String,
includeZero: Boolean = false, includeZero: Boolean = false
): Flow<List<OwnedItem>> ): Flow<List<OwnedItem>>
fun getOwnedItems(includeZero: Boolean = false): Flow<Map<String, OwnedItem>> fun getOwnedItems(includeZero: Boolean = false): Flow<Map<String, OwnedItem>>
@ -69,13 +69,13 @@ interface InventoryRepository : BaseRepository {
fun getMounts( fun getMounts(
type: String?, type: String?,
group: String?, group: String?,
color: String?, color: String?
): Flow<List<Mount>> ): Flow<List<Mount>>
fun getPets( fun getPets(
type: String?, type: String?,
group: String?, group: String?,
color: String?, color: String?
): Flow<List<Pet>> ): Flow<List<Pet>>
fun updateOwnedEquipment(user: User) fun updateOwnedEquipment(user: User)
@ -83,35 +83,35 @@ interface InventoryRepository : BaseRepository {
suspend fun changeOwnedCount( suspend fun changeOwnedCount(
type: String, type: String,
key: String, key: String,
amountToAdd: Int, amountToAdd: Int
) )
suspend fun sellItem( suspend fun sellItem(
type: String, type: String,
key: String, key: String
): User? ): User?
suspend fun sellItem(item: OwnedItem): User? suspend fun sellItem(item: OwnedItem): User?
suspend fun equipGear( suspend fun equipGear(
equipment: String, equipment: String,
asCostume: Boolean, asCostume: Boolean
): Items? ): Items?
suspend fun equip( suspend fun equip(
type: String, type: String,
key: String, key: String
): Items? ): Items?
suspend fun feedPet( suspend fun feedPet(
pet: Pet, pet: Pet,
food: Food, food: Food
): FeedResponse? ): FeedResponse?
suspend fun hatchPet( suspend fun hatchPet(
egg: Egg, egg: Egg,
hatchingPotion: HatchingPotion, hatchingPotion: HatchingPotion,
successFunction: () -> Unit, successFunction: () -> Unit
): Items? ): Items?
suspend fun inviteToQuest(quest: QuestContent): Quest? suspend fun inviteToQuest(quest: QuestContent): Quest?
@ -120,7 +120,7 @@ interface InventoryRepository : BaseRepository {
user: User?, user: User?,
id: String, id: String,
value: Double, value: Double,
purchaseQuantity: Int, purchaseQuantity: Int
): BuyResponse? ): BuyResponse?
suspend fun retrieveShopInventory(identifier: String): Shop? suspend fun retrieveShopInventory(identifier: String): Shop?
@ -131,7 +131,7 @@ interface InventoryRepository : BaseRepository {
suspend fun purchaseHourglassItem( suspend fun purchaseHourglassItem(
purchaseType: String, purchaseType: String,
key: String, key: String
): Void? ): Void?
suspend fun purchaseQuest(key: String): Void? suspend fun purchaseQuest(key: String): Void?
@ -141,14 +141,14 @@ interface InventoryRepository : BaseRepository {
suspend fun purchaseItem( suspend fun purchaseItem(
purchaseType: String, purchaseType: String,
key: String, key: String,
purchaseQuantity: Int, purchaseQuantity: Int
): Void? ): Void?
suspend fun togglePinnedItem(item: ShopItem): List<ShopItem>? suspend fun togglePinnedItem(item: ShopItem): List<ShopItem>?
fun getItems( fun getItems(
itemClass: Class<out Item>, itemClass: Class<out Item>,
keys: Array<String>, keys: Array<String>
): Flow<List<Item>> ): Flow<List<Item>>
fun getItems(itemClass: Class<out Item>): Flow<List<Item>> fun getItems(itemClass: Class<out Item>): Flow<List<Item>>
@ -158,7 +158,7 @@ interface InventoryRepository : BaseRepository {
fun getItem( fun getItem(
type: String, type: String,
key: String, key: String
): Flow<Item> ): Flow<Item>
fun getAvailableLimitedItems(): Flow<List<Item>> fun getAvailableLimitedItems(): Flow<List<Item>>

View file

@ -6,13 +6,13 @@ import com.habitrpg.android.habitica.models.user.User
interface SetupCustomizationRepository { interface SetupCustomizationRepository {
fun getCustomizations( fun getCustomizations(
type: String, type: String,
user: User, user: User
): List<SetupCustomization> ): List<SetupCustomization>
fun getCustomizations( fun getCustomizations(
type: String, type: String,
subtype: String?, subtype: String?,
user: User, user: User
): List<SetupCustomization> ): List<SetupCustomization>
companion object { companion object {

View file

@ -26,12 +26,12 @@ interface SocialRepository : BaseRepository {
suspend fun flagMessage( suspend fun flagMessage(
chatMessageID: String, chatMessageID: String,
additionalInfo: String, additionalInfo: String,
groupID: String? = null, groupID: String? = null
): Void? ): Void?
suspend fun reportMember( suspend fun reportMember(
memberID: String, memberID: String,
data: Map<String, String>, data: Map<String, String>
): Void? ): Void?
suspend fun likeMessage(chatMessage: ChatMessage): ChatMessage? suspend fun likeMessage(chatMessage: ChatMessage): ChatMessage?
@ -40,12 +40,12 @@ interface SocialRepository : BaseRepository {
suspend fun postGroupChat( suspend fun postGroupChat(
groupId: String, groupId: String,
messageObject: HashMap<String, String>, messageObject: HashMap<String, String>
): PostChatMessageResult? ): PostChatMessageResult?
suspend fun postGroupChat( suspend fun postGroupChat(
groupId: String, groupId: String,
message: String, message: String
): PostChatMessageResult? ): PostChatMessageResult?
suspend fun retrieveGroup(id: String): Group? suspend fun retrieveGroup(id: String): Group?
@ -54,7 +54,7 @@ interface SocialRepository : BaseRepository {
suspend fun leaveGroup( suspend fun leaveGroup(
id: String?, id: String?,
keepChallenges: Boolean, keepChallenges: Boolean
): Group? ): Group?
suspend fun joinGroup(id: String?): Group? suspend fun joinGroup(id: String?): Group?
@ -65,7 +65,7 @@ interface SocialRepository : BaseRepository {
leader: String?, leader: String?,
type: String?, type: String?,
privacy: String?, privacy: String?,
leaderCreateChallenge: Boolean?, leaderCreateChallenge: Boolean?
): Group? ): Group?
suspend fun updateGroup( suspend fun updateGroup(
@ -73,14 +73,14 @@ interface SocialRepository : BaseRepository {
name: String?, name: String?,
description: String?, description: String?,
leader: String?, leader: String?,
leaderCreateChallenge: Boolean?, leaderCreateChallenge: Boolean?
): Group? ): Group?
fun getInboxMessages(replyToUserID: String?): Flow<RealmResults<ChatMessage>> fun getInboxMessages(replyToUserID: String?): Flow<RealmResults<ChatMessage>>
suspend fun retrieveInboxMessages( suspend fun retrieveInboxMessages(
uuid: String, uuid: String,
page: Int, page: Int
): List<ChatMessage>? ): List<ChatMessage>?
suspend fun retrieveInboxConversations(): List<InboxConversation>? suspend fun retrieveInboxConversations(): List<InboxConversation>?
@ -89,12 +89,12 @@ interface SocialRepository : BaseRepository {
suspend fun postPrivateMessage( suspend fun postPrivateMessage(
recipientId: String, recipientId: String,
messageObject: HashMap<String, String>, messageObject: HashMap<String, String>
): List<ChatMessage>? ): List<ChatMessage>?
suspend fun postPrivateMessage( suspend fun postPrivateMessage(
recipientId: String, recipientId: String,
message: String, message: String
): List<ChatMessage>? ): List<ChatMessage>?
suspend fun getPartyMembers(id: String): Flow<List<Member>> suspend fun getPartyMembers(id: String): Flow<List<Member>>
@ -103,50 +103,50 @@ interface SocialRepository : BaseRepository {
suspend fun retrievePartyMembers( suspend fun retrievePartyMembers(
id: String, id: String,
includeAllPublicFields: Boolean, includeAllPublicFields: Boolean
): List<Member>? ): List<Member>?
suspend fun inviteToGroup( suspend fun inviteToGroup(
id: String, id: String,
inviteData: Map<String, Any>, inviteData: Map<String, Any>
): List<InviteResponse>? ): List<InviteResponse>?
suspend fun retrieveMember( suspend fun retrieveMember(
userId: String?, userId: String?,
fromHall: Boolean = false, fromHall: Boolean = false
): Member? ): Member?
suspend fun findUsernames( suspend fun findUsernames(
username: String, username: String,
context: String? = null, context: String? = null,
id: String? = null, id: String? = null
): List<FindUsernameResult>? ): List<FindUsernameResult>?
suspend fun markPrivateMessagesRead(user: User?) suspend fun markPrivateMessagesRead(user: User?)
fun markSomePrivateMessagesAsRead( fun markSomePrivateMessagesAsRead(
user: User?, user: User?,
messages: List<ChatMessage>, messages: List<ChatMessage>
) )
suspend fun transferGroupOwnership( suspend fun transferGroupOwnership(
groupID: String, groupID: String,
userID: String, userID: String
): Group? ): Group?
suspend fun removeMemberFromGroup( suspend fun removeMemberFromGroup(
groupID: String, groupID: String,
userID: String, userID: String
): List<Member>? ): List<Member>?
suspend fun acceptQuest( suspend fun acceptQuest(
user: User?, user: User?,
partyId: String = "party", partyId: String = "party"
): Void? ): Void?
suspend fun rejectQuest( suspend fun rejectQuest(
user: User?, user: User?,
partyId: String = "party", partyId: String = "party"
): Void? ): Void?
suspend fun leaveQuest(partyId: String): Void? suspend fun leaveQuest(partyId: String): Void?
@ -163,7 +163,7 @@ interface SocialRepository : BaseRepository {
suspend fun transferGems( suspend fun transferGems(
giftedID: String, giftedID: String,
amount: Int, amount: Int
): Void? ): Void?
fun getGroupMembership(id: String): Flow<GroupMembership?> fun getGroupMembership(id: String): Flow<GroupMembership?>
@ -176,13 +176,13 @@ interface SocialRepository : BaseRepository {
suspend fun updateMember( suspend fun updateMember(
memberID: String, memberID: String,
data: Map<String, Map<String, Boolean>>, data: Map<String, Map<String, Boolean>>
): Member? ): Member?
suspend fun retrievePartySeekingUsers(page: Int = 0): List<Member>? suspend fun retrievePartySeekingUsers(page: Int = 0): List<Member>?
suspend fun retrievegroupInvites( suspend fun retrievegroupInvites(
id: String, id: String,
includeAllPublicFields: Boolean, includeAllPublicFields: Boolean
): List<Member>? ): List<Member>?
} }

View file

@ -15,24 +15,24 @@ interface TaskRepository : BaseRepository {
fun getTasks( fun getTasks(
taskType: TaskType, taskType: TaskType,
userID: String? = null, userID: String? = null,
includedGroupIDs: Array<String>, includedGroupIDs: Array<String>
): Flow<List<Task>> ): Flow<List<Task>>
fun saveTasks( fun saveTasks(
userId: String, userId: String,
order: TasksOrder, order: TasksOrder,
tasks: TaskList, tasks: TaskList
) )
suspend fun retrieveTasks( suspend fun retrieveTasks(
userId: String, userId: String,
tasksOrder: TasksOrder, tasksOrder: TasksOrder
): TaskList? ): TaskList?
suspend fun retrieveTasks( suspend fun retrieveTasks(
userId: String, userId: String,
tasksOrder: TasksOrder, tasksOrder: TasksOrder,
dueDate: Date, dueDate: Date
): TaskList? ): TaskList?
suspend fun taskChecked( suspend fun taskChecked(
@ -40,7 +40,7 @@ interface TaskRepository : BaseRepository {
task: Task, task: Task,
up: Boolean, up: Boolean,
force: Boolean, force: Boolean,
notifyFunc: ((TaskScoringResult) -> Unit)?, notifyFunc: ((TaskScoringResult) -> Unit)?
): TaskScoringResult? ): TaskScoringResult?
suspend fun taskChecked( suspend fun taskChecked(
@ -48,12 +48,12 @@ interface TaskRepository : BaseRepository {
taskId: String, taskId: String,
up: Boolean, up: Boolean,
force: Boolean, force: Boolean,
notifyFunc: ((TaskScoringResult) -> Unit)?, notifyFunc: ((TaskScoringResult) -> Unit)?
): TaskScoringResult? ): TaskScoringResult?
suspend fun scoreChecklistItem( suspend fun scoreChecklistItem(
taskId: String, taskId: String,
itemId: String, itemId: String
): Task? ): Task?
fun getTask(taskId: String): Flow<Task> fun getTask(taskId: String): Flow<Task>
@ -62,12 +62,12 @@ interface TaskRepository : BaseRepository {
suspend fun createTask( suspend fun createTask(
task: Task, task: Task,
force: Boolean = false, force: Boolean = false
): Task? ): Task?
suspend fun updateTask( suspend fun updateTask(
task: Task, task: Task,
force: Boolean = false, force: Boolean = false
): Task? ): Task?
suspend fun deleteTask(taskId: String): Void? suspend fun deleteTask(taskId: String): Void?
@ -78,35 +78,35 @@ interface TaskRepository : BaseRepository {
fun markTaskCompleted( fun markTaskCompleted(
taskId: String, taskId: String,
isCompleted: Boolean, isCompleted: Boolean
) )
fun <T : BaseMainObject> modify( fun <T : BaseMainObject> modify(
obj: T, obj: T,
transaction: (T) -> Unit, transaction: (T) -> Unit
) )
fun swapTaskPosition( fun swapTaskPosition(
firstPosition: Int, firstPosition: Int,
secondPosition: Int, secondPosition: Int
) )
suspend fun updateTaskPosition( suspend fun updateTaskPosition(
taskType: TaskType, taskType: TaskType,
taskID: String, taskID: String,
newPosition: Int, newPosition: Int
): List<String>? ): List<String>?
fun getUnmanagedTask(taskid: String): Flow<Task> fun getUnmanagedTask(taskid: String): Flow<Task>
fun updateTaskInBackground( fun updateTaskInBackground(
task: Task, task: Task,
assignChanges: Map<String, MutableList<String>>, assignChanges: Map<String, MutableList<String>>
) )
fun createTaskInBackground( fun createTaskInBackground(
task: Task, task: Task,
assignChanges: Map<String, MutableList<String>>, assignChanges: Map<String, MutableList<String>>
) )
fun getTaskCopies(): Flow<List<Task>> fun getTaskCopies(): Flow<List<Task>>
@ -121,7 +121,7 @@ interface TaskRepository : BaseRepository {
suspend fun unlinkAllTasks( suspend fun unlinkAllTasks(
challengeID: String?, challengeID: String?,
keepOption: String, keepOption: String
): Void? ): Void?
fun getTasksForChallenge(challengeID: String?): Flow<List<Task>> fun getTasksForChallenge(challengeID: String?): Flow<List<Task>>
@ -130,6 +130,6 @@ interface TaskRepository : BaseRepository {
suspend fun markTaskNeedsWork( suspend fun markTaskNeedsWork(
task: Task, task: Task,
userID: String, userID: String
) )
} }

View file

@ -27,13 +27,13 @@ interface UserRepository : BaseRepository {
suspend fun updateUser( suspend fun updateUser(
key: String, key: String,
value: Any?, value: Any?
): User? ): User?
suspend fun retrieveUser( suspend fun retrieveUser(
withTasks: Boolean = false, withTasks: Boolean = false,
forced: Boolean = false, forced: Boolean = false,
overrideExisting: Boolean = false, overrideExisting: Boolean = false
): User? ): User?
suspend fun revive(): Equipment? suspend fun revive(): Equipment?
@ -49,12 +49,12 @@ interface UserRepository : BaseRepository {
suspend fun useSkill( suspend fun useSkill(
key: String, key: String,
target: String?, target: String?,
taskId: String, taskId: String
): SkillResponse? ): SkillResponse?
suspend fun useSkill( suspend fun useSkill(
key: String, key: String,
target: String?, target: String?
): SkillResponse? ): SkillResponse?
suspend fun disableClasses(): User? suspend fun disableClasses(): User?
@ -63,7 +63,7 @@ interface UserRepository : BaseRepository {
suspend fun unlockPath( suspend fun unlockPath(
path: String, path: String,
price: Int, price: Int
): UnlockResponse? ): UnlockResponse?
suspend fun unlockPath(customization: Customization): UnlockResponse? suspend fun unlockPath(customization: Customization): UnlockResponse?
@ -94,18 +94,18 @@ interface UserRepository : BaseRepository {
suspend fun updateLoginName( suspend fun updateLoginName(
newLoginName: String, newLoginName: String,
password: String? = null, password: String? = null
): User? ): User?
suspend fun updateEmail( suspend fun updateEmail(
newEmail: String, newEmail: String,
password: String, password: String
): Void? ): Void?
suspend fun updatePassword( suspend fun updatePassword(
oldPassword: String, oldPassword: String,
newPassword: String, newPassword: String,
newPasswordConfirmation: String, newPasswordConfirmation: String
): Void? ): Void?
suspend fun verifyUsername(username: String): VerifyUsernameResponse? suspend fun verifyUsername(username: String): VerifyUsernameResponse?
@ -116,13 +116,13 @@ interface UserRepository : BaseRepository {
strength: Int, strength: Int,
intelligence: Int, intelligence: Int,
constitution: Int, constitution: Int,
perception: Int, perception: Int
): Stats? ): Stats?
suspend fun useCustomization( suspend fun useCustomization(
type: String, type: String,
category: String?, category: String?,
identifier: String, identifier: String
): User? ): User?
suspend fun retrieveAchievements(): List<Achievement>? suspend fun retrieveAchievements(): List<Achievement>?

View file

@ -73,7 +73,7 @@ class ApiClientImpl(
private val converter: Converter.Factory, private val converter: Converter.Factory,
override val hostConfig: HostConfig, override val hostConfig: HostConfig,
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
@ -115,7 +115,7 @@ class ApiClientImpl(
val timezoneOffset = val timezoneOffset =
-TimeUnit.MINUTES.convert( -TimeUnit.MINUTES.convert(
timeZone.getOffset(calendar.timeInMillis).toLong(), timeZone.getOffset(calendar.timeInMillis).toLong(),
TimeUnit.MILLISECONDS, TimeUnit.MILLISECONDS
) )
val cacheSize: Long = 10 * 1024 * 1024 // 10 MB val cacheSize: Long = 10 * 1024 * 1024 // 10 MB
@ -199,7 +199,7 @@ class ApiClientImpl(
username: String, username: String,
email: String, email: String,
password: String, password: String,
confirmPassword: String, confirmPassword: String
): UserAuthResponse? { ): UserAuthResponse? {
val auth = UserAuth() val auth = UserAuth()
auth.username = username auth.username = username
@ -211,7 +211,7 @@ class ApiClientImpl(
override suspend fun connectUser( override suspend fun connectUser(
username: String, username: String,
password: String, password: String
): UserAuthResponse? { ): UserAuthResponse? {
val auth = UserAuth() val auth = UserAuth()
auth.username = username auth.username = username
@ -222,7 +222,7 @@ class ApiClientImpl(
override suspend fun connectSocial( override suspend fun connectSocial(
network: String, network: String,
userId: String, userId: String,
accessToken: String, accessToken: String
): UserAuthResponse? { ): UserAuthResponse? {
val auth = UserAuthSocial() val auth = UserAuthSocial()
auth.network = network auth.network = network
@ -257,7 +257,7 @@ class ApiClientImpl(
} else if (throwableClass == SocketTimeoutException::class.java || UnknownHostException::class.java == throwableClass || IOException::class.java == throwableClass) { } else if (throwableClass == SocketTimeoutException::class.java || UnknownHostException::class.java == throwableClass || IOException::class.java == throwableClass) {
this.showConnectionProblemDialog( this.showConnectionProblemDialog(
R.string.network_error_no_network_body, R.string.network_error_no_network_body,
isUserInputCall, isUserInputCall
) )
} else if (HttpException::class.java.isAssignableFrom(throwable.javaClass)) { } else if (HttpException::class.java.isAssignableFrom(throwable.javaClass)) {
val error = throwable as HttpException val error = throwable as HttpException
@ -286,7 +286,7 @@ class ApiClientImpl(
showConnectionProblemDialog( showConnectionProblemDialog(
R.string.authentication_error_title, R.string.authentication_error_title,
R.string.authentication_error_body, R.string.authentication_error_body,
isUserInputCall, isUserInputCall
) )
} }
} else if (status in 500..599) { } else if (status in 500..599) {
@ -303,7 +303,7 @@ class ApiClientImpl(
override suspend fun updateMember( override suspend fun updateMember(
memberID: String, memberID: String,
updateData: Map<String, Map<String, Boolean>>, updateData: Map<String, Map<String, Boolean>>
): Member? { ): Member? {
return process { apiService.updateUser(memberID, updateData) } return process { apiService.updateUser(memberID, updateData) }
} }
@ -333,7 +333,7 @@ class ApiClientImpl(
override suspend fun retrieveInboxMessages( override suspend fun retrieveInboxMessages(
uuid: String, uuid: String,
page: Int, page: Int
): List<ChatMessage>? { ): List<ChatMessage>? {
return process { apiService.getInboxMessages(uuid, page) } return process { apiService.getInboxMessages(uuid, page) }
} }
@ -348,7 +348,7 @@ class ApiClientImpl(
private fun showConnectionProblemDialog( private fun showConnectionProblemDialog(
resourceMessageString: Int, resourceMessageString: Int,
isFromUserInput: Boolean, isFromUserInput: Boolean
) { ) {
showConnectionProblemDialog(null, context.getString(resourceMessageString), isFromUserInput) showConnectionProblemDialog(null, context.getString(resourceMessageString), isFromUserInput)
} }
@ -356,12 +356,12 @@ class ApiClientImpl(
private fun showConnectionProblemDialog( private fun showConnectionProblemDialog(
resourceTitleString: Int, resourceTitleString: Int,
resourceMessageString: Int, resourceMessageString: Int,
isFromUserInput: Boolean, isFromUserInput: Boolean
) { ) {
showConnectionProblemDialog( showConnectionProblemDialog(
context.getString(resourceTitleString), context.getString(resourceTitleString),
context.getString(resourceMessageString), context.getString(resourceMessageString),
isFromUserInput, isFromUserInput
) )
} }
@ -370,7 +370,7 @@ class ApiClientImpl(
private fun showConnectionProblemDialog( private fun showConnectionProblemDialog(
resourceTitleString: String?, resourceTitleString: String?,
resourceMessageString: String, resourceMessageString: String,
isFromUserInput: Boolean, isFromUserInput: Boolean
) { ) {
erroredRequestCount += 1 erroredRequestCount += 1
val application = val application =
@ -381,7 +381,7 @@ class ApiClientImpl(
erroredRequestCount, erroredRequestCount,
resourceTitleString, resourceTitleString,
resourceMessageString, resourceMessageString,
isFromUserInput, isFromUserInput
) )
} }
@ -402,7 +402,7 @@ class ApiClientImpl(
override fun updateAuthenticationCredentials( override fun updateAuthenticationCredentials(
userID: String?, userID: String?,
apiToken: String?, apiToken: String?
) { ) {
this.hostConfig.userID = userID ?: "" this.hostConfig.userID = userID ?: ""
this.hostConfig.apiKey = apiToken ?: "" this.hostConfig.apiKey = apiToken ?: ""
@ -415,7 +415,7 @@ class ApiClientImpl(
override suspend fun reportChallenge( override suspend fun reportChallenge(
challengeid: String, challengeid: String,
updateData: Map<String, String>, updateData: Map<String, String>
): Void? { ): Void? {
return process { apiService.reportChallenge(challengeid, updateData) } return process { apiService.reportChallenge(challengeid, updateData) }
} }
@ -438,21 +438,21 @@ class ApiClientImpl(
override suspend fun equipItem( override suspend fun equipItem(
type: String, type: String,
itemKey: String, itemKey: String
): Items? { ): Items? {
return process { apiService.equipItem(type, itemKey) } return process { apiService.equipItem(type, itemKey) }
} }
override suspend fun buyItem( override suspend fun buyItem(
itemKey: String, itemKey: String,
purchaseQuantity: Int, purchaseQuantity: Int
): BuyResponse? { ): BuyResponse? {
return process { apiService.buyItem(itemKey, mapOf(Pair("quantity", purchaseQuantity))) } return process { apiService.buyItem(itemKey, mapOf(Pair("quantity", purchaseQuantity))) }
} }
override suspend fun unlinkAllTasks( override suspend fun unlinkAllTasks(
challengeID: String?, challengeID: String?,
keepOption: String, keepOption: String
): Void? { ): Void? {
return process { apiService.unlinkAllTasks(challengeID, keepOption) } return process { apiService.unlinkAllTasks(challengeID, keepOption) }
} }
@ -464,13 +464,13 @@ class ApiClientImpl(
override suspend fun purchaseItem( override suspend fun purchaseItem(
type: String, type: String,
itemKey: String, itemKey: String,
purchaseQuantity: Int, purchaseQuantity: Int
): Void? { ): Void? {
return process { return process {
apiService.purchaseItem( apiService.purchaseItem(
type, type,
itemKey, itemKey,
mapOf(Pair("quantity", purchaseQuantity)), mapOf(Pair("quantity", purchaseQuantity))
) )
} }
} }
@ -499,7 +499,7 @@ class ApiClientImpl(
override suspend fun purchaseHourglassItem( override suspend fun purchaseHourglassItem(
type: String, type: String,
itemKey: String, itemKey: String
): Void? { ): Void? {
return process { apiService.purchaseHourglassItem(type, itemKey) } return process { apiService.purchaseHourglassItem(type, itemKey) }
} }
@ -518,14 +518,14 @@ class ApiClientImpl(
override suspend fun sellItem( override suspend fun sellItem(
itemType: String, itemType: String,
itemKey: String, itemKey: String
): User? { ): User? {
return process { apiService.sellItem(itemType, itemKey) } return process { apiService.sellItem(itemType, itemKey) }
} }
override suspend fun feedPet( override suspend fun feedPet(
petKey: String, petKey: String,
foodKey: String, foodKey: String
): FeedResponse? { ): FeedResponse? {
val response = apiService.feedPet(petKey, foodKey) val response = apiService.feedPet(petKey, foodKey)
response.data?.message = response.message response.data?.message = response.message
@ -534,7 +534,7 @@ class ApiClientImpl(
override suspend fun hatchPet( override suspend fun hatchPet(
eggKey: String, eggKey: String,
hatchingPotionKey: String, hatchingPotionKey: String
): Items? { ): Items? {
return process { apiService.hatchPet(eggKey, hatchingPotionKey) } return process { apiService.hatchPet(eggKey, hatchingPotionKey) }
} }
@ -547,7 +547,7 @@ class ApiClientImpl(
override suspend fun getTasks( override suspend fun getTasks(
type: String, type: String,
dueDate: String, dueDate: String
): TaskList? { ): TaskList? {
return process { apiService.getTasks(type, dueDate) } return process { apiService.getTasks(type, dueDate) }
} }
@ -566,7 +566,7 @@ class ApiClientImpl(
override suspend fun postTaskDirection( override suspend fun postTaskDirection(
id: String, id: String,
direction: String, direction: String
): TaskDirectionData? { ): TaskDirectionData? {
return process { apiService.postTaskDirection(id, direction) } return process { apiService.postTaskDirection(id, direction) }
} }
@ -577,14 +577,14 @@ class ApiClientImpl(
override suspend fun postTaskNewPosition( override suspend fun postTaskNewPosition(
id: String, id: String,
position: Int, position: Int
): List<String>? { ): List<String>? {
return process { apiService.postTaskNewPosition(id, position) } return process { apiService.postTaskNewPosition(id, position) }
} }
override suspend fun scoreChecklistItem( override suspend fun scoreChecklistItem(
taskId: String, taskId: String,
itemId: String, itemId: String
): Task? { ): Task? {
return process { apiService.scoreChecklistItem(taskId, itemId) } return process { apiService.scoreChecklistItem(taskId, itemId) }
} }
@ -595,7 +595,7 @@ class ApiClientImpl(
override suspend fun createGroupTask( override suspend fun createGroupTask(
groupId: String, groupId: String,
item: Task, item: Task
): Task? { ): Task? {
return process { apiService.createGroupTask(groupId, item) } return process { apiService.createGroupTask(groupId, item) }
} }
@ -606,7 +606,7 @@ class ApiClientImpl(
override suspend fun updateTask( override suspend fun updateTask(
id: String, id: String,
item: Task, item: Task
): Task? { ): Task? {
return process { apiService.updateTask(id, item) } return process { apiService.updateTask(id, item) }
} }
@ -621,7 +621,7 @@ class ApiClientImpl(
override suspend fun updateTag( override suspend fun updateTag(
id: String, id: String,
tag: Tag, tag: Tag
): Tag? { ): Tag? {
return process { apiService.updateTag(id, tag) } return process { apiService.updateTag(id, tag) }
} }
@ -637,14 +637,14 @@ class ApiClientImpl(
override suspend fun useSkill( override suspend fun useSkill(
skillName: String, skillName: String,
targetType: String, targetType: String,
targetId: String, targetId: String
): SkillResponse? { ): SkillResponse? {
return process { apiService.useSkill(skillName, targetType, targetId) } return process { apiService.useSkill(skillName, targetType, targetId) }
} }
override suspend fun useSkill( override suspend fun useSkill(
skillName: String, skillName: String,
targetType: String, targetType: String
): SkillResponse? { ): SkillResponse? {
return process { apiService.useSkill(skillName, targetType) } return process { apiService.useSkill(skillName, targetType) }
} }
@ -679,14 +679,14 @@ class ApiClientImpl(
override suspend fun updateGroup( override suspend fun updateGroup(
id: String, id: String,
item: Group, item: Group
): Group? { ): Group? {
return processResponse(apiService.updateGroup(id, item)) return processResponse(apiService.updateGroup(id, item))
} }
override suspend fun removeMemberFromGroup( override suspend fun removeMemberFromGroup(
groupID: String, groupID: String,
userID: String, userID: String
): Void? { ): Void? {
return processResponse(apiService.removeMemberFromGroup(groupID, userID)) return processResponse(apiService.removeMemberFromGroup(groupID, userID))
} }
@ -701,21 +701,21 @@ class ApiClientImpl(
override suspend fun leaveGroup( override suspend fun leaveGroup(
groupId: String, groupId: String,
keepChallenges: String, keepChallenges: String
): Void? { ): Void? {
return processResponse(apiService.leaveGroup(groupId, keepChallenges)) return processResponse(apiService.leaveGroup(groupId, keepChallenges))
} }
override suspend fun postGroupChat( override suspend fun postGroupChat(
groupId: String, groupId: String,
message: Map<String, String>, message: Map<String, String>
): PostChatMessageResult? { ): PostChatMessageResult? {
return process { apiService.postGroupChat(groupId, message) } return process { apiService.postGroupChat(groupId, message) }
} }
override suspend fun deleteMessage( override suspend fun deleteMessage(
groupId: String, groupId: String,
messageId: String, messageId: String
): Void? { ): Void? {
return process { apiService.deleteMessage(groupId, messageId) } return process { apiService.deleteMessage(groupId, messageId) }
} }
@ -726,7 +726,7 @@ class ApiClientImpl(
override suspend fun getGroupMembers( override suspend fun getGroupMembers(
groupId: String, groupId: String,
includeAllPublicFields: Boolean?, includeAllPublicFields: Boolean?
): List<Member>? { ): List<Member>? {
return processResponse(apiService.getGroupMembers(groupId, includeAllPublicFields)) return processResponse(apiService.getGroupMembers(groupId, includeAllPublicFields))
} }
@ -734,21 +734,21 @@ class ApiClientImpl(
override suspend fun getGroupMembers( override suspend fun getGroupMembers(
groupId: String, groupId: String,
includeAllPublicFields: Boolean?, includeAllPublicFields: Boolean?,
lastId: String, lastId: String
): List<Member>? { ): List<Member>? {
return processResponse(apiService.getGroupMembers(groupId, includeAllPublicFields, lastId)) return processResponse(apiService.getGroupMembers(groupId, includeAllPublicFields, lastId))
} }
override suspend fun likeMessage( override suspend fun likeMessage(
groupId: String, groupId: String,
mid: String, mid: String
): ChatMessage? { ): ChatMessage? {
return process { apiService.likeMessage(groupId, mid) } return process { apiService.likeMessage(groupId, mid) }
} }
override suspend fun reportMember( override suspend fun reportMember(
mid: String, mid: String,
data: Map<String, String>, data: Map<String, String>
): Void? { ): Void? {
return process { apiService.reportMember(mid, data) } return process { apiService.reportMember(mid, data) }
} }
@ -756,14 +756,14 @@ class ApiClientImpl(
override suspend fun flagMessage( override suspend fun flagMessage(
groupId: String, groupId: String,
mid: String, mid: String,
data: MutableMap<String, String>, data: MutableMap<String, String>
): Void? { ): Void? {
return process { apiService.flagMessage(groupId, mid, data) } return process { apiService.flagMessage(groupId, mid, data) }
} }
override suspend fun flagInboxMessage( override suspend fun flagInboxMessage(
mid: String, mid: String,
data: MutableMap<String, String>, data: MutableMap<String, String>
): Void? { ): Void? {
return process { apiService.flagInboxMessage(mid, data) } return process { apiService.flagInboxMessage(mid, data) }
} }
@ -774,7 +774,7 @@ class ApiClientImpl(
override suspend fun inviteToGroup( override suspend fun inviteToGroup(
groupId: String, groupId: String,
inviteData: Map<String, Any>, inviteData: Map<String, Any>
): List<InviteResponse>? { ): List<InviteResponse>? {
return process { apiService.inviteToGroup(groupId, inviteData) } return process { apiService.inviteToGroup(groupId, inviteData) }
} }
@ -785,7 +785,7 @@ class ApiClientImpl(
override suspend fun getGroupInvites( override suspend fun getGroupInvites(
groupId: String, groupId: String,
includeAllPublicFields: Boolean?, includeAllPublicFields: Boolean?
): List<Member>? { ): List<Member>? {
return process { apiService.getGroupInvites(groupId, includeAllPublicFields) } return process { apiService.getGroupInvites(groupId, includeAllPublicFields) }
} }
@ -804,14 +804,14 @@ class ApiClientImpl(
override suspend fun forceStartQuest( override suspend fun forceStartQuest(
groupId: String, groupId: String,
group: Group, group: Group
): Quest? { ): Quest? {
return process { apiService.forceStartQuest(groupId, group) } return process { apiService.forceStartQuest(groupId, group) }
} }
override suspend fun inviteToQuest( override suspend fun inviteToQuest(
groupId: String, groupId: String,
questKey: String, questKey: String
): Quest? { ): Quest? {
return process { apiService.inviteToQuest(groupId, questKey) } return process { apiService.inviteToQuest(groupId, questKey) }
} }
@ -841,7 +841,7 @@ class ApiClientImpl(
override suspend fun markTaskNeedsWork( override suspend fun markTaskNeedsWork(
taskID: String, taskID: String,
userID: String, userID: String
): Task? { ): Task? {
return process { apiService.markTaskNeedsWork(taskID, userID) } return process { apiService.markTaskNeedsWork(taskID, userID) }
} }
@ -863,7 +863,7 @@ class ApiClientImpl(
override suspend fun findUsernames( override suspend fun findUsernames(
username: String, username: String,
context: String?, context: String?,
id: String?, id: String?
): List<FindUsernameResult>? { ): List<FindUsernameResult>? {
return process { apiService.findUsernames(username, context, id) } return process { apiService.findUsernames(username, context, id) }
} }
@ -886,7 +886,7 @@ class ApiClientImpl(
override suspend fun getUserChallenges( override suspend fun getUserChallenges(
page: Int, page: Int,
memberOnly: Boolean, memberOnly: Boolean
): List<Challenge>? { ): List<Challenge>? {
return if (memberOnly) { return if (memberOnly) {
process { apiService.getUserChallenges(page, memberOnly) } process { apiService.getUserChallenges(page, memberOnly) }
@ -909,7 +909,7 @@ class ApiClientImpl(
override suspend fun leaveChallenge( override suspend fun leaveChallenge(
challengeId: String, challengeId: String,
body: LeaveChallengeBody, body: LeaveChallengeBody
): Void? { ): Void? {
return process { apiService.leaveChallenge(challengeId, body) } return process { apiService.leaveChallenge(challengeId, body) }
} }
@ -920,14 +920,14 @@ class ApiClientImpl(
override suspend fun createChallengeTasks( override suspend fun createChallengeTasks(
challengeId: String, challengeId: String,
tasks: List<Task>, tasks: List<Task>
): List<Task>? { ): List<Task>? {
return process { apiService.createChallengeTasks(challengeId, tasks) } return process { apiService.createChallengeTasks(challengeId, tasks) }
} }
override suspend fun createChallengeTask( override suspend fun createChallengeTask(
challengeId: String, challengeId: String,
task: Task, task: Task
): Task? { ): Task? {
return process { apiService.createChallengeTask(challengeId, task) } return process { apiService.createChallengeTask(challengeId, task) }
} }
@ -984,7 +984,7 @@ class ApiClientImpl(
override suspend fun togglePinnedItem( override suspend fun togglePinnedItem(
pinType: String, pinType: String,
path: String, path: String
): Void? { ): Void? {
return process { apiService.togglePinnedItem(pinType, path) } return process { apiService.togglePinnedItem(pinType, path) }
} }
@ -997,7 +997,7 @@ class ApiClientImpl(
override suspend fun updateLoginName( override suspend fun updateLoginName(
newLoginName: String, newLoginName: String,
password: String, password: String
): Void? { ): Void? {
val updateObject = HashMap<String, String>() val updateObject = HashMap<String, String>()
updateObject["username"] = newLoginName updateObject["username"] = newLoginName
@ -1019,7 +1019,7 @@ class ApiClientImpl(
override suspend fun updateEmail( override suspend fun updateEmail(
newEmail: String, newEmail: String,
password: String, password: String
): Void? { ): Void? {
val updateObject = HashMap<String, String>() val updateObject = HashMap<String, String>()
updateObject["newEmail"] = newEmail updateObject["newEmail"] = newEmail
@ -1032,7 +1032,7 @@ class ApiClientImpl(
override suspend fun updatePassword( override suspend fun updatePassword(
oldPassword: String, oldPassword: String,
newPassword: String, newPassword: String,
newPasswordConfirmation: String, newPasswordConfirmation: String
): Void? { ): Void? {
val updateObject = HashMap<String, String>() val updateObject = HashMap<String, String>()
updateObject["password"] = oldPassword updateObject["password"] = oldPassword
@ -1047,14 +1047,14 @@ class ApiClientImpl(
override suspend fun transferGems( override suspend fun transferGems(
giftedID: String, giftedID: String,
amount: Int, amount: Int
): Void? { ): Void? {
return process { return process {
apiService.transferGems( apiService.transferGems(
mapOf( mapOf(
Pair("toUserId", giftedID), Pair("toUserId", giftedID),
Pair("gemAmount", amount), Pair("gemAmount", amount)
), )
) )
} }
} }
@ -1069,14 +1069,14 @@ class ApiClientImpl(
override suspend fun assignToTask( override suspend fun assignToTask(
taskId: String, taskId: String,
ids: List<String>, ids: List<String>
): Task? { ): Task? {
return process { apiService.assignToTask(taskId, ids) } return process { apiService.assignToTask(taskId, ids) }
} }
override suspend fun unassignFromTask( override suspend fun unassignFromTask(
taskId: String, taskId: String,
userID: String, userID: String
): Task? { ): Task? {
return process { apiService.unassignFromTask(taskId, userID) } return process { apiService.unassignFromTask(taskId, userID) }
} }
@ -1085,7 +1085,7 @@ class ApiClientImpl(
strength: Int, strength: Int,
intelligence: Int, intelligence: Int,
constitution: Int, constitution: Int,
perception: Int, perception: Int
): Stats? { ): Stats? {
val body = HashMap<String, Map<String, Int>>() val body = HashMap<String, Map<String, Int>>()
val stats = HashMap<String, Int>() val stats = HashMap<String, Int>()

View file

@ -9,7 +9,7 @@ import com.habitrpg.android.habitica.modules.AuthenticationHandler
abstract class BaseRepositoryImpl<T : BaseLocalRepository>( abstract class BaseRepositoryImpl<T : BaseLocalRepository>(
protected val localRepository: T, protected val localRepository: T,
protected val apiClient: ApiClient, protected val apiClient: ApiClient,
protected val authenticationHandler: AuthenticationHandler, protected val authenticationHandler: AuthenticationHandler
) : BaseRepository { ) : BaseRepository {
val currentUserID: String val currentUserID: String
get() = authenticationHandler.currentUserID ?: "" get() = authenticationHandler.currentUserID ?: ""

View file

@ -16,7 +16,7 @@ import kotlinx.coroutines.flow.Flow
class ChallengeRepositoryImpl( class ChallengeRepositoryImpl(
localRepository: ChallengeLocalRepository, localRepository: ChallengeLocalRepository,
apiClient: ApiClient, apiClient: ApiClient,
authenticationHandler: AuthenticationHandler, authenticationHandler: AuthenticationHandler
) : BaseRepositoryImpl<ChallengeLocalRepository>(localRepository, apiClient, authenticationHandler), ) : BaseRepositoryImpl<ChallengeLocalRepository>(localRepository, apiClient, authenticationHandler),
ChallengeRepository { ChallengeRepository {
override fun isChallengeMember(challengeID: String): Flow<Boolean> { override fun isChallengeMember(challengeID: String): Flow<Boolean> {
@ -25,7 +25,7 @@ class ChallengeRepositoryImpl(
override suspend fun reportChallenge( override suspend fun reportChallenge(
challengeid: String, challengeid: String,
updateData: Map<String, String>, updateData: Map<String, String>
): Void? { ): Void? {
return apiClient.reportChallenge(challengeid, updateData) return apiClient.reportChallenge(challengeid, updateData)
} }
@ -85,18 +85,20 @@ class ChallengeRepositoryImpl(
private suspend fun addChallengeTasks( private suspend fun addChallengeTasks(
challenge: Challenge, challenge: Challenge,
addedTaskList: List<Task>, addedTaskList: List<Task>
) { ) {
val savedTasks: List<Task>? = when { val savedTasks: List<Task>? = when {
addedTaskList.count() == 1 -> addedTaskList.count() == 1 ->
listOf(apiClient.createChallengeTask( listOf(
challenge.id ?: "", apiClient.createChallengeTask(
addedTaskList[0], challenge.id ?: "",
)).filterNotNull() addedTaskList[0]
)
).filterNotNull()
else -> else ->
apiClient.createChallengeTasks( apiClient.createChallengeTasks(
challenge.id ?: "", challenge.id ?: "",
addedTaskList, addedTaskList
) )
} }
if (savedTasks != null) { if (savedTasks != null) {
@ -109,7 +111,7 @@ class ChallengeRepositoryImpl(
override suspend fun createChallenge( override suspend fun createChallenge(
challenge: Challenge, challenge: Challenge,
taskList: List<Task>, taskList: List<Task>
): Challenge? { ): Challenge? {
challenge.tasksOrder = getTaskOrders(taskList) challenge.tasksOrder = getTaskOrders(taskList)
@ -125,7 +127,7 @@ class ChallengeRepositoryImpl(
fullTaskList: List<Task>, fullTaskList: List<Task>,
addedTaskList: List<Task>, addedTaskList: List<Task>,
updatedTaskList: List<Task>, updatedTaskList: List<Task>,
removedTaskList: List<String>, removedTaskList: List<String>
): Challenge? { ): Challenge? {
val savedTasks = updatedTaskList val savedTasks = updatedTaskList
.map { localRepository.getUnmanagedCopy(it) }.mapNotNull { task -> .map { localRepository.getUnmanagedCopy(it) }.mapNotNull { task ->
@ -166,7 +168,7 @@ class ChallengeRepositoryImpl(
override suspend fun retrieveChallenges( override suspend fun retrieveChallenges(
page: Int, page: Int,
memberOnly: Boolean, memberOnly: Boolean
): List<Challenge>? { ): List<Challenge>? {
val challenges = apiClient.getUserChallenges(page, memberOnly) val challenges = apiClient.getUserChallenges(page, memberOnly)
if (challenges != null) { if (challenges != null) {
@ -177,7 +179,7 @@ class ChallengeRepositoryImpl(
override suspend fun leaveChallenge( override suspend fun leaveChallenge(
challenge: Challenge, challenge: Challenge,
keepTasks: String, keepTasks: String
): Void? { ): Void? {
apiClient.leaveChallenge(challenge.id ?: "", LeaveChallengeBody(keepTasks)) apiClient.leaveChallenge(challenge.id ?: "", LeaveChallengeBody(keepTasks))
localRepository.setParticipating(currentUserID, challenge.id ?: "", false) localRepository.setParticipating(currentUserID, challenge.id ?: "", false)

View file

@ -17,7 +17,7 @@ class ContentRepositoryImpl<T : ContentLocalRepository>(
localRepository: T, localRepository: T,
apiClient: ApiClient, apiClient: ApiClient,
context: Context, context: Context,
authenticationHandler: AuthenticationHandler, authenticationHandler: AuthenticationHandler
) : BaseRepositoryImpl<T>(localRepository, apiClient, authenticationHandler), ContentRepository { ) : BaseRepositoryImpl<T>(localRepository, apiClient, authenticationHandler), ContentRepository {
private val mysteryItem = SpecialItem.makeMysteryItem(context) private val mysteryItem = SpecialItem.makeMysteryItem(context)

View file

@ -10,17 +10,17 @@ import kotlinx.coroutines.flow.Flow
class CustomizationRepositoryImpl( class CustomizationRepositoryImpl(
localRepository: CustomizationLocalRepository, localRepository: CustomizationLocalRepository,
apiClient: ApiClient, apiClient: ApiClient,
authenticationHandler: AuthenticationHandler, authenticationHandler: AuthenticationHandler
) : BaseRepositoryImpl<CustomizationLocalRepository>( ) : BaseRepositoryImpl<CustomizationLocalRepository>(
localRepository, localRepository,
apiClient, apiClient,
authenticationHandler, authenticationHandler
), ),
CustomizationRepository { CustomizationRepository {
override fun getCustomizations( override fun getCustomizations(
type: String, type: String,
category: String?, category: String?,
onlyAvailable: Boolean, onlyAvailable: Boolean
): Flow<List<Customization>> { ): Flow<List<Customization>> {
return localRepository.getCustomizations(type, category, onlyAvailable) return localRepository.getCustomizations(type, category, onlyAvailable)
} }

View file

@ -10,7 +10,7 @@ import kotlinx.coroutines.flow.Flow
class FAQRepositoryImpl( class FAQRepositoryImpl(
localRepository: FAQLocalRepository, localRepository: FAQLocalRepository,
apiClient: ApiClient, apiClient: ApiClient,
authenticationHandler: AuthenticationHandler, authenticationHandler: AuthenticationHandler
) : BaseRepositoryImpl<FAQLocalRepository>(localRepository, apiClient, authenticationHandler), ) : BaseRepositoryImpl<FAQLocalRepository>(localRepository, apiClient, authenticationHandler),
FAQRepository { FAQRepository {
override fun getArticle(position: Int): Flow<FAQArticle> { override fun getArticle(position: Int): Flow<FAQArticle> {

View file

@ -35,7 +35,7 @@ class InventoryRepositoryImpl(
localRepository: InventoryLocalRepository, localRepository: InventoryLocalRepository,
apiClient: ApiClient, apiClient: ApiClient,
authenticationHandler: AuthenticationHandler, authenticationHandler: AuthenticationHandler,
var appConfigManager: AppConfigManager, var appConfigManager: AppConfigManager
) : BaseRepositoryImpl<InventoryLocalRepository>(localRepository, apiClient, authenticationHandler), ) : BaseRepositoryImpl<InventoryLocalRepository>(localRepository, apiClient, authenticationHandler),
InventoryRepository { InventoryRepository {
override fun getQuestContent(keys: List<String>) = localRepository.getQuestContent(keys) override fun getQuestContent(keys: List<String>) = localRepository.getQuestContent(keys)
@ -76,20 +76,20 @@ class InventoryRepositoryImpl(
override fun getEquipmentType( override fun getEquipmentType(
type: String, type: String,
set: String, set: String
): Flow<List<Equipment>> { ): Flow<List<Equipment>> {
return localRepository.getEquipmentType(type, set) return localRepository.getEquipmentType(type, set)
} }
override fun getOwnedItems( override fun getOwnedItems(
itemType: String, itemType: String,
includeZero: Boolean, includeZero: Boolean
): Flow<List<OwnedItem>> { ): Flow<List<OwnedItem>> {
return authenticationHandler.userIDFlow.flatMapLatest { return authenticationHandler.userIDFlow.flatMapLatest {
localRepository.getOwnedItems( localRepository.getOwnedItems(
itemType, itemType,
it, it,
includeZero, includeZero
) )
} }
} }
@ -98,14 +98,14 @@ class InventoryRepositoryImpl(
return authenticationHandler.userIDFlow.flatMapLatest { return authenticationHandler.userIDFlow.flatMapLatest {
localRepository.getOwnedItems( localRepository.getOwnedItems(
it, it,
includeZero, includeZero
) )
} }
} }
override fun getItems( override fun getItems(
itemClass: Class<out Item>, itemClass: Class<out Item>,
keys: Array<String>, keys: Array<String>
): Flow<List<Item>> { ): Flow<List<Item>> {
return localRepository.getItems(itemClass, keys) return localRepository.getItems(itemClass, keys)
} }
@ -140,7 +140,7 @@ class InventoryRepositoryImpl(
override fun getMounts( override fun getMounts(
type: String?, type: String?,
group: String?, group: String?,
color: String?, color: String?
): Flow<List<Mount>> { ): Flow<List<Mount>> {
return localRepository.getMounts(type, group, color) return localRepository.getMounts(type, group, color)
} }
@ -156,7 +156,7 @@ class InventoryRepositoryImpl(
override fun getPets( override fun getPets(
type: String?, type: String?,
group: String?, group: String?,
color: String?, color: String?
): Flow<List<Pet>> { ): Flow<List<Pet>> {
return localRepository.getPets(type, group, color) return localRepository.getPets(type, group, color)
} }
@ -172,14 +172,14 @@ class InventoryRepositoryImpl(
override suspend fun changeOwnedCount( override suspend fun changeOwnedCount(
type: String, type: String,
key: String, key: String,
amountToAdd: Int, amountToAdd: Int
) { ) {
localRepository.changeOwnedCount(type, key, currentUserID, amountToAdd) localRepository.changeOwnedCount(type, key, currentUserID, amountToAdd)
} }
override suspend fun sellItem( override suspend fun sellItem(
type: String, type: String,
key: String, key: String
): User? { ): User? {
val item = val item =
localRepository.getOwnedItem(currentUserID, type, key, true).firstOrNull() localRepository.getOwnedItem(currentUserID, type, key, true).firstOrNull()
@ -204,14 +204,14 @@ class InventoryRepositoryImpl(
override fun getItem( override fun getItem(
type: String, type: String,
key: String, key: String
): Flow<Item> { ): Flow<Item> {
return localRepository.getItem(type, key) return localRepository.getItem(type, key)
} }
private suspend fun sellItem( private suspend fun sellItem(
item: Item, item: Item,
ownedItem: OwnedItem, ownedItem: OwnedItem
): User? { ): User? {
localRepository.executeTransaction { localRepository.executeTransaction {
val liveItem = localRepository.getLiveObject(ownedItem) val liveItem = localRepository.getLiveObject(ownedItem)
@ -223,14 +223,14 @@ class InventoryRepositoryImpl(
override suspend fun equipGear( override suspend fun equipGear(
equipment: String, equipment: String,
asCostume: Boolean, asCostume: Boolean
): Items? { ): Items? {
return equip(if (asCostume) "costume" else "equipped", equipment) return equip(if (asCostume) "costume" else "equipped", equipment)
} }
override suspend fun equip( override suspend fun equip(
type: String, type: String,
key: String, key: String
): Items? { ): Items? {
val liveUser = localRepository.getLiveUser(currentUserID) val liveUser = localRepository.getLiveUser(currentUserID)
@ -277,7 +277,7 @@ class InventoryRepositoryImpl(
override suspend fun feedPet( override suspend fun feedPet(
pet: Pet, pet: Pet,
food: Food, food: Food
): FeedResponse? { ): FeedResponse? {
val feedResponse = apiClient.feedPet(pet.key, food.key) ?: return null val feedResponse = apiClient.feedPet(pet.key, food.key) ?: return null
localRepository.feedPet(food.key, pet.key, feedResponse.value ?: 0, currentUserID) localRepository.feedPet(food.key, pet.key, feedResponse.value ?: 0, currentUserID)
@ -287,7 +287,7 @@ class InventoryRepositoryImpl(
override suspend fun hatchPet( override suspend fun hatchPet(
egg: Egg, egg: Egg,
hatchingPotion: HatchingPotion, hatchingPotion: HatchingPotion,
successFunction: () -> Unit, successFunction: () -> Unit
): Items? { ): Items? {
if (appConfigManager.enableLocalChanges()) { if (appConfigManager.enableLocalChanges()) {
localRepository.hatchPet(egg.key, hatchingPotion.key, currentUserID) localRepository.hatchPet(egg.key, hatchingPotion.key, currentUserID)
@ -311,7 +311,7 @@ class InventoryRepositoryImpl(
user: User?, user: User?,
id: String, id: String,
value: Double, value: Double,
purchaseQuantity: Int, purchaseQuantity: Int
): BuyResponse? { ): BuyResponse? {
val buyResponse = apiClient.buyItem(id, purchaseQuantity) ?: return null val buyResponse = apiClient.buyItem(id, purchaseQuantity) ?: return null
val foundUser = user ?: localRepository.getLiveUser(currentUserID) ?: return buyResponse val foundUser = user ?: localRepository.getLiveUser(currentUserID) ?: return buyResponse
@ -359,7 +359,7 @@ class InventoryRepositoryImpl(
override suspend fun purchaseHourglassItem( override suspend fun purchaseHourglassItem(
purchaseType: String, purchaseType: String,
key: String, key: String
): Void? { ): Void? {
return apiClient.purchaseHourglassItem(purchaseType, key) return apiClient.purchaseHourglassItem(purchaseType, key)
} }
@ -375,7 +375,7 @@ class InventoryRepositoryImpl(
override suspend fun purchaseItem( override suspend fun purchaseItem(
purchaseType: String, purchaseType: String,
key: String, key: String,
purchaseQuantity: Int, purchaseQuantity: Int
): Void? { ): Void? {
val response = apiClient.purchaseItem(purchaseType, key, purchaseQuantity) val response = apiClient.purchaseItem(purchaseType, key, purchaseQuantity)
if (key == "gem") { if (key == "gem") {

View file

@ -9,204 +9,204 @@ import javax.inject.Inject
@Suppress("StringLiteralDuplication") @Suppress("StringLiteralDuplication")
class SetupCustomizationRepositoryImpl class SetupCustomizationRepositoryImpl
@Inject @Inject
constructor(private val context: Context) : SetupCustomizationRepository { constructor(private val context: Context) : SetupCustomizationRepository {
private val wheelchairs: List<SetupCustomization> private val wheelchairs: List<SetupCustomization>
get() = get() =
listOf( listOf(
SetupCustomization.createWheelchair("none", 0), SetupCustomization.createWheelchair("none", 0),
SetupCustomization.createWheelchair("black", R.drawable.creator_chair_black), SetupCustomization.createWheelchair("black", R.drawable.creator_chair_black),
SetupCustomization.createWheelchair("blue", R.drawable.creator_chair_blue), SetupCustomization.createWheelchair("blue", R.drawable.creator_chair_blue),
SetupCustomization.createWheelchair("green", R.drawable.creator_chair_green), SetupCustomization.createWheelchair("green", R.drawable.creator_chair_green),
SetupCustomization.createWheelchair("pink", R.drawable.creator_chair_pink), SetupCustomization.createWheelchair("pink", R.drawable.creator_chair_pink),
SetupCustomization.createWheelchair("red", R.drawable.creator_chair_red), SetupCustomization.createWheelchair("red", R.drawable.creator_chair_red),
SetupCustomization.createWheelchair("yellow", R.drawable.creator_chair_yellow), SetupCustomization.createWheelchair("yellow", R.drawable.creator_chair_yellow)
)
private val glasses: List<SetupCustomization>
get() =
listOf(
SetupCustomization.createGlasses("", R.drawable.creator_blank_face),
SetupCustomization.createGlasses(
"eyewear_special_blackTopFrame",
R.drawable.creator_eyewear_special_blacktopframe,
),
SetupCustomization.createGlasses(
"eyewear_special_blueTopFrame",
R.drawable.creator_eyewear_special_bluetopframe,
),
SetupCustomization.createGlasses(
"eyewear_special_greenTopFrame",
R.drawable.creator_eyewear_special_greentopframe,
),
SetupCustomization.createGlasses(
"eyewear_special_pinkTopFrame",
R.drawable.creator_eyewear_special_pinktopframe,
),
SetupCustomization.createGlasses(
"eyewear_special_redTopFrame",
R.drawable.creator_eyewear_special_redtopframe,
),
SetupCustomization.createGlasses(
"eyewear_special_yellowTopFrame",
R.drawable.creator_eyewear_special_yellowtopframe,
),
SetupCustomization.createGlasses(
"eyewear_special_whiteTopFrame",
R.drawable.creator_eyewear_special_whitetopframe,
),
)
private val flowers: List<SetupCustomization>
get() =
listOf(
SetupCustomization.createFlower("0", R.drawable.creator_blank_face),
SetupCustomization.createFlower("1", R.drawable.creator_hair_flower_1),
SetupCustomization.createFlower("2", R.drawable.creator_hair_flower_2),
SetupCustomization.createFlower("3", R.drawable.creator_hair_flower_3),
SetupCustomization.createFlower("4", R.drawable.creator_hair_flower_4),
SetupCustomization.createFlower("5", R.drawable.creator_hair_flower_5),
SetupCustomization.createFlower("6", R.drawable.creator_hair_flower_6),
)
private val hairColors: List<SetupCustomization>
get() =
listOf(
SetupCustomization.createHairColor("white", R.color.hair_white),
SetupCustomization.createHairColor("brown", R.color.hair_brown),
SetupCustomization.createHairColor("blond", R.color.hair_blond),
SetupCustomization.createHairColor("red", R.color.hair_red),
SetupCustomization.createHairColor("black", R.color.hair_black),
)
private val sizes: List<SetupCustomization>
get() =
listOf(
SetupCustomization.createSize(
"slim",
R.drawable.creator_slim_shirt_black,
context.getString(R.string.avatar_size_slim),
),
SetupCustomization.createSize(
"broad",
R.drawable.creator_broad_shirt_black,
context.getString(R.string.avatar_size_broad),
),
)
private val skins: List<SetupCustomization>
get() =
listOf(
SetupCustomization.createSkin("ddc994", R.color.skin_ddc994),
SetupCustomization.createSkin("f5a76e", R.color.skin_f5a76e),
SetupCustomization.createSkin("ea8349", R.color.skin_ea8349),
SetupCustomization.createSkin("c06534", R.color.skin_c06534),
SetupCustomization.createSkin("98461a", R.color.skin_98461a),
SetupCustomization.createSkin("915533", R.color.skin_915533),
SetupCustomization.createSkin("c3e1dc", R.color.skin_c3e1dc),
SetupCustomization.createSkin("6bd049", R.color.skin_6bd049),
)
override fun getCustomizations(
type: String,
user: User,
): List<SetupCustomization> {
return getCustomizations(type, null, user)
}
override fun getCustomizations(
type: String,
subtype: String?,
user: User,
): List<SetupCustomization> {
return when (type) {
SetupCustomizationRepository.CATEGORY_BODY -> {
when (subtype) {
SetupCustomizationRepository.SUBCATEGORY_SIZE -> sizes
SetupCustomizationRepository.SUBCATEGORY_SHIRT ->
getShirts(
user.preferences?.size ?: "slim",
)
else -> emptyList()
}
}
SetupCustomizationRepository.CATEGORY_SKIN -> skins
SetupCustomizationRepository.CATEGORY_HAIR -> {
when (subtype) {
SetupCustomizationRepository.SUBCATEGORY_BANGS ->
getBangs(
user.preferences?.hair?.color ?: "",
)
SetupCustomizationRepository.SUBCATEGORY_PONYTAIL ->
getHairBases(
user.preferences?.hair?.color ?: "",
)
SetupCustomizationRepository.SUBCATEGORY_COLOR -> hairColors
else -> emptyList()
}
}
SetupCustomizationRepository.CATEGORY_EXTRAS -> {
when (subtype) {
SetupCustomizationRepository.SUBCATEGORY_FLOWER -> flowers
SetupCustomizationRepository.SUBCATEGORY_GLASSES -> glasses
SetupCustomizationRepository.SUBCATEGORY_WHEELCHAIR -> wheelchairs
else -> emptyList()
}
}
else -> emptyList()
}
}
private fun getHairBases(color: String): List<SetupCustomization> {
return listOf(
SetupCustomization.createHairPonytail("0", R.drawable.creator_blank_face),
SetupCustomization.createHairPonytail("1", getResId("creator_hair_base_1_$color")),
SetupCustomization.createHairPonytail("3", getResId("creator_hair_base_3_$color")),
) )
}
private fun getBangs(color: String): List<SetupCustomization> { private val glasses: List<SetupCustomization>
return listOf( get() =
SetupCustomization.createHairBangs("0", R.drawable.creator_blank_face), listOf(
SetupCustomization.createHairBangs("1", getResId("creator_hair_bangs_1_$color")), SetupCustomization.createGlasses("", R.drawable.creator_blank_face),
SetupCustomization.createHairBangs("2", getResId("creator_hair_bangs_2_$color")), SetupCustomization.createGlasses(
SetupCustomization.createHairBangs("3", getResId("creator_hair_bangs_3_$color")), "eyewear_special_blackTopFrame",
R.drawable.creator_eyewear_special_blacktopframe
),
SetupCustomization.createGlasses(
"eyewear_special_blueTopFrame",
R.drawable.creator_eyewear_special_bluetopframe
),
SetupCustomization.createGlasses(
"eyewear_special_greenTopFrame",
R.drawable.creator_eyewear_special_greentopframe
),
SetupCustomization.createGlasses(
"eyewear_special_pinkTopFrame",
R.drawable.creator_eyewear_special_pinktopframe
),
SetupCustomization.createGlasses(
"eyewear_special_redTopFrame",
R.drawable.creator_eyewear_special_redtopframe
),
SetupCustomization.createGlasses(
"eyewear_special_yellowTopFrame",
R.drawable.creator_eyewear_special_yellowtopframe
),
SetupCustomization.createGlasses(
"eyewear_special_whiteTopFrame",
R.drawable.creator_eyewear_special_whitetopframe
)
) )
}
private fun getShirts(size: String): List<SetupCustomization> { private val flowers: List<SetupCustomization>
return if (size == "broad") { get() =
listOf( listOf(
SetupCustomization.createShirt("black", R.drawable.creator_broad_shirt_black), SetupCustomization.createFlower("0", R.drawable.creator_blank_face),
SetupCustomization.createShirt("blue", R.drawable.creator_broad_shirt_blue), SetupCustomization.createFlower("1", R.drawable.creator_hair_flower_1),
SetupCustomization.createShirt("green", R.drawable.creator_broad_shirt_green), SetupCustomization.createFlower("2", R.drawable.creator_hair_flower_2),
SetupCustomization.createShirt("pink", R.drawable.creator_broad_shirt_pink), SetupCustomization.createFlower("3", R.drawable.creator_hair_flower_3),
SetupCustomization.createShirt("white", R.drawable.creator_broad_shirt_white), SetupCustomization.createFlower("4", R.drawable.creator_hair_flower_4),
SetupCustomization.createShirt("yellow", R.drawable.creator_broad_shirt_yellow), SetupCustomization.createFlower("5", R.drawable.creator_hair_flower_5),
) SetupCustomization.createFlower("6", R.drawable.creator_hair_flower_6)
} else { )
listOf(
SetupCustomization.createShirt("black", R.drawable.creator_slim_shirt_black),
SetupCustomization.createShirt("blue", R.drawable.creator_slim_shirt_blue),
SetupCustomization.createShirt("green", R.drawable.creator_slim_shirt_green),
SetupCustomization.createShirt("pink", R.drawable.creator_slim_shirt_pink),
SetupCustomization.createShirt("white", R.drawable.creator_slim_shirt_white),
SetupCustomization.createShirt("yellow", R.drawable.creator_slim_shirt_yellow),
)
}
}
private fun getResId(resName: String): Int { private val hairColors: List<SetupCustomization>
return try { get() =
context.resources.getIdentifier(resName, "drawable", context.packageName) listOf(
} catch (e: Exception) { SetupCustomization.createHairColor("white", R.color.hair_white),
-1 SetupCustomization.createHairColor("brown", R.color.hair_brown),
SetupCustomization.createHairColor("blond", R.color.hair_blond),
SetupCustomization.createHairColor("red", R.color.hair_red),
SetupCustomization.createHairColor("black", R.color.hair_black)
)
private val sizes: List<SetupCustomization>
get() =
listOf(
SetupCustomization.createSize(
"slim",
R.drawable.creator_slim_shirt_black,
context.getString(R.string.avatar_size_slim)
),
SetupCustomization.createSize(
"broad",
R.drawable.creator_broad_shirt_black,
context.getString(R.string.avatar_size_broad)
)
)
private val skins: List<SetupCustomization>
get() =
listOf(
SetupCustomization.createSkin("ddc994", R.color.skin_ddc994),
SetupCustomization.createSkin("f5a76e", R.color.skin_f5a76e),
SetupCustomization.createSkin("ea8349", R.color.skin_ea8349),
SetupCustomization.createSkin("c06534", R.color.skin_c06534),
SetupCustomization.createSkin("98461a", R.color.skin_98461a),
SetupCustomization.createSkin("915533", R.color.skin_915533),
SetupCustomization.createSkin("c3e1dc", R.color.skin_c3e1dc),
SetupCustomization.createSkin("6bd049", R.color.skin_6bd049)
)
override fun getCustomizations(
type: String,
user: User
): List<SetupCustomization> {
return getCustomizations(type, null, user)
}
override fun getCustomizations(
type: String,
subtype: String?,
user: User
): List<SetupCustomization> {
return when (type) {
SetupCustomizationRepository.CATEGORY_BODY -> {
when (subtype) {
SetupCustomizationRepository.SUBCATEGORY_SIZE -> sizes
SetupCustomizationRepository.SUBCATEGORY_SHIRT ->
getShirts(
user.preferences?.size ?: "slim"
)
else -> emptyList()
}
} }
SetupCustomizationRepository.CATEGORY_SKIN -> skins
SetupCustomizationRepository.CATEGORY_HAIR -> {
when (subtype) {
SetupCustomizationRepository.SUBCATEGORY_BANGS ->
getBangs(
user.preferences?.hair?.color ?: ""
)
SetupCustomizationRepository.SUBCATEGORY_PONYTAIL ->
getHairBases(
user.preferences?.hair?.color ?: ""
)
SetupCustomizationRepository.SUBCATEGORY_COLOR -> hairColors
else -> emptyList()
}
}
SetupCustomizationRepository.CATEGORY_EXTRAS -> {
when (subtype) {
SetupCustomizationRepository.SUBCATEGORY_FLOWER -> flowers
SetupCustomizationRepository.SUBCATEGORY_GLASSES -> glasses
SetupCustomizationRepository.SUBCATEGORY_WHEELCHAIR -> wheelchairs
else -> emptyList()
}
}
else -> emptyList()
} }
} }
private fun getHairBases(color: String): List<SetupCustomization> {
return listOf(
SetupCustomization.createHairPonytail("0", R.drawable.creator_blank_face),
SetupCustomization.createHairPonytail("1", getResId("creator_hair_base_1_$color")),
SetupCustomization.createHairPonytail("3", getResId("creator_hair_base_3_$color"))
)
}
private fun getBangs(color: String): List<SetupCustomization> {
return listOf(
SetupCustomization.createHairBangs("0", R.drawable.creator_blank_face),
SetupCustomization.createHairBangs("1", getResId("creator_hair_bangs_1_$color")),
SetupCustomization.createHairBangs("2", getResId("creator_hair_bangs_2_$color")),
SetupCustomization.createHairBangs("3", getResId("creator_hair_bangs_3_$color"))
)
}
private fun getShirts(size: String): List<SetupCustomization> {
return if (size == "broad") {
listOf(
SetupCustomization.createShirt("black", R.drawable.creator_broad_shirt_black),
SetupCustomization.createShirt("blue", R.drawable.creator_broad_shirt_blue),
SetupCustomization.createShirt("green", R.drawable.creator_broad_shirt_green),
SetupCustomization.createShirt("pink", R.drawable.creator_broad_shirt_pink),
SetupCustomization.createShirt("white", R.drawable.creator_broad_shirt_white),
SetupCustomization.createShirt("yellow", R.drawable.creator_broad_shirt_yellow)
)
} else {
listOf(
SetupCustomization.createShirt("black", R.drawable.creator_slim_shirt_black),
SetupCustomization.createShirt("blue", R.drawable.creator_slim_shirt_blue),
SetupCustomization.createShirt("green", R.drawable.creator_slim_shirt_green),
SetupCustomization.createShirt("pink", R.drawable.creator_slim_shirt_pink),
SetupCustomization.createShirt("white", R.drawable.creator_slim_shirt_white),
SetupCustomization.createShirt("yellow", R.drawable.creator_slim_shirt_yellow)
)
}
}
private fun getResId(resName: String): Int {
return try {
context.resources.getIdentifier(resName, "drawable", context.packageName)
} catch (e: Exception) {
-1
}
}
}

View file

@ -28,12 +28,12 @@ import java.util.UUID
class SocialRepositoryImpl( class SocialRepositoryImpl(
localRepository: SocialLocalRepository, localRepository: SocialLocalRepository,
apiClient: ApiClient, apiClient: ApiClient,
authenticationHandler: AuthenticationHandler, authenticationHandler: AuthenticationHandler
) : BaseRepositoryImpl<SocialLocalRepository>(localRepository, apiClient, authenticationHandler), ) : BaseRepositoryImpl<SocialLocalRepository>(localRepository, apiClient, authenticationHandler),
SocialRepository { SocialRepository {
override suspend fun transferGroupOwnership( override suspend fun transferGroupOwnership(
groupID: String, groupID: String,
userID: String, userID: String
): Group? { ): Group? {
val group = val group =
localRepository.getGroup(groupID).first()?.let { localRepository.getUnmanagedCopy(it) } localRepository.getGroup(groupID).first()?.let { localRepository.getUnmanagedCopy(it) }
@ -43,7 +43,7 @@ class SocialRepositoryImpl(
override suspend fun removeMemberFromGroup( override suspend fun removeMemberFromGroup(
groupID: String, groupID: String,
userID: String, userID: String
): List<Member>? { ): List<Member>? {
apiClient.removeMemberFromGroup(groupID, userID) apiClient.removeMemberFromGroup(groupID, userID)
return retrievePartyMembers(groupID, true) return retrievePartyMembers(groupID, true)
@ -59,7 +59,7 @@ class SocialRepositoryImpl(
override suspend fun updateMember( override suspend fun updateMember(
memberID: String, memberID: String,
data: Map<String, Map<String, Boolean>>, data: Map<String, Map<String, Boolean>>
): Member? { ): Member? {
return apiClient.updateMember(memberID, data) return apiClient.updateMember(memberID, data)
} }
@ -72,14 +72,14 @@ class SocialRepositoryImpl(
authenticationHandler.userIDFlow.flatMapLatest { authenticationHandler.userIDFlow.flatMapLatest {
localRepository.getGroupMembership( localRepository.getGroupMembership(
it, it,
id, id
) )
} }
override fun getGroupMemberships(): Flow<List<GroupMembership>> { override fun getGroupMemberships(): Flow<List<GroupMembership>> {
return authenticationHandler.userIDFlow.flatMapLatest { return authenticationHandler.userIDFlow.flatMapLatest {
localRepository.getGroupMemberships( localRepository.getGroupMemberships(
it, it
) )
} }
} }
@ -101,7 +101,7 @@ class SocialRepositoryImpl(
override suspend fun flagMessage( override suspend fun flagMessage(
chatMessageID: String, chatMessageID: String,
additionalInfo: String, additionalInfo: String,
groupID: String?, groupID: String?
): Void? { ): Void? {
return when { return when {
chatMessageID.isBlank() -> return null chatMessageID.isBlank() -> return null
@ -120,7 +120,7 @@ class SocialRepositoryImpl(
override suspend fun reportMember( override suspend fun reportMember(
memberID: String, memberID: String,
data: Map<String, String>, data: Map<String, String>
): Void? { ): Void? {
return apiClient.reportMember(memberID, data) return apiClient.reportMember(memberID, data)
} }
@ -147,7 +147,7 @@ class SocialRepositoryImpl(
override suspend fun postGroupChat( override suspend fun postGroupChat(
groupId: String, groupId: String,
messageObject: HashMap<String, String>, messageObject: HashMap<String, String>
): PostChatMessageResult? { ): PostChatMessageResult? {
val result = apiClient.postGroupChat(groupId, messageObject) val result = apiClient.postGroupChat(groupId, messageObject)
result?.message?.groupId = groupId result?.message?.groupId = groupId
@ -156,7 +156,7 @@ class SocialRepositoryImpl(
override suspend fun postGroupChat( override suspend fun postGroupChat(
groupId: String, groupId: String,
message: String, message: String
): PostChatMessageResult? { ): PostChatMessageResult? {
val messageObject = HashMap<String, String>() val messageObject = HashMap<String, String>()
messageObject["message"] = message messageObject["message"] = message
@ -179,7 +179,7 @@ class SocialRepositoryImpl(
override suspend fun leaveGroup( override suspend fun leaveGroup(
id: String?, id: String?,
keepChallenges: Boolean, keepChallenges: Boolean
): Group? { ): Group? {
if (id?.isNotBlank() != true) { if (id?.isNotBlank() != true) {
return null return null
@ -208,7 +208,7 @@ class SocialRepositoryImpl(
leader: String?, leader: String?,
type: String?, type: String?,
privacy: String?, privacy: String?,
leaderCreateChallenge: Boolean?, leaderCreateChallenge: Boolean?
): Group? { ): Group? {
val group = Group() val group = Group()
group.name = name group.name = name
@ -226,7 +226,7 @@ class SocialRepositoryImpl(
name: String?, name: String?,
description: String?, description: String?,
leader: String?, leader: String?,
leaderCreateChallenge: Boolean?, leaderCreateChallenge: Boolean?
): Group? { ): Group? {
if (group == null) { if (group == null) {
return null return null
@ -247,13 +247,13 @@ class SocialRepositoryImpl(
authenticationHandler.userIDFlow.flatMapLatest { authenticationHandler.userIDFlow.flatMapLatest {
localRepository.getInboxMessages( localRepository.getInboxMessages(
it, it,
replyToUserID, replyToUserID
) )
} }
override suspend fun retrieveInboxMessages( override suspend fun retrieveInboxMessages(
uuid: String, uuid: String,
page: Int, page: Int
): List<ChatMessage>? { ): List<ChatMessage>? {
val messages = apiClient.retrieveInboxMessages(uuid, page) ?: return null val messages = apiClient.retrieveInboxMessages(uuid, page) ?: return null
messages.forEach { messages.forEach {
@ -271,7 +271,7 @@ class SocialRepositoryImpl(
override suspend fun postPrivateMessage( override suspend fun postPrivateMessage(
recipientId: String, recipientId: String,
messageObject: HashMap<String, String>, messageObject: HashMap<String, String>
): List<ChatMessage>? { ): List<ChatMessage>? {
apiClient.postPrivateMessage(messageObject) apiClient.postPrivateMessage(messageObject)
return retrieveInboxMessages(recipientId, 0) return retrieveInboxMessages(recipientId, 0)
@ -279,7 +279,7 @@ class SocialRepositoryImpl(
override suspend fun postPrivateMessage( override suspend fun postPrivateMessage(
recipientId: String, recipientId: String,
message: String, message: String
): List<ChatMessage>? { ): List<ChatMessage>? {
val messageObject = HashMap<String, String>() val messageObject = HashMap<String, String>()
messageObject["message"] = message messageObject["message"] = message
@ -293,7 +293,7 @@ class SocialRepositoryImpl(
override suspend fun retrievePartyMembers( override suspend fun retrievePartyMembers(
id: String, id: String,
includeAllPublicFields: Boolean, includeAllPublicFields: Boolean
): List<Member>? { ): List<Member>? {
val members = apiClient.getGroupMembers(id, includeAllPublicFields) val members = apiClient.getGroupMembers(id, includeAllPublicFields)
members?.let { localRepository.savePartyMembers(id, it) } members?.let { localRepository.savePartyMembers(id, it) }
@ -302,13 +302,13 @@ class SocialRepositoryImpl(
override suspend fun inviteToGroup( override suspend fun inviteToGroup(
id: String, id: String,
inviteData: Map<String, Any>, inviteData: Map<String, Any>
) = ) =
apiClient.inviteToGroup(id, inviteData) apiClient.inviteToGroup(id, inviteData)
override suspend fun retrieveMember( override suspend fun retrieveMember(
userId: String?, userId: String?,
fromHall: Boolean, fromHall: Boolean
): Member? { ): Member? {
return if (userId == null) { return if (userId == null) {
null null
@ -328,14 +328,14 @@ class SocialRepositoryImpl(
override suspend fun retrievegroupInvites( override suspend fun retrievegroupInvites(
id: String, id: String,
includeAllPublicFields: Boolean, includeAllPublicFields: Boolean
) = ) =
apiClient.getGroupInvites(id, includeAllPublicFields) apiClient.getGroupInvites(id, includeAllPublicFields)
override suspend fun findUsernames( override suspend fun findUsernames(
username: String, username: String,
context: String?, context: String?,
id: String?, id: String?
): List<FindUsernameResult>? { ): List<FindUsernameResult>? {
return apiClient.findUsernames(username, context, id) return apiClient.findUsernames(username, context, id)
} }
@ -351,7 +351,7 @@ class SocialRepositoryImpl(
override fun markSomePrivateMessagesAsRead( override fun markSomePrivateMessagesAsRead(
user: User?, user: User?,
messages: List<ChatMessage>, messages: List<ChatMessage>
) { ) {
if (user?.isManaged == true) { if (user?.isManaged == true) {
val numOfUnseenMessages = messages.count { !it.isSeen } val numOfUnseenMessages = messages.count { !it.isSeen }
@ -376,7 +376,7 @@ class SocialRepositoryImpl(
override suspend fun acceptQuest( override suspend fun acceptQuest(
user: User?, user: User?,
partyId: String, partyId: String
): Void? { ): Void? {
apiClient.acceptQuest(partyId) apiClient.acceptQuest(partyId)
user?.let { user?.let {
@ -387,7 +387,7 @@ class SocialRepositoryImpl(
override suspend fun rejectQuest( override suspend fun rejectQuest(
user: User?, user: User?,
partyId: String, partyId: String
): Void? { ): Void? {
apiClient.rejectQuest(partyId) apiClient.rejectQuest(partyId)
user?.let { user?.let {
@ -434,7 +434,7 @@ class SocialRepositoryImpl(
override suspend fun transferGems( override suspend fun transferGems(
giftedID: String, giftedID: String,
amount: Int, amount: Int
): Void? { ): Void? {
return apiClient.transferGems(giftedID, amount) return apiClient.transferGems(giftedID, amount)
} }

View file

@ -14,7 +14,7 @@ import kotlinx.coroutines.flow.flatMapLatest
class TagRepositoryImpl( class TagRepositoryImpl(
localRepository: TagLocalRepository, localRepository: TagLocalRepository,
apiClient: ApiClient, apiClient: ApiClient,
authenticationHandler: AuthenticationHandler, authenticationHandler: AuthenticationHandler
) : BaseRepositoryImpl<TagLocalRepository>(localRepository, apiClient, authenticationHandler), ) : BaseRepositoryImpl<TagLocalRepository>(localRepository, apiClient, authenticationHandler),
TagRepository { TagRepository {
override fun getTags() = authenticationHandler.userIDFlow.flatMapLatest { getTags(it) } override fun getTags() = authenticationHandler.userIDFlow.flatMapLatest { getTags(it) }

View file

@ -38,7 +38,7 @@ class TaskRepositoryImpl(
localRepository: TaskLocalRepository, localRepository: TaskLocalRepository,
apiClient: ApiClient, apiClient: ApiClient,
authenticationHandler: AuthenticationHandler, authenticationHandler: AuthenticationHandler,
val appConfigManager: AppConfigManager, val appConfigManager: AppConfigManager
) : BaseRepositoryImpl<TaskLocalRepository>(localRepository, apiClient, authenticationHandler), ) : BaseRepositoryImpl<TaskLocalRepository>(localRepository, apiClient, authenticationHandler),
TaskRepository { TaskRepository {
private var lastTaskAction: Long = 0 private var lastTaskAction: Long = 0
@ -46,25 +46,25 @@ class TaskRepositoryImpl(
override fun getTasks( override fun getTasks(
taskType: TaskType, taskType: TaskType,
userID: String?, userID: String?,
includedGroupIDs: Array<String>, includedGroupIDs: Array<String>
): Flow<List<Task>> = ): Flow<List<Task>> =
this.localRepository.getTasks( this.localRepository.getTasks(
taskType, taskType,
userID ?: authenticationHandler.currentUserID ?: "", userID ?: authenticationHandler.currentUserID ?: "",
includedGroupIDs, includedGroupIDs
) )
override fun saveTasks( override fun saveTasks(
userId: String, userId: String,
order: TasksOrder, order: TasksOrder,
tasks: TaskList, tasks: TaskList
) { ) {
localRepository.saveTasks(userId, order, tasks) localRepository.saveTasks(userId, order, tasks)
} }
override suspend fun retrieveTasks( override suspend fun retrieveTasks(
userId: String, userId: String,
tasksOrder: TasksOrder, tasksOrder: TasksOrder
): TaskList? { ): TaskList? {
val tasks = apiClient.getTasks() ?: return null val tasks = apiClient.getTasks() ?: return null
this.localRepository.saveTasks(userId, tasksOrder, tasks) this.localRepository.saveTasks(userId, tasksOrder, tasks)
@ -76,7 +76,7 @@ class TaskRepositoryImpl(
val tasks = taskList.tasks val tasks = taskList.tasks
this.localRepository.saveCompletedTodos( this.localRepository.saveCompletedTodos(
userId ?: authenticationHandler.currentUserID ?: "", userId ?: authenticationHandler.currentUserID ?: "",
tasks.values, tasks.values
) )
return taskList return taskList
} }
@ -84,7 +84,7 @@ class TaskRepositoryImpl(
override suspend fun retrieveTasks( override suspend fun retrieveTasks(
userId: String, userId: String,
tasksOrder: TasksOrder, tasksOrder: TasksOrder,
dueDate: Date, dueDate: Date
): TaskList? { ): TaskList? {
val formatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZZZ", Locale.US) val formatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZZZ", Locale.US)
val taskList = this.apiClient.getTasks("dailys", formatter.format(dueDate)) ?: return null val taskList = this.apiClient.getTasks("dailys", formatter.format(dueDate)) ?: return null
@ -98,14 +98,14 @@ class TaskRepositoryImpl(
task: Task, task: Task,
up: Boolean, up: Boolean,
force: Boolean, force: Boolean,
notifyFunc: ((TaskScoringResult) -> Unit)?, notifyFunc: ((TaskScoringResult) -> Unit)?
): TaskScoringResult? { ): TaskScoringResult? {
val localData = val localData =
if (user != null && appConfigManager.enableLocalTaskScoring()) { if (user != null && appConfigManager.enableLocalTaskScoring()) {
ScoreTaskLocallyInteractor.score( ScoreTaskLocallyInteractor.score(
user, user,
task, task,
if (up) TaskDirection.UP else TaskDirection.DOWN, if (up) TaskDirection.UP else TaskDirection.DOWN
) )
} else { } else {
null null
@ -127,7 +127,7 @@ class TaskRepositoryImpl(
val res = val res =
this.apiClient.postTaskDirection( this.apiClient.postTaskDirection(
id, id,
(if (up) TaskDirection.UP else TaskDirection.DOWN).text, (if (up) TaskDirection.UP else TaskDirection.DOWN).text
) ?: return null ) ?: return null
// There are cases where the user object is not set correctly. So the app refetches it as a fallback // There are cases where the user object is not set correctly. So the app refetches it as a fallback
val thisUser = val thisUser =
@ -142,8 +142,8 @@ class TaskRepositoryImpl(
mapOf( mapOf(
"type" to (task.type ?: ""), "type" to (task.type ?: ""),
"scored_up" to up, "scored_up" to up,
"value" to task.value, "value" to task.value
), )
) )
if (res.lvl == 0) { if (res.lvl == 0) {
// Team tasks that require approval have weird data that we should just ignore. // Team tasks that require approval have weird data that we should just ignore.
@ -166,7 +166,7 @@ class TaskRepositoryImpl(
res: TaskDirectionData, res: TaskDirectionData,
task: Task, task: Task,
up: Boolean, up: Boolean,
localDelta: Float, localDelta: Float
) { ) {
this.localRepository.executeTransaction { this.localRepository.executeTransaction {
val bgTask = localRepository.getLiveObject(task) ?: return@executeTransaction val bgTask = localRepository.getLiveObject(task) ?: return@executeTransaction
@ -235,13 +235,13 @@ class TaskRepositoryImpl(
bgUser.party?.quest?.progress?.up = ( bgUser.party?.quest?.progress?.up = (
bgUser.party?.quest?.progress?.up bgUser.party?.quest?.progress?.up
?: 0F ?: 0F
) + (res._tmp?.quest?.progressDelta?.toFloat() ?: 0F) ) + (res._tmp?.quest?.progressDelta?.toFloat() ?: 0F)
} }
} }
override suspend fun markTaskNeedsWork( override suspend fun markTaskNeedsWork(
task: Task, task: Task,
userID: String, userID: String
) { ) {
val savedTask = apiClient.markTaskNeedsWork(task.id ?: "", userID) val savedTask = apiClient.markTaskNeedsWork(task.id ?: "", userID)
if (savedTask != null) { if (savedTask != null) {
@ -260,7 +260,7 @@ class TaskRepositoryImpl(
taskId: String, taskId: String,
up: Boolean, up: Boolean,
force: Boolean, force: Boolean,
notifyFunc: ((TaskScoringResult) -> Unit)?, notifyFunc: ((TaskScoringResult) -> Unit)?
): TaskScoringResult? { ): TaskScoringResult? {
val task = localRepository.getTask(taskId).firstOrNull() ?: return null val task = localRepository.getTask(taskId).firstOrNull() ?: return null
return taskChecked(user, task, up, force, notifyFunc) return taskChecked(user, task, up, force, notifyFunc)
@ -268,7 +268,7 @@ class TaskRepositoryImpl(
override suspend fun scoreChecklistItem( override suspend fun scoreChecklistItem(
taskId: String, taskId: String,
itemId: String, itemId: String
): Task? { ): Task? {
val task = apiClient.scoreChecklistItem(taskId, itemId) val task = apiClient.scoreChecklistItem(taskId, itemId)
val updatedItem: ChecklistItem? = task?.checklist?.lastOrNull { itemId == it.id } val updatedItem: ChecklistItem? = task?.checklist?.lastOrNull { itemId == it.id }
@ -284,7 +284,7 @@ class TaskRepositoryImpl(
override suspend fun createTask( override suspend fun createTask(
task: Task, task: Task,
force: Boolean, force: Boolean
): Task? { ): Task? {
val now = Date().time val now = Date().time
if (lastTaskAction > now - 500 && !force) { if (lastTaskAction > now - 500 && !force) {
@ -327,7 +327,7 @@ class TaskRepositoryImpl(
@Suppress("ReturnCount") @Suppress("ReturnCount")
override suspend fun updateTask( override suspend fun updateTask(
task: Task, task: Task,
force: Boolean, force: Boolean
): Task? { ): Task? {
val now = Date().time val now = Date().time
if ((lastTaskAction > now - 500 && !force) || !task.isValid) { if ((lastTaskAction > now - 500 && !force) || !task.isValid) {
@ -368,21 +368,21 @@ class TaskRepositoryImpl(
override fun markTaskCompleted( override fun markTaskCompleted(
taskId: String, taskId: String,
isCompleted: Boolean, isCompleted: Boolean
) { ) {
localRepository.markTaskCompleted(taskId, isCompleted) localRepository.markTaskCompleted(taskId, isCompleted)
} }
override fun <T : BaseMainObject> modify( override fun <T : BaseMainObject> modify(
obj: T, obj: T,
transaction: (T) -> Unit, transaction: (T) -> Unit
) { ) {
localRepository.modify(obj, transaction) localRepository.modify(obj, transaction)
} }
override fun swapTaskPosition( override fun swapTaskPosition(
firstPosition: Int, firstPosition: Int,
secondPosition: Int, secondPosition: Int
) { ) {
localRepository.swapTaskPosition(firstPosition, secondPosition) localRepository.swapTaskPosition(firstPosition, secondPosition)
} }
@ -390,7 +390,7 @@ class TaskRepositoryImpl(
override suspend fun updateTaskPosition( override suspend fun updateTaskPosition(
taskType: TaskType, taskType: TaskType,
taskID: String, taskID: String,
newPosition: Int, newPosition: Int
): List<String>? { ): List<String>? {
val positions = apiClient.postTaskNewPosition(taskID, newPosition) ?: return null val positions = apiClient.postTaskNewPosition(taskID, newPosition) ?: return null
localRepository.updateTaskPositions(positions) localRepository.updateTaskPositions(positions)
@ -402,7 +402,7 @@ class TaskRepositoryImpl(
override fun updateTaskInBackground( override fun updateTaskInBackground(
task: Task, task: Task,
assignChanges: Map<String, MutableList<String>>, assignChanges: Map<String, MutableList<String>>
) { ) {
MainScope().launchCatching { MainScope().launchCatching {
val updatedTask = updateTask(task) ?: return@launchCatching val updatedTask = updateTask(task) ?: return@launchCatching
@ -412,7 +412,7 @@ class TaskRepositoryImpl(
override fun createTaskInBackground( override fun createTaskInBackground(
task: Task, task: Task,
assignChanges: Map<String, MutableList<String>>, assignChanges: Map<String, MutableList<String>>
) { ) {
MainScope().launchCatching { MainScope().launchCatching {
val createdTask = createTask(task) ?: return@launchCatching val createdTask = createTask(task) ?: return@launchCatching
@ -422,7 +422,7 @@ class TaskRepositoryImpl(
private suspend fun handleAssignmentChanges( private suspend fun handleAssignmentChanges(
task: Task, task: Task,
assignChanges: Map<String, MutableList<String>>, assignChanges: Map<String, MutableList<String>>
) { ) {
val taskID = task.id ?: return val taskID = task.id ?: return
assignChanges["assign"]?.let { assignments -> assignChanges["assign"]?.let { assignments ->
@ -474,7 +474,7 @@ class TaskRepositoryImpl(
override suspend fun unlinkAllTasks( override suspend fun unlinkAllTasks(
challengeID: String?, challengeID: String?,
keepOption: String, keepOption: String
): Void? { ): Void? {
return apiClient.unlinkAllTasks(challengeID, keepOption) return apiClient.unlinkAllTasks(challengeID, keepOption)
} }

View file

@ -10,7 +10,7 @@ import kotlinx.coroutines.flow.Flow
class TutorialRepositoryImpl( class TutorialRepositoryImpl(
localRepository: TutorialLocalRepository, localRepository: TutorialLocalRepository,
apiClient: ApiClient, apiClient: ApiClient,
authenticationHandler: AuthenticationHandler, authenticationHandler: AuthenticationHandler
) : BaseRepositoryImpl<TutorialLocalRepository>(localRepository, apiClient, authenticationHandler), ) : BaseRepositoryImpl<TutorialLocalRepository>(localRepository, apiClient, authenticationHandler),
TutorialRepository { TutorialRepository {
override fun getTutorialStep(key: String): Flow<TutorialStep> = override fun getTutorialStep(key: String): Flow<TutorialStep> =

View file

@ -40,7 +40,7 @@ class UserRepositoryImpl(
apiClient: ApiClient, apiClient: ApiClient,
authenticationHandler: AuthenticationHandler, authenticationHandler: AuthenticationHandler,
private val taskRepository: TaskRepository, private val taskRepository: TaskRepository,
private val appConfigManager: AppConfigManager, private val appConfigManager: AppConfigManager
) : BaseRepositoryImpl<UserLocalRepository>(localRepository, apiClient, authenticationHandler), UserRepository { ) : BaseRepositoryImpl<UserLocalRepository>(localRepository, apiClient, authenticationHandler), UserRepository {
companion object { companion object {
private var lastReadNotification: String? = null private var lastReadNotification: String? = null
@ -65,7 +65,7 @@ class UserRepositoryImpl(
private suspend fun updateUser( private suspend fun updateUser(
userID: String, userID: String,
updateData: Map<String, Any?>, updateData: Map<String, Any?>
): User? { ): User? {
val networkUser = apiClient.updateUser(updateData) ?: return null val networkUser = apiClient.updateUser(updateData) ?: return null
val oldUser = localRepository.getUser(userID).firstOrNull() val oldUser = localRepository.getUser(userID).firstOrNull()
@ -75,7 +75,7 @@ class UserRepositoryImpl(
private suspend fun updateUser( private suspend fun updateUser(
userID: String, userID: String,
key: String, key: String,
value: Any?, value: Any?
): User? { ): User? {
return updateUser(userID, mapOf(key to value)) return updateUser(userID, mapOf(key to value))
} }
@ -86,7 +86,7 @@ class UserRepositoryImpl(
override suspend fun updateUser( override suspend fun updateUser(
key: String, key: String,
value: Any?, value: Any?
): User? { ): User? {
return updateUser(currentUserID, key, value) return updateUser(currentUserID, key, value)
} }
@ -95,7 +95,7 @@ class UserRepositoryImpl(
override suspend fun retrieveUser( override suspend fun retrieveUser(
withTasks: Boolean, withTasks: Boolean,
forced: Boolean, forced: Boolean,
overrideExisting: Boolean, overrideExisting: Boolean
): User? { ): User? {
// Only retrieve again after 3 minutes or it's forced. // Only retrieve again after 3 minutes or it's forced.
if (forced || lastSync == null || Date().time - (lastSync?.time ?: 0) > 180000) { if (forced || lastSync == null || Date().time - (lastSync?.time ?: 0) > 180000) {
@ -164,7 +164,7 @@ class UserRepositoryImpl(
override suspend fun useSkill( override suspend fun useSkill(
key: String, key: String,
target: String?, target: String?,
taskId: String, taskId: String
): SkillResponse? { ): SkillResponse? {
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
@ -178,7 +178,7 @@ class UserRepositoryImpl(
override suspend fun useSkill( override suspend fun useSkill(
key: String, key: String,
target: String?, target: String?
): SkillResponse? { ): SkillResponse? {
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
@ -203,7 +203,7 @@ class UserRepositoryImpl(
override suspend fun unlockPath( override suspend fun unlockPath(
path: String, path: String,
price: Int, price: Int
): UnlockResponse? { ): UnlockResponse? {
val unlockResponse = apiClient.unlockPath(path) ?: return null val unlockResponse = apiClient.unlockPath(path) ?: return null
val user = localRepository.getUser(currentUserID).firstOrNull() ?: return unlockResponse val user = localRepository.getUser(currentUserID).firstOrNull() ?: return unlockResponse
@ -284,7 +284,7 @@ class UserRepositoryImpl(
override suspend fun updateLoginName( override suspend fun updateLoginName(
newLoginName: String, newLoginName: String,
password: String?, password: String?
): User? { ): User? {
if (!password.isNullOrEmpty()) { if (!password.isNullOrEmpty()) {
apiClient.updateLoginName(newLoginName.trim(), password.trim()) apiClient.updateLoginName(newLoginName.trim(), password.trim())
@ -303,13 +303,13 @@ class UserRepositoryImpl(
override suspend fun updateEmail( override suspend fun updateEmail(
newEmail: String, newEmail: String,
password: String, password: String
) = apiClient.updateEmail(newEmail.trim(), password) ) = apiClient.updateEmail(newEmail.trim(), password)
override suspend fun updatePassword( override suspend fun updatePassword(
oldPassword: String, oldPassword: String,
newPassword: String, newPassword: String,
newPasswordConfirmation: String, newPasswordConfirmation: String
) = apiClient.updatePassword(oldPassword.trim(), newPassword.trim(), newPasswordConfirmation.trim()) ) = apiClient.updatePassword(oldPassword.trim(), newPassword.trim(), newPasswordConfirmation.trim())
override suspend fun allocatePoint(stat: Attribute): Stats? { override suspend fun allocatePoint(stat: Attribute): Stats? {
@ -343,14 +343,14 @@ class UserRepositoryImpl(
strength: Int, strength: Int,
intelligence: Int, intelligence: Int,
constitution: Int, constitution: Int,
perception: Int, perception: Int
): Stats? { ): Stats? {
val stats = val stats =
apiClient.bulkAllocatePoints( apiClient.bulkAllocatePoints(
strength, strength,
intelligence, intelligence,
constitution, constitution,
perception, perception
) ?: return null ) ?: return null
val user = getLiveUser() val user = getLiveUser()
if (user != null) { if (user != null) {
@ -391,7 +391,7 @@ class UserRepositoryImpl(
override suspend fun useCustomization( override suspend fun useCustomization(
type: String, type: String,
category: String?, category: String?,
identifier: String, identifier: String
): User? { ): User? {
if (appConfigManager.enableLocalChanges()) { if (appConfigManager.enableLocalChanges()) {
val liveUser = getLiveUser() val liveUser = getLiveUser()
@ -466,7 +466,7 @@ class UserRepositoryImpl(
localRepository.save( localRepository.save(
members.map { members.map {
GroupMembership(it.id, id) GroupMembership(it.id, id)
}, }
) )
members.let { localRepository.save(members) } members.let { localRepository.save(members) }
return team return team
@ -494,7 +494,7 @@ class UserRepositoryImpl(
private fun mergeUser( private fun mergeUser(
oldUser: User?, oldUser: User?,
newUser: User, newUser: User
): User { ): User {
if (oldUser == null || !oldUser.isValid) { if (oldUser == null || !oldUser.isValid) {
return oldUser ?: newUser return oldUser ?: newUser

View file

@ -15,7 +15,7 @@ interface BaseLocalRepository {
fun <T : BaseMainObject> modify( fun <T : BaseMainObject> modify(
obj: T, obj: T,
transaction: (T) -> Unit, transaction: (T) -> Unit
) )
fun <T : BaseObject> getLiveObject(obj: T): T? fun <T : BaseObject> getLiveObject(obj: T): T?

View file

@ -17,25 +17,25 @@ interface ChallengeLocalRepository : BaseLocalRepository {
fun setParticipating( fun setParticipating(
userID: String, userID: String,
challengeID: String, challengeID: String,
isParticipating: Boolean, isParticipating: Boolean
) )
fun saveChallenges( fun saveChallenges(
challenges: List<Challenge>, challenges: List<Challenge>,
clearChallenges: Boolean, clearChallenges: Boolean,
memberOnly: Boolean, memberOnly: Boolean,
userID: String, userID: String
) )
fun getChallengeMembership( fun getChallengeMembership(
userId: String, userId: String,
id: String, id: String
): Flow<ChallengeMembership> ): Flow<ChallengeMembership>
fun getChallengeMemberships(userId: String): Flow<List<ChallengeMembership>> fun getChallengeMemberships(userId: String): Flow<List<ChallengeMembership>>
fun isChallengeMember( fun isChallengeMember(
userID: String, userID: String,
challengeID: String, challengeID: String
): Flow<Boolean> ): Flow<Boolean>
} }

View file

@ -7,6 +7,6 @@ interface CustomizationLocalRepository : ContentLocalRepository {
fun getCustomizations( fun getCustomizations(
type: String, type: String,
category: String?, category: String?,
onlyAvailable: Boolean, onlyAvailable: Boolean
): Flow<List<Customization>> ): Flow<List<Customization>>
} }

View file

@ -42,17 +42,17 @@ interface InventoryLocalRepository : ContentLocalRepository {
fun getOwnedItems( fun getOwnedItems(
itemType: String, itemType: String,
userID: String, userID: String,
includeZero: Boolean, includeZero: Boolean
): Flow<List<OwnedItem>> ): Flow<List<OwnedItem>>
fun getOwnedItems( fun getOwnedItems(
userID: String, userID: String,
includeZero: Boolean, includeZero: Boolean
): Flow<Map<String, OwnedItem>> ): Flow<Map<String, OwnedItem>>
fun getEquipmentType( fun getEquipmentType(
type: String, type: String,
set: String, set: String
): Flow<List<Equipment>> ): Flow<List<Equipment>>
fun getEquipment(key: String): Flow<Equipment> fun getEquipment(key: String): Flow<Equipment>
@ -60,13 +60,13 @@ interface InventoryLocalRepository : ContentLocalRepository {
fun getMounts( fun getMounts(
type: String?, type: String?,
group: String?, group: String?,
color: String?, color: String?
): Flow<List<Mount>> ): Flow<List<Mount>>
fun getPets( fun getPets(
type: String?, type: String?,
group: String?, group: String?,
color: String?, color: String?
): Flow<List<Pet>> ): Flow<List<Pet>>
fun updateOwnedEquipment(user: User) fun updateOwnedEquipment(user: User)
@ -75,24 +75,24 @@ interface InventoryLocalRepository : ContentLocalRepository {
type: String, type: String,
key: String, key: String,
userID: String, userID: String,
amountToAdd: Int, amountToAdd: Int
) )
fun changeOwnedCount( fun changeOwnedCount(
item: OwnedItem, item: OwnedItem,
amountToAdd: Int?, amountToAdd: Int?
) )
fun getItem( fun getItem(
type: String, type: String,
key: String, key: String
): Flow<Item> ): Flow<Item>
fun getOwnedItem( fun getOwnedItem(
userID: String, userID: String,
type: String, type: String,
key: String, key: String,
includeZero: Boolean, includeZero: Boolean
): Flow<OwnedItem> ): Flow<OwnedItem>
fun decrementMysteryItemCount(user: User?) fun decrementMysteryItemCount(user: User?)
@ -102,20 +102,20 @@ interface InventoryLocalRepository : ContentLocalRepository {
fun hatchPet( fun hatchPet(
eggKey: String, eggKey: String,
potionKey: String, potionKey: String,
userID: String, userID: String
) )
fun unhatchPet( fun unhatchPet(
eggKey: String, eggKey: String,
potionKey: String, potionKey: String,
userID: String, userID: String
) )
fun feedPet( fun feedPet(
foodKey: String, foodKey: String,
petKey: String, petKey: String,
feedValue: Int, feedValue: Int,
userID: String, userID: String
) )
fun getLatestMysteryItem(): Flow<Equipment> fun getLatestMysteryItem(): Flow<Equipment>
@ -123,14 +123,14 @@ interface InventoryLocalRepository : ContentLocalRepository {
fun soldItem( fun soldItem(
userID: String, userID: String,
updatedUser: User, updatedUser: User
): User ): User
fun getAvailableLimitedItems(): Flow<List<Item>> fun getAvailableLimitedItems(): Flow<List<Item>>
fun save( fun save(
items: Items, items: Items,
userID: String, userID: String
) )
fun getLiveObject(obj: OwnedItem): OwnedItem? fun getLiveObject(obj: OwnedItem): OwnedItem?
@ -139,6 +139,6 @@ interface InventoryLocalRepository : ContentLocalRepository {
fun getItems( fun getItems(
itemClass: Class<out Item>, itemClass: Class<out Item>,
keys: Array<String>, keys: Array<String>
): Flow<List<Item>> ): Flow<List<Item>>
} }

View file

@ -12,7 +12,7 @@ import kotlinx.coroutines.flow.Flow
interface SocialLocalRepository : BaseLocalRepository { interface SocialLocalRepository : BaseLocalRepository {
fun getUserGroups( fun getUserGroups(
userID: String, userID: String,
type: String?, type: String?
): Flow<List<Group>> ): Flow<List<Group>>
fun getGroup(id: String): Flow<Group?> fun getGroup(id: String): Flow<Group?>
@ -29,30 +29,30 @@ interface SocialLocalRepository : BaseLocalRepository {
fun updateRSVPNeeded( fun updateRSVPNeeded(
user: User?, user: User?,
newValue: Boolean, newValue: Boolean
) )
fun likeMessage( fun likeMessage(
chatMessage: ChatMessage, chatMessage: ChatMessage,
userId: String, userId: String,
liked: Boolean, liked: Boolean
) )
fun savePartyMembers( fun savePartyMembers(
groupId: String?, groupId: String?,
members: List<Member>, members: List<Member>
) )
fun removeQuest(partyId: String) fun removeQuest(partyId: String)
fun setQuestActivity( fun setQuestActivity(
party: Group?, party: Group?,
active: Boolean, active: Boolean
) )
fun saveChatMessages( fun saveChatMessages(
groupId: String?, groupId: String?,
chatMessages: List<ChatMessage>, chatMessages: List<ChatMessage>
) )
fun doesGroupExist(id: String): Boolean fun doesGroupExist(id: String): Boolean
@ -60,43 +60,43 @@ interface SocialLocalRepository : BaseLocalRepository {
fun updateMembership( fun updateMembership(
userId: String, userId: String,
id: String, id: String,
isMember: Boolean, isMember: Boolean
) )
fun getGroupMembership( fun getGroupMembership(
userId: String, userId: String,
id: String, id: String
): Flow<GroupMembership?> ): Flow<GroupMembership?>
fun getGroupMemberships(userId: String): Flow<List<GroupMembership>> fun getGroupMemberships(userId: String): Flow<List<GroupMembership>>
fun rejectGroupInvitation( fun rejectGroupInvitation(
userID: String, userID: String,
groupID: String, groupID: String
) )
fun getInboxMessages( fun getInboxMessages(
userId: String, userId: String,
replyToUserID: String?, replyToUserID: String?
): Flow<RealmResults<ChatMessage>> ): Flow<RealmResults<ChatMessage>>
fun getInboxConversation(userId: String): Flow<RealmResults<InboxConversation>> fun getInboxConversation(userId: String): Flow<RealmResults<InboxConversation>>
fun saveGroupMemberships( fun saveGroupMemberships(
userID: String?, userID: String?,
memberships: List<GroupMembership>, memberships: List<GroupMembership>
) )
fun saveInboxMessages( fun saveInboxMessages(
userID: String, userID: String,
recipientID: String, recipientID: String,
messages: List<ChatMessage>, messages: List<ChatMessage>,
page: Int, page: Int
) )
fun saveInboxConversations( fun saveInboxConversations(
userID: String, userID: String,
conversations: List<InboxConversation>, conversations: List<InboxConversation>
) )
fun getMember(userID: String?): Flow<Member?> fun getMember(userID: String?): Flow<Member?>

View file

@ -11,7 +11,7 @@ interface TaskLocalRepository : BaseLocalRepository {
fun getTasks( fun getTasks(
taskType: TaskType, taskType: TaskType,
userID: String, userID: String,
includedGroupIDs: Array<String>, includedGroupIDs: Array<String>
): Flow<List<Task>> ): Flow<List<Task>>
fun getTasks(userId: String): Flow<List<Task>> fun getTasks(userId: String): Flow<List<Task>>
@ -19,7 +19,7 @@ interface TaskLocalRepository : BaseLocalRepository {
fun saveTasks( fun saveTasks(
ownerID: String, ownerID: String,
tasksOrder: TasksOrder, tasksOrder: TasksOrder,
tasks: TaskList, tasks: TaskList
) )
fun deleteTask(taskID: String) fun deleteTask(taskID: String)
@ -30,17 +30,17 @@ interface TaskLocalRepository : BaseLocalRepository {
fun markTaskCompleted( fun markTaskCompleted(
taskId: String, taskId: String,
isCompleted: Boolean, isCompleted: Boolean
) )
fun swapTaskPosition( fun swapTaskPosition(
firstPosition: Int, firstPosition: Int,
secondPosition: Int, secondPosition: Int
) )
fun getTaskAtPosition( fun getTaskAtPosition(
taskType: String, taskType: String,
position: Int, position: Int
): Flow<Task> ): Flow<Task>
fun updateIsdue(daily: TaskList): TaskList fun updateIsdue(daily: TaskList): TaskList
@ -49,7 +49,7 @@ interface TaskLocalRepository : BaseLocalRepository {
fun saveCompletedTodos( fun saveCompletedTodos(
userId: String, userId: String,
tasks: MutableCollection<Task>, tasks: MutableCollection<Task>
) )
fun getErroredTasks(userID: String): Flow<List<Task>> fun getErroredTasks(userID: String): Flow<List<Task>>
@ -58,6 +58,6 @@ interface TaskLocalRepository : BaseLocalRepository {
fun getTasksForChallenge( fun getTasksForChallenge(
challengeID: String?, challengeID: String?,
userID: String?, userID: String?
): Flow<List<Task>> ): Flow<List<Task>>
} }

View file

@ -19,7 +19,7 @@ interface UserLocalRepository : BaseLocalRepository {
fun saveUser( fun saveUser(
user: User, user: User,
overrideExisting: Boolean = true, overrideExisting: Boolean = true
) )
fun saveMessages(messages: List<ChatMessage>) fun saveMessages(messages: List<ChatMessage>)

View file

@ -16,129 +16,129 @@ import java.util.concurrent.atomic.AtomicBoolean
abstract class RealmBaseLocalRepository internal constructor(override var realm: Realm) : abstract class RealmBaseLocalRepository internal constructor(override var realm: Realm) :
BaseLocalRepository { BaseLocalRepository {
override val isClosed: Boolean override val isClosed: Boolean
get() = realm.isClosed get() = realm.isClosed
override fun close() { override fun close() {
realm.close() realm.close()
} }
override fun executeTransaction(transaction: (Realm) -> Unit) { override fun executeTransaction(transaction: (Realm) -> Unit) {
pendingSaves.add(transaction) pendingSaves.add(transaction)
if (isSaving.compareAndSet(false, true)) { if (isSaving.compareAndSet(false, true)) {
process() process()
}
}
override fun <T : BaseObject> getUnmanagedCopy(managedObject: T): T {
return if (managedObject is RealmObject && managedObject.isManaged && managedObject.isValid) {
realm.copyFromRealm(managedObject)
} else {
managedObject
}
}
override fun <T : BaseObject> getUnmanagedCopy(list: List<T>): List<T> {
if (isClosed) {
return emptyList()
}
return realm.copyFromRealm(list)
}
companion object {
private var isSaving = AtomicBoolean(false)
private var pendingSaves = mutableListOf<Any>()
}
private fun <T : RealmModel> copy(
realm: Realm,
obj: T,
) {
try {
realm.insertOrUpdate(obj)
} catch (_: java.lang.IllegalArgumentException) {
}
}
private fun process() {
if (isClosed) {
return
}
realm.executeTransaction {
while (pendingSaves.isNotEmpty()) {
val pending = pendingSaves.removeFirst()
@Suppress("UNCHECKED_CAST")
if (pending is RealmModel) {
copy(it, pending)
} else if (pending as? List<BaseObject> != null) {
it.insertOrUpdate(pending)
} else if (pending is Function0<*>) {
pending.invoke()
} else if (pending as? Function1<Realm, *> != null) {
pending.invoke(it)
}
}
isSaving.set(false)
}
}
override fun <T : BaseObject> save(obj: T) {
pendingSaves.add(obj)
if (isSaving.compareAndSet(false, true)) {
process()
}
}
override fun <T : BaseObject> save(objects: List<T>) {
pendingSaves.add(objects)
if (isSaving.compareAndSet(false, true)) {
process()
}
}
override fun <T : BaseMainObject> modify(
obj: T,
transaction: (T) -> Unit,
) {
if (isClosed) {
return
}
val liveObject = getLiveObject(obj) ?: return
executeTransaction {
transaction(liveObject)
}
}
override fun <T : BaseMainObject> delete(obj: T) {
if (isClosed) {
return
}
val liveObject = getLiveObject(obj) ?: return
executeTransaction {
liveObject.deleteFromRealm()
}
}
override fun getLiveUser(id: String): User? {
return realm.where(User::class.java).equalTo("id", id).findFirst()
}
override fun <T : BaseObject> getLiveObject(obj: T): T? {
if (isClosed) return null
if (obj !is RealmObject || !obj.isManaged) return obj
val baseObject = obj as? BaseMainObject ?: return null
@Suppress("UNCHECKED_CAST")
return realm.where(baseObject.realmClass)
.equalTo(baseObject.primaryIdentifierName, baseObject.primaryIdentifier)
.findFirst() as? T
}
fun queryUser(userID: String): Flow<User?> {
return realm.where(User::class.java)
.equalTo("id", userID)
.findAll()
.toFlow()
.filter { it.isLoaded && it.isValid && !it.isEmpty() }
.map { it.firstOrNull() }
} }
} }
override fun <T : BaseObject> getUnmanagedCopy(managedObject: T): T {
return if (managedObject is RealmObject && managedObject.isManaged && managedObject.isValid) {
realm.copyFromRealm(managedObject)
} else {
managedObject
}
}
override fun <T : BaseObject> getUnmanagedCopy(list: List<T>): List<T> {
if (isClosed) {
return emptyList()
}
return realm.copyFromRealm(list)
}
companion object {
private var isSaving = AtomicBoolean(false)
private var pendingSaves = mutableListOf<Any>()
}
private fun <T : RealmModel> copy(
realm: Realm,
obj: T
) {
try {
realm.insertOrUpdate(obj)
} catch (_: java.lang.IllegalArgumentException) {
}
}
private fun process() {
if (isClosed) {
return
}
realm.executeTransaction {
while (pendingSaves.isNotEmpty()) {
val pending = pendingSaves.removeFirst()
@Suppress("UNCHECKED_CAST")
if (pending is RealmModel) {
copy(it, pending)
} else if (pending as? List<BaseObject> != null) {
it.insertOrUpdate(pending)
} else if (pending is Function0<*>) {
pending.invoke()
} else if (pending as? Function1<Realm, *> != null) {
pending.invoke(it)
}
}
isSaving.set(false)
}
}
override fun <T : BaseObject> save(obj: T) {
pendingSaves.add(obj)
if (isSaving.compareAndSet(false, true)) {
process()
}
}
override fun <T : BaseObject> save(objects: List<T>) {
pendingSaves.add(objects)
if (isSaving.compareAndSet(false, true)) {
process()
}
}
override fun <T : BaseMainObject> modify(
obj: T,
transaction: (T) -> Unit
) {
if (isClosed) {
return
}
val liveObject = getLiveObject(obj) ?: return
executeTransaction {
transaction(liveObject)
}
}
override fun <T : BaseMainObject> delete(obj: T) {
if (isClosed) {
return
}
val liveObject = getLiveObject(obj) ?: return
executeTransaction {
liveObject.deleteFromRealm()
}
}
override fun getLiveUser(id: String): User? {
return realm.where(User::class.java).equalTo("id", id).findFirst()
}
override fun <T : BaseObject> getLiveObject(obj: T): T? {
if (isClosed) return null
if (obj !is RealmObject || !obj.isManaged) return obj
val baseObject = obj as? BaseMainObject ?: return null
@Suppress("UNCHECKED_CAST")
return realm.where(baseObject.realmClass)
.equalTo(baseObject.primaryIdentifierName, baseObject.primaryIdentifier)
.findFirst() as? T
}
fun queryUser(userID: String): Flow<User?> {
return realm.where(User::class.java)
.equalTo("id", userID)
.findAll()
.toFlow()
.filter { it.isLoaded && it.isValid && !it.isEmpty() }
.map { it.firstOrNull() }
}
}

View file

@ -20,7 +20,7 @@ class RealmChallengeLocalRepository(realm: Realm) :
ChallengeLocalRepository { ChallengeLocalRepository {
override fun isChallengeMember( override fun isChallengeMember(
userID: String, userID: String,
challengeID: String, challengeID: String
): Flow<Boolean> = ): Flow<Boolean> =
realm.where(ChallengeMembership::class.java) realm.where(ChallengeMembership::class.java)
.equalTo("userID", userID) .equalTo("userID", userID)
@ -32,7 +32,7 @@ class RealmChallengeLocalRepository(realm: Realm) :
override fun getChallengeMembership( override fun getChallengeMembership(
userId: String, userId: String,
id: String, id: String
) = ) =
realm.where(ChallengeMembership::class.java) realm.where(ChallengeMembership::class.java)
.equalTo("userID", userId) .equalTo("userID", userId)
@ -106,7 +106,7 @@ class RealmChallengeLocalRepository(realm: Realm) :
override fun setParticipating( override fun setParticipating(
userID: String, userID: String,
challengeID: String, challengeID: String,
isParticipating: Boolean, isParticipating: Boolean
) { ) {
val user = realm.where(User::class.java).equalTo("id", userID).findFirst() ?: return val user = realm.where(User::class.java).equalTo("id", userID).findFirst() ?: return
executeTransaction { executeTransaction {
@ -125,7 +125,7 @@ class RealmChallengeLocalRepository(realm: Realm) :
challenges: List<Challenge>, challenges: List<Challenge>,
clearChallenges: Boolean, clearChallenges: Boolean,
memberOnly: Boolean, memberOnly: Boolean,
userID: String, userID: String
) { ) {
if (clearChallenges || memberOnly) { if (clearChallenges || memberOnly) {
val localChallenges = realm.where(Challenge::class.java).findAll().createSnapshot() val localChallenges = realm.where(Challenge::class.java).findAll().createSnapshot()

View file

@ -14,7 +14,7 @@ class RealmCustomizationLocalRepository(realm: Realm) :
override fun getCustomizations( override fun getCustomizations(
type: String, type: String,
category: String?, category: String?,
onlyAvailable: Boolean, onlyAvailable: Boolean
): Flow<List<Customization>> { ): Flow<List<Customization>> {
var query = var query =
realm.where(Customization::class.java) realm.where(Customization::class.java)

View file

@ -90,7 +90,7 @@ class RealmInventoryLocalRepository(realm: Realm) :
override fun getEquipmentType( override fun getEquipmentType(
type: String, type: String,
set: String, set: String
): Flow<out List<Equipment>> { ): Flow<out List<Equipment>> {
return realm.where(Equipment::class.java) return realm.where(Equipment::class.java)
.equalTo("type", type) .equalTo("type", type)
@ -103,7 +103,7 @@ class RealmInventoryLocalRepository(realm: Realm) :
override fun getOwnedItems( override fun getOwnedItems(
itemType: String, itemType: String,
userID: String, userID: String,
includeZero: Boolean, includeZero: Boolean
): Flow<List<OwnedItem>> { ): Flow<List<OwnedItem>> {
return queryUser(userID).map { return queryUser(userID).map {
val items = val items =
@ -130,7 +130,7 @@ class RealmInventoryLocalRepository(realm: Realm) :
override fun getItems( override fun getItems(
itemClass: Class<out Item>, itemClass: Class<out Item>,
keys: Array<String>, keys: Array<String>
): Flow<List<Item>> { ): Flow<List<Item>> {
return realm.where(itemClass).`in`("key", keys).findAll().toFlow() return realm.where(itemClass).`in`("key", keys).findAll().toFlow()
.filter { it.isLoaded } .filter { it.isLoaded }
@ -138,7 +138,7 @@ class RealmInventoryLocalRepository(realm: Realm) :
override fun getOwnedItems( override fun getOwnedItems(
userID: String, userID: String,
includeZero: Boolean, includeZero: Boolean
): Flow<Map<String, OwnedItem>> { ): Flow<Map<String, OwnedItem>> {
return queryUser(userID) return queryUser(userID)
.filterNotNull() .filterNotNull()
@ -178,7 +178,7 @@ class RealmInventoryLocalRepository(realm: Realm) :
override fun getMounts( override fun getMounts(
type: String?, type: String?,
group: String?, group: String?,
color: String?, color: String?
): Flow<List<Mount>> { ): Flow<List<Mount>> {
var query = var query =
realm.where(Mount::class.java) realm.where(Mount::class.java)
@ -217,7 +217,7 @@ class RealmInventoryLocalRepository(realm: Realm) :
override fun getPets( override fun getPets(
type: String?, type: String?,
group: String?, group: String?,
color: String?, color: String?
): Flow<List<Pet>> { ): Flow<List<Pet>> {
var query = var query =
realm.where(Pet::class.java) realm.where(Pet::class.java)
@ -256,7 +256,7 @@ class RealmInventoryLocalRepository(realm: Realm) :
type: String, type: String,
key: String, key: String,
userID: String, userID: String,
amountToAdd: Int, amountToAdd: Int
) { ) {
val item = getOwnedItem(userID, type, key, true).firstOrNull() val item = getOwnedItem(userID, type, key, true).firstOrNull()
if (item != null) { if (item != null) {
@ -266,7 +266,7 @@ class RealmInventoryLocalRepository(realm: Realm) :
override fun changeOwnedCount( override fun changeOwnedCount(
item: OwnedItem, item: OwnedItem,
amountToAdd: Int?, amountToAdd: Int?
) { ) {
val liveItem = getLiveObject(item) ?: return val liveItem = getLiveObject(item) ?: return
amountToAdd?.let { amount -> amountToAdd?.let { amount ->
@ -278,7 +278,7 @@ class RealmInventoryLocalRepository(realm: Realm) :
userID: String, userID: String,
type: String, type: String,
key: String, key: String,
includeZero: Boolean, includeZero: Boolean
): Flow<OwnedItem> { ): Flow<OwnedItem> {
return queryUser(userID) return queryUser(userID)
.filterNotNull() .filterNotNull()
@ -291,7 +291,7 @@ class RealmInventoryLocalRepository(realm: Realm) :
"quests" -> it.items?.quests "quests" -> it.items?.quests
else -> emptyList() else -> emptyList()
} ?: emptyList() } ?: emptyList()
) )
items = items.filter { it.key == key } items = items.filter { it.key == key }
if (includeZero) { if (includeZero) {
items items
@ -305,7 +305,7 @@ class RealmInventoryLocalRepository(realm: Realm) :
override fun getItem( override fun getItem(
type: String, type: String,
key: String, key: String
): Flow<Item> { ): Flow<Item> {
val itemClass: Class<out RealmObject> = val itemClass: Class<out RealmObject> =
when (type) { when (type) {
@ -374,7 +374,7 @@ class RealmInventoryLocalRepository(realm: Realm) :
override fun hatchPet( override fun hatchPet(
eggKey: String, eggKey: String,
potionKey: String, potionKey: String,
userID: String, userID: String
) { ) {
val newPet = OwnedPet() val newPet = OwnedPet()
newPet.key = "$eggKey-$potionKey" newPet.key = "$eggKey-$potionKey"
@ -399,7 +399,7 @@ class RealmInventoryLocalRepository(realm: Realm) :
override fun save( override fun save(
items: Items, items: Items,
userID: String, userID: String
) { ) {
val user = realm.where(User::class.java).equalTo("id", userID).findFirst() ?: return val user = realm.where(User::class.java).equalTo("id", userID).findFirst() ?: return
items.setItemTypes() items.setItemTypes()
@ -411,7 +411,7 @@ class RealmInventoryLocalRepository(realm: Realm) :
override fun unhatchPet( override fun unhatchPet(
eggKey: String, eggKey: String,
potionKey: String, potionKey: String,
userID: String, userID: String
) { ) {
val pet = realm.where(OwnedPet::class.java).equalTo("key", "$eggKey-$potionKey").findFirst() val pet = realm.where(OwnedPet::class.java).equalTo("key", "$eggKey-$potionKey").findFirst()
val user = realm.where(User::class.java).equalTo("id", userID).findFirst() ?: return val user = realm.where(User::class.java).equalTo("id", userID).findFirst() ?: return
@ -429,7 +429,7 @@ class RealmInventoryLocalRepository(realm: Realm) :
foodKey: String, foodKey: String,
petKey: String, petKey: String,
feedValue: Int, feedValue: Int,
userID: String, userID: String
) { ) {
val user = realm.where(User::class.java).equalTo("id", userID).findFirst() ?: return val user = realm.where(User::class.java).equalTo("id", userID).findFirst() ?: return
val pet = user.items?.pets?.firstOrNull { it.key == petKey } ?: return val pet = user.items?.pets?.firstOrNull { it.key == petKey } ?: return
@ -484,7 +484,7 @@ class RealmInventoryLocalRepository(realm: Realm) :
override fun soldItem( override fun soldItem(
userID: String, userID: String,
updatedUser: User, updatedUser: User
): User { ): User {
val user = val user =
realm.where(User::class.java) realm.where(User::class.java)
@ -522,7 +522,7 @@ class RealmInventoryLocalRepository(realm: Realm) :
realm.where(Food::class.java) realm.where(Food::class.java)
.lessThan("event.start", Date()) .lessThan("event.start", Date())
.greaterThan("event.end", Date()) .greaterThan("event.end", Date())
.findAll().toFlow(), .findAll().toFlow()
) { items, food -> ) { items, food ->
items.addAll(food) items.addAll(food)
items items
@ -531,7 +531,7 @@ class RealmInventoryLocalRepository(realm: Realm) :
realm.where(HatchingPotion::class.java) realm.where(HatchingPotion::class.java)
.lessThan("event.start", Date()) .lessThan("event.start", Date())
.greaterThan("event.end", Date()) .greaterThan("event.end", Date())
.findAll().toFlow(), .findAll().toFlow()
) { items, food -> ) { items, food ->
items.addAll(food) items.addAll(food)
items items
@ -540,7 +540,7 @@ class RealmInventoryLocalRepository(realm: Realm) :
realm.where(QuestContent::class.java) realm.where(QuestContent::class.java)
.lessThan("event.start", Date()) .lessThan("event.start", Date())
.greaterThan("event.end", Date()) .greaterThan("event.end", Date())
.findAll().toFlow(), .findAll().toFlow()
) { items, food -> ) { items, food ->
items.addAll(food) items.addAll(food)
items items

View file

@ -23,7 +23,7 @@ class RealmSocialLocalRepository(realm: Realm) :
SocialLocalRepository { SocialLocalRepository {
override fun getGroupMembership( override fun getGroupMembership(
userId: String, userId: String,
id: String, id: String
) = ) =
realm.where(GroupMembership::class.java) realm.where(GroupMembership::class.java)
.equalTo("userID", userId) .equalTo("userID", userId)
@ -43,7 +43,7 @@ class RealmSocialLocalRepository(realm: Realm) :
override fun updateMembership( override fun updateMembership(
userId: String, userId: String,
id: String, id: String,
isMember: Boolean, isMember: Boolean
) { ) {
if (isMember) { if (isMember) {
save(GroupMembership(userId, id)) save(GroupMembership(userId, id))
@ -73,7 +73,7 @@ class RealmSocialLocalRepository(realm: Realm) :
userID: String, userID: String,
recipientID: String, recipientID: String,
messages: List<ChatMessage>, messages: List<ChatMessage>,
page: Int, page: Int
) { ) {
messages.forEach { it.userID = userID } messages.forEach { it.userID = userID }
for (message in messages) { for (message in messages) {
@ -103,7 +103,7 @@ class RealmSocialLocalRepository(realm: Realm) :
override fun saveInboxConversations( override fun saveInboxConversations(
userID: String, userID: String,
conversations: List<InboxConversation>, conversations: List<InboxConversation>
) { ) {
conversations.forEach { it.userID = userID } conversations.forEach { it.userID = userID }
save(conversations) save(conversations)
@ -131,7 +131,7 @@ class RealmSocialLocalRepository(realm: Realm) :
override fun saveGroupMemberships( override fun saveGroupMemberships(
userID: String?, userID: String?,
memberships: List<GroupMembership>, memberships: List<GroupMembership>
) { ) {
save(memberships) save(memberships)
if (userID != null) { if (userID != null) {
@ -153,7 +153,7 @@ class RealmSocialLocalRepository(realm: Realm) :
@OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
override fun getUserGroups( override fun getUserGroups(
userID: String, userID: String,
type: String?, type: String?
) = ) =
realm.where(GroupMembership::class.java) realm.where(GroupMembership::class.java)
.equalTo("userID", userID) .equalTo("userID", userID)
@ -167,7 +167,7 @@ class RealmSocialLocalRepository(realm: Realm) :
"id", "id",
memberships.map { memberships.map {
return@map it.groupID return@map it.groupID
}.toTypedArray(), }.toTypedArray()
) )
.sort("memberCount", Sort.DESCENDING) .sort("memberCount", Sort.DESCENDING)
.findAll() .findAll()
@ -213,7 +213,7 @@ class RealmSocialLocalRepository(realm: Realm) :
override fun updateRSVPNeeded( override fun updateRSVPNeeded(
user: User?, user: User?,
newValue: Boolean, newValue: Boolean
) { ) {
executeTransaction { user?.party?.quest?.rsvpNeeded = newValue } executeTransaction { user?.party?.quest?.rsvpNeeded = newValue }
} }
@ -221,7 +221,7 @@ class RealmSocialLocalRepository(realm: Realm) :
override fun likeMessage( override fun likeMessage(
chatMessage: ChatMessage, chatMessage: ChatMessage,
userId: String, userId: String,
liked: Boolean, liked: Boolean
) { ) {
val liveMessage = getLiveObject(chatMessage) val liveMessage = getLiveObject(chatMessage)
if (liveMessage == null) { if (liveMessage == null) {
@ -253,7 +253,7 @@ class RealmSocialLocalRepository(realm: Realm) :
override fun savePartyMembers( override fun savePartyMembers(
groupId: String?, groupId: String?,
members: List<Member>, members: List<Member>
) { ) {
save(members) save(members)
if (groupId != null) { if (groupId != null) {
@ -275,7 +275,7 @@ class RealmSocialLocalRepository(realm: Realm) :
override fun rejectGroupInvitation( override fun rejectGroupInvitation(
userID: String, userID: String,
groupID: String, groupID: String
) { ) {
val user = realm.where(User::class.java).equalTo("id", userID).findFirst() val user = realm.where(User::class.java).equalTo("id", userID).findFirst()
executeTransaction { executeTransaction {
@ -292,7 +292,7 @@ class RealmSocialLocalRepository(realm: Realm) :
override fun setQuestActivity( override fun setQuestActivity(
party: Group?, party: Group?,
active: Boolean, active: Boolean
) { ) {
if (party == null) return if (party == null) return
val liveParty = getLiveObject(party) val liveParty = getLiveObject(party)
@ -303,7 +303,7 @@ class RealmSocialLocalRepository(realm: Realm) :
override fun saveChatMessages( override fun saveChatMessages(
groupId: String?, groupId: String?,
chatMessages: List<ChatMessage>, chatMessages: List<ChatMessage>
) { ) {
save(chatMessages) save(chatMessages)
if (groupId != null) { if (groupId != null) {
@ -331,7 +331,7 @@ class RealmSocialLocalRepository(realm: Realm) :
override fun getInboxMessages( override fun getInboxMessages(
userId: String, userId: String,
replyToUserID: String?, replyToUserID: String?
) = ) =
realm.where(ChatMessage::class.java) realm.where(ChatMessage::class.java)
.equalTo("isInboxMessage", true) .equalTo("isInboxMessage", true)

View file

@ -24,7 +24,7 @@ class RealmTaskLocalRepository(realm: Realm) :
override fun getTasks( override fun getTasks(
taskType: TaskType, taskType: TaskType,
userID: String, userID: String,
includedGroupIDs: Array<String>, includedGroupIDs: Array<String>
): Flow<List<Task>> { ): Flow<List<Task>> {
if (realm.isClosed) return emptyFlow() if (realm.isClosed) return emptyFlow()
return findTasks(taskType, userID) return findTasks(taskType, userID)
@ -34,7 +34,7 @@ class RealmTaskLocalRepository(realm: Realm) :
private fun findTasks( private fun findTasks(
taskType: TaskType, taskType: TaskType,
ownerID: String, ownerID: String
): RealmResults<Task> { ): RealmResults<Task> {
return realm.where(Task::class.java) return realm.where(Task::class.java)
.equalTo("typeValue", taskType.value) .equalTo("typeValue", taskType.value)
@ -55,7 +55,7 @@ class RealmTaskLocalRepository(realm: Realm) :
override fun saveTasks( override fun saveTasks(
ownerID: String, ownerID: String,
tasksOrder: TasksOrder, tasksOrder: TasksOrder,
tasks: TaskList, tasks: TaskList
) { ) {
val sortedTasks = mutableListOf<Task>() val sortedTasks = mutableListOf<Task>()
sortedTasks.addAll(sortTasks(tasks.tasks, tasksOrder.habits)) sortedTasks.addAll(sortTasks(tasks.tasks, tasksOrder.habits))
@ -85,7 +85,7 @@ class RealmTaskLocalRepository(realm: Realm) :
override fun saveCompletedTodos( override fun saveCompletedTodos(
userId: String, userId: String,
tasks: MutableCollection<Task>, tasks: MutableCollection<Task>
) { ) {
removeCompletedTodos(userId, tasks) removeCompletedTodos(userId, tasks)
executeTransaction { realm1 -> realm1.insertOrUpdate(tasks) } executeTransaction { realm1 -> realm1.insertOrUpdate(tasks) }
@ -113,7 +113,7 @@ class RealmTaskLocalRepository(realm: Realm) :
private fun sortTasks( private fun sortTasks(
taskMap: MutableMap<String, Task>, taskMap: MutableMap<String, Task>,
taskOrder: List<String>, taskOrder: List<String>
): List<Task> { ): List<Task> {
val taskList = ArrayList<Task>() val taskList = ArrayList<Task>()
var position = 0 var position = 0
@ -131,7 +131,7 @@ class RealmTaskLocalRepository(realm: Realm) :
private fun removeOldTasks( private fun removeOldTasks(
ownerID: String, ownerID: String,
onlineTaskList: List<Task>, onlineTaskList: List<Task>
) { ) {
if (realm.isClosed) return if (realm.isClosed) return
val localTasks = val localTasks =
@ -157,7 +157,7 @@ class RealmTaskLocalRepository(realm: Realm) :
private fun removeCompletedTodos( private fun removeCompletedTodos(
userID: String, userID: String,
onlineTaskList: MutableCollection<Task>, onlineTaskList: MutableCollection<Task>
) { ) {
val localTasks = val localTasks =
realm.where(Task::class.java) realm.where(Task::class.java)
@ -206,7 +206,7 @@ class RealmTaskLocalRepository(realm: Realm) :
override fun markTaskCompleted( override fun markTaskCompleted(
taskId: String, taskId: String,
isCompleted: Boolean, isCompleted: Boolean
) { ) {
val task = realm.where(Task::class.java).equalTo("id", taskId).findFirst() val task = realm.where(Task::class.java).equalTo("id", taskId).findFirst()
executeTransaction { task?.completed = true } executeTransaction { task?.completed = true }
@ -214,7 +214,7 @@ class RealmTaskLocalRepository(realm: Realm) :
override fun swapTaskPosition( override fun swapTaskPosition(
firstPosition: Int, firstPosition: Int,
secondPosition: Int, secondPosition: Int
) { ) {
val firstTask = realm.where(Task::class.java).equalTo("position", firstPosition).findFirst() val firstTask = realm.where(Task::class.java).equalTo("position", firstPosition).findFirst()
val secondTask = val secondTask =
@ -229,7 +229,7 @@ class RealmTaskLocalRepository(realm: Realm) :
override fun getTaskAtPosition( override fun getTaskAtPosition(
taskType: String, taskType: String,
position: Int, position: Int
): Flow<Task> { ): Flow<Task> {
return realm.where(Task::class.java).equalTo("typeValue", taskType) return realm.where(Task::class.java).equalTo("typeValue", taskType)
.equalTo("position", position) .equalTo("position", position)
@ -282,7 +282,7 @@ class RealmTaskLocalRepository(realm: Realm) :
override fun getTasksForChallenge( override fun getTasksForChallenge(
challengeID: String?, challengeID: String?,
userID: String?, userID: String?
): Flow<List<Task>> { ): Flow<List<Task>> {
return realm.where(Task::class.java) return realm.where(Task::class.java)
.equalTo("challengeID", challengeID) .equalTo("challengeID", challengeID)

View file

@ -84,7 +84,7 @@ class RealmUserLocalRepository(realm: Realm) :
override fun saveUser( override fun saveUser(
user: User, user: User,
overrideExisting: Boolean, overrideExisting: Boolean
) { ) {
if (realm.isClosed) return if (realm.isClosed) return
val oldUser = val oldUser =
@ -108,7 +108,7 @@ class RealmUserLocalRepository(realm: Realm) :
private fun removeOldTags( private fun removeOldTags(
userId: String, userId: String,
onlineTags: List<Tag>, onlineTags: List<Tag>
) { ) {
val tags = realm.where(Tag::class.java).equalTo("userId", userId).findAll().createSnapshot() val tags = realm.where(Tag::class.java).equalTo("userId", userId).findAll().createSnapshot()
val tagsToDelete = tags.filterNot { onlineTags.contains(it) } val tagsToDelete = tags.filterNot { onlineTags.contains(it) }

View file

@ -5,21 +5,21 @@ import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
fun HabiticaAlertDialog.addOkButton( fun HabiticaAlertDialog.addOkButton(
isPrimary: Boolean = true, isPrimary: Boolean = true,
listener: ((HabiticaAlertDialog, Int) -> Unit)? = null, listener: ((HabiticaAlertDialog, Int) -> Unit)? = null
) { ) {
this.addButton(R.string.ok, isPrimary, false, true, listener) this.addButton(R.string.ok, isPrimary, false, true, listener)
} }
fun HabiticaAlertDialog.addCloseButton( fun HabiticaAlertDialog.addCloseButton(
isPrimary: Boolean = false, isPrimary: Boolean = false,
listener: ((HabiticaAlertDialog, Int) -> Unit)? = null, listener: ((HabiticaAlertDialog, Int) -> Unit)? = null
) { ) {
this.addButton(R.string.close, isPrimary, false, true, listener) this.addButton(R.string.close, isPrimary, false, true, listener)
} }
fun HabiticaAlertDialog.addCancelButton( fun HabiticaAlertDialog.addCancelButton(
isPrimary: Boolean = false, isPrimary: Boolean = false,
listener: ((HabiticaAlertDialog, Int) -> Unit)? = null, listener: ((HabiticaAlertDialog, Int) -> Unit)? = null
) { ) {
this.addButton(R.string.cancel, isPrimary, false, true, listener) this.addButton(R.string.cancel, isPrimary, false, true, listener)
} }

View file

@ -10,7 +10,7 @@ fun Animal.getTranslatedType(c: Context?): String? {
fun getTranslatedAnimalType( fun getTranslatedAnimalType(
c: Context?, c: Context?,
type: String?, type: String?
): String? { ): String? {
if (c == null) { if (c == null) {
return type return type

View file

@ -6,6 +6,6 @@ import android.util.AttributeSet
fun AttributeSet.styledAttributes( fun AttributeSet.styledAttributes(
context: Context?, context: Context?,
style: IntArray, style: IntArray
): TypedArray? = ): TypedArray? =
context?.theme?.obtainStyledAttributes(this, style, 0, 0) context?.theme?.obtainStyledAttributes(this, style, 0, 0)

View file

@ -17,7 +17,7 @@ class DateUtils {
fun createDate( fun createDate(
year: Int, year: Int,
month: Int, month: Int,
day: Int, day: Int
): Date { ): Date {
val cal = Calendar.getInstance() val cal = Calendar.getInstance()
cal.set(Calendar.YEAR, year) cal.set(Calendar.YEAR, year)
@ -32,7 +32,7 @@ class DateUtils {
fun isSameDay( fun isSameDay(
date1: Date, date1: Date,
date2: Date, date2: Date
): Boolean { ): Boolean {
val cal1 = Calendar.getInstance() val cal1 = Calendar.getInstance()
val cal2 = Calendar.getInstance() val cal2 = Calendar.getInstance()

View file

@ -3,8 +3,6 @@ package com.habitrpg.android.habitica.extensions
import com.habitrpg.common.habitica.helpers.LanguageHelper import com.habitrpg.common.habitica.helpers.LanguageHelper
import java.util.Locale import java.util.Locale
fun Locale.getSystemDefault(): Locale { fun Locale.getSystemDefault(): Locale {
return LanguageHelper.systemLocale return LanguageHelper.systemLocale
} }

View file

@ -10,7 +10,7 @@ import java.util.Locale
fun Resources.forceLocale( fun Resources.forceLocale(
activity: BaseActivity, activity: BaseActivity,
locale: Locale, locale: Locale
) { ) {
Locale.setDefault(locale) Locale.setDefault(locale)
val configuration = Configuration() val configuration = Configuration()

View file

@ -12,7 +12,7 @@ class OnChangeTextWatcher(private var function: (CharSequence?, Int, Int, Int) -
s: CharSequence?, s: CharSequence?,
start: Int, start: Int,
count: Int, count: Int,
after: Int, after: Int
) { // no-on ) { // no-on
} }
@ -20,7 +20,7 @@ class OnChangeTextWatcher(private var function: (CharSequence?, Int, Int, Int) -
s: CharSequence?, s: CharSequence?,
start: Int, start: Int,
before: Int, before: Int,
count: Int, count: Int
) { ) {
function(s, start, before, count) function(s, start, before, count)
} }
@ -35,7 +35,7 @@ class BeforeChangeTextWatcher(private var function: (CharSequence?, Int, Int, In
s: CharSequence?, s: CharSequence?,
start: Int, start: Int,
count: Int, count: Int,
after: Int, after: Int
) { ) {
function(s, start, count, after) function(s, start, count, after)
} }
@ -44,7 +44,7 @@ class BeforeChangeTextWatcher(private var function: (CharSequence?, Int, Int, In
s: CharSequence?, s: CharSequence?,
start: Int, start: Int,
before: Int, before: Int,
count: Int, count: Int
) { // no-on ) { // no-on
} }
} }
@ -58,7 +58,7 @@ class AfterChangeTextWatcher(private var function: (Editable?) -> Unit) : TextWa
s: CharSequence?, s: CharSequence?,
start: Int, start: Int,
count: Int, count: Int,
after: Int, after: Int
) { // no-on ) { // no-on
} }
@ -66,7 +66,7 @@ class AfterChangeTextWatcher(private var function: (Editable?) -> Unit) : TextWa
s: CharSequence?, s: CharSequence?,
start: Int, start: Int,
before: Int, before: Int,
count: Int, count: Int
) { // no-on ) { // no-on
} }
} }

View file

@ -8,7 +8,7 @@ import com.habitrpg.common.habitica.extensions.getThemeColor
fun Window.updateStatusBarColor( fun Window.updateStatusBarColor(
color: Int, color: Int,
isLight: Boolean, isLight: Boolean
) { ) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
statusBarColor = color statusBarColor = color

View file

@ -16,7 +16,7 @@ fun String.parseToZonedDateTime(): ZonedDateTime? {
formatter().parseBest( formatter().parseBest(
this, this,
ZonedDateTime::from, ZonedDateTime::from,
LocalDateTime::from, LocalDateTime::from
) )
return if (parsed is ZonedDateTime) { return if (parsed is ZonedDateTime) {
parsed parsed
@ -65,4 +65,4 @@ fun Calendar.matchesRepeatDays(repeatDays: Days?): Boolean {
Calendar.SUNDAY -> repeatDays.su Calendar.SUNDAY -> repeatDays.su
else -> false else -> false
} }
} }

View file

@ -23,7 +23,7 @@ import kotlin.time.toDuration
enum class AdType { enum class AdType {
ARMOIRE, ARMOIRE,
SPELL, SPELL,
FAINT, FAINT
; ;
val adUnitID: String val adUnitID: String
@ -68,7 +68,7 @@ class AdHandler(val activity: Activity, val type: AdType, val rewardAction: (Boo
UNINITIALIZED, UNINITIALIZED,
INITIALIZING, INITIALIZING,
READY, READY,
DISABLED, DISABLED
} }
private lateinit var sharedPreferences: SharedPreferences private lateinit var sharedPreferences: SharedPreferences
@ -103,7 +103,7 @@ class AdHandler(val activity: Activity, val type: AdType, val rewardAction: (Boo
fun initialize( fun initialize(
context: Context, context: Context,
onComplete: () -> Unit, onComplete: () -> Unit
) { ) {
if (currentAdStatus != AdStatus.UNINITIALIZED) return if (currentAdStatus != AdStatus.UNINITIALIZED) return
@ -125,7 +125,7 @@ class AdHandler(val activity: Activity, val type: AdType, val rewardAction: (Boo
fun whenAdsInitialized( fun whenAdsInitialized(
context: Context, context: Context,
onComplete: () -> Unit, onComplete: () -> Unit
) { ) {
when (currentAdStatus) { when (currentAdStatus) {
AdStatus.READY -> { AdStatus.READY -> {

View file

@ -13,12 +13,12 @@ import com.habitrpg.android.habitica.R
enum class AnalyticsTarget { enum class AnalyticsTarget {
AMPLITUDE, AMPLITUDE,
FIREBASE, FIREBASE
} }
enum class EventCategory(val key: String) { enum class EventCategory(val key: String) {
BEHAVIOUR("behaviour"), BEHAVIOUR("behaviour"),
NAVIGATION("navigation"), NAVIGATION("navigation")
} }
enum class HitType(val key: String) { enum class HitType(val key: String) {
@ -26,7 +26,7 @@ enum class HitType(val key: String) {
PAGEVIEW("pageview"), PAGEVIEW("pageview"),
CREATE_WIDGET("create"), CREATE_WIDGET("create"),
REMOVE_WIDGET("remove"), REMOVE_WIDGET("remove"),
UPDATE_WIDGET("update"), UPDATE_WIDGET("update")
} }
object Analytics { object Analytics {
@ -39,7 +39,7 @@ object Analytics {
category: EventCategory?, category: EventCategory?,
hitType: HitType?, hitType: HitType?,
additionalData: Map<String, Any>? = null, additionalData: Map<String, Any>? = null,
target: AnalyticsTarget? = null, target: AnalyticsTarget? = null
) { ) {
if (BuildConfig.DEBUG) { if (BuildConfig.DEBUG) {
return return
@ -49,7 +49,7 @@ object Analytics {
"eventAction" to eventAction, "eventAction" to eventAction,
"eventCategory" to category?.key, "eventCategory" to category?.key,
"hitType" to hitType?.key, "hitType" to hitType?.key,
"status" to "displayed", "status" to "displayed"
) )
if (additionalData != null) { if (additionalData != null) {
data.putAll(additionalData) data.putAll(additionalData)
@ -79,8 +79,8 @@ object Analytics {
Amplitude( Amplitude(
Configuration( Configuration(
context.getString(R.string.amplitude_app_id), context.getString(R.string.amplitude_app_id),
context, context
), )
) )
firebase = FirebaseAnalytics.getInstance(context) firebase = FirebaseAnalytics.getInstance(context)
} }
@ -109,7 +109,7 @@ object Analytics {
fun setUserProperty( fun setUserProperty(
identifier: String, identifier: String,
value: Any?, value: Any?
) { ) {
if (this::amplitude.isInitialized) { if (this::amplitude.isInitialized) {
amplitude.identify(mapOf(identifier to value)) amplitude.identify(mapOf(identifier to value))

View file

@ -128,7 +128,7 @@ class AppConfigManager(contentRepository: ContentRepository) :
getHabiticaPromotionFromKey( getHabiticaPromotionFromKey(
event.promo ?: event.eventKey ?: "", event.promo ?: event.eventKey ?: "",
event.start, event.start,
event.end, event.end
) )
if (thisPromo != null) { if (thisPromo != null) {
promo = thisPromo promo = thisPromo
@ -147,7 +147,6 @@ class AppConfigManager(contentRepository: ContentRepository) :
return null return null
} }
fun knownIssues(): List<Map<String, String>> { fun knownIssues(): List<Map<String, String>> {
val type = object : TypeToken<List<Map<String, String>>>() {}.type val type = object : TypeToken<List<Map<String, String>>>() {}.type
return Gson().fromJson(remoteConfig.getString("knownIssues"), type) return Gson().fromJson(remoteConfig.getString("knownIssues"), type)

View file

@ -8,7 +8,7 @@ class AprilFoolsHandler {
fun handle( fun handle(
name: String?, name: String?,
endDate: Date?, endDate: Date?
) { ) {
if (endDate != null) { if (endDate != null) {
this.eventEnd = endDate this.eventEnd = endDate

View file

@ -6,7 +6,7 @@ import com.habitrpg.android.habitica.models.tasks.Task
interface GroupPlanInfoProvider { interface GroupPlanInfoProvider {
fun assignedTextForTask( fun assignedTextForTask(
resources: Resources, resources: Resources,
assignedUsers: List<String>, assignedUsers: List<String>
): String ): String
fun canScoreTask(task: Task): Boolean fun canScoreTask(task: Task): Boolean

View file

@ -15,18 +15,18 @@ import kotlin.coroutines.EmptyCoroutineContext
@Composable @Composable
fun <T> rememberFlow( fun <T> rememberFlow(
flow: Flow<T>, flow: Flow<T>,
lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current, lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current
): Flow<T> { ): Flow<T> {
return remember( return remember(
key1 = flow, key1 = flow,
key2 = lifecycleOwner, key2 = lifecycleOwner
) { flow.flowWithLifecycle(lifecycleOwner.lifecycle, Lifecycle.State.STARTED) } ) { flow.flowWithLifecycle(lifecycleOwner.lifecycle, Lifecycle.State.STARTED) }
} }
@Composable @Composable
fun <T : R, R> Flow<T>.collectAsStateLifecycleAware( fun <T : R, R> Flow<T>.collectAsStateLifecycleAware(
initial: R, initial: R,
context: CoroutineContext = EmptyCoroutineContext, context: CoroutineContext = EmptyCoroutineContext
): State<R> { ): State<R> {
val lifecycleAwareFlow = rememberFlow(flow = this) val lifecycleAwareFlow = rememberFlow(flow = this)
return lifecycleAwareFlow.collectAsState(initial = initial, context = context) return lifecycleAwareFlow.collectAsState(initial = initial, context = context)

View file

@ -13,7 +13,7 @@ class NotificationOpenHandler {
companion object { companion object {
fun handleOpenedByNotification( fun handleOpenedByNotification(
identifier: String, identifier: String,
intent: Intent, intent: Intent
) { ) {
MainScope().launch(context = Dispatchers.Main) { MainScope().launch(context = Dispatchers.Main) {
when (identifier) { when (identifier) {
@ -22,13 +22,13 @@ class NotificationOpenHandler {
PushNotificationManager.QUEST_INVITE_PUSH_NOTIFICATION_KEY -> openPartyScreen() PushNotificationManager.QUEST_INVITE_PUSH_NOTIFICATION_KEY -> openPartyScreen()
PushNotificationManager.GUILD_INVITE_PUSH_NOTIFICATION_KEY -> PushNotificationManager.GUILD_INVITE_PUSH_NOTIFICATION_KEY ->
openGuildDetailScreen( openGuildDetailScreen(
intent.getStringExtra("groupID"), intent.getStringExtra("groupID")
) )
PushNotificationManager.RECEIVED_PRIVATE_MESSAGE_PUSH_NOTIFICATION_KEY -> PushNotificationManager.RECEIVED_PRIVATE_MESSAGE_PUSH_NOTIFICATION_KEY ->
openPrivateMessageScreen( openPrivateMessageScreen(
intent.getStringExtra("replyToUUID"), intent.getStringExtra("replyToUUID"),
intent.getStringExtra("replyToUsername"), intent.getStringExtra("replyToUsername")
) )
PushNotificationManager.CHANGE_USERNAME_PUSH_NOTIFICATION_KEY -> openSettingsScreen() PushNotificationManager.CHANGE_USERNAME_PUSH_NOTIFICATION_KEY -> openSettingsScreen()
@ -36,13 +36,13 @@ class NotificationOpenHandler {
PushNotificationManager.CHAT_MENTION_NOTIFICATION_KEY -> PushNotificationManager.CHAT_MENTION_NOTIFICATION_KEY ->
handleChatMessage( handleChatMessage(
intent.getStringExtra("type"), intent.getStringExtra("type"),
intent.getStringExtra("groupID"), intent.getStringExtra("groupID")
) )
PushNotificationManager.GROUP_ACTIVITY_NOTIFICATION_KEY -> PushNotificationManager.GROUP_ACTIVITY_NOTIFICATION_KEY ->
handleChatMessage( handleChatMessage(
intent.getStringExtra("type"), intent.getStringExtra("type"),
intent.getStringExtra("groupID"), intent.getStringExtra("groupID")
) )
PushNotificationManager.G1G1_PROMO_KEY -> openGiftOneGetOneInfoScreen() PushNotificationManager.G1G1_PROMO_KEY -> openGiftOneGetOneInfoScreen()
@ -58,18 +58,18 @@ class NotificationOpenHandler {
private fun openSubscriptionScreen() { private fun openSubscriptionScreen() {
MainNavigationController.navigate( MainNavigationController.navigate(
R.id.gemPurchaseActivity, R.id.gemPurchaseActivity,
bundleOf(Pair("openSubscription", true)), bundleOf(Pair("openSubscription", true))
) )
} }
private fun openPrivateMessageScreen( private fun openPrivateMessageScreen(
userID: String?, userID: String?,
userName: String?, userName: String?
) { ) {
if (userID != null && userName != null) { if (userID != null && userName != null) {
MainNavigationController.navigate( MainNavigationController.navigate(
R.id.inboxMessageListFragment, R.id.inboxMessageListFragment,
bundleOf("userID" to userID, "username" to userName), bundleOf("userID" to userID, "username" to userName)
) )
} else { } else {
MainNavigationController.navigate(R.id.inboxFragment) MainNavigationController.navigate(R.id.inboxFragment)
@ -80,7 +80,7 @@ class NotificationOpenHandler {
val tabToOpen = if (isChatNotification) 1 else 0 val tabToOpen = if (isChatNotification) 1 else 0
MainNavigationController.navigate( MainNavigationController.navigate(
R.id.partyFragment, R.id.partyFragment,
bundleOf("tabToOpen" to tabToOpen), bundleOf("tabToOpen" to tabToOpen)
) )
} }
@ -106,7 +106,7 @@ class NotificationOpenHandler {
private fun handleChatMessage( private fun handleChatMessage(
type: String?, type: String?,
groupID: String?, groupID: String?
) { ) {
when (type) { when (type) {
"party" -> openPartyScreen() "party" -> openPartyScreen()

View file

@ -27,7 +27,7 @@ interface NotificationsManager {
fun dismissTaskNotification( fun dismissTaskNotification(
context: Context, context: Context,
task: Task, task: Task
) )
} }
@ -60,7 +60,7 @@ class MainNotificationsManager : NotificationsManager {
override fun dismissTaskNotification( override fun dismissTaskNotification(
context: Context, context: Context,
task: Task, task: Task
) { ) {
NotificationManagerCompat.from(context).cancel(task.id.hashCode()) NotificationManagerCompat.from(context).cancel(task.id.hashCode())
} }

View file

@ -23,7 +23,6 @@ import com.android.billingclient.api.acknowledgePurchase
import com.android.billingclient.api.consumePurchase import com.android.billingclient.api.consumePurchase
import com.android.billingclient.api.queryProductDetails import com.android.billingclient.api.queryProductDetails
import com.android.billingclient.api.queryPurchasesAsync import com.android.billingclient.api.queryPurchasesAsync
import com.google.api.Billing
import com.google.firebase.crashlytics.FirebaseCrashlytics import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.habitrpg.android.habitica.HabiticaBaseApplication import com.habitrpg.android.habitica.HabiticaBaseApplication
import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.R
@ -64,21 +63,21 @@ class PurchaseHandler(
override fun onPurchasesUpdated( override fun onPurchasesUpdated(
result: BillingResult, result: BillingResult,
purchases: MutableList<Purchase>?, purchases: MutableList<Purchase>?
) { ) {
purchases?.let { processPurchases(result, it) } purchases?.let { processPurchases(result, it) }
} }
override fun onQueryPurchasesResponse( override fun onQueryPurchasesResponse(
result: BillingResult, result: BillingResult,
purchases: MutableList<Purchase>, purchases: MutableList<Purchase>
) { ) {
processPurchases(result, purchases) processPurchases(result, purchases)
} }
private fun processPurchases( private fun processPurchases(
result: BillingResult, result: BillingResult,
purchases: List<Purchase>, purchases: List<Purchase>
) { ) {
when (result.responseCode) { when (result.responseCode) {
BillingClient.BillingResponseCode.OK -> { BillingClient.BillingResponseCode.OK -> {
@ -90,8 +89,8 @@ class PurchaseHandler(
for (purchase in purchases) { for (purchase in purchases) {
if (plan?.isActive == true && if (plan?.isActive == true &&
PurchaseTypes.allSubscriptionTypes.contains( PurchaseTypes.allSubscriptionTypes.contains(
purchase.products.firstOrNull(), purchase.products.firstOrNull()
) )
) { ) {
if (((plan.dateTerminated != null) == purchase.isAutoRenewing) || if (((plan.dateTerminated != null) == purchase.isAutoRenewing) ||
mostRecentSub?.orderId != purchase.orderId || mostRecentSub?.orderId != purchase.orderId ||
@ -139,7 +138,7 @@ class PurchaseHandler(
READY, READY,
UNAVAILABLE, UNAVAILABLE,
DISCONNECTED, DISCONNECTED,
CONNECTING, CONNECTING
; ;
val canMaybePurchase: Boolean val canMaybePurchase: Boolean
@ -203,7 +202,7 @@ class PurchaseHandler(
retryListening() retryListening()
} }
} }
}, }
) )
} }
@ -228,13 +227,13 @@ class PurchaseHandler(
val subResponse = val subResponse =
billingClient.queryPurchasesAsync( billingClient.queryPurchasesAsync(
QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.SUBS) QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.SUBS)
.build(), .build()
) )
processPurchases(subResponse.billingResult, subResponse.purchasesList) processPurchases(subResponse.billingResult, subResponse.purchasesList)
val iapResponse = val iapResponse =
billingClient.queryPurchasesAsync( billingClient.queryPurchasesAsync(
QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.INAPP) QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.INAPP)
.build(), .build()
) )
processPurchases(iapResponse.billingResult, iapResponse.purchasesList) processPurchases(iapResponse.billingResult, iapResponse.purchasesList)
} }
@ -256,13 +255,13 @@ class PurchaseHandler(
private suspend fun getSKUs( private suspend fun getSKUs(
type: String, type: String,
identifiers: List<String>, identifiers: List<String>
) = ) =
loadInventory(type, identifiers) ?: emptyList() loadInventory(type, identifiers) ?: emptyList()
private suspend fun getSKU( private suspend fun getSKU(
type: String, type: String,
identifier: String, identifier: String
): ProductDetails? { ): ProductDetails? {
val inventory = loadInventory(type, listOf(identifier)) val inventory = loadInventory(type, listOf(identifier))
return inventory?.firstOrNull() return inventory?.firstOrNull()
@ -270,11 +269,12 @@ class PurchaseHandler(
private suspend fun loadInventory( private suspend fun loadInventory(
type: String, type: String,
skus: List<String>, skus: List<String>
): List<ProductDetails>? { ): List<ProductDetails>? {
retryUntil(8, initialDelay = 500, maxDelay = 2000) { retryUntil(8, initialDelay = 500, maxDelay = 2000) {
if (billingClient.connectionState == BillingClient.ConnectionState.DISCONNECTED || if (billingClient.connectionState == BillingClient.ConnectionState.DISCONNECTED ||
billingClient.connectionState == BillingClient.ConnectionState.CLOSED) { billingClient.connectionState == BillingClient.ConnectionState.CLOSED
) {
startListening() startListening()
} }
billingClientState.canMaybePurchase && billingClient.isReady billingClientState.canMaybePurchase && billingClient.isReady
@ -283,7 +283,7 @@ class PurchaseHandler(
QueryProductDetailsParams.newBuilder().setProductList( QueryProductDetailsParams.newBuilder().setProductList(
skus.map { skus.map {
Product.newBuilder().setProductId(it).setProductType(type).build() Product.newBuilder().setProductId(it).setProductType(type).build()
}, }
).build() ).build()
val skuDetailsResult = val skuDetailsResult =
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
@ -293,8 +293,8 @@ class PurchaseHandler(
Log.e("PurchaseHandler", "Failed to load inventory: ${skuDetailsResult.billingResult.debugMessage}") Log.e("PurchaseHandler", "Failed to load inventory: ${skuDetailsResult.billingResult.debugMessage}")
FirebaseCrashlytics.getInstance().recordException( FirebaseCrashlytics.getInstance().recordException(
Throwable( Throwable(
"Failed to load inventory: ${skuDetailsResult.billingResult.debugMessage}", "Failed to load inventory: ${skuDetailsResult.billingResult.debugMessage}"
), )
) )
return null return null
} }
@ -306,7 +306,7 @@ class PurchaseHandler(
skuDetails: ProductDetails, skuDetails: ProductDetails,
recipient: String? = null, recipient: String? = null,
recipientUsername: String? = null, recipientUsername: String? = null,
isSaleGemPurchase: Boolean = false, isSaleGemPurchase: Boolean = false
) { ) {
this.isSaleGemPurchase = isSaleGemPurchase this.isSaleGemPurchase = isSaleGemPurchase
recipient?.let { recipient?.let {
@ -320,14 +320,14 @@ class PurchaseHandler(
params = params.setOfferToken(offerToken) params = params.setOfferToken(offerToken)
} }
return@map params.build() return@map params.build()
}, }
).build() ).build()
billingClient.launchBillingFlow(activity, flowParams) billingClient.launchBillingFlow(activity, flowParams)
} }
private suspend fun consume( private suspend fun consume(
purchase: Purchase, purchase: Purchase,
retries: Int = 4, retries: Int = 4
) { ) {
retryUntil { billingClientState.canMaybePurchase && billingClient.isReady } retryUntil { billingClientState.canMaybePurchase && billingClient.isReady }
val params = ConsumeParams.newBuilder().setPurchaseToken(purchase.purchaseToken).build() val params = ConsumeParams.newBuilder().setPurchaseToken(purchase.purchaseToken).build()
@ -348,8 +348,8 @@ class PurchaseHandler(
private fun handle(purchase: Purchase) { private fun handle(purchase: Purchase) {
if (purchase.purchaseState != Purchase.PurchaseState.PURCHASED || if (purchase.purchaseState != Purchase.PurchaseState.PURCHASED ||
processedPurchases.contains( processedPurchases.contains(
purchase.orderId, purchase.orderId
) )
) { ) {
return return
} }
@ -433,7 +433,7 @@ class PurchaseHandler(
private suspend fun acknowledgePurchase( private suspend fun acknowledgePurchase(
purchase: Purchase, purchase: Purchase,
retries: Int = 4, retries: Int = 4
) { ) {
val params = val params =
AcknowledgePurchaseParams.newBuilder().setPurchaseToken(purchase.purchaseToken).build() AcknowledgePurchaseParams.newBuilder().setPurchaseToken(purchase.purchaseToken).build()
@ -470,7 +470,7 @@ class PurchaseHandler(
private fun handleError( private fun handleError(
throwable: Throwable, throwable: Throwable,
purchase: Purchase, purchase: Purchase
) { ) {
when (throwable) { when (throwable) {
is HttpException -> { is HttpException -> {
@ -576,7 +576,7 @@ class PurchaseHandler(
private fun displayConfirmationDialog( private fun displayConfirmationDialog(
purchase: Purchase, purchase: Purchase,
giftedToID: String? = null, giftedToID: String? = null,
giftedTo: String? = null, giftedTo: String? = null
) { ) {
if (displayedConfirmations.contains(purchase.orderId)) { if (displayedConfirmations.contains(purchase.orderId)) {
return return
@ -599,7 +599,7 @@ class PurchaseHandler(
R.string.gift_confirmation_text_sub R.string.gift_confirmation_text_sub
}, },
giftedTo, giftedTo,
durationString(sku), durationString(sku)
) )
} }
@ -609,7 +609,7 @@ class PurchaseHandler(
} else { } else {
context.getString( context.getString(
R.string.subscription_confirmation_multiple, R.string.subscription_confirmation_multiple,
durationString(sku), durationString(sku)
) )
} }
} }
@ -619,7 +619,7 @@ class PurchaseHandler(
context.getString( context.getString(
R.string.gift_confirmation_text_gems_new, R.string.gift_confirmation_text_gems_new,
giftedTo, giftedTo,
gemAmountString(sku), gemAmountString(sku)
) )
} }
@ -648,7 +648,7 @@ class PurchaseHandler(
private fun displayGryphatriceConfirmationDialog( private fun displayGryphatriceConfirmationDialog(
purchase: Purchase, purchase: Purchase,
giftedTo: String? = null, giftedTo: String? = null
) { ) {
MainScope().launch(ExceptionHandler.coroutine()) { MainScope().launch(ExceptionHandler.coroutine()) {
val application = val application =
@ -681,7 +681,7 @@ class PurchaseHandler(
fun addGift( fun addGift(
sku: String, sku: String,
userID: String, userID: String,
username: String, username: String
) { ) {
pendingGifts[sku] = Triple(Date(), userID, username) pendingGifts[sku] = Triple(Date(), userID, username)
savePendingGifts() savePendingGifts()
@ -708,7 +708,7 @@ suspend fun retryUntil(
initialDelay: Long = 100, // 0.1 second initialDelay: Long = 100, // 0.1 second
maxDelay: Long = 1000, // 1 second maxDelay: Long = 1000, // 1 second
factor: Double = 2.0, factor: Double = 2.0,
block: suspend () -> Boolean, block: suspend () -> Boolean
) { ) {
var currentDelay = initialDelay var currentDelay = initialDelay
repeat(times - 1) { repeat(times - 1) {

View file

@ -16,7 +16,7 @@ object PurchaseTypes {
SUBSCRIPTION_1_MONTH, SUBSCRIPTION_1_MONTH,
SUBSCRIPTION_3_MONTH, SUBSCRIPTION_3_MONTH,
SUBSCRIPTION_6_MONTH, SUBSCRIPTION_6_MONTH,
SUBSCRIPTION_12_MONTH, SUBSCRIPTION_12_MONTH
) )
const val SUBSCRIPTION_1_MONTH_NORENEW = const val SUBSCRIPTION_1_MONTH_NORENEW =
"com.habitrpg.android.habitica.norenew_subscription.1month" "com.habitrpg.android.habitica.norenew_subscription.1month"
@ -31,6 +31,6 @@ object PurchaseTypes {
SUBSCRIPTION_1_MONTH_NORENEW, SUBSCRIPTION_1_MONTH_NORENEW,
SUBSCRIPTION_3_MONTH_NORENEW, SUBSCRIPTION_3_MONTH_NORENEW,
SUBSCRIPTION_6_MONTH_NORENEW, SUBSCRIPTION_6_MONTH_NORENEW,
SUBSCRIPTION_12_MONTH_NORENEW, SUBSCRIPTION_12_MONTH_NORENEW
) )
} }

View file

@ -60,7 +60,7 @@ class ReviewManager(context: Context, private val configManager: AppConfigManage
fun requestReview( fun requestReview(
activity: AppCompatActivity, activity: AppCompatActivity,
currentCheckins: Int, currentCheckins: Int
) { ) {
if (!canRequestReview(currentCheckins)) return if (!canRequestReview(currentCheckins)) return

View file

@ -7,65 +7,65 @@ import javax.inject.Singleton
@Singleton @Singleton
class SoundManager class SoundManager
@Inject @Inject
constructor(var soundFileLoader: SoundFileLoader) { constructor(var soundFileLoader: SoundFileLoader) {
var soundTheme: String = SOUND_THEME_OFF var soundTheme: String = SOUND_THEME_OFF
private val loadedSoundFiles: MutableMap<String, SoundFile> = HashMap() private val loadedSoundFiles: MutableMap<String, SoundFile> = HashMap()
fun preloadAllFiles() { fun preloadAllFiles() {
loadedSoundFiles.clear() loadedSoundFiles.clear()
if (soundTheme == SOUND_THEME_OFF) { if (soundTheme == SOUND_THEME_OFF) {
return return
}
val soundFiles = ArrayList<SoundFile>()
soundFiles.add(SoundFile(soundTheme, SOUND_ACHIEVEMENT_UNLOCKED))
soundFiles.add(SoundFile(soundTheme, SOUND_CHAT))
soundFiles.add(SoundFile(soundTheme, SOUND_DAILY))
soundFiles.add(SoundFile(soundTheme, SOUND_DEATH))
soundFiles.add(SoundFile(soundTheme, SOUND_ITEM_DROP))
soundFiles.add(SoundFile(soundTheme, SOUND_LEVEL_UP))
soundFiles.add(SoundFile(soundTheme, SOUND_MINUS_HABIT))
soundFiles.add(SoundFile(soundTheme, SOUND_PLUS_HABIT))
soundFiles.add(SoundFile(soundTheme, SOUND_REWARD))
soundFiles.add(SoundFile(soundTheme, SOUND_TODO))
MainScope().launchCatching {
soundFileLoader.download(soundFiles)
}
} }
fun loadAndPlayAudio(type: String) { val soundFiles = ArrayList<SoundFile>()
if (soundTheme == SOUND_THEME_OFF) { soundFiles.add(SoundFile(soundTheme, SOUND_ACHIEVEMENT_UNLOCKED))
return soundFiles.add(SoundFile(soundTheme, SOUND_CHAT))
} soundFiles.add(SoundFile(soundTheme, SOUND_DAILY))
soundFiles.add(SoundFile(soundTheme, SOUND_DEATH))
if (loadedSoundFiles.containsKey(type)) { soundFiles.add(SoundFile(soundTheme, SOUND_ITEM_DROP))
loadedSoundFiles[type]?.play() soundFiles.add(SoundFile(soundTheme, SOUND_LEVEL_UP))
} else { soundFiles.add(SoundFile(soundTheme, SOUND_MINUS_HABIT))
val soundFiles = ArrayList<SoundFile>() soundFiles.add(SoundFile(soundTheme, SOUND_PLUS_HABIT))
soundFiles.add(SoundFile(soundTheme, SOUND_REWARD))
soundFiles.add(SoundFile(soundTheme, type)) soundFiles.add(SoundFile(soundTheme, SOUND_TODO))
MainScope().launchCatching { MainScope().launchCatching {
val newFiles = soundFileLoader.download(soundFiles) soundFileLoader.download(soundFiles)
val file = newFiles[0]
loadedSoundFiles[type] = file
file.play()
}
}
}
companion object {
const val SOUND_ACHIEVEMENT_UNLOCKED = "Achievement_Unlocked"
const val SOUND_CHAT = "Chat"
const val SOUND_DAILY = "Daily"
const val SOUND_DEATH = "Death"
const val SOUND_ITEM_DROP = "Item_Drop"
const val SOUND_LEVEL_UP = "Level_Up"
const val SOUND_MINUS_HABIT = "Minus_Habit"
const val SOUND_PLUS_HABIT = "Plus_Habit"
const val SOUND_REWARD = "Reward"
const val SOUND_TODO = "Todo"
const val SOUND_THEME_OFF = "off"
} }
} }
fun loadAndPlayAudio(type: String) {
if (soundTheme == SOUND_THEME_OFF) {
return
}
if (loadedSoundFiles.containsKey(type)) {
loadedSoundFiles[type]?.play()
} else {
val soundFiles = ArrayList<SoundFile>()
soundFiles.add(SoundFile(soundTheme, type))
MainScope().launchCatching {
val newFiles = soundFileLoader.download(soundFiles)
val file = newFiles[0]
loadedSoundFiles[type] = file
file.play()
}
}
}
companion object {
const val SOUND_ACHIEVEMENT_UNLOCKED = "Achievement_Unlocked"
const val SOUND_CHAT = "Chat"
const val SOUND_DAILY = "Daily"
const val SOUND_DEATH = "Death"
const val SOUND_ITEM_DROP = "Item_Drop"
const val SOUND_LEVEL_UP = "Level_Up"
const val SOUND_MINUS_HABIT = "Minus_Habit"
const val SOUND_PLUS_HABIT = "Plus_Habit"
const val SOUND_REWARD = "Reward"
const val SOUND_TODO = "Todo"
const val SOUND_THEME_OFF = "off"
}
}

View file

@ -34,7 +34,7 @@ import java.util.Date
class TaskAlarmManager( class TaskAlarmManager(
private var context: Context, private var context: Context,
private var taskRepository: TaskRepository, private var taskRepository: TaskRepository,
private var authenticationHandler: AuthenticationHandler, private var authenticationHandler: AuthenticationHandler
) { ) {
private val am: AlarmManager? = context.getSystemService(Context.ALARM_SERVICE) as? AlarmManager private val am: AlarmManager? = context.getSystemService(Context.ALARM_SERVICE) as? AlarmManager
private val upcomingReminderOccurrencesToSchedule = 3 private val upcomingReminderOccurrencesToSchedule = 3
@ -141,7 +141,7 @@ class TaskAlarmManager(
private fun setAlarmForRemindersItem( private fun setAlarmForRemindersItem(
reminderItemTask: Task, reminderItemTask: Task,
remindersItem: RemindersItem?, remindersItem: RemindersItem?,
occurrenceIndex: Int, occurrenceIndex: Int
) { ) {
if (remindersItem == null) return if (remindersItem == null) return
@ -166,7 +166,7 @@ class TaskAlarmManager(
context, context,
intentId, intentId,
intent, intent,
withImmutableFlag(PendingIntent.FLAG_NO_CREATE), withImmutableFlag(PendingIntent.FLAG_NO_CREATE)
) )
if (previousSender != null) { if (previousSender != null) {
previousSender.cancel() previousSender.cancel()
@ -178,7 +178,7 @@ class TaskAlarmManager(
context, context,
intentId, intentId,
intent, intent,
withImmutableFlag(PendingIntent.FLAG_CANCEL_CURRENT), withImmutableFlag(PendingIntent.FLAG_CANCEL_CURRENT)
) )
CoroutineScope(Dispatchers.IO).launch { CoroutineScope(Dispatchers.IO).launch {
@ -188,7 +188,7 @@ class TaskAlarmManager(
private fun removeAlarmForRemindersItem( private fun removeAlarmForRemindersItem(
remindersItem: RemindersItem, remindersItem: RemindersItem,
occurrenceIndex: Int? = null, occurrenceIndex: Int? = null
) { ) {
val intent = Intent(context, TaskReceiver::class.java) val intent = Intent(context, TaskReceiver::class.java)
intent.action = remindersItem.id intent.action = remindersItem.id
@ -197,19 +197,19 @@ class TaskAlarmManager(
( (
remindersItem.id?.hashCode() remindersItem.id?.hashCode()
?: (0 and 0xfffffff) ?: (0 and 0xfffffff)
) + occurrenceIndex ) + occurrenceIndex
} else { } else {
( (
remindersItem.id?.hashCode() remindersItem.id?.hashCode()
?: (0 and 0xfffffff) ?: (0 and 0xfffffff)
) )
} }
val sender = val sender =
PendingIntent.getBroadcast( PendingIntent.getBroadcast(
context, context,
intentId, intentId,
intent, intent,
withImmutableFlag(PendingIntent.FLAG_UPDATE_CURRENT), withImmutableFlag(PendingIntent.FLAG_UPDATE_CURRENT)
) )
val am = context.getSystemService(Context.ALARM_SERVICE) as? AlarmManager val am = context.getSystemService(Context.ALARM_SERVICE) as? AlarmManager
sender.cancel() sender.cancel()
@ -250,7 +250,7 @@ class TaskAlarmManager(
context, context,
0, 0,
notificationIntent, notificationIntent,
withImmutableFlag(PendingIntent.FLAG_NO_CREATE), withImmutableFlag(PendingIntent.FLAG_NO_CREATE)
) )
if (previousSender != null) { if (previousSender != null) {
previousSender.cancel() previousSender.cancel()
@ -262,7 +262,7 @@ class TaskAlarmManager(
context, context,
0, 0,
notificationIntent, notificationIntent,
withImmutableFlag(PendingIntent.FLAG_UPDATE_CURRENT), withImmutableFlag(PendingIntent.FLAG_UPDATE_CURRENT)
) )
setAlarm(context, triggerTime, pendingIntent) setAlarm(context, triggerTime, pendingIntent)
@ -280,7 +280,7 @@ class TaskAlarmManager(
private fun setAlarm( private fun setAlarm(
context: Context, context: Context,
time: Long, time: Long,
pendingIntent: PendingIntent?, pendingIntent: PendingIntent?
) { ) {
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as? AlarmManager val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as? AlarmManager
@ -297,15 +297,17 @@ class TaskAlarmManager(
} }
if (canScheduleExact) { if (canScheduleExact) {
alarmManager.setExactAndAllowWhileIdle(notificationType, time, pendingIntent) alarmManager.setExactAndAllowWhileIdle(notificationType, time, pendingIntent)
HLogger.log(LogLevel.DEBUG, HLogger.log(
LogLevel.DEBUG,
"TaskAlarmManager", "TaskAlarmManager",
"setAlarm: Scheduling for $time using setExact ${Date().time}", "setAlarm: Scheduling for $time using setExact ${Date().time}"
) )
} else { } else {
alarmManager.setAndAllowWhileIdle(notificationType, time, pendingIntent) alarmManager.setAndAllowWhileIdle(notificationType, time, pendingIntent)
HLogger.log(LogLevel.DEBUG, HLogger.log(
LogLevel.DEBUG,
"TaskAlarmManager", "TaskAlarmManager",
"setAlarm: Scheduling for $time using setAndAllowWhileIdle", "setAlarm: Scheduling for $time using setAndAllowWhileIdle"
) )
} }
} catch (ex: Exception) { } catch (ex: Exception) {
@ -315,7 +317,7 @@ class TaskAlarmManager(
notificationType, notificationType,
time, time,
600000, 600000,
pendingIntent, pendingIntent
) )
} }

View file

@ -13,7 +13,6 @@ import com.habitrpg.shared.habitica.models.tasks.TaskDifficulty
import com.habitrpg.shared.habitica.models.tasks.TaskType import com.habitrpg.shared.habitica.models.tasks.TaskType
import java.text.DateFormat import java.text.DateFormat
import java.util.Date import java.util.Date
import java.util.Locale
class TaskDescriptionBuilder(private val context: Context) { class TaskDescriptionBuilder(private val context: Context) {
fun describe(task: Task): String { fun describe(task: Task): String {
@ -22,7 +21,7 @@ class TaskDescriptionBuilder(private val context: Context) {
context.getString( context.getString(
R.string.habit_summary_description, R.string.habit_summary_description,
describeHabitDirections(task.up ?: false, task.down ?: false), describeHabitDirections(task.up ?: false, task.down ?: false),
describeDifficulty(task.priority), describeDifficulty(task.priority)
) )
TaskType.TODO -> { TaskType.TODO -> {
@ -30,12 +29,12 @@ class TaskDescriptionBuilder(private val context: Context) {
context.getString( context.getString(
R.string.todo_summary_description_duedate, R.string.todo_summary_description_duedate,
describeDifficulty(task.priority), describeDifficulty(task.priority),
describeDate(task.dueDate!!), describeDate(task.dueDate!!)
) )
} else { } else {
context.getString( context.getString(
R.string.todo_summary_description, R.string.todo_summary_description,
describeDifficulty(task.priority), describeDifficulty(task.priority)
) )
} }
} }
@ -45,7 +44,7 @@ class TaskDescriptionBuilder(private val context: Context) {
R.string.daily_summary_description, R.string.daily_summary_description,
describeDifficulty(task.priority), describeDifficulty(task.priority),
describeRepeatInterval(task.frequency, task.everyX ?: 1), describeRepeatInterval(task.frequency, task.everyX ?: 1),
describeRepeatDays(task), describeRepeatDays(task)
) )
else -> "" else -> ""
@ -102,7 +101,7 @@ class TaskDescriptionBuilder(private val context: Context) {
context.getString( context.getString(
R.string.on_the_x_of_month, R.string.on_the_x_of_month,
occurrence, occurrence,
joinToCount(dayStrings), joinToCount(dayStrings)
) )
} else { } else {
"" ""
@ -116,7 +115,7 @@ class TaskDescriptionBuilder(private val context: Context) {
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 -> ""
@ -141,7 +140,7 @@ class TaskDescriptionBuilder(private val context: Context) {
private fun describeRepeatInterval( private fun describeRepeatInterval(
interval: Frequency?, interval: Frequency?,
everyX: Int, everyX: Int
): String { ): String {
if (everyX == 0) { if (everyX == 0) {
return context.getString(R.string.never) return context.getString(R.string.never)
@ -151,28 +150,28 @@ class TaskDescriptionBuilder(private val context: Context) {
context.resources.getQuantityString( context.resources.getQuantityString(
R.plurals.repeat_daily, R.plurals.repeat_daily,
everyX, everyX,
everyX, everyX
) )
Frequency.WEEKLY -> Frequency.WEEKLY ->
context.resources.getQuantityString( context.resources.getQuantityString(
R.plurals.repeat_weekly, R.plurals.repeat_weekly,
everyX, everyX,
everyX, everyX
) )
Frequency.MONTHLY -> Frequency.MONTHLY ->
context.resources.getQuantityString( context.resources.getQuantityString(
R.plurals.repeat_monthly, R.plurals.repeat_monthly,
everyX, everyX,
everyX, everyX
) )
Frequency.YEARLY -> Frequency.YEARLY ->
context.resources.getQuantityString( context.resources.getQuantityString(
R.plurals.repeat_yearly, R.plurals.repeat_yearly,
everyX, everyX,
everyX, everyX
) )
null -> "" null -> ""
@ -181,7 +180,7 @@ class TaskDescriptionBuilder(private val context: Context) {
private fun describeHabitDirections( private fun describeHabitDirections(
up: Boolean, up: Boolean,
down: Boolean, down: Boolean
): String { ): String {
return if (up && down) { return if (up && down) {
context.getString(R.string.positive_and_negative) context.getString(R.string.positive_and_negative)

View file

@ -26,7 +26,7 @@ class UserStatComputer {
fun computeClassBonus( fun computeClassBonus(
equipmentList: List<Equipment>?, equipmentList: List<Equipment>?,
user: Avatar, user: Avatar
): List<StatsRow> { ): List<StatsRow> {
val skillRows = ArrayList<StatsRow>() val skillRows = ArrayList<StatsRow>()

View file

@ -62,13 +62,13 @@ class GroupActivityNotification(context: Context, identifier: String?) :
return NotificationCompat.MessagingStyle.Message( return NotificationCompat.MessagingStyle.Message(
messageText, messageText,
timestamp.time, timestamp.time,
sender, sender
) )
} }
override fun setNotificationActions( override fun setNotificationActions(
notificationId: Int, notificationId: Int,
data: Map<String, String>, data: Map<String, String>
) { ) {
super.setNotificationActions(notificationId, data) super.setNotificationActions(notificationId, data)
val groupID = data["groupID"] ?: return val groupID = data["groupID"] ?: return
@ -89,14 +89,14 @@ class GroupActivityNotification(context: Context, identifier: String?) :
context, context,
groupID.hashCode(), groupID.hashCode(),
intent, intent,
withMutableFlag(PendingIntent.FLAG_UPDATE_CURRENT), withMutableFlag(PendingIntent.FLAG_UPDATE_CURRENT)
) )
val action: NotificationCompat.Action = val action: NotificationCompat.Action =
NotificationCompat.Action.Builder( NotificationCompat.Action.Builder(
R.drawable.ic_send_grey_600_24dp, R.drawable.ic_send_grey_600_24dp,
context.getString(R.string.reply), context.getString(R.string.reply),
replyPendingIntent, replyPendingIntent
) )
.addRemoteInput(remoteInput) .addRemoteInput(remoteInput)
.build() .build()

View file

@ -19,7 +19,7 @@ class GuildInviteLocalNotification(context: Context, identifier: String?) :
override fun setNotificationActions( override fun setNotificationActions(
notificationId: Int, notificationId: Int,
data: Map<String, String>, data: Map<String, String>
) { ) {
super.setNotificationActions(notificationId, data) super.setNotificationActions(notificationId, data)
val res = context.resources val res = context.resources
@ -34,7 +34,7 @@ class GuildInviteLocalNotification(context: Context, identifier: String?) :
context, context,
groupID.hashCode(), groupID.hashCode(),
acceptInviteIntent, acceptInviteIntent,
withImmutableFlag(PendingIntent.FLAG_UPDATE_CURRENT), withImmutableFlag(PendingIntent.FLAG_UPDATE_CURRENT)
) )
notificationBuilder.addAction(0, "Accept", pendingIntentAccept) notificationBuilder.addAction(0, "Accept", pendingIntentAccept)
@ -47,7 +47,7 @@ class GuildInviteLocalNotification(context: Context, identifier: String?) :
context, context,
groupID.hashCode() + 1, groupID.hashCode() + 1,
rejectInviteIntent, rejectInviteIntent,
withImmutableFlag(PendingIntent.FLAG_UPDATE_CURRENT), withImmutableFlag(PendingIntent.FLAG_UPDATE_CURRENT)
) )
notificationBuilder.addAction(0, "Reject", pendingIntentReject) notificationBuilder.addAction(0, "Reject", pendingIntentReject)
} }

View file

@ -18,7 +18,7 @@ import java.util.Date
*/ */
abstract class HabiticaLocalNotification( abstract class HabiticaLocalNotification(
protected var context: Context, protected var context: Context,
protected var identifier: String?, protected var identifier: String?
) { ) {
protected var data: Map<String, String>? = null protected var data: Map<String, String>? = null
protected var title: String? = null protected var title: String? = null
@ -40,7 +40,7 @@ abstract class HabiticaLocalNotification(
open fun notifyLocally( open fun notifyLocally(
title: String?, title: String?,
message: String?, message: String?,
data: MutableMap<String, String>, data: MutableMap<String, String>
) { ) {
this.title = title this.title = title
this.message = message this.message = message
@ -71,7 +71,7 @@ abstract class HabiticaLocalNotification(
protected open fun setNotificationActions( protected open fun setNotificationActions(
notificationId: Int, notificationId: Int,
data: Map<String, String>, data: Map<String, String>
) { ) {
val intent = Intent(context, MainActivity::class.java) val intent = Intent(context, MainActivity::class.java)
configureMainIntent(intent) configureMainIntent(intent)
@ -81,7 +81,7 @@ abstract class HabiticaLocalNotification(
context, context,
3000, 3000,
intent, intent,
withImmutableFlag(PendingIntent.FLAG_UPDATE_CURRENT), withImmutableFlag(PendingIntent.FLAG_UPDATE_CURRENT)
) )
notificationBuilder.setContentIntent(pendingIntent) notificationBuilder.setContentIntent(pendingIntent)
} }

View file

@ -6,89 +6,89 @@ class HabiticaLocalNotificationFactory {
// use getShape method to get object of type shape // use getShape method to get object of type shape
fun build( fun build(
notificationType: String?, notificationType: String?,
context: Context?, context: Context?
): HabiticaLocalNotification { ): HabiticaLocalNotification {
return when { return when {
PushNotificationManager.PARTY_INVITE_PUSH_NOTIFICATION_KEY.equals( PushNotificationManager.PARTY_INVITE_PUSH_NOTIFICATION_KEY.equals(
notificationType, notificationType,
true, true
) -> { ) -> {
PartyInviteLocalNotification(context!!, notificationType) PartyInviteLocalNotification(context!!, notificationType)
} }
PushNotificationManager.RECEIVED_PRIVATE_MESSAGE_PUSH_NOTIFICATION_KEY.equals( PushNotificationManager.RECEIVED_PRIVATE_MESSAGE_PUSH_NOTIFICATION_KEY.equals(
notificationType, notificationType,
true, true
) -> { ) -> {
ReceivedPrivateMessageLocalNotification(context!!, notificationType) ReceivedPrivateMessageLocalNotification(context!!, notificationType)
} }
PushNotificationManager.RECEIVED_GEMS_PUSH_NOTIFICATION_KEY.equals( PushNotificationManager.RECEIVED_GEMS_PUSH_NOTIFICATION_KEY.equals(
notificationType, notificationType,
true, true
) -> { ) -> {
ReceivedGemsGiftLocalNotification(context!!, notificationType) ReceivedGemsGiftLocalNotification(context!!, notificationType)
} }
PushNotificationManager.RECEIVED_SUBSCRIPTION_GIFT_PUSH_NOTIFICATION_KEY.equals( PushNotificationManager.RECEIVED_SUBSCRIPTION_GIFT_PUSH_NOTIFICATION_KEY.equals(
notificationType, notificationType,
true, true
) -> { ) -> {
ReceivedSubscriptionGiftLocalNotification(context!!, notificationType) ReceivedSubscriptionGiftLocalNotification(context!!, notificationType)
} }
PushNotificationManager.GUILD_INVITE_PUSH_NOTIFICATION_KEY.equals( PushNotificationManager.GUILD_INVITE_PUSH_NOTIFICATION_KEY.equals(
notificationType, notificationType,
true, true
) -> { ) -> {
GuildInviteLocalNotification(context!!, notificationType) GuildInviteLocalNotification(context!!, notificationType)
} }
PushNotificationManager.QUEST_INVITE_PUSH_NOTIFICATION_KEY.equals( PushNotificationManager.QUEST_INVITE_PUSH_NOTIFICATION_KEY.equals(
notificationType, notificationType,
true, true
) -> { ) -> {
QuestInviteLocalNotification(context!!, notificationType) QuestInviteLocalNotification(context!!, notificationType)
} }
PushNotificationManager.QUEST_BEGUN_PUSH_NOTIFICATION_KEY.equals( PushNotificationManager.QUEST_BEGUN_PUSH_NOTIFICATION_KEY.equals(
notificationType, notificationType,
true, true
) -> { ) -> {
QuestBegunLocalNotification(context!!, notificationType) QuestBegunLocalNotification(context!!, notificationType)
} }
PushNotificationManager.WON_CHALLENGE_PUSH_NOTIFICATION_KEY.equals( PushNotificationManager.WON_CHALLENGE_PUSH_NOTIFICATION_KEY.equals(
notificationType, notificationType,
true, true
) -> { ) -> {
WonChallengeLocalNotification(context!!, notificationType) WonChallengeLocalNotification(context!!, notificationType)
} }
PushNotificationManager.CHANGE_USERNAME_PUSH_NOTIFICATION_KEY.equals( PushNotificationManager.CHANGE_USERNAME_PUSH_NOTIFICATION_KEY.equals(
notificationType, notificationType,
true, true
) -> { ) -> {
ChangeUsernameLocalNotification(context!!, notificationType) ChangeUsernameLocalNotification(context!!, notificationType)
} }
PushNotificationManager.GIFT_ONE_GET_ONE_PUSH_NOTIFICATION_KEY.equals( PushNotificationManager.GIFT_ONE_GET_ONE_PUSH_NOTIFICATION_KEY.equals(
notificationType, notificationType,
true, true
) -> { ) -> {
GiftOneGetOneLocalNotification(context!!, notificationType) GiftOneGetOneLocalNotification(context!!, notificationType)
} }
PushNotificationManager.CHAT_MENTION_NOTIFICATION_KEY.equals( PushNotificationManager.CHAT_MENTION_NOTIFICATION_KEY.equals(
notificationType, notificationType,
true, true
) -> { ) -> {
ChatMentionNotification(context!!, notificationType) ChatMentionNotification(context!!, notificationType)
} }
PushNotificationManager.GROUP_ACTIVITY_NOTIFICATION_KEY.equals( PushNotificationManager.GROUP_ACTIVITY_NOTIFICATION_KEY.equals(
notificationType, notificationType,
true, true
) -> { ) -> {
GroupActivityNotification(context!!, notificationType) GroupActivityNotification(context!!, notificationType)
} }

View file

@ -14,7 +14,7 @@ class PartyInviteLocalNotification(context: Context, identifier: String?) :
HabiticaLocalNotification(context, identifier) { HabiticaLocalNotification(context, identifier) {
override fun setNotificationActions( override fun setNotificationActions(
notificationId: Int, notificationId: Int,
data: Map<String, String>, data: Map<String, String>
) { ) {
super.setNotificationActions(notificationId, data) super.setNotificationActions(notificationId, data)
val res = context.resources val res = context.resources
@ -29,7 +29,7 @@ class PartyInviteLocalNotification(context: Context, identifier: String?) :
context, context,
groupID.hashCode(), groupID.hashCode(),
acceptInviteIntent, acceptInviteIntent,
withImmutableFlag(PendingIntent.FLAG_UPDATE_CURRENT), withImmutableFlag(PendingIntent.FLAG_UPDATE_CURRENT)
) )
notificationBuilder.addAction(0, context.getString(R.string.accept), pendingIntentAccept) notificationBuilder.addAction(0, context.getString(R.string.accept), pendingIntentAccept)
@ -42,7 +42,7 @@ class PartyInviteLocalNotification(context: Context, identifier: String?) :
context, context,
groupID.hashCode() + 1, groupID.hashCode() + 1,
rejectInviteIntent, rejectInviteIntent,
withImmutableFlag(PendingIntent.FLAG_UPDATE_CURRENT), withImmutableFlag(PendingIntent.FLAG_UPDATE_CURRENT)
) )
notificationBuilder.addAction(0, context.getString(R.string.reject), pendingIntentReject) notificationBuilder.addAction(0, context.getString(R.string.reject), pendingIntentReject)
} }

View file

@ -18,7 +18,7 @@ import java.io.IOException
class PushNotificationManager( class PushNotificationManager(
var apiClient: ApiClient, var apiClient: ApiClient,
private val sharedPreferences: SharedPreferences, private val sharedPreferences: SharedPreferences,
private val context: Context, private val context: Context
) { ) {
var refreshedToken: String = "" var refreshedToken: String = ""
set(value) { set(value) {
@ -136,7 +136,7 @@ class PushNotificationManager(
fun displayNotification( fun displayNotification(
remoteMessage: RemoteMessage, remoteMessage: RemoteMessage,
context: Context, context: Context,
pushNotificationManager: PushNotificationManager? = null, pushNotificationManager: PushNotificationManager? = null
) { ) {
val remoteMessageIdentifier = remoteMessage.data["identifier"] val remoteMessageIdentifier = remoteMessage.data["identifier"]
@ -148,7 +148,7 @@ class PushNotificationManager(
"receive notification", "receive notification",
EventCategory.BEHAVIOUR, EventCategory.BEHAVIOUR,
HitType.EVENT, HitType.EVENT,
additionalData, additionalData
) )
} }
@ -156,7 +156,7 @@ class PushNotificationManager(
val localNotification = val localNotification =
notificationFactory.build( notificationFactory.build(
remoteMessageIdentifier, remoteMessageIdentifier,
context, context
) )
localNotification.setExtras(remoteMessage.data) localNotification.setExtras(remoteMessage.data)
val notification = remoteMessage.notification val notification = remoteMessage.notification
@ -164,13 +164,13 @@ class PushNotificationManager(
localNotification.notifyLocally( localNotification.notifyLocally(
notification.title ?: remoteMessage.data["title"], notification.title ?: remoteMessage.data["title"],
notification.body ?: remoteMessage.data["body"], notification.body ?: remoteMessage.data["body"],
remoteMessage.data, remoteMessage.data
) )
} else { } else {
localNotification.notifyLocally( localNotification.notifyLocally(
remoteMessage.data["title"], remoteMessage.data["title"],
remoteMessage.data["body"], remoteMessage.data["body"],
remoteMessage.data, remoteMessage.data
) )
} }
} }

View file

@ -18,7 +18,7 @@ class QuestInviteLocalNotification(context: Context, identifier: String?) :
override fun setNotificationActions( override fun setNotificationActions(
notificationId: Int, notificationId: Int,
data: Map<String, String>, data: Map<String, String>
) { ) {
super.setNotificationActions(notificationId, data) super.setNotificationActions(notificationId, data)
val res = context.resources val res = context.resources
@ -37,7 +37,7 @@ class QuestInviteLocalNotification(context: Context, identifier: String?) :
context, context,
3001, 3001,
acceptInviteIntent, acceptInviteIntent,
flags, flags
) )
notificationBuilder.addAction(0, "Accept", pendingIntentAccept) notificationBuilder.addAction(0, "Accept", pendingIntentAccept)
@ -49,7 +49,7 @@ class QuestInviteLocalNotification(context: Context, identifier: String?) :
context, context,
2001, 2001,
rejectInviteIntent, rejectInviteIntent,
flags, flags
) )
notificationBuilder.addAction(0, "Reject", pendingIntentReject) notificationBuilder.addAction(0, "Reject", pendingIntentReject)
} }

View file

@ -44,7 +44,7 @@ class ReceivedPrivateMessageLocalNotification(context: Context, identifier: Stri
context.getString( context.getString(
R.string.inbox_messages_title, R.string.inbox_messages_title,
oldMessages.size, oldMessages.size,
data["senderName"], data["senderName"]
) )
} else { } else {
context.getString(R.string.inbox_messages_title_nosender, oldMessages.size) context.getString(R.string.inbox_messages_title_nosender, oldMessages.size)
@ -60,8 +60,8 @@ class ReceivedPrivateMessageLocalNotification(context: Context, identifier: Stri
notification.setContentTitle( notification.setContentTitle(
context.getString( context.getString(
R.string.inbox_messages_title_single, R.string.inbox_messages_title_single,
data["senderName"], data["senderName"]
), )
) )
} }
return notification return notification
@ -79,7 +79,7 @@ class ReceivedPrivateMessageLocalNotification(context: Context, identifier: Stri
override fun setNotificationActions( override fun setNotificationActions(
notificationId: Int, notificationId: Int,
data: Map<String, String>, data: Map<String, String>
) { ) {
super.setNotificationActions(notificationId, data) super.setNotificationActions(notificationId, data)
val senderID = data["replyTo"] ?: return val senderID = data["replyTo"] ?: return
@ -100,14 +100,14 @@ class ReceivedPrivateMessageLocalNotification(context: Context, identifier: Stri
context, context,
senderID.hashCode(), senderID.hashCode(),
intent, intent,
withMutableFlag(PendingIntent.FLAG_UPDATE_CURRENT), withMutableFlag(PendingIntent.FLAG_UPDATE_CURRENT)
) )
val action: NotificationCompat.Action = val action: NotificationCompat.Action =
NotificationCompat.Action.Builder( NotificationCompat.Action.Builder(
R.drawable.ic_send_grey_600_24dp, R.drawable.ic_send_grey_600_24dp,
context.getString(R.string.reply), context.getString(R.string.reply),
replyPendingIntent, replyPendingIntent
) )
.addRemoteInput(remoteInput) .addRemoteInput(remoteInput)
.build() .build()

View file

@ -8,27 +8,27 @@ import com.habitrpg.shared.habitica.models.responses.TaskScoringResult
import javax.inject.Inject import javax.inject.Inject
class BuyRewardUseCase class BuyRewardUseCase
@Inject @Inject
constructor( constructor(
private val taskRepository: TaskRepository, private val taskRepository: TaskRepository,
private val soundManager: SoundManager, private val soundManager: SoundManager
) : UseCase<BuyRewardUseCase.RequestValues, TaskScoringResult?>() { ) : UseCase<BuyRewardUseCase.RequestValues, TaskScoringResult?>() {
override suspend fun run(requestValues: RequestValues): TaskScoringResult? { override suspend fun run(requestValues: RequestValues): TaskScoringResult? {
val response = val response =
taskRepository.taskChecked( taskRepository.taskChecked(
requestValues.user, requestValues.user,
requestValues.task, requestValues.task,
false, false,
false, false,
requestValues.notifyFunc, requestValues.notifyFunc
) )
soundManager.loadAndPlayAudio(SoundManager.SOUND_REWARD) soundManager.loadAndPlayAudio(SoundManager.SOUND_REWARD)
return response return response
}
class RequestValues(
internal val user: User?,
val task: Task,
val notifyFunc: (TaskScoringResult) -> Unit,
) : UseCase.RequestValues
} }
class RequestValues(
internal val user: User?,
val task: Task,
val notifyFunc: (TaskScoringResult) -> Unit
) : UseCase.RequestValues
}

View file

@ -8,45 +8,45 @@ import com.habitrpg.android.habitica.ui.activities.ClassSelectionActivity
import javax.inject.Inject import javax.inject.Inject
class CheckClassSelectionUseCase class CheckClassSelectionUseCase
@Inject @Inject
constructor() : constructor() :
UseCase<CheckClassSelectionUseCase.RequestValues, Unit>() { UseCase<CheckClassSelectionUseCase.RequestValues, Unit>() {
override suspend fun run(requestValues: RequestValues) { override suspend fun run(requestValues: RequestValues) {
val user = requestValues.user val user = requestValues.user
if (requestValues.currentClass == null) { if (requestValues.currentClass == null) {
if ((user?.stats?.lvl ?: 0) >= 9 && if ((user?.stats?.lvl ?: 0) >= 9 &&
user?.preferences?.disableClasses != true && user?.preferences?.disableClasses != true &&
user?.flags?.classSelected != true user?.flags?.classSelected != true
) { ) {
displayClassSelectionActivity(false, null, requestValues.activity) displayClassSelectionActivity(false, null, requestValues.activity)
}
} else {
displayClassSelectionActivity(
requestValues.isClassSelected,
requestValues.currentClass,
requestValues.activity,
)
} }
} else {
displayClassSelectionActivity(
requestValues.isClassSelected,
requestValues.currentClass,
requestValues.activity
)
} }
private fun displayClassSelectionActivity(
isClassSelected: Boolean,
currentClass: String?,
activity: Activity,
) {
val bundle = Bundle()
bundle.putBoolean("isClassSelected", isClassSelected)
bundle.putString("currentClass", currentClass)
val intent = Intent(activity, ClassSelectionActivity::class.java)
intent.putExtras(bundle)
activity.startActivity(intent)
}
class RequestValues(
val user: User?,
val isClassSelected: Boolean,
val currentClass: String?,
val activity: Activity,
) : UseCase.RequestValues
} }
private fun displayClassSelectionActivity(
isClassSelected: Boolean,
currentClass: String?,
activity: Activity
) {
val bundle = Bundle()
bundle.putBoolean("isClassSelected", isClassSelected)
bundle.putString("currentClass", currentClass)
val intent = Intent(activity, ClassSelectionActivity::class.java)
intent.putExtras(bundle)
activity.startActivity(intent)
}
class RequestValues(
val user: User?,
val isClassSelected: Boolean,
val currentClass: String?,
val activity: Activity
) : UseCase.RequestValues
}

View file

@ -13,44 +13,44 @@ import kotlinx.coroutines.launch
import javax.inject.Inject import javax.inject.Inject
class DisplayItemDropUseCase class DisplayItemDropUseCase
@Inject @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) {
val data = requestValues.data val data = requestValues.data
val snackbarText = StringBuilder(data?.drop?.dialog ?: "") val snackbarText = StringBuilder(data?.drop?.dialog ?: "")
if ((data?.questItemsFound ?: 0) > 0 && requestValues.showQuestItems) {
if (snackbarText.isNotEmpty()) {
snackbarText.append('\n')
}
snackbarText.append(
requestValues.context.getString(
R.string.quest_items_found,
data!!.questItemsFound,
),
)
}
if ((data?.questItemsFound ?: 0) > 0 && requestValues.showQuestItems) {
if (snackbarText.isNotEmpty()) { if (snackbarText.isNotEmpty()) {
MainScope().launch(context = Dispatchers.Main) { snackbarText.append('\n')
delay(3000L)
HabiticaSnackbar.showSnackbar(
requestValues.snackbarTargetView,
snackbarText,
HabiticaSnackbar.SnackbarDisplayType.DROP,
true,
)
soundManager.loadAndPlayAudio(SoundManager.SOUND_ITEM_DROP)
}
} }
return snackbarText.append(
requestValues.context.getString(
R.string.quest_items_found,
data!!.questItemsFound
)
)
} }
class RequestValues( if (snackbarText.isNotEmpty()) {
val data: TaskScoringResult?, MainScope().launch(context = Dispatchers.Main) {
val context: AppCompatActivity, delay(3000L)
val snackbarTargetView: ViewGroup, HabiticaSnackbar.showSnackbar(
val showQuestItems: Boolean, requestValues.snackbarTargetView,
) : UseCase.RequestValues snackbarText,
HabiticaSnackbar.SnackbarDisplayType.DROP,
true
)
soundManager.loadAndPlayAudio(SoundManager.SOUND_ITEM_DROP)
}
}
return
} }
class RequestValues(
val data: TaskScoringResult?,
val context: AppCompatActivity,
val snackbarTargetView: ViewGroup,
val showQuestItems: Boolean
) : UseCase.RequestValues
}

View file

@ -22,64 +22,64 @@ import kotlinx.coroutines.MainScope
import javax.inject.Inject import javax.inject.Inject
class FeedPetUseCase class FeedPetUseCase
@Inject @Inject
constructor( constructor(
private val inventoryRepository: InventoryRepository, private val inventoryRepository: InventoryRepository
) : UseCase<FeedPetUseCase.RequestValues, FeedResponse?>() { ) : UseCase<FeedPetUseCase.RequestValues, FeedResponse?>() {
override suspend fun run(requestValues: RequestValues): FeedResponse? { override suspend fun run(requestValues: RequestValues): FeedResponse? {
val feedResponse = inventoryRepository.feedPet(requestValues.pet, requestValues.food) val feedResponse = inventoryRepository.feedPet(requestValues.pet, requestValues.food)
(requestValues.context as? SnackbarActivity)?.showSnackbar(content = feedResponse?.message) (requestValues.context as? SnackbarActivity)?.showSnackbar(content = feedResponse?.message)
if (feedResponse?.value == -1) { if (feedResponse?.value == -1) {
val mountWrapper = MountImageviewBinding.inflate(requestValues.context.layoutInflater) val mountWrapper = MountImageviewBinding.inflate(requestValues.context.layoutInflater)
mountWrapper.mountImageview.setMount(requestValues.pet.key) mountWrapper.mountImageview.setMount(requestValues.pet.key)
val currentActivity = val currentActivity =
HabiticaBaseApplication.getInstance(requestValues.context)?.currentActivity?.get() HabiticaBaseApplication.getInstance(requestValues.context)?.currentActivity?.get()
val dialog = HabiticaAlertDialog(requestValues.context) val dialog = HabiticaAlertDialog(requestValues.context)
if (currentActivity != null) { if (currentActivity != null) {
mountWrapper.backgroundView.setContent { mountWrapper.backgroundView.setContent {
HabiticaTheme { HabiticaTheme {
BackgroundScene(Modifier.clip(HabiticaTheme.shapes.large)) BackgroundScene(Modifier.clip(HabiticaTheme.shapes.large))
}
}
dialog.window?.let {
mountWrapper.root.setViewTreeSavedStateRegistryOwner(currentActivity)
it.decorView.setViewTreeSavedStateRegistryOwner(currentActivity)
mountWrapper.root.setViewTreeLifecycleOwner(currentActivity)
it.decorView.setViewTreeLifecycleOwner(currentActivity)
} }
} }
dialog.setTitle( dialog.window?.let {
requestValues.context.getString( mountWrapper.root.setViewTreeSavedStateRegistryOwner(currentActivity)
R.string.evolved_pet_title, it.decorView.setViewTreeSavedStateRegistryOwner(currentActivity)
requestValues.pet.text, mountWrapper.root.setViewTreeLifecycleOwner(currentActivity)
), it.decorView.setViewTreeLifecycleOwner(currentActivity)
)
dialog.isCelebratory = true
dialog.setAdditionalContentView(mountWrapper.root)
dialog.addButton(R.string.onwards, true)
dialog.addButton(R.string.share, false) { hatchingDialog, _ ->
val message =
requestValues.context.getString(
R.string.share_raised,
requestValues.pet.text,
)
MainScope().launchCatching {
ShareMountUseCase().callInteractor(
ShareMountUseCase.RequestValues(
requestValues.pet.key,
message,
requestValues.context,
),
)
}
hatchingDialog.dismiss()
} }
dialog.enqueue()
} }
return feedResponse dialog.setTitle(
requestValues.context.getString(
R.string.evolved_pet_title,
requestValues.pet.text
)
)
dialog.isCelebratory = true
dialog.setAdditionalContentView(mountWrapper.root)
dialog.addButton(R.string.onwards, true)
dialog.addButton(R.string.share, false) { hatchingDialog, _ ->
val message =
requestValues.context.getString(
R.string.share_raised,
requestValues.pet.text
)
MainScope().launchCatching {
ShareMountUseCase().callInteractor(
ShareMountUseCase.RequestValues(
requestValues.pet.key,
message,
requestValues.context
)
)
}
hatchingDialog.dismiss()
}
dialog.enqueue()
} }
return feedResponse
class RequestValues(val pet: Pet, val food: Food, val context: Context) :
UseCase.RequestValues
} }
class RequestValues(val pet: Pet, val food: Food, val context: Context) :
UseCase.RequestValues
}

View file

@ -23,71 +23,71 @@ import kotlinx.coroutines.MainScope
import javax.inject.Inject import javax.inject.Inject
class HatchPetUseCase class HatchPetUseCase
@Inject @Inject
constructor( constructor(
private val inventoryRepository: InventoryRepository, private val inventoryRepository: InventoryRepository
) : UseCase<HatchPetUseCase.RequestValues, Items?>() { ) : 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 = PetImageviewBinding.inflate(requestValues.context.layoutInflater) val petWrapper = PetImageviewBinding.inflate(requestValues.context.layoutInflater)
val petKey = requestValues.egg.key + "-" + requestValues.potion.key val petKey = requestValues.egg.key + "-" + requestValues.potion.key
petWrapper.petImageview.loadImage("stable_Pet-$petKey") petWrapper.petImageview.loadImage("stable_Pet-$petKey")
val potionName = requestValues.potion.text val potionName = requestValues.potion.text
val eggName = requestValues.egg.text val eggName = requestValues.egg.text
val currentActivity = val currentActivity =
HabiticaBaseApplication.getInstance(requestValues.context)?.currentActivity?.get() HabiticaBaseApplication.getInstance(requestValues.context)?.currentActivity?.get()
val dialog = HabiticaAlertDialog(requestValues.context) val dialog = HabiticaAlertDialog(requestValues.context)
if (currentActivity != null) { if (currentActivity != null) {
petWrapper.backgroundView.setContent { petWrapper.backgroundView.setContent {
HabiticaTheme { HabiticaTheme {
BackgroundScene(Modifier.clip(HabiticaTheme.shapes.large)) BackgroundScene(Modifier.clip(HabiticaTheme.shapes.large))
}
}
dialog.window?.let {
petWrapper.root.setViewTreeSavedStateRegistryOwner(currentActivity)
it.decorView.setViewTreeSavedStateRegistryOwner(currentActivity)
petWrapper.root.setViewTreeLifecycleOwner(currentActivity)
it.decorView.setViewTreeLifecycleOwner(currentActivity)
} }
} }
dialog.isCelebratory = true dialog.window?.let {
dialog.setTitle( petWrapper.root.setViewTreeSavedStateRegistryOwner(currentActivity)
requestValues.context.getString( it.decorView.setViewTreeSavedStateRegistryOwner(currentActivity)
R.string.hatched_pet_title, petWrapper.root.setViewTreeLifecycleOwner(currentActivity)
potionName, it.decorView.setViewTreeLifecycleOwner(currentActivity)
eggName,
),
)
dialog.setAdditionalContentView(petWrapper.root)
dialog.addButton(R.string.equip, true) { _, _ ->
MainScope().launchCatching {
inventoryRepository.equip(
"pet",
requestValues.egg.key + "-" + requestValues.potion.key,
)
}
} }
dialog.addButton(R.string.share, false) { hatchingDialog, _ ->
MainScope().launchCatching {
SharePetUseCase().callInteractor(
SharePetUseCase.RequestValues(
petKey,
requestValues.context.getString(
R.string.share_hatched,
potionName,
eggName,
),
requestValues.context,
),
)
}
hatchingDialog.dismiss()
}
dialog.setExtraCloseButtonVisibility(View.VISIBLE)
dialog.enqueue()
} }
dialog.isCelebratory = true
dialog.setTitle(
requestValues.context.getString(
R.string.hatched_pet_title,
potionName,
eggName
)
)
dialog.setAdditionalContentView(petWrapper.root)
dialog.addButton(R.string.equip, true) { _, _ ->
MainScope().launchCatching {
inventoryRepository.equip(
"pet",
requestValues.egg.key + "-" + requestValues.potion.key
)
}
}
dialog.addButton(R.string.share, false) { hatchingDialog, _ ->
MainScope().launchCatching {
SharePetUseCase().callInteractor(
SharePetUseCase.RequestValues(
petKey,
requestValues.context.getString(
R.string.share_hatched,
potionName,
eggName
),
requestValues.context
)
)
}
hatchingDialog.dismiss()
}
dialog.setExtraCloseButtonVisibility(View.VISIBLE)
dialog.enqueue()
} }
class RequestValues(val potion: HatchingPotion, val egg: Egg, val context: Context) :
UseCase.RequestValues
} }
class RequestValues(val potion: HatchingPotion, val egg: Egg, val context: Context) :
UseCase.RequestValues
}

View file

@ -7,21 +7,21 @@ import com.habitrpg.android.habitica.ui.activities.MainActivity
import javax.inject.Inject import javax.inject.Inject
class InsufficientGemsUseCase class InsufficientGemsUseCase
@Inject @Inject
constructor( constructor(
private val purchaseHandler: PurchaseHandler, private val purchaseHandler: PurchaseHandler
) : UseCase<InsufficientGemsUseCase.RequestValues, Unit>() { ) : UseCase<InsufficientGemsUseCase.RequestValues, Unit>() {
override suspend fun run(requestValues: RequestValues) { override suspend fun run(requestValues: RequestValues) {
val activity = requestValues.activity as? MainActivity ?: return val activity = requestValues.activity as? MainActivity ?: return
val gemSku = val gemSku =
if (requestValues.gemPrice > 4) { if (requestValues.gemPrice > 4) {
PurchaseTypes.PURCHASE_21_GEMS PurchaseTypes.PURCHASE_21_GEMS
} else { } else {
PurchaseTypes.PURCHASE_4_GEMS PurchaseTypes.PURCHASE_4_GEMS
} }
val sku = purchaseHandler.getInAppPurchaseSKU(gemSku) ?: return val sku = purchaseHandler.getInAppPurchaseSKU(gemSku) ?: return
purchaseHandler.purchase(activity, sku) purchaseHandler.purchase(activity, sku)
}
class RequestValues(val gemPrice: Int, val activity: Activity) : UseCase.RequestValues
} }
class RequestValues(val gemPrice: Int, val activity: Activity) : UseCase.RequestValues
}

View file

@ -16,116 +16,116 @@ import kotlinx.coroutines.MainScope
import javax.inject.Inject import javax.inject.Inject
class LevelUpUseCase class LevelUpUseCase
@Inject @Inject
constructor( constructor(
private val soundManager: SoundManager, private val soundManager: SoundManager,
private val checkClassSelectionUseCase: CheckClassSelectionUseCase, private val checkClassSelectionUseCase: CheckClassSelectionUseCase
) : UseCase<LevelUpUseCase.RequestValues, Stats?>() { ) : UseCase<LevelUpUseCase.RequestValues, Stats?>() {
override suspend fun run(requestValues: RequestValues): Stats? { override suspend fun run(requestValues: RequestValues): Stats? {
soundManager.loadAndPlayAudio(SoundManager.SOUND_LEVEL_UP) soundManager.loadAndPlayAudio(SoundManager.SOUND_LEVEL_UP)
val suppressedModals = requestValues.user.preferences?.suppressModals val suppressedModals = requestValues.user.preferences?.suppressModals
if (requestValues.newLevel == 10) { if (requestValues.newLevel == 10) {
val binding = DialogLevelup10Binding.inflate(requestValues.activity.layoutInflater) val binding = DialogLevelup10Binding.inflate(requestValues.activity.layoutInflater)
binding.healerIconView.setImageBitmap(HabiticaIconsHelper.imageOfHealerLightBg()) binding.healerIconView.setImageBitmap(HabiticaIconsHelper.imageOfHealerLightBg())
binding.mageIconView.setImageBitmap(HabiticaIconsHelper.imageOfMageLightBg()) binding.mageIconView.setImageBitmap(HabiticaIconsHelper.imageOfMageLightBg())
binding.rogueIconView.setImageBitmap(HabiticaIconsHelper.imageOfRogueLightBg()) binding.rogueIconView.setImageBitmap(HabiticaIconsHelper.imageOfRogueLightBg())
binding.warriorIconView.setImageBitmap(HabiticaIconsHelper.imageOfWarriorLightBg()) binding.warriorIconView.setImageBitmap(HabiticaIconsHelper.imageOfWarriorLightBg())
val alert = HabiticaAlertDialog(requestValues.activity) val alert = HabiticaAlertDialog(requestValues.activity)
alert.setTitle( alert.setTitle(
requestValues.activity.getString( requestValues.activity.getString(
R.string.levelup_header, R.string.levelup_header,
requestValues.newLevel, requestValues.newLevel
),
) )
alert.setAdditionalContentView(binding.root) )
alert.addButton(R.string.select_class, true) { _, _ -> alert.setAdditionalContentView(binding.root)
MainScope().launchCatching { alert.addButton(R.string.select_class, true) { _, _ ->
showClassSelection(requestValues) MainScope().launchCatching {
} showClassSelection(requestValues)
}
alert.addButton(R.string.not_now, false)
alert.isCelebratory = true
if (!requestValues.activity.isFinishing) {
alert.enqueue()
}
} else {
if (suppressedModals?.levelUp == true) {
HabiticaSnackbar.showSnackbar(
requestValues.snackbarTargetView,
requestValues.activity.getString(
R.string.levelup_header,
requestValues.newLevel,
),
HabiticaSnackbar.SnackbarDisplayType.SUCCESS,
true,
)
return requestValues.user.stats
}
val customView =
requestValues.activity.layoutInflater.inflate(R.layout.dialog_levelup, null)
if (customView != null) {
val dialogAvatarView = customView.findViewById<AvatarView>(R.id.avatarView)
dialogAvatarView.setAvatar(requestValues.user)
}
val alert = HabiticaAlertDialog(requestValues.activity)
alert.setTitle(
requestValues.activity.getString(
R.string.levelup_header,
requestValues.newLevel,
),
)
alert.setAdditionalContentView(customView)
alert.addButton(R.string.onwards, true) { _, _ ->
MainScope().launchCatching {
showClassSelection(requestValues)
}
}
alert.addButton(R.string.share, false) { _, _ ->
MainScope().launchCatching {
val usecase = ShareAvatarUseCase()
usecase.callInteractor(
ShareAvatarUseCase.RequestValues(
requestValues.activity,
requestValues.user,
requestValues.activity.getString(
R.string.share_levelup,
requestValues.newLevel,
),
"levelup",
),
)
}
}
alert.isCelebratory = true
if (!requestValues.activity.isFinishing) {
alert.enqueue()
} }
} }
return requestValues.user.stats alert.addButton(R.string.not_now, false)
} alert.isCelebratory = true
private suspend fun showClassSelection(requestValues: RequestValues) { if (!requestValues.activity.isFinishing) {
checkClassSelectionUseCase.callInteractor( alert.enqueue()
CheckClassSelectionUseCase.RequestValues( }
requestValues.user, } else {
true, if (suppressedModals?.levelUp == true) {
null, HabiticaSnackbar.showSnackbar(
requestValues.activity, requestValues.snackbarTargetView,
), requestValues.activity.getString(
R.string.levelup_header,
requestValues.newLevel
),
HabiticaSnackbar.SnackbarDisplayType.SUCCESS,
true
)
return requestValues.user.stats
}
val customView =
requestValues.activity.layoutInflater.inflate(R.layout.dialog_levelup, null)
if (customView != null) {
val dialogAvatarView = customView.findViewById<AvatarView>(R.id.avatarView)
dialogAvatarView.setAvatar(requestValues.user)
}
val alert = HabiticaAlertDialog(requestValues.activity)
alert.setTitle(
requestValues.activity.getString(
R.string.levelup_header,
requestValues.newLevel
)
) )
} alert.setAdditionalContentView(customView)
alert.addButton(R.string.onwards, true) { _, _ ->
MainScope().launchCatching {
showClassSelection(requestValues)
}
}
alert.addButton(R.string.share, false) { _, _ ->
MainScope().launchCatching {
val usecase = ShareAvatarUseCase()
usecase.callInteractor(
ShareAvatarUseCase.RequestValues(
requestValues.activity,
requestValues.user,
requestValues.activity.getString(
R.string.share_levelup,
requestValues.newLevel
),
"levelup"
)
)
}
}
alert.isCelebratory = true
class RequestValues( if (!requestValues.activity.isFinishing) {
val user: User, alert.enqueue()
val level: Int?, }
val activity: BaseActivity,
val snackbarTargetView: ViewGroup,
) : UseCase.RequestValues {
val newLevel: Int = level ?: 0
} }
return requestValues.user.stats
} }
private suspend fun showClassSelection(requestValues: RequestValues) {
checkClassSelectionUseCase.callInteractor(
CheckClassSelectionUseCase.RequestValues(
requestValues.user,
true,
null,
requestValues.activity
)
)
}
class RequestValues(
val user: User,
val level: Int?,
val activity: BaseActivity,
val snackbarTargetView: ViewGroup
) : UseCase.RequestValues {
val newLevel: Int = level ?: 0
}
}

View file

@ -24,187 +24,187 @@ import javax.inject.Inject
import kotlin.math.abs import kotlin.math.abs
class NotifyUserUseCase class NotifyUserUseCase
@Inject @Inject
constructor( constructor(
private val levelUpUseCase: LevelUpUseCase, private val levelUpUseCase: LevelUpUseCase,
private val userRepository: UserRepository, private val userRepository: UserRepository
) : UseCase<NotifyUserUseCase.RequestValues, Stats?>() { ) : UseCase<NotifyUserUseCase.RequestValues, Stats?>() {
override suspend fun run(requestValues: RequestValues): Stats? { override suspend fun run(requestValues: RequestValues): Stats? {
if (requestValues.user == null) { if (requestValues.user == null) {
return null return null
} }
val pair = val pair =
getNotificationAndAddStatsToUser( getNotificationAndAddStatsToUser(
requestValues.context, requestValues.context,
requestValues.xp, requestValues.xp,
requestValues.hp, requestValues.hp,
requestValues.gold, requestValues.gold,
requestValues.mp, requestValues.mp,
requestValues.questDamage, requestValues.questDamage,
requestValues.user
)
val view = pair.first
val type = pair.second
if (view != null && type != null) {
HabiticaSnackbar.showSnackbar(requestValues.snackbarTargetView, null, null, view, type)
}
if (requestValues.hasLeveledUp == true) {
levelUpUseCase.callInteractor(
LevelUpUseCase.RequestValues(
requestValues.user, requestValues.user,
requestValues.level,
requestValues.context,
requestValues.snackbarTargetView
) )
val view = pair.first )
val type = pair.second userRepository.retrieveUser(true)
if (view != null && type != null) { }
HabiticaSnackbar.showSnackbar(requestValues.snackbarTargetView, null, null, view, type) return requestValues.user.stats
}
class RequestValues(
val context: BaseActivity,
val snackbarTargetView: ViewGroup,
val user: User?,
val xp: Double?,
val hp: Double?,
val gold: Double?,
val mp: Double?,
val questDamage: Double?,
val hasLeveledUp: Boolean?,
val level: Int?
) : UseCase.RequestValues
companion object {
val formatter =
NumberFormat.getInstance().apply {
this.minimumFractionDigits = 0
this.maximumFractionDigits = 2
} }
if (requestValues.hasLeveledUp == true) {
levelUpUseCase.callInteractor( fun getNotificationAndAddStatsToUser(
LevelUpUseCase.RequestValues( context: Context,
requestValues.user, xp: Double?,
requestValues.level, hp: Double?,
requestValues.context, gold: Double?,
requestValues.snackbarTargetView, mp: Double?,
), questDamage: Double?,
user: User?
): Pair<View, SnackbarDisplayType> {
var displayType = SnackbarDisplayType.SUCCESS
val container = LinearLayout(context)
container.orientation = LinearLayout.HORIZONTAL
if (xp != null && xp > 0) {
container.addView(
createTextView(
context,
xp,
HabiticaIconsHelper.imageOfExperience()
)
) )
userRepository.retrieveUser(true)
} }
return requestValues.user.stats if (hp != null && hp != 0.0) {
if (hp < 0) {
displayType = SnackbarDisplayType.FAILURE
}
container.addView(
createTextView(
context,
hp,
HabiticaIconsHelper.imageOfHeartDarkBg()
)
)
}
if (gold != null && gold != 0.0) {
container.addView(createTextView(context, gold, HabiticaIconsHelper.imageOfGold()))
if (gold < 0) {
displayType = SnackbarDisplayType.FAILURE
}
}
if (mp != null && mp > 0 && user?.hasClass == true) {
container.addView(createTextView(context, mp, HabiticaIconsHelper.imageOfMagic()))
}
if (questDamage != null && questDamage > 0) {
container.addView(
createTextView(
context,
questDamage,
HabiticaIconsHelper.imageOfDamage()
)
)
}
val childCount = container.childCount
if (childCount == 0) {
return Pair(null, displayType)
}
val padding = context.resources.getDimension(R.dimen.spacing_medium).toInt()
(1 until childCount)
.map { container.getChildAt(it) }
.forEach { it.setPadding(padding, 0, 0, 0) }
return Pair(container, displayType)
} }
class RequestValues( private fun createTextView(
val context: BaseActivity, context: Context,
val snackbarTargetView: ViewGroup, value: Double,
val user: User?, icon: Bitmap
val xp: Double?, ): View {
val hp: Double?, val textView = TextView(context)
val gold: Double?, val iconDrawable = BitmapDrawable(context.resources, icon)
val mp: Double?, textView.setCompoundDrawablesWithIntrinsicBounds(iconDrawable, null, null, null)
val questDamage: Double?, val text: String =
val hasLeveledUp: Boolean?, if (value > 0) {
val level: Int?,
) : UseCase.RequestValues
companion object {
val formatter =
NumberFormat.getInstance().apply {
this.minimumFractionDigits = 0
this.maximumFractionDigits = 2
}
fun getNotificationAndAddStatsToUser(
context: Context,
xp: Double?,
hp: Double?,
gold: Double?,
mp: Double?,
questDamage: Double?,
user: User?,
): Pair<View, SnackbarDisplayType> {
var displayType = SnackbarDisplayType.SUCCESS
val container = LinearLayout(context)
container.orientation = LinearLayout.HORIZONTAL
if (xp != null && xp > 0) {
container.addView(
createTextView(
context,
xp,
HabiticaIconsHelper.imageOfExperience(),
),
)
}
if (hp != null && hp != 0.0) {
if (hp < 0) {
displayType = SnackbarDisplayType.FAILURE
}
container.addView(
createTextView(
context,
hp,
HabiticaIconsHelper.imageOfHeartDarkBg(),
),
)
}
if (gold != null && gold != 0.0) {
container.addView(createTextView(context, gold, HabiticaIconsHelper.imageOfGold()))
if (gold < 0) {
displayType = SnackbarDisplayType.FAILURE
}
}
if (mp != null && mp > 0 && user?.hasClass == true) {
container.addView(createTextView(context, mp, HabiticaIconsHelper.imageOfMagic()))
}
if (questDamage != null && questDamage > 0) {
container.addView(
createTextView(
context,
questDamage,
HabiticaIconsHelper.imageOfDamage(),
),
)
}
val childCount = container.childCount
if (childCount == 0) {
return Pair(null, displayType)
}
val padding = context.resources.getDimension(R.dimen.spacing_medium).toInt()
(1 until childCount)
.map { container.getChildAt(it) }
.forEach { it.setPadding(padding, 0, 0, 0) }
return Pair(container, displayType)
}
private fun createTextView(
context: Context,
value: Double,
icon: Bitmap,
): View {
val textView = TextView(context)
val iconDrawable = BitmapDrawable(context.resources, icon)
textView.setCompoundDrawablesWithIntrinsicBounds(iconDrawable, null, null, null)
val text: String =
if (value > 0) {
" + " + formatter.format(abs(value))
} else {
" - " + formatter.format(abs(value))
}
textView.text = text
textView.gravity = Gravity.CENTER_VERTICAL
textView.setTextColor(ContextCompat.getColor(context, R.color.white))
return textView
}
private fun formatValue(value: Double): String {
return if (value >= 0) {
" + " + formatter.format(abs(value)) " + " + formatter.format(abs(value))
} else { } else {
" - " + formatter.format(abs(value)) " - " + formatter.format(abs(value))
} }
} textView.text = text
textView.gravity = Gravity.CENTER_VERTICAL
textView.setTextColor(ContextCompat.getColor(context, R.color.white))
return textView
}
fun getNotificationAndAddStatsToUserAsText( private fun formatValue(value: Double): String {
xp: Double?, return if (value >= 0) {
hp: Double?, " + " + formatter.format(abs(value))
gold: Double?, } else {
mp: Double?, " - " + formatter.format(abs(value))
): Pair<SpannableStringBuilder, SnackbarDisplayType> {
val builder = SpannableStringBuilder()
var displayType = SnackbarDisplayType.NORMAL
if (xp != null && xp != 0.0) {
builder.append(formatValue(xp)).append(" Exp")
}
if (hp != null && hp != 0.0) {
if (hp < 0) {
displayType = SnackbarDisplayType.FAILURE
}
builder.append(formatValue(hp)).append(" Health")
}
if (gold != null && gold != 0.0) {
if (gold < 0) {
displayType = SnackbarDisplayType.FAILURE
}
builder.append(formatValue(gold)).append(" Gold")
}
if (mp != null && mp != 0.0) {
builder.append(formatValue(mp)).append(" Exp").append(" Mana")
}
return Pair(builder, displayType)
} }
} }
fun getNotificationAndAddStatsToUserAsText(
xp: Double?,
hp: Double?,
gold: Double?,
mp: Double?
): Pair<SpannableStringBuilder, SnackbarDisplayType> {
val builder = SpannableStringBuilder()
var displayType = SnackbarDisplayType.NORMAL
if (xp != null && xp != 0.0) {
builder.append(formatValue(xp)).append(" Exp")
}
if (hp != null && hp != 0.0) {
if (hp < 0) {
displayType = SnackbarDisplayType.FAILURE
}
builder.append(formatValue(hp)).append(" Health")
}
if (gold != null && gold != 0.0) {
if (gold < 0) {
displayType = SnackbarDisplayType.FAILURE
}
builder.append(formatValue(gold)).append(" Gold")
}
if (mp != null && mp != 0.0) {
builder.append(formatValue(mp)).append(" Exp").append(" Mana")
}
return Pair(builder, displayType)
}
} }
}

View file

@ -18,7 +18,7 @@ class ScoreTaskLocallyInteractor {
private fun calculateDelta( private fun calculateDelta(
task: Task, task: Task,
direction: TaskDirection, direction: TaskDirection
): Double { ): Double {
val currentValue = val currentValue =
when { when {
@ -35,7 +35,7 @@ class ScoreTaskLocallyInteractor {
nextDelta *= 1 + ( nextDelta *= 1 + (
task.checklist?.map { if (it.completed) 1 else 0 }?.reduce { _, _ -> 0 } task.checklist?.map { if (it.completed) 1 else 0 }?.reduce { _, _ -> 0 }
?: 0 ?: 0
) )
} }
} }
@ -45,35 +45,35 @@ class ScoreTaskLocallyInteractor {
private fun scoreHabit( private fun scoreHabit(
user: User, user: User,
task: Task, task: Task,
direction: TaskDirection, direction: TaskDirection
) { ) {
} }
private fun scoreDaily( private fun scoreDaily(
user: User, user: User,
task: Task, task: Task,
direction: TaskDirection, direction: TaskDirection
) { ) {
} }
private fun scoreToDo( private fun scoreToDo(
user: User, user: User,
task: Task, task: Task,
direction: TaskDirection, direction: TaskDirection
) { ) {
} }
private fun scoreReward( private fun scoreReward(
user: User, user: User,
task: Task, task: Task,
direction: TaskDirection, direction: TaskDirection
) { ) {
} }
fun score( fun score(
user: User, user: User,
task: Task, task: Task,
direction: TaskDirection, direction: TaskDirection
): TaskDirectionData? { ): TaskDirectionData? {
return if (task.type == TaskType.HABIT || direction == TaskDirection.UP) { return if (task.type == TaskType.HABIT || direction == TaskDirection.UP) {
val stats = user.stats ?: return null val stats = user.stats ?: return null
@ -121,7 +121,7 @@ class ScoreTaskLocallyInteractor {
delta: Double, delta: Double,
stats: Stats, stats: Stats,
computedStats: Stats, computedStats: Stats,
task: Task, task: Task
) { ) {
var conBonus = 1f - ((computedStats.constitution?.toFloat() ?: 0f) / 250f) var conBonus = 1f - ((computedStats.constitution?.toFloat() ?: 0f) / 250f)
if (conBonus < 0.1) { if (conBonus < 0.1) {
@ -137,13 +137,13 @@ class ScoreTaskLocallyInteractor {
stats: Stats, stats: Stats,
computedStats: Stats, computedStats: Stats,
task: Task, task: Task,
direction: TaskDirection, direction: TaskDirection
) { ) {
val intBonus = 1f + ((computedStats.intelligence?.toFloat() ?: 0f) * 0.025f) val intBonus = 1f + ((computedStats.intelligence?.toFloat() ?: 0f) * 0.025f)
result.exp = ( result.exp = (
stats.exp stats.exp
?: 0.0 ?: 0.0
) + (delta * intBonus * task.priority * 6).roundToLong().toDouble() ) + (delta * intBonus * task.priority * 6).roundToLong().toDouble()
val perBonus = 1f + ((computedStats.per?.toFloat() ?: 0f) * 0.02f) val perBonus = 1f + ((computedStats.per?.toFloat() ?: 0f) * 0.02f)
val goldMod = delta * task.priority * perBonus val goldMod = delta * task.priority * perBonus

View file

@ -8,32 +8,32 @@ import com.habitrpg.shared.habitica.models.Avatar
import javax.inject.Inject import javax.inject.Inject
class ShareAvatarUseCase class ShareAvatarUseCase
@Inject @Inject
constructor() : UseCase<ShareAvatarUseCase.RequestValues, Unit>() { constructor() : UseCase<ShareAvatarUseCase.RequestValues, Unit>() {
override suspend fun run(requestValues: RequestValues) { override suspend fun run(requestValues: RequestValues) {
val avatarView = val avatarView =
AvatarView( AvatarView(
requestValues.activity, requestValues.activity,
showBackground = true, showBackground = true,
showMount = true, showMount = true,
showPet = true, showPet = true
) )
avatarView.setAvatar(requestValues.avatar) avatarView.setAvatar(requestValues.avatar)
var sharedImage: Bitmap? = null var sharedImage: Bitmap? = null
avatarView.onAvatarImageReady { image -> avatarView.onAvatarImageReady { image ->
sharedImage = image?.scale(image.width * 3, image.height * 3, false) sharedImage = image?.scale(image.width * 3, image.height * 3, false)
requestValues.activity.shareContent( requestValues.activity.shareContent(
requestValues.identifier, requestValues.identifier,
requestValues.message, requestValues.message,
sharedImage, sharedImage
) )
}
} }
class RequestValues(
val activity: BaseActivity,
val avatar: Avatar,
val message: String?,
val identifier: String,
) : UseCase.RequestValues
} }
class RequestValues(
val activity: BaseActivity,
val avatar: Avatar,
val message: String?,
val identifier: String
) : UseCase.RequestValues
}

View file

@ -52,7 +52,7 @@ class ShareMountUseCase : UseCase<ShareMountUseCase.RequestValues, Unit>() {
Bitmap.createBitmap( Bitmap.createBitmap(
width, width,
height, height,
Bitmap.Config.ARGB_8888, Bitmap.Config.ARGB_8888
) )
val canvas = Canvas(sharedImage) val canvas = Canvas(sharedImage)
var attempts = 0 var attempts = 0
@ -65,9 +65,9 @@ class ShareMountUseCase : UseCase<ShareMountUseCase.RequestValues, Unit>() {
mountWrapper.root.draw(canvas) mountWrapper.root.draw(canvas)
( (
(requestValues.context as? BaseActivity) ?: HabiticaBaseApplication.getInstance( (requestValues.context as? BaseActivity) ?: HabiticaBaseApplication.getInstance(
requestValues.context, requestValues.context
)?.currentActivity?.get() )?.currentActivity?.get()
)?.shareContent("pet", requestValues.message, sharedImage) )?.shareContent("pet", requestValues.message, sharedImage)
containerView?.removeView(mountWrapper.root) containerView?.removeView(mountWrapper.root)
} }
// trigger layout // trigger layout

View file

@ -51,7 +51,7 @@ class SharePetUseCase : UseCase<SharePetUseCase.RequestValues, Unit>() {
Bitmap.createBitmap( Bitmap.createBitmap(
width, width,
height, height,
Bitmap.Config.ARGB_8888, Bitmap.Config.ARGB_8888
) )
val canvas = Canvas(sharedImage) val canvas = Canvas(sharedImage)
var attempts = 0 var attempts = 0
@ -63,9 +63,9 @@ class SharePetUseCase : UseCase<SharePetUseCase.RequestValues, Unit>() {
petWrapper.root.draw(canvas) petWrapper.root.draw(canvas)
( (
(requestValues.context as? BaseActivity) ?: HabiticaBaseApplication.getInstance( (requestValues.context as? BaseActivity) ?: HabiticaBaseApplication.getInstance(
requestValues.context, requestValues.context
)?.currentActivity?.get() )?.currentActivity?.get()
)?.shareContent("pet", requestValues.message, sharedImage) )?.shareContent("pet", requestValues.message, sharedImage)
containerView?.removeView(petWrapper.root) containerView?.removeView(petWrapper.root)
} }
val m = FrameLayout.LayoutParams(width, height) val m = FrameLayout.LayoutParams(width, height)

View file

@ -28,7 +28,7 @@ import kotlinx.coroutines.launch
class ShowNotificationInteractor( class ShowNotificationInteractor(
private val activity: Activity, private val activity: Activity,
private val lifecycleScope: LifecycleCoroutineScope, private val lifecycleScope: LifecycleCoroutineScope
) { ) {
fun handleNotification(notification: Notification): Boolean { fun handleNotification(notification: Notification): Boolean {
when (notification.type) { when (notification.type) {
@ -41,7 +41,7 @@ class ShowNotificationInteractor(
Notification.Type.ACHIEVEMENT_GUILD_JOINED.type -> showAchievementDialog(notification) Notification.Type.ACHIEVEMENT_GUILD_JOINED.type -> showAchievementDialog(notification)
Notification.Type.ACHIEVEMENT_CHALLENGE_JOINED.type -> Notification.Type.ACHIEVEMENT_CHALLENGE_JOINED.type ->
showAchievementDialog( showAchievementDialog(
notification, notification
) )
Notification.Type.ACHIEVEMENT_INVITED_FRIEND.type -> showAchievementDialog(notification) Notification.Type.ACHIEVEMENT_INVITED_FRIEND.type -> showAchievementDialog(notification)
@ -52,12 +52,12 @@ class ShowNotificationInteractor(
Notification.Type.ACHIEVEMENT_JUST_ADD_WATER.type -> showAchievementDialog(notification) Notification.Type.ACHIEVEMENT_JUST_ADD_WATER.type -> showAchievementDialog(notification)
Notification.Type.ACHIEVEMENT_LOST_MASTERCLASSER.type -> Notification.Type.ACHIEVEMENT_LOST_MASTERCLASSER.type ->
showAchievementDialog( showAchievementDialog(
notification, notification
) )
Notification.Type.ACHIEVEMENT_MIND_OVER_MATTER.type -> Notification.Type.ACHIEVEMENT_MIND_OVER_MATTER.type ->
showAchievementDialog( showAchievementDialog(
notification, notification
) )
Notification.Type.ACHIEVEMENT_DUST_DEVIL.type -> showAchievementDialog(notification) Notification.Type.ACHIEVEMENT_DUST_DEVIL.type -> showAchievementDialog(notification)
@ -65,12 +65,12 @@ class ShowNotificationInteractor(
Notification.Type.ACHIEVEMENT_MONSTER_MAGUS.type -> showAchievementDialog(notification) Notification.Type.ACHIEVEMENT_MONSTER_MAGUS.type -> showAchievementDialog(notification)
Notification.Type.ACHIEVEMENT_UNDEAD_UNDERTAKER.type -> Notification.Type.ACHIEVEMENT_UNDEAD_UNDERTAKER.type ->
showAchievementDialog( showAchievementDialog(
notification, notification
) )
Notification.Type.ACHIEVEMENT_PRIMED_FOR_PAINTING.type -> Notification.Type.ACHIEVEMENT_PRIMED_FOR_PAINTING.type ->
showAchievementDialog( showAchievementDialog(
notification, notification
) )
Notification.Type.ACHIEVEMENT_PEARLY_PRO.type -> showAchievementDialog(notification) Notification.Type.ACHIEVEMENT_PEARLY_PRO.type -> showAchievementDialog(notification)
@ -79,18 +79,18 @@ class ShowNotificationInteractor(
Notification.Type.ACHIEVEMENT_BUG_BONANZA.type -> showAchievementDialog(notification) Notification.Type.ACHIEVEMENT_BUG_BONANZA.type -> showAchievementDialog(notification)
Notification.Type.ACHIEVEMENT_BARE_NECESSITIES.type -> Notification.Type.ACHIEVEMENT_BARE_NECESSITIES.type ->
showAchievementDialog( showAchievementDialog(
notification, notification
) )
Notification.Type.ACHIEVEMENT_FRESHWATER_FRIENDS.type -> Notification.Type.ACHIEVEMENT_FRESHWATER_FRIENDS.type ->
showAchievementDialog( showAchievementDialog(
notification, notification
) )
Notification.Type.ACHIEVEMENT_GOOD_AS_GOLD.type -> showAchievementDialog(notification) Notification.Type.ACHIEVEMENT_GOOD_AS_GOLD.type -> showAchievementDialog(notification)
Notification.Type.ACHIEVEMENT_ALL_THAT_GLITTERS.type -> Notification.Type.ACHIEVEMENT_ALL_THAT_GLITTERS.type ->
showAchievementDialog( showAchievementDialog(
notification, notification
) )
Notification.Type.ACHIEVEMENT_GOOD_AS_GOLD.type -> showAchievementDialog(notification) Notification.Type.ACHIEVEMENT_GOOD_AS_GOLD.type -> showAchievementDialog(notification)
@ -102,7 +102,7 @@ class ShowNotificationInteractor(
Notification.Type.ACHIEVEMENT_GENERIC.type -> showAchievementDialog(notification) Notification.Type.ACHIEVEMENT_GENERIC.type -> showAchievementDialog(notification)
Notification.Type.ACHIEVEMENT_ONBOARDING_COMPLETE.type -> Notification.Type.ACHIEVEMENT_ONBOARDING_COMPLETE.type ->
showAchievementDialog( showAchievementDialog(
notification, notification
) )
Notification.Type.FIRST_DROP.type -> showFirstDropDialog(notification) Notification.Type.FIRST_DROP.type -> showFirstDropDialog(notification)
@ -152,7 +152,7 @@ class ShowNotificationInteractor(
(activity as? SnackbarActivity)?.showSnackbar( (activity as? SnackbarActivity)?.showSnackbar(
title = notificationData?.message, title = notificationData?.message,
content = nextUnlockText, content = nextUnlockText,
displayType = HabiticaSnackbar.SnackbarDisplayType.BLUE, displayType = HabiticaSnackbar.SnackbarDisplayType.BLUE
) )
} }
} }

View file

@ -3,7 +3,7 @@ package com.habitrpg.android.habitica.models
data class CustomizationFilter( data class CustomizationFilter(
var onlyPurchased: Boolean = false, var onlyPurchased: Boolean = false,
var ascending: Boolean = false, var ascending: Boolean = false,
var months: MutableList<String> = mutableListOf(), var months: MutableList<String> = mutableListOf()
) { ) {
val isFiltering: Boolean val isFiltering: Boolean
get() { get() {
@ -14,7 +14,7 @@ data class CustomizationFilter(
if (other is CustomizationFilter) { if (other is CustomizationFilter) {
return onlyPurchased == other.onlyPurchased && ascending == other.ascending && months.size == other.months.size && return onlyPurchased == other.onlyPurchased && ascending == other.ascending && months.size == other.months.size &&
months.containsAll( months.containsAll(
other.months, other.months
) )
} }
return super.equals(other) return super.equals(other)

View file

@ -13,7 +13,7 @@ class SetupCustomization {
fun createSize( fun createSize(
key: String, key: String,
drawableId: Int, drawableId: Int,
text: String, text: String
): SetupCustomization { ): SetupCustomization {
val customization = SetupCustomization() val customization = SetupCustomization()
customization.key = key customization.key = key
@ -27,7 +27,7 @@ class SetupCustomization {
fun createShirt( fun createShirt(
key: String, key: String,
drawableId: Int, drawableId: Int
): SetupCustomization { ): SetupCustomization {
val customization = SetupCustomization() val customization = SetupCustomization()
customization.key = key customization.key = key
@ -40,7 +40,7 @@ class SetupCustomization {
fun createSkin( fun createSkin(
key: String, key: String,
colorId: Int?, colorId: Int?
): SetupCustomization { ): SetupCustomization {
val customization = SetupCustomization() val customization = SetupCustomization()
customization.key = key customization.key = key
@ -52,7 +52,7 @@ class SetupCustomization {
fun createHairColor( fun createHairColor(
key: String, key: String,
colorId: Int?, colorId: Int?
): SetupCustomization { ): SetupCustomization {
val customization = SetupCustomization() val customization = SetupCustomization()
customization.key = key customization.key = key
@ -65,7 +65,7 @@ class SetupCustomization {
fun createHairBangs( fun createHairBangs(
key: String, key: String,
drawableId: Int?, drawableId: Int?
): SetupCustomization { ): SetupCustomization {
val customization = SetupCustomization() val customization = SetupCustomization()
customization.key = key customization.key = key
@ -78,7 +78,7 @@ class SetupCustomization {
fun createHairPonytail( fun createHairPonytail(
key: String, key: String,
drawableId: Int?, drawableId: Int?
): SetupCustomization { ): SetupCustomization {
val customization = SetupCustomization() val customization = SetupCustomization()
customization.key = key customization.key = key
@ -91,7 +91,7 @@ class SetupCustomization {
fun createGlasses( fun createGlasses(
key: String, key: String,
drawableId: Int?, drawableId: Int?
): SetupCustomization { ): SetupCustomization {
val customization = SetupCustomization() val customization = SetupCustomization()
customization.key = key customization.key = key
@ -104,7 +104,7 @@ class SetupCustomization {
fun createFlower( fun createFlower(
key: String, key: String,
drawableId: Int?, drawableId: Int?
): SetupCustomization { ): SetupCustomization {
val customization = SetupCustomization() val customization = SetupCustomization()
customization.key = key customization.key = key
@ -117,7 +117,7 @@ class SetupCustomization {
fun createWheelchair( fun createWheelchair(
key: String, key: String,
drawableId: Int?, drawableId: Int?
): SetupCustomization { ): SetupCustomization {
val customization = SetupCustomization() val customization = SetupCustomization()
customization.key = key customization.key = key

View file

@ -27,8 +27,8 @@ open class TutorialStep : RealmObject(), BaseMainObject {
this.displayedOn == null || Date().time - ( this.displayedOn == null || Date().time - (
displayedOn?.time displayedOn?.time
?: 0 ?: 0
) > 86400000 ) > 86400000
) )
} }
override val realmClass: Class<out RealmModel> override val realmClass: Class<out RealmModel>
get() = TutorialStep::class.java get() = TutorialStep::class.java

View file

@ -49,7 +49,7 @@ open class Customization : RealmObject(), BaseObject {
fun getIconName( fun getIconName(
userSize: String?, userSize: String?,
hairColor: String?, hairColor: String?
): String? { ): String? {
if (this.type == "hair" && this.category == "color") { if (this.type == "hair" && this.category == "color") {
return "icon_color_hair_bangs_1_$identifier" return "icon_color_hair_bangs_1_$identifier"
@ -60,7 +60,7 @@ open class Customization : RealmObject(), BaseObject {
fun getImageName( fun getImageName(
userSize: String?, userSize: String?,
hairColor: String?, hairColor: String?
): String? { ): String? {
if (!this.isValid) { if (!this.isValid) {
return null return null
@ -96,7 +96,7 @@ open class Customization : RealmObject(), BaseObject {
path + path +
this.customizationSet?.substring( this.customizationSet?.substring(
5, 5,
7, 7
) + this.customizationSet?.substring(0, 4) ) + this.customizationSet?.substring(0, 4)
} else { } else {
path + "." + this.customizationSet path + "." + this.customizationSet

View file

@ -3,7 +3,7 @@ package com.habitrpg.android.habitica.models.inventory
import io.realm.RealmObject import io.realm.RealmObject
import io.realm.annotations.PrimaryKey import io.realm.annotations.PrimaryKey
open class EquipmentSet: RealmObject() { open class EquipmentSet : RealmObject() {
@PrimaryKey @PrimaryKey
var key: String = "" var key: String = ""
var text: String = "" var text: String = ""

View file

@ -54,14 +54,14 @@ class FallExtraGemsHabiticaPromotion(startDate: Date?, endDate: Date?) : Habitic
view.setSubtitleImage( view.setSubtitleImage(
ContextCompat.getDrawable( ContextCompat.getDrawable(
context, context,
R.drawable.fall_promo_menu_description, R.drawable.fall_promo_menu_description
), )
) )
view.setSubtitleText(null) view.setSubtitleText(null)
view.setDecoration( view.setDecoration(
ContextCompat.getDrawable(context, R.drawable.fall_promo_menu_left), ContextCompat.getDrawable(context, R.drawable.fall_promo_menu_left),
ContextCompat.getDrawable(context, R.drawable.fall_promo_menu_right), ContextCompat.getDrawable(context, R.drawable.fall_promo_menu_right)
) )
view.binding.button.backgroundTintList = view.binding.button.backgroundTintList =
@ -84,27 +84,27 @@ class FallExtraGemsHabiticaPromotion(startDate: Date?, endDate: Date?) : Habitic
binding.promoBannerLeftImage.setImageDrawable( binding.promoBannerLeftImage.setImageDrawable(
ContextCompat.getDrawable( ContextCompat.getDrawable(
context, context,
R.drawable.fall_promo_banner_left, R.drawable.fall_promo_banner_left
), )
) )
binding.promoBannerRightImage.setImageDrawable( binding.promoBannerRightImage.setImageDrawable(
ContextCompat.getDrawable( ContextCompat.getDrawable(
context, context,
R.drawable.fall_promo_banner_right, R.drawable.fall_promo_banner_right
), )
) )
binding.promoBannerTitleImage.setImageDrawable( binding.promoBannerTitleImage.setImageDrawable(
ContextCompat.getDrawable( ContextCompat.getDrawable(
context, context,
R.drawable.fall_promo_title, R.drawable.fall_promo_title
), )
) )
val formatter = SimpleDateFormat("MMM d", Locale.getDefault()) val formatter = SimpleDateFormat("MMM d", Locale.getDefault())
binding.promoBannerDurationView.text = binding.promoBannerDurationView.text =
context.getString( context.getString(
R.string.x_to_y, R.string.x_to_y,
formatter.format(startDate), formatter.format(startDate),
formatter.format(endDate), formatter.format(endDate)
) )
binding.promoBannerDurationView.setTextColor(Color.parseColor("#FEE2B6")) binding.promoBannerDurationView.setTextColor(Color.parseColor("#FEE2B6"))
} }
@ -115,7 +115,7 @@ class FallExtraGemsHabiticaPromotion(startDate: Date?, endDate: Date?) : Habitic
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
override fun configureGemView( override fun configureGemView(
binding: PurchaseGemViewBinding, binding: PurchaseGemViewBinding,
regularAmount: Int, regularAmount: Int
) { ) {
val context = binding.root.context val context = binding.root.context
binding.root.background = promoBackgroundDrawable(context) binding.root.background = promoBackgroundDrawable(context)
@ -156,20 +156,20 @@ class FallExtraGemsHabiticaPromotion(startDate: Date?, endDate: Date?) : Habitic
fragment.binding?.promoBannerLeftImage?.setImageDrawable( fragment.binding?.promoBannerLeftImage?.setImageDrawable(
ContextCompat.getDrawable( ContextCompat.getDrawable(
context, context,
R.drawable.fall_promo_info_left, R.drawable.fall_promo_info_left
), )
) )
fragment.binding?.promoBannerRightImage?.setImageDrawable( fragment.binding?.promoBannerRightImage?.setImageDrawable(
ContextCompat.getDrawable( ContextCompat.getDrawable(
context, context,
R.drawable.fall_promo_info_right, R.drawable.fall_promo_info_right
), )
) )
fragment.binding?.promoBannerTitleImage?.setImageDrawable( fragment.binding?.promoBannerTitleImage?.setImageDrawable(
ContextCompat.getDrawable( ContextCompat.getDrawable(
context, context,
R.drawable.fall_promo_title, R.drawable.fall_promo_title
), )
) )
fragment.binding?.promoBannerSubtitleView?.setText(R.string.limited_event) fragment.binding?.promoBannerSubtitleView?.setText(R.string.limited_event)
fragment.binding?.promoBannerDurationView?.setTextColor(Color.parseColor("#FEE2B6")) fragment.binding?.promoBannerDurationView?.setTextColor(Color.parseColor("#FEE2B6"))
@ -178,13 +178,13 @@ class FallExtraGemsHabiticaPromotion(startDate: Date?, endDate: Date?) : Habitic
context.getString( context.getString(
R.string.x_to_y, R.string.x_to_y,
formatter.format(startDate), formatter.format(startDate),
formatter.format(endDate), formatter.format(endDate)
) )
fragment.binding?.promoBannerDurationView?.setTextColor( fragment.binding?.promoBannerDurationView?.setTextColor(
ContextCompat.getColor( ContextCompat.getColor(
context, context,
R.color.white, R.color.white
), )
) )
fragment.binding?.promptText?.setText(R.string.fall_promo_info_prompt) fragment.binding?.promptText?.setText(R.string.fall_promo_info_prompt)
fragment.binding?.promptText?.setTextColor(Color.parseColor("#F78E2F")) fragment.binding?.promptText?.setTextColor(Color.parseColor("#F78E2F"))
@ -197,7 +197,7 @@ class FallExtraGemsHabiticaPromotion(startDate: Date?, endDate: Date?) : Habitic
context.getString( context.getString(
R.string.fall_promo_info_instructions, R.string.fall_promo_info_instructions,
formatter.format(startDate), formatter.format(startDate),
formatter.format(endDate), formatter.format(endDate)
) )
val limitationsFormatter = val limitationsFormatter =
SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.LONG, SimpleDateFormat.LONG) SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.LONG, SimpleDateFormat.LONG)
@ -209,7 +209,7 @@ class FallExtraGemsHabiticaPromotion(startDate: Date?, endDate: Date?) : Habitic
limitationsFormatter.format(startDate), limitationsFormatter.format(startDate),
utcTimeFormatter.format(startDate), utcTimeFormatter.format(startDate),
limitationsFormatter.format(endDate), limitationsFormatter.format(endDate),
utcTimeFormatter.format(endDate), utcTimeFormatter.format(endDate)
) )
} }
} }

View file

@ -18,7 +18,6 @@ import com.habitrpg.common.habitica.helpers.MainNavigationController
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
import java.util.TimeZone
class GiftOneGetOneHabiticaPromotion(startDate: Date?, endDate: Date?) : HabiticaPromotion() { class GiftOneGetOneHabiticaPromotion(startDate: Date?, endDate: Date?) : HabiticaPromotion() {
override val identifier: String override val identifier: String
@ -54,7 +53,7 @@ class GiftOneGetOneHabiticaPromotion(startDate: Date?, endDate: Date?) : Habitic
view.setDecoration( view.setDecoration(
ContextCompat.getDrawable(context, R.drawable.g1g1_promo_menu_left), ContextCompat.getDrawable(context, R.drawable.g1g1_promo_menu_left),
ContextCompat.getDrawable(context, R.drawable.g1g1_promo_menu_right), ContextCompat.getDrawable(context, R.drawable.g1g1_promo_menu_right)
) )
view.binding.button.backgroundTintList = view.binding.button.backgroundTintList =
@ -81,14 +80,14 @@ class GiftOneGetOneHabiticaPromotion(startDate: Date?, endDate: Date?) : Habitic
binding.promoBannerLeftImage.setImageDrawable( binding.promoBannerLeftImage.setImageDrawable(
ContextCompat.getDrawable( ContextCompat.getDrawable(
context, context,
R.drawable.g1g1_promo_left, R.drawable.g1g1_promo_left
), )
) )
binding.promoBannerRightImage.setImageDrawable( binding.promoBannerRightImage.setImageDrawable(
ContextCompat.getDrawable( ContextCompat.getDrawable(
context, context,
R.drawable.g1g1_promo_right, R.drawable.g1g1_promo_right
), )
) )
binding.promoBannerTitleImage.visibility = View.GONE binding.promoBannerTitleImage.visibility = View.GONE
binding.promoBannerDurationView.visibility = View.GONE binding.promoBannerDurationView.visibility = View.GONE
@ -107,14 +106,14 @@ class GiftOneGetOneHabiticaPromotion(startDate: Date?, endDate: Date?) : Habitic
binding.content.promoBannerLeftImage.setImageDrawable( binding.content.promoBannerLeftImage.setImageDrawable(
ContextCompat.getDrawable( ContextCompat.getDrawable(
context, context,
R.drawable.g1g1_promo_left, R.drawable.g1g1_promo_left
), )
) )
binding.content.promoBannerRightImage.setImageDrawable( binding.content.promoBannerRightImage.setImageDrawable(
ContextCompat.getDrawable( ContextCompat.getDrawable(
context, context,
R.drawable.g1g1_promo_right, R.drawable.g1g1_promo_right
), )
) )
binding.content.promoBannerTitleImage.visibility = View.GONE binding.content.promoBannerTitleImage.visibility = View.GONE
binding.content.promoBannerDurationView.visibility = View.GONE binding.content.promoBannerDurationView.visibility = View.GONE
@ -128,7 +127,7 @@ class GiftOneGetOneHabiticaPromotion(startDate: Date?, endDate: Date?) : Habitic
override fun configureGemView( override fun configureGemView(
binding: PurchaseGemViewBinding, binding: PurchaseGemViewBinding,
regularAmount: Int, regularAmount: Int
) { ) {
} }
@ -138,14 +137,14 @@ class GiftOneGetOneHabiticaPromotion(startDate: Date?, endDate: Date?) : Habitic
fragment.binding?.promoBannerLeftImage?.setImageDrawable( fragment.binding?.promoBannerLeftImage?.setImageDrawable(
ContextCompat.getDrawable( ContextCompat.getDrawable(
context, context,
R.drawable.g1g1_promo_left, R.drawable.g1g1_promo_left
), )
) )
fragment.binding?.promoBannerRightImage?.setImageDrawable( fragment.binding?.promoBannerRightImage?.setImageDrawable(
ContextCompat.getDrawable( ContextCompat.getDrawable(
context, context,
R.drawable.g1g1_promo_right, R.drawable.g1g1_promo_right
), )
) )
fragment.binding?.promoBannerTitleImage?.visibility = View.GONE fragment.binding?.promoBannerTitleImage?.visibility = View.GONE
fragment.binding?.promoBannerTitleText?.visibility = View.VISIBLE fragment.binding?.promoBannerTitleText?.visibility = View.VISIBLE
@ -156,20 +155,20 @@ class GiftOneGetOneHabiticaPromotion(startDate: Date?, endDate: Date?) : Habitic
context.getString( context.getString(
R.string.x_to_y, R.string.x_to_y,
formatter.format(startDate), formatter.format(startDate),
formatter.format(endDate), formatter.format(endDate)
) )
fragment.binding?.promoBannerDurationView?.setTextColor( fragment.binding?.promoBannerDurationView?.setTextColor(
ContextCompat.getColor( ContextCompat.getColor(
context, context,
R.color.white, R.color.white
), )
) )
fragment.binding?.promptText?.setText(R.string.g1g1_promo_info_prompt) fragment.binding?.promptText?.setText(R.string.g1g1_promo_info_prompt)
fragment.binding?.promptText?.setTextColor( fragment.binding?.promptText?.setTextColor(
ContextCompat.getColor( ContextCompat.getColor(
context, context,
R.color.text_teal, R.color.text_teal
), )
) )
fragment.binding?.promptButton?.background = fragment.binding?.promptButton?.background =
ContextCompat.getDrawable(context, R.drawable.layout_rounded_bg_brand_400) ContextCompat.getDrawable(context, R.drawable.layout_rounded_bg_brand_400)
@ -178,7 +177,7 @@ class GiftOneGetOneHabiticaPromotion(startDate: Date?, endDate: Date?) : Habitic
fragment.binding?.promptButton?.setOnClickListener { fragment.binding?.promptButton?.setOnClickListener {
fragment.context?.let { context -> fragment.context?.let { context ->
SubscriptionFragment.showGiftSubscriptionDialog( SubscriptionFragment.showGiftSubscriptionDialog(
context, context
) )
} }
} }
@ -191,7 +190,7 @@ class GiftOneGetOneHabiticaPromotion(startDate: Date?, endDate: Date?) : Habitic
context.getString( context.getString(
R.string.g1g1_promo_info_limitations_noutc, R.string.g1g1_promo_info_limitations_noutc,
limitationsFormatter.format(startDate), limitationsFormatter.format(startDate),
limitationsFormatter.format(endDate), limitationsFormatter.format(endDate)
) )
} }
} }

View file

@ -14,7 +14,7 @@ enum class PromoType {
GEMS_AMOUNT, GEMS_AMOUNT,
GEMS_PRICE, GEMS_PRICE,
SUBSCRIPTION, SUBSCRIPTION,
SURVEY, SURVEY
} }
abstract class HabiticaPromotion { abstract class HabiticaPromotion {
@ -50,7 +50,7 @@ abstract class HabiticaPromotion {
abstract fun configureGemView( abstract fun configureGemView(
binding: PurchaseGemViewBinding, binding: PurchaseGemViewBinding,
regularAmount: Int, regularAmount: Int
) )
abstract fun configureInfoFragment(fragment: PromoInfoFragment) abstract fun configureInfoFragment(fragment: PromoInfoFragment)
@ -59,19 +59,19 @@ abstract class HabiticaPromotion {
fun getHabiticaPromotionFromKey( fun getHabiticaPromotionFromKey(
key: String, key: String,
startDate: Date?, startDate: Date?,
endDate: Date?, endDate: Date?
): HabiticaPromotion? { ): HabiticaPromotion? {
return when (key) { return when (key) {
"fall_extra_gems", "fall2020", "testFall2020" -> "fall_extra_gems", "fall2020", "testFall2020" ->
FallExtraGemsHabiticaPromotion( FallExtraGemsHabiticaPromotion(
startDate, startDate,
endDate, endDate
) )
"spooky_extra_gems", "fall2020SecondPromo", "spooky2020" -> "spooky_extra_gems", "fall2020SecondPromo", "spooky2020" ->
SpookyExtraGemsHabiticaPromotion( SpookyExtraGemsHabiticaPromotion(
startDate, startDate,
endDate, endDate
) )
"g1g1" -> GiftOneGetOneHabiticaPromotion(startDate, endDate) "g1g1" -> GiftOneGetOneHabiticaPromotion(startDate, endDate)

View file

@ -55,14 +55,14 @@ class SpookyExtraGemsHabiticaPromotion(startDate: Date?, endDate: Date?) : Habit
view.setSubtitleImage( view.setSubtitleImage(
ContextCompat.getDrawable( ContextCompat.getDrawable(
context, context,
R.drawable.spooky_promo_menu_description, R.drawable.spooky_promo_menu_description
), )
) )
view.setSubtitleText(null) view.setSubtitleText(null)
view.setDecoration( view.setDecoration(
ContextCompat.getDrawable(context, R.drawable.spooky_promo_menu_left), ContextCompat.getDrawable(context, R.drawable.spooky_promo_menu_left),
ContextCompat.getDrawable(context, R.drawable.spooky_promo_menu_right), ContextCompat.getDrawable(context, R.drawable.spooky_promo_menu_right)
) )
view.binding.button.backgroundTintList = view.binding.button.backgroundTintList =
@ -85,27 +85,27 @@ class SpookyExtraGemsHabiticaPromotion(startDate: Date?, endDate: Date?) : Habit
binding.promoBannerLeftImage.setImageDrawable( binding.promoBannerLeftImage.setImageDrawable(
ContextCompat.getDrawable( ContextCompat.getDrawable(
context, context,
R.drawable.spooky_promo_banner_left, R.drawable.spooky_promo_banner_left
), )
) )
binding.promoBannerRightImage.setImageDrawable( binding.promoBannerRightImage.setImageDrawable(
ContextCompat.getDrawable( ContextCompat.getDrawable(
context, context,
R.drawable.spooky_promo_banner_right, R.drawable.spooky_promo_banner_right
), )
) )
binding.promoBannerTitleImage.setImageDrawable( binding.promoBannerTitleImage.setImageDrawable(
ContextCompat.getDrawable( ContextCompat.getDrawable(
context, context,
R.drawable.spooky_promo_title, R.drawable.spooky_promo_title
), )
) )
val formatter = SimpleDateFormat("MMM d", Locale.getDefault()) val formatter = SimpleDateFormat("MMM d", Locale.getDefault())
binding.promoBannerDurationView.text = binding.promoBannerDurationView.text =
context.getString( context.getString(
R.string.x_to_y, R.string.x_to_y,
formatter.format(startDate), formatter.format(startDate),
formatter.format(endDate), formatter.format(endDate)
) )
binding.promoBannerDurationView.setTextColor(ContextCompat.getColor(context, R.color.white)) binding.promoBannerDurationView.setTextColor(ContextCompat.getColor(context, R.color.white))
} }
@ -116,7 +116,7 @@ class SpookyExtraGemsHabiticaPromotion(startDate: Date?, endDate: Date?) : Habit
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
override fun configureGemView( override fun configureGemView(
binding: PurchaseGemViewBinding, binding: PurchaseGemViewBinding,
regularAmount: Int, regularAmount: Int
) { ) {
val context = binding.root.context val context = binding.root.context
binding.root.background = promoBackgroundDrawable(context) binding.root.background = promoBackgroundDrawable(context)
@ -157,47 +157,47 @@ class SpookyExtraGemsHabiticaPromotion(startDate: Date?, endDate: Date?) : Habit
fragment.binding?.promoBannerLeftImage?.setImageDrawable( fragment.binding?.promoBannerLeftImage?.setImageDrawable(
ContextCompat.getDrawable( ContextCompat.getDrawable(
context, context,
R.drawable.spooky_promo_info_left, R.drawable.spooky_promo_info_left
), )
) )
fragment.binding?.promoBannerRightImage?.setImageDrawable( fragment.binding?.promoBannerRightImage?.setImageDrawable(
ContextCompat.getDrawable( ContextCompat.getDrawable(
context, context,
R.drawable.spooky_promo_info_right, R.drawable.spooky_promo_info_right
), )
) )
fragment.binding?.promoBannerTitleImage?.setImageDrawable( fragment.binding?.promoBannerTitleImage?.setImageDrawable(
ContextCompat.getDrawable( ContextCompat.getDrawable(
context, context,
R.drawable.spooky_promo_title, R.drawable.spooky_promo_title
), )
) )
fragment.binding?.promoBannerSubtitleView?.setText(R.string.limited_event) fragment.binding?.promoBannerSubtitleView?.setText(R.string.limited_event)
fragment.binding?.promoBannerDurationView?.setTextColor( fragment.binding?.promoBannerDurationView?.setTextColor(
ContextCompat.getColor( ContextCompat.getColor(
context, context,
R.color.white, R.color.white
), )
) )
val formatter = SimpleDateFormat("MMM d", Locale.getDefault()) val formatter = SimpleDateFormat("MMM d", Locale.getDefault())
fragment.binding?.promoBannerDurationView?.text = fragment.binding?.promoBannerDurationView?.text =
context.getString( context.getString(
R.string.x_to_y, R.string.x_to_y,
formatter.format(startDate), formatter.format(startDate),
formatter.format(endDate), formatter.format(endDate)
) )
fragment.binding?.promoBannerDurationView?.setTextColor( fragment.binding?.promoBannerDurationView?.setTextColor(
ContextCompat.getColor( ContextCompat.getColor(
context, context,
R.color.white, R.color.white
), )
) )
fragment.binding?.promptText?.setText(R.string.spooky_promo_info_prompt) fragment.binding?.promptText?.setText(R.string.spooky_promo_info_prompt)
fragment.binding?.promptText?.setTextColor( fragment.binding?.promptText?.setTextColor(
ContextCompat.getColor( ContextCompat.getColor(
context, context,
R.color.orange_50, R.color.orange_50
), )
) )
fragment.binding?.promptButton?.background = buttonDrawable(context) fragment.binding?.promptButton?.background = buttonDrawable(context)
fragment.binding?.promptButton?.setText(R.string.view_gem_bundles) fragment.binding?.promptButton?.setText(R.string.view_gem_bundles)
@ -208,7 +208,7 @@ class SpookyExtraGemsHabiticaPromotion(startDate: Date?, endDate: Date?) : Habit
context.getString( context.getString(
R.string.spooky_promo_info_instructions, R.string.spooky_promo_info_instructions,
formatter.format(startDate), formatter.format(startDate),
formatter.format(endDate), formatter.format(endDate)
) )
val limitationsFormatter = SimpleDateFormat.getDateTimeInstance() val limitationsFormatter = SimpleDateFormat.getDateTimeInstance()
val utcTimeFormatter = SimpleDateFormat.getTimeInstance(SimpleDateFormat.LONG) val utcTimeFormatter = SimpleDateFormat.getTimeInstance(SimpleDateFormat.LONG)
@ -219,7 +219,7 @@ class SpookyExtraGemsHabiticaPromotion(startDate: Date?, endDate: Date?) : Habit
limitationsFormatter.format(startDate), limitationsFormatter.format(startDate),
utcTimeFormatter.format(startDate), utcTimeFormatter.format(startDate),
limitationsFormatter.format(endDate), limitationsFormatter.format(endDate),
utcTimeFormatter.format(endDate), utcTimeFormatter.format(endDate)
) )
} }
} }

View file

@ -52,7 +52,7 @@ class Survey2021Promotion : HabiticaPromotion(), HabiticaWebPromotion {
view.setDecoration( view.setDecoration(
ContextCompat.getDrawable(context, R.drawable.survey_art_left), ContextCompat.getDrawable(context, R.drawable.survey_art_left),
ContextCompat.getDrawable(context, R.drawable.survey_art_right), ContextCompat.getDrawable(context, R.drawable.survey_art_right)
) )
view.binding.button.backgroundTintList = view.binding.button.backgroundTintList =
@ -67,7 +67,7 @@ class Survey2021Promotion : HabiticaPromotion(), HabiticaWebPromotion {
override fun menuOnNavigation(context: Context) { override fun menuOnNavigation(context: Context) {
MainNavigationController.navigate( MainNavigationController.navigate(
R.id.promoWebFragment, R.id.promoWebFragment,
PromoWebFragmentArgs.Builder(url ?: "").build().toBundle(), PromoWebFragmentArgs.Builder(url ?: "").build().toBundle()
) )
} }
@ -79,7 +79,7 @@ class Survey2021Promotion : HabiticaPromotion(), HabiticaWebPromotion {
override fun configureGemView( override fun configureGemView(
binding: PurchaseGemViewBinding, binding: PurchaseGemViewBinding,
regularAmount: Int, regularAmount: Int
) { ) {
} }

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