Skip to content

Commit

Permalink
Merge pull request #4518 from owncloud/feature/light_users
Browse files Browse the repository at this point in the history
[FEATURE REQUEST] oCIS Users light
  • Loading branch information
joragua authored Dec 4, 2024
2 parents 7faf3bd + 7908a14 commit 59f9378
Show file tree
Hide file tree
Showing 23 changed files with 366 additions and 138 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ ownCloud admins and users.
* Enhancement - Quota improvements from GraphAPI: [#4411](https://github.com/owncloud/android/issues/4411)
* Enhancement - Upgraded AGP version to 8.7.2: [#4478](https://github.com/owncloud/android/issues/4478)
* Enhancement - Added text labels for BottomNavigationView: [#4484](https://github.com/owncloud/android/issues/4484)
* Enhancement - OCIS Light Users: [#4490](https://github.com/owncloud/android/issues/4490)
* Enhancement - Enforce OIDC auth flow via branding: [#4500](https://github.com/owncloud/android/issues/4500)

## Details
Expand Down Expand Up @@ -94,6 +95,13 @@ ownCloud admins and users.
https://github.com/owncloud/android/issues/4484
https://github.com/owncloud/android/pull/4498

* Enhancement - OCIS Light Users: [#4490](https://github.com/owncloud/android/issues/4490)

OCIS light users (users without personal space) are now supported in the app

https://github.com/owncloud/android/issues/4490
https://github.com/owncloud/android/pull/4518

* Enhancement - Enforce OIDC auth flow via branding: [#4500](https://github.com/owncloud/android/issues/4500)

A new branded parameter `enforce_oidc` has been added to enforce the app to
Expand Down
6 changes: 6 additions & 0 deletions changelog/unreleased/4518
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Enhancement: oCIS Light Users

oCIS light users (users without personal space) are now supported in the app

https://github.com/owncloud/android/issues/4490
https://github.com/owncloud/android/pull/4518
13 changes: 12 additions & 1 deletion owncloudApp/src/main/java/com/owncloud/android/MainApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import com.owncloud.android.dependecyinjection.viewModelModule
import com.owncloud.android.domain.capabilities.usecases.GetStoredCapabilitiesUseCase
import com.owncloud.android.domain.spaces.model.OCSpace
import com.owncloud.android.domain.spaces.usecases.GetPersonalSpaceForAccountUseCase
import com.owncloud.android.domain.user.usecases.GetStoredQuotaUseCase
import com.owncloud.android.extensions.createNotificationChannel
import com.owncloud.android.lib.common.SingleSessionManager
import com.owncloud.android.presentation.authentication.AccountUtils
Expand Down Expand Up @@ -194,7 +195,17 @@ class MainApp : Application() {
}
}

spacesAllowed && personalSpace == null
val getStoredQuotaUseCase: GetStoredQuotaUseCase by inject()
val quota = withContext(CoroutineScope(CoroutinesDispatcherProvider().io).coroutineContext) {
getStoredQuotaUseCase(
GetStoredQuotaUseCase.Params(
accountName = account.name
)
)
}
val isLightUser = quota.getDataOrNull()?.available == -4L

spacesAllowed && personalSpace == null && !isLightUser
}

override fun onActivityStarted(activity: Activity) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ val viewModelModule = module {
viewModel { AuthenticationViewModel(get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get()) }
viewModel { MigrationViewModel(MainApp.dataFolder, get(), get(), get(), get(), get(), get(), get()) }
viewModel { TransfersViewModel(get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get(), get()) }
viewModel { ReceiveExternalFilesViewModel(get(), get(), get()) }
viewModel { ReceiveExternalFilesViewModel(get(), get(), get(), get()) }
viewModel { (accountName: String, showPersonalSpace: Boolean) ->
SpacesListViewModel(get(), get(), get(), get(), get(), accountName, showPersonalSpace)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,11 @@ class ManageAccountsAdapter(

private fun updateQuota(quotaText: TextView, quotaBar: ProgressBar, userQuota: UserQuota, context: Context) {
when {
userQuota.available == -4L -> { // Light users (oCIS)
quotaBar.visibility = View.GONE
quotaText.text = context.getString(R.string.drawer_unavailable_used_storage)
}

userQuota.available < 0 -> { // Pending, unknown or unlimited free storage. The progress bar is hid
quotaBar.visibility = View.GONE
quotaText.text = DisplayUtils.bytesToHumanReadable(userQuota.used, context, false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import androidx.lifecycle.viewModelScope
import com.owncloud.android.domain.user.model.UserQuota
import com.owncloud.android.domain.automaticuploads.model.AutomaticUploadsConfiguration
import com.owncloud.android.domain.automaticuploads.usecases.GetAutomaticUploadsConfigurationUseCase
import com.owncloud.android.domain.user.usecases.GetStoredQuotaUseCase
import com.owncloud.android.domain.user.usecases.GetUserQuotasAsStreamUseCase
import com.owncloud.android.domain.utils.Event
import com.owncloud.android.extensions.ViewModelExt.runUseCaseWithResult
Expand All @@ -40,11 +41,14 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext

class ManageAccountsViewModel(
private val accountProvider: AccountProvider,
private val removeLocalFilesForAccountUseCase: RemoveLocalFilesForAccountUseCase,
private val getAutomaticUploadsConfigurationUseCase: GetAutomaticUploadsConfigurationUseCase,
private val getStoredQuotaUseCase: GetStoredQuotaUseCase,
getUserQuotasAsStreamUseCase: GetUserQuotasAsStreamUseCase,
private val coroutinesDispatcherProvider: CoroutinesDispatcherProvider,
) : ViewModel() {
Expand Down Expand Up @@ -84,4 +88,11 @@ class ManageAccountsViewModel(
return accountName == automaticUploadsConfiguration?.pictureUploadsConfiguration?.accountName ||
accountName == automaticUploadsConfiguration?.videoUploadsConfiguration?.accountName
}

fun checkUserLight(accountName: String): Boolean = runBlocking(CoroutinesDispatcherProvider().io) {
val quota = withContext(CoroutinesDispatcherProvider().io) {
getStoredQuotaUseCase(GetStoredQuotaUseCase.Params(accountName))
}
quota.getDataOrNull()?.available == -4L
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* @author David González Verdugo
* @author Abel García de Prada
* @author Aitor Ballesteros Pavón
* @author Jorge Aguado Recio
*
* Copyright (C) 2024 ownCloud GmbH.
*
Expand Down Expand Up @@ -58,6 +59,7 @@ class DrawerViewModel(
accountName: String
) = runUseCaseWithResult(
coroutineDispatcher = coroutinesDispatcherProvider.io,
requiresConnection = false,
showLoading = true,
liveData = _userQuota,
useCase = getStoredQuotaUseCase,
Expand Down Expand Up @@ -105,4 +107,5 @@ class DrawerViewModel(
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* ownCloud Android client application
*
* @author Jorge Aguado Recio
*
* Copyright (C) 2024 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* 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 <http://www.gnu.org/licenses/>.
*/

package com.owncloud.android.presentation.files.filelist

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import com.owncloud.android.R
import com.owncloud.android.databinding.MainEmptyListFragmentBinding


class MainEmptyListFragment : Fragment() {

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

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = MainEmptyListFragmentBinding.inflate(inflater, container, false)
return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
binding.emptyDataParent.apply {
listEmptyDatasetIcon.setImageResource(R.drawable.ic_folder)
listEmptyDatasetTitle.setText(R.string.file_list_empty_title_all_files)
listEmptyDatasetSubTitle.setText(R.string.light_users_subtitle)
}
val titleToolbar = requireActivity().findViewById<TextView>(R.id.root_toolbar_title)
titleToolbar.apply {
setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0)
isClickable = false
}
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ class MainFileListFragment : Fragment(),
binding.recyclerViewMainFileList.adapter = fileListAdapter

// Set Swipe to refresh and its listener
binding.swipeRefreshMainFileList.isEnabled = mainFileListViewModel.fileListOption.value != FileListOption.AV_OFFLINE
binding.swipeRefreshMainFileList.setOnRefreshListener {
fileOperationsViewModel.performOperation(
FileOperation.RefreshFolderOperation(
Expand Down Expand Up @@ -317,7 +318,7 @@ class MainFileListFragment : Fragment(),
fileActions?.onCurrentFolderUpdated(currentFolderDisplayed, mainFileListViewModel.getSpace())
val fileListOption = mainFileListViewModel.fileListOption.value
val refreshFolderNeeded = fileListOption.isAllFiles() ||
(!fileListOption.isAllFiles() && currentFolderDisplayed.remotePath != ROOT_PATH)
(!fileListOption.isAllFiles() && currentFolderDisplayed.remotePath != ROOT_PATH && !fileListOption.isAvailableOffline())
if (refreshFolderNeeded) {
fileOperationsViewModel.performOperation(
FileOperation.RefreshFolderOperation(
Expand Down Expand Up @@ -609,29 +610,28 @@ class MainFileListFragment : Fragment(),
)
showOrHideEmptyView(fileListUiState)

fileListUiState.space?.let {
binding.spaceHeader.root.apply {
if (fileListUiState.space.isProject && fileListUiState.folderToDisplay?.remotePath == ROOT_PATH) {
isVisible = true
animate().translationY(0f).duration = 100
} else {
animate().translationY(-height.toFloat()).withEndAction { isVisible = false }
}

binding.spaceHeader.root.apply {
if (fileListUiState.space?.isProject == true && fileListUiState.folderToDisplay?.remotePath == ROOT_PATH) {
isVisible = true
animate().translationY(0f).duration = 100
} else {
animate().translationY(-height.toFloat()).withEndAction { isVisible = false }
}
}

val spaceSpecialImage = it.getSpaceSpecialImage()
if (spaceSpecialImage != null) {
binding.spaceHeader.spaceHeaderImage.load(
ThumbnailsRequester.getPreviewUriForSpaceSpecial(spaceSpecialImage),
ThumbnailsRequester.getCoilImageLoader()
) {
placeholder(R.drawable.ic_spaces)
error(R.drawable.ic_spaces)
}
val spaceSpecialImage = fileListUiState.space?.getSpaceSpecialImage()
if (spaceSpecialImage != null) {
binding.spaceHeader.spaceHeaderImage.load(
ThumbnailsRequester.getPreviewUriForSpaceSpecial(spaceSpecialImage),
ThumbnailsRequester.getCoilImageLoader()
) {
placeholder(R.drawable.ic_spaces)
error(R.drawable.ic_spaces)
}
binding.spaceHeader.spaceHeaderName.text = it.name
binding.spaceHeader.spaceHeaderSubtitle.text = it.description
}
binding.spaceHeader.spaceHeaderName.text = fileListUiState.space?.name
binding.spaceHeader.spaceHeaderSubtitle.text = fileListUiState.space?.description

actionMode?.invalidate()
}
Expand Down Expand Up @@ -810,8 +810,9 @@ class MainFileListFragment : Fragment(),
}

fun updateFileListOption(newFileListOption: FileListOption, file: OCFile) {
mainFileListViewModel.updateFolderToDisplay(file)
mainFileListViewModel.updateFileListOption(newFileListOption)
binding.swipeRefreshMainFileList.isEnabled = newFileListOption != FileListOption.AV_OFFLINE
mainFileListViewModel.updateFolderToDisplay(file)
showOrHideFab(newFileListOption, file)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ class ReleaseNotesViewModel(
subtitle = R.string.release_notes_4_5_0_subtitle_quota_improvements,
type = ReleaseNoteType.ENHANCEMENT
),
ReleaseNote(
title = R.string.release_notes_4_5_0_title_light_users,
subtitle = R.string.release_notes_4_5_0_subtitle_light_users,
type = ReleaseNoteType.ENHANCEMENT
),
)
}
}
Loading

0 comments on commit 59f9378

Please sign in to comment.