Skip to content

Commit

Permalink
Updated empty state view icons for light and dark mode with test cases.
Browse files Browse the repository at this point in the history
  • Loading branch information
surinder-tsys committed Jan 15, 2025
1 parent b11ea53 commit 3b356ad
Show file tree
Hide file tree
Showing 34 changed files with 553 additions and 68 deletions.
186 changes: 186 additions & 0 deletions app/src/androidTest/java/com/nmc/android/ui/EmptyStateViewIT.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
package com.nmc.android.ui

import androidx.test.core.app.ActivityScenario
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.rules.ActivityScenarioRule
import com.nextcloud.test.TestActivity
import com.owncloud.android.AbstractIT
import com.owncloud.android.R
import com.owncloud.android.lib.resources.notifications.models.Notification
import com.owncloud.android.ui.activity.FolderPickerActivity
import com.owncloud.android.ui.activity.NotificationsActivity
import com.owncloud.android.ui.activity.ReceiveExternalFilesActivity
import com.owncloud.android.ui.activity.UploadListActivity
import com.owncloud.android.ui.fragment.GalleryFragment
import com.owncloud.android.ui.fragment.OCFileListFragment
import com.owncloud.android.ui.fragment.SearchType
import com.owncloud.android.ui.trashbin.TrashbinActivity
import org.junit.Rule
import org.junit.Test

/**
* test to validate empty state on different screens
*/
class EmptyStateViewIT : AbstractIT() {

@get:Rule
val testActivityRule = ActivityScenarioRule(TestActivity::class.java)

@Test
fun validate_emptyState_NoSearch() {
loadOCFileListFragmentWithSearchType(SearchType.NO_SEARCH)
onView(withId(R.id.empty_list_icon)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_headline)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_headline)).check(matches(withText("No files here")))
onView(withId(R.id.empty_list_view_text)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_text)).check(matches(withText("Upload some content or sync with your devices.")))
}

@Test
fun validate_emptyState_FileSearch() {
loadOCFileListFragmentWithSearchType(SearchType.FILE_SEARCH)
onView(withId(R.id.empty_list_icon)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_headline)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_headline)).check(matches(withText("No results")))
onView(withId(R.id.empty_list_view_text)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_text)).check(matches(withText("Search for a file (at least 2 characters)")))
}

@Test
fun validate_emptyState_FavoriteSearch() {
loadOCFileListFragmentWithSearchType(SearchType.FAVORITE_SEARCH)
onView(withId(R.id.empty_list_icon)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_headline)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_headline)).check(matches(withText("Nothing favorited yet")))
onView(withId(R.id.empty_list_view_text)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_text)).check(matches(withText("Files and folders you mark as favorites will show up here.")))
}

@Test
fun validate_emptyState_RecentSearch() {
loadOCFileListFragmentWithSearchType(SearchType.RECENTLY_MODIFIED_SEARCH)
onView(withId(R.id.empty_list_icon)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_headline)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_headline)).check(matches(withText("No results")))
onView(withId(R.id.empty_list_view_text)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_text)).check(matches(withText("Found no files modified within the last 7 days")))
}

@Test
fun validate_emptyState_SharedSearch() {
loadOCFileListFragmentWithSearchType(SearchType.SHARED_FILTER)
onView(withId(R.id.empty_list_icon)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_headline)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_headline)).check(matches(withText("Nothing shared yet")))
onView(withId(R.id.empty_list_view_text)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_text)).check(matches(withText("Files and folders you share will show up here.")))
}

@Test
fun validate_emptyState_GallerySearch() {
loadGalleryFragment()
onView(withId(R.id.empty_list_icon)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_headline)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_headline)).check(matches(withText("No files here")))
onView(withId(R.id.empty_list_view_text)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_text)).check(matches(withText("No photos or videos uploaded yet")))
}

