diff --git a/app/build.gradle b/app/build.gradle index 4e98fe81..8c444441 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -83,22 +83,26 @@ android { enableSplit = false } } + kotlinOptions { + freeCompilerArgs += "-opt-in=kotlin.RequiresOptIn" + } } +ext.coroutinesVersion = "1.6.0" ext.lifecycleVersion = "2.3.1" ext.roomVersion = '2.3.0' ext.retrofitVersion = '2.9.0' -ext.okhttpVersion = '4.9.1' +ext.okhttpVersion = '4.9.3' ext.glideVersion = '4.12.0' -ext.daggerVersion = '2.37' -ext.materialdrawerVersion = '8.4.1' +ext.daggerVersion = '2.40.5' +ext.materialdrawerVersion = '8.4.5' // if libraries are changed here, they should also be changed in LicenseActivity dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0' - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-rx3:1.5.0' + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-rx3:$coroutinesVersion" implementation "androidx.core:core-ktx:1.5.0" implementation "androidx.appcompat:appcompat:1.3.0" @@ -106,7 +110,7 @@ dependencies { implementation "androidx.browser:browser:1.3.0" implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" implementation "androidx.recyclerview:recyclerview:1.2.1" - implementation "androidx.exifinterface:exifinterface:1.3.2" + implementation "androidx.exifinterface:exifinterface:1.3.3" implementation "androidx.cardview:cardview:1.0.0" implementation "androidx.preference:preference-ktx:1.1.1" implementation "androidx.sharetarget:sharetarget:1.1.0" @@ -116,7 +120,7 @@ dependencies { implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion" implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion" implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:$lifecycleVersion" - implementation "androidx.constraintlayout:constraintlayout:2.0.4" + implementation "androidx.constraintlayout:constraintlayout:2.1.2" implementation "androidx.paging:paging-runtime-ktx:3.0.0" implementation "androidx.viewpager2:viewpager2:1.0.0" implementation "androidx.work:work-runtime:2.5.0" @@ -124,7 +128,9 @@ dependencies { implementation "androidx.room:room-rxjava3:$roomVersion" kapt "androidx.room:room-compiler:$roomVersion" - implementation "com.google.android.material:material:1.3.0" + implementation "com.google.android.material:material:1.4.0" + + implementation "com.google.code.gson:gson:2.8.9" implementation "com.squareup.retrofit2:retrofit:$retrofitVersion" implementation "com.squareup.retrofit2:converter-gson:$retrofitVersion" @@ -139,7 +145,7 @@ dependencies { implementation "com.github.bumptech.glide:okhttp3-integration:$glideVersion" kapt "com.github.bumptech.glide:compiler:$glideVersion" - implementation "com.github.penfeizhou.android.animation:glide-plugin:2.12.0" + implementation "com.github.penfeizhou.android.animation:glide-plugin:2.17.0" implementation "io.reactivex.rxjava3:rxjava:3.0.12" implementation "io.reactivex.rxjava3:rxandroid:3.0.0" @@ -160,21 +166,21 @@ dependencies { implementation "com.mikepenz:materialdrawer:$materialdrawerVersion" implementation "com.mikepenz:materialdrawer-iconics:$materialdrawerVersion" - implementation 'com.mikepenz:google-material-typeface:3.0.1.4.original-kotlin@aar' + implementation 'com.mikepenz:google-material-typeface:4.0.0.2-kotlin@aar' implementation "com.github.CanHub:Android-Image-Cropper:3.1.0" implementation "de.c1710:filemojicompat:1.0.18" - testImplementation "androidx.test.ext:junit:1.1.2" + testImplementation "androidx.test.ext:junit:1.1.3" testImplementation "org.robolectric:robolectric:4.4" testImplementation "org.mockito:mockito-inline:3.6.28" testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0" - androidTestImplementation "androidx.test.espresso:espresso-core:3.3.0" + androidTestImplementation "androidx.test.espresso:espresso-core:3.4.0" androidTestImplementation "androidx.room:room-testing:$roomVersion" - androidTestImplementation "androidx.test.ext:junit:1.1.2" + androidTestImplementation "androidx.test.ext:junit:1.1.3" testImplementation "androidx.arch.core:core-testing:2.1.0" - testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.5.0' + testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesVersion" } diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index af6372d4..d5092d82 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -33,6 +33,10 @@ public static final ** CREATOR; } +-keepclassmembers class **.R$* { + public static ; +} + # TUSKY SPECIFIC OPTIONS # keep members of our model classes, they are used in json de/serialization @@ -47,6 +51,18 @@ public *; } +# https://github.com/google/gson/blob/master/examples/android-proguard-example/proguard.cfg +# Retain generic signatures of TypeToken and its subclasses with R8 version 3.0 and higher. +-keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken +-keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken + +# Retain generic signatures of classes used in MastodonApi so Retrofit works +-keep,allowobfuscation,allowshrinking class io.reactivex.rxjava3.core.Single +-keep,allowobfuscation,allowshrinking class retrofit2.Response +-keep,allowobfuscation,allowshrinking class kotlin.collections.List +-keep,allowobfuscation,allowshrinking class kotlin.collections.Map +-keep,allowobfuscation,allowshrinking class retrofit2.Call + # preserve line numbers for crash reporting -keepattributes SourceFile,LineNumberTable -renamesourcefileattribute SourceFile diff --git a/app/src/main/java/com/keylesspalace/tusky/EditProfileActivity.kt b/app/src/main/java/com/keylesspalace/tusky/EditProfileActivity.kt index 1115cd41..ef0e3e98 100644 --- a/app/src/main/java/com/keylesspalace/tusky/EditProfileActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/EditProfileActivity.kt @@ -165,17 +165,16 @@ class EditProfileActivity : BaseActivity(), Injectable { } snackbar.show() } + is Loading -> { } } } viewModel.obtainInstance() viewModel.instanceData.observe(this) { result -> - when (result) { - is Success -> { - val instance = result.data - if (instance?.maxBioChars != null && instance.maxBioChars > 0) { - binding.noteEditTextLayout.counterMaxLength = instance.maxBioChars - } + if (result is Success) { + val instance = result.data + if (instance?.maxBioChars != null && instance.maxBioChars > 0) { + binding.noteEditTextLayout.counterMaxLength = instance.maxBioChars } } } @@ -278,6 +277,7 @@ class EditProfileActivity : BaseActivity(), Injectable { permissions: Array, grantResults: IntArray ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) when (requestCode) { PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE -> { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { diff --git a/app/src/main/java/com/keylesspalace/tusky/components/account/AccountActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/account/AccountActivity.kt index 48e351c7..087b52dc 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/account/AccountActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/account/AccountActivity.kt @@ -68,7 +68,9 @@ import com.keylesspalace.tusky.interfaces.LinkListener import com.keylesspalace.tusky.interfaces.ReselectableFragment import com.keylesspalace.tusky.settings.PrefKeys import com.keylesspalace.tusky.util.DefaultTextWatcher +import com.keylesspalace.tusky.util.Error import com.keylesspalace.tusky.util.LinkHelper +import com.keylesspalace.tusky.util.Loading import com.keylesspalace.tusky.util.Success import com.keylesspalace.tusky.util.ThemeUtils import com.keylesspalace.tusky.util.emojify @@ -351,6 +353,7 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidI .setAction(R.string.action_retry) { viewModel.refresh() } .show() } + is Loading -> { } } } viewModel.relationshipData.observe(this) { diff --git a/app/src/main/java/com/keylesspalace/tusky/components/conversation/ConversationsFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/conversation/ConversationsFragment.kt index 25f3864d..958a9c99 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/conversation/ConversationsFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/conversation/ConversationsFragment.kt @@ -52,6 +52,7 @@ import kotlinx.coroutines.launch import java.io.IOException import javax.inject.Inject +@OptIn(ExperimentalPagingApi::class) class ConversationsFragment : SFragment(), StatusActionListener, Injectable, ReselectableFragment { @Inject @@ -72,7 +73,6 @@ class ConversationsFragment : SFragment(), StatusActionListener, Injectable, Res return inflater.inflate(R.layout.fragment_timeline, container, false) } - @ExperimentalPagingApi override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val preferences = PreferenceManager.getDefaultSharedPreferences(view.context) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/conversation/ConversationsRemoteMediator.kt b/app/src/main/java/com/keylesspalace/tusky/components/conversation/ConversationsRemoteMediator.kt index 7418c3b0..26984c8e 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/conversation/ConversationsRemoteMediator.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/conversation/ConversationsRemoteMediator.kt @@ -7,7 +7,7 @@ import androidx.paging.RemoteMediator import com.keylesspalace.tusky.db.AppDatabase import com.keylesspalace.tusky.network.MastodonApi -@ExperimentalPagingApi +@OptIn(ExperimentalPagingApi::class) class ConversationsRemoteMediator( private val accountId: Long, private val api: MastodonApi, diff --git a/app/src/main/java/com/keylesspalace/tusky/components/conversation/ConversationsViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/conversation/ConversationsViewModel.kt index eafdbdf2..396f8e48 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/conversation/ConversationsViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/conversation/ConversationsViewModel.kt @@ -37,7 +37,7 @@ class ConversationsViewModel @Inject constructor( private val api: MastodonApi ) : RxAwareViewModel() { - @ExperimentalPagingApi + @OptIn(ExperimentalPagingApi::class) val conversationFlow = Pager( config = PagingConfig(pageSize = 10, enablePlaceholders = false, initialLoadSize = 20), remoteMediator = ConversationsRemoteMediator(accountManager.activeAccount!!.id, api, database), diff --git a/app/src/main/java/com/keylesspalace/tusky/components/scheduled/ScheduledTootActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/scheduled/ScheduledTootActivity.kt index 06a4dee0..dfcbd95f 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/scheduled/ScheduledTootActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/scheduled/ScheduledTootActivity.kt @@ -81,7 +81,7 @@ class ScheduledTootActivity : BaseActivity(), ScheduledTootActionListener, Injec } adapter.addLoadStateListener { loadState -> - if (loadState.refresh is Error) { + if (loadState.refresh is LoadState.Error) { binding.progressBar.hide() binding.errorMessageView.setup(R.drawable.elephant_error, R.string.error_generic) { refreshStatuses() diff --git a/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/CachedTimelineRemoteMediator.kt b/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/CachedTimelineRemoteMediator.kt index 1d23ff21..98f6452d 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/CachedTimelineRemoteMediator.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/CachedTimelineRemoteMediator.kt @@ -33,7 +33,7 @@ import com.keylesspalace.tusky.util.dec import kotlinx.coroutines.rx3.await import retrofit2.HttpException -@ExperimentalPagingApi +@OptIn(ExperimentalPagingApi::class) class CachedTimelineRemoteMediator( accountManager: AccountManager, private val api: MastodonApi, diff --git a/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/CachedTimelineViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/CachedTimelineViewModel.kt index 066949d0..0cdf43bc 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/CachedTimelineViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/CachedTimelineViewModel.kt @@ -63,7 +63,7 @@ class CachedTimelineViewModel @Inject constructor( private val gson: Gson ) : TimelineViewModel(timelineCases, api, eventHub, accountManager, sharedPreferences, filterModel) { - @ExperimentalPagingApi + @OptIn(ExperimentalPagingApi::class) override val statuses = Pager( config = PagingConfig(pageSize = LOAD_AT_ONCE), remoteMediator = CachedTimelineRemoteMediator(accountManager, api, db, gson), diff --git a/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/NetworkTimelineRemoteMediator.kt b/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/NetworkTimelineRemoteMediator.kt index 4ce6c4cb..114faa92 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/NetworkTimelineRemoteMediator.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/NetworkTimelineRemoteMediator.kt @@ -26,7 +26,7 @@ import com.keylesspalace.tusky.util.toViewData import com.keylesspalace.tusky.viewdata.StatusViewData import retrofit2.HttpException -@ExperimentalPagingApi +@OptIn(ExperimentalPagingApi::class) class NetworkTimelineRemoteMediator( private val accountManager: AccountManager, private val viewModel: NetworkTimelineViewModel diff --git a/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/NetworkTimelineViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/NetworkTimelineViewModel.kt index b0bdfbcb..5815662d 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/NetworkTimelineViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/NetworkTimelineViewModel.kt @@ -63,7 +63,7 @@ class NetworkTimelineViewModel @Inject constructor( var nextKey: String? = null - @ExperimentalPagingApi + @OptIn(ExperimentalPagingApi::class) override val statuses = Pager( config = PagingConfig(pageSize = LOAD_AT_ONCE), pagingSourceFactory = { diff --git a/app/src/main/res/raw/keep.xml b/app/src/main/res/raw/keep.xml deleted file mode 100644 index c9c47c15..00000000 --- a/app/src/main/res/raw/keep.xml +++ /dev/null @@ -1,3 +0,0 @@ - - diff --git a/build.gradle b/build.gradle index ccc0c7fa..18b1872a 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,12 @@ buildscript { - ext.kotlin_version = '1.5.10' + ext.kotlin_version = '1.6.10' repositories { google() mavenCentral() gradlePluginPortal() } dependencies { - classpath 'com.android.tools.build:gradle:4.2.1' + classpath "com.android.tools.build:gradle:7.0.4" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jlleitschuh.gradle:ktlint-gradle:10.1.0" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 29e41345..669386b8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists