diff --git a/app/build.gradle b/app/build.gradle index 4f268d64..b07f0e7b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -110,7 +110,7 @@ dependencies { implementation "com.eightbitlab:blurview:1.6.4" implementation "io.mikael:urlbuilder:2.0.9" implementation "org.codeberg.gitnex-garage:emoji-java:v5.1.2" - implementation "org.codeberg.gitnex:tea4j:1.0.0" + implementation "org.codeberg.gitnex:tea4j:1.0.1" coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.1" } diff --git a/app/src/main/java/org/mian/gitnex/adapters/FilesAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/FilesAdapter.java index 719377e7..0f9b0c11 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/FilesAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/FilesAdapter.java @@ -23,25 +23,26 @@ import java.util.List; public class FilesAdapter extends RecyclerView.Adapter implements Filterable { - private List filesList; - private Context mCtx; - private List filesListFull; + private final List originalFiles = new ArrayList<>(); + private final List alteredFiles = new ArrayList<>(); - private FilesAdapterListener filesListener; + private Context mCtx; + + private final FilesAdapterListener filesListener; public interface FilesAdapterListener { void onClickDir(String str); void onClickFile(String str); } - class FilesViewHolder extends RecyclerView.ViewHolder { + class FilesViewHolder extends RecyclerView.ViewHolder { - private ImageView fileTypeImage; - private ImageView dirTypeImage; - private ImageView unknownTypeImage; - private TextView fileName; - private TextView fileType; - private TextView fileInfo; + private final ImageView fileTypeImage; + private final ImageView dirTypeImage; + private final ImageView unknownTypeImage; + private final TextView fileName; + private final TextView fileType; + private final TextView fileInfo; private FilesViewHolder(View itemView) { @@ -138,11 +139,24 @@ public class FilesAdapter extends RecyclerView.Adapter filesListMain, FilesAdapterListener filesListener) { + public FilesAdapter(Context mCtx, FilesAdapterListener filesListener) { + this.mCtx = mCtx; - this.filesList = filesListMain; - filesListFull = new ArrayList<>(filesList); this.filesListener = filesListener; + + } + + public List getOriginalFiles() { + return originalFiles; + } + + public void notifyOriginalDataSetChanged() { + + alteredFiles.clear(); + alteredFiles.addAll(originalFiles); + + notifyDataSetChanged(); + } @NonNull @@ -155,7 +169,7 @@ public class FilesAdapter extends RecyclerView.Adapter filteredList = new ArrayList<>(); if (constraint == null || constraint.length() == 0) { - filteredList.addAll(filesListFull); + filteredList.addAll(originalFiles); } else { String filterPattern = constraint.toString().toLowerCase().trim(); - for (Files item : filesListFull) { + for (Files item : originalFiles) { if (item.getName().toLowerCase().contains(filterPattern) || item.getPath().toLowerCase().contains(filterPattern)) { filteredList.add(item); } @@ -216,10 +232,14 @@ public class FilesAdapter extends RecyclerView.Adapter(Collections.singletonList(BreadcrumbItem.createSimpleItem(getResources().getString(R.string.filesBreadcrumbRoot) + getResources().getString(R.string.colonDivider) + ref)))); + // noinspection unchecked + mBreadcrumbsView.setCallback(new DefaultBreadcrumbsCallback() { + + @SuppressLint("SetTextI18n") + @Override + public void onNavigateBack(BreadcrumbItem item, int position) { + + if(position == 0) { + + path.clear(); + fetchDataAsync(Authorization.get(getContext()), repoOwner, repoName, ref); + return; + + } + + path.pop(path.size() - position); + fetchDataAsyncSub(Authorization.get(getContext()), repoOwner, repoName, path.toString(), ref); + + } + + @Override public void onNavigateNewLocation(BreadcrumbItem newItem, int changedPosition) {} + + }); ((RepoDetailActivity) requireActivity()).setFragmentRefreshListenerFiles(repoBranch -> { - fileStructure.setText(""); + path.clear(); ref = repoBranch; mBreadcrumbsView.setItems(new ArrayList<>(Collections.singletonList(BreadcrumbItem.createSimpleItem(getResources().getString(R.string.filesBreadcrumbRoot) + getResources().getString(R.string.colonDivider) + ref)))); fetchDataAsync(Authorization.get(getContext()), repoOwner, repoName, repoBranch); @@ -128,48 +159,10 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter @Override public void onClickDir(String dirName) { - StringBuilder breadcrumbBuilder = new StringBuilder(); - - breadcrumbBuilder.append(fileStructure.getText().toString()).append("/").append(dirName); - - fileStructure.setText(breadcrumbBuilder); - - String dirName_ = fileStructure.getText().toString(); - dirName_ = dirName_.startsWith("/") ? dirName_.substring(1) : dirName_; - final String finalDirName_ = dirName_; - + path.add(dirName); mBreadcrumbsView.addItem(new BreadcrumbItem(Collections.singletonList(dirName))); - //noinspection unchecked - mBreadcrumbsView.setCallback(new DefaultBreadcrumbsCallback() { - @SuppressLint("SetTextI18n") - @Override - public void onNavigateBack(BreadcrumbItem item, int position) { - - if(position == 0) { - - fetchDataAsync(Authorization.get(getContext()), repoOwner, repoName, ref); - fileStructure.setText(""); - return; - } - - String filterDir = fileStructure.getText().toString(); - String result = filterDir.substring(0, filterDir.indexOf(item.getSelectedItem())); - fileStructure.setText(result + item.getSelectedItem()); - - String currentIndex = (result + item.getSelectedItem()).substring(1); - - fetchDataAsyncSub(Authorization.get(getContext()), repoOwner, repoName, currentIndex, ref); - - } - - @Override - public void onNavigateNewLocation(BreadcrumbItem newItem, int changedPosition) { - - } - }); - - fetchDataAsyncSub(Authorization.get(getContext()), repoOwner, repoName, finalDirName_, ref); + fetchDataAsyncSub(Authorization.get(getContext()), repoOwner, repoName, path.toString(), ref); } @@ -178,9 +171,9 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter Intent intent = new Intent(getContext(), FileViewActivity.class); - if(!fileStructure.getText().toString().equals("Root")) { + if(path.size() != 0) { - intent.putExtra("singleFileName", fileStructure.getText().toString() + "/" + fileName); + intent.putExtra("singleFileName", path.toString() + "/" + fileName); } else { @@ -199,24 +192,23 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter filesModel.getFilesList(instanceToken, owner, repo, ref, getContext(), mProgressBar, noDataFiles).observe(getViewLifecycleOwner(), filesListMain -> { - adapter = new FilesAdapter(getContext(), filesListMain, FilesFragment.this); - mBreadcrumbsView.removeItemAfter(1); + filesAdapter.getOriginalFiles().clear(); + filesAdapter.getOriginalFiles().addAll(filesListMain); + filesAdapter.notifyOriginalDataSetChanged(); - if(adapter.getItemCount() > 0) { + if(filesListMain.size() > 0) { - mRecyclerView.setAdapter(adapter); AppUtil.setMultiVisibility(View.VISIBLE, mRecyclerView, filesFrame); noDataFiles.setVisibility(View.GONE); + } else { - - adapter.notifyDataSetChanged(); - mRecyclerView.setAdapter(adapter); AppUtil.setMultiVisibility(View.VISIBLE, mRecyclerView, filesFrame, noDataFiles); } filesFrame.setVisibility(View.VISIBLE); mProgressBar.setVisibility(View.GONE); + }); } @@ -230,16 +222,16 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter filesModel2.getFilesList2(instanceToken, owner, repo, filesDir, ref, getContext(), mProgressBar, noDataFiles).observe(this, filesListMain2 -> { - adapter = new FilesAdapter(getContext(), filesListMain2, FilesFragment.this); + filesAdapter.getOriginalFiles().clear(); + filesAdapter.getOriginalFiles().addAll(filesListMain2); + filesAdapter.notifyOriginalDataSetChanged(); + + if(filesListMain2.size() > 0) { - if(adapter.getItemCount() > 0) { - mRecyclerView.setAdapter(adapter); AppUtil.setMultiVisibility(View.VISIBLE, mRecyclerView, filesFrame); noDataFiles.setVisibility(View.GONE); } else { - adapter.notifyDataSetChanged(); - mRecyclerView.setAdapter(adapter); AppUtil.setMultiVisibility(View.VISIBLE, mRecyclerView, filesFrame, noDataFiles); } @@ -268,7 +260,7 @@ public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapter public boolean onQueryTextChange(String newText) { if(mRecyclerView.getAdapter() != null) { - adapter.getFilter().filter(newText); + filesAdapter.getFilter().filter(newText); } return false; diff --git a/app/src/main/java/org/mian/gitnex/helpers/Path.java b/app/src/main/java/org/mian/gitnex/helpers/Path.java new file mode 100644 index 00000000..06567592 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/helpers/Path.java @@ -0,0 +1,137 @@ +package org.mian.gitnex.helpers; + +import androidx.annotation.NonNull; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.StringJoiner; + +/** + * @author opyale + */ + +public class Path { + + private final List segments; + private final List onChangedListeners; + + public Path(String... segments) { + + this.segments = new ArrayList<>(Arrays.asList(segments)); + this.onChangedListeners = new ArrayList<>(); + + } + + public interface OnChangedListener { void onChanged(); } + + public Path addListener(OnChangedListener onChangedListener) { + + onChangedListeners.add(onChangedListener); + return this; + + } + + public Path removeListener(OnChangedListener onChangedListener) { + + onChangedListeners.remove(onChangedListener); + return this; + + } + + private void pathChanged() { + + for(OnChangedListener onChangedListener : onChangedListeners) { + onChangedListener.onChanged(); + } + } + + public Path add(String segment) { + + if(segment != null && !segment.trim().isEmpty()) { + + try { + segments.add(URLEncoder.encode(segment, "UTF-8")); + } catch(UnsupportedEncodingException ignored) {} + } + + pathChanged(); + return this; + + } + + public int size() { + + return segments.size(); + } + + public Path join(Path path) { + + this.segments.addAll(path.segments); + + pathChanged(); + return this; + + } + + public Path pop(int count) { + + for(int i=0; i !s.trim().isEmpty()) + .toArray(String[]::new) + ); + + } + + @NonNull + @Override + public String toString() { + + StringJoiner stringJoiner = new StringJoiner("/"); + + for(String segment : segments) + stringJoiner.add(segment); + + return stringJoiner.toString(); + + } + +} diff --git a/app/src/main/res/layout/fragment_files.xml b/app/src/main/res/layout/fragment_files.xml index 7e8a65aa..d7b891d0 100644 --- a/app/src/main/res/layout/fragment_files.xml +++ b/app/src/main/res/layout/fragment_files.xml @@ -9,25 +9,20 @@ - - + android:orientation="vertical" + android:visibility="gone" + tools:visibility="visible"> + app:UnSelectedTextColor="@color/lightGray" />