From 0838266628501248d3c1f8ec986e7d3c9acff704 Mon Sep 17 00:00:00 2001 From: nextcloud-android-bot Date: Tue, 21 May 2024 02:26:17 +0000 Subject: [PATCH 01/20] =?UTF-8?q?=F0=9F=94=84=20synced=20local=20'.github/?= =?UTF-8?q?workflows/'=20with=20remote=20'config/workflows/'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nextcloud-android-bot --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/scorecard.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 40940c1b394e..5026fd90b430 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -39,7 +39,7 @@ jobs: with: swap-size-gb: 10 - name: Initialize CodeQL - uses: github/codeql-action/init@b7cec7526559c32f1616476ff32d17ba4c59b2d6 # v3.25.5 + uses: github/codeql-action/init@9fdb3e49720b44c48891d036bb502feb25684276 # v3.25.6 with: languages: ${{ matrix.language }} - name: Set up JDK 17 @@ -53,4 +53,4 @@ jobs: echo "org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties" ./gradlew assembleDebug - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b7cec7526559c32f1616476ff32d17ba4c59b2d6 # v3.25.5 + uses: github/codeql-action/analyze@9fdb3e49720b44c48891d036bb502feb25684276 # v3.25.6 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 274e40c61746..7f7abf93f42e 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -42,6 +42,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@b7cec7526559c32f1616476ff32d17ba4c59b2d6 # v3.25.5 + uses: github/codeql-action/upload-sarif@9fdb3e49720b44c48891d036bb502feb25684276 # v3.25.6 with: sarif_file: results.sarif From 9311e47b4a85dbc82797bc60e9af2dc8474b9b75 Mon Sep 17 00:00:00 2001 From: Nextcloud bot Date: Tue, 21 May 2024 02:35:17 +0000 Subject: [PATCH 02/20] Fix(l10n): Update translations from Transifex Signed-off-by: Nextcloud bot --- app/src/main/res/values-es-rCL/strings.xml | 6 ++++++ app/src/main/res/values-ja-rJP/strings.xml | 1 + app/src/main/res/values-lv/strings.xml | 4 ++++ app/src/main/res/values-sk-rSK/strings.xml | 2 ++ 4 files changed, 13 insertions(+) diff --git a/app/src/main/res/values-es-rCL/strings.xml b/app/src/main/res/values-es-rCL/strings.xml index 65ce9cf03eb5..c818ce7297a1 100644 --- a/app/src/main/res/values-es-rCL/strings.xml +++ b/app/src/main/res/values-es-rCL/strings.xml @@ -3,13 +3,19 @@ %1$s aplicación Android Acerca de versión %1$s + versión %1$s, build #%2$s + Fallo al crear la cuenta Ícono de la cuenta ¡No se encontró la cuenta! Editar + Borrar todas las notificaciones + Vaciar papelera de reciclaje Enviar/Compartir Vista de cuadrícula Vista de lista + Restaurar contactos y calendario Nueva carpeta + Mover o copiar Abrir con Buscar Detalles diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml index 35bc52075406..86b33da09a7a 100644 --- a/app/src/main/res/values-ja-rJP/strings.xml +++ b/app/src/main/res/values-ja-rJP/strings.xml @@ -40,6 +40,7 @@ すべて テキストを入力 失敗 + スケジュール済 完了 不明 入力 diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml index 080f09398c09..e3b70d2f7df4 100644 --- a/app/src/main/res/values-lv/strings.xml +++ b/app/src/main/res/values-lv/strings.xml @@ -157,6 +157,7 @@ Deaktivēt Atmest Noraidīt paziņojumu + Vairāki attēli Pabeigts Nevarēja lejupielādēt %1$s Lejupielāde neizdevās, piesakieties vēlreiz. @@ -383,6 +384,8 @@ Sūtīt Saglabāt kā Izmantot attēlu kā + Iestatīt stāvokli + Iestatīt stāvokļa ziņojumu Dalīties Koplietošana Beidzas %1$s @@ -437,6 +440,7 @@ Statusa ziņojums Noklusējuma Lejupielādes + Attēli Gads \"%1$s\" ir bijis kopīgots ar jums %1$s koplietots \"%2$s\" ar tevi diff --git a/app/src/main/res/values-sk-rSK/strings.xml b/app/src/main/res/values-sk-rSK/strings.xml index 5b1b219f4d05..7e773a88bd4a 100644 --- a/app/src/main/res/values-sk-rSK/strings.xml +++ b/app/src/main/res/values-sk-rSK/strings.xml @@ -34,6 +34,8 @@ Pridaj do %1$s Rozšírené nastavenia Povoliť sprístupňovanie ďalej + Základná URL + Názov proxy servera Brána proxy Zobrazí jeden widget z hlavného panela Hľadať v %s From 0e2faf3d2700220f9863fcde974a781d95b11167 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Thu, 16 May 2024 15:10:15 +0200 Subject: [PATCH 03/20] Use view pager 2 and delete image properly Signed-off-by: alperozturk --- .../ui/preview/PreviewImageActivity.java | 80 ++++++++--------- .../ui/preview/PreviewImageFragment.java | 14 ++- .../ui/preview/PreviewImagePagerAdapter.java | 89 +++++++++---------- .../res/layout/preview_image_activity.xml | 9 +- .../res/layout/preview_image_fragment.xml | 2 +- 5 files changed, 97 insertions(+), 97 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java index 0121fd6d2dc3..56518d26fd8a 100644 --- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java @@ -21,6 +21,7 @@ import android.os.Bundle; import android.view.MenuItem; import android.view.View; +import android.view.ViewGroup; import com.nextcloud.client.account.User; import com.nextcloud.client.di.Injectable; @@ -59,7 +60,8 @@ import androidx.appcompat.app.ActionBar; import androidx.drawerlayout.widget.DrawerLayout; import androidx.localbroadcastmanager.content.LocalBroadcastManager; -import androidx.viewpager.widget.ViewPager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.viewpager2.widget.ViewPager2; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; /** @@ -68,7 +70,6 @@ @SuppressWarnings("PMD.AvoidDuplicateLiterals") public class PreviewImageActivity extends FileActivity implements FileFragment.ContainerActivity, - ViewPager.OnPageChangeListener, OnRemoteOperationListener, Injectable { @@ -78,7 +79,7 @@ public class PreviewImageActivity extends FileActivity implements private static final String KEY_SYSTEM_VISIBLE = "TRUE"; private OCFile livePhotoFile; - private ViewPager viewPager; + private ViewPager2 viewPager; private PreviewImagePagerAdapter previewImagePagerAdapter; private int savedPosition; private boolean hasSavedPosition; @@ -158,7 +159,7 @@ private void initViewPager(User user) { if (virtualFolderType != null && virtualFolderType != VirtualFolderType.NONE) { VirtualFolderType type = (VirtualFolderType) virtualFolderType; - previewImagePagerAdapter = new PreviewImagePagerAdapter(getSupportFragmentManager(), + previewImagePagerAdapter = new PreviewImagePagerAdapter(this, type, user, getStorageManager()); @@ -172,7 +173,7 @@ private void initViewPager(User user) { } previewImagePagerAdapter = new PreviewImagePagerAdapter( - getSupportFragmentManager(), + this, livePhotoFile, parentFolder, user, @@ -188,7 +189,12 @@ private void initViewPager(User user) { position = position >= 0 ? position : 0; viewPager.setAdapter(previewImagePagerAdapter); - viewPager.addOnPageChangeListener(this); + viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { + @Override + public void onPageSelected(int position) { + selectPage(position); + } + }); viewPager.setCurrentItem(position); if (position == 0 && !getFile().isDown()) { @@ -247,7 +253,7 @@ public void onStart() { if (file != null) { /// Refresh the activity according to the Account and OCFile set setFile(file); // reset after getting it fresh from storageManager - getSupportActionBar().setTitle(getFile().getFileName()); + updateActionBarTitle(getFile().getFileName()); //if (!stateWasRecovered) { initViewPager(optionalUser.get()); //} @@ -271,13 +277,21 @@ public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationRe super.onRemoteOperationFinish(operation, result); if (operation instanceof RemoveFileOperation) { - // initialize the pager with the new file list - initViewPager(getUser().get()); - if (viewPager.getAdapter().getCount() > 0) { - // Trigger page reselection, to update the title - onPageSelected(viewPager.getCurrentItem()); + final RecyclerView.Adapter adapter = viewPager.getAdapter(); + + if (adapter != null) { + previewImagePagerAdapter.delete(viewPager.getCurrentItem()); + + if (adapter.getItemCount() > 0) { + int nextPosition = viewPager.getCurrentItem() + 1; + viewPager.setCurrentItem(nextPosition); + updateActionBarTitle(String.valueOf(previewImagePagerAdapter.getPageTitle(nextPosition))); + + } else { + // Last file has been deleted, so finish the activity + finish(); + } } else { - // Last file has been deleted, so finish the activity finish(); } } else if (operation instanceof SynchronizeFileOperation) { @@ -301,7 +315,7 @@ private void observeWorkerState() { requestWaitingForBinder = false; Log_OC.d(TAG, "Simulating reselection of current page after connection " + "of download binder"); - onPageSelected(viewPager.getCurrentItem()); + selectPage(viewPager.getCurrentItem()); } } else { Log_OC.d(TAG, "Download worker stopped"); @@ -384,8 +398,7 @@ public void requestForDownload(OCFile file, String downloadBehaviour) { * * @param position Position index of the new selected page */ - @Override - public void onPageSelected(int position) { + public void selectPage(int position) { savedPosition = position; hasSavedPosition = true; @@ -405,40 +418,17 @@ public void onPageSelected(int position) { } } - // Update ActionBar title if (currentFile != null) { - if (getSupportActionBar() != null) { - getSupportActionBar().setTitle(currentFile.getFileName()); - } - setDrawerIndicatorEnabled(false); + updateActionBarTitle(currentFile.getFileName()); } - } - /** - * Called when the scroll state changes. Useful for discovering when the user begins dragging, - * when the pager is automatically settling to the current page. when it is fully stopped/idle. - * - * @param state The new scroll state (SCROLL_STATE_IDLE, _DRAGGING, _SETTLING - */ - @Override - public void onPageScrollStateChanged(int state) { - // not used at the moment + setDrawerIndicatorEnabled(false); } - /** - * This method will be invoked when the current page is scrolled, either as part of a - * programmatically initiated smooth scroll or a user initiated touch scroll. - * - * @param position Position index of the first page currently being displayed. - * Page position+1 will be visible if positionOffset is - * nonzero. - * @param positionOffset Value from [0, 1) indicating the offset from the page - * at position. - * @param positionOffsetPixels Value in pixels indicating the offset from position. - */ - @Override - public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { - // not used at the moment + public void updateActionBarTitle(String title) { + if (getSupportActionBar() != null) { + getSupportActionBar().setTitle(title); + } } /** diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageFragment.java b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageFragment.java index fd4a7f9a425a..59ac9f8418e3 100644 --- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageFragment.java @@ -81,6 +81,7 @@ import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentStatePagerAdapter; import androidx.fragment.app.FragmentTransaction; +import androidx.viewpager2.adapter.FragmentStateAdapter; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import pl.droidsonroids.gif.GifDrawable; @@ -127,7 +128,7 @@ public class PreviewImageFragment extends FileFragment implements Injectable { * This method hides to client objects the need of doing the construction in two steps. * * @param imageFile An {@link OCFile} to preview as an image in the fragment - * @param ignoreFirstSavedState Flag to work around an unexpected behaviour of {@link FragmentStatePagerAdapter} ; + * @param ignoreFirstSavedState Flag to work around an unexpected behaviour of {@link FragmentStateAdapter} ; * TODO better solution */ public static PreviewImageFragment newInstance(@NonNull OCFile imageFile, @@ -232,8 +233,17 @@ public void onActivityCreated(Bundle savedInstanceState) { if (savedInstanceState != null) { if (!ignoreFirstSavedState) { OCFile file = BundleExtensionsKt.getParcelableArgument(savedInstanceState, EXTRA_FILE, OCFile.class); + if (file == null) { + return; + } + setFile(file); - binding.image.setScale(Math.min(binding.image.getMaximumScale(), savedInstanceState.getFloat(EXTRA_ZOOM))); + + try { + binding.image.setScale(Math.min(binding.image.getMaximumScale(), savedInstanceState.getFloat(EXTRA_ZOOM))); + } catch (IllegalArgumentException e) { + Log_OC.d(TAG, "Error caught at setScale: " + e); + } } else { ignoreFirstSavedState = false; } diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.java b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.java index 1d39872b8515..895b27e7237e 100644 --- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.java +++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.java @@ -11,7 +11,6 @@ package com.owncloud.android.ui.preview; import android.util.SparseArray; -import android.view.ViewGroup; import com.nextcloud.client.account.User; import com.nextcloud.client.preferences.AppPreferences; @@ -31,40 +30,41 @@ import androidx.annotation.NonNull; import androidx.annotation.OptIn; import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentStatePagerAdapter; +import androidx.fragment.app.FragmentActivity; import androidx.media3.common.util.UnstableApi; +import androidx.viewpager2.adapter.FragmentStateAdapter; /** * Adapter class that provides Fragment instances */ -public class PreviewImagePagerAdapter extends FragmentStatePagerAdapter { +public class PreviewImagePagerAdapter extends FragmentStateAdapter { private OCFile selectedFile; private List mImageFiles; - private User user; - private Set mObsoleteFragments; - private Set mObsoletePositions; - private Set mDownloadErrors; - private FileDataStorageManager mStorageManager; - private SparseArray mCachedFragments; + private final User user; + private final Set mObsoleteFragments; + private final Set mObsoletePositions; + private final Set mDownloadErrors; + private final FileDataStorageManager mStorageManager; + private final SparseArray mCachedFragments; /** * Constructor * - * @param fragmentManager {@link FragmentManager} instance that will handle the {@link Fragment}s provided by the + * @param fragmentActivity {@link FragmentActivity} instance that will handle the {@link Fragment}s provided by the * adapter. * @param parentFolder Folder where images will be searched for. * @param storageManager Bridge to database. */ - public PreviewImagePagerAdapter(FragmentManager fragmentManager, + public PreviewImagePagerAdapter(FragmentActivity fragmentActivity, OCFile selectedFile, OCFile parentFolder, User user, FileDataStorageManager storageManager, boolean onlyOnDevice, AppPreferences preferences) { - super(fragmentManager); + super(fragmentActivity); + if (parentFolder == null) { throw new IllegalArgumentException("NULL parent folder"); } @@ -89,20 +89,17 @@ public PreviewImagePagerAdapter(FragmentManager fragmentManager, /** * Constructor * - * @param fragmentManager {@link FragmentManager} instance that will handle the {@link Fragment}s provided by the + * @param fragmentActivity {@link FragmentActivity} instance that will handle the {@link Fragment}s provided by the * adapter. * @param type Type of virtual folder, e.g. favorite or photos * @param storageManager Bridge to database. */ - public PreviewImagePagerAdapter(FragmentManager fragmentManager, + public PreviewImagePagerAdapter(FragmentActivity fragmentActivity, VirtualFolderType type, User user, FileDataStorageManager storageManager) { - super(fragmentManager); + super(fragmentActivity); - if (fragmentManager == null) { - throw new IllegalArgumentException("NULL FragmentManager instance"); - } if (type == null) { throw new IllegalArgumentException("NULL parent folder"); } @@ -129,6 +126,26 @@ public PreviewImagePagerAdapter(FragmentManager fragmentManager, mCachedFragments = new SparseArray<>(); } + public void delete(int position) { + if (position < 0 || position >= mImageFiles.size()) { + return; + } + + FileFragment fragmentToDelete = mCachedFragments.get(position); + if (fragmentToDelete == null) { + return; + } + + mObsoleteFragments.add(fragmentToDelete); + mObsoletePositions.add(position); + + mImageFiles.remove(position); + mDownloadErrors.remove(position); + mCachedFragments.remove(position); + + notifyDataSetChanged(); + } + /** * Returns the image files handled by the adapter. * @@ -182,12 +199,6 @@ public int getFilePosition(OCFile file) { return mImageFiles.indexOf(file); } - @Override - public int getCount() { - return mImageFiles.size(); - } - - @Override public CharSequence getPageTitle(int position) { OCFile file = getFileAt(position); @@ -198,7 +209,6 @@ public CharSequence getPageTitle(int position) { } } - public void updateFile(int position, OCFile file) { FileFragment fragmentToUpdate = mCachedFragments.get(position); if (fragmentToUpdate != null) { @@ -208,7 +218,6 @@ public void updateFile(int position, OCFile file) { mImageFiles.set(position, file); } - public void updateWithDownloadError(int position) { FileFragment fragmentToUpdate = mCachedFragments.get(position); if (fragmentToUpdate != null) { @@ -217,30 +226,20 @@ public void updateWithDownloadError(int position) { mDownloadErrors.add(position); } - @Override - public int getItemPosition(@NonNull Object object) { - if (mObsoleteFragments.remove(object)) { - return POSITION_NONE; - } - return super.getItemPosition(object); + + + public boolean pendingErrorAt(int position) { + return mDownloadErrors.contains(position); } @NonNull @Override - public Object instantiateItem(@NonNull ViewGroup container, int position) { - Object fragment = super.instantiateItem(container, position); - mCachedFragments.put(position, (FileFragment) fragment); - return fragment; + public Fragment createFragment(int position) { + return getItem(position); } @Override - public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) { - mCachedFragments.remove(position); - super.destroyItem(container, position, object); - } - - - public boolean pendingErrorAt(int position) { - return mDownloadErrors.contains(position); + public int getItemCount() { + return mImageFiles.size(); } } diff --git a/app/src/main/res/layout/preview_image_activity.xml b/app/src/main/res/layout/preview_image_activity.xml index a51e50a07841..35746487f5f1 100644 --- a/app/src/main/res/layout/preview_image_activity.xml +++ b/app/src/main/res/layout/preview_image_activity.xml @@ -10,16 +10,17 @@ ~ SPDX-FileCopyrightText: 2013 David A. Velasco ~ SPDX-License-Identifier: GPL-2.0-only AND (AGPL-3.0-or-later OR GPL-2.0-only) --> - - + android:layout_height="match_parent" /> + android:animateLayoutChanges="false"> Date: Thu, 16 May 2024 15:50:59 +0200 Subject: [PATCH 04/20] Notify only deleted position Signed-off-by: alperozturk --- .../ui/preview/PreviewImageActivity.java | 17 +++++++++-------- .../ui/preview/PreviewImagePagerAdapter.java | 14 +++++++++++--- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java index 56518d26fd8a..5ef3d7054c22 100644 --- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java @@ -52,6 +52,8 @@ import com.owncloud.android.utils.MimeTypeUtil; import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; import javax.inject.Inject; @@ -277,16 +279,15 @@ public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationRe super.onRemoteOperationFinish(operation, result); if (operation instanceof RemoveFileOperation) { - final RecyclerView.Adapter adapter = viewPager.getAdapter(); + if (viewPager.getAdapter() != null) { + int deletePosition = viewPager.getCurrentItem(); + previewImagePagerAdapter.delete(deletePosition); - if (adapter != null) { - previewImagePagerAdapter.delete(viewPager.getCurrentItem()); - - if (adapter.getItemCount() > 0) { - int nextPosition = viewPager.getCurrentItem() + 1; + if (viewPager.getAdapter().getItemCount() > 0) { + int nextPosition = deletePosition + 1; viewPager.setCurrentItem(nextPosition); - updateActionBarTitle(String.valueOf(previewImagePagerAdapter.getPageTitle(nextPosition))); - + String nextItemTitle = String.valueOf(previewImagePagerAdapter.getPageTitle(nextPosition)); + updateActionBarTitle(nextItemTitle); } else { // Last file has been deleted, so finish the activity finish(); diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.java b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.java index 895b27e7237e..75a81335a595 100644 --- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.java +++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.java @@ -143,7 +143,7 @@ public void delete(int position) { mDownloadErrors.remove(position); mCachedFragments.remove(position); - notifyDataSetChanged(); + notifyItemRemoved(position); } /** @@ -160,6 +160,16 @@ public OCFile getFileAt(int position) { } } + @Override + public long getItemId(int position) { + return mImageFiles.get(position).hashCode(); + } + + @Override + public boolean containsItem(long itemId) { + return super.containsItem(itemId); + } + private void addVideoOfLivePhoto(OCFile file) { file.livePhotoVideo = selectedFile; } @@ -226,8 +236,6 @@ public void updateWithDownloadError(int position) { mDownloadErrors.add(position); } - - public boolean pendingErrorAt(int position) { return mDownloadErrors.contains(position); } From 8618a5a98038eefcf34796504e8bf548cfdad98b Mon Sep 17 00:00:00 2001 From: alperozturk Date: Thu, 16 May 2024 16:20:37 +0200 Subject: [PATCH 05/20] Simplify onRemoteOperationFinish Signed-off-by: alperozturk --- .../ui/preview/PreviewImageActivity.java | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java index 5ef3d7054c22..2102fa2b45f1 100644 --- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java @@ -279,22 +279,27 @@ public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationRe super.onRemoteOperationFinish(operation, result); if (operation instanceof RemoveFileOperation) { - if (viewPager.getAdapter() != null) { - int deletePosition = viewPager.getCurrentItem(); - previewImagePagerAdapter.delete(deletePosition); - - if (viewPager.getAdapter().getItemCount() > 0) { - int nextPosition = deletePosition + 1; - viewPager.setCurrentItem(nextPosition); - String nextItemTitle = String.valueOf(previewImagePagerAdapter.getPageTitle(nextPosition)); - updateActionBarTitle(nextItemTitle); - } else { - // Last file has been deleted, so finish the activity - finish(); - } - } else { + if (viewPager.getAdapter() == null) { + finish(); + return; + } + + int deletePosition = viewPager.getCurrentItem(); + previewImagePagerAdapter.delete(deletePosition); + + if (viewPager.getAdapter().getItemCount() <= 0) { finish(); + return; } + + int nextPosition = deletePosition + 1; + if (nextPosition < 0 || nextPosition >= viewPager.getAdapter().getItemCount()) { + finish(); + } + + viewPager.setCurrentItem(nextPosition); + String nextItemTitle = String.valueOf(previewImagePagerAdapter.getPageTitle(nextPosition)); + updateActionBarTitle(nextItemTitle); } else if (operation instanceof SynchronizeFileOperation) { onSynchronizeFileOperationFinish(result); } From d47c5b82c11d736130a7ac6c91307e776eefa895 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Thu, 16 May 2024 16:37:31 +0200 Subject: [PATCH 06/20] Rename .java to .kt Signed-off-by: alperozturk --- ...{PreviewImagePagerAdapter.java => PreviewImagePagerAdapter.kt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename app/src/main/java/com/owncloud/android/ui/preview/{PreviewImagePagerAdapter.java => PreviewImagePagerAdapter.kt} (100%) diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.java b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.kt similarity index 100% rename from app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.java rename to app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.kt From cd8e11b065d5f5402d69b8aa434f4a46e878d035 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Thu, 16 May 2024 16:37:32 +0200 Subject: [PATCH 07/20] Convert to kotlin and fix delete Signed-off-by: alperozturk --- .../ui/preview/PreviewImagePagerAdapter.kt | 286 ++++++++---------- 1 file changed, 125 insertions(+), 161 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.kt b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.kt index 75a81335a595..a88ccab92945 100644 --- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.kt +++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.kt @@ -8,142 +8,118 @@ * SPDX-FileCopyrightText: 2013 David A. Velasco * SPDX-License-Identifier: GPL-2.0-only AND (AGPL-3.0-or-later OR GPL-2.0-only) */ -package com.owncloud.android.ui.preview; - -import android.util.SparseArray; - -import com.nextcloud.client.account.User; -import com.nextcloud.client.preferences.AppPreferences; -import com.owncloud.android.datamodel.FileDataStorageManager; -import com.owncloud.android.datamodel.OCFile; -import com.owncloud.android.datamodel.VirtualFolderType; -import com.owncloud.android.ui.fragment.FileFragment; -import com.owncloud.android.utils.FileSortOrder; -import com.owncloud.android.utils.FileStorageUtils; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import javax.annotation.Nullable; - -import androidx.annotation.NonNull; -import androidx.annotation.OptIn; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentActivity; -import androidx.media3.common.util.UnstableApi; -import androidx.viewpager2.adapter.FragmentStateAdapter; +package com.owncloud.android.ui.preview + +import android.util.SparseArray +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentActivity +import androidx.viewpager2.adapter.FragmentStateAdapter +import com.nextcloud.client.account.User +import com.nextcloud.client.preferences.AppPreferences +import com.owncloud.android.datamodel.FileDataStorageManager +import com.owncloud.android.datamodel.OCFile +import com.owncloud.android.datamodel.VirtualFolderType +import com.owncloud.android.ui.fragment.FileFragment +import com.owncloud.android.utils.FileStorageUtils /** * Adapter class that provides Fragment instances */ -public class PreviewImagePagerAdapter extends FragmentStateAdapter { +class PreviewImagePagerAdapter : FragmentStateAdapter { - private OCFile selectedFile; - private List mImageFiles; - private final User user; - private final Set mObsoleteFragments; - private final Set mObsoletePositions; - private final Set mDownloadErrors; - private final FileDataStorageManager mStorageManager; - private final SparseArray mCachedFragments; + private var selectedFile: OCFile? = null + private var imageFiles: MutableList = mutableListOf() + private val user: User + private val mObsoleteFragments: MutableSet + private val mObsoletePositions: MutableSet + private val mDownloadErrors: MutableSet + private val mStorageManager: FileDataStorageManager + private val mCachedFragments: SparseArray /** * Constructor * - * @param fragmentActivity {@link FragmentActivity} instance that will handle the {@link Fragment}s provided by the - * adapter. + * @param fragmentActivity [FragmentActivity] instance that will handle the [Fragment]s provided by the + * adapter. * @param parentFolder Folder where images will be searched for. * @param storageManager Bridge to database. */ - public PreviewImagePagerAdapter(FragmentActivity fragmentActivity, - OCFile selectedFile, - OCFile parentFolder, - User user, - FileDataStorageManager storageManager, - boolean onlyOnDevice, - AppPreferences preferences) { - super(fragmentActivity); - - if (parentFolder == null) { - throw new IllegalArgumentException("NULL parent folder"); - } - if (storageManager == null) { - throw new IllegalArgumentException("NULL storage manager"); - } - - this.user = user; - this.selectedFile = selectedFile; - mStorageManager = storageManager; - mImageFiles = mStorageManager.getFolderImages(parentFolder, onlyOnDevice); - - FileSortOrder sortOrder = preferences.getSortOrderByFolder(parentFolder); - mImageFiles = sortOrder.sortCloudFiles(mImageFiles); - - mObsoleteFragments = new HashSet<>(); - mObsoletePositions = new HashSet<>(); - mDownloadErrors = new HashSet<>(); - mCachedFragments = new SparseArray<>(); + constructor( + fragmentActivity: FragmentActivity?, + selectedFile: OCFile?, + parentFolder: OCFile?, + user: User, + storageManager: FileDataStorageManager?, + onlyOnDevice: Boolean, + preferences: AppPreferences + ) : super(fragmentActivity!!) { + requireNotNull(parentFolder) { "NULL parent folder" } + requireNotNull(storageManager) { "NULL storage manager" } + + this.user = user + this.selectedFile = selectedFile + mStorageManager = storageManager + imageFiles = mStorageManager.getFolderImages(parentFolder, onlyOnDevice) + + val sortOrder = preferences.getSortOrderByFolder(parentFolder) + imageFiles = sortOrder.sortCloudFiles(imageFiles.toMutableList()).toMutableList() + + mObsoleteFragments = HashSet() + mObsoletePositions = HashSet() + mDownloadErrors = HashSet() + mCachedFragments = SparseArray() } /** * Constructor * - * @param fragmentActivity {@link FragmentActivity} instance that will handle the {@link Fragment}s provided by the - * adapter. + * @param fragmentActivity [FragmentActivity] instance that will handle the [Fragment]s provided by the + * adapter. * @param type Type of virtual folder, e.g. favorite or photos * @param storageManager Bridge to database. */ - public PreviewImagePagerAdapter(FragmentActivity fragmentActivity, - VirtualFolderType type, - User user, - FileDataStorageManager storageManager) { - super(fragmentActivity); - - if (type == null) { - throw new IllegalArgumentException("NULL parent folder"); - } - if (type == VirtualFolderType.NONE) { - throw new IllegalArgumentException("NONE virtual folder type"); - } - if (storageManager == null) { - throw new IllegalArgumentException("NULL storage manager"); - } - - this.user = user; - mStorageManager = storageManager; + constructor( + fragmentActivity: FragmentActivity?, + type: VirtualFolderType?, + user: User, + storageManager: FileDataStorageManager? + ) : super(fragmentActivity!!) { + requireNotNull(type) { "NULL parent folder" } + require(type != VirtualFolderType.NONE) { "NONE virtual folder type" } + requireNotNull(storageManager) { "NULL storage manager" } + + this.user = user + mStorageManager = storageManager if (type == VirtualFolderType.GALLERY) { - mImageFiles = mStorageManager.getAllGalleryItems(); - mImageFiles = FileStorageUtils.sortOcFolderDescDateModifiedWithoutFavoritesFirst(mImageFiles); + imageFiles = mStorageManager.allGalleryItems + imageFiles = FileStorageUtils.sortOcFolderDescDateModifiedWithoutFavoritesFirst(imageFiles) } else { - mImageFiles = mStorageManager.getVirtualFolderContent(type, true); + imageFiles = mStorageManager.getVirtualFolderContent(type, true) } - mObsoleteFragments = new HashSet<>(); - mObsoletePositions = new HashSet<>(); - mDownloadErrors = new HashSet<>(); - mCachedFragments = new SparseArray<>(); + mObsoleteFragments = HashSet() + mObsoletePositions = HashSet() + mDownloadErrors = HashSet() + mCachedFragments = SparseArray() } - public void delete(int position) { - if (position < 0 || position >= mImageFiles.size()) { - return; + fun delete(position: Int) { + if (position < 0 || position >= imageFiles.size) { + return } - FileFragment fragmentToDelete = mCachedFragments.get(position); - if (fragmentToDelete == null) { - return; + mCachedFragments[position]?.let { + mObsoleteFragments.add(it) } - mObsoleteFragments.add(fragmentToDelete); - mObsoletePositions.add(position); + mObsoletePositions.add(position) - mImageFiles.remove(position); - mDownloadErrors.remove(position); - mCachedFragments.remove(position); + imageFiles.removeAt(position) + mDownloadErrors.remove(position) + mCachedFragments.remove(position) - notifyItemRemoved(position); + notifyItemRemoved(position) } /** @@ -151,103 +127,91 @@ public class PreviewImagePagerAdapter extends FragmentStateAdapter { * * @return OCFile desired image or null if position is not in adapter */ - @Nullable - public OCFile getFileAt(int position) { - try { - return mImageFiles.get(position); - } catch (IndexOutOfBoundsException exception) { - return null; + fun getFileAt(position: Int): OCFile? { + return try { + imageFiles!![position] + } catch (exception: IndexOutOfBoundsException) { + null } } - @Override - public long getItemId(int position) { - return mImageFiles.get(position).hashCode(); - } - - @Override - public boolean containsItem(long itemId) { - return super.containsItem(itemId); + override fun getItemId(position: Int): Long { + return imageFiles[position].hashCode().toLong() } - private void addVideoOfLivePhoto(OCFile file) { - file.livePhotoVideo = selectedFile; + private fun addVideoOfLivePhoto(file: OCFile) { + file.livePhotoVideo = selectedFile } - @NonNull - @OptIn(markerClass = UnstableApi.class) - public Fragment getItem(int i) { - OCFile file = getFileAt(i); - Fragment fragment; + fun getItem(i: Int): Fragment { + val file = getFileAt(i) + val fragment: Fragment if (file == null) { - fragment = PreviewImageErrorFragment.newInstance(); - } else if (file.isDown()) { - fragment = PreviewImageFragment.newInstance(file, mObsoletePositions.contains(i), false); + fragment = PreviewImageErrorFragment.newInstance() + } else if (file.isDown) { + fragment = PreviewImageFragment.newInstance(file, mObsoletePositions.contains(i), false) } else { - addVideoOfLivePhoto(file); + addVideoOfLivePhoto(file) if (mDownloadErrors.remove(i)) { - fragment = FileDownloadFragment.newInstance(file, user, true); - ((FileDownloadFragment) fragment).setError(true); + fragment = FileDownloadFragment.newInstance(file, user, true) + (fragment as FileDownloadFragment).setError(true) } else { - if (file.isEncrypted()) { - fragment = FileDownloadFragment.newInstance(file, user, mObsoletePositions.contains(i)); + fragment = if (file.isEncrypted) { + FileDownloadFragment.newInstance(file, user, mObsoletePositions.contains(i)) } else if (PreviewMediaFragment.canBePreviewed(file)) { - fragment = PreviewMediaFragment.newInstance(file, user, 0, false, file.livePhotoVideo != null); + PreviewMediaFragment.newInstance(file, user, 0, false, file.livePhotoVideo != null) } else { - fragment = PreviewImageFragment.newInstance(file, mObsoletePositions.contains(i), true); + PreviewImageFragment.newInstance(file, mObsoletePositions.contains(i), true) } } } - mObsoletePositions.remove(i); - return fragment; + mObsoletePositions.remove(i) + return fragment } - public int getFilePosition(OCFile file) { - return mImageFiles.indexOf(file); + fun getFilePosition(file: OCFile): Int { + return imageFiles.indexOf(file) } - public CharSequence getPageTitle(int position) { - OCFile file = getFileAt(position); + fun getPageTitle(position: Int): CharSequence { + val file = getFileAt(position) - if (file != null) { - return file.getFileName(); + return if (file != null) { + file.fileName } else { - return ""; + "" } } - public void updateFile(int position, OCFile file) { - FileFragment fragmentToUpdate = mCachedFragments.get(position); + fun updateFile(position: Int, file: OCFile) { + val fragmentToUpdate = mCachedFragments[position] if (fragmentToUpdate != null) { - mObsoleteFragments.add(fragmentToUpdate); + mObsoleteFragments.add(fragmentToUpdate) } - mObsoletePositions.add(position); - mImageFiles.set(position, file); + mObsoletePositions.add(position) + imageFiles[position] = file } - public void updateWithDownloadError(int position) { - FileFragment fragmentToUpdate = mCachedFragments.get(position); + fun updateWithDownloadError(position: Int) { + val fragmentToUpdate = mCachedFragments[position] if (fragmentToUpdate != null) { - mObsoleteFragments.add(fragmentToUpdate); + mObsoleteFragments.add(fragmentToUpdate) } - mDownloadErrors.add(position); + mDownloadErrors.add(position) } - public boolean pendingErrorAt(int position) { - return mDownloadErrors.contains(position); + fun pendingErrorAt(position: Int): Boolean { + return mDownloadErrors.contains(position) } - @NonNull - @Override - public Fragment createFragment(int position) { - return getItem(position); + override fun createFragment(position: Int): Fragment { + return getItem(position) } - @Override - public int getItemCount() { - return mImageFiles.size(); + override fun getItemCount(): Int { + return imageFiles.size } } From d6678531023fbafcaf72f4f4048207a884915fcf Mon Sep 17 00:00:00 2001 From: alperozturk Date: Thu, 16 May 2024 16:39:09 +0200 Subject: [PATCH 08/20] Optimize imports Signed-off-by: alperozturk --- .../com/owncloud/android/ui/preview/PreviewImageActivity.java | 4 ---- .../owncloud/android/ui/preview/PreviewImagePagerAdapter.kt | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java index 2102fa2b45f1..4f5d4508a600 100644 --- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java @@ -21,7 +21,6 @@ import android.os.Bundle; import android.view.MenuItem; import android.view.View; -import android.view.ViewGroup; import com.nextcloud.client.account.User; import com.nextcloud.client.di.Injectable; @@ -52,8 +51,6 @@ import com.owncloud.android.utils.MimeTypeUtil; import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; import java.util.Optional; import javax.inject.Inject; @@ -62,7 +59,6 @@ import androidx.appcompat.app.ActionBar; import androidx.drawerlayout.widget.DrawerLayout; import androidx.localbroadcastmanager.content.LocalBroadcastManager; -import androidx.recyclerview.widget.RecyclerView; import androidx.viewpager2.widget.ViewPager2; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.kt b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.kt index a88ccab92945..2f9069a7960a 100644 --- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.kt +++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.kt @@ -129,7 +129,7 @@ class PreviewImagePagerAdapter : FragmentStateAdapter { */ fun getFileAt(position: Int): OCFile? { return try { - imageFiles!![position] + imageFiles[position] } catch (exception: IndexOutOfBoundsException) { null } From d1c2cc43d9366798e765b5da649d96ac4e970b26 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Thu, 16 May 2024 16:46:18 +0200 Subject: [PATCH 09/20] Remove unused CustomViewPager Signed-off-by: alperozturk --- .../ui/components/CustomViewPager.java | 47 ------------------- 1 file changed, 47 deletions(-) delete mode 100644 app/src/main/java/com/owncloud/android/ui/components/CustomViewPager.java diff --git a/app/src/main/java/com/owncloud/android/ui/components/CustomViewPager.java b/app/src/main/java/com/owncloud/android/ui/components/CustomViewPager.java deleted file mode 100644 index d3ce4a5f512b..000000000000 --- a/app/src/main/java/com/owncloud/android/ui/components/CustomViewPager.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Nextcloud - Android Client - * - * SPDX-FileCopyrightText: 2018 Tobias Kaminsky - * SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only - */ -package com.owncloud.android.ui.components; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.util.AttributeSet; -import android.view.MotionEvent; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.viewpager.widget.ViewPager; - -public class CustomViewPager extends ViewPager { - public CustomViewPager(@NonNull Context context) { - super(context); - } - - public CustomViewPager(@NonNull Context context, @Nullable AttributeSet attrs) { - super(context, attrs); - } - - @SuppressLint("ClickableViewAccessibility") - @Override - public boolean onTouchEvent(MotionEvent ev) { - try { - return super.onTouchEvent(ev); - } catch (IllegalArgumentException ex) { - // no logging as this might flood log and we cannot do anything - } - return false; - } - - @Override - public boolean onInterceptTouchEvent(MotionEvent ev) { - try { - return super.onInterceptTouchEvent(ev); - } catch (IllegalArgumentException ex) { - // no logging as this might flood log and we cannot do anything - } - return false; - } -} From 4e1dda37634b11597f1ae431f1b6b11dbe1e90ce Mon Sep 17 00:00:00 2001 From: alperozturk Date: Thu, 16 May 2024 16:58:43 +0200 Subject: [PATCH 10/20] Fix code analytics Signed-off-by: alperozturk --- .../com/owncloud/android/ui/preview/PreviewImagePagerAdapter.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.kt b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.kt index 2f9069a7960a..24906d602caa 100644 --- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.kt +++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.kt @@ -44,6 +44,7 @@ class PreviewImagePagerAdapter : FragmentStateAdapter { * @param parentFolder Folder where images will be searched for. * @param storageManager Bridge to database. */ + @Suppress("LongParameterList") constructor( fragmentActivity: FragmentActivity?, selectedFile: OCFile?, @@ -127,6 +128,7 @@ class PreviewImagePagerAdapter : FragmentStateAdapter { * * @return OCFile desired image or null if position is not in adapter */ + @Suppress("TooGenericExceptionCaught") fun getFileAt(position: Int): OCFile? { return try { imageFiles[position] From 07e00f4bc5202b2b3a91b1ec6f0cdebf4cf311f2 Mon Sep 17 00:00:00 2001 From: ZetaTom <70907959+ZetaTom@users.noreply.github.com> Date: Fri, 17 May 2024 09:51:26 +0200 Subject: [PATCH 11/20] Fix scrolling in view pager. Signed-off-by: ZetaTom <70907959+ZetaTom@users.noreply.github.com> --- .../ui/preview/PreviewImageActivity.java | 21 +++++-------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java index 4f5d4508a600..f52bb10a2561 100644 --- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java @@ -193,7 +193,7 @@ public void onPageSelected(int position) { selectPage(position); } }); - viewPager.setCurrentItem(position); + viewPager.setCurrentItem(position, false); if (position == 0 && !getFile().isDown()) { // this is necessary because mViewPager.setCurrentItem(0) just after setting the @@ -275,27 +275,16 @@ public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationRe super.onRemoteOperationFinish(operation, result); if (operation instanceof RemoveFileOperation) { - if (viewPager.getAdapter() == null) { - finish(); - return; - } - int deletePosition = viewPager.getCurrentItem(); - previewImagePagerAdapter.delete(deletePosition); + int nextPosition = deletePosition > 0 ? deletePosition - 1 : 0; - if (viewPager.getAdapter().getItemCount() <= 0) { + if (previewImagePagerAdapter.getItemCount() <= 1) { finish(); return; } - int nextPosition = deletePosition + 1; - if (nextPosition < 0 || nextPosition >= viewPager.getAdapter().getItemCount()) { - finish(); - } - - viewPager.setCurrentItem(nextPosition); - String nextItemTitle = String.valueOf(previewImagePagerAdapter.getPageTitle(nextPosition)); - updateActionBarTitle(nextItemTitle); + viewPager.setCurrentItem(nextPosition, true); + previewImagePagerAdapter.delete(deletePosition); } else if (operation instanceof SynchronizeFileOperation) { onSynchronizeFileOperationFinish(result); } From 11139e4d1bdeda3dc4f0948bbb82c18116dc470a Mon Sep 17 00:00:00 2001 From: alperozturk Date: Fri, 17 May 2024 10:02:27 +0200 Subject: [PATCH 12/20] Reduce lint Signed-off-by: alperozturk --- .../ui/preview/PreviewImageActivity.java | 33 ++++++++----------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java index f52bb10a2561..2954944d2cd6 100644 --- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java @@ -83,7 +83,6 @@ public class PreviewImageActivity extends FileActivity implements private boolean hasSavedPosition; private boolean requestWaitingForBinder; private DownloadFinishReceiver downloadFinishReceiver; - private UploadFinishReceiver uploadFinishReceiver; private View fullScreenAnchorView; private boolean isDownloadWorkStarted = false; @@ -184,7 +183,7 @@ private void initViewPager(User user) { viewPager = findViewById(R.id.fragmentPager); int position = hasSavedPosition ? savedPosition : previewImagePagerAdapter.getFilePosition(getFile()); - position = position >= 0 ? position : 0; + position = Math.max(position, 0); viewPager.setAdapter(previewImagePagerAdapter); viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { @@ -333,7 +332,7 @@ protected void onResume() { IntentFilter downloadIntentFilter = new IntentFilter(FileDownloadWorker.Companion.getDownloadFinishMessage()); localBroadcastManager.registerReceiver(downloadFinishReceiver, downloadIntentFilter); - uploadFinishReceiver = new UploadFinishReceiver(); + UploadFinishReceiver uploadFinishReceiver = new UploadFinishReceiver(); IntentFilter uploadIntentFilter = new IntentFilter(FileUploadWorker.Companion.getUploadFinishMessage()); localBroadcastManager.registerReceiver(uploadFinishReceiver, uploadIntentFilter); } @@ -424,7 +423,7 @@ public void updateActionBarTitle(String title) { /** * Class waiting for broadcast events from the {@link FileDownloadWorker} service. - * + *

* Updates the UI when a download is started or finished, provided that it is relevant for the * folder displayed in the gallery. */ @@ -446,8 +445,9 @@ private void previewNewImage(Intent intent) { String accountName = intent.getStringExtra(FileDownloadWorker.EXTRA_ACCOUNT_NAME); String downloadedRemotePath = intent.getStringExtra(FileDownloadWorker.EXTRA_REMOTE_PATH); String downloadBehaviour = intent.getStringExtra(OCFileListFragment.DOWNLOAD_BEHAVIOUR); + if (getAccount().name.equals(accountName) && downloadedRemotePath != null) { - OCFile file = getStorageManager().getFileByPath(downloadedRemotePath); + OCFile file = getStorageManager().getFileByEncryptedRemotePath(downloadedRemotePath); boolean downloadWasFine = intent.getBooleanExtra(FileDownloadWorker.EXTRA_DOWNLOAD_RESULT, false); if (EditImageActivity.OPEN_IMAGE_EDITOR.equals(downloadBehaviour)) { @@ -457,16 +457,19 @@ private void previewNewImage(Intent intent) { if (position >= 0) { if (downloadWasFine) { previewImagePagerAdapter.updateFile(position, file); - } else { previewImagePagerAdapter.updateWithDownloadError(position); } - previewImagePagerAdapter.notifyDataSetChanged(); // will trigger the creation of new fragments + previewImagePagerAdapter.notifyItemChanged(position); } else if (downloadWasFine) { - initViewPager(getUser().get()); - int newPosition = previewImagePagerAdapter.getFilePosition(file); - if (newPosition >= 0) { - viewPager.setCurrentItem(newPosition); + Optional user = getUser(); + + if (user.isPresent()) { + initViewPager(user.get()); + int newPosition = previewImagePagerAdapter.getFilePosition(file); + if (newPosition >= 0) { + viewPager.setCurrentItem(newPosition); + } } } } @@ -483,19 +486,11 @@ public void toggleFullScreen() { if (visible) { hideSystemUI(fullScreenAnchorView); - // actionBar.hide(); // propagated through - // OnSystemUiVisibilityChangeListener() } else { showSystemUI(fullScreenAnchorView); - // actionBar.show(); // propagated through - // OnSystemUiVisibilityChangeListener() } } - public void switchToFullScreen() { - hideSystemUI(fullScreenAnchorView); - } - public void startImageEditor(OCFile file) { if (file.isDown()) { Intent editImageIntent = new Intent(this, EditImageActivity.class); From f94ad4e754433deaa7988c300cd7f87d82118f79 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Tue, 21 May 2024 09:39:31 +0200 Subject: [PATCH 13/20] Use non nullable parameters, delete unused functions Signed-off-by: alperozturk --- .../ui/preview/PreviewImageActivity.java | 5 ++-- .../ui/preview/PreviewImagePagerAdapter.kt | 24 +++++-------------- 2 files changed, 8 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java index 2954944d2cd6..0b9dd92b523e 100644 --- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.java @@ -166,7 +166,7 @@ private void initViewPager(User user) { if (parentFolder == null) { // should not be necessary - parentFolder = getStorageManager().getFileByPath(OCFile.ROOT_PATH); + parentFolder = getStorageManager().getFileByEncryptedRemotePath(OCFile.ROOT_PATH); } previewImagePagerAdapter = new PreviewImagePagerAdapter( @@ -410,9 +410,8 @@ public void selectPage(int position) { if (currentFile != null) { updateActionBarTitle(currentFile.getFileName()); + setDrawerIndicatorEnabled(false); } - - setDrawerIndicatorEnabled(false); } public void updateActionBarTitle(String title) { diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.kt b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.kt index 24906d602caa..ac5128fc5874 100644 --- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.kt +++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.kt @@ -46,16 +46,15 @@ class PreviewImagePagerAdapter : FragmentStateAdapter { */ @Suppress("LongParameterList") constructor( - fragmentActivity: FragmentActivity?, + fragmentActivity: FragmentActivity, selectedFile: OCFile?, parentFolder: OCFile?, user: User, - storageManager: FileDataStorageManager?, + storageManager: FileDataStorageManager, onlyOnDevice: Boolean, preferences: AppPreferences - ) : super(fragmentActivity!!) { + ) : super(fragmentActivity) { requireNotNull(parentFolder) { "NULL parent folder" } - requireNotNull(storageManager) { "NULL storage manager" } this.user = user this.selectedFile = selectedFile @@ -80,14 +79,13 @@ class PreviewImagePagerAdapter : FragmentStateAdapter { * @param storageManager Bridge to database. */ constructor( - fragmentActivity: FragmentActivity?, + fragmentActivity: FragmentActivity, type: VirtualFolderType?, user: User, - storageManager: FileDataStorageManager? - ) : super(fragmentActivity!!) { + storageManager: FileDataStorageManager + ) : super(fragmentActivity) { requireNotNull(type) { "NULL parent folder" } require(type != VirtualFolderType.NONE) { "NONE virtual folder type" } - requireNotNull(storageManager) { "NULL storage manager" } this.user = user mStorageManager = storageManager @@ -178,16 +176,6 @@ class PreviewImagePagerAdapter : FragmentStateAdapter { return imageFiles.indexOf(file) } - fun getPageTitle(position: Int): CharSequence { - val file = getFileAt(position) - - return if (file != null) { - file.fileName - } else { - "" - } - } - fun updateFile(position: Int, file: OCFile) { val fragmentToUpdate = mCachedFragments[position] if (fragmentToUpdate != null) { From 2082b625ec05c0826237ed6b4fc04763132a1a12 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Tue, 21 May 2024 11:52:24 +0200 Subject: [PATCH 14/20] Fix compatibility problems with some browsers Signed-off-by: alperozturk --- .../authentication/AuthenticatorActivity.java | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java b/app/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java index 313713c47f7b..6e24fffa8e8f 100644 --- a/app/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java +++ b/app/src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java @@ -143,6 +143,9 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.LifecycleEventObserver; +import androidx.lifecycle.ProcessLifecycleOwner; import de.cotech.hw.fido.WebViewFidoBridge; import de.cotech.hw.fido.ui.FidoDialogOptions; import de.cotech.hw.fido2.WebViewWebauthnBridge; @@ -360,10 +363,18 @@ protected void onCreate(Bundle savedInstanceState) { } initServerPreFragment(savedInstanceState); + ProcessLifecycleOwner.get().getLifecycle().addObserver(lifecycleEventObserver); // webViewUtil.checkWebViewVersion(); } + private final LifecycleEventObserver lifecycleEventObserver = ((lifecycleOwner, event) -> { + if (event == Lifecycle.Event.ON_START && token != null) { + Log_OC.d(TAG, "Start poolLogin"); + poolLogin(clientFactory.createPlainClient()); + } + }); + private void deleteCookies() { try { CookieSyncManager.createInstance(this); @@ -403,7 +414,8 @@ private void anonymouslyPostLoginRequest(String url) { String loginUrl = login; runOnUiThread(() -> { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(loginUrl)); - loginFlowResultLauncher.launch(intent); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); }); token = jsonObject.getAsJsonObject("poll").get("token").getAsString(); @@ -412,9 +424,6 @@ private void anonymouslyPostLoginRequest(String url) { thread.start(); } - private final ActivityResultLauncher loginFlowResultLauncher = registerForActivityResult( - new ActivityResultContracts.StartActivityForResult(), result -> poolLogin(clientFactory.createPlainClient())); - private static String getWebLoginUserAgent() { return Build.MANUFACTURER.substring(0, 1).toUpperCase(Locale.getDefault()) + Build.MANUFACTURER.substring(1).toLowerCase(Locale.getDefault()) + " " + Build.MODEL + " (Android)"; @@ -828,6 +837,8 @@ protected void onDestroy() { mOperationsServiceBinder = null; } + Log_OC.d(TAG, "AuthenticatorActivity onDestroy called"); + super.onDestroy(); } @@ -1039,6 +1050,7 @@ private void initLoginInfoView() { cancelButton.setOnClickListener(v -> { loginFlowExecutorService.shutdown(); + ProcessLifecycleOwner.get().getLifecycle().removeObserver(lifecycleEventObserver); recreate(); }); } @@ -1638,7 +1650,7 @@ public void onServiceDisconnected(ComponentName component) { private boolean isRedirectedToTheDefaultBrowser = false; private void poolLogin(PlainClient client) { - loginFlowExecutorService.scheduleAtFixedRate(() -> { + loginFlowExecutorService.scheduleWithFixedDelay(() -> { if (!isLoginProcessCompleted) { performLoginFlowV2(client); } @@ -1694,6 +1706,7 @@ private void completeLoginFlow(String response, int status) { checkOcServer(); loginFlowExecutorService.shutdown(); + ProcessLifecycleOwner.get().getLifecycle().removeObserver(lifecycleEventObserver); } /** From 475ecf681ed3d99a3537b526893928ed7e7027e1 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 21 May 2024 09:59:32 +0000 Subject: [PATCH 15/20] Analysis: update lint results to reflect reduced error/warning count Signed-off-by: github-actions --- scripts/analysis/lint-results.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/analysis/lint-results.txt b/scripts/analysis/lint-results.txt index fa64b20338d3..9531ef5b263b 100644 --- a/scripts/analysis/lint-results.txt +++ b/scripts/analysis/lint-results.txt @@ -1,2 +1,2 @@ DO NOT TOUCH; GENERATED BY DRONE - Lint Report: 3 errors and 72 warnings + Lint Report: 3 errors and 71 warnings From ba4bfe5412edf9bbcdfc272a2342924cea0d2f6f Mon Sep 17 00:00:00 2001 From: alperozturk Date: Tue, 21 May 2024 12:23:52 +0200 Subject: [PATCH 16/20] Update lint results Signed-off-by: alperozturk --- scripts/analysis/lint-results.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/analysis/lint-results.txt b/scripts/analysis/lint-results.txt index fa64b20338d3..9531ef5b263b 100644 --- a/scripts/analysis/lint-results.txt +++ b/scripts/analysis/lint-results.txt @@ -1,2 +1,2 @@ DO NOT TOUCH; GENERATED BY DRONE - Lint Report: 3 errors and 72 warnings + Lint Report: 3 errors and 71 warnings From 801e00cf82ebc766bfa52d83f59d55df1759d8ff Mon Sep 17 00:00:00 2001 From: Benedek Major Date: Thu, 2 May 2024 01:48:50 +0200 Subject: [PATCH 17/20] Replaced own walkFileTree with correct implementation from nnio package. This prevents a NullPointerException on the case, that listFiles() returns a null pointer, as that is allowed per spec. Signed-off-by: Benedek Major --- .../com/owncloud/android/utils/FileUtil.java | 20 ------------------- .../android/utils/FilesSyncHelper.java | 3 ++- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/utils/FileUtil.java b/app/src/main/java/com/owncloud/android/utils/FileUtil.java index 09f64481d911..b378f564fe7d 100644 --- a/app/src/main/java/com/owncloud/android/utils/FileUtil.java +++ b/app/src/main/java/com/owncloud/android/utils/FileUtil.java @@ -12,11 +12,6 @@ import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.lib.resources.files.UploadFileRemoteOperation; -import org.lukhnos.nnio.file.FileVisitResult; -import org.lukhnos.nnio.file.FileVisitor; -import org.lukhnos.nnio.file.Path; -import org.lukhnos.nnio.file.impl.FileBasedPathImpl; - import java.io.File; import java.io.IOException; import java.nio.file.Files; @@ -68,19 +63,4 @@ Long getCreationTimestamp(File file) { return null; } } - - public static Path walkFileTree(Path start, FileVisitor visitor) throws IOException { - if (org.lukhnos.nnio.file.Files.isDirectory(start)) { - org.lukhnos.nnio.file.FileVisitResult preVisitDirectoryResult = visitor.preVisitDirectory(start, null); - if (preVisitDirectoryResult == FileVisitResult.CONTINUE) { - for (File child : start.toFile().listFiles()) { - walkFileTree(FileBasedPathImpl.get(child), visitor); - } - } - visitor.postVisitDirectory(start, null); - } else { - visitor.visitFile(start, new org.lukhnos.nnio.file.attribute.BasicFileAttributes(start.toFile())); - } - return start; - } } diff --git a/app/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java b/app/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java index 941771b11873..46edde295352 100644 --- a/app/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java +++ b/app/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java @@ -36,6 +36,7 @@ import org.lukhnos.nnio.file.Paths; import org.lukhnos.nnio.file.SimpleFileVisitor; import org.lukhnos.nnio.file.attribute.BasicFileAttributes; +import org.lukhnos.nnio.file.Files; import java.io.File; import java.io.IOException; @@ -63,7 +64,7 @@ private static void insertCustomFolderIntoDB(Path path, final long enabledTimestampMs = syncedFolder.getEnabledTimestampMs(); try { - FileUtil.walkFileTree(path, new SimpleFileVisitor<>() { + Files.walkFileTree(path, new SimpleFileVisitor<>() { @Override public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) { File file = path.toFile(); From 1cdb0c7498f7742ce0d1a9d8616c435c4bc41b82 Mon Sep 17 00:00:00 2001 From: Benedek Major Date: Fri, 10 May 2024 12:45:12 +0200 Subject: [PATCH 18/20] Bump org.lukhnos.nnio from 0.3 to 0.3.1 Signed-off-by: Benedek Major --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index fb694bdbd9bb..90cfbdd9350d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -303,7 +303,7 @@ dependencies { implementation 'commons-io:commons-io:2.16.1' implementation 'org.greenrobot:eventbus:3.3.1' implementation 'com.googlecode.ez-vcard:ez-vcard:0.12.1' - implementation 'org.lukhnos:nnio:0.3' + implementation 'org.lukhnos:nnio:0.3.1' implementation 'org.bouncycastle:bcpkix-jdk18on:1.78.1' implementation 'com.google.code.gson:gson:2.10.1' implementation 'com.github.nextcloud-deps:sectioned-recyclerview:0.6.1' From 056e4ae0ef1da03e652da5b01ca081bd63789cb8 Mon Sep 17 00:00:00 2001 From: Benedek Major Date: Fri, 10 May 2024 13:19:01 +0200 Subject: [PATCH 19/20] Updated verification metadata for nnio 0.3.1 Signed-off-by: Benedek Major --- gradle/verification-metadata.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 69481bab3622..119b788e2984 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -136,6 +136,7 @@ + @@ -10228,6 +10229,14 @@ + + + + + + + + From a04edc5db83e8121c5633194cb6cd4bfb77196dc Mon Sep 17 00:00:00 2001 From: Benedek Major Date: Fri, 10 May 2024 13:54:24 +0200 Subject: [PATCH 20/20] Replace null value with new SKIP_SUBTREE enum option Signed-off-by: Benedek Major --- .../main/java/com/owncloud/android/utils/FilesSyncHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java b/app/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java index 46edde295352..9b7242e8f645 100644 --- a/app/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java +++ b/app/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java @@ -92,7 +92,7 @@ public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) { @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { if (syncedFolder.isExcludeHidden() && dir.compareTo(Paths.get(syncedFolder.getLocalPath())) != 0 && dir.toFile().isHidden()) { - return null; + return FileVisitResult.SKIP_SUBTREE; } return FileVisitResult.CONTINUE; }