Skip to content

Commit 6fe414e

Browse files
committed
Albums functionality
1 parent 104d1e6 commit 6fe414e

File tree

63 files changed

+6301
-66
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+6301
-66
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,9 @@
601601
android:launchMode="singleTop"
602602
android:theme="@style/Theme.ownCloud.Dialog.NoTitle"
603603
android:windowSoftInputMode="adjustResize" />
604+
<activity
605+
android:name=".ui.activity.AlbumsPickerActivity"
606+
android:exported="false" />
604607
<activity
605608
android:name=".ui.activity.ShareActivity"
606609
android:exported="false"

app/src/main/java/com/nextcloud/client/di/ComponentsModule.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.nextcloud.ui.ImageDetailFragment;
3333
import com.nextcloud.ui.SetOnlineStatusBottomSheet;
3434
import com.nextcloud.ui.SetStatusMessageBottomSheet;
35+
import com.nextcloud.ui.albumItemActions.AlbumItemActionsBottomSheet;
3536
import com.nextcloud.ui.composeActivity.ComposeActivity;
3637
import com.nextcloud.ui.fileactions.FileActionsBottomSheet;
3738
import com.nextcloud.ui.trashbinFileActions.TrashbinFileActionsBottomSheet;
@@ -82,6 +83,7 @@
8283
import com.owncloud.android.ui.dialog.ChooseTemplateDialogFragment;
8384
import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
8485
import com.owncloud.android.ui.dialog.ConflictsResolveDialog;
86+
import com.owncloud.android.ui.dialog.CreateAlbumDialogFragment;
8587
import com.owncloud.android.ui.dialog.CreateFolderDialogFragment;
8688
import com.owncloud.android.ui.dialog.ExpirationDatePickerDialogFragment;
8789
import com.owncloud.android.ui.dialog.IndeterminateProgressDialog;
@@ -114,6 +116,9 @@
114116
import com.owncloud.android.ui.fragment.OCFileListFragment;
115117
import com.owncloud.android.ui.fragment.SharedListFragment;
116118
import com.owncloud.android.ui.fragment.UnifiedSearchFragment;
119+
import com.owncloud.android.ui.fragment.albums.AlbumItemsFragment;
120+
import com.owncloud.android.ui.fragment.albums.AlbumsFragment;
121+
import com.owncloud.android.ui.activity.AlbumsPickerActivity;
117122
import com.owncloud.android.ui.fragment.contactsbackup.BackupFragment;
118123
import com.owncloud.android.ui.fragment.contactsbackup.BackupListFragment;
119124
import com.owncloud.android.ui.preview.FileDownloadFragment;
@@ -505,4 +510,19 @@ abstract class ComponentsModule {
505510

506511
@ContributesAndroidInjector
507512
abstract SetStatusMessageBottomSheet setStatusMessageBottomSheet();
513+
514+
@ContributesAndroidInjector
515+
abstract AlbumsPickerActivity albumsPickerActivity();
516+
517+
@ContributesAndroidInjector
518+
abstract CreateAlbumDialogFragment createAlbumDialogFragment();
519+
520+
@ContributesAndroidInjector
521+
abstract AlbumsFragment albumsFragment();
522+
523+
@ContributesAndroidInjector
524+
abstract AlbumItemsFragment albumItemsFragment();
525+
526+
@ContributesAndroidInjector
527+
abstract AlbumItemActionsBottomSheet albumItemActionsBottomSheet();
508528
}

app/src/main/java/com/nextcloud/client/jobs/BackgroundJobFactory.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import com.nextcloud.client.jobs.download.FileDownloadWorker
2828
import com.nextcloud.client.jobs.metadata.MetadataWorker
2929
import com.nextcloud.client.jobs.offlineOperations.OfflineOperationsWorker
3030
import com.nextcloud.client.jobs.folderDownload.FolderDownloadWorker
31+
import com.nextcloud.client.jobs.upload.AlbumFileUploadWorker
3132
import com.nextcloud.client.jobs.upload.FileUploadWorker
3233
import com.nextcloud.client.logger.Logger
3334
import com.nextcloud.client.network.ConnectivityService
@@ -97,6 +98,7 @@ class BackgroundJobFactory @Inject constructor(
9798
FilesExportWork::class -> createFilesExportWork(context, workerParameters)
9899
FileUploadWorker::class -> createFilesUploadWorker(context, workerParameters)
99100
FileDownloadWorker::class -> createFilesDownloadWorker(context, workerParameters)
101+
AlbumFileUploadWorker::class -> createAlbumsFilesUploadWorker(context, workerParameters)
100102
GeneratePdfFromImagesWork::class -> createPDFGenerateWork(context, workerParameters)
101103
HealthStatusWork::class -> createHealthStatusWork(context, workerParameters)
102104
TestJob::class -> createTestJob(context, workerParameters)
@@ -249,6 +251,20 @@ class BackgroundJobFactory @Inject constructor(
249251
params
250252
)
251253

254+
private fun createAlbumsFilesUploadWorker(context: Context, params: WorkerParameters): AlbumFileUploadWorker =
255+
AlbumFileUploadWorker(
256+
uploadsStorageManager,
257+
connectivityService,
258+
powerManagementService,
259+
accountManager,
260+
viewThemeUtils.get(),
261+
localBroadcastManager.get(),
262+
backgroundJobManager.get(),
263+
preferences,
264+
context,
265+
params
266+
)
267+
252268
private fun createPDFGenerateWork(context: Context, params: WorkerParameters): GeneratePdfFromImagesWork =
253269
GeneratePdfFromImagesWork(
254270
appContext = context,

app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManager.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,12 @@ interface BackgroundJobManager {
138138
fun startNotificationJob(subject: String, signature: String)
139139
fun startAccountRemovalJob(accountName: String, remoteWipe: Boolean)
140140
fun startFilesUploadJob(user: User, uploadIds: LongArray, showSameFileAlreadyExistsNotification: Boolean)
141+
fun startAlbumFilesUploadJob(
142+
user: User,
143+
uploadIds: LongArray,
144+
albumName: String,
145+
showSameFileAlreadyExistsNotification: Boolean
146+
)
141147
fun getFileUploads(user: User): LiveData<List<JobInfo>>
142148
fun cancelFilesUploadJob(user: User)
143149
fun isStartFileUploadJobScheduled(accountName: String): Boolean

app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManagerImpl.kt

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import com.nextcloud.client.jobs.download.FileDownloadWorker
3131
import com.nextcloud.client.jobs.folderDownload.FolderDownloadWorker
3232
import com.nextcloud.client.jobs.metadata.MetadataWorker
3333
import com.nextcloud.client.jobs.offlineOperations.OfflineOperationsWorker
34+
import com.nextcloud.client.jobs.upload.AlbumFileUploadWorker
3435
import com.nextcloud.client.jobs.upload.FileUploadHelper
3536
import com.nextcloud.client.jobs.upload.FileUploadWorker
3637
import com.nextcloud.client.preferences.AppPreferences
@@ -85,6 +86,7 @@ internal class BackgroundJobManagerImpl(
8586
const val JOB_NOTIFICATION = "notification"
8687
const val JOB_ACCOUNT_REMOVAL = "account_removal"
8788
const val JOB_FILES_UPLOAD = "files_upload"
89+
const val ALBUM_JOB_FILES_UPLOAD = "album_files_upload"
8890
const val JOB_FOLDER_DOWNLOAD = "folder_download"
8991
const val JOB_FILES_DOWNLOAD = "files_download"
9092
const val JOB_PDF_GENERATION = "pdf_generation"
@@ -638,6 +640,7 @@ internal class BackgroundJobManagerImpl(
638640
}
639641

640642
private fun startFileUploadJobTag(accountName: String): String = JOB_FILES_UPLOAD + accountName
643+
private fun startAlbumsFileUploadJobTag(accountName: String): String = ALBUM_JOB_FILES_UPLOAD + accountName
641644

642645
override fun isStartFileUploadJobScheduled(accountName: String): Boolean =
643646
workManager.isWorkScheduled(startFileUploadJobTag(accountName))
@@ -701,6 +704,68 @@ internal class BackgroundJobManagerImpl(
701704
}
702705
}
703706

707+
/**
708+
* This method supports uploading and copying selected files to Album
709+
*
710+
* @param user The user for whom the upload job is being created.
711+
* @param uploadIds Array of upload IDs to be processed. These IDs originate from multiple sources
712+
* and cannot be determined directly from the account name or a single function
713+
* within the worker.
714+
* @param albumName Album on which selected files should be copy after upload
715+
*/
716+
override fun startAlbumFilesUploadJob(
717+
user: User,
718+
uploadIds: LongArray,
719+
albumName: String,
720+
showSameFileAlreadyExistsNotification: Boolean
721+
) {
722+
defaultDispatcherScope.launch {
723+
val batchSize = FileUploadHelper.MAX_FILE_COUNT
724+
val batches = uploadIds.toList().chunked(batchSize)
725+
val tag = startAlbumsFileUploadJobTag(user.accountName)
726+
727+
val constraints = Constraints.Builder()
728+
.setRequiredNetworkType(NetworkType.CONNECTED)
729+
.build()
730+
731+
val dataBuilder = Data.Builder()
732+
.putBoolean(
733+
FileUploadWorker.SHOW_SAME_FILE_ALREADY_EXISTS_NOTIFICATION,
734+
showSameFileAlreadyExistsNotification
735+
)
736+
.putString(FileUploadWorker.ACCOUNT, user.accountName)
737+
.putInt(FileUploadWorker.TOTAL_UPLOAD_SIZE, uploadIds.size)
738+
.putString(AlbumFileUploadWorker.ALBUM_NAME, albumName)
739+
740+
val workRequests = batches.mapIndexed { index, batch ->
741+
dataBuilder
742+
.putLongArray(FileUploadWorker.UPLOAD_IDS, batch.toLongArray())
743+
.putInt(FileUploadWorker.CURRENT_BATCH_INDEX, index)
744+
745+
oneTimeRequestBuilder(AlbumFileUploadWorker::class, ALBUM_JOB_FILES_UPLOAD, user)
746+
.addTag(tag)
747+
.setInputData(dataBuilder.build())
748+
.setConstraints(constraints)
749+
.build()
750+
}
751+
752+
// Chain the work requests sequentially
753+
if (workRequests.isNotEmpty()) {
754+
var workChain = workManager.beginUniqueWork(
755+
tag,
756+
ExistingWorkPolicy.APPEND_OR_REPLACE,
757+
workRequests.first()
758+
)
759+
760+
workRequests.drop(1).forEach { request ->
761+
workChain = workChain.then(request)
762+
}
763+
764+
workChain.enqueue()
765+
}
766+
}
767+
}
768+
704769
private fun startFileDownloadJobTag(user: User, fileId: Long): String =
705770
JOB_FOLDER_DOWNLOAD + user.accountName + fileId
706771

0 commit comments

Comments
 (0)