Merge pull request #12132 from nextcloud/refactor/convert-MediaFolder-to-kt

Convert Media Folder to Kotlin
This commit is contained in:
Andy Scherzinger 2023-11-09 16:34:50 +01:00 committed by GitHub
commit 7b546e3589
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 128 additions and 138 deletions

View file

@ -25,6 +25,8 @@ import android.app.Activity
import androidx.test.espresso.Espresso import androidx.test.espresso.Espresso
import androidx.test.espresso.Espresso.onView import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.closeSoftKeyboard
import androidx.test.espresso.action.ViewActions.scrollTo
import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.contrib.DrawerActions import androidx.test.espresso.contrib.DrawerActions
import androidx.test.espresso.contrib.NavigationViewActions import androidx.test.espresso.contrib.NavigationViewActions
@ -238,12 +240,15 @@ class FileDisplayActivityIT : AbstractOnServerIT() {
onView(withId(R.id.sort_button)).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE))) onView(withId(R.id.sort_button)).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE)))
// browse into folder // browse into folder
onView(withId(R.id.list_root)).perform( onView(withId(R.id.list_root))
RecyclerViewActions.actionOnItemAtPosition<OCFileListItemViewHolder>( .perform(scrollTo())
0, .perform(closeSoftKeyboard())
click() .perform(
RecyclerViewActions.actionOnItemAtPosition<OCFileListItemViewHolder>(
0,
click()
)
) )
)
shortSleep() shortSleep()
checkToolbarTitle(topFolder) checkToolbarTitle(topFolder)
// sort button should now be visible // sort button should now be visible

View file

