Skip to content

Commit 4f268d4

Browse files
committed
Album files Fav and remove operation added.
Album picker activity to pick album while adding media.
1 parent db5c34f commit 4f268d4

12 files changed

Lines changed: 907 additions & 140 deletions

File tree

app/src/main/AndroidManifest.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,9 @@
586586
<activity
587587
android:name=".ui.activity.FolderPickerActivity"
588588
android:exported="false" />
589+
<activity
590+
android:name=".ui.fragment.albums.AlbumsPickerActivity"
591+
android:exported="false" />
589592
<activity
590593
android:name=".ui.activity.FilePickerActivity"
591594
android:exported="false"

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
import com.owncloud.android.ui.fragment.UnifiedSearchFragment;
119119
import com.owncloud.android.ui.fragment.albums.AlbumItemsFragment;
120120
import com.owncloud.android.ui.fragment.albums.AlbumsFragment;
121+
import com.owncloud.android.ui.fragment.albums.AlbumsPickerActivity;
121122
import com.owncloud.android.ui.fragment.contactsbackup.BackupFragment;
122123
import com.owncloud.android.ui.fragment.contactsbackup.BackupListFragment;
123124
import com.owncloud.android.ui.preview.FileDownloadFragment;
@@ -406,6 +407,9 @@ abstract class ComponentsModule {
406407
@ContributesAndroidInjector
407408
abstract FileActivity fileActivity();
408409

410+
@ContributesAndroidInjector
411+
abstract AlbumsPickerActivity albumsPickerActivity();
412+
409413
@ContributesAndroidInjector
410414
abstract FileDownloadFragment fileDownloadFragment();
411415

app/src/main/java/com/owncloud/android/operations/albums/ReadAlbumItemsOperation.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ private void readData(MultiStatus remoteData, OwnCloudClient client) {
9797
OCFile ocFile = fileDataStorageManager.getFileByLocalId(remoteFile.getLocalId());
9898
if (ocFile == null) {
9999
ocFile = FileStorageUtils.fillOCFile(remoteFile);
100+
} else{
101+
// required: as OCFile will only contains file_name.png not with /albums/album_name/file_name
102+
// to fix this we have to get the remote path from remote file and assign to OCFile
103+
ocFile.setRemotePath(remoteFile.getRemotePath());
104+
ocFile.setDecryptedRemotePath(remoteFile.getRemotePath());
100105
}
101106
this.mFolderAndFiles.add(ocFile);
102107
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Nextcloud - Android Client
3+
*
4+
* SPDX-FileCopyrightText: 2025 Your Name <your@email.com>
5+
* SPDX-License-Identifier: AGPL-3.0-or-later
6+
*/
7+
8+
package com.owncloud.android.operations.albums;
9+
10+
import android.net.Uri;
11+
12+
import com.nextcloud.common.SessionTimeOut;
13+
import com.nextcloud.common.SessionTimeOutKt;
14+
import com.owncloud.android.lib.common.OwnCloudClient;
15+
import com.owncloud.android.lib.common.operations.RemoteOperation;
16+
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
17+
import com.owncloud.android.lib.common.utils.Log_OC;
18+
import com.owncloud.android.lib.resources.files.RemoveFileRemoteOperation;
19+
20+
import org.apache.jackrabbit.webdav.client.methods.DeleteMethod;
21+
22+
public class RemoveAlbumFileRemoteOperation extends RemoteOperation {
23+
private static final String TAG = RemoveFileRemoteOperation.class.getSimpleName();
24+
private final String mRemotePath;
25+
private final SessionTimeOut sessionTimeOut;
26+
27+
public RemoveAlbumFileRemoteOperation(String remotePath) {
28+
this(remotePath, SessionTimeOutKt.getDefaultSessionTimeOut());
29+
}
30+
31+
public RemoveAlbumFileRemoteOperation(String remotePath, SessionTimeOut sessionTimeOut) {
32+
this.mRemotePath = remotePath;
33+
this.sessionTimeOut = sessionTimeOut;
34+
}
35+
36+
protected RemoteOperationResult run(OwnCloudClient client) {
37+
RemoteOperationResult result;
38+
DeleteMethod delete = null;
39+
String webDavUrl = client.getDavUri().toString()+"/photos/";
40+
String encodedPath = (client.getUserId() + Uri.encode(this.mRemotePath)).replace("%2F", "/");
41+
String fullFilePath = webDavUrl + encodedPath;
42+
43+
try {
44+
delete = new DeleteMethod(fullFilePath);
45+
int status = client.executeMethod(delete, this.sessionTimeOut.getReadTimeOut(), this.sessionTimeOut.getConnectionTimeOut());
46+
delete.getResponseBodyAsString();
47+
result = new RemoteOperationResult(delete.succeeded() || status == 404, delete);
48+
Log_OC.i(TAG, "Remove " + this.mRemotePath + ": " + result.getLogMessage());
49+
} catch (Exception e) {
50+
result = new RemoteOperationResult(e);
51+
Log_OC.e(TAG, "Remove " + this.mRemotePath + ": " + result.getLogMessage(), e);
52+
} finally {
53+
if (delete != null) {
54+
delete.releaseConnection();
55+
}
56+
57+
}
58+
59+
return result;
60+
}
61+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Nextcloud - Android Client
3+
*
4+
* SPDX-FileCopyrightText: 2025 Your Name <your@email.com>
5+
* SPDX-License-Identifier: AGPL-3.0-or-later
6+
*/
7+
8+
package com.owncloud.android.operations.albums;
9+
10+
import android.net.Uri;
11+
12+
import com.owncloud.android.lib.common.OwnCloudClient;
13+
import com.owncloud.android.lib.common.operations.RemoteOperation;
14+
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
15+
import com.owncloud.android.lib.common.utils.Log_OC;
16+
17+
import org.apache.jackrabbit.webdav.client.methods.PropPatchMethod;
18+
import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
19+
import org.apache.jackrabbit.webdav.property.DavPropertySet;
20+
import org.apache.jackrabbit.webdav.property.DefaultDavProperty;
21+
import org.apache.jackrabbit.webdav.xml.Namespace;
22+
23+
import java.io.IOException;
24+
25+
public class ToggleAlbumFavoriteRemoteOperation extends RemoteOperation {
26+
private boolean makeItFavorited;
27+
private String filePath;
28+
29+
public ToggleAlbumFavoriteRemoteOperation(boolean makeItFavorited, String filePath) {
30+
this.makeItFavorited = makeItFavorited;
31+
this.filePath = filePath;
32+
}
33+
34+
protected RemoteOperationResult run(OwnCloudClient client) {
35+
Log_OC.e("Toogle Album Fav", "File: "+filePath +" -- isFav: "+makeItFavorited);
36+
RemoteOperationResult result;
37+
PropPatchMethod propPatchMethod = null;
38+
DavPropertySet newProps = new DavPropertySet();
39+
DavPropertyNameSet removeProperties = new DavPropertyNameSet();
40+
if (this.makeItFavorited) {
41+
DefaultDavProperty<String> favoriteProperty = new DefaultDavProperty("oc:favorite", "1", Namespace.getNamespace("http://owncloud.org/ns"));
42+
newProps.add(favoriteProperty);
43+
} else {
44+
removeProperties.add("oc:favorite", Namespace.getNamespace("http://owncloud.org/ns"));
45+
}
46+
47+
String webDavUrl = client.getDavUri().toString()+"/photos/";
48+
String encodedPath = (client.getUserId() + Uri.encode(this.filePath)).replace("%2F", "/");
49+
String fullFilePath = webDavUrl + encodedPath;
50+
51+
try {
52+
propPatchMethod = new PropPatchMethod(fullFilePath, newProps, removeProperties);
53+
int status = client.executeMethod(propPatchMethod);
54+
boolean isSuccess = status == 207 || status == 200;
55+
if (isSuccess) {
56+
result = new RemoteOperationResult(true, status, propPatchMethod.getResponseHeaders());
57+
} else {
58+
client.exhaustResponse(propPatchMethod.getResponseBodyAsStream());
59+
result = new RemoteOperationResult(false, status, propPatchMethod.getResponseHeaders());
60+
}
61+
} catch (IOException e) {
62+
result = new RemoteOperationResult(e);
63+
} finally {
64+
if (propPatchMethod != null) {
65+
propPatchMethod.releaseConnection();
66+
}
67+
68+
}
69+
70+
return result;
71+
}
72+
}

app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2139,7 +2139,7 @@ private void onCreateAlbumOperationFinish(CreateNewAlbumOperation operation, Rem
21392139
} else {
21402140
try {
21412141
if (ResultCode.FOLDER_ALREADY_EXISTS == result.getCode()) {
2142-
DisplayUtils.showSnackMessage(this, R.string.folder_already_exists);
2142+
DisplayUtils.showSnackMessage(this, R.string.album_already_exists);
21432143
} else {
21442144
DisplayUtils.showSnackMessage(this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()));
21452145
}

app/src/main/java/com/owncloud/android/ui/adapter/GalleryAdapter.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,10 @@ class GalleryAdapter(
312312
notifyItemChanged(getItemPosition(file))
313313
}
314314

315+
fun setCheckedItem(files: Set<OCFile>?) {
316+
ocFileListDelegate.setCheckedItem(files)
317+
}
318+
315319
override fun getFilesCount(): Int {
316320
return files.fold(0) { acc, item -> acc + item.rows.size }
317321
}

app/src/main/java/com/owncloud/android/ui/fragment/GalleryFragment.java

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99
package com.owncloud.android.ui.fragment;
1010

11+
import android.app.Activity;
1112
import android.content.BroadcastReceiver;
1213
import android.content.Context;
1314
import android.content.Intent;
@@ -39,16 +40,18 @@
3940
import com.owncloud.android.ui.asynctasks.GallerySearchTask;
4041
import com.owncloud.android.ui.events.ChangeMenuEvent;
4142
import com.owncloud.android.ui.fragment.albums.AlbumsFragment;
43+
import com.owncloud.android.ui.fragment.albums.AlbumsPickerActivity;
4244
import com.owncloud.android.utils.DisplayUtils;
4345

4446
import java.util.ArrayList;
4547
import java.util.Set;
4648

4749
import javax.inject.Inject;
4850

51+
import androidx.activity.result.ActivityResultLauncher;
52+
import androidx.activity.result.contract.ActivityResultContracts;
4953
import androidx.annotation.NonNull;
5054
import androidx.annotation.Nullable;
51-
import androidx.fragment.app.FragmentTransaction;
5255
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
5356
import androidx.recyclerview.widget.GridLayoutManager;
5457
import androidx.recyclerview.widget.RecyclerView;
@@ -77,6 +80,7 @@ public class GalleryFragment extends OCFileListFragment implements GalleryFragme
7780
private final static int maxColumnSizeLandscape = 5;
7881
private final static int maxColumnSizePortrait = 2;
7982
private int columnSize;
83+
private Set<OCFile> checkedFiles;
8084

8185
protected void setPhotoSearchQueryRunning(boolean value) {
8286
this.photoSearchQueryRunning = value;
@@ -440,30 +444,33 @@ public void markAsFavorite(String remotePath, boolean favorite) {
440444
mAdapter.markAsFavorite(remotePath, favorite);
441445
}
442446

443-
public void addImagesToAlbum(Set<OCFile> checkedFiles) {
444-
FragmentTransaction transaction = requireActivity().getSupportFragmentManager().beginTransaction();
445-
transaction.addToBackStack(null);
446-
transaction.add(R.id.left_fragment_container, AlbumsFragment.Companion.newInstance(true), AlbumsFragment.Companion.getTAG());
447-
transaction.commit();
448-
requireActivity().getSupportFragmentManager().setFragmentResultListener(AlbumsFragment.SELECT_ALBUM_REQ_KEY, getViewLifecycleOwner(), (requestKey, bundle) -> {
449-
if (requestKey.equals(AlbumsFragment.SELECT_ALBUM_REQ_KEY)) {
450-
String albumName = bundle.getString(AlbumsFragment.ARG_SELECTED_ALBUM_NAME);
447+
final ActivityResultLauncher<Intent> activityResult =
448+
registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), intentResult -> {
449+
if (Activity.RESULT_OK == intentResult.getResultCode() && intentResult.getData() != null) {
450+
String albumName = intentResult.getData().getStringExtra(AlbumsFragment.ARG_SELECTED_ALBUM_NAME);
451451
Log_OC.e(TAG, "Selected album name: " + albumName);
452452

453453
connectivityService.isNetworkAndServerAvailable(result -> {
454454
if (result) {
455+
if (checkedFiles == null || checkedFiles.isEmpty()) {
456+
return;
457+
}
455458
final ArrayList<String> paths = new ArrayList<>(checkedFiles.size());
456459
for (OCFile file : checkedFiles) {
457460
paths.add(file.getRemotePath());
458461
}
459462
mContainerActivity.getFileOperationsHelper().albumCopyFiles(paths, albumName);
463+
checkedFiles = null;
460464
} else {
461465
DisplayUtils.showSnackMessage(requireActivity(), getString(R.string.offline_mode));
462466
}
463467
});
464-
// clear result listener once done
465-
requireActivity().getSupportFragmentManager().clearFragmentResultListener(AlbumsFragment.SELECT_ALBUM_REQ_KEY);
466468
}
467469
});
470+
471+
public void addImagesToAlbum(Set<OCFile> checkedFiles) {
472+
this.checkedFiles = checkedFiles;
473+
474+
activityResult.launch(AlbumsPickerActivity.Companion.intentForPickingAlbum(requireActivity()));
468475
}
469476
}

0 commit comments

Comments
 (0)