@Test
fun validate_emptyState_Notification() {
val activityScenario = ActivityScenario.launch(NotificationsActivity::class.java)
waitForIdleSync()
activityScenario.onActivity {
it.runOnUiThread { it.populateList(ArrayList<Notification>()) }
}

onView(withId(R.id.empty_list_icon)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_headline)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_headline)).check(matches(withText("No notifications")))
onView(withId(R.id.empty_list_view_text)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_text)).check(matches(withText("Please check back later.")))
}

@Test
fun validate_errorState_Trashbin() {
ActivityScenario.launch(TrashbinActivity::class.java)
onView(withId(R.id.empty_list_icon)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_headline)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_headline)).check(matches(withText("Error")))
onView(withId(R.id.empty_list_view_text)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_text)).check(matches(withText("Loading trash bin failed!")))
}

@Test
fun validate_emptyState_Trashbin() {
val activityScenario = ActivityScenario.launch(TrashbinActivity::class.java)
activityScenario.onActivity {
it.showTrashbinFolder(emptyList())
}
onView(withId(R.id.empty_list_icon)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_headline)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_headline)).check(matches(withText("No deleted files")))
onView(withId(R.id.empty_list_view_text)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_text)).check(matches(withText("You will be able to recover deleted files from here.")))
}

@Test
fun validate_emptyState_FolderPicker() {
ActivityScenario.launch(FolderPickerActivity::class.java)
onView(withId(R.id.empty_list_icon)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_headline)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_headline)).check(matches(withText("No files here")))
onView(withId(R.id.empty_list_view_text)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_text)).check(matches(withText("Upload some content or sync with your devices.")))
}

@Test
fun validate_emptyState_ReceivedExternalFiles() {
ActivityScenario.launch(ReceiveExternalFilesActivity::class.java)
onView(withId(R.id.empty_list_icon)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_headline)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_headline)).check(matches(withText("No files here")))
onView(withId(R.id.empty_list_view_text)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_text)).check(matches(withText("")))
}

@Test
fun validate_emptyState_UploadList() {
ActivityScenario.launch(UploadListActivity::class.java)
onView(withId(R.id.empty_list_icon)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_headline)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_headline)).check(matches(withText("No uploads available")))
onView(withId(R.id.empty_list_view_text)).check(matches(isCompletelyDisplayed()))
onView(withId(R.id.empty_list_view_text)).check(matches(withText("Upload some content or activate auto upload.")))
}

private fun loadOCFileListFragmentWithSearchType(searchType: SearchType) {
testActivityRule.scenario.onActivity {
it.addFragment(OCFileListFragment())
}

waitForIdleSync()

testActivityRule.scenario.onActivity {
val fragment = (it.fragment as OCFileListFragment)
fragment.setEmptyListMessage(searchType)
}
}

private fun loadGalleryFragment() {
testActivityRule.scenario.onActivity {
it.addFragment(GalleryFragment())
}

waitForIdleSync()

testActivityRule.scenario.onActivity {
val fragment = (it.fragment as GalleryFragment)
fragment.setEmptyListMessage(SearchType.GALLERY_SEARCH)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ open class FolderPickerActivity :
it.setMessageForEmptyList(
R.string.folder_list_empty_headline,
R.string.file_list_empty_moving,
R.drawable.ic_list_empty_create_folder,
R.drawable.ic_list_empty_folder,
true
)
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ class NotificationsActivity : AppCompatActivity(), NotificationsContract.View, I
* sets up the UI elements and loads all notification items.
*/
private fun setupContent() {
binding.emptyList.emptyListIcon.setImageResource(R.drawable.ic_notification)
binding.emptyList.emptyListIcon.setImageResource(R.drawable.ic_list_empty_notification)
setLoadingMessageEmpty()
val layoutManager = LinearLayoutManager(this)
binding.list.layoutManager = layoutManager
Expand Down Expand Up @@ -335,7 +335,7 @@ class NotificationsActivity : AppCompatActivity(), NotificationsContract.View, I
binding.emptyList.emptyListView.visibility = View.VISIBLE
binding.emptyList.emptyListViewHeadline.text = headline
binding.emptyList.emptyListViewText.text = message
binding.emptyList.emptyListIcon.setImageResource(R.drawable.ic_notification)
binding.emptyList.emptyListIcon.setImageResource(R.drawable.ic_list_empty_notification)
binding.emptyList.emptyListViewText.visibility = View.VISIBLE
binding.emptyList.emptyListIcon.visibility = View.VISIBLE
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -766,16 +766,16 @@ private void populateDirectoryList(OCFile file) {

List<OCFile> files = getStorageManager().getFolderContent(mFile, false);

if (files.isEmpty()) {
setMessageForEmptyList(R.string.file_list_empty_headline, R.string.empty,
R.drawable.uploads);
mEmptyListContainer.setVisibility(View.VISIBLE);
binding.list.setVisibility(View.GONE);
} else {
mEmptyListContainer.setVisibility(View.GONE);
files = sortFileList(files);
setupReceiveExternalFilesAdapter(files);
}
if (files.isEmpty()) {
setMessageForEmptyList(R.string.file_list_empty_headline, R.string.empty,
R.drawable.ic_list_empty_uploads);
mEmptyListContainer.setVisibility(View.VISIBLE);
binding.list.setVisibility(View.GONE);
} else {
mEmptyListContainer.setVisibility(View.GONE);
files = sortFileList(files);
setupReceiveExternalFilesAdapter(files);
}

MaterialButton btnChooseFolder = binding.uploaderChooseFolder;
viewThemeUtils.material.colorMaterialButtonPrimaryFilled(btnChooseFolder);
Expand Down Expand Up @@ -822,7 +822,7 @@ public void setMessageForEmptyList(@StringRes final int headline, @StringRes fin
if (mEmptyListContainer != null && mEmptyListMessage != null) {
mEmptyListHeadline.setText(headline);
mEmptyListMessage.setText(message);
mEmptyListIcon.setImageDrawable(viewThemeUtils.platform.tintPrimaryDrawable(this, icon));
mEmptyListIcon.setImageResource(icon);
mEmptyListIcon.setVisibility(View.VISIBLE);
mEmptyListMessage.setVisibility(View.VISIBLE);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,8 @@ class SyncedFoldersActivity :
binding.list.layoutManager = lm
binding.list.adapter = adapter
load(getItemsDisplayedPerFolder(), false)
//NMC customization
binding.emptyList.emptyListIcon.setImageResource(R.drawable.ic_list_empty_synced_folders)
}

private fun showHiddenItems() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,7 @@ private void handleUploadWorkerState() {
private void setupContent() {
binding.list.setEmptyView(binding.emptyList.getRoot());
binding.emptyList.getRoot().setVisibility(View.GONE);
binding.emptyList.emptyListIcon.setImageResource(R.drawable.uploads);
binding.emptyList.emptyListIcon.getDrawable().mutate();
binding.emptyList.emptyListIcon.setAlpha(0.5f);
binding.emptyList.emptyListIcon.setImageResource(R.drawable.ic_list_empty_uploads);
binding.emptyList.emptyListIcon.setVisibility(View.VISIBLE);
binding.emptyList.emptyListViewHeadline.setText(getString(R.string.upload_list_empty_headline));
binding.emptyList.emptyListViewText.setText(getString(R.string.upload_list_empty_text_auto_upload));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -586,22 +586,14 @@ public void setMessageForEmptyList(@StringRes final int headline, @StringRes fin
@DrawableRes final int icon, final boolean tintIcon) {
new Handler(Looper.getMainLooper()).post(() -> {

if (mEmptyListContainer != null && mEmptyListMessage != null) {
mEmptyListHeadline.setText(headline);
mEmptyListMessage.setText(message);

if (tintIcon) {
if (getContext() != null) {
mEmptyListIcon.setImageDrawable(
viewThemeUtils.platform.tintPrimaryDrawable(getContext(), icon));
}
} else {
if (mEmptyListContainer != null && mEmptyListMessage != null) {
mEmptyListHeadline.setText(headline);
mEmptyListMessage.setText(message);
//tinting is not required in NMC
mEmptyListIcon.setImageResource(icon);
mEmptyListIcon.setVisibility(View.VISIBLE);
mEmptyListMessage.setVisibility(View.VISIBLE);
}

mEmptyListIcon.setVisibility(View.VISIBLE);
mEmptyListMessage.setVisibility(View.VISIBLE);
}
});
}

Expand All @@ -619,8 +611,8 @@ public void setEmptyListMessage(final SearchType searchType) {
true);
} else if (searchType == SearchType.FILE_SEARCH) {
setMessageForEmptyList(R.string.file_list_empty_headline_server_search,
R.string.file_list_empty,
R.drawable.ic_search_light_grey);
R.string.search_result_empty,
R.drawable.ic_search_empty);
} else if (searchType == SearchType.FAVORITE_SEARCH) {
setMessageForEmptyList(R.string.file_list_empty_favorite_headline,
R.string.file_list_empty_favorites_filter_list,
Expand All @@ -632,15 +624,15 @@ public void setEmptyListMessage(final SearchType searchType) {
} else if (searchType == SearchType.REGULAR_FILTER) {
setMessageForEmptyList(R.string.file_list_empty_headline_search,
R.string.file_list_empty_search,
R.drawable.ic_search_light_grey);
R.drawable.ic_search_empty);
} else if (searchType == SearchType.SHARED_FILTER) {
setMessageForEmptyList(R.string.file_list_empty_shared_headline,
R.string.file_list_empty_shared,
R.drawable.ic_list_empty_shared);
} else if (searchType == SearchType.GALLERY_SEARCH) {
setMessageForEmptyList(R.string.file_list_empty_headline_server_search,
R.string.file_list_empty_gallery,
R.drawable.file_image);
setMessageForEmptyList(R.string.file_list_empty_headline,
R.string.gallery_list_empty,
R.drawable.ic_list_empty_media);
} else if (searchType == SearchType.LOCAL_SEARCH) {
setMessageForEmptyList(R.string.file_list_empty_headline_server_search,
R.string.file_list_empty_local_search,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,8 @@ class UnifiedSearchFragment :
requireContext().getString(R.string.file_list_empty_headline_server_search)
binding.emptyList.emptyListViewText.text =
requireContext().getString(R.string.file_list_empty_unified_search_no_results)
binding.emptyList.emptyListIcon.setImageDrawable(
viewThemeUtils.platform.tintDrawable(requireContext(), R.drawable.ic_search_grey)
)
//NMC Customization
binding.emptyList.emptyListIcon.setImageResource(R.drawable.ic_search_empty)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ class TrashbinActivity :
recyclerView.setEmptyView(binding.emptyList.emptyListView)

binding.emptyList.emptyListView.visibility = View.GONE
binding.emptyList.emptyListIcon.setImageResource(R.drawable.ic_delete)
binding.emptyList.emptyListIcon.setImageResource(R.drawable.ic_list_empty_trashbin)
binding.emptyList.emptyListIcon.visibility = View.VISIBLE
binding.emptyList.emptyListViewHeadline.text = getString(R.string.trashbin_empty_headline)
binding.emptyList.emptyListViewText.text = getString(R.string.trashbin_empty_message)
Expand Down Expand Up @@ -306,7 +306,7 @@ class TrashbinActivity :
trashbinListAdapter?.setTrashbinFiles(trashbinFiles, true)
binding.swipeContainingList.isRefreshing = false
binding.loadingContent.visibility = View.GONE
binding.emptyList.emptyListIcon.setImageResource(R.drawable.ic_delete)
binding.emptyList.emptyListIcon.setImageResource(R.drawable.ic_list_empty_trashbin)
binding.emptyList.emptyListViewHeadline.text = getString(R.string.trashbin_empty_headline)
binding.emptyList.emptyListViewText.text = getString(R.string.trashbin_empty_message)
binding.list.visibility = View.VISIBLE
Expand Down
Loading

0 comments on commit 3b356ad

Please sign in to comment.