Skip to content

Commit eec13d2

Browse files
feat(sharing): Show expiration date state in share list
Signed-off-by: Andy Scherzinger <[email protected]>
1 parent 37702f2 commit eec13d2

File tree

16 files changed

+1684
-72
lines changed

16 files changed

+1684
-72
lines changed

app/schemas/it.niedermann.owncloud.notes.persistence.NotesDatabase/27.json

Lines changed: 741 additions & 0 deletions
Large diffs are not rendered by default.

app/schemas/it.niedermann.owncloud.notes.persistence.NotesDatabase/28.json

Lines changed: 746 additions & 0 deletions
Large diffs are not rendered by default.

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

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import android.util.Log;
2020
import android.view.View;
2121
import android.widget.ImageView;
22+
import android.widget.LinearLayout;
2223
import android.widget.TextView;
2324

2425
import androidx.annotation.ColorInt;
@@ -28,7 +29,6 @@
2829
import androidx.appcompat.widget.SearchView;
2930
import androidx.appcompat.widget.Toolbar;
3031
import androidx.core.content.ContextCompat;
31-
import androidx.core.content.res.ResourcesCompat;
3232
import androidx.core.graphics.drawable.DrawableCompat;
3333

3434
import com.google.android.material.appbar.AppBarLayout;
@@ -220,6 +220,28 @@ public void themeToolbarSearchView(@NonNull SearchView searchView) {
220220
});
221221
}
222222

223+
/**
224+
* @deprecated Should be replaced with {@link com.google.android.material.search.SearchView}
225+
*/
226+
@Deprecated
227+
public void themeContentSearchView(@NonNull SearchView searchView) {
228+
withScheme(searchView, scheme -> {
229+
// hacky as no default way is provided
230+
final var editText = (AppCompatAutoCompleteTextView) searchView
231+
.findViewById(androidx.appcompat.R.id.search_src_text);
232+
final var searchPlate = (LinearLayout) searchView.findViewById(androidx.appcompat.R.id.search_plate);
233+
final var closeButton = (ImageView) searchView.findViewById(androidx.appcompat.R.id.search_close_btn);
234+
final var searchButton = (ImageView) searchView.findViewById(androidx.appcompat.R.id.search_button);
235+
editText.setHintTextColor(dynamicColor.onSurfaceVariant().getArgb(scheme));
236+
editText.setHighlightColor(dynamicColor.inverseOnSurface().getArgb(scheme));
237+
editText.setTextColor(dynamicColor.onSurface().getArgb(scheme));
238+
closeButton.setColorFilter(dynamicColor.onSurface().getArgb(scheme));
239+
searchButton.setColorFilter(dynamicColor.onSurface().getArgb(scheme));
240+
searchPlate.setBackgroundColor(dynamicColor.surfaceContainerHigh().getArgb(scheme));
241+
return searchView;
242+
});
243+
}
244+
223245
public void themeInternalLinkIcon(ImageView view) {
224246
withScheme(view, scheme -> {
225247
view

app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,11 @@
5858
NotesListWidgetData.class,
5959
ShareEntity.class,
6060
Capabilities.class
61-
}, version = 27,
61+
}, version = 28,
6262
autoMigrations = {
6363
@AutoMigration(from = 25, to = 26),
6464
@AutoMigration(from = 26, to = 27),
65+
@AutoMigration(from = 27, to = 28),
6566
}
6667
)
6768
@TypeConverters({Converters.class})

app/src/main/java/it/niedermann/owncloud/notes/persistence/entity/ShareEntity.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,6 @@ data class ShareEntity(
2424
val displayname_file_owner: String? = null,
2525
val uid_owner: String? = null,
2626
val displayname_owner: String? = null,
27-
val url: String? = null
27+
val url: String? = null,
28+
val expiration_date: Long? = null
2829
)

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -807,12 +807,17 @@ public void applyBrand(int color) {
807807
final var util = BrandingUtil.of(color, this);
808808
util.platform.themeStatusBar(this);
809809
util.material.themeToolbar(binding.toolbar);
810-
util.androidx.themeToolbarSearchView(binding.searchView);
810+
util.notes.themeContentSearchView(binding.searchView);
811+
util.platform.colorImageView(binding.searchViewIcon, ColorRole.ON_SURFACE_VARIANT);
812+
util.platform.colorImageView(binding.pickContactEmailBtn, ColorRole.ON_SURFACE_VARIANT);
811813
util.platform.colorCircularProgressBar(binding.loadingLayoutIndicator, ColorRole.PRIMARY);
812814
util.platform.themeHorizontalProgressBar(binding.progressBar);
813815
util.platform.colorViewBackground(getWindow().getDecorView());
814816
util.platform.colorViewBackground(binding.getRoot());
815817
util.material.colorMaterialButtonPrimaryOutlined(binding.btnShareButton);
818+
util.platform.colorTextView(binding.title, ColorRole.ON_SURFACE);
819+
util.platform.colorTextView(binding.fileName, ColorRole.ON_SURFACE_VARIANT);
820+
util.notes.themeSearchCardView(binding.searchCardWrapper);
816821
}
817822

818823
@Override

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

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,35 @@ import androidx.core.database.getIntOrNull
1919
import androidx.core.database.getStringOrNull
2020
import androidx.cursoradapter.widget.CursorAdapter
2121
import it.niedermann.owncloud.notes.R
22+
import it.niedermann.owncloud.notes.branding.BrandingUtil
23+
import it.niedermann.owncloud.notes.databinding.ItemSuggestionAdapterBinding
2224
import it.niedermann.owncloud.notes.persistence.entity.Account
2325
import it.niedermann.owncloud.notes.share.helper.AvatarLoader
2426

25-
class SuggestionAdapter(context: Context, cursor: Cursor?, private val account: Account) : CursorAdapter(context, cursor, false) {
27+
/**
28+
* [CursorAdapter] used to display search suggestions for sharees for sharing notes.
29+
*
30+
* This adapter handles the layout and binding of suggestion data, including the
31+
* display of user avatars or system icons based on the provided search cursor.
32+
*
33+
* @param context The [Context] in which the adapter is running.
34+
* @param cursor The [Cursor] from which to get the data.
35+
* @param account The [Account] used for loading authenticated avatars.
36+
*/
37+
class SuggestionAdapter(context: Context, cursor: Cursor?, private val account: Account) :
38+
CursorAdapter(context, cursor, false) {
2639
override fun newView(context: Context, cursor: Cursor, parent: ViewGroup): View {
27-
val inflater = LayoutInflater.from(context)
28-
return inflater.inflate(R.layout.item_suggestion_adapter, parent, false)
40+
val binding = ItemSuggestionAdapterBinding.inflate(LayoutInflater.from(context), parent, false)
41+
val brandingUtil = BrandingUtil.of(BrandingUtil.readBrandMainColor(parent.context), parent.context)
42+
binding.root.setBackgroundColor(brandingUtil.getScheme(parent.context).surfaceContainerHigh)
43+
return binding.root
2944
}
3045

3146
override fun bindView(view: View, context: Context, cursor: Cursor) {
3247
val suggestion =
3348
cursor.getString(cursor.getColumnIndexOrThrow(SearchManager.SUGGEST_COLUMN_TEXT_1))
3449
view.findViewById<TextView>(R.id.suggestion_text).text = suggestion
3550

36-
3751
val icon = view.findViewById<ImageView>(R.id.suggestion_icon)
3852
val iconColumn = cursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_1)
3953

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

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,19 @@
77
package it.niedermann.owncloud.notes.share.adapter.holder;
88

99
import android.content.Context;
10-
import android.graphics.PorterDuff;
1110
import android.text.TextUtils;
1211
import android.view.View;
1312

14-
import androidx.annotation.ColorInt;
1513
import androidx.annotation.NonNull;
1614
import androidx.core.content.res.ResourcesCompat;
1715

1816
import com.nextcloud.android.common.ui.theme.utils.ColorRole;
1917
import com.owncloud.android.lib.resources.shares.OCShare;
2018
import com.owncloud.android.lib.resources.shares.ShareType;
2119

20+
import java.text.SimpleDateFormat;
21+
import java.util.Date;
22+
2223
import it.niedermann.owncloud.notes.R;
2324
import it.niedermann.owncloud.notes.branding.BrandedViewHolder;
2425
import it.niedermann.owncloud.notes.branding.BrandingUtil;
@@ -83,6 +84,19 @@ public void bind(OCShare publicShare, ShareeListAdapterListener listener) {
8384
binding.shareByLinkContainer.setOnClickListener(v -> listener.showPermissionsDialog(publicShare));
8485
}
8586

87+
if (publicShare.getExpirationDate() > 0) {
88+
binding.expirationStatus.setContentDescription(
89+
context.getString(
90+
R.string.share_expires,
91+
SimpleDateFormat.getDateInstance().format(new Date(publicShare.getExpirationDate()))
92+
)
93+
);
94+
binding.expirationStatus.setVisibility(View.VISIBLE);
95+
} else {
96+
binding.expirationStatus.setContentDescription(null);
97+
binding.expirationStatus.setVisibility(View.GONE);
98+
}
99+
86100
binding.copyLink.setOnClickListener(v -> listener.copyLink(publicShare));
87101
}
88102

@@ -102,6 +116,7 @@ public void applyBrand(int color) {
102116
brandingUtil.androidx.colorPrimaryTextViewElement(binding.permissionName);
103117
brandingUtil.platform.colorTextView(binding.label, ColorRole.ON_SURFACE);
104118
brandingUtil.platform.colorImageViewBackgroundAndIcon(binding.icon);
119+
brandingUtil.platform.colorImageView(binding.expirationStatus, ColorRole.ON_PRIMARY_CONTAINER);
105120
}
106121
}
107122
}

app/src/main/java/it/niedermann/owncloud/notes/share/model/CreateShareResponse.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,5 +139,9 @@ data class CreateShareResponse(
139139

140140
@Expose
141141
@SerializedName("password")
142-
val password: String?
142+
val password: String?,
143+
144+
@Expose
145+
@SerializedName("expiration")
146+
val expirationDate: String?
143147
)

app/src/main/java/it/niedermann/owncloud/notes/share/model/CreateShareResponseExtensions.kt

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,18 @@ package it.niedermann.owncloud.notes.share.model
88

99
import com.owncloud.android.lib.resources.shares.OCShare
1010
import com.owncloud.android.lib.resources.shares.ShareType
11+
import it.niedermann.owncloud.notes.shared.util.extensions.toExpirationDateLong
1112

12-
fun List<CreateShareResponse>.toOCShareList(): List<OCShare> {
13-
return map { response ->
14-
response.toOCShare()
15-
}.filter { it.id != -1L }
16-
}
13+
/**
14+
* Maps a list of [CreateShareResponse] to a list of [OCShare] objects.
15+
*
16+
* Filters out any responses that could not be parsed correctly (where the ID is -1).
17+
*
18+
* @return A list of valid [OCShare] instances.
19+
*/
20+
fun List<CreateShareResponse>.toOCShareList(): List<OCShare> = map { response ->
21+
response.toOCShare()
22+
}.filter { it.id != -1L }
1723

1824
fun CreateShareResponse.toOCShare(): OCShare {
1925
val response = this
@@ -31,13 +37,14 @@ fun CreateShareResponse.toOCShare(): OCShare {
3137
sharedWithDisplayName = response.shareWithDisplayname
3238
isFolder = response.itemType == "folder"
3339
userId = response.uidOwner
34-
shareLink = response.url
40+
shareLink = response.url
3541
isPasswordProtected = !response.password.isNullOrEmpty()
3642
note = response.note
3743
isHideFileDownload = (response.hideDownload == 1L)
3844
label = response.label
3945
isHasPreview = response.hasPreview
4046
mimetype = response.mimetype
4147
ownerDisplayName = response.displaynameOwner
48+
expirationDate = response.expirationDate?.toExpirationDateLong() ?: 0L
4249
}
4350
}

0 commit comments

Comments
 (0)