Skip to content

Commit 37702f2

Browse files
Merge pull request #2972 from nextcloud/style/noid/sharingM3Style
Sharing M3 style
2 parents 1307684 + 55d9ac8 commit 37702f2

16 files changed

+219
-98
lines changed

app/src/main/java/it/niedermann/owncloud/notes/branding/NotesViewThemeUtils.java

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -224,17 +224,11 @@ public void themeInternalLinkIcon(ImageView view) {
224224
withScheme(view, scheme -> {
225225
view
226226
.getBackground()
227-
.setColorFilter(ResourcesCompat.getColor(view.getContext().getResources(),
228-
R.color.nc_grey,
229-
null),
230-
PorterDuff.Mode.SRC_IN);
227+
.setColorFilter(dynamicColor.surfaceContainerHigh().getArgb(scheme), PorterDuff.Mode.SRC_IN);
231228
view
232229
.getDrawable()
233230
.mutate()
234-
.setColorFilter(ResourcesCompat.getColor(view.getContext().getResources(),
235-
R.color.icon_on_nc_grey,
236-
null),
237-
PorterDuff.Mode.SRC_IN);
231+
.setColorFilter(dynamicColor.onSurface().getArgb(scheme), PorterDuff.Mode.SRC_IN);
238232
return view;
239233
});
240234
}

app/src/main/java/it/niedermann/owncloud/notes/share/NoteShareActivity.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ public void onCreate(@Nullable Bundle savedInstanceState) {
108108
executorService = Executors.newSingleThreadScheduledExecutor();
109109
binding = ActivityNoteShareBinding.inflate(getLayoutInflater());
110110
setContentView(binding.getRoot());
111+
setSupportActionBar(binding.toolbar);
112+
binding.toolbar.setNavigationOnClickListener(v -> backPressed());
111113
registerResultLauncher();
112114
initializeArguments();
113115
initializeOnBackPressedDispatcher();
@@ -127,14 +129,18 @@ private void initializeOnBackPressedDispatcher() {
127129
getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
128130
@Override
129131
public void handleOnBackPressed() {
130-
Intent intent = new Intent(NoteShareActivity.this, MainActivity.class);
131-
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
132-
startActivity(intent);
133-
finish();
132+
backPressed();
134133
}
135134
});
136135
}
137136

137+
private void backPressed() {
138+
Intent intent = new Intent(NoteShareActivity.this, MainActivity.class);
139+
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
140+
startActivity(intent);
141+
finish();
142+
}
143+
138144
private void initializeArguments() {
139145
Bundle bundler = getIntent().getExtras();
140146
note = BundleExtensionsKt.getSerializableArgument(bundler, ARG_NOTE, Note.class);
@@ -156,6 +162,8 @@ private void initializeArguments() {
156162
repository.getSharesForNotesAndSaveShareEntities();
157163

158164
runOnUiThread(() -> {
165+
binding.title.setText(R.string.activity_sharing_title);
166+
binding.fileName.setText(note.getTitle());
159167
binding.searchContainer.setVisibility(View.VISIBLE);
160168
binding.sharesList.setVisibility(View.VISIBLE);
161169
binding.sharesList.setAdapter(new ShareeListAdapter(this, new ArrayList<>(), this, account));
@@ -798,6 +806,7 @@ private void updateShare(OCShare share) {
798806
public void applyBrand(int color) {
799807
final var util = BrandingUtil.of(color, this);
800808
util.platform.themeStatusBar(this);
809+
util.material.themeToolbar(binding.toolbar);
801810
util.androidx.themeToolbarSearchView(binding.searchView);
802811
util.platform.colorCircularProgressBar(binding.loadingLayoutIndicator, ColorRole.PRIMARY);
803812
util.platform.themeHorizontalProgressBar(binding.progressBar);

app/src/main/java/it/niedermann/owncloud/notes/share/adapter/ShareeListAdapter.java

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import androidx.core.content.ContextCompat;
1717
import androidx.recyclerview.widget.RecyclerView;
1818

19+
import com.nextcloud.android.common.ui.theme.utils.ColorRole;
1920
import com.owncloud.android.lib.resources.shares.OCShare;
2021
import com.owncloud.android.lib.resources.shares.ShareType;
2122

@@ -90,30 +91,36 @@ public int getItemViewType(int position) {
9091
@NonNull
9192
@Override
9293
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
94+
BrandingUtil brandingUtil = BrandingUtil.of(color, parent.getContext());
95+
LayoutInflater layoutInflater = LayoutInflater.from(activity);
9396
switch (ShareType.fromValue(viewType)) {
9497
case PUBLIC_LINK, EMAIL -> {
95-
return new LinkShareViewHolder(
96-
ItemShareLinkShareBinding.inflate(LayoutInflater.from(activity),
97-
parent,
98-
false),
99-
activity);
98+
ItemShareLinkShareBinding binding = ItemShareLinkShareBinding.inflate(
99+
layoutInflater, parent, false);
100+
brandingUtil.platform.colorTextView(binding.name, ColorRole.ON_SURFACE);
101+
brandingUtil.platform.colorTextView(binding.subline, ColorRole.ON_SURFACE_VARIANT);
102+
return new LinkShareViewHolder(binding, activity);
100103
}
101104
case NEW_PUBLIC_LINK -> {
102-
ItemAddPublicShareBinding binding = ItemAddPublicShareBinding.inflate(LayoutInflater.from(activity), parent, false);
103-
BrandingUtil.of(color, parent.getContext()).notes.themeInternalLinkIcon(binding.addNewPublicShareLinkIcon);
105+
ItemAddPublicShareBinding binding = ItemAddPublicShareBinding.inflate(
106+
layoutInflater, parent, false);
107+
brandingUtil.notes.themeInternalLinkIcon(binding.addNewPublicShareLinkIcon);
108+
brandingUtil.platform.colorTextView(binding.addNewPublicShareLinkText, ColorRole.ON_SURFACE);
104109
return new NewLinkShareViewHolder(binding);
105110
}
106111
case INTERNAL -> {
107-
ItemInternalShareLinkBinding binding = ItemInternalShareLinkBinding.inflate(LayoutInflater.from(activity), parent, false);
108-
BrandingUtil.of(color, parent.getContext()).notes.themeInternalLinkIcon(binding.copyInternalLinkIcon);
112+
ItemInternalShareLinkBinding binding = ItemInternalShareLinkBinding.inflate(
113+
layoutInflater, parent, false);
114+
brandingUtil.notes.themeInternalLinkIcon(binding.copyInternalLinkIcon);
115+
brandingUtil.platform.colorTextView(binding.shareInternalLink, ColorRole.ON_SURFACE);
116+
brandingUtil.platform.colorTextView(binding.shareInternalLinkText, ColorRole.ON_SURFACE_VARIANT);
109117
return new InternalShareViewHolder(binding, activity);
110118
}
111119
default -> {
112-
return new ShareViewHolder(ItemShareShareBinding.inflate(LayoutInflater.from(activity),
113-
parent,
114-
false),
115-
account,
116-
activity);
120+
ItemShareShareBinding binding = ItemShareShareBinding.inflate(
121+
layoutInflater, parent, false);
122+
brandingUtil.platform.colorTextView(binding.name, ColorRole.ON_SURFACE);
123+
return new ShareViewHolder(binding, account, activity);
117124
}
118125
}
119126
}

app/src/main/java/it/niedermann/owncloud/notes/share/adapter/holder/LinkShareViewHolder.java

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111
import android.text.TextUtils;
1212
import android.view.View;
1313

14+
import androidx.annotation.ColorInt;
1415
import androidx.annotation.NonNull;
1516
import androidx.core.content.res.ResourcesCompat;
1617

18+
import com.nextcloud.android.common.ui.theme.utils.ColorRole;
1719
import com.owncloud.android.lib.resources.shares.OCShare;
1820
import com.owncloud.android.lib.resources.shares.ShareType;
1921

@@ -28,6 +30,8 @@ public class LinkShareViewHolder extends BrandedViewHolder {
2830
private ItemShareLinkShareBinding binding;
2931
private Context context;
3032

33+
private BrandingUtil brandingUtil;
34+
3135
public LinkShareViewHolder(@NonNull View itemView) {
3236
super(itemView);
3337
bindBranding();
@@ -46,13 +50,17 @@ public void bind(OCShare publicShare, ShareeListAdapterListener listener) {
4650
binding.icon.setImageDrawable(ResourcesCompat.getDrawable(context.getResources(),
4751
R.drawable.ic_email,
4852
null));
53+
if (publicShare.getLabel() != null && !publicShare.getLabel().isEmpty()) {
54+
brandingUtil.platform.colorTextView(binding.name, ColorRole.ON_SURFACE_VARIANT);
55+
binding.label.setText(publicShare.getLabel());
56+
binding.label.setVisibility(View.VISIBLE);
57+
} else {
58+
brandingUtil.platform.colorTextView(binding.name, ColorRole.ON_SURFACE);
59+
binding.label.setVisibility(View.GONE);
60+
}
4961
binding.copyLink.setVisibility(View.GONE);
50-
51-
binding.icon.getBackground().setColorFilter(context.getResources().getColor(R.color.nc_grey),
52-
PorterDuff.Mode.SRC_IN);
53-
binding.icon.getDrawable().mutate().setColorFilter(context.getResources().getColor(R.color.icon_on_nc_grey),
54-
PorterDuff.Mode.SRC_IN);
5562
} else {
63+
brandingUtil.platform.colorTextView(binding.name, ColorRole.ON_SURFACE);
5664
if (!TextUtils.isEmpty(publicShare.getLabel())) {
5765
String text = String.format(context.getString(R.string.share_link_with_label), publicShare.getLabel());
5866
binding.name.setText(text);
@@ -89,10 +97,11 @@ private void setPermissionName(OCShare publicShare, String permissionName) {
8997

9098
@Override
9199
public void applyBrand(int color) {
92-
final var util = BrandingUtil.of(color, context);
100+
brandingUtil = BrandingUtil.of(color, context);
93101
if (binding != null) {
94-
util.androidx.colorPrimaryTextViewElement(binding.permissionName);
95-
util.platform.colorImageViewBackgroundAndIcon(binding.icon);
102+
brandingUtil.androidx.colorPrimaryTextViewElement(binding.permissionName);
103+
brandingUtil.platform.colorTextView(binding.label, ColorRole.ON_SURFACE);
104+
brandingUtil.platform.colorImageViewBackgroundAndIcon(binding.icon);
96105
}
97106
}
98107
}

app/src/main/java/it/niedermann/owncloud/notes/share/adapter/holder/NewLinkShareViewHolder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ public NewLinkShareViewHolder(ItemAddPublicShareBinding binding) {
2727
}
2828

2929
public void bind(ShareeListAdapterListener listener) {
30-
binding.addNewPublicShareLink.setOnClickListener(v -> listener.createPublicShareLink());
30+
binding.addNewPublicShareLinkPlus.setOnClickListener(v -> listener.createPublicShareLink());
3131
}
3232
}

app/src/main/java/it/niedermann/owncloud/notes/share/adapter/holder/ShareViewHolder.java

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,23 @@
1818
import com.owncloud.android.lib.resources.shares.OCShare;
1919

2020
import it.niedermann.owncloud.notes.R;
21+
import it.niedermann.owncloud.notes.branding.BrandedViewHolder;
22+
import it.niedermann.owncloud.notes.branding.BrandingUtil;
2123
import it.niedermann.owncloud.notes.databinding.ItemShareShareBinding;
2224
import it.niedermann.owncloud.notes.persistence.entity.Account;
2325
import it.niedermann.owncloud.notes.share.helper.AvatarLoader;
2426
import it.niedermann.owncloud.notes.share.helper.SharingMenuHelper;
2527
import it.niedermann.owncloud.notes.share.listener.ShareeListAdapterListener;
2628
import it.niedermann.owncloud.notes.shared.util.FilesSpecificViewThemeUtils;
2729

28-
public class ShareViewHolder extends RecyclerView.ViewHolder {
30+
public class ShareViewHolder extends BrandedViewHolder {
2931
private ItemShareShareBinding binding;
3032
private Account account;
3133
private Context context;
3234

3335
public ShareViewHolder(@NonNull View itemView) {
3436
super(itemView);
37+
bindBranding();
3538
}
3639

3740
public ShareViewHolder(ItemShareShareBinding binding,
@@ -41,10 +44,11 @@ public ShareViewHolder(ItemShareShareBinding binding,
4144
this.binding = binding;
4245
this.account = account;
4346
this.context = context;
47+
bindBranding();
4448
}
4549

4650
public void bind(OCShare share, ShareeListAdapterListener listener) {
47-
String accountName = account.getDisplayName();
51+
String accountUserName = account.getUserName();
4852
String name = share.getSharedWithDisplayName();
4953
binding.icon.setTag(null);
5054
final var shareType = share.getShareType();
@@ -85,12 +89,8 @@ public void bind(OCShare share, ShareeListAdapterListener listener) {
8589

8690
binding.name.setText(name);
8791

88-
if (accountName == null) {
89-
binding.overflowMenu.setVisibility(View.GONE);
90-
return;
91-
}
92-
93-
if (accountName.equalsIgnoreCase(share.getShareWith()) || accountName.equalsIgnoreCase(share.getUserId())) {
92+
if (accountUserName.equalsIgnoreCase(share.getShareWith()) ||
93+
accountUserName.equalsIgnoreCase(share.getUserId())) {
9494
binding.overflowMenu.setVisibility(View.VISIBLE);
9595

9696
String permissionName = SharingMenuHelper.getPermissionName(context, share);
@@ -120,4 +120,13 @@ private void setImage(ImageView avatar, String name, @DrawableRes int fallback)
120120
avatar.setImageResource(fallback);
121121
}
122122
}
123+
124+
@Override
125+
public void applyBrand(int color) {
126+
final var util = BrandingUtil.of(color, context);
127+
if (binding != null) {
128+
util.androidx.colorPrimaryTextViewElement(binding.permissionName);
129+
util.platform.colorImageViewBackgroundAndIcon(binding.icon);
130+
}
131+
}
123132
}

app/src/main/java/it/niedermann/owncloud/notes/share/repository/ShareRepository.kt

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,14 @@ import it.niedermann.owncloud.notes.shared.util.extensions.toExpirationDateStrin
3737
import org.json.JSONObject
3838
import java.util.Date
3939

40-
class ShareRepository(
41-
private val applicationContext: Context,
42-
private val account: SingleSignOnAccount
43-
) {
40+
class ShareRepository(private val applicationContext: Context, private val account: SingleSignOnAccount) {
4441

4542
private val tag = "ShareRepository"
4643
private val gson = Gson()
4744
private val apiProvider: ApiProvider by lazy { ApiProvider.getInstance() }
4845
private val notesRepository: NotesRepository by lazy {
4946
NotesRepository.getInstance(
50-
applicationContext,
47+
applicationContext
5148
)
5249
}
5350

@@ -61,7 +58,13 @@ class ShareRepository(
6158
val notesPathResponseResult = getNotesPathResponseResult() ?: return null
6259
val notesPath = notesPathResponseResult.notesPath
6360
val notesSuffix = notesPathResponseResult.fileSuffix
64-
return StringConstants.PATH + notesPath + StringConstants.PATH + note.title + notesSuffix
61+
return if (note.category.isEmpty()) {
62+
StringConstants.PATH + notesPath + StringConstants.PATH + note.title + notesSuffix
63+
} else {
64+
StringConstants.PATH + notesPath + StringConstants.PATH + note.category + StringConstants.PATH +
65+
note.title +
66+
notesSuffix
67+
}
6568
}
6669

6770
fun getShareEntitiesForSpecificNote(note: Note): List<ShareEntity> {
@@ -135,11 +138,17 @@ class ShareRepository(
135138

136139
private fun LinkedTreeMap<*, *>.getList(key: String): ArrayList<*>? = this[key] as? ArrayList<*>
137140

138-
fun getSharees(
139-
searchString: String,
140-
page: Int,
141-
perPage: Int
142-
): ArrayList<JSONObject> {
141+
/**
142+
* Searches for potential share recipients (sharees).
143+
*
144+
* Queries the server for users, groups, remotes, emails, circles, and rooms that match the provided criteria.
145+
*
146+
* @param searchString Query string.
147+
* @param page Page number for paginated results.
148+
* @param perPage Number of results to return per page.
149+
* @return [ArrayList] of [JSONObject]s representing the share recipients.
150+
*/
151+
fun getSharees(searchString: String, page: Int, perPage: Int): ArrayList<JSONObject> {
143152
val shareAPI = apiProvider.getShareAPI(applicationContext, account)
144153
val call = shareAPI.getSharees(
145154
search = searchString,
@@ -232,6 +241,13 @@ class ShareRepository(
232241
)
233242
}
234243

244+
/**
245+
* Fetches all shares for the given file or folder identified by its remote ID.
246+
*
247+
* @param remoteId The remote file ID on the server for which to retrieve shares.
248+
* @return A list of [OCShare] objects if the request is successful, or `null` if the request fails or an exception
249+
* occurs.
250+
*/
235251
fun getShares(remoteId: Long): List<OCShare>? {
236252
val shareAPI = apiProvider.getShareAPI(applicationContext, account)
237253
val call = shareAPI.getShares(remoteId)
@@ -299,7 +315,6 @@ class ShareRepository(
299315
val call = shareAPI.removeShare(share.id)
300316
val response = call.execute()
301317
if (response.isSuccessful) {
302-
303318
if (share.shareType != null && share.shareType == ShareType.PUBLIC_LINK) {
304319
note.setIsShared(false)
305320
updateNote(note)
@@ -316,16 +331,20 @@ class ShareRepository(
316331
}
317332
}
318333

319-
fun updateShare(
320-
shareId: Long,
321-
requestBody: UpdateShareRequest
322-
): ApiResult<OcsResponse<CreateShareResponse>?> {
334+
/**
335+
* Updates an existing share.
336+
*
337+
* @param shareId The id of the share to update.
338+
* @param requestBody The [UpdateShareRequest] containing the new share attributes.
339+
* @return An [ApiResult] with the server response [OcsResponse] on success, or an error result on failure.
340+
*/
341+
fun updateShare(shareId: Long, requestBody: UpdateShareRequest): ApiResult<OcsResponse<CreateShareResponse>?> {
323342
val shareAPI = apiProvider.getShareAPI(applicationContext, account)
324343
val call = shareAPI.updateShare(shareId, requestBody)
325344
val response = call.execute()
326345
return try {
327346
if (response.isSuccessful) {
328-
Log_OC.d(tag, "Share updated successfully: ${response.body().toString()}")
347+
Log_OC.d(tag, "Share updated successfully: ${response.body()}")
329348
ApiResult.Success(
330349
data = response.body(),
331350
message = applicationContext.getString(R.string.note_share_created)
@@ -396,10 +415,15 @@ class ShareRepository(
396415
}
397416
}
398417

399-
fun updateSharePermission(
400-
shareId: Long,
401-
permissions: Int? = null,
402-
): ApiResult<OcsResponse<CreateShareResponse>?> {
418+
/**
419+
* Updates the permissions for an existing share.
420+
*
421+
* @param shareId The id of the share to update.
422+
* @param permissions The new permission level to set
423+
* @return An [ApiResult] containing the server response [OcsResponse] with the updated share details on success,
424+
* or an error message on failure.
425+
*/
426+
fun updateSharePermission(shareId: Long, permissions: Int? = null): ApiResult<OcsResponse<CreateShareResponse>?> {
403427
val shareAPI = apiProvider.getShareAPI(applicationContext, account)
404428
val requestBody = UpdateSharePermissionRequest(permissions = permissions)
405429

app/src/main/res/drawable/ic_content_copy.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99
android:width="24dp"
1010
android:viewportWidth="24"
1111
android:viewportHeight="24">
12-
<path android:fillColor="#757575" android:pathData="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z" />
12+
<path android:fillColor="@color/icon_color_default" android:pathData="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z" />
1313
</vector>

0 commit comments

Comments
 (0)