@ -128,11 +128,15 @@ public abstract class AbstractOnServerIT extends AbstractIT {
if (!remoteFile.getRemotePath().equals("/")) { if (!remoteFile.getRemotePath().equals("/")) {
if (remoteFile.isEncrypted()) { if (remoteFile.isEncrypted()) {
assertTrue(new ToggleEncryptionRemoteOperation(remoteFile.getLocalId(), ToggleEncryptionRemoteOperation operation = new ToggleEncryptionRemoteOperation(remoteFile.getLocalId(),
remoteFile.getRemotePath(), remoteFile.getRemotePath(),
false) false);
.execute(client)
.isSuccess()); boolean operationResult = operation
.execute(client)
.isSuccess();
assertTrue(operationResult);
} }
boolean removeResult = false; boolean removeResult = false;

View file

@ -105,12 +105,19 @@ class MediaFoldersDetectionWork constructor(
) )
val imageMediaFolderPaths: MutableList<String> = ArrayList() val imageMediaFolderPaths: MutableList<String> = ArrayList()
val videoMediaFolderPaths: MutableList<String> = ArrayList() val videoMediaFolderPaths: MutableList<String> = ArrayList()
for (imageMediaFolder in imageMediaFolders) { for (imageMediaFolder in imageMediaFolders) {
imageMediaFolderPaths.add(imageMediaFolder.absolutePath) imageMediaFolder.absolutePath?.let {
imageMediaFolderPaths.add(it)
}
} }
for (videoMediaFolder in videoMediaFolders) { for (videoMediaFolder in videoMediaFolders) {
imageMediaFolderPaths.add(videoMediaFolder.absolutePath) videoMediaFolder.absolutePath?.let {
imageMediaFolderPaths.add(it)
}
} }
val arbitraryDataString = arbitraryDataProvider.getValue(ACCOUNT_NAME_GLOBAL, KEY_MEDIA_FOLDERS) val arbitraryDataString = arbitraryDataProvider.getValue(ACCOUNT_NAME_GLOBAL, KEY_MEDIA_FOLDERS)
if (!TextUtils.isEmpty(arbitraryDataString)) { if (!TextUtils.isEmpty(arbitraryDataString)) {
mediaFoldersModel = gson.fromJson(arbitraryDataString, MediaFoldersModel::class.java) mediaFoldersModel = gson.fromJson(arbitraryDataString, MediaFoldersModel::class.java)

View file

@ -254,9 +254,12 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector {
if (!isCrashReportingProcess && !appInfo.isDebugBuild()) { if (!isCrashReportingProcess && !appInfo.isDebugBuild()) {
Thread.UncaughtExceptionHandler defaultPlatformHandler = Thread.getDefaultUncaughtExceptionHandler(); Thread.UncaughtExceptionHandler defaultPlatformHandler = Thread.getDefaultUncaughtExceptionHandler();
final ExceptionHandler crashReporter = new ExceptionHandler(this,
defaultPlatformHandler); if (defaultPlatformHandler != null) {
Thread.setDefaultUncaughtExceptionHandler(crashReporter); final ExceptionHandler crashReporter = new ExceptionHandler(this,
defaultPlatformHandler);
Thread.setDefaultUncaughtExceptionHandler(crashReporter);
}
} }
} }
@ -791,25 +794,34 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector {
+ syncedFolder.getId() + " - " + syncedFolder.getLocalPath()); + syncedFolder.getId() + " - " + syncedFolder.getLocalPath());
for (MediaFolder imageMediaFolder : imageMediaFolders) { for (MediaFolder imageMediaFolder : imageMediaFolders) {
if (imageMediaFolder.absolutePath.equals(syncedFolder.getLocalPath())) { String absolutePathOfImageFolder = imageMediaFolder.absolutePath;
newSyncedFolder = (SyncedFolder) syncedFolder.clone();
newSyncedFolder.setType(MediaFolderType.IMAGE); if (absolutePathOfImageFolder != null) {
primaryKey = syncedFolderProvider.storeSyncedFolder(newSyncedFolder); if (absolutePathOfImageFolder.equals(syncedFolder.getLocalPath())) {
Log_OC.i(TAG, "Migrated image synced_folders record: " newSyncedFolder = (SyncedFolder) syncedFolder.clone();
+ primaryKey + " - " + newSyncedFolder.getLocalPath()); newSyncedFolder.setType(MediaFolderType.IMAGE);
break; primaryKey = syncedFolderProvider.storeSyncedFolder(newSyncedFolder);
Log_OC.i(TAG, "Migrated image synced_folders record: "
+ primaryKey + " - " + newSyncedFolder.getLocalPath());
break;
}
} }
} }
for (MediaFolder videoMediaFolder : videoMediaFolders) { for (MediaFolder videoMediaFolder : videoMediaFolders) {
if (videoMediaFolder.absolutePath.equals(syncedFolder.getLocalPath())) { String absolutePathOfVideoFolder = videoMediaFolder.absolutePath;
newSyncedFolder = (SyncedFolder) syncedFolder.clone();
newSyncedFolder.setType(MediaFolderType.VIDEO); if (absolutePathOfVideoFolder != null) {
primaryKey = syncedFolderProvider.storeSyncedFolder(newSyncedFolder); if (absolutePathOfVideoFolder.equals(syncedFolder.getLocalPath())) {
Log_OC.i(TAG, "Migrated video synced_folders record: " newSyncedFolder = (SyncedFolder) syncedFolder.clone();
+ primaryKey + " - " + newSyncedFolder.getLocalPath()); newSyncedFolder.setType(MediaFolderType.VIDEO);
break; primaryKey = syncedFolderProvider.storeSyncedFolder(newSyncedFolder);
Log_OC.i(TAG, "Migrated video synced_folders record: "
+ primaryKey + " - " + newSyncedFolder.getLocalPath());
break;
}
} }
} }
} }
@ -835,19 +847,22 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector {
List<SyncedFolder> syncedFolderList = syncedFolderProvider.getSyncedFolders(); List<SyncedFolder> syncedFolderList = syncedFolderProvider.getSyncedFolders();
Map<Pair<String, String>, Long> syncedFolders = new HashMap<>(); Map<Pair<String, String>, Long> syncedFolders = new HashMap<>();
ArrayList<Long> ids = new ArrayList<>();
for (SyncedFolder syncedFolder : syncedFolderList) { for (SyncedFolder syncedFolder : syncedFolderList) {
Pair<String, String> checkPair = new Pair<>(syncedFolder.getAccount(), syncedFolder.getLocalPath()); Pair<String, String> checkPair = new Pair<>(syncedFolder.getAccount(), syncedFolder.getLocalPath());
if (syncedFolders.containsKey(checkPair)) { if (syncedFolders.containsKey(checkPair)) {
if (syncedFolder.getId() > syncedFolders.get(checkPair)) { Long folderId = syncedFolders.get(checkPair);
syncedFolders.put(checkPair, syncedFolder.getId());
if (folderId != null) {
if (syncedFolder.getId() > folderId) {
syncedFolders.put(checkPair, syncedFolder.getId());
}
} }
} else { } else {
syncedFolders.put(checkPair, syncedFolder.getId()); syncedFolders.put(checkPair, syncedFolder.getId());
} }
} }
ids.addAll(syncedFolders.values()); ArrayList<Long> ids = new ArrayList<>(syncedFolders.values());
if (ids.size() > 0) { if (ids.size() > 0) {
int deletedCount = syncedFolderProvider.deleteSyncedFoldersNotInList(ids); int deletedCount = syncedFolderProvider.deleteSyncedFoldersNotInList(ids);
@ -865,18 +880,11 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector {
return dispatchingAndroidInjector; return dispatchingAndroidInjector;
} }
public static void setAppTheme(DarkMode mode) { public static void setAppTheme(DarkMode mode) {
switch (mode) { switch (mode) {
case LIGHT: case LIGHT -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); case DARK -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
break; case SYSTEM -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
case DARK:
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
break;
case SYSTEM:
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
break;
} }
} }
} }

