Skip to content

Commit fcac749

Browse files
tobiasKaminskybackportbot[bot]
authored andcommitted
simplified share layout
Signed-off-by: tobiasKaminsky <[email protected]>
1 parent 4e1e2a5 commit fcac749

16 files changed

+308
-184
lines changed

Diff for: app/src/androidTest/java/com/owncloud/android/ui/fragment/FileDetailSharingFragmentIT.kt

-4
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,6 @@ class FileDetailSharingFragmentIT : AbstractIT() {
288288
onView(ViewMatchers.withId(R.id.menu_share_send_new_email)).check(matches(isDisplayed()))
289289
onView(ViewMatchers.withId(R.id.menu_share_send_link)).check(matches(isDisplayed()))
290290
onView(ViewMatchers.withId(R.id.menu_share_unshare)).check(matches(isDisplayed()))
291-
onView(ViewMatchers.withId(R.id.menu_share_add_another_link)).check(matches(isDisplayed()))
292291

293292
// click event
294293
onView(ViewMatchers.withId(R.id.menu_share_advanced_permissions)).perform(ViewActions.click())
@@ -416,7 +415,6 @@ class FileDetailSharingFragmentIT : AbstractIT() {
416415
onView(ViewMatchers.withId(R.id.menu_share_send_new_email)).check(matches(isDisplayed()))
417416
onView(ViewMatchers.withId(R.id.menu_share_send_link)).check(matches(isDisplayed()))
418417
onView(ViewMatchers.withId(R.id.menu_share_unshare)).check(matches(isDisplayed()))
419-
onView(ViewMatchers.withId(R.id.menu_share_add_another_link)).check(matches(isDisplayed()))
420418

421419
// click event
422420
onView(ViewMatchers.withId(R.id.menu_share_advanced_permissions)).perform(ViewActions.click())
@@ -531,7 +529,6 @@ class FileDetailSharingFragmentIT : AbstractIT() {
531529
onView(ViewMatchers.withId(R.id.menu_share_send_new_email)).check(matches(isDisplayed()))
532530
onView(ViewMatchers.withId(R.id.menu_share_send_link)).check(matches(not(isDisplayed())))
533531
onView(ViewMatchers.withId(R.id.menu_share_unshare)).check(matches(isDisplayed()))
534-
onView(ViewMatchers.withId(R.id.menu_share_add_another_link)).check(matches(not(isDisplayed())))
535532

536533
// click event
537534
onView(ViewMatchers.withId(R.id.menu_share_advanced_permissions)).perform(ViewActions.click())
@@ -657,7 +654,6 @@ class FileDetailSharingFragmentIT : AbstractIT() {
657654
onView(ViewMatchers.withId(R.id.menu_share_send_new_email)).check(matches(isDisplayed()))
658655
onView(ViewMatchers.withId(R.id.menu_share_send_link)).check(matches(not(isDisplayed())))
659656
onView(ViewMatchers.withId(R.id.menu_share_unshare)).check(matches(isDisplayed()))
660-
onView(ViewMatchers.withId(R.id.menu_share_add_another_link)).check(matches(not(isDisplayed())))
661657

662658
// click event
663659
onView(ViewMatchers.withId(R.id.menu_share_advanced_permissions)).perform(ViewActions.click())
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/*
2+
* Nextcloud - Android Client
3+
*
4+
* SPDX-FileCopyrightText: 2025 Tobias Kaminsky <[email protected]>
5+
* SPDX-License-Identifier: AGPL-3.0-or-later
6+
*/
7+
8+
package com.owncloud.android.datamodel
9+
10+
enum class SharesType {
11+
INTERNAL,
12+
EXTERNAL
13+
}

Diff for: app/src/main/java/com/owncloud/android/ui/adapter/ShareViewHolder.java

+5
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ public void bind(OCShare share,
6060
float avatarRadiusDimension) {
6161
this.avatarRadiusDimension = avatarRadiusDimension;
6262
String name = share.getSharedWithDisplayName();
63+
64+
if ("".equals(name) && !"".equals(share.getShareWith())) {
65+
name = share.getShareWith();
66+
}
67+
6368
binding.icon.setTag(null);
6469

6570
switch (share.getShareType()) {

Diff for: app/src/main/java/com/owncloud/android/ui/adapter/ShareeListAdapter.java

+22-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
import android.annotation.SuppressLint;
1515
import android.graphics.drawable.Drawable;
1616
import android.view.LayoutInflater;
17-
import android.view.View;
1817
import android.view.ViewGroup;
1918
import android.widget.ImageView;
2019

@@ -26,6 +25,7 @@
2625
import com.owncloud.android.databinding.FileDetailsSharePublicLinkAddNewItemBinding;
2726
import com.owncloud.android.databinding.FileDetailsShareSecureFileDropAddNewItemBinding;
2827
import com.owncloud.android.databinding.FileDetailsShareShareItemBinding;
28+
import com.owncloud.android.datamodel.SharesType;
2929
import com.owncloud.android.lib.resources.shares.OCShare;
3030
import com.owncloud.android.lib.resources.shares.ShareType;
3131
import com.owncloud.android.ui.activity.FileActivity;
@@ -52,21 +52,25 @@ public class ShareeListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
5252
private final User user;
5353
private final ViewThemeUtils viewThemeUtils;
5454
private final boolean encrypted;
55+
private final SharesType sharesType;
56+
private boolean showAll = false;
5557

5658
public ShareeListAdapter(FileActivity fileActivity,
5759
List<OCShare> shares,
5860
ShareeListAdapterListener listener,
5961
String userId,
6062
User user,
6163
final ViewThemeUtils viewThemeUtils,
62-
boolean encrypted) {
64+
boolean encrypted,
65+
SharesType sharesType) {
6366
this.fileActivity = fileActivity;
6467
this.shares = shares;
6568
this.listener = listener;
6669
this.userId = userId;
6770
this.user = user;
6871
this.viewThemeUtils = viewThemeUtils;
6972
this.encrypted = encrypted;
73+
this.sharesType = sharesType;
7074

7175
avatarRadiusDimension = fileActivity.getResources().getDimension(R.dimen.user_icon_radius);
7276

@@ -170,12 +174,26 @@ public long getItemId(int position) {
170174
public int getItemCount() {
171175
boolean shareViaLink = MDMConfig.INSTANCE.shareViaLink(fileActivity);
172176
if (shareViaLink) {
173-
return shares.size();
177+
if (showAll) {
178+
return shares.size();
179+
} else {
180+
return Math.min(shares.size(), 3);
181+
}
174182
} else {
175183
return 1;
176184
}
177185
}
178186

187+
@SuppressLint("NotifyDataSetChanged")
188+
public void toggleShowAll() {
189+
this.showAll = !this.showAll;
190+
notifyDataSetChanged();
191+
}
192+
193+
public boolean isShowAll() {
194+
return showAll;
195+
}
196+
179197
@SuppressLint("NotifyDataSetChanged")
180198
public void addShares(List<OCShare> sharesToAdd) {
181199
shares.addAll(sharesToAdd);
@@ -227,7 +245,7 @@ protected final void sortShares() {
227245
shares.addAll(users);
228246

229247
// add internal share link at end
230-
if (!encrypted) {
248+
if (!encrypted && sharesType == SharesType.INTERNAL) {
231249
final OCShare ocShare = new OCShare();
232250
ocShare.setShareType(ShareType.INTERNAL);
233251
shares.add(ocShare);

Diff for: app/src/main/java/com/owncloud/android/ui/fragment/FileDetailSharingFragment.java

+98-37
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@
3737
import com.nextcloud.client.network.ClientFactory;
3838
import com.nextcloud.utils.extensions.BundleExtensionsKt;
3939
import com.nextcloud.utils.extensions.FileExtensionsKt;
40+
import com.nextcloud.utils.extensions.ViewExtensionsKt;
4041
import com.nextcloud.utils.mdm.MDMConfig;
4142
import com.owncloud.android.R;
4243
import com.owncloud.android.databinding.FileDetailsSharingFragmentBinding;
4344
import com.owncloud.android.datamodel.FileDataStorageManager;
4445
import com.owncloud.android.datamodel.OCFile;
46+
import com.owncloud.android.datamodel.SharesType;
4547
import com.owncloud.android.lib.common.OwnCloudAccount;
4648
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
4749
import com.owncloud.android.lib.common.utils.Log_OC;
@@ -77,6 +79,7 @@
7779
import androidx.appcompat.widget.SearchView;
7880
import androidx.fragment.app.Fragment;
7981
import androidx.recyclerview.widget.LinearLayoutManager;
82+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
8083

8184
public class FileDetailSharingFragment extends Fragment implements ShareeListAdapterListener,
8285
DisplayUtils.AvatarGenerationListener,
@@ -97,6 +100,10 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
97100
private FileDetailsSharingFragmentBinding binding;
98101

99102
private OnEditShareListener onEditShareListener;
103+
104+
private ShareeListAdapter internalShareeListAdapter;
105+
106+
private ShareeListAdapter externalShareeListAdapter;
100107

101108
@Inject UserAccountManager accountManager;
102109
@Inject ClientFactory clientFactory;
@@ -162,15 +169,31 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
162169
String userId = accountManager.getUserData(user.toPlatformAccount(),
163170
com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_USER_ID);
164171

165-
binding.sharesList.setAdapter(new ShareeListAdapter(fileActivity,
166-
new ArrayList<>(),
167-
this,
168-
userId,
169-
user,
170-
viewThemeUtils,
171-
file.isEncrypted()));
172+
internalShareeListAdapter = new ShareeListAdapter(fileActivity,
173+
new ArrayList<>(),
174+
this,
175+
userId,
176+
user,
177+
viewThemeUtils,
178+
file.isEncrypted(),
179+
SharesType.INTERNAL);
172180

173-
binding.sharesList.setLayoutManager(new LinearLayoutManager(requireContext()));
181+
binding.sharesListInternal.setAdapter(internalShareeListAdapter);
182+
183+
binding.sharesListInternal.setLayoutManager(new LinearLayoutManager(requireContext()));
184+
185+
externalShareeListAdapter = new ShareeListAdapter(fileActivity,
186+
new ArrayList<>(),
187+
this,
188+
userId,
189+
user,
190+
viewThemeUtils,
191+
file.isEncrypted(),
192+
SharesType.EXTERNAL);
193+
194+
binding.sharesListExternal.setAdapter(externalShareeListAdapter);
195+
196+
binding.sharesListExternal.setLayoutManager(new LinearLayoutManager(requireContext()));
174197

175198
binding.pickContactEmailBtn.setOnClickListener(v -> checkContactPermission());
176199

@@ -221,13 +244,36 @@ private void setupView() {
221244
fileActivity.getComponentName());
222245
viewThemeUtils.androidx.themeToolbarSearchView(binding.searchView);
223246

247+
viewThemeUtils.material.colorMaterialTextButton(binding.sharesListInternalShowAll);
248+
binding.sharesListInternalShowAll.setOnClickListener(view -> {
249+
internalShareeListAdapter.toggleShowAll();
250+
251+
if (internalShareeListAdapter.isShowAll()) {
252+
binding.sharesListInternalShowAll.setText(R.string.show_less);
253+
} else {
254+
binding.sharesListInternalShowAll.setText(R.string.show_all);
255+
}
256+
});
257+
258+
viewThemeUtils.material.colorMaterialTextButton(binding.sharesListExternalShowAll);
259+
binding.sharesListExternalShowAll.setOnClickListener(view -> {
260+
externalShareeListAdapter.toggleShowAll();
224261

225-
if (file.canReshare()) {
262+
if (internalShareeListAdapter.isShowAll()) {
263+
binding.sharesListExternalShowAll.setText(R.string.show_less);
264+
} else {
265+
binding.sharesListExternalShowAll.setText(R.string.show_all);
266+
}
267+
});
268+
269+
if (file.canReshare() && !FileDetailSharingFragmentHelper.isPublicShareDisabled(capabilities)) {
226270
if (file.isEncrypted() || (parentFile != null && parentFile.isEncrypted())) {
227271
if (file.getE2eCounter() == -1) {
228272
// V1 cannot share
229273
binding.searchContainer.setVisibility(View.GONE);
274+
binding.createLink.setVisibility(View.GONE);
230275
} else {
276+
binding.createLink.setText(R.string.add_new_secure_file_drop);
231277
binding.searchView.setQueryHint(getResources().getString(R.string.secure_share_search));
232278

233279
if (file.isSharedViaLink()) {
@@ -237,13 +283,20 @@ private void setupView() {
237283
}
238284
}
239285
} else {
240-
binding.searchView.setQueryHint(getResources().getString(R.string.share_search));
286+
binding.createLink.setText(R.string.create_link);
287+
binding.searchView.setQueryHint(getResources().getString(R.string.share_search_internal));
241288
}
289+
290+
binding.createLink.setOnClickListener(v -> createPublicShareLink());
291+
242292
} else {
243293
binding.searchView.setQueryHint(getResources().getString(R.string.resharing_is_not_allowed));
294+
binding.createLink.setVisibility(View.GONE);
295+
binding.externalSharesHeadline.setVisibility(View.GONE);
244296
binding.searchView.setInputType(InputType.TYPE_NULL);
245297
binding.pickContactEmailBtn.setVisibility(View.GONE);
246298
disableSearchView(binding.searchView);
299+
binding.createLink.setOnClickListener(null);
247300
}
248301

249302
checkShareViaUser();
@@ -453,45 +506,63 @@ public void refreshCapabilitiesFromDB() {
453506
* Get public link from the DB to fill in the "Share link" section in the UI. Takes into account server capabilities
454507
* before reading database.
455508
*/
509+
@SuppressFBWarnings("PSC")
456510
public void refreshSharesFromDB() {
457511
OCFile newFile = fileDataStorageManager.getFileById(file.getFileId());
458512
if (newFile != null) {
459513
file = newFile;
460514
}
461515

462-
ShareeListAdapter adapter = (ShareeListAdapter) binding.sharesList.getAdapter();
463-
464-
if (adapter == null) {
516+
if (internalShareeListAdapter == null) {
465517
DisplayUtils.showSnackMessage(getView(), getString(R.string.could_not_retrieve_shares));
466518
return;
467519
}
468-
adapter.getShares().clear();
520+
internalShareeListAdapter.getShares().clear();
469521

470522
// to show share with users/groups info
471523
List<OCShare> shares = fileDataStorageManager.getSharesWithForAFile(file.getRemotePath(),
472524
user.getAccountName());
473525

474-
adapter.addShares(shares);
526+
List<OCShare> internalShares = new ArrayList<>();
527+
List<OCShare> externalShares = new ArrayList<>();
475528

476-
if (FileDetailSharingFragmentHelper.isPublicShareDisabled(capabilities) || !file.canReshare()) {
477-
return;
529+
for (OCShare share : shares) {
530+
if (share.getShareType() != null) {
531+
switch (share.getShareType()) {
532+
case PUBLIC_LINK:
533+
case FEDERATED_GROUP:
534+
case FEDERATED:
535+
case EMAIL:
536+
externalShares.add(share);
537+
break;
538+
539+
default:
540+
internalShares.add(share);
541+
break;
542+
}
543+
}
478544
}
545+
546+
internalShareeListAdapter.addShares(internalShares);
547+
548+
ViewExtensionsKt.setVisibleIf(binding.sharesListInternalShowAll,
549+
internalShareeListAdapter.getShares().size() > 3
550+
);
551+
552+
externalShareeListAdapter.getShares().clear();
479553

480554
// Get public share
481555
List<OCShare> publicShares = fileDataStorageManager.getSharesByPathAndType(file.getRemotePath(),
482556
ShareType.PUBLIC_LINK,
483557
"");
484558

485-
if (publicShares.isEmpty() && containsNoNewPublicShare(adapter.getShares()) &&
486-
(!file.isEncrypted() || capabilities.getEndToEndEncryption().isTrue())) {
487-
final OCShare ocShare = new OCShare();
488-
ocShare.setShareType(ShareType.NEW_PUBLIC_LINK);
489-
publicShares.add(ocShare);
490-
} else {
491-
adapter.removeNewPublicShare();
492-
}
559+
externalShareeListAdapter.addShares(externalShares);
493560

494-
adapter.addShares(publicShares);
561+
externalShareeListAdapter.addShares(publicShares);
562+
563+
ViewExtensionsKt.setVisibleIf(binding.sharesListExternalShowAll,
564+
externalShareeListAdapter.getShares().size() > 3
565+
);
495566
}
496567

497568
private void checkContactPermission() {
@@ -545,16 +616,6 @@ private void handleContactResult(@NonNull Uri contactUri) {
545616
}
546617
}
547618

548-
private boolean containsNoNewPublicShare(List<OCShare> shares) {
549-
for (OCShare share : shares) {
550-
if (share.getShareType() == ShareType.NEW_PUBLIC_LINK) {
551-
return false;
552-
}
553-
}
554-
555-
return true;
556-
}
557-
558619
@Override
559620
public void onSaveInstanceState(@NonNull Bundle outState) {
560621
super.onSaveInstanceState(outState);
@@ -598,7 +659,7 @@ public void sendNewEmail(OCShare share) {
598659
@Override
599660
public void unShare(OCShare share) {
600661
unshareWith(share);
601-
ShareeListAdapter adapter = (ShareeListAdapter) binding.sharesList.getAdapter();
662+
ShareeListAdapter adapter = (ShareeListAdapter) binding.sharesListInternal.getAdapter();
602663
if (adapter == null) {
603664
DisplayUtils.showSnackMessage(getView(), getString(R.string.failed_update_ui));
604665
return;

0 commit comments

Comments
 (0)