diff --git a/CHANGELOG.md b/CHANGELOG.md index 575aa6a32..fc22a2b99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,20 +1,5 @@ # Wikimedia Commons for Android -## v6.0.2 - -### What's changed -* Addressed a bug that prevented the keyboard from appearing in various text fields, such as on the upload wizard -* Links in the "File usages" list are now clickable and will take you to the correct page. -* Titles for file usages are now clearer and easier to understand -* Bug fixes and stability improvements - -## v6.0.1 - -### What's changed -* The app now supports Android 15 with an improved user interface -* Enhanced Nearby with robust and more reliable labels -* Bug fixes and stability improvements - ## v5.6.1 ### What's changed diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 7a6a2bcf4..674a6473f 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -18,14 +18,14 @@ if (isRunningOnTravisAndIsNotPRBuild) { android { namespace = "fr.free.nrw.commons" - compileSdk = 35 + compileSdk = 34 defaultConfig { applicationId = "fr.free.nrw.commons" minSdk = 21 - targetSdk = 35 - versionCode = 1058 - versionName = "6.0.2" + targetSdk = 34 + versionCode = 1055 + versionName = "5.6.1" setProperty("archivesBaseName", "app-commons-v$versionName-" + getBranchName()) testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e8215bd90..d56a874b5 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -101,6 +101,7 @@ android:name=".upload.UploadActivity" android:configChanges="orientation|screenSize|keyboard" android:exported="true" + android:hardwareAccelerated="false" android:icon="@mipmap/ic_launcher" android:windowSoftInputMode="adjustResize"> diff --git a/app/src/main/java/fr/free/nrw/commons/AboutActivity.kt b/app/src/main/java/fr/free/nrw/commons/AboutActivity.kt index 865ad3ddb..ebbb4097a 100644 --- a/app/src/main/java/fr/free/nrw/commons/AboutActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/AboutActivity.kt @@ -19,7 +19,6 @@ import fr.free.nrw.commons.utils.ConfigUtils.getVersionNameWithSha import fr.free.nrw.commons.utils.DialogUtil.showAlertDialog import java.util.Collections import androidx.core.net.toUri -import fr.free.nrw.commons.utils.applyEdgeToEdgeTopInsets import fr.free.nrw.commons.utils.handleWebUrl import fr.free.nrw.commons.utils.setUnderlinedText @@ -48,7 +47,6 @@ class AboutActivity : BaseActivity() { */ binding = ActivityAboutBinding.inflate(layoutInflater) val view: View = binding!!.root - applyEdgeToEdgeTopInsets(binding!!.toolbarLayout) setContentView(view) setSupportActionBar(binding!!.toolbarBinding.toolbar) diff --git a/app/src/main/java/fr/free/nrw/commons/OkHttpConnectionFactory.kt b/app/src/main/java/fr/free/nrw/commons/OkHttpConnectionFactory.kt index 1c28d5fe4..d15c72f57 100644 --- a/app/src/main/java/fr/free/nrw/commons/OkHttpConnectionFactory.kt +++ b/app/src/main/java/fr/free/nrw/commons/OkHttpConnectionFactory.kt @@ -50,7 +50,7 @@ object OkHttpConnectionFactory { } } -class CommonHeaderRequestInterceptor : Interceptor { +private class CommonHeaderRequestInterceptor : Interceptor { @Throws(IOException::class) override fun intercept(chain: Interceptor.Chain): Response { val request = chain.request().newBuilder() diff --git a/app/src/main/java/fr/free/nrw/commons/WelcomeActivity.kt b/app/src/main/java/fr/free/nrw/commons/WelcomeActivity.kt index 0882ba117..439ed1e92 100644 --- a/app/src/main/java/fr/free/nrw/commons/WelcomeActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/WelcomeActivity.kt @@ -9,7 +9,6 @@ import fr.free.nrw.commons.databinding.ActivityWelcomeBinding import fr.free.nrw.commons.databinding.PopupForCopyrightBinding import fr.free.nrw.commons.quiz.QuizActivity import fr.free.nrw.commons.theme.BaseActivity -import fr.free.nrw.commons.utils.applyEdgeToEdgeAllInsets import fr.free.nrw.commons.utils.ConfigUtils.isBetaFlavour class WelcomeActivity : BaseActivity() { @@ -24,7 +23,6 @@ class WelcomeActivity : BaseActivity() { public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityWelcomeBinding.inflate(layoutInflater) - applyEdgeToEdgeAllInsets(binding!!.welcomePager.rootView) setContentView(binding!!.root) isQuiz = intent?.extras?.getBoolean("isQuiz", false) ?: false diff --git a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.kt b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.kt index 688f508ae..7a665197b 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.kt @@ -22,7 +22,6 @@ import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatDelegate import androidx.core.app.NavUtils import androidx.core.content.ContextCompat -import androidx.core.view.WindowCompat import fr.free.nrw.commons.BuildConfig import fr.free.nrw.commons.CommonsApplication import fr.free.nrw.commons.R @@ -33,13 +32,11 @@ import fr.free.nrw.commons.contributions.MainActivity import fr.free.nrw.commons.databinding.ActivityLoginBinding import fr.free.nrw.commons.di.ApplicationlessInjection import fr.free.nrw.commons.kvstore.JsonKvStore -import fr.free.nrw.commons.utils.applyEdgeToEdgeAllInsets import fr.free.nrw.commons.utils.AbstractTextWatcher import fr.free.nrw.commons.utils.ActivityUtils.startActivityWithFlags import fr.free.nrw.commons.utils.ConfigUtils.isBetaFlavour import fr.free.nrw.commons.utils.SystemThemeUtils import fr.free.nrw.commons.utils.ViewUtil.hideKeyboard -import fr.free.nrw.commons.utils.handleKeyboardInsets import fr.free.nrw.commons.utils.handleWebUrl import io.reactivex.disposables.CompositeDisposable import timber.log.Timber @@ -82,14 +79,7 @@ class LoginActivity : AccountAuthenticatorActivity() { delegate.installViewFactory() delegate.onCreate(savedInstanceState) - WindowCompat.getInsetsController(window, window.decorView) - .isAppearanceLightStatusBars = !isDarkTheme - - WindowCompat.setDecorFitsSystemWindows(window, false) - binding = ActivityLoginBinding.inflate(layoutInflater) - applyEdgeToEdgeAllInsets(binding!!.root) - binding?.aboutPrivacyPolicy?.handleKeyboardInsets() with(binding!!) { setContentView(root) diff --git a/app/src/main/java/fr/free/nrw/commons/auth/SignupActivity.kt b/app/src/main/java/fr/free/nrw/commons/auth/SignupActivity.kt index 22f557bcd..5b48ecd8f 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/SignupActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/auth/SignupActivity.kt @@ -10,7 +10,6 @@ import android.widget.Toast import fr.free.nrw.commons.BuildConfig import fr.free.nrw.commons.R import fr.free.nrw.commons.theme.BaseActivity -import fr.free.nrw.commons.utils.applyEdgeToEdgeAllInsets import timber.log.Timber class SignupActivity : BaseActivity() { @@ -22,7 +21,6 @@ class SignupActivity : BaseActivity() { Timber.d("Signup Activity started") webView = WebView(this) - applyEdgeToEdgeAllInsets(webView!!) with(webView!!) { setContentView(this) webViewClient = MyWebViewClient() diff --git a/app/src/main/java/fr/free/nrw/commons/bookmarks/items/BookmarkItemsContentProvider.kt b/app/src/main/java/fr/free/nrw/commons/bookmarks/items/BookmarkItemsContentProvider.kt index c532ed3cc..8007ba208 100644 --- a/app/src/main/java/fr/free/nrw/commons/bookmarks/items/BookmarkItemsContentProvider.kt +++ b/app/src/main/java/fr/free/nrw/commons/bookmarks/items/BookmarkItemsContentProvider.kt @@ -36,7 +36,7 @@ class BookmarkItemsContentProvider : CommonsDaggerContentProvider() { requireDb(), projection, selection, selectionArgs, null, null, sortOrder ).apply { - setNotificationUri(context?.contentResolver, uri) + setNotificationUri(requireContext().contentResolver, uri) } } @@ -66,7 +66,7 @@ class BookmarkItemsContentProvider : CommonsDaggerContentProvider() { ) } - context?.contentResolver?.notifyChange(uri, null) + requireContext().contentResolver.notifyChange(uri, null) return rowsUpdated } @@ -75,7 +75,7 @@ class BookmarkItemsContentProvider : CommonsDaggerContentProvider() { */ override fun insert(uri: Uri, contentValues: ContentValues?): Uri? { val id = requireDb().insert(TABLE_NAME, null, contentValues) - context?.contentResolver?.notifyChange(uri, null) + requireContext().contentResolver.notifyChange(uri, null) return "$BASE_URI/$id".toUri() } @@ -89,7 +89,7 @@ class BookmarkItemsContentProvider : CommonsDaggerContentProvider() { "$COLUMN_ID = ?", arrayOf(uri.lastPathSegment) ) - context?.contentResolver?.notifyChange(uri, null) + requireContext().contentResolver.notifyChange(uri, null) return rows } diff --git a/app/src/main/java/fr/free/nrw/commons/bookmarks/pictures/BookmarkPicturesContentProvider.kt b/app/src/main/java/fr/free/nrw/commons/bookmarks/pictures/BookmarkPicturesContentProvider.kt index a47eed8ca..bf6f6039b 100644 --- a/app/src/main/java/fr/free/nrw/commons/bookmarks/pictures/BookmarkPicturesContentProvider.kt +++ b/app/src/main/java/fr/free/nrw/commons/bookmarks/pictures/BookmarkPicturesContentProvider.kt @@ -36,7 +36,7 @@ class BookmarkPicturesContentProvider : CommonsDaggerContentProvider() { requireDb(), projection, selection, selectionArgs, null, null, sortOrder ) - cursor.setNotificationUri(context?.contentResolver, uri) + cursor.setNotificationUri(requireContext().contentResolver, uri) return cursor } @@ -66,7 +66,7 @@ class BookmarkPicturesContentProvider : CommonsDaggerContentProvider() { "Parameter `selection` should be empty when updating an ID" ) } - context?.contentResolver?.notifyChange(uri, null) + requireContext().contentResolver.notifyChange(uri, null) return rowsUpdated } @@ -75,7 +75,7 @@ class BookmarkPicturesContentProvider : CommonsDaggerContentProvider() { */ override fun insert(uri: Uri, contentValues: ContentValues?): Uri { val id = requireDb().insert(TABLE_NAME, null, contentValues) - context?.contentResolver?.notifyChange(uri, null) + requireContext().contentResolver.notifyChange(uri, null) return "$BASE_URI/$id".toUri() } @@ -85,7 +85,7 @@ class BookmarkPicturesContentProvider : CommonsDaggerContentProvider() { "media_name = ?", arrayOf(uri.lastPathSegment) ) - context?.contentResolver?.notifyChange(uri, null) + requireContext().contentResolver.notifyChange(uri, null) return rows } diff --git a/app/src/main/java/fr/free/nrw/commons/category/CategoryDetailsActivity.kt b/app/src/main/java/fr/free/nrw/commons/category/CategoryDetailsActivity.kt index fefe462a9..c998f96ac 100644 --- a/app/src/main/java/fr/free/nrw/commons/category/CategoryDetailsActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/category/CategoryDetailsActivity.kt @@ -23,7 +23,6 @@ import fr.free.nrw.commons.explore.categories.sub.SubCategoriesFragment import fr.free.nrw.commons.media.MediaDetailPagerFragment import fr.free.nrw.commons.media.MediaDetailProvider import fr.free.nrw.commons.theme.BaseActivity -import fr.free.nrw.commons.utils.applyEdgeToEdgeAllInsets import fr.free.nrw.commons.utils.handleWebUrl import fr.free.nrw.commons.wikidata.model.WikiSite import fr.free.nrw.commons.wikidata.model.page.PageTitle @@ -58,7 +57,6 @@ class CategoryDetailsActivity : BaseActivity(), binding = ActivityCategoryDetailsBinding.inflate(layoutInflater) val view = binding.root - applyEdgeToEdgeAllInsets(view) setContentView(view) supportFragmentManager = getSupportFragmentManager() viewPagerAdapter = ViewPagerAdapter(this, supportFragmentManager) diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/MainActivity.kt b/app/src/main/java/fr/free/nrw/commons/contributions/MainActivity.kt index 5c2c44ab5..b9fa3e395 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/MainActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/contributions/MainActivity.kt @@ -34,7 +34,6 @@ import fr.free.nrw.commons.quiz.QuizChecker import fr.free.nrw.commons.settings.SettingsFragment import fr.free.nrw.commons.startWelcome import fr.free.nrw.commons.theme.BaseActivity -import fr.free.nrw.commons.utils.applyEdgeToEdgeAllInsets import fr.free.nrw.commons.upload.UploadProgressActivity import fr.free.nrw.commons.upload.worker.WorkRequestHelper.Companion.makeOneTimeWorkRequest import fr.free.nrw.commons.utils.ViewUtilWrapper @@ -113,7 +112,6 @@ class MainActivity : BaseActivity(), FragmentManager.OnBackStackChangedListener public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = MainBinding.inflate(layoutInflater) - applyEdgeToEdgeAllInsets(binding!!.root) setContentView(binding!!.root) setSupportActionBar(binding!!.toolbarBinding.toolbar) tabLayout = binding!!.fragmentMainNavTabLayout diff --git a/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/CustomSelectorActivity.kt b/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/CustomSelectorActivity.kt index 2534b4aeb..7e7d7e4cd 100644 --- a/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/CustomSelectorActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/CustomSelectorActivity.kt @@ -40,7 +40,6 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.content.ContextCompat -import androidx.core.view.ViewGroupCompat import androidx.lifecycle.ViewModelProvider import fr.free.nrw.commons.R import fr.free.nrw.commons.customselector.database.NotForUploadStatus @@ -57,8 +56,6 @@ import fr.free.nrw.commons.media.ZoomableActivity import fr.free.nrw.commons.theme.BaseActivity import fr.free.nrw.commons.upload.FileUtilsWrapper import fr.free.nrw.commons.utils.CustomSelectorUtils -import fr.free.nrw.commons.utils.applyEdgeToEdgeBottomPaddingInsets -import fr.free.nrw.commons.utils.applyEdgeToEdgeTopInsets import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -201,9 +198,6 @@ class CustomSelectorActivity : .fillMaxWidth(), ) } - ViewGroupCompat.installCompatInsetsDispatch(binding.root) - applyEdgeToEdgeTopInsets(toolbarBinding.toolbarLayout) - bottomSheetBinding.bottomLayout.applyEdgeToEdgeBottomPaddingInsets() val view = binding.root setContentView(view) diff --git a/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/FolderFragment.kt b/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/FolderFragment.kt index 0c3c5bdd0..6ca2b06e4 100644 --- a/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/FolderFragment.kt +++ b/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/FolderFragment.kt @@ -18,7 +18,6 @@ import fr.free.nrw.commons.databinding.FragmentCustomSelectorBinding import fr.free.nrw.commons.di.CommonsDaggerSupportFragment import fr.free.nrw.commons.media.MediaClient import fr.free.nrw.commons.upload.FileProcessor -import fr.free.nrw.commons.utils.applyEdgeToEdgeBottomPaddingInsets import javax.inject.Inject /** @@ -100,7 +99,6 @@ class FolderFragment : CommonsDaggerSupportFragment() { selectorRV = binding?.selectorRv loader = binding?.loader with(binding?.selectorRv) { - this?.applyEdgeToEdgeBottomPaddingInsets() this?.layoutManager = gridLayoutManager this?.setHasFixedSize(true) this?.adapter = folderAdapter diff --git a/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/ImageFragment.kt b/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/ImageFragment.kt index 4f37106cc..6e08e30f1 100644 --- a/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/ImageFragment.kt +++ b/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/ImageFragment.kt @@ -41,7 +41,6 @@ import fr.free.nrw.commons.media.MediaClient import fr.free.nrw.commons.theme.BaseActivity import fr.free.nrw.commons.upload.FileProcessor import fr.free.nrw.commons.upload.FileUtilsWrapper -import fr.free.nrw.commons.utils.applyEdgeToEdgeBottomPaddingInsets import io.reactivex.schedulers.Schedulers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow @@ -218,7 +217,6 @@ class ImageFragment : imageAdapter.setSingleSelection(singleSelection) gridLayoutManager = GridLayoutManager(context, getSpanCount()) with(binding?.selectorRv) { - this?.applyEdgeToEdgeBottomPaddingInsets() this?.layoutManager = gridLayoutManager this?.setHasFixedSize(true) this?.adapter = imageAdapter diff --git a/app/src/main/java/fr/free/nrw/commons/description/DescriptionEditActivity.kt b/app/src/main/java/fr/free/nrw/commons/description/DescriptionEditActivity.kt index 89d43845b..44cefe4d5 100644 --- a/app/src/main/java/fr/free/nrw/commons/description/DescriptionEditActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/description/DescriptionEditActivity.kt @@ -7,7 +7,6 @@ import android.speech.RecognizerIntent import android.view.View import androidx.activity.result.ActivityResult import androidx.activity.result.contract.ActivityResultContracts -import androidx.core.view.WindowCompat import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import fr.free.nrw.commons.CommonsApplication @@ -21,11 +20,9 @@ import fr.free.nrw.commons.description.EditDescriptionConstants.WIKITEXT import fr.free.nrw.commons.recentlanguages.RecentLanguagesDao import fr.free.nrw.commons.settings.Prefs import fr.free.nrw.commons.theme.BaseActivity -import fr.free.nrw.commons.utils.applyEdgeToEdgeBottomInsets import fr.free.nrw.commons.upload.UploadMediaDetail import fr.free.nrw.commons.upload.UploadMediaDetailAdapter import fr.free.nrw.commons.utils.DialogUtil.showAlertDialog -import fr.free.nrw.commons.utils.applyEdgeToEdgeTopPaddingInsets import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.functions.Consumer import io.reactivex.schedulers.Schedulers @@ -90,10 +87,6 @@ class DescriptionEditActivity : super.onCreate(savedInstanceState) binding = ActivityDescriptionEditBinding.inflate(layoutInflater) - applyEdgeToEdgeBottomInsets(binding.btnEditSubmit) - WindowCompat.getInsetsController(window, window.decorView) - .isAppearanceLightStatusBars = false - binding.toolbar.applyEdgeToEdgeTopPaddingInsets() setContentView(binding.root) val bundle = intent.extras diff --git a/app/src/main/java/fr/free/nrw/commons/di/NetworkingModule.kt b/app/src/main/java/fr/free/nrw/commons/di/NetworkingModule.kt index 9246ff303..2539db312 100644 --- a/app/src/main/java/fr/free/nrw/commons/di/NetworkingModule.kt +++ b/app/src/main/java/fr/free/nrw/commons/di/NetworkingModule.kt @@ -7,7 +7,6 @@ import dagger.Provides import fr.free.nrw.commons.BetaConstants import fr.free.nrw.commons.BuildConfig import fr.free.nrw.commons.OkHttpConnectionFactory -import fr.free.nrw.commons.CommonHeaderRequestInterceptor import fr.free.nrw.commons.actions.PageEditClient import fr.free.nrw.commons.actions.PageEditInterface import fr.free.nrw.commons.actions.ThanksInterface @@ -61,7 +60,6 @@ class NetworkingModule { .connectTimeout(120, TimeUnit.SECONDS) .writeTimeout(120, TimeUnit.SECONDS) .addInterceptor(httpLoggingInterceptor) - .addInterceptor(CommonHeaderRequestInterceptor()) .readTimeout(120, TimeUnit.SECONDS) .cache(Cache(File(context.cacheDir, "okHttpCache"), OK_HTTP_CACHE_SIZE)) .build() diff --git a/app/src/main/java/fr/free/nrw/commons/explore/SearchActivity.kt b/app/src/main/java/fr/free/nrw/commons/explore/SearchActivity.kt index 0d7dfd218..7b7bb2cd5 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/SearchActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/SearchActivity.kt @@ -22,7 +22,6 @@ import fr.free.nrw.commons.media.MediaDetailProvider import fr.free.nrw.commons.theme.BaseActivity import fr.free.nrw.commons.utils.FragmentUtils.isFragmentUIActive import fr.free.nrw.commons.utils.ViewUtil.hideKeyboard -import fr.free.nrw.commons.utils.applyEdgeToEdgeAllInsets import io.reactivex.android.schedulers.AndroidSchedulers import timber.log.Timber import java.util.Date @@ -49,7 +48,6 @@ class SearchActivity : BaseActivity(), MediaDetailProvider, CategoryImagesCallba override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivitySearchBinding.inflate(layoutInflater) - applyEdgeToEdgeAllInsets(binding!!.root) setContentView(binding!!.root) title = getString(R.string.title_activity_search) diff --git a/app/src/main/java/fr/free/nrw/commons/explore/depictions/WikidataItemDetailsActivity.kt b/app/src/main/java/fr/free/nrw/commons/explore/depictions/WikidataItemDetailsActivity.kt index 32af67e95..4696ae8d4 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/depictions/WikidataItemDetailsActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/depictions/WikidataItemDetailsActivity.kt @@ -24,7 +24,6 @@ import fr.free.nrw.commons.media.MediaDetailProvider import fr.free.nrw.commons.theme.BaseActivity import fr.free.nrw.commons.upload.structure.depictions.DepictModel import fr.free.nrw.commons.upload.structure.depictions.DepictedItem -import fr.free.nrw.commons.utils.applyEdgeToEdgeAllInsets import fr.free.nrw.commons.utils.handleWebUrl import fr.free.nrw.commons.wikidata.WikidataConstants import io.reactivex.android.schedulers.AndroidSchedulers @@ -56,7 +55,6 @@ class WikidataItemDetailsActivity : BaseActivity(), MediaDetailProvider, Categor super.onCreate(savedInstanceState) binding = ActivityWikidataItemDetailsBinding.inflate(layoutInflater) - applyEdgeToEdgeAllInsets(binding!!.root) setContentView(binding!!.root) supportFragmentManager = getSupportFragmentManager() viewPagerAdapter = ViewPagerAdapter(this, getSupportFragmentManager()) diff --git a/app/src/main/java/fr/free/nrw/commons/explore/recentsearches/RecentSearchesContentProvider.kt b/app/src/main/java/fr/free/nrw/commons/explore/recentsearches/RecentSearchesContentProvider.kt index c18f101ae..21f7a1a22 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/recentsearches/RecentSearchesContentProvider.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/recentsearches/RecentSearchesContentProvider.kt @@ -50,7 +50,7 @@ class RecentSearchesContentProvider : CommonsDaggerContentProvider() { else -> throw IllegalArgumentException("Unknown URI$uri") } - cursor.setNotificationUri(context?.contentResolver, uri) + cursor.setNotificationUri(requireContext().contentResolver, uri) return cursor } @@ -67,7 +67,7 @@ class RecentSearchesContentProvider : CommonsDaggerContentProvider() { else -> throw IllegalArgumentException("Unknown URI: $uri") } - context?.contentResolver?.notifyChange(uri, null) + requireContext().contentResolver.notifyChange(uri, null) return "$BASE_URI/$id".toUri() } @@ -88,7 +88,7 @@ class RecentSearchesContentProvider : CommonsDaggerContentProvider() { else -> throw IllegalArgumentException("Unknown URI - $uri") } - context?.contentResolver?.notifyChange(uri, null) + requireContext().contentResolver.notifyChange(uri, null) return rows } @@ -108,7 +108,7 @@ class RecentSearchesContentProvider : CommonsDaggerContentProvider() { } sqlDB.setTransactionSuccessful() sqlDB.endTransaction() - context?.contentResolver?.notifyChange(uri, null) + requireContext().contentResolver.notifyChange(uri, null) return values.size } @@ -147,7 +147,7 @@ class RecentSearchesContentProvider : CommonsDaggerContentProvider() { else -> throw IllegalArgumentException("Unknown URI: $uri with type $uriType") } - context?.contentResolver?.notifyChange(uri, null) + requireContext().contentResolver.notifyChange(uri, null) return rowsUpdated } diff --git a/app/src/main/java/fr/free/nrw/commons/filepicker/FilePicker.kt b/app/src/main/java/fr/free/nrw/commons/filepicker/FilePicker.kt index 5dc90d775..a7e3a671d 100644 --- a/app/src/main/java/fr/free/nrw/commons/filepicker/FilePicker.kt +++ b/app/src/main/java/fr/free/nrw/commons/filepicker/FilePicker.kt @@ -208,7 +208,6 @@ object FilePicker : Constants { @JvmStatic fun handleExternalImagesPicked(data: Intent?, activity: Activity): List { return try { - takePersistableUriPermissions(activity, data) getFilesFromGalleryPictures(data, activity) } catch (e: IOException) { e.printStackTrace() @@ -274,7 +273,7 @@ object FilePicker : Constants { callbacks: Callbacks ) { if (result.resultCode == Activity.RESULT_OK && !isPhoto(result.data)) { - takePersistableUriPermissions(activity, result.data) + takePersistableUriPermissions(activity, result) try { val files = getFilesFromGalleryPictures(result.data, activity) callbacks.onImagesPicked(files, ImageSource.DOCUMENTS, restoreType(activity)) @@ -296,8 +295,8 @@ object FilePicker : Constants { * This helps fix the SecurityException reported in this issue: * https://github.com/commons-app/apps-android-commons/issues/6357 */ - private fun takePersistableUriPermissions(context: Context, data: Intent?) { - data?.let { intentData -> + private fun takePersistableUriPermissions(context: Context, result: ActivityResult) { + result.data?.let { intentData -> val takeFlags: Int = (Intent.FLAG_GRANT_READ_URI_PERMISSION) // Persist the URI permission for all URIs in the clip data // if multiple images are selected, @@ -368,7 +367,7 @@ object FilePicker : Constants { callbacks: Callbacks ) { if (result.resultCode == Activity.RESULT_OK && !isPhoto(result.data)) { - takePersistableUriPermissions(activity, result.data) + takePersistableUriPermissions(activity, result) try { val files = getFilesFromGalleryPictures(result.data, activity) callbacks.onImagesPicked(files, ImageSource.GALLERY, restoreType(activity)) diff --git a/app/src/main/java/fr/free/nrw/commons/fileusages/FileUsagesUiModel.kt b/app/src/main/java/fr/free/nrw/commons/fileusages/FileUsagesUiModel.kt index 540c87e4c..63b0740d0 100644 --- a/app/src/main/java/fr/free/nrw/commons/fileusages/FileUsagesUiModel.kt +++ b/app/src/main/java/fr/free/nrw/commons/fileusages/FileUsagesUiModel.kt @@ -1,68 +1,18 @@ package fr.free.nrw.commons.fileusages -import android.net.Uri -import timber.log.Timber - /** - * Data model for displaying file usage information in the UI, including the title and link to the page. + * Show where file is being used on Commons and oher wikis. */ data class FileUsagesUiModel( val title: String, val link: String? ) -/** - * Converts a FileUsage object to a UI model for Commons file usages. - * Creates a link to the file's page on Commons. - */ fun FileUsage.toUiModel(): FileUsagesUiModel { - // Replace spaces with underscores and URL-encode the title for the link - val encodedTitle = Uri.encode(title.replace(" ", "_")) - return FileUsagesUiModel( - title = title, - link = "https://commons.wikimedia.org/wiki/$encodedTitle" - ) + return FileUsagesUiModel(title = title, link = "https://commons.wikimedia.org/wiki/$title") } -/** - * Converts a GlobalFileUsage object to a UI model for file usages on other wikis. - * Generates a link to the page and prefixes the title with the wiki code (e.g., "(en) Title"). - */ fun GlobalFileUsage.toUiModel(): FileUsagesUiModel { - // Log input values for debugging - Timber.d("Converting GlobalFileUsage: wiki=$wiki, title=$title") - - // Check for invalid or empty inputs - if (wiki.isBlank() || title.isBlank()) { - Timber.w("Invalid input: wiki=$wiki, title=$title") - return FileUsagesUiModel(title = title, link = null) - } - - // Extract wiki code for prefix (e.g., "en" from "en.wikipedia.org" or "enwiki") - val wikiCode = when { - wiki.contains(".") -> wiki.substringBefore(".") // e.g., "en" from "en.wikipedia.org" - wiki == "commonswiki" -> "commons" - wiki.endsWith("wiki") -> wiki.removeSuffix("wiki") - else -> wiki - } - - // Create prefixed title, e.g., "(en) Changi East Depot" - val prefixedTitle = "($wikiCode) $title" - - // Determine the domain for the URL - val domain = when { - wiki.contains(".") -> wiki // Already a full domain, e.g., "en.wikipedia.org" - wiki == "commonswiki" -> "commons.wikimedia.org" - wiki.endsWith("wiki") -> wiki.removeSuffix("wiki") + ".wikipedia.org" - else -> "$wiki.wikipedia.org" // Fallback for simple codes like "en" - } - - // Normalize title: replace spaces with underscores and URL-encode - val encodedTitle = Uri.encode(title.replace(" ", "_")) - - // Build the full URL - val url = "https://$domain/wiki/$encodedTitle" - Timber.d("Generated URL: $url") - - return FileUsagesUiModel(title = prefixedTitle, link = url) -} \ No newline at end of file + // link is associated with sub items under wiki group (which is not used ATM) + return FileUsagesUiModel(title = wiki, link = null) +} diff --git a/app/src/main/java/fr/free/nrw/commons/locationpicker/LocationPickerActivity.kt b/app/src/main/java/fr/free/nrw/commons/locationpicker/LocationPickerActivity.kt index e4fedf2e4..a8b6ddf26 100644 --- a/app/src/main/java/fr/free/nrw/commons/locationpicker/LocationPickerActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/locationpicker/LocationPickerActivity.kt @@ -25,7 +25,6 @@ import androidx.core.content.ContextCompat import androidx.core.content.IntentCompat import androidx.core.os.BundleCompat import androidx.core.text.HtmlCompat -import androidx.core.view.WindowCompat import com.google.android.material.floatingactionbutton.FloatingActionButton import fr.free.nrw.commons.CameraPosition import fr.free.nrw.commons.CommonsApplication @@ -45,8 +44,6 @@ import fr.free.nrw.commons.upload.mediaDetails.UploadMediaDetailFragment.Compani import fr.free.nrw.commons.upload.mediaDetails.UploadMediaDetailFragment.Companion.LAST_ZOOM import fr.free.nrw.commons.utils.DialogUtil import fr.free.nrw.commons.utils.MapUtils.ZOOM_LEVEL -import fr.free.nrw.commons.utils.applyEdgeToEdgeBottomInsets -import fr.free.nrw.commons.utils.applyEdgeToEdgeTopPaddingInsets import fr.free.nrw.commons.utils.handleGeoCoordinates import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.schedulers.Schedulers @@ -333,9 +330,6 @@ class LocationPickerActivity : BaseActivity(), LocationPermissionCallback { */ private fun getToolbarUI() { val toolbar: ConstraintLayout = findViewById(R.id.location_picker_toolbar) - WindowCompat.getInsetsController(window, window.decorView) - .isAppearanceLightStatusBars = false - toolbar.applyEdgeToEdgeTopPaddingInsets() largeToolbarText = findViewById(R.id.location_picker_toolbar_primary_text_view) smallToolbarText = findViewById(R.id.location_picker_toolbar_secondary_text_view) toolbar.setBackgroundColor(ContextCompat.getColor(this, R.color.primaryColor)) @@ -466,7 +460,6 @@ class LocationPickerActivity : BaseActivity(), LocationPermissionCallback { */ private fun addPlaceSelectedButton() { placeSelectedButton = findViewById(R.id.location_chosen_button) - applyEdgeToEdgeBottomInsets(placeSelectedButton) placeSelectedButton.setOnClickListener { placeSelected() } } diff --git a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.kt b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.kt index dc1e86137..d34c162dc 100644 --- a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.kt +++ b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.kt @@ -541,7 +541,6 @@ class MediaDetailFragment : CommonsDaggerSupportFragment(), CategoryEditHelper.C } ) binding.progressBarEdit.visibility = View.GONE - binding.descriptionEdit.visibility = View.VISIBLE } override fun onConfigurationChanged(newConfig: Configuration) { @@ -2129,17 +2128,22 @@ fun FileUsagesContainer( val uriHandle = LocalUriHandler.current Column(modifier = modifier) { + Row( modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween ) { + Text( text = stringResource(R.string.usages_on_commons_heading), textAlign = TextAlign.Center, style = MaterialTheme.typography.titleSmall ) - IconButton(onClick = { isCommonsListExpanded = !isCommonsListExpanded }) { + + IconButton(onClick = { + isCommonsListExpanded = !isCommonsListExpanded + }) { Icon( imageVector = if (isCommonsListExpanded) Icons.Default.KeyboardArrowUp else Icons.Default.KeyboardArrowDown, @@ -2153,8 +2157,11 @@ fun FileUsagesContainer( MediaDetailViewModel.FileUsagesContainerState.Loading -> { LinearProgressIndicator() } + is MediaDetailViewModel.FileUsagesContainerState.Success -> { + val data = commonsContainerState.data + if (data.isNullOrEmpty()) { ListItem(headlineContent = { Text( @@ -2174,7 +2181,7 @@ fun FileUsagesContainer( headlineContent = { Text( modifier = Modifier.clickable { - usage.link?.let { uriHandle.openUri(it) } + uriHandle.openUri(usage.link!!) }, text = usage.title, style = MaterialTheme.typography.titleSmall.copy( @@ -2182,11 +2189,11 @@ fun FileUsagesContainer( textDecoration = TextDecoration.Underline ) ) - } - ) + }) } } } + is MediaDetailViewModel.FileUsagesContainerState.Error -> { ListItem(headlineContent = { Text( @@ -2196,10 +2203,12 @@ fun FileUsagesContainer( ) }) } + MediaDetailViewModel.FileUsagesContainerState.Initial -> {} } } + Row( modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically, @@ -2210,7 +2219,10 @@ fun FileUsagesContainer( textAlign = TextAlign.Center, style = MaterialTheme.typography.titleSmall ) - IconButton(onClick = { isOtherWikisListExpanded = !isOtherWikisListExpanded }) { + + IconButton(onClick = { + isOtherWikisListExpanded = !isOtherWikisListExpanded + }) { Icon( imageVector = if (isOtherWikisListExpanded) Icons.Default.KeyboardArrowUp else Icons.Default.KeyboardArrowDown, @@ -2224,8 +2236,11 @@ fun FileUsagesContainer( MediaDetailViewModel.FileUsagesContainerState.Loading -> { LinearProgressIndicator() } + is MediaDetailViewModel.FileUsagesContainerState.Success -> { + val data = globalContainerState.data + if (data.isNullOrEmpty()) { ListItem(headlineContent = { Text( @@ -2244,20 +2259,16 @@ fun FileUsagesContainer( }, headlineContent = { Text( - modifier = Modifier.clickable { - usage.link?.let { uriHandle.openUri(it) } - }, text = usage.title, style = MaterialTheme.typography.titleSmall.copy( - color = Color(0xFF5A6AEC), textDecoration = TextDecoration.Underline ) ) - } - ) + }) } } } + is MediaDetailViewModel.FileUsagesContainerState.Error -> { ListItem(headlineContent = { Text( @@ -2267,8 +2278,10 @@ fun FileUsagesContainer( ) }) } + MediaDetailViewModel.FileUsagesContainerState.Initial -> {} } } + } -} \ No newline at end of file +} diff --git a/app/src/main/java/fr/free/nrw/commons/notification/NotificationActivity.kt b/app/src/main/java/fr/free/nrw/commons/notification/NotificationActivity.kt index 4a43bf470..76975964b 100644 --- a/app/src/main/java/fr/free/nrw/commons/notification/NotificationActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/notification/NotificationActivity.kt @@ -8,7 +8,6 @@ import android.os.Bundle import android.view.Menu import android.view.MenuItem import android.view.View -import androidx.core.view.ViewGroupCompat import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.material.snackbar.Snackbar @@ -20,10 +19,8 @@ import fr.free.nrw.commons.databinding.ActivityNotificationBinding import fr.free.nrw.commons.notification.models.Notification import fr.free.nrw.commons.notification.models.NotificationType import fr.free.nrw.commons.theme.BaseActivity -import fr.free.nrw.commons.utils.applyEdgeToEdgeTopInsets import fr.free.nrw.commons.utils.NetworkUtils import fr.free.nrw.commons.utils.ViewUtil -import fr.free.nrw.commons.utils.applyEdgeToEdgeBottomPaddingInsets import fr.free.nrw.commons.utils.handleWebUrl import io.reactivex.Observable import io.reactivex.android.schedulers.AndroidSchedulers @@ -59,9 +56,6 @@ class NotificationActivity : BaseActivity() { super.onCreate(savedInstanceState) isRead = intent.getStringExtra("title") == "read" binding = ActivityNotificationBinding.inflate(layoutInflater) - ViewGroupCompat.installCompatInsetsDispatch(binding.root) - applyEdgeToEdgeTopInsets(binding.toolbar.toolbar) - binding.listView.applyEdgeToEdgeBottomPaddingInsets() setContentView(binding.root) mNotificationWorkerFragment = supportFragmentManager.findFragmentByTag( tagNotificationWorkerFragment diff --git a/app/src/main/java/fr/free/nrw/commons/profile/ProfileActivity.kt b/app/src/main/java/fr/free/nrw/commons/profile/ProfileActivity.kt index c368d6cd4..d80be9ea2 100644 --- a/app/src/main/java/fr/free/nrw/commons/profile/ProfileActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/profile/ProfileActivity.kt @@ -21,7 +21,6 @@ import fr.free.nrw.commons.databinding.ActivityProfileBinding import fr.free.nrw.commons.profile.achievements.AchievementsFragment import fr.free.nrw.commons.profile.leaderboard.LeaderboardFragment import fr.free.nrw.commons.theme.BaseActivity -import fr.free.nrw.commons.utils.applyEdgeToEdgeAllInsets import fr.free.nrw.commons.utils.DialogUtil import java.io.File import java.io.FileOutputStream @@ -62,7 +61,6 @@ class ProfileActivity : BaseActivity() { super.onCreate(savedInstanceState) binding = ActivityProfileBinding.inflate(layoutInflater) - applyEdgeToEdgeAllInsets(binding.root) setContentView(binding.root) setSupportActionBar(binding.toolbarBinding.toolbar) diff --git a/app/src/main/java/fr/free/nrw/commons/quiz/QuizActivity.kt b/app/src/main/java/fr/free/nrw/commons/quiz/QuizActivity.kt index 11fd1e6a6..e65b819e5 100644 --- a/app/src/main/java/fr/free/nrw/commons/quiz/QuizActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/quiz/QuizActivity.kt @@ -3,11 +3,9 @@ package fr.free.nrw.commons.quiz import android.annotation.SuppressLint import android.content.Intent import android.os.Bundle -import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity -import androidx.core.view.WindowCompat import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat import com.facebook.drawee.drawable.ProgressBarDrawable @@ -17,7 +15,6 @@ import fr.free.nrw.commons.databinding.ActivityQuizBinding import java.util.ArrayList import fr.free.nrw.commons.R -import fr.free.nrw.commons.utils.applyEdgeToEdgeAllInsets class QuizActivity : AppCompatActivity() { @@ -40,11 +37,7 @@ class QuizActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - enableEdgeToEdge() binding = ActivityQuizBinding.inflate(layoutInflater) - applyEdgeToEdgeAllInsets(binding.root) - WindowCompat.getInsetsController(window, window.decorView) - .isAppearanceLightStatusBars = true setContentView(binding.root) quizController.initialize(this) diff --git a/app/src/main/java/fr/free/nrw/commons/quiz/QuizResultActivity.kt b/app/src/main/java/fr/free/nrw/commons/quiz/QuizResultActivity.kt index 6979edd15..81372b4a6 100644 --- a/app/src/main/java/fr/free/nrw/commons/quiz/QuizResultActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/quiz/QuizResultActivity.kt @@ -12,11 +12,9 @@ import android.view.MenuItem import android.view.View import android.widget.ImageView import android.widget.TextView -import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity -import androidx.core.view.WindowCompat import fr.free.nrw.commons.databinding.ActivityQuizResultBinding import java.io.File @@ -24,7 +22,6 @@ import java.io.FileOutputStream import fr.free.nrw.commons.R import fr.free.nrw.commons.contributions.MainActivity -import fr.free.nrw.commons.utils.applyEdgeToEdgeAllInsets /** @@ -38,11 +35,7 @@ class QuizResultActivity : AppCompatActivity() { public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - enableEdgeToEdge() binding = ActivityQuizResultBinding.inflate(layoutInflater) - applyEdgeToEdgeAllInsets(binding!!.root) - WindowCompat.getInsetsController(window, window.decorView) - .isAppearanceLightStatusBars = true setContentView(binding?.root) setSupportActionBar(binding?.toolbar?.toolbar) diff --git a/app/src/main/java/fr/free/nrw/commons/recentlanguages/RecentLanguagesContentProvider.kt b/app/src/main/java/fr/free/nrw/commons/recentlanguages/RecentLanguagesContentProvider.kt index 80128ba73..04c18fbb7 100644 --- a/app/src/main/java/fr/free/nrw/commons/recentlanguages/RecentLanguagesContentProvider.kt +++ b/app/src/main/java/fr/free/nrw/commons/recentlanguages/RecentLanguagesContentProvider.kt @@ -59,7 +59,7 @@ class RecentLanguagesContentProvider : CommonsDaggerContentProvider() { null, sortOrder ) - cursor.setNotificationUri(context?.contentResolver, uri) + cursor.setNotificationUri(requireContext().contentResolver, uri) return cursor } @@ -90,7 +90,7 @@ class RecentLanguagesContentProvider : CommonsDaggerContentProvider() { throw IllegalArgumentException("Parameter `selection` should be empty when updating an ID") } - context?.contentResolver?.notifyChange(uri, null) + requireContext().contentResolver?.notifyChange(uri, null) return rowsUpdated } @@ -105,7 +105,7 @@ class RecentLanguagesContentProvider : CommonsDaggerContentProvider() { null, contentValues ) - context?.contentResolver?.notifyChange(uri, null) + requireContext().contentResolver?.notifyChange(uri, null) return "$BASE_URI/$id".toUri() } @@ -119,7 +119,7 @@ class RecentLanguagesContentProvider : CommonsDaggerContentProvider() { "language_code = ?", arrayOf(uri.lastPathSegment) ) - context?.contentResolver?.notifyChange(uri, null) + requireContext().contentResolver?.notifyChange(uri, null) return rows } } diff --git a/app/src/main/java/fr/free/nrw/commons/review/ReviewActivity.kt b/app/src/main/java/fr/free/nrw/commons/review/ReviewActivity.kt index 1d26eacae..20f289f8f 100644 --- a/app/src/main/java/fr/free/nrw/commons/review/ReviewActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/review/ReviewActivity.kt @@ -16,7 +16,6 @@ import fr.free.nrw.commons.databinding.ActivityReviewBinding import fr.free.nrw.commons.delete.DeleteHelper import fr.free.nrw.commons.media.MediaDetailFragment import fr.free.nrw.commons.theme.BaseActivity -import fr.free.nrw.commons.utils.applyEdgeToEdgeAllInsets import fr.free.nrw.commons.utils.DialogUtil import fr.free.nrw.commons.utils.ViewUtil import io.reactivex.android.schedulers.AndroidSchedulers @@ -74,7 +73,6 @@ class ReviewActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityReviewBinding.inflate(layoutInflater) - applyEdgeToEdgeAllInsets(binding.root) setContentView(binding.root) setSupportActionBar(binding.toolbarBinding?.toolbar) @@ -109,8 +107,10 @@ class ReviewActivity : BaseActivity() { setUpMediaDetailFragment() } - binding.skipImageInfo?.setOnTouchListener { _, event -> - if (event.action == MotionEvent.ACTION_UP) { + binding.skipImage.setOnTouchListener { _, event -> + if (event.action == MotionEvent.ACTION_UP && + event.rawX >= (binding.skipImage.right - binding.skipImage.compoundDrawables[2].bounds.width()) + ) { showSkipImageInfo() true } else { diff --git a/app/src/main/java/fr/free/nrw/commons/settings/SettingsActivity.kt b/app/src/main/java/fr/free/nrw/commons/settings/SettingsActivity.kt index 233e688f4..91c88d7b0 100644 --- a/app/src/main/java/fr/free/nrw/commons/settings/SettingsActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/settings/SettingsActivity.kt @@ -4,7 +4,6 @@ import android.os.Bundle import android.view.MenuItem import fr.free.nrw.commons.databinding.ActivitySettingsBinding import fr.free.nrw.commons.theme.BaseActivity -import fr.free.nrw.commons.utils.applyEdgeToEdgeAllInsets /** @@ -22,7 +21,6 @@ class SettingsActivity : BaseActivity() { super.onCreate(savedInstanceState) binding = ActivitySettingsBinding.inflate(layoutInflater) val view = binding.root - applyEdgeToEdgeAllInsets(view) setContentView(view) setSupportActionBar(binding.toolbarBinding.toolbar) diff --git a/app/src/main/java/fr/free/nrw/commons/theme/BaseActivity.kt b/app/src/main/java/fr/free/nrw/commons/theme/BaseActivity.kt index d317a7d35..d2d936460 100644 --- a/app/src/main/java/fr/free/nrw/commons/theme/BaseActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/theme/BaseActivity.kt @@ -4,7 +4,6 @@ import android.content.res.Configuration import android.os.Bundle import android.util.DisplayMetrics import android.view.WindowManager -import androidx.activity.enableEdgeToEdge import javax.inject.Inject import javax.inject.Named import fr.free.nrw.commons.R @@ -37,7 +36,6 @@ abstract class BaseActivity : CommonsDaggerAppCompatActivity() { 1f ) adjustFontScale(resources.configuration, fontScale) - enableEdgeToEdge() } override fun onResume() { diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt b/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt index c2bed5fff..38e7dace8 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt @@ -13,7 +13,6 @@ import android.os.Build.VERSION_CODES import android.os.Bundle import android.provider.Settings import android.view.View -import android.view.inputmethod.InputMethodManager import android.widget.CheckBox import androidx.activity.OnBackPressedCallback import androidx.appcompat.app.AlertDialog @@ -39,7 +38,6 @@ import fr.free.nrw.commons.mwapi.UserClient import fr.free.nrw.commons.nearby.Place import fr.free.nrw.commons.settings.Prefs import fr.free.nrw.commons.theme.BaseActivity -import fr.free.nrw.commons.utils.applyEdgeToEdgeAllInsets import fr.free.nrw.commons.upload.ThumbnailsAdapter.OnThumbnailDeletedListener import fr.free.nrw.commons.upload.categories.UploadCategoriesFragment import fr.free.nrw.commons.upload.depicts.DepictsFragment @@ -179,7 +177,6 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C presenter?.setupBasicKvStoreFactory { BasicKvStore(this@UploadActivity, it) } _binding = ActivityUploadBinding.inflate(layoutInflater) - applyEdgeToEdgeAllInsets(_binding!!.root, false) setContentView(binding.root) // Overrides the back button to make sure the user is prepared to lose their progress @@ -806,19 +803,6 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C override fun onNextButtonClicked(index: Int) { if (index < fragments!!.size - 1) { - // Hide the keyboard before navigating to Media License screen - val isUploadCategoriesFragment = fragments!!.getOrNull(index)?.let { - it is UploadCategoriesFragment - } ?: false - if (isUploadCategoriesFragment) { - val inputMethodManager = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager - currentFocus?.let { focusedView -> - inputMethodManager.hideSoftInputFromWindow( - focusedView.windowToken, - InputMethodManager.HIDE_NOT_ALWAYS - ) - } - } binding.vpUpload.setCurrentItem(index + 1, false) fragments!![index + 1].onBecameVisible() (binding.rvThumbnails.layoutManager as LinearLayoutManager) diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadProgressActivity.kt b/app/src/main/java/fr/free/nrw/commons/upload/UploadProgressActivity.kt index 665f106e2..3cf9d3a65 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/UploadProgressActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadProgressActivity.kt @@ -10,7 +10,6 @@ import fr.free.nrw.commons.ViewPagerAdapter import fr.free.nrw.commons.contributions.ContributionDao import fr.free.nrw.commons.databinding.ActivityUploadProgressBinding import fr.free.nrw.commons.theme.BaseActivity -import fr.free.nrw.commons.utils.applyEdgeToEdgeAllInsets import javax.inject.Inject /** @@ -36,7 +35,6 @@ class UploadProgressActivity : BaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityUploadProgressBinding.inflate(layoutInflater) - applyEdgeToEdgeAllInsets(binding.root) setContentView(binding.root) viewPagerAdapter = ViewPagerAdapter(this, supportFragmentManager) binding.uploadProgressViewPager.setAdapter(viewPagerAdapter) diff --git a/app/src/main/java/fr/free/nrw/commons/upload/categories/UploadCategoriesFragment.kt b/app/src/main/java/fr/free/nrw/commons/upload/categories/UploadCategoriesFragment.kt index 798ab74fe..262013045 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/categories/UploadCategoriesFragment.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/categories/UploadCategoriesFragment.kt @@ -26,7 +26,6 @@ import fr.free.nrw.commons.media.MediaDetailFragment import fr.free.nrw.commons.upload.UploadActivity import fr.free.nrw.commons.upload.UploadBaseFragment import fr.free.nrw.commons.utils.DialogUtil.showAlertDialog -import fr.free.nrw.commons.utils.handleKeyboardInsets import fr.free.nrw.commons.wikidata.WikidataConstants.SELECTED_NEARBY_PLACE_CATEGORY import io.reactivex.Notification import io.reactivex.android.schedulers.AndroidSchedulers @@ -70,7 +69,6 @@ class UploadCategoriesFragment : UploadBaseFragment(), CategoriesContract.View { savedInstanceState: Bundle? ): View? { binding = UploadCategoriesFragmentBinding.inflate(inflater, container, false) - binding!!.llContainerButtons.handleKeyboardInsets() return binding!!.root } diff --git a/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsFragment.kt b/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsFragment.kt index 484750410..39bcabb46 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsFragment.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsFragment.kt @@ -27,7 +27,6 @@ import fr.free.nrw.commons.upload.UploadActivity import fr.free.nrw.commons.upload.UploadBaseFragment import fr.free.nrw.commons.upload.structure.depictions.DepictedItem import fr.free.nrw.commons.utils.DialogUtil.showAlertDialog -import fr.free.nrw.commons.utils.handleKeyboardInsets import fr.free.nrw.commons.wikidata.WikidataConstants.SELECTED_NEARBY_PLACE import io.reactivex.Notification import io.reactivex.android.schedulers.AndroidSchedulers @@ -70,7 +69,6 @@ class DepictsFragment : UploadBaseFragment(), DepictsContract.View { savedInstanceState: Bundle? ): View { _binding = UploadDepictsFragmentBinding.inflate(inflater, container, false) - _binding!!.navigationButtonsContainer.handleKeyboardInsets() return binding.root } diff --git a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.kt b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.kt index 6ece53170..43a9c3236 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.kt @@ -50,7 +50,6 @@ import fr.free.nrw.commons.utils.ImageUtils.IMAGE_OK import fr.free.nrw.commons.utils.ImageUtils.getErrorMessageForResult import fr.free.nrw.commons.utils.NetworkUtils.isInternetConnectionEstablished import fr.free.nrw.commons.utils.ViewUtil.showLongToast -import fr.free.nrw.commons.utils.handleKeyboardInsets import timber.log.Timber import java.io.File import java.util.ArrayList @@ -154,7 +153,6 @@ class UploadMediaDetailFragment : UploadBaseFragment(), UploadMediaDetailsContra inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { _binding = FragmentUploadMediaDetailFragmentBinding.inflate(inflater, container, false) - _binding!!.mediaDetailCardView.handleKeyboardInsets() return binding.root } diff --git a/app/src/main/java/fr/free/nrw/commons/utils/ConfigUtils.kt b/app/src/main/java/fr/free/nrw/commons/utils/ConfigUtils.kt index 95fa62a20..332c8d023 100644 --- a/app/src/main/java/fr/free/nrw/commons/utils/ConfigUtils.kt +++ b/app/src/main/java/fr/free/nrw/commons/utils/ConfigUtils.kt @@ -12,9 +12,9 @@ object ConfigUtils { val isBetaFlavour: Boolean = BuildConfig.FLAVOR == "beta" @JvmStatic - private fun Context.getVersionName(): String? = + private fun Context.getVersionName(): String = try { - packageManager.getPackageInfo(packageName, 0).versionName ?: BuildConfig.VERSION_NAME + packageManager.getPackageInfo(packageName, 0).versionName } catch (e: PackageManager.NameNotFoundException) { BuildConfig.VERSION_NAME } diff --git a/app/src/main/java/fr/free/nrw/commons/utils/EdgeToEdgeUtils.kt b/app/src/main/java/fr/free/nrw/commons/utils/EdgeToEdgeUtils.kt deleted file mode 100644 index d0c2b12e8..000000000 --- a/app/src/main/java/fr/free/nrw/commons/utils/EdgeToEdgeUtils.kt +++ /dev/null @@ -1,229 +0,0 @@ -package fr.free.nrw.commons.utils - -import android.view.View -import android.view.ViewGroup.MarginLayoutParams -import androidx.core.view.ViewCompat -import androidx.core.view.WindowInsetsAnimationCompat -import androidx.core.view.WindowInsetsCompat -import androidx.core.view.marginBottom -import androidx.core.view.marginLeft -import androidx.core.view.marginRight -import androidx.core.view.marginTop -import androidx.core.view.updateLayoutParams -import androidx.core.view.updatePadding -import fr.free.nrw.commons.R - -/** - * Applies edge-to-edge system bar insets to a [View]’s margins using a custom adjustment block. - * - * Stores the initial margins to ensure inset calculations are additive, and applies the provided - * [block] with an [InsetsAccumulator] containing initial and system bar inset values. - * - * @param typeMask The type of window insets to apply. Defaults to [WindowInsetsCompat.Type.systemBars]. - * @param shouldConsumeInsets If `true`, the insets are consumed and not propagated to child views. - * @param block Lambda applied to update [MarginLayoutParams] using the accumulated insets. - */ -fun View.applyEdgeToEdgeInsets( - typeMask: Int = WindowInsetsCompat.Type.systemBars(), - shouldConsumeInsets: Boolean = true, - block: MarginLayoutParams.(InsetsAccumulator) -> Unit -) { - ViewCompat.setOnApplyWindowInsetsListener(this) { view, windowInsets -> - val insets = windowInsets.getInsets(typeMask) - - val initialTop = if (view.getTag(R.id.initial_margin_top) != null) { - view.getTag(R.id.initial_margin_top) as Int - } else { - view.setTag(R.id.initial_margin_top, view.marginTop) - view.marginTop - } - - val initialBottom = if (view.getTag(R.id.initial_margin_bottom) != null) { - view.getTag(R.id.initial_margin_bottom) as Int - } else { - view.setTag(R.id.initial_margin_bottom, view.marginBottom) - view.marginBottom - } - - val initialLeft = if (view.getTag(R.id.initial_margin_left) != null) { - view.getTag(R.id.initial_margin_left) as Int - } else { - view.setTag(R.id.initial_margin_left, view.marginLeft) - view.marginLeft - } - - val initialRight = if (view.getTag(R.id.initial_margin_right) != null) { - view.getTag(R.id.initial_margin_right) as Int - } else { - view.setTag(R.id.initial_margin_right, view.marginRight) - view.marginRight - } - - val accumulator = InsetsAccumulator( - initialTop, - insets.top, - initialBottom, - insets.bottom, - initialLeft, - insets.left, - initialRight, - insets.right - ) - - view.updateLayoutParams { - apply { block(accumulator) } - } - - if(shouldConsumeInsets) WindowInsetsCompat.CONSUMED else windowInsets - } -} - -/** - * Applies edge-to-edge system bar insets to the top padding of the view. - * - * @param typeMask The type of window insets to apply. Defaults to [WindowInsetsCompat.Type.systemBars]. - */ -fun View.applyEdgeToEdgeTopPaddingInsets( - typeMask: Int = WindowInsetsCompat.Type.systemBars(), -) { - ViewCompat.setOnApplyWindowInsetsListener(this) { view, windowInsets -> - val insets = windowInsets.getInsets(typeMask) - - view.updatePadding( - left = insets.left, - right = insets.right, - top = insets.top - ) - - WindowInsetsCompat.CONSUMED - } -} - -/** - * Applies edge-to-edge system bar insets to the bottom padding of the view. - * - * @param typeMask The type of window insets to apply. Defaults to [WindowInsetsCompat.Type.systemBars]. - */ -fun View.applyEdgeToEdgeBottomPaddingInsets( - typeMask: Int = WindowInsetsCompat.Type.systemBars(), -) { - ViewCompat.setOnApplyWindowInsetsListener(this) { view, windowInsets -> - val insets = windowInsets.getInsets(typeMask) - - view.updatePadding( - left = insets.left, - right = insets.right, - bottom = insets.bottom - ) - - WindowInsetsCompat.CONSUMED - } -} - -/** - * Applies system bar insets to all margins (top, bottom, left, right) of the view. - * - * @param view The target view. - * @param shouldConsumeInsets If `true`, the insets are consumed and not propagated to child views. - */ -fun applyEdgeToEdgeAllInsets( - view: View, - shouldConsumeInsets: Boolean = true -) = view.applyEdgeToEdgeInsets(shouldConsumeInsets = shouldConsumeInsets) { insets -> - leftMargin = insets.left - rightMargin = insets.right - topMargin = insets.top - bottomMargin = insets.bottom -} - -/** - * Applies system bar insets to the top and horizontal margins of the view. - * - * @param view The target view. - */ -fun applyEdgeToEdgeTopInsets(view: View) = view.applyEdgeToEdgeInsets { insets -> - leftMargin = insets.left - rightMargin = insets.right - topMargin = insets.top -} - -/** - * Applies system bar insets to the bottom and horizontal margins of the view. - * - * @param view The target view. - */ -fun applyEdgeToEdgeBottomInsets(view: View) = view.applyEdgeToEdgeInsets { insets -> - leftMargin = insets.left - rightMargin = insets.right - bottomMargin = insets.bottom -} - -/** - * Adjusts a [View]'s bottom margin dynamically to account for the on-screen keyboard (IME), - * ensuring the view remains visible above the keyboard during transitions. - * - * Preserves the initial margin, adjusts during IME visibility changes, - * and accounts for navigation bar insets to avoid double offsets. - */ -fun View.handleKeyboardInsets() { - var existingBottomMargin = 0 - - ViewCompat.setOnApplyWindowInsetsListener(this) { view, windowInsets -> - existingBottomMargin = if (view.getTag(R.id.initial_margin_bottom) != null) { - view.getTag(R.id.initial_margin_bottom) as Int - } else { - view.setTag(R.id.initial_margin_bottom, view.marginBottom) - view.marginBottom - } - - WindowInsetsCompat.CONSUMED - } - - // Animate during IME transition - ViewCompat.setWindowInsetsAnimationCallback( - this, - object : WindowInsetsAnimationCompat.Callback( - DISPATCH_MODE_CONTINUE_ON_SUBTREE - ) { - override fun onProgress( - insets: WindowInsetsCompat, - runningAnimations: MutableList - ): WindowInsetsCompat { - val lp = layoutParams as MarginLayoutParams - val navBarInsets = insets.getInsets(WindowInsetsCompat.Type.navigationBars()) - val imeInsets = insets.getInsets(WindowInsetsCompat.Type.ime()) - val imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime()) - - // Avoid extra space due to system nav bar when the keyboard is shown - val imeBottomMargin = imeInsets.bottom - navBarInsets.bottom - - lp.bottomMargin = if(imeVisible && imeBottomMargin >= existingBottomMargin) - imeBottomMargin + existingBottomMargin - else existingBottomMargin - - layoutParams = lp - return WindowInsetsCompat.CONSUMED - } - } - ) -} - -/** - * Holds both initial margin values and system bar insets, providing summed values - * for each side (top, bottom, left, right) to apply in layout updates. - */ -data class InsetsAccumulator( - private val initialTop: Int, - private val insetTop: Int, - private val initialBottom: Int, - private val insetBottom: Int, - private val initialLeft: Int, - private val insetLeft: Int, - private val initialRight: Int, - private val insetRight: Int -) { - val top = initialTop + insetTop - val bottom = initialBottom + insetBottom - val left = initialLeft + insetLeft - val right = initialRight + insetRight -} \ No newline at end of file diff --git a/app/src/main/java/fr/free/nrw/commons/utils/ImageUtils.kt b/app/src/main/java/fr/free/nrw/commons/utils/ImageUtils.kt index fa538bb21..ebff3d054 100644 --- a/app/src/main/java/fr/free/nrw/commons/utils/ImageUtils.kt +++ b/app/src/main/java/fr/free/nrw/commons/utils/ImageUtils.kt @@ -24,7 +24,6 @@ import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import io.reactivex.schedulers.Schedulers import timber.log.Timber -import androidx.core.graphics.createBitmap /** * Created by blueSir9 on 3/10/17. @@ -308,19 +307,16 @@ object ImageUtils { * * @return */ @JvmStatic - fun addRedBorder(bitmap: Bitmap, borderSize: Int, context: Context): Bitmap? { - return bitmap.config?.let { config -> - val bmpWithBorder = - createBitmap( - width = bitmap.width + borderSize * 2, - height = bitmap.height + borderSize * 2, - config = config - ) - val canvas = Canvas(bmpWithBorder) - canvas.drawColor(ContextCompat.getColor(context, R.color.deleteRed)) - canvas.drawBitmap(bitmap, borderSize.toFloat(), borderSize.toFloat(), null) - return bmpWithBorder - } + fun addRedBorder(bitmap: Bitmap, borderSize: Int, context: Context): Bitmap { + val bmpWithBorder = Bitmap.createBitmap( + bitmap.width + borderSize * 2, + bitmap.height + borderSize * 2, + bitmap.config + ) + val canvas = Canvas(bmpWithBorder) + canvas.drawColor(ContextCompat.getColor(context, R.color.deleteRed)) + canvas.drawBitmap(bitmap, borderSize.toFloat(), borderSize.toFloat(), null) + return bmpWithBorder } /** diff --git a/app/src/main/res/layout/activity_notification.xml b/app/src/main/res/layout/activity_notification.xml index 800c8aa0b..a8b60dea3 100644 --- a/app/src/main/res/layout/activity_notification.xml +++ b/app/src/main/res/layout/activity_notification.xml @@ -35,7 +35,6 @@ android:scrollbars="vertical" android:fadeScrollbars="false" android:scrollbarThumbVertical="@color/primaryColor" - android:clipToPadding="false" android:scrollbarSize="@dimen/dimen_6"/> diff --git a/app/src/main/res/layout/activity_review.xml b/app/src/main/res/layout/activity_review.xml index 2075fb888..871d25c7d 100644 --- a/app/src/main/res/layout/activity_review.xml +++ b/app/src/main/res/layout/activity_review.xml @@ -24,35 +24,22 @@ android:id="@+id/toolbarBinding" layout="@layout/toolbar" /> - - - - - - - + android:layout_gravity="center_horizontal" + android:drawableEnd="@drawable/ic_info_outline_24dp" + android:drawablePadding="@dimen/medium_height" + android:drawableTint="@color/button_blue_dark" + android:paddingLeft="@dimen/medium_height" + android:paddingRight="@dimen/medium_height" + android:text="@string/skip_image" + android:textAllCaps="true" + android:textColor="@color/button_blue_dark" + android:textStyle="bold" /> diff --git a/app/src/main/res/layout/upload_depicts_fragment.xml b/app/src/main/res/layout/upload_depicts_fragment.xml index a1b85666c..9fa621396 100644 --- a/app/src/main/res/layout/upload_depicts_fragment.xml +++ b/app/src/main/res/layout/upload_depicts_fragment.xml @@ -124,35 +124,38 @@ + android:id="@+id/button_divider" + android:layout_width="match_parent" + android:layout_height="1dp" + android:layout_above="@+id/depicts_next" + android:background="@color/divider_grey" /> - -