View file

@ -16,29 +16,31 @@
* GNU AFFERO GENERAL PUBLIC LICENSE for more details. * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
* *
* You should have received a copy of the GNU Affero General Public * You should have received a copy of the GNU Affero General Public
* License along with this program. If not, see <http://www.gnu.org/licenses/>. * License along with this program. If not, see <http:></http:>//www.gnu.org/licenses/>.
*/ */
package com.owncloud.android.datamodel; package com.owncloud.android.datamodel
import java.util.ArrayList;
import java.util.List;
/** /**
* Business object representing a media folder with all information that are gathered via media queries. * Business object representing a media folder with all information that are gathered via media queries.
*/ */
public class MediaFolder { class MediaFolder {
/** name of the folder. */ /** name of the folder. */
public String folderName; @JvmField
var folderName: String? = null
/** absolute path of the folder. */ /** absolute path of the folder. */
public String absolutePath; @JvmField
var absolutePath: String? = null
/** list of file paths of the folder's content */
public List<String> filePaths = new ArrayList<>();
/** total number of files in the media folder. */ /** list of file paths of the folder's content */
public long numberOfFiles; @JvmField
var filePaths: List<String> = ArrayList()
/** type of media folder. */ /** total number of files in the media folder. */
public MediaFolderType type; @JvmField
var numberOfFiles: Long = 0
/** type of media folder. */
@JvmField
var type: MediaFolderType? = null
} }

View file

@ -17,37 +17,28 @@
* You should have received a copy of the GNU Affero General Public * You should have received a copy of the GNU Affero General Public
* License along with this program. If not, see <http://www.gnu.org/licenses/>. * License along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.owncloud.android.datamodel; package com.owncloud.android.datamodel
import android.util.SparseArray; import android.util.SparseArray
/** /**
* Types of media folder. * Types of media folder.
*/ */
public enum MediaFolderType { enum class MediaFolderType(@JvmField val id: Int) {
CUSTOM(0), CUSTOM(0), IMAGE(1), VIDEO(2);
IMAGE(1),
VIDEO(2);
private Integer id; companion object {
private val reverseMap = SparseArray<MediaFolderType>(3)
private static SparseArray<MediaFolderType> reverseMap = new SparseArray<>(3); init {
reverseMap.put(CUSTOM.id, CUSTOM)
reverseMap.put(IMAGE.id, IMAGE)
reverseMap.put(VIDEO.id, VIDEO)
}
static { @JvmStatic
reverseMap.put(CUSTOM.getId(), CUSTOM); fun getById(id: Int?): MediaFolderType {
reverseMap.put(IMAGE.getId(), IMAGE); return reverseMap[id!!]
reverseMap.put(VIDEO.getId(), VIDEO); }
}
MediaFolderType(Integer id) {
this.id = id;
}
public static MediaFolderType getById(Integer id) {
return reverseMap.get(id);
}
public Integer getId() {
return this.id;
} }
} }

