Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2ebf3f31 authored by dev-12's avatar dev-12
Browse files

Merge branch '3536-error-blink-on-searchinstall' into 'main'

Fix blinking of search and update list

See merge request !607
parents 761e4649 d7307528
Loading
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
<component name="ProjectCodeStyleConfiguration">
    <code_scheme name="Project" version="173">
        <codeStyleSettings language="kotlin">
            <indentOptions>
                <option name="CONTINUATION_INDENT_SIZE" value="4" />
            </indentOptions>
        </codeStyleSettings>
    </code_scheme>
</component>
 No newline at end of file
+5 −4
Original line number Diff line number Diff line
@@ -40,17 +40,18 @@ import com.facebook.shimmer.ShimmerDrawable
import com.google.android.material.button.MaterialButton
import com.google.android.material.snackbar.Snackbar
import foundation.e.apps.R
import foundation.e.apps.data.cleanapk.CleanApkRetrofit
import foundation.e.apps.data.enums.Status
import foundation.e.apps.data.enums.User
import foundation.e.apps.data.application.ApplicationInstaller
import foundation.e.apps.data.application.data.Application
import foundation.e.apps.data.cleanapk.CleanApkRetrofit
import foundation.e.apps.data.enums.Source
import foundation.e.apps.data.enums.Status
import foundation.e.apps.data.enums.User
import foundation.e.apps.databinding.ApplicationListItemBinding
import foundation.e.apps.install.pkg.InstallerService
import foundation.e.apps.ui.AppInfoFetchViewModel
import foundation.e.apps.ui.MainActivityViewModel
import foundation.e.apps.ui.PrivacyInfoViewModel
import foundation.e.apps.ui.applicationlist.diffUtils.ConciseAppDiffUtils
import foundation.e.apps.ui.search.SearchFragmentDirections
import foundation.e.apps.ui.updates.UpdatesFragmentDirections
import foundation.e.apps.utils.disableInstallButton
@@ -67,7 +68,7 @@ class ApplicationListRVAdapter(
    private val currentDestinationId: Int,
    private var lifecycleOwner: LifecycleOwner?,
    private var paidAppHandler: ((Application) -> Unit)? = null
) : ListAdapter<Application, ApplicationListRVAdapter.ViewHolder>(ApplicationDiffUtil()) {
) : ListAdapter<Application, ApplicationListRVAdapter.ViewHolder>(ConciseAppDiffUtils()) {

    private var optionalCategory = ""

+117 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 e Foundation
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */

package foundation.e.apps.ui.applicationlist.diffUtils

import androidx.recyclerview.widget.DiffUtil
import foundation.e.apps.BuildConfig
import foundation.e.apps.data.application.data.Application
import timber.log.Timber

class ConciseAppDiffUtils : DiffUtil.ItemCallback<Application>() {

    companion object {
        private val PERFORMANCE_DEBUGGING = BuildConfig.DEBUG
        private const val TAG = "ConciseAppDiffUtils"
    }

    override fun areItemsTheSame(oldItem: Application, newItem: Application): Boolean {
        /*
         * #Application._id is based on App.id which is (unimplemented/default) hashCode of the App
         * class we care about package name and it's source to define if the item is same.
         */
        val isSame = oldItem.package_name == newItem.package_name &&
            oldItem.source.ordinal == newItem.source.ordinal

        if (PERFORMANCE_DEBUGGING && !isSame) {
            val oldInfo = "Old(pkg=${oldItem.package_name}, src=${oldItem.source})"
            val newInfo = "New(pkg=${newItem.package_name}, src=${newItem.source})"
            Timber.tag(TAG).d("item aren't same : $oldInfo vs $newInfo")
        }
        return isSame
    }

    override fun areContentsTheSame(oldItem: Application, newItem: Application): Boolean {
        /*
         * most of the properties in the Application is val
         * so they won't change the same way var would
         * and in search screen we don't care about most fields
         * like a version changes should not be considered as a
         * significant changes to re render the item
         */

        val areAllPropsSame = oldItem.name == newItem.name &&
            oldItem.author == newItem.author && oldItem.package_name == newItem.package_name &&
            oldItem.category == newItem.category && oldItem.licence == newItem.licence &&
            oldItem.icon_image_path == newItem.icon_image_path &&
            oldItem.description == newItem.description &&
            oldItem.isPurchased == newItem.isPurchased &&
            oldItem.isPlaceHolder == newItem.isPlaceHolder &&
            oldItem.ratings.usageQualityScore == newItem.ratings.usageQualityScore &&
            oldItem.status.ordinal == newItem.status.ordinal

        if (PERFORMANCE_DEBUGGING && !areAllPropsSame) {
            logContentChanged(oldItem, newItem)
        }
        return areAllPropsSame
    }

    private fun logContentChanged(oldItem: Application, newItem: Application) {
        val diff = StringBuilder("contents are not the same for ${oldItem.package_name}:\n")

        if (oldItem.name != newItem.name) {
            diff.append("  name: '${oldItem.name}' vs '${newItem.name}'\n")
        }
        if (oldItem.author != newItem.author) {
            diff.append("  author: '${oldItem.author}' vs '${newItem.author}'\n")
        }
        if (oldItem.category != newItem.category) {
            diff.append("  category: '${oldItem.category}' vs '${newItem.category}'\n")
        }
        if (oldItem.description != newItem.description) {
            diff.append("  description: (changed)\n") // descriptions might be very long
        }
        if (oldItem.icon_image_path != newItem.icon_image_path) {
            val oldIcon = oldItem.icon_image_path
            val newIcon = newItem.icon_image_path
            diff.append("  icon_image_path: '$oldIcon' vs '$newIcon'\n")
        }
        if (oldItem.licence != newItem.licence) {
            diff.append("  licence: '${oldItem.licence}' vs '${newItem.licence}'\n")
        }
        if (oldItem.isPurchased != newItem.isPurchased) {
            diff.append("  isPurchased: ${oldItem.isPurchased} vs ${newItem.isPurchased}\n")
        }
        if (oldItem.isPlaceHolder != newItem.isPlaceHolder) {
            diff.append("  isPlaceHolder: ${oldItem.isPlaceHolder} vs ${newItem.isPlaceHolder}\n")
        }
        if (oldItem.ratings.usageQualityScore != newItem.ratings.usageQualityScore) {
            val oldRating = oldItem.ratings.usageQualityScore
            val newRating = newItem.ratings.usageQualityScore
            diff.append("  usageQualityScore: $oldRating vs $newRating\n")
        }
        if (oldItem.package_name != newItem.package_name) {
            diff.append("  package_name: '${oldItem.package_name}' vs '${newItem.package_name}'\n")
        }
        if (oldItem.status.ordinal != newItem.status.ordinal) {
            diff.append("  status: '${oldItem.status.name}' vs '${newItem.status.name}'\n")
        }

        Timber.tag(TAG).d(diff.toString())
    }
}