mirror of
https://github.com/nextcloud/android.git
synced 2024-11-23 05:35:39 +03:00
add exclude hidden file or folder option when create custom media folder type
Signed-off-by: JinWeiyang <jwy8645@163.com>
This commit is contained in:
parent
f7502cead3
commit
82fc3cf217
15 changed files with 182 additions and 31 deletions
|
@ -74,7 +74,8 @@ public class SyncedFoldersActivityIT extends AbstractIT {
|
||||||
"Name",
|
"Name",
|
||||||
MediaFolderType.IMAGE,
|
MediaFolderType.IMAGE,
|
||||||
false,
|
false,
|
||||||
SubFolderRule.YEAR_MONTH);
|
SubFolderRule.YEAR_MONTH,
|
||||||
|
false);
|
||||||
SyncedFolderPreferencesDialogFragment sut = SyncedFolderPreferencesDialogFragment.newInstance(item, 0);
|
SyncedFolderPreferencesDialogFragment sut = SyncedFolderPreferencesDialogFragment.newInstance(item, 0);
|
||||||
|
|
||||||
Intent intent = new Intent(targetContext, SyncedFoldersActivity.class);
|
Intent intent = new Intent(targetContext, SyncedFoldersActivity.class);
|
||||||
|
|
|
@ -187,7 +187,8 @@ class SyncedFolderUtilsTest : AbstractIT() {
|
||||||
0L,
|
0L,
|
||||||
MediaFolderType.IMAGE,
|
MediaFolderType.IMAGE,
|
||||||
false,
|
false,
|
||||||
SubFolderRule.YEAR_MONTH
|
SubFolderRule.YEAR_MONTH,
|
||||||
|
false
|
||||||
)
|
)
|
||||||
Assert.assertFalse(SyncedFolderUtils.isQualifyingMediaFolder(folder))
|
Assert.assertFalse(SyncedFolderUtils.isQualifyingMediaFolder(folder))
|
||||||
}
|
}
|
||||||
|
@ -210,7 +211,8 @@ class SyncedFolderUtilsTest : AbstractIT() {
|
||||||
0L,
|
0L,
|
||||||
MediaFolderType.IMAGE,
|
MediaFolderType.IMAGE,
|
||||||
false,
|
false,
|
||||||
SubFolderRule.YEAR_MONTH
|
SubFolderRule.YEAR_MONTH,
|
||||||
|
false
|
||||||
)
|
)
|
||||||
Assert.assertFalse(SyncedFolderUtils.isQualifyingMediaFolder(folder))
|
Assert.assertFalse(SyncedFolderUtils.isQualifyingMediaFolder(folder))
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,5 +59,7 @@ data class SyncedFolderEntity(
|
||||||
@ColumnInfo(name = ProviderTableMeta.SYNCED_FOLDER_HIDDEN)
|
@ColumnInfo(name = ProviderTableMeta.SYNCED_FOLDER_HIDDEN)
|
||||||
val hidden: Int?,
|
val hidden: Int?,
|
||||||
@ColumnInfo(name = ProviderTableMeta.SYNCED_FOLDER_SUBFOLDER_RULE)
|
@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 MediaFolderType type;
|
||||||
private boolean hidden;
|
private boolean hidden;
|
||||||
private SubFolderRule subfolderRule;
|
private SubFolderRule subfolderRule;
|
||||||
|
private boolean excludeHidden;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* constructor for new, to be persisted entity.
|
* 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 timestampMs the current timestamp in milliseconds
|
||||||
* @param type the type of the folder
|
* @param type the type of the folder
|
||||||
* @param hidden hide item flag
|
* @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,
|
public SyncedFolder(String localPath,
|
||||||
String remotePath,
|
String remotePath,
|
||||||
|
@ -82,7 +85,8 @@ public class SyncedFolder implements Serializable, Cloneable {
|
||||||
long timestampMs,
|
long timestampMs,
|
||||||
MediaFolderType type,
|
MediaFolderType type,
|
||||||
boolean hidden,
|
boolean hidden,
|
||||||
SubFolderRule subFolderRule) {
|
SubFolderRule subFolderRule,
|
||||||
|
boolean excludeHidden) {
|
||||||
this(UNPERSISTED_ID,
|
this(UNPERSISTED_ID,
|
||||||
localPath,
|
localPath,
|
||||||
remotePath,
|
remotePath,
|
||||||
|
@ -97,7 +101,8 @@ public class SyncedFolder implements Serializable, Cloneable {
|
||||||
timestampMs,
|
timestampMs,
|
||||||
type,
|
type,
|
||||||
hidden,
|
hidden,
|
||||||
subFolderRule);
|
subFolderRule,
|
||||||
|
excludeHidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -119,7 +124,8 @@ public class SyncedFolder implements Serializable, Cloneable {
|
||||||
long timestampMs,
|
long timestampMs,
|
||||||
MediaFolderType type,
|
MediaFolderType type,
|
||||||
boolean hidden,
|
boolean hidden,
|
||||||
SubFolderRule subFolderRule) {
|
SubFolderRule subFolderRule,
|
||||||
|
boolean excludeHidden) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.localPath = localPath;
|
this.localPath = localPath;
|
||||||
this.remotePath = remotePath;
|
this.remotePath = remotePath;
|
||||||
|
@ -134,6 +140,7 @@ public class SyncedFolder implements Serializable, Cloneable {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.hidden = hidden;
|
this.hidden = hidden;
|
||||||
this.subfolderRule = subFolderRule;
|
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 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 type the type of the folder
|
||||||
* @param hidden hide item flag
|
* @param hidden hide item flag
|
||||||
* @param subFolderRule whether to filter subFolder by year/month/day
|
* @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,
|
public SyncedFolderDisplayItem(long id,
|
||||||
String localPath,
|
String localPath,
|
||||||
|
@ -72,7 +73,8 @@ public class SyncedFolderDisplayItem extends SyncedFolder {
|
||||||
long numberOfFiles,
|
long numberOfFiles,
|
||||||
MediaFolderType type,
|
MediaFolderType type,
|
||||||
boolean hidden,
|
boolean hidden,
|
||||||
SubFolderRule subFolderRule) {
|
SubFolderRule subFolderRule,
|
||||||
|
boolean excludeHidden) {
|
||||||
super(id,
|
super(id,
|
||||||
localPath,
|
localPath,
|
||||||
remotePath,
|
remotePath,
|
||||||
|
@ -87,7 +89,8 @@ public class SyncedFolderDisplayItem extends SyncedFolder {
|
||||||
timestampMs,
|
timestampMs,
|
||||||
type,
|
type,
|
||||||
hidden,
|
hidden,
|
||||||
subFolderRule);
|
subFolderRule,
|
||||||
|
excludeHidden);
|
||||||
this.filePaths = filePaths;
|
this.filePaths = filePaths;
|
||||||
this.folderName = folderName;
|
this.folderName = folderName;
|
||||||
this.numberOfFiles = numberOfFiles;
|
this.numberOfFiles = numberOfFiles;
|
||||||
|
@ -108,7 +111,8 @@ public class SyncedFolderDisplayItem extends SyncedFolder {
|
||||||
String folderName,
|
String folderName,
|
||||||
MediaFolderType type,
|
MediaFolderType type,
|
||||||
boolean hidden,
|
boolean hidden,
|
||||||
SubFolderRule subFolderRule) {
|
SubFolderRule subFolderRule,
|
||||||
|
boolean excludeHidden) {
|
||||||
super(id,
|
super(id,
|
||||||
localPath,
|
localPath,
|
||||||
remotePath,
|
remotePath,
|
||||||
|
@ -123,7 +127,8 @@ public class SyncedFolderDisplayItem extends SyncedFolder {
|
||||||
timestampMs,
|
timestampMs,
|
||||||
type,
|
type,
|
||||||
hidden,
|
hidden,
|
||||||
subFolderRule);
|
subFolderRule,
|
||||||
|
excludeHidden);
|
||||||
this.folderName = folderName;
|
this.folderName = folderName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -372,6 +372,8 @@ public class SyncedFolderProvider extends Observable {
|
||||||
ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_HIDDEN)) == 1;
|
ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_HIDDEN)) == 1;
|
||||||
SubFolderRule subFolderRule = SubFolderRule.values()[cursor.getInt(
|
SubFolderRule subFolderRule = SubFolderRule.values()[cursor.getInt(
|
||||||
cursor.getColumnIndexOrThrow(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_SUBFOLDER_RULE))];
|
cursor.getColumnIndexOrThrow(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_SUBFOLDER_RULE))];
|
||||||
|
boolean excludeHidden = cursor.getInt(cursor.getColumnIndexOrThrow(
|
||||||
|
ProviderMeta.ProviderTableMeta.SYNCED_EXCLUDE_HIDDEN)) == 1;
|
||||||
|
|
||||||
|
|
||||||
syncedFolder = new SyncedFolder(id,
|
syncedFolder = new SyncedFolder(id,
|
||||||
|
@ -388,7 +390,8 @@ public class SyncedFolderProvider extends Observable {
|
||||||
enabledTimestampMs,
|
enabledTimestampMs,
|
||||||
type,
|
type,
|
||||||
hidden,
|
hidden,
|
||||||
subFolderRule);
|
subFolderRule,
|
||||||
|
excludeHidden);
|
||||||
}
|
}
|
||||||
return syncedFolder;
|
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_TYPE, syncedFolder.getType().id);
|
||||||
cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_HIDDEN, syncedFolder.isHidden());
|
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_FOLDER_SUBFOLDER_RULE, syncedFolder.getSubfolderRule().ordinal());
|
||||||
|
cv.put(ProviderMeta.ProviderTableMeta.SYNCED_EXCLUDE_HIDDEN, syncedFolder.isExcludeHidden());
|
||||||
|
|
||||||
return cv;
|
return cv;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_NAME_COLLISION_POLICY = "name_collision_policy";
|
||||||
public static final String SYNCED_FOLDER_HIDDEN = "hidden";
|
public static final String SYNCED_FOLDER_HIDDEN = "hidden";
|
||||||
public static final String SYNCED_FOLDER_SUBFOLDER_RULE = "sub_folder_rule";
|
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
|
// Columns of external links table
|
||||||
public static final String EXTERNAL_LINKS_ICON_URL = "icon_url";
|
public static final String EXTERNAL_LINKS_ICON_URL = "icon_url";
|
||||||
|
|
|
@ -403,7 +403,8 @@ class SyncedFoldersActivity :
|
||||||
files.size.toLong(),
|
files.size.toLong(),
|
||||||
syncedFolder.type,
|
syncedFolder.type,
|
||||||
syncedFolder.isHidden,
|
syncedFolder.isHidden,
|
||||||
syncedFolder.subfolderRule
|
syncedFolder.subfolderRule,
|
||||||
|
syncedFolder.isExcludeHidden
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,7 +434,8 @@ class SyncedFoldersActivity :
|
||||||
mediaFolder.numberOfFiles,
|
mediaFolder.numberOfFiles,
|
||||||
mediaFolder.type,
|
mediaFolder.type,
|
||||||
syncedFolder.isHidden,
|
syncedFolder.isHidden,
|
||||||
syncedFolder.subfolderRule
|
syncedFolder.subfolderRule,
|
||||||
|
syncedFolder.isExcludeHidden
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -462,7 +464,8 @@ class SyncedFoldersActivity :
|
||||||
mediaFolder.numberOfFiles,
|
mediaFolder.numberOfFiles,
|
||||||
mediaFolder.type,
|
mediaFolder.type,
|
||||||
false,
|
false,
|
||||||
SubFolderRule.YEAR_MONTH
|
SubFolderRule.YEAR_MONTH,
|
||||||
|
false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,7 +557,8 @@ class SyncedFoldersActivity :
|
||||||
null,
|
null,
|
||||||
MediaFolderType.CUSTOM,
|
MediaFolderType.CUSTOM,
|
||||||
false,
|
false,
|
||||||
SubFolderRule.YEAR_MONTH
|
SubFolderRule.YEAR_MONTH,
|
||||||
|
false
|
||||||
)
|
)
|
||||||
onSyncFolderSettingsClick(0, emptyCustomFolder)
|
onSyncFolderSettingsClick(0, emptyCustomFolder)
|
||||||
} else {
|
} else {
|
||||||
|
@ -670,7 +674,8 @@ class SyncedFoldersActivity :
|
||||||
File(syncedFolder.localPath).name,
|
File(syncedFolder.localPath).name,
|
||||||
syncedFolder.type,
|
syncedFolder.type,
|
||||||
syncedFolder.isHidden,
|
syncedFolder.isHidden,
|
||||||
syncedFolder.subFolderRule
|
syncedFolder.subFolderRule,
|
||||||
|
syncedFolder.isExcludeHidden
|
||||||
)
|
)
|
||||||
saveOrUpdateSyncedFolder(newCustomFolder)
|
saveOrUpdateSyncedFolder(newCustomFolder)
|
||||||
adapter.addSyncFolderItem(newCustomFolder)
|
adapter.addSyncFolderItem(newCustomFolder)
|
||||||
|
@ -688,7 +693,8 @@ class SyncedFoldersActivity :
|
||||||
syncedFolder.uploadAction,
|
syncedFolder.uploadAction,
|
||||||
syncedFolder.nameCollisionPolicy.serialize(),
|
syncedFolder.nameCollisionPolicy.serialize(),
|
||||||
syncedFolder.isEnabled,
|
syncedFolder.isEnabled,
|
||||||
syncedFolder.subFolderRule
|
syncedFolder.subFolderRule,
|
||||||
|
syncedFolder.isExcludeHidden
|
||||||
)
|
)
|
||||||
saveOrUpdateSyncedFolder(item)
|
saveOrUpdateSyncedFolder(item)
|
||||||
|
|
||||||
|
@ -759,6 +765,7 @@ class SyncedFoldersActivity :
|
||||||
* @param uploadAction upload action
|
* @param uploadAction upload action
|
||||||
* @param nameCollisionPolicy what to do on name collision
|
* @param nameCollisionPolicy what to do on name collision
|
||||||
* @param enabled is sync enabled
|
* @param enabled is sync enabled
|
||||||
|
* @param excludeHidden exclude hidden file or folder, for {@link MediaFolderType#CUSTOM} only
|
||||||
*/
|
*/
|
||||||
@Suppress("LongParameterList")
|
@Suppress("LongParameterList")
|
||||||
private fun updateSyncedFolderItem(
|
private fun updateSyncedFolderItem(
|
||||||
|
@ -773,7 +780,8 @@ class SyncedFoldersActivity :
|
||||||
uploadAction: Int,
|
uploadAction: Int,
|
||||||
nameCollisionPolicy: Int,
|
nameCollisionPolicy: Int,
|
||||||
enabled: Boolean,
|
enabled: Boolean,
|
||||||
subFolderRule: SubFolderRule
|
subFolderRule: SubFolderRule,
|
||||||
|
excludeHidden: Boolean
|
||||||
) {
|
) {
|
||||||
item.id = id
|
item.id = id
|
||||||
item.localPath = localPath
|
item.localPath = localPath
|
||||||
|
@ -786,6 +794,7 @@ class SyncedFoldersActivity :
|
||||||
item.setNameCollisionPolicy(nameCollisionPolicy)
|
item.setNameCollisionPolicy(nameCollisionPolicy)
|
||||||
item.setEnabled(enabled, clock.currentTime)
|
item.setEnabled(enabled, clock.currentTime)
|
||||||
item.setSubFolderRule(subFolderRule)
|
item.setSubFolderRule(subFolderRule)
|
||||||
|
item.setExcludeHidden(excludeHidden)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onRequestPermissionsResult(
|
override fun onRequestPermissionsResult(
|
||||||
|
|
|
@ -130,12 +130,16 @@ class SyncedFolderPreferencesDialogFragment : DialogFragment(), Injectable {
|
||||||
// hide local folder chooser and delete for non-custom folders
|
// hide local folder chooser and delete for non-custom folders
|
||||||
binding.localFolderContainer.visibility = View.GONE
|
binding.localFolderContainer.visibility = View.GONE
|
||||||
isNeutralButtonActive = false
|
isNeutralButtonActive = false
|
||||||
|
binding.settingInstantUploadExcludeHiddenContainer.visibility = View.GONE
|
||||||
} else if (syncedFolder!!.id <= SyncedFolder.UNPERSISTED_ID) {
|
} else if (syncedFolder!!.id <= SyncedFolder.UNPERSISTED_ID) {
|
||||||
isNeutralButtonActive = false
|
isNeutralButtonActive = false
|
||||||
|
|
||||||
// Hide delete/enabled for unpersisted custom folders
|
// Hide delete/enabled for unpersisted custom folders
|
||||||
binding.syncEnabled.visibility = View.GONE
|
binding.syncEnabled.visibility = View.GONE
|
||||||
|
|
||||||
|
// Show exclude hidden checkbox when {@link MediaFolderType#CUSTOM}
|
||||||
|
binding.settingInstantUploadExcludeHiddenContainer.visibility = View.VISIBLE
|
||||||
|
|
||||||
// auto set custom folder to enabled
|
// auto set custom folder to enabled
|
||||||
syncedFolder?.isEnabled = true
|
syncedFolder?.isEnabled = true
|
||||||
|
|
||||||
|
@ -146,6 +150,10 @@ class SyncedFolderPreferencesDialogFragment : DialogFragment(), Injectable {
|
||||||
binding.btnPositive.isEnabled = false
|
binding.btnPositive.isEnabled = false
|
||||||
} else {
|
} else {
|
||||||
binding.localFolderContainer.visibility = View.GONE
|
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.settingInstantUploadOnWifiCheckbox,
|
||||||
binding.settingInstantUploadOnChargingCheckbox,
|
binding.settingInstantUploadOnChargingCheckbox,
|
||||||
binding.settingInstantUploadExistingCheckbox,
|
binding.settingInstantUploadExistingCheckbox,
|
||||||
binding.settingInstantUploadPathUseSubfoldersCheckbox
|
binding.settingInstantUploadPathUseSubfoldersCheckbox,
|
||||||
|
binding.settingInstantUploadExcludeHiddenCheckbox
|
||||||
)
|
)
|
||||||
|
|
||||||
viewThemeUtils?.material?.colorMaterialButtonPrimaryTonal(binding.btnPositive)
|
viewThemeUtils?.material?.colorMaterialButtonPrimaryTonal(binding.btnPositive)
|
||||||
|
@ -209,6 +218,7 @@ class SyncedFolderPreferencesDialogFragment : DialogFragment(), Injectable {
|
||||||
binding.settingInstantUploadOnChargingCheckbox.isChecked = it.isChargingOnly
|
binding.settingInstantUploadOnChargingCheckbox.isChecked = it.isChargingOnly
|
||||||
binding.settingInstantUploadExistingCheckbox.isChecked = it.isExisting
|
binding.settingInstantUploadExistingCheckbox.isChecked = it.isExisting
|
||||||
binding.settingInstantUploadPathUseSubfoldersCheckbox.isChecked = it.isSubfolderByDate
|
binding.settingInstantUploadPathUseSubfoldersCheckbox.isChecked = it.isSubfolderByDate
|
||||||
|
binding.settingInstantUploadExcludeHiddenCheckbox.isChecked = it.isExcludeHidden
|
||||||
|
|
||||||
binding.settingInstantUploadSubfolderRuleSpinner.setSelection(it.subFolderRule.ordinal)
|
binding.settingInstantUploadSubfolderRuleSpinner.setSelection(it.subFolderRule.ordinal)
|
||||||
|
|
||||||
|
@ -311,6 +321,8 @@ class SyncedFolderPreferencesDialogFragment : DialogFragment(), Injectable {
|
||||||
binding.settingInstantUploadExistingContainer.alpha = alpha
|
binding.settingInstantUploadExistingContainer.alpha = alpha
|
||||||
binding.settingInstantUploadPathUseSubfoldersContainer.isEnabled = enable
|
binding.settingInstantUploadPathUseSubfoldersContainer.isEnabled = enable
|
||||||
binding.settingInstantUploadPathUseSubfoldersContainer.alpha = alpha
|
binding.settingInstantUploadPathUseSubfoldersContainer.alpha = alpha
|
||||||
|
binding.settingInstantUploadExcludeHiddenContainer.isEnabled = enable
|
||||||
|
binding.settingInstantUploadExcludeHiddenContainer.alpha = alpha
|
||||||
binding.remoteFolderContainer.isEnabled = enable
|
binding.remoteFolderContainer.isEnabled = enable
|
||||||
binding.remoteFolderContainer.alpha = alpha
|
binding.remoteFolderContainer.alpha = alpha
|
||||||
binding.localFolderContainer.isEnabled = enable
|
binding.localFolderContainer.isEnabled = enable
|
||||||
|
@ -321,6 +333,7 @@ class SyncedFolderPreferencesDialogFragment : DialogFragment(), Injectable {
|
||||||
binding.settingInstantUploadOnChargingCheckbox.isEnabled = enable
|
binding.settingInstantUploadOnChargingCheckbox.isEnabled = enable
|
||||||
binding.settingInstantUploadExistingCheckbox.isEnabled = enable
|
binding.settingInstantUploadExistingCheckbox.isEnabled = enable
|
||||||
binding.settingInstantUploadPathUseSubfoldersCheckbox.isEnabled = enable
|
binding.settingInstantUploadPathUseSubfoldersCheckbox.isEnabled = enable
|
||||||
|
binding.settingInstantUploadExcludeHiddenCheckbox.isEnabled = enable
|
||||||
}
|
}
|
||||||
|
|
||||||
checkWritableFolder()
|
checkWritableFolder()
|
||||||
|
@ -364,6 +377,10 @@ class SyncedFolderPreferencesDialogFragment : DialogFragment(), Injectable {
|
||||||
binding.settingInstantUploadSubfolderRuleContainer.visibility = View.GONE
|
binding.settingInstantUploadSubfolderRuleContainer.visibility = View.GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
binding.settingInstantUploadExcludeHiddenContainer.setOnClickListener {
|
||||||
|
syncedFolder.isExcludeHidden = !syncedFolder.isExcludeHidden
|
||||||
|
binding.settingInstantUploadExcludeHiddenCheckbox.toggle()
|
||||||
|
}
|
||||||
binding.settingInstantUploadSubfolderRuleSpinner.onItemSelectedListener =
|
binding.settingInstantUploadSubfolderRuleSpinner.onItemSelectedListener =
|
||||||
object : AdapterView.OnItemSelectedListener {
|
object : AdapterView.OnItemSelectedListener {
|
||||||
override fun onItemSelected(adapterView: AdapterView<*>?, view: View, i: Int, l: Long) {
|
override fun onItemSelected(adapterView: AdapterView<*>?, view: View, i: Int, l: Long) {
|
||||||
|
|
|
@ -49,6 +49,7 @@ public class SyncedFolderParcelable implements Parcelable {
|
||||||
private String account;
|
private String account;
|
||||||
private int section;
|
private int section;
|
||||||
private SubFolderRule subFolderRule;
|
private SubFolderRule subFolderRule;
|
||||||
|
private boolean excludeHidden;
|
||||||
|
|
||||||
public SyncedFolderParcelable(SyncedFolderDisplayItem syncedFolderDisplayItem, int section) {
|
public SyncedFolderParcelable(SyncedFolderDisplayItem syncedFolderDisplayItem, int section) {
|
||||||
id = syncedFolderDisplayItem.getId();
|
id = syncedFolderDisplayItem.getId();
|
||||||
|
@ -68,6 +69,7 @@ public class SyncedFolderParcelable implements Parcelable {
|
||||||
this.section = section;
|
this.section = section;
|
||||||
hidden = syncedFolderDisplayItem.isHidden();
|
hidden = syncedFolderDisplayItem.isHidden();
|
||||||
subFolderRule = syncedFolderDisplayItem.getSubfolderRule();
|
subFolderRule = syncedFolderDisplayItem.getSubfolderRule();
|
||||||
|
excludeHidden = syncedFolderDisplayItem.isExcludeHidden();
|
||||||
}
|
}
|
||||||
|
|
||||||
private SyncedFolderParcelable(Parcel read) {
|
private SyncedFolderParcelable(Parcel read) {
|
||||||
|
@ -87,6 +89,7 @@ public class SyncedFolderParcelable implements Parcelable {
|
||||||
section = read.readInt();
|
section = read.readInt();
|
||||||
hidden = read.readInt() != 0;
|
hidden = read.readInt() != 0;
|
||||||
subFolderRule = SubFolderRule.values()[read.readInt()];
|
subFolderRule = SubFolderRule.values()[read.readInt()];
|
||||||
|
excludeHidden = read.readInt() != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SyncedFolderParcelable() {
|
public SyncedFolderParcelable() {
|
||||||
|
@ -111,6 +114,7 @@ public class SyncedFolderParcelable implements Parcelable {
|
||||||
dest.writeInt(section);
|
dest.writeInt(section);
|
||||||
dest.writeInt(hidden ? 1 : 0);
|
dest.writeInt(hidden ? 1 : 0);
|
||||||
dest.writeInt(subFolderRule.ordinal());
|
dest.writeInt(subFolderRule.ordinal());
|
||||||
|
dest.writeInt(excludeHidden ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Creator<SyncedFolderParcelable> CREATOR =
|
public static final Creator<SyncedFolderParcelable> CREATOR =
|
||||||
|
@ -279,4 +283,12 @@ public class SyncedFolderParcelable implements Parcelable {
|
||||||
this.section = section;
|
this.section = section;
|
||||||
}
|
}
|
||||||
public void setSubFolderRule(SubFolderRule subFolderRule) { this.subFolderRule = subFolderRule; }
|
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.common.utils.Log_OC;
|
||||||
import com.owncloud.android.lib.resources.files.UploadFileRemoteOperation;
|
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.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
@ -77,4 +82,19 @@ public final class FileUtil {
|
||||||
return null;
|
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 com.owncloud.android.lib.common.utils.Log_OC;
|
||||||
|
|
||||||
import org.lukhnos.nnio.file.FileVisitResult;
|
import org.lukhnos.nnio.file.FileVisitResult;
|
||||||
import org.lukhnos.nnio.file.Files;
|
|
||||||
import org.lukhnos.nnio.file.Path;
|
import org.lukhnos.nnio.file.Path;
|
||||||
import org.lukhnos.nnio.file.Paths;
|
import org.lukhnos.nnio.file.Paths;
|
||||||
import org.lukhnos.nnio.file.SimpleFileVisitor;
|
import org.lukhnos.nnio.file.SimpleFileVisitor;
|
||||||
|
@ -94,10 +93,14 @@ public final class FilesSyncHelper {
|
||||||
FilesystemDataProvider filesystemDataProvider = new FilesystemDataProvider(contentResolver);
|
FilesystemDataProvider filesystemDataProvider = new FilesystemDataProvider(contentResolver);
|
||||||
Path path = Paths.get(syncedFolder.getLocalPath());
|
Path path = Paths.get(syncedFolder.getLocalPath());
|
||||||
|
|
||||||
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
|
FileUtil.walkFileTree(path, new SimpleFileVisitor<Path>() {
|
||||||
@Override
|
@Override
|
||||||
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) {
|
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) {
|
||||||
File file = path.toFile();
|
File file = path.toFile();
|
||||||
|
if (syncedFolder.isExcludeHidden() && file.isHidden()) {
|
||||||
|
// exclude hidden file or folder
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
if (syncedFolder.isExisting() || attrs.lastModifiedTime().toMillis() >= enabledTimestampMs) {
|
if (syncedFolder.isExisting() || attrs.lastModifiedTime().toMillis() >= enabledTimestampMs) {
|
||||||
filesystemDataProvider.storeOrUpdateFileValue(path.toAbsolutePath().toString(),
|
filesystemDataProvider.storeOrUpdateFileValue(path.toAbsolutePath().toString(),
|
||||||
attrs.lastModifiedTime().toMillis(),
|
attrs.lastModifiedTime().toMillis(),
|
||||||
|
@ -107,6 +110,14 @@ public final class FilesSyncHelper {
|
||||||
return FileVisitResult.CONTINUE;
|
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
|
@Override
|
||||||
public FileVisitResult visitFileFailed(Path file, IOException exc) {
|
public FileVisitResult visitFileFailed(Path file, IOException exc) {
|
||||||
return FileVisitResult.CONTINUE;
|
return FileVisitResult.CONTINUE;
|
||||||
|
@ -186,11 +197,10 @@ public final class FilesSyncHelper {
|
||||||
|
|
||||||
for (OCUpload failedUpload : failedUploads) {
|
for (OCUpload failedUpload : failedUploads) {
|
||||||
accountExists = false;
|
accountExists = false;
|
||||||
if(!failedUpload.isWhileChargingOnly()){
|
if (!failedUpload.isWhileChargingOnly()) {
|
||||||
whileChargingOnly = false;
|
whileChargingOnly = false;
|
||||||
}
|
}
|
||||||
if(!failedUpload.isUseWifiOnly())
|
if (!failedUpload.isUseWifiOnly()) {
|
||||||
{
|
|
||||||
useWifiOnly = false;
|
useWifiOnly = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,22 +218,21 @@ public final class FilesSyncHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
failedUploads = uploadsStorageManager.getFailedUploads();
|
failedUploads = uploadsStorageManager.getFailedUploads();
|
||||||
if(failedUploads.length == 0)
|
if (failedUploads.length == 0) {
|
||||||
{
|
|
||||||
//nothing to do
|
//nothing to do
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(whileChargingOnly){
|
if (whileChargingOnly) {
|
||||||
final BatteryStatus batteryStatus = powerManagementService.getBattery();
|
final BatteryStatus batteryStatus = powerManagementService.getBattery();
|
||||||
final boolean charging = batteryStatus.isCharging() || batteryStatus.isFull();
|
final boolean charging = batteryStatus.isCharging() || batteryStatus.isFull();
|
||||||
if(!charging){
|
if (!charging) {
|
||||||
//all uploads requires charging
|
//all uploads requires charging
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useWifiOnly && !connectivityService.getConnectivity().isWifi()){
|
if (useWifiOnly && !connectivityService.getConnectivity().isWifi()) {
|
||||||
//all uploads requires wifi
|
//all uploads requires wifi
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -305,6 +305,57 @@
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</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
|
<LinearLayout
|
||||||
android:id="@+id/setting_instant_upload_subfolder_rule_container"
|
android:id="@+id/setting_instant_upload_subfolder_rule_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
@ -368,6 +368,8 @@
|
||||||
<string name="prefs_synced_folders_remote_path_title">Remote folder</string>
|
<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_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_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 file or folder</string>
|
||||||
|
|
||||||
<string name="prefs_instant_upload_subfolder_rule_title">Subfolder options</string>
|
<string name="prefs_instant_upload_subfolder_rule_title">Subfolder options</string>
|
||||||
|
|
||||||
|
|
|
@ -178,6 +178,7 @@ public class SyncedFoldersActivityTest {
|
||||||
2,
|
2,
|
||||||
MediaFolderType.IMAGE,
|
MediaFolderType.IMAGE,
|
||||||
false,
|
false,
|
||||||
SubFolderRule.YEAR_MONTH);
|
SubFolderRule.YEAR_MONTH,
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue