Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -285,10 +285,6 @@
<activity
android:name=".ui.activity.NotificationsActivity"
android:exported="false" />
<activity
android:name=".ui.activities.ActivitiesActivity"
android:configChanges="orientation|screenSize|keyboardHidden"
android:exported="false" />
<activity
android:name=".ui.activity.SyncedFoldersActivity"
android:exported="false" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
import com.owncloud.android.services.AccountManagerService;
import com.owncloud.android.services.OperationsService;
import com.owncloud.android.syncadapter.FileSyncService;
import com.owncloud.android.ui.activities.ActivitiesActivity;
import com.owncloud.android.ui.activity.BaseActivity;
import com.owncloud.android.ui.activity.ConflictsResolveActivity;
import com.owncloud.android.ui.activity.ContactsPreferenceActivity;
Expand Down Expand Up @@ -101,6 +100,7 @@
import com.owncloud.android.ui.dialog.TermsOfServiceDialog;
import com.owncloud.android.ui.dialog.ThemeSelectionDialog;
import com.owncloud.android.ui.dialog.setupEncryption.SetupEncryptionDialogFragment;
import com.owncloud.android.ui.fragment.ActivitiesFragment;
import com.owncloud.android.ui.fragment.ExtendedListFragment;
import com.owncloud.android.ui.fragment.FeatureFragment;
import com.owncloud.android.ui.fragment.FileDetailActivitiesFragment;
Expand Down Expand Up @@ -142,7 +142,7 @@
@Module
abstract class ComponentsModule {
@ContributesAndroidInjector
abstract ActivitiesActivity activitiesActivity();
abstract ActivitiesFragment activitiesFragment();

@ContributesAndroidInjector
abstract AuthenticatorActivity authenticatorActivity();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@
import com.owncloud.android.lib.resources.status.OCCapability;
import com.owncloud.android.lib.resources.users.GetUserInfoRemoteOperation;
import com.owncloud.android.operations.GetCapabilitiesOperation;
import com.owncloud.android.ui.activities.ActivitiesActivity;
import com.owncloud.android.ui.events.AccountRemovedEvent;
import com.owncloud.android.ui.events.ChangeMenuEvent;
import com.owncloud.android.ui.events.SearchEvent;
Expand Down Expand Up @@ -626,7 +625,7 @@ private void onNavigationItemClicked(final MenuItem menuItem) {
startActivity(TrashbinActivity.class, Intent.FLAG_ACTIVITY_CLEAR_TOP);
} else if (itemId == R.id.nav_activity) {
resetOnlyPersonalAndOnDevice();
startActivity(ActivitiesActivity.class, Intent.FLAG_ACTIVITY_CLEAR_TOP);
pushFragment(NavigatorScreen.Activities.INSTANCE);
} else if (itemId == R.id.nav_settings) {
resetOnlyPersonalAndOnDevice();
final Intent intent = new Intent(this, SettingsActivity.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,102 +2,102 @@
* Nextcloud - Android Client
*
* SPDX-FileCopyrightText: 2026 Alper Ozturk <alper.ozturk@nextcloud.com>
* SPDX-FileCopyrightText: 2018 Edvard Holst <edvard.holst@gmail.com>
* SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
package com.owncloud.android.ui.activities
package com.owncloud.android.ui.fragment

import android.content.Intent
import android.os.Bundle
import android.view.MenuItem
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.size
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.nextcloud.client.account.UserAccountManager
import com.nextcloud.client.network.ConnectivityService
import com.nextcloud.common.NextcloudClient
import com.owncloud.android.R
import com.owncloud.android.databinding.ActivityListLayoutBinding
import com.owncloud.android.databinding.FragmentActivitiesBinding
import com.owncloud.android.datamodel.OCFile
import com.owncloud.android.lib.common.utils.Log_OC
import com.owncloud.android.lib.resources.activities.model.RichObject
import com.owncloud.android.lib.resources.files.FileUtils
import com.owncloud.android.ui.activities.ActivitiesContract
import com.owncloud.android.ui.activities.ActivitiesPresenter
import com.owncloud.android.ui.activities.adapter.ActivityListAdapter
import com.owncloud.android.ui.activities.data.activities.ActivitiesRepository
import com.owncloud.android.ui.activities.data.files.FilesRepository
import com.owncloud.android.ui.activity.DrawerActivity
import com.owncloud.android.ui.activity.FileActivity
import com.owncloud.android.ui.activity.FileDisplayActivity
import com.owncloud.android.ui.activities.adapter.ActivityListAdapter
import com.owncloud.android.ui.interfaces.ActivityListInterface
import com.owncloud.android.ui.navigation.NavigatorActivity
import com.owncloud.android.ui.preview.PreviewImageActivity
import com.owncloud.android.ui.preview.PreviewImageFragment.Companion.canBePreviewed
import com.owncloud.android.utils.DisplayUtils
import java.util.function.Supplier
import com.owncloud.android.utils.theme.ViewThemeUtils
import javax.inject.Inject

@Suppress("MagicNumber")
class ActivitiesActivity :
DrawerActivity(),
class ActivitiesFragment :
Fragment(),
ActivityListInterface,
ActivitiesContract.View {
var binding: ActivityListLayoutBinding? = null
private var adapter: ActivityListAdapter? = null
private var lastGiven: Long = 0
private var isLoadingActivities = false
private var actionListener: ActivitiesContract.ActionListener? = null

@Inject
lateinit var activitiesRepository: ActivitiesRepository

@Inject
lateinit var viewThemeUtils: ViewThemeUtils

@Inject
lateinit var filesRepository: FilesRepository

@Inject
lateinit var connectivityService: ConnectivityService

override fun onCreate(savedInstanceState: Bundle?) {
Log_OC.v(TAG, "onCreate() start")
super.onCreate(savedInstanceState)

actionListener = ActivitiesPresenter(activitiesRepository, filesRepository, this)

binding = ActivityListLayoutBinding.inflate(layoutInflater)
setContentView(binding?.getRoot())
@Inject
lateinit var userAccountManager: UserAccountManager

setupToolbar()
private var _binding: FragmentActivitiesBinding? = null
private val binding get() = _binding!!

binding?.swipeContainingList?.let { viewThemeUtils.androidx.themeSwipeRefreshLayout(it) }
private var adapter: ActivityListAdapter? = null
private var lastGiven: Long = 0
private var isLoadingActivities = false
private var actionListener: ActivitiesContract.ActionListener? = null

setupDrawer(menuItemId)
updateActionBarTitleAndHomeButtonByString(getString(R.string.drawer_item_activities))
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
_binding = FragmentActivitiesBinding.inflate(inflater, container, false)
return binding.root
}

binding?.swipeContainingList?.setOnRefreshListener {
// We set lastGiven variable to undefined here since when manually refreshing
// activities data we want to clear the list and reset the pagination.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
actionListener = ActivitiesPresenter(activitiesRepository, filesRepository, this)
viewThemeUtils.androidx.themeSwipeRefreshLayout(binding.swipeContainingList)
binding.swipeContainingList.setOnRefreshListener {
lastGiven = ActivitiesContract.ActionListener.UNDEFINED.toLong()
actionListener?.loadActivities(lifecycleScope, lastGiven)
}
setupContent()
}

override fun getMenuItemId(): Int = R.id.nav_activity

@Suppress("MagicNumber")
private fun setupContent() {
binding?.emptyList?.emptyListIcon?.setImageResource(R.drawable.ic_activity)
binding.emptyList.emptyListIcon.setImageResource(R.drawable.ic_activity)

adapter = ActivityListAdapter(
this,
requireActivity(),
userAccountManager,
this,
false,
viewThemeUtils
)
binding?.list?.setAdapter(adapter)

val layoutManager = LinearLayoutManager(this)
binding.list.adapter = adapter

binding?.list?.run {
val layoutManager = LinearLayoutManager(requireContext())
binding.list.run {
setLayoutManager(layoutManager)
addOnScrollListener(getOnScrollListener(layoutManager))
}
Expand All @@ -108,113 +108,99 @@ class ActivitiesActivity :
private fun getOnScrollListener(layoutManager: LinearLayoutManager) = object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)

val visibleItemCount = recyclerView.size
val totalItemCount = layoutManager.getItemCount()
val totalItemCount = layoutManager.itemCount
val firstVisibleItemIndex = layoutManager.findFirstVisibleItemPosition()

// synchronize loading state when item count changes
if (!isLoadingActivities && (totalItemCount - visibleItemCount) <= (firstVisibleItemIndex + 5) &&
if (!isLoadingActivities &&
(totalItemCount - visibleItemCount) <= (firstVisibleItemIndex + 5) &&
lastGiven > 0
) {
// Almost reached the end, continue to load new activities
actionListener?.loadActivities(lifecycleScope, lastGiven)
}
}
}

override fun onOptionsItemSelected(item: MenuItem): Boolean = if (item.itemId == android.R.id.home) {
if (isDrawerOpen) {
closeDrawer()
} else {
openDrawer()
}
true
} else {
Log_OC.w(TAG, "Unknown menu item triggered")
super.onOptionsItemSelected(item)
}

override fun onResume() {
super.onResume()
highlightNavigationViewItem(menuItemId)
actionListener?.onResume()
setupContent()
}

override fun onStop() {
super.onStop()
actionListener?.onStop()
}

override fun onActivityClicked(richObject: RichObject) {
val path = FileUtils.PATH_SEPARATOR + richObject.path
actionListener?.openActivity(path, this)
val baseActivity = requireActivity() as NavigatorActivity
actionListener?.openActivity(path, baseActivity)
}

override fun showActivities(activities: List<Any>, client: NextcloudClient, lastGiven: Long) {
val clear = this.lastGiven == ActivitiesContract.ActionListener.UNDEFINED.toLong()
adapter?.setActivityItems(activities, client, clear)
this.lastGiven = lastGiven

// Hide the recyclerView if list is empty
if (adapter?.isEmpty() == true) {
showEmptyContent(
getString(R.string.activities_no_results_headline),
getString(R.string.activities_no_results_message)
)
binding?.loadingContent?.visibility = View.GONE
binding?.list?.visibility = View.GONE
binding.loadingContent.visibility = View.GONE
binding.list.visibility = View.GONE
} else {
binding?.emptyList?.emptyListView?.visibility = View.GONE
binding?.loadingContent?.visibility = View.GONE
binding?.list?.visibility = View.VISIBLE
binding.emptyList.emptyListView.visibility = View.GONE
binding.loadingContent.visibility = View.GONE
binding.list.visibility = View.VISIBLE
}
}

override fun showActivitiesLoadError(error: String) {
connectivityService.isNetworkAndServerAvailable {
if (it) {
DisplayUtils.showSnackMessage(this, error)
DisplayUtils.showSnackMessage(requireView(), error)
} else {
showEmptyContent(
getString(R.string.server_not_reachable),
getString(R.string.server_not_reachable_content)
)
binding?.emptyList?.emptyListIcon?.setImageResource(R.drawable.ic_sync_off)
binding.emptyList.emptyListIcon.setImageResource(R.drawable.ic_sync_off)
}
}
}

override fun showActivityDetailUI(ocFile: OCFile) {
val user = userAccountManager.user
val intent = if (canBePreviewed(ocFile)) {
Intent(baseContext, PreviewImageActivity::class.java)
Intent(requireContext(), PreviewImageActivity::class.java)
} else {
Intent(baseContext, FileDisplayActivity::class.java)
Intent(requireContext(), FileDisplayActivity::class.java)
}.apply {
putExtra(FileActivity.EXTRA_FILE, ocFile)
putExtra(
FileActivity.EXTRA_USER,
user.orElseThrow(Supplier { RuntimeException() })
)
putExtra(FileActivity.EXTRA_USER, user)
}

startActivity(intent)
}

override fun showActivityDetailUIIsNull() {
DisplayUtils.showSnackMessage(this, R.string.file_not_found)
DisplayUtils.showSnackMessage(requireView(), R.string.file_not_found)
}

override fun showActivityDetailError(error: String) {
DisplayUtils.showSnackMessage(this, error)
DisplayUtils.showSnackMessage(requireView(), error)
}

override fun showLoadingMessage() {
binding?.emptyList?.emptyListView?.visibility = View.GONE
binding.emptyList.emptyListView.visibility = View.GONE
}

override fun showEmptyContent(headline: String, message: String) {
binding?.run {
binding.run {
emptyList.emptyListViewHeadline.text = headline
emptyList.emptyListViewText.text = message
loadingContent.visibility = View.GONE
emptyList.emptyListIcon.setVisibility(View.VISIBLE)
emptyList.emptyListIcon.visibility = View.VISIBLE
emptyList.emptyListViewHeadline.visibility = View.VISIBLE
emptyList.emptyListViewText.visibility = View.VISIBLE
emptyList.emptyListView.visibility = View.VISIBLE
Expand All @@ -224,16 +210,12 @@ class ActivitiesActivity :
override fun setProgressIndicatorState(isActive: Boolean) {
isLoadingActivities = isActive
if (adapter?.isEmpty() == false) {
binding?.swipeContainingList?.post { binding?.swipeContainingList?.isRefreshing = isActive }
binding.swipeContainingList.post { binding.swipeContainingList.isRefreshing = isActive }
}
}

override fun onStop() {
super.onStop()
actionListener?.onStop()
}

companion object {
private val TAG: String = ActivitiesActivity::class.java.getSimpleName()
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
Loading
Loading