Skip to content

Commit

Permalink
Logic to save and restore file browser position
Browse files Browse the repository at this point in the history
  • Loading branch information
harshad1 committed Jun 7, 2024
1 parent f0506b4 commit ec4de19
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -262,14 +262,14 @@ public void onTextChanged(CharSequence s, int start, int before, int count) {

// Get template string
// -------------------------------------------------------------------------------------
final int ti = templateSpinner.getSelectedItemPosition() - 1;
final int ti = templateSpinner.getSelectedItemPosition();
final String template;
if (ti < 0) {
if (ti == 0) {
template = "";
} else if (ti <= snippets.size()) {
template = GsFileUtils.readTextFileFast(snippets.get(ti).second).first;
template = GsFileUtils.readTextFileFast(snippets.get(ti - 1).second).first;
} else {
template = templates.get(ti - snippets.size()).second;
template = templates.get(ti - snippets.size() - 1).second;
}

final Pair<String, Integer> content = getTemplateContent(template, title);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Parcelable;
import android.text.Spannable;
import android.text.Spanned;
import android.text.TextUtils;
Expand Down Expand Up @@ -84,9 +85,11 @@ public class GsFileBrowserListAdapter extends RecyclerView.Adapter<GsFileBrowser
private final Context _context;
private StringFilter _filter;
private RecyclerView _recyclerView;
private LinearLayoutManager _layoutManager;
private final SharedPreferences _prefApp;
private final HashMap<File, File> _virtualMapping = new HashMap<>();
private final Map<File, Integer> _fileIdMap = new HashMap<>();
private final Map<File, Parcelable> _folderScrollMap = new HashMap<>();

//########################
//## Methods
Expand Down Expand Up @@ -211,6 +214,7 @@ public void onBindViewHolder(@NonNull FilesystemViewerViewHolder holder, int pos
public void onAttachedToRecyclerView(@NonNull final RecyclerView view) {
super.onAttachedToRecyclerView(view);
_recyclerView = view;
_layoutManager = (LinearLayoutManager) view.getLayoutManager();
}

public String formatFileDescription(final File file, String format) {
Expand All @@ -229,7 +233,7 @@ public void saveInstanceState(final @NonNull Bundle outState) {

if (_recyclerView != null) {
if (_recyclerView.getLayoutManager() != null) {
outState.putParcelable(EXTRA_RECYCLER_SCROLL_STATE, _recyclerView.getLayoutManager().onSaveInstanceState());
outState.putParcelable(EXTRA_RECYCLER_SCROLL_STATE, _layoutManager.onSaveInstanceState());
}
}
}
Expand All @@ -254,8 +258,8 @@ public void restoreSavedInstanceState(final Bundle savedInstanceState) {
}
}

if (savedInstanceState.containsKey(EXTRA_RECYCLER_SCROLL_STATE) && _recyclerView.getLayoutManager() != null) {
_recyclerView.postDelayed(() -> _recyclerView.getLayoutManager().onRestoreInstanceState(savedInstanceState.getParcelable(EXTRA_RECYCLER_SCROLL_STATE)), 200);
if (savedInstanceState.containsKey(EXTRA_RECYCLER_SCROLL_STATE) && _layoutManager != null) {
_recyclerView.postDelayed(() -> _layoutManager.onRestoreInstanceState(savedInstanceState.getParcelable(EXTRA_RECYCLER_SCROLL_STATE)), 200);
}
}

Expand Down Expand Up @@ -336,23 +340,14 @@ private int getPathLevel(String path) {
return level;
}

private void saveItemState(final TagContainer data) {
if (data != null) {
final int currentItemLevel = getPathLevel(data.file.getAbsolutePath());
final int currentFolderLevel = getPathLevel(_currentFolder.getAbsolutePath());

if (currentItemLevel > currentFolderLevel) {
final RecyclerView.LayoutManager layoutManager = _recyclerView.getLayoutManager();
}
}
}

@Override
@SuppressWarnings("UnnecessaryReturnStatement")
public void onClick(View view) {
final TagContainer data = (TagContainer) view.getTag();
if (_currentSelection.size() == 0) {
saveItemState(data);

if (!_currentSelection.isEmpty()) {
// Blink in multi-select
GsContextUtils.blinkView(view);
}

switch (view.getId()) {
Expand Down Expand Up @@ -497,13 +492,14 @@ public boolean canGoUp() {
return canGoUp(_currentFolder);
}

public boolean canGoUp(File currentFolder) {
File parentFolder = _currentFolder != null ? _currentFolder.getParentFile() : null;
return parentFolder != null && (!_dopt.mustStartWithRootFolder || parentFolder.getAbsolutePath().startsWith(_dopt.rootFolder.getAbsolutePath()));
public boolean canGoUp(final File folder) {
final File parent = folder != null ? folder.getParentFile() : null;
return parent != null && (!_dopt.mustStartWithRootFolder || parent.getAbsolutePath().startsWith(_dopt.rootFolder.getAbsolutePath()));
}

@Override
public boolean onLongClick(final View view) {
GsContextUtils.blinkView(view);
if (view.getId() == R.id.opoc_filesystem_item__root) {
final TagContainer data = (TagContainer) view.getTag();
toggleSelection(data);
Expand Down Expand Up @@ -548,7 +544,7 @@ public void doAfterChange(final GsCallback.a0 callback) {
public void onChanged() {
super.onChanged();
// Ignore if the load takes too long
if ((System.currentTimeMillis() - init) < 2000) {
if ((System.currentTimeMillis() - init) < 5000) {
_recyclerView.post(callback::callback);
}
unregisterAdapterDataObserver(this);
Expand All @@ -569,7 +565,7 @@ public void showFile(final File file) {

if (getFilePosition(file) < 0) {
doAfterChange(() -> showAndFlash(file));
loadFolder(dir); // Will reload folder if necessary
loadFolder(dir, false); // Will reload folder if necessary
} else {
showAndFlash(file);
}
Expand All @@ -582,23 +578,26 @@ public void showFile(final File file) {
*/
private void showAndFlash(final File file) {
final int pos = getFilePosition(file);
final LinearLayoutManager manager = (LinearLayoutManager) _recyclerView.getLayoutManager();

if (pos >= 0 && manager != null) {
if (pos >= 0 && _layoutManager != null) {

// Scroll to position if needed
final int firstVisible = manager.findFirstCompletelyVisibleItemPosition();
final int lastVisible = manager.findLastCompletelyVisibleItemPosition();
final int firstVisible = _layoutManager.findFirstCompletelyVisibleItemPosition();
final int lastVisible = _layoutManager.findLastCompletelyVisibleItemPosition();
final int delay;
if (pos < firstVisible || pos > lastVisible) {
manager.scrollToPositionWithOffset(pos, 1);
_layoutManager.scrollToPositionWithOffset(pos, 1);
delay = 500;
} else {
delay = 100;
}

_recyclerView.postDelayed(() -> {
final RecyclerView.ViewHolder holder = _recyclerView.findViewHolderForLayoutPosition(pos);
if (holder != null) {
GsContextUtils.rippleView(holder.itemView);
GsContextUtils.blinkView(holder.itemView);
}
}, 100);
}, delay);
}
}

Expand All @@ -617,25 +616,23 @@ public int getFilePosition(final File file) {

private static final ExecutorService executorService = new ThreadPoolExecutor(0, 3, 60, TimeUnit.SECONDS, new SynchronousQueue<>());

// Stop blinking if we are currently blinking
private void stopBlinking() {
if (_recyclerView != null) {
for (int i = 0; i < _recyclerView.getChildCount(); i++) {
GsContextUtils.stopRipple(_recyclerView.getChildAt(i));
}
}
private void loadFolder(final File folder) {
loadFolder(folder, true);
}

private void loadFolder(final File folder) {
private void loadFolder(final File folder, final boolean showChild) {
final boolean folderChanged = !folder.equals(_currentFolder);
if (folderChanged && _currentFolder != null && _layoutManager != null) {
_folderScrollMap.put(_currentFolder, _layoutManager.onSaveInstanceState());
}

executorService.execute(() -> {
synchronized (LOAD_FOLDER_SYNC_OBJECT) {
synchronized (_adapterData) {

if (_dopt.refresh != null) {
_dopt.refresh.callback();
}

final File prevFolder = _currentFolder;
_currentFolder = folder;
_virtualMapping.clear();
final List<File> newData = new ArrayList<>();

Expand Down Expand Up @@ -669,13 +666,13 @@ private void loadFolder(final File folder) {
_virtualMapping.put(VIRTUAL_STORAGE_APP_DATA_PRIVATE, appDataFolder);
newData.add(VIRTUAL_STORAGE_APP_DATA_PRIVATE);
}
} else if (_currentFolder.isDirectory()) {
GsCollectionUtils.addAll(newData, _currentFolder.listFiles(GsFileBrowserListAdapter.this));
} else if (_currentFolder.equals(VIRTUAL_STORAGE_RECENTS)) {
} else if (folder.isDirectory()) {
GsCollectionUtils.addAll(newData, folder.listFiles(GsFileBrowserListAdapter.this));
} else if (folder.equals(VIRTUAL_STORAGE_RECENTS)) {
newData.addAll(_dopt.recentFiles);
} else if (_currentFolder.equals(VIRTUAL_STORAGE_POPULAR)) {
} else if (folder.equals(VIRTUAL_STORAGE_POPULAR)) {
newData.addAll(_dopt.popularFiles);
} else if (_currentFolder.equals(VIRTUAL_STORAGE_FAVOURITE)) {
} else if (folder.equals(VIRTUAL_STORAGE_FAVOURITE)) {
newData.addAll(_dopt.favouriteFiles);
} else if (folder.getAbsolutePath().equals("/storage/emulated")) {
newData.add(new File(folder, "0"));
Expand Down Expand Up @@ -705,34 +702,45 @@ private void loadFolder(final File folder) {
}

// Don't sort recent items - use the default order
if (!_currentFolder.equals(VIRTUAL_STORAGE_RECENTS)) {
if (!folder.equals(VIRTUAL_STORAGE_RECENTS)) {
GsFileUtils.sortFiles(newData, _dopt.sortByType, _dopt.sortFolderFirst, _dopt.sortReverse);
}

if (canGoUp(_currentFolder)) {
newData.add(0, _currentFolder.equals(new File("/storage/emulated/0")) ? new File("/storage/emulated") : _currentFolder.getParentFile());
if (canGoUp(folder)) {
newData.add(0, folder.equals(new File("/storage/emulated/0")) ? new File("/storage/emulated") : folder.getParentFile());
}

if (!newData.equals(_adapterData)) {
if (folderChanged || !newData.equals(_adapterData)) {
_adapterData.clear();
_adapterData.addAll(newData);
_currentSelection.retainAll(_adapterData);
_filter.filter(_filter._lastFilter);

if (!_currentFolder.equals(prevFolder)) {
if (folderChanged) {
_fileIdMap.clear();
}

// Set the current folder before notifying the UI
final File folderToShow = _currentFolder;
_currentFolder = folder;

// Must be called from UI thread
_recyclerView.post(() -> {
// Must be called from UI thread
// TODO - add logic to notify the changed bits
notifyDataSetChanged();
stopBlinking();

if (prevFolder != null && _currentFolder.equals(prevFolder.getParentFile())) {
doAfterChange(() -> showAndFlash(prevFolder));
if (folderChanged && showChild) {
doAfterChange(() -> {
final Parcelable scrollState = _folderScrollMap.remove(folder);
if (scrollState != null && _layoutManager != null) {
_layoutManager.onRestoreInstanceState(scrollState);
}
// We still show and flash as the folder contents may have changed
_recyclerView.postDelayed(() -> showAndFlash(folderToShow), 250);
});
}

// TODO - add logic to notify the changed bits
notifyDataSetChanged();

if (_dopt.listener != null) {
_dopt.listener.onFsViewerDoUiUpdate(GsFileBrowserListAdapter.this);
}
Expand Down Expand Up @@ -780,9 +788,6 @@ public static boolean isVirtualStorage(File file) {
VIRTUAL_STORAGE_RECENTS.equals(file);
}

private final static Object LOAD_FOLDER_SYNC_OBJECT = new Object();


//########################
//##
//## StringFilter
Expand Down
30 changes: 5 additions & 25 deletions app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import android.Manifest;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.app.Activity;
Expand Down Expand Up @@ -49,6 +50,7 @@
import android.graphics.Rect;
import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.RippleDrawable;
import android.graphics.drawable.VectorDrawable;
Expand Down Expand Up @@ -2883,14 +2885,13 @@ public boolean isDarkModeEnabled(final Context context) {
}

public static void blinkView(final View view) {

if (view == null) {
return;
}

final ObjectAnimator animator = ObjectAnimator.ofFloat(
view, View.ALPHA, 0.1f, 1.0f, 0.1f, 1.0f)
.setDuration(500);
final ObjectAnimator animator = ObjectAnimator
.ofFloat(view, View.ALPHA, 0.2f, 1.0f)
.setDuration(500L);

view.setTag(BLINK_ANIMATOR_TAG, new WeakReference<>(animator));

Expand Down Expand Up @@ -2920,27 +2921,6 @@ public static void stopBlinking(final View view) {
}
}
}

}

public static void rippleView(final View view) {
if (view != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
final Drawable drawable = view.getForeground();
if (drawable instanceof RippleDrawable) {
drawable.setState(new int[]{android.R.attr.state_pressed, android.R.attr.state_enabled});
view.postDelayed(() -> drawable.setState(new int[]{}), 250);
}
}
}

public static void stopRipple(final View view) {
if (view != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Drawable drawable = view.getForeground();
if (drawable instanceof RippleDrawable) {
drawable.setState(new int[]{});
drawable.jumpToCurrentState();
}
}
}

public static boolean fadeInOut(final View in, final View out, final boolean animate) {
Expand Down
1 change: 0 additions & 1 deletion app/src/main/res/layout/opoc_filesystem_item.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
android:orientation="horizontal"
android:paddingBottom="8dp">

Expand Down

0 comments on commit ec4de19

Please sign in to comment.