View file

@ -1,51 +0,0 @@
/*
* Nextcloud Android client application
*
* @author Mario Danic
* @author Andy Scherzinger
* Copyright (C) 2018 Mario Danic
* Copyright (C) 2018 Andy Scherzinger
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.owncloud.android.datamodel;
import java.util.List;
public class MediaFoldersModel {
private List<String> imageMediaFolders;
private List<String> videoMediaFolders;
public MediaFoldersModel(List<String> imageMediaFolders, List<String> videoMediaFolders) {
this.imageMediaFolders = imageMediaFolders;
this.videoMediaFolders = videoMediaFolders;
}
public List<String> getImageMediaFolders() {
return this.imageMediaFolders;
}
public List<String> getVideoMediaFolders() {
return this.videoMediaFolders;
}
public void setImageMediaFolders(List<String> imageMediaFolders) {
this.imageMediaFolders = imageMediaFolders;
}
public void setVideoMediaFolders(List<String> videoMediaFolders) {
this.videoMediaFolders = videoMediaFolders;
}
}

View file

@ -0,0 +1,24 @@
/*
* Nextcloud Android client application
*
* @author Mario Danic
* @author Andy Scherzinger
* Copyright (C) 2018 Mario Danic
* Copyright (C) 2018 Andy Scherzinger
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.owncloud.android.datamodel
class MediaFoldersModel(var imageMediaFolders: List<String>, var videoMediaFolders: List<String>)

View file

@ -415,7 +415,7 @@ public class SyncedFolderProvider extends Observable {
cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_UPLOAD_ACTION, syncedFolder.getUploadAction()); cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_UPLOAD_ACTION, syncedFolder.getUploadAction());
cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_NAME_COLLISION_POLICY, cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_NAME_COLLISION_POLICY,
syncedFolder.getNameCollisionPolicyInt()); syncedFolder.getNameCollisionPolicyInt());
cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_TYPE, syncedFolder.getType().getId()); 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());

View file

@ -248,7 +248,7 @@ public class SyncedFolderAdapter extends SectionedRecyclerViewAdapter<SectionedV
public int getSectionByLocalPathAndType(String localPath, int type) { public int getSectionByLocalPathAndType(String localPath, int type) {
for (int i = 0; i < filteredSyncFolderItems.size(); i++) { for (int i = 0; i < filteredSyncFolderItems.size(); i++) {
if (filteredSyncFolderItems.get(i).getLocalPath().equalsIgnoreCase(localPath) && if (filteredSyncFolderItems.get(i).getLocalPath().equalsIgnoreCase(localPath) &&
filteredSyncFolderItems.get(i).getType().getId().equals(type)) { filteredSyncFolderItems.get(i).getType().id == type) {
return i; return i;
} }
} }

View file

@ -105,7 +105,7 @@ public class SyncedFolderParcelable implements Parcelable {
dest.writeInt(existing ? 1 : 0); dest.writeInt(existing ? 1 : 0);
dest.writeInt(enabled ? 1 : 0); dest.writeInt(enabled ? 1 : 0);
dest.writeInt(subfolderByDate ? 1 : 0); dest.writeInt(subfolderByDate ? 1 : 0);
dest.writeInt(type.getId()); dest.writeInt(type.id);
dest.writeString(account); dest.writeString(account);
dest.writeInt(uploadAction); dest.writeInt(uploadAction);
dest.writeInt(nameCollisionPolicy.serialize()); dest.writeInt(nameCollisionPolicy.serialize());