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 4344b09a6..3018fd620 100644 --- a/app/src/main/java/com/seafile/seadroid2/context/NavContext.java +++ b/app/src/main/java/com/seafile/seadroid2/context/NavContext.java @@ -100,21 +100,23 @@ public DirentModel getTopDirentModel() { /** * Get the parents model of the current Dirent, maybe RepoModel */ - public boolean hasParentWritePermission() { + public boolean isParentHasWritePermission() { if (!inRepo()) { + //repo list page should not have permission verification throw new IllegalArgumentException("Please check your code"); } if (inRepoRoot()) { - return hasWritePermissionWithRepo(); + return getRepoModel().hasWritePermission(); } BaseModel bd = navStack.elementAt(navStack.size() - 1); DirentModel d = (DirentModel) bd; - if (d != null) { - return d.hasWritePermission(); + if (d == null) { + return false; } - return false; + + return d.hasWritePermission(); } public RepoModel getRepoModel() { @@ -135,7 +137,6 @@ public BaseModel getTopModel() { return navStack.peek(); } - /** * @return /a/b/c/d/e/ */ @@ -160,27 +161,6 @@ public String getNavPath() { return fullPath; } -// -// /** -// * /a/b/c/d/e.txt -> e.txt -// */ -// public String getLastNameOfPath() { -// String fullPath = getNavPath(); -// if (TextUtils.isEmpty(fullPath)) { -// return null; -// } -// -// if (!fullPath.contains("/")) { -// return fullPath; -// } -// -// String[] slash = fullPath.split("/"); -// if (slash.length == 0) { -// return null; -// } -// -// return slash[slash.length - 1]; -// } /** * /a/b/c -> c @@ -201,24 +181,4 @@ public String getLastPathName() { return null; } - - // - public boolean hasWritePermissionWithRepo() { - -// BaseModel baseModel = getTopModel(); -// if (baseModel == null) { -// return false; -// } -// -// if (baseModel instanceof RepoModel) { -// return ((RepoModel) baseModel).hasWritePermission(); -// } -// -// if (baseModel instanceof DirentModel) { -// return ((DirentModel) baseModel).hasWritePermission(); -// } - - return getRepoModel().hasWritePermission(); - } - } diff --git a/app/src/main/java/com/seafile/seadroid2/framework/data/db/entities/FileTransferEntity.java b/app/src/main/java/com/seafile/seadroid2/framework/data/db/entities/FileTransferEntity.java index 3ada42758..0ca8f6f12 100644 --- a/app/src/main/java/com/seafile/seadroid2/framework/data/db/entities/FileTransferEntity.java +++ b/app/src/main/java/com/seafile/seadroid2/framework/data/db/entities/FileTransferEntity.java @@ -191,6 +191,7 @@ public String getParent_path() { public String repo_id; public String repo_name; + //who public String related_account; /** diff --git a/app/src/main/java/com/seafile/seadroid2/framework/http/SafeOkHttpClient.java b/app/src/main/java/com/seafile/seadroid2/framework/http/SafeOkHttpClient.java index c8fe25103..25524a5c1 100644 --- a/app/src/main/java/com/seafile/seadroid2/framework/http/SafeOkHttpClient.java +++ b/app/src/main/java/com/seafile/seadroid2/framework/http/SafeOkHttpClient.java @@ -35,7 +35,7 @@ public SafeOkHttpClient(Account account) { super(account); } - private TrustManager[] getTrustManagers() { + public static TrustManager[] getTrustManagers() { try { TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init((KeyStore) null); diff --git a/app/src/main/java/com/seafile/seadroid2/framework/http/UnsafeOkHttpClient.java b/app/src/main/java/com/seafile/seadroid2/framework/http/UnsafeOkHttpClient.java new file mode 100644 index 000000000..fd253584b --- /dev/null +++ b/app/src/main/java/com/seafile/seadroid2/framework/http/UnsafeOkHttpClient.java @@ -0,0 +1,103 @@ + +package com.seafile.seadroid2.framework.http; + +import com.blankj.utilcode.util.CollectionUtils; +import com.seafile.seadroid2.account.Account; + +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import okhttp3.ConnectionSpec; +import okhttp3.Interceptor; +import okhttp3.OkHttpClient; + +public class UnsafeOkHttpClient extends BaseOkHttpClient { + public UnsafeOkHttpClient() { + super(null); + } + + public UnsafeOkHttpClient(Account account) { + super(account); + } + + private final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[]{}; + } + } + }; + + public OkHttpClient.Builder getBuilder() { + OkHttpClient.Builder builder = new OkHttpClient.Builder(); + + + try { + // Install the all-trusting trust manager + final SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); + // Create an ssl socket factory with our all-trusting manager + final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); + + builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]); + } catch (Exception e) { + e.printStackTrace(); + } + + builder.connectionSpecs(Arrays.asList( + ConnectionSpec.MODERN_TLS, + ConnectionSpec.COMPATIBLE_TLS, + ConnectionSpec.CLEARTEXT)); + builder.cache(cache); + builder.hostnameVerifier(new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + return true; + } + }); + //cache control + builder.interceptors().add(REWRITE_CACHE_CONTROL_INTERCEPTOR); + builder.networkInterceptors().add(REWRITE_CACHE_CONTROL_INTERCEPTOR); + + //add interceptors + List interceptors = getInterceptors(); + if (!CollectionUtils.isEmpty(interceptors)) { + for (Interceptor i : interceptors) { + builder.interceptors().add(i); + } + } + + //timeout + builder.writeTimeout(DEFAULT_TIME_OUT, TimeUnit.MILLISECONDS); + builder.readTimeout(DEFAULT_TIME_OUT, TimeUnit.MILLISECONDS); + builder.connectTimeout(DEFAULT_TIME_OUT, TimeUnit.MILLISECONDS); + + return builder; + } + + @Override + public OkHttpClient getOkClient() { + OkHttpClient.Builder builder = getBuilder(); + return builder.build(); + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/seafile/seadroid2/framework/http/interceptor/CurrentTokenInterceptor.java b/app/src/main/java/com/seafile/seadroid2/framework/http/interceptor/CurrentTokenInterceptor.java index 5745aabe5..9a80888c5 100644 --- a/app/src/main/java/com/seafile/seadroid2/framework/http/interceptor/CurrentTokenInterceptor.java +++ b/app/src/main/java/com/seafile/seadroid2/framework/http/interceptor/CurrentTokenInterceptor.java @@ -2,6 +2,7 @@ import android.text.TextUtils; +import com.seafile.seadroid2.framework.util.SLogs; import com.seafile.seadroid2.framework.util.TokenManager; import java.io.IOException; @@ -26,7 +27,6 @@ private Request.Builder initBuilder(Request.Builder builder) { if (!TextUtils.isEmpty(authToken)) { builder.addHeader("Authorization", "Token " + authToken); } - return builder; } } diff --git a/app/src/main/java/com/seafile/seadroid2/framework/util/GlideCache.java b/app/src/main/java/com/seafile/seadroid2/framework/util/GlideCache.java index 2a85c011a..f69075797 100644 --- a/app/src/main/java/com/seafile/seadroid2/framework/util/GlideCache.java +++ b/app/src/main/java/com/seafile/seadroid2/framework/util/GlideCache.java @@ -1,6 +1,9 @@ package com.seafile.seadroid2.framework.util; import android.content.Context; +import android.webkit.CookieManager; +import android.webkit.WebSettings; +import android.webkit.WebView; import androidx.annotation.NonNull; @@ -14,6 +17,7 @@ import com.bumptech.glide.module.AppGlideModule; import com.seafile.seadroid2.SeadroidApplication; import com.seafile.seadroid2.framework.http.HttpIO; +import com.seafile.seadroid2.framework.http.UnsafeOkHttpClient; import com.seafile.seadroid2.framework.http.interceptor.CurrentTokenInterceptor; import com.seafile.seadroid2.framework.http.interceptor.HeaderInterceptor; @@ -21,6 +25,10 @@ import java.io.IOException; import java.io.InputStream; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLSession; + import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.Request; @@ -57,6 +65,26 @@ public void registerComponents(@NonNull Context context, @NonNull Glide glide, @ } private OkHttpClient getClient() { - return new OkHttpClient.Builder().addInterceptor(new CurrentTokenInterceptor()).build(); + UnsafeOkHttpClient unsafeOkHttpClient = new UnsafeOkHttpClient(); + OkHttpClient.Builder builder = unsafeOkHttpClient.getBuilder(); + builder.followRedirects(true); + builder.addInterceptor(new CurrentTokenInterceptor()); +// builder.addInterceptor(new Interceptor() { +// @Override +// public Response intercept(Chain chain) throws IOException { +// Request request = chain.request(); +// String url = request.url().toString(); +// +// String kie = CookieManager.getInstance().getCookie(URLs.getHost(url)); +// Request.Builder requestBuilder = request.newBuilder(); +// if (kie != null) { +// requestBuilder.addHeader("Cookie", kie); +// } +// +// Request newRequest = requestBuilder.build(); +// return chain.proceed(newRequest); +// } +// }); + return builder.build(); } } 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 7a3679bde..7e24c25e7 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 @@ -68,6 +68,7 @@ private static synchronized HashMap getSuffixIconMap() { 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); 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 4b84ce547..334ba299a 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 @@ -412,10 +412,6 @@ public void subscribe(SingleEmitter> emitter) throws Exception }).flatMap(new Function, SingleSource>>() { @Override public SingleSource> apply(List netModels) throws Exception { - if (CollectionUtils.isEmpty(netModels)) { - return Single.just(netModels); - } - Completable deleted = AppDatabase.getInstance().direntDao().deleteAllByParentPath(repoId, parentDir); Single deleteAllByPathSingle = deleted.toSingleDefault(0L); return deleteAllByPathSingle.flatMap(new Function>>() { @@ -437,8 +433,7 @@ public SingleSource> apply(List direntModels) thr return insertAllSingle.flatMap(new Function>>() { @Override public SingleSource> apply(Long aLong) throws Exception { - - SLogs.d("Dirents本地数据库已更新"); + SLogs.d("The list has been inserted into the local database"); return Single.just(direntModels); } }); 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 40419d0ae..1339a861f 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 @@ -114,11 +114,13 @@ public static String getFileNameFromPath(String path) { return path.substring(path.lastIndexOf("/") + 1); } + public static final String[] _units = new String[]{"B", "KB", "MB", "GB", "TB"}; + public static final DecimalFormat _decimalFormat = new DecimalFormat("#,##0.#"); + public static String readableFileSize(long size) { if (size <= 0) return "0 KB"; - final String[] units = new String[]{"B", "KB", "MB", "GB", "TB"}; int digitGroups = (int) (Math.log10(size) / Math.log10(1000)); - return new DecimalFormat("#,##0.#").format(size / Math.pow(1000, digitGroups)) + " " + units[digitGroups]; + return _decimalFormat.format(size / Math.pow(1000, digitGroups)) + " " + _units[digitGroups]; } public static boolean isViewableImage(String name) { diff --git a/app/src/main/java/com/seafile/seadroid2/ui/account/SeafileAuthenticatorActivity.java b/app/src/main/java/com/seafile/seadroid2/ui/account/SeafileAuthenticatorActivity.java index 2dd8887be..a993ea2a5 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/account/SeafileAuthenticatorActivity.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/account/SeafileAuthenticatorActivity.java @@ -28,6 +28,7 @@ import com.seafile.seadroid2.account.Authenticator; import com.seafile.seadroid2.account.SupportAccountManager; import com.seafile.seadroid2.config.Constants; +import com.seafile.seadroid2.framework.http.HttpIO; import com.seafile.seadroid2.framework.util.SLogs; import com.seafile.seadroid2.ui.camera_upload.CameraUploadManager; @@ -225,12 +226,6 @@ public void onActivityResult(ActivityResult o) { private void finishLogin(Intent intent) { SLogs.d(DEBUG_TAG, "finishLogin"); - //firebase - event -login - Bundle eventBundle = new Bundle(); - eventBundle.putString(FirebaseAnalytics.Param.METHOD, "finishLogin"); - FirebaseAnalytics.getInstance(this).logEvent(FirebaseAnalytics.Event.LOGIN, eventBundle); - - String newAccountName = intent.getStringExtra(AccountManager.KEY_ACCOUNT_NAME); String accountType = intent.getStringExtra(AccountManager.KEY_ACCOUNT_TYPE); String authToken = intent.getStringExtra(AccountManager.KEY_AUTHTOKEN); @@ -299,7 +294,10 @@ private void finishLogin(Intent intent) { SupportAccountManager.getInstance().setUserData(newAccount, Authenticator.KEY_SHIB, "shib"); } + //save current account SupportAccountManager.getInstance().saveCurrentAccount(newAccountName); + //reset httpio instance + HttpIO.resetLoggedInInstance(); // set sync settings ContentResolver.setIsSyncable(newAccount, CameraUploadManager.AUTHORITY, cameraIsSyncable); 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 897a67c2a..b06e1fbb5 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 @@ -275,7 +275,7 @@ public SeafException getExceptionByThrowable(Throwable throwable) throws IOExcep return SeafException.sslException; } - return new SeafException(SeafException.CODE_ERROR, throwable.getMessage()); + return new SeafException(SeafException.CODE_ERROR, throwable.getLocalizedMessage()); } private SeafException checkResErrorBody(Response resp) throws IOException { diff --git a/app/src/main/java/com/seafile/seadroid2/ui/file/FileActivity.java b/app/src/main/java/com/seafile/seadroid2/ui/file/FileActivity.java index c2c0a7bf3..aa8cae9f1 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/file/FileActivity.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/file/FileActivity.java @@ -309,7 +309,7 @@ private void onFileDownloadFailed(SeafException seafException) { } else if (seafException == SeafException.invalidPassword) { handlePassword(); } else { - ToastUtils.showLong(String.format("Failed to download file \"%s\"", direntModel.name)); + ToastUtils.showLong(String.format("Failed to download file \"%s\"", seafException.getMessage())); finishWithCancel(); } diff --git a/app/src/main/java/com/seafile/seadroid2/ui/file/FileViewModel.java b/app/src/main/java/com/seafile/seadroid2/ui/file/FileViewModel.java index 5457a52bd..dd2962362 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/file/FileViewModel.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/file/FileViewModel.java @@ -1,5 +1,7 @@ package com.seafile.seadroid2.ui.file; +import android.text.TextUtils; + import androidx.lifecycle.MutableLiveData; import com.blankj.utilcode.util.CollectionUtils; @@ -100,12 +102,16 @@ public void subscribe(SingleEmitter emitter) throws Exception { .getListByFullPathsSync(repoModel.repo_id, CollectionUtils.newArrayList(direntModel.full_path), TransferAction.DOWNLOAD); if (CollectionUtils.isEmpty(transferEntityList)) { + if (TextUtils.isEmpty(direntModel.related_account)){ + direntModel.related_account = account.email; + } FileTransferEntity transferEntity = FileTransferEntity.convertDirentModel2This(repoModel.encrypted, direntModel); //newest file id transferEntity.file_id = direntModel.id; transferEntity.file_size = direntModel.size; transferEntity.target_path = destinationFile.getAbsolutePath(); + transferEntity.related_account = direntModel.related_account; AppDatabase.getInstance().fileTransferDAO().insert(transferEntity); @@ -148,6 +154,13 @@ public void subscribe(SingleEmitter emitter) throws Exception { public void accept(Boolean abool) throws Exception { download(account, direntModel, destinationFile); } + }, new Consumer() { + @Override + public void accept(Throwable throwable) throws Exception { + + SeafException seafException = getExceptionByThrowable(throwable); + getSeafExceptionLiveData().setValue(seafException); + } }); } 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 832d3a191..d6aef4156 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 @@ -26,7 +26,6 @@ import androidx.annotation.NonNull; import androidx.appcompat.widget.SearchView; import androidx.core.view.MenuCompat; -import androidx.fragment.app.DialogFragment; import androidx.fragment.app.Fragment; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; @@ -68,9 +67,7 @@ import com.seafile.seadroid2.ui.dialog_fragment.NewDirFileDialogFragment; import com.seafile.seadroid2.ui.dialog_fragment.NewRepoDialogFragment; import com.seafile.seadroid2.ui.dialog_fragment.PasswordDialogFragment; -import com.seafile.seadroid2.ui.dialog_fragment.SortFilesDialogFragment; import com.seafile.seadroid2.ui.dialog_fragment.listener.OnRefreshDataListener; -import com.seafile.seadroid2.ui.dialog_fragment.listener.OnSortItemClickListener; import com.seafile.seadroid2.ui.repo.RepoQuickFragment; import com.seafile.seadroid2.ui.search.Search2Activity; import com.seafile.seadroid2.ui.transfer_list.TransferActivity; @@ -637,7 +634,7 @@ public boolean onPrepareOptionsMenu(Menu menu) { if (binding.pager.getCurrentItem() == INDEX_LIBRARY_TAB) { if (getNavContext().inRepo()) { menuBinding.createRepo.setVisible(false); - if (getNavContext().hasParentWritePermission()) { + if (getNavContext().isParentHasWritePermission()) { menuBinding.add.setEnabled(true); menuBinding.select.setEnabled(true); } else { @@ -910,21 +907,6 @@ private void restartThis() { overridePendingTransition(R.anim.fade_in, R.anim.fade_out); } - //////////////////////////////// - // show dialog - //////////////////////////////// - @Deprecated - private void showSortFilesDialog() { - SortFilesDialogFragment dialog = new SortFilesDialogFragment(); - dialog.setOnSortItemClickListener(new OnSortItemClickListener() { - @Override - public void onSortFileItemClick(DialogFragment dialog, int position) { - mainViewModel.getOnResortListLiveData().setValue(position); - } - }); - dialog.show(getSupportFragmentManager(), SortFilesDialogFragment.class.getSimpleName()); - } - private void showPasswordDialog(RepoModel repoModel, String path) { PasswordDialogFragment dialogFragment = PasswordDialogFragment.newInstance(); dialogFragment.initData(repoModel.repo_id, repoModel.repo_name); @@ -981,10 +963,11 @@ else if (which == 3) // take a photo // private void showNewDirDialog() { - if (!getNavContext().hasWritePermissionWithRepo()) { + 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, true); @@ -1000,7 +983,7 @@ public void onActionStatus(boolean isDone) { } private void showNewFileDialog() { - if (!getNavContext().hasWritePermissionWithRepo()) { + if (!getNavContext().isParentHasWritePermission()) { ToastUtils.showLong(R.string.library_read_only); return; } @@ -1020,7 +1003,7 @@ public void onActionStatus(boolean isDone) { } private void pickFile() { - if (!getNavContext().hasWritePermissionWithRepo()) { + if (!getNavContext().isParentHasWritePermission()) { ToastUtils.showLong(R.string.library_read_only); return; } diff --git a/app/src/main/java/com/seafile/seadroid2/ui/media/image_preview/PhotoFragment.java b/app/src/main/java/com/seafile/seadroid2/ui/media/image_preview/PhotoFragment.java index a9911ce57..d735d9062 100644 --- a/app/src/main/java/com/seafile/seadroid2/ui/media/image_preview/PhotoFragment.java +++ b/app/src/main/java/com/seafile/seadroid2/ui/media/image_preview/PhotoFragment.java @@ -10,12 +10,15 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.webkit.CookieManagerCompat; +import androidx.webkit.UserAgentMetadata; import com.blankj.utilcode.util.EncodeUtils; import com.blankj.utilcode.util.SizeUtils; import com.bumptech.glide.load.DataSource; import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.load.engine.GlideException; +import com.bumptech.glide.load.resource.gif.GifDrawable; import com.bumptech.glide.request.RequestListener; import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.target.Target; @@ -24,6 +27,7 @@ import com.seafile.seadroid2.R; import com.seafile.seadroid2.account.Account; import com.seafile.seadroid2.account.SupportAccountManager; +import com.seafile.seadroid2.databinding.FragmentPhotoViewBinding; import com.seafile.seadroid2.framework.data.db.entities.DirentModel; import com.seafile.seadroid2.framework.datastore.DataManager; import com.seafile.seadroid2.framework.util.GlideApp; @@ -31,6 +35,7 @@ import com.seafile.seadroid2.ui.base.fragment.BaseFragment; import java.io.File; +import java.util.Locale; public class PhotoFragment extends BaseFragment { @@ -38,6 +43,7 @@ public class PhotoFragment extends BaseFragment { private DirentModel direntModel; private OnPhotoTapListener onPhotoTapListener; + private FragmentPhotoViewBinding binding; public void setOnPhotoTapListener(OnPhotoTapListener onPhotoTapListener) { this.onPhotoTapListener = onPhotoTapListener; @@ -72,19 +78,20 @@ public void onCreate(@Nullable Bundle savedInstanceState) { @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - return LayoutInflater.from(getContext()).inflate(R.layout.fragment_photo_view, container, false); + binding = FragmentPhotoViewBinding.inflate(inflater, container, false); + return binding.getRoot(); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - PhotoView photoView = view.findViewById(R.id.photo_view); - photoView.setZoomable(true); - photoView.setZoomTransitionDuration(300); - photoView.setMaximumScale(5f); - photoView.setMinimumScale(0.8f); - photoView.setOnPhotoTapListener(new OnPhotoTapListener() { + + binding.photoView.setZoomable(true); + binding.photoView.setZoomTransitionDuration(300); + binding.photoView.setMaximumScale(5f); + binding.photoView.setMinimumScale(0.8f); + binding.photoView.setOnPhotoTapListener(new OnPhotoTapListener() { @Override public void onPhotoTap(ImageView view, float x, float y) { if (onPhotoTapListener != null) { @@ -101,46 +108,53 @@ public void onPhotoTap(ImageView view, float x, float y) { GlideApp.with(requireContext()) .load(file) - .into(photoView); + .into(binding.photoView); return; } String url = getUrl(); if (url == null) { - photoView.setImageResource(R.drawable.icon_image_error_filled); - } else { - RequestOptions opt = new RequestOptions() - .skipMemoryCache(true) - .error(R.drawable.icon_image_error_filled) - .diskCacheStrategy(DiskCacheStrategy.NONE); - - GlideApp.with(requireContext()) - .load(url) - .apply(opt) - .fitCenter() - .listener(new RequestListener() { - @Override - public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { - progressBar.setVisibility(View.GONE); - return false; - } - - @Override - public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { - progressBar.setVisibility(View.GONE); - return false; - } - }) - .into(photoView); + binding.photoView.setImageResource(R.drawable.icon_image_error_filled); + return; } + + RequestOptions opt = new RequestOptions() + .skipMemoryCache(true) + .error(R.drawable.icon_image_error_filled) + .diskCacheStrategy(DiskCacheStrategy.NONE); + GlideApp.with(requireContext()) + .load(url) + .apply(opt) + .fitCenter() + .listener(new RequestListener() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { + binding.progressBar.setVisibility(View.GONE); + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { + binding.progressBar.setVisibility(View.GONE); + return false; + } + }) + .into(binding.photoView); } + private String getUrl() { Account account = SupportAccountManager.getInstance().getCurrentAccount(); if (account == null) { return null; } +// //https://dev.seafile.com/seafhttp/repos/4809a6f3-250c-4435-bdd8-b68f34c128d1/files//6f64603fd19f9ec45d05ec379e69e22.gif/?op=download +// //https://dev.seafile.com/seahub/repo/4809a6f3-250c-4435-bdd8-b68f34c128d1/raw/6f64603fd19f9ec45d05ec379e69e22.gif +// if (direntModel.name.toLowerCase().endsWith(".gif")) { +// return String.format(Locale.ROOT, "%srepo/%s/raw/%s", account.getServer(), direntModel.repo_id, direntModel.name); +// } + // return String.format("%srepo/%s/raw%s", account.getServer(), repoId, fileFullPath); int size = SizeUtils.dp2px(300); return String.format("%sapi2/repos/%s/thumbnail/?p=%s&size=%s", account.getServer(), direntModel.repo_id, EncodeUtils.urlEncode(direntModel.full_path), size); 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 4ddff643b..3b4af28af 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 @@ -38,6 +38,7 @@ import com.seafile.seadroid2.framework.data.model.GroupItemModel; 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; @@ -285,11 +286,7 @@ private void onBindDirents(DirentViewHolder holder, DirentModel model) { if (repoEncrypted || !Utils.isViewableImage(model.name)) { holder.binding.itemIcon.setImageResource(model.getIcon()); } else { - String url = convertThumbnailUrl(model.repo_id, model.full_path); - GlideApp.with(getContext()) - .load(url) - .apply(GlideLoadConfig.getOptions()) - .into(holder.binding.itemIcon); + loadImage(model, holder.binding.itemIcon); } //action mode @@ -379,11 +376,7 @@ private void onBindDirentsGrid(DirentGridViewHolder holder, DirentModel model) { holder.binding.itemIcon.setImageResource(model.getIcon()); } else { holder.binding.itemIcon.setScaleType(ImageView.ScaleType.CENTER_CROP); - String url = convertMiddleUrl(model.repo_id, model.full_path); - GlideApp.with(getContext()) - .load(url) - .apply(GlideLoadConfig.getOptions()) - .into(holder.binding.itemIcon); + loadImage(model, holder.binding.itemIcon); } //action mode @@ -418,11 +411,7 @@ private void onBindDirentsGallery(DirentGalleryViewHolder holder, DirentModel mo if (repoEncrypted || !Utils.isViewableImage(model.name)) { holder.binding.itemIcon.setImageResource(model.getIcon()); } else { - String url = convertMiddleUrl(model.repo_id, model.full_path); - GlideApp.with(getContext()) - .load(url) - .apply(GlideLoadConfig.getOptions()) - .into(holder.binding.itemIcon); + loadImage(model, holder.binding.itemIcon); } //action mode @@ -443,17 +432,31 @@ private void onBindDirentsGallery(DirentGalleryViewHolder holder, DirentModel mo } } - private String convertThumbnailUrl(String repoId, String filePath) { - return convertThumbnailUrl(repoId, filePath, 128); + private void loadImage(DirentModel direntModel, ImageView imageView) { + + if (direntModel.name.toLowerCase().endsWith(".gif")) { + imageView.setImageResource(direntModel.getIcon()); + } else { + String url = convertThumbnailUrl(direntModel); + GlideApp.with(getContext()).load(url) + .apply(GlideLoadConfig.getOptions()) + .into(imageView); + } + + + } + + private String convertThumbnailUrl(DirentModel direntModel) { + return convertThumbnailUrl(direntModel, 128); } - private String convertMiddleUrl(String repoId, String filePath) { - return convertThumbnailUrl(repoId, filePath, 256); + private String convertMiddleUrl(DirentModel direntModel) { + return convertThumbnailUrl(direntModel, 256); } - private String convertThumbnailUrl(String repoId, String filePath, int size) { - String newFilePath = EncodeUtils.urlEncode(filePath); - return String.format(Locale.ROOT, "%sapi2/repos/%s/thumbnail/?p=%s&size=%d", SERVER, repoId, newFilePath, size); + private String convertThumbnailUrl(DirentModel direntModel, int size) { + String newFilePath = EncodeUtils.urlEncode(direntModel.full_path); + return String.format(Locale.ROOT, "%sapi2/repos/%s/thumbnail/?p=%s&size=%d", SERVER, direntModel.repo_id, newFilePath, size); } public void setActionModeOn(boolean actionModeOn) { 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 a03840998..f8caa48f6 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 @@ -569,8 +569,7 @@ private void navTo(BaseModel model) { if (!getNavContext().inRepo()) { getNavContext().push(model); loadData(isForce()); - } else if (model instanceof DirentModel) { - DirentModel direntModel = (DirentModel) model; + } else if (model instanceof DirentModel direntModel) { if (direntModel.isDir()) { getNavContext().push(direntModel); loadData(isForce()); @@ -762,7 +761,7 @@ public boolean onCreateActionMode(ActionMode mode, Menu menu) { if (adapter == null) return true; // to hidden "r" permissions files or folder - if (!getNavContext().hasWritePermissionWithRepo()) { + if (!getNavContext().isParentHasWritePermission()) { menu.findItem(R.id.action_mode_delete).setVisible(false); menu.findItem(R.id.action_mode_move).setVisible(false); } 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 276d6900a..db6e7db41 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 @@ -271,19 +271,17 @@ public void onResultData(RepoModel uRepoModel) { dialogFragment.show(getSupportFragmentManager(), PasswordDialogFragment.class.getSimpleName()); } - private void showNewDirDialog() { if (!mNavContext.inRepo()) { ToastUtils.showLong(R.string.choose_a_library); return; } - if (!mNavContext.hasWritePermissionWithRepo()) { + 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); 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 5075ad0ba..fbb639334 100644 --- a/app/src/main/res/layout/bottom_sheet_item_grid.xml +++ b/app/src/main/res/layout/bottom_sheet_item_grid.xml @@ -13,7 +13,7 @@ android:layout_height="48dp" android:layout_marginVertical="4dp" android:importantForAccessibility="no" - android:padding="8dp" + android:padding="12dp" tools:src="@drawable/ic_cancel" /> \ No newline at end of file