Api 33 support (#2719)
* update to Api 33, fix some deprecations * fix deprecated serializable/parcelable methods * ask for notification permission * fix code formatting * add back comment in PreferencesActivity
This commit is contained in:
		
					parent
					
						
							
								58e8f75287
							
						
					
				
			
			
				commit
				
					
						d17a0c43ab
					
				
			
		
					 20 changed files with 174 additions and 90 deletions
				
			
		|  | @ -19,11 +19,11 @@ def getGitSha = { | |||
| } | ||||
| 
 | ||||
| android { | ||||
|     compileSdkVersion 31 | ||||
|     compileSdkVersion 33 | ||||
|     defaultConfig { | ||||
|         applicationId APP_ID | ||||
|         minSdkVersion 23 | ||||
|         targetSdkVersion 31 | ||||
|         targetSdkVersion 33 | ||||
|         versionCode 94 | ||||
|         versionName "19.0" | ||||
|         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | ||||
|  | @ -108,16 +108,17 @@ dependencies { | |||
|     implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion" | ||||
|     implementation "org.jetbrains.kotlinx:kotlinx-coroutines-rx3:$coroutinesVersion" | ||||
| 
 | ||||
|     implementation "androidx.core:core-ktx:1.8.0" | ||||
|     implementation "androidx.appcompat:appcompat:1.4.2" | ||||
|     implementation "androidx.fragment:fragment-ktx:1.5.1" | ||||
|     implementation "androidx.core:core-ktx:1.9.0" | ||||
|     implementation "androidx.appcompat:appcompat:1.5.1" | ||||
|     implementation "androidx.activity:activity-ktx:1.6.0" | ||||
|     implementation "androidx.fragment:fragment-ktx:1.5.3" | ||||
|     implementation "androidx.browser:browser:1.4.0" | ||||
|     implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" | ||||
|     implementation "androidx.recyclerview:recyclerview:1.2.1" | ||||
|     implementation "androidx.exifinterface:exifinterface:1.3.3" | ||||
|     implementation "androidx.exifinterface:exifinterface:1.3.4" | ||||
|     implementation "androidx.cardview:cardview:1.0.0" | ||||
|     implementation "androidx.preference:preference-ktx:1.2.0" | ||||
|     implementation "androidx.sharetarget:sharetarget:1.2.0-rc01" | ||||
|     implementation "androidx.sharetarget:sharetarget:1.2.0" | ||||
|     implementation "androidx.emoji2:emoji2:$emoji2_version" | ||||
|     implementation "androidx.emoji2:emoji2-views:$emoji2_version" | ||||
|     implementation "androidx.emoji2:emoji2-views-helper:$emoji2_version" | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
|     package="com.keylesspalace.tusky"> | ||||
| 
 | ||||
|     <uses-permission android:name="android.permission.INTERNET" /> | ||||
|     <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> | ||||
|     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> | ||||
|     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> | ||||
|     <uses-permission android:name="android.permission.VIBRATE" /> <!-- For notifications --> | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ import android.content.Intent | |||
| import android.os.Bundle | ||||
| import com.keylesspalace.tusky.databinding.ActivityAccountListBinding | ||||
| import com.keylesspalace.tusky.fragment.AccountListFragment | ||||
| import com.keylesspalace.tusky.util.requireSerializableExtra | ||||
| import dagger.android.DispatchingAndroidInjector | ||||
| import dagger.android.HasAndroidInjector | ||||
| import javax.inject.Inject | ||||
|  | @ -44,7 +45,7 @@ class AccountListActivity : BaseActivity(), HasAndroidInjector { | |||
|         val binding = ActivityAccountListBinding.inflate(layoutInflater) | ||||
|         setContentView(binding.root) | ||||
| 
 | ||||
|         val type = intent.getSerializableExtra(EXTRA_TYPE) as Type | ||||
|         val type: Type = intent.requireSerializableExtra(EXTRA_TYPE) | ||||
|         val id: String? = intent.getStringExtra(EXTRA_ID) | ||||
|         val accountLocked: Boolean = intent.getBooleanExtra(EXTRA_ACCOUNT_LOCKED, false) | ||||
| 
 | ||||
|  |  | |||
|  | @ -132,7 +132,7 @@ public abstract class BaseActivity extends AppCompatActivity implements Injectab | |||
|     @Override | ||||
|     public boolean onOptionsItemSelected(MenuItem item) { | ||||
|         if (item.getItemId() == android.R.id.home) { | ||||
|             onBackPressed(); | ||||
|             getOnBackPressedDispatcher().onBackPressed(); | ||||
|             return true; | ||||
|         } | ||||
|         return super.onOptionsItemSelected(item); | ||||
|  |  | |||
|  | @ -15,9 +15,11 @@ | |||
| 
 | ||||
| package com.keylesspalace.tusky | ||||
| 
 | ||||
| import android.Manifest | ||||
| import android.content.Context | ||||
| import android.content.DialogInterface | ||||
| import android.content.Intent | ||||
| import android.content.pm.PackageManager | ||||
| import android.content.res.ColorStateList | ||||
| import android.graphics.Bitmap | ||||
| import android.graphics.Color | ||||
|  | @ -31,8 +33,11 @@ import android.view.KeyEvent | |||
| import android.view.MenuItem | ||||
| import android.view.View | ||||
| import android.widget.ImageView | ||||
| import androidx.activity.OnBackPressedCallback | ||||
| import androidx.appcompat.app.AlertDialog | ||||
| import androidx.coordinatorlayout.widget.CoordinatorLayout | ||||
| import androidx.core.app.ActivityCompat | ||||
| import androidx.core.content.ContextCompat | ||||
| import androidx.core.content.pm.ShortcutManagerCompat | ||||
| import androidx.core.view.GravityCompat | ||||
| import androidx.lifecycle.Lifecycle | ||||
|  | @ -267,6 +272,33 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje | |||
|         } | ||||
| 
 | ||||
|         selectedEmojiPack = preferences.getString(EMOJI_PREFERENCE, "") | ||||
| 
 | ||||
|         onBackPressedDispatcher.addCallback( | ||||
|             this, | ||||
|             object : OnBackPressedCallback(true) { | ||||
|                 override fun handleOnBackPressed() { | ||||
|                     when { | ||||
|                         binding.mainDrawerLayout.isOpen -> { | ||||
|                             binding.mainDrawerLayout.close() | ||||
|                         } | ||||
|                         binding.viewPager.currentItem != 0 -> { | ||||
|                             binding.viewPager.currentItem = 0 | ||||
|                         } | ||||
|                         else -> { | ||||
|                             finish() | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         ) | ||||
| 
 | ||||
|         if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { | ||||
|             ActivityCompat.requestPermissions( | ||||
|                 this, | ||||
|                 arrayOf(Manifest.permission.POST_NOTIFICATIONS), | ||||
|                 1 | ||||
|             ) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     override fun onResume() { | ||||
|  | @ -292,20 +324,6 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     override fun onBackPressed() { | ||||
|         when { | ||||
|             binding.mainDrawerLayout.isOpen -> { | ||||
|                 binding.mainDrawerLayout.close() | ||||
|             } | ||||
|             binding.viewPager.currentItem != 0 -> { | ||||
|                 binding.viewPager.currentItem = 0 | ||||
|             } | ||||
|             else -> { | ||||
|                 super.onBackPressed() | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { | ||||
|         when (keyCode) { | ||||
|             KeyEvent.KEYCODE_MENU -> { | ||||
|  |  | |||
|  | @ -20,9 +20,9 @@ import android.os.Bundle | |||
| import android.util.Log | ||||
| import android.view.View | ||||
| import android.widget.FrameLayout | ||||
| import androidx.activity.OnBackPressedCallback | ||||
| import androidx.appcompat.app.AlertDialog | ||||
| import androidx.appcompat.widget.AppCompatEditText | ||||
| import androidx.core.view.isVisible | ||||
| import androidx.core.view.updatePadding | ||||
| import androidx.lifecycle.Lifecycle | ||||
| import androidx.lifecycle.lifecycleScope | ||||
|  | @ -74,6 +74,12 @@ class TabPreferenceActivity : BaseActivity(), Injectable, ItemInteractionListene | |||
| 
 | ||||
|     private val hashtagRegex by lazy { Pattern.compile("([\\w_]*[\\p{Alpha}_][\\w_]*)", Pattern.CASE_INSENSITIVE) } | ||||
| 
 | ||||
|     private val onFabDismissedCallback = object : OnBackPressedCallback(false) { | ||||
|         override fun handleOnBackPressed() { | ||||
|             toggleFab(false) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     override fun onCreate(savedInstanceState: Bundle?) { | ||||
|         super.onCreate(savedInstanceState) | ||||
| 
 | ||||
|  | @ -149,6 +155,8 @@ class TabPreferenceActivity : BaseActivity(), Injectable, ItemInteractionListene | |||
|         binding.maxTabsInfo.text = resources.getQuantityString(R.plurals.max_tab_number_reached, MAX_TAB_COUNT, MAX_TAB_COUNT) | ||||
| 
 | ||||
|         updateAvailableTabs() | ||||
| 
 | ||||
|         onBackPressedDispatcher.addCallback(onFabDismissedCallback) | ||||
|     } | ||||
| 
 | ||||
|     override fun onTabAdded(tab: TabData) { | ||||
|  | @ -209,6 +217,8 @@ class TabPreferenceActivity : BaseActivity(), Injectable, ItemInteractionListene | |||
|         binding.actionButton.visible(!expand) | ||||
|         binding.sheet.visible(expand) | ||||
|         binding.scrim.visible(expand) | ||||
| 
 | ||||
|         onFabDismissedCallback.isEnabled = expand | ||||
|     } | ||||
| 
 | ||||
|     private fun showAddHashtagDialog(tab: TabData? = null, tabPosition: Int = 0) { | ||||
|  | @ -338,14 +348,6 @@ class TabPreferenceActivity : BaseActivity(), Injectable, ItemInteractionListene | |||
|         tabsChanged = true | ||||
|     } | ||||
| 
 | ||||
|     override fun onBackPressed() { | ||||
|         if (binding.actionButton.isVisible) { | ||||
|             super.onBackPressed() | ||||
|         } else { | ||||
|             toggleFab(false) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     override fun onPause() { | ||||
|         super.onPause() | ||||
|         if (tabsChanged) { | ||||
|  |  | |||
|  | @ -54,6 +54,7 @@ import com.keylesspalace.tusky.fragment.ViewImageFragment | |||
| import com.keylesspalace.tusky.pager.ImagePagerAdapter | ||||
| import com.keylesspalace.tusky.pager.SingleImagePagerAdapter | ||||
| import com.keylesspalace.tusky.util.getTemporaryMediaFilename | ||||
| import com.keylesspalace.tusky.util.parcelableArrayListExtra | ||||
| import com.keylesspalace.tusky.util.viewBinding | ||||
| import com.keylesspalace.tusky.viewdata.AttachmentViewData | ||||
| import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers | ||||
|  | @ -94,7 +95,7 @@ class ViewMediaActivity : BaseActivity(), ViewImageFragment.PhotoActionsListener | |||
|         supportPostponeEnterTransition() | ||||
| 
 | ||||
|         // Gather the parameters. | ||||
|         attachments = intent.getParcelableArrayListExtra(EXTRA_ATTACHMENTS) | ||||
|         attachments = intent.parcelableArrayListExtra(EXTRA_ATTACHMENTS) | ||||
|         val initialPosition = intent.getIntExtra(EXTRA_ATTACHMENT_INDEX, 0) | ||||
| 
 | ||||
|         // Adapter is actually of existential type PageAdapter & SharedElementsTransitionListener | ||||
|  |  | |||
|  | @ -40,6 +40,7 @@ import android.widget.ImageButton | |||
| import android.widget.LinearLayout | ||||
| import android.widget.PopupMenu | ||||
| import android.widget.Toast | ||||
| import androidx.activity.OnBackPressedCallback | ||||
| import androidx.activity.result.contract.ActivityResultContracts | ||||
| import androidx.activity.viewModels | ||||
| import androidx.annotation.ColorInt | ||||
|  | @ -92,6 +93,8 @@ import com.keylesspalace.tusky.util.hide | |||
| import com.keylesspalace.tusky.util.highlightSpans | ||||
| import com.keylesspalace.tusky.util.loadAvatar | ||||
| import com.keylesspalace.tusky.util.onTextChanged | ||||
| import com.keylesspalace.tusky.util.parcelableArrayListExtra | ||||
| import com.keylesspalace.tusky.util.parcelableExtra | ||||
| import com.keylesspalace.tusky.util.show | ||||
| import com.keylesspalace.tusky.util.viewBinding | ||||
| import com.keylesspalace.tusky.util.visible | ||||
|  | @ -237,8 +240,7 @@ class ComposeActivity : | |||
| 
 | ||||
|         /* If the composer is started up as a reply to another post, override the "starting" state | ||||
|          * based on what the intent from the reply request passes. */ | ||||
| 
 | ||||
|         val composeOptions: ComposeOptions? = intent.getParcelableExtra(COMPOSE_OPTIONS_EXTRA) | ||||
|         val composeOptions: ComposeOptions? = intent.parcelableExtra(COMPOSE_OPTIONS_EXTRA) | ||||
| 
 | ||||
|         viewModel.setup(composeOptions) | ||||
| 
 | ||||
|  | @ -299,12 +301,12 @@ class ComposeActivity : | |||
|                 if (type.startsWith("image/") || type.startsWith("video/") || type.startsWith("audio/")) { | ||||
|                     when (intent.action) { | ||||
|                         Intent.ACTION_SEND -> { | ||||
|                             intent.getParcelableExtra<Uri>(Intent.EXTRA_STREAM)?.let { uri -> | ||||
|                             intent.parcelableExtra<Uri>(Intent.EXTRA_STREAM)?.let { uri -> | ||||
|                                 pickMedia(uri) | ||||
|                             } | ||||
|                         } | ||||
|                         Intent.ACTION_SEND_MULTIPLE -> { | ||||
|                             intent.getParcelableArrayListExtra<Uri>(Intent.EXTRA_STREAM)?.forEach { uri -> | ||||
|                             intent.parcelableArrayListExtra<Uri>(Intent.EXTRA_STREAM)?.forEach { uri -> | ||||
|                                 pickMedia(uri) | ||||
|                             } | ||||
|                         } | ||||
|  | @ -510,6 +512,27 @@ class ComposeActivity : | |||
|         binding.actionPhotoTake.setOnClickListener { initiateCameraApp() } | ||||
|         binding.actionPhotoPick.setOnClickListener { onMediaPick() } | ||||
|         binding.addPollTextActionTextView.setOnClickListener { openPollDialog() } | ||||
| 
 | ||||
|         onBackPressedDispatcher.addCallback( | ||||
|             this, | ||||
|             object : OnBackPressedCallback(true) { | ||||
|                 override fun handleOnBackPressed() { | ||||
|                     if (composeOptionsBehavior.state == BottomSheetBehavior.STATE_EXPANDED || | ||||
|                         addMediaBehavior.state == BottomSheetBehavior.STATE_EXPANDED || | ||||
|                         emojiBehavior.state == BottomSheetBehavior.STATE_EXPANDED || | ||||
|                         scheduleBehavior.state == BottomSheetBehavior.STATE_EXPANDED | ||||
|                     ) { | ||||
|                         composeOptionsBehavior.state = BottomSheetBehavior.STATE_HIDDEN | ||||
|                         addMediaBehavior.state = BottomSheetBehavior.STATE_HIDDEN | ||||
|                         emojiBehavior.state = BottomSheetBehavior.STATE_HIDDEN | ||||
|                         scheduleBehavior.state = BottomSheetBehavior.STATE_HIDDEN | ||||
|                         return | ||||
|                     } | ||||
| 
 | ||||
|                     handleCloseButton() | ||||
|                 } | ||||
|             } | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     private fun setupLanguageSpinner(initialLanguage: String?) { | ||||
|  | @ -1069,23 +1092,6 @@ class ComposeActivity : | |||
|         return super.onOptionsItemSelected(item) | ||||
|     } | ||||
| 
 | ||||
|     override fun onBackPressed() { | ||||
|         // Acting like a teen: deliberately ignoring parent. | ||||
|         if (composeOptionsBehavior.state == BottomSheetBehavior.STATE_EXPANDED || | ||||
|             addMediaBehavior.state == BottomSheetBehavior.STATE_EXPANDED || | ||||
|             emojiBehavior.state == BottomSheetBehavior.STATE_EXPANDED || | ||||
|             scheduleBehavior.state == BottomSheetBehavior.STATE_EXPANDED | ||||
|         ) { | ||||
|             composeOptionsBehavior.state = BottomSheetBehavior.STATE_HIDDEN | ||||
|             addMediaBehavior.state = BottomSheetBehavior.STATE_HIDDEN | ||||
|             emojiBehavior.state = BottomSheetBehavior.STATE_HIDDEN | ||||
|             scheduleBehavior.state = BottomSheetBehavior.STATE_HIDDEN | ||||
|             return | ||||
|         } | ||||
| 
 | ||||
|         handleCloseButton() | ||||
|     } | ||||
| 
 | ||||
|     override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { | ||||
|         Log.d(TAG, event.toString()) | ||||
|         if (event.action == KeyEvent.ACTION_DOWN) { | ||||
|  | @ -1098,7 +1104,7 @@ class ComposeActivity : | |||
|             } | ||||
| 
 | ||||
|             if (keyCode == KeyEvent.KEYCODE_BACK) { | ||||
|                 onBackPressed() | ||||
|                 onBackPressedDispatcher.onBackPressed() | ||||
|                 return true | ||||
|             } | ||||
|         } | ||||
|  |  | |||
|  | @ -38,6 +38,7 @@ import com.bumptech.glide.request.target.CustomTarget | |||
| import com.bumptech.glide.request.transition.Transition | ||||
| import com.github.chrisbanes.photoview.PhotoView | ||||
| import com.keylesspalace.tusky.R | ||||
| import com.keylesspalace.tusky.util.parcelable | ||||
| 
 | ||||
| // https://github.com/tootsuite/mastodon/blob/c6904c0d3766a2ea8a81ab025c127169ecb51373/app/models/media_attachment.rb#L32 | ||||
| private const val MEDIA_DESCRIPTION_CHARACTER_LIMIT = 1500 | ||||
|  | @ -93,8 +94,7 @@ class CaptionDialog : DialogFragment() { | |||
|         val window = dialog.window | ||||
|         window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) | ||||
| 
 | ||||
|         val previewUri = | ||||
|             arguments?.getParcelable<Uri>(PREVIEW_URI_ARG) ?: error("Preview Uri is null") | ||||
|         val previewUri: Uri = arguments?.parcelable(PREVIEW_URI_ARG) ?: error("Preview Uri is null") | ||||
|         // Load the image and manually set it into the ImageView because it doesn't have a fixed size. | ||||
|         Glide.with(this) | ||||
|             .load(previewUri) | ||||
|  |  | |||
|  | @ -23,6 +23,7 @@ import com.keylesspalace.tusky.R | |||
| import com.keylesspalace.tusky.databinding.ActivityLoginWebviewBinding | ||||
| import com.keylesspalace.tusky.di.Injectable | ||||
| import com.keylesspalace.tusky.util.hide | ||||
| import com.keylesspalace.tusky.util.parcelableExtra | ||||
| import com.keylesspalace.tusky.util.viewBinding | ||||
| import kotlinx.parcelize.Parcelize | ||||
| 
 | ||||
|  | @ -39,7 +40,7 @@ class OauthLogin : ActivityResultContract<LoginData, LoginResult>() { | |||
|         return if (resultCode == Activity.RESULT_CANCELED) { | ||||
|             LoginResult.Cancel | ||||
|         } else { | ||||
|             intent!!.getParcelableExtra(RESULT_EXTRA)!! | ||||
|             intent!!.parcelableExtra(RESULT_EXTRA)!! | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -48,7 +49,7 @@ class OauthLogin : ActivityResultContract<LoginData, LoginResult>() { | |||
|         private const val DATA_EXTRA = "data" | ||||
| 
 | ||||
|         fun parseData(intent: Intent): LoginData { | ||||
|             return intent.getParcelableExtra(DATA_EXTRA)!! | ||||
|             return intent.parcelableExtra(DATA_EXTRA)!! | ||||
|         } | ||||
| 
 | ||||
|         fun makeResultIntent(result: LoginResult): Intent { | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ import android.content.Intent | |||
| import android.content.SharedPreferences | ||||
| import android.os.Bundle | ||||
| import android.util.Log | ||||
| import androidx.activity.OnBackPressedCallback | ||||
| import androidx.fragment.app.Fragment | ||||
| import androidx.fragment.app.commit | ||||
| import androidx.preference.PreferenceManager | ||||
|  | @ -47,7 +48,17 @@ class PreferencesActivity : | |||
|     @Inject | ||||
|     lateinit var androidInjector: DispatchingAndroidInjector<Any> | ||||
| 
 | ||||
|     private var restartActivitiesOnExit: Boolean = false | ||||
|     private val restartActivitiesOnBackPressedCallback = object : OnBackPressedCallback(false) { | ||||
|         override fun handleOnBackPressed() { | ||||
|             /* Switching themes won't actually change the theme of activities on the back stack. | ||||
|              * Either the back stack activities need to all be recreated, or do the easier thing, which | ||||
|              * is hijack the back button press and use it to launch a new MainActivity and clear the | ||||
|              * back stack. */ | ||||
|             val intent = Intent(this@PreferencesActivity, MainActivity::class.java) | ||||
|             intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK | ||||
|             startActivityWithSlideInAnimation(intent) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     override fun onCreate(savedInstanceState: Bundle?) { | ||||
|         super.onCreate(savedInstanceState) | ||||
|  | @ -92,7 +103,8 @@ class PreferencesActivity : | |||
|             replace(R.id.fragment_container, fragment, fragmentTag) | ||||
|         } | ||||
| 
 | ||||
|         restartActivitiesOnExit = intent.getBooleanExtra("restart", false) | ||||
|         onBackPressedDispatcher.addCallback(this, restartActivitiesOnBackPressedCallback) | ||||
|         restartActivitiesOnBackPressedCallback.isEnabled = savedInstanceState?.getBoolean(EXTRA_RESTART_ON_BACK, false) ?: false | ||||
|     } | ||||
| 
 | ||||
|     override fun onResume() { | ||||
|  | @ -106,11 +118,11 @@ class PreferencesActivity : | |||
|     } | ||||
| 
 | ||||
|     private fun saveInstanceState(outState: Bundle) { | ||||
|         outState.putBoolean("restart", restartActivitiesOnExit) | ||||
|         outState.putBoolean(EXTRA_RESTART_ON_BACK, restartActivitiesOnBackPressedCallback.isEnabled) | ||||
|     } | ||||
| 
 | ||||
|     override fun onSaveInstanceState(outState: Bundle) { | ||||
|         outState.putBoolean("restart", restartActivitiesOnExit) | ||||
|         outState.putBoolean(EXTRA_RESTART_ON_BACK, restartActivitiesOnBackPressedCallback.isEnabled) | ||||
|         super.onSaveInstanceState(outState) | ||||
|     } | ||||
| 
 | ||||
|  | @ -121,16 +133,16 @@ class PreferencesActivity : | |||
|                 Log.d("activeTheme", theme) | ||||
|                 ThemeUtils.setAppNightMode(theme) | ||||
| 
 | ||||
|                 restartActivitiesOnExit = true | ||||
|                 restartActivitiesOnBackPressedCallback.isEnabled = true | ||||
|                 this.restartCurrentActivity() | ||||
|             } | ||||
|             "statusTextSize", "absoluteTimeView", "showBotOverlay", "animateGifAvatars", "useBlurhash", | ||||
|             "showSelfUsername", "showCardsInTimelines", "confirmReblogs", "confirmFavourites", | ||||
|             "enableSwipeForTabs", "mainNavPosition", PrefKeys.HIDE_TOP_TOOLBAR -> { | ||||
|                 restartActivitiesOnExit = true | ||||
|                 restartActivitiesOnBackPressedCallback.isEnabled = true | ||||
|             } | ||||
|             "language" -> { | ||||
|                 restartActivitiesOnExit = true | ||||
|                 restartActivitiesOnBackPressedCallback.isEnabled = true | ||||
|                 this.restartCurrentActivity() | ||||
|             } | ||||
|         } | ||||
|  | @ -148,20 +160,6 @@ class PreferencesActivity : | |||
|         overridePendingTransition(R.anim.fade_in, R.anim.fade_out) | ||||
|     } | ||||
| 
 | ||||
|     override fun onBackPressed() { | ||||
|         /* Switching themes won't actually change the theme of activities on the back stack. | ||||
|          * Either the back stack activities need to all be recreated, or do the easier thing, which | ||||
|          * is hijack the back button press and use it to launch a new MainActivity and clear the | ||||
|          * back stack. */ | ||||
|         if (restartActivitiesOnExit) { | ||||
|             val intent = Intent(this, MainActivity::class.java) | ||||
|             intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK | ||||
|             startActivityWithSlideInAnimation(intent) | ||||
|         } else { | ||||
|             super.onBackPressed() | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     override fun androidInjector() = androidInjector | ||||
| 
 | ||||
|     companion object { | ||||
|  | @ -172,6 +170,7 @@ class PreferencesActivity : | |||
|         const val TAB_FILTER_PREFERENCES = 3 | ||||
|         const val PROXY_PREFERENCES = 4 | ||||
|         private const val EXTRA_PREFERENCE_TYPE = "EXTRA_PREFERENCE_TYPE" | ||||
|         private const val EXTRA_RESTART_ON_BACK = "restart" | ||||
| 
 | ||||
|         @JvmStatic | ||||
|         fun newIntent(context: Context, preferenceType: Int): Intent { | ||||
|  |  | |||
|  | @ -383,7 +383,7 @@ class SearchStatusesFragment : SearchFragment<StatusViewData.Concrete>(), Status | |||
|         } != null | ||||
|     } | ||||
| 
 | ||||
|     private fun showOpenAsDialog(statusUrl: String, dialogTitle: CharSequence) { | ||||
|     private fun showOpenAsDialog(statusUrl: String, dialogTitle: CharSequence?) { | ||||
|         bottomSheetActivity?.showAccountChooserDialog( | ||||
|             dialogTitle, false, | ||||
|             object : AccountSelectionListener { | ||||
|  |  | |||
|  | @ -102,7 +102,7 @@ class ViewThreadFragment : SFragment(), OnRefreshListener, StatusActionListener, | |||
|     override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||||
| 
 | ||||
|         binding.toolbar.setNavigationOnClickListener { | ||||
|             activity?.onBackPressed() | ||||
|             activity?.onBackPressedDispatcher?.onBackPressed() | ||||
|         } | ||||
|         binding.toolbar.setOnMenuItemClickListener { menuItem -> | ||||
|             when (menuItem.itemId) { | ||||
|  |  | |||
|  | @ -49,6 +49,7 @@ import com.keylesspalace.tusky.network.MastodonApi | |||
| import com.keylesspalace.tusky.settings.PrefKeys | ||||
| import com.keylesspalace.tusky.util.HttpHeaderLink | ||||
| import com.keylesspalace.tusky.util.hide | ||||
| import com.keylesspalace.tusky.util.requireSerializable | ||||
| import com.keylesspalace.tusky.util.show | ||||
| import com.keylesspalace.tusky.util.viewBinding | ||||
| import com.keylesspalace.tusky.view.EndlessOnScrollListener | ||||
|  | @ -78,8 +79,8 @@ class AccountListFragment : Fragment(R.layout.fragment_account_list), AccountAct | |||
| 
 | ||||
|     override fun onCreate(savedInstanceState: Bundle?) { | ||||
|         super.onCreate(savedInstanceState) | ||||
|         type = arguments?.getSerializable(ARG_TYPE) as Type | ||||
|         id = arguments?.getString(ARG_ID) | ||||
|         type = requireArguments().requireSerializable(ARG_TYPE) | ||||
|         id = requireArguments().getString(ARG_ID) | ||||
|     } | ||||
| 
 | ||||
|     override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||||
|  | @ -100,7 +101,7 @@ class AccountListFragment : Fragment(R.layout.fragment_account_list), AccountAct | |||
|             Type.BLOCKS -> BlocksAdapter(this, animateAvatar, animateEmojis) | ||||
|             Type.MUTES -> MutesAdapter(this, animateAvatar, animateEmojis) | ||||
|             Type.FOLLOW_REQUESTS -> { | ||||
|                 val headerAdapter = FollowRequestsHeaderAdapter(accountManager.activeAccount!!.domain, arguments?.get(ARG_ACCOUNT_LOCKED) == true) | ||||
|                 val headerAdapter = FollowRequestsHeaderAdapter(accountManager.activeAccount!!.domain, arguments?.getBoolean(ARG_ACCOUNT_LOCKED) == true) | ||||
|                 val followRequestsAdapter = FollowRequestsAdapter(this, animateAvatar, animateEmojis) | ||||
|                 binding.recyclerView.adapter = ConcatAdapter(headerAdapter, followRequestsAdapter) | ||||
|                 followRequestsAdapter | ||||
|  |  | |||
|  | @ -36,6 +36,7 @@ import com.keylesspalace.tusky.ViewMediaActivity | |||
| import com.keylesspalace.tusky.databinding.FragmentViewImageBinding | ||||
| import com.keylesspalace.tusky.entity.Attachment | ||||
| import com.keylesspalace.tusky.util.hide | ||||
| import com.keylesspalace.tusky.util.parcelable | ||||
| import com.keylesspalace.tusky.util.visible | ||||
| import io.reactivex.rxjava3.subjects.BehaviorSubject | ||||
| import kotlin.math.abs | ||||
|  | @ -92,7 +93,7 @@ class ViewImageFragment : ViewMediaFragment() { | |||
|         super.onViewCreated(view, savedInstanceState) | ||||
| 
 | ||||
|         val arguments = this.requireArguments() | ||||
|         val attachment = arguments.getParcelable<Attachment>(ARG_ATTACHMENT) | ||||
|         val attachment: Attachment? = arguments.parcelable(ARG_ATTACHMENT) | ||||
|         this.shouldStartTransition = arguments.getBoolean(ARG_START_POSTPONED_TRANSITION) | ||||
|         val url: String? | ||||
|         var description: String? = null | ||||
|  |  | |||
|  | @ -31,6 +31,7 @@ import com.keylesspalace.tusky.ViewMediaActivity | |||
| import com.keylesspalace.tusky.databinding.FragmentViewVideoBinding | ||||
| import com.keylesspalace.tusky.entity.Attachment | ||||
| import com.keylesspalace.tusky.util.hide | ||||
| import com.keylesspalace.tusky.util.parcelable | ||||
| import com.keylesspalace.tusky.util.visible | ||||
| import com.keylesspalace.tusky.view.ExposedPlayPauseVideoView | ||||
| 
 | ||||
|  | @ -170,7 +171,7 @@ class ViewVideoFragment : ViewMediaFragment() { | |||
| 
 | ||||
|     override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||||
|         super.onViewCreated(view, savedInstanceState) | ||||
|         val attachment = arguments?.getParcelable<Attachment>(ARG_ATTACHMENT) | ||||
|         val attachment: Attachment? = requireArguments().parcelable(ARG_ATTACHMENT) | ||||
| 
 | ||||
|         if (attachment == null) { | ||||
|             throw IllegalArgumentException("attachment has to be set") | ||||
|  |  | |||
|  | @ -29,6 +29,7 @@ import com.keylesspalace.tusky.entity.Status | |||
| import com.keylesspalace.tusky.service.SendStatusService | ||||
| import com.keylesspalace.tusky.service.StatusToSend | ||||
| import com.keylesspalace.tusky.util.randomAlphanumericString | ||||
| import com.keylesspalace.tusky.util.requireSerializableExtra | ||||
| import dagger.android.AndroidInjection | ||||
| import javax.inject.Inject | ||||
| 
 | ||||
|  | @ -48,7 +49,7 @@ class SendStatusBroadcastReceiver : BroadcastReceiver() { | |||
|             val senderIdentifier = intent.getStringExtra(NotificationHelper.KEY_SENDER_ACCOUNT_IDENTIFIER) | ||||
|             val senderFullName = intent.getStringExtra(NotificationHelper.KEY_SENDER_ACCOUNT_FULL_NAME) | ||||
|             val citedStatusId = intent.getStringExtra(NotificationHelper.KEY_CITED_STATUS_ID) | ||||
|             val visibility = intent.getSerializableExtra(NotificationHelper.KEY_VISIBILITY) as Status.Visibility | ||||
|             val visibility: Status.Visibility = intent.requireSerializableExtra(NotificationHelper.KEY_VISIBILITY)!! | ||||
|             val spoiler = intent.getStringExtra(NotificationHelper.KEY_SPOILER) ?: "" | ||||
|             val mentions = intent.getStringArrayExtra(NotificationHelper.KEY_MENTIONS) ?: emptyArray() | ||||
| 
 | ||||
|  |  | |||
|  | @ -31,6 +31,7 @@ import com.keylesspalace.tusky.entity.NewPoll | |||
| import com.keylesspalace.tusky.entity.NewStatus | ||||
| import com.keylesspalace.tusky.entity.Status | ||||
| import com.keylesspalace.tusky.network.MastodonApi | ||||
| import com.keylesspalace.tusky.util.parcelableExtra | ||||
| import dagger.android.AndroidInjection | ||||
| import kotlinx.coroutines.CoroutineScope | ||||
| import kotlinx.coroutines.Dispatchers | ||||
|  | @ -72,7 +73,7 @@ class SendStatusService : Service(), Injectable { | |||
| 
 | ||||
|     override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { | ||||
|         if (intent.hasExtra(KEY_STATUS)) { | ||||
|             val statusToSend = intent.getParcelableExtra<StatusToSend>(KEY_STATUS) | ||||
|             val statusToSend: StatusToSend = intent.parcelableExtra(KEY_STATUS) | ||||
|                 ?: throw IllegalStateException("SendStatusService started without $KEY_STATUS extra") | ||||
| 
 | ||||
|             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||||
|  |  | |||
|  | @ -0,0 +1,49 @@ | |||
| @file:Suppress("DEPRECATION") | ||||
| 
 | ||||
| package com.keylesspalace.tusky.util | ||||
| 
 | ||||
| import android.content.Intent | ||||
| import android.os.Build | ||||
| import android.os.Bundle | ||||
| import android.os.Parcelable | ||||
| import java.io.Serializable | ||||
| 
 | ||||
| inline fun <reified T : Serializable> Intent.requireSerializableExtra(name: String?): T { | ||||
|     return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { | ||||
|         getSerializableExtra(name, T::class.java)!! | ||||
|     } else { | ||||
|         getSerializableExtra(name) as T | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| inline fun <reified T : Parcelable> Intent.parcelableArrayListExtra(name: String?): ArrayList<T>? { | ||||
|     return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { | ||||
|         getParcelableArrayListExtra(name, T::class.java) | ||||
|     } else { | ||||
|         getParcelableArrayListExtra(name) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| inline fun <reified T : Parcelable> Bundle.parcelable(name: String?): T? { | ||||
|     return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { | ||||
|         getParcelable(name, T::class.java) | ||||
|     } else { | ||||
|         getParcelable(name) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| inline fun <reified T : Parcelable> Intent.parcelableExtra(name: String?): T? { | ||||
|     return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { | ||||
|         getParcelableExtra(name, T::class.java) | ||||
|     } else { | ||||
|         getParcelableExtra(name) as T? | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| inline fun <reified T : Serializable> Bundle.requireSerializable(name: String?): T { | ||||
|     return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { | ||||
|         getSerializable(name, T::class.java)!! | ||||
|     } else { | ||||
|         getSerializable(name) as T | ||||
|     } | ||||
| } | ||||
|  | @ -464,7 +464,7 @@ class ComposeActivityTest { | |||
|     } | ||||
| 
 | ||||
|     private fun clickBack() { | ||||
|         activity.onBackPressed() | ||||
|         activity.onBackPressedDispatcher.onBackPressed() | ||||
|     } | ||||
| 
 | ||||
|     private fun insertSomeTextInContent(text: String? = null) { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue