diff --git a/README.md b/README.md index 3da4e9a6..87e59de2 100644 --- a/README.md +++ b/README.md @@ -83,5 +83,6 @@ Open source libraries - Abumoallim/android-multi-select-dialog - Pes/materialcolorpicker - Hendraanggrian/socialview +- Fython/BreadcrumbsView [Follow me on Fediverse - mastodon.social/@mmarif](https://mastodon.social/@mmarif) diff --git a/app/build.gradle b/app/build.gradle index 8d3b7bbe..c383c54e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -68,4 +68,6 @@ dependencies { implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version" + + implementation "com.github.HamidrezaAmz:BreadcrumbsView:0.2.9" } diff --git a/app/src/main/java/org/mian/gitnex/activities/FileViewActivity.java b/app/src/main/java/org/mian/gitnex/activities/FileViewActivity.java index 5c4065d1..5a288813 100644 --- a/app/src/main/java/org/mian/gitnex/activities/FileViewActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/FileViewActivity.java @@ -2,6 +2,7 @@ package org.mian.gitnex.activities; import android.content.Context; import android.os.Bundle; +import android.text.method.ScrollingMovementMethod; import android.util.Log; import android.view.View; import android.widget.ImageView; @@ -58,6 +59,7 @@ public class FileViewActivity extends AppCompatActivity { String singleFileName = getIntent().getStringExtra("singleFileName"); TextView toolbar_title = findViewById(R.id.toolbar_title); + toolbar_title.setMovementMethod(new ScrollingMovementMethod()); toolbar_title.setText(singleFileName); initCloseListener(); 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 23560292..d8c731f4 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/FilesAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/FilesAdapter.java @@ -1,7 +1,6 @@ package org.mian.gitnex.adapters; import android.content.Context; -import android.content.Intent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -12,10 +11,8 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import org.mian.gitnex.R; -import org.mian.gitnex.activities.FileViewActivity; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.models.Files; -import org.mian.gitnex.util.TinyDB; import java.util.ArrayList; import java.util.List; @@ -29,6 +26,13 @@ public class FilesAdapter extends RecyclerView.Adapter filesListFull; + private FilesAdapterListener filesListener; + + public interface FilesAdapterListener { + void onClickDir(String str); + void onClickFile(String str); + } + class FilesViewHolder extends RecyclerView.ViewHolder { private ImageView fileTypeImage; @@ -49,16 +53,12 @@ public class FilesAdapter extends RecyclerView.Adapter filesListMain) { + public FilesAdapter(Context mCtx, List filesListMain, FilesAdapterListener filesListener) { this.mCtx = mCtx; this.filesList = filesListMain; filesListFull = new ArrayList<>(filesList); + this.filesListener = filesListener; } @NonNull diff --git a/app/src/main/java/org/mian/gitnex/fragments/FilesFragment.java b/app/src/main/java/org/mian/gitnex/fragments/FilesFragment.java index c2412745..171a082c 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/FilesFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/FilesFragment.java @@ -1,5 +1,6 @@ package org.mian.gitnex.fragments; +import android.content.Intent; import android.net.Uri; import android.os.Bundle; import androidx.annotation.NonNull; @@ -10,8 +11,6 @@ import androidx.lifecycle.ViewModelProvider; import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; -import android.os.Handler; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -23,29 +22,36 @@ import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; import org.mian.gitnex.R; +import org.mian.gitnex.activities.FileViewActivity; import org.mian.gitnex.adapters.FilesAdapter; import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.models.Files; import org.mian.gitnex.util.AppUtil; import org.mian.gitnex.util.TinyDB; import org.mian.gitnex.viewmodels.FilesViewModel; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Objects; +import moe.feng.common.view.breadcrumbs.BreadcrumbsView; +import moe.feng.common.view.breadcrumbs.DefaultBreadcrumbsCallback; +import moe.feng.common.view.breadcrumbs.model.BreadcrumbItem; /** * Author M M Arif */ -public class FilesFragment extends Fragment { +public class FilesFragment extends Fragment implements FilesAdapter.FilesAdapterListener { private ProgressBar mProgressBar; private FilesAdapter adapter; private RecyclerView mRecyclerView; private TextView noDataFiles; private LinearLayout filesFrame; + private TextView fileStructure; private static String repoNameF = "param2"; private static String repoOwnerF = "param1"; - private boolean initialLoad = true; + private BreadcrumbsView mBreadcrumbsView; private String repoName; private String repoOwner; @@ -88,53 +94,118 @@ public class FilesFragment extends Fragment { noDataFiles = v.findViewById(R.id.noDataFiles); filesFrame = v.findViewById(R.id.filesFrame); - final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh); - + fileStructure = v.findViewById(R.id.fileStructure); mRecyclerView = v.findViewById(R.id.recyclerView); mRecyclerView.setHasFixedSize(true); mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); - String filesDirDB = tinyDb.getString("filesDir"); - DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL); mRecyclerView.addItemDecoration(dividerItemDecoration); mProgressBar = v.findViewById(R.id.progress_bar); - swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { - @Override - public void onRefresh() { - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - swipeRefresh.setRefreshing(false); - FilesViewModel.loadFilesList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName); - } - }, 200); - } - }); - + mBreadcrumbsView = v.findViewById(R.id.breadcrumbs_view); + mBreadcrumbsView.setItems(new ArrayList<>(Arrays.asList( + BreadcrumbItem.createSimpleItem(getResources().getString(R.string.filesBreadcrumbRoot)) + ))); fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName); return v; } + @Override + public void onResume() { + super.onResume(); + } + + private static BreadcrumbItem createItem(String title) { + List list = new ArrayList<>(); + list.add(title); + return new BreadcrumbItem(list); + } + + @Override + public void onClickDir(String dirName) { + + TinyDB tinyDb = new TinyDB(getContext()); + final String instanceUrl = tinyDb.getString("instanceUrl"); + final String loginUid = tinyDb.getString("loginUid"); + final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + + StringBuilder breadcrumbBuilder = new StringBuilder(); + + breadcrumbBuilder.append(fileStructure.getText().toString()).append("/").append(dirName); + + fileStructure.setText(breadcrumbBuilder); + + mBreadcrumbsView.addItem(createItem(dirName)); + mBreadcrumbsView.setCallback(new DefaultBreadcrumbsCallback() { + @Override + public void onNavigateBack(BreadcrumbItem item, int position) { + + if(position == 0) { + fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName); + fileStructure.setText(""); + return; + } + + String filterDir = fileStructure.getText().toString(); + String result = filterDir.substring(0, filterDir.indexOf(item.getSelectedItem())); + fileStructure.setText(result + item.getSelectedItem()); + fetchDataAsyncSub(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, fileStructure.getText().toString()); + + } + + @Override + public void onNavigateNewLocation(BreadcrumbItem newItem, int changedPosition) { + + } + }); + + fetchDataAsyncSub(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, fileStructure.getText().toString()); + + } + + @Override + public void onClickFile(String fileName) { + + Intent intent = new Intent(getContext(), FileViewActivity.class); + + if(!fileStructure.getText().toString().equals("Root")) { + + intent.putExtra("singleFileName", fileStructure.getText().toString()+"/"+fileName); + } + else { + + intent.putExtra("singleFileName", fileName); + } + + Objects.requireNonNull(getContext()).startActivity(intent); + } + private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) { + mRecyclerView.setVisibility(View.GONE); + mProgressBar.setVisibility(View.VISIBLE); + FilesViewModel filesModel = new ViewModelProvider(this).get(FilesViewModel.class); filesModel.getFilesList(instanceUrl, instanceToken, owner, repo).observe(this, new Observer>() { @Override public void onChanged(@Nullable List filesListMain) { - adapter = new FilesAdapter(getContext(), filesListMain); + adapter = new FilesAdapter(getContext(), filesListMain, FilesFragment.this); + + mBreadcrumbsView.removeItemAfter(1); if(adapter.getItemCount() > 0) { + mRecyclerView.setVisibility(View.VISIBLE); mRecyclerView.setAdapter(adapter); filesFrame.setVisibility(View.VISIBLE); noDataFiles.setVisibility(View.GONE); } else { + mRecyclerView.setVisibility(View.VISIBLE); adapter.notifyDataSetChanged(); mRecyclerView.setAdapter(adapter); filesFrame.setVisibility(View.VISIBLE); @@ -149,18 +220,23 @@ public class FilesFragment extends Fragment { private void fetchDataAsyncSub(String instanceUrl, String instanceToken, String owner, String repo, String filesDir) { + mRecyclerView.setVisibility(View.GONE); + mProgressBar.setVisibility(View.VISIBLE); + FilesViewModel filesModel2 = new ViewModelProvider(this).get(FilesViewModel.class); filesModel2.getFilesList2(instanceUrl, instanceToken, owner, repo, filesDir).observe(this, new Observer>() { @Override public void onChanged(@Nullable List filesListMain2) { - adapter = new FilesAdapter(getContext(), filesListMain2); + adapter = new FilesAdapter(getContext(), filesListMain2, FilesFragment.this); if(adapter.getItemCount() > 0) { + mRecyclerView.setVisibility(View.VISIBLE); mRecyclerView.setAdapter(adapter); filesFrame.setVisibility(View.VISIBLE); noDataFiles.setVisibility(View.GONE); } else { + mRecyclerView.setVisibility(View.VISIBLE); adapter.notifyDataSetChanged(); mRecyclerView.setAdapter(adapter); filesFrame.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/FilesViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/FilesViewModel.java index c55aba8e..9e073b7c 100644 --- a/app/src/main/java/org/mian/gitnex/viewmodels/FilesViewModel.java +++ b/app/src/main/java/org/mian/gitnex/viewmodels/FilesViewModel.java @@ -86,12 +86,15 @@ public class FilesViewModel extends ViewModel { @Override public void onResponse(@NonNull Call> call, @NonNull Response> response) { - Collections.sort(response.body(), new Comparator() { - @Override - public int compare(Files byType1, Files byType2) { - return byType1.getType().compareTo(byType2.getType()); - } - }); + assert response.body() != null; + if(response.body().size() > 0) { + Collections.sort(response.body(), new Comparator() { + @Override + public int compare(Files byType1, Files byType2) { + return byType1.getType().compareTo(byType2.getType()); + } + }); + } if (response.isSuccessful()) { filesList.postValue(response.body()); diff --git a/app/src/main/res/layout/activity_file_view.xml b/app/src/main/res/layout/activity_file_view.xml index a22d64c8..4875b678 100644 --- a/app/src/main/res/layout/activity_file_view.xml +++ b/app/src/main/res/layout/activity_file_view.xml @@ -35,8 +35,11 @@ android:layout_gravity="center_vertical" android:text="@string/defaultFilename" android:textColor="@color/white" - android:maxLines="1" - android:textSize="20sp" /> + android:ellipsize="none" + android:scrollbars="horizontal" + android:singleLine="true" + android:layout_marginEnd="20dp" + android:textSize="18sp" /> @@ -58,7 +61,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="@color/colorWhite" - android:textSize="16sp" + android:textSize="14sp" android:padding="15dp" /> diff --git a/app/src/main/res/layout/files_list.xml b/app/src/main/res/layout/files_list.xml index 09ac6c76..f9390c74 100644 --- a/app/src/main/res/layout/files_list.xml +++ b/app/src/main/res/layout/files_list.xml @@ -25,7 +25,7 @@ android:layout_height="28dp" android:layout_marginEnd="15dp" android:contentDescription="@string/repoContentAvatar" - android:src="@drawable/ic_android" /> + android:src="@drawable/ic_file" /> - @@ -16,32 +16,27 @@ > + + + app:CustomTextSize="16sp" + app:SelectedTextColor="@color/colorAccent" + app:UnSelectedTextColor="@color/lightGray" + android:text="@string/filesBreadcrumbRoot"/> - - - - - + android:layout_height="match_parent" + android:background="@color/colorPrimary" + android:padding="4dp" + android:scrollbars="vertical" /> Unwatch Repository Repository added to watch list Repository removed from watch list + Root