diff --git a/app/build.gradle b/app/build.gradle index bfc791ad8..7111c400d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,8 +14,8 @@ android { targetSdkVersion rootProject.ext.targetSdkVersion compileSdk rootProject.ext.compileSdkVersion - versionCode 156 - versionName "3.0.5" + versionCode 157 + versionName "3.0.6" multiDexEnabled true resValue "string", "authorities", defaultConfig.applicationId + '.debug.cameraupload.provider' @@ -114,7 +114,7 @@ android { if (output.outputFile != null && output.outputFile.name.endsWith('.apk')) { def versionName = defaultConfig.versionName - def outputFileName = "${versionName}_snapshot_build_temp.apk" + def outputFileName = "${versionName}_patch_build_temp.apk" outputFileName = outputFileName.replace(" ", "_") output.outputFileName = outputFileName @@ -135,7 +135,7 @@ android { versionName = prefix + "(" + suffix + ")" } - def newOutputFileName = "seafile_${versionName}_build${versionCode}_snapshot${buildCount}.apk" + def newOutputFileName = "seafile_${versionName}_build${versionCode}_patch${buildCount}.apk" newOutputFileName = newOutputFileName.replace(" ", "_").replace("-", "_") def apkFile = output.outputFile def newApkFile = new File(apkFile.parent, newOutputFileName) diff --git a/app/src/main/java/com/seafile/seadroid2/annotation/Todo.java b/app/src/main/java/com/seafile/seadroid2/annotation/Todo.java new file mode 100644 index 000000000..d4ff3dcd2 --- /dev/null +++ b/app/src/main/java/com/seafile/seadroid2/annotation/Todo.java @@ -0,0 +1,17 @@ +package com.seafile.seadroid2.annotation; + + +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; + +import java.lang.annotation.Target; + +/** + * In this project, this feature is not yet complete, and will continue to be maintained in the future + */ + +@Target({TYPE, METHOD, CONSTRUCTOR, FIELD}) +public @interface Todo { +} diff --git a/app/src/main/java/com/seafile/seadroid2/bottomsheetmenu/BottomSheetMenuAdapter.java b/app/src/main/java/com/seafile/seadroid2/bottomsheetmenu/BottomSheetMenuAdapter.java deleted file mode 100644 index ae88e6671..000000000 --- a/app/src/main/java/com/seafile/seadroid2/bottomsheetmenu/BottomSheetMenuAdapter.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.seafile.seadroid2.bottomsheetmenu; - -import android.view.LayoutInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - -import com.seafile.seadroid2.R; - -import java.util.ArrayList; -import java.util.List; - -public class BottomSheetMenuAdapter extends RecyclerView.Adapter { - private List dataList = new ArrayList<>(); - private int columnCount = 1; - private OnMenuClickListener onMenuClickListener; - - public BottomSheetMenuAdapter(List dataList, int columnCount) { - this.dataList = dataList; - this.columnCount = columnCount; - } - - public void setOnMenuClickListener(OnMenuClickListener onMenuClickListener) { - this.onMenuClickListener = onMenuClickListener; - } - - @NonNull - @Override - public BottomSheetViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - int layoutId = columnCount == 1 ? R.layout.bottom_sheet_item_list : R.layout.bottom_sheet_item_grid; - View view = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false); - return new BottomSheetViewHolder(view); - } - - @Override - public void onBindViewHolder(@NonNull BottomSheetViewHolder holder, int position) { - final int p = position; - holder.icon.setImageDrawable(dataList.get(p).getIcon()); - holder.name.setText(dataList.get(p).getTitle()); - if (onMenuClickListener != null) { - holder.itemView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - onMenuClickListener.onMenuClick(dataList.get(p)); - } - }); - } - } - - @Override - public int getItemCount() { - return dataList.size(); - } - - public static class BottomSheetViewHolder extends RecyclerView.ViewHolder { - public ImageView icon; - public TextView name; - - public BottomSheetViewHolder(@NonNull View itemView) { - super(itemView); - icon = itemView.findViewById(R.id.icon); - name = itemView.findViewById(R.id.name); - } - } - -} diff --git a/app/src/main/java/com/seafile/seadroid2/config/AbsLayoutItemType.java b/app/src/main/java/com/seafile/seadroid2/config/AbsLayoutItemType.java index d922b5eea..43aa784d4 100644 --- a/app/src/main/java/com/seafile/seadroid2/config/AbsLayoutItemType.java +++ b/app/src/main/java/com/seafile/seadroid2/config/AbsLayoutItemType.java @@ -11,6 +11,8 @@ public class AbsLayoutItemType { public static final int DIRENT_GRID = 12; public static final int DIRENT_GALLERY = 13; + public static final int SEARCH = 50; + public static final int ACTIVITY = 20; public static final int GROUP_ITEM = 30; diff --git a/app/src/main/java/com/seafile/seadroid2/context/NavContext.java b/app/src/main/java/com/seafile/seadroid2/context/NavContext.java index 3018fd620..590b8d29e 100644 --- a/app/src/main/java/com/seafile/seadroid2/context/NavContext.java +++ b/app/src/main/java/com/seafile/seadroid2/context/NavContext.java @@ -12,7 +12,9 @@ public class NavContext { private final Stack navStack = new Stack<>(); - // repoId = xxx, path = / + /** + * repoId = xxx, path = / + */ public boolean inRepoRoot() { return navStack.size() == 1; } @@ -54,7 +56,7 @@ public void pop() { navStack.pop(); } - public void navToPath(RepoModel repoModel, String full_path) { + public void switchToPath(RepoModel repoModel, String full_path) { navStack.clear(); navStack.push(repoModel); @@ -97,27 +99,26 @@ public DirentModel getTopDirentModel() { return (DirentModel) navStack.peek(); } - /** - * Get the parents model of the current Dirent, maybe RepoModel - */ - public boolean isParentHasWritePermission() { - if (!inRepo()) { - //repo list page should not have permission verification - throw new IllegalArgumentException("Please check your code"); - } - - if (inRepoRoot()) { - return getRepoModel().hasWritePermission(); - } - - BaseModel bd = navStack.elementAt(navStack.size() - 1); - DirentModel d = (DirentModel) bd; - if (d == null) { - return false; - } - - return d.hasWritePermission(); - } +// /** +// * Get the parents model of the current Dirent, maybe RepoModel +// */ +// public boolean isParentHasWritePermission() { +// if (!inRepo()) { +// //repo list page should not have permission verification +// throw new IllegalArgumentException("Please check your code"); +// } +// +// if (inRepoRoot()) { +// return getRepoModel().hasWritePermission(); +// } +// +// BaseModel bd = navStack.elementAt(navStack.size() - 1); +// if (bd instanceof DirentModel d) { +// return d.hasWritePermission(); +// } else { +// return false; +// } +// } public RepoModel getRepoModel() { if (navStack.empty()) { diff --git a/app/src/main/java/com/seafile/seadroid2/enums/ActionModeCallbackType.java b/app/src/main/java/com/seafile/seadroid2/enums/ActionModeCallbackType.java new file mode 100644 index 000000000..91d496292 --- /dev/null +++ b/app/src/main/java/com/seafile/seadroid2/enums/ActionModeCallbackType.java @@ -0,0 +1,5 @@ +package com.seafile.seadroid2.enums; + +public enum ActionModeCallbackType { + CREATE, DESTORY, SELECT_ALL, SELECT_NONE +} diff --git a/app/src/main/java/com/seafile/seadroid2/enums/RepoSelectType.java b/app/src/main/java/com/seafile/seadroid2/enums/RepoSelectType.java index 72254c1c4..8d8421a74 100644 --- a/app/src/main/java/com/seafile/seadroid2/enums/RepoSelectType.java +++ b/app/src/main/java/com/seafile/seadroid2/enums/RepoSelectType.java @@ -11,7 +11,7 @@ public enum RepoSelectType { NOT_SELECTABLE(-1), ONLY_ACCOUNT(0), ONLY_REPO(1), - DIRENT(2); + FOLDER(2); RepoSelectType(int i) { diff --git a/app/src/main/java/com/seafile/seadroid2/framework/data/db/AppDatabase.java b/app/src/main/java/com/seafile/seadroid2/framework/data/db/AppDatabase.java index db8a5fa0c..f406282f7 100644 --- a/app/src/main/java/com/seafile/seadroid2/framework/data/db/AppDatabase.java +++ b/app/src/main/java/com/seafile/seadroid2/framework/data/db/AppDatabase.java @@ -1,7 +1,6 @@ package com.seafile.seadroid2.framework.data.db; import androidx.annotation.NonNull; -import androidx.room.Dao; import androidx.room.Database; import androidx.room.Room; import androidx.room.RoomDatabase; @@ -9,34 +8,34 @@ import androidx.sqlite.db.SupportSQLiteDatabase; import com.seafile.seadroid2.SeadroidApplication; -import com.seafile.seadroid2.framework.data.db.dao.CertCacheDAO; import com.seafile.seadroid2.framework.data.db.dao.DirentDAO; import com.seafile.seadroid2.framework.data.db.dao.EncKeyCacheDAO; import com.seafile.seadroid2.framework.data.db.dao.FileTransferDAO; import com.seafile.seadroid2.framework.data.db.dao.FolderBackupMonitorDAO; +import com.seafile.seadroid2.framework.data.db.dao.PermissionDAO; import com.seafile.seadroid2.framework.data.db.dao.RepoDAO; import com.seafile.seadroid2.framework.data.db.dao.StarredDirentDAO; -import com.seafile.seadroid2.framework.data.db.entities.CertEntity; import com.seafile.seadroid2.framework.data.db.entities.DirentModel; import com.seafile.seadroid2.framework.data.db.entities.EncKeyCacheEntity; import com.seafile.seadroid2.framework.data.db.entities.FolderBackupMonitorEntity; +import com.seafile.seadroid2.framework.data.db.entities.PermissionEntity; import com.seafile.seadroid2.framework.data.db.entities.RepoModel; import com.seafile.seadroid2.framework.data.db.entities.FileTransferEntity; import com.seafile.seadroid2.framework.data.db.entities.StarredModel; +import com.seafile.seadroid2.framework.util.SLogs; @Database(entities = { RepoModel.class, DirentModel.class, FolderBackupMonitorEntity.class, EncKeyCacheEntity.class, - CertEntity.class, FileTransferEntity.class, - StarredModel.class -}, version = 2, exportSchema = false) + StarredModel.class, + PermissionEntity.class, +}, version = 3, exportSchema = false) public abstract class AppDatabase extends RoomDatabase { private static final String DATABASE_NAME = "seafile_room.db"; private static volatile AppDatabase _instance; - public static AppDatabase getInstance() { if (_instance == null) { synchronized (AppDatabase.class) { @@ -44,6 +43,7 @@ public static AppDatabase getInstance() { _instance = Room .databaseBuilder(SeadroidApplication.getAppContext(), AppDatabase.class, DATABASE_NAME) .addMigrations(MIGRATION_1_2) + .addMigrations(MIGRATION_2_3) .build(); } } @@ -63,6 +63,33 @@ public void migrate(@NonNull SupportSQLiteDatabase database) { }; + static final Migration MIGRATION_2_3 = new Migration(2, 3) { + + @Override + public void migrate(@NonNull SupportSQLiteDatabase database) { + database.execSQL("DROP TABLE IF EXISTS cert_cache"); + + database.execSQL("DROP TABLE IF EXISTS permissions"); + database.execSQL("CREATE TABLE permissions (" + + "id INTEGER NOT NULL DEFAULT 0, " + + "repo_id TEXT NOT NULL DEFAULT '', " + + "description TEXT, " + + "name TEXT DEFAULT '', " + + "'create' INTEGER NOT NULL DEFAULT 0, " + + "upload INTEGER NOT NULL DEFAULT 0, " + + "download INTEGER NOT NULL DEFAULT 0, " + + "preview INTEGER NOT NULL DEFAULT 0, " + + "copy INTEGER NOT NULL DEFAULT 0, " + + "'delete' INTEGER NOT NULL DEFAULT 0, " + + "modify INTEGER NOT NULL DEFAULT 0, " + + "download_external_link INTEGER NOT NULL DEFAULT 0, " + + "'v' INTEGER NOT NULL DEFAULT 1, " + + "data_status INTEGER NOT NULL DEFAULT 0, " + + "PRIMARY KEY(repo_id, id))"); + } + }; + + public abstract RepoDAO repoDao(); public abstract DirentDAO direntDao(); @@ -71,11 +98,9 @@ public void migrate(@NonNull SupportSQLiteDatabase database) { public abstract EncKeyCacheDAO encKeyCacheDAO(); - @Deprecated - public abstract CertCacheDAO certDAO(); - public abstract FolderBackupMonitorDAO folderBackupMonitorDAO(); public abstract FileTransferDAO fileTransferDAO(); + public abstract PermissionDAO permissionDAO(); } diff --git a/app/src/main/java/com/seafile/seadroid2/framework/data/db/dao/CertCacheDAO.java b/app/src/main/java/com/seafile/seadroid2/framework/data/db/dao/CertCacheDAO.java deleted file mode 100644 index e7e8fe1ae..000000000 --- a/app/src/main/java/com/seafile/seadroid2/framework/data/db/dao/CertCacheDAO.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.seafile.seadroid2.framework.data.db.dao; - -import androidx.room.Dao; -import androidx.room.Insert; -import androidx.room.OnConflictStrategy; -import androidx.room.Query; - -import com.seafile.seadroid2.framework.data.db.entities.CertEntity; - -import java.util.List; - -import io.reactivex.Completable; - -@Deprecated -@Dao -public interface CertCacheDAO { - @Insert(onConflict = OnConflictStrategy.REPLACE) - Completable insert(CertEntity entity); - - @Insert(onConflict = OnConflictStrategy.REPLACE) - Completable insertAllAsync(List entities); - - @Insert(onConflict = OnConflictStrategy.REPLACE) - void insertAll(List entities); - - @Query("DELETE FROM cert_cache where url = :u") - void deleteByUrl(String u); - - @Query("select * from cert_cache where url = :u limit 1") - List getListByUrl(String u); - -// @Query("select * from repo_config_cache where repo_id = :repoId limit 1") -// Single> getByRepoId(String repoId); -} diff --git a/app/src/main/java/com/seafile/seadroid2/framework/data/db/dao/DirentDAO.java b/app/src/main/java/com/seafile/seadroid2/framework/data/db/dao/DirentDAO.java index 0653c7bb2..faf9800dc 100644 --- a/app/src/main/java/com/seafile/seadroid2/framework/data/db/dao/DirentDAO.java +++ b/app/src/main/java/com/seafile/seadroid2/framework/data/db/dao/DirentDAO.java @@ -38,6 +38,9 @@ public interface DirentDAO { @Query("select * from dirents where uid in ( :uids )") List getListByIdsSync(List uids); + @Query("select * from dirents where uid in ( :uids )") + Single> getListByIdsAsync(List uids); + @Insert(onConflict = OnConflictStrategy.REPLACE) void insert(DirentModel model); diff --git a/app/src/main/java/com/seafile/seadroid2/framework/data/db/dao/PermissionDAO.java b/app/src/main/java/com/seafile/seadroid2/framework/data/db/dao/PermissionDAO.java new file mode 100644 index 000000000..66fe2de1a --- /dev/null +++ b/app/src/main/java/com/seafile/seadroid2/framework/data/db/dao/PermissionDAO.java @@ -0,0 +1,45 @@ +package com.seafile.seadroid2.framework.data.db.dao; + +import androidx.room.Dao; +import androidx.room.Insert; +import androidx.room.OnConflictStrategy; +import androidx.room.Query; + +import com.seafile.seadroid2.framework.data.db.entities.PermissionEntity; + +import java.util.List; + +import io.reactivex.Completable; +import io.reactivex.Single; + +@Dao +public interface PermissionDAO { + + @Query("select * from permissions where id = :id limit 1") + List getByIdSync(int id); + + @Query("select * from permissions where id IN (:ids)") + Single> getByIdsAsync(List ids); + + @Query("select * from permissions where repo_id = :repoId and id = :id limit 1") + Single> getWithAsync(String repoId, int id); + + @Query("select * from permissions where repo_id = :repoId") + Single> getByRepoIdAsync(String repoId); + + + + @Query("DELETE FROM permissions") + void deleteAll(); + + @Insert(onConflict = OnConflictStrategy.REPLACE) + void insert(PermissionEntity PermissionEntity); + + @Insert(onConflict = OnConflictStrategy.REPLACE) + void insertAllSync(List list); + + @Insert(onConflict = OnConflictStrategy.REPLACE) + Completable insertAllAsync(List list); + + +} diff --git a/app/src/main/java/com/seafile/seadroid2/framework/data/db/dao/RepoDAO.java b/app/src/main/java/com/seafile/seadroid2/framework/data/db/dao/RepoDAO.java index c72996d4a..a30c00fd7 100644 --- a/app/src/main/java/com/seafile/seadroid2/framework/data/db/dao/RepoDAO.java +++ b/app/src/main/java/com/seafile/seadroid2/framework/data/db/dao/RepoDAO.java @@ -24,6 +24,9 @@ public interface RepoDAO { @Query("select * from repos where repo_id = :repo_id limit 1") Single> getRepoById(String repo_id); + @Query("select * from repos where repo_id IN (:ids)") + Single> getRepoListByIds(List ids); + @Query("select * from repos where repo_id = :repo_id limit 1") List getByIdSync(String repo_id); diff --git a/app/src/main/java/com/seafile/seadroid2/framework/data/db/entities/CertEntity.java b/app/src/main/java/com/seafile/seadroid2/framework/data/db/entities/CertEntity.java deleted file mode 100644 index 92177c948..000000000 --- a/app/src/main/java/com/seafile/seadroid2/framework/data/db/entities/CertEntity.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.seafile.seadroid2.framework.data.db.entities; - -import androidx.room.Entity; -import androidx.room.PrimaryKey; - -@Deprecated -@Entity(tableName = "cert_cache") -public class CertEntity { - @PrimaryKey(autoGenerate = true) - public long id; - - public String url; - public String cert; - - @Override - public String toString() { - return "CertEntity{" + - "url='" + url + '\'' + - ", cert='" + cert + '\'' + - '}'; - } -} diff --git a/app/src/main/java/com/seafile/seadroid2/framework/data/db/entities/DirentModel.java b/app/src/main/java/com/seafile/seadroid2/framework/data/db/entities/DirentModel.java index 4b29a29f0..fdcddfdf2 100644 --- a/app/src/main/java/com/seafile/seadroid2/framework/data/db/entities/DirentModel.java +++ b/app/src/main/java/com/seafile/seadroid2/framework/data/db/entities/DirentModel.java @@ -5,6 +5,7 @@ import android.text.TextUtils; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.room.Entity; import androidx.room.Ignore; import androidx.room.PrimaryKey; @@ -19,6 +20,8 @@ import com.seafile.seadroid2.framework.util.Times; import com.seafile.seadroid2.framework.util.Utils; +import org.apache.commons.lang3.StringUtils; + @Entity(tableName = "dirents") public class DirentModel extends BaseModel implements Parcelable { @@ -102,7 +105,9 @@ public String getSubtitle() { public int getIcon() { if (isDir()) { - if (!hasWritePermission()) { + if (isCustomPermission()) { + return R.drawable.baseline_folder_24; + } else if (!hasWritePermission()) { return R.drawable.baseline_folder_read_only_24; } else { return R.drawable.baseline_folder_24; @@ -111,6 +116,9 @@ public int getIcon() { return Icons.getFileIcon(name); } + /** + * You'll also need to check if it's a custom permission + */ public boolean hasWritePermission() { if (TextUtils.isEmpty(permission)) { return false; @@ -127,6 +135,9 @@ public boolean hasWritePermission() { return permission.contains("w"); } + /** + * You'll also need to check if it's a custom permission + */ public boolean hasDownloadPermission() { if (TextUtils.isEmpty(permission)) { return false; @@ -143,6 +154,18 @@ public boolean hasDownloadPermission() { return true; } + /** + * is start with "custom-" ? + */ + public boolean isCustomPermission() { + return !TextUtils.isEmpty(permission) && permission.startsWith("custom-"); + } + + public int getCustomPermissionNum() { + String[] ss = StringUtils.split(permission, "-"); + return Integer.parseInt(ss[1]); + } + public static DirentModel convertStarredModelToThis(StarredModel starredModel) { if (starredModel == null) { return null; diff --git a/app/src/main/java/com/seafile/seadroid2/framework/data/db/entities/PermissionEntity.java b/app/src/main/java/com/seafile/seadroid2/framework/data/db/entities/PermissionEntity.java new file mode 100644 index 000000000..81f830563 --- /dev/null +++ b/app/src/main/java/com/seafile/seadroid2/framework/data/db/entities/PermissionEntity.java @@ -0,0 +1,157 @@ +package com.seafile.seadroid2.framework.data.db.entities; + +import android.text.TextUtils; + +import androidx.annotation.NonNull; +import androidx.room.Entity; +import androidx.room.Ignore; + +import com.seafile.seadroid2.framework.data.model.BaseModel; +import com.seafile.seadroid2.framework.data.model.permission.PermissionWrapperModel; + +import java.util.HashMap; +import java.util.Set; + +@Entity(tableName = "permissions", primaryKeys = {"repo_id", "id"}) +public class PermissionEntity extends BaseModel { + + @NonNull + public String repo_id = ""; + + public int id; + public String description; + public String name; + + //permissions + public boolean create; + public boolean upload; + public boolean download; + public boolean preview; + public boolean copy; + public boolean delete; + public boolean modify; + public boolean download_external_link; + + + /** + * key -> repo_id or dirent_id(uid) + */ + @Ignore + public HashMap cachedMap; + + public boolean hasId(String id) { + if (cachedMap == null) { + return false; + } + + return cachedMap.containsKey(id); + } + + public void cacheBaseModel(BaseModel model) { + if (cachedMap == null) { + cachedMap = new HashMap<>(); + return; + } + + if (model instanceof RepoModel m) { + cachedMap.put(m.repo_id, m); + } else if (model instanceof DirentModel m) { + cachedMap.put(m.uid, m); + } + } + + public void removeById(String id) { + if (cachedMap == null) { + return; + } + + cachedMap.remove(id); + } + + public void removeByModel(BaseModel model) { + if (cachedMap == null) { + return; + } + + if (model instanceof RepoModel m) { + cachedMap.remove(m.repo_id); + } else if (model instanceof DirentModel m) { + cachedMap.remove(m.uid); + } + } + + public boolean isEmptyIds() { + return cachedMap == null || cachedMap.isEmpty(); + } + + public PermissionEntity() { + } + + public PermissionEntity(@NonNull String repoId, @NonNull PermissionWrapperModel model) { + this.id = model.id; + this.name = model.name; + this.description = model.description; + + this.create = model.permission.create; + this.upload = model.permission.upload; + this.download = model.permission.download; + this.copy = model.permission.copy; + this.delete = model.permission.delete; + this.modify = model.permission.modify; + this.download_external_link = model.permission.download_external_link; + this.preview = model.permission.preview; + this.repo_id = repoId; + } + + public PermissionEntity(@NonNull String repoId, @NonNull String permission) { + if (TextUtils.isEmpty(permission)) { + throw new IllegalArgumentException("permission is null"); + } + + this.name = permission; + this.id = -1; + this.repo_id = repoId; + + if ("cloud-edit".equals(permission)) { + //用户可以通过浏览器在线查看和编辑,文件不能被下载。 + this.create = true; + this.upload = false; + this.download = false; + this.preview = true; + this.copy = true; + this.delete = true; + this.modify = true; + this.download_external_link = false; + + } else if ("preview".equals(permission)) { + //用户只能通过浏览器在线查看,文件不能被下载。 + this.create = false; + this.upload = false; + this.download = false; + this.preview = true; + this.copy = false; + this.delete = false; + this.modify = false; + this.download_external_link = false; + } else if ("r".equals(permission)) { + //用户可以查看、下载和同步文件 + this.create = false; + this.upload = false; + this.download = true; + this.preview = true; + this.copy = true; + this.delete = false; + this.modify = false; + this.download_external_link = false; + } else if ("rw".equals(permission)) { + this.create = true; + this.upload = true; + this.download = true; + this.preview = true; + this.copy = true; + this.delete = true; + this.modify = true; + this.download_external_link = true; + } + } +} diff --git a/app/src/main/java/com/seafile/seadroid2/framework/data/db/entities/RepoModel.java b/app/src/main/java/com/seafile/seadroid2/framework/data/db/entities/RepoModel.java index 5b73beed7..1cadcae4f 100644 --- a/app/src/main/java/com/seafile/seadroid2/framework/data/db/entities/RepoModel.java +++ b/app/src/main/java/com/seafile/seadroid2/framework/data/db/entities/RepoModel.java @@ -11,6 +11,8 @@ import com.seafile.seadroid2.framework.data.model.adapter.EncryptFieldJsonAdapter; import com.seafile.seadroid2.framework.util.Utils; +import org.apache.commons.lang3.StringUtils; + @Entity(tableName = "repos", primaryKeys = {"repo_id", "group_id"}) public class RepoModel extends BaseModel { @@ -78,14 +80,20 @@ public String getSubtitle() { } public int getIcon() { - if (encrypted) + if (encrypted) { return R.drawable.baseline_repo_encrypted_24; - if (!hasWritePermission()) + } else if (isCustomPermission()) { + return R.drawable.baseline_repo_24; + } else if (!hasWritePermission()) { return R.drawable.baseline_repo_readonly_24; + } return R.drawable.baseline_repo_24; } + /** + * You should to check if it's a custom permission firstly + */ public boolean hasWritePermission() { if (TextUtils.isEmpty(permission)) { return false; @@ -99,9 +107,27 @@ public boolean hasWritePermission() { return false; } - return !TextUtils.isEmpty(permission) && permission.contains("w"); + return permission.contains("w"); } + /** + * if start with "custom-" + */ + public boolean isCustomPermission() { + return !TextUtils.isEmpty(permission) && permission.startsWith("custom-"); + } + + /** + * please check {@link #isCustomPermission()} first + */ + public int getCustomPermissionNum() { + if (!isCustomPermission()) { + throw new IllegalArgumentException("please check isCustomPermission() first"); + } + + String[] ss = StringUtils.split(permission, "-"); + return Integer.parseInt(ss[1]); + } // /** // * If the result is true, and the decryption was successful, diff --git a/app/src/main/java/com/seafile/seadroid2/framework/data/model/BaseModel.java b/app/src/main/java/com/seafile/seadroid2/framework/data/model/BaseModel.java index ba76eaac6..fdcf7d675 100644 --- a/app/src/main/java/com/seafile/seadroid2/framework/data/model/BaseModel.java +++ b/app/src/main/java/com/seafile/seadroid2/framework/data/model/BaseModel.java @@ -2,6 +2,7 @@ import androidx.room.Ignore; +import com.seafile.seadroid2.config.Constants; import com.seafile.seadroid2.framework.data.db.entities.FileTransferEntity; import com.seafile.seadroid2.ui.data_migrate.DataMigrationActivity; @@ -28,7 +29,7 @@ public class BaseModel { /** * @see com.seafile.seadroid2.config.Constants.DataStatus */ - public int data_status = 0; + public int data_status = Constants.DataStatus.NORMAL; @Ignore public boolean is_checked = false; diff --git a/app/src/main/java/com/seafile/seadroid2/framework/data/model/ResultModel.java b/app/src/main/java/com/seafile/seadroid2/framework/data/model/ResultModel.java index 3a3bef276..512468939 100644 --- a/app/src/main/java/com/seafile/seadroid2/framework/data/model/ResultModel.java +++ b/app/src/main/java/com/seafile/seadroid2/framework/data/model/ResultModel.java @@ -3,4 +3,12 @@ public class ResultModel { public boolean success; public String error_msg; + + @Override + public String toString() { + return "ResultModel{" + + "success=" + success + + ", error_msg='" + error_msg + '\'' + + '}'; + } } diff --git a/app/src/main/java/com/seafile/seadroid2/framework/data/model/permission/PermissionListWrapperModel.java b/app/src/main/java/com/seafile/seadroid2/framework/data/model/permission/PermissionListWrapperModel.java new file mode 100644 index 000000000..8694d5045 --- /dev/null +++ b/app/src/main/java/com/seafile/seadroid2/framework/data/model/permission/PermissionListWrapperModel.java @@ -0,0 +1,9 @@ +package com.seafile.seadroid2.framework.data.model.permission; + +import com.seafile.seadroid2.framework.data.db.entities.PermissionEntity; + +import java.util.List; + +public class PermissionListWrapperModel { + public List permission_list; +} diff --git a/app/src/main/java/com/seafile/seadroid2/framework/data/model/permission/PermissionModel.java b/app/src/main/java/com/seafile/seadroid2/framework/data/model/permission/PermissionModel.java new file mode 100644 index 000000000..6c39febde --- /dev/null +++ b/app/src/main/java/com/seafile/seadroid2/framework/data/model/permission/PermissionModel.java @@ -0,0 +1,12 @@ +package com.seafile.seadroid2.framework.data.model.permission; + +public class PermissionModel { + public boolean create; + public boolean upload; + public boolean download; + public boolean preview; + public boolean copy; + public boolean delete; + public boolean modify; + public boolean download_external_link; +} diff --git a/app/src/main/java/com/seafile/seadroid2/framework/data/model/permission/PermissionWrapperModel.java b/app/src/main/java/com/seafile/seadroid2/framework/data/model/permission/PermissionWrapperModel.java new file mode 100644 index 000000000..46f14fdb5 --- /dev/null +++ b/app/src/main/java/com/seafile/seadroid2/framework/data/model/permission/PermissionWrapperModel.java @@ -0,0 +1,8 @@ +package com.seafile.seadroid2.framework.data.model.permission; + +public class PermissionWrapperModel { + public int id; + public String description; + public String name; + public PermissionModel permission; +} diff --git a/app/src/main/java/com/seafile/seadroid2/framework/data/model/repo/Dirent2Model.java b/app/src/main/java/com/seafile/seadroid2/framework/data/model/repo/Dirent2Model.java index 7fda920cf..47d42e265 100644 --- a/app/src/main/java/com/seafile/seadroid2/framework/data/model/repo/Dirent2Model.java +++ b/app/src/main/java/com/seafile/seadroid2/framework/data/model/repo/Dirent2Model.java @@ -13,4 +13,20 @@ public class Dirent2Model extends BaseModel { public String user_contact_email; public boolean repo_encrypted; public boolean is_dir; + + @Override + public String toString() { + return "Dirent2Model{" + + "repo_id='" + repo_id + '\'' + + ", repo_name='" + repo_name + '\'' + + ", path='" + path + '\'' + + ", obj_name='" + obj_name + '\'' + + ", mtime='" + mtime + '\'' + + ", user_email='" + user_email + '\'' + + ", user_name='" + user_name + '\'' + + ", user_contact_email='" + user_contact_email + '\'' + + ", repo_encrypted=" + repo_encrypted + + ", is_dir=" + is_dir + + '}'; + } } diff --git a/app/src/main/java/com/seafile/seadroid2/framework/data/model/repo/RepoPermissionWrapper.java b/app/src/main/java/com/seafile/seadroid2/framework/data/model/repo/RepoPermissionWrapper.java new file mode 100644 index 000000000..0b30c0da0 --- /dev/null +++ b/app/src/main/java/com/seafile/seadroid2/framework/data/model/repo/RepoPermissionWrapper.java @@ -0,0 +1,30 @@ +package com.seafile.seadroid2.framework.data.model.repo; + +import com.seafile.seadroid2.framework.data.db.entities.PermissionEntity; +import com.seafile.seadroid2.framework.data.db.entities.RepoModel; + +public class RepoPermissionWrapper { + public RepoModel repoModel; + public PermissionEntity permission; + + public RepoPermissionWrapper(RepoModel repoModel, PermissionEntity permission) { + this.repoModel = repoModel; + this.permission = permission; + } + + public PermissionEntity getPermission() { + return permission; + } + + public void setPermission(PermissionEntity permission) { + this.permission = permission; + } + + public void setRepoModel(RepoModel repoModel) { + this.repoModel = repoModel; + } + + public RepoModel getRepoModel() { + return repoModel; + } +} diff --git a/app/src/main/java/com/seafile/seadroid2/framework/data/model/search/SearchModel.java b/app/src/main/java/com/seafile/seadroid2/framework/data/model/search/SearchModel.java index 7be2f540c..51d5cb61d 100644 --- a/app/src/main/java/com/seafile/seadroid2/framework/data/model/search/SearchModel.java +++ b/app/src/main/java/com/seafile/seadroid2/framework/data/model/search/SearchModel.java @@ -30,6 +30,10 @@ public class SearchModel extends BaseModel implements Parcelable { public long last_modified; public long size; // size of file, 0 if type is dir + public boolean isDir() { + return is_dir; + } + public String getTitle() { String formatName = StringUtils.substringAfterLast(fullpath, '/'); if (TextUtils.isEmpty(formatName)) { @@ -46,7 +50,8 @@ public String getTitle() { // } public String getSubtitle() { - return repo_name; + String p = Utils.getPathFromFullPath(fullpath); + return repo_name + p; } @@ -69,6 +74,7 @@ public static DirentModel converterThis2DirentModel(SearchModel model) { d.name = model.name; d.repo_id = model.repo_id; d.repo_name = model.repo_name; + d.last_modified_at = model.last_modified; d.size = model.size; return d; } diff --git a/app/src/main/java/com/seafile/seadroid2/framework/datastore/sp/SettingsManager.java b/app/src/main/java/com/seafile/seadroid2/framework/datastore/sp/SettingsManager.java index 7a0cd636e..f26b92353 100644 --- a/app/src/main/java/com/seafile/seadroid2/framework/datastore/sp/SettingsManager.java +++ b/app/src/main/java/com/seafile/seadroid2/framework/datastore/sp/SettingsManager.java @@ -4,6 +4,7 @@ import com.seafile.seadroid2.R; import com.seafile.seadroid2.SeadroidApplication; +import com.seafile.seadroid2.preferences.Settings; /** * Access the app settings @@ -98,4 +99,16 @@ public final class SettingsManager { public static final long DECRYPTION_EXPIRATION_TIME = 1000 * 60 * 60 * 24;//1 days public static final int REPO_ENC_VERSION = 2; + + + //force refresh starred list state + public static final String ON_FORCE_REFRESH_STARRED_LIST_KEY = "on_force_refresh_starred_list"; + + public static void setForceRefreshStarredListState(boolean state) { + Settings.getCommonPreferences().edit().putBoolean(ON_FORCE_REFRESH_STARRED_LIST_KEY, state).apply(); + } + + public static boolean getForceRefreshStarredListState() { + return Settings.getCommonPreferences().getBoolean(ON_FORCE_REFRESH_STARRED_LIST_KEY, false); + } } diff --git a/app/src/main/java/com/seafile/seadroid2/framework/http/BaseOkHttpClient.java b/app/src/main/java/com/seafile/seadroid2/framework/http/BaseOkHttpClient.java index cf31fd645..1e3f73424 100644 --- a/app/src/main/java/com/seafile/seadroid2/framework/http/BaseOkHttpClient.java +++ b/app/src/main/java/com/seafile/seadroid2/framework/http/BaseOkHttpClient.java @@ -3,6 +3,7 @@ import android.text.TextUtils; import com.blankj.utilcode.util.NetworkUtils; +import com.seafile.seadroid2.BuildConfig; import com.seafile.seadroid2.SeadroidApplication; import com.seafile.seadroid2.account.Account; import com.seafile.seadroid2.framework.http.interceptor.HeaderInterceptor; @@ -47,7 +48,7 @@ protected List getInterceptors() { //print log HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(); loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC); -// loggingInterceptor.setLevel(BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.BASIC); + loggingInterceptor.setLevel(BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.BASIC); interceptors.add(loggingInterceptor); if (account != null && !TextUtils.isEmpty(account.token)) { diff --git a/app/src/main/java/com/seafile/seadroid2/framework/util/Icons.java b/app/src/main/java/com/seafile/seadroid2/framework/util/Icons.java index 7e24c25e7..db3698ae0 100644 --- a/app/src/main/java/com/seafile/seadroid2/framework/util/Icons.java +++ b/app/src/main/java/com/seafile/seadroid2/framework/util/Icons.java @@ -26,11 +26,11 @@ public static int getFileIcon(String name) { // return getFileOldIcon(name); String suffix = FileUtils.getFileExtension(name); if (TextUtils.isEmpty(suffix)) { - return R.drawable.icon_extended_file; + return R.drawable.icon_format_file; } if (codes.contains(suffix)) { - return R.drawable.icon_extended_css; + return R.drawable.icon_format_css; } if (getSuffixIconMap().containsKey(suffix)) { @@ -41,138 +41,74 @@ public static int getFileIcon(String name) { return getResIdForMimetype(mime); } - public static int getFileOldIcon(String name) { - - String suffix = FileUtils.getFileExtension(name); - if (TextUtils.isEmpty(suffix)) { - return R.drawable.file; - } - - if (getSuffixIconMapOld().containsKey(suffix)) { - return getSuffixIconMapOld().get(suffix); - } - - String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(suffix); - return getResIdForMimetypeOld(mime); - } private static synchronized HashMap getSuffixIconMap() { if (suffixIconMap != null) return suffixIconMap; suffixIconMap = Maps.newHashMap(); - suffixIconMap.put("pdf", R.drawable.icon_extended_pdf); - suffixIconMap.put("doc", R.drawable.icon_extended_doc); - suffixIconMap.put("docx", R.drawable.icon_extended_doc); - suffixIconMap.put("md", R.drawable.icon_extended_md); - suffixIconMap.put("markdown", R.drawable.icon_extended_md); - suffixIconMap.put("txt", R.drawable.icon_extended_txt); - suffixIconMap.put("png", R.drawable.icon_extended_png); - suffixIconMap.put("gif", R.drawable.icon_extended_png); - suffixIconMap.put("psd", R.drawable.icon_extended_psd); - suffixIconMap.put("ppt", R.drawable.icon_extended_ppt); - suffixIconMap.put("sdoc", R.drawable.icon_extended_sdoc); - suffixIconMap.put("xls", R.drawable.icon_extended_xls); - suffixIconMap.put("mp3", R.drawable.icon_extended_mp3); - suffixIconMap.put("mov", R.drawable.icon_extended_mov); - suffixIconMap.put("css", R.drawable.icon_extended_css); + suffixIconMap.put("pdf", R.drawable.icon_format_pdf); + suffixIconMap.put("doc", R.drawable.icon_format_word); + suffixIconMap.put("docx", R.drawable.icon_format_word); + suffixIconMap.put("md", R.drawable.icon_format_md); + suffixIconMap.put("markdown", R.drawable.icon_format_md); + suffixIconMap.put("txt", R.drawable.icon_format_txt); + suffixIconMap.put("png", R.drawable.icon_format_pic); + suffixIconMap.put("gif", R.drawable.icon_format_pic); + suffixIconMap.put("psd", R.drawable.icon_format_psd); + suffixIconMap.put("ppt", R.drawable.icon_format_ppt); + suffixIconMap.put("sdoc", R.drawable.icon_format_sdoc); + suffixIconMap.put("xls", R.drawable.icon_format_excel); + suffixIconMap.put("mp3", R.drawable.icon_format_music); + suffixIconMap.put("mov", R.drawable.icon_format_video); + suffixIconMap.put("css", R.drawable.icon_format_css); //code return suffixIconMap; } - - private static synchronized HashMap getSuffixIconMapOld() { - if (suffixIconMap != null) - return suffixIconMap; - - suffixIconMap = Maps.newHashMap(); - suffixIconMap.put("pdf", R.drawable.file_pdf); - suffixIconMap.put("doc", R.drawable.file_ms_word); - suffixIconMap.put("docx", R.drawable.file_ms_word); - suffixIconMap.put("md", R.drawable.file_text); - suffixIconMap.put("markdown", R.drawable.file_text); - return suffixIconMap; - } - /** * https://stackoverflow.com/questions/4212861/what-is-a-correct-mime-type-for-docx-pptx-etc */ private static int getResIdForMimetype(String mimetype) { if (TextUtils.isEmpty(mimetype)) { - return R.drawable.icon_extended_file; + return R.drawable.icon_format_file; } if (mimetype.contains("pdf")) { - return R.drawable.icon_extended_pdf; + return R.drawable.icon_format_pdf; } else if (mimetype.contains("image/")) { - return R.drawable.icon_extended_png; + return R.drawable.icon_format_pic; } else if (mimetype.contains("text/")) { - return R.drawable.icon_extended_txt; + return R.drawable.icon_format_txt; } else if (mimetype.contains("audio/")) { - return R.drawable.icon_extended_mp3; + return R.drawable.icon_format_music; } else if (mimetype.contains("video/")) { - return R.drawable.icon_extended_mov; + return R.drawable.icon_format_video; } else if (mimetype.contains("msword") || mimetype.contains("ms-word")) { - return R.drawable.icon_extended_doc; + return R.drawable.icon_format_word; } else if (mimetype.contains("mspowerpoint") || mimetype.contains("ms-powerpoint")) { - return R.drawable.icon_extended_ppt; + return R.drawable.icon_format_ppt; } else if (mimetype.contains("msexcel") || mimetype.contains("ms-excel")) { - return R.drawable.icon_extended_xls; + return R.drawable.icon_format_excel; } else if (mimetype.contains("openxmlformats-officedocument")) { if (mimetype.contains("wordprocessingml")) { - return R.drawable.icon_extended_doc; + return R.drawable.icon_format_word; } else if (mimetype.contains("spreadsheetml")) { - return R.drawable.icon_extended_xls; + return R.drawable.icon_format_excel; } else if (mimetype.contains("presentationml")) { - return R.drawable.icon_extended_ppt; + return R.drawable.icon_format_ppt; } } else if (mimetype.equals("application/vnd.android.package-archive")) { - return R.drawable.icon_extended_file; + return R.drawable.icon_format_file; } else if (mimetype.equals("application/zip")) { - return R.drawable.icon_extended_zip; + return R.drawable.icon_format_zip; } else if (mimetype.equals("application/x-iwork-numbers-sffnumbers")) { - return R.drawable.icon_extended_file; + return R.drawable.icon_format_file; } else if (mimetype.equals("application/x-iwork-pages-sffpages")) { - return R.drawable.icon_extended_file; + return R.drawable.icon_format_file; } - return R.drawable.icon_extended_file; + return R.drawable.icon_format_file; } - - public static int getResIdForMimetypeOld(String mimetype) { - if (mimetype == null) - return R.drawable.file; - - if (mimetype.contains("image/")) { - return R.drawable.file_image; - } else if (mimetype.contains("text")) { - return R.drawable.file_text; - } else if (mimetype.contains("audio")) { - return R.drawable.file_audio; - } else if (mimetype.contains("video")) { - return R.drawable.file_video; - } else if (mimetype.contains("pdf")) { - return R.drawable.file_pdf; - } else if (mimetype.contains("msword") || mimetype.contains("ms-word")) { - return R.drawable.file_ms_word; - } else if (mimetype.contains("mspowerpoint") || mimetype.contains("ms-powerpoint")) { - return R.drawable.file_ms_ppt; - } else if (mimetype.contains("msexcel") || mimetype.contains("ms-excel")) { - return R.drawable.file_ms_excel; - } else if (mimetype.contains("openxmlformats-officedocument")) { - if (mimetype.contains("wordprocessingml")) { - return R.drawable.file_ms_word; - } else if (mimetype.contains("spreadsheetml")) { - return R.drawable.file_ms_excel; - } else if (mimetype.contains("presentationml")) { - return R.drawable.file_ms_ppt; - } - // } else if (mimetype.contains("application")) { - // return R.drawable.file_binary; - } - - return R.drawable.file; - } - } diff --git a/app/src/main/java/com/seafile/seadroid2/framework/util/Objs.java b/app/src/main/java/com/seafile/seadroid2/framework/util/Objs.java index 334ba299a..275987c7f 100644 --- a/app/src/main/java/com/seafile/seadroid2/framework/util/Objs.java +++ b/app/src/main/java/com/seafile/seadroid2/framework/util/Objs.java @@ -391,6 +391,7 @@ private static TreeMap> groupRepos(List repos //////dirent //////////////////////////// public static Single> getDirentsSingleFromServer(Account account, String repoId, String repoName, String parentDir) { + Single netSingle = HttpIO.getInstanceByAccount(account).execute(RepoService.class).getDirents(repoId, parentDir); return netSingle.flatMap(new Function>>() { @Override diff --git a/app/src/main/java/com/seafile/seadroid2/framework/util/Utils.java b/app/src/main/java/com/seafile/seadroid2/framework/util/Utils.java index c4b6341a8..886356dbf 100644 --- a/app/src/main/java/com/seafile/seadroid2/framework/util/Utils.java +++ b/app/src/main/java/com/seafile/seadroid2/framework/util/Utils.java @@ -75,7 +75,27 @@ public static JSONObject parseJsonObject(String json) { } } + public static String getPathFromFullPath(String path) { + if (path == null) { + // the caller should not give null + Log.w(DEBUG_TAG, "path is null"); + return null; + } + if (!path.contains("/")) { + return "/"; + } + + if (path.endsWith("/")) { + return path; + } + + String parent = path.substring(0, path.lastIndexOf("/")); + if (parent.isEmpty()) { + return "/"; + } else + return parent; + } public static String getParentPath(String path) { if (path == null) { // the caller should not give null diff --git a/app/src/main/java/com/seafile/seadroid2/ssl/CertsDBHelper.java b/app/src/main/java/com/seafile/seadroid2/ssl/CertsDBHelper.java index 3ffceb286..dc20576a3 100644 --- a/app/src/main/java/com/seafile/seadroid2/ssl/CertsDBHelper.java +++ b/app/src/main/java/com/seafile/seadroid2/ssl/CertsDBHelper.java @@ -1,23 +1,10 @@ package com.seafile.seadroid2.ssl; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.security.cert.X509Certificate; -import java.util.List; - import android.content.Context; -import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; -import android.util.Base64; -import com.blankj.utilcode.util.CollectionUtils; import com.seafile.seadroid2.SeadroidApplication; -import com.seafile.seadroid2.framework.data.db.AppDatabase; -import com.seafile.seadroid2.framework.data.db.entities.CertEntity; public class CertsDBHelper extends SQLiteOpenHelper { // If you change the database schema, you must increment the database version. diff --git a/app/src/main/java/com/seafile/seadroid2/ssl/CertsManager.java b/app/src/main/java/com/seafile/seadroid2/ssl/CertsManager.java index 5cc91bb45..d39f018d5 100644 --- a/app/src/main/java/com/seafile/seadroid2/ssl/CertsManager.java +++ b/app/src/main/java/com/seafile/seadroid2/ssl/CertsManager.java @@ -5,21 +5,12 @@ import java.util.Map; import android.text.TextUtils; -import android.util.Log; import com.blankj.utilcode.util.EncryptUtils; import com.google.common.collect.Maps; -import com.seafile.seadroid2.R; -import com.seafile.seadroid2.framework.data.db.AppDatabase; -import com.seafile.seadroid2.framework.data.db.entities.CertEntity; -import com.seafile.seadroid2.framework.datastore.DataManager; import com.seafile.seadroid2.framework.datastore.DataStoreKeys; -import com.seafile.seadroid2.framework.datastore.DataStoreManager; -import com.seafile.seadroid2.framework.datastore.sp.SettingsManager; -import com.seafile.seadroid2.framework.util.ConcurrentAsyncTask; import com.seafile.seadroid2.account.Account; import com.seafile.seadroid2.preferences.Settings; -import com.seafile.seadroid2.preferences.SharedPreferencesHelper; /** * Save the ssl certificates the user has confirmed to trust diff --git a/app/src/main/java/com/seafile/seadroid2/ui/account/AccountDetailActivity.java b/app/src/main/java/com/seafile/seadroid2/ui/account/AccountDetailActivity.java index c6595be0c..b96d0ce27 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/account/AccountDetailActivity.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/account/AccountDetailActivity.java @@ -436,26 +436,4 @@ private void login() { getViewModel().login(tempAccount, passwd, authToken, rememberDevice); } - - private Dialog dialog; - - private void showProgressDialog() { - - if (dialog == null) { - MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this); - builder.setView(R.layout.layout_dialog_progress_bar); - dialog = builder.create(); - } - - if (dialog.isShowing()) { - dialog.dismiss(); - } - dialog.show(); - } - - private void dismissProgressDialog() { - if (dialog != null) { - dialog.dismiss(); - } - } } diff --git a/app/src/main/java/com/seafile/seadroid2/ui/account/AccountsActivity.java b/app/src/main/java/com/seafile/seadroid2/ui/account/AccountsActivity.java index 5581f2764..97ee1984d 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/account/AccountsActivity.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/account/AccountsActivity.java @@ -203,28 +203,6 @@ private void onListItemClick(int position) { } } - private Dialog dialog; - - private void showProgressDialog() { - - if (dialog == null) { - MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this); - builder.setView(R.layout.layout_dialog_progress_bar); - dialog = builder.create(); - } - - if (dialog.isShowing()) { - dialog.dismiss(); - } - dialog.show(); - } - - private void dismissProgressDialog() { - if (dialog != null) { - dialog.dismiss(); - } - } - @Override protected void onDestroy() { Log.d(DEBUG_TAG, "onDestroy"); diff --git a/app/src/main/java/com/seafile/seadroid2/ui/base/BaseActivity.java b/app/src/main/java/com/seafile/seadroid2/ui/base/BaseActivity.java index 380cc8381..db0bf401e 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/base/BaseActivity.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/base/BaseActivity.java @@ -1,5 +1,6 @@ package com.seafile.seadroid2.ui.base; +import android.app.Dialog; import android.os.Bundle; import androidx.annotation.NonNull; @@ -8,6 +9,7 @@ import androidx.appcompat.app.AppCompatDelegate; import androidx.appcompat.widget.Toolbar; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.seafile.seadroid2.R; import com.seafile.seadroid2.framework.helper.NightModeHelper; @@ -47,4 +49,32 @@ public void setContentView(int layoutResID) { super.setContentView(layoutResID); getActionBarToolbar(); } + + private Dialog dialog; + + public void showProgressDialog(boolean isShow) { + if (isShow) { + showProgressDialog(); + } else { + dismissProgressDialog(); + } + } + + public void showProgressDialog() { + if (dialog == null) { + MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this); + builder.setView(R.layout.layout_dialog_progress_bar); + dialog = builder.create(); + } + + if (!dialog.isShowing()) { + dialog.show(); + } + } + + public void dismissProgressDialog() { + if (dialog != null && dialog.isShowing()) { + dialog.dismiss(); + } + } } diff --git a/app/src/main/java/com/seafile/seadroid2/ui/base/fragment/CustomDialogFragment.java b/app/src/main/java/com/seafile/seadroid2/ui/base/fragment/CustomDialogFragment.java index a0337386b..185c75638 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/base/fragment/CustomDialogFragment.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/base/fragment/CustomDialogFragment.java @@ -77,11 +77,11 @@ public void showLoading(boolean isShow) { @NonNull @Override public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { - rootView = LayoutInflater.from(requireContext()).inflate(R.layout.layout_dialog_container, null); + rootView = getLayoutInflater().inflate(R.layout.layout_dialog_container, null); LinearLayout containerView = rootView.findViewById(R.id.container); // - LayoutInflater.from(requireContext()).inflate(getLayoutId(), containerView); + getLayoutInflater().inflate(getLayoutId(), containerView); //action bar positiveView = rootView.findViewById(R.id.text_view_positive); diff --git a/app/src/main/java/com/seafile/seadroid2/ui/base/viewmodel/BaseViewModel.java b/app/src/main/java/com/seafile/seadroid2/ui/base/viewmodel/BaseViewModel.java index b06e1fbb5..8cbc4d260 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/base/viewmodel/BaseViewModel.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/base/viewmodel/BaseViewModel.java @@ -52,7 +52,11 @@ public class BaseViewModel extends ViewModel { private final MutableLiveData RefreshLiveData = new MutableLiveData<>(false); private final MutableLiveData> ExceptionLiveData = new MutableLiveData<>(); private final MutableLiveData SeafExceptionLiveData = new MutableLiveData<>(); + private final MutableLiveData ShowLoadingDialogLiveData = new MutableLiveData<>(false); + public MutableLiveData getShowLoadingDialogLiveData() { + return ShowLoadingDialogLiveData; + } public MutableLiveData getRefreshLiveData() { return RefreshLiveData; diff --git a/app/src/main/java/com/seafile/seadroid2/bottomsheetmenu/ActionMenu.java b/app/src/main/java/com/seafile/seadroid2/ui/bottomsheetmenu/ActionMenu.java similarity index 98% rename from app/src/main/java/com/seafile/seadroid2/bottomsheetmenu/ActionMenu.java rename to app/src/main/java/com/seafile/seadroid2/ui/bottomsheetmenu/ActionMenu.java index eea46dd88..72b8826cf 100644 --- a/app/src/main/java/com/seafile/seadroid2/bottomsheetmenu/ActionMenu.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/bottomsheetmenu/ActionMenu.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.seafile.seadroid2.bottomsheetmenu; +package com.seafile.seadroid2.ui.bottomsheetmenu; import android.content.ComponentName; import android.content.Context; @@ -29,7 +29,7 @@ import java.util.Iterator; import java.util.List; -class ActionMenu implements android.view.Menu { +public class ActionMenu implements android.view.Menu { private static final int[] sCategoryToOrder = new int[]{ 1, /* No category */ 4, /* CONTAINER */ @@ -58,7 +58,7 @@ class ActionMenu implements android.view.Menu { private boolean mIsQwerty; private ArrayList mItems; - ActionMenu(Context context) { + public ActionMenu(Context context) { mContext = context; mItems = new ArrayList<>(); } diff --git a/app/src/main/java/com/seafile/seadroid2/bottomsheetmenu/ActionMenuItem.java b/app/src/main/java/com/seafile/seadroid2/ui/bottomsheetmenu/ActionMenuItem.java similarity index 99% rename from app/src/main/java/com/seafile/seadroid2/bottomsheetmenu/ActionMenuItem.java rename to app/src/main/java/com/seafile/seadroid2/ui/bottomsheetmenu/ActionMenuItem.java index 47f28f68c..0c6399341 100644 --- a/app/src/main/java/com/seafile/seadroid2/bottomsheetmenu/ActionMenuItem.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/bottomsheetmenu/ActionMenuItem.java @@ -1,4 +1,4 @@ -package com.seafile.seadroid2.bottomsheetmenu; +package com.seafile.seadroid2.ui.bottomsheetmenu; /* * Copyright (C) 2010 The Android Open Source Project diff --git a/app/src/main/java/com/seafile/seadroid2/bottomsheetmenu/BottomSheetHelper.java b/app/src/main/java/com/seafile/seadroid2/ui/bottomsheetmenu/BottomSheetHelper.java similarity index 96% rename from app/src/main/java/com/seafile/seadroid2/bottomsheetmenu/BottomSheetHelper.java rename to app/src/main/java/com/seafile/seadroid2/ui/bottomsheetmenu/BottomSheetHelper.java index 77ca716dd..b1415e039 100644 --- a/app/src/main/java/com/seafile/seadroid2/bottomsheetmenu/BottomSheetHelper.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/bottomsheetmenu/BottomSheetHelper.java @@ -1,4 +1,4 @@ -package com.seafile.seadroid2.bottomsheetmenu; +package com.seafile.seadroid2.ui.bottomsheetmenu; import android.view.MenuItem; diff --git a/app/src/main/java/com/seafile/seadroid2/ui/bottomsheetmenu/BottomSheetMenuAdapter.java b/app/src/main/java/com/seafile/seadroid2/ui/bottomsheetmenu/BottomSheetMenuAdapter.java new file mode 100644 index 000000000..6a5a99c8a --- /dev/null +++ b/app/src/main/java/com/seafile/seadroid2/ui/bottomsheetmenu/BottomSheetMenuAdapter.java @@ -0,0 +1,68 @@ +package com.seafile.seadroid2.ui.bottomsheetmenu; + +import android.content.Context; +import android.content.res.ColorStateList; +import android.view.LayoutInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.seafile.seadroid2.R; +import com.seafile.seadroid2.ui.base.adapter.BaseAdapter; +import com.seafile.seadroid2.ui.base.viewholder.BaseViewHolder; + +public class BottomSheetMenuAdapter extends BaseAdapter { + private final int columnCount; + + public BottomSheetMenuAdapter(int columnCount) { + this.columnCount = columnCount; + } + + @Override + protected void onBindViewHolder(@NonNull BottomSheetMenuAdapter.BottomSheetViewHolder holder, int i, @Nullable MenuItem menuItem) { + if (menuItem == null) { + return; + } + + holder.icon.setImageDrawable(menuItem.getIcon()); + holder.name.setText(menuItem.getTitle()); + + holder.name.setEnabled(menuItem.isEnabled()); + holder.itemView.setClickable(menuItem.isEnabled()); + + int color; + if (menuItem.isEnabled()) { + color = ContextCompat.getColor(getContext(), R.color.bottom_sheet_pop_enable_color); + } else { + color = ContextCompat.getColor(getContext(), R.color.bottom_sheet_pop_disable_color); + } + holder.icon.setImageTintList(ColorStateList.valueOf(color)); + + } + + @NonNull + @Override + protected BottomSheetMenuAdapter.BottomSheetViewHolder onCreateViewHolder(@NonNull Context context, @NonNull ViewGroup viewGroup, int i) { + int layoutId = columnCount == 1 ? R.layout.bottom_sheet_item_list : R.layout.bottom_sheet_item_grid; + View view = LayoutInflater.from(getContext()).inflate(layoutId, viewGroup, false); + return new BottomSheetMenuAdapter.BottomSheetViewHolder(view); + } + + public static class BottomSheetViewHolder extends BaseViewHolder { + public ImageView icon; + public TextView name; + + public BottomSheetViewHolder(@NonNull View itemView) { + super(itemView); + icon = itemView.findViewById(R.id.icon); + name = itemView.findViewById(R.id.text); + } + } + +} diff --git a/app/src/main/java/com/seafile/seadroid2/bottomsheetmenu/BottomSheetMenuFragment.java b/app/src/main/java/com/seafile/seadroid2/ui/bottomsheetmenu/BottomSheetMenuFragment.java similarity index 78% rename from app/src/main/java/com/seafile/seadroid2/bottomsheetmenu/BottomSheetMenuFragment.java rename to app/src/main/java/com/seafile/seadroid2/ui/bottomsheetmenu/BottomSheetMenuFragment.java index af28dff79..83ec86a10 100644 --- a/app/src/main/java/com/seafile/seadroid2/bottomsheetmenu/BottomSheetMenuFragment.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/bottomsheetmenu/BottomSheetMenuFragment.java @@ -1,4 +1,4 @@ -package com.seafile.seadroid2.bottomsheetmenu; +package com.seafile.seadroid2.ui.bottomsheetmenu; import android.app.Dialog; import android.content.Context; @@ -19,6 +19,7 @@ import androidx.recyclerview.widget.RecyclerView; import com.blankj.utilcode.util.CollectionUtils; +import com.chad.library.adapter4.BaseQuickAdapter; import com.google.android.material.bottomsheet.BottomSheetDialog; import com.google.android.material.bottomsheet.BottomSheetDialogFragment; import com.seafile.seadroid2.R; @@ -49,7 +50,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(requireContext(), R.style.ThemeOverlay_Catalog_BottomSheetDialog_Scrollable); - bottomSheetDialog.setContentView(R.layout.layout_bottom_sheet_recycler_menu); + bottomSheetDialog.setContentView(R.layout.layout_bottom_sheet_menu_dialog); bottomSheetDialog.setDismissWithAnimation(true); View parentView = bottomSheetDialog.findViewById(R.id.bottom_sheet_container); @@ -64,29 +65,37 @@ public void setView(View rootView) { TextView title = rootView.findViewById(R.id.title); title.setText(builder.title); } - - if (!CollectionUtils.isEmpty(builder.menuItems)) { - RecyclerView rv = rootView.findViewById(R.id.rv); - if (builder.columnCount == 1) { - rv.setLayoutManager(new LinearLayoutManager(requireContext())); - } else { - rv.setLayoutManager(new GridLayoutManager(requireContext(), builder.columnCount)); - } - BottomSheetMenuAdapter adapter = new BottomSheetMenuAdapter(builder.menuItems, builder.columnCount); - adapter.setOnMenuClickListener(new OnMenuClickListener() { - @Override - public void onMenuClick(MenuItem menuItem) { - dismiss(); - if (builder.onMenuClickListener != null) { - builder.onMenuClickListener.onMenuClick(menuItem); - } - } - }); + if (CollectionUtils.isEmpty(builder.menuItems)) { + return; + } - rv.setAdapter(adapter); + RecyclerView rv = rootView.findViewById(R.id.rv); + if (builder.columnCount == 1) { + rv.setLayoutManager(new LinearLayoutManager(requireContext())); + } else { + rv.setLayoutManager(new GridLayoutManager(requireContext(), builder.columnCount)); } + BottomSheetMenuAdapter adapter = getBottomSheetMenuAdapter(); + adapter.submitList(builder.menuItems); + + rv.setAdapter(adapter); + + } + + private @NonNull BottomSheetMenuAdapter getBottomSheetMenuAdapter() { + BottomSheetMenuAdapter adapter = new BottomSheetMenuAdapter(builder.columnCount); + adapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() { + @Override + public void onClick(@NonNull BaseQuickAdapter baseQuickAdapter, @NonNull View view, int i) { + dismiss(); + if (builder.onMenuClickListener != null) { + builder.onMenuClickListener.onMenuClick(adapter.getItem(i)); + } + } + }); + return adapter; } @@ -122,7 +131,6 @@ public Builder setMenuSheetId(int menuSheetId) { inflater.inflate(menuSheetId, menu); List items = new ArrayList(menu.size()); - for (int i = 0; i < menu.size(); i++) { items.add(menu.getItem(i)); } @@ -185,5 +193,9 @@ public BottomSheetMenuFragment build() { public void show(FragmentManager fragmentManager) { build().show(fragmentManager, BottomSheetMenuFragment.class.getSimpleName()); } + + public void show(FragmentManager fragmentManager, String tag) { + build().show(fragmentManager, tag); + } } } diff --git a/app/src/main/java/com/seafile/seadroid2/bottomsheetmenu/OnMenuClickListener.java b/app/src/main/java/com/seafile/seadroid2/ui/bottomsheetmenu/OnMenuClickListener.java similarity index 69% rename from app/src/main/java/com/seafile/seadroid2/bottomsheetmenu/OnMenuClickListener.java rename to app/src/main/java/com/seafile/seadroid2/ui/bottomsheetmenu/OnMenuClickListener.java index e6bae6e4f..f76e4ca3e 100644 --- a/app/src/main/java/com/seafile/seadroid2/bottomsheetmenu/OnMenuClickListener.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/bottomsheetmenu/OnMenuClickListener.java @@ -1,4 +1,4 @@ -package com.seafile.seadroid2.bottomsheetmenu; +package com.seafile.seadroid2.ui.bottomsheetmenu; import android.view.MenuItem; diff --git a/app/src/main/java/com/seafile/seadroid2/ui/data_migrate/DataMigrationActivity.java b/app/src/main/java/com/seafile/seadroid2/ui/data_migrate/DataMigrationActivity.java index e5c71c37c..b7a26bb75 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/data_migrate/DataMigrationActivity.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/data_migrate/DataMigrationActivity.java @@ -26,7 +26,6 @@ import com.seafile.seadroid2.databinding.ActivityDataMigrationBinding; import com.seafile.seadroid2.framework.data.DatabaseHelper; import com.seafile.seadroid2.framework.data.db.AppDatabase; -import com.seafile.seadroid2.framework.data.db.entities.CertEntity; import com.seafile.seadroid2.framework.data.db.entities.EncKeyCacheEntity; import com.seafile.seadroid2.framework.data.db.entities.FileTransferEntity; import com.seafile.seadroid2.framework.data.db.entities.FolderBackupMonitorEntity; @@ -986,34 +985,25 @@ private void queryCertsDB() { null // The sort order ); - List list = CollectionUtils.newArrayList(); try { c.moveToFirst(); while (!c.isAfterLast()) { - CertEntity item = new CertEntity(); int urlIndex = c.getColumnIndexOrThrow("url"); int certIndex = c.getColumnIndexOrThrow("cert"); - item.url = c.getString(urlIndex); - item.cert = c.getString(certIndex); + String url = c.getString(urlIndex); + String cert = c.getString(certIndex); c.moveToNext(); - list.add(item); + String keyPrefix = EncryptUtils.encryptMD5ToString(url); + Settings.getCommonPreferences().edit().putString(DataStoreKeys.KEY_SERVER_CERT_INFO + "_" + keyPrefix, cert).apply(); } } finally { c.close(); } - SLogs.d("--------------------" + table); - for (CertEntity entity : list) { - SLogs.d(entity.toString()); - - String keyPrefix = EncryptUtils.encryptMD5ToString(entity.url); - Settings.getCommonPreferences().edit().putString(DataStoreKeys.KEY_SERVER_CERT_INFO + "_" + keyPrefix, entity.cert).apply(); - } - //Not stored in the database // AppDatabase.getInstance().certDAO().insertAll(list); SLogs.d("--------------------" + table + " -> 完成"); diff --git a/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/CopyMoveDialogFragment.java b/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/CopyMoveDialogFragment.java index 46e3d8156..0c7ac4a39 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/CopyMoveDialogFragment.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/CopyMoveDialogFragment.java @@ -37,11 +37,14 @@ protected int getLayoutId() { @Override public int getDialogTitleRes() { if (ctx != null) { - if (ctx.isdir) { - return ctx.isCopy() ? R.string.copy_folder_ing : R.string.move_folder_ing; - } else { - return ctx.isCopy() ? R.string.copy_file_ing : R.string.move_file_ing; - } +// if (ctx.isdir) { +// return ctx.isCopy() ? R.string.copy_folder_ing : R.string.move_folder_ing; +// } else { +// return ctx.isCopy() ? R.string.copy_file_ing : R.string.move_file_ing; +// } + + return ctx.isCopy() ? R.string.copy_file_ing : R.string.move_file_ing; + } return super.getDialogTitleRes(); @@ -52,11 +55,13 @@ protected void initView(LinearLayout containerView) { super.initView(containerView); int strMsgId; - if (ctx.isdir) { - strMsgId = ctx.isCopy() ? R.string.copy_file_from : R.string.move_file_from; - } else { - strMsgId = ctx.isCopy() ? R.string.copy_file_from : R.string.move_file_from; - } +// if (ctx.isdir) { +// strMsgId = ctx.isCopy() ? R.string.copy_file_from : R.string.move_file_from; +// } else { +// strMsgId = ctx.isCopy() ? R.string.copy_file_from : R.string.move_file_from; +// } + + strMsgId = ctx.isCopy() ? R.string.copy_file_from : R.string.move_file_from; String strMsg = getString(strMsgId); diff --git a/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/DeleteFileDialogFragment.java b/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/DeleteFileDialogFragment.java index 653273e47..e47c448e8 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/DeleteFileDialogFragment.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/DeleteFileDialogFragment.java @@ -1,8 +1,11 @@ package com.seafile.seadroid2.ui.dialog_fragment; +import android.os.Bundle; +import android.os.Parcelable; import android.widget.LinearLayout; import android.widget.TextView; +import androidx.annotation.Nullable; import androidx.lifecycle.Observer; import com.blankj.utilcode.util.CollectionUtils; @@ -17,22 +20,29 @@ import java.util.List; public class DeleteFileDialogFragment extends RequestCustomDialogFragmentWithVM { - private List dirents; - private boolean isDir; - - public static DeleteFileDialogFragment newInstance() { - return new DeleteFileDialogFragment(); + private List dirents; + private boolean isDir = false; + + public static DeleteFileDialogFragment newInstance(List direntIds) { + DeleteFileDialogFragment fragment = new DeleteFileDialogFragment(); + Bundle bundle = new Bundle(); + bundle.putStringArrayList("dirent_ids", new ArrayList<>(direntIds)); + fragment.setArguments(bundle); + return fragment; } - public void initData(DirentModel dirent) { - this.dirents = new ArrayList<>(); - dirents.add(dirent); - isDir = dirent.isDir(); - } + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Bundle bundle = getArguments(); + + if (bundle == null || !bundle.containsKey("dirent_ids")) { + throw new RuntimeException("need a dirent_ids param"); + } + + dirents = bundle.getStringArrayList("dirent_ids"); - public void initData(List dirents) { - this.dirents = dirents; - isDir = false; } @Override @@ -47,8 +57,7 @@ protected void onPositiveClick() { return; } - Account account = SupportAccountManager.getInstance().getCurrentAccount(); - getViewModel().deleteDirents(account.getSignature(), dirents, false); + getViewModel().delete(dirents, false); } @Override diff --git a/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/DeleteRepoDialogFragment.java b/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/DeleteRepoDialogFragment.java index b52185acc..119ba31d9 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/DeleteRepoDialogFragment.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/DeleteRepoDialogFragment.java @@ -8,18 +8,22 @@ import androidx.annotation.Nullable; import androidx.lifecycle.Observer; +import com.blankj.utilcode.util.CollectionUtils; import com.blankj.utilcode.util.ToastUtils; import com.seafile.seadroid2.R; import com.seafile.seadroid2.ui.base.fragment.RequestCustomDialogFragmentWithVM; import com.seafile.seadroid2.framework.data.model.ResultModel; import com.seafile.seadroid2.ui.dialog_fragment.viewmodel.DeleteRepoViewModel; +import java.util.ArrayList; +import java.util.List; + public class DeleteRepoDialogFragment extends RequestCustomDialogFragmentWithVM { - private String repoId; + private List repoIds; - public static DeleteRepoDialogFragment newInstance(String repoId) { + public static DeleteRepoDialogFragment newInstance(List repoIds) { Bundle args = new Bundle(); - args.putString("repoId", repoId); + args.putStringArrayList("repo_ids", new ArrayList<>(repoIds)); DeleteRepoDialogFragment fragment = new DeleteRepoDialogFragment(); fragment.setArguments(args); return fragment; @@ -28,18 +32,14 @@ public static DeleteRepoDialogFragment newInstance(String repoId) { @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if (getArguments() == null) { - throw new IllegalArgumentException("this dialogFragment need Arguments"); - } - if (!getArguments().containsKey("repoId")) { - throw new IllegalArgumentException("this dialogFragment need repoId param"); + if (getArguments() == null || !getArguments().containsKey("repo_ids")) { + throw new IllegalArgumentException("this dialogFragment need Arguments"); } - repoId = getArguments().getString("repoId", null); - - if (TextUtils.isEmpty(repoId)) { - throw new IllegalArgumentException("this dialogFragment need repoId param"); + repoIds = getArguments().getStringArrayList("repo_ids"); + if (CollectionUtils.isEmpty(repoIds)) { + throw new IllegalArgumentException("need repoIds param"); } } @@ -55,7 +55,7 @@ public int getDialogTitleRes() { @Override protected void onPositiveClick() { - getViewModel().deleteRepo(repoId); + getViewModel().deleteRepo(repoIds); } @Override diff --git a/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/DialogService.java b/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/DialogService.java index 8eff6cbfe..7a9a88ed0 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/DialogService.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/DialogService.java @@ -9,6 +9,7 @@ import java.util.List; import java.util.Map; +import io.reactivex.Flowable; import io.reactivex.Single; import okhttp3.RequestBody; import retrofit2.http.Body; diff --git a/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/RenameDialogFragment.java b/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/RenameDialogFragment.java index 76d7216b3..596a220ce 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/RenameDialogFragment.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/RenameDialogFragment.java @@ -1,35 +1,61 @@ package com.seafile.seadroid2.ui.dialog_fragment; +import android.os.Bundle; import android.text.Editable; import android.text.TextUtils; import android.widget.EditText; import android.widget.LinearLayout; +import androidx.annotation.Nullable; import androidx.lifecycle.Observer; import com.blankj.utilcode.util.ToastUtils; import com.seafile.seadroid2.R; +import com.seafile.seadroid2.framework.data.db.entities.DirentModel; import com.seafile.seadroid2.ui.base.fragment.RequestCustomDialogFragmentWithVM; import com.seafile.seadroid2.framework.data.model.dirents.FileCreateModel; import com.seafile.seadroid2.ui.dialog_fragment.viewmodel.RenameRepoViewModel; -public class RenameDialogFragment extends RequestCustomDialogFragmentWithVM { - private String curName, repoId, curPath, type; +import java.util.ArrayList; +import java.util.List; - public static RenameDialogFragment newInstance() { - return new RenameDialogFragment(); - } +public class RenameDialogFragment extends RequestCustomDialogFragmentWithVM { /** - * @param type "repo" or "dir" or "file" + * "repo" or "dir" or "file" */ - public void initData(String curName, String curPath, String repoId, String type) { - this.curName = curName; - this.curPath = curPath; - this.repoId = repoId; - this.type = type; + private String type; + private String curName, repoId, curPath; + + public static RenameDialogFragment newInstance(String curName, String curPath, String repoId, String type) { + + RenameDialogFragment fragment = new RenameDialogFragment(); + Bundle bundle = new Bundle(); + bundle.putString("name", curName); + bundle.putString("path", curPath); + bundle.putString("repoId", repoId); + bundle.putString("type", type); + fragment.setArguments(bundle); + return fragment; } + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Bundle bundle = getArguments(); + + if (bundle == null || !bundle.containsKey("repoId")) { + throw new RuntimeException("need a dirent param"); + } + + curName = bundle.getString("name"); + curPath = bundle.getString("path"); + repoId = bundle.getString("repoId"); + type = bundle.getString("type"); + } + + @Override protected int getLayoutId() { return R.layout.view_dialog_new_file; diff --git a/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/viewmodel/DeleteDirsViewModel.java b/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/viewmodel/DeleteDirsViewModel.java index 93bd12646..045bcc476 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/viewmodel/DeleteDirsViewModel.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/viewmodel/DeleteDirsViewModel.java @@ -33,8 +33,27 @@ public MutableLiveData getActionLiveData() { return ActionLiveData; } + public void delete(List direntIds, boolean isDeleteLocalFile) { + Single> dSingle = AppDatabase.getInstance().direntDao().getListByIdsAsync(direntIds); + addSingleDisposable(dSingle, new Consumer>() { + @Override + public void accept(List dirents) throws Exception { + deleteDirents(dirents, isDeleteLocalFile); + } + }, new Consumer() { + @Override + public void accept(Throwable throwable) throws Exception { + getRefreshLiveData().setValue(false); + getActionLiveData().setValue(true); + + String string = getErrorMsgByThrowable(throwable); + DeleteDirentModel d = new DeleteDirentModel(); + d.error_msg = string; + } + }); + } - public void deleteDirents(String related_account, List dirents, boolean isDeleteLocalFile) { + private void deleteDirents(List dirents, boolean isDeleteLocalFile) { getRefreshLiveData().setValue(true); Flowable flowable; @@ -43,8 +62,7 @@ public void deleteDirents(String related_account, List dirents, boo .flatMapSingle(new Function>() { @Override public SingleSource apply(DirentModel dirent) throws Exception { - String obj = dirent.isDir() ? "dir" : "file"; - return HttpIO.getCurrentInstance().execute(DialogService.class).deleteDirent(dirent.repo_id, obj, dirent.full_path); + return HttpIO.getCurrentInstance().execute(DialogService.class).deleteDirent(dirent.repo_id, dirent.type, dirent.full_path); } }); } else { @@ -89,8 +107,7 @@ public SingleSource apply(String filePath) throws Exception { } } - String obj = dirent.isDir() ? "dir" : "file"; - return HttpIO.getCurrentInstance().execute(DialogService.class).deleteDirent(dirent.repo_id, obj, dirent.full_path); + return HttpIO.getCurrentInstance().execute(DialogService.class).deleteDirent(dirent.repo_id, dirent.type, dirent.full_path); } }); } diff --git a/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/viewmodel/DeleteRepoViewModel.java b/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/viewmodel/DeleteRepoViewModel.java index 1ffb31cbe..bf55d0333 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/viewmodel/DeleteRepoViewModel.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/dialog_fragment/viewmodel/DeleteRepoViewModel.java @@ -4,8 +4,10 @@ import androidx.lifecycle.MutableLiveData; +import com.blankj.utilcode.util.CollectionUtils; import com.seafile.seadroid2.framework.datastore.sp_livedata.AlbumBackupSharePreferenceHelper; import com.seafile.seadroid2.framework.datastore.sp_livedata.FolderBackupSharePreferenceHelper; +import com.seafile.seadroid2.framework.util.SLogs; import com.seafile.seadroid2.preferences.Settings; import com.seafile.seadroid2.ui.base.viewmodel.BaseViewModel; import com.seafile.seadroid2.framework.data.model.ResultModel; @@ -13,8 +15,19 @@ import com.seafile.seadroid2.ui.dialog_fragment.DialogService; import com.seafile.seadroid2.ui.folder_backup.RepoConfig; +import org.reactivestreams.Publisher; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Flow; + +import io.reactivex.Flowable; import io.reactivex.Single; +import io.reactivex.SingleSource; +import io.reactivex.functions.Action; import io.reactivex.functions.Consumer; +import io.reactivex.functions.Function; +import kotlin.Pair; public class DeleteRepoViewModel extends BaseViewModel { private final MutableLiveData ActionLiveData = new MutableLiveData<>(); @@ -23,20 +36,33 @@ public MutableLiveData getActionLiveData() { return ActionLiveData; } - public void deleteRepo(String repoId) { + public void deleteRepo(List repoIds) { + if (CollectionUtils.isEmpty(repoIds)) { + return; + } getRefreshLiveData().setValue(true); - Single single = HttpIO.getCurrentInstance().execute(DialogService.class).deleteRepo(repoId); - addSingleDisposable(single, new Consumer() { + List>> flowableList = new ArrayList<>(); + for (String repoId : repoIds) { + flowableList.add(getDeleteFlowable(repoId)); + } + + Flowable> mergedFlowable = Flowable.mergeDelayError(flowableList, 5, Flowable.bufferSize()); + addFlowableDisposable(mergedFlowable, new Consumer>() { @Override - public void accept(String resultModel) throws Exception { - getRefreshLiveData().setValue(false); + public void accept(Pair pair) throws Exception { + + SLogs.d("DeleteRepoViewModel deleteRepo result: repoId = " + pair.getFirst() + ", result = " + pair.getSecond()); + + + String repoId = pair.getFirst(); + String o = pair.getSecond(); ResultModel resultModel1 = new ResultModel(); - if (TextUtils.equals("success", resultModel)) { + if (TextUtils.equals("success", o)) { resultModel1.success = true; } else { - resultModel1.error_msg = resultModel; + resultModel1.error_msg = o; } if (resultModel1.success) { @@ -52,8 +78,6 @@ public void accept(String resultModel) throws Exception { FolderBackupSharePreferenceHelper.writeBackupSwitch(false); } } - - getActionLiveData().setValue(resultModel1); } }, new Consumer() { @Override @@ -64,8 +88,25 @@ public void accept(Throwable throwable) throws Exception { resultModel.error_msg = getErrorMsgByThrowable(throwable); getActionLiveData().setValue(resultModel); } + }, new Action() { + @Override + public void run() throws Exception { + //todo 检查一下getActionLiveData + getRefreshLiveData().setValue(false); + getActionLiveData().setValue(new ResultModel()); + } }); } + private Flowable> getDeleteFlowable(String repoId) { + Single single = HttpIO.getCurrentInstance().execute(DialogService.class).deleteRepo(repoId); + return single.flatMap(new Function>>() { + @Override + public SingleSource> apply(String s) throws Exception { + return Single.just(new Pair<>(repoId, s)); + } + }).toFlowable(); + } + } diff --git a/app/src/main/java/com/seafile/seadroid2/ui/editor/EditorActivity.java b/app/src/main/java/com/seafile/seadroid2/ui/editor/EditorActivity.java index 4e4fa1f7c..89bec8bf6 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/editor/EditorActivity.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/editor/EditorActivity.java @@ -181,25 +181,6 @@ public void afterTextChanged(Editable s) { }); } - private Dialog dialog; - - private void showProgressDialog() { - - if (dialog == null) { - MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this); - builder.setView(R.layout.layout_dialog_progress_bar); - dialog = builder.create(); - } - - dialog.show(); - } - - private void dismissProgressDialog() { - if (dialog != null) { - dialog.dismiss(); - } - } - @Override public void onDetachedFromWindow() { mPerformEdit.clearHistory(); diff --git a/app/src/main/java/com/seafile/seadroid2/ui/folder_backup/FolderBackupSelectedPathActivity.java b/app/src/main/java/com/seafile/seadroid2/ui/folder_backup/FolderBackupSelectedPathActivity.java index c378eb72d..bac328156 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/folder_backup/FolderBackupSelectedPathActivity.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/folder_backup/FolderBackupSelectedPathActivity.java @@ -19,8 +19,8 @@ import com.chad.library.adapter4.QuickAdapterHelper; import com.seafile.seadroid2.R; -import com.seafile.seadroid2.bottomsheetmenu.BottomSheetHelper; -import com.seafile.seadroid2.bottomsheetmenu.BottomSheetMenuFragment; +import com.seafile.seadroid2.ui.bottomsheetmenu.BottomSheetHelper; +import com.seafile.seadroid2.ui.bottomsheetmenu.BottomSheetMenuFragment; import com.seafile.seadroid2.framework.datastore.sp_livedata.FolderBackupSharePreferenceHelper; import com.seafile.seadroid2.ui.base.BaseActivity; diff --git a/app/src/main/java/com/seafile/seadroid2/ui/main/MainActivity.java b/app/src/main/java/com/seafile/seadroid2/ui/main/MainActivity.java index d6aef4156..3cdc20e98 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/main/MainActivity.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/main/MainActivity.java @@ -2,7 +2,6 @@ import android.Manifest; import android.app.Activity; -import android.app.Dialog; import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; @@ -17,6 +16,7 @@ import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; +import android.view.View; import androidx.activity.OnBackPressedCallback; import androidx.activity.result.ActivityResult; @@ -44,13 +44,17 @@ import com.seafile.seadroid2.account.SupportAccountManager; import com.seafile.seadroid2.context.NavContext; import com.seafile.seadroid2.databinding.ActivityMainBinding; +import com.seafile.seadroid2.enums.ActionModeCallbackType; import com.seafile.seadroid2.enums.FileViewType; import com.seafile.seadroid2.enums.NightMode; import com.seafile.seadroid2.enums.SortBy; import com.seafile.seadroid2.framework.data.ServerInfo; +import com.seafile.seadroid2.framework.data.db.entities.DirentModel; import com.seafile.seadroid2.framework.data.db.entities.EncKeyCacheEntity; import com.seafile.seadroid2.framework.data.db.entities.FileTransferEntity; +import com.seafile.seadroid2.framework.data.db.entities.PermissionEntity; import com.seafile.seadroid2.framework.data.db.entities.RepoModel; +import com.seafile.seadroid2.framework.data.model.BaseModel; import com.seafile.seadroid2.framework.data.model.dirents.DirentFileModel; import com.seafile.seadroid2.framework.file_monitor.FileSyncService; import com.seafile.seadroid2.framework.helper.NightModeHelper; @@ -69,7 +73,6 @@ import com.seafile.seadroid2.ui.dialog_fragment.PasswordDialogFragment; import com.seafile.seadroid2.ui.dialog_fragment.listener.OnRefreshDataListener; import com.seafile.seadroid2.ui.repo.RepoQuickFragment; -import com.seafile.seadroid2.ui.search.Search2Activity; import com.seafile.seadroid2.ui.transfer_list.TransferActivity; import java.io.File; @@ -287,7 +290,7 @@ public void accept(EncKeyCacheEntity encKeyCacheEntity) throws Exception { // expired showPasswordDialog(repoModel, finalPath); } else { - getNavContext().navToPath(repoModel, finalPath); + getNavContext().switchToPath(repoModel, finalPath); binding.pager.setCurrentItem(0); getReposFragment().loadData(); refreshToolbarTitle(); @@ -296,7 +299,7 @@ public void accept(EncKeyCacheEntity encKeyCacheEntity) throws Exception { }); } else { - getNavContext().navToPath(repoModel, finalPath); + getNavContext().switchToPath(repoModel, finalPath); binding.pager.setCurrentItem(0); getReposFragment().loadData(); refreshToolbarTitle(); @@ -376,12 +379,14 @@ private void initViewPager() { @Override public void onPageSelected(int position) { super.onPageSelected(position); + onViewPageSelected(position); } }); } private void onViewPageSelected(int position) { + if (0 == position) { binding.navBottomView.setSelectedItemId(R.id.tabs_library); @@ -396,6 +401,9 @@ private void onViewPageSelected(int position) { return; } + if (menuBinding.search.isActionViewExpanded()) { + menuBinding.search.collapseActionView(); + } menuBinding.search.setVisible(false); menuBinding.sortGroup.setVisible(false); @@ -465,6 +473,24 @@ public void onChanged(NightMode nightMode) { // } } }); + + mainViewModel.getOnActionModeLiveData().observe(this, new Observer() { + @Override + public void onChanged(ActionModeCallbackType callbackType) { + + onShowRepoActionMode(callbackType); + + } + }); + } + + private void onShowRepoActionMode(ActionModeCallbackType type) { + if (type == ActionModeCallbackType.CREATE) { + binding.pager.setUserInputEnabled(false); + } else if (type == ActionModeCallbackType.DESTORY) { + binding.pager.setUserInputEnabled(true); + } + } private void refreshToolbarTitle() { @@ -545,7 +571,6 @@ private void finishAndStartAccountsActivity() { finish(); } - //////////////////////////// /// menu //////////////////////////// @@ -596,7 +621,6 @@ private void enableUpButton(boolean isEnable) { @Override public boolean onCreateOptionsMenu(Menu menu) { menuBinding = MenuBinding.inflate(menu, getMenuInflater()); - MenuCompat.setGroupDividerEnabled(menu, true); initSearchView(); @@ -614,9 +638,7 @@ private void initSearchView() { searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { - searchView.clearFocus(); - startSearchPage(query); - return true; + return false; } @Override @@ -625,6 +647,8 @@ public boolean onQueryTextChange(String newText) { return false; } }); + + menuBinding.search.collapseActionView(); menuBinding.search.setActionView(searchView); } @@ -634,21 +658,22 @@ public boolean onPrepareOptionsMenu(Menu menu) { if (binding.pager.getCurrentItem() == INDEX_LIBRARY_TAB) { if (getNavContext().inRepo()) { menuBinding.createRepo.setVisible(false); - if (getNavContext().isParentHasWritePermission()) { - menuBinding.add.setEnabled(true); - menuBinding.select.setEnabled(true); - } else { - menuBinding.add.setEnabled(false); - menuBinding.select.setEnabled(false); - } + + checkCurrentPathHasWritePermission(new java.util.function.Consumer() { + @Override + public void accept(Boolean aBoolean) { + menuBinding.add.setEnabled(aBoolean); + } + }); } else { menuBinding.createRepo.setVisible(true); menuBinding.add.setVisible(false); - menuBinding.select.setVisible(false); } + menuBinding.select.setVisible(true); menuBinding.sortGroup.setVisible(true); } else { + menuBinding.search.setVisible(false); menuBinding.sortGroup.setVisible(false); menuBinding.createRepo.setVisible(false); menuBinding.add.setVisible(false); @@ -662,21 +687,11 @@ public boolean onPrepareOptionsMenu(Menu menu) { @Override public boolean onOptionsItemSelected(MenuItem item) { - boolean isRet = true; if (item.getItemId() == android.R.id.home) { if (getNavContext().inRepo() && binding.pager.getCurrentItem() == INDEX_LIBRARY_TAB) { getOnBackPressedDispatcher().onBackPressed(); } - } else if (item.getItemId() == R.id.menu_action_search_go) { - Optional optional = checkServerInfo(); - if (optional.isPresent() && optional.get().isSearchEnabled()) { - SearchView searchView = (SearchView) menuBinding.search.getActionView(); - if (searchView != null) { - searchView.clearFocus(); - startSearchPage(searchView.getQuery().toString()); - } - } } else if (item.getItemId() == R.id.create_repo) { showNewRepoDialog(); } else if (item.getItemId() == R.id.add) { @@ -687,7 +702,7 @@ public boolean onOptionsItemSelected(MenuItem item) { startActivity(newIntent); } else if (item.getItemId() == R.id.select) { if (binding.pager.getCurrentItem() == INDEX_LIBRARY_TAB) { - getReposFragment().startContextualActionMode(); + getReposFragment().startOrUpdateContextualActionBar(); } } else if (item.getItemId() == R.id.menu_action_view_list) { Settings.FILE_LIST_VIEW_TYPE.putValue(FileViewType.LIST); @@ -734,11 +749,6 @@ public boolean onMenuItemActionExpand(@NonNull MenuItem item) { menuIdState.put("select", menuBinding.select.isVisible()); menuIdState.put("transferList", menuBinding.transferList.isVisible()); - Optional optional = checkServerInfo(); - if (optional.isPresent() && optional.get().isSearchEnabled()) { - menuBinding.searchNext.setVisible(true); - } - menuBinding.sortGroup.setVisible(false); menuBinding.createRepo.setVisible(false); menuBinding.add.setVisible(false); @@ -750,7 +760,6 @@ public boolean onMenuItemActionExpand(@NonNull MenuItem item) { @Override public boolean onMenuItemActionCollapse(@NonNull MenuItem item) { - menuBinding.searchNext.setVisible(false); menuBinding.sortGroup.setVisible(Boolean.TRUE.equals(menuIdState.get("sortGroup"))); menuBinding.createRepo.setVisible(Boolean.TRUE.equals(menuIdState.get("createRepo"))); @@ -810,7 +819,6 @@ private static class MenuBinding { public MenuItem viewGallery; public MenuItem search; - public MenuItem searchNext; public MenuItem createRepo; public MenuItem add; @@ -837,7 +845,6 @@ public static MenuBinding inflate(Menu menu, MenuInflater inflater) { binding1.viewGallery = menu.findItem(R.id.menu_action_view_gallery); binding1.search = menu.findItem(R.id.menu_action_search); - binding1.searchNext = menu.findItem(R.id.menu_action_search_go); binding1.createRepo = menu.findItem(R.id.create_repo); binding1.add = menu.findItem(R.id.add); @@ -847,13 +854,6 @@ public static MenuBinding inflate(Menu menu, MenuInflater inflater) { } } - private void startSearchPage(String query) { - Optional optional = checkServerInfo(); - if (optional.isPresent() && optional.get().isSearchEnabled()) { - Search2Activity.start(this, query); - } - } - /** * @see MainActivity -> android:configChanges="uiMode|orientation|screenSize" */ @@ -914,7 +914,7 @@ private void showPasswordDialog(RepoModel repoModel, String path) { @Override public void onActionStatus(boolean isDone) { if (isDone) { - getNavContext().navToPath(repoModel, path); + getNavContext().switchToPath(repoModel, path); binding.pager.setCurrentItem(0); getReposFragment().loadData(); refreshToolbarTitle(); @@ -961,54 +961,102 @@ else if (which == 3) // take a photo }).show(); } - // - private void showNewDirDialog() { - if (!getNavContext().isParentHasWritePermission()) { - ToastUtils.showLong(R.string.library_read_only); + private void checkCurrentPathHasWritePermission(java.util.function.Consumer consumer) { + BaseModel baseModel = getNavContext().getTopModel(); + if (null == baseModel) { return; } - String rid = getNavContext().getRepoModel().repo_id; - String parentPath = getNavContext().getNavPath(); - NewDirFileDialogFragment dialogFragment = NewDirFileDialogFragment.newInstance(rid, parentPath, true); - dialogFragment.setRefreshListener(new OnRefreshDataListener() { + if (baseModel instanceof RepoModel m) { + if (!m.isCustomPermission()) { + consumer.accept(m.hasWritePermission()); + } else { + mainViewModel.getPermissionFromLocal(m.repo_id, m.getCustomPermissionNum(), new Consumer() { + @Override + public void accept(PermissionEntity entity) throws Exception { + consumer.accept(entity != null && entity.create); + } + }); + } + } else if (baseModel instanceof DirentModel m) { + if (!m.isCustomPermission()) { + consumer.accept(m.hasWritePermission()); + } else { + mainViewModel.getPermissionFromLocal(m.repo_id, m.getCustomPermissionNum(), new Consumer() { + @Override + public void accept(PermissionEntity entity) throws Exception { + consumer.accept(entity != null && entity.create); + } + }); + } + } + } + + // + private void showNewDirDialog() { + checkCurrentPathHasWritePermission(new java.util.function.Consumer() { @Override - public void onActionStatus(boolean isDone) { - if (isDone) { - mainViewModel.getOnForceRefreshRepoListLiveData().setValue(true); + public void accept(Boolean aBoolean) { + if (!aBoolean) { + ToastUtils.showLong(R.string.library_read_only); + return; } + + String rid = getNavContext().getRepoModel().repo_id; + String parentPath = getNavContext().getNavPath(); + NewDirFileDialogFragment dialogFragment = NewDirFileDialogFragment.newInstance(rid, parentPath, true); + dialogFragment.setRefreshListener(new OnRefreshDataListener() { + @Override + public void onActionStatus(boolean isDone) { + if (isDone) { + mainViewModel.getOnForceRefreshRepoListLiveData().setValue(true); + } + } + }); + dialogFragment.show(getSupportFragmentManager(), NewDirFileDialogFragment.class.getSimpleName()); } }); - dialogFragment.show(getSupportFragmentManager(), NewDirFileDialogFragment.class.getSimpleName()); } private void showNewFileDialog() { - if (!getNavContext().isParentHasWritePermission()) { - ToastUtils.showLong(R.string.library_read_only); - return; - } - - String rid = getNavContext().getRepoModel().repo_id; - String parentPath = getNavContext().getNavPath(); - NewDirFileDialogFragment dialogFragment = NewDirFileDialogFragment.newInstance(rid, parentPath, false); - dialogFragment.setRefreshListener(new OnRefreshDataListener() { + checkCurrentPathHasWritePermission(new java.util.function.Consumer() { @Override - public void onActionStatus(boolean isDone) { - if (isDone) { - mainViewModel.getOnForceRefreshRepoListLiveData().setValue(true); + public void accept(Boolean aBoolean) { + if (!aBoolean) { + ToastUtils.showLong(R.string.library_read_only); + return; } + + + String rid = getNavContext().getRepoModel().repo_id; + String parentPath = getNavContext().getNavPath(); + NewDirFileDialogFragment dialogFragment = NewDirFileDialogFragment.newInstance(rid, parentPath, false); + dialogFragment.setRefreshListener(new OnRefreshDataListener() { + @Override + public void onActionStatus(boolean isDone) { + if (isDone) { + mainViewModel.getOnForceRefreshRepoListLiveData().setValue(true); + } + } + }); + dialogFragment.show(getSupportFragmentManager(), NewDirFileDialogFragment.class.getSimpleName()); } }); - dialogFragment.show(getSupportFragmentManager(), NewDirFileDialogFragment.class.getSimpleName()); } private void pickFile() { - if (!getNavContext().isParentHasWritePermission()) { - ToastUtils.showLong(R.string.library_read_only); - return; - } + checkCurrentPathHasWritePermission(new java.util.function.Consumer() { + @Override + public void accept(Boolean aBoolean) { + if (!aBoolean) { + ToastUtils.showLong(R.string.library_read_only); + return; + } + + takeFile(false); + } + }); - takeFile(false); } @@ -1154,26 +1202,6 @@ public void onActivityResult(Boolean o) { } }); - private Dialog dialog; - - private void showProgressDialog() { - if (dialog == null) { - MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this); - builder.setView(R.layout.layout_dialog_progress_bar); - dialog = builder.create(); - } - - if (dialog.isShowing()) { - dialog.dismiss(); - } - dialog.show(); - } - - private void dismissProgressDialog() { - if (dialog != null) { - dialog.dismiss(); - } - } ///////////////////////////// private void doSelectedMultiFile(List uriList) { diff --git a/app/src/main/java/com/seafile/seadroid2/ui/main/MainViewModel.java b/app/src/main/java/com/seafile/seadroid2/ui/main/MainViewModel.java index 11408d1d5..691070670 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/main/MainViewModel.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/main/MainViewModel.java @@ -14,13 +14,17 @@ import com.seafile.seadroid2.R; import com.seafile.seadroid2.account.Account; import com.seafile.seadroid2.account.SupportAccountManager; +import com.seafile.seadroid2.enums.ActionModeCallbackType; import com.seafile.seadroid2.framework.data.db.entities.EncKeyCacheEntity; import com.seafile.seadroid2.framework.data.db.entities.FileTransferEntity; +import com.seafile.seadroid2.framework.data.db.entities.PermissionEntity; import com.seafile.seadroid2.framework.data.model.dirents.DirentFileModel; import com.seafile.seadroid2.enums.TransferAction; import com.seafile.seadroid2.enums.TransferDataSource; import com.seafile.seadroid2.enums.TransferResult; import com.seafile.seadroid2.enums.TransferStatus; +import com.seafile.seadroid2.framework.data.model.permission.PermissionListWrapperModel; +import com.seafile.seadroid2.framework.data.model.permission.PermissionWrapperModel; import com.seafile.seadroid2.framework.datastore.DataManager; import com.seafile.seadroid2.framework.util.Utils; import com.seafile.seadroid2.framework.worker.ExistingFileStrategy; @@ -50,13 +54,18 @@ import java.io.OutputStream; import java.nio.file.Files; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Optional; +import io.reactivex.Completable; import io.reactivex.Single; import io.reactivex.SingleEmitter; import io.reactivex.SingleOnSubscribe; +import io.reactivex.SingleSource; import io.reactivex.functions.Consumer; +import io.reactivex.functions.Function; +import kotlin.Pair; public class MainViewModel extends BaseViewModel { // private final MutableLiveData> OnNewFileDownloadLiveData = new MutableLiveData<>(); @@ -65,7 +74,6 @@ public class MainViewModel extends BaseViewModel { //force refresh repo/dirents private final MutableLiveData OnForceRefreshRepoListLiveData = new MutableLiveData<>(); - private final MutableLiveData OnForceRefreshStarredListLiveData = new MutableLiveData<>(); //show swipeRefresh in Repo Fragment private final MutableLiveData OnShowRefreshLoadingInRepoLiveData = new MutableLiveData<>(); @@ -74,6 +82,11 @@ public class MainViewModel extends BaseViewModel { private final MutableLiveData OnNavChangeListenerLiveData = new MutableLiveData<>(); private final MutableLiveData _searchViewExpandedLiveData = new MutableLiveData<>(false); + private final MutableLiveData _onActionModeLiveData = new MutableLiveData<>(); + + public MutableLiveData getOnActionModeLiveData() { + return _onActionModeLiveData; + } public MutableLiveData getSearchViewExpandedLiveData() { return _searchViewExpandedLiveData; @@ -108,10 +121,6 @@ public MutableLiveData getOnNavContextChangeListenerLiveData() { return OnNavChangeListenerLiveData; } - public MutableLiveData getOnForceRefreshStarredListLiveData() { - return OnForceRefreshStarredListLiveData; - } - public MutableLiveData getServerInfoLiveData() { return _serverInfoLiveData; } @@ -173,7 +182,7 @@ public void accept(List repoModels) throws Exception { if (consumer != null) { if (CollectionUtils.isEmpty(repoModels)) { //no data in sqlite, request RepoApi again - requestRepoModelFromServer(repoId, consumer); + getRepoModelFromRemote(repoId, consumer); } else { consumer.accept(repoModels.get(0)); getOnShowRefreshLoadingInRepoLiveData().setValue(false); @@ -191,7 +200,7 @@ public void accept(Throwable throwable) throws Exception { }); } - private void requestRepoModelFromServer(String repoId, Consumer consumer) { + private void getRepoModelFromRemote(String repoId, Consumer consumer) { //from net Single singleNet = HttpIO.getCurrentInstance().execute(RepoService.class).getRepos(); addSingleDisposable(singleNet, new Consumer() { @@ -226,6 +235,129 @@ public void accept(Throwable throwable) throws Exception { }); } + public void getPermissionFromLocal(String repoId, int pNum, Consumer consumer) { + Single> pSingle = AppDatabase.getInstance().permissionDAO().getWithAsync(repoId, pNum); + Single s = pSingle.flatMap(new Function, SingleSource>() { + @Override + public SingleSource apply(List pList) throws Exception { + + if (CollectionUtils.isEmpty(pList)) { + return null; + } + + return Single.just(pList.get(0)); + } + }).flatMap(new Function>() { + @Override + public SingleSource apply(PermissionEntity entity) throws Exception { + Single> r = getLoadRepoPermissionFromRemoteSingle(repoId); + + return r.flatMap(new Function, SingleSource>() { + @Override + public SingleSource apply(List permissionEntities) throws Exception { + if (CollectionUtils.isEmpty(permissionEntities)) { + return null; + + } + Optional p = permissionEntities.stream().filter(f -> f.id == pNum).findFirst(); + if (p.isPresent()) { + return Single.just(p.get()); + } + return null; + } + }); + } + }); + + addSingleDisposable(s, new Consumer() { + @Override + public void accept(PermissionEntity entity) throws Exception { + if (consumer != null) { + consumer.accept(entity); + } + } + }); + } + + + private Single> getLoadRepoPermissionFromRemoteSingle(String repoId) { + Single single = HttpIO.getCurrentInstance().execute(RepoService.class).getCustomSharePermissions(repoId); + return single.flatMap(new Function>>() { + @Override + public SingleSource> apply(PermissionListWrapperModel wrapperModel) throws Exception { + + List list = CollectionUtils.newArrayList(); + + for (PermissionWrapperModel model : wrapperModel.permission_list) { + list.add(new PermissionEntity(repoId, model)); + } + + Completable insertCompletable = AppDatabase.getInstance().permissionDAO().insertAllAsync(list); + Single insertAllSingle = insertCompletable.toSingleDefault(0L); + return insertAllSingle.flatMap(new Function>>() { + @Override + public SingleSource> apply(Long aLong) throws Exception { + SLogs.d("The list has been inserted into the local database"); + return Single.just(list); + } + }); + } + }); + } + + + public void getRepoModelFromLocal(String repoId, Consumer> consumer) { + //from db + Single> dbSingle = AppDatabase.getInstance().repoDao().getRepoById(repoId); + Single> r = dbSingle.flatMap(new Function, SingleSource>>() { + @Override + public SingleSource> apply(List repoModels) throws Exception { + if (CollectionUtils.isEmpty(repoModels)) { + return null; + } + + RepoModel repoModel = repoModels.get(0); + if (TextUtils.isEmpty(repoModel.permission)) { + return Single.just(new Pair<>(repoModel, null)); + } + + if (!repoModel.isCustomPermission()) { + return Single.just(new Pair<>(repoModel, null)); + } + + int pNum = repoModel.getCustomPermissionNum(); + + Single> pSingle = AppDatabase.getInstance().permissionDAO().getWithAsync(repoId, pNum); + + return pSingle.flatMap(new Function, SingleSource>>() { + @Override + public SingleSource> apply(List permissionEntities) throws Exception { + if (CollectionUtils.isEmpty(permissionEntities)) { + return Single.just(new Pair<>(repoModel, null)); + } + + return Single.just(new Pair<>(repoModel, permissionEntities.get(0))); + } + }); + } + }); + + + addSingleDisposable(r, new Consumer>() { + @Override + public void accept(Pair pair) throws Exception { + if (consumer != null) { + consumer.accept(pair); + } + } + }, new Consumer() { + @Override + public void accept(Throwable throwable) throws Exception { + SLogs.e(throwable); + } + }); + } + public void getEncCacheDB(String repoId, Consumer consumer) { Single> single = AppDatabase.getInstance().encKeyCacheDAO().getListByRepoIdAsync(repoId); addSingleDisposable(single, new Consumer>() { diff --git a/app/src/main/java/com/seafile/seadroid2/ui/media/image_preview/ImagePreviewActivity.java b/app/src/main/java/com/seafile/seadroid2/ui/media/image_preview/ImagePreviewActivity.java index 48394b47b..46b08dad9 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/media/image_preview/ImagePreviewActivity.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/media/image_preview/ImagePreviewActivity.java @@ -1,43 +1,32 @@ package com.seafile.seadroid2.ui.media.image_preview; -import android.app.Dialog; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.view.View; -import android.view.WindowInsets; -import android.view.WindowInsetsController; import androidx.activity.OnBackPressedCallback; import androidx.annotation.Nullable; -import androidx.core.view.ViewCompat; -import androidx.core.view.WindowCompat; -import androidx.core.view.WindowInsetsCompat; -import androidx.core.view.WindowInsetsControllerCompat; import androidx.fragment.app.Fragment; import androidx.lifecycle.Observer; -import androidx.lifecycle.ViewModelProvider; import androidx.viewpager2.widget.ViewPager2; import com.blankj.utilcode.util.BarUtils; import com.blankj.utilcode.util.CollectionUtils; import com.blankj.utilcode.util.NetworkUtils; import com.blankj.utilcode.util.ToastUtils; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.seafile.seadroid2.R; -import com.seafile.seadroid2.framework.data.db.entities.DirentModel; import com.seafile.seadroid2.databinding.ActivityImagePreviewBinding; +import com.seafile.seadroid2.framework.data.db.entities.DirentModel; import com.seafile.seadroid2.framework.data.db.entities.RepoModel; +import com.seafile.seadroid2.framework.data.db.entities.StarredModel; import com.seafile.seadroid2.framework.data.model.activities.ActivityModel; import com.seafile.seadroid2.framework.data.model.search.SearchModel; -import com.seafile.seadroid2.framework.data.db.entities.StarredModel; -import com.seafile.seadroid2.ui.base.BaseActivity; +import com.seafile.seadroid2.framework.util.Objs; import com.seafile.seadroid2.ui.adapter.ViewPager2Adapter; import com.seafile.seadroid2.ui.base.BaseActivityWithVM; import com.seafile.seadroid2.ui.dialog_fragment.DeleteFileDialogFragment; import com.seafile.seadroid2.ui.dialog_fragment.listener.OnRefreshDataListener; -import com.seafile.seadroid2.framework.util.Objs; -import com.seafile.seadroid2.framework.util.Utils; import java.util.ArrayList; import java.util.List; @@ -261,10 +250,9 @@ private void deleteFile() { int position = binding.pager.getCurrentItem(); - DeleteFileDialogFragment dialogFragment = DeleteFileDialogFragment.newInstance(); - DirentModel direntModel = getSelectedDirent(); - dialogFragment.initData(direntModel); + + DeleteFileDialogFragment dialogFragment = DeleteFileDialogFragment.newInstance(CollectionUtils.newArrayList(direntModel.uid)); dialogFragment.setRefreshListener(new OnRefreshDataListener() { @Override public void onActionStatus(boolean isDone) { @@ -316,23 +304,5 @@ private void downloadFile() { } - private Dialog dialog; - private void showProgressDialog() { - if (dialog == null) { - MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this); - builder.setView(R.layout.layout_dialog_progress_bar); - dialog = builder.create(); - } - - if (!dialog.isShowing()) { - dialog.show(); - } - } - - private void dismissProgressDialog() { - if (dialog != null) { - dialog.dismiss(); - } - } } diff --git a/app/src/main/java/com/seafile/seadroid2/ui/media/image_preview/ImagePreviewViewModel.java b/app/src/main/java/com/seafile/seadroid2/ui/media/image_preview/ImagePreviewViewModel.java index c49eb4b84..79db9d4b4 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/media/image_preview/ImagePreviewViewModel.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/media/image_preview/ImagePreviewViewModel.java @@ -18,6 +18,7 @@ import com.seafile.seadroid2.ui.repo.RepoService; import com.seafile.seadroid2.framework.http.HttpIO; import com.seafile.seadroid2.ui.base.viewmodel.BaseViewModel; +import com.seafile.seadroid2.ui.star.StarredService; import java.util.HashMap; import java.util.List; @@ -111,7 +112,7 @@ public void star(String repoId, String path) { requestDataMap.put("path", path); Map bodyMap = generateRequestBody(requestDataMap); - Single single = HttpIO.getCurrentInstance().execute(RepoService.class).star(bodyMap); + Single single = HttpIO.getCurrentInstance().execute(StarredService.class).star(bodyMap); addSingleDisposable(single, new Consumer() { @Override public void accept(Dirent2Model resultModel) throws Exception { @@ -134,7 +135,7 @@ public void accept(Throwable throwable) throws Exception { public void unStar(String repoId, String path) { getRefreshLiveData().setValue(true); - Single single = HttpIO.getCurrentInstance().execute(RepoService.class).unStar(repoId, path); + Single single = HttpIO.getCurrentInstance().execute(StarredService.class).unStar(repoId, path); addSingleDisposable(single, new Consumer() { @Override public void accept(ResultModel resultModel) throws Exception { diff --git a/app/src/main/java/com/seafile/seadroid2/ui/repo/RepoQuickAdapter.java b/app/src/main/java/com/seafile/seadroid2/ui/repo/RepoQuickAdapter.java index 3b4af28af..ba3ce56f4 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/repo/RepoQuickAdapter.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/repo/RepoQuickAdapter.java @@ -1,7 +1,9 @@ package com.seafile.seadroid2.ui.repo; import android.content.Context; +import android.content.res.ColorStateList; import android.graphics.drawable.Drawable; +import android.os.Bundle; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; @@ -36,17 +38,16 @@ import com.seafile.seadroid2.framework.data.db.entities.RepoModel; import com.seafile.seadroid2.framework.data.model.BaseModel; import com.seafile.seadroid2.framework.data.model.GroupItemModel; +import com.seafile.seadroid2.framework.data.model.search.SearchModel; import com.seafile.seadroid2.framework.http.HttpIO; import com.seafile.seadroid2.framework.util.GlideApp; -import com.seafile.seadroid2.framework.util.GlideRequests; import com.seafile.seadroid2.framework.util.Utils; import com.seafile.seadroid2.ui.base.adapter.BaseMultiAdapter; import com.seafile.seadroid2.ui.viewholder.GroupItemViewHolder; import com.seafile.seadroid2.widget.AnimatedStateListDrawableCompatUtils; -import org.checkerframework.checker.units.qual.A; - import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.function.Predicate; @@ -55,7 +56,7 @@ public class RepoQuickAdapter extends BaseMultiAdapter { private final String SERVER = HttpIO.getCurrentInstance().getServerUrl(); - private boolean actionModeOn; + private boolean onActionMode; private boolean repoEncrypted = false; private FileViewType fileViewType = FileViewType.LIST; @@ -83,8 +84,8 @@ public void setSelectType(RepoSelectType selectType, int selectedMaxCount) { public Drawable getStarDrawable() { if (null == starDrawable) { - int DP_16 = SizeUtils.dp2px(16); - starDrawable = ContextCompat.getDrawable(getContext(), R.drawable.baseline_star_24); + int DP_16 = SizeUtils.dp2px(12); + starDrawable = ContextCompat.getDrawable(getContext(), R.drawable.ic_star_32); starDrawable.setBounds(0, 0, DP_16, DP_16); starDrawable.setTint(ContextCompat.getColor(getContext(), R.color.light_grey)); } @@ -139,7 +140,14 @@ public RepoViewHolder onCreate(@NonNull Context context, @NonNull ViewGroup view @Override public void onBind(@NonNull RepoViewHolder viewHolder, int i, @Nullable BaseModel baseModel) { - onBindRepos(viewHolder, (RepoModel) baseModel); + onBind(viewHolder, i, baseModel, Collections.emptyList()); + } + + @Override + public void onBind(@NonNull RepoViewHolder holder, int position, @Nullable BaseModel item, @NonNull List payloads) { + + onBindRepos(holder, (RepoModel) item, payloads); + } }).addItemType(AbsLayoutItemType.DIRENT_LIST, new OnMultiItem() { @NonNull @@ -151,7 +159,12 @@ public DirentViewHolder onCreate(@NonNull Context context, @NonNull ViewGroup vi @Override public void onBind(@NonNull DirentViewHolder viewHolder, int i, @Nullable BaseModel baseModel) { - onBindDirents(viewHolder, (DirentModel) baseModel); + onBind(viewHolder, i, baseModel, Collections.emptyList()); + } + + @Override + public void onBind(@NonNull DirentViewHolder holder, int position, @Nullable BaseModel item, @NonNull List payloads) { + onBindDirents(holder, (DirentModel) item, payloads); } }).addItemType(AbsLayoutItemType.DIRENT_GRID, new OnMultiItem() { @NonNull @@ -163,7 +176,12 @@ public DirentGridViewHolder onCreate(@NonNull Context context, @NonNull ViewGrou @Override public void onBind(@NonNull DirentGridViewHolder viewHolder, int i, @Nullable BaseModel baseModel) { - onBindDirentsGrid(viewHolder, (DirentModel) baseModel); + onBind(viewHolder, i, baseModel, Collections.emptyList()); + } + + @Override + public void onBind(@NonNull DirentGridViewHolder holder, int position, @Nullable BaseModel item, @NonNull List payloads) { + onBindDirentsGrid(holder, (DirentModel) item, payloads); } }).addItemType(AbsLayoutItemType.DIRENT_GALLERY, new OnMultiItem() { @NonNull @@ -175,7 +193,25 @@ public DirentGalleryViewHolder onCreate(@NonNull Context context, @NonNull ViewG @Override public void onBind(@NonNull DirentGalleryViewHolder viewHolder, int i, @Nullable BaseModel baseModel) { - onBindDirentsGallery(viewHolder, (DirentModel) baseModel); + onBind(viewHolder, i, baseModel, Collections.emptyList()); + } + + @Override + public void onBind(@NonNull DirentGalleryViewHolder holder, int position, @Nullable BaseModel item, @NonNull List payloads) { + onBindDirentsGallery(holder, (DirentModel) item, payloads); + + } + }).addItemType(AbsLayoutItemType.SEARCH, new OnMultiItem() { + @NonNull + @Override + public DirentViewHolder onCreate(@NonNull Context context, @NonNull ViewGroup viewGroup, int i) { + ItemDirentBinding binding = ItemDirentBinding.inflate(LayoutInflater.from(context), viewGroup, false); + return new DirentViewHolder(binding); + } + + @Override + public void onBind(@NonNull DirentViewHolder viewHolder, int i, @Nullable BaseModel baseModel) { + onBindSearch(viewHolder, (SearchModel) baseModel); } }).addItemType(AbsLayoutItemType.NOT_SUPPORTED, new OnMultiItem() { @NonNull @@ -186,7 +222,13 @@ public UnsupportedViewHolder onCreate(@NonNull Context context, @NonNull ViewGro } @Override - public void onBind(@NonNull UnsupportedViewHolder viewHolder, int i, @Nullable BaseModel baseModel) { + public void onBind(@NonNull UnsupportedViewHolder unsupportedViewHolder, int i, @Nullable BaseModel baseModel) { + + } + + @Override + public void onBind(@NonNull UnsupportedViewHolder holder, int position, @Nullable BaseModel item, @NonNull List payloads) { + super.onBind(holder, position, item, payloads); } }).onItemViewType(new OnItemViewTypeListener() { @Override @@ -203,6 +245,8 @@ public int onItemViewType(int i, @NonNull List list) { } else { return AbsLayoutItemType.DIRENT_GALLERY; } + } else if (list.get(i) instanceof SearchModel) { + return AbsLayoutItemType.SEARCH; } else if (list.get(i) instanceof Account) { return AbsLayoutItemType.ACCOUNT; } @@ -212,7 +256,7 @@ public int onItemViewType(int i, @NonNull List list) { } private void onBindAccount(AccountViewHolder holder, BaseModel model) { - holder.binding.getRoot().setBackground(null); +// holder.binding.getRoot().setBackground(null); Account account = (Account) model; @@ -256,19 +300,42 @@ private void onBindGroup(int position, GroupItemViewHolder holder, GroupItemMode // holder.binding.listSeparatorItemActionText.setRotation(model.is_checked ? 90 : 270); } - private void onBindRepos(RepoViewHolder holder, RepoModel model) { + private void onBindRepos(RepoViewHolder holder, RepoModel model, @NonNull List payloads) { + if (!CollectionUtils.isEmpty(payloads)) { + Bundle bundle = (Bundle) payloads.get(0); + boolean isChecked = bundle.getBoolean("is_check"); + +// holder.binding.getRoot().setChecked(model.is_checked); + + if (isChecked) { + holder.binding.itemMultiSelect.setImageResource(R.drawable.ic_checkbox_checked); + } else { + holder.binding.itemMultiSelect.setImageResource(R.drawable.ic_checkbox_unchecked); + } + return; + } + holder.binding.itemTitle.setText(model.repo_name); holder.binding.itemSubtitle.setText(model.getSubtitle()); holder.binding.itemIcon.setImageResource(model.getIcon()); +// holder.binding.getRoot().setBackground(AnimatedStateListDrawableCompatUtils.createDrawableCompat(getContext())); + + if (selectType.ordinal() == RepoSelectType.ONLY_REPO.ordinal() || onActionMode) { +// holder.binding.getRoot().setChecked(model.is_checked); - if (selectType.ordinal() >= RepoSelectType.ONLY_REPO.ordinal()) { - holder.binding.itemSelectView.setVisibility(model.is_checked ? View.VISIBLE : View.INVISIBLE); - holder.binding.expandableToggleButton.setVisibility(View.INVISIBLE); + holder.binding.itemMultiSelect.setVisibility(View.VISIBLE); + if (model.is_checked) { + holder.binding.itemMultiSelect.setImageResource(R.drawable.ic_checkbox_checked); + } else { + holder.binding.itemMultiSelect.setImageResource(R.drawable.ic_checkbox_unchecked); + } } else { - holder.binding.expandableToggleButton.setVisibility(View.VISIBLE); - holder.binding.itemSelectView.setVisibility(View.GONE); + holder.binding.itemMultiSelect.setVisibility(View.GONE); +// holder.binding.getRoot().setChecked(false); } + holder.binding.expandableToggleButton.setVisibility(View.GONE); + holder.binding.itemTitle.setCompoundDrawablePadding(Constants.DP.DP_4); if (model.starred) { holder.binding.itemTitle.setCompoundDrawables(null, null, getStarDrawable(), null); @@ -277,11 +344,25 @@ private void onBindRepos(RepoViewHolder holder, RepoModel model) { } } - private void onBindDirents(DirentViewHolder holder, DirentModel model) { + private void onBindDirents(DirentViewHolder holder, DirentModel model, @NonNull List payloads) { + if (!CollectionUtils.isEmpty(payloads)) { + Bundle bundle = (Bundle) payloads.get(0); + boolean isChecked = bundle.getBoolean("is_check"); + +// holder.binding.getRoot().setChecked(model.is_checked); + + if (isChecked) { + holder.binding.itemMultiSelect.setImageResource(R.drawable.ic_checkbox_checked); + } else { + holder.binding.itemMultiSelect.setImageResource(R.drawable.ic_checkbox_unchecked); + } + return; + } + holder.binding.itemTitle.setText(model.name); holder.binding.itemSubtitle.setText(model.getSubtitle()); - holder.binding.getRoot().setBackground(AnimatedStateListDrawableCompatUtils.createDrawableCompat(getContext())); +// holder.binding.getRoot().setBackground(AnimatedStateListDrawableCompatUtils.createDrawableCompat(getContext())); if (repoEncrypted || !Utils.isViewableImage(model.name)) { holder.binding.itemIcon.setImageResource(model.getIcon()); @@ -290,22 +371,20 @@ private void onBindDirents(DirentViewHolder holder, DirentModel model) { } //action mode - if (actionModeOn) { - holder.binding.itemMultiSelect.setVisibility(View.VISIBLE); - - holder.binding.getRoot().setChecked(model.is_checked); + if (onActionMode) { +// holder.binding.getRoot().setChecked(model.is_checked); + holder.binding.itemMultiSelect.setVisibility(View.VISIBLE); if (model.is_checked) { - holder.binding.itemMultiSelect.setImageResource(R.drawable.multi_select_item_checked); + holder.binding.itemMultiSelect.setImageResource(R.drawable.ic_checkbox_checked); } else { - holder.binding.itemMultiSelect.setImageResource(R.drawable.multi_select_item_unchecked); + holder.binding.itemMultiSelect.setImageResource(R.drawable.ic_checkbox_unchecked); } } else { holder.binding.itemMultiSelect.setVisibility(View.GONE); - holder.binding.itemMultiSelect.setImageResource(R.drawable.multi_select_item_unchecked); - - holder.binding.getRoot().setChecked(false); + holder.binding.itemMultiSelect.setImageResource(R.drawable.ic_checkbox_unchecked); +// holder.binding.getRoot().setChecked(false); } holder.binding.itemDownloadStatusProgressbar.setVisibility(View.GONE); @@ -314,8 +393,11 @@ private void onBindDirents(DirentViewHolder holder, DirentModel model) { if (selectType.ordinal() < RepoSelectType.ONLY_ACCOUNT.ordinal()) { holder.binding.itemTitle.setTextColor(ContextCompat.getColor(getContext(), R.color.item_title_color)); holder.binding.itemSubtitle.setTextColor(ContextCompat.getColor(getContext(), R.color.item_subtitle_color)); - - holder.binding.expandableToggleButton.setVisibility(View.VISIBLE); +// if (onActionMode) { +// holder.binding.expandableToggleButton.setVisibility(View.GONE); +// } else { +// holder.binding.expandableToggleButton.setVisibility(View.VISIBLE); +// } } else { if (!model.isDir()) { @@ -326,8 +408,9 @@ private void onBindDirents(DirentViewHolder holder, DirentModel model) { holder.binding.itemSubtitle.setTextColor(ContextCompat.getColor(getContext(), R.color.item_subtitle_color)); } - holder.binding.expandableToggleButton.setVisibility(View.INVISIBLE); +// holder.binding.expandableToggleButton.setVisibility(View.INVISIBLE); } + holder.binding.expandableToggleButton.setVisibility(View.GONE); if (model.isDir()) { holder.binding.itemDownloadStatusProgressbar.setVisibility(View.GONE); @@ -360,10 +443,24 @@ private void onBindDirents(DirentViewHolder holder, DirentModel model) { } } - private void onBindDirentsGrid(DirentGridViewHolder holder, DirentModel model) { + private void onBindDirentsGrid(DirentGridViewHolder holder, DirentModel model, @NonNull List payloads) { + if (!CollectionUtils.isEmpty(payloads)) { + Bundle bundle = (Bundle) payloads.get(0); + boolean isChecked = bundle.getBoolean("is_check"); + +// holder.binding.getRoot().setChecked(model.is_checked); + + if (isChecked) { + holder.binding.itemMultiSelect.setImageResource(R.drawable.ic_checkbox_checked); + } else { + holder.binding.itemMultiSelect.setImageResource(R.drawable.ic_checkbox_unchecked); + } + return; + } + holder.binding.itemTitle.setText(model.name); - holder.binding.getRoot().setBackground(AnimatedStateListDrawableCompatUtils.createDrawableCompat(getContext())); +// holder.binding.getRoot().setBackground(AnimatedStateListDrawableCompatUtils.createDrawableCompat(getContext())); if (model.isDir()) { holder.binding.itemOutline.setVisibility(View.GONE); @@ -380,20 +477,20 @@ private void onBindDirentsGrid(DirentGridViewHolder holder, DirentModel model) { } //action mode - if (actionModeOn) { + if (onActionMode) { holder.binding.itemMultiSelect.setVisibility(View.VISIBLE); - holder.binding.getRoot().setChecked(model.is_checked); +// holder.binding.getRoot().setChecked(model.is_checked); if (model.is_checked) { - holder.binding.itemMultiSelect.setImageResource(R.drawable.multi_select_item_checked); + holder.binding.itemMultiSelect.setImageResource(R.drawable.ic_checkbox_checked); } else { - holder.binding.itemMultiSelect.setImageResource(R.drawable.multi_select_item_unchecked); + holder.binding.itemMultiSelect.setImageResource(R.drawable.ic_checkbox_unchecked); } } else { holder.binding.itemMultiSelect.setVisibility(View.GONE); - holder.binding.itemMultiSelect.setImageResource(R.drawable.multi_select_item_unchecked); + holder.binding.itemMultiSelect.setImageResource(R.drawable.ic_checkbox_unchecked); - holder.binding.getRoot().setChecked(false); +// holder.binding.getRoot().setChecked(false); } if (model.starred) { @@ -403,10 +500,21 @@ private void onBindDirentsGrid(DirentGridViewHolder holder, DirentModel model) { } } - private void onBindDirentsGallery(DirentGalleryViewHolder holder, DirentModel model) { -// holder.binding.itemTitle.setText(model.name); + private void onBindDirentsGallery(DirentGalleryViewHolder holder, DirentModel model, @NonNull List payloads) { + if (!CollectionUtils.isEmpty(payloads)) { + Bundle bundle = (Bundle) payloads.get(0); + boolean isChecked = bundle.getBoolean("is_check"); + +// holder.binding.getRoot().setChecked(model.is_checked); - holder.binding.getRoot().setBackground(AnimatedStateListDrawableCompatUtils.createDrawableCompat(getContext())); + if (isChecked) { + holder.binding.itemMultiSelect.setImageResource(R.drawable.ic_checkbox_checked); + } else { + holder.binding.itemMultiSelect.setImageResource(R.drawable.ic_checkbox_unchecked); + } + return; + } +// holder.binding.getRoot().setBackground(AnimatedStateListDrawableCompatUtils.createDrawableCompat(getContext())); if (repoEncrypted || !Utils.isViewableImage(model.name)) { holder.binding.itemIcon.setImageResource(model.getIcon()); @@ -415,23 +523,47 @@ private void onBindDirentsGallery(DirentGalleryViewHolder holder, DirentModel mo } //action mode - if (actionModeOn) { + if (onActionMode) { holder.binding.itemMultiSelect.setVisibility(View.VISIBLE); - holder.binding.getRoot().setChecked(model.is_checked); +// holder.binding.getRoot().setChecked(model.is_checked); if (model.is_checked) { - holder.binding.itemMultiSelect.setImageResource(R.drawable.multi_select_item_checked); + holder.binding.itemMultiSelect.setImageResource(R.drawable.ic_checkbox_checked); } else { - holder.binding.itemMultiSelect.setImageResource(R.drawable.multi_select_item_unchecked); + holder.binding.itemMultiSelect.setImageResource(R.drawable.ic_checkbox_unchecked); } } else { - holder.binding.getRoot().setChecked(false); +// holder.binding.getRoot().setChecked(false); holder.binding.itemMultiSelect.setVisibility(View.GONE); - holder.binding.itemMultiSelect.setImageResource(R.drawable.multi_select_item_unchecked); + holder.binding.itemMultiSelect.setImageResource(R.drawable.ic_checkbox_unchecked); } } + private void onBindSearch(DirentViewHolder holder, SearchModel model) { + holder.binding.itemTitle.setText(model.name); + holder.binding.itemSubtitle.setText(model.getSubtitle()); + +// holder.binding.getRoot().setBackground(AnimatedStateListDrawableCompatUtils.createDrawableCompat(getContext())); + + if (repoEncrypted || !Utils.isViewableImage(model.name)) { + holder.binding.itemIcon.setImageResource(model.getIcon()); + } else { + DirentModel direntModel = new DirentModel(); + direntModel.full_path = model.fullpath; + direntModel.repo_id = model.repo_id; + loadImage(direntModel, holder.binding.itemIcon); + } + + holder.binding.expandableToggleButton.setVisibility(View.GONE); + holder.binding.itemMultiSelect.setVisibility(View.GONE); + holder.binding.itemDownloadStatusProgressbar.setVisibility(View.GONE); + holder.binding.itemDownloadStatus.setVisibility(View.GONE); + + holder.binding.itemTitle.setCompoundDrawables(null, null, null, null); + + } + private void loadImage(DirentModel direntModel, ImageView imageView) { if (direntModel.name.toLowerCase().endsWith(".gif")) { @@ -459,41 +591,41 @@ private String convertThumbnailUrl(DirentModel direntModel, int size) { return String.format(Locale.ROOT, "%sapi2/repos/%s/thumbnail/?p=%s&size=%d", SERVER, direntModel.repo_id, newFilePath, size); } - public void setActionModeOn(boolean actionModeOn) { - this.actionModeOn = actionModeOn; + public void setOnActionMode(boolean on) { + this.onActionMode = on; - if (!actionModeOn) { + if (!on) { setItemSelected(false); } notifyItemRangeChanged(0, getItemCount()); } - public boolean getActionMode() { - return actionModeOn; + public boolean isOnActionMode() { + return onActionMode; } public void setItemSelected(boolean itemSelected) { for (BaseModel item : getItems()) { - if (item instanceof DirentModel) { - DirentModel model = (DirentModel) item; - model.is_checked = itemSelected; + + if (item instanceof GroupItemModel) { + continue; + } else if (item instanceof Account) { + continue; + } else if (item instanceof SearchModel) { + continue; } + + item.is_checked = itemSelected; } - notifyItemRangeChanged(0, getItemCount()); + Bundle bundle = new Bundle(); + bundle.putBoolean("is_check", itemSelected); + notifyItemRangeChanged(0, getItemCount(), bundle); } - public List getSelectedList() { - List list = new ArrayList<>(); - for (BaseModel item : getItems()) { - if (item instanceof DirentModel model) { - if (model.is_checked) { - list.add(model); - } - } - } - return list; + public List getSelectedList() { + return getItems().stream().filter(f -> f.is_checked).collect(Collectors.toList()); } /** @@ -560,18 +692,16 @@ private int getSelectedPositionByMode() { return -1; } - public void notifySearchChanged(String searchContent) { + public void filterListBySearchKeyword(String searchContent) { this.searchContent = searchContent; if (CollectionUtils.isEmpty(finalList)) { - submitList(finalList); return; } List filterList; - Predicate predicate = getSearchFilter(); - if (predicate != null) { - filterList = finalList.stream().filter(predicate).collect(Collectors.toList()); + if (!TextUtils.isEmpty(searchContent)) { + filterList = finalList.stream().filter(_searchFilter).collect(Collectors.toList()); } else { filterList = finalList; } @@ -639,6 +769,12 @@ public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) { return TextUtils.equals(newT.full_path, oldT.full_path); } + if (getItems().get(oldItemPosition) instanceof SearchModel) { + SearchModel newT = (SearchModel) getItems().get(oldItemPosition); + SearchModel oldT = (SearchModel) newList.get(newItemPosition); + return TextUtils.equals(newT.fullpath, oldT.fullpath); + } + return true; } @@ -685,6 +821,24 @@ public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) { && TextUtils.equals(newT.server, oldT.server); } + if (getItems().get(oldItemPosition) instanceof SearchModel) { + SearchModel newT = (SearchModel) getItems().get(oldItemPosition); + SearchModel oldT = (SearchModel) newList.get(newItemPosition); + return TextUtils.equals(newT.fullpath, oldT.fullpath) + && TextUtils.equals(newT.name, oldT.name) + && newT.is_dir == oldT.is_dir + && newT.size == oldT.size + && newT.last_modified == oldT.last_modified + && TextUtils.equals(newT.repo_id, oldT.repo_id) + && TextUtils.equals(newT.repo_name, oldT.repo_name) + && TextUtils.equals(newT.repo_owner_email, oldT.repo_owner_email) + && TextUtils.equals(newT.repo_owner_name, oldT.repo_owner_name) + && TextUtils.equals(newT.repo_owner_contact_email, oldT.repo_owner_contact_email) + && TextUtils.equals(newT.thumbnail_url, oldT.thumbnail_url) + && TextUtils.equals(newT.repo_type, oldT.repo_type) + && TextUtils.equals(newT.content_highlight, oldT.content_highlight); + } + if (getItems().get(oldItemPosition) instanceof DirentModel) { DirentModel newT = (DirentModel) getItems().get(oldItemPosition); DirentModel oldT = (DirentModel) newList.get(newItemPosition); @@ -725,13 +879,6 @@ public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) { diffResult.dispatchUpdatesTo(this); } - public Predicate getSearchFilter() { - if (TextUtils.isEmpty(searchContent)) { - return null; - } - return _searchFilter; - } - private String searchContent; private final Predicate _searchFilter = new Predicate<>() { @Override diff --git a/app/src/main/java/com/seafile/seadroid2/ui/repo/RepoQuickFragment.java b/app/src/main/java/com/seafile/seadroid2/ui/repo/RepoQuickFragment.java index f8caa48f6..33fb7f094 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/repo/RepoQuickFragment.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/repo/RepoQuickFragment.java @@ -6,12 +6,14 @@ import android.content.Intent; import android.os.Bundle; import android.text.TextUtils; +import android.view.Gravity; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.widget.FrameLayout; import android.widget.TextView; import androidx.activity.result.ActivityResult; @@ -27,12 +29,14 @@ import androidx.lifecycle.ViewModelProvider; import androidx.media3.common.util.UnstableApi; import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; import androidx.work.Data; import androidx.work.WorkInfo; import com.blankj.utilcode.util.CollectionUtils; import com.blankj.utilcode.util.TimeUtils; import com.blankj.utilcode.util.ToastUtils; +import com.chad.library.adapter4.BaseQuickAdapter; import com.github.panpf.recycler.sticky.StickyItemDecoration; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.common.collect.Maps; @@ -40,8 +44,10 @@ import com.seafile.seadroid2.SeafException; import com.seafile.seadroid2.account.Account; import com.seafile.seadroid2.account.SupportAccountManager; -import com.seafile.seadroid2.bottomsheetmenu.BottomSheetHelper; -import com.seafile.seadroid2.bottomsheetmenu.BottomSheetMenuFragment; +import com.seafile.seadroid2.enums.ActionModeCallbackType; +import com.seafile.seadroid2.framework.data.model.repo.RepoPermissionWrapper; +import com.seafile.seadroid2.framework.datastore.sp.SettingsManager; +import com.seafile.seadroid2.ui.bottomsheetmenu.BottomSheetMenuAdapter; import com.seafile.seadroid2.config.AbsLayoutItemType; import com.seafile.seadroid2.config.Constants; import com.seafile.seadroid2.context.CopyMoveContext; @@ -56,6 +62,7 @@ import com.seafile.seadroid2.framework.data.db.entities.RepoModel; import com.seafile.seadroid2.framework.data.model.BaseModel; import com.seafile.seadroid2.framework.data.model.GroupItemModel; +import com.seafile.seadroid2.framework.data.model.search.SearchModel; import com.seafile.seadroid2.framework.datastore.DataManager; import com.seafile.seadroid2.framework.util.Objs; import com.seafile.seadroid2.framework.util.SLogs; @@ -78,18 +85,23 @@ import com.seafile.seadroid2.ui.dialog_fragment.listener.OnRefreshDataListener; import com.seafile.seadroid2.ui.dialog_fragment.listener.OnResultListener; import com.seafile.seadroid2.ui.file.FileActivity; +import com.seafile.seadroid2.ui.main.MainActivity; import com.seafile.seadroid2.ui.main.MainViewModel; import com.seafile.seadroid2.ui.markdown.MarkdownActivity; import com.seafile.seadroid2.ui.media.image_preview.ImagePreviewActivity; import com.seafile.seadroid2.ui.media.player.exoplayer.CustomExoVideoPlayerActivity; import com.seafile.seadroid2.ui.sdoc.SDocWebViewActivity; +import com.seafile.seadroid2.ui.search.SearchViewModel; import com.seafile.seadroid2.ui.selector.ObjSelectorActivity; import com.seafile.seadroid2.view.TipsViews; import java.io.File; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; import io.reactivex.functions.Consumer; @@ -100,11 +112,14 @@ public class RepoQuickFragment extends BaseFragmentWithVM { private final int forceRefreshInterval = 1000 * 60 * 5;//5m private final HashMap mRefreshStatusExpireTimeMap = new HashMap<>(); + private final HashMap mPermissionRefreshStatusExpireTimeMap = new HashMap<>(); private LayoutFastRvBinding binding; private RepoQuickAdapter adapter; private MainViewModel mainViewModel; + private SearchViewModel searchViewModel; + private final Map scrollPositions = Maps.newHashMap(); private AppCompatActivity activity; private ActionMode actionMode; @@ -131,6 +146,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); mainViewModel = new ViewModelProvider(requireActivity()).get(MainViewModel.class); + searchViewModel = new ViewModelProvider(this).get(SearchViewModel.class); } @Override @@ -226,18 +242,34 @@ private void initAdapter() { adapter.setFileViewType(lastViewType); adapter.setOnItemClickListener((baseQuickAdapter, view, i) -> { - if (adapter.getActionMode()) { + if (adapter.isOnActionMode()) { //toggle - toggleAdapterItemSelectedOnLongClick(i); + toggleAdapterItemSelectedState(i); //update bar title - updateContextualActionBar(); + startOrUpdateContextualActionBar(); + + BaseModel baseModel = adapter.getItems().get(i); + List selected = adapter.getSelectedList(); + if (baseModel instanceof RepoModel m) { + if (CollectionUtils.isEmpty(selected)) { + getViewModel().inflateRepoMenu(requireContext()); + } else { + getViewModel().inflateRepoMenuWithParams(requireContext(), m, getDisableMenuIds(), getWillBeRemovedMenuIds(), isPermissionForce(m.repo_id)); + } + } else if (baseModel instanceof DirentModel m) { + if (CollectionUtils.isEmpty(selected)) { + getViewModel().inflateDirentMenu(requireContext()); + } else { + getViewModel().inflateDirentMenuWithParams(requireContext(), CollectionUtils.newArrayList(m), m.is_checked, getDisableMenuIds(), getWillBeRemovedMenuIds(), isPermissionForce(m.repo_id)); + } + } + return; } BaseModel baseModel = adapter.getItems().get(i); - if (baseModel instanceof RepoModel) { - RepoModel repoModel = (RepoModel) baseModel; + if (baseModel instanceof RepoModel repoModel) { if (repoModel.encrypted) { decrypt(repoModel); } else { @@ -245,66 +277,31 @@ private void initAdapter() { } } else if (baseModel instanceof DirentModel) { navTo(baseModel); + } else if (baseModel instanceof SearchModel) { + navTo(baseModel); } }); adapter.setOnItemLongClickListener((baseQuickAdapter, view, i) -> { - if (getNavContext().inRepo()) { - - //return - if (adapter.getActionMode()) { - return true; - } - - //start action mode - startContextualActionMode(); - - //toggle - toggleAdapterItemSelectedOnLongClick(i); - - //It's actually updating the title of the ActionBar - updateContextualActionBar(); - + //return + if (adapter.isOnActionMode()) { return true; - } else { - return false; } - }); -// adapter.addOnItemChildClickListener(R.id.group_container, new BaseQuickAdapter.OnItemChildClickListener() { -// @Override -// public void onItemClick(@NonNull BaseQuickAdapter baseQuickAdapter, @NonNull View view, int i) { -// GroupItemModel groupItemModel = (GroupItemModel) adapter.getItems().get(i); -// groupItemModel.is_checked = !groupItemModel.is_checked; -// Bundle bundle = new Bundle(); -// bundle.putBoolean("is_checked", groupItemModel.is_checked); -// adapter.notifyItemChanged(i, bundle); -// } -// }); + adapter.setOnActionMode(true); - adapter.addOnItemChildClickListener(R.id.expandable_toggle_button, (baseQuickAdapter, view, i) -> { + //toggle this item + toggleAdapterItemSelectedState(i); - //when ActionMode is On, return - if (adapter.getActionMode()) { - return; - } + startOrUpdateContextualActionBar(); - //open bottom sheet dialog - if (getNavContext().inRepo()) { - DirentModel direntModel = (DirentModel) adapter.getItems().get(i); - if (direntModel.isDir()) { - showDirNewBottomSheet(direntModel); - } else { - showFileBottomSheet(direntModel); - } - } else { - showRepoBottomSheet((RepoModel) adapter.getItems().get(i)); - } + return true; }); binding.rv.setAdapter(adapter); } + private void initViewModel() { getViewModel().getRefreshLiveData().observe(getViewLifecycleOwner(), new Observer() { @Override @@ -313,17 +310,30 @@ public void onChanged(Boolean aBoolean) { } }); + getViewModel().getShowLoadingDialogLiveData().observe(getViewLifecycleOwner(), new Observer() { + @Override + public void onChanged(Boolean aBoolean) { + + MainActivity mainActivity = (MainActivity) getActivity(); + if (mainActivity != null) { + mainActivity.showProgressDialog(aBoolean); + } + } + }); + getViewModel().getSeafExceptionLiveData().observe(getViewLifecycleOwner(), this::showErrorView); - getViewModel().getStarLiveData().observe(getViewLifecycleOwner(), aBoolean -> { + getViewModel().getStarredLiveData().observe(getViewLifecycleOwner(), aBoolean -> { if (aBoolean) { loadData(true); } - mainViewModel.getOnForceRefreshStarredListLiveData().setValue(true); + closeActionMode(); + + SettingsManager.setForceRefreshStarredListState(true); }); - getViewModel().getObjsListLiveData().observe(getViewLifecycleOwner(), repoModels -> { + getViewModel().getObjListLiveData().observe(getViewLifecycleOwner(), repoModels -> { //notify navContext changed mainViewModel.getOnNavContextChangeListenerLiveData().setValue(true); @@ -333,8 +343,15 @@ public void onChanged(Boolean aBoolean) { restoreScrollPosition(); }); + getViewModel().getMenuItemListLiveData().observe(getViewLifecycleOwner(), new Observer>() { + @Override + public void onChanged(List menuItems) { + showBottomSheetWindow(menuItems); + } + }); + + mainViewModel.getOnResortListLiveData().observe(getViewLifecycleOwner(), a -> { - SLogs.d("resort: " + a); loadData(); }); @@ -345,7 +362,20 @@ public void onChanged(Boolean aBoolean) { mainViewModel.getOnSearchLiveData().observe(getViewLifecycleOwner(), new Observer() { @Override public void onChanged(String s) { - adapter.notifySearchChanged(s); + search(s); + } + }); + + mainViewModel.getOnActionModeLiveData().observe(getViewLifecycleOwner(), new Observer() { + @Override + public void onChanged(ActionModeCallbackType callbackType) { + onShowActionMode(callbackType); + } + }); + searchViewModel.getSearchListLiveData().observe(getViewLifecycleOwner(), new Observer>() { + @Override + public void onChanged(List searchModels) { + deduplicateSearchData(searchModels); } }); @@ -378,6 +408,271 @@ public void onChanged(Boolean aBoolean) { }); } + + @Override + public void onPause() { + super.onPause(); + + //close search view + } + + private View floatingView; + private BottomSheetMenuAdapter bottomSheetMenuAdapter; + + private List getDisableMenuIds() { + List selectedList = adapter.getSelectedList(); + if (selectedList == null || selectedList.isEmpty()) { + return null; + } + + if (selectedList.size() == 1) { + BaseModel baseModel = selectedList.get(0); + if (baseModel instanceof RepoModel m) { + + } else if (baseModel instanceof DirentModel m) { + if (m.isDir()){ + return CollectionUtils.newArrayList(R.id.upload); + } + } + + return null; + } + + long selectedRepoModelCount = selectedList.stream().filter(f -> f instanceof RepoModel).count(); + long selectedFolderCount = selectedList.stream() + .filter(f -> f instanceof DirentModel) + .map(m -> (DirentModel) m) + .filter(p -> p.isDir()) + .count(); + + if (selectedRepoModelCount > 0) { + return CollectionUtils.newArrayList(R.id.share, R.id.export, R.id.open, R.id.rename, R.id.upload, R.id.delete); + } else if (selectedFolderCount > 0) { + return CollectionUtils.newArrayList(R.id.share, R.id.export, R.id.open, R.id.rename, R.id.upload); + } else { + return CollectionUtils.newArrayList(R.id.share, R.id.export, R.id.open, R.id.rename); + } + } + + private List getWillBeRemovedMenuIds() { + List selectedList = adapter.getSelectedList(); + + if (CollectionUtils.isEmpty(selectedList)) { + return CollectionUtils.newArrayList(R.id.unstar); + } + + if (selectedList.size() == 1) { + + BaseModel baseModel = selectedList.get(0); + if (baseModel instanceof RepoModel m) { + return CollectionUtils.newArrayList(m.starred ? R.id.star : R.id.unstar); + } else if (baseModel instanceof DirentModel m) { + return CollectionUtils.newArrayList(m.starred ? R.id.star : R.id.unstar); + } + + //remove all starred menu + return CollectionUtils.newArrayList(R.id.star, R.id.unstar); + } + + boolean isAllStarred = true; + for (BaseModel baseModel : selectedList) { + if (baseModel instanceof RepoModel m) { + if (m.starred) { + continue; + } + isAllStarred = false; + break; + } else if (baseModel instanceof DirentModel m) { + if (m.starred) { + continue; + } + isAllStarred = false; + break; + } + } + + if (isAllStarred) { + return CollectionUtils.newArrayList(R.id.star); + } else { + return CollectionUtils.newArrayList(R.id.unstar); + } + } + + private void showBottomSheetWindow(List localMenuItems) { + if (CollectionUtils.isEmpty(localMenuItems)) { + removeFloatingView(); + return; + } + + if (floatingView != null && floatingView.isAttachedToWindow()) { + bottomSheetMenuAdapter.submitList(localMenuItems); + return; + } + + + floatingView = getLayoutInflater().inflate(R.layout.layout_bottom_sheet_menu_view, null, false); + + int columnCount = 5; + RecyclerView rv = floatingView.findViewById(R.id.rv); + rv.setLayoutManager(new GridLayoutManager(requireContext(), columnCount)); + + bottomSheetMenuAdapter = new BottomSheetMenuAdapter(columnCount); + bottomSheetMenuAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() { + @Override + public void onClick(@NonNull BaseQuickAdapter baseQuickAdapter, @NonNull View view, int i) { + MenuItem item = bottomSheetMenuAdapter.getItem(i); + if (item == null) { + return; + } + if (!item.isEnabled()) { + return; + } + + onBottomSheetItemClick(item); + } + }); + + bottomSheetMenuAdapter.submitList(localMenuItems); + rv.setAdapter(bottomSheetMenuAdapter); + + FrameLayout.LayoutParams p = new FrameLayout.LayoutParams(-1, -2); + p.gravity = Gravity.BOTTOM; + + View decorView = requireActivity().getWindow().getDecorView(); + FrameLayout content = decorView.findViewById(android.R.id.content); + content.addView(floatingView, p); + } + + private void onBottomSheetItemClick(MenuItem item) { + if (item == null) { + return; + } + + List selectedList = adapter.getSelectedList(); + + if (item.getItemId() == R.id.star) { + getViewModel().multiStarOrNot(selectedList, true); + } else if (item.getItemId() == R.id.unstar) { + getViewModel().multiStarOrNot(selectedList, false); + } else if (item.getItemId() == R.id.rename) { + rename(selectedList); + } else if (item.getItemId() == R.id.move) { + RepoModel repoModel = getNavContext().getRepoModel(); + String parent_dir = getNavContext().getNavPath(); + + move(repoModel.repo_id, repoModel.repo_name, parent_dir, selectedList); + } else if (item.getItemId() == R.id.copy) { + RepoModel repoModel = getNavContext().getRepoModel(); + String parent_dir = getNavContext().getNavPath(); + + copy(repoModel.repo_id, repoModel.repo_name, parent_dir, selectedList); + } else if (item.getItemId() == R.id.delete) { + if (!getNavContext().inRepo()) { + deleteRepo(selectedList); + } else { + deleteDirents(selectedList); + } + } else if (item.getItemId() == R.id.upload) { + addUploadTask(selectedList, true); + } else if (item.getItemId() == R.id.download) { + download(selectedList); + } else if (item.getItemId() == R.id.share) { + showShareDialog(selectedList); + } else if (item.getItemId() == R.id.export) { + exportFile(selectedList); + } else if (item.getItemId() == R.id.open) { + openWith(selectedList); + } + } + + private void onShowActionMode(ActionModeCallbackType callbackType) { + + if (callbackType == ActionModeCallbackType.CREATE) { + int p = Constants.DP.DP_32 * 4; + binding.rv.setPadding(0, 0, 0, p); + } else if (callbackType == ActionModeCallbackType.DESTORY) { + int p = 0; + binding.rv.setPadding(0, 0, 0, p); + } + + if (callbackType == ActionModeCallbackType.CREATE) { + if (!adapter.isOnActionMode()) { + adapter.setOnActionMode(true); + } + + //select repo list + List models = adapter.getSelectedList(); + if (!getNavContext().inRepo()) { + if (CollectionUtils.isEmpty(models)) { + //click the select item of MenuItem + getViewModel().inflateRepoMenu(requireContext()); + } else { + //When press and hold to select some list item, only one can be selected + RepoModel repoModel = (RepoModel) models.get(0); + getViewModel().inflateRepoMenuWithParams(requireContext(), repoModel, getDisableMenuIds(), getWillBeRemovedMenuIds(), isPermissionForce(repoModel.repo_id)); + } + } else { + if (CollectionUtils.isEmpty(models)) { + getViewModel().inflateDirentMenu(requireContext()); + } else { + DirentModel direntModel = (DirentModel) models.get(0); + getViewModel().inflateDirentMenuWithParams(requireContext(), CollectionUtils.newArrayList(direntModel), true, getDisableMenuIds(), getWillBeRemovedMenuIds(), isPermissionForce(direntModel.repo_id)); + } + } + } else if (callbackType == ActionModeCallbackType.SELECT_ALL) { + // + List baseModels = adapter.getSelectedList(); + + if (!getNavContext().inRepo()) { + List repoModels = baseModels.stream().map(baseModel -> (RepoModel) baseModel).collect(Collectors.toList()); + getViewModel().inflateRepoMenuWithParams(requireContext(), repoModels, true, getDisableMenuIds(), getWillBeRemovedMenuIds(), false); + } else { + List direntModels = baseModels.stream().map(baseModel -> (DirentModel) baseModel).collect(Collectors.toList()); + getViewModel().inflateDirentMenuWithParams(requireContext(), direntModels, true, getDisableMenuIds(), getWillBeRemovedMenuIds(), false); + } + + + } else if (callbackType == ActionModeCallbackType.SELECT_NONE) { + //clear menu permission list + getViewModel().clearCachePermissionMap(); + + // + if (!getNavContext().inRepo()) { + getViewModel().inflateRepoMenu(requireContext()); + } else { + getViewModel().inflateDirentMenu(requireContext()); + } + } else if (callbackType == ActionModeCallbackType.DESTORY) { + removeFloatingView(); + closeActionMode(); + } else { + removeFloatingView(); + closeActionMode(); + } + } + + private void removeFloatingView() { + if (floatingView == null) { + return; + } + + if (!floatingView.isAttachedToWindow()) { + floatingView = null; + return; + } + + //clear permission list cache + getViewModel().clearCachePermissionMap(); + + + View decorView = requireActivity().getWindow().getDecorView(); + FrameLayout content = decorView.findViewById(android.R.id.content); + content.removeView(floatingView); + + floatingView = null; + bottomSheetMenuAdapter = null; + } + public void reloadData() { loadData(isForce()); } @@ -501,6 +796,18 @@ private boolean isForce() { return expire == null || now > expire; } + private boolean isPermissionForce(String repoId) { + long now = TimeUtils.getNowMills(); + Long expire = mPermissionRefreshStatusExpireTimeMap.get(repoId); + + boolean ss = expire == null || now > expire; + if (ss) { + mPermissionRefreshStatusExpireTimeMap.put(repoId, (now + forceRefreshInterval)); + } + return ss; + } + + public void loadData() { loadData(false); } @@ -517,6 +824,9 @@ public void loadData(boolean forceRefresh) { String k = getNavContext().getRepoModel().repo_id + getNavContext().getNavPath(); mRefreshStatusExpireTimeMap.put(k, now); } + + //force refresh permission list + mPermissionRefreshStatusExpireTimeMap.clear(); } getViewModel().loadData(getNavContext(), forceRefresh); @@ -530,6 +840,18 @@ private void notifyDataChanged(List repoModels) { } } + private void search(String keyword) { + adapter.filterListBySearchKeyword(keyword); + + // + searchViewModel.searchNext(keyword, 1, 20); + } + + private void deduplicateSearchData(List searchModels) { + //todo deduplicate + adapter.addAll(searchModels); + } + private void showEmptyTip() { FileViewType type = Settings.FILE_LIST_VIEW_TYPE.queryValue(); if (FileViewType.GALLERY == type) { @@ -566,8 +888,9 @@ private void navTo(BaseModel model) { //save saveScrollPosition(); - if (!getNavContext().inRepo()) { - getNavContext().push(model); + if (model instanceof RepoModel model1) { + getNavContext().push(model1); + loadData(isForce()); } else if (model instanceof DirentModel direntModel) { if (direntModel.isDir()) { @@ -576,13 +899,35 @@ private void navTo(BaseModel model) { } else { open(direntModel); } + } else if (model instanceof SearchModel searchModel) { + + DirentModel direntModel = SearchModel.converterThis2DirentModel(searchModel); + if (direntModel.isDir()) { + String repoId = getNavContext().getRepoModel().repo_id; + + //switch to special path in special repo + if (TextUtils.equals(repoId, direntModel.repo_id)) { + getNavContext().switchToPath(getNavContext().getRepoModel(), searchModel.fullpath); + loadData(isForce()); + } else { + getViewModel().getRepoModelAndPermissionEntity(searchModel.repo_id, isPermissionForce(searchModel.repo_id), new Consumer() { + @Override + public void accept(RepoPermissionWrapper wrapper) throws Exception { + getNavContext().switchToPath(wrapper.repoModel, searchModel.fullpath); + loadData(isForce()); + } + }); + } + } else { + open(direntModel); + } } } public boolean backTo() { if (getNavContext().inRepo()) { - if (adapter.getActionMode()) { - adapter.setActionModeOn(false); + if (adapter.isOnActionMode()) { + adapter.setOnActionMode(false); } else { // removeCurrentScrollPosition(); @@ -695,54 +1040,49 @@ private void restoreScrollPosition() { public void onDetach() { super.onDetach(); - if (actionMode != null) { - actionMode.finish(); - } + removeFloatingView(); + closeActionMode(); } - private void toggleAdapterItemSelectedOnLongClick(int i) { - DirentModel direntModel = (DirentModel) adapter.getItems().get(i); - direntModel.is_checked = !direntModel.is_checked; - adapter.getItems().set(i, direntModel); - adapter.notifyItemChanged(i); + @Override + public void onDestroy() { + super.onDestroy(); } - public void closeActionMode() { - if (adapter.getActionMode()) { - adapter.setActionModeOn(false); - - actionMode.finish(); - actionMode = null; + private void toggleAdapterItemSelectedState(int i) { + BaseModel baseModel = adapter.getItems().get(i); + if (baseModel instanceof RepoModel repoModel) { + repoModel.is_checked = !repoModel.is_checked; + adapter.set(i, repoModel); + } else if (baseModel instanceof DirentModel direntModel) { + direntModel.is_checked = !direntModel.is_checked; + adapter.set(i, direntModel); } } - public void startContextualActionMode() { - if (!getNavContext().inRepo()) return; - - //action mode on - if (!adapter.getActionMode()) { - adapter.setActionModeOn(true); + public void closeActionMode() { + if (adapter.isOnActionMode()) { + adapter.setOnActionMode(false); } - if (actionMode == null) { - // start the actionMode - actionMode = activity.startSupportActionMode(new ActionModeCallback()); + if (actionMode != null) { + actionMode.finish(); + actionMode = null; } } + /** - * update state of contextual action bar (CAB) + * start or update state of contextual action bar (CAB) */ - public void updateContextualActionBar() { - if (!getNavContext().inRepo()) return; - + public void startOrUpdateContextualActionBar() { if (actionMode == null) { // there are some selected items, start the actionMode actionMode = activity.startSupportActionMode(new ActionModeCallback()); - } else { - int count = adapter.getSelectedList().size(); - actionMode.setTitle(getResources().getQuantityString(R.plurals.transfer_list_items_selected, count, count)); } + + int count = adapter.getSelectedList().size(); + actionMode.setTitle(getResources().getQuantityString(R.plurals.transfer_list_items_selected, count, count)); } /** @@ -760,11 +1100,13 @@ public boolean onCreateActionMode(ActionMode mode, Menu menu) { inflater.inflate(R.menu.repos_fragment_menu, menu); if (adapter == null) return true; - // to hidden "r" permissions files or folder - if (!getNavContext().isParentHasWritePermission()) { - menu.findItem(R.id.action_mode_delete).setVisible(false); - menu.findItem(R.id.action_mode_move).setVisible(false); - } + mainViewModel.getOnActionModeLiveData().setValue(ActionModeCallbackType.CREATE); + +// // to hidden "r" permissions files or folder +// if (!getNavContext().isParentHasWritePermission()) { +// menu.findItem(R.id.action_mode_delete).setVisible(false); +// menu.findItem(R.id.action_mode_move).setVisible(false); +// } return true; } @@ -775,8 +1117,8 @@ public boolean onPrepareActionMode(ActionMode mode, Menu menu) { * The ActionBarPolicy determines how many action button to place in the ActionBar * and the default amount is 2. */ - menu.findItem(R.id.action_mode_delete).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); - menu.findItem(R.id.action_mode_copy).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); +// menu.findItem(R.id.action_mode_delete).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); +// menu.findItem(R.id.action_mode_copy).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); menu.findItem(R.id.action_mode_select_all).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); // Here you can perform updates to the contextual action bar (CAB) due to @@ -787,7 +1129,7 @@ public boolean onPrepareActionMode(ActionMode mode, Menu menu) { @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { //check data - List selectedDirents = adapter.getSelectedList(); + List selectedDirents = adapter.getSelectedList(); if (CollectionUtils.isEmpty(selectedDirents) || !getNavContext().inRepo()) { if (item.getItemId() != R.id.action_mode_select_all) { ToastUtils.showLong(R.string.action_mode_no_items_selected); @@ -798,23 +1140,19 @@ public boolean onActionItemClicked(ActionMode mode, MenuItem item) { int itemId = item.getItemId(); if (itemId == R.id.action_mode_select_all) { adapter.setItemSelected(!allItemsSelected); - updateContextualActionBar(); + + startOrUpdateContextualActionBar(); + + if (!allItemsSelected) { + mainViewModel.getOnActionModeLiveData().setValue(ActionModeCallbackType.SELECT_ALL); + } else { + mainViewModel.getOnActionModeLiveData().setValue(ActionModeCallbackType.SELECT_NONE); + } allItemsSelected = !allItemsSelected; - } else if (itemId == R.id.action_mode_delete) { - deleteDirents(selectedDirents); - } else if (itemId == R.id.action_mode_copy) { - DirentModel dirent = selectedDirents.get(0); - copyFiles(dirent.repo_id, dirent.repo_name, dirent.parent_dir, selectedDirents); - } else if (itemId == R.id.action_mode_move) { - DirentModel dirent = selectedDirents.get(0); - moveFiles(dirent.repo_id, dirent.repo_name, dirent.parent_dir, selectedDirents); - } else if (itemId == R.id.action_mode_download) { - downloadDirents(selectedDirents); - } else { - return false; } + return true; } @@ -822,155 +1160,9 @@ public boolean onActionItemClicked(ActionMode mode, MenuItem item) { public void onDestroyActionMode(ActionMode mode) { if (adapter == null) return; - adapter.setActionModeOn(false); - - // Here you can make any necessary updates to the activity when - // the contextual action bar (CAB) is removed. By default, selected items are deselected/unchecked. - if (actionMode != null) { - actionMode = null; - } - } - - } - - public void showRepoBottomSheet(RepoModel model) { - - int rid = R.menu.bottom_sheet_op_repo; - BottomSheetMenuFragment.Builder builder = BottomSheetHelper.buildSheet(getActivity(), rid, menuItem -> { - if (menuItem.getItemId() == R.id.star || menuItem.getItemId() == R.id.unstar) { - starOrNot(model); - } else if (menuItem.getItemId() == R.id.rename_repo) { - rename(model.repo_id, null, model.repo_name, "repo"); - } else if (menuItem.getItemId() == R.id.delete_repo) { - deleteRepo(model.repo_id); - } - }); - - if (model.starred) { - builder.removeMenu(R.id.star); - } else { - builder.removeMenu(R.id.unstar); - } - - if (!model.hasWritePermission()) { - builder.removeMenu(R.id.delete_repo); - builder.removeMenu(R.id.rename_repo); + mainViewModel.getOnActionModeLiveData().setValue(ActionModeCallbackType.DESTORY); } - builder.show(getChildFragmentManager()); - } - - public void showDirNewBottomSheet(DirentModel dirent) { - int rid = R.menu.bottom_sheet_op_dir; - BottomSheetMenuFragment.Builder builder = BottomSheetHelper.buildSheet(getActivity(), rid, menuItem -> { - int itemId = menuItem.getItemId(); - - if (itemId == R.id.star || itemId == R.id.unstar) { - starOrNot(dirent); - } else if (itemId == R.id.share) { - showShareDialog(dirent); - } else if (itemId == R.id.delete) { - deleteDirent(dirent); - } else if (itemId == R.id.copy) { - copyFiles(dirent.repo_id, dirent.repo_name, dirent.parent_dir, CollectionUtils.newArrayList(dirent)); - } else if (itemId == R.id.move) { - moveFiles(dirent.repo_id, dirent.repo_name, dirent.parent_dir, CollectionUtils.newArrayList(dirent)); - } else if (itemId == R.id.rename) { - rename(dirent.repo_id, dirent.full_path, dirent.name, "dir"); - } else if (itemId == R.id.download) { - download(dirent); - } - }); - - if (dirent.starred) { - builder.removeMenu(R.id.star); - } else { - builder.removeMenu(R.id.unstar); - } - - if (!dirent.hasWritePermission()) { - builder.removeMenu(R.id.rename); - builder.removeMenu(R.id.delete); - builder.removeMenu(R.id.move); - } - - if (!dirent.hasDownloadPermission()) { - builder.removeMenu(R.id.download); - } - - String repoId = getNavContext().getRepoModel().repo_id; - getViewModel().getRepoModelFromLocal(repoId, new Consumer() { - @Override - public void accept(RepoModel repoModel) throws Exception { - if (repoModel != null && repoModel.encrypted) { - builder.removeMenu(R.id.share); - } - builder.show(getChildFragmentManager()); - } - }); - } - - private void showFileBottomSheet(DirentModel dirent) { - int rid = R.menu.bottom_sheet_op_file; - BottomSheetMenuFragment.Builder builder = BottomSheetHelper.buildSheet(getActivity(), rid, menuItem -> { - int itemId = menuItem.getItemId(); - - if (itemId == R.id.share) { - showShareDialog(dirent); - } else if (itemId == R.id.open) { - openWith(dirent); - } else if (itemId == R.id.delete) { - deleteDirent(dirent); - } else if (itemId == R.id.copy) { - copyFiles(dirent.repo_id, dirent.repo_name, dirent.parent_dir, CollectionUtils.newArrayList(dirent)); - } else if (itemId == R.id.move) { - moveFiles(dirent.repo_id, dirent.repo_name, dirent.parent_dir, CollectionUtils.newArrayList(dirent)); - } else if (itemId == R.id.rename) { - rename(dirent.repo_id, dirent.full_path, dirent.name, "file"); - } else if (itemId == R.id.update) { - addUploadTask(dirent, true); - } else if (itemId == R.id.download) { - download(dirent); - } else if (itemId == R.id.export) { - exportFile(dirent); - } else if (itemId == R.id.star || itemId == R.id.unstar) { - starOrNot(dirent); - } - }); - - if (dirent.starred) { - builder.removeMenu(R.id.star); - } else { - builder.removeMenu(R.id.unstar); - } - - - if (!dirent.hasWritePermission()) { - builder.removeMenu(R.id.rename); - builder.removeMenu(R.id.delete); - builder.removeMenu(R.id.move); - builder.removeMenu(R.id.update); - } - - if (!dirent.hasDownloadPermission()) { - builder.removeMenu(R.id.download); - } - -// if (!Utils.isTextMimeType(dirent.name)) { -// builder.removeMenu(R.id.open); -// } - - if (getNavContext().getRepoModel().encrypted) { - builder.removeMenu(R.id.share); - } - - Account account = SupportAccountManager.getInstance().getCurrentAccount(); - - File f = DataManager.getLocalRepoFile(account, getNavContext().getRepoModel().repo_id, getNavContext().getRepoModel().repo_name, dirent.full_path); - if (!f.exists()) { - builder.removeMenu(R.id.update); - } - builder.show(getChildFragmentManager()); } @@ -1026,7 +1218,7 @@ private void open(DirentModel dirent) { } //Open with another app - openWith(dirent); + openWith(CollectionUtils.newArrayList(dirent)); } private File getLocalDestinationFile(String repoId, String repoName, String fullPathInRepo) { @@ -1035,7 +1227,15 @@ private File getLocalDestinationFile(String repoId, String repoName, String full return DataManager.getLocalRepoFile(account, repoId, repoName, fullPathInRepo); } - private void openWith(DirentModel direntModel) { + private void openWith(List direntModels) { + if (CollectionUtils.isEmpty(direntModels)) { + return; + } + + closeActionMode(); + + DirentModel direntModel = (DirentModel) direntModels.get(0); + File local = getLocalDestinationFile(direntModel.repo_id, direntModel.repo_name, direntModel.full_path); if (local.exists() && local.length() == direntModel.size) { WidgetUtils.openWith(requireActivity(), local); @@ -1045,53 +1245,84 @@ private void openWith(DirentModel direntModel) { } } - public void download(DirentModel direntModel) { - BackgroundJobManagerImpl.getInstance().startDownloadChainWorker(new String[]{direntModel.uid}); + public void download(List direntModels) { + if (CollectionUtils.isEmpty(direntModels)) { + return; + } + + List direntModels1 = direntModels.stream().map(m -> (DirentModel) m).collect(Collectors.toList()); + List uids = direntModels1.stream().map(m -> m.uid).collect(Collectors.toList()); + String[] sArray = uids.toArray(new String[0]); + BackgroundJobManagerImpl.getInstance().startDownloadChainWorker(sArray); + + closeActionMode(); } - public void rename(String repoID, String curPath, String curName, String type) { - RenameDialogFragment dialogFragment = RenameDialogFragment.newInstance(); - dialogFragment.initData(curName, curPath, repoID, type); + public void rename(List models) { + if (CollectionUtils.isEmpty(models)) { + return; + } + + RenameDialogFragment dialogFragment; + + BaseModel first = models.get(0); + if (first instanceof DirentModel dirent) { + dialogFragment = RenameDialogFragment.newInstance(dirent.name, dirent.full_path, dirent.repo_id, dirent.type); + } else if (first instanceof RepoModel repo) { + dialogFragment = RenameDialogFragment.newInstance(repo.repo_name, "/", repo.repo_id, "repo"); + } else { + return; + } + dialogFragment.setRefreshListener(new OnRefreshDataListener() { @Override public void onActionStatus(boolean isDone) { if (isDone) { - mainViewModel.getOnForceRefreshRepoListLiveData().setValue(true); + ToastUtils.showLong(R.string.rename_successful); } + + loadData(true); + closeActionMode(); } }); dialogFragment.show(getChildFragmentManager(), RenameDialogFragment.class.getSimpleName()); } - public void deleteRepo(String repoID) { - DeleteRepoDialogFragment dialogFragment = DeleteRepoDialogFragment.newInstance(repoID); + public void deleteRepo(List repoModels) { + if (CollectionUtils.isEmpty(repoModels)) { + return; + } + + List repoIds = repoModels.stream().map(m -> (RepoModel) m).map(m -> m.repo_id).collect(Collectors.toList()); + DeleteRepoDialogFragment dialogFragment = DeleteRepoDialogFragment.newInstance(repoIds); dialogFragment.setRefreshListener(isDone -> { if (isDone) { ToastUtils.showLong(R.string.delete_successful); - - loadData(true); } + + closeActionMode(); + loadData(true); }); dialogFragment.show(getChildFragmentManager(), DeleteRepoDialogFragment.class.getSimpleName()); } - public void deleteDirent(DirentModel dirent) { - deleteDirents(CollectionUtils.newArrayList(dirent)); - } + public void deleteDirents(List dirents) { + if (CollectionUtils.isEmpty(dirents)) { + return; + } - public void deleteDirents(List dirents) { - DeleteFileDialogFragment dialogFragment = DeleteFileDialogFragment.newInstance(); - dialogFragment.initData(dirents); + List direntUids = dirents.stream().map(m -> (DirentModel) m).map(m -> m.uid).collect(Collectors.toList()); + DeleteFileDialogFragment dialogFragment = DeleteFileDialogFragment.newInstance(direntUids); dialogFragment.setRefreshListener(new OnRefreshDataListener() { @Override public void onActionStatus(boolean isDone) { if (isDone) { ToastUtils.showLong(R.string.delete_successful); + } - closeActionMode(); + closeActionMode(); - loadData(true); - } + loadData(true); } }); dialogFragment.show(getChildFragmentManager(), DeleteFileDialogFragment.class.getSimpleName()); @@ -1101,7 +1332,16 @@ public void onActionStatus(boolean isDone) { * Share a file. Generating a file share link and send the link or file to someone * through some app. */ - public void showShareDialog(DirentModel direntModel) { + public void showShareDialog(List dirents) { + if (CollectionUtils.isEmpty(dirents)) { + return; + } + + //close action mode firstly + closeActionMode(); + + DirentModel direntModel = (DirentModel) dirents.get(0); + MaterialAlertDialogBuilder mBuilder = new MaterialAlertDialogBuilder(requireContext()); boolean inChina = Utils.isInChina(); @@ -1129,10 +1369,29 @@ public void showShareDialog(DirentModel direntModel) { }).show(); } + + private void exportFile(List dirents) { + if (CollectionUtils.isEmpty(dirents)) { + return; + } + + DirentModel direntModel = (DirentModel) dirents.get(0); + + File destinationFile = getLocalDestinationFile(direntModel.repo_id, direntModel.repo_name, direntModel.full_path); + + if (!destinationFile.exists()) { + Intent intent = FileActivity.start(requireContext(), direntModel, "export"); + fileActivityLauncher.launch(intent); + } else { + Objs.exportFile(this, destinationFile); + } + } + + /** * Copy multiple files */ - public void copyFiles(String srcRepoId, String srcRepoName, String srcDir, List dirents) { + public void copy(String srcRepoId, String srcRepoName, String srcDir, List dirents) { chooseCopyMoveDestForMultiFiles(srcRepoId, srcRepoName, srcDir, dirents, OpType.COPY); } @@ -1140,29 +1399,25 @@ public void copyFiles(String srcRepoId, String srcRepoName, String srcDir, List< /** * Move multiple files */ - public void moveFiles(String srcRepoId, String srcRepoName, String srcDir, List dirents) { + public void move(String srcRepoId, String srcRepoName, String srcDir, List dirents) { chooseCopyMoveDestForMultiFiles(srcRepoId, srcRepoName, srcDir, dirents, OpType.MOVE); } - /** - * Move multiple files - */ - public void downloadDirents(List dirents) { - String[] uids = dirents.stream().map(m -> m.uid).toArray(String[]::new); - BackgroundJobManagerImpl.getInstance().startDownloadChainWorker(uids); - - closeActionMode(); - } - private CopyMoveContext copyMoveContext = null; /** * Choose copy/move destination for multiple files */ private void chooseCopyMoveDestForMultiFiles(String repoID, String repoName, - String dirPath, List dirents, + String dirPath, List dirents, OpType op) { - copyMoveContext = new CopyMoveContext(repoID, repoName, dirPath, dirents, op); + if (CollectionUtils.isEmpty(dirents)) { + return; + } + + List direntModels = dirents.stream().map(m -> (DirentModel) m).collect(Collectors.toList()); + + copyMoveContext = new CopyMoveContext(repoID, repoName, dirPath, direntModels, op); Intent intent = new Intent(requireContext(), ObjSelectorActivity.class); intent.putExtra(ObjSelectorActivity.DATA_ACCOUNT, SupportAccountManager.getInstance().getCurrentAccount()); @@ -1215,24 +1470,6 @@ public void onActionStatus(boolean isDone) { dialogFragment.show(getChildFragmentManager(), CopyMoveDialogFragment.class.getSimpleName()); } - private void starOrNot(BaseModel model) { - if (model instanceof RepoModel) { - RepoModel repoModel = (RepoModel) model; - if (repoModel.starred) { - getViewModel().unStar(repoModel.repo_id, "/"); - } else { - getViewModel().star(repoModel.repo_id, "/"); - } - } else if (model instanceof DirentModel) { - DirentModel direntModel = (DirentModel) model; - String path = Utils.pathJoin(getNavContext().getNavPath(), direntModel.name); - if (direntModel.starred) { - getViewModel().unStar(direntModel.repo_id, path); - } else { - getViewModel().star(direntModel.repo_id, path); - } - } - } private final ActivityResultLauncher imagePreviewActivityLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback() { @Override @@ -1280,8 +1517,8 @@ public void onActivityResult(ActivityResult o) { } else if ("open_with".equals(action)) { - WidgetUtils.openWith(requireActivity(), destinationFile); + } else if ("open_text_mime".equals(action)) { MarkdownActivity.start(requireActivity(), localFullPath, repoId, targetFile); @@ -1289,17 +1526,6 @@ public void onActivityResult(ActivityResult o) { } }); - private void exportFile(DirentModel dirent) { - File destinationFile = getLocalDestinationFile(dirent.repo_id, dirent.repo_name, dirent.full_path); - - if (!destinationFile.exists()) { - Intent intent = FileActivity.start(requireContext(), dirent, "export"); - fileActivityLauncher.launch(intent); - } else { - Objs.exportFile(this, destinationFile); - } - } - private void shareFile(DirentModel dirent) { if (dirent.isDir()) { Objs.shareDirToWeChat(this, dirent.repo_id, dirent.full_path); @@ -1317,7 +1543,15 @@ private void shareFile(DirentModel dirent) { ////////////////add task///////////// - private void addUploadTask(DirentModel dirent, boolean isUpdate) { + private void addUploadTask(List dirents, boolean isUpdate) { + if (CollectionUtils.isEmpty(dirents)) { + return; + } + + List direntModels = dirents.stream().map(m -> (DirentModel) m).collect(Collectors.toList()); + + DirentModel dirent = direntModels.get(0); + RepoModel targetedModel = getNavContext().getRepoModel(); String targetDir = getNavContext().getNavPath(); File localFilePath = getLocalDestinationFile(dirent.repo_id, dirent.repo_name, dirent.full_path); diff --git a/app/src/main/java/com/seafile/seadroid2/ui/repo/RepoService.java b/app/src/main/java/com/seafile/seadroid2/ui/repo/RepoService.java index 2ffebabca..ef7678051 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/repo/RepoService.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/repo/RepoService.java @@ -1,11 +1,15 @@ package com.seafile.seadroid2.ui.repo; +import com.seafile.seadroid2.framework.data.db.entities.PermissionEntity; import com.seafile.seadroid2.framework.data.db.entities.RepoModel; import com.seafile.seadroid2.framework.data.model.ResultModel; +import com.seafile.seadroid2.framework.data.model.permission.PermissionListWrapperModel; +import com.seafile.seadroid2.framework.data.model.permission.PermissionWrapperModel; import com.seafile.seadroid2.framework.data.model.repo.Dirent2Model; import com.seafile.seadroid2.framework.data.model.repo.DirentWrapperModel; import com.seafile.seadroid2.framework.data.model.repo.RepoWrapperModel; +import java.security.Permission; import java.util.Map; import io.reactivex.Single; @@ -41,11 +45,9 @@ public interface RepoService { @GET("api/v2.1/repos/{repo_id}/dir/?with_thumbnail=true") Call getDirentsSync(@Path("repo_id") String repoId, @Query("p") String path); - @Multipart - @POST("api/v2.1/starred-items/") - Single star(@PartMap Map map); - - @DELETE("api/v2.1/starred-items/") - Single unStar(@Query("repo_id") String repoId, @Query("path") String path); + @GET("api/v2.1/repos/{repo_id}/custom-share-permissions/{permission_id}/") + Single getCustomSharePermissionById(@Path("repo_id") String repoId, @Path("permission_id") int id); + @GET("api/v2.1/repos/{repo_id}/custom-share-permissions/") + Single getCustomSharePermissions(@Path("repo_id") String repoId); } diff --git a/app/src/main/java/com/seafile/seadroid2/ui/repo/RepoViewModel.java b/app/src/main/java/com/seafile/seadroid2/ui/repo/RepoViewModel.java index 49fc3ddf3..daca7b503 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/repo/RepoViewModel.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/repo/RepoViewModel.java @@ -1,25 +1,37 @@ package com.seafile.seadroid2.ui.repo; +import android.content.Context; import android.text.TextUtils; +import android.view.MenuInflater; +import android.view.MenuItem; +import androidx.annotation.NonNull; import androidx.lifecycle.MutableLiveData; import com.blankj.utilcode.util.CollectionUtils; import com.blankj.utilcode.util.NetworkUtils; import com.blankj.utilcode.util.ToastUtils; +import com.seafile.seadroid2.R; import com.seafile.seadroid2.SeafException; import com.seafile.seadroid2.account.Account; import com.seafile.seadroid2.account.SupportAccountManager; +import com.seafile.seadroid2.annotation.Todo; +import com.seafile.seadroid2.annotation.Unstable; +import com.seafile.seadroid2.framework.data.model.repo.RepoPermissionWrapper; +import com.seafile.seadroid2.ui.bottomsheetmenu.ActionMenu; import com.seafile.seadroid2.context.NavContext; import com.seafile.seadroid2.enums.FileViewType; import com.seafile.seadroid2.framework.data.db.AppDatabase; import com.seafile.seadroid2.framework.data.db.entities.DirentModel; import com.seafile.seadroid2.framework.data.db.entities.EncKeyCacheEntity; import com.seafile.seadroid2.framework.data.db.entities.FileTransferEntity; +import com.seafile.seadroid2.framework.data.db.entities.PermissionEntity; import com.seafile.seadroid2.framework.data.db.entities.RepoModel; import com.seafile.seadroid2.framework.data.model.BaseModel; import com.seafile.seadroid2.framework.data.model.ResultModel; import com.seafile.seadroid2.enums.TransferStatus; +import com.seafile.seadroid2.framework.data.model.permission.PermissionListWrapperModel; +import com.seafile.seadroid2.framework.data.model.permission.PermissionWrapperModel; import com.seafile.seadroid2.framework.data.model.repo.Dirent2Model; import com.seafile.seadroid2.framework.http.HttpIO; import com.seafile.seadroid2.framework.util.Utils; @@ -27,29 +39,37 @@ import com.seafile.seadroid2.ui.base.viewmodel.BaseViewModel; import com.seafile.seadroid2.framework.util.Objs; import com.seafile.seadroid2.framework.util.SLogs; +import com.seafile.seadroid2.ui.star.StarredService; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.stream.Collectors; +import io.reactivex.Completable; +import io.reactivex.Flowable; import io.reactivex.Single; +import io.reactivex.SingleSource; +import io.reactivex.functions.Action; import io.reactivex.functions.BiFunction; import io.reactivex.functions.Consumer; +import io.reactivex.functions.Function; +import kotlin.Pair; import okhttp3.RequestBody; public class RepoViewModel extends BaseViewModel { - private final MutableLiveData> ObjsListLiveData = new MutableLiveData<>(); - private final MutableLiveData StarLiveData = new MutableLiveData<>(); + private final MutableLiveData> _objListLiveData = new MutableLiveData<>(); + private final MutableLiveData _starredLiveData = new MutableLiveData<>(); - public MutableLiveData getStarLiveData() { - return StarLiveData; + public MutableLiveData getStarredLiveData() { + return _starredLiveData; } - public MutableLiveData> getObjsListLiveData() { - return ObjsListLiveData; + public MutableLiveData> getObjListLiveData() { + return _objListLiveData; } public void getEncCacheDB(String repoId, Consumer consumer) { @@ -67,29 +87,6 @@ public void accept(List list) throws Exception { } - public void getRepoModelFromLocal(String repoId, Consumer consumer) { - //from db - Single> singleDb = AppDatabase.getInstance().repoDao().getRepoById(repoId); - addSingleDisposable(singleDb, new Consumer>() { - @Override - public void accept(List repoModels) throws Exception { - if (consumer != null) { - if (CollectionUtils.isEmpty(repoModels)) { - //no data in sqlite, request RepoApi again - consumer.accept(null); - } else { - consumer.accept(repoModels.get(0)); - } - } - } - }, new Consumer() { - @Override - public void accept(Throwable throwable) throws Exception { - SLogs.e(throwable); - } - }); - } - public void loadData(NavContext context, boolean forceRefresh) { Account account = SupportAccountManager.getInstance().getCurrentAccount(); if (account == null) { @@ -126,7 +123,7 @@ public void accept(List repoModels) { } List list = Objs.parseRepoListForAdapter(repoModels, account.getSignature(), false); - getObjsListLiveData().setValue(list); + getObjListLiveData().setValue(list); if (isForce) { loadReposFromRemote(account); @@ -149,7 +146,7 @@ private void loadReposFromRemote(Account account) { addSingleDisposable(resultSingle, new Consumer>() { @Override public void accept(List models) throws Exception { - getObjsListLiveData().setValue(models); + getObjListLiveData().setValue(models); getRefreshLiveData().setValue(false); } }, new Consumer() { @@ -188,7 +185,7 @@ public void accept(List direntModels) throws Exception { if (CollectionUtils.isEmpty(rets)) { loadDirentsFromRemote(account, context); } else { - getObjsListLiveData().setValue(Objs.parseLocalDirents(rets)); + getObjListLiveData().setValue(Objs.parseLocalDirents(rets)); getRefreshLiveData().setValue(false); } } @@ -233,7 +230,7 @@ public void accept(List direntModels) throws Exception { if (CollectionUtils.isEmpty(direntModels)) { loadDirentsFromRemote(account, context); } else { - getObjsListLiveData().setValue(Objs.parseLocalDirents(direntModels)); + getObjListLiveData().setValue(Objs.parseLocalDirents(direntModels)); getRefreshLiveData().setValue(false); } } @@ -250,6 +247,10 @@ private void loadDirentsFromRemote(Account account, NavContext context) { String repoName = context.getRepoModel().repo_name; String parentDir = context.getNavPath(); + if ("/".equals(parentDir)) { + loadPermissionFromRemote(repoId); + } + Single> resultSingle = Objs.getDirentsSingleFromServer(account, repoId, repoName, parentDir); addSingleDisposable(resultSingle, new Consumer>() { @@ -265,9 +266,9 @@ public void accept(List direntModels) throws Exception { } } - getObjsListLiveData().setValue(new ArrayList<>(rets)); + getObjListLiveData().setValue(new ArrayList<>(rets)); } else { - getObjsListLiveData().setValue(new ArrayList<>(direntModels)); + getObjListLiveData().setValue(new ArrayList<>(direntModels)); } getRefreshLiveData().setValue(false); @@ -287,48 +288,577 @@ public void accept(Throwable throwable) throws Exception { }); } - //star - public void star(String repoId, String path) { - getRefreshLiveData().setValue(true); + public List inflateMenu(Context context, int rid) { + ActionMenu menu = new ActionMenu(context); - Map requestDataMap = new HashMap<>(); - requestDataMap.put("repo_id", repoId); - requestDataMap.put("path", path); - Map bodyMap = generateRequestBody(requestDataMap); + MenuInflater inflater = new MenuInflater(context); + inflater.inflate(rid, menu); - Single single = HttpIO.getCurrentInstance().execute(RepoService.class).star(bodyMap); - addSingleDisposable(single, new Consumer() { + List items = new ArrayList<>(menu.size()); + for (int i = 0; i < menu.size(); i++) { + items.add(menu.getItem(i)); + } + + return items; + } + + private final MutableLiveData> _menuItemListLiveData = new MutableLiveData<>(); + + public MutableLiveData> getMenuItemListLiveData() { + return _menuItemListLiveData; + } + + + public void getRepoModelAndPermissionEntity(String repoId, boolean isForce, Consumer consumer) { + Single>> r = getRepoModelAndAllPermissionSingle(repoId, isForce); + addSingleDisposable(r, new Consumer>>() { @Override - public void accept(Dirent2Model resultModel) throws Exception { - getStarLiveData().setValue(true); + public void accept(Pair> pair) throws Exception { + if (consumer != null) { + if (CollectionUtils.isEmpty(pair.getSecond())) { + consumer.accept(new RepoPermissionWrapper(pair.getFirst(), null)); + return; + } + + List list = pair.getSecond(); + + RepoModel repoModel = pair.getFirst(); + Optional permission = list.stream().filter(f -> f.id == repoModel.getCustomPermissionNum()).findFirst(); + + if (!permission.isPresent()) { + consumer.accept(new RepoPermissionWrapper(pair.getFirst(), null)); + return; + } + + consumer.accept(new RepoPermissionWrapper(pair.getFirst(), permission.get())); + } } - }, new Consumer() { + }); + } + + /** + * do not use + *
  • get the list of libraries first.
  • + *
  • obtain the corresponding local permission data from the library list
  • + *
  • if the length of the local permission data list and the library list are the same, the data will be returned directly
  • + *
  • if not, send multiple requests to the server concurrently to obtain the permission list data
  • + *
  • merge the permission list data and the library list data to return
  • + */ + @Unstable + @Todo + private Single> getMultipleRepoModelAndRelatePermissionDataSingle(List repoIds, boolean isForce) { + Single> dbSingle = AppDatabase.getInstance().repoDao().getRepoListByIds(repoIds); + return dbSingle.flatMap(new Function, SingleSource>>() { @Override - public void accept(Throwable throwable) throws Exception { - getRefreshLiveData().setValue(false); + public SingleSource> apply(List repoModels) throws Exception { + if (CollectionUtils.isEmpty(repoModels)) { + return Single.error(new IllegalArgumentException("No RepoModels found for the given repoIds")); + } - String errMsg = getErrorMsgByThrowable(throwable); - ToastUtils.showLong(errMsg); + if (isForce) { + // return empty list + List wrappers = repoModels.stream() + .map(model -> new RepoPermissionWrapper(model, null)) + .collect(Collectors.toList()); + return Single.just(wrappers); + } + + return handleRepoPermissions(repoModels); } + }).onErrorResumeNext(throwable -> { + // 错误处理,记录日志或返回默认值 + SLogs.e("Error in getRepoModelAndAllPermissionSingle2", throwable); + return Single.error(throwable); }); } - public void unStar(String repoId, String path) { - getRefreshLiveData().setValue(true); + @Unstable + @Todo + private Single> handleRepoPermissions(List repoModels) { + List customPermissionIds = repoModels.stream() + .filter(RepoModel::isCustomPermission) + .map(RepoModel::getCustomPermissionNum) + .collect(Collectors.toList()); + + if (customPermissionIds.isEmpty()) { + // 如果没有自定义权限,直接返回默认权限 + List wrappers = repoModels.stream() + .map(repo -> new RepoPermissionWrapper(repo, + new PermissionEntity(repo.repo_id, repo.permission))) + .collect(Collectors.toList()); + return Single.just(wrappers); + } + + Single> pSingle = AppDatabase.getInstance().permissionDAO().getByIdsAsync(customPermissionIds); + return pSingle.map(permissionEntities -> mapPermissionsToWrappers(repoModels, permissionEntities, customPermissionIds)); + } + + @Unstable + @Todo + private List mapPermissionsToWrappers(List repoModels, + List permissionEntities, + List customPermissionIds) { + boolean isValid = customPermissionIds.size() == permissionEntities.size(); + List wrappers = new ArrayList<>(); + + for (RepoModel model : repoModels) { + if (model.isCustomPermission()) { + Optional matchedPermission = permissionEntities.stream() + .filter(entity -> TextUtils.equals(entity.repo_id, model.repo_id)) + .findFirst(); + wrappers.add(new RepoPermissionWrapper(model, matchedPermission.orElse(null))); + } else { + wrappers.add(new RepoPermissionWrapper(model, + new PermissionEntity(model.repo_id, model.permission))); + } + } + + // 如果权限不完整,需从远程加载 + if (!isValid) { + wrappers.forEach(wrapper -> { + if (wrapper.getPermission() == null) { + wrapper.setPermission(null); + } + }); + } + + return wrappers; + } + + /** + * get the repoModel and repoMode‘s PermissionEntity from local, if not exist, get from remote. + * if isForce is true, get from remote directly and save to db + */ + private Single>> getRepoModelAndAllPermissionSingle(String repoId, boolean isForce) { + Single> dbSingle = AppDatabase.getInstance().repoDao().getRepoById(repoId); + return dbSingle.flatMap(new Function, SingleSource>>>() { + @Override + public SingleSource>> apply(List repoModels) throws Exception { + if (CollectionUtils.isEmpty(repoModels)) { + return null; + } + + RepoModel repoModel = repoModels.get(0); + if (TextUtils.isEmpty(repoModel.permission)) { + //This issue doesn't actually happen, but it's still checked again from the remote check + return Single.just(new Pair<>(repoModel, null)); + } + + if (isForce) { + //get permission from remote + return Single.just(new Pair<>(repoModel, null)); + } + + //get special number permission from db + Single> pSingle = AppDatabase.getInstance().permissionDAO().getByRepoIdAsync(repoId); + + return pSingle.flatMap((Function, SingleSource>>>) pList -> { + + //no data in local db + if (CollectionUtils.isEmpty(pList)) { + return Single.just(new Pair<>(repoModel, null)); + } + + //get first permission + return Single.just(new Pair<>(repoModel, pList)); + }); + } + }) + //from remote + .flatMap((Function>, SingleSource>>>) pair -> { + if (pair.getSecond() != null) { + return Single.just(pair); + } + + Single> permissionSingle = getLoadRepoPermissionFromRemoteSingle(repoId); + return permissionSingle.flatMap((Function, SingleSource>>>) remoteList -> { + if (CollectionUtils.isEmpty(remoteList)) { + return Single.just(pair); + } + + return Single.just(new Pair<>(pair.getFirst(), remoteList)); + }); + }); + } + + /** + *
    +     *     <"rw", PermissionEntity(permission,ids)>
    +     *     <"r", PermissionEntity(permission,ids)>
    +     *     <"custom-48", PermissionEntity(permission,ids)>
    +     *     <"custom-49", PermissionEntity(permission,ids)>
    +     * 
    + */ + private final HashMap _permissionMap = new HashMap<>(); + + public HashMap getPermissionStackMap() { + return _permissionMap; + } + + public void inflateRepoMenu(Context context) { + getPermissionStackMap().clear(); + toParseMenu(context, R.menu.bottom_sheet_op_repo, null, CollectionUtils.newArrayList(R.id.unstar)); + } + + /** + * @param repoModels + */ + public void inflateRepoMenuWithParams(Context context, List repoModels, boolean is_checked, List disableMenuIds, List removedMenuIds, boolean isForce) { + if (CollectionUtils.isEmpty(repoModels)) { + return; + } + + int menuId = R.menu.bottom_sheet_op_repo; + if (!is_checked) { + multipleRemoveCachedRepoPermissionMapData(repoModels); + + toParseMenu(context, menuId, disableMenuIds, removedMenuIds); + return; + } + + if (repoModels.size() == 1) { + inflateRepoMenuWithParams(context, repoModels.get(0), disableMenuIds, removedMenuIds, isForce); + } else { + List permissionEntities = CollectionUtils.newArrayList(); + for (RepoModel repoModel : repoModels) { + //NOTICE this is a special permission("r"), not a real permission + //because: currently, multiple repo lists cannot be deleted at the same time + //it will be fixed later + permissionEntities.add(new PermissionEntity(repoModel.repo_id, "r")); + } + + multipleCacheRepoPermissionMapData(repoModels, permissionEntities); + + toParseMenu(context, menuId, disableMenuIds, removedMenuIds); + } + } + + public void inflateRepoMenuWithParams(Context context, RepoModel repoModel, List disableMenuIds, List removedMenuIds, boolean isForce) { + int menuId = R.menu.bottom_sheet_op_repo; + + if (!repoModel.is_checked) { + //remove permission + removeCachedPermissionMapData(repoModel.permission, repoModel.repo_id); + + toParseMenu(context, menuId, disableMenuIds, removedMenuIds); + return; + } + + Single>> r = getRepoModelAndAllPermissionSingle(repoModel.repo_id, isForce); + addSingleDisposable(r, new Consumer>>() { + @Override + public void accept(Pair> pair) throws Exception { + + multipleCacheRepoPermissionMapData(CollectionUtils.newArrayList(repoModel), pair.getSecond()); + + toParseMenu(context, menuId, disableMenuIds, removedMenuIds); + } + }); + } + + public void inflateDirentMenu(Context context) { + getPermissionStackMap().clear(); + + toParseMenu(context, R.menu.bottom_sheet_op_dirent, null, CollectionUtils.newArrayList(R.id.unstar)); + } + + public void inflateDirentMenuWithParams(Context context, List direntModels, boolean isChecked, List disableMenuIds, List removedMenuIds, boolean isForce) { + if (CollectionUtils.isEmpty(direntModels)) { + return; + } + + int menuId = R.menu.bottom_sheet_op_dirent; + + if (!isChecked) { + //remove permission + multipleRemoveCachedDirentPermissionMapData(direntModels); + + toParseMenu(context, menuId, disableMenuIds, removedMenuIds); + return; + } + + String repo_id = direntModels.get(0).repo_id; + + Single>> r = getRepoModelAndAllPermissionSingle(repo_id, isForce); + addSingleDisposable(r, new Consumer>>() { + @Override + public void accept(Pair> pair) throws Exception { + RepoModel repoModel = pair.getFirst(); + List permissionList = pair.getSecond(); - Single single = HttpIO.getCurrentInstance().execute(RepoService.class).unStar(repoId, path); - addSingleDisposable(single, new Consumer() { + multipleCacheDirentPermissionMapData(direntModels, permissionList); + + toParseMenu(context, menuId, disableMenuIds, removedMenuIds); + } + }); + } + + public void clearCachePermissionMap() { + getPermissionStackMap().clear(); + } + + private void multipleRemoveCachedDirentPermissionMapData(List direntModels) { + if (CollectionUtils.isEmpty(direntModels)) { + return; + } + + for (DirentModel direntModel : direntModels) { + removeCachedPermissionMapData(direntModel.permission, direntModel.uid); + } + } + + private void multipleRemoveCachedRepoPermissionMapData(List repoModels) { + if (CollectionUtils.isEmpty(repoModels)) { + return; + } + for (RepoModel repoModel : repoModels) { + removeCachedPermissionMapData(repoModel.permission, repoModel.repo_id); + } + } + + private void removeCachedPermissionMapData(String permission, String id) { + if (!getPermissionStackMap().containsKey(permission)) { + return; + } + + PermissionEntity entity = getPermissionStackMap().get(permission); + if (entity == null) { + return; + } + + if (!entity.hasId(id)) { + return; + } + + entity.removeById(id); + + // + if (entity.isEmptyIds()) { + getPermissionStackMap().remove(permission); + } + } + + private void multipleCacheDirentPermissionMapData(List models, List entities) { + if (CollectionUtils.isEmpty(models)) { + return; + } + + for (DirentModel model : models) { + if (!model.isCustomPermission()) { + cachePermissionMapData(model.permission, model, new PermissionEntity(model.repo_id, model.permission)); + } else { + entities.stream().filter(f -> f.id == model.getCustomPermissionNum()).findFirst().ifPresent(entity -> cachePermissionMapData(model.permission, model, entity)); + } + } + } + + private void multipleCacheRepoPermissionMapData(List models, List entities) { + if (CollectionUtils.isEmpty(models)) { + return; + } + + for (RepoModel model : models) { + if (!model.isCustomPermission()) { + cachePermissionMapData(model.permission, model, new PermissionEntity(model.repo_id, model.permission)); + } else { + entities.stream().filter(f -> f.id == model.getCustomPermissionNum()).findFirst().ifPresent(entity -> cachePermissionMapData(model.permission, model, entity)); + } + } + } + + private void cachePermissionMapData(String permission, BaseModel baseModel, @NonNull PermissionEntity entity) { + if (!getPermissionStackMap().containsKey(permission)) { + entity.cacheBaseModel(baseModel); + } else { + PermissionEntity entity1 = getPermissionStackMap().get(permission); + assert entity1 != null; + entity1.cacheBaseModel(baseModel); + } + + getPermissionStackMap().put(permission, entity); + } + + private void toParseMenu(Context context, int menuId, List disableMenuIds, List removedMenuIds) { + List permissionList = new ArrayList<>(getPermissionStackMap().values()); + List items = parseMenu(context, menuId, permissionList, disableMenuIds, removedMenuIds); + getMenuItemListLiveData().setValue(items); + } + + private List parseMenu(Context context, int menuId, List permissionList, List disableMenuIds, List removedMenuIds) { + List items = inflateMenu(context, menuId); + + //if no permission list, disable all menu + if (CollectionUtils.isEmpty(permissionList)) { + for (MenuItem item : items) { + item.setEnabled(false); + } + + if (!CollectionUtils.isEmpty(removedMenuIds)) { + items = items.stream().filter(item -> item.getItemId() != R.id.unstar).collect(Collectors.toList()); + } + return items; + } + + //enable firstly + for (MenuItem item : items) { + item.setEnabled(true); + } + + //to disable + for (MenuItem item : items) { + if (!item.isEnabled()) { + continue; + } + + if (item.getItemId() == R.id.rename) { + long l = permissionList.stream().filter(f -> !f.modify).count(); + item.setEnabled(!(l > 0)); + } else if (item.getItemId() == R.id.move) { + long l = permissionList.stream().filter(f -> !f.modify).count(); + item.setEnabled(!(l > 0)); + } else if (item.getItemId() == R.id.copy) { + long l = permissionList.stream().filter(f -> !f.copy).count(); + item.setEnabled(!(l > 0)); + } else if (item.getItemId() == R.id.delete) { + long l = permissionList.stream().filter(f -> !f.delete).count(); + item.setEnabled(!(l > 0)); + } else if (item.getItemId() == R.id.upload) { + long l = permissionList.stream().filter(f -> !f.upload).count(); + item.setEnabled(!(l > 0)); + } else if (item.getItemId() == R.id.download) { + long l = permissionList.stream().filter(f -> !f.download).count(); + item.setEnabled(!(l > 0)); + } else if (item.getItemId() == R.id.share) { + long l = permissionList.stream().filter(f -> !f.download_external_link).count(); + item.setEnabled(!(l > 0)); + } else if (item.getItemId() == R.id.export) { + long l = permissionList.stream().filter(f -> !f.download).count(); + item.setEnabled(!(l > 0)); + } else if (item.getItemId() == R.id.open) { + long l = permissionList.stream().filter(f -> !f.download).count(); + item.setEnabled(!(l > 0)); + } + + if (!CollectionUtils.isEmpty(disableMenuIds)) { + if (disableMenuIds.contains(item.getItemId())) { + item.setEnabled(false); + } + } + } + + if (!CollectionUtils.isEmpty(removedMenuIds)) { + items = items.stream().filter(item -> !removedMenuIds.contains(item.getItemId())).collect(Collectors.toList()); + } + + return items; + } + + private Single> getLoadRepoPermissionFromRemoteSingle(String repoId) { + Single single = HttpIO.getCurrentInstance().execute(RepoService.class).getCustomSharePermissions(repoId); + return single.flatMap(new Function>>() { + @Override + public SingleSource> apply(PermissionListWrapperModel wrapperModel) throws Exception { + + List list = CollectionUtils.newArrayList(); + + for (PermissionWrapperModel model : wrapperModel.permission_list) { + list.add(new PermissionEntity(repoId, model)); + } + + Completable insertCompletable = AppDatabase.getInstance().permissionDAO().insertAllAsync(list); + Single insertAllSingle = insertCompletable.toSingleDefault(0L); + return insertAllSingle.flatMap(new Function>>() { + @Override + public SingleSource> apply(Long aLong) throws Exception { + SLogs.d("The list has been inserted into the local database"); + return Single.just(list); + } + }); + } + }); + } + + private void loadPermissionFromRemote(String repoId) { + Single> r = getLoadRepoPermissionFromRemoteSingle(repoId); + + addSingleDisposable(r, new Consumer>() { + @Override + public void accept(List list) throws Exception { + SLogs.e("permission has been loaded"); + } + }); + } + + public void multiStarOrNot(List selectedList, boolean isStar) { + if (CollectionUtils.isEmpty(selectedList)) { + return; + } + + getShowLoadingDialogLiveData().setValue(true); + + List> singles = new ArrayList<>(); + for (BaseModel baseModel : selectedList) { + if (baseModel instanceof RepoModel m) { + + if (isStar == m.starred) { + continue; + } + + singles.add(getStarSingle(m.repo_id, "/", isStar)); + } else if (baseModel instanceof DirentModel m) { + if (isStar == m.starred) { + continue; + } + + singles.add(getStarSingle(m.repo_id, m.full_path, isStar)); + } + } + + if (CollectionUtils.isEmpty(singles)) { + getShowLoadingDialogLiveData().setValue(false); + return; + } + + Flowable flowable = Flowable.mergeDelayError(singles, 5, Flowable.bufferSize()); + addFlowableDisposable(flowable, new Consumer() { @Override - public void accept(ResultModel resultModel) throws Exception { - getStarLiveData().setValue(true); + public void accept(Object o) throws Exception { + if (o instanceof Dirent2Model dirent2Model) { + SLogs.d("dirent star success:" + dirent2Model); + } else if (o instanceof ResultModel resultModel) { + SLogs.d("repo star success:" + resultModel); + } } }, new Consumer() { @Override public void accept(Throwable throwable) throws Exception { - getRefreshLiveData().setValue(false); String errMsg = getErrorMsgByThrowable(throwable); ToastUtils.showLong(errMsg); } + }, new Action() { + @Override + public void run() throws Exception { + getShowLoadingDialogLiveData().setValue(false); + getStarredLiveData().setValue(true); + } }); + + + } + + private Flowable getStarSingle(String repoId, String path, boolean isStar) { + if (isStar) { + Map requestDataMap = new HashMap<>(); + requestDataMap.put("repo_id", repoId); + requestDataMap.put("path", path); + + Map bodyMap = generateRequestBody(requestDataMap); + Single single = HttpIO.getCurrentInstance().execute(StarredService.class).star(bodyMap); + + return single.toFlowable(); + } else { + Single single1 = HttpIO.getCurrentInstance().execute(StarredService.class).unStar(repoId, path); + return single1.toFlowable(); + } } } diff --git a/app/src/main/java/com/seafile/seadroid2/ui/sdoc/profile/SDocProfileDialog.java b/app/src/main/java/com/seafile/seadroid2/ui/sdoc/profile/SDocProfileDialog.java index d795dc554..a8d9086f7 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/sdoc/profile/SDocProfileDialog.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/sdoc/profile/SDocProfileDialog.java @@ -352,7 +352,7 @@ private int getIconByColumnType(String type) { case ColumnType.NUMBER: return R.drawable.ic_number; case ColumnType.RATE: - return R.drawable.ic_star2; + return R.drawable.ic_star_32; case ColumnType.URL: return R.drawable.ic_url; case ColumnType.LINK: @@ -642,7 +642,7 @@ private void parseRate(LinearLayout view, MetadataModel model) { ColorStateList stateList = ColorStateList.valueOf(t); ltr.setImageTintList(stateList); - ltr.setImageResource(R.drawable.ic_star2); + ltr.setImageResource(R.drawable.ic_star_32); view.findViewById(R.id.flex_box).addView(ltr, flexLayoutParams); } diff --git a/app/src/main/java/com/seafile/seadroid2/ui/search/Search2Activity.java b/app/src/main/java/com/seafile/seadroid2/ui/search/Search2Activity.java index 54ed1a95d..7e5265d6e 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/search/Search2Activity.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/search/Search2Activity.java @@ -157,7 +157,7 @@ public void onChanged(SeafException e) { } }); - getViewModel().getListLiveData().observe(this, new Observer>() { + getViewModel().getSearchListLiveData().observe(this, new Observer>() { @Override public void onChanged(List result) { if (CollectionUtils.isEmpty(result)) { @@ -348,7 +348,7 @@ private void loadNext(String query, boolean isRefresh) { page++; - getViewModel().loadNext(query, page, PAGE_SIZE); + getViewModel().searchNext(query, page, PAGE_SIZE); } public void onItemClick(SearchModel searchedFile) { diff --git a/app/src/main/java/com/seafile/seadroid2/ui/search/SearchViewModel.java b/app/src/main/java/com/seafile/seadroid2/ui/search/SearchViewModel.java index 0901259df..d36a252a5 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/search/SearchViewModel.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/search/SearchViewModel.java @@ -1,5 +1,7 @@ package com.seafile.seadroid2.ui.search; +import android.text.TextUtils; + import androidx.lifecycle.MutableLiveData; import com.blankj.utilcode.util.CollectionUtils; @@ -23,17 +25,21 @@ public class SearchViewModel extends BaseViewModel { private final MutableLiveData> mListLiveData = new MutableLiveData<>(); - public MutableLiveData> getListLiveData() { + public MutableLiveData> getSearchListLiveData() { return mListLiveData; } - public void loadNext(String q, int pageNo, int pageSize) { + public void searchNext(String q, int pageNo, int pageSize) { + if (TextUtils.isEmpty(q)){ + return; + } + getRefreshLiveData().setValue(true); Single single = HttpIO.getCurrentInstance().execute(SearchService.class).search("all", q, "all", pageNo, pageSize); addSingleDisposable(single, new Consumer() { @Override public void accept(SearchWrapperModel searchWrapperModel) throws Exception { - getListLiveData().setValue(searchWrapperModel.results); + getSearchListLiveData().setValue(searchWrapperModel.results); getRefreshLiveData().setValue(false); } }, new Consumer() { diff --git a/app/src/main/java/com/seafile/seadroid2/ui/selector/ObjSelectorActivity.java b/app/src/main/java/com/seafile/seadroid2/ui/selector/ObjSelectorActivity.java index db6e7db41..0bd581ed2 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/selector/ObjSelectorActivity.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/selector/ObjSelectorActivity.java @@ -21,13 +21,14 @@ import com.seafile.seadroid2.account.Account; import com.seafile.seadroid2.config.AbsLayoutItemType; import com.seafile.seadroid2.context.NavContext; +import com.seafile.seadroid2.databinding.ActivitySelectorObjBinding; import com.seafile.seadroid2.enums.FileViewType; import com.seafile.seadroid2.enums.RepoSelectType; import com.seafile.seadroid2.framework.data.db.entities.DirentModel; import com.seafile.seadroid2.framework.data.db.entities.EncKeyCacheEntity; +import com.seafile.seadroid2.framework.data.db.entities.PermissionEntity; import com.seafile.seadroid2.framework.data.db.entities.RepoModel; import com.seafile.seadroid2.framework.data.model.BaseModel; -import com.seafile.seadroid2.databinding.ActivitySelectorObjBinding; import com.seafile.seadroid2.ui.base.BaseActivity; import com.seafile.seadroid2.ui.dialog_fragment.NewDirFileDialogFragment; import com.seafile.seadroid2.ui.dialog_fragment.PasswordDialogFragment; @@ -188,7 +189,7 @@ private void initRv() { binding.rv.addItemDecoration(decoration); adapter = new RepoQuickAdapter(); - adapter.setSelectType(RepoSelectType.DIRENT); + adapter.setSelectType(RepoSelectType.FOLDER); adapter.setFileViewType(FileViewType.LIST); adapter.setOnItemClickListener((baseQuickAdapter, view, i) -> { @@ -271,29 +272,43 @@ public void onResultData(RepoModel uRepoModel) { dialogFragment.show(getSupportFragmentManager(), PasswordDialogFragment.class.getSimpleName()); } + private void checkCurrentPathHasWritePermission(java.util.function.Consumer consumer) { + DirentModel direntModel = mNavContext.getTopDirentModel(); + if (!direntModel.isCustomPermission()) { + consumer.accept(direntModel.hasWritePermission()); + } else { + viewModel.getPermissionFromLocal(direntModel.repo_id, direntModel.getCustomPermissionNum(), new Consumer() { + @Override + public void accept(PermissionEntity entity) throws Exception { + consumer.accept(entity != null && entity.create); + } + }); + } + } + + private void showNewDirDialog() { if (!mNavContext.inRepo()) { ToastUtils.showLong(R.string.choose_a_library); return; } - - if (!mNavContext.isParentHasWritePermission()) { - ToastUtils.showLong(R.string.library_read_only); - return; - } - - String rid = mNavContext.getRepoModel().repo_id; - String parentPath = mNavContext.getNavPath(); - NewDirFileDialogFragment dialogFragment = NewDirFileDialogFragment.newInstance(rid, parentPath, true); - dialogFragment.setRefreshListener(new OnRefreshDataListener() { + checkCurrentPathHasWritePermission(new java.util.function.Consumer() { @Override - public void onActionStatus(boolean isDone) { - if (isDone) { - loadData(); - } + public void accept(Boolean aBoolean) { + String rid = mNavContext.getRepoModel().repo_id; + String parentPath = mNavContext.getNavPath(); + NewDirFileDialogFragment dialogFragment = NewDirFileDialogFragment.newInstance(rid, parentPath, true); + dialogFragment.setRefreshListener(new OnRefreshDataListener() { + @Override + public void onActionStatus(boolean isDone) { + if (isDone) { + loadData(); + } + } + }); + dialogFragment.show(getSupportFragmentManager(), NewDirFileDialogFragment.class.getSimpleName()); } }); - dialogFragment.show(getSupportFragmentManager(), NewDirFileDialogFragment.class.getSimpleName()); } private void loadData() { diff --git a/app/src/main/java/com/seafile/seadroid2/ui/selector/ObjSelectorViewModel.java b/app/src/main/java/com/seafile/seadroid2/ui/selector/ObjSelectorViewModel.java index 7c9edde62..d1e4cd03b 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/selector/ObjSelectorViewModel.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/selector/ObjSelectorViewModel.java @@ -10,6 +10,9 @@ import com.seafile.seadroid2.framework.data.db.AppDatabase; import com.seafile.seadroid2.framework.data.db.entities.DirentModel; import com.seafile.seadroid2.framework.data.db.entities.EncKeyCacheEntity; +import com.seafile.seadroid2.framework.data.db.entities.PermissionEntity; +import com.seafile.seadroid2.framework.data.model.permission.PermissionListWrapperModel; +import com.seafile.seadroid2.framework.data.model.permission.PermissionWrapperModel; import com.seafile.seadroid2.ui.base.viewmodel.BaseViewModel; import com.seafile.seadroid2.context.NavContext; import com.seafile.seadroid2.framework.data.model.BaseModel; @@ -22,9 +25,13 @@ import java.util.ArrayList; import java.util.List; +import java.util.Optional; +import io.reactivex.Completable; import io.reactivex.Single; +import io.reactivex.SingleSource; import io.reactivex.functions.Consumer; +import io.reactivex.functions.Function; import kotlin.Pair; public class ObjSelectorViewModel extends BaseViewModel { @@ -114,4 +121,76 @@ public void accept(Throwable throwable) throws Exception { } }); } + + + public void getPermissionFromLocal(String repoId, int pNum, Consumer consumer) { + Single> pSingle = AppDatabase.getInstance().permissionDAO().getWithAsync(repoId, pNum); + Single s = pSingle.flatMap(new Function, SingleSource>() { + @Override + public SingleSource apply(List pList) throws Exception { + + if (CollectionUtils.isEmpty(pList)) { + return null; + } + + return Single.just(pList.get(0)); + } + }).flatMap(new Function>() { + @Override + public SingleSource apply(PermissionEntity entity) throws Exception { + Single> r = getLoadRepoPermissionFromRemoteSingle(repoId); + + return r.flatMap(new Function, SingleSource>() { + @Override + public SingleSource apply(List permissionEntities) throws Exception { + if (CollectionUtils.isEmpty(permissionEntities)) { + return null; + + } + Optional p = permissionEntities.stream().filter(f -> f.id == pNum).findFirst(); + if (p.isPresent()) { + return Single.just(p.get()); + } + return null; + } + }); + } + }); + + addSingleDisposable(s, new Consumer() { + @Override + public void accept(PermissionEntity entity) throws Exception { + if (consumer != null) { + consumer.accept(entity); + } + } + }); + } + + + private Single> getLoadRepoPermissionFromRemoteSingle(String repoId) { + Single single = HttpIO.getCurrentInstance().execute(RepoService.class).getCustomSharePermissions(repoId); + return single.flatMap(new Function>>() { + @Override + public SingleSource> apply(PermissionListWrapperModel wrapperModel) throws Exception { + + List list = CollectionUtils.newArrayList(); + + for (PermissionWrapperModel model : wrapperModel.permission_list) { + list.add(new PermissionEntity(repoId, model)); + } + + Completable insertCompletable = AppDatabase.getInstance().permissionDAO().insertAllAsync(list); + Single insertAllSingle = insertCompletable.toSingleDefault(0L); + return insertAllSingle.flatMap(new Function>>() { + @Override + public SingleSource> apply(Long aLong) throws Exception { + SLogs.d("The list has been inserted into the local database"); + return Single.just(list); + } + }); + } + }); + } + } diff --git a/app/src/main/java/com/seafile/seadroid2/ui/settings/TabSettingsFragment.java b/app/src/main/java/com/seafile/seadroid2/ui/settings/TabSettingsFragment.java index b083d5b5c..a80a83bdf 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/settings/TabSettingsFragment.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/settings/TabSettingsFragment.java @@ -239,9 +239,8 @@ private void initAlbumBackupPref() { mAlbumBackupAdvanced.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(@NonNull Preference preference) { - BackgroundJobManagerImpl.getInstance().startMediaChainWorker(true); -// Intent intent = new Intent(requireActivity(), SettingsAlbumBackupAdvancedActivity.class); -// albumBackupAdvanceLauncher.launch(intent); + Intent intent = new Intent(requireActivity(), SettingsAlbumBackupAdvancedActivity.class); + albumBackupAdvanceLauncher.launch(intent); return true; } }); diff --git a/app/src/main/java/com/seafile/seadroid2/ui/star/StarredQuickFragment.java b/app/src/main/java/com/seafile/seadroid2/ui/star/StarredQuickFragment.java index 4b799c2f3..d51578abf 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/star/StarredQuickFragment.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/star/StarredQuickFragment.java @@ -16,6 +16,7 @@ import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.OptIn; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; @@ -26,9 +27,11 @@ import com.seafile.seadroid2.SeafException; import com.seafile.seadroid2.account.Account; import com.seafile.seadroid2.account.SupportAccountManager; -import com.seafile.seadroid2.bottomsheetmenu.BottomSheetHelper; -import com.seafile.seadroid2.bottomsheetmenu.BottomSheetMenuFragment; -import com.seafile.seadroid2.bottomsheetmenu.OnMenuClickListener; +import com.seafile.seadroid2.annotation.Unstable; +import com.seafile.seadroid2.framework.datastore.sp.SettingsManager; +import com.seafile.seadroid2.ui.bottomsheetmenu.BottomSheetHelper; +import com.seafile.seadroid2.ui.bottomsheetmenu.BottomSheetMenuFragment; +import com.seafile.seadroid2.ui.bottomsheetmenu.OnMenuClickListener; import com.seafile.seadroid2.config.Constants; import com.seafile.seadroid2.databinding.LayoutFrameSwipeRvBinding; import com.seafile.seadroid2.framework.data.db.entities.StarredModel; @@ -94,8 +97,6 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat initViewModel(); } - private boolean isForce = false; - @Override public void onFirstResume() { super.onFirstResume(); @@ -103,13 +104,23 @@ public void onFirstResume() { } @Override - public void onResume() { - super.onResume(); - if (isForce) { + public void onOtherResume() { + super.onOtherResume(); + + if (isForce()) { reload(); } } + private boolean isForce() { + boolean isForce = SettingsManager.getForceRefreshStarredListState(); + if (isForce) { + SettingsManager.setForceRefreshStarredListState(false); + } + + return isForce; + } + private void initAdapter() { adapter = new StarredAdapter(); TextView tipView = TipsViews.getTipTextView(requireContext()); @@ -125,7 +136,7 @@ private void initAdapter() { }); - adapter.addOnItemChildClickListener(R.id.item_action, new BaseQuickAdapter.OnItemChildClickListener() { + adapter.addOnItemChildClickListener(R.id.expandable_toggle_button, new BaseQuickAdapter.OnItemChildClickListener() { @Override public void onItemClick(@NonNull BaseQuickAdapter baseQuickAdapter, @NonNull View view, int i) { showBottomSheet(adapter.getItems().get(i)); @@ -145,13 +156,6 @@ private void showErrorTip(SeafException seafException) { } private void initViewModel() { - mainViewModel.getOnForceRefreshStarredListLiveData().observe(getViewLifecycleOwner(), new Observer() { - @Override - public void onChanged(Boolean aBoolean) { - isForce = aBoolean; - } - }); - getViewModel().getRefreshLiveData().observe(getViewLifecycleOwner(), new Observer() { @Override public void onChanged(Boolean aBoolean) { @@ -210,7 +214,7 @@ public void onMenuClick(MenuItem menuItem) { builder.removeMenu(R.id.nav_to); } - builder.show(getChildFragmentManager()); + builder.show(getChildFragmentManager(), StarredQuickFragment.class.getSimpleName()); } private void navTo(StarredModel starredModel) { @@ -225,6 +229,7 @@ private void navTo(StarredModel starredModel) { } } + @OptIn(markerClass = Unstable.class) private void open(StarredModel model) { if (model.is_dir) { MainActivity.navToThis(requireContext(), model.repo_id, model.repo_name, model.path, model.is_dir); diff --git a/app/src/main/java/com/seafile/seadroid2/ui/star/StarredService.java b/app/src/main/java/com/seafile/seadroid2/ui/star/StarredService.java index de5a85f0a..0906c241f 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/star/StarredService.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/star/StarredService.java @@ -1,18 +1,30 @@ package com.seafile.seadroid2.ui.star; import com.seafile.seadroid2.framework.data.model.ResultModel; +import com.seafile.seadroid2.framework.data.model.repo.Dirent2Model; import com.seafile.seadroid2.framework.data.model.star.StarredWrapperModel; +import java.util.Map; + import io.reactivex.Single; +import okhttp3.RequestBody; +import retrofit2.http.Body; import retrofit2.http.DELETE; import retrofit2.http.GET; +import retrofit2.http.Multipart; +import retrofit2.http.POST; +import retrofit2.http.PartMap; import retrofit2.http.Query; public interface StarredService { @GET("api/v2.1/starred-items/") Single getStarItems(); + @Multipart + @POST("api/v2.1/starred-items/") + Single star(@PartMap Map map); + @DELETE("api/v2.1/starred-items/") - Single unStarItem(@Query("repo_id") String repoId, @Query("path") String path); + Single unStar(@Query("repo_id") String repoId, @Query("path") String path); } diff --git a/app/src/main/java/com/seafile/seadroid2/ui/star/StarredViewModel.java b/app/src/main/java/com/seafile/seadroid2/ui/star/StarredViewModel.java index edbf73af9..6aafb742d 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/star/StarredViewModel.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/star/StarredViewModel.java @@ -59,7 +59,7 @@ public void accept(Throwable throwable) throws Exception { } public void unStarItem(String repoId, String path) { - Single flowable = HttpIO.getCurrentInstance().execute(StarredService.class).unStarItem(repoId, path); + Single flowable = HttpIO.getCurrentInstance().execute(StarredService.class).unStar(repoId, path); addSingleDisposable(flowable, new Consumer() { @Override public void accept(ResultModel resultModel) throws Exception { diff --git a/app/src/main/java/com/seafile/seadroid2/ui/transfer_list/TransferActivity.java b/app/src/main/java/com/seafile/seadroid2/ui/transfer_list/TransferActivity.java index 4bcf3df8e..a393ca992 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/transfer_list/TransferActivity.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/transfer_list/TransferActivity.java @@ -29,8 +29,6 @@ public class TransferActivity extends BaseActivity implements Toolbar.OnMenuItem private TransferListLayoutBinding binding; private final List fragments = new ArrayList<>(); - private Menu overFlowMenu = null; - @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); @@ -156,16 +154,6 @@ public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) { } - @Override - public boolean onKeyUp(int keyCode, KeyEvent event) { - switch (keyCode) { - case KeyEvent.KEYCODE_MENU: - if (overFlowMenu != null) { - overFlowMenu.performIdentifierAction(R.id.transfer_overflow_menu, 0); - } - } - return super.onKeyUp(keyCode, event); - } @Override public boolean onCreateOptionsMenu(Menu menu) { diff --git a/app/src/main/java/com/seafile/seadroid2/ui/transfer_list/TransferListFragment.java b/app/src/main/java/com/seafile/seadroid2/ui/transfer_list/TransferListFragment.java index 387e846df..c8f764aeb 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/transfer_list/TransferListFragment.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/transfer_list/TransferListFragment.java @@ -25,8 +25,8 @@ import com.chad.library.adapter4.QuickAdapterHelper; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.seafile.seadroid2.R; -import com.seafile.seadroid2.bottomsheetmenu.BottomSheetHelper; -import com.seafile.seadroid2.bottomsheetmenu.BottomSheetMenuFragment; +import com.seafile.seadroid2.ui.bottomsheetmenu.BottomSheetHelper; +import com.seafile.seadroid2.ui.bottomsheetmenu.BottomSheetMenuFragment; import com.seafile.seadroid2.databinding.LayoutFrameSwipeRvBinding; import com.seafile.seadroid2.framework.data.db.entities.FileTransferEntity; import com.seafile.seadroid2.enums.TransferAction; diff --git a/app/src/main/res/color/selector_color_primary.xml b/app/src/main/res/color/selector_color_primary.xml index 617987d0c..de16632b6 100644 --- a/app/src/main/res/color/selector_color_primary.xml +++ b/app/src/main/res/color/selector_color_primary.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/file_audio.png b/app/src/main/res/drawable-hdpi/file_audio.png deleted file mode 100644 index c045a7aee..000000000 Binary files a/app/src/main/res/drawable-hdpi/file_audio.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/file_ms_excel.png b/app/src/main/res/drawable-hdpi/file_ms_excel.png deleted file mode 100644 index b455e282f..000000000 Binary files a/app/src/main/res/drawable-hdpi/file_ms_excel.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/file_ms_ppt.png b/app/src/main/res/drawable-hdpi/file_ms_ppt.png deleted file mode 100644 index 67e9cff16..000000000 Binary files a/app/src/main/res/drawable-hdpi/file_ms_ppt.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/file_ms_word.png b/app/src/main/res/drawable-hdpi/file_ms_word.png deleted file mode 100644 index a00455dd5..000000000 Binary files a/app/src/main/res/drawable-hdpi/file_ms_word.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/file_pdf.png b/app/src/main/res/drawable-hdpi/file_pdf.png deleted file mode 100644 index 480bd2cc6..000000000 Binary files a/app/src/main/res/drawable-hdpi/file_pdf.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/file_text.png b/app/src/main/res/drawable-hdpi/file_text.png deleted file mode 100644 index e44b6b3e3..000000000 Binary files a/app/src/main/res/drawable-hdpi/file_text.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/file_video.png b/app/src/main/res/drawable-hdpi/file_video.png deleted file mode 100644 index 858d057cd..000000000 Binary files a/app/src/main/res/drawable-hdpi/file_video.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_action_overflow.png b/app/src/main/res/drawable-hdpi/ic_action_overflow.png deleted file mode 100644 index 0f761b878..000000000 Binary files a/app/src/main/res/drawable-hdpi/ic_action_overflow.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_am_copy.png b/app/src/main/res/drawable-hdpi/ic_am_copy.png deleted file mode 100644 index 20a811859..000000000 Binary files a/app/src/main/res/drawable-hdpi/ic_am_copy.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_am_del.png b/app/src/main/res/drawable-hdpi/ic_am_del.png deleted file mode 100644 index 845b32da7..000000000 Binary files a/app/src/main/res/drawable-hdpi/ic_am_del.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_am_download.png b/app/src/main/res/drawable-hdpi/ic_am_download.png deleted file mode 100644 index 7c069e248..000000000 Binary files a/app/src/main/res/drawable-hdpi/ic_am_download.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_am_move.png b/app/src/main/res/drawable-hdpi/ic_am_move.png deleted file mode 100644 index 5d336a073..000000000 Binary files a/app/src/main/res/drawable-hdpi/ic_am_move.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_gallery_empty2.png b/app/src/main/res/drawable-hdpi/ic_gallery_empty2.png deleted file mode 100644 index 7658372fb..000000000 Binary files a/app/src/main/res/drawable-hdpi/ic_gallery_empty2.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_gallery_video_overlay.png b/app/src/main/res/drawable-hdpi/ic_gallery_video_overlay.png deleted file mode 100644 index 0e3370ee6..000000000 Binary files a/app/src/main/res/drawable-hdpi/ic_gallery_video_overlay.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_missing_thumbnail_picture.png b/app/src/main/res/drawable-hdpi/ic_missing_thumbnail_picture.png deleted file mode 100644 index 1baff71b2..000000000 Binary files a/app/src/main/res/drawable-hdpi/ic_missing_thumbnail_picture.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_missing_thumbnail_video.png b/app/src/main/res/drawable-hdpi/ic_missing_thumbnail_video.png deleted file mode 100644 index 9e9118e20..000000000 Binary files a/app/src/main/res/drawable-hdpi/ic_missing_thumbnail_video.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/icon_delete.png b/app/src/main/res/drawable-hdpi/icon_delete.png deleted file mode 100644 index 335dd5f1f..000000000 Binary files a/app/src/main/res/drawable-hdpi/icon_delete.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/file.png b/app/src/main/res/drawable-hdpi/icon_format_file.png similarity index 100% rename from app/src/main/res/drawable-hdpi/file.png rename to app/src/main/res/drawable-hdpi/icon_format_file.png diff --git a/app/src/main/res/drawable-hdpi/repo_encrypted.png b/app/src/main/res/drawable-hdpi/repo_encrypted.png deleted file mode 100644 index 3d2466611..000000000 Binary files a/app/src/main/res/drawable-hdpi/repo_encrypted.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/repo_readonly.png b/app/src/main/res/drawable-hdpi/repo_readonly.png deleted file mode 100644 index 1ef287b4e..000000000 Binary files a/app/src/main/res/drawable-hdpi/repo_readonly.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/search.png b/app/src/main/res/drawable-hdpi/search.png deleted file mode 100644 index cb83b2b1f..000000000 Binary files a/app/src/main/res/drawable-hdpi/search.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/sort.png b/app/src/main/res/drawable-hdpi/sort.png deleted file mode 100644 index b457021bd..000000000 Binary files a/app/src/main/res/drawable-hdpi/sort.png and /dev/null differ diff --git a/app/src/main/res/drawable-ldpi/file_audio.png b/app/src/main/res/drawable-ldpi/file_audio.png deleted file mode 100644 index a47353352..000000000 Binary files a/app/src/main/res/drawable-ldpi/file_audio.png and /dev/null differ diff --git a/app/src/main/res/drawable-ldpi/file_image.png b/app/src/main/res/drawable-ldpi/file_image.png deleted file mode 100644 index d5bfcc38e..000000000 Binary files a/app/src/main/res/drawable-ldpi/file_image.png and /dev/null differ diff --git a/app/src/main/res/drawable-ldpi/file_ms_excel.png b/app/src/main/res/drawable-ldpi/file_ms_excel.png deleted file mode 100644 index 7d11a4732..000000000 Binary files a/app/src/main/res/drawable-ldpi/file_ms_excel.png and /dev/null differ diff --git a/app/src/main/res/drawable-ldpi/file_ms_ppt.png b/app/src/main/res/drawable-ldpi/file_ms_ppt.png deleted file mode 100644 index c7edb7f43..000000000 Binary files a/app/src/main/res/drawable-ldpi/file_ms_ppt.png and /dev/null differ diff --git a/app/src/main/res/drawable-ldpi/file_ms_word.png b/app/src/main/res/drawable-ldpi/file_ms_word.png deleted file mode 100644 index 59d6b3f9e..000000000 Binary files a/app/src/main/res/drawable-ldpi/file_ms_word.png and /dev/null differ diff --git a/app/src/main/res/drawable-ldpi/file_pdf.png b/app/src/main/res/drawable-ldpi/file_pdf.png deleted file mode 100644 index d520079f0..000000000 Binary files a/app/src/main/res/drawable-ldpi/file_pdf.png and /dev/null differ diff --git a/app/src/main/res/drawable-ldpi/file_text.png b/app/src/main/res/drawable-ldpi/file_text.png deleted file mode 100644 index a69b0f14f..000000000 Binary files a/app/src/main/res/drawable-ldpi/file_text.png and /dev/null differ diff --git a/app/src/main/res/drawable-ldpi/file_video.png b/app/src/main/res/drawable-ldpi/file_video.png deleted file mode 100644 index 24d0a61b4..000000000 Binary files a/app/src/main/res/drawable-ldpi/file_video.png and /dev/null differ diff --git a/app/src/main/res/drawable-ldpi/file.png b/app/src/main/res/drawable-ldpi/icon_format_file.png similarity index 100% rename from app/src/main/res/drawable-ldpi/file.png rename to app/src/main/res/drawable-ldpi/icon_format_file.png diff --git a/app/src/main/res/drawable-ldpi/search.png b/app/src/main/res/drawable-ldpi/search.png deleted file mode 100644 index d60aa712b..000000000 Binary files a/app/src/main/res/drawable-ldpi/search.png and /dev/null differ diff --git a/app/src/main/res/drawable-ldpi/sort.png b/app/src/main/res/drawable-ldpi/sort.png deleted file mode 100644 index f301587e0..000000000 Binary files a/app/src/main/res/drawable-ldpi/sort.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/btn_check_buttonless_off.png b/app/src/main/res/drawable-mdpi/btn_check_buttonless_off.png deleted file mode 100755 index bf588869b..000000000 Binary files a/app/src/main/res/drawable-mdpi/btn_check_buttonless_off.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/btn_check_buttonless_on.png b/app/src/main/res/drawable-mdpi/btn_check_buttonless_on.png deleted file mode 100755 index 324a6b0b1..000000000 Binary files a/app/src/main/res/drawable-mdpi/btn_check_buttonless_on.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/file_audio.png b/app/src/main/res/drawable-mdpi/file_audio.png deleted file mode 100644 index 3ccbd026e..000000000 Binary files a/app/src/main/res/drawable-mdpi/file_audio.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/file_image.png b/app/src/main/res/drawable-mdpi/file_image.png deleted file mode 100644 index 83e796347..000000000 Binary files a/app/src/main/res/drawable-mdpi/file_image.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/file_ms_excel.png b/app/src/main/res/drawable-mdpi/file_ms_excel.png deleted file mode 100644 index 491af9590..000000000 Binary files a/app/src/main/res/drawable-mdpi/file_ms_excel.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/file_ms_ppt.png b/app/src/main/res/drawable-mdpi/file_ms_ppt.png deleted file mode 100644 index fb028eaf8..000000000 Binary files a/app/src/main/res/drawable-mdpi/file_ms_ppt.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/file_ms_word.png b/app/src/main/res/drawable-mdpi/file_ms_word.png deleted file mode 100644 index 501d1ba8b..000000000 Binary files a/app/src/main/res/drawable-mdpi/file_ms_word.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/file_pdf.png b/app/src/main/res/drawable-mdpi/file_pdf.png deleted file mode 100644 index aa3715b1b..000000000 Binary files a/app/src/main/res/drawable-mdpi/file_pdf.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/file_text.png b/app/src/main/res/drawable-mdpi/file_text.png deleted file mode 100644 index 094ce919c..000000000 Binary files a/app/src/main/res/drawable-mdpi/file_text.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/file_video.png b/app/src/main/res/drawable-mdpi/file_video.png deleted file mode 100644 index d35d72bdf..000000000 Binary files a/app/src/main/res/drawable-mdpi/file_video.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_action_overflow.png b/app/src/main/res/drawable-mdpi/ic_action_overflow.png deleted file mode 100644 index 02023ca08..000000000 Binary files a/app/src/main/res/drawable-mdpi/ic_action_overflow.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_am_copy.png b/app/src/main/res/drawable-mdpi/ic_am_copy.png deleted file mode 100644 index f21a2f6b2..000000000 Binary files a/app/src/main/res/drawable-mdpi/ic_am_copy.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_am_del.png b/app/src/main/res/drawable-mdpi/ic_am_del.png deleted file mode 100644 index 99d5863a6..000000000 Binary files a/app/src/main/res/drawable-mdpi/ic_am_del.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_am_download.png b/app/src/main/res/drawable-mdpi/ic_am_download.png deleted file mode 100644 index e311dcea4..000000000 Binary files a/app/src/main/res/drawable-mdpi/ic_am_download.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_am_move.png b/app/src/main/res/drawable-mdpi/ic_am_move.png deleted file mode 100644 index 6324bc4bf..000000000 Binary files a/app/src/main/res/drawable-mdpi/ic_am_move.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_error_mms_video_overlay.png b/app/src/main/res/drawable-mdpi/ic_error_mms_video_overlay.png deleted file mode 100644 index 4f50072cc..000000000 Binary files a/app/src/main/res/drawable-mdpi/ic_error_mms_video_overlay.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_gallery_empty2.png b/app/src/main/res/drawable-mdpi/ic_gallery_empty2.png deleted file mode 100644 index f950e08e6..000000000 Binary files a/app/src/main/res/drawable-mdpi/ic_gallery_empty2.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_gallery_video_overlay.png b/app/src/main/res/drawable-mdpi/ic_gallery_video_overlay.png deleted file mode 100644 index ae263a725..000000000 Binary files a/app/src/main/res/drawable-mdpi/ic_gallery_video_overlay.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_missing_thumbnail_picture.png b/app/src/main/res/drawable-mdpi/ic_missing_thumbnail_picture.png deleted file mode 100644 index e938a339b..000000000 Binary files a/app/src/main/res/drawable-mdpi/ic_missing_thumbnail_picture.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_missing_thumbnail_video.png b/app/src/main/res/drawable-mdpi/ic_missing_thumbnail_video.png deleted file mode 100644 index 3ab50992d..000000000 Binary files a/app/src/main/res/drawable-mdpi/ic_missing_thumbnail_video.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/file.png b/app/src/main/res/drawable-mdpi/icon_format_file.png similarity index 100% rename from app/src/main/res/drawable-mdpi/file.png rename to app/src/main/res/drawable-mdpi/icon_format_file.png diff --git a/app/src/main/res/drawable-mdpi/search.png b/app/src/main/res/drawable-mdpi/search.png deleted file mode 100644 index 71d42c00f..000000000 Binary files a/app/src/main/res/drawable-mdpi/search.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/sort.png b/app/src/main/res/drawable-mdpi/sort.png deleted file mode 100644 index b0f933c89..000000000 Binary files a/app/src/main/res/drawable-mdpi/sort.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/add_file.png b/app/src/main/res/drawable-xhdpi/add_file.png deleted file mode 100755 index a384a34db..000000000 Binary files a/app/src/main/res/drawable-xhdpi/add_file.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/file_audio.png b/app/src/main/res/drawable-xhdpi/file_audio.png deleted file mode 100644 index 7fb6da7f3..000000000 Binary files a/app/src/main/res/drawable-xhdpi/file_audio.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/file_image.png b/app/src/main/res/drawable-xhdpi/file_image.png deleted file mode 100644 index 1bc343f4e..000000000 Binary files a/app/src/main/res/drawable-xhdpi/file_image.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/file_ms_excel.png b/app/src/main/res/drawable-xhdpi/file_ms_excel.png deleted file mode 100644 index bb503ea10..000000000 Binary files a/app/src/main/res/drawable-xhdpi/file_ms_excel.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/file_ms_ppt.png b/app/src/main/res/drawable-xhdpi/file_ms_ppt.png deleted file mode 100644 index e59799633..000000000 Binary files a/app/src/main/res/drawable-xhdpi/file_ms_ppt.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/file_ms_word.png b/app/src/main/res/drawable-xhdpi/file_ms_word.png deleted file mode 100644 index 38a039b6d..000000000 Binary files a/app/src/main/res/drawable-xhdpi/file_ms_word.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/file_pdf.png b/app/src/main/res/drawable-xhdpi/file_pdf.png deleted file mode 100644 index a85003535..000000000 Binary files a/app/src/main/res/drawable-xhdpi/file_pdf.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/file_text.png b/app/src/main/res/drawable-xhdpi/file_text.png deleted file mode 100644 index dbf8d8fbc..000000000 Binary files a/app/src/main/res/drawable-xhdpi/file_text.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/file_video.png b/app/src/main/res/drawable-xhdpi/file_video.png deleted file mode 100644 index c1beff3d3..000000000 Binary files a/app/src/main/res/drawable-xhdpi/file_video.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_action_overflow.png b/app/src/main/res/drawable-xhdpi/ic_action_overflow.png deleted file mode 100644 index ddac0e6a5..000000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_action_overflow.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_am_copy.png b/app/src/main/res/drawable-xhdpi/ic_am_copy.png deleted file mode 100644 index f2a39261e..000000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_am_copy.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_am_del.png b/app/src/main/res/drawable-xhdpi/ic_am_del.png deleted file mode 100644 index 69106ab4d..000000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_am_del.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_am_download.png b/app/src/main/res/drawable-xhdpi/ic_am_download.png deleted file mode 100644 index 3494a82f5..000000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_am_download.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_am_move.png b/app/src/main/res/drawable-xhdpi/ic_am_move.png deleted file mode 100644 index 72f6b068b..000000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_am_move.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/icon_delete.png b/app/src/main/res/drawable-xhdpi/icon_delete.png deleted file mode 100644 index fad4a8ba7..000000000 Binary files a/app/src/main/res/drawable-xhdpi/icon_delete.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/file.png b/app/src/main/res/drawable-xhdpi/icon_format_file.png similarity index 100% rename from app/src/main/res/drawable-xhdpi/file.png rename to app/src/main/res/drawable-xhdpi/icon_format_file.png diff --git a/app/src/main/res/drawable-xhdpi/repo_encrypted.png b/app/src/main/res/drawable-xhdpi/repo_encrypted.png deleted file mode 100644 index a600c7369..000000000 Binary files a/app/src/main/res/drawable-xhdpi/repo_encrypted.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/repo_readonly.png b/app/src/main/res/drawable-xhdpi/repo_readonly.png deleted file mode 100644 index c8e705dc5..000000000 Binary files a/app/src/main/res/drawable-xhdpi/repo_readonly.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/search.png b/app/src/main/res/drawable-xhdpi/search.png deleted file mode 100644 index 0dfbcdc1b..000000000 Binary files a/app/src/main/res/drawable-xhdpi/search.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/sort.png b/app/src/main/res/drawable-xhdpi/sort.png deleted file mode 100644 index 7503e9e59..000000000 Binary files a/app/src/main/res/drawable-xhdpi/sort.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/add_file.png b/app/src/main/res/drawable-xxhdpi/add_file.png deleted file mode 100644 index 18e434ff8..000000000 Binary files a/app/src/main/res/drawable-xxhdpi/add_file.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_overflow.png b/app/src/main/res/drawable-xxhdpi/ic_action_overflow.png deleted file mode 100644 index 035ffa0b4..000000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_action_overflow.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_save.png b/app/src/main/res/drawable-xxhdpi/ic_action_save.png deleted file mode 100644 index c7bf6c2bb..000000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_action_save.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_am_copy.png b/app/src/main/res/drawable-xxhdpi/ic_am_copy.png deleted file mode 100644 index 0ee263cad..000000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_am_copy.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_am_del.png b/app/src/main/res/drawable-xxhdpi/ic_am_del.png deleted file mode 100644 index c28bf4b23..000000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_am_del.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_am_download.png b/app/src/main/res/drawable-xxhdpi/ic_am_download.png deleted file mode 100644 index 058e85622..000000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_am_download.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_am_move.png b/app/src/main/res/drawable-xxhdpi/ic_am_move.png deleted file mode 100644 index 2eb941393..000000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_am_move.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_delete.png b/app/src/main/res/drawable-xxhdpi/icon_delete.png deleted file mode 100644 index 3b92b64ec..000000000 Binary files a/app/src/main/res/drawable-xxhdpi/icon_delete.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/repo_encrypted.png b/app/src/main/res/drawable-xxhdpi/repo_encrypted.png deleted file mode 100644 index 19d86d139..000000000 Binary files a/app/src/main/res/drawable-xxhdpi/repo_encrypted.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/repo_readonly.png b/app/src/main/res/drawable-xxhdpi/repo_readonly.png deleted file mode 100644 index 1b32bb684..000000000 Binary files a/app/src/main/res/drawable-xxhdpi/repo_readonly.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/search.png b/app/src/main/res/drawable-xxhdpi/search.png deleted file mode 100644 index c7dfd9bd4..000000000 Binary files a/app/src/main/res/drawable-xxhdpi/search.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/sort.png b/app/src/main/res/drawable-xxhdpi/sort.png deleted file mode 100644 index 9fdcb1269..000000000 Binary files a/app/src/main/res/drawable-xxhdpi/sort.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_action_overflow.png b/app/src/main/res/drawable-xxxhdpi/ic_action_overflow.png deleted file mode 100644 index 9db0e1283..000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_action_overflow.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_action_redo.png b/app/src/main/res/drawable-xxxhdpi/ic_action_redo.png deleted file mode 100644 index f7efbf5d4..000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_action_redo.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_action_undo.png b/app/src/main/res/drawable-xxxhdpi/ic_action_undo.png deleted file mode 100644 index 68277ba2a..000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_action_undo.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_am_copy.png b/app/src/main/res/drawable-xxxhdpi/ic_am_copy.png deleted file mode 100644 index 361bbdeac..000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_am_copy.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_am_del.png b/app/src/main/res/drawable-xxxhdpi/ic_am_del.png deleted file mode 100644 index 4ec5c6352..000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_am_del.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_am_download.png b/app/src/main/res/drawable-xxxhdpi/ic_am_download.png deleted file mode 100644 index 42899321f..000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_am_download.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_am_move.png b/app/src/main/res/drawable-xxxhdpi/ic_am_move.png deleted file mode 100644 index 52d3931ca..000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_am_move.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_extended_css.png b/app/src/main/res/drawable-xxxhdpi/icon_extended_css.png deleted file mode 100644 index 3cfbacac0..000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/icon_extended_css.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_extended_doc.png b/app/src/main/res/drawable-xxxhdpi/icon_extended_doc.png deleted file mode 100644 index 3740f001a..000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/icon_extended_doc.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_extended_file.png b/app/src/main/res/drawable-xxxhdpi/icon_extended_file.png deleted file mode 100644 index 6e67ca0da..000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/icon_extended_file.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_extended_md.png b/app/src/main/res/drawable-xxxhdpi/icon_extended_md.png deleted file mode 100644 index 9b8455a78..000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/icon_extended_md.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_extended_mov.png b/app/src/main/res/drawable-xxxhdpi/icon_extended_mov.png deleted file mode 100644 index 55b19048c..000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/icon_extended_mov.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_extended_mp3.png b/app/src/main/res/drawable-xxxhdpi/icon_extended_mp3.png deleted file mode 100644 index eb6063997..000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/icon_extended_mp3.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_extended_pdf.png b/app/src/main/res/drawable-xxxhdpi/icon_extended_pdf.png deleted file mode 100644 index 9495b2cc2..000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/icon_extended_pdf.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_extended_png.png b/app/src/main/res/drawable-xxxhdpi/icon_extended_png.png deleted file mode 100644 index 2e4bd3bb6..000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/icon_extended_png.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_extended_ppt.png b/app/src/main/res/drawable-xxxhdpi/icon_extended_ppt.png deleted file mode 100644 index cda6e1260..000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/icon_extended_ppt.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_extended_psd.png b/app/src/main/res/drawable-xxxhdpi/icon_extended_psd.png deleted file mode 100644 index 6de733bc7..000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/icon_extended_psd.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_extended_sdoc.png b/app/src/main/res/drawable-xxxhdpi/icon_extended_sdoc.png deleted file mode 100644 index fe0c1e820..000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/icon_extended_sdoc.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_extended_txt.png b/app/src/main/res/drawable-xxxhdpi/icon_extended_txt.png deleted file mode 100644 index db0cdf290..000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/icon_extended_txt.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_extended_xls.png b/app/src/main/res/drawable-xxxhdpi/icon_extended_xls.png deleted file mode 100644 index 8de2791e7..000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/icon_extended_xls.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_extended_zip.png b/app/src/main/res/drawable-xxxhdpi/icon_extended_zip.png deleted file mode 100644 index 597db92c0..000000000 Binary files a/app/src/main/res/drawable-xxxhdpi/icon_extended_zip.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_format_css.png b/app/src/main/res/drawable-xxxhdpi/icon_format_css.png new file mode 100644 index 000000000..152fdb2a8 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_format_css.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_format_excel.png b/app/src/main/res/drawable-xxxhdpi/icon_format_excel.png new file mode 100644 index 000000000..8b37fcd60 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_format_excel.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_format_file.png b/app/src/main/res/drawable-xxxhdpi/icon_format_file.png new file mode 100644 index 000000000..c2d45a8d1 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_format_file.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_format_md.png b/app/src/main/res/drawable-xxxhdpi/icon_format_md.png new file mode 100644 index 000000000..365e29ea5 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_format_md.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_format_music.png b/app/src/main/res/drawable-xxxhdpi/icon_format_music.png new file mode 100644 index 000000000..067a149a1 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_format_music.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_format_pdf.png b/app/src/main/res/drawable-xxxhdpi/icon_format_pdf.png new file mode 100644 index 000000000..6390dd4db Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_format_pdf.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_format_pic.png b/app/src/main/res/drawable-xxxhdpi/icon_format_pic.png new file mode 100644 index 000000000..ab86222b0 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_format_pic.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_format_ppt.png b/app/src/main/res/drawable-xxxhdpi/icon_format_ppt.png new file mode 100644 index 000000000..fd28d2c93 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_format_ppt.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_format_psd.png b/app/src/main/res/drawable-xxxhdpi/icon_format_psd.png new file mode 100644 index 000000000..d6b4e6219 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_format_psd.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_format_sdoc.png b/app/src/main/res/drawable-xxxhdpi/icon_format_sdoc.png new file mode 100644 index 000000000..7b4d90357 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_format_sdoc.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_format_txt.png b/app/src/main/res/drawable-xxxhdpi/icon_format_txt.png new file mode 100644 index 000000000..43b660a8e Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_format_txt.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_format_video.png b/app/src/main/res/drawable-xxxhdpi/icon_format_video.png new file mode 100644 index 000000000..33d6e8a55 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_format_video.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_format_word.png b/app/src/main/res/drawable-xxxhdpi/icon_format_word.png new file mode 100644 index 000000000..8132ff79b Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_format_word.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_format_zip.png b/app/src/main/res/drawable-xxxhdpi/icon_format_zip.png new file mode 100644 index 000000000..12c5cfd60 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_format_zip.png differ diff --git a/app/src/main/res/drawable/baseline_activities_24.xml b/app/src/main/res/drawable/baseline_activities_24.xml deleted file mode 100644 index 999954588..000000000 --- a/app/src/main/res/drawable/baseline_activities_24.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - diff --git a/app/src/main/res/drawable/baseline_activities_32.xml b/app/src/main/res/drawable/baseline_activities_32.xml new file mode 100644 index 000000000..ecbaf9600 --- /dev/null +++ b/app/src/main/res/drawable/baseline_activities_32.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/baseline_activities_bold_24.xml b/app/src/main/res/drawable/baseline_activities_bold_24.xml deleted file mode 100644 index c78f2f5df..000000000 --- a/app/src/main/res/drawable/baseline_activities_bold_24.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - diff --git a/app/src/main/res/drawable/baseline_add_24.xml b/app/src/main/res/drawable/baseline_add_24.xml index f0e955833..63c79f09e 100644 --- a/app/src/main/res/drawable/baseline_add_24.xml +++ b/app/src/main/res/drawable/baseline_add_24.xml @@ -4,6 +4,6 @@ android:viewportWidth="24" android:viewportHeight="24"> diff --git a/app/src/main/res/drawable/baseline_arrow_back_24.xml b/app/src/main/res/drawable/baseline_arrow_back_24.xml index 2f142289d..b35bd4d7a 100644 --- a/app/src/main/res/drawable/baseline_arrow_back_24.xml +++ b/app/src/main/res/drawable/baseline_arrow_back_24.xml @@ -5,6 +5,6 @@ android:viewportWidth="24" android:viewportHeight="24"> diff --git a/app/src/main/res/drawable/baseline_arrow_forward_24.xml b/app/src/main/res/drawable/baseline_arrow_forward_24.xml index 6710c2253..17d33ccec 100644 --- a/app/src/main/res/drawable/baseline_arrow_forward_24.xml +++ b/app/src/main/res/drawable/baseline_arrow_forward_24.xml @@ -5,6 +5,6 @@ android:viewportWidth="24" android:viewportHeight="24"> diff --git a/app/src/main/res/drawable/baseline_delete_20.xml b/app/src/main/res/drawable/baseline_delete_20.xml deleted file mode 100644 index 08172bb13..000000000 --- a/app/src/main/res/drawable/baseline_delete_20.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - diff --git a/app/src/main/res/drawable/baseline_edit_24.xml b/app/src/main/res/drawable/baseline_edit_24.xml index 8e18d509d..7598117c7 100644 --- a/app/src/main/res/drawable/baseline_edit_24.xml +++ b/app/src/main/res/drawable/baseline_edit_24.xml @@ -5,5 +5,5 @@ android:viewportHeight="24"> + android:fillColor="#999999"/> diff --git a/app/src/main/res/drawable/baseline_expandable_24.xml b/app/src/main/res/drawable/baseline_expandable_24.xml deleted file mode 100644 index 4f2c72d8e..000000000 --- a/app/src/main/res/drawable/baseline_expandable_24.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - diff --git a/app/src/main/res/drawable/baseline_folder_24.xml b/app/src/main/res/drawable/baseline_folder_24.xml index dd89a805c..a134eee6a 100644 --- a/app/src/main/res/drawable/baseline_folder_24.xml +++ b/app/src/main/res/drawable/baseline_folder_24.xml @@ -6,11 +6,9 @@ + android:strokeColor="#999999"/> + android:strokeColor="#999999"/> diff --git a/app/src/main/res/drawable/baseline_folder_read_only_24.xml b/app/src/main/res/drawable/baseline_folder_read_only_24.xml index 469d6dfdd..b64b14455 100644 --- a/app/src/main/res/drawable/baseline_folder_read_only_24.xml +++ b/app/src/main/res/drawable/baseline_folder_read_only_24.xml @@ -10,15 +10,13 @@ + android:strokeColor="#999999"/> + android:strokeColor="#999999"/> diff --git a/app/src/main/res/drawable/baseline_libraries_32.xml b/app/src/main/res/drawable/baseline_libraries_32.xml new file mode 100644 index 000000000..873b5a0b9 --- /dev/null +++ b/app/src/main/res/drawable/baseline_libraries_32.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/baseline_more_vert_24.xml b/app/src/main/res/drawable/baseline_more_vert_24.xml index 59dbd60f5..7bf4a0055 100644 --- a/app/src/main/res/drawable/baseline_more_vert_24.xml +++ b/app/src/main/res/drawable/baseline_more_vert_24.xml @@ -4,6 +4,6 @@ android:viewportWidth="24" android:viewportHeight="24"> diff --git a/app/src/main/res/drawable/baseline_repo_bold_24.xml b/app/src/main/res/drawable/baseline_repo_bold_24.xml index df4e2588d..6be907ce2 100644 --- a/app/src/main/res/drawable/baseline_repo_bold_24.xml +++ b/app/src/main/res/drawable/baseline_repo_bold_24.xml @@ -8,34 +8,34 @@ android:strokeLineJoin="round" android:strokeWidth="1.3" android:fillColor="#00000000" - android:strokeColor="@color/bar_icon_tint_color" + android:strokeColor="#999999" android:strokeLineCap="round"/> diff --git a/app/src/main/res/drawable/baseline_repo_bold_32.xml b/app/src/main/res/drawable/baseline_repo_bold_32.xml new file mode 100644 index 000000000..a09df8cb4 --- /dev/null +++ b/app/src/main/res/drawable/baseline_repo_bold_32.xml @@ -0,0 +1,41 @@ + + + + + + + diff --git a/app/src/main/res/drawable/baseline_repo_encrypted_24.xml b/app/src/main/res/drawable/baseline_repo_encrypted_24.xml index e4e2b5536..e10b83090 100644 --- a/app/src/main/res/drawable/baseline_repo_encrypted_24.xml +++ b/app/src/main/res/drawable/baseline_repo_encrypted_24.xml @@ -17,7 +17,7 @@ android:strokeLineJoin="round" android:strokeWidth="1" android:fillColor="#00000000" - android:strokeColor="@color/item_icon_tint_color" + android:strokeColor="#999999" android:strokeLineCap="round"/> @@ -28,7 +28,7 @@ android:strokeLineJoin="round" android:strokeWidth="1" android:fillColor="#00000000" - android:strokeColor="@color/item_icon_tint_color" + android:strokeColor="#999999" android:strokeLineCap="round"/> @@ -39,7 +39,7 @@ android:strokeLineJoin="round" android:strokeWidth="1" android:fillColor="#00000000" - android:strokeColor="@color/item_icon_tint_color" + android:strokeColor="#999999" android:strokeLineCap="round"/> @@ -50,7 +50,7 @@ android:strokeLineJoin="round" android:strokeWidth="1" android:fillColor="#00000000" - android:strokeColor="@color/item_icon_tint_color" + android:strokeColor="#999999" android:strokeLineCap="round"/> @@ -61,7 +61,7 @@ android:strokeLineJoin="round" android:strokeWidth="1" android:fillColor="#00000000" - android:strokeColor="@color/item_icon_tint_color" + android:strokeColor="#999999" android:strokeLineCap="round"/> @@ -71,20 +71,20 @@ android:strokeLineJoin="round" android:strokeWidth="1" android:fillColor="#00000000" - android:strokeColor="@color/item_icon_tint_color" + android:strokeColor="#999999" android:strokeLineCap="round"/> diff --git a/app/src/main/res/drawable/baseline_repo_readonly_24.xml b/app/src/main/res/drawable/baseline_repo_readonly_24.xml index fa02eeeed..e78b31668 100644 --- a/app/src/main/res/drawable/baseline_repo_readonly_24.xml +++ b/app/src/main/res/drawable/baseline_repo_readonly_24.xml @@ -17,7 +17,7 @@ android:strokeLineJoin="round" android:strokeWidth="1" android:fillColor="#00000000" - android:strokeColor="@color/item_icon_tint_color" + android:strokeColor="#999999" android:strokeLineCap="round"/> @@ -28,7 +28,7 @@ android:strokeLineJoin="round" android:strokeWidth="1" android:fillColor="#00000000" - android:strokeColor="@color/item_icon_tint_color" + android:strokeColor="#999999" android:strokeLineCap="round"/> @@ -39,7 +39,7 @@ android:strokeLineJoin="round" android:strokeWidth="1" android:fillColor="#00000000" - android:strokeColor="@color/item_icon_tint_color" + android:strokeColor="#999999" android:strokeLineCap="round"/> @@ -50,7 +50,7 @@ android:strokeLineJoin="round" android:strokeWidth="1" android:fillColor="#00000000" - android:strokeColor="@color/item_icon_tint_color" + android:strokeColor="#999999" android:strokeLineCap="round"/> @@ -61,7 +61,7 @@ android:strokeLineJoin="round" android:strokeWidth="1" android:fillColor="#00000000" - android:strokeColor="@color/item_icon_tint_color" + android:strokeColor="#999999" android:strokeLineCap="round"/> @@ -71,27 +71,27 @@ android:strokeLineJoin="round" android:strokeWidth="1" android:fillColor="#00000000" - android:strokeColor="@color/item_icon_tint_color" + android:strokeColor="#999999" android:strokeLineCap="round"/> diff --git a/app/src/main/res/drawable/baseline_schedule_24.xml b/app/src/main/res/drawable/baseline_schedule_24.xml deleted file mode 100644 index 0c89ae89c..000000000 --- a/app/src/main/res/drawable/baseline_schedule_24.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - diff --git a/app/src/main/res/drawable/baseline_search_24.xml b/app/src/main/res/drawable/baseline_search_24.xml index 968087902..9e4d91f15 100644 --- a/app/src/main/res/drawable/baseline_search_24.xml +++ b/app/src/main/res/drawable/baseline_search_24.xml @@ -6,8 +6,7 @@ + android:fillColor="#999999" + android:pathData="M9.901,15.683C12.794,15.683 15.139,13.329 15.139,10.425C15.139,7.522 12.794,5.168 9.901,5.168C7.009,5.168 4.664,7.522 4.664,10.425C4.664,13.329 7.009,15.683 9.901,15.683ZM14.849,14.502L20.08,19.753C20.307,19.981 20.307,20.351 20.08,20.579C19.852,20.807 19.484,20.807 19.257,20.579L14.032,15.334C12.917,16.28 11.475,16.851 9.901,16.851C6.366,16.851 3.5,13.974 3.5,10.425C3.5,6.877 6.366,4 9.901,4C13.436,4 16.302,6.877 16.302,10.425C16.302,11.973 15.757,13.393 14.849,14.502Z" /> diff --git a/app/src/main/res/drawable/baseline_settings_24.xml b/app/src/main/res/drawable/baseline_settings_24.xml deleted file mode 100644 index 294213597..000000000 --- a/app/src/main/res/drawable/baseline_settings_24.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - diff --git a/app/src/main/res/drawable/baseline_settings_32.xml b/app/src/main/res/drawable/baseline_settings_32.xml new file mode 100644 index 000000000..1092217d1 --- /dev/null +++ b/app/src/main/res/drawable/baseline_settings_32.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/baseline_sort_24.xml b/app/src/main/res/drawable/baseline_sort_24.xml index f5fbabdd8..9fe129669 100644 --- a/app/src/main/res/drawable/baseline_sort_24.xml +++ b/app/src/main/res/drawable/baseline_sort_24.xml @@ -4,6 +4,6 @@ android:viewportWidth="24" android:viewportHeight="24"> diff --git a/app/src/main/res/drawable/baseline_star_24.xml b/app/src/main/res/drawable/baseline_star_24.xml deleted file mode 100644 index 7cf531d99..000000000 --- a/app/src/main/res/drawable/baseline_star_24.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/baseline_star_outline_24.xml b/app/src/main/res/drawable/baseline_star_outline_24.xml index 2de43f65e..0735fb743 100644 --- a/app/src/main/res/drawable/baseline_star_outline_24.xml +++ b/app/src/main/res/drawable/baseline_star_outline_24.xml @@ -4,6 +4,6 @@ android:viewportWidth="24" android:viewportHeight="24"> diff --git a/app/src/main/res/drawable/baseline_starred_32.xml b/app/src/main/res/drawable/baseline_starred_32.xml new file mode 100644 index 000000000..6153d4543 --- /dev/null +++ b/app/src/main/res/drawable/baseline_starred_32.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/baseline_transfer_delete_24.xml b/app/src/main/res/drawable/baseline_transfer_delete_24.xml index aed69638b..7d7266725 100644 --- a/app/src/main/res/drawable/baseline_transfer_delete_24.xml +++ b/app/src/main/res/drawable/baseline_transfer_delete_24.xml @@ -5,8 +5,8 @@ android:viewportHeight="24"> + android:fillColor="#999999"/> + android:fillColor="#999999"/> diff --git a/app/src/main/res/drawable/baseline_transfer_restart_24.xml b/app/src/main/res/drawable/baseline_transfer_restart_24.xml index 34029764a..73520d07e 100644 --- a/app/src/main/res/drawable/baseline_transfer_restart_24.xml +++ b/app/src/main/res/drawable/baseline_transfer_restart_24.xml @@ -4,6 +4,6 @@ android:viewportWidth="24" android:viewportHeight="24"> diff --git a/app/src/main/res/drawable/baseline_transfer_select_all2_24.xml b/app/src/main/res/drawable/baseline_transfer_select_all2_24.xml index 425ba9aec..e1d1bd32e 100644 --- a/app/src/main/res/drawable/baseline_transfer_select_all2_24.xml +++ b/app/src/main/res/drawable/baseline_transfer_select_all2_24.xml @@ -5,8 +5,8 @@ android:viewportHeight="24"> + android:fillColor="#999999"/> + android:fillColor="#999999"/> diff --git a/app/src/main/res/drawable/baseline_transfer_select_all_24.xml b/app/src/main/res/drawable/baseline_transfer_select_all_24.xml deleted file mode 100644 index 61c51c8aa..000000000 --- a/app/src/main/res/drawable/baseline_transfer_select_all_24.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/color_preference_widget_background.xml b/app/src/main/res/drawable/color_preference_widget_background.xml deleted file mode 100644 index e91c2a973..000000000 --- a/app/src/main/res/drawable/color_preference_widget_background.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - diff --git a/app/src/main/res/drawable/ic_check_square_solid.xml b/app/src/main/res/drawable/ic_check_square_solid.xml index e251c6c4c..5daf886a0 100644 --- a/app/src/main/res/drawable/ic_check_square_solid.xml +++ b/app/src/main/res/drawable/ic_check_square_solid.xml @@ -5,5 +5,5 @@ android:viewportHeight="32"> + android:fillColor="#666666"/> diff --git a/app/src/main/res/drawable/ic_checkbox_checked.xml b/app/src/main/res/drawable/ic_checkbox_checked.xml new file mode 100644 index 000000000..f11148b17 --- /dev/null +++ b/app/src/main/res/drawable/ic_checkbox_checked.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_checkbox_unchecked.xml b/app/src/main/res/drawable/ic_checkbox_unchecked.xml new file mode 100644 index 000000000..9327481c5 --- /dev/null +++ b/app/src/main/res/drawable/ic_checkbox_unchecked.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_star2.xml b/app/src/main/res/drawable/ic_star2.xml deleted file mode 100644 index 3077dd5bc..000000000 --- a/app/src/main/res/drawable/ic_star2.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_star_32.xml b/app/src/main/res/drawable/ic_star_32.xml new file mode 100644 index 000000000..fbc02f523 --- /dev/null +++ b/app/src/main/res/drawable/ic_star_32.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/icon_file_ae_colorful.xml b/app/src/main/res/drawable/icon_file_ae_colorful.xml deleted file mode 100644 index 345333679..000000000 --- a/app/src/main/res/drawable/icon_file_ae_colorful.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/icon_file_ai_colorful.xml b/app/src/main/res/drawable/icon_file_ai_colorful.xml deleted file mode 100644 index 66cf9460c..000000000 --- a/app/src/main/res/drawable/icon_file_ai_colorful.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - diff --git a/app/src/main/res/drawable/icon_file_android_colorful.xml b/app/src/main/res/drawable/icon_file_android_colorful.xml deleted file mode 100644 index 16b9a4bec..000000000 --- a/app/src/main/res/drawable/icon_file_android_colorful.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - diff --git a/app/src/main/res/drawable/icon_file_audio_colorful.xml b/app/src/main/res/drawable/icon_file_audio_colorful.xml deleted file mode 100644 index ab9347b42..000000000 --- a/app/src/main/res/drawable/icon_file_audio_colorful.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/icon_file_calendar_colorful.xml b/app/src/main/res/drawable/icon_file_calendar_colorful.xml deleted file mode 100644 index 44783e1e2..000000000 --- a/app/src/main/res/drawable/icon_file_calendar_colorful.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/icon_file_code_colorful.xml b/app/src/main/res/drawable/icon_file_code_colorful.xml deleted file mode 100644 index e19feb65a..000000000 --- a/app/src/main/res/drawable/icon_file_code_colorful.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/icon_file_csv_colorful.xml b/app/src/main/res/drawable/icon_file_csv_colorful.xml deleted file mode 100644 index 1dbd47209..000000000 --- a/app/src/main/res/drawable/icon_file_csv_colorful.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/icon_file_excel_colorful.xml b/app/src/main/res/drawable/icon_file_excel_colorful.xml deleted file mode 100644 index ff232f8d0..000000000 --- a/app/src/main/res/drawable/icon_file_excel_colorful.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/icon_file_image_colorful.xml b/app/src/main/res/drawable/icon_file_image_colorful.xml deleted file mode 100644 index 925116130..000000000 --- a/app/src/main/res/drawable/icon_file_image_colorful.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - diff --git a/app/src/main/res/drawable/icon_file_keynote_colorful.xml b/app/src/main/res/drawable/icon_file_keynote_colorful.xml deleted file mode 100644 index 86263a6e4..000000000 --- a/app/src/main/res/drawable/icon_file_keynote_colorful.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - diff --git a/app/src/main/res/drawable/icon_file_link_blue_colorful.xml b/app/src/main/res/drawable/icon_file_link_blue_colorful.xml deleted file mode 100644 index 6c1b39386..000000000 --- a/app/src/main/res/drawable/icon_file_link_blue_colorful.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/icon_file_link_deta_colorful.xml b/app/src/main/res/drawable/icon_file_link_deta_colorful.xml deleted file mode 100644 index 9744979e8..000000000 --- a/app/src/main/res/drawable/icon_file_link_deta_colorful.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/icon_file_nopermission_colorful.xml b/app/src/main/res/drawable/icon_file_nopermission_colorful.xml deleted file mode 100644 index 92d5d83b6..000000000 --- a/app/src/main/res/drawable/icon_file_nopermission_colorful.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/icon_file_numbers_colorful.xml b/app/src/main/res/drawable/icon_file_numbers_colorful.xml deleted file mode 100644 index b2e5cb255..000000000 --- a/app/src/main/res/drawable/icon_file_numbers_colorful.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - diff --git a/app/src/main/res/drawable/icon_file_otherfile_colorful.xml b/app/src/main/res/drawable/icon_file_otherfile_colorful.xml deleted file mode 100644 index bfe822887..000000000 --- a/app/src/main/res/drawable/icon_file_otherfile_colorful.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - diff --git a/app/src/main/res/drawable/icon_file_pages_colorful.xml b/app/src/main/res/drawable/icon_file_pages_colorful.xml deleted file mode 100644 index a41e3f0a5..000000000 --- a/app/src/main/res/drawable/icon_file_pages_colorful.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - diff --git a/app/src/main/res/drawable/icon_file_pdf_colorful.xml b/app/src/main/res/drawable/icon_file_pdf_colorful.xml deleted file mode 100644 index e4c99a5c9..000000000 --- a/app/src/main/res/drawable/icon_file_pdf_colorful.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/icon_file_ppt_colorful.xml b/app/src/main/res/drawable/icon_file_ppt_colorful.xml deleted file mode 100644 index af0a6a503..000000000 --- a/app/src/main/res/drawable/icon_file_ppt_colorful.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/icon_file_ps_colorful.xml b/app/src/main/res/drawable/icon_file_ps_colorful.xml deleted file mode 100644 index 6a60e2e36..000000000 --- a/app/src/main/res/drawable/icon_file_ps_colorful.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/icon_file_sketch_colorful.xml b/app/src/main/res/drawable/icon_file_sketch_colorful.xml deleted file mode 100644 index 3bda5f114..000000000 --- a/app/src/main/res/drawable/icon_file_sketch_colorful.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/icon_file_slide_colorful.xml b/app/src/main/res/drawable/icon_file_slide_colorful.xml deleted file mode 100644 index 9938e3282..000000000 --- a/app/src/main/res/drawable/icon_file_slide_colorful.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/icon_file_text_colorful.xml b/app/src/main/res/drawable/icon_file_text_colorful.xml deleted file mode 100644 index c6844f504..000000000 --- a/app/src/main/res/drawable/icon_file_text_colorful.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/icon_file_unknow_colorful.xml b/app/src/main/res/drawable/icon_file_unknow_colorful.xml deleted file mode 100644 index 3620b4829..000000000 --- a/app/src/main/res/drawable/icon_file_unknow_colorful.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/icon_file_video_colorful.xml b/app/src/main/res/drawable/icon_file_video_colorful.xml deleted file mode 100644 index bf7c7b370..000000000 --- a/app/src/main/res/drawable/icon_file_video_colorful.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/icon_file_word_colorful.xml b/app/src/main/res/drawable/icon_file_word_colorful.xml deleted file mode 100644 index 62459273b..000000000 --- a/app/src/main/res/drawable/icon_file_word_colorful.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - diff --git a/app/src/main/res/drawable/icon_file_zip_colorful.xml b/app/src/main/res/drawable/icon_file_zip_colorful.xml deleted file mode 100644 index 5bbb033cc..000000000 --- a/app/src/main/res/drawable/icon_file_zip_colorful.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - diff --git a/app/src/main/res/drawable/icon_star.xml b/app/src/main/res/drawable/icon_star.xml deleted file mode 100644 index 6d7dad89a..000000000 --- a/app/src/main/res/drawable/icon_star.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/icon_star_fill.xml b/app/src/main/res/drawable/icon_star_fill.xml deleted file mode 100644 index 64a9fa2df..000000000 --- a/app/src/main/res/drawable/icon_star_fill.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/scrollbar_vertical.xml b/app/src/main/res/drawable/scrollbar_vertical.xml deleted file mode 100644 index f98af17a0..000000000 --- a/app/src/main/res/drawable/scrollbar_vertical.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/scrollbar_vertical_bg.xml b/app/src/main/res/drawable/scrollbar_vertical_bg.xml deleted file mode 100644 index 8ff9db793..000000000 --- a/app/src/main/res/drawable/scrollbar_vertical_bg.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/seekbar_for_webview_style.xml b/app/src/main/res/drawable/seekbar_for_webview_style.xml index 3dd305187..945f226a7 100644 --- a/app/src/main/res/drawable/seekbar_for_webview_style.xml +++ b/app/src/main/res/drawable/seekbar_for_webview_style.xml @@ -3,13 +3,12 @@ - + + android:endColor="@color/toolbar_progress_bar_background_color" + android:startColor="@color/toolbar_progress_bar_background_color" /> @@ -17,13 +16,12 @@ - + + android:endColor="@color/toolbar_progress_bar_second_color" + android:startColor="@color/toolbar_progress_bar_second_color" /> diff --git a/app/src/main/res/drawable/selection_control_ripple.xml b/app/src/main/res/drawable/selection_control_ripple.xml new file mode 100644 index 000000000..6e36e0e6c --- /dev/null +++ b/app/src/main/res/drawable/selection_control_ripple.xml @@ -0,0 +1,19 @@ + + + diff --git a/app/src/main/res/drawable/shape_solid_grey103_r2.xml b/app/src/main/res/drawable/shape_solid_grey103_r2.xml new file mode 100644 index 000000000..6dc53c8b2 --- /dev/null +++ b/app/src/main/res/drawable/shape_solid_grey103_r2.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_image_preview.xml b/app/src/main/res/layout/activity_image_preview.xml index 7a00ac7fe..c1f5d7f55 100644 --- a/app/src/main/res/layout/activity_image_preview.xml +++ b/app/src/main/res/layout/activity_image_preview.xml @@ -18,7 +18,7 @@ android:gravity="end" android:orientation="horizontal" android:padding="@dimen/gallery_padding" - android:visibility="gone"> + android:visibility="visible"> - + android:layout_height="match_parent"> - + android:layout_height="match_parent" + android:orientation="vertical"> - + - + + + + + - + + - - \ No newline at end of file + android:layout_height="400dp" + android:layout_gravity="bottom" + android:background="@color/material_blue_grey_500" + app:behavior_hideable="false" + app:behavior_peekHeight="200dp" + app:layout_behavior="@string/bottom_sheet_behavior" /> + diff --git a/app/src/main/res/layout/bottom_sheet_item_grid.xml b/app/src/main/res/layout/bottom_sheet_item_grid.xml index fbb639334..e997b4c8e 100644 --- a/app/src/main/res/layout/bottom_sheet_item_grid.xml +++ b/app/src/main/res/layout/bottom_sheet_item_grid.xml @@ -1,5 +1,6 @@ \ No newline at end of file diff --git a/app/src/main/res/layout/bottom_sheet_item_list.xml b/app/src/main/res/layout/bottom_sheet_item_list.xml index 9ea7e12c2..02fc025f9 100644 --- a/app/src/main/res/layout/bottom_sheet_item_list.xml +++ b/app/src/main/res/layout/bottom_sheet_item_list.xml @@ -17,14 +17,12 @@ tools:src="@drawable/ic_cancel" /> \ No newline at end of file diff --git a/app/src/main/res/layout/color_preference_widget.xml b/app/src/main/res/layout/color_preference_widget.xml deleted file mode 100644 index bd958c295..000000000 --- a/app/src/main/res/layout/color_preference_widget.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - diff --git a/app/src/main/res/layout/item_activity.xml b/app/src/main/res/layout/item_activity.xml index a3bcf2b01..271b26792 100644 --- a/app/src/main/res/layout/item_activity.xml +++ b/app/src/main/res/layout/item_activity.xml @@ -8,8 +8,8 @@ + app:layout_constraintStart_toEndOf="@+id/item_avatar" + app:layout_constraintTop_toBottomOf="@+id/item_desc" /> + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0" /> + android:paddingHorizontal="16dp"> - - @@ -90,17 +78,36 @@ - - + app:layout_constraintTop_toTopOf="parent"> + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_dirent_grid.xml b/app/src/main/res/layout/item_dirent_grid.xml index 8b4af1521..01ddd4a39 100644 --- a/app/src/main/res/layout/item_dirent_grid.xml +++ b/app/src/main/res/layout/item_dirent_grid.xml @@ -20,7 +20,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitCenter" - android:src="@drawable/baseline_settings_24" + android:src="@drawable/baseline_repo_24" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" @@ -48,8 +48,8 @@ android:id="@+id/title_container" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginStart="8dp" - android:layout_marginTop="8dp" + android:layout_marginStart="16dp" + android:layout_marginTop="16dp" android:layout_marginBottom="8dp" android:gravity="center_vertical" android:orientation="horizontal"> @@ -57,22 +57,10 @@ - - - diff --git a/app/src/main/res/layout/item_group_item.xml b/app/src/main/res/layout/item_group_item.xml index 64d9ab6a3..b64291781 100644 --- a/app/src/main/res/layout/item_group_item.xml +++ b/app/src/main/res/layout/item_group_item.xml @@ -4,7 +4,7 @@ android:id="@+id/group_container" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="?android:attr/colorBackground" + android:background="@color/bar_background_color" android:foreground="?selectableItemBackground" android:orientation="vertical"> @@ -16,26 +16,12 @@ android:paddingHorizontal="16dp" android:paddingVertical="8dp" android:text="@string/app_name" - android:textColor="@color/item_subtitle_color" - android:textSize="16sp" + android:textColor="@color/item_title_color" + android:textSize="@dimen/lv_subtitle_txt_size" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> - - - + android:paddingHorizontal="16dp"> @@ -47,31 +47,34 @@ tools:text="@string/app_name" /> - + app:layout_constraintStart_toEndOf="@+id/text_container" + app:layout_constraintTop_toTopOf="parent"> - + + + + - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/item_sdoc_comment.xml b/app/src/main/res/layout/item_sdoc_comment.xml index ee802319c..073f33b27 100644 --- a/app/src/main/res/layout/item_sdoc_comment.xml +++ b/app/src/main/res/layout/item_sdoc_comment.xml @@ -54,15 +54,15 @@ app:layout_constraintStart_toEndOf="@+id/comment_user_avatar" app:layout_constraintTop_toBottomOf="@+id/comment_nick_name" /> - - - - - - - - - + + tools:src="@drawable/baseline_more_vert_24" /> + android:foreground="?android:selectableItemBackground" + android:paddingHorizontal="16dp"> @@ -51,30 +47,27 @@ - - - - + app:layout_constraintTop_toTopOf="parent" + app:tint="@color/item_subtitle_color" /> diff --git a/app/src/main/res/layout/item_transfer_list.xml b/app/src/main/res/layout/item_transfer_list.xml index 4d88fe110..a6cf03648 100644 --- a/app/src/main/res/layout/item_transfer_list.xml +++ b/app/src/main/res/layout/item_transfer_list.xml @@ -25,13 +25,15 @@ + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintVertical_bias="0.1" /> - - - - - + app:layout_constraintEnd_toEndOf="parent" + app:tint="@color/item_subtitle_color" /> diff --git a/app/src/main/res/layout/layout_bottom_sheet_recycler_menu.xml b/app/src/main/res/layout/layout_bottom_sheet_menu_dialog.xml similarity index 83% rename from app/src/main/res/layout/layout_bottom_sheet_recycler_menu.xml rename to app/src/main/res/layout/layout_bottom_sheet_menu_dialog.xml index db17813f2..6b8a44625 100644 --- a/app/src/main/res/layout/layout_bottom_sheet_recycler_menu.xml +++ b/app/src/main/res/layout/layout_bottom_sheet_menu_dialog.xml @@ -1,5 +1,6 @@ - - - + android:paddingBottom="16dp" + tools:listitem="@layout/bottom_sheet_item_grid" /> \ No newline at end of file diff --git a/app/src/main/res/layout/layout_bottom_sheet_menu_view.xml b/app/src/main/res/layout/layout_bottom_sheet_menu_view.xml new file mode 100644 index 000000000..8cfd6ac4f --- /dev/null +++ b/app/src/main/res/layout/layout_bottom_sheet_menu_view.xml @@ -0,0 +1,28 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_dialog_button_positive_negative_loading.xml b/app/src/main/res/layout/layout_dialog_button_positive_negative_loading.xml index c7983b7ab..aaebe067d 100644 --- a/app/src/main/res/layout/layout_dialog_button_positive_negative_loading.xml +++ b/app/src/main/res/layout/layout_dialog_button_positive_negative_loading.xml @@ -10,22 +10,22 @@ android:id="@+id/text_view_negative" android:layout_width="wrap_content" android:layout_height="?actionBarSize" - android:foreground="?selectableItemBackground" + android:foreground="@drawable/selection_control_ripple" android:gravity="center" android:paddingHorizontal="?attr/dialogPreferredPadding" android:text="@string/cancel" - android:textColor="@color/md_theme_primary" /> + android:textColor="?attr/colorPrimary" /> + android:textColor="?attr/colorPrimary" /> diff --git a/app/src/main/res/layout/layout_fast_rv.xml b/app/src/main/res/layout/layout_fast_rv.xml index 1eae37595..f24b54fa0 100644 --- a/app/src/main/res/layout/layout_fast_rv.xml +++ b/app/src/main/res/layout/layout_fast_rv.xml @@ -1,6 +1,5 @@ @@ -20,4 +19,6 @@ android:id="@+id/sticky_container" android:layout_width="match_parent" android:layout_height="wrap_content" /> - \ No newline at end of file + + + diff --git a/app/src/main/res/layout/layout_search_view.xml b/app/src/main/res/layout/layout_search_view.xml new file mode 100644 index 000000000..32e41ce38 --- /dev/null +++ b/app/src/main/res/layout/layout_search_view.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/toolbar_actionbar_progress_bar.xml b/app/src/main/res/layout/toolbar_actionbar_progress_bar.xml index 8432a0469..3e6b6c73d 100644 --- a/app/src/main/res/layout/toolbar_actionbar_progress_bar.xml +++ b/app/src/main/res/layout/toolbar_actionbar_progress_bar.xml @@ -19,8 +19,8 @@ android:layout_height="wrap_content" android:indeterminate="false" android:max="100" - android:maxHeight="2dp" - android:minHeight="2dp" + android:maxHeight="1dp" + android:minHeight="1dp" android:progress="10" android:progressDrawable="@drawable/seekbar_for_webview_style" /> diff --git a/app/src/main/res/layout/view_dialog_message_textview.xml b/app/src/main/res/layout/view_dialog_message_textview.xml index 6018aaed5..fe091bd06 100644 --- a/app/src/main/res/layout/view_dialog_message_textview.xml +++ b/app/src/main/res/layout/view_dialog_message_textview.xml @@ -4,9 +4,6 @@ android:id="@+id/message_view" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginHorizontal="4dp" android:gravity="start" - android:textAppearance="?android:attr/textAppearanceLarge" - android:textColor="@color/grey" - android:textSize="16sp" + android:textAppearance="?android:attr/textAppearanceSmall" tools:text="@string/app_name" /> \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_navigation_menu.xml b/app/src/main/res/menu/bottom_navigation_menu.xml index 9ab5e404a..726782915 100644 --- a/app/src/main/res/menu/bottom_navigation_menu.xml +++ b/app/src/main/res/menu/bottom_navigation_menu.xml @@ -1,22 +1,23 @@ - + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_sdoc_menu.xml b/app/src/main/res/menu/bottom_sdoc_menu.xml index b4d114084..3373e07ba 100644 --- a/app/src/main/res/menu/bottom_sdoc_menu.xml +++ b/app/src/main/res/menu/bottom_sdoc_menu.xml @@ -3,25 +3,25 @@ xmlns:app="http://schemas.android.com/apk/res-auto"> \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_sheet_op_dirent.xml b/app/src/main/res/menu/bottom_sheet_op_dirent.xml new file mode 100644 index 000000000..88213bf53 --- /dev/null +++ b/app/src/main/res/menu/bottom_sheet_op_dirent.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_sheet_op_file.xml b/app/src/main/res/menu/bottom_sheet_op_file.xml index 81c93cc49..be0f18ce4 100644 --- a/app/src/main/res/menu/bottom_sheet_op_file.xml +++ b/app/src/main/res/menu/bottom_sheet_op_file.xml @@ -47,7 +47,7 @@ \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_sheet_unstarred.xml b/app/src/main/res/menu/bottom_sheet_unstarred.xml index f87efd677..a2c840bcb 100644 --- a/app/src/main/res/menu/bottom_sheet_unstarred.xml +++ b/app/src/main/res/menu/bottom_sheet_unstarred.xml @@ -1,14 +1,17 @@ - + \ No newline at end of file diff --git a/app/src/main/res/menu/browser_menu.xml b/app/src/main/res/menu/browser_menu.xml index 2152704c1..f65bf1524 100644 --- a/app/src/main/res/menu/browser_menu.xml +++ b/app/src/main/res/menu/browser_menu.xml @@ -1,24 +1,20 @@ - - - - - - - + + + + + + + + + + + + + + + + + + + + + android:title="@string/transfer_list_select_all" + app:iconTint="@color/bar_icon_tint_color" + app:showAsAction="ifRoom" /> diff --git a/app/src/main/res/menu/transfer_list_menu.xml b/app/src/main/res/menu/transfer_list_menu.xml index 1de8b79ae..4896017d7 100644 --- a/app/src/main/res/menu/transfer_list_menu.xml +++ b/app/src/main/res/menu/transfer_list_menu.xml @@ -3,21 +3,14 @@ xmlns:app="http://schemas.android.com/apk/res-auto"> - - - - - + android:id="@+id/cancel_transfer_tasks" + android:title="@string/transfer_list_cancel_all" + android:visible="true" + app:showAsAction="never" /> + + \ No newline at end of file diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index f4fc885a1..2313886bd 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -2,7 +2,6 @@ #FFFFFF #000000 - #FFF2F2F2 #6E6E6E #FF0000 #BDBDBD @@ -54,21 +53,35 @@ #4A4A4A #86848B - - #2c2c2c - #2c2c2c + + @color/material_grey_919 + @color/material_grey_911 + @color/material_grey_200 + @color/material_grey_200 - #d3d3d3 - #7F7F7F - #9a9a9a + + @color/material_grey_599 - #191919 - #f2f2f2 - #f2f2f2 + + @color/bar_title_color + @color/material_grey_700 + + @color/material_grey_700 + @color/material_grey_919 + @color/material_grey_919 @color/blue_500 @color/white + + @color/material_grey_824 + + + #d3d3d3 + #7F7F7F + #9a9a9a + + #191919 #f2f2f2 diff --git a/app/src/main/res/values-night/styles.xml b/app/src/main/res/values-night/styles.xml index f0ddbbce5..0688e981d 100644 --- a/app/src/main/res/values-night/styles.xml +++ b/app/src/main/res/values-night/styles.xml @@ -2,14 +2,15 @@ - - - - diff --git a/app/src/main/res/values-sw600dp/dimens.xml b/app/src/main/res/values-sw600dp/dimens.xml index 274b0f164..ef9019a5a 100644 --- a/app/src/main/res/values-sw600dp/dimens.xml +++ b/app/src/main/res/values-sw600dp/dimens.xml @@ -8,13 +8,7 @@ 25dp - - 64dp - 48dp - - 32dp - 32dp 14sp 70dp 48dp diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index e5649c725..605a4e8c4 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -2,7 +2,6 @@ #FFFFFF #000000 - #FFF2F2F2 #6E6E6E #FF0000 #BDBDBD @@ -24,6 +23,8 @@ #969696 #e1e2e3 + + #FFC783 #ea8201 #CF7300 @@ -43,7 +44,6 @@ #FFFBFE #1C1B1F - #FF90CAF9 #FF2196F3 @@ -55,21 +55,34 @@ #4A4A4A #86848B - - #E3E3E3 - #F1F1F1 + + @color/material_grey_50 + @color/material_grey_100 + @color/material_grey_900 + @color/material_grey_900 - #333333 - #888888 - #A0A0A0 + + @color/material_grey_599 - #f9f9f9 - #191919 - #191919 + + @color/material_grey_599 + @color/material_grey_300 + + @color/material_grey_50 + @color/material_grey_500 + #E3E3E3 @color/blue_500 @color/white + + #F1F1F1 + + + #212529 + @color/material_grey_599 + #A0A0A0 + #f2f2f2 #191919 diff --git a/app/src/main/res/values/colors_material.xml b/app/src/main/res/values/colors_material.xml index 217a299c8..1651cea50 100644 --- a/app/src/main/res/values/colors_material.xml +++ b/app/src/main/res/values/colors_material.xml @@ -259,16 +259,24 @@ #3E2723 #FAFAFA + #F8F8F8 #F5F5F5 + #F3F3F3 #EEEEEE #E0E0E0 #BDBDBD #9E9E9E + #999999 #757575 + #666666 #616161 #424242 #212121 + #222222 + #191919 + #111111 + #ECEFF1 #CFD8DC #B0BEC5 diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 7c1784535..4104e264e 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -40,7 +40,7 @@ 10dp - 68dp + 60dp 10dp 10dp 10dp @@ -50,14 +50,14 @@ 32dp 10dp 15dp - 60dp - 60dp + 34dp + 34dp 2dp 60dp 4dp 8dp - 16sp - 14sp + 14sp + 12sp 8dp 14dp 14dp diff --git a/app/src/main/res/values/ids.xml b/app/src/main/res/values/ids.xml index 7d1becc26..cc9727188 100644 --- a/app/src/main/res/values/ids.xml +++ b/app/src/main/res/values/ids.xml @@ -1,4 +1,16 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index b506990eb..87a53e5fc 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,14 +1,17 @@ - @@ -42,6 +47,7 @@ @color/bar_background_color @color/bar_background_color @color/bar_title_color + @style/TextAppearance.Material3.ActionBar.Subtitle @@ -51,6 +57,7 @@ @null @color/selector_color_primary @color/selector_color_primary + @color/fancy_orange_light labeled ?actionBarSize 8dp @@ -59,19 +66,26 @@ - -