Fixes for new Ktor API
This commit is contained in:
parent
b65edb31c6
commit
ed6babe09f
11 changed files with 85 additions and 82 deletions
|
@ -14,7 +14,7 @@ android {
|
|||
}
|
||||
defaultConfig {
|
||||
applicationId "com.wbrawner.budget"
|
||||
minSdkVersion 23
|
||||
minSdkVersion 26
|
||||
targetSdkVersion 30
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
|
|
@ -50,21 +50,16 @@ class SplashViewModel : ViewModel(), AsyncViewModel<AuthenticationState> {
|
|||
else "https://$server"
|
||||
baseUrlHelper.url = correctServer
|
||||
userRepository.login(username, password).also {
|
||||
loadBudgetData()
|
||||
budgetRepository.prefetchData()
|
||||
}
|
||||
sharedPreferences.edit {
|
||||
putString(PREF_KEY_BASE_URL, correctServer)
|
||||
}
|
||||
AuthenticationState.Authenticated
|
||||
} catch (e: Exception) {
|
||||
// TODO: Return error message here
|
||||
AuthenticationState.Unauthenticated(server, username, password, e.message)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun loadBudgetData() {
|
||||
budgetRepository.prefetchData()
|
||||
}
|
||||
}
|
||||
|
||||
sealed class AuthenticationState {
|
||||
|
|
|
@ -7,7 +7,7 @@ android {
|
|||
compileSdkVersion 30
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 21
|
||||
minSdkVersion 26
|
||||
targetSdkVersion 30
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
package com.wbrawner.budget.lib.network
|
||||
|
||||
data class BudgetBalanceResponse(val id: String, val balance: Long)
|
||||
data class BalanceResponse(val balance: Long)
|
|
@ -11,111 +11,109 @@ import retrofit2.http.*
|
|||
|
||||
interface TwigsApiService {
|
||||
// Budgets
|
||||
@GET("budgets")
|
||||
@GET("api/budgets")
|
||||
suspend fun getBudgets(
|
||||
@Query("count") count: Int? = null,
|
||||
@Query("page") page: Int? = null
|
||||
): List<Budget>
|
||||
|
||||
@GET("budgets/{id}")
|
||||
@GET("api/budgets/{id}")
|
||||
suspend fun getBudget(@Path("id") id: String): Budget
|
||||
|
||||
@GET("budgets/{id}/balance")
|
||||
suspend fun getBudgetBalance(@Path("id") id: String): BudgetBalanceResponse
|
||||
|
||||
@POST("budgets")
|
||||
@POST("api/budgets")
|
||||
suspend fun newBudget(@Body budget: NewBudgetRequest): Budget
|
||||
|
||||
@PUT("budgets/{id}")
|
||||
@PUT("api/budgets/{id}")
|
||||
suspend fun updateBudget(
|
||||
@Path("id") id: String,
|
||||
@Body budget: Budget
|
||||
): Budget
|
||||
|
||||
@DELETE("budgets/{id}")
|
||||
@DELETE("api/budgets/{id}")
|
||||
suspend fun deleteBudget(@Path("id") id: String)
|
||||
|
||||
// Categories
|
||||
@GET("categories")
|
||||
@GET("api/categories")
|
||||
suspend fun getCategories(
|
||||
@Query("budgetIds") budgetIds: Array<String>? = null,
|
||||
@Query("count") count: Int? = null,
|
||||
@Query("page") page: Int? = null
|
||||
@Query("budgetIds") budgetIds: Array<String>? = null,
|
||||
@Query("archived") archived: Boolean? = false,
|
||||
@Query("count") count: Int? = null,
|
||||
@Query("page") page: Int? = null,
|
||||
): List<Category>
|
||||
|
||||
@GET("categories/{id}")
|
||||
@GET("api/categories/{id}")
|
||||
suspend fun getCategory(@Path("id") id: String): Category
|
||||
|
||||
@GET("categories/{id}/balance")
|
||||
suspend fun getCategoryBalance(@Path("id") id: String): CategoryBalanceResponse
|
||||
|
||||
@POST("categories")
|
||||
@POST("api/categories")
|
||||
suspend fun newCategory(@Body category: Category): Category
|
||||
|
||||
@PUT("categories/{id}")
|
||||
@PUT("api/categories/{id}")
|
||||
suspend fun updateCategory(
|
||||
@Path("id") id: String,
|
||||
@Body category: Category
|
||||
): Category
|
||||
|
||||
@DELETE("categories/{id}")
|
||||
@DELETE("api/categories/{id}")
|
||||
suspend fun deleteCategory(@Path("id") id: String)
|
||||
|
||||
// Transactions
|
||||
@GET("transactions")
|
||||
@GET("api/transactions")
|
||||
suspend fun getTransactions(
|
||||
@Query("budgetIds") budgetIds: List<String>? = null,
|
||||
@Query("categoryIds") categoryIds: List<String>? = null,
|
||||
@Query("from") from: String? = null,
|
||||
@Query("to") to: String? = null,
|
||||
@Query("count") count: Int? = null,
|
||||
@Query("page") page: Int? = null
|
||||
@Query("budgetIds") budgetIds: List<String>? = null,
|
||||
@Query("categoryIds") categoryIds: List<String>? = null,
|
||||
@Query("from") from: String? = null,
|
||||
@Query("to") to: String? = null,
|
||||
@Query("count") count: Int? = null,
|
||||
@Query("page") page: Int? = null
|
||||
): List<Transaction>
|
||||
|
||||
@GET("transactions/{id}")
|
||||
@GET("api/transactions/{id}")
|
||||
suspend fun getTransaction(@Path("id") id: String): Transaction
|
||||
|
||||
@POST("transactions")
|
||||
@GET("api/transactions/sum")
|
||||
suspend fun sumTransactions(
|
||||
@Query("budgetId") budgetId: String? = null,
|
||||
@Query("categoryId") categoryId: String? = null
|
||||
): BalanceResponse
|
||||
|
||||
@POST("api/transactions")
|
||||
suspend fun newTransaction(@Body transaction: Transaction): Transaction
|
||||
|
||||
@PUT("transactions/{id}")
|
||||
@PUT("api/transactions/{id}")
|
||||
suspend fun updateTransaction(
|
||||
@Path("id") id: String,
|
||||
@Body transaction: Transaction
|
||||
@Path("id") id: String,
|
||||
@Body transaction: Transaction
|
||||
): Transaction
|
||||
|
||||
@DELETE("transactions/{id}")
|
||||
@DELETE("api/transactions/{id}")
|
||||
suspend fun deleteTransaction(@Path("id") id: String)
|
||||
|
||||
// Users
|
||||
@GET("users")
|
||||
@GET("api/users")
|
||||
suspend fun getUsers(
|
||||
@Query("budgetId") budgetid: String? = null,
|
||||
@Query("count") count: Int? = null,
|
||||
@Query("page") page: Int? = null
|
||||
): List<User>
|
||||
|
||||
@POST("users/login")
|
||||
@POST("api/users/login")
|
||||
suspend fun login(@Body request: LoginRequest): Session
|
||||
|
||||
@GET("users/me")
|
||||
suspend fun getProfile(): User
|
||||
|
||||
@GET("users/search")
|
||||
@GET("api/users/search")
|
||||
suspend fun searchUsers(@Query("query") query: String): List<User>
|
||||
|
||||
@GET("users/{id}")
|
||||
@GET("api/users/{id}")
|
||||
suspend fun getUser(@Path("id") id: String): User
|
||||
|
||||
@POST("users")
|
||||
@POST("api/users")
|
||||
suspend fun newUser(@Body user: User): User
|
||||
|
||||
@PUT("users/{id}")
|
||||
@PUT("api/users/{id}")
|
||||
suspend fun updateUser(
|
||||
@Path("id") id: String,
|
||||
@Body user: User
|
||||
): User
|
||||
|
||||
@DELETE("users/{id}")
|
||||
@DELETE("api/users/{id}")
|
||||
suspend fun deleteUser(@Path("id") id: String)
|
||||
}
|
|
@ -93,7 +93,8 @@ class NetworkBudgetRepository(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun getBalance(id: String): Long = apiService.getBudgetBalance(id).balance
|
||||
override suspend fun getBalance(id: String): Long =
|
||||
apiService.sumTransactions(budgetId = id).balance
|
||||
}
|
||||
|
||||
data class NewBudgetRequest(
|
||||
|
|
|
@ -19,7 +19,6 @@ class NetworkCategoryRepository @Inject constructor(private val apiService: Twig
|
|||
|
||||
override suspend fun delete(id: String) = apiService.deleteCategory(id)
|
||||
|
||||
// TODO: Implement this method server-side and then here
|
||||
override suspend fun getBalance(id: String): Long = apiService.getCategoryBalance(id).balance
|
||||
override suspend fun getBalance(id: String): Long =
|
||||
apiService.sumTransactions(categoryId = id).balance
|
||||
}
|
||||
|
||||
|
|
|
@ -3,29 +3,25 @@ package com.wbrawner.budget.lib.repository
|
|||
import com.wbrawner.budget.common.transaction.Transaction
|
||||
import com.wbrawner.budget.common.transaction.TransactionRepository
|
||||
import com.wbrawner.budget.lib.network.TwigsApiService
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class NetworkTransactionRepository @Inject constructor(private val apiService: TwigsApiService) : TransactionRepository {
|
||||
private val dateFormatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.ENGLISH)
|
||||
class NetworkTransactionRepository @Inject constructor(private val apiService: TwigsApiService) :
|
||||
TransactionRepository {
|
||||
|
||||
override suspend fun create(newItem: Transaction): Transaction = apiService.newTransaction(newItem)
|
||||
override suspend fun create(newItem: Transaction): Transaction =
|
||||
apiService.newTransaction(newItem)
|
||||
|
||||
override suspend fun findAll(
|
||||
budgetIds: List<String>?,
|
||||
categoryIds: List<String>?,
|
||||
start: Calendar?,
|
||||
end: Calendar?
|
||||
budgetIds: List<String>?,
|
||||
categoryIds: List<String>?,
|
||||
start: Calendar?,
|
||||
end: Calendar?
|
||||
): List<Transaction> = apiService.getTransactions(
|
||||
budgetIds,
|
||||
categoryIds,
|
||||
start?.let {
|
||||
dateFormatter.format(it.time)
|
||||
},
|
||||
end?.let {
|
||||
dateFormatter.format(it.time)
|
||||
}
|
||||
budgetIds,
|
||||
categoryIds,
|
||||
start?.toInstant()?.toString(),
|
||||
end?.toInstant()?.toString()
|
||||
)
|
||||
|
||||
override suspend fun findAll(): List<Transaction> = findAll(null)
|
||||
|
@ -33,7 +29,7 @@ class NetworkTransactionRepository @Inject constructor(private val apiService: T
|
|||
override suspend fun findById(id: String): Transaction = apiService.getTransaction(id)
|
||||
|
||||
override suspend fun update(updatedItem: Transaction): Transaction =
|
||||
apiService.updateTransaction(updatedItem.id!!, updatedItem)
|
||||
apiService.updateTransaction(updatedItem.id!!, updatedItem)
|
||||
|
||||
override suspend fun delete(id: String) = apiService.deleteTransaction(id)
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.content.SharedPreferences
|
|||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.wbrawner.budget.common.PREF_KEY_TOKEN
|
||||
import com.wbrawner.budget.common.PREF_KEY_USER_ID
|
||||
import com.wbrawner.budget.common.user.LoginRequest
|
||||
import com.wbrawner.budget.common.user.User
|
||||
import com.wbrawner.budget.common.user.UserRepository
|
||||
|
@ -21,24 +22,36 @@ class NetworkUserRepository @Inject constructor(
|
|||
|
||||
init {
|
||||
GlobalScope.launch {
|
||||
try {
|
||||
getProfile()
|
||||
} catch (ignored: Exception) {
|
||||
}
|
||||
sharedPreferences.getString(PREF_KEY_USER_ID, null)
|
||||
?.let {
|
||||
try {
|
||||
getProfile()
|
||||
} catch (ignored: Exception) {
|
||||
sharedPreferences.edit()
|
||||
.remove(PREF_KEY_USER_ID)
|
||||
.remove(PREF_KEY_TOKEN)
|
||||
.apply()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun login(username: String, password: String): User {
|
||||
apiService.login(LoginRequest(username, password)).also {
|
||||
sharedPreferences.edit()
|
||||
.putString(PREF_KEY_TOKEN, it.token)
|
||||
.apply()
|
||||
.putString(PREF_KEY_USER_ID, it.userId)
|
||||
.putString(PREF_KEY_TOKEN, it.token)
|
||||
.apply()
|
||||
}
|
||||
return getProfile()
|
||||
}
|
||||
|
||||
override suspend fun getProfile(): User = apiService.getProfile().also {
|
||||
(currentUser as MutableLiveData).postValue(it)
|
||||
override suspend fun getProfile(): User {
|
||||
val userId = sharedPreferences.getString(PREF_KEY_USER_ID, null)
|
||||
?: throw RuntimeException("Not authenticated")
|
||||
return apiService.getUser(userId).also {
|
||||
(currentUser as MutableLiveData).postValue(it)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun create(newItem: User): User = apiService.newUser(newItem)
|
||||
|
|
|
@ -8,7 +8,7 @@ android {
|
|||
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 21
|
||||
minSdkVersion 26
|
||||
targetSdkVersion 30
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
|
|
@ -2,10 +2,11 @@ package com.wbrawner.budget.common
|
|||
|
||||
import java.util.*
|
||||
|
||||
const val PREF_KEY_USER_ID = "userId"
|
||||
const val PREF_KEY_TOKEN = "sessionToken"
|
||||
|
||||
data class Session(
|
||||
val id: String,
|
||||
val userId: String,
|
||||
val token: String,
|
||||
val expiration: Date
|
||||
)
|
Loading…
Reference in a new issue