Skip to content

Commit

Permalink
Customizations done for Sharing with test cases.
Browse files Browse the repository at this point in the history
Download limit functionality added.
Email selection from contact implemented with Test Cases.
  • Loading branch information
surinder-tsys committed Sep 9, 2024
1 parent 8f42be4 commit aef61f8
Show file tree
Hide file tree
Showing 79 changed files with 3,532 additions and 682 deletions.
396 changes: 396 additions & 0 deletions app/src/androidTest/java/com/nmc/android/ui/FileSharingIT.kt

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package com.nmc.android.ui

import android.content.res.Resources
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import androidx.test.espresso.UiController
import androidx.test.espresso.ViewAction
import org.hamcrest.Description
import org.hamcrest.Matcher
import org.hamcrest.TypeSafeMatcher

object RecyclerViewAssertions {

fun clickChildViewWithId(id: Int): ViewAction {
return object : ViewAction {
override fun getConstraints(): Matcher<View>? {
return null
}

override fun getDescription(): String {
return "Click on a child view with specified id."
}

override fun perform(uiController: UiController?, view: View) {
val v: View = view.findViewById(id)
v.performClick()
}
}
}

fun withRecyclerView(recyclerViewId: Int): RecyclerViewMatcher {
return RecyclerViewMatcher(recyclerViewId)
}

class RecyclerViewMatcher(private val recyclerViewId: Int) {
fun atPosition(position: Int): Matcher<View> {
return atPositionOnView(position, -1)
}

fun atPositionOnView(position: Int, targetViewId: Int): Matcher<View> {
return object : TypeSafeMatcher<View>() {
var resources: Resources? = null
var childView: View? = null

override fun describeTo(description: Description?) {
var idDescription = recyclerViewId.toString()
resources?.let {
idDescription = try {
resources!!.getResourceName(recyclerViewId)
} catch (exception: Resources.NotFoundException) {
"$recyclerViewId (resource name not found)"
}
}

description?.appendText("with id: $idDescription")
}

override fun matchesSafely(view: View?): Boolean {
resources = view?.resources

if (childView == null) {
val recyclerView = view?.rootView?.findViewById<RecyclerView>(recyclerViewId)

if (recyclerView != null && recyclerView.id == recyclerViewId) {
childView = recyclerView.findViewHolderForAdapterPosition(position)?.itemView
} else {
return false
}
}

return if (targetViewId == -1) {
view == childView
} else {
val targetView = childView?.findViewById<View>(targetViewId)
view == targetView
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ class FileDetailSharingFragmentIT : AbstractIT() {
onView(ViewMatchers.withId(R.id.share_process_set_password_switch)).check(matches(isDisplayed()))
onView(ViewMatchers.withId(R.id.share_process_change_name_switch)).check(matches(isDisplayed()))
onView(ViewMatchers.withId(R.id.share_process_allow_resharing_checkbox)).check(matches(not(isDisplayed())))
onView(ViewMatchers.withId(R.id.share_process_download_limit_switch)).check(matches(not(isDisplayed())))

// read-only
onView(ViewMatchers.withId(R.id.share_process_permission_read_only)).check(matches(isChecked()))
Expand Down Expand Up @@ -383,6 +384,7 @@ class FileDetailSharingFragmentIT : AbstractIT() {
onView(ViewMatchers.withId(R.id.share_process_set_password_switch)).check(matches(isDisplayed()))
onView(ViewMatchers.withId(R.id.share_process_change_name_switch)).check(matches(isDisplayed()))
onView(ViewMatchers.withId(R.id.share_process_allow_resharing_checkbox)).check(matches(not(isDisplayed())))
onView(ViewMatchers.withId(R.id.share_process_download_limit_switch)).check(matches(isDisplayed()))

// read-only
publicShare.permissions = 17 // from server
Expand Down Expand Up @@ -500,6 +502,7 @@ class FileDetailSharingFragmentIT : AbstractIT() {
onView(ViewMatchers.withId(R.id.share_process_set_password_switch)).check(matches(not(isDisplayed())))
onView(ViewMatchers.withId(R.id.share_process_change_name_switch)).check(matches(not(isDisplayed())))
onView(ViewMatchers.withId(R.id.share_process_allow_resharing_checkbox)).check(matches(isDisplayed()))
onView(ViewMatchers.withId(R.id.share_process_download_limit_switch)).check(matches(not(isDisplayed())))

// read-only
userShare.permissions = 17 // from server
Expand Down Expand Up @@ -623,6 +626,7 @@ class FileDetailSharingFragmentIT : AbstractIT() {
onView(ViewMatchers.withId(R.id.share_process_set_password_switch)).check(matches(not(isDisplayed())))
onView(ViewMatchers.withId(R.id.share_process_change_name_switch)).check(matches(not(isDisplayed())))
onView(ViewMatchers.withId(R.id.share_process_allow_resharing_checkbox)).check(matches(isDisplayed()))
onView(ViewMatchers.withId(R.id.share_process_download_limit_switch)).check(matches(not(isDisplayed())))

// read-only
userShare.permissions = 17 // from server
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,8 @@
android:label="@string/share_dialog_title"
android:launchMode="singleTop"
android:theme="@style/Theme.ownCloud.Dialog.NoTitle"
android:windowSoftInputMode="adjustResize">
android:configChanges="orientation|screenSize"
android:windowSoftInputMode="adjustPan">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
Expand Down
117 changes: 117 additions & 0 deletions app/src/main/java/com/nmc/android/utils/CheckableThemeUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package com.nmc.android.utils

import android.content.res.ColorStateList
import androidx.appcompat.widget.AppCompatCheckBox
import androidx.appcompat.widget.SwitchCompat
import androidx.core.content.res.ResourcesCompat
import com.owncloud.android.R

object CheckableThemeUtils {
@JvmStatic
fun tintCheckbox(vararg checkBoxes: AppCompatCheckBox) {
for (checkBox in checkBoxes) {
val checkEnabled = ResourcesCompat.getColor(
checkBox.context.resources,
R.color.checkbox_checked_enabled,
checkBox.context.theme
)
val checkDisabled = ResourcesCompat.getColor(
checkBox.context.resources,
R.color.checkbox_checked_disabled,
checkBox.context.theme
)
val uncheckEnabled = ResourcesCompat.getColor(
checkBox.context.resources,
R.color.checkbox_unchecked_enabled,
checkBox.context.theme
)
val uncheckDisabled = ResourcesCompat.getColor(
checkBox.context.resources,
R.color.checkbox_unchecked_disabled,
checkBox.context.theme
)

val states = arrayOf(
intArrayOf(android.R.attr.state_enabled, android.R.attr.state_checked),
intArrayOf(-android.R.attr.state_enabled, android.R.attr.state_checked),
intArrayOf(android.R.attr.state_enabled, -android.R.attr.state_checked),
intArrayOf(-android.R.attr.state_enabled, -android.R.attr.state_checked)
)
val colors = intArrayOf(
checkEnabled,
checkDisabled,
uncheckEnabled,
uncheckDisabled
)
checkBox.buttonTintList = ColorStateList(states, colors)
}
}

@JvmStatic
@JvmOverloads
fun tintSwitch(switchView: SwitchCompat, color: Int = 0, colorText: Boolean = false) {
if (colorText) {
switchView.setTextColor(color)
}

val states = arrayOf(
intArrayOf(android.R.attr.state_enabled, android.R.attr.state_checked),
intArrayOf(android.R.attr.state_enabled, -android.R.attr.state_checked),
intArrayOf(-android.R.attr.state_enabled)
)

val thumbColorCheckedEnabled = ResourcesCompat.getColor(
switchView.context.resources,
R.color.switch_thumb_checked_enabled,
switchView.context.theme
)
val thumbColorUncheckedEnabled =
ResourcesCompat.getColor(
switchView.context.resources,
R.color.switch_thumb_unchecked_enabled,
switchView.context.theme
)
val thumbColorDisabled =
ResourcesCompat.getColor(
switchView.context.resources,
R.color.switch_thumb_disabled,
switchView.context.theme
)

val thumbColors = intArrayOf(
thumbColorCheckedEnabled,
thumbColorUncheckedEnabled,
thumbColorDisabled
)
val thumbColorStateList = ColorStateList(states, thumbColors)

val trackColorCheckedEnabled = ResourcesCompat.getColor(
switchView.context.resources,
R.color.switch_track_checked_enabled,
switchView.context.theme
)
val trackColorUncheckedEnabled =
ResourcesCompat.getColor(
switchView.context.resources,
R.color.switch_track_unchecked_enabled,
switchView.context.theme
)
val trackColorDisabled =
ResourcesCompat.getColor(
switchView.context.resources,
R.color.switch_track_disabled,
switchView.context.theme
)

val trackColors = intArrayOf(
trackColorCheckedEnabled,
trackColorUncheckedEnabled,
trackColorDisabled
)

val trackColorStateList = ColorStateList(states, trackColors)

switchView.thumbTintList = thumbColorStateList
switchView.trackTintList = trackColorStateList
}
}
18 changes: 18 additions & 0 deletions app/src/main/java/com/nmc/android/utils/DisplayUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.nmc.android.utils

import android.content.res.Configuration
import com.owncloud.android.MainApp
import com.owncloud.android.R

object DisplayUtils {

@JvmStatic
fun isShowDividerForList(): Boolean = isTablet() || isLandscapeOrientation()

@JvmStatic
fun isTablet(): Boolean = MainApp.getAppContext().resources.getBoolean(R.bool.isTablet)

@JvmStatic
fun isLandscapeOrientation(): Boolean =
MainApp.getAppContext().resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
}
21 changes: 21 additions & 0 deletions app/src/main/java/com/nmc/android/utils/KeyboardUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.nmc.android.utils;

import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.view.inputmethod.InputMethodManager;

public class KeyboardUtils {

public static void showSoftKeyboard(Context context, View view) {
view.requestFocus();
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
}

public static void hideKeyboardFrom(Context context, View view) {
view.clearFocus();
InputMethodManager imm = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
22 changes: 22 additions & 0 deletions app/src/main/java/com/nmc/android/utils/SearchViewThemeUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.nmc.android.utils

import android.content.Context
import android.widget.ImageView
import androidx.appcompat.widget.SearchView
import com.owncloud.android.R

object SearchViewThemeUtils {
fun themeSearchView(context: Context, searchView: SearchView) {
val fontColor = context.resources.getColor(R.color.fontAppbar, null)
val editText: SearchView.SearchAutoComplete = searchView.findViewById(R.id.search_src_text)
editText.textSize = 16F
editText.setTextColor(fontColor)
editText.highlightColor = context.resources.getColor(R.color.et_highlight_color, null)
editText.setHintTextColor(context.resources.getColor(R.color.fontSecondaryAppbar, null))
val closeButton: ImageView = searchView.findViewById(R.id.search_close_btn)
closeButton.setColorFilter(fontColor)
val searchButton: ImageView = searchView.findViewById(R.id.search_button)
searchButton.setImageResource(R.drawable.ic_search)
searchButton.setColorFilter(fontColor)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,9 @@ protected RemoteOperationResult run(OwnCloudClient client) {

// once creating share link update other information
UpdateShareInfoOperation updateShareInfoOperation = new UpdateShareInfoOperation(share, getStorageManager());
updateShareInfoOperation.setExpirationDateInMillis(expirationDateInMillis);
if (expirationDateInMillis > 0) {
updateShareInfoOperation.setExpirationDateInMillis(expirationDateInMillis);
}
updateShareInfoOperation.setHideFileDownload(hideFileDownload);
updateShareInfoOperation.setNote(noteMessage);
updateShareInfoOperation.setLabel(label);
Expand Down
Loading

0 comments on commit aef61f8

Please sign in to comment.