Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
090cce9
Albums functionality.
surinder-tsys Jun 2, 2025
46839b9
Rename .java to .kt
surinder-tsys Jun 6, 2025
9539858
Code refactoring and operation migrated to kotlin
surinder-tsys Jun 6, 2025
bd2dcb2
Fix -> video click event, overflow menu item hide and theming add menu
surinder-tsys Jun 6, 2025
6670d1f
Fix: preview album items
surinder-tsys Jul 11, 2025
193efb4
upload files to album, hide video overlay icon, minor ui and bug fixes
surinder-tsys Jan 22, 2026
c10eea4
wip
tobiasKaminsky Jan 23, 2026
27574d2
Albums functionality.
surinder-tsys Jun 2, 2025
ff3fa29
Rename .java to .kt
surinder-tsys Jun 6, 2025
97c7c75
Code refactoring and operation migrated to kotlin
surinder-tsys Jun 6, 2025
6beace7
upload files to album, hide video overlay icon, minor ui and bug fixes
surinder-tsys Jan 22, 2026
b97e10c
small fix
tobiasKaminsky Jan 26, 2026
e366f05
code fixes
surinder-tsys Jan 29, 2026
1d91d34
album upload worker state handled via localbroadcastmanager
surinder-tsys Jan 30, 2026
5e43d5d
simplify upload file calls
alperozturk96 Feb 2, 2026
e7226b4
separate worker parameters
alperozturk96 Feb 2, 2026
88c3c09
separate params
alperozturk96 Feb 2, 2026
0de1ad0
simplify album fragment
alperozturk96 Feb 2, 2026
9362e9c
use optional generic function to access fragment
alperozturk96 Feb 3, 2026
a1a0a86
fix code analytics, simplify
alperozturk96 Feb 3, 2026
0ffdfb5
m3 card
alperozturk96 Feb 19, 2026
af21a2b
m3 card
alperozturk96 Feb 19, 2026
ddd5876
use fab
alperozturk96 Feb 19, 2026
397c99b
use action bottom sheet for album item actions
alperozturk96 Feb 19, 2026
253a0bb
use action bottom sheet for album item actions
alperozturk96 Feb 19, 2026
df4004a
fix fab button appereance
alperozturk96 Feb 20, 2026
fcc1da2
fix git conflict
alperozturk96 Feb 26, 2026
561259f
small typo fixes
alperozturk96 Feb 26, 2026
1a9fdac
use outlined card
alperozturk96 Feb 26, 2026
2f86614
album items fragment code cleanup
alperozturk96 Feb 26, 2026
45d3c20
fix(spotbugs): NAB: Needless Autoboxing
alperozturk96 Feb 26, 2026
6659336
fix menu item highlighting
alperozturk96 Feb 26, 2026
6301c1b
adopt overlay manager
alperozturk96 Mar 18, 2026
22202dd
add albumOperationListener
alperozturk96 Mar 26, 2026
91f3d36
rebased with master
surinder-tsys Apr 30, 2026
3878bf1
Albums functionality.
surinder-tsys Jun 2, 2025
27d069a
upload files to album, hide video overlay icon, minor ui and bug fixes
surinder-tsys Jan 22, 2026
f499f52
wip
alperozturk96 Aug 11, 2026
35b2c26
wip
alperozturk96 Aug 11, 2026
88e2430
wip
alperozturk96 Aug 11, 2026
962c495
wip
alperozturk96 Aug 11, 2026
3c1d67d
feat(albums): add link sharing and add-to-album
surinder-tsys Aug 11, 2026
5966424
wip
alperozturk96 Aug 11, 2026
038c296
refactor album sharing bottom sheet
alperozturk96 Aug 11, 2026
f6b0c26
wip
alperozturk96 Aug 11, 2026
d619684
wip
alperozturk96 Aug 12, 2026
e901089
wip
alperozturk96 Aug 12, 2026
a192a60
introduce ThumbnailArguments
alperozturk96 Aug 12, 2026
cab5d3a
introduce ThumbnailArguments
alperozturk96 Aug 12, 2026
8e1d928
use thread safe CopyOnWriteArrayList
alperozturk96 Aug 12, 2026
c6d68b3
use empty state
alperozturk96 Aug 12, 2026
21a13da
unify column count logic
alperozturk96 Aug 12, 2026
692974d
unify column count logic
alperozturk96 Aug 12, 2026
b717f9f
remove unused orientation logic
alperozturk96 Aug 12, 2026
2bf089f
wip
alperozturk96 Aug 12, 2026
34635c1
wip
alperozturk96 Aug 12, 2026
7c5d164
wip
alperozturk96 Aug 12, 2026
d663aa2
wip
alperozturk96 Aug 12, 2026
2f418d8
wip
alperozturk96 Aug 12, 2026
94bfc46
wip
alperozturk96 Aug 12, 2026
91804e6
wip
alperozturk96 Aug 12, 2026
ec185da
wip
alperozturk96 Aug 12, 2026
11047c7
wip
alperozturk96 Aug 12, 2026
80c5aba
wip
alperozturk96 Aug 14, 2026
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
5 changes: 4 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Nextcloud - Android Client
~
~ SPDX-FileCopyrightText: 2024 TSI-mc <surinder.kumar@t-systems.com>
~ SPDX-FileCopyrightText: 2024-2025 TSI-mc <surinder.kumar@t-systems.com>
~ SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
~ SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
-->
Expand Down Expand Up @@ -626,6 +626,9 @@
android:launchMode="singleTop"
android:theme="@style/Theme.ownCloud.Dialog.NoTitle"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".ui.activity.AlbumsPickerActivity"
android:exported="false" />
<activity
android:name=".ui.activity.ShareActivity"
android:exported="false"
Expand Down
26 changes: 25 additions & 1 deletion app/src/main/java/com/nextcloud/client/di/ComponentsModule.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Nextcloud - Android Client
*
* SPDX-FileCopyrightText: 2024 TSI-mc <surinder.kumar@t-systems.com>
* SPDX-FileCopyrightText: 2024-2026 TSI-mc <surinder.kumar@t-systems.com>
* SPDX-FileCopyrightText: 2020 Chris Narkiewicz <hello@ezaquarii.com>
* SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
*/
Expand Down Expand Up @@ -31,6 +31,7 @@
import com.nextcloud.ui.fileInfo.FileInfoFragment;
import com.nextcloud.ui.SetOnlineStatusBottomSheet;
import com.nextcloud.ui.SetStatusMessageBottomSheet;
import com.nextcloud.ui.albumItemActions.AlbumItemActionsBottomSheet;
import com.nextcloud.ui.composeActivity.ComposeActivity;
import com.nextcloud.ui.fileactions.FileActionsBottomSheet;
import com.nextcloud.ui.trashbinFileActions.TrashbinFileActionsBottomSheet;
Expand All @@ -46,6 +47,7 @@
import com.owncloud.android.services.AccountManagerService;
import com.owncloud.android.services.OperationsService;
import com.owncloud.android.syncadapter.FileSyncService;
import com.owncloud.android.ui.activity.AlbumsPickerActivity;
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 @@ -79,6 +81,7 @@
import com.owncloud.android.ui.dialog.ChooseTemplateDialogFragment;
import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
import com.owncloud.android.ui.dialog.ConflictsResolveDialog;
import com.owncloud.android.ui.dialog.CreateAlbumDialogFragment;
import com.owncloud.android.ui.dialog.CreateFolderDialogFragment;
import com.owncloud.android.ui.dialog.ExpirationDatePickerDialogFragment;
import com.owncloud.android.ui.dialog.IndeterminateProgressDialog;
Expand Down Expand Up @@ -113,6 +116,9 @@
import com.owncloud.android.ui.fragment.OCFileListFragment;
import com.owncloud.android.ui.fragment.SharedListFragment;
import com.owncloud.android.ui.fragment.UnifiedSearchFragment;
import com.owncloud.android.ui.fragment.albums.AlbumItemsFragment;
import com.owncloud.android.ui.fragment.albums.bottomsheet.AlbumSharingBottomSheet;
import com.owncloud.android.ui.fragment.albums.AlbumsFragment;
import com.owncloud.android.ui.fragment.community.CommunityFragment;
import com.owncloud.android.ui.fragment.contactsbackup.BackupFragment;
import com.owncloud.android.ui.fragment.contactsbackup.BackupListFragment;
Expand Down Expand Up @@ -512,4 +518,22 @@ abstract class ComponentsModule {

@ContributesAndroidInjector
abstract CommunityFragment communityFragment();

@ContributesAndroidInjector
abstract AlbumsPickerActivity albumsPickerActivity();

@ContributesAndroidInjector
abstract CreateAlbumDialogFragment createAlbumDialogFragment();

@ContributesAndroidInjector
abstract AlbumsFragment albumsFragment();

@ContributesAndroidInjector
abstract AlbumItemsFragment albumItemsFragment();

@ContributesAndroidInjector
abstract AlbumItemActionsBottomSheet albumItemActionsBottomSheet();

@ContributesAndroidInjector
abstract AlbumSharingBottomSheet albumSharingBottomSheet();
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import com.nextcloud.client.jobs.BackgroundJobManager
import com.nextcloud.client.jobs.upload.FileUploadHelper
import com.nextcloud.client.jobs.upload.FileUploadWorker
import com.nextcloud.client.logger.Logger
import com.nextcloud.model.OCUploadLocalPathData
import com.owncloud.android.datamodel.OCFile
import com.owncloud.android.files.services.NameCollisionPolicy
import com.owncloud.android.operations.UploadFileOperation
Expand Down Expand Up @@ -166,17 +167,8 @@ class DocumentScanViewModel @Inject constructor(
uploadFolder + OCFile.PATH_SEPARATOR + File(it).name
}.toTypedArray()

FileUploadHelper.instance().uploadNewFiles(
currentAccountProvider.user,
pageList.toTypedArray(),
uploadPaths,
FileUploadWorker.LOCAL_BEHAVIOUR_DELETE,
true,
UploadFileOperation.CREATED_BY_USER,
false,
false,
NameCollisionPolicy.ASK_USER
)
val data = OCUploadLocalPathData.forDocument(currentAccountProvider.user, pageList.toTypedArray(), uploadPaths)
FileUploadHelper.instance().uploadNewFiles(data)
}

fun onExportCanceled() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import com.nextcloud.client.account.UserAccountManager
import com.nextcloud.client.jobs.upload.FileUploadHelper
import com.nextcloud.client.jobs.upload.FileUploadWorker
import com.nextcloud.client.logger.Logger
import com.nextcloud.model.OCUploadLocalPathData
import com.owncloud.android.R
import com.owncloud.android.datamodel.OCFile
import com.owncloud.android.files.services.NameCollisionPolicy
Expand Down Expand Up @@ -108,18 +109,8 @@ class GeneratePdfFromImagesWork(
private fun uploadFile(user: User, uploadFolder: String, pdfPath: String) {
val uploadPath = uploadFolder + OCFile.PATH_SEPARATOR + File(pdfPath).name

FileUploadHelper().uploadNewFiles(
user,
arrayOf(pdfPath),
arrayOf(uploadPath),
// MIME type will be detected from file name
FileUploadWorker.LOCAL_BEHAVIOUR_DELETE,
true,
UploadFileOperation.CREATED_BY_USER,
false,
false,
NameCollisionPolicy.ASK_USER
)
val data = OCUploadLocalPathData.forDocument(user, arrayOf(pdfPath), arrayOf(uploadPath))
FileUploadHelper().uploadNewFiles(data)
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import com.canhub.cropper.CropImageView
import com.nextcloud.client.di.Injectable
import com.nextcloud.client.jobs.upload.FileUploadHelper
import com.nextcloud.client.jobs.upload.FileUploadWorker
import com.nextcloud.model.OCUploadLocalPathData
import com.nextcloud.utils.extensions.getParcelableArgument
import com.owncloud.android.R
import com.owncloud.android.databinding.ActivityEditImageBinding
Expand Down Expand Up @@ -95,17 +96,18 @@ class EditImageActivity :
resultUri?.substring(resultUri.lastIndexOf('.'))

resultUri?.let {
FileUploadHelper().uploadNewFiles(
val data = OCUploadLocalPathData(
user = storageManager.user,
localPaths = arrayOf(it),
remotePaths = arrayOf(file.parentRemotePath + File.separator + newFileName),
createRemoteFolder = false,
createdBy = UploadFileOperation.CREATED_BY_USER,
creationType = UploadFileOperation.CREATED_BY_USER,
requiresWifi = false,
requiresCharging = false,
nameCollisionPolicy = NameCollisionPolicy.RENAME,
collisionPolicy = NameCollisionPolicy.RENAME,
localBehavior = FileUploadWorker.LOCAL_BEHAVIOUR_DELETE
)
FileUploadHelper().uploadNewFiles(data)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Nextcloud - Android Client
*
* SPDX-FileCopyrightText: 2020 Chris Narkiewicz <hello@ezaquarii.com>
* SPDX-FileCopyrightText: 2026 TSI-mc <surinder.kumar@t-systems.com>
* SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
*/
package com.nextcloud.client.jobs
Expand Down Expand Up @@ -29,6 +30,7 @@ import com.nextcloud.client.jobs.download.FileDownloadWorker
import com.nextcloud.client.jobs.folderDownload.FolderDownloadWorker
import com.nextcloud.client.jobs.metadata.MetadataWorker
import com.nextcloud.client.jobs.offlineOperations.OfflineOperationsWorker
import com.nextcloud.client.jobs.upload.AlbumFileUploadWorker
import com.nextcloud.client.jobs.upload.FileUploadWorker
import com.nextcloud.client.logger.Logger
import com.nextcloud.client.network.ConnectivityService
Expand Down Expand Up @@ -99,6 +101,7 @@ class BackgroundJobFactory @Inject constructor(
CalendarImportWork::class -> createCalendarImportWork(context, workerParameters)
FilesExportWork::class -> createFilesExportWork(context, workerParameters)
FileUploadWorker::class -> createFilesUploadWorker(context, workerParameters)
AlbumFileUploadWorker::class -> createAlbumsFilesUploadWorker(context, workerParameters)
FileDownloadWorker::class -> createFilesDownloadWorker(context, workerParameters)
GeneratePdfFromImagesWork::class -> createPDFGenerateWork(context, workerParameters)
HealthStatusWork::class -> createHealthStatusWork(context, workerParameters)
Expand Down Expand Up @@ -262,6 +265,20 @@ class BackgroundJobFactory @Inject constructor(
params
)

private fun createAlbumsFilesUploadWorker(context: Context, params: WorkerParameters): AlbumFileUploadWorker =
AlbumFileUploadWorker(
uploadsStorageManager,
connectivityService,
powerManagementService,
accountManager,
viewThemeUtils.get(),
localBroadcastManager.get(),
backgroundJobManager.get(),
preferences,
context,
params
)

private fun createPDFGenerateWork(context: Context, params: WorkerParameters): GeneratePdfFromImagesWork =
GeneratePdfFromImagesWork(
appContext = context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Nextcloud - Android Client
*
* SPDX-FileCopyrightText: 2020 Chris Narkiewicz <hello@ezaquarii.com>
* SPDX-FileCopyrightText: 2026 TSI-mc <surinder.kumar@t-systems.com>
* SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
*/
package com.nextcloud.client.jobs
Expand Down Expand Up @@ -137,6 +138,7 @@ interface BackgroundJobManager {
showSameFileAlreadyExistsNotification: Boolean,
skipAutoUploadCheck: Boolean = false
)
fun startAlbumFilesUploadJob(user: User, uploadIds: LongArray, albumName: String)
fun getFileUploads(user: User): LiveData<List<JobInfo>>
fun cancelFilesUploadJob(user: User)
fun isStartFileUploadJobScheduled(accountName: String): Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import com.nextcloud.client.jobs.download.FileDownloadWorker
import com.nextcloud.client.jobs.folderDownload.FolderDownloadWorker
import com.nextcloud.client.jobs.metadata.MetadataWorker
import com.nextcloud.client.jobs.offlineOperations.OfflineOperationsWorker
import com.nextcloud.client.jobs.upload.AlbumFileUploadWorker
import com.nextcloud.client.jobs.upload.FileUploadHelper
import com.nextcloud.client.jobs.upload.FileUploadWorker
import com.nextcloud.client.jobs.worker.WorkerFilesPayload
Expand Down Expand Up @@ -117,6 +118,7 @@ internal class BackgroundJobManagerImpl(
const val OFFLINE_OPERATIONS_PERIODIC_JOB_INTERVAL_MINUTES = 5L
const val DEFAULT_IMMEDIATE_JOB_DELAY_SEC = 3L
const val DEFAULT_BACKOFF_CRITERIA_DELAY_SEC = 300L
const val ALBUM_JOB_FILES_UPLOAD = "album_files_upload"

private const val KEEP_LOG_MILLIS = 1000 * 60 * 60 * 24 * 3L

Expand Down Expand Up @@ -676,6 +678,61 @@ internal class BackgroundJobManagerImpl(
}
}

private fun startAlbumsFileUploadJobTag(accountName: String): String = ALBUM_JOB_FILES_UPLOAD + accountName

/**
* This method supports uploading and copying selected files to Album
*
* @param user The user for whom the upload job is being created.
* @param uploadIds Array of upload IDs to be processed. These IDs originate from multiple sources
* and cannot be determined directly from the account name or a single function
* within the worker.
* @param albumName Album on which selected files should be copy after upload
*/
override fun startAlbumFilesUploadJob(user: User, uploadIds: LongArray, albumName: String) {
defaultDispatcherScope.launch {
val batchSize = FileUploadHelper.MAX_FILE_COUNT
val batches = uploadIds.toList().chunked(batchSize)
val tag = startAlbumsFileUploadJobTag(user.accountName)

val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()

val dataBuilder = Data.Builder()
.putString(AlbumFileUploadWorker.ACCOUNT, user.accountName)
.putInt(AlbumFileUploadWorker.TOTAL_UPLOAD_SIZE, uploadIds.size)
.putString(AlbumFileUploadWorker.ALBUM_NAME, albumName)

val workRequests = batches.mapIndexed { index, batch ->
dataBuilder
.putLongArray(AlbumFileUploadWorker.UPLOAD_IDS, batch.toLongArray())
.putInt(AlbumFileUploadWorker.CURRENT_BATCH_INDEX, index)

oneTimeRequestBuilder(AlbumFileUploadWorker::class, ALBUM_JOB_FILES_UPLOAD, user)
.addTag(tag)
.setInputData(dataBuilder.build())
.setConstraints(constraints)
.build()
}

// Chain the work requests sequentially
if (workRequests.isNotEmpty()) {
var workChain = workManager.beginUniqueWork(
tag,
ExistingWorkPolicy.APPEND_OR_REPLACE,
workRequests.first()
)

workRequests.drop(1).forEach { request ->
workChain = workChain.then(request)
}

workChain.enqueue()
}
}
}

private fun startFileDownloadJobTag(accountName: String, fileId: Long): String =
JOB_FOLDER_DOWNLOAD + accountName + fileId

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,15 @@ open class WorkerNotificationManager(
notification,
ForegroundServiceType.DataSync
)

fun createSilentNotification(title: String, iconId: Int): Notification = notificationBuilder
.setContentTitle(title)
.setSmallIcon(iconId)
.setOngoing(true)
.setSound(null)
.setVibrate(null)
.setOnlyAlertOnce(true)
.setPriority(NotificationCompat.PRIORITY_LOW)
.setSilent(true)
.build()
}
Loading
Loading