Browse Source

wip

Signed-off-by: tobiasKaminsky <tobias@kaminsky.me>
tobiasKaminsky 4 years ago
parent
commit
96ea22525e

+ 19 - 9
src/androidTest/java/com/owncloud/android/ui/fragment/UnifiedSearchFragmentIT.kt

@@ -25,10 +25,13 @@ import androidx.test.espresso.intent.rule.IntentsTestRule
 import androidx.test.internal.runner.junit4.statement.UiThreadStatement
 import com.nextcloud.client.TestActivity
 import com.owncloud.android.AbstractIT
+import com.owncloud.android.datamodel.OCFile
 import com.owncloud.android.lib.common.SearchResult
+import com.owncloud.android.lib.common.SearchResultEntry
 import com.owncloud.android.ui.unifiedsearch.UnifiedSearchViewModel
 import org.junit.Rule
 import org.junit.Test
+import java.io.File
 
 class UnifiedSearchFragmentIT : AbstractIT() {
     @get:Rule
@@ -47,20 +50,20 @@ class UnifiedSearchFragmentIT : AbstractIT() {
             sut.onSearchResultChanged(
                 mutableListOf(
                     SearchResult(
-                        "files",
+                        "Files",
                         false,
-                        listOf(ex
-                            SearchResultEntry ("thumbnailUrl",
-                            "Test",
-                            "in /Files/",
-                            "resourceUrl",
-                            "icon",
-                            false
+                        listOf(
+                            SearchResultEntry("thumbnailUrl",
+                                "Test",
+                                "in /Files/",
+                                "resourceUrl",
+                                "icon",
+                                false
+                            )
                         )
                     )
                 )
             )
-            )
         }
 
         longSleep()
@@ -74,6 +77,13 @@ class UnifiedSearchFragmentIT : AbstractIT() {
         val localRepository = UnifiedSearchLocalRepository()
         testViewModel.setRepository(localRepository)
 
+        val ocFile = OCFile("/folder/test1.txt").apply {
+            storagePath = "/sdcard/1.txt"
+            storageManager.saveFile(this)
+        }
+
+        File(ocFile.storagePath).createNewFile()
+
         activity.addFragment(sut)
 
         shortSleep()

+ 9 - 2
src/androidTest/java/com/owncloud/android/ui/fragment/UnifiedSearchLocalRepository.kt

@@ -43,9 +43,16 @@ class UnifiedSearchLocalRepository : IUnifiedSearchRepository {
         ("thumbnailUrl",
             "Test",
             "in Files",
-            "resourceUrl",
+            "http://localhost/nc/index.php/apps/files/?dir=/Files&scrollto=Test",
             "icon",
-            false))))
+            false),
+            SearchResultEntry
+            ("thumbnailUrl",
+                "Test1",
+                "in Folder",
+                "http://localhost/nc/index.php/apps/files/?dir=/folder&scrollto=test1.txt",
+                "icon",
+                false))))
         vm.onSearchResult(result)
         Log_OC.d(this, "loadMore")
     }

+ 5 - 0
src/main/java/com/nextcloud/client/di/AppModule.java

@@ -231,4 +231,9 @@ class AppModule {
     LocalBroadcastManager localBroadcastManager(Context context) {
         return LocalBroadcastManager.getInstance(context);
     }
+
+    @Provides
+    FileDataStorageManager storageManager(CurrentAccountProvider currentAccountProvider, Context context) {
+        return new FileDataStorageManager(currentAccountProvider.getCurrentAccount(), context.getContentResolver());
+    }
 }

+ 2 - 1
src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java

@@ -155,7 +155,8 @@ public class FileDataStorageManager {
         return ocFile;
     }
 
-    public OCFile getFileByLocalPath(String path) {
+    public @Nullable
+    OCFile getFileByLocalPath(String path) {
         Cursor cursor = getFileCursorForValue(ProviderTableMeta.FILE_STORAGE_PATH, path);
         OCFile ocFile = null;
 

+ 17 - 1
src/main/java/com/owncloud/android/ui/adapter/UnifiedSearchItemViewHolder.kt

@@ -22,15 +22,31 @@
 package com.owncloud.android.ui.adapter
 
 import android.content.Context
+import android.view.View
 import com.afollestad.sectionedrecyclerview.SectionedViewHolder
 import com.owncloud.android.databinding.UnifiedSearchItemBinding
+import com.owncloud.android.datamodel.FileDataStorageManager
 import com.owncloud.android.lib.common.SearchResultEntry
+import com.owncloud.android.ui.interfaces.UnifiedSearchListInterface
 
-class UnifiedSearchItemViewHolder(val binding: UnifiedSearchItemBinding, val context: Context) :
+class UnifiedSearchItemViewHolder(val binding: UnifiedSearchItemBinding,
+                                  val context: Context,
+                                  val storageManager: FileDataStorageManager,
+                                  val listInterface: UnifiedSearchListInterface) :
     SectionedViewHolder(binding.root) {
 
     fun bind(entry: SearchResultEntry) {
         binding.title.text = entry.title
         binding.subline.text = entry.subline
+
+        val ocFile = storageManager.getFileByDecryptedRemotePath(entry.remotePath())
+
+        if (ocFile?.isDown == true) {
+            binding.localFileIndicator.visibility = View.VISIBLE
+        } else {
+            binding.localFileIndicator.visibility = View.GONE
+        }
+
+        binding.unifiedSearchItemLayout.setOnClickListener { listInterface.onSearchResultClicked(entry) }
     }
 }

+ 29 - 23
src/main/java/com/owncloud/android/ui/adapter/UnifiedSearchListAdapter.java

@@ -77,6 +77,7 @@ import com.owncloud.android.operations.RemoteOperationFailedException;
 import com.owncloud.android.ui.TextDrawable;
 import com.owncloud.android.ui.fragment.ExtendedListFragment;
 import com.owncloud.android.ui.interfaces.OCFileListFragmentInterface;
+import com.owncloud.android.ui.interfaces.UnifiedSearchListInterface;
 import com.owncloud.android.utils.BitmapUtils;
 import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.FileSortOrder;
@@ -122,7 +123,7 @@ public class UnifiedSearchListAdapter extends SectionedRecyclerViewAdapter<Secti
 
     private List<SearchResult> list = new ArrayList<>();
 
-    private FileDataStorageManager mStorageManager;
+    private FileDataStorageManager storageManager;
     private User user;
     private OCFileListFragmentInterface ocFileListFragmentInterface;
 
@@ -140,8 +141,11 @@ public class UnifiedSearchListAdapter extends SectionedRecyclerViewAdapter<Secti
     private boolean showShareAvatar = false;
     private OCFile highlightedItem;
     private Context context;
+    private UnifiedSearchListInterface listInterface;
 
-    public UnifiedSearchListAdapter(Context context) {
+    public UnifiedSearchListAdapter(FileDataStorageManager storageManager,
+                                    UnifiedSearchListInterface listInterface,
+                                    Context context) {
 //        this.ocFileListFragmentInterface = ocFileListFragmentInterface;
 //        this.activity = activity;
 //        this.preferences = preferences;
@@ -150,6 +154,8 @@ public class UnifiedSearchListAdapter extends SectionedRecyclerViewAdapter<Secti
 //        this.gridView = gridView;
         checkedFiles = new HashSet<>();
         this.context = context;
+        this.storageManager = storageManager;
+        this.listInterface = listInterface;
 
         if (this.user != null) {
             AccountManager platformAccountManager = AccountManager.get(this.activity);
@@ -177,7 +183,7 @@ public class UnifiedSearchListAdapter extends SectionedRecyclerViewAdapter<Secti
                                                                                 parent,
                                                                                 false);
 
-            return new UnifiedSearchItemViewHolder(binding, context);
+            return new UnifiedSearchItemViewHolder(binding, context, storageManager, listInterface);
         }
     }
 
@@ -296,7 +302,7 @@ public class UnifiedSearchListAdapter extends SectionedRecyclerViewAdapter<Secti
             if (mFiles.get(i).getRemoteId().equals(fileId)) {
                 OCFile file = mFiles.get(i);
                 file.setEncrypted(encrypted);
-                mStorageManager.saveFile(file);
+                storageManager.saveFile(file);
 
                 break;
             }
@@ -628,13 +634,13 @@ public class UnifiedSearchListAdapter extends SectionedRecyclerViewAdapter<Secti
                              ) {
         this.onlyOnDevice = onlyOnDevice;
 
-        if (updatedStorageManager != null && !updatedStorageManager.equals(mStorageManager)) {
-            mStorageManager = updatedStorageManager;
-            showShareAvatar = mStorageManager.getCapability(account.getAccountName()).getVersion().isShareesOnDavSupported();
+        if (updatedStorageManager != null && !updatedStorageManager.equals(storageManager)) {
+            storageManager = updatedStorageManager;
+            showShareAvatar = storageManager.getCapability(account.getAccountName()).getVersion().isShareesOnDavSupported();
             this.user = account;
         }
-        if (mStorageManager != null) {
-            mFiles = mStorageManager.getFolderContent(directory, onlyOnDevice);
+        if (storageManager != null) {
+            mFiles = storageManager.getFolderContent(directory, onlyOnDevice);
 
             if (!preferences.isShowHiddenFilesEnabled()) {
                 mFiles = filterHiddenFiles(mFiles);
@@ -662,13 +668,13 @@ public class UnifiedSearchListAdapter extends SectionedRecyclerViewAdapter<Secti
                         FileDataStorageManager storageManager,
                         @Nullable OCFile folder,
                         boolean clear) {
-        if (storageManager != null && mStorageManager == null) {
-            mStorageManager = storageManager;
-            showShareAvatar = mStorageManager.getCapability(user.getAccountName()).getVersion().isShareesOnDavSupported();
+        if (storageManager != null && this.storageManager == null) {
+            this.storageManager = storageManager;
+            showShareAvatar = this.storageManager.getCapability(user.getAccountName()).getVersion().isShareesOnDavSupported();
         }
 
-        if (mStorageManager == null) {
-            mStorageManager = new FileDataStorageManager(user.toPlatformAccount(), activity.getContentResolver());
+        if (this.storageManager == null) {
+            this.storageManager = new FileDataStorageManager(user.toPlatformAccount(), activity.getContentResolver());
         }
 
         if (clear) {
@@ -689,11 +695,11 @@ public class UnifiedSearchListAdapter extends SectionedRecyclerViewAdapter<Secti
                     break;
             }
 
-            mStorageManager.deleteVirtuals(type);
+            this.storageManager.deleteVirtuals(type);
         }
 
         // early exit
-        if (objects.size() > 0 && mStorageManager != null) {
+        if (objects.size() > 0 && this.storageManager != null) {
             if (searchType == ExtendedListFragment.SearchType.SHARED_FILTER) {
                 parseShares(objects);
             } else {
@@ -734,7 +740,7 @@ public class UnifiedSearchListAdapter extends SectionedRecyclerViewAdapter<Secti
                 if (result.isSuccess()) {
                     OCFile file = FileStorageUtils.fillOCFile((RemoteFile) result.getData().get(0));
                     FileStorageUtils.searchForLocalFileInDefaultPath(file, user.toPlatformAccount());
-                    file = mStorageManager.saveFileWithParent(file, activity);
+                    file = storageManager.saveFileWithParent(file, activity);
 
                     ShareType newShareType = ocShare.getShareType();
                     if (newShareType == ShareType.PUBLIC_LINK) {
@@ -748,7 +754,7 @@ public class UnifiedSearchListAdapter extends SectionedRecyclerViewAdapter<Secti
                         file.setSharedWithSharee(true);
                     }
 
-                    mStorageManager.saveFile(file);
+                    storageManager.saveFile(file);
 
                     if (!mFiles.contains(file)) {
                         mFiles.add(file);
@@ -759,7 +765,7 @@ public class UnifiedSearchListAdapter extends SectionedRecyclerViewAdapter<Secti
             }
         }
 
-        mStorageManager.saveShares(shares);
+        storageManager.saveShares(shares);
     }
 
     private void parseVirtuals(List<Object> objects, ExtendedListFragment.SearchType searchType) {
@@ -797,10 +803,10 @@ public class UnifiedSearchListAdapter extends SectionedRecyclerViewAdapter<Secti
 
             try {
                 if (ExtendedListFragment.SearchType.PHOTO_SEARCH == searchType) {
-                    mStorageManager.saveFile(ocFile);
+                    storageManager.saveFile(ocFile);
                 } else {
 
-                    ocFile = mStorageManager.saveFileWithParent(ocFile, activity);
+                    ocFile = storageManager.saveFileWithParent(ocFile, activity);
 
                     // also sync folder content
                     if (ocFile.isFolder()) {
@@ -809,7 +815,7 @@ public class UnifiedSearchListAdapter extends SectionedRecyclerViewAdapter<Secti
                                                                                             currentSyncTime,
                                                                                             true,
                                                                                             false,
-                                                                                            mStorageManager,
+                                                                                            storageManager,
                                                                                             user.toPlatformAccount(),
                                                                                             activity);
                         refreshFolderOperation.execute(user.toPlatformAccount(), activity);
@@ -831,7 +837,7 @@ public class UnifiedSearchListAdapter extends SectionedRecyclerViewAdapter<Secti
         }
 
         preferences.setPhotoSearchTimestamp(System.currentTimeMillis());
-        mStorageManager.saveVirtuals(contentValues);
+        storageManager.saveVirtuals(contentValues);
     }
 
     public void showVirtuals(VirtualFolderType type, boolean onlyImages, FileDataStorageManager storageManager) {

+ 1 - 17
src/main/java/com/owncloud/android/ui/asynctasks/FetchRemoteFileTask.java

@@ -22,10 +22,8 @@
 package com.owncloud.android.ui.asynctasks;
 
 import android.os.AsyncTask;
-import android.text.TextUtils;
 
 import com.nextcloud.client.account.User;
-import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
@@ -36,8 +34,6 @@ import com.owncloud.android.lib.resources.files.SearchRemoteOperation;
 import com.owncloud.android.lib.resources.files.model.RemoteFile;
 import com.owncloud.android.operations.RefreshFolderOperation;
 import com.owncloud.android.ui.activity.FileDisplayActivity;
-import com.owncloud.android.ui.fragment.OCFileListFragment;
-import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.FileStorageUtils;
 
 import static com.owncloud.android.lib.resources.files.SearchRemoteOperation.SearchType.FILE_ID_SEARCH;
@@ -124,18 +120,6 @@ public class FetchRemoteFileTask extends AsyncTask<Void, Void, String> {
     protected void onPostExecute(String message) {
         super.onPostExecute(message);
 
-        fileDisplayActivity.dismissLoadingDialog();
-
-        OCFileListFragment listOfFiles = fileDisplayActivity.getListOfFilesFragment();
-        if (listOfFiles != null) {
-            if (TextUtils.isEmpty(message)) {
-                OCFile temp = fileDisplayActivity.getFile();
-                fileDisplayActivity.setFile(fileDisplayActivity.getCurrentDir());
-                listOfFiles.listDirectory(fileDisplayActivity.getCurrentDir(), temp, MainApp.isOnlyOnDevice(), false);
-                fileDisplayActivity.updateActionBarTitleAndHomeButton(null);
-            } else {
-                DisplayUtils.showSnackMessage(listOfFiles.getView(), message);
-            }
-        }
+        fileDisplayActivity.showFile(message);
     }
 }

+ 48 - 2
src/main/java/com/owncloud/android/ui/fragment/UnifiedSearchFragment.kt

@@ -28,11 +28,19 @@ import androidx.annotation.VisibleForTesting
 import androidx.fragment.app.Fragment
 import androidx.lifecycle.ViewModelProvider
 import androidx.recyclerview.widget.GridLayoutManager
+import com.nextcloud.client.account.CurrentAccountProvider
+import com.nextcloud.client.core.AsyncRunner
 import com.nextcloud.client.di.Injectable
 import com.nextcloud.client.di.ViewModelFactory
+import com.nextcloud.client.network.ClientFactory
 import com.owncloud.android.databinding.ListFragmentBinding
+import com.owncloud.android.datamodel.FileDataStorageManager
 import com.owncloud.android.lib.common.SearchResult
+import com.owncloud.android.lib.common.SearchResultEntry
+import com.owncloud.android.ui.activities.GetRemoteFileTask
+import com.owncloud.android.ui.activity.FileDisplayActivity
 import com.owncloud.android.ui.adapter.UnifiedSearchListAdapter
+import com.owncloud.android.ui.interfaces.UnifiedSearchListInterface
 import com.owncloud.android.ui.unifiedsearch.UnifiedSearchViewModel
 import javax.inject.Inject
 
@@ -40,7 +48,7 @@ import javax.inject.Inject
  * Starts query to all capable unified search providers and displays them Opens result in our app, redirect to other
  * apps, if installed, or opens browser
  */
-class UnifiedSearchFragment : Fragment(), Injectable {
+class UnifiedSearchFragment : Fragment(), Injectable, UnifiedSearchListInterface {
     private lateinit var adapter: UnifiedSearchListAdapter
     private var _binding: ListFragmentBinding? = null
     private val binding get() = _binding!!
@@ -49,6 +57,18 @@ class UnifiedSearchFragment : Fragment(), Injectable {
     @Inject
     lateinit var vmFactory: ViewModelFactory
 
+    @Inject
+    lateinit var storageManager: FileDataStorageManager
+
+    @Inject
+    lateinit var runner: AsyncRunner
+
+    @Inject
+    lateinit var currentAccountProvider: CurrentAccountProvider
+
+    @Inject
+    lateinit var clientFactory: ClientFactory
+
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         vm = ViewModelProvider(this, vmFactory).get(UnifiedSearchViewModel::class.java)
@@ -76,7 +96,7 @@ class UnifiedSearchFragment : Fragment(), Injectable {
         super.onViewCreated(view, savedInstanceState)
 
         val gridLayoutManager = GridLayoutManager(requireContext(), 1)
-        adapter = UnifiedSearchListAdapter(requireContext())
+        adapter = UnifiedSearchListAdapter(storageManager, this, requireContext())
         adapter.setLayoutManager(gridLayoutManager)
         binding.listRoot.layoutManager = gridLayoutManager
         binding.listRoot.adapter = adapter
@@ -92,6 +112,32 @@ class UnifiedSearchFragment : Fragment(), Injectable {
         _binding = null
     }
 
+    fun showFile(result: GetRemoteFileTask.Result) {
+        activity.let {
+            if (activity is FileDisplayActivity) {
+                val fda = activity as FileDisplayActivity
+                fda.file = result.file
+                fda.showFile("")
+            }
+        }
+    }
+
+    override fun onSearchResultClicked(searchResultEntry: SearchResultEntry) {
+        openFile(searchResultEntry.remotePath())
+    }
+
+    fun openFile(fileUrl: String) {
+        val user = currentAccountProvider.user
+        val task = GetRemoteFileTask(
+            requireContext(),
+            fileUrl,
+            clientFactory.create(currentAccountProvider.user),
+            FileDataStorageManager(user.toPlatformAccount(), requireContext().contentResolver),
+            user
+        )
+        runner.postQuickTask(task, onResult = this::showFile)
+    }
+
     @VisibleForTesting
     fun onSearchResultChanged(list: MutableList<SearchResult>) {
         binding.emptyList.emptyListView.visibility = View.GONE

+ 30 - 0
src/main/java/com/owncloud/android/ui/interfaces/UnifiedSearchListInterface.kt

@@ -0,0 +1,30 @@
+/*
+ *
+ * Nextcloud Android client application
+ *
+ * @author Tobias Kaminsky
+ * Copyright (C) 2020 Tobias Kaminsky
+ * Copyright (C) 2020 Nextcloud GmbH
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package com.owncloud.android.ui.interfaces
+
+import com.owncloud.android.lib.common.SearchResultEntry
+
+interface UnifiedSearchListInterface {
+
+    fun onSearchResultClicked(searchResultEntry: SearchResultEntry)
+}

+ 30 - 23
src/main/java/com/owncloud/android/ui/unifiedsearch/UnifiedSearchViewModel.kt

@@ -19,6 +19,7 @@
  */
 package com.owncloud.android.ui.unifiedsearch
 
+import android.content.Context
 import android.content.res.Resources
 import androidx.annotation.VisibleForTesting
 import androidx.lifecycle.MutableLiveData
@@ -27,8 +28,10 @@ import com.nextcloud.client.account.CurrentAccountProvider
 import com.nextcloud.client.core.AsyncRunner
 import com.nextcloud.client.network.ClientFactory
 import com.owncloud.android.R
+import com.owncloud.android.datamodel.FileDataStorageManager
 import com.owncloud.android.lib.common.SearchResult
 import com.owncloud.android.lib.common.utils.Log_OC
+import com.owncloud.android.ui.activities.GetRemoteFileTask
 import javax.inject.Inject
 
 @Suppress("LongParameterList")
@@ -38,6 +41,7 @@ class UnifiedSearchViewModel() : ViewModel() {
     lateinit var runner: AsyncRunner
     lateinit var clientFactory: ClientFactory
     lateinit var resources: Resources
+    lateinit var context: Context
 
     private lateinit var repository: IUnifiedSearchRepository
     private var loadingStarted: Boolean = false
@@ -53,11 +57,13 @@ class UnifiedSearchViewModel() : ViewModel() {
         currentAccountProvider: CurrentAccountProvider,
         runner: AsyncRunner,
         clientFactory: ClientFactory,
-        resources: Resources) : this() {
+        resources: Resources,
+        context: Context) : this() {
         this.currentAccountProvider = currentAccountProvider
         this.runner = runner
         this.clientFactory = clientFactory
         this.resources = resources
+        this.context = context
 
         repository = UnifiedSearchRemoteRepository(
             clientFactory,
@@ -90,20 +96,20 @@ class UnifiedSearchViewModel() : ViewModel() {
     }
 
 
-//    fun openFile(fileUrl: String) {
-//        if (isLoading.value == false) {
-//            (isLoading as MutableLiveData).value = true
-//            val user = currentUser.user
-//            val task = GetRemoteFileTask(
-//                context,
-//                fileUrl,
-//                clientFactory.create(currentUser.user),
-//                FileDataStorageManager(user.toPlatformAccount(), contentResolver),
-//                user
-//            )
-//            runner.postQuickTask(task, onResult = this::onFileRequestResult)
-//        }
-//    }
+    fun openFile(fileUrl: String) {
+        if (isLoading.value == false) {
+            isLoading.value = true
+            val user = currentAccountProvider.user
+            val task = GetRemoteFileTask(
+                context,
+                fileUrl,
+                clientFactory.create(currentAccountProvider.user),
+                FileDataStorageManager(user.toPlatformAccount(), context.contentResolver),
+                user
+            )
+            runner.postQuickTask(task, onResult = this::onFileRequestResult)
+        }
+    }
 
     open fun clearError() {
         error.value = ""
@@ -144,12 +150,13 @@ class UnifiedSearchViewModel() : ViewModel() {
 //        }
 //    }
 
-//    private fun onFileRequestResult(result: GetRemoteFileTask.Result) {
-//        (isLoading as MutableLiveData).value = false
-//        if (result.success) {
-//            (file as MutableLiveData).value = result.file
-//        } else {
-//            (file as MutableLiveData).value = null
-//        }
-//    }
+    private fun onFileRequestResult(result: GetRemoteFileTask.Result) {
+        isLoading.value = false
+        if (result.success) {
+            // unifiedSearchFragment.showFile(result.file)
+            //(file as MutableLiveData).value = result.file
+        } else {
+            error.value = "Error showing search result"
+        }
+    }
 }

+ 2 - 12
src/main/res/layout/unified_search_item.xml

@@ -22,7 +22,7 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/upload_list_item_layout"
+    android:id="@+id/unified_search_item_layout"
     android:layout_width="match_parent"
     android:layout_height="@dimen/standard_list_item_size"
     android:baselineAligned="false"
@@ -66,22 +66,12 @@
             android:contentDescription="@string/downloader_download_succeeded_ticker"
             android:scaleType="fitCenter"
             android:src="@drawable/ic_synced"
+            android:visibility="gone"
             app:layout_constraintBottom_toBottomOf="@+id/thumbnail_layout"
             app:layout_constraintEnd_toEndOf="@+id/thumbnail_layout"
             app:layout_constraintStart_toEndOf="@+id/thumbnail_layout"
             app:layout_constraintTop_toBottomOf="@+id/thumbnail_layout" />
 
-        <ImageView
-            android:id="@+id/favorite_action"
-            android:layout_width="@dimen/list_item_favorite_action_layout_width"
-            android:layout_height="@dimen/list_item_favorite_action_layout_height"
-            android:contentDescription="@string/favorite"
-            android:src="@drawable/favorite"
-            app:layout_constraintBottom_toTopOf="@+id/thumbnail_layout"
-            app:layout_constraintEnd_toEndOf="@+id/thumbnail_layout"
-            app:layout_constraintStart_toEndOf="@+id/thumbnail_layout"
-            app:layout_constraintTop_toTopOf="@+id/thumbnail_layout" />
-
     </androidx.constraintlayout.widget.ConstraintLayout>
 
     <LinearLayout