update dependencies, migrate code & cleanup (#12)
* update dependencies, migrate code & cleanup * migrate from Kotlin Android extensions to Kotlin Parcelize * fix import order
This commit is contained in:
parent
7c14af603e
commit
466dba6096
|
@ -1,16 +1,16 @@
|
||||||
plugins {
|
plugins {
|
||||||
id("com.android.application")
|
id("com.android.application")
|
||||||
id("kotlin-android")
|
id("kotlin-android")
|
||||||
id("kotlin-android-extensions")
|
|
||||||
id("kotlin-kapt")
|
id("kotlin-kapt")
|
||||||
|
id("kotlin-parcelize")
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion(30)
|
compileSdk = 31
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "at.connyduck.pixelcat"
|
applicationId = "at.connyduck.pixelcat"
|
||||||
minSdkVersion(24)
|
minSdk = 24
|
||||||
targetSdkVersion(30)
|
targetSdk = 31
|
||||||
versionCode = 1
|
versionCode = 1
|
||||||
versionName = "0.0 snapshot1"
|
versionName = "0.0 snapshot1"
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
@ -29,19 +29,15 @@ android {
|
||||||
targetCompatibility = JavaVersion.VERSION_1_8
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
|
|
||||||
androidExtensions {
|
|
||||||
features = setOf("parcelize")
|
|
||||||
}
|
|
||||||
|
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
viewBinding = true
|
viewBinding = true
|
||||||
}
|
}
|
||||||
|
|
||||||
packagingOptions {
|
packagingOptions {
|
||||||
exclude("LICENSE_OFL")
|
resources.excludes.add("LICENSE_OFL")
|
||||||
exclude("LICENSE_UNICODE")
|
resources.excludes.add("LICENSE_UNICODE")
|
||||||
exclude("okhttp3/internal/publicsuffix/NOTICE")
|
resources.excludes.add("okhttp3/internal/publicsuffix/NOTICE")
|
||||||
exclude("DebugProbesKt.bin")
|
resources.excludes.add("DebugProbesKt.bin")
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets["main"].java.srcDir("src/main/kotlin")
|
sourceSets["main"].java.srcDir("src/main/kotlin")
|
||||||
|
@ -60,37 +56,36 @@ tasks {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
val lifecycleVersion = "2.3.0-alpha07"
|
val lifecycleVersion = "2.4.0"
|
||||||
val emojiCompatVersion = "1.2.0-alpha01"
|
val emojiCompatVersion = "1.2.0-alpha01"
|
||||||
val roomVersion = "2.3.0-alpha03"
|
val roomVersion = "2.4.1"
|
||||||
val okHttpVersion = "4.8.1"
|
val okHttpVersion = "4.9.3"
|
||||||
val retrofitVersion = "2.9.0"
|
val retrofitVersion = "2.9.0"
|
||||||
val moshiVersion = "1.10.0"
|
val moshiVersion = "1.13.0"
|
||||||
val daggerVersion = "2.28.3"
|
val daggerVersion = "2.40.5"
|
||||||
val jUnitVersion = "5.7.0"
|
val jUnitVersion = "5.8.2"
|
||||||
|
|
||||||
implementation(kotlin("stdlib-jdk7"))
|
implementation("androidx.core:core-ktx:1.7.0")
|
||||||
|
implementation("androidx.appcompat:appcompat:1.4.1")
|
||||||
implementation("androidx.core:core-ktx:1.5.0-alpha03")
|
implementation("androidx.activity:activity-ktx:1.4.0")
|
||||||
implementation("androidx.appcompat:appcompat:1.3.0-alpha02")
|
implementation("androidx.fragment:fragment-ktx:1.4.1")
|
||||||
implementation("androidx.activity:activity-ktx:1.2.0-alpha08")
|
implementation("com.google.android.material:material:1.5.0")
|
||||||
implementation("androidx.fragment:fragment-ktx:1.3.0-alpha08")
|
implementation("androidx.constraintlayout:constraintlayout:2.1.3")
|
||||||
implementation("com.google.android.material:material:1.3.0-alpha02")
|
|
||||||
implementation("androidx.constraintlayout:constraintlayout:2.0.1")
|
|
||||||
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
|
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
|
||||||
implementation("androidx.recyclerview:recyclerview:1.2.0-alpha05")
|
implementation("androidx.recyclerview:recyclerview:1.2.1")
|
||||||
implementation("androidx.annotation:annotation:1.1.0")
|
implementation("androidx.annotation:annotation:1.3.0")
|
||||||
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion")
|
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion")
|
||||||
implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion")
|
implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion")
|
||||||
implementation("androidx.lifecycle:lifecycle-runtime-ktx:$lifecycleVersion")
|
implementation("androidx.lifecycle:lifecycle-runtime-ktx:$lifecycleVersion")
|
||||||
implementation("androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion")
|
implementation("androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion")
|
||||||
implementation("androidx.preference:preference:1.1.1")
|
implementation("androidx.preference:preference-ktx:1.2.0")
|
||||||
implementation("androidx.emoji:emoji-bundled:$emojiCompatVersion")
|
implementation("androidx.emoji:emoji-bundled:$emojiCompatVersion")
|
||||||
implementation("androidx.emoji:emoji-appcompat:$emojiCompatVersion")
|
implementation("androidx.emoji:emoji-appcompat:$emojiCompatVersion")
|
||||||
implementation("androidx.paging:paging-runtime-ktx:3.0.0-alpha06")
|
implementation("androidx.paging:paging-runtime-ktx:3.1.0")
|
||||||
implementation("androidx.viewpager2:viewpager2:1.0.0")
|
implementation("androidx.viewpager2:viewpager2:1.0.0")
|
||||||
|
|
||||||
implementation("androidx.room:room-ktx:$roomVersion")
|
implementation("androidx.room:room-ktx:$roomVersion")
|
||||||
|
implementation("androidx.room:room-paging:$roomVersion")
|
||||||
kapt("androidx.room:room-compiler:$roomVersion")
|
kapt("androidx.room:room-compiler:$roomVersion")
|
||||||
|
|
||||||
implementation("com.squareup.okhttp3:okhttp:$okHttpVersion")
|
implementation("com.squareup.okhttp3:okhttp:$okHttpVersion")
|
||||||
|
@ -103,17 +98,17 @@ dependencies {
|
||||||
implementation("com.squareup.moshi:moshi-adapters:$moshiVersion")
|
implementation("com.squareup.moshi:moshi-adapters:$moshiVersion")
|
||||||
kapt("com.squareup.moshi:moshi-kotlin-codegen:$moshiVersion")
|
kapt("com.squareup.moshi:moshi-kotlin-codegen:$moshiVersion")
|
||||||
|
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9")
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0")
|
||||||
|
|
||||||
implementation("com.fxn769:pix:1.4.4")
|
implementation("com.fxn769:pix:1.5.6")
|
||||||
|
|
||||||
implementation("com.github.yalantis:ucrop:2.2.5")
|
implementation("com.github.yalantis:ucrop:2.2.5")
|
||||||
|
|
||||||
implementation("me.relex:circleindicator:2.1.4")
|
implementation("me.relex:circleindicator:2.1.6")
|
||||||
|
|
||||||
implementation("io.coil-kt:coil:1.0.0-rc3")
|
implementation("io.coil-kt:coil:1.0.0-rc3")
|
||||||
|
|
||||||
implementation("com.github.connyduck:sparkbutton:4.0.0")
|
implementation("com.github.connyduck:sparkbutton:4.1.0")
|
||||||
|
|
||||||
implementation("com.google.dagger:dagger:$daggerVersion")
|
implementation("com.google.dagger:dagger:$daggerVersion")
|
||||||
kapt("com.google.dagger:dagger-compiler:$daggerVersion")
|
kapt("com.google.dagger:dagger-compiler:$daggerVersion")
|
||||||
|
|
|
@ -17,7 +17,8 @@
|
||||||
android:usesCleartextTraffic="false"
|
android:usesCleartextTraffic="false"
|
||||||
tools:ignore="AllowBackup,GoogleAppIndexingWarning">
|
tools:ignore="AllowBackup,GoogleAppIndexingWarning">
|
||||||
<!-- TODO order activities -->
|
<!-- TODO order activities -->
|
||||||
<activity android:name=".components.splash.SplashActivity">
|
<activity android:name=".components.splash.SplashActivity"
|
||||||
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,6 @@ import at.connyduck.pixelcat.databinding.ActivityComposeBinding
|
||||||
import at.connyduck.pixelcat.util.viewBinding
|
import at.connyduck.pixelcat.util.viewBinding
|
||||||
import com.fxn.pix.Options
|
import com.fxn.pix.Options
|
||||||
import com.fxn.pix.Pix
|
import com.fxn.pix.Pix
|
||||||
import com.fxn.utility.ImageQuality
|
|
||||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -104,24 +103,23 @@ class ComposeActivity : BaseActivity(), OnImageActionClickListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.imageLiveData.observe(
|
viewModel.imageLiveData.observe(
|
||||||
this,
|
this
|
||||||
{
|
) {
|
||||||
adapter.submitList(it)
|
adapter.submitList(it)
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
|
||||||
viewModel.visibility.observe(
|
viewModel.visibility.observe(
|
||||||
this,
|
this
|
||||||
{
|
) {
|
||||||
val visibilityString = when (it) {
|
val visibilityString = when (it) {
|
||||||
VISIBILITY.PUBLIC -> R.string.compose_visibility_public
|
VISIBILITY.PUBLIC -> R.string.compose_visibility_public
|
||||||
VISIBILITY.UNLISTED -> R.string.compose_visibility_unlisted
|
VISIBILITY.UNLISTED -> R.string.compose_visibility_unlisted
|
||||||
VISIBILITY.FOLLOWERS_ONLY -> R.string.compose_visibility_followers_only
|
VISIBILITY.FOLLOWERS_ONLY -> R.string.compose_visibility_followers_only
|
||||||
}
|
|
||||||
|
|
||||||
binding.composeVisibilityButton.text = getString(R.string.compose_visibility, getString(visibilityString))
|
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
binding.composeVisibilityButton.text =
|
||||||
|
getString(R.string.compose_visibility, getString(visibilityString))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
|
@ -141,7 +139,6 @@ class ComposeActivity : BaseActivity(), OnImageActionClickListener {
|
||||||
override fun onAddImage() {
|
override fun onAddImage() {
|
||||||
val options = Options.init()
|
val options = Options.init()
|
||||||
.setRequestCode(REQUEST_CODE_PICK_MEDIA)
|
.setRequestCode(REQUEST_CODE_PICK_MEDIA)
|
||||||
.setImageQuality(ImageQuality.HIGH)
|
|
||||||
.setScreenOrientation(Options.SCREEN_ORIENTATION_PORTRAIT)
|
.setScreenOrientation(Options.SCREEN_ORIENTATION_PORTRAIT)
|
||||||
|
|
||||||
Pix.start(this, options)
|
Pix.start(this, options)
|
||||||
|
|
|
@ -38,13 +38,13 @@ import at.connyduck.pixelcat.model.NewStatus
|
||||||
import at.connyduck.pixelcat.network.FediverseApi
|
import at.connyduck.pixelcat.network.FediverseApi
|
||||||
import at.connyduck.pixelcat.network.calladapter.NetworkResponseError
|
import at.connyduck.pixelcat.network.calladapter.NetworkResponseError
|
||||||
import dagger.android.DaggerService
|
import dagger.android.DaggerService
|
||||||
import kotlinx.android.parcel.Parcelize
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.SupervisorJob
|
import kotlinx.coroutines.SupervisorJob
|
||||||
import kotlinx.coroutines.cancel
|
import kotlinx.coroutines.cancel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
import okhttp3.MediaType.Companion.toMediaType
|
import okhttp3.MediaType.Companion.toMediaType
|
||||||
import okhttp3.MultipartBody
|
import okhttp3.MultipartBody
|
||||||
import okhttp3.RequestBody.Companion.asRequestBody
|
import okhttp3.RequestBody.Companion.asRequestBody
|
||||||
|
|
|
@ -43,14 +43,9 @@ import at.connyduck.pixelcat.components.util.extension.visible
|
||||||
import at.connyduck.pixelcat.dagger.ViewModelFactory
|
import at.connyduck.pixelcat.dagger.ViewModelFactory
|
||||||
import at.connyduck.pixelcat.databinding.ActivityLoginBinding
|
import at.connyduck.pixelcat.databinding.ActivityLoginBinding
|
||||||
import at.connyduck.pixelcat.util.viewBinding
|
import at.connyduck.pixelcat.util.viewBinding
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
||||||
import kotlinx.coroutines.FlowPreview
|
|
||||||
import kotlinx.coroutines.flow.collect
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@FlowPreview
|
|
||||||
@ExperimentalCoroutinesApi
|
|
||||||
class LoginActivity : BaseActivity() {
|
class LoginActivity : BaseActivity() {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
package at.connyduck.pixelcat.components.login
|
package at.connyduck.pixelcat.components.login
|
||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import kotlinx.android.parcel.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class LoginModel(
|
data class LoginModel(
|
||||||
|
|
|
@ -25,25 +25,21 @@ import at.connyduck.pixelcat.config.Config
|
||||||
import at.connyduck.pixelcat.db.AccountManager
|
import at.connyduck.pixelcat.db.AccountManager
|
||||||
import at.connyduck.pixelcat.db.entitity.AccountAuthData
|
import at.connyduck.pixelcat.db.entitity.AccountAuthData
|
||||||
import at.connyduck.pixelcat.network.FediverseApi
|
import at.connyduck.pixelcat.network.FediverseApi
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.FlowPreview
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.channels.ConflatedBroadcastChannel
|
|
||||||
import kotlinx.coroutines.flow.asFlow
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import okhttp3.HttpUrl
|
import okhttp3.HttpUrl
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@FlowPreview
|
|
||||||
@ExperimentalCoroutinesApi
|
|
||||||
class LoginViewModel @Inject constructor(
|
class LoginViewModel @Inject constructor(
|
||||||
private val api: FediverseApi,
|
private val api: FediverseApi,
|
||||||
private val accountManager: AccountManager
|
private val accountManager: AccountManager
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
private val loginState = ConflatedBroadcastChannel(LoginModel(state = LoginState.NO_ERROR))
|
private val loginState = MutableStateFlow(LoginModel(state = LoginState.NO_ERROR))
|
||||||
|
|
||||||
fun observe() = loginState.asFlow()
|
fun observe(): Flow<LoginModel> = loginState
|
||||||
|
|
||||||
fun startLogin(input: String) {
|
fun startLogin(input: String) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
|
@ -52,7 +48,7 @@ class LoginViewModel @Inject constructor(
|
||||||
try {
|
try {
|
||||||
HttpUrl.Builder().host(domainInput).scheme("https").build()
|
HttpUrl.Builder().host(domainInput).scheme("https").build()
|
||||||
} catch (e: IllegalArgumentException) {
|
} catch (e: IllegalArgumentException) {
|
||||||
loginState.send(LoginModel(input, LoginState.INVALID_DOMAIN))
|
loginState.value = LoginModel(input, LoginState.INVALID_DOMAIN)
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,11 +57,11 @@ class LoginViewModel @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exceptionMatch) {
|
if (exceptionMatch) {
|
||||||
loginState.send(LoginModel(input, LoginState.AUTH_ERROR))
|
loginState.value = LoginModel(input, LoginState.AUTH_ERROR)
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
|
|
||||||
loginState.send(LoginModel(input, LoginState.LOADING))
|
loginState.value = LoginModel(input, LoginState.LOADING)
|
||||||
|
|
||||||
api.authenticateAppAsync(
|
api.authenticateAppAsync(
|
||||||
domain = domainInput,
|
domain = domainInput,
|
||||||
|
@ -75,10 +71,10 @@ class LoginViewModel @Inject constructor(
|
||||||
scopes = Config.oAuthScopes
|
scopes = Config.oAuthScopes
|
||||||
).fold(
|
).fold(
|
||||||
{ appData ->
|
{ appData ->
|
||||||
loginState.send(LoginModel(input, LoginState.SUCCESS, domainInput, appData.clientId, appData.clientSecret))
|
loginState.value = LoginModel(input, LoginState.SUCCESS, domainInput, appData.clientId, appData.clientSecret)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
loginState.send(LoginModel(input, LoginState.AUTH_ERROR))
|
loginState.value = LoginModel(input, LoginState.AUTH_ERROR)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -107,19 +103,17 @@ class LoginViewModel @Inject constructor(
|
||||||
clientSecret = loginModel.clientSecret
|
clientSecret = loginModel.clientSecret
|
||||||
)
|
)
|
||||||
accountManager.addAccount(loginModel.domain, authData)
|
accountManager.addAccount(loginModel.domain, authData)
|
||||||
loginState.send(loginState.value.copy(state = LoginState.SUCCESS_FINAL))
|
loginState.value = loginState.value.copy(state = LoginState.SUCCESS_FINAL)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
loginState.send(loginState.value.copy(state = LoginState.AUTH_ERROR))
|
loginState.value = loginState.value.copy(state = LoginState.AUTH_ERROR)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeError() {
|
fun removeError() {
|
||||||
viewModelScope.launch {
|
loginState.value = loginState.value.copy(state = LoginState.NO_ERROR)
|
||||||
loginState.send(loginState.value.copy(state = LoginState.NO_ERROR))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun canonicalizeDomain(domain: String): String {
|
private fun canonicalizeDomain(domain: String): String {
|
||||||
|
@ -131,6 +125,6 @@ class LoginViewModel @Inject constructor(
|
||||||
if (at != -1) {
|
if (at != -1) {
|
||||||
s = s.substring(at + 1)
|
s = s.substring(at + 1)
|
||||||
}
|
}
|
||||||
return s.trim().toLowerCase(Locale.ROOT)
|
return s.trim().lowercase(Locale.ROOT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,7 @@ import at.connyduck.pixelcat.databinding.ActivityMainBinding
|
||||||
import at.connyduck.pixelcat.db.AccountManager
|
import at.connyduck.pixelcat.db.AccountManager
|
||||||
import com.fxn.pix.Options
|
import com.fxn.pix.Options
|
||||||
import com.fxn.pix.Pix
|
import com.fxn.pix.Pix
|
||||||
import com.fxn.utility.ImageQuality
|
import com.google.android.material.navigation.NavigationBarView
|
||||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class MainActivity : BaseActivity() {
|
class MainActivity : BaseActivity() {
|
||||||
|
@ -54,8 +53,8 @@ class MainActivity : BaseActivity() {
|
||||||
private lateinit var mainFragmentAdapter: MainFragmentAdapter
|
private lateinit var mainFragmentAdapter: MainFragmentAdapter
|
||||||
|
|
||||||
private val onNavigationItemSelectedListener =
|
private val onNavigationItemSelectedListener =
|
||||||
BottomNavigationView.OnNavigationItemSelectedListener { item ->
|
NavigationBarView.OnItemSelectedListener { item ->
|
||||||
return@OnNavigationItemSelectedListener when (item.itemId) {
|
return@OnItemSelectedListener when (item.itemId) {
|
||||||
R.id.navigation_home -> {
|
R.id.navigation_home -> {
|
||||||
binding.mainViewPager.setCurrentItem(0, false)
|
binding.mainViewPager.setCurrentItem(0, false)
|
||||||
true
|
true
|
||||||
|
@ -67,7 +66,6 @@ class MainActivity : BaseActivity() {
|
||||||
R.id.navigation_compose -> {
|
R.id.navigation_compose -> {
|
||||||
val options = Options.init()
|
val options = Options.init()
|
||||||
.setRequestCode(100)
|
.setRequestCode(100)
|
||||||
.setImageQuality(ImageQuality.HIGH)
|
|
||||||
.setScreenOrientation(Options.SCREEN_ORIENTATION_PORTRAIT)
|
.setScreenOrientation(Options.SCREEN_ORIENTATION_PORTRAIT)
|
||||||
|
|
||||||
Pix.start(this, options)
|
Pix.start(this, options)
|
||||||
|
@ -102,7 +100,7 @@ class MainActivity : BaseActivity() {
|
||||||
binding.mainViewPager.adapter = mainFragmentAdapter
|
binding.mainViewPager.adapter = mainFragmentAdapter
|
||||||
binding.mainViewPager.isUserInputEnabled = false
|
binding.mainViewPager.isUserInputEnabled = false
|
||||||
|
|
||||||
binding.navigation.setOnNavigationItemSelectedListener(onNavigationItemSelectedListener)
|
binding.navigation.setOnItemSelectedListener(onNavigationItemSelectedListener)
|
||||||
|
|
||||||
mainViewModel.whatever()
|
mainViewModel.whatever()
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.paging.ExperimentalPagingApi
|
|
||||||
import androidx.paging.LoadState
|
import androidx.paging.LoadState
|
||||||
import androidx.recyclerview.widget.DividerItemDecoration
|
import androidx.recyclerview.widget.DividerItemDecoration
|
||||||
import androidx.recyclerview.widget.SimpleItemAnimator
|
import androidx.recyclerview.widget.SimpleItemAnimator
|
||||||
|
@ -52,7 +51,6 @@ class NotificationsFragment :
|
||||||
|
|
||||||
private val binding by viewBinding(FragmentNotificationsBinding::bind)
|
private val binding by viewBinding(FragmentNotificationsBinding::bind)
|
||||||
|
|
||||||
@ExperimentalPagingApi
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
|
||||||
binding.notificationSwipeRefresh.setColorSchemeColors(
|
binding.notificationSwipeRefresh.setColorSchemeColors(
|
||||||
|
|
|
@ -33,14 +33,13 @@ import kotlinx.coroutines.flow.asFlow
|
||||||
import kotlinx.coroutines.flow.flatMapConcat
|
import kotlinx.coroutines.flow.flatMapConcat
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@OptIn(ExperimentalPagingApi::class, FlowPreview::class)
|
||||||
class NotificationsViewModel @Inject constructor(
|
class NotificationsViewModel @Inject constructor(
|
||||||
accountManager: AccountManager,
|
accountManager: AccountManager,
|
||||||
private val db: AppDatabase,
|
private val db: AppDatabase,
|
||||||
private val api: FediverseApi
|
private val api: FediverseApi
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
@OptIn(FlowPreview::class)
|
|
||||||
@ExperimentalPagingApi
|
|
||||||
val notificationsFlow = accountManager::activeAccount.asFlow()
|
val notificationsFlow = accountManager::activeAccount.asFlow()
|
||||||
.flatMapConcat { activeAccount ->
|
.flatMapConcat { activeAccount ->
|
||||||
Pager(
|
Pager(
|
||||||
|
|
|
@ -23,13 +23,13 @@ import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.paging.ExperimentalPagingApi
|
|
||||||
import androidx.recyclerview.widget.ConcatAdapter
|
import androidx.recyclerview.widget.ConcatAdapter
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import at.connyduck.pixelcat.R
|
import at.connyduck.pixelcat.R
|
||||||
import at.connyduck.pixelcat.components.bottomsheet.accountselection.AccountSelectionBottomSheet
|
import at.connyduck.pixelcat.components.bottomsheet.accountselection.AccountSelectionBottomSheet
|
||||||
import at.connyduck.pixelcat.components.bottomsheet.menu.MenuBottomSheet
|
import at.connyduck.pixelcat.components.bottomsheet.menu.MenuBottomSheet
|
||||||
import at.connyduck.pixelcat.components.main.MainActivity
|
import at.connyduck.pixelcat.components.main.MainActivity
|
||||||
|
import at.connyduck.pixelcat.components.util.Error
|
||||||
import at.connyduck.pixelcat.components.util.Success
|
import at.connyduck.pixelcat.components.util.Success
|
||||||
import at.connyduck.pixelcat.components.util.extension.getDisplayWidthInPx
|
import at.connyduck.pixelcat.components.util.extension.getDisplayWidthInPx
|
||||||
import at.connyduck.pixelcat.dagger.ViewModelFactory
|
import at.connyduck.pixelcat.dagger.ViewModelFactory
|
||||||
|
@ -63,7 +63,6 @@ class ProfileFragment : DaggerFragment(R.layout.fragment_profile) {
|
||||||
private val headerAdapter = ProfileHeaderAdapter()
|
private val headerAdapter = ProfileHeaderAdapter()
|
||||||
private lateinit var imageAdapter: ProfileImageAdapter
|
private lateinit var imageAdapter: ProfileImageAdapter
|
||||||
|
|
||||||
@ExperimentalPagingApi
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
|
||||||
if (activity is MainActivity) {
|
if (activity is MainActivity) {
|
||||||
|
@ -111,23 +110,22 @@ class ProfileFragment : DaggerFragment(R.layout.fragment_profile) {
|
||||||
viewModel.setAccountInfo(arg(ACCOUNT_ID))
|
viewModel.setAccountInfo(arg(ACCOUNT_ID))
|
||||||
|
|
||||||
viewModel.profile.observe(
|
viewModel.profile.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
when (it) {
|
when (it) {
|
||||||
is Success -> onAccountChanged(it.data)
|
is Success -> onAccountChanged(it.data)
|
||||||
is Error -> showError()
|
is Error -> showError()
|
||||||
}
|
else -> {}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
viewModel.relationship.observe(
|
viewModel.relationship.observe(
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner
|
||||||
{
|
) {
|
||||||
when (it) {
|
when (it) {
|
||||||
is Success -> onRelationshipChanged(it.data)
|
is Success -> onRelationshipChanged(it.data)
|
||||||
is Error -> showError()
|
is Error -> showError()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
viewModel.imageFlow.collectLatest { imageAdapter.submitData(it) }
|
viewModel.imageFlow.collectLatest { imageAdapter.submitData(it) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
package at.connyduck.pixelcat.components.profile
|
package at.connyduck.pixelcat.components.profile
|
||||||
|
|
||||||
import androidx.paging.PagingSource
|
import androidx.paging.PagingSource
|
||||||
|
import androidx.paging.PagingState
|
||||||
import at.connyduck.pixelcat.db.AccountManager
|
import at.connyduck.pixelcat.db.AccountManager
|
||||||
import at.connyduck.pixelcat.model.Status
|
import at.connyduck.pixelcat.model.Status
|
||||||
import at.connyduck.pixelcat.network.FediverseApi
|
import at.connyduck.pixelcat.network.FediverseApi
|
||||||
|
@ -54,4 +55,6 @@ class ProfileImagePagingSource(
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getRefreshKey(state: PagingState<String, Status>): String? = null
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ import kotlinx.coroutines.FlowPreview
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@OptIn(FlowPreview::class, ExperimentalPagingApi::class)
|
||||||
class ProfileViewModel @Inject constructor(
|
class ProfileViewModel @Inject constructor(
|
||||||
private val api: FediverseApi,
|
private val api: FediverseApi,
|
||||||
private val accountManager: AccountManager
|
private val accountManager: AccountManager
|
||||||
|
@ -45,8 +46,6 @@ class ProfileViewModel @Inject constructor(
|
||||||
val profile = MutableLiveData<UiState<Account>>()
|
val profile = MutableLiveData<UiState<Account>>()
|
||||||
val relationship = MutableLiveData<UiState<Relationship>>()
|
val relationship = MutableLiveData<UiState<Relationship>>()
|
||||||
|
|
||||||
@OptIn(FlowPreview::class)
|
|
||||||
@ExperimentalPagingApi
|
|
||||||
val imageFlow = Pager(
|
val imageFlow = Pager(
|
||||||
config = PagingConfig(pageSize = 10, enablePlaceholders = false),
|
config = PagingConfig(pageSize = 10, enablePlaceholders = false),
|
||||||
pagingSourceFactory = { ProfileImagePagingSource(api, accountId, accountManager) }
|
pagingSourceFactory = { ProfileImagePagingSource(api, accountId, accountManager) }
|
||||||
|
|
|
@ -23,7 +23,6 @@ import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.paging.ExperimentalPagingApi
|
|
||||||
import androidx.paging.LoadState
|
import androidx.paging.LoadState
|
||||||
import androidx.recyclerview.widget.DividerItemDecoration
|
import androidx.recyclerview.widget.DividerItemDecoration
|
||||||
import androidx.recyclerview.widget.SimpleItemAnimator
|
import androidx.recyclerview.widget.SimpleItemAnimator
|
||||||
|
@ -49,7 +48,6 @@ class TimelineFragment : DaggerFragment(R.layout.fragment_timeline), TimeLineAct
|
||||||
|
|
||||||
private val binding by viewBinding(FragmentTimelineBinding::bind)
|
private val binding by viewBinding(FragmentTimelineBinding::bind)
|
||||||
|
|
||||||
@ExperimentalPagingApi
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
|
||||||
binding.timelineSwipeRefresh.setColorSchemeColors(
|
binding.timelineSwipeRefresh.setColorSchemeColors(
|
||||||
|
|
|
@ -35,6 +35,7 @@ import kotlinx.coroutines.flow.flatMapConcat
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@OptIn(FlowPreview::class, ExperimentalPagingApi::class)
|
||||||
class TimelineViewModel @Inject constructor(
|
class TimelineViewModel @Inject constructor(
|
||||||
accountManager: AccountManager,
|
accountManager: AccountManager,
|
||||||
private val db: AppDatabase,
|
private val db: AppDatabase,
|
||||||
|
@ -42,8 +43,6 @@ class TimelineViewModel @Inject constructor(
|
||||||
private val useCases: TimelineUseCases
|
private val useCases: TimelineUseCases
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
@OptIn(FlowPreview::class)
|
|
||||||
@ExperimentalPagingApi
|
|
||||||
val statusFlow = accountManager::activeAccount.asFlow()
|
val statusFlow = accountManager::activeAccount.asFlow()
|
||||||
.flatMapConcat { activeAccount ->
|
.flatMapConcat { activeAccount ->
|
||||||
Pager(
|
Pager(
|
||||||
|
|
|
@ -76,46 +76,44 @@ class DetailActivity : BaseActivity(), TimeLineActionListener {
|
||||||
binding.detailRecyclerView.adapter = ConcatAdapter(statusAdapter, repliesAdapter)
|
binding.detailRecyclerView.adapter = ConcatAdapter(statusAdapter, repliesAdapter)
|
||||||
|
|
||||||
viewModel.currentStatus.observe(
|
viewModel.currentStatus.observe(
|
||||||
this,
|
this
|
||||||
{
|
) {
|
||||||
when (it) {
|
when (it) {
|
||||||
is Success -> {
|
is Success -> {
|
||||||
binding.detailSwipeRefresh.show()
|
binding.detailSwipeRefresh.show()
|
||||||
binding.detailStatus.hide()
|
binding.detailStatus.hide()
|
||||||
binding.detailProgress.hide()
|
binding.detailProgress.hide()
|
||||||
binding.detailSwipeRefresh.isRefreshing = false
|
binding.detailSwipeRefresh.isRefreshing = false
|
||||||
binding.detailRecyclerView.show()
|
binding.detailRecyclerView.show()
|
||||||
statusAdapter.submitList(listOf(it.data))
|
statusAdapter.submitList(listOf(it.data))
|
||||||
it.data?.let { status ->
|
it.data?.let { status ->
|
||||||
if (intent.getBooleanExtra(EXTRA_REPLY, false)) {
|
if (intent.getBooleanExtra(EXTRA_REPLY, false)) {
|
||||||
intent.removeExtra(EXTRA_REPLY)
|
intent.removeExtra(EXTRA_REPLY)
|
||||||
onReply(status)
|
onReply(status)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is Loading -> {
|
}
|
||||||
binding.detailSwipeRefresh.hide()
|
is Loading -> {
|
||||||
binding.detailStatus.hide()
|
binding.detailSwipeRefresh.hide()
|
||||||
binding.detailProgress.show()
|
binding.detailStatus.hide()
|
||||||
}
|
binding.detailProgress.show()
|
||||||
is Error -> {
|
}
|
||||||
binding.detailSwipeRefresh.hide()
|
is Error -> {
|
||||||
binding.detailStatus.show()
|
binding.detailSwipeRefresh.hide()
|
||||||
binding.detailProgress.hide()
|
binding.detailStatus.show()
|
||||||
binding.detailStatus.showGeneralError()
|
binding.detailProgress.hide()
|
||||||
}
|
binding.detailStatus.showGeneralError()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
viewModel.replies.observe(
|
viewModel.replies.observe(
|
||||||
this,
|
this
|
||||||
{
|
) {
|
||||||
if (it is Success) {
|
if (it is Success) {
|
||||||
repliesAdapter.submitList(it.data)
|
repliesAdapter.submitList(it.data)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFavorite(status: StatusEntity) {
|
override fun onFavorite(status: StatusEntity) {
|
||||||
|
|
|
@ -132,7 +132,7 @@ class DetailViewModel @Inject constructor(
|
||||||
NewStatus(
|
NewStatus(
|
||||||
status = replyText,
|
status = replyText,
|
||||||
inReplyToId = statusToReply.actionableId,
|
inReplyToId = statusToReply.actionableId,
|
||||||
visibility = statusToReply.visibility.name.toLowerCase(Locale.ROOT),
|
visibility = statusToReply.visibility.name.lowercase(Locale.ROOT),
|
||||||
sensitive = statusToReply.sensitive,
|
sensitive = statusToReply.sensitive,
|
||||||
mediaIds = null
|
mediaIds = null
|
||||||
)
|
)
|
||||||
|
|
|
@ -27,6 +27,6 @@ import java.util.Locale
|
||||||
* @return the mime type, or null if it couldn't be determined
|
* @return the mime type, or null if it couldn't be determined
|
||||||
*/
|
*/
|
||||||
fun getMimeType(filePath: String): String? {
|
fun getMimeType(filePath: String): String? {
|
||||||
val extension = filePath.split('.').lastOrNull()?.toLowerCase(Locale.ROOT) ?: return null
|
val extension = filePath.split('.').lastOrNull()?.lowercase(Locale.ROOT) ?: return null
|
||||||
return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
|
return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,9 +46,9 @@ data class Account(
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val name: String
|
val name: String
|
||||||
get() = if (displayName.isEmpty()) {
|
get() = displayName.ifEmpty {
|
||||||
localUsername
|
localUsername
|
||||||
} else displayName
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
|
|
|
@ -32,17 +32,16 @@ class FragmentViewBindingDelegate<T : ViewBinding>(
|
||||||
object : DefaultLifecycleObserver {
|
object : DefaultLifecycleObserver {
|
||||||
override fun onCreate(owner: LifecycleOwner) {
|
override fun onCreate(owner: LifecycleOwner) {
|
||||||
fragment.viewLifecycleOwnerLiveData.observe(
|
fragment.viewLifecycleOwnerLiveData.observe(
|
||||||
fragment,
|
fragment
|
||||||
{ t ->
|
) { t ->
|
||||||
t?.lifecycle?.addObserver(
|
t?.lifecycle?.addObserver(
|
||||||
object : DefaultLifecycleObserver {
|
object : DefaultLifecycleObserver {
|
||||||
override fun onDestroy(owner: LifecycleOwner) {
|
override fun onDestroy(owner: LifecycleOwner) {
|
||||||
binding = null
|
binding = null
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
}
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,9 +5,9 @@ buildscript {
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath("com.android.tools.build:gradle:4.1.0")
|
classpath("com.android.tools.build:gradle:7.1.0")
|
||||||
classpath(kotlin("gradle-plugin", version = "1.4.10"))
|
classpath(kotlin("gradle-plugin", version = "1.6.10"))
|
||||||
classpath("org.jlleitschuh.gradle:ktlint-gradle:9.4.0")
|
classpath("org.jlleitschuh.gradle:ktlint-gradle:10.2.1")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -1,5 +1,5 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|
Loading…
Reference in New Issue