diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 43d5f0f8..320443e0 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -178,6 +178,14 @@
android:name=".activities.MostVisitedReposActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|keyboard|keyboardHidden|navigation"
android:windowSoftInputMode="adjustResize"/>
+
+
tab.setText(tabTitles[position]))
+ .attach();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(@NonNull MenuItem item) {
+ if (item.getItemId() == android.R.id.home) {
+ finish();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ private static class ExplorePagerAdapter extends FragmentStateAdapter {
+
+ public ExplorePagerAdapter(@NonNull FragmentActivity fa) {
+ super(fa);
+ }
+
+ @NonNull @Override
+ public Fragment createFragment(int position) {
+ return switch (position) {
+ case 0 -> new ExploreRepositoriesFragment();
+ case 1 -> new ExploreIssuesFragment();
+ case 2 -> new ExplorePublicOrganizationsFragment();
+ case 3 -> new ExploreUsersFragment();
+ default -> throw new IllegalStateException("Unexpected position: " + position);
+ };
+ }
+
+ @Override
+ public int getItemCount() {
+ return 4;
+ }
+ }
+}
diff --git a/app/src/main/java/org/mian/gitnex/activities/MainActivity.java b/app/src/main/java/org/mian/gitnex/activities/MainActivity.java
index f16205d4..7937174c 100644
--- a/app/src/main/java/org/mian/gitnex/activities/MainActivity.java
+++ b/app/src/main/java/org/mian/gitnex/activities/MainActivity.java
@@ -160,7 +160,10 @@ public class MainActivity extends BaseActivity
R.id.notificationsFragment, null, navOptions);
return true;
} else if (itemId == R.id.exploreFragment) {
- navController.navigate(R.id.exploreFragment, null, navOptions);
+ Intent intent = new Intent(ctx, ExploreActivity.class);
+ startActivity(intent);
+ this.overridePendingTransition(
+ android.R.anim.fade_in, android.R.anim.fade_out);
return true;
}
} catch (IllegalArgumentException ignored) {
@@ -506,7 +509,9 @@ public class MainActivity extends BaseActivity
navController.navigate(R.id.notificationsFragment, null, navOptions);
break;
case "explore":
- navController.navigate(R.id.exploreFragment, null, navOptions);
+ Intent intent = new Intent(ctx, ExploreActivity.class);
+ startActivity(intent);
+ this.overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
break;
case "profile":
Intent intentProfile = new Intent(this, ProfileActivity.class);
@@ -573,8 +578,9 @@ public class MainActivity extends BaseActivity
navController.navigate(R.id.repositoriesFragment, null, navOptions);
break;
case 5:
- binding.toolbarTitle.setText(getResources().getString(R.string.pageTitleExplore));
- navController.navigate(R.id.exploreFragment, null, navOptions);
+ Intent intent = new Intent(ctx, ExploreActivity.class);
+ startActivity(intent);
+ this.overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
break;
case 6:
navController.navigate(R.id.notificationsFragment, null, navOptions);
diff --git a/app/src/main/java/org/mian/gitnex/activities/MostVisitedReposActivity.java b/app/src/main/java/org/mian/gitnex/activities/MostVisitedReposActivity.java
index 18aa47e4..f067a0d5 100644
--- a/app/src/main/java/org/mian/gitnex/activities/MostVisitedReposActivity.java
+++ b/app/src/main/java/org/mian/gitnex/activities/MostVisitedReposActivity.java
@@ -95,10 +95,9 @@ public class MostVisitedReposActivity extends BaseActivity {
private void setupRefreshLayout() {
binding.pullToRefresh.setOnRefreshListener(
- () -> {
- new Handler(Looper.getMainLooper())
- .postDelayed(() -> fetchDataAsync(currentActiveAccountId), 250);
- });
+ () ->
+ new Handler(Looper.getMainLooper())
+ .postDelayed(() -> fetchDataAsync(currentActiveAccountId), 250));
}
private void fetchDataAsync(int accountId) {
diff --git a/app/src/main/java/org/mian/gitnex/activities/StarredReposActivity.java b/app/src/main/java/org/mian/gitnex/activities/StarredReposActivity.java
new file mode 100644
index 00000000..e78bee98
--- /dev/null
+++ b/app/src/main/java/org/mian/gitnex/activities/StarredReposActivity.java
@@ -0,0 +1,155 @@
+package org.mian.gitnex.activities;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.View;
+import androidx.lifecycle.ViewModelProvider;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import java.util.ArrayList;
+import java.util.List;
+import org.gitnex.tea4j.v2.models.Repository;
+import org.mian.gitnex.adapters.ReposListAdapter;
+import org.mian.gitnex.databinding.ActivityRepositoriesBinding;
+import org.mian.gitnex.helpers.Constants;
+import org.mian.gitnex.helpers.EndlessRecyclerViewScrollListener;
+import org.mian.gitnex.viewmodels.RepositoriesViewModel;
+
+/**
+ * @author mmarif
+ */
+public class StarredReposActivity extends BaseActivity {
+
+ private ActivityRepositoriesBinding binding;
+ private RepositoriesViewModel viewModel;
+ private ReposListAdapter adapter;
+ private EndlessRecyclerViewScrollListener scrollListener;
+ private int resultLimit;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ binding = ActivityRepositoriesBinding.inflate(getLayoutInflater());
+ setContentView(binding.getRoot());
+
+ resultLimit = Constants.getCurrentResultLimit(this);
+ viewModel = new ViewModelProvider(this).get(RepositoriesViewModel.class);
+
+ setupUI();
+ setupSearch();
+ observeViewModel();
+
+ refreshData();
+ }
+
+ private void setupUI() {
+ binding.btnBack.setOnClickListener(v -> finish());
+ binding.btnSearch.setOnClickListener(v -> binding.searchView.show());
+ binding.btnNewRepository.setOnClickListener(
+ v -> startActivity(new Intent(ctx, CreateRepoActivity.class)));
+
+ adapter = new ReposListAdapter(new ArrayList<>(), this);
+ LinearLayoutManager layoutManager = new LinearLayoutManager(this);
+ binding.recyclerView.setLayoutManager(layoutManager);
+ binding.recyclerView.setAdapter(adapter);
+
+ scrollListener =
+ new EndlessRecyclerViewScrollListener(layoutManager) {
+ @Override
+ public void onLoadMore(int page, int totalItemsCount, RecyclerView view) {
+ if (binding.searchView.isShowing()) return;
+
+ viewModel.fetchRepos(
+ ctx, "starredRepos", "", null, page, resultLimit, null, false);
+ }
+ };
+ binding.recyclerView.addOnScrollListener(scrollListener);
+
+ binding.pullToRefresh.setOnRefreshListener(
+ () -> {
+ binding.pullToRefresh.setRefreshing(false);
+ refreshData();
+ });
+ }
+
+ private void setupSearch() {
+ binding.searchResultsRecycler.setAdapter(adapter);
+
+ binding.searchView
+ .getEditText()
+ .addTextChangedListener(
+ new TextWatcher() {
+ @Override
+ public void onTextChanged(
+ CharSequence s, int start, int before, int count) {
+ adapter.getFilter().filter(s.toString().trim());
+ }
+
+ @Override
+ public void beforeTextChanged(
+ CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {}
+ });
+
+ binding.searchView.addTransitionListener(
+ (searchView, previousState, newState) -> {
+ if (newState
+ == com.google.android.material.search.SearchView.TransitionState
+ .HIDDEN) {
+ List originalList = viewModel.getRepos().getValue();
+ if (originalList != null) {
+ adapter.updateList(originalList);
+ }
+ binding.recyclerView.scrollToPosition(0);
+ }
+ });
+ }
+
+ private void observeViewModel() {
+ viewModel
+ .getRepos()
+ .observe(
+ this,
+ list -> {
+ adapter.updateList(list);
+ updateUiState();
+ });
+
+ viewModel
+ .getIsLoading()
+ .observe(
+ this,
+ loading -> {
+ boolean hasData = adapter.getItemCount() > 0;
+ binding.expressiveLoader.setVisibility(
+ loading && !hasData ? View.VISIBLE : View.GONE);
+ });
+
+ viewModel.getHasLoadedOnce().observe(this, hasLoaded -> updateUiState());
+ }
+
+ private void updateUiState() {
+ boolean isEmpty = adapter.getItemCount() == 0;
+ boolean loaded = Boolean.TRUE.equals(viewModel.getHasLoadedOnce().getValue());
+ binding.layoutEmpty.getRoot().setVisibility(loaded && isEmpty ? View.VISIBLE : View.GONE);
+ }
+
+ private void refreshData() {
+ if (scrollListener != null) scrollListener.resetState();
+ viewModel.resetPagination();
+ viewModel.fetchRepos(this, "starredRepos", "", null, 1, resultLimit, null, true);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ if (MainActivity.reloadRepos) {
+ refreshData();
+ MainActivity.reloadRepos = false;
+ }
+ }
+}
diff --git a/app/src/main/java/org/mian/gitnex/fragments/ExploreFragment.java b/app/src/main/java/org/mian/gitnex/fragments/ExploreFragment.java
deleted file mode 100644
index 997d3fa0..00000000
--- a/app/src/main/java/org/mian/gitnex/fragments/ExploreFragment.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package org.mian.gitnex.fragments;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.fragment.app.Fragment;
-import androidx.viewpager2.adapter.FragmentStateAdapter;
-import androidx.viewpager2.widget.ViewPager2;
-import com.google.android.material.tabs.TabLayout;
-import com.google.android.material.tabs.TabLayoutMediator;
-import org.mian.gitnex.R;
-import org.mian.gitnex.helpers.AppDatabaseSettings;
-import org.mian.gitnex.helpers.ViewPager2Transformers;
-
-/**
- * @author mmarif
- */
-public class ExploreFragment extends Fragment {
-
- @Nullable @Override
- public View onCreateView(
- @NonNull LayoutInflater inflater,
- @Nullable ViewGroup container,
- @Nullable Bundle savedInstanceState) {
-
- View view = inflater.inflate(R.layout.fragment_explore, container, false);
-
- Context ctx = getContext();
-
- ViewPager2 viewPager = view.findViewById(R.id.containerExplore);
- viewPager.setOffscreenPageLimit(1);
- TabLayout tabLayout = view.findViewById(R.id.tabsExplore);
-
- ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
-
- viewPager.setAdapter(new ViewPagerAdapter(this));
-
- ViewPager2Transformers.returnSelectedTransformer(
- viewPager,
- Integer.parseInt(
- AppDatabaseSettings.getSettingsValue(
- ctx, AppDatabaseSettings.APP_TABS_ANIMATION_KEY)));
-
- String[] tabTitles = {
- getResources().getString(R.string.navRepos),
- getResources().getString(R.string.pageTitleIssues),
- getResources().getString(R.string.navOrg),
- getResources().getString(R.string.pageTitleUsers)
- };
- new TabLayoutMediator(
- tabLayout, viewPager, (tab, position) -> tab.setText(tabTitles[position]))
- .attach();
-
- return view;
- }
-
- public static class ViewPagerAdapter extends FragmentStateAdapter {
-
- public ViewPagerAdapter(@NonNull ExploreFragment fa) {
- super(fa);
- }
-
- @NonNull @Override
- public Fragment createFragment(int position) {
- Fragment fragment =
- switch (position) {
- case 0 -> // Repositories
- new ExploreRepositoriesFragment();
- case 1 -> // Issues
- new ExploreIssuesFragment();
- case 2 -> // Organizations
- new ExplorePublicOrganizationsFragment();
- case 3 -> // Users
- new ExploreUsersFragment();
- default -> null;
- };
- assert fragment != null;
- return fragment;
- }
-
- @Override
- public int getItemCount() {
- return 4;
- }
- }
-}
diff --git a/app/src/main/java/org/mian/gitnex/fragments/HomeDashboardFragment.java b/app/src/main/java/org/mian/gitnex/fragments/HomeDashboardFragment.java
index f1a300a6..88dd71cb 100644
--- a/app/src/main/java/org/mian/gitnex/fragments/HomeDashboardFragment.java
+++ b/app/src/main/java/org/mian/gitnex/fragments/HomeDashboardFragment.java
@@ -22,6 +22,7 @@ import org.mian.gitnex.activities.MainActivity;
import org.mian.gitnex.activities.MostVisitedReposActivity;
import org.mian.gitnex.activities.NotesActivity;
import org.mian.gitnex.activities.ProfileActivity;
+import org.mian.gitnex.activities.StarredReposActivity;
import org.mian.gitnex.adapters.UserAccountsAdapter;
import org.mian.gitnex.database.api.BaseApi;
import org.mian.gitnex.database.api.UserAccountsApi;
@@ -155,7 +156,15 @@ public class HomeDashboardFragment extends Fragment {
});
binding.repoStarredCard
.getRoot()
- .setOnClickListener(v -> navigateTo(R.id.action_to_starredRepositories));
+ .setOnClickListener(
+ v -> {
+ Intent intent =
+ new Intent(requireContext(), StarredReposActivity.class);
+ startActivity(intent);
+ requireActivity()
+ .overridePendingTransition(
+ android.R.anim.fade_in, android.R.anim.fade_out);
+ });
binding.repoWatchedCard
.getRoot()
.setOnClickListener(v -> navigateTo(R.id.action_to_watchedRepositories));
diff --git a/app/src/main/java/org/mian/gitnex/fragments/StarredRepositoriesFragment.java b/app/src/main/java/org/mian/gitnex/fragments/StarredRepositoriesFragment.java
deleted file mode 100644
index a228a135..00000000
--- a/app/src/main/java/org/mian/gitnex/fragments/StarredRepositoriesFragment.java
+++ /dev/null
@@ -1,177 +0,0 @@
-package org.mian.gitnex.fragments;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.inputmethod.EditorInfo;
-import androidx.annotation.NonNull;
-import androidx.appcompat.widget.SearchView;
-import androidx.core.view.MenuProvider;
-import androidx.fragment.app.Fragment;
-import androidx.lifecycle.Lifecycle;
-import androidx.lifecycle.ViewModelProvider;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-import java.util.ArrayList;
-import org.mian.gitnex.R;
-import org.mian.gitnex.activities.CreateRepoActivity;
-import org.mian.gitnex.activities.MainActivity;
-import org.mian.gitnex.adapters.ReposListAdapter;
-import org.mian.gitnex.databinding.FragmentRepositoriesBinding;
-import org.mian.gitnex.helpers.Constants;
-import org.mian.gitnex.helpers.EndlessRecyclerViewScrollListener;
-import org.mian.gitnex.viewmodels.RepositoriesViewModel;
-
-/**
- * @author mmarif
- */
-public class StarredRepositoriesFragment extends Fragment {
-
- private FragmentRepositoriesBinding binding;
- private RepositoriesViewModel viewModel;
- private ReposListAdapter adapter;
- private EndlessRecyclerViewScrollListener scrollListener;
- private int resultLimit;
- private boolean isSearching = false;
-
- @Override
- public View onCreateView(
- @NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- binding = FragmentRepositoriesBinding.inflate(inflater, container, false);
- resultLimit = Constants.getCurrentResultLimit(requireContext());
- viewModel = new ViewModelProvider(this).get(RepositoriesViewModel.class);
-
- setupRecyclerView();
- setupSwipeRefresh();
- setupMenu();
- observeViewModel();
-
- refreshData();
- return binding.getRoot();
- }
-
- private void setupRecyclerView() {
- adapter = new ReposListAdapter(new ArrayList<>(), requireContext());
- LinearLayoutManager layoutManager = new LinearLayoutManager(requireContext());
- binding.recyclerView.setLayoutManager(layoutManager);
- binding.recyclerView.setAdapter(adapter);
-
- scrollListener =
- new EndlessRecyclerViewScrollListener(layoutManager) {
- @Override
- public void onLoadMore(int page, int totalItemsCount, RecyclerView view) {
- if (!isSearching) {
- viewModel.fetchRepos(
- requireContext(),
- "starredRepos",
- "",
- null,
- page,
- resultLimit,
- null,
- false);
- }
- }
- };
- binding.recyclerView.addOnScrollListener(scrollListener);
-
- binding.addNewRepo.setOnClickListener(
- v -> startActivity(new Intent(getContext(), CreateRepoActivity.class)));
- }
-
- private void setupMenu() {
- requireActivity()
- .addMenuProvider(
- new MenuProvider() {
- @Override
- public void onCreateMenu(
- @NonNull Menu menu, @NonNull MenuInflater menuInflater) {
- menuInflater.inflate(R.menu.search_menu, menu);
- MenuItem searchItem = menu.findItem(R.id.action_search);
- SearchView searchView = (SearchView) searchItem.getActionView();
- if (searchView != null) {
- searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
- searchView.setOnQueryTextListener(
- new SearchView.OnQueryTextListener() {
- @Override
- public boolean onQueryTextSubmit(String query) {
- return false;
- }
-
- @Override
- public boolean onQueryTextChange(String newText) {
- isSearching = !newText.isEmpty();
- adapter.getFilter().filter(newText);
- return true;
- }
- });
- }
- }
-
- @Override
- public boolean onMenuItemSelected(@NonNull MenuItem menuItem) {
- return false;
- }
- },
- getViewLifecycleOwner(),
- Lifecycle.State.RESUMED);
- }
-
- private void observeViewModel() {
- viewModel
- .getRepos()
- .observe(
- getViewLifecycleOwner(),
- list -> {
- adapter.updateList(list);
- updateUiState();
- });
-
- viewModel
- .getIsLoading()
- .observe(
- getViewLifecycleOwner(),
- loading -> {
- boolean hasData = adapter.getItemCount() > 0;
- binding.expressiveLoader.setVisibility(
- loading && !hasData ? View.VISIBLE : View.GONE);
- });
-
- viewModel.getHasLoadedOnce().observe(getViewLifecycleOwner(), hasLoaded -> updateUiState());
- }
-
- private void updateUiState() {
- boolean isEmpty = adapter.getItemCount() == 0;
- boolean loaded = Boolean.TRUE.equals(viewModel.getHasLoadedOnce().getValue());
- binding.layoutEmpty.getRoot().setVisibility(loaded && isEmpty ? View.VISIBLE : View.GONE);
- }
-
- private void refreshData() {
- if (scrollListener != null) scrollListener.resetState();
- viewModel.resetPagination();
- viewModel.fetchRepos(
- requireContext(), "starredRepos", "", null, 1, resultLimit, null, true);
- }
-
- private void setupSwipeRefresh() {
- binding.pullToRefresh.setOnRefreshListener(
- () -> {
- binding.pullToRefresh.setRefreshing(false);
- refreshData();
- });
- }
-
- @Override
- public void onResume() {
- super.onResume();
- if (MainActivity.reloadRepos) {
- refreshData();
- MainActivity.reloadRepos = false;
- }
- }
-}
diff --git a/app/src/main/res/layout/fragment_explore.xml b/app/src/main/res/layout/activity_explore.xml
similarity index 64%
rename from app/src/main/res/layout/fragment_explore.xml
rename to app/src/main/res/layout/activity_explore.xml
index 4a14f5f7..f2c16483 100644
--- a/app/src/main/res/layout/fragment_explore.xml
+++ b/app/src/main/res/layout/activity_explore.xml
@@ -2,29 +2,32 @@
+
+
+ app:tabMode="fixed"
+ app:tabGravity="fill"
+ app:tabIndicatorAnimationMode="elastic"
+ app:tabSelectedTextColor="?attr/colorPrimary" />
@@ -32,6 +35,6 @@
android:id="@+id/containerExplore"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
+ app:layout_behavior="@string/appbar_scrolling_view_behavior" />
diff --git a/app/src/main/res/layout/activity_repositories.xml b/app/src/main/res/layout/activity_repositories.xml
new file mode 100644
index 00000000..8a2c319e
--- /dev/null
+++ b/app/src/main/res/layout/activity_repositories.xml
@@ -0,0 +1,132 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml
index cf7bedf6..08d28918 100644
--- a/app/src/main/res/navigation/nav_graph.xml
+++ b/app/src/main/res/navigation/nav_graph.xml
@@ -18,11 +18,6 @@
app:destination="@id/myRepositoriesFragment"
app:popUpTo="@id/homeDashboardFragment"
app:popUpToInclusive="false" />
-
-
-
-
-