mirror of
https://github.com/nextcloud/android.git
synced 2024-11-22 21:25:35 +03:00
Merge pull request #12323 from BBBOND/feature/add-exclude-hidden-file-or-folder-option-when-create-custom-media-folder
Feature/add exclude hidden file or folder option when create custom media folder type
This commit is contained in:
commit
bc0c9cf5ce
21 changed files with 1395 additions and 50 deletions
|
@ -291,7 +291,7 @@ dependencies {
|
|||
qaImplementation project(':appscan')
|
||||
|
||||
spotbugsPlugins 'com.h3xstream.findsecbugs:findsecbugs-plugin:1.12.0'
|
||||
spotbugsPlugins 'com.mebigfatguy.fb-contrib:fb-contrib:7.6.4'
|
||||
spotbugsPlugins 'com.mebigfatguy.fb-contrib:fb-contrib:7.6.0'
|
||||
|
||||
implementation "com.google.dagger:dagger:$daggerVersion"
|
||||
implementation "com.google.dagger:dagger-android:$daggerVersion"
|
||||
|
|
|
@ -59,7 +59,7 @@ complexity:
|
|||
excludes: ['**/androidTest/**']
|
||||
LabeledExpression:
|
||||
active: false
|
||||
ignoredLabels: ""
|
||||
ignoredLabels: []
|
||||
LargeClass:
|
||||
active: true
|
||||
threshold: 600
|
||||
|
@ -132,7 +132,7 @@ exceptions:
|
|||
active: true
|
||||
ExceptionRaisedInUnexpectedLocation:
|
||||
active: false
|
||||
methodNames: 'toString,hashCode,equals,finalize'
|
||||
methodNames: [toString,hashCode,equals,finalize]
|
||||
InstanceOfCheckForException:
|
||||
active: false
|
||||
NotImplementedDeclaration:
|
||||
|
@ -145,14 +145,14 @@ exceptions:
|
|||
active: false
|
||||
SwallowedException:
|
||||
active: false
|
||||
ignoredExceptionTypes: 'InterruptedException,NumberFormatException,ParseException,MalformedURLException'
|
||||
ignoredExceptionTypes: [InterruptedException,NumberFormatException,ParseException,MalformedURLException]
|
||||
ThrowingExceptionFromFinally:
|
||||
active: false
|
||||
ThrowingExceptionInMain:
|
||||
active: false
|
||||
ThrowingExceptionsWithoutMessageOrCause:
|
||||
active: false
|
||||
exceptions: 'IllegalArgumentException,IllegalStateException,IOException'
|
||||
exceptions: [IllegalArgumentException,IllegalStateException,IOException]
|
||||
ThrowingNewInstanceOfSameException:
|
||||
active: false
|
||||
TooGenericExceptionCaught:
|
||||
|
@ -190,7 +190,7 @@ naming:
|
|||
enumEntryPattern: '^[A-Z][_a-zA-Z0-9]*'
|
||||
ForbiddenClassName:
|
||||
active: false
|
||||
forbiddenName: ''
|
||||
forbiddenName: []
|
||||
FunctionMaxLength:
|
||||
active: false
|
||||
maximumFunctionNameLength: 30
|
||||
|
@ -291,7 +291,7 @@ style:
|
|||
active: false
|
||||
DataClassContainsFunctions:
|
||||
active: false
|
||||
conversionFunctionPrefix: 'to'
|
||||
conversionFunctionPrefix: [to]
|
||||
EqualsNullCall:
|
||||
active: false
|
||||
EqualsOnSignatureLine:
|
||||
|
@ -306,19 +306,19 @@ style:
|
|||
values: 'TODO:,FIXME:,STOPSHIP:'
|
||||
ForbiddenImport:
|
||||
active: false
|
||||
imports: ''
|
||||
imports: []
|
||||
ForbiddenVoid:
|
||||
active: false
|
||||
FunctionOnlyReturningConstant:
|
||||
active: false
|
||||
ignoreOverridableFunction: true
|
||||
excludedFunctions: 'describeContents'
|
||||
excludedFunctions: [describeContents]
|
||||
LoopWithTooManyJumpStatements:
|
||||
active: false
|
||||
maxJumpCount: 1
|
||||
MagicNumber:
|
||||
active: true
|
||||
ignoreNumbers: '-1,0,1,2'
|
||||
ignoreNumbers: ["-1","0","1","2"]
|
||||
ignoreHashCodeFunction: true
|
||||
ignorePropertyDeclaration: false
|
||||
ignoreConstantDeclaration: true
|
||||
|
@ -362,7 +362,7 @@ style:
|
|||
ReturnCount:
|
||||
active: true
|
||||
max: 2
|
||||
excludedFunctions: "equals"
|
||||
excludedFunctions: [equals]
|
||||
excludeLabeled: false
|
||||
excludeReturnFromLambda: true
|
||||
SafeCast:
|
||||
|
@ -409,4 +409,4 @@ style:
|
|||
active: false
|
||||
WildcardImport:
|
||||
active: true
|
||||
excludeImports: 'java.util.*,kotlinx.android.synthetic.*'
|
||||
excludeImports: [java.util.*,kotlinx.android.synthetic.*]
|
||||
|
|
1197
app/schemas/com.nextcloud.client.database.NextcloudDatabase/78.json
Normal file
1197
app/schemas/com.nextcloud.client.database.NextcloudDatabase/78.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -74,7 +74,8 @@ public class SyncedFoldersActivityIT extends AbstractIT {
|
|||
"Name",
|
||||
MediaFolderType.IMAGE,
|
||||
false,
|
||||
SubFolderRule.YEAR_MONTH);
|
||||
SubFolderRule.YEAR_MONTH,
|
||||
false);
|
||||
SyncedFolderPreferencesDialogFragment sut = SyncedFolderPreferencesDialogFragment.newInstance(item, 0);
|
||||
|
||||
Intent intent = new Intent(targetContext, SyncedFoldersActivity.class);
|
||||
|
|
|
@ -187,7 +187,8 @@ class SyncedFolderUtilsTest : AbstractIT() {
|
|||
0L,
|
||||
MediaFolderType.IMAGE,
|
||||
false,
|
||||
SubFolderRule.YEAR_MONTH
|
||||
SubFolderRule.YEAR_MONTH,
|
||||
false
|
||||
)
|
||||
Assert.assertFalse(SyncedFolderUtils.isQualifyingMediaFolder(folder))
|
||||
}
|
||||
|
@ -210,7 +211,8 @@ class SyncedFolderUtilsTest : AbstractIT() {
|
|||
0L,
|
||||
MediaFolderType.IMAGE,
|
||||
false,
|
||||
SubFolderRule.YEAR_MONTH
|
||||
SubFolderRule.YEAR_MONTH,
|
||||
false
|
||||
)
|
||||
Assert.assertFalse(SyncedFolderUtils.isQualifyingMediaFolder(folder))
|
||||
}
|
||||
|
|
|
@ -70,7 +70,8 @@ import com.owncloud.android.db.ProviderMeta
|
|||
AutoMigration(from = 73, to = 74, spec = DatabaseMigrationUtil.ResetCapabilitiesPostMigration::class),
|
||||
AutoMigration(from = 74, to = 75),
|
||||
AutoMigration(from = 75, to = 76),
|
||||
AutoMigration(from = 76, to = 77)
|
||||
AutoMigration(from = 76, to = 77),
|
||||
AutoMigration(from = 77, to = 78)
|
||||
],
|
||||
exportSchema = true
|
||||
)
|
||||
|
|
|
@ -59,5 +59,7 @@ data class SyncedFolderEntity(
|
|||
@ColumnInfo(name = ProviderTableMeta.SYNCED_FOLDER_HIDDEN)
|
||||
val hidden: Int?,
|
||||
@ColumnInfo(name = ProviderTableMeta.SYNCED_FOLDER_SUBFOLDER_RULE)
|
||||
val subFolderRule: Int?
|
||||
val subFolderRule: Int?,
|
||||
@ColumnInfo(name = ProviderTableMeta.SYNCED_EXCLUDE_HIDDEN)
|
||||
val excludeHidden: Int?
|
||||
)
|
||||
|
|
|
@ -51,6 +51,7 @@ public class SyncedFolder implements Serializable, Cloneable {
|
|||
private MediaFolderType type;
|
||||
private boolean hidden;
|
||||
private SubFolderRule subfolderRule;
|
||||
private boolean excludeHidden;
|
||||
|
||||
/**
|
||||
* constructor for new, to be persisted entity.
|
||||
|
@ -68,6 +69,8 @@ public class SyncedFolder implements Serializable, Cloneable {
|
|||
* @param timestampMs the current timestamp in milliseconds
|
||||
* @param type the type of the folder
|
||||
* @param hidden hide item flag
|
||||
* @param subFolderRule whether to filter subFolder by year/month/day
|
||||
* @param excludeHidden exclude hidden file or folder, for {@link MediaFolderType#CUSTOM} only
|
||||
*/
|
||||
public SyncedFolder(String localPath,
|
||||
String remotePath,
|
||||
|
@ -82,7 +85,8 @@ public class SyncedFolder implements Serializable, Cloneable {
|
|||
long timestampMs,
|
||||
MediaFolderType type,
|
||||
boolean hidden,
|
||||
SubFolderRule subFolderRule) {
|
||||
SubFolderRule subFolderRule,
|
||||
boolean excludeHidden) {
|
||||
this(UNPERSISTED_ID,
|
||||
localPath,
|
||||
remotePath,
|
||||
|
@ -97,7 +101,8 @@ public class SyncedFolder implements Serializable, Cloneable {
|
|||
timestampMs,
|
||||
type,
|
||||
hidden,
|
||||
subFolderRule);
|
||||
subFolderRule,
|
||||
excludeHidden);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -119,7 +124,8 @@ public class SyncedFolder implements Serializable, Cloneable {
|
|||
long timestampMs,
|
||||
MediaFolderType type,
|
||||
boolean hidden,
|
||||
SubFolderRule subFolderRule) {
|
||||
SubFolderRule subFolderRule,
|
||||
boolean excludeHidden) {
|
||||
this.id = id;
|
||||
this.localPath = localPath;
|
||||
this.remotePath = remotePath;
|
||||
|
@ -134,6 +140,7 @@ public class SyncedFolder implements Serializable, Cloneable {
|
|||
this.type = type;
|
||||
this.hidden = hidden;
|
||||
this.subfolderRule = subFolderRule;
|
||||
this.excludeHidden = excludeHidden;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -263,4 +270,12 @@ public class SyncedFolder implements Serializable, Cloneable {
|
|||
}
|
||||
|
||||
public void setSubFolderRule(SubFolderRule subFolderRule) { this.subfolderRule = subFolderRule; }
|
||||
|
||||
public boolean isExcludeHidden() {
|
||||
return excludeHidden;
|
||||
}
|
||||
|
||||
public void setExcludeHidden(boolean excludeHidden) {
|
||||
this.excludeHidden = excludeHidden;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ public class SyncedFolderDisplayItem extends SyncedFolder {
|
|||
* @param type the type of the folder
|
||||
* @param hidden hide item flag
|
||||
* @param subFolderRule whether to filter subFolder by year/month/day
|
||||
* @param excludeHidden exclude hidden file or folder, for {@link MediaFolderType#CUSTOM} only
|
||||
*/
|
||||
public SyncedFolderDisplayItem(long id,
|
||||
String localPath,
|
||||
|
@ -72,7 +73,8 @@ public class SyncedFolderDisplayItem extends SyncedFolder {
|
|||
long numberOfFiles,
|
||||
MediaFolderType type,
|
||||
boolean hidden,
|
||||
SubFolderRule subFolderRule) {
|
||||
SubFolderRule subFolderRule,
|
||||
boolean excludeHidden) {
|
||||
super(id,
|
||||
localPath,
|
||||
remotePath,
|
||||
|
@ -87,7 +89,8 @@ public class SyncedFolderDisplayItem extends SyncedFolder {
|
|||
timestampMs,
|
||||
type,
|
||||
hidden,
|
||||
subFolderRule);
|
||||
subFolderRule,
|
||||
excludeHidden);
|
||||
this.filePaths = filePaths;
|
||||
this.folderName = folderName;
|
||||
this.numberOfFiles = numberOfFiles;
|
||||
|
@ -108,7 +111,8 @@ public class SyncedFolderDisplayItem extends SyncedFolder {
|
|||
String folderName,
|
||||
MediaFolderType type,
|
||||
boolean hidden,
|
||||
SubFolderRule subFolderRule) {
|
||||
SubFolderRule subFolderRule,
|
||||
boolean excludeHidden) {
|
||||
super(id,
|
||||
localPath,
|
||||
remotePath,
|
||||
|
@ -123,7 +127,8 @@ public class SyncedFolderDisplayItem extends SyncedFolder {
|
|||
timestampMs,
|
||||
type,
|
||||
hidden,
|
||||
subFolderRule);
|
||||
subFolderRule,
|
||||
excludeHidden);
|
||||
this.folderName = folderName;
|
||||
}
|
||||
|
||||
|
|
|
@ -372,6 +372,8 @@ public class SyncedFolderProvider extends Observable {
|
|||
ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_HIDDEN)) == 1;
|
||||
SubFolderRule subFolderRule = SubFolderRule.values()[cursor.getInt(
|
||||
cursor.getColumnIndexOrThrow(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_SUBFOLDER_RULE))];
|
||||
boolean excludeHidden = cursor.getInt(cursor.getColumnIndexOrThrow(
|
||||
ProviderMeta.ProviderTableMeta.SYNCED_EXCLUDE_HIDDEN)) == 1;
|
||||
|
||||
|
||||
syncedFolder = new SyncedFolder(id,
|
||||
|
@ -388,7 +390,8 @@ public class SyncedFolderProvider extends Observable {
|
|||
enabledTimestampMs,
|
||||
type,
|
||||
hidden,
|
||||
subFolderRule);
|
||||
subFolderRule,
|
||||
excludeHidden);
|
||||
}
|
||||
return syncedFolder;
|
||||
}
|
||||
|
@ -417,6 +420,7 @@ public class SyncedFolderProvider extends Observable {
|
|||
cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_TYPE, syncedFolder.getType().id);
|
||||
cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_HIDDEN, syncedFolder.isHidden());
|
||||
cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_SUBFOLDER_RULE, syncedFolder.getSubfolderRule().ordinal());
|
||||
cv.put(ProviderMeta.ProviderTableMeta.SYNCED_EXCLUDE_HIDDEN, syncedFolder.isExcludeHidden());
|
||||
|
||||
return cv;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ import java.util.List;
|
|||
*/
|
||||
public class ProviderMeta {
|
||||
public static final String DB_NAME = "filelist";
|
||||
public static final int DB_VERSION = 77;
|
||||
public static final int DB_VERSION = 78;
|
||||
|
||||
private ProviderMeta() {
|
||||
// No instance
|
||||
|
@ -302,6 +302,7 @@ public class ProviderMeta {
|
|||
public static final String SYNCED_FOLDER_NAME_COLLISION_POLICY = "name_collision_policy";
|
||||
public static final String SYNCED_FOLDER_HIDDEN = "hidden";
|
||||
public static final String SYNCED_FOLDER_SUBFOLDER_RULE = "sub_folder_rule";
|
||||
public static final String SYNCED_EXCLUDE_HIDDEN = "exclude_hidden";
|
||||
|
||||
// Columns of external links table
|
||||
public static final String EXTERNAL_LINKS_ICON_URL = "icon_url";
|
||||
|
|
|
@ -24,8 +24,6 @@ package com.owncloud.android.operations;
|
|||
import android.content.Context;
|
||||
|
||||
import com.nextcloud.client.account.User;
|
||||
import com.owncloud.android.datamodel.ArbitraryDataProvider;
|
||||
import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
import com.owncloud.android.datamodel.e2e.v2.decrypted.DecryptedFolderMetadataFile;
|
||||
|
@ -55,7 +53,6 @@ public class RemoveRemoteEncryptedFileOperation extends RemoteOperation<Void> {
|
|||
private final String fileName;
|
||||
private final Context context;
|
||||
private final boolean isFolder;
|
||||
private final ArbitraryDataProvider arbitraryDataProvider;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -75,8 +72,6 @@ public class RemoveRemoteEncryptedFileOperation extends RemoteOperation<Void> {
|
|||
this.context = context;
|
||||
this.parentFolder = parentFolder;
|
||||
this.isFolder = isFolder;
|
||||
|
||||
arbitraryDataProvider = new ArbitraryDataProviderImpl(context);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -403,7 +403,8 @@ class SyncedFoldersActivity :
|
|||
files.size.toLong(),
|
||||
syncedFolder.type,
|
||||
syncedFolder.isHidden,
|
||||
syncedFolder.subfolderRule
|
||||
syncedFolder.subfolderRule,
|
||||
syncedFolder.isExcludeHidden
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -433,7 +434,8 @@ class SyncedFoldersActivity :
|
|||
mediaFolder.numberOfFiles,
|
||||
mediaFolder.type,
|
||||
syncedFolder.isHidden,
|
||||
syncedFolder.subfolderRule
|
||||
syncedFolder.subfolderRule,
|
||||
syncedFolder.isExcludeHidden
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -462,7 +464,8 @@ class SyncedFoldersActivity :
|
|||
mediaFolder.numberOfFiles,
|
||||
mediaFolder.type,
|
||||
false,
|
||||
SubFolderRule.YEAR_MONTH
|
||||
SubFolderRule.YEAR_MONTH,
|
||||
false
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -554,7 +557,8 @@ class SyncedFoldersActivity :
|
|||
null,
|
||||
MediaFolderType.CUSTOM,
|
||||
false,
|
||||
SubFolderRule.YEAR_MONTH
|
||||
SubFolderRule.YEAR_MONTH,
|
||||
false
|
||||
)
|
||||
onSyncFolderSettingsClick(0, emptyCustomFolder)
|
||||
} else {
|
||||
|
@ -670,7 +674,8 @@ class SyncedFoldersActivity :
|
|||
File(syncedFolder.localPath).name,
|
||||
syncedFolder.type,
|
||||
syncedFolder.isHidden,
|
||||
syncedFolder.subFolderRule
|
||||
syncedFolder.subFolderRule,
|
||||
syncedFolder.isExcludeHidden
|
||||
)
|
||||
saveOrUpdateSyncedFolder(newCustomFolder)
|
||||
adapter.addSyncFolderItem(newCustomFolder)
|
||||
|
@ -688,7 +693,8 @@ class SyncedFoldersActivity :
|
|||
syncedFolder.uploadAction,
|
||||
syncedFolder.nameCollisionPolicy.serialize(),
|
||||
syncedFolder.isEnabled,
|
||||
syncedFolder.subFolderRule
|
||||
syncedFolder.subFolderRule,
|
||||
syncedFolder.isExcludeHidden
|
||||
)
|
||||
saveOrUpdateSyncedFolder(item)
|
||||
|
||||
|
@ -759,6 +765,7 @@ class SyncedFoldersActivity :
|
|||
* @param uploadAction upload action
|
||||
* @param nameCollisionPolicy what to do on name collision
|
||||
* @param enabled is sync enabled
|
||||
* @param excludeHidden exclude hidden file or folder, for {@link MediaFolderType#CUSTOM} only
|
||||
*/
|
||||
@Suppress("LongParameterList")
|
||||
private fun updateSyncedFolderItem(
|
||||
|
@ -773,7 +780,8 @@ class SyncedFoldersActivity :
|
|||
uploadAction: Int,
|
||||
nameCollisionPolicy: Int,
|
||||
enabled: Boolean,
|
||||
subFolderRule: SubFolderRule
|
||||
subFolderRule: SubFolderRule,
|
||||
excludeHidden: Boolean
|
||||
) {
|
||||
item.id = id
|
||||
item.localPath = localPath
|
||||
|
@ -786,6 +794,7 @@ class SyncedFoldersActivity :
|
|||
item.setNameCollisionPolicy(nameCollisionPolicy)
|
||||
item.setEnabled(enabled, clock.currentTime)
|
||||
item.setSubFolderRule(subFolderRule)
|
||||
item.setExcludeHidden(excludeHidden)
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(
|
||||
|
|
|
@ -130,12 +130,16 @@ class SyncedFolderPreferencesDialogFragment : DialogFragment(), Injectable {
|
|||
// hide local folder chooser and delete for non-custom folders
|
||||
binding.localFolderContainer.visibility = View.GONE
|
||||
isNeutralButtonActive = false
|
||||
binding.settingInstantUploadExcludeHiddenContainer.visibility = View.GONE
|
||||
} else if (syncedFolder!!.id <= SyncedFolder.UNPERSISTED_ID) {
|
||||
isNeutralButtonActive = false
|
||||
|
||||
// Hide delete/enabled for unpersisted custom folders
|
||||
binding.syncEnabled.visibility = View.GONE
|
||||
|
||||
// Show exclude hidden checkbox when {@link MediaFolderType#CUSTOM}
|
||||
binding.settingInstantUploadExcludeHiddenContainer.visibility = View.VISIBLE
|
||||
|
||||
// auto set custom folder to enabled
|
||||
syncedFolder?.isEnabled = true
|
||||
|
||||
|
@ -146,6 +150,10 @@ class SyncedFolderPreferencesDialogFragment : DialogFragment(), Injectable {
|
|||
binding.btnPositive.isEnabled = false
|
||||
} else {
|
||||
binding.localFolderContainer.visibility = View.GONE
|
||||
if (MediaFolderType.CUSTOM.id == syncedFolder!!.type.id) {
|
||||
// Show exclude hidden checkbox when {@link MediaFolderType#CUSTOM}
|
||||
binding.settingInstantUploadExcludeHiddenContainer.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,7 +164,8 @@ class SyncedFolderPreferencesDialogFragment : DialogFragment(), Injectable {
|
|||
binding.settingInstantUploadOnWifiCheckbox,
|
||||
binding.settingInstantUploadOnChargingCheckbox,
|
||||
binding.settingInstantUploadExistingCheckbox,
|
||||
binding.settingInstantUploadPathUseSubfoldersCheckbox
|
||||
binding.settingInstantUploadPathUseSubfoldersCheckbox,
|
||||
binding.settingInstantUploadExcludeHiddenCheckbox
|
||||
)
|
||||
|
||||
viewThemeUtils?.material?.colorMaterialButtonPrimaryTonal(binding.btnPositive)
|
||||
|
@ -209,6 +218,7 @@ class SyncedFolderPreferencesDialogFragment : DialogFragment(), Injectable {
|
|||
binding.settingInstantUploadOnChargingCheckbox.isChecked = it.isChargingOnly
|
||||
binding.settingInstantUploadExistingCheckbox.isChecked = it.isExisting
|
||||
binding.settingInstantUploadPathUseSubfoldersCheckbox.isChecked = it.isSubfolderByDate
|
||||
binding.settingInstantUploadExcludeHiddenCheckbox.isChecked = it.isExcludeHidden
|
||||
|
||||
binding.settingInstantUploadSubfolderRuleSpinner.setSelection(it.subFolderRule.ordinal)
|
||||
|
||||
|
@ -311,6 +321,8 @@ class SyncedFolderPreferencesDialogFragment : DialogFragment(), Injectable {
|
|||
binding.settingInstantUploadExistingContainer.alpha = alpha
|
||||
binding.settingInstantUploadPathUseSubfoldersContainer.isEnabled = enable
|
||||
binding.settingInstantUploadPathUseSubfoldersContainer.alpha = alpha
|
||||
binding.settingInstantUploadExcludeHiddenContainer.isEnabled = enable
|
||||
binding.settingInstantUploadExcludeHiddenContainer.alpha = alpha
|
||||
binding.remoteFolderContainer.isEnabled = enable
|
||||
binding.remoteFolderContainer.alpha = alpha
|
||||
binding.localFolderContainer.isEnabled = enable
|
||||
|
@ -321,6 +333,7 @@ class SyncedFolderPreferencesDialogFragment : DialogFragment(), Injectable {
|
|||
binding.settingInstantUploadOnChargingCheckbox.isEnabled = enable
|
||||
binding.settingInstantUploadExistingCheckbox.isEnabled = enable
|
||||
binding.settingInstantUploadPathUseSubfoldersCheckbox.isEnabled = enable
|
||||
binding.settingInstantUploadExcludeHiddenCheckbox.isEnabled = enable
|
||||
}
|
||||
|
||||
checkWritableFolder()
|
||||
|
@ -364,6 +377,10 @@ class SyncedFolderPreferencesDialogFragment : DialogFragment(), Injectable {
|
|||
binding.settingInstantUploadSubfolderRuleContainer.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
binding.settingInstantUploadExcludeHiddenContainer.setOnClickListener {
|
||||
syncedFolder.isExcludeHidden = !syncedFolder.isExcludeHidden
|
||||
binding.settingInstantUploadExcludeHiddenCheckbox.toggle()
|
||||
}
|
||||
binding.settingInstantUploadSubfolderRuleSpinner.onItemSelectedListener =
|
||||
object : AdapterView.OnItemSelectedListener {
|
||||
override fun onItemSelected(adapterView: AdapterView<*>?, view: View, i: Int, l: Long) {
|
||||
|
|
|
@ -49,6 +49,7 @@ public class SyncedFolderParcelable implements Parcelable {
|
|||
private String account;
|
||||
private int section;
|
||||
private SubFolderRule subFolderRule;
|
||||
private boolean excludeHidden;
|
||||
|
||||
public SyncedFolderParcelable(SyncedFolderDisplayItem syncedFolderDisplayItem, int section) {
|
||||
id = syncedFolderDisplayItem.getId();
|
||||
|
@ -68,6 +69,7 @@ public class SyncedFolderParcelable implements Parcelable {
|
|||
this.section = section;
|
||||
hidden = syncedFolderDisplayItem.isHidden();
|
||||
subFolderRule = syncedFolderDisplayItem.getSubfolderRule();
|
||||
excludeHidden = syncedFolderDisplayItem.isExcludeHidden();
|
||||
}
|
||||
|
||||
private SyncedFolderParcelable(Parcel read) {
|
||||
|
@ -87,6 +89,7 @@ public class SyncedFolderParcelable implements Parcelable {
|
|||
section = read.readInt();
|
||||
hidden = read.readInt() != 0;
|
||||
subFolderRule = SubFolderRule.values()[read.readInt()];
|
||||
excludeHidden = read.readInt() != 0;
|
||||
}
|
||||
|
||||
public SyncedFolderParcelable() {
|
||||
|
@ -111,6 +114,7 @@ public class SyncedFolderParcelable implements Parcelable {
|
|||
dest.writeInt(section);
|
||||
dest.writeInt(hidden ? 1 : 0);
|
||||
dest.writeInt(subFolderRule.ordinal());
|
||||
dest.writeInt(excludeHidden ? 1 : 0);
|
||||
}
|
||||
|
||||
public static final Creator<SyncedFolderParcelable> CREATOR =
|
||||
|
@ -279,4 +283,12 @@ public class SyncedFolderParcelable implements Parcelable {
|
|||
this.section = section;
|
||||
}
|
||||
public void setSubFolderRule(SubFolderRule subFolderRule) { this.subFolderRule = subFolderRule; }
|
||||
|
||||
public boolean isExcludeHidden() {
|
||||
return excludeHidden;
|
||||
}
|
||||
|
||||
public void setExcludeHidden(boolean excludeHidden) {
|
||||
this.excludeHidden = excludeHidden;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,11 @@ import android.text.TextUtils;
|
|||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import com.owncloud.android.lib.resources.files.UploadFileRemoteOperation;
|
||||
|
||||
import org.lukhnos.nnio.file.FileVisitResult;
|
||||
import org.lukhnos.nnio.file.FileVisitor;
|
||||
import org.lukhnos.nnio.file.Path;
|
||||
import org.lukhnos.nnio.file.impl.FileBasedPathImpl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
@ -77,4 +82,19 @@ public final class FileUtil {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Path walkFileTree(Path start, FileVisitor<? super Path> visitor) throws IOException {
|
||||
if (org.lukhnos.nnio.file.Files.isDirectory(start)) {
|
||||
org.lukhnos.nnio.file.FileVisitResult preVisitDirectoryResult = visitor.preVisitDirectory(start, null);
|
||||
if (preVisitDirectoryResult == FileVisitResult.CONTINUE) {
|
||||
for (File child : start.toFile().listFiles()) {
|
||||
walkFileTree(FileBasedPathImpl.get(child), visitor);
|
||||
}
|
||||
}
|
||||
visitor.postVisitDirectory(start, null);
|
||||
} else {
|
||||
visitor.visitFile(start, new org.lukhnos.nnio.file.attribute.BasicFileAttributes(start.toFile()));
|
||||
}
|
||||
return start;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,6 @@ import com.owncloud.android.db.UploadResult;
|
|||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
|
||||
import org.lukhnos.nnio.file.FileVisitResult;
|
||||
import org.lukhnos.nnio.file.Files;
|
||||
import org.lukhnos.nnio.file.Path;
|
||||
import org.lukhnos.nnio.file.Paths;
|
||||
import org.lukhnos.nnio.file.SimpleFileVisitor;
|
||||
|
@ -94,10 +93,14 @@ public final class FilesSyncHelper {
|
|||
FilesystemDataProvider filesystemDataProvider = new FilesystemDataProvider(contentResolver);
|
||||
Path path = Paths.get(syncedFolder.getLocalPath());
|
||||
|
||||
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
|
||||
FileUtil.walkFileTree(path, new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) {
|
||||
File file = path.toFile();
|
||||
if (syncedFolder.isExcludeHidden() && file.isHidden()) {
|
||||
// exclude hidden file or folder
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
if (syncedFolder.isExisting() || attrs.lastModifiedTime().toMillis() >= enabledTimestampMs) {
|
||||
filesystemDataProvider.storeOrUpdateFileValue(path.toAbsolutePath().toString(),
|
||||
attrs.lastModifiedTime().toMillis(),
|
||||
|
@ -107,6 +110,14 @@ public final class FilesSyncHelper {
|
|||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
|
||||
if (syncedFolder.isExcludeHidden() && dir.compareTo(Paths.get(syncedFolder.getLocalPath())) != 0 && dir.toFile().isHidden()) {
|
||||
return null;
|
||||
}
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult visitFileFailed(Path file, IOException exc) {
|
||||
return FileVisitResult.CONTINUE;
|
||||
|
@ -186,11 +197,10 @@ public final class FilesSyncHelper {
|
|||
|
||||
for (OCUpload failedUpload : failedUploads) {
|
||||
accountExists = false;
|
||||
if(!failedUpload.isWhileChargingOnly()){
|
||||
if (!failedUpload.isWhileChargingOnly()) {
|
||||
whileChargingOnly = false;
|
||||
}
|
||||
if(!failedUpload.isUseWifiOnly())
|
||||
{
|
||||
if (!failedUpload.isUseWifiOnly()) {
|
||||
useWifiOnly = false;
|
||||
}
|
||||
|
||||
|
@ -208,22 +218,21 @@ public final class FilesSyncHelper {
|
|||
}
|
||||
|
||||
failedUploads = uploadsStorageManager.getFailedUploads();
|
||||
if(failedUploads.length == 0)
|
||||
{
|
||||
if (failedUploads.length == 0) {
|
||||
//nothing to do
|
||||
return;
|
||||
}
|
||||
|
||||
if(whileChargingOnly){
|
||||
if (whileChargingOnly) {
|
||||
final BatteryStatus batteryStatus = powerManagementService.getBattery();
|
||||
final boolean charging = batteryStatus.isCharging() || batteryStatus.isFull();
|
||||
if(!charging){
|
||||
if (!charging) {
|
||||
//all uploads requires charging
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (useWifiOnly && !connectivityService.getConnectivity().isWifi()){
|
||||
if (useWifiOnly && !connectivityService.getConnectivity().isWifi()) {
|
||||
//all uploads requires wifi
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -123,6 +123,7 @@ class WebViewUtil(private val context: Context) {
|
|||
* @return
|
||||
*/
|
||||
@SuppressLint("PrivateApi", "DiscouragedPrivateApi")
|
||||
@Suppress("TooGenericExceptionCaught")
|
||||
fun setProxyKKPlus(webView: WebView) {
|
||||
val proxyHost = OwnCloudClientManagerFactory.getProxyHost()
|
||||
val proxyPort = OwnCloudClientManagerFactory.getProxyPort()
|
||||
|
|
|
@ -305,6 +305,57 @@
|
|||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/setting_instant_upload_exclude_hidden_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:padding="@dimen/standard_padding">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/setting_instant_upload_exclude_hidden_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="marquee"
|
||||
android:maxLines="2"
|
||||
android:text="@string/prefs_instant_upload_exclude_hidden_title"
|
||||
android:textAppearance="?attr/textAppearanceListItem" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/setting_instant_upload_exclude_hidden_summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/setting_instant_upload_exclude_hidden_label"
|
||||
android:layout_alignStart="@id/setting_instant_upload_exclude_hidden_label"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="2"
|
||||
android:text="@string/prefs_instant_upload_exclude_hidden_summary"
|
||||
android:textColor="?android:attr/textColorSecondary" />
|
||||
</RelativeLayout>
|
||||
|
||||
<!-- Preference should place its actual preference widget here. -->
|
||||
<LinearLayout
|
||||
android:id="@+id/setting_instant_upload_exclude_hidden_frame"
|
||||
android:layout_width="@dimen/synced_folders_control_width"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:padding="@dimen/standard_padding">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatCheckBox
|
||||
android:id="@+id/setting_instant_upload_exclude_hidden_checkbox"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@null"
|
||||
android:clickable="false"
|
||||
android:focusable="false" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/setting_instant_upload_subfolder_rule_container"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -368,6 +368,8 @@
|
|||
<string name="prefs_synced_folders_remote_path_title">Remote folder</string>
|
||||
<string name="prefs_instant_upload_path_use_subfolders_title">Use subfolders</string>
|
||||
<string name="prefs_instant_upload_path_use_date_subfolders_summary">Store in subfolders based on date</string>
|
||||
<string name="prefs_instant_upload_exclude_hidden_title">Exclude hidden</string>
|
||||
<string name="prefs_instant_upload_exclude_hidden_summary">Exclude hidden files and folders</string>
|
||||
|
||||
<string name="prefs_instant_upload_subfolder_rule_title">Subfolder options</string>
|
||||
|
||||
|
|
|
@ -178,6 +178,7 @@ public class SyncedFoldersActivityTest {
|
|||
2,
|
||||
MediaFolderType.IMAGE,
|
||||
false,
|
||||
SubFolderRule.YEAR_MONTH);
|
||||
SubFolderRule.YEAR_MONTH,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue