From 0ee5b43996e24bd8f4231164e85963f6534819b8 Mon Sep 17 00:00:00 2001 From: M M Arif Date: Thu, 23 Apr 2020 20:40:13 +0000 Subject: [PATCH] Optimize fragments, add filters, fix search and clean up (#439) Code Reformat hide not found message Refactor issues, remove fastadapter. fix swipe back filter icon issue, fix crash on issues with faster swiping Change filter icon based on selection, empty the list for progress bar, check for gitea version to pass limit and other improvements Separate menu and interface for pr Add filter bottom sheet to PRs, issues Fix search/filter pull requests Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: 6543 <6543@noreply.gitea.io> Reviewed-on: https://gitea.com/gitnex/GitNex/pulls/439 Reviewed-by: opyale --- .../mian/gitnex/activities/MainActivity.java | 957 +++++++++--------- .../gitnex/activities/RepoDetailActivity.java | 838 ++++++++------- .../mian/gitnex/adapters/IssuesAdapter.java | 291 +++--- .../gitnex/adapters/PullRequestsAdapter.java | 293 +++--- .../BottomSheetIssuesFilterFragment.java | 63 ++ .../BottomSheetPullRequestFilterFragment.java | 63 ++ .../BottomSheetSingleIssueFragment.java | 308 +++--- .../mian/gitnex/fragments/FilesFragment.java | 430 ++++---- .../fragments/IssuesClosedFragment.java | 311 ------ .../mian/gitnex/fragments/IssuesFragment.java | 312 ++++++ .../gitnex/fragments/IssuesMainFragment.java | 155 --- .../gitnex/fragments/IssuesOpenFragment.java | 308 ------ .../fragments/PullRequestsFragment.java | 400 ++++---- .../gitnex/helpers/StaticGlobalVariables.java | 14 +- .../mian/gitnex/interfaces/ApiInterface.java | 5 +- .../main/res/drawable/ic_filter_closed.xml | 5 + .../res/layout/bottom_sheet_issues_filter.xml | 48 + .../bottom_sheet_pull_request_filter.xml | 48 + app/src/main/res/menu/filter_menu.xml | 12 + app/src/main/res/menu/filter_menu_pr.xml | 12 + 20 files changed, 2349 insertions(+), 2524 deletions(-) create mode 100644 app/src/main/java/org/mian/gitnex/fragments/BottomSheetIssuesFilterFragment.java create mode 100644 app/src/main/java/org/mian/gitnex/fragments/BottomSheetPullRequestFilterFragment.java delete mode 100644 app/src/main/java/org/mian/gitnex/fragments/IssuesClosedFragment.java create mode 100644 app/src/main/java/org/mian/gitnex/fragments/IssuesFragment.java delete mode 100644 app/src/main/java/org/mian/gitnex/fragments/IssuesMainFragment.java delete mode 100644 app/src/main/java/org/mian/gitnex/fragments/IssuesOpenFragment.java create mode 100644 app/src/main/res/drawable/ic_filter_closed.xml create mode 100644 app/src/main/res/layout/bottom_sheet_issues_filter.xml create mode 100644 app/src/main/res/layout/bottom_sheet_pull_request_filter.xml create mode 100644 app/src/main/res/menu/filter_menu.xml create mode 100644 app/src/main/res/menu/filter_menu_pr.xml 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 1cf83a64..71ba6e25 100644 --- a/app/src/main/java/org/mian/gitnex/activities/MainActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/MainActivity.java @@ -4,14 +4,6 @@ import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; -import androidx.annotation.NonNull; -import com.google.android.material.navigation.NavigationView; -import androidx.appcompat.widget.Toolbar; -import androidx.core.view.GravityCompat; -import androidx.drawerlayout.widget.DrawerLayout; -import androidx.appcompat.app.ActionBarDrawerToggle; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.graphics.Typeface; @@ -22,6 +14,14 @@ import android.view.MenuItem; import android.view.View; import android.widget.ImageView; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.appcompat.app.ActionBarDrawerToggle; +import androidx.appcompat.widget.Toolbar; +import androidx.core.view.GravityCompat; +import androidx.drawerlayout.widget.DrawerLayout; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import com.google.android.material.navigation.NavigationView; import com.squareup.picasso.NetworkPolicy; import org.mian.gitnex.R; import org.mian.gitnex.clients.PicassoService; @@ -31,19 +31,19 @@ import org.mian.gitnex.fragments.AdministrationFragment; import org.mian.gitnex.fragments.ExploreRepositoriesFragment; import org.mian.gitnex.fragments.MyRepositoriesFragment; import org.mian.gitnex.fragments.OrganizationsFragment; +import org.mian.gitnex.fragments.ProfileFragment; +import org.mian.gitnex.fragments.RepositoriesFragment; import org.mian.gitnex.fragments.SettingsFragment; import org.mian.gitnex.fragments.StarredRepositoriesFragment; import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.ChangeLog; +import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.models.GiteaVersion; import org.mian.gitnex.models.UserInfo; import org.mian.gitnex.util.AppUtil; -import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.util.TinyDB; -import org.mian.gitnex.fragments.ProfileFragment; -import org.mian.gitnex.fragments.RepositoriesFragment; import java.util.Objects; import retrofit2.Call; import retrofit2.Callback; @@ -54,494 +54,477 @@ import retrofit2.Callback; public class MainActivity extends BaseActivity implements NavigationView.OnNavigationItemSelectedListener { - private DrawerLayout drawer; - private TextView userFullName; - private TextView userEmail; - private ImageView userAvatar; - private TextView toolbarTitle; - final Context ctx = this; - private Typeface myTypeface; - - @Override - protected int getLayoutResourceId(){ - return R.layout.activity_main; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - - super.onCreate(savedInstanceState); - final TinyDB tinyDb = new TinyDB(getApplicationContext()); - tinyDb.putBoolean("noConnection", false); - //userAvatar = findViewById(R.id.userAvatar); - - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - - if(tinyDb.getString("dateFormat").isEmpty()) { - tinyDb.putString("dateFormat", "pretty"); - } - - if(tinyDb.getString("codeBlockStr").isEmpty()) { - tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorLightGreen)); - tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.black)); - } - - if(tinyDb.getString("enableCounterIssueBadgeInit").isEmpty()) { - tinyDb.putBoolean("enableCounterIssueBadge", true); - } - - if(tinyDb.getString("homeScreenStr").isEmpty()) { - tinyDb.putInt("homeScreenId", 0); - } - - String appLocale = tinyDb.getString("locale"); - AppUtil.setAppLocale(getResources(), appLocale); - - boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); - - if(!tinyDb.getBoolean("loggedInMode")) { - logout(this, ctx); - return; - } - - Toolbar toolbar = findViewById(R.id.toolbar); - toolbarTitle = toolbar.findViewById(R.id.toolbar_title); - - switch(tinyDb.getInt("customFontId", -1)) { - - case 0: - myTypeface = Typeface.createFromAsset(getAssets(), "fonts/roboto.ttf"); - break; - - case 2: - myTypeface = Typeface.createFromAsset(getAssets(), "fonts/sourcecodeproregular.ttf"); - break; - - default: - myTypeface = Typeface.createFromAsset(getAssets(), "fonts/manroperegular.ttf"); - break; - - } - - toolbarTitle.setTypeface(myTypeface); - setSupportActionBar(toolbar); - - FragmentManager fm = getSupportFragmentManager(); - Fragment fragmentById = fm.findFragmentById(R.id.fragment_container); - if (fragmentById instanceof SettingsFragment) { - toolbarTitle.setText(getResources().getString(R.string.pageTitleSettings)); - } - else if (fragmentById instanceof MyRepositoriesFragment) { - toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos)); - } - else if (fragmentById instanceof StarredRepositoriesFragment) { - toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos)); - } - else if (fragmentById instanceof OrganizationsFragment) { - toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations)); - } - else if (fragmentById instanceof ExploreRepositoriesFragment) { - toolbarTitle.setText(getResources().getString(R.string.pageTitleExplore)); - } - else if (fragmentById instanceof ProfileFragment) { - toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile)); - } - else if (fragmentById instanceof AboutFragment) { - toolbarTitle.setText(getResources().getString(R.string.pageTitleAbout)); - } - else if (fragmentById instanceof AdministrationFragment) { - toolbarTitle.setText(getResources().getString(R.string.pageTitleAdministration)); - } - - drawer = findViewById(R.id.drawer_layout); - NavigationView navigationView = findViewById(R.id.nav_view); - navigationView.setNavigationItemSelectedListener(this); - final View hView = navigationView.getHeaderView(0); - - ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, - R.string.navigation_drawer_open, R.string.navigation_drawer_close); - toggle.getDrawerArrowDrawable().setColor(getResources().getColor(R.color.darkGreen)); - drawer.addDrawerListener(toggle); - - drawer.addDrawerListener(new DrawerLayout.DrawerListener() { - - @Override - public void onDrawerSlide(@NonNull View drawerView, float slideOffset) { - - } - - @Override - public void onDrawerOpened(@NonNull View drawerView) { - - if(tinyDb.getBoolean("noConnection")) { - Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection)); - tinyDb.putBoolean("noConnection", false); - } - - String userEmailNav = tinyDb.getString("userEmail"); - String userFullNameNav = tinyDb.getString("userFullname"); - String userAvatarNav = tinyDb.getString("userAvatar"); - - userEmail = hView.findViewById(R.id.userEmail); - if (!userEmailNav.equals("")) { - userEmail.setText(userEmailNav); - userEmail.setTypeface(myTypeface); - } - - userFullName = hView.findViewById(R.id.userFullname); - if (!userFullNameNav.equals("")) { - userFullName.setText(userFullNameNav); - userFullName.setTypeface(myTypeface); - } - - userAvatar = hView.findViewById(R.id.userAvatar); - if (!userAvatarNav.equals("")) { - PicassoService.getInstance(ctx).get().load(userAvatarNav).networkPolicy(NetworkPolicy.OFFLINE).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(160, 160).centerCrop().into(userAvatar); - } - - userAvatar.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, - new ProfileFragment()).commit(); - drawer.closeDrawers(); - } - }); - - } - - @Override - public void onDrawerClosed(@NonNull View drawerView) { - // Called when a drawer has settled in a completely closed state. - } - - @Override - public void onDrawerStateChanged(int newState) { - // Called when the drawer motion state changes. The new state will be one of STATE_IDLE, STATE_DRAGGING or STATE_SETTLING. - } - }); - - toggle.syncState(); - - if(savedInstanceState == null) { - if(tinyDb.getInt("homeScreenId") == 0) { - toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos)); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, - new MyRepositoriesFragment()).commit(); - navigationView.setCheckedItem(R.id.nav_home); - } - else if(tinyDb.getInt("homeScreenId") == 1) { - toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos)); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, - new StarredRepositoriesFragment()).commit(); - navigationView.setCheckedItem(R.id.nav_starred_repos); - } - else if(tinyDb.getInt("homeScreenId") == 2) { - toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations)); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, - new OrganizationsFragment()).commit(); - navigationView.setCheckedItem(R.id.nav_organizations); - } - else if(tinyDb.getInt("homeScreenId") == 3) { - toolbarTitle.setText(getResources().getString(R.string.pageTitleRepositories)); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, - new RepositoriesFragment()).commit(); - navigationView.setCheckedItem(R.id.nav_repositories); - } - else if(tinyDb.getInt("homeScreenId") == 4) { - toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile)); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, - new ProfileFragment()).commit(); - navigationView.setCheckedItem(R.id.nav_profile); - } - else { - toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos)); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, - new MyRepositoriesFragment()).commit(); - navigationView.setCheckedItem(R.id.nav_home); - } - } - - if(!connToInternet) { - - if(!tinyDb.getBoolean("noConnection")) { - Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection)); - } - - tinyDb.putBoolean("noConnection", true); - - } else { - - displayUserInfo(instanceUrl, instanceToken, loginUid); - giteaVersion(instanceUrl); - tinyDb.putBoolean("noConnection", false); - - } - - // Changelog popup - int versionCode = 0; - try { - PackageInfo packageInfo = getApplicationContext().getPackageManager() - .getPackageInfo(getApplicationContext().getPackageName(), 0); - versionCode = packageInfo.versionCode; - } - catch (PackageManager.NameNotFoundException e) { - Log.e("changelogDialog", Objects.requireNonNull(e.getMessage())); - } - - if (versionCode > tinyDb.getInt("versionCode")) { - tinyDb.putInt("versionCode", versionCode); - tinyDb.putBoolean("versionFlag", true); - ChangeLog changelogDialog = new ChangeLog(this); - changelogDialog.showDialog(); - } - } - - public void setActionBarTitle (@NonNull String title) { - Objects.requireNonNull(getSupportActionBar()).setTitle(title); - } - - @Override - public void onBackPressed() { - - if(drawer.isDrawerOpen(GravityCompat.START)) { - drawer.closeDrawer(GravityCompat.START); - } - else { - super.onBackPressed(); - } - - } - - @Override - public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) { - - switch (menuItem.getItemId()) { - case R.id.nav_home: - toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos)); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, - new MyRepositoriesFragment()).commit(); - break; - case R.id.nav_organizations: - toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations)); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, - new OrganizationsFragment()).commit(); - break; - case R.id.nav_profile: - toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile)); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, - new ProfileFragment()).commit(); - break; - case R.id.nav_repositories: - toolbarTitle.setText(getResources().getString(R.string.pageTitleRepositories)); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, - new RepositoriesFragment()).commit(); - - break; - case R.id.nav_settings: - toolbarTitle.setText(getResources().getString(R.string.pageTitleSettings)); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, - new SettingsFragment()).commit(); - break; - case R.id.nav_logout: - logout(this, ctx); - overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); - break; - case R.id.nav_about: - toolbarTitle.setText(getResources().getString(R.string.pageTitleAbout)); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, - new AboutFragment()).commit(); - break; - case R.id.nav_rate_app: - rateThisApp(); - break; - case R.id.nav_starred_repos: - toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos)); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, - new StarredRepositoriesFragment()).commit(); - break; - case R.id.nav_explore: - toolbarTitle.setText(getResources().getString(R.string.pageTitleExplore)); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, - new ExploreRepositoriesFragment()).commit(); - break; - case R.id.nav_administration: - toolbarTitle.setText(getResources().getString(R.string.pageTitleAdministration)); - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, - new AdministrationFragment()).commit(); - break; - - } - - drawer.closeDrawer(GravityCompat.START); - return true; - } - - public void rateThisApp() { - try { - startActivity(new Intent(Intent.ACTION_VIEW, - Uri.parse("market://details?id=" + getPackageName()))); - } catch (ActivityNotFoundException e) { - startActivity(new Intent(Intent.ACTION_VIEW, - Uri.parse("https://play.google.com/store/apps/details?id=" + getPackageName()))); - } - } - - public static void logout(Activity activity, Context ctx) { - - TinyDB tinyDb = new TinyDB(ctx.getApplicationContext()); - tinyDb.putBoolean("loggedInMode", false); - tinyDb.remove("basicAuthPassword"); - tinyDb.putBoolean("basicAuthFlag", false); - //tinyDb.clear(); - activity.finish(); - ctx.startActivity(new Intent(ctx, LoginActivity.class)); - - } - - private void giteaVersion(final String instanceUrl) { - - final TinyDB tinyDb = new TinyDB(getApplicationContext()); - - final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token"); - - Call callVersion = RetrofitClient - .getInstance(instanceUrl, getApplicationContext()) - .getApiInterface() - .getGiteaVersionWithToken(token); - - callVersion.enqueue(new Callback() { - - @Override - public void onResponse(@NonNull final Call callVersion, @NonNull retrofit2.Response responseVersion) { - - if (responseVersion.code() == 200) { - - GiteaVersion version = responseVersion.body(); - assert version != null; - - tinyDb.putString("giteaVersion", version.getVersion()); - - } - - } - - @Override - public void onFailure(@NonNull Call callVersion, @NonNull Throwable t) { - - Log.e("onFailure-version", t.toString()); - - } - - }); - - } - - private void displayUserInfo(String instanceUrl, String token, String loginUid) { - - final TinyDB tinyDb = new TinyDB(getApplicationContext()); - - Call call = RetrofitClient - .getInstance(instanceUrl, getApplicationContext()) - .getApiInterface() - .getUserInfo(Authorization.returnAuthentication(getApplicationContext(), loginUid, token)); - - NavigationView navigationView = findViewById(R.id.nav_view); - final View hView = navigationView.getHeaderView(0); - - call.enqueue(new Callback() { - - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - - UserInfo userDetails = response.body(); + private DrawerLayout drawer; + private TextView userFullName; + private TextView userEmail; + private ImageView userAvatar; + private TextView toolbarTitle; + final Context ctx = this; + private Typeface myTypeface; + + @Override + protected int getLayoutResourceId() { + + return R.layout.activity_main; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + + super.onCreate(savedInstanceState); + final TinyDB tinyDb = new TinyDB(getApplicationContext()); + tinyDb.putBoolean("noConnection", false); + //userAvatar = findViewById(R.id.userAvatar); + + final String instanceUrl = tinyDb.getString("instanceUrl"); + final String loginUid = tinyDb.getString("loginUid"); + final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + + if(tinyDb.getString("dateFormat").isEmpty()) { + tinyDb.putString("dateFormat", "pretty"); + } + + if(tinyDb.getString("codeBlockStr").isEmpty()) { + tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorLightGreen)); + tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.black)); + } + + if(tinyDb.getString("enableCounterIssueBadgeInit").isEmpty()) { + tinyDb.putBoolean("enableCounterIssueBadge", true); + } + + if(tinyDb.getString("homeScreenStr").isEmpty()) { + tinyDb.putInt("homeScreenId", 0); + } + + String appLocale = tinyDb.getString("locale"); + AppUtil.setAppLocale(getResources(), appLocale); + + boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext()); + + if(!tinyDb.getBoolean("loggedInMode")) { + logout(this, ctx); + return; + } + + Toolbar toolbar = findViewById(R.id.toolbar); + toolbarTitle = toolbar.findViewById(R.id.toolbar_title); + + switch(tinyDb.getInt("customFontId", -1)) { + + case 0: + myTypeface = Typeface.createFromAsset(getAssets(), "fonts/roboto.ttf"); + break; + + case 2: + myTypeface = Typeface.createFromAsset(getAssets(), "fonts/sourcecodeproregular.ttf"); + break; + + default: + myTypeface = Typeface.createFromAsset(getAssets(), "fonts/manroperegular.ttf"); + break; + + } + + toolbarTitle.setTypeface(myTypeface); + setSupportActionBar(toolbar); + + FragmentManager fm = getSupportFragmentManager(); + Fragment fragmentById = fm.findFragmentById(R.id.fragment_container); + if(fragmentById instanceof SettingsFragment) { + toolbarTitle.setText(getResources().getString(R.string.pageTitleSettings)); + } + else if(fragmentById instanceof MyRepositoriesFragment) { + toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos)); + } + else if(fragmentById instanceof StarredRepositoriesFragment) { + toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos)); + } + else if(fragmentById instanceof OrganizationsFragment) { + toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations)); + } + else if(fragmentById instanceof ExploreRepositoriesFragment) { + toolbarTitle.setText(getResources().getString(R.string.pageTitleExplore)); + } + else if(fragmentById instanceof ProfileFragment) { + toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile)); + } + else if(fragmentById instanceof AboutFragment) { + toolbarTitle.setText(getResources().getString(R.string.pageTitleAbout)); + } + else if(fragmentById instanceof AdministrationFragment) { + toolbarTitle.setText(getResources().getString(R.string.pageTitleAdministration)); + } + + drawer = findViewById(R.id.drawer_layout); + NavigationView navigationView = findViewById(R.id.nav_view); + navigationView.setNavigationItemSelectedListener(this); + final View hView = navigationView.getHeaderView(0); + + ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); + toggle.getDrawerArrowDrawable().setColor(getResources().getColor(R.color.darkGreen)); + drawer.addDrawerListener(toggle); + + drawer.addDrawerListener(new DrawerLayout.DrawerListener() { + + @Override + public void onDrawerSlide(@NonNull View drawerView, float slideOffset) { + + } + + @Override + public void onDrawerOpened(@NonNull View drawerView) { + + if(tinyDb.getBoolean("noConnection")) { + Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection)); + tinyDb.putBoolean("noConnection", false); + } + + String userEmailNav = tinyDb.getString("userEmail"); + String userFullNameNav = tinyDb.getString("userFullname"); + String userAvatarNav = tinyDb.getString("userAvatar"); + + userEmail = hView.findViewById(R.id.userEmail); + if(!userEmailNav.equals("")) { + userEmail.setText(userEmailNav); + userEmail.setTypeface(myTypeface); + } + + userFullName = hView.findViewById(R.id.userFullname); + if(!userFullNameNav.equals("")) { + userFullName.setText(userFullNameNav); + userFullName.setTypeface(myTypeface); + } + + userAvatar = hView.findViewById(R.id.userAvatar); + if(!userAvatarNav.equals("")) { + PicassoService.getInstance(ctx).get().load(userAvatarNav).networkPolicy(NetworkPolicy.OFFLINE).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(160, 160).centerCrop().into(userAvatar); + } + + userAvatar.setOnClickListener(new View.OnClickListener() { + + public void onClick(View v) { + + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit(); + drawer.closeDrawers(); + } + }); + + } + + @Override + public void onDrawerClosed(@NonNull View drawerView) { + // Called when a drawer has settled in a completely closed state. + } + + @Override + public void onDrawerStateChanged(int newState) { + // Called when the drawer motion state changes. The new state will be one of STATE_IDLE, STATE_DRAGGING or STATE_SETTLING. + } + }); + + toggle.syncState(); + + if(savedInstanceState == null) { + if(tinyDb.getInt("homeScreenId") == 0) { + toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos)); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyRepositoriesFragment()).commit(); + navigationView.setCheckedItem(R.id.nav_home); + } + else if(tinyDb.getInt("homeScreenId") == 1) { + toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos)); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new StarredRepositoriesFragment()).commit(); + navigationView.setCheckedItem(R.id.nav_starred_repos); + } + else if(tinyDb.getInt("homeScreenId") == 2) { + toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations)); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new OrganizationsFragment()).commit(); + navigationView.setCheckedItem(R.id.nav_organizations); + } + else if(tinyDb.getInt("homeScreenId") == 3) { + toolbarTitle.setText(getResources().getString(R.string.pageTitleRepositories)); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new RepositoriesFragment()).commit(); + navigationView.setCheckedItem(R.id.nav_repositories); + } + else if(tinyDb.getInt("homeScreenId") == 4) { + toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile)); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit(); + navigationView.setCheckedItem(R.id.nav_profile); + } + else { + toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos)); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyRepositoriesFragment()).commit(); + navigationView.setCheckedItem(R.id.nav_home); + } + } + + if(!connToInternet) { + + if(!tinyDb.getBoolean("noConnection")) { + Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection)); + } + + tinyDb.putBoolean("noConnection", true); + + } + else { + + displayUserInfo(instanceUrl, instanceToken, loginUid); + giteaVersion(instanceUrl); + tinyDb.putBoolean("noConnection", false); + + } + + // Changelog popup + int versionCode = 0; + try { + PackageInfo packageInfo = getApplicationContext().getPackageManager().getPackageInfo(getApplicationContext().getPackageName(), 0); + versionCode = packageInfo.versionCode; + } + catch(PackageManager.NameNotFoundException e) { + Log.e("changelogDialog", Objects.requireNonNull(e.getMessage())); + } + + if(versionCode > tinyDb.getInt("versionCode")) { + tinyDb.putInt("versionCode", versionCode); + tinyDb.putBoolean("versionFlag", true); + ChangeLog changelogDialog = new ChangeLog(this); + changelogDialog.showDialog(); + } + } + + public void setActionBarTitle(@NonNull String title) { + + Objects.requireNonNull(getSupportActionBar()).setTitle(title); + } + + @Override + public void onBackPressed() { + + if(drawer.isDrawerOpen(GravityCompat.START)) { + drawer.closeDrawer(GravityCompat.START); + } + else { + super.onBackPressed(); + } + + } + + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) { + + switch(menuItem.getItemId()) { + case R.id.nav_home: + toolbarTitle.setText(getResources().getString(R.string.pageTitleMyRepos)); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyRepositoriesFragment()).commit(); + break; + case R.id.nav_organizations: + toolbarTitle.setText(getResources().getString(R.string.pageTitleOrganizations)); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new OrganizationsFragment()).commit(); + break; + case R.id.nav_profile: + toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile)); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit(); + break; + case R.id.nav_repositories: + toolbarTitle.setText(getResources().getString(R.string.pageTitleRepositories)); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new RepositoriesFragment()).commit(); + + break; + case R.id.nav_settings: + toolbarTitle.setText(getResources().getString(R.string.pageTitleSettings)); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new SettingsFragment()).commit(); + break; + case R.id.nav_logout: + logout(this, ctx); + overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); + break; + case R.id.nav_about: + toolbarTitle.setText(getResources().getString(R.string.pageTitleAbout)); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new AboutFragment()).commit(); + break; + case R.id.nav_rate_app: + rateThisApp(); + break; + case R.id.nav_starred_repos: + toolbarTitle.setText(getResources().getString(R.string.pageTitleStarredRepos)); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new StarredRepositoriesFragment()).commit(); + break; + case R.id.nav_explore: + toolbarTitle.setText(getResources().getString(R.string.pageTitleExplore)); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ExploreRepositoriesFragment()).commit(); + break; + case R.id.nav_administration: + toolbarTitle.setText(getResources().getString(R.string.pageTitleAdministration)); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new AdministrationFragment()).commit(); + break; + + } + + drawer.closeDrawer(GravityCompat.START); + return true; + } + + public void rateThisApp() { + + try { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + getPackageName()))); + } + catch(ActivityNotFoundException e) { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + getPackageName()))); + } + } + + public static void logout(Activity activity, Context ctx) { + + TinyDB tinyDb = new TinyDB(ctx.getApplicationContext()); + tinyDb.putBoolean("loggedInMode", false); + tinyDb.remove("basicAuthPassword"); + tinyDb.putBoolean("basicAuthFlag", false); + //tinyDb.clear(); + activity.finish(); + ctx.startActivity(new Intent(ctx, LoginActivity.class)); + + } + + private void giteaVersion(final String instanceUrl) { + + final TinyDB tinyDb = new TinyDB(getApplicationContext()); + + final String token = "token " + tinyDb.getString(tinyDb.getString("loginUid") + "-token"); + + Call callVersion = RetrofitClient.getInstance(instanceUrl, getApplicationContext()).getApiInterface().getGiteaVersionWithToken(token); + + callVersion.enqueue(new Callback() { + + @Override + public void onResponse(@NonNull final Call callVersion, @NonNull retrofit2.Response responseVersion) { + + if(responseVersion.code() == 200) { + + GiteaVersion version = responseVersion.body(); + assert version != null; + + tinyDb.putString("giteaVersion", version.getVersion()); + + } + + } + + @Override + public void onFailure(@NonNull Call callVersion, @NonNull Throwable t) { + + Log.e("onFailure-version", t.toString()); + + } + + }); + + } - if (response.isSuccessful()) { + private void displayUserInfo(String instanceUrl, String token, String loginUid) { - if (response.code() == 200) { + final TinyDB tinyDb = new TinyDB(getApplicationContext()); - assert userDetails != null; - if(userDetails.getIs_admin() != null) { - tinyDb.putBoolean("userIsAdmin", userDetails.getIs_admin()); - navigationView.getMenu().findItem(R.id.nav_administration).setVisible(userDetails.getIs_admin()); - } - tinyDb.putString("userLogin", userDetails.getLogin()); - tinyDb.putInt("userId", userDetails.getId()); - if(!userDetails.getFullname().equals("")) { - tinyDb.putString("userFullname", userDetails.getFullname()); - } - else { - tinyDb.putString("userFullname", userDetails.getLogin()); - } + Call call = RetrofitClient.getInstance(instanceUrl, getApplicationContext()).getApiInterface().getUserInfo(Authorization.returnAuthentication(getApplicationContext(), loginUid, token)); - tinyDb.putString("userEmail", userDetails.getEmail()); - tinyDb.putString("userAvatar", userDetails.getAvatar()); - if(userDetails.getLang() != null) { - tinyDb.putString("userLang", userDetails.getLang()); - } - else - { - tinyDb.putString("userLang", "..."); - } + NavigationView navigationView = findViewById(R.id.nav_view); + final View hView = navigationView.getHeaderView(0); - userAvatar = hView.findViewById(R.id.userAvatar); - if (!Objects.requireNonNull(userDetails).getAvatar().equals("")) { - PicassoService.getInstance(ctx).get().load(userDetails.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(160, 160).centerCrop().into(userAvatar); - } else { - userAvatar.setImageResource(R.mipmap.app_logo_round); - } + call.enqueue(new Callback() { - userFullName = hView.findViewById(R.id.userFullname); - if (!userDetails.getFullname().equals("")) { - userFullName.setText(userDetails.getFullname()); - } else if (!userDetails.getLogin().equals("")) { - userFullName.setText(userDetails.getLogin()); - } else { - userFullName.setText("..."); - } + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - userEmail = hView.findViewById(R.id.userEmail); - if (!userDetails.getEmail().equals("")) { - userEmail.setText(userDetails.getEmail()); - } else { - userEmail.setText("..."); - } + UserInfo userDetails = response.body(); - userAvatar.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, - new ProfileFragment()).commit(); - drawer.closeDrawers(); - } - }); + if(response.isSuccessful()) { - } + if(response.code() == 200) { - } - else if(response.code() == 401) { + assert userDetails != null; + if(userDetails.getIs_admin() != null) { + tinyDb.putBoolean("userIsAdmin", userDetails.getIs_admin()); + navigationView.getMenu().findItem(R.id.nav_administration).setVisible(userDetails.getIs_admin()); + } + tinyDb.putString("userLogin", userDetails.getLogin()); + tinyDb.putInt("userId", userDetails.getId()); + if(!userDetails.getFullname().equals("")) { + tinyDb.putString("userFullname", userDetails.getFullname()); + } + else { + tinyDb.putString("userFullname", userDetails.getLogin()); + } - AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle), - getResources().getString(R.string.alertDialogTokenRevokedMessage), - getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), - getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); + tinyDb.putString("userEmail", userDetails.getEmail()); + tinyDb.putString("userAvatar", userDetails.getAvatar()); + if(userDetails.getLang() != null) { + tinyDb.putString("userLang", userDetails.getLang()); + } + else { + tinyDb.putString("userLang", "..."); + } - } - else { + userAvatar = hView.findViewById(R.id.userAvatar); + if(!Objects.requireNonNull(userDetails).getAvatar().equals("")) { + PicassoService.getInstance(ctx).get().load(userDetails.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(160, 160).centerCrop().into(userAvatar); + } + else { + userAvatar.setImageResource(R.mipmap.app_logo_round); + } - String toastError = getResources().getString(R.string.genericApiStatusError) + String.valueOf(response.code()); - Toasty.info(getApplicationContext(), toastError); - - } - - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - Log.e("onFailure", t.toString()); - } - }); - - } + userFullName = hView.findViewById(R.id.userFullname); + if(!userDetails.getFullname().equals("")) { + userFullName.setText(userDetails.getFullname()); + } + else if(!userDetails.getLogin().equals("")) { + userFullName.setText(userDetails.getLogin()); + } + else { + userFullName.setText("..."); + } + + userEmail = hView.findViewById(R.id.userEmail); + if(!userDetails.getEmail().equals("")) { + userEmail.setText(userDetails.getEmail()); + } + else { + userEmail.setText("..."); + } + + userAvatar.setOnClickListener(new View.OnClickListener() { + + public void onClick(View v) { + + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit(); + drawer.closeDrawers(); + } + }); + + } + + } + else if(response.code() == 401) { + + AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle), getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton), getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton)); + + } + else { + + String toastError = getResources().getString(R.string.genericApiStatusError) + String.valueOf(response.code()); + Toasty.info(getApplicationContext(), toastError); + + } + + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + + Log.e("onFailure", t.toString()); + } + }); + + } } diff --git a/app/src/main/java/org/mian/gitnex/activities/RepoDetailActivity.java b/app/src/main/java/org/mian/gitnex/activities/RepoDetailActivity.java index e1d8b100..180fd31c 100644 --- a/app/src/main/java/org/mian/gitnex/activities/RepoDetailActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/RepoDetailActivity.java @@ -1,19 +1,10 @@ package org.mian.gitnex.activities; -import com.google.android.material.tabs.TabLayout; -import com.google.gson.JsonElement; -import androidx.annotation.NonNull; -import androidx.appcompat.widget.Toolbar; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentStatePagerAdapter; -import androidx.viewpager.widget.ViewPager; -import retrofit2.Call; -import retrofit2.Callback; import android.annotation.SuppressLint; import android.content.Intent; import android.content.res.ColorStateList; import android.graphics.Typeface; +import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; @@ -23,13 +14,23 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentStatePagerAdapter; +import androidx.viewpager.widget.ViewPager; +import com.google.android.material.tabs.TabLayout; +import com.google.gson.JsonElement; import org.mian.gitnex.R; import org.mian.gitnex.clients.RetrofitClient; +import org.mian.gitnex.fragments.BottomSheetIssuesFilterFragment; +import org.mian.gitnex.fragments.BottomSheetPullRequestFilterFragment; import org.mian.gitnex.fragments.BottomSheetRepoFragment; import org.mian.gitnex.fragments.BranchesFragment; import org.mian.gitnex.fragments.CollaboratorsFragment; import org.mian.gitnex.fragments.FilesFragment; -import org.mian.gitnex.fragments.IssuesMainFragment; +import org.mian.gitnex.fragments.IssuesFragment; import org.mian.gitnex.fragments.LabelsFragment; import org.mian.gitnex.fragments.MilestonesFragment; import org.mian.gitnex.fragments.PullRequestsFragment; @@ -42,413 +43,480 @@ import org.mian.gitnex.models.WatchRepository; import org.mian.gitnex.util.AppUtil; import org.mian.gitnex.util.TinyDB; import java.util.Objects; -import android.net.Uri; +import retrofit2.Call; +import retrofit2.Callback; /** * Author M M Arif */ -public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoFragment.BottomSheetListener { +public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoFragment.BottomSheetListener, BottomSheetIssuesFilterFragment.BottomSheetListener, BottomSheetPullRequestFilterFragment.BottomSheetListener { - private TextView textViewBadgeIssue; - private TextView textViewBadgePull; - private TextView textViewBadgeRelease; + private TextView textViewBadgeIssue; + private TextView textViewBadgePull; + private TextView textViewBadgeRelease; - @Override - protected int getLayoutResourceId(){ - return R.layout.activity_repo_detail; - } + private FragmentRefreshListener fragmentRefreshListener; + private FragmentRefreshListenerPr fragmentRefreshListenerPr; - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + // issues interface + public FragmentRefreshListener getFragmentRefreshListener() { - TinyDB tinyDb = new TinyDB(getApplicationContext()); - String repoFullName = tinyDb.getString("repoFullName"); - String[] parts = repoFullName.split("/"); - String repoName1 = parts[1]; - - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String repoOwner = parts[0]; - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - - String appLocale = tinyDb.getString("locale"); - AppUtil.setAppLocale(getResources(), appLocale); - - Toolbar toolbar = findViewById(R.id.toolbar); - TextView toolbarTitle = toolbar.findViewById(R.id.toolbar_title); - - setSupportActionBar(toolbar); - Objects.requireNonNull(getSupportActionBar()).setTitle(repoName1); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - - SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); - - ViewPager mViewPager = findViewById(R.id.container); - mViewPager.setAdapter(mSectionsPagerAdapter); - - TabLayout tabLayout = findViewById(R.id.tabs); - - Typeface myTypeface; - - switch(tinyDb.getInt("customFontId", -1)) { - - case 0: - myTypeface = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/roboto.ttf"); - break; - - case 2: - myTypeface = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/sourcecodeproregular.ttf"); - break; - - default: - myTypeface = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/manroperegular.ttf"); - break; - - } - - toolbarTitle.setTypeface(myTypeface); - toolbarTitle.setText(repoName1); - - ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0); - int tabsCount = vg.getChildCount(); - for (int j = 0; j < tabsCount; j++) { - ViewGroup vgTab = (ViewGroup) vg.getChildAt(j); - int tabChildCount = vgTab.getChildCount(); - for (int i = 0; i < tabChildCount; i++) { - View tabViewChild = vgTab.getChildAt(i); - if (tabViewChild instanceof TextView) { - ((TextView) tabViewChild).setTypeface(myTypeface); - } - } - } - - // only show Collaborators if you have permission to - final View collaboratorTab = vg.getChildAt(8); - if (tinyDb.getBoolean("isRepoAdmin")) { - collaboratorTab.setVisibility(View.VISIBLE); - } - else { - collaboratorTab.setVisibility(View.GONE); - } - - mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout)); - tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager)); - - if(tinyDb.getBoolean("enableCounterBadges")) { - - @SuppressLint("InflateParams") View tabHeader2 = LayoutInflater.from(this).inflate(R.layout.badge_issue, null); - textViewBadgeIssue = tabHeader2.findViewById(R.id.counterBadgeIssue); - - @SuppressLint("InflateParams") View tabHeader4 = LayoutInflater.from(this).inflate(R.layout.badge_pull, null); - textViewBadgePull = tabHeader4.findViewById(R.id.counterBadgePull); - - @SuppressLint("InflateParams") View tabHeader6 = LayoutInflater.from(this).inflate(R.layout.badge_release, null); - textViewBadgeRelease = tabHeader6.findViewById(R.id.counterBadgeRelease); - - textViewBadgeIssue.setVisibility(View.GONE); - textViewBadgePull.setVisibility(View.GONE); - textViewBadgeRelease.setVisibility(View.GONE); - - getRepoInfo(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1); - ColorStateList textColor = tabLayout.getTabTextColors(); - - // issue count - if (textViewBadgeIssue.getText() != "") { - TabLayout.Tab tabOpenIssues = tabLayout.getTabAt(2); - Objects.requireNonNull(tabLayout.getTabAt(2)).setCustomView(tabHeader2); - assert tabOpenIssues != null; - TextView openIssueTabView = Objects.requireNonNull(tabOpenIssues.getCustomView()).findViewById(R.id.counterBadgeIssueText); - openIssueTabView.setTextColor(textColor); - } - - // pull count - if (textViewBadgePull.getText() != "") { // only show if API returned a number - Objects.requireNonNull(tabLayout.getTabAt(3)).setCustomView(tabHeader4); - TabLayout.Tab tabOpenPulls = tabLayout.getTabAt(3); - assert tabOpenPulls != null; - TextView openPullTabView = Objects.requireNonNull(tabOpenPulls.getCustomView()).findViewById(R.id.counterBadgePullText); - openPullTabView.setTextColor(textColor); - } - - // release count - if (VersionCheck.compareVersion("1.11.5", tinyDb.getString("giteaVersion")) < 1) { - if(textViewBadgeRelease.getText() != "") { // only show if API returned a number - Objects.requireNonNull(tabLayout.getTabAt(5)).setCustomView(tabHeader6); - TabLayout.Tab tabOpenRelease = tabLayout.getTabAt(5); - assert tabOpenRelease != null; - TextView openReleaseTabView = Objects.requireNonNull(tabOpenRelease.getCustomView()).findViewById(R.id.counterBadgeReleaseText); - openReleaseTabView.setTextColor(textColor); - } - } - } - - checkRepositoryStarStatus(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1); - checkRepositoryWatchStatus(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1); - - } - - @Override - public void onResume() { - - super.onResume(); - TinyDB tinyDb = new TinyDB(getApplicationContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - String repoFullName = tinyDb.getString("repoFullName"); - String[] parts = repoFullName.split("/"); - final String repoOwner = parts[0]; - final String repoName = parts[1]; - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - - if(tinyDb.getBoolean("enableCounterIssueBadge")) { - getRepoInfo(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName); - } - - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.repo_dotted_menu, menu); - return true; - - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - - int id = item.getItemId(); - - switch (id) { - case android.R.id.home: - finish(); - return true; - case R.id.repoMenu: - BottomSheetRepoFragment bottomSheet = new BottomSheetRepoFragment(); - bottomSheet.show(getSupportFragmentManager(), "repoBottomSheet"); - return true; - default: - return super.onOptionsItemSelected(item); - } - - } - - @Override - public void onButtonClicked(String text) { - - TinyDB tinyDb = new TinyDB(getApplicationContext()); - String repoFullName = tinyDb.getString("repoFullName"); - String instanceUrlWithProtocol = "https://" + tinyDb.getString("instanceUrlRaw"); - if(!tinyDb.getString("instanceUrlWithProtocol").isEmpty()) { - instanceUrlWithProtocol = tinyDb.getString("instanceUrlWithProtocol"); - } - Uri url = Uri.parse(instanceUrlWithProtocol + "/" + repoFullName); - - switch (text) { - case "label": - startActivity(new Intent(RepoDetailActivity.this, CreateLabelActivity.class)); - break; - case "newIssue": - startActivity(new Intent(RepoDetailActivity.this, CreateIssueActivity.class)); - break; - case "newMilestone": - startActivity(new Intent(RepoDetailActivity.this, CreateMilestoneActivity.class)); - break; - case "addCollaborator": - startActivity(new Intent(RepoDetailActivity.this, AddCollaboratorToRepositoryActivity.class)); - break; - case "createRelease": - startActivity(new Intent(RepoDetailActivity.this, CreateReleaseActivity.class)); - break; - case "openWebRepo": - Intent i = new Intent(Intent.ACTION_VIEW, url); - startActivity(i); - break; - case "shareRepo": - Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); - sharingIntent.setType("text/plain"); - sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, url); - sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, url); - startActivity(Intent.createChooser(sharingIntent, url.toString())); - break; - case "newFile": - startActivity(new Intent(RepoDetailActivity.this, CreateFileActivity.class)); - break; - } - - } - - public class SectionsPagerAdapter extends FragmentStatePagerAdapter { - - SectionsPagerAdapter(FragmentManager fm) { - super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); - } - - @NonNull - @Override - public Fragment getItem(int position) { - - TinyDB tinyDb = new TinyDB(getApplicationContext()); - String repoFullName = tinyDb.getString("repoFullName"); - String[] parts = repoFullName.split("/"); - String repoOwner = parts[0]; - String repoName = parts[1]; - - Fragment fragment = null; - switch (position) { - case 0: // information - return RepoInfoFragment.newInstance(repoOwner, repoName); - case 1: // files - return FilesFragment.newInstance(repoOwner, repoName); - case 2: // issues - fragment = new IssuesMainFragment(); - break; - case 3: // pull requests - fragment = new PullRequestsFragment(); - break; - case 4: // branches - return BranchesFragment.newInstance(repoOwner, repoName); - case 5: // releases - return ReleasesFragment.newInstance(repoOwner, repoName); - case 6: // milestones - return MilestonesFragment.newInstance(repoOwner, repoName); - case 7: // labels - return LabelsFragment.newInstance(repoOwner, repoName); - case 8: // collaborators - return CollaboratorsFragment.newInstance(repoOwner, repoName); - } - assert fragment != null; - return fragment; - } - - @Override - public int getCount() { - return 9; - } - - } - - private void getRepoInfo(String instanceUrl, String token, final String owner, String repo) { - - TinyDB tinyDb = new TinyDB(getApplicationContext()); - - Call call = RetrofitClient - .getInstance(instanceUrl, getApplicationContext()) - .getApiInterface() - .getUserRepository(token, owner, repo); - - call.enqueue(new Callback() { - - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - - UserRepositories repoInfo = response.body(); - - if (response.isSuccessful()) { - - if (response.code() == 200) { - - if(tinyDb.getBoolean("enableCounterBadges")) { - assert repoInfo != null; - - if(repoInfo.getOpen_issues_count() != null) { - textViewBadgeIssue.setVisibility(View.VISIBLE); - textViewBadgeIssue.setText(repoInfo.getOpen_issues_count()); - } - - if(repoInfo.getOpen_pull_count() != null) { - textViewBadgePull.setVisibility(View.VISIBLE); - textViewBadgePull.setText(repoInfo.getOpen_pull_count()); - } - - if(repoInfo.getRelease_count() != null) { - textViewBadgeRelease.setVisibility(View.VISIBLE); - textViewBadgeRelease.setText(repoInfo.getRelease_count()); - } - } + return fragmentRefreshListener; + } - } + public void setFragmentRefreshListener(FragmentRefreshListener fragmentRefreshListener) { - } - else { - Log.e("onFailure", String.valueOf(response.code())); - } + this.fragmentRefreshListener = fragmentRefreshListener; + } - } + public interface FragmentRefreshListener { - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - Log.e("onFailure", t.toString()); - } + void onRefresh(String text); - }); + } - } + // pr interface + public FragmentRefreshListenerPr getFragmentRefreshListenerPr() { - private void checkRepositoryStarStatus(String instanceUrl, String instanceToken, final String owner, String repo) { + return fragmentRefreshListenerPr; + } - Call call; + public void setFragmentRefreshListenerPr(FragmentRefreshListenerPr fragmentRefreshListenerPr) { - call = RetrofitClient - .getInstance(instanceUrl, getApplicationContext()) - .getApiInterface() - .checkRepoStarStatus(instanceToken, owner, repo); + this.fragmentRefreshListenerPr = fragmentRefreshListenerPr; + } - call.enqueue(new Callback() { + public interface FragmentRefreshListenerPr { - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + void onRefresh(String text); - TinyDB tinyDb = new TinyDB(getApplicationContext()); - tinyDb.putInt("repositoryStarStatus", response.code()); + } - } + @Override + protected int getLayoutResourceId() { - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - Log.e("onFailure", t.toString()); - } - }); + return R.layout.activity_repo_detail; + } - } + @Override + public void onCreate(Bundle savedInstanceState) { - private void checkRepositoryWatchStatus(String instanceUrl, String instanceToken, final String owner, String repo) { + super.onCreate(savedInstanceState); - Call call; + TinyDB tinyDb = new TinyDB(getApplicationContext()); + String repoFullName = tinyDb.getString("repoFullName"); + String[] parts = repoFullName.split("/"); + String repoName1 = parts[1]; - call = RetrofitClient - .getInstance(instanceUrl, getApplicationContext()) - .getApiInterface() - .checkRepoWatchStatus(instanceToken, owner, repo); + final String instanceUrl = tinyDb.getString("instanceUrl"); + final String repoOwner = parts[0]; + final String loginUid = tinyDb.getString("loginUid"); + final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - call.enqueue(new Callback() { + tinyDb.putString("repoIssuesState", "open"); + tinyDb.putString("repoPrState", "open"); - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + String appLocale = tinyDb.getString("locale"); + AppUtil.setAppLocale(getResources(), appLocale); - TinyDB tinyDb = new TinyDB(getApplicationContext()); + Toolbar toolbar = findViewById(R.id.toolbar); + TextView toolbarTitle = toolbar.findViewById(R.id.toolbar_title); - if(response.code() == 200) { - assert response.body() != null; - if(response.body().getSubscribed()) { - tinyDb.putBoolean("repositoryWatchStatus", true); - } - } - else { - tinyDb.putBoolean("repositoryWatchStatus", false); - } + setSupportActionBar(toolbar); + Objects.requireNonNull(getSupportActionBar()).setTitle(repoName1); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); - } + SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - Log.e("onFailure", t.toString()); - } - }); + ViewPager mViewPager = findViewById(R.id.container); + mViewPager.setAdapter(mSectionsPagerAdapter); - } + TabLayout tabLayout = findViewById(R.id.tabs); + + Typeface myTypeface; + + switch(tinyDb.getInt("customFontId", -1)) { + + case 0: + myTypeface = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/roboto.ttf"); + break; + + case 2: + myTypeface = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/sourcecodeproregular.ttf"); + break; + + default: + myTypeface = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/manroperegular.ttf"); + break; + + } + + toolbarTitle.setTypeface(myTypeface); + toolbarTitle.setText(repoName1); + + ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0); + int tabsCount = vg.getChildCount(); + for(int j = 0; j < tabsCount; j++) { + ViewGroup vgTab = (ViewGroup) vg.getChildAt(j); + int tabChildCount = vgTab.getChildCount(); + for(int i = 0; i < tabChildCount; i++) { + View tabViewChild = vgTab.getChildAt(i); + if(tabViewChild instanceof TextView) { + ((TextView) tabViewChild).setTypeface(myTypeface); + } + } + } + + // only show Collaborators if you have permission to + final View collaboratorTab = vg.getChildAt(8); + if(tinyDb.getBoolean("isRepoAdmin")) { + collaboratorTab.setVisibility(View.VISIBLE); + } + else { + collaboratorTab.setVisibility(View.GONE); + } + + mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout)); + tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager)); + + if(tinyDb.getBoolean("enableCounterBadges")) { + + @SuppressLint("InflateParams") View tabHeader2 = LayoutInflater.from(this).inflate(R.layout.badge_issue, null); + textViewBadgeIssue = tabHeader2.findViewById(R.id.counterBadgeIssue); + + @SuppressLint("InflateParams") View tabHeader4 = LayoutInflater.from(this).inflate(R.layout.badge_pull, null); + textViewBadgePull = tabHeader4.findViewById(R.id.counterBadgePull); + + @SuppressLint("InflateParams") View tabHeader6 = LayoutInflater.from(this).inflate(R.layout.badge_release, null); + textViewBadgeRelease = tabHeader6.findViewById(R.id.counterBadgeRelease); + + textViewBadgeIssue.setVisibility(View.GONE); + textViewBadgePull.setVisibility(View.GONE); + textViewBadgeRelease.setVisibility(View.GONE); + + getRepoInfo(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1); + ColorStateList textColor = tabLayout.getTabTextColors(); + + // issue count + if(textViewBadgeIssue.getText() != "") { + TabLayout.Tab tabOpenIssues = tabLayout.getTabAt(2); + Objects.requireNonNull(tabLayout.getTabAt(2)).setCustomView(tabHeader2); + assert tabOpenIssues != null; + TextView openIssueTabView = Objects.requireNonNull(tabOpenIssues.getCustomView()).findViewById(R.id.counterBadgeIssueText); + openIssueTabView.setTextColor(textColor); + } + + // pull count + if(textViewBadgePull.getText() != "") { // only show if API returned a number + Objects.requireNonNull(tabLayout.getTabAt(3)).setCustomView(tabHeader4); + TabLayout.Tab tabOpenPulls = tabLayout.getTabAt(3); + assert tabOpenPulls != null; + TextView openPullTabView = Objects.requireNonNull(tabOpenPulls.getCustomView()).findViewById(R.id.counterBadgePullText); + openPullTabView.setTextColor(textColor); + } + + // release count + if(VersionCheck.compareVersion("1.11.5", tinyDb.getString("giteaVersion")) < 1) { + if(textViewBadgeRelease.getText() != "") { // only show if API returned a number + Objects.requireNonNull(tabLayout.getTabAt(5)).setCustomView(tabHeader6); + TabLayout.Tab tabOpenRelease = tabLayout.getTabAt(5); + assert tabOpenRelease != null; + TextView openReleaseTabView = Objects.requireNonNull(tabOpenRelease.getCustomView()).findViewById(R.id.counterBadgeReleaseText); + openReleaseTabView.setTextColor(textColor); + } + } + } + + checkRepositoryStarStatus(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1); + checkRepositoryWatchStatus(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1); + + } + + @Override + public void onResume() { + + super.onResume(); + TinyDB tinyDb = new TinyDB(getApplicationContext()); + final String instanceUrl = tinyDb.getString("instanceUrl"); + final String loginUid = tinyDb.getString("loginUid"); + String repoFullName = tinyDb.getString("repoFullName"); + String[] parts = repoFullName.split("/"); + final String repoOwner = parts[0]; + final String repoName = parts[1]; + final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + + if(tinyDb.getBoolean("enableCounterIssueBadge")) { + getRepoInfo(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName); + } + + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.repo_dotted_menu, menu); + return true; + + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + + int id = item.getItemId(); + + switch(id) { + case android.R.id.home: + finish(); + return true; + case R.id.repoMenu: + BottomSheetRepoFragment bottomSheet = new BottomSheetRepoFragment(); + bottomSheet.show(getSupportFragmentManager(), "repoBottomSheet"); + return true; + case R.id.filter: + BottomSheetIssuesFilterFragment filterBottomSheet = new BottomSheetIssuesFilterFragment(); + filterBottomSheet.show(getSupportFragmentManager(), "repoFilterMenuBottomSheet"); + return true; + case R.id.filterPr: + BottomSheetPullRequestFilterFragment filterPrBottomSheet = new BottomSheetPullRequestFilterFragment(); + filterPrBottomSheet.show(getSupportFragmentManager(), "repoFilterMenuPrBottomSheet"); + return true; + default: + return super.onOptionsItemSelected(item); + } + + } + + @Override + public void onButtonClicked(String text) { + + TinyDB tinyDb = new TinyDB(getApplicationContext()); + String repoFullName = tinyDb.getString("repoFullName"); + String instanceUrlWithProtocol = "https://" + tinyDb.getString("instanceUrlRaw"); + if(!tinyDb.getString("instanceUrlWithProtocol").isEmpty()) { + instanceUrlWithProtocol = tinyDb.getString("instanceUrlWithProtocol"); + } + Uri url = Uri.parse(instanceUrlWithProtocol + "/" + repoFullName); + + switch(text) { + case "label": + startActivity(new Intent(RepoDetailActivity.this, CreateLabelActivity.class)); + break; + case "newIssue": + startActivity(new Intent(RepoDetailActivity.this, CreateIssueActivity.class)); + break; + case "newMilestone": + startActivity(new Intent(RepoDetailActivity.this, CreateMilestoneActivity.class)); + break; + case "addCollaborator": + startActivity(new Intent(RepoDetailActivity.this, AddCollaboratorToRepositoryActivity.class)); + break; + case "createRelease": + startActivity(new Intent(RepoDetailActivity.this, CreateReleaseActivity.class)); + break; + case "openWebRepo": + Intent i = new Intent(Intent.ACTION_VIEW, url); + startActivity(i); + break; + case "shareRepo": + Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); + sharingIntent.setType("text/plain"); + sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, url); + sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, url); + startActivity(Intent.createChooser(sharingIntent, url.toString())); + break; + case "newFile": + startActivity(new Intent(RepoDetailActivity.this, CreateFileActivity.class)); + break; + case "openIssues": + if(getFragmentRefreshListener() != null) { + getFragmentRefreshListener().onRefresh("open"); + } + break; + case "closedIssues": + if(getFragmentRefreshListener() != null) { + getFragmentRefreshListener().onRefresh("closed"); + } + break; + case "openPr": + if(getFragmentRefreshListenerPr() != null) { + getFragmentRefreshListenerPr().onRefresh("open"); + } + break; + case "closedPr": + if(getFragmentRefreshListenerPr() != null) { + getFragmentRefreshListenerPr().onRefresh("closed"); + } + break; + } + + } + + public class SectionsPagerAdapter extends FragmentStatePagerAdapter { + + SectionsPagerAdapter(FragmentManager fm) { + + super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); + } + + @NonNull + @Override + public Fragment getItem(int position) { + + TinyDB tinyDb = new TinyDB(getApplicationContext()); + String repoFullName = tinyDb.getString("repoFullName"); + String[] parts = repoFullName.split("/"); + String repoOwner = parts[0]; + String repoName = parts[1]; + + Fragment fragment = null; + switch(position) { + case 0: // information + return RepoInfoFragment.newInstance(repoOwner, repoName); + case 1: // files + return FilesFragment.newInstance(repoOwner, repoName); + case 2: // issues + fragment = new IssuesFragment(); + break; + case 3: // pull requests + fragment = new PullRequestsFragment(); + break; + case 4: // branches + return BranchesFragment.newInstance(repoOwner, repoName); + case 5: // releases + return ReleasesFragment.newInstance(repoOwner, repoName); + case 6: // milestones + return MilestonesFragment.newInstance(repoOwner, repoName); + case 7: // labels + return LabelsFragment.newInstance(repoOwner, repoName); + case 8: // collaborators + return CollaboratorsFragment.newInstance(repoOwner, repoName); + } + assert fragment != null; + return fragment; + } + + @Override + public int getCount() { + + return 9; + } + + } + + private void getRepoInfo(String instanceUrl, String token, final String owner, String repo) { + + TinyDB tinyDb = new TinyDB(getApplicationContext()); + + Call call = RetrofitClient.getInstance(instanceUrl, getApplicationContext()).getApiInterface().getUserRepository(token, owner, repo); + + call.enqueue(new Callback() { + + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + + UserRepositories repoInfo = response.body(); + + if(response.isSuccessful()) { + + if(response.code() == 200) { + + if(tinyDb.getBoolean("enableCounterBadges")) { + assert repoInfo != null; + + if(repoInfo.getOpen_issues_count() != null) { + textViewBadgeIssue.setVisibility(View.VISIBLE); + textViewBadgeIssue.setText(repoInfo.getOpen_issues_count()); + } + + if(repoInfo.getOpen_pull_count() != null) { + textViewBadgePull.setVisibility(View.VISIBLE); + textViewBadgePull.setText(repoInfo.getOpen_pull_count()); + } + + if(repoInfo.getRelease_count() != null) { + textViewBadgeRelease.setVisibility(View.VISIBLE); + textViewBadgeRelease.setText(repoInfo.getRelease_count()); + } + } + + } + + } + else { + Log.e("onFailure", String.valueOf(response.code())); + } + + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + + Log.e("onFailure", t.toString()); + } + + }); + + } + + private void checkRepositoryStarStatus(String instanceUrl, String instanceToken, final String owner, String repo) { + + Call call; + + call = RetrofitClient.getInstance(instanceUrl, getApplicationContext()).getApiInterface().checkRepoStarStatus(instanceToken, owner, repo); + + call.enqueue(new Callback() { + + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + + TinyDB tinyDb = new TinyDB(getApplicationContext()); + tinyDb.putInt("repositoryStarStatus", response.code()); + + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + + Log.e("onFailure", t.toString()); + } + }); + + } + + private void checkRepositoryWatchStatus(String instanceUrl, String instanceToken, final String owner, String repo) { + + Call call; + + call = RetrofitClient.getInstance(instanceUrl, getApplicationContext()).getApiInterface().checkRepoWatchStatus(instanceToken, owner, repo); + + call.enqueue(new Callback() { + + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + + TinyDB tinyDb = new TinyDB(getApplicationContext()); + + if(response.code() == 200) { + assert response.body() != null; + if(response.body().getSubscribed()) { + tinyDb.putBoolean("repositoryWatchStatus", true); + } + } + else { + tinyDb.putBoolean("repositoryWatchStatus", false); + } + + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + + Log.e("onFailure", t.toString()); + } + }); + + } } diff --git a/app/src/main/java/org/mian/gitnex/adapters/IssuesAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/IssuesAdapter.java index 74909b77..286b15fd 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/IssuesAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/IssuesAdapter.java @@ -1,29 +1,28 @@ package org.mian.gitnex.adapters; +import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; import android.text.Html; +import android.view.LayoutInflater; import android.view.View; +import android.view.ViewGroup; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.TextView; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView; -import com.mikepenz.fastadapter.FastAdapter; -import com.mikepenz.fastadapter.items.AbstractItem; -import com.mikepenz.fastadapter.listeners.ClickEventHook; -import com.mikepenz.fastadapter.utils.EventHookUtil; import org.mian.gitnex.R; import org.mian.gitnex.activities.IssueDetailActivity; import org.mian.gitnex.clients.PicassoService; import org.mian.gitnex.helpers.ClickListener; import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.TimeHelper; +import org.mian.gitnex.models.Issues; import org.mian.gitnex.util.TinyDB; import org.ocpsoft.prettytime.PrettyTime; import java.text.DateFormat; import java.text.SimpleDateFormat; -import java.util.Date; import java.util.List; import java.util.Locale; @@ -31,112 +30,74 @@ import java.util.Locale; * Author M M Arif */ -public class IssuesAdapter extends AbstractItem { +public class IssuesAdapter extends RecyclerView.Adapter { - final private Context ctx; - private String issueTitle; - private int issueNumber; - private String issueAssigneeAvatar; - private Date issueCreatedTime; - private int issueCommentsCount; - private String userFullname; - private String userLogin; + private Context context; + private final int TYPE_LOAD = 0; + private List issuesList; + private OnLoadMoreListener loadMoreListener; + private boolean isLoading = false, isMoreDataAvailable = true; - private boolean isSelectable = true; + public IssuesAdapter(Context context, List issuesListMain) { - public IssuesAdapter(Context ctx) { - this.ctx = ctx; - } + this.context = context; + this.issuesList = issuesListMain; - public IssuesAdapter withNewItems(String issueTitle, int issueNumber, String issueAssigneeAvatar, Date issueCreatedTime, int issueCommentsCount, String userFullname, String userLogin) { - - this.setNewItems(issueTitle, issueNumber, issueAssigneeAvatar, issueCreatedTime, issueCommentsCount, userFullname, userLogin); - return this; - - } - - private void setNewItems(String issueTitle, int issueNumber, String issueAssigneeAvatar, Date issueCreatedTime, int issueCommentsCount, String userFullname, String userLogin) { - - this.issueTitle = issueTitle; - this.issueNumber = issueNumber; - this.issueAssigneeAvatar = issueAssigneeAvatar; - this.issueCreatedTime = issueCreatedTime; - this.issueCommentsCount = issueCommentsCount; - this.userFullname = userFullname; - this.userLogin = userLogin; - - } - - private int getIssueNumber() { - return issueNumber; - } - - public String getIssueTitle() { - return issueTitle; - } - - private String getIssueAssigneeAvatar() { - return issueAssigneeAvatar; - } - - private Date getIssueCreatedTime() { - return issueCreatedTime; - } - - private int getIssueCommentsCount() { - return issueCommentsCount; - } - - private String getUserFullname() { - return userFullname; - } - - private String getUserLogin() { - return userLogin; - } - - @Override - public boolean isEnabled() { - return true; - } - - @Override - public IssuesAdapter withEnabled(boolean enabled) { - return null; - } - - @Override - public boolean isSelectable() { - return isSelectable; - } - - @Override - public IssuesAdapter withSelectable(boolean selectable) { - this.isSelectable = selectable; - return this; - } - - @Override - public int getType() { - return R.id.relativeLayoutFrameIssuesList; - } - - @Override - public int getLayoutRes() { - return R.layout.list_issues; } @NonNull @Override - public IssuesAdapter.ViewHolder getViewHolder(@NonNull View v) { - return new IssuesAdapter.ViewHolder(v); + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + + LayoutInflater inflater = LayoutInflater.from(context); + + if(viewType == TYPE_LOAD) { + return new IssuesHolder(inflater.inflate(R.layout.list_issues, parent, false)); + } + else { + return new LoadHolder(inflater.inflate(R.layout.row_load, parent, false)); + } + } - public class ViewHolder extends FastAdapter.ViewHolder { + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { - final TinyDB tinyDb = new TinyDB(ctx); - final String locale = tinyDb.getString("locale"); - final String timeFormat = tinyDb.getString("dateFormat"); + if(position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) { + + isLoading = true; + loadMoreListener.onLoadMore(); + + } + + if(getItemViewType(position) == TYPE_LOAD) { + + ((IssuesHolder) holder).bindData(issuesList.get(position)); + + } + + } + + @Override + public int getItemViewType(int position) { + + if(issuesList.get(position).getTitle() != null) { + return TYPE_LOAD; + } + else { + return 1; + } + + } + + @Override + public int getItemCount() { + + return issuesList.size(); + + } + + class IssuesHolder extends RecyclerView.ViewHolder { private TextView issueNumber; private ImageView issueAssigneeAvatar; @@ -144,7 +105,7 @@ public class IssuesAdapter extends AbstractItem { + + Context context = v.getContext(); + + Intent intent = new Intent(context, IssueDetailActivity.class); + intent.putExtra("issueNumber", issueNumber.getText()); + + TinyDB tinyDb = new TinyDB(context); + tinyDb.putString("issueNumber", issueNumber.getText().toString()); + tinyDb.putString("issueType", "issue"); + context.startActivity(intent); + + }); + frameCommentsCount.setOnClickListener(v -> { + + Context context = v.getContext(); + + Intent intent = new Intent(context, IssueDetailActivity.class); + intent.putExtra("issueNumber", issueNumber.getText()); + + TinyDB tinyDb = new TinyDB(context); + tinyDb.putString("issueNumber", issueNumber.getText().toString()); + tinyDb.putString("issueType", "issue"); + context.startActivity(intent); + + }); + } - @Override - public void bindView(@NonNull IssuesAdapter item, @NonNull List payloads) { + @SuppressLint("SetTextI18n") + void bindData(Issues issuesModel) { - if (!item.getUserFullname().equals("")) { - issueAssigneeAvatar.setOnClickListener(new ClickListener(ctx.getResources().getString(R.string.issueCreator) + item.getUserFullname(), ctx)); + final TinyDB tinyDb = new TinyDB(context); + final String locale = tinyDb.getString("locale"); + final String timeFormat = tinyDb.getString("dateFormat"); + + if(!issuesModel.getUser().getFull_name().equals("")) { + issueAssigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getFull_name(), context)); } else { - issueAssigneeAvatar.setOnClickListener(new ClickListener(ctx.getResources().getString(R.string.issueCreator) + item.getUserLogin(), ctx)); + issueAssigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getLogin(), context)); } - PicassoService.getInstance(ctx).get().load(item.getIssueAssigneeAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar); + PicassoService.getInstance(context).get().load(issuesModel.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(issueAssigneeAvatar); - String issueNumber_ = "" + ctx.getResources().getString(R.string.hash) + item.getIssueNumber() + ""; - issueTitle.setText(Html.fromHtml(issueNumber_ + " " + item.getIssueTitle())); + String issueNumber_ = "" + context.getResources().getString(R.string.hash) + issuesModel.getNumber() + ""; + issueTitle.setText(Html.fromHtml(issueNumber_ + " " + issuesModel.getTitle())); - issueNumber.setText(String.valueOf(item.getIssueNumber())); - issueCommentsCount.setText(String.valueOf(item.getIssueCommentsCount())); - - switch (timeFormat) { + issueNumber.setText(String.valueOf(issuesModel.getNumber())); + issueCommentsCount.setText(String.valueOf(issuesModel.getComments())); + switch(timeFormat) { case "pretty": { PrettyTime prettyTime = new PrettyTime(new Locale(locale)); - String createdTime = prettyTime.format(item.getIssueCreatedTime()); + String createdTime = prettyTime.format(issuesModel.getCreated_at()); issueCreatedTime.setText(createdTime); - issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(item.getIssueCreatedTime()), ctx)); + issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(issuesModel.getCreated_at()), context)); break; } case "normal": { - DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + ctx.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale)); - String createdTime = formatter.format(item.getIssueCreatedTime()); + DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale)); + String createdTime = formatter.format(issuesModel.getCreated_at()); issueCreatedTime.setText(createdTime); break; } case "normal1": { - DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + ctx.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale)); - String createdTime = formatter.format(item.getIssueCreatedTime()); + DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale)); + String createdTime = formatter.format(issuesModel.getCreated_at()); issueCreatedTime.setText(createdTime); break; } - } } - @Override - public void unbindView(@NonNull IssuesAdapter item) { - - issueTitle.setText(null); - issueCommentsCount.setText(null); - issueCreatedTime.setText(null); - - } - } - public static class IssueTitleClickEvent extends ClickEventHook { + static class LoadHolder extends RecyclerView.ViewHolder { - @Nullable - @Override - public List onBindMany(@NonNull RecyclerView.ViewHolder viewHolder) { - - if (viewHolder instanceof IssuesAdapter.ViewHolder) { - return EventHookUtil.toList(((ViewHolder) viewHolder).issueTitle); - } - - return super.onBindMany(viewHolder); + LoadHolder(View itemView) { + super(itemView); } - @Override - public void onClick(View v, int position, @NonNull FastAdapter fastAdapter, IssuesAdapter item) { + } - Context context = v.getContext(); + public void setMoreDataAvailable(boolean moreDataAvailable) { - Intent intent = new Intent(context, IssueDetailActivity.class); - intent.putExtra("issueNumber", item.getIssueNumber()); + isMoreDataAvailable = moreDataAvailable; - TinyDB tinyDb = new TinyDB(context); - tinyDb.putString("issueNumber", String.valueOf(item.getIssueNumber())); - tinyDb.putString("issueType", "issue"); - context.startActivity(intent); + } - } + public void notifyDataChanged() { + notifyDataSetChanged(); + isLoading = false; + + } + + public interface OnLoadMoreListener { + + void onLoadMore(); + + } + + public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) { + + this.loadMoreListener = loadMoreListener; + + } + + public void updateList(List list) { + + issuesList = list; + notifyDataSetChanged(); } } diff --git a/app/src/main/java/org/mian/gitnex/adapters/PullRequestsAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/PullRequestsAdapter.java index d2223994..d5c8ba76 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/PullRequestsAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/PullRequestsAdapter.java @@ -7,8 +7,6 @@ import android.text.Html; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.Filter; -import android.widget.Filterable; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; @@ -22,10 +20,6 @@ import org.mian.gitnex.helpers.RoundedTransformation; import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.models.PullRequests; import org.mian.gitnex.util.TinyDB; -import org.ocpsoft.prettytime.PrettyTime; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; import java.util.List; import java.util.Locale; @@ -33,231 +27,196 @@ import java.util.Locale; * Author M M Arif */ -public class PullRequestsAdapter extends RecyclerView.Adapter implements Filterable { +public class PullRequestsAdapter extends RecyclerView.Adapter { - private Context context; - private final int TYPE_LOAD = 0; - private List prList; - private List prListFull; - private PullRequestsAdapter.OnLoadMoreListener loadMoreListener; - private boolean isLoading = false, isMoreDataAvailable = true; + private Context context; + private final int TYPE_LOAD = 0; + private List prList; + private PullRequestsAdapter.OnLoadMoreListener loadMoreListener; + private boolean isLoading = false, isMoreDataAvailable = true; - public PullRequestsAdapter(Context context, List prListMain) { + public PullRequestsAdapter(Context context, List prListMain) { - this.context = context; - this.prList = prListMain; - prListFull = new ArrayList<>(prList); + this.context = context; + this.prList = prListMain; - } + } - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - LayoutInflater inflater = LayoutInflater.from(context); + LayoutInflater inflater = LayoutInflater.from(context); - if(viewType == TYPE_LOAD){ - return new PullRequestsAdapter.PullRequestsHolder(inflater.inflate(R.layout.list_pr, parent,false)); - } - else { - return new PullRequestsAdapter.LoadHolder(inflater.inflate(R.layout.row_load,parent,false)); - } + if(viewType == TYPE_LOAD) { + return new PullRequestsAdapter.PullRequestsHolder(inflater.inflate(R.layout.list_pr, parent, false)); + } + else { + return new PullRequestsAdapter.LoadHolder(inflater.inflate(R.layout.row_load, parent, false)); + } - } + } - @Override - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { - if(position >= getItemCount()-1 && isMoreDataAvailable && !isLoading && loadMoreListener!=null) { + if(position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null) { - isLoading = true; - loadMoreListener.onLoadMore(); + isLoading = true; + loadMoreListener.onLoadMore(); - } + } - if(getItemViewType(position) == TYPE_LOAD) { + if(getItemViewType(position) == TYPE_LOAD) { - ((PullRequestsAdapter.PullRequestsHolder)holder).bindData(prList.get(position)); + ((PullRequestsAdapter.PullRequestsHolder) holder).bindData(prList.get(position)); - } + } - } + } - @Override - public int getItemViewType(int position) { + @Override + public int getItemViewType(int position) { - if(prList.get(position).getTitle() != null) { - return TYPE_LOAD; - } - else { - return 1; - } + if(prList.get(position).getTitle() != null) { + return TYPE_LOAD; + } + else { + return 1; + } - } + } - @Override - public int getItemCount() { + @Override + public int getItemCount() { - return prList.size(); + return prList.size(); - } + } - class PullRequestsHolder extends RecyclerView.ViewHolder { + class PullRequestsHolder extends RecyclerView.ViewHolder { - private TextView prNumber; - private ImageView assigneeAvatar; - private TextView prTitle; - private TextView prCreatedTime; - private TextView prCommentsCount; + private TextView prNumber; + private ImageView assigneeAvatar; + private TextView prTitle; + private TextView prCreatedTime; + private TextView prCommentsCount; - PullRequestsHolder(View itemView) { + PullRequestsHolder(View itemView) { - super(itemView); + super(itemView); - prNumber = itemView.findViewById(R.id.prNumber); - assigneeAvatar = itemView.findViewById(R.id.assigneeAvatar); - prTitle = itemView.findViewById(R.id.prTitle); - prCommentsCount = itemView.findViewById(R.id.prCommentsCount); - LinearLayout frameCommentsCount = itemView.findViewById(R.id.frameCommentsCount); - prCreatedTime = itemView.findViewById(R.id.prCreatedTime); + prNumber = itemView.findViewById(R.id.prNumber); + assigneeAvatar = itemView.findViewById(R.id.assigneeAvatar); + prTitle = itemView.findViewById(R.id.prTitle); + prCommentsCount = itemView.findViewById(R.id.prCommentsCount); + LinearLayout frameCommentsCount = itemView.findViewById(R.id.frameCommentsCount); + prCreatedTime = itemView.findViewById(R.id.prCreatedTime); - prTitle.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { + prTitle.setOnClickListener(v -> { - Context context = v.getContext(); + Context context = v.getContext(); - Intent intent = new Intent(context, IssueDetailActivity.class); - intent.putExtra("issueNumber", prNumber.getText()); + Intent intent = new Intent(context, IssueDetailActivity.class); + intent.putExtra("issueNumber", prNumber.getText()); - TinyDB tinyDb = new TinyDB(context); - tinyDb.putString("issueNumber", prNumber.getText().toString()); - tinyDb.putString("issueType", "pr"); - context.startActivity(intent); + TinyDB tinyDb = new TinyDB(context); + tinyDb.putString("issueNumber", prNumber.getText().toString()); + tinyDb.putString("issueType", "pr"); + context.startActivity(intent); - } - }); - frameCommentsCount.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { + }); + frameCommentsCount.setOnClickListener(v -> { - Context context = v.getContext(); + Context context = v.getContext(); - Intent intent = new Intent(context, IssueDetailActivity.class); - intent.putExtra("issueNumber", prNumber.getText()); + Intent intent = new Intent(context, IssueDetailActivity.class); + intent.putExtra("issueNumber", prNumber.getText()); - TinyDB tinyDb = new TinyDB(context); - tinyDb.putString("issueNumber", prNumber.getText().toString()); - tinyDb.putString("issueType", "pr"); - context.startActivity(intent); + TinyDB tinyDb = new TinyDB(context); + tinyDb.putString("issueNumber", prNumber.getText().toString()); + tinyDb.putString("issueType", "pr"); + context.startActivity(intent); - } - }); + }); - } + } - @SuppressLint("SetTextI18n") - void bindData(PullRequests prModel){ + @SuppressLint("SetTextI18n") + void bindData(PullRequests prModel) { - final TinyDB tinyDb = new TinyDB(context); - final String locale = tinyDb.getString("locale"); - final String timeFormat = tinyDb.getString("dateFormat"); + final TinyDB tinyDb = new TinyDB(context); + final String locale = tinyDb.getString("locale"); + final String timeFormat = tinyDb.getString("dateFormat"); - if (!prModel.getUser().getFull_name().equals("")) { - assigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.prCreator) + prModel.getUser().getFull_name(), context)); - } else { - assigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.prCreator) + prModel.getUser().getLogin(), context)); - } + if(!prModel.getUser().getFull_name().equals("")) { + assigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.prCreator) + prModel.getUser().getFull_name(), context)); + } + else { + assigneeAvatar.setOnClickListener(new ClickListener(context.getResources().getString(R.string.prCreator) + prModel.getUser().getLogin(), context)); + } - if (prModel.getUser().getAvatar_url() != null) { - PicassoService.getInstance(context).get().load(prModel.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(assigneeAvatar); - } else { - PicassoService.getInstance(context).get().load(prModel.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(assigneeAvatar); - } + if(prModel.getUser().getAvatar_url() != null) { + PicassoService.getInstance(context).get().load(prModel.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(assigneeAvatar); + } + else { + PicassoService.getInstance(context).get().load(prModel.getUser().getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(8, 0)).resize(120, 120).centerCrop().into(assigneeAvatar); + } - String prNumber_ = "" + context.getResources().getString(R.string.hash) + prModel.getNumber() + ""; - prTitle.setText(Html.fromHtml(prNumber_ + " " + prModel.getTitle())); + String prNumber_ = "" + context.getResources().getString(R.string.hash) + prModel.getNumber() + ""; + prTitle.setText(Html.fromHtml(prNumber_ + " " + prModel.getTitle())); - prNumber.setText(String.valueOf(prModel.getNumber())); - prCommentsCount.setText(String.valueOf(prModel.getComments())); + prNumber.setText(String.valueOf(prModel.getNumber())); + prCommentsCount.setText(String.valueOf(prModel.getComments())); - prCreatedTime.setText(TimeHelper.formatTime(prModel.getCreated_at(), new Locale(locale), timeFormat, context)); + prCreatedTime.setText(TimeHelper.formatTime(prModel.getCreated_at(), new Locale(locale), timeFormat, context)); - if(timeFormat.equals("pretty")) { - prCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(prModel.getCreated_at()), context)); - } + if(timeFormat.equals("pretty")) { + prCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(prModel.getCreated_at()), context)); + } - } + } - } + } - static class LoadHolder extends RecyclerView.ViewHolder { + static class LoadHolder extends RecyclerView.ViewHolder { - LoadHolder(View itemView) { - super(itemView); - } + LoadHolder(View itemView) { - } + super(itemView); + } - public void setMoreDataAvailable(boolean moreDataAvailable) { + } - isMoreDataAvailable = moreDataAvailable; + public void setMoreDataAvailable(boolean moreDataAvailable) { - } + isMoreDataAvailable = moreDataAvailable; - public void notifyDataChanged() { + } - notifyDataSetChanged(); - isLoading = false; + public void notifyDataChanged() { - } + notifyDataSetChanged(); + isLoading = false; - public interface OnLoadMoreListener { + } - void onLoadMore(); + public interface OnLoadMoreListener { - } + void onLoadMore(); - public void setLoadMoreListener(PullRequestsAdapter.OnLoadMoreListener loadMoreListener) { + } - this.loadMoreListener = loadMoreListener; + public void setLoadMoreListener(PullRequestsAdapter.OnLoadMoreListener loadMoreListener) { - } + this.loadMoreListener = loadMoreListener; - @Override - public Filter getFilter() { - return prFilter; - } + } - private Filter prFilter = new Filter() { - @Override - protected FilterResults performFiltering(CharSequence constraint) { - List filteredList = new ArrayList<>(); + public void updateList(List list) { - if (constraint == null || constraint.length() == 0) { - filteredList.addAll(prList); - } else { - String filterPattern = constraint.toString().toLowerCase().trim(); - - for (PullRequests item : prList) { - if (item.getTitle().toLowerCase().contains(filterPattern) || item.getBody().toLowerCase().contains(filterPattern)) { - filteredList.add(item); - } - } - } - - FilterResults results = new FilterResults(); - results.values = filteredList; - - return results; - } - - @Override - protected void publishResults(CharSequence constraint, FilterResults results) { - prList.clear(); - prList.addAll((List) results.values); - notifyDataSetChanged(); - } - }; + prList = list; + notifyDataSetChanged(); + } } diff --git a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetIssuesFilterFragment.java b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetIssuesFilterFragment.java new file mode 100644 index 00000000..bb77966f --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetIssuesFilterFragment.java @@ -0,0 +1,63 @@ +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 android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; +import org.mian.gitnex.R; + +/** + * Author M M Arif + */ + +public class BottomSheetIssuesFilterFragment extends BottomSheetDialogFragment { + + private BottomSheetIssuesFilterFragment.BottomSheetListener bmListener; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + + View v = inflater.inflate(R.layout.bottom_sheet_issues_filter, container, false); + + TextView openIssues = v.findViewById(R.id.openIssues); + TextView closedIssues = v.findViewById(R.id.closedIssues); + + openIssues.setOnClickListener(v1 -> { + bmListener.onButtonClicked("openIssues"); + dismiss(); + }); + + closedIssues.setOnClickListener(v12 -> { + bmListener.onButtonClicked("closedIssues"); + dismiss(); + }); + + return v; + } + + public interface BottomSheetListener { + + void onButtonClicked(String text); + + } + + @Override + public void onAttach(@NonNull Context context) { + + super.onAttach(context); + + try { + bmListener = (BottomSheetIssuesFilterFragment.BottomSheetListener) context; + } + catch(ClassCastException e) { + throw new ClassCastException(context.toString() + " must implement BottomSheetListener"); + } + } + +} diff --git a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetPullRequestFilterFragment.java b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetPullRequestFilterFragment.java new file mode 100644 index 00000000..982c2ffa --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetPullRequestFilterFragment.java @@ -0,0 +1,63 @@ +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 android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; +import org.mian.gitnex.R; + +/** + * Author M M Arif + */ + +public class BottomSheetPullRequestFilterFragment extends BottomSheetDialogFragment { + + private BottomSheetPullRequestFilterFragment.BottomSheetListener bmListener; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + + View v = inflater.inflate(R.layout.bottom_sheet_pull_request_filter, container, false); + + TextView openPr = v.findViewById(R.id.openPr); + TextView closedPr = v.findViewById(R.id.closedPr); + + openPr.setOnClickListener(v1 -> { + bmListener.onButtonClicked("openPr"); + dismiss(); + }); + + closedPr.setOnClickListener(v12 -> { + bmListener.onButtonClicked("closedPr"); + dismiss(); + }); + + return v; + } + + public interface BottomSheetListener { + + void onButtonClicked(String text); + + } + + @Override + public void onAttach(@NonNull Context context) { + + super.onAttach(context); + + try { + bmListener = (BottomSheetPullRequestFilterFragment.BottomSheetListener) context; + } + catch(ClassCastException e) { + throw new ClassCastException(context.toString() + " must implement BottomSheetListener"); + } + } + +} diff --git a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetSingleIssueFragment.java b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetSingleIssueFragment.java index dd8dd3ca..7daa9360 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetSingleIssueFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetSingleIssueFragment.java @@ -1,5 +1,7 @@ package org.mian.gitnex.fragments; +import android.content.ClipData; +import android.content.ClipboardManager; import android.content.Context; import android.content.Intent; import android.os.Bundle; @@ -7,6 +9,8 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.google.android.material.bottomsheet.BottomSheetDialogFragment; import org.mian.gitnex.R; import org.mian.gitnex.actions.IssueActions; @@ -17,10 +21,6 @@ import org.mian.gitnex.activities.FileDiffActivity; import org.mian.gitnex.activities.MergePullRequestActivity; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.util.TinyDB; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import android.content.ClipboardManager; -import android.content.ClipData; import java.util.Objects; /** @@ -29,213 +29,219 @@ import java.util.Objects; public class BottomSheetSingleIssueFragment extends BottomSheetDialogFragment { - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.bottom_sheet_single_issue_layout, container, false); + View v = inflater.inflate(R.layout.bottom_sheet_single_issue_layout, container, false); - final Context ctx = getContext(); - final TinyDB tinyDB = new TinyDB(ctx); + final Context ctx = getContext(); + final TinyDB tinyDB = new TinyDB(ctx); - TextView editIssue = v.findViewById(R.id.editIssue); - TextView editLabels = v.findViewById(R.id.editLabels); - TextView closeIssue = v.findViewById(R.id.closeIssue); - TextView reOpenIssue = v.findViewById(R.id.reOpenIssue); - TextView addRemoveAssignees = v.findViewById(R.id.addRemoveAssignees); - TextView copyIssueUrl = v.findViewById(R.id.copyIssueUrl); - TextView openFilesDiff = v.findViewById(R.id.openFilesDiff); - TextView mergePullRequest = v.findViewById(R.id.mergePullRequest); - TextView shareIssue = v.findViewById(R.id.shareIssue); - TextView subscribeIssue = v.findViewById(R.id.subscribeIssue); - TextView unsubscribeIssue = v.findViewById(R.id.unsubscribeIssue); + TextView editIssue = v.findViewById(R.id.editIssue); + TextView editLabels = v.findViewById(R.id.editLabels); + TextView closeIssue = v.findViewById(R.id.closeIssue); + TextView reOpenIssue = v.findViewById(R.id.reOpenIssue); + TextView addRemoveAssignees = v.findViewById(R.id.addRemoveAssignees); + TextView copyIssueUrl = v.findViewById(R.id.copyIssueUrl); + TextView openFilesDiff = v.findViewById(R.id.openFilesDiff); + TextView mergePullRequest = v.findViewById(R.id.mergePullRequest); + TextView shareIssue = v.findViewById(R.id.shareIssue); + TextView subscribeIssue = v.findViewById(R.id.subscribeIssue); + TextView unsubscribeIssue = v.findViewById(R.id.unsubscribeIssue); - if(tinyDB.getString("issueType").equals("pr")) { + if(tinyDB.getString("issueType").equals("pr")) { - editIssue.setText(R.string.editPrText); - copyIssueUrl.setText(R.string.copyPrUrlText); - shareIssue.setText(R.string.sharePr); + editIssue.setText(R.string.editPrText); + copyIssueUrl.setText(R.string.copyPrUrlText); + shareIssue.setText(R.string.sharePr); - if(tinyDB.getBoolean("prMerged")) { - mergePullRequest.setVisibility(View.GONE); - } - else { - mergePullRequest.setVisibility(View.VISIBLE); - } + if(tinyDB.getBoolean("prMerged") || tinyDB.getString("repoPrState").equals("closed")) { + mergePullRequest.setVisibility(View.GONE); + } + else { + mergePullRequest.setVisibility(View.VISIBLE); + } - if(tinyDB.getString("repoType").equals("public")) { - openFilesDiff.setVisibility(View.VISIBLE); - } - else { - openFilesDiff.setVisibility(View.GONE); - } + if(tinyDB.getString("repoType").equals("public")) { + openFilesDiff.setVisibility(View.VISIBLE); + } + else { + openFilesDiff.setVisibility(View.GONE); + } - } - else { + } + else { - mergePullRequest.setVisibility(View.GONE); + mergePullRequest.setVisibility(View.GONE); - } + } - mergePullRequest.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { + mergePullRequest.setOnClickListener(new View.OnClickListener() { - startActivity(new Intent(ctx, MergePullRequestActivity.class)); - dismiss(); + @Override + public void onClick(View v) { - } - }); + startActivity(new Intent(ctx, MergePullRequestActivity.class)); + dismiss(); - openFilesDiff.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { + } + }); - startActivity(new Intent(ctx, FileDiffActivity.class)); - dismiss(); + openFilesDiff.setOnClickListener(new View.OnClickListener() { - } - }); + @Override + public void onClick(View v) { - editIssue.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { + startActivity(new Intent(ctx, FileDiffActivity.class)); + dismiss(); - startActivity(new Intent(ctx, EditIssueActivity.class)); - dismiss(); + } + }); - } - }); + editIssue.setOnClickListener(new View.OnClickListener() { - editLabels.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { + @Override + public void onClick(View v) { - startActivity(new Intent(ctx, AddRemoveLabelsActivity.class)); - dismiss(); + startActivity(new Intent(ctx, EditIssueActivity.class)); + dismiss(); - } - }); + } + }); - addRemoveAssignees.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { + editLabels.setOnClickListener(new View.OnClickListener() { - startActivity(new Intent(ctx, AddRemoveAssigneesActivity.class)); - dismiss(); + @Override + public void onClick(View v) { - } - }); + startActivity(new Intent(ctx, AddRemoveLabelsActivity.class)); + dismiss(); - shareIssue.setOnClickListener(v1 -> { + } + }); - // get url of repo - String repoFullName = tinyDB.getString("repoFullName"); - String instanceUrlWithProtocol = "https://" + tinyDB.getString("instanceUrlRaw"); - if (!tinyDB.getString("instanceUrlWithProtocol").isEmpty()) { - instanceUrlWithProtocol = tinyDB.getString("instanceUrlWithProtocol"); - } + addRemoveAssignees.setOnClickListener(new View.OnClickListener() { - // get issue Url - String issueUrl = instanceUrlWithProtocol + "/" + repoFullName + "/issues/" + tinyDB.getString("issueNumber"); + @Override + public void onClick(View v) { - // share issue - Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); - sharingIntent.setType("text/plain"); - sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, getResources().getString(R.string.hash) + tinyDB.getString("issueNumber") + " " + tinyDB.getString("issueTitle")); - sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, issueUrl); - startActivity(Intent.createChooser(sharingIntent, getResources().getString(R.string.hash) + tinyDB.getString("issueNumber") + " " + tinyDB.getString("issueTitle"))); + startActivity(new Intent(ctx, AddRemoveAssigneesActivity.class)); + dismiss(); - dismiss(); + } + }); - }); + shareIssue.setOnClickListener(v1 -> { - copyIssueUrl.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { + // get url of repo + String repoFullName = tinyDB.getString("repoFullName"); + String instanceUrlWithProtocol = "https://" + tinyDB.getString("instanceUrlRaw"); + if(!tinyDB.getString("instanceUrlWithProtocol").isEmpty()) { + instanceUrlWithProtocol = tinyDB.getString("instanceUrlWithProtocol"); + } - // get url of repo - String repoFullName = tinyDB.getString("repoFullName"); - String instanceUrlWithProtocol = "https://" + tinyDB.getString("instanceUrlRaw"); - if (!tinyDB.getString("instanceUrlWithProtocol").isEmpty()) { - instanceUrlWithProtocol = tinyDB.getString("instanceUrlWithProtocol"); - } + // get issue Url + String issueUrl = instanceUrlWithProtocol + "/" + repoFullName + "/issues/" + tinyDB.getString("issueNumber"); - // get issue Url - String issueUrl = instanceUrlWithProtocol + "/" + repoFullName + "/issues/" + tinyDB.getString("issueNumber"); + // share issue + Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); + sharingIntent.setType("text/plain"); + sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, getResources().getString(R.string.hash) + tinyDB.getString("issueNumber") + " " + tinyDB.getString("issueTitle")); + sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, issueUrl); + startActivity(Intent.createChooser(sharingIntent, getResources().getString(R.string.hash) + tinyDB.getString("issueNumber") + " " + tinyDB.getString("issueTitle"))); - // copy to clipboard - ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(ctx).getSystemService(android.content.Context.CLIPBOARD_SERVICE); - ClipData clip = ClipData.newPlainText("issueUrl", issueUrl); - assert clipboard != null; - clipboard.setPrimaryClip(clip); + dismiss(); - dismiss(); + }); - Toasty.info(ctx, ctx.getString(R.string.copyIssueUrlToastMsg)); + copyIssueUrl.setOnClickListener(new View.OnClickListener() { - } - }); + @Override + public void onClick(View v) { - if(tinyDB.getString("issueType").equals("issue")) { + // get url of repo + String repoFullName = tinyDB.getString("repoFullName"); + String instanceUrlWithProtocol = "https://" + tinyDB.getString("instanceUrlRaw"); + if(!tinyDB.getString("instanceUrlWithProtocol").isEmpty()) { + instanceUrlWithProtocol = tinyDB.getString("instanceUrlWithProtocol"); + } - if (tinyDB.getString("issueState").equals("open")) { // close issue + // get issue Url + String issueUrl = instanceUrlWithProtocol + "/" + repoFullName + "/issues/" + tinyDB.getString("issueNumber"); - reOpenIssue.setVisibility(View.GONE); - closeIssue.setVisibility(View.VISIBLE); + // copy to clipboard + ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(ctx).getSystemService(android.content.Context.CLIPBOARD_SERVICE); + ClipData clip = ClipData.newPlainText("issueUrl", issueUrl); + assert clipboard != null; + clipboard.setPrimaryClip(clip); - closeIssue.setOnClickListener(closeSingleIssue -> { + dismiss(); - IssueActions.closeReopenIssue(ctx, Integer.parseInt(tinyDB.getString("issueNumber")), "closed"); - dismiss(); + Toasty.info(ctx, ctx.getString(R.string.copyIssueUrlToastMsg)); - }); + } + }); - } - else if (tinyDB.getString("issueState").equals("closed")) { + if(tinyDB.getString("issueType").equals("issue")) { - closeIssue.setVisibility(View.GONE); - reOpenIssue.setVisibility(View.VISIBLE); + if(tinyDB.getString("issueState").equals("open")) { // close issue - reOpenIssue.setOnClickListener(reOpenSingleIssue -> { + reOpenIssue.setVisibility(View.GONE); + closeIssue.setVisibility(View.VISIBLE); - IssueActions.closeReopenIssue(ctx, Integer.parseInt(tinyDB.getString("issueNumber")), "open"); - dismiss(); + closeIssue.setOnClickListener(closeSingleIssue -> { - }); + IssueActions.closeReopenIssue(ctx, Integer.parseInt(tinyDB.getString("issueNumber")), "closed"); + dismiss(); - } + }); - } - else { + } + else if(tinyDB.getString("issueState").equals("closed")) { - reOpenIssue.setVisibility(View.GONE); - closeIssue.setVisibility(View.GONE); + closeIssue.setVisibility(View.GONE); + reOpenIssue.setVisibility(View.VISIBLE); - } + reOpenIssue.setOnClickListener(reOpenSingleIssue -> { - subscribeIssue.setOnClickListener(subscribeToIssue -> { + IssueActions.closeReopenIssue(ctx, Integer.parseInt(tinyDB.getString("issueNumber")), "open"); + dismiss(); - IssueActions.subscribe(ctx, subscribeIssue, unsubscribeIssue); - //dismiss(); + }); - }); + } - unsubscribeIssue.setOnClickListener(unsubscribeToIssue -> { + } + else { - IssueActions.unsubscribe(ctx, subscribeIssue, unsubscribeIssue); - //dismiss(); + reOpenIssue.setVisibility(View.GONE); + closeIssue.setVisibility(View.GONE); - }); + } - //if RepoWatch True Provide Unsubscribe first - // ToDo: API to check if user is subscribed to an issue (do not exist can be guessed by many api endpoints :/) - if (tinyDB.getBoolean("repoWatch")) { - subscribeIssue.setVisibility(View.GONE); - unsubscribeIssue.setVisibility(View.VISIBLE); - } + subscribeIssue.setOnClickListener(subscribeToIssue -> { - return v; - } + IssueActions.subscribe(ctx, subscribeIssue, unsubscribeIssue); + //dismiss(); + + }); + + unsubscribeIssue.setOnClickListener(unsubscribeToIssue -> { + + IssueActions.unsubscribe(ctx, subscribeIssue, unsubscribeIssue); + //dismiss(); + + }); + + //if RepoWatch True Provide Unsubscribe first + // ToDo: API to check if user is subscribed to an issue (do not exist can be guessed by many api endpoints :/) + if(tinyDB.getBoolean("repoWatch")) { + subscribeIssue.setVisibility(View.GONE); + unsubscribeIssue.setVisibility(View.VISIBLE); + } + + return v; + } } 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 458e4978..a7474ed9 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/FilesFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/FilesFragment.java @@ -4,14 +4,6 @@ import android.annotation.SuppressLint; import android.content.Intent; import android.net.Uri; import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.lifecycle.Observer; -import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.DividerItemDecoration; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -22,12 +14,19 @@ import android.view.inputmethod.EditorInfo; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.Observer; +import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.DividerItemDecoration; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; 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; @@ -44,268 +43,275 @@ import moe.feng.common.view.breadcrumbs.model.BreadcrumbItem; 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 BreadcrumbsView mBreadcrumbsView; + 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 BreadcrumbsView mBreadcrumbsView; - private String repoName; - private String repoOwner; + private String repoName; + private String repoOwner; - private OnFragmentInteractionListener mListener; + private OnFragmentInteractionListener mListener; - public FilesFragment() { - } + public FilesFragment() { - public static FilesFragment newInstance(String param1, String param2) { - FilesFragment fragment = new FilesFragment(); - Bundle args = new Bundle(); - args.putString(repoOwnerF, param1); - args.putString(repoNameF, param2); - fragment.setArguments(args); - return fragment; - } + } - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - if (getArguments() != null) { - repoName = getArguments().getString(repoNameF); - repoOwner = getArguments().getString(repoOwnerF); - } - } + public static FilesFragment newInstance(String param1, String param2) { - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { + FilesFragment fragment = new FilesFragment(); + Bundle args = new Bundle(); + args.putString(repoOwnerF, param1); + args.putString(repoNameF, param2); + fragment.setArguments(args); + return fragment; + } - View v = inflater.inflate(R.layout.fragment_files, container, false); - setHasOptionsMenu(true); + @Override + public void onCreate(Bundle savedInstanceState) { - 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"); + super.onCreate(savedInstanceState); + if(getArguments() != null) { + repoName = getArguments().getString(repoNameF); + repoOwner = getArguments().getString(repoOwnerF); + } + } - noDataFiles = v.findViewById(R.id.noDataFiles); - filesFrame = v.findViewById(R.id.filesFrame); + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - fileStructure = v.findViewById(R.id.fileStructure); - mRecyclerView = v.findViewById(R.id.recyclerView); - mRecyclerView.setHasFixedSize(true); - mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + View v = inflater.inflate(R.layout.fragment_files, container, false); + setHasOptionsMenu(true); - DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), - DividerItemDecoration.VERTICAL); - mRecyclerView.addItemDecoration(dividerItemDecoration); + 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"); - mProgressBar = v.findViewById(R.id.progress_bar); + noDataFiles = v.findViewById(R.id.noDataFiles); + filesFrame = v.findViewById(R.id.filesFrame); - mBreadcrumbsView = v.findViewById(R.id.breadcrumbs_view); - mBreadcrumbsView.setItems(new ArrayList<>(Arrays.asList( - BreadcrumbItem.createSimpleItem(getResources().getString(R.string.filesBreadcrumbRoot)) - ))); + fileStructure = v.findViewById(R.id.fileStructure); + mRecyclerView = v.findViewById(R.id.recyclerView); + mRecyclerView.setHasFixedSize(true); + mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); - fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName); + DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL); + mRecyclerView.addItemDecoration(dividerItemDecoration); - return v; - } + mProgressBar = v.findViewById(R.id.progress_bar); - @Override - public void onResume() { - super.onResume(); - } + mBreadcrumbsView = v.findViewById(R.id.breadcrumbs_view); + mBreadcrumbsView.setItems(new ArrayList<>(Arrays.asList(BreadcrumbItem.createSimpleItem(getResources().getString(R.string.filesBreadcrumbRoot))))); - private static BreadcrumbItem createItem(String title) { - List list = new ArrayList<>(); - list.add(title); - return new BreadcrumbItem(list); - } + fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName); - @Override - public void onClickDir(String dirName) { + return v; + } - 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"); + @Override + public void onResume() { - StringBuilder breadcrumbBuilder = new StringBuilder(); + super.onResume(); + } - breadcrumbBuilder.append(fileStructure.getText().toString()).append("/").append(dirName); + private static BreadcrumbItem createItem(String title) { - fileStructure.setText(breadcrumbBuilder); + List list = new ArrayList<>(); + list.add(title); + return new BreadcrumbItem(list); + } - String dirName_ = fileStructure.getText().toString(); - dirName_ = dirName_.startsWith("/") ? dirName_.substring(1) : dirName_; - final String finalDirName_ = dirName_; + @Override + public void onClickDir(String dirName) { - mBreadcrumbsView.addItem(createItem(dirName)); - //noinspection unchecked - mBreadcrumbsView.setCallback(new DefaultBreadcrumbsCallback() { - @SuppressLint("SetTextI18n") - @Override - public void onNavigateBack(BreadcrumbItem item, int position) { + 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"); - if(position == 0) { - fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName); - fileStructure.setText(""); - return; - } + StringBuilder breadcrumbBuilder = new StringBuilder(); - String filterDir = fileStructure.getText().toString(); - String result = filterDir.substring(0, filterDir.indexOf(item.getSelectedItem())); - fileStructure.setText(result + item.getSelectedItem()); + breadcrumbBuilder.append(fileStructure.getText().toString()).append("/").append(dirName); - String currentIndex = (result + item.getSelectedItem()).substring(1); + fileStructure.setText(breadcrumbBuilder); - fetchDataAsyncSub(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, currentIndex); + String dirName_ = fileStructure.getText().toString(); + dirName_ = dirName_.startsWith("/") ? dirName_.substring(1) : dirName_; + final String finalDirName_ = dirName_; - } + mBreadcrumbsView.addItem(createItem(dirName)); + //noinspection unchecked + mBreadcrumbsView.setCallback(new DefaultBreadcrumbsCallback() { - @Override - public void onNavigateNewLocation(BreadcrumbItem newItem, int changedPosition) { + @SuppressLint("SetTextI18n") + @Override + public void onNavigateBack(BreadcrumbItem item, int position) { - } - }); + if(position == 0) { + fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName); + fileStructure.setText(""); + return; + } - fetchDataAsyncSub(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, finalDirName_); + 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); - @Override - public void onClickFile(String fileName) { + fetchDataAsyncSub(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, currentIndex); - Intent intent = new Intent(getContext(), FileViewActivity.class); + } - if(!fileStructure.getText().toString().equals("Root")) { + @Override + public void onNavigateNewLocation(BreadcrumbItem newItem, int changedPosition) { - intent.putExtra("singleFileName", fileStructure.getText().toString()+"/"+fileName); - } - else { + } + }); - intent.putExtra("singleFileName", fileName); - } + fetchDataAsyncSub(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, finalDirName_); - Objects.requireNonNull(getContext()).startActivity(intent); - } + } - private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) { + @Override + public void onClickFile(String fileName) { - mRecyclerView.setVisibility(View.GONE); - mProgressBar.setVisibility(View.VISIBLE); + Intent intent = new Intent(getContext(), FileViewActivity.class); - FilesViewModel filesModel = new ViewModelProvider(this).get(FilesViewModel.class); + if(!fileStructure.getText().toString().equals("Root")) { - filesModel.getFilesList(instanceUrl, instanceToken, owner, repo, getContext()).observe(getViewLifecycleOwner(), new Observer>() { - @Override - public void onChanged(@Nullable List filesListMain) { - adapter = new FilesAdapter(getContext(), filesListMain, FilesFragment.this); + intent.putExtra("singleFileName", fileStructure.getText().toString() + "/" + fileName); + } + else { - 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); - noDataFiles.setVisibility(View.VISIBLE); - } - filesFrame.setVisibility(View.VISIBLE); - mProgressBar.setVisibility(View.GONE); - } - }); + intent.putExtra("singleFileName", fileName); + } - } + Objects.requireNonNull(getContext()).startActivity(intent); + } - private void fetchDataAsyncSub(String instanceUrl, String instanceToken, String owner, String repo, String filesDir) { + private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) { - mRecyclerView.setVisibility(View.GONE); - mProgressBar.setVisibility(View.VISIBLE); + mRecyclerView.setVisibility(View.GONE); + mProgressBar.setVisibility(View.VISIBLE); - FilesViewModel filesModel2 = new ViewModelProvider(this).get(FilesViewModel.class); + FilesViewModel filesModel = new ViewModelProvider(this).get(FilesViewModel.class); - filesModel2.getFilesList2(instanceUrl, instanceToken, owner, repo, filesDir, getContext()).observe(this, new Observer>() { - @Override - public void onChanged(@Nullable List 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); - noDataFiles.setVisibility(View.VISIBLE); - } - filesFrame.setVisibility(View.VISIBLE); - mProgressBar.setVisibility(View.GONE); - } - }); + filesModel.getFilesList(instanceUrl, instanceToken, owner, repo, getContext()).observe(getViewLifecycleOwner(), new Observer>() { - } + @Override + public void onChanged(@Nullable List filesListMain) { - @Override - public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + adapter = new FilesAdapter(getContext(), filesListMain, FilesFragment.this); - boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext())); + 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); + noDataFiles.setVisibility(View.VISIBLE); + } + filesFrame.setVisibility(View.VISIBLE); + mProgressBar.setVisibility(View.GONE); + } + }); - inflater.inflate(R.menu.search_menu, menu); - super.onCreateOptionsMenu(menu, inflater); + } - MenuItem searchItem = menu.findItem(R.id.action_search); - androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView(); - searchView.setImeOptions(EditorInfo.IME_ACTION_DONE); - //searchView.setQueryHint(getContext().getString(R.string.search)); + private void fetchDataAsyncSub(String instanceUrl, String instanceToken, String owner, String repo, String filesDir) { - /*if(!connToInternet) { - return; - }*/ + mRecyclerView.setVisibility(View.GONE); + mProgressBar.setVisibility(View.VISIBLE); - searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() { - @Override - public boolean onQueryTextSubmit(String query) { - return false; - } + FilesViewModel filesModel2 = new ViewModelProvider(this).get(FilesViewModel.class); - @Override - public boolean onQueryTextChange(String newText) { - if(mRecyclerView.getAdapter() != null) { - adapter.getFilter().filter(newText); - } - return false; - } - }); + filesModel2.getFilesList2(instanceUrl, instanceToken, owner, repo, filesDir, getContext()).observe(this, new Observer>() { - } + @Override + public void onChanged(@Nullable List filesListMain2) { - public void onButtonPressed(Uri uri) { - if (mListener != null) { - mListener.onFragmentInteraction(uri); - } - } + 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); + noDataFiles.setVisibility(View.VISIBLE); + } + filesFrame.setVisibility(View.VISIBLE); + mProgressBar.setVisibility(View.GONE); + } + }); - @Override - public void onDetach() { - super.onDetach(); - mListener = null; - } + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + + inflater.inflate(R.menu.search_menu, menu); + super.onCreateOptionsMenu(menu, inflater); + + MenuItem searchItem = menu.findItem(R.id.action_search); + androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView(); + searchView.setImeOptions(EditorInfo.IME_ACTION_DONE); + + searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() { + + @Override + public boolean onQueryTextSubmit(String query) { + + return false; + } + + @Override + public boolean onQueryTextChange(String newText) { + + if(mRecyclerView.getAdapter() != null) { + adapter.getFilter().filter(newText); + } + return false; + } + }); + + } + + public void onButtonPressed(Uri uri) { + + if(mListener != null) { + mListener.onFragmentInteraction(uri); + } + } + + @Override + public void onDetach() { + + super.onDetach(); + mListener = null; + } + + public interface OnFragmentInteractionListener { + + void onFragmentInteraction(Uri uri); + + } - public interface OnFragmentInteractionListener { - void onFragmentInteraction(Uri uri); - } } diff --git a/app/src/main/java/org/mian/gitnex/fragments/IssuesClosedFragment.java b/app/src/main/java/org/mian/gitnex/fragments/IssuesClosedFragment.java deleted file mode 100644 index 9cdbff68..00000000 --- a/app/src/main/java/org/mian/gitnex/fragments/IssuesClosedFragment.java +++ /dev/null @@ -1,311 +0,0 @@ -package org.mian.gitnex.fragments; - -import android.content.Context; -import android.os.Bundle; -import android.os.Handler; -import android.util.Log; -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 android.widget.ProgressBar; -import android.widget.TextView; -import org.mian.gitnex.R; -import org.mian.gitnex.clients.RetrofitClient; -import org.mian.gitnex.helpers.StaticGlobalVariables; -import org.mian.gitnex.helpers.VersionCheck; -import org.mian.gitnex.adapters.IssuesAdapter; -import org.mian.gitnex.models.Issues; -import org.mian.gitnex.util.TinyDB; -import java.util.ArrayList; -import java.util.List; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.recyclerview.widget.DefaultItemAnimator; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; -import com.mikepenz.fastadapter.IItemAdapter; -import com.mikepenz.fastadapter.adapters.ItemAdapter; -import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter; -import com.mikepenz.fastadapter.listeners.ItemFilterListener; -import com.mikepenz.fastadapter_extensions.items.ProgressItem; -import com.mikepenz.fastadapter_extensions.scroll.EndlessRecyclerOnScrollListener; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import static com.mikepenz.fastadapter.adapters.ItemAdapter.items; - -/** - * Author M M Arif - */ - -public class IssuesClosedFragment extends Fragment implements ItemFilterListener { - - private Context ctx; - private ProgressBar mProgressBarClosed; - private boolean loadNextFlag = false; - private String TAG = StaticGlobalVariables.tagIssuesListClosed; - private TextView noDataIssuesClosed; - private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances; - private String requestType = StaticGlobalVariables.issuesRequestType; - private String issueState = StaticGlobalVariables.issueStateClosed; - - private List items = new ArrayList<>(); - private FastItemAdapter fastItemAdapter; - private ItemAdapter footerAdapter; - private EndlessRecyclerOnScrollListener endlessRecyclerOnScrollListener; - - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - - final View v = inflater.inflate(R.layout.fragment_issues_closed, container, false); - setHasOptionsMenu(true); - - 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"); - String repoFullName = tinyDb.getString("repoFullName"); - String[] parts = repoFullName.split("/"); - final String repoOwner = parts[0]; - final String repoName = parts[1]; - - if (VersionCheck.compareVersion("1.12.0", tinyDb.getString("giteaVersion")) < 1) { - resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances; - } - - noDataIssuesClosed = v.findViewById(R.id.noDataIssuesClosed); - mProgressBarClosed = v.findViewById(R.id.progress_barClosed); - final SwipeRefreshLayout swipeRefreshLayout = v.findViewById(R.id.pullToRefreshClosed); - - RecyclerView recyclerView = v.findViewById(R.id.recyclerViewClosed); - recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); - recyclerView.setHasFixedSize(true); - - fastItemAdapter = new FastItemAdapter<>(); - fastItemAdapter.withSelectable(true); - - footerAdapter = items(); - //noinspection unchecked - fastItemAdapter.addAdapter(StaticGlobalVariables.issuesPageInit, footerAdapter); - - fastItemAdapter.getItemFilter().withFilterPredicate((IItemAdapter.Predicate) (item, constraint) -> item.getIssueTitle().toLowerCase().contains(constraint.toString().toLowerCase())); - - fastItemAdapter.getItemFilter().withItemFilterListener(this); - - recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); - recyclerView.setItemAnimator(new DefaultItemAnimator()); - recyclerView.setAdapter(fastItemAdapter); - - endlessRecyclerOnScrollListener = new EndlessRecyclerOnScrollListener(footerAdapter) { - - @Override - public void onLoadMore(final int currentPage) { - - loadNext(instanceUrl, instanceToken, repoOwner, repoName, resultLimit, issueState, requestType, currentPage); - - } - - }; - - swipeRefreshLayout.setOnRefreshListener(() -> { - - mProgressBarClosed.setVisibility(View.VISIBLE); - fastItemAdapter.clear(); - endlessRecyclerOnScrollListener.resetPageCount(); - swipeRefreshLayout.setRefreshing(false); - - }); - - recyclerView.addOnScrollListener(endlessRecyclerOnScrollListener); - - loadInitial(instanceUrl, instanceToken, repoOwner, repoName, issueState, resultLimit, requestType); - - fastItemAdapter.withEventHook(new IssuesAdapter.IssueTitleClickEvent()); - - assert savedInstanceState != null; - fastItemAdapter.withSavedInstanceState(savedInstanceState); - - return v; - - } - - @Override - public void onResume() { - - super.onResume(); - TinyDB tinyDb = new TinyDB(getContext()); - - if(tinyDb.getBoolean("resumeClosedIssues")) { - - mProgressBarClosed.setVisibility(View.VISIBLE); - fastItemAdapter.clear(); - endlessRecyclerOnScrollListener.resetPageCount(); - tinyDb.putBoolean("resumeClosedIssues", false); - - } - - } - - private void loadInitial(String instanceUrl, String token, String repoOwner, String repoName, String issueState, int resultLimit, String requestType) { - - Call> call = RetrofitClient.getInstance(instanceUrl, getContext()).getApiInterface().getClosedIssues(token, repoOwner, repoName, 1, issueState, resultLimit, requestType); - - call.enqueue(new Callback>() { - - @Override - public void onResponse(@NonNull Call> call, @NonNull Response> response) { - - if(response.isSuccessful()) { - - assert response.body() != null; - if(response.body().size() > 0) { - - if(response.body().size() == resultLimit) { - loadNextFlag = true; - } - - for(int i = 0; i < response.body().size(); i++) { - items.add(new IssuesAdapter(getContext()).withNewItems(response.body().get(i).getTitle(), response.body().get(i).getNumber(), response.body().get(i).getUser().getAvatar_url(), response.body().get(i).getCreated_at(), response.body().get(i).getComments(), response.body().get(i).getUser().getFull_name(), response.body().get(i).getUser().getLogin())); - } - - fastItemAdapter.add(items); - noDataIssuesClosed.setVisibility(View.GONE); - - } - else { - noDataIssuesClosed.setVisibility(View.VISIBLE); - } - - mProgressBarClosed.setVisibility(View.GONE); - - } - else { - Log.i(TAG, String.valueOf(response.code())); - } - - } - - @Override - public void onFailure(@NonNull Call> call, @NonNull Throwable t) { - - Log.e(TAG, t.toString()); - } - - }); - - } - - private void loadNext(String instanceUrl, String token, String repoOwner, String repoName, int resultLimit, String issueState, String requestType, final int currentPage) { - - footerAdapter.clear(); - //noinspection unchecked - footerAdapter.add(new ProgressItem().withEnabled(false)); - Handler handler = new Handler(); - - handler.postDelayed(() -> { - - Call> call = RetrofitClient.getInstance(instanceUrl, getContext()).getApiInterface().getClosedIssues(token, repoOwner, repoName, currentPage + 1, issueState, resultLimit, requestType); - - call.enqueue(new Callback>() { - - @Override - public void onResponse(@NonNull Call> call, @NonNull Response> response) { - - if(response.isSuccessful()) { - - assert response.body() != null; - - if(response.body().size() > 0) { - - loadNextFlag = response.body().size() == resultLimit; - - for(int i = 0; i < response.body().size(); i++) { - - fastItemAdapter.add(fastItemAdapter.getAdapterItemCount(), new IssuesAdapter(getContext()).withNewItems(response.body().get(i).getTitle(), response.body().get(i).getNumber(), response.body().get(i).getUser().getAvatar_url(), response.body().get(i).getCreated_at(), response.body().get(i).getComments(), response.body().get(i).getUser().getFull_name(), response.body().get(i).getUser().getLogin())); - - } - - footerAdapter.clear(); - mProgressBarClosed.setVisibility(View.GONE); - - } - else { - footerAdapter.clear(); - } - - mProgressBarClosed.setVisibility(View.GONE); - - } - else { - Log.i(TAG, String.valueOf(response.code())); - } - - } - - @Override - public void onFailure(@NonNull Call> call, @NonNull Throwable t) { - - Log.i(TAG, t.toString()); - } - - }); - - }, 1000); - - if(!loadNextFlag) { - footerAdapter.clear(); - } - - } - - @Override - public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - - inflater.inflate(R.menu.search_menu, menu); - super.onCreateOptionsMenu(menu, inflater); - - MenuItem searchItem = menu.findItem(R.id.action_search); - androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView(); - searchView.setImeOptions(EditorInfo.IME_ACTION_DONE); - - searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() { - - @Override - public boolean onQueryTextSubmit(String query) { - - return false; - } - - @Override - public boolean onQueryTextChange(String newText) { - - fastItemAdapter.filter(newText); - return true; - } - - }); - - endlessRecyclerOnScrollListener.enable(); - - } - - @Override - public void itemsFiltered(@Nullable CharSequence constraint, @Nullable List results) { - - endlessRecyclerOnScrollListener.disable(); - } - - @Override - public void onReset() { - - endlessRecyclerOnScrollListener.enable(); - } - -} diff --git a/app/src/main/java/org/mian/gitnex/fragments/IssuesFragment.java b/app/src/main/java/org/mian/gitnex/fragments/IssuesFragment.java new file mode 100644 index 00000000..091408b2 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/fragments/IssuesFragment.java @@ -0,0 +1,312 @@ +package org.mian.gitnex.fragments; + +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; +import android.util.Log; +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 android.widget.ProgressBar; +import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; +import org.mian.gitnex.R; +import org.mian.gitnex.activities.RepoDetailActivity; +import org.mian.gitnex.adapters.IssuesAdapter; +import org.mian.gitnex.clients.IssuesService; +import org.mian.gitnex.helpers.Authorization; +import org.mian.gitnex.helpers.StaticGlobalVariables; +import org.mian.gitnex.helpers.Toasty; +import org.mian.gitnex.helpers.VersionCheck; +import org.mian.gitnex.interfaces.ApiInterface; +import org.mian.gitnex.models.Issues; +import org.mian.gitnex.util.TinyDB; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +/** + * Author M M Arif + */ + +public class IssuesFragment extends Fragment { + + private Menu menu; + private RecyclerView recyclerView; + private List issuesList; + private IssuesAdapter adapter; + private ApiInterface api; + private Context context; + private int pageSize = StaticGlobalVariables.issuesPageInit; + private ProgressBar mProgressBar; + private String TAG = StaticGlobalVariables.tagIssuesList; + private TextView noDataIssues; + private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances; + private String requestType = StaticGlobalVariables.issuesRequestType; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + + final View v = inflater.inflate(R.layout.fragment_issues, container, false); + setHasOptionsMenu(true); + context = getContext(); + + TinyDB tinyDb = new TinyDB(getContext()); + String repoFullName = tinyDb.getString("repoFullName"); + String[] parts = repoFullName.split("/"); + final String repoOwner = parts[0]; + final String repoName = parts[1]; + final String instanceUrl = tinyDb.getString("instanceUrl"); + final String loginUid = tinyDb.getString("loginUid"); + final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + + final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh); + + // if gitea is 1.12 or higher use the new limit + if(VersionCheck.compareVersion("1.12.0", tinyDb.getString("giteaVersion")) < 1) { + resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances; + } + + recyclerView = v.findViewById(R.id.recyclerView); + issuesList = new ArrayList<>(); + + mProgressBar = v.findViewById(R.id.progress_bar); + noDataIssues = v.findViewById(R.id.noDataIssues); + + swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> { + + swipeRefresh.setRefreshing(false); + loadInitial(instanceToken, repoOwner, repoName, resultLimit, requestType, tinyDb.getString("repoIssuesState")); + adapter.notifyDataChanged(); + + }, 200)); + + adapter = new IssuesAdapter(getContext(), issuesList); + adapter.setLoadMoreListener(() -> recyclerView.post(() -> { + + if(issuesList.size() == resultLimit || pageSize == resultLimit) { + + int page = (issuesList.size() + resultLimit) / resultLimit; + loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, resultLimit, requestType, tinyDb.getString("repoIssuesState")); + + } + + })); + + recyclerView.setHasFixedSize(true); + recyclerView.setLayoutManager(new LinearLayoutManager(context)); + recyclerView.setAdapter(adapter); + + ((RepoDetailActivity) Objects.requireNonNull(getActivity())).setFragmentRefreshListener(issueState -> { + + if(issueState.equals("closed")) { + menu.getItem(1).setIcon(R.drawable.ic_filter_closed); + } + else { + menu.getItem(1).setIcon(R.drawable.ic_filter); + } + + issuesList.clear(); + adapter = new IssuesAdapter(getContext(), issuesList); + tinyDb.putString("repoIssuesState", issueState); + mProgressBar.setVisibility(View.VISIBLE); + noDataIssues.setVisibility(View.GONE); + loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, resultLimit, requestType, issueState); + recyclerView.setAdapter(adapter); + + }); + + api = IssuesService.createService(ApiInterface.class, instanceUrl, getContext()); + loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, resultLimit, requestType, tinyDb.getString("repoIssuesState")); + + return v; + + } + + @Override + public void onResume() { + + super.onResume(); + TinyDB tinyDb = new TinyDB(getContext()); + final String loginUid = tinyDb.getString("loginUid"); + String repoFullName = tinyDb.getString("repoFullName"); + String[] parts = repoFullName.split("/"); + final String repoOwner = parts[0]; + final String repoName = parts[1]; + final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + + if(tinyDb.getBoolean("resumeIssues")) { + + loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, resultLimit, requestType, tinyDb.getString("repoIssuesState")); + tinyDb.putBoolean("resumeIssues", false); + + } + + } + + private void loadInitial(String token, String repoOwner, String repoName, int resultLimit, String requestType, String issueState) { + + Call> call = api.getIssues(token, repoOwner, repoName, 1, resultLimit, requestType, issueState); + + call.enqueue(new Callback>() { + + @Override + public void onResponse(@NonNull Call> call, @NonNull Response> response) { + + if(response.isSuccessful()) { + + assert response.body() != null; + if(response.body().size() > 0) { + + issuesList.clear(); + issuesList.addAll(response.body()); + adapter.notifyDataChanged(); + noDataIssues.setVisibility(View.GONE); + + } + else { + issuesList.clear(); + adapter.notifyDataChanged(); + noDataIssues.setVisibility(View.VISIBLE); + } + mProgressBar.setVisibility(View.GONE); + } + else { + Log.e(TAG, String.valueOf(response.code())); + } + + } + + @Override + public void onFailure(@NonNull Call> call, @NonNull Throwable t) { + + Log.e(TAG, t.toString()); + } + + }); + + } + + private void loadMore(String token, String repoOwner, String repoName, int page, int resultLimit, String requestType, String issueState) { + + //add loading progress view + issuesList.add(new Issues("load")); + adapter.notifyItemInserted((issuesList.size() - 1)); + + Call> call = api.getIssues(token, repoOwner, repoName, page, resultLimit, requestType, issueState); + + call.enqueue(new Callback>() { + + @Override + public void onResponse(@NonNull Call> call, @NonNull Response> response) { + + if(response.isSuccessful()) { + + //remove loading view + issuesList.remove(issuesList.size() - 1); + + List result = response.body(); + + assert result != null; + if(result.size() > 0) { + + pageSize = result.size(); + issuesList.addAll(result); + + } + else { + + Toasty.info(context, getString(R.string.noMoreData)); + adapter.setMoreDataAvailable(false); + + } + + adapter.notifyDataChanged(); + + } + else { + + Log.e(TAG, String.valueOf(response.code())); + + } + + } + + @Override + public void onFailure(@NonNull Call> call, @NonNull Throwable t) { + + Log.e(TAG, t.toString()); + + } + + }); + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + + this.menu = menu; + inflater.inflate(R.menu.search_menu, menu); + inflater.inflate(R.menu.filter_menu, menu); + super.onCreateOptionsMenu(menu, inflater); + + TinyDB tinyDb = new TinyDB(context); + + if(tinyDb.getString("repoIssuesState").equals("closed")) { + menu.getItem(1).setIcon(R.drawable.ic_filter_closed); + } + else { + menu.getItem(1).setIcon(R.drawable.ic_filter); + } + + MenuItem searchItem = menu.findItem(R.id.action_search); + androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView(); + searchView.setImeOptions(EditorInfo.IME_ACTION_DONE); + + searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() { + + @Override + public boolean onQueryTextSubmit(String query) { + + return false; + } + + @Override + public boolean onQueryTextChange(String newText) { + + filter(newText); + return false; + + } + + }); + + } + + private void filter(String text) { + + List arr = new ArrayList<>(); + + for(Issues d : issuesList) { + if(d.getTitle().toLowerCase().contains(text) || d.getBody().toLowerCase().contains(text)) { + arr.add(d); + } + } + + adapter.updateList(arr); + } + +} diff --git a/app/src/main/java/org/mian/gitnex/fragments/IssuesMainFragment.java b/app/src/main/java/org/mian/gitnex/fragments/IssuesMainFragment.java deleted file mode 100644 index 0391e5d7..00000000 --- a/app/src/main/java/org/mian/gitnex/fragments/IssuesMainFragment.java +++ /dev/null @@ -1,155 +0,0 @@ -package org.mian.gitnex.fragments; - -import android.content.Context; -import android.graphics.Typeface; -import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentStatePagerAdapter; -import androidx.viewpager.widget.ViewPager; -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.widget.TextView; -import com.google.android.material.tabs.TabLayout; -import org.mian.gitnex.R; -import org.mian.gitnex.util.TinyDB; -import java.util.Objects; - -/** - * Author M M Arif - */ - -public class IssuesMainFragment extends Fragment { - - private Context ctx; - - public IssuesMainFragment() { - - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - - View v = inflater.inflate(R.layout.fragment_issues_main, container, false); - setHasOptionsMenu(true); - - TinyDB tinyDb = new TinyDB(getContext()); - - SectionsPagerAdapter mSectionsPagerAdapter = new IssuesMainFragment.SectionsPagerAdapter(getChildFragmentManager()); - - ViewPager mViewPager = v.findViewById(R.id.issuesContainer); - mViewPager.setAdapter(mSectionsPagerAdapter); - - Typeface myTypeface; - if(tinyDb.getInt("customFontId") == 0) { - - myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/roboto.ttf"); - - } - else if (tinyDb.getInt("customFontId") == 1) { - - myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/manroperegular.ttf"); - - } - else if (tinyDb.getInt("customFontId") == 2) { - - myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/sourcecodeproregular.ttf"); - - } - else { - - myTypeface = Typeface.createFromAsset(Objects.requireNonNull(getContext()).getAssets(), "fonts/roboto.ttf"); - - } - - TabLayout tabLayout = v.findViewById(R.id.tabs); - - ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0); - int tabsCount = vg.getChildCount(); - - for (int j = 0; j < tabsCount; j++) { - - ViewGroup vgTab = (ViewGroup) vg.getChildAt(j); - int tabChildCount = vgTab.getChildCount(); - - for (int i = 0; i < tabChildCount; i++) { - - View tabViewChild = vgTab.getChildAt(i); - if (tabViewChild instanceof TextView) { - ((TextView) tabViewChild).setTypeface(myTypeface); - } - - } - - } - - mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout)); - tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager)); - - return v; - - } - - public static class SectionsPagerAdapter extends FragmentStatePagerAdapter { - - SectionsPagerAdapter(FragmentManager fm) { - super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); - } - - @NonNull - @Override - public Fragment getItem(int position) { - - Fragment fragment = null; - switch (position) { - case 0: // open issues - fragment = new IssuesOpenFragment(); - break; - case 1: // closed issues - fragment = new IssuesClosedFragment(); - break; - } - assert fragment != null; - return fragment; - } - - @Override - public int getCount() { - return 2; - } - - } - - @Override - public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - - menu.clear(); - Objects.requireNonNull(getActivity()).getMenuInflater().inflate(R.menu.repo_dotted_menu, menu); - super.onCreateOptionsMenu(menu, inflater); - - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - - int id = item.getItemId(); - - switch (id) { - case android.R.id.home: - return true; - case R.id.repoMenu: - BottomSheetRepoFragment bottomSheet = new BottomSheetRepoFragment(); - bottomSheet.show(getChildFragmentManager(), "repoBottomSheet"); - return true; - default: - return super.onOptionsItemSelected(item); - } - - } - -} diff --git a/app/src/main/java/org/mian/gitnex/fragments/IssuesOpenFragment.java b/app/src/main/java/org/mian/gitnex/fragments/IssuesOpenFragment.java deleted file mode 100644 index 902b6bdc..00000000 --- a/app/src/main/java/org/mian/gitnex/fragments/IssuesOpenFragment.java +++ /dev/null @@ -1,308 +0,0 @@ -package org.mian.gitnex.fragments; - -import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.recyclerview.widget.DefaultItemAnimator; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import android.os.Handler; -import android.util.Log; -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 android.widget.ProgressBar; -import android.widget.TextView; -import com.mikepenz.fastadapter.IItemAdapter; -import com.mikepenz.fastadapter.adapters.ItemAdapter; -import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter; -import com.mikepenz.fastadapter.listeners.ItemFilterListener; -import com.mikepenz.fastadapter_extensions.items.ProgressItem; -import com.mikepenz.fastadapter_extensions.scroll.EndlessRecyclerOnScrollListener; -import org.mian.gitnex.R; -import org.mian.gitnex.clients.RetrofitClient; -import org.mian.gitnex.helpers.StaticGlobalVariables; -import org.mian.gitnex.helpers.VersionCheck; -import org.mian.gitnex.adapters.IssuesAdapter; -import org.mian.gitnex.models.Issues; -import org.mian.gitnex.util.TinyDB; -import java.util.ArrayList; -import java.util.List; -import static com.mikepenz.fastadapter.adapters.ItemAdapter.items; - -/** - * Author M M Arif - */ - -public class IssuesOpenFragment extends Fragment implements ItemFilterListener { - - private ProgressBar mProgressBar; - private boolean loadNextFlag = false; - private String TAG = StaticGlobalVariables.tagIssuesListOpen; - private TextView noDataIssues; - private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances; - private String requestType = StaticGlobalVariables.issuesRequestType; - - private List items = new ArrayList<>(); - private FastItemAdapter fastItemAdapter; - private ItemAdapter footerAdapter; - private EndlessRecyclerOnScrollListener endlessRecyclerOnScrollListener; - - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - - final View v = inflater.inflate(R.layout.fragment_issues, container, false); - setHasOptionsMenu(true); - - 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"); - String repoFullName = tinyDb.getString("repoFullName"); - String[] parts = repoFullName.split("/"); - final String repoOwner = parts[0]; - final String repoName = parts[1]; - - if (VersionCheck.compareVersion("1.12.0", tinyDb.getString("giteaVersion")) < 1) { - resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances; - } - - noDataIssues = v.findViewById(R.id.noDataIssues); - mProgressBar = v.findViewById(R.id.progress_bar); - final SwipeRefreshLayout swipeRefreshLayout = v.findViewById(R.id.pullToRefresh); - - RecyclerView recyclerView = v.findViewById(R.id.recyclerView); - recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); - recyclerView.setHasFixedSize(true); - - fastItemAdapter = new FastItemAdapter<>(); - fastItemAdapter.withSelectable(true); - - footerAdapter = items(); - //noinspection unchecked - fastItemAdapter.addAdapter(StaticGlobalVariables.issuesPageInit, footerAdapter); - - fastItemAdapter.getItemFilter().withFilterPredicate((IItemAdapter.Predicate) (item, constraint) -> item.getIssueTitle().toLowerCase().contains(constraint.toString().toLowerCase())); - - fastItemAdapter.getItemFilter().withItemFilterListener(this); - - recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); - recyclerView.setItemAnimator(new DefaultItemAnimator()); - recyclerView.setAdapter(fastItemAdapter); - - endlessRecyclerOnScrollListener = new EndlessRecyclerOnScrollListener(footerAdapter) { - - @Override - public void onLoadMore(final int currentPage) { - - loadNext(instanceUrl, instanceToken, repoOwner, repoName, resultLimit, requestType, currentPage); - - } - - }; - - swipeRefreshLayout.setOnRefreshListener(() -> { - - mProgressBar.setVisibility(View.VISIBLE); - fastItemAdapter.clear(); - endlessRecyclerOnScrollListener.resetPageCount(); - swipeRefreshLayout.setRefreshing(false); - - }); - - recyclerView.addOnScrollListener(endlessRecyclerOnScrollListener); - - loadInitial(instanceUrl, instanceToken, repoOwner, repoName, resultLimit, requestType); - - fastItemAdapter.withEventHook(new IssuesAdapter.IssueTitleClickEvent()); - - assert savedInstanceState != null; - fastItemAdapter.withSavedInstanceState(savedInstanceState); - - return v; - - } - - @Override - public void onResume() { - - super.onResume(); - TinyDB tinyDb = new TinyDB(getContext()); - - if(tinyDb.getBoolean("resumeIssues")) { - - mProgressBar.setVisibility(View.VISIBLE); - fastItemAdapter.clear(); - endlessRecyclerOnScrollListener.resetPageCount(); - tinyDb.putBoolean("resumeIssues", false); - - } - - } - - private void loadInitial(String instanceUrl, String token, String repoOwner, String repoName, int resultLimit, String requestType) { - - Call> call = RetrofitClient.getInstance(instanceUrl, getContext()).getApiInterface().getIssues(token, repoOwner, repoName, 1, resultLimit, requestType); - - call.enqueue(new Callback>() { - - @Override - public void onResponse(@NonNull Call> call, @NonNull Response> response) { - - if(response.isSuccessful()) { - - assert response.body() != null; - if(response.body().size() > 0) { - - if(response.body().size() == resultLimit) { - loadNextFlag = true; - } - - for(int i = 0; i < response.body().size(); i++) { - items.add(new IssuesAdapter(getContext()).withNewItems(response.body().get(i).getTitle(), response.body().get(i).getNumber(), response.body().get(i).getUser().getAvatar_url(), response.body().get(i).getCreated_at(), response.body().get(i).getComments(), response.body().get(i).getUser().getFull_name(), response.body().get(i).getUser().getLogin())); - } - - fastItemAdapter.add(items); - noDataIssues.setVisibility(View.GONE); - - } - else { - noDataIssues.setVisibility(View.VISIBLE); - } - - mProgressBar.setVisibility(View.GONE); - - } - else { - Log.i(TAG, String.valueOf(response.code())); - } - - } - - @Override - public void onFailure(@NonNull Call> call, @NonNull Throwable t) { - - Log.e(TAG, t.toString()); - } - - }); - - } - - private void loadNext(String instanceUrl, String token, String repoOwner, String repoName, int resultLimit, String requestType, final int currentPage) { - - footerAdapter.clear(); - //noinspection unchecked - footerAdapter.add(new ProgressItem().withEnabled(false)); - Handler handler = new Handler(); - - handler.postDelayed(() -> { - - Call> call = RetrofitClient.getInstance(instanceUrl, getContext()).getApiInterface().getIssues(token, repoOwner, repoName, currentPage + 1, resultLimit, requestType); - - call.enqueue(new Callback>() { - - @Override - public void onResponse(@NonNull Call> call, @NonNull Response> response) { - - if(response.isSuccessful()) { - - assert response.body() != null; - - if(response.body().size() > 0) { - - loadNextFlag = response.body().size() == resultLimit; - - for(int i = 0; i < response.body().size(); i++) { - - fastItemAdapter.add(fastItemAdapter.getAdapterItemCount(), new IssuesAdapter(getContext()).withNewItems(response.body().get(i).getTitle(), response.body().get(i).getNumber(), response.body().get(i).getUser().getAvatar_url(), response.body().get(i).getCreated_at(), response.body().get(i).getComments(), response.body().get(i).getUser().getFull_name(), response.body().get(i).getUser().getLogin())); - - } - - footerAdapter.clear(); - noDataIssues.setVisibility(View.GONE); - - } - else { - footerAdapter.clear(); - } - - mProgressBar.setVisibility(View.GONE); - - } - else { - Log.i(TAG, String.valueOf(response.code())); - } - - } - - @Override - public void onFailure(@NonNull Call> call, @NonNull Throwable t) { - - Log.i(TAG, t.toString()); - } - - }); - - }, 1000); - - if(!loadNextFlag) { - footerAdapter.clear(); - } - - } - - @Override - public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - - inflater.inflate(R.menu.search_menu, menu); - super.onCreateOptionsMenu(menu, inflater); - - MenuItem searchItem = menu.findItem(R.id.action_search); - androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView(); - searchView.setImeOptions(EditorInfo.IME_ACTION_DONE); - - searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() { - - @Override - public boolean onQueryTextSubmit(String query) { - - return false; - } - - @Override - public boolean onQueryTextChange(String newText) { - - fastItemAdapter.filter(newText); - return true; - } - - }); - - endlessRecyclerOnScrollListener.enable(); - - } - - @Override - public void itemsFiltered(@Nullable CharSequence constraint, @Nullable List results) { - - endlessRecyclerOnScrollListener.disable(); - } - - @Override - public void onReset() { - - endlessRecyclerOnScrollListener.enable(); - } - -} diff --git a/app/src/main/java/org/mian/gitnex/fragments/PullRequestsFragment.java b/app/src/main/java/org/mian/gitnex/fragments/PullRequestsFragment.java index ea8e5cbe..ab50d096 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/PullRequestsFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/PullRequestsFragment.java @@ -2,13 +2,6 @@ package org.mian.gitnex.fragments; import android.content.Context; import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -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.util.Log; import android.view.LayoutInflater; @@ -20,14 +13,23 @@ import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.widget.ProgressBar; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.DividerItemDecoration; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import org.mian.gitnex.R; +import org.mian.gitnex.activities.RepoDetailActivity; import org.mian.gitnex.adapters.PullRequestsAdapter; import org.mian.gitnex.clients.PullRequestsService; import org.mian.gitnex.helpers.Authorization; +import org.mian.gitnex.helpers.StaticGlobalVariables; import org.mian.gitnex.helpers.Toasty; +import org.mian.gitnex.helpers.VersionCheck; import org.mian.gitnex.interfaces.ApiInterface; import org.mian.gitnex.models.PullRequests; -import org.mian.gitnex.util.AppUtil; import org.mian.gitnex.util.TinyDB; import java.util.ArrayList; import java.util.List; @@ -42,254 +44,274 @@ import retrofit2.Response; public class PullRequestsFragment extends Fragment { - private ProgressBar mProgressBar; - private RecyclerView recyclerView; - private List prList; - private PullRequestsAdapter adapter; - private ApiInterface apiPR; - private String TAG = "PullRequestsListFragment - "; - private Context context; - private int pageSize = 1; - private TextView noData; - private String prState = "open"; - private int resultLimit = 50; - - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - - final View v = inflater.inflate(R.layout.fragment_pull_requests, container, false); - setHasOptionsMenu(true); + private Menu menu; + private ProgressBar mProgressBar; + private RecyclerView recyclerView; + private List prList; + private PullRequestsAdapter adapter; + private ApiInterface apiPR; + private String TAG = StaticGlobalVariables.tagPullRequestsList; + private Context context; + private int pageSize = StaticGlobalVariables.prPageInit; + private TextView noData; + private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances; - TinyDB tinyDb = new TinyDB(getContext()); - String repoFullName = tinyDb.getString("repoFullName"); - //Log.i("repoFullName", tinyDb.getString("repoFullName")); - String[] parts = repoFullName.split("/"); - final String repoOwner = parts[0]; - final String repoName = parts[1]; - final String instanceUrl = tinyDb.getString("instanceUrl"); - final String loginUid = tinyDb.getString("loginUid"); - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh); + final View v = inflater.inflate(R.layout.fragment_pull_requests, container, false); + setHasOptionsMenu(true); + context = getContext(); - context = getContext(); - recyclerView = v.findViewById(R.id.recyclerView); - prList = new ArrayList<>(); + TinyDB tinyDb = new TinyDB(getContext()); + String repoFullName = tinyDb.getString("repoFullName"); + String[] parts = repoFullName.split("/"); + final String repoOwner = parts[0]; + final String repoName = parts[1]; + final String instanceUrl = tinyDb.getString("instanceUrl"); + final String loginUid = tinyDb.getString("loginUid"); + final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - mProgressBar = v.findViewById(R.id.progress_bar); - noData = v.findViewById(R.id.noData); + final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh); - swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { - @Override - public void onRefresh() { - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - - swipeRefresh.setRefreshing(false); - loadInitial(instanceToken, repoOwner, repoName, pageSize, prState, resultLimit); - adapter.notifyDataChanged(); - - } - }, 200); - } - }); - - adapter = new PullRequestsAdapter(getContext(), prList); - adapter.setLoadMoreListener(new PullRequestsAdapter.OnLoadMoreListener() { - @Override - public void onLoadMore() { + // if gitea is 1.12 or higher use the new limit + if(VersionCheck.compareVersion("1.12.0", tinyDb.getString("giteaVersion")) < 1) { + resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances; + } - recyclerView.post(new Runnable() { - @Override - public void run() { - if(prList.size() == 10 || pageSize == 10) { + recyclerView = v.findViewById(R.id.recyclerView); + prList = new ArrayList<>(); - int page = (prList.size() + 10) / 10; - loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, prState, resultLimit); + mProgressBar = v.findViewById(R.id.progress_bar); + noData = v.findViewById(R.id.noData); - } - /*else { + swipeRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> { - Toasty.info(context, getString(R.string.noMoreData)); + swipeRefresh.setRefreshing(false); + loadInitial(instanceToken, repoOwner, repoName, pageSize, tinyDb.getString("repoPrState"), resultLimit); + adapter.notifyDataChanged(); - }*/ - } - }); + }, 200)); - } - }); + adapter = new PullRequestsAdapter(getContext(), prList); + adapter.setLoadMoreListener(() -> recyclerView.post(() -> { - DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), - DividerItemDecoration.VERTICAL); - recyclerView.setHasFixedSize(true); - recyclerView.addItemDecoration(dividerItemDecoration); - recyclerView.setLayoutManager(new LinearLayoutManager(context)); - recyclerView.setAdapter(adapter); + if(prList.size() == 10 || pageSize == resultLimit) { - apiPR = PullRequestsService.createService(ApiInterface.class, instanceUrl, getContext()); - loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, pageSize, prState, resultLimit); + int page = (prList.size() + resultLimit) / resultLimit; + loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, tinyDb.getString("repoPrState"), resultLimit); - return v; + } - } + })); - @Override - public void onResume() { + DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL); + recyclerView.setHasFixedSize(true); + recyclerView.addItemDecoration(dividerItemDecoration); + recyclerView.setLayoutManager(new LinearLayoutManager(context)); + recyclerView.setAdapter(adapter); - super.onResume(); - TinyDB tinyDb = new TinyDB(getContext()); - final String loginUid = tinyDb.getString("loginUid"); - String repoFullName = tinyDb.getString("repoFullName"); - String[] parts = repoFullName.split("/"); - final String repoOwner = parts[0]; - final String repoName = parts[1]; - final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + ((RepoDetailActivity) Objects.requireNonNull(getActivity())).setFragmentRefreshListenerPr(prState -> { - if(tinyDb.getBoolean("resumePullRequests")) { + if(prState.equals("closed")) { + menu.getItem(1).setIcon(R.drawable.ic_filter_closed); + } + else { + menu.getItem(1).setIcon(R.drawable.ic_filter); + } - loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, pageSize, prState, resultLimit); - tinyDb.putBoolean("resumePullRequests", false); - tinyDb.putBoolean("prMerged", false); + prList.clear(); + adapter = new PullRequestsAdapter(context, prList); + tinyDb.putString("repoPrState", prState); + mProgressBar.setVisibility(View.VISIBLE); + noData.setVisibility(View.GONE); + loadInitial(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName, pageSize, prState, resultLimit); + recyclerView.setAdapter(adapter); - } + }); - } + apiPR = PullRequestsService.createService(ApiInterface.class, instanceUrl, context); + loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, pageSize, tinyDb.getString("repoPrState"), resultLimit); - private void loadInitial(String token, String repoOwner, String repoName, int page, String prState, int resultLimit) { + return v; - Call> call = apiPR.getPullRequests(token, repoOwner, repoName, page, prState, resultLimit); + } - call.enqueue(new Callback>() { + @Override + public void onResume() { - @Override - public void onResponse(@NonNull Call> call, @NonNull Response> response) { + super.onResume(); + TinyDB tinyDb = new TinyDB(getContext()); + final String loginUid = tinyDb.getString("loginUid"); + String repoFullName = tinyDb.getString("repoFullName"); + String[] parts = repoFullName.split("/"); + final String repoOwner = parts[0]; + final String repoName = parts[1]; + final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - if(response.isSuccessful()) { + if(tinyDb.getBoolean("resumePullRequests")) { - assert response.body() != null; - if(response.body().size() > 0) { + loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, pageSize, tinyDb.getString("repoPrState"), resultLimit); + tinyDb.putBoolean("resumePullRequests", false); + tinyDb.putBoolean("prMerged", false); - prList.clear(); - prList.addAll(response.body()); - adapter.notifyDataChanged(); - noData.setVisibility(View.GONE); + } - } - else { - prList.clear(); - adapter.notifyDataChanged(); - noData.setVisibility(View.VISIBLE); - } - mProgressBar.setVisibility(View.GONE); - } - else { - Log.i(TAG, String.valueOf(response.code())); - } + } - Log.i("http", String.valueOf(response.code())); + private void loadInitial(String token, String repoOwner, String repoName, int page, String prState, int resultLimit) { - } + Call> call = apiPR.getPullRequests(token, repoOwner, repoName, page, prState, resultLimit); - @Override - public void onFailure(@NonNull Call> call, @NonNull Throwable t) { - Log.e(TAG, t.toString()); - } + call.enqueue(new Callback>() { - }); + @Override + public void onResponse(@NonNull Call> call, @NonNull Response> response) { - } + if(response.isSuccessful()) { - private void loadMore(String token, String repoOwner, String repoName, int page, String prState, int resultLimit){ + assert response.body() != null; + if(response.body().size() > 0) { - //add loading progress view - prList.add(new PullRequests("load")); - adapter.notifyItemInserted((prList.size() - 1)); + prList.clear(); + prList.addAll(response.body()); + adapter.notifyDataChanged(); + noData.setVisibility(View.GONE); - Call> call = apiPR.getPullRequests(token, repoOwner, repoName, page, prState, resultLimit); + } + else { + prList.clear(); + adapter.notifyDataChanged(); + noData.setVisibility(View.VISIBLE); + } + mProgressBar.setVisibility(View.GONE); + } + else { + Log.i(TAG, String.valueOf(response.code())); + } - call.enqueue(new Callback>() { + Log.i(TAG, String.valueOf(response.code())); - @Override - public void onResponse(@NonNull Call> call, @NonNull Response> response) { + } - if(response.isSuccessful()){ + @Override + public void onFailure(@NonNull Call> call, @NonNull Throwable t) { - //remove loading view - prList.remove(prList.size()-1); + Log.e(TAG, t.toString()); + } - List result = response.body(); + }); - assert result != null; - if(result.size() > 0) { + } - pageSize = result.size(); - prList.addAll(result); + private void loadMore(String token, String repoOwner, String repoName, int page, String prState, int resultLimit) { - } - else { + //add loading progress view + prList.add(new PullRequests("load")); + adapter.notifyItemInserted((prList.size() - 1)); - Toasty.info(context, getString(R.string.noMoreData)); - adapter.setMoreDataAvailable(false); + Call> call = apiPR.getPullRequests(token, repoOwner, repoName, page, prState, resultLimit); - } + call.enqueue(new Callback>() { - adapter.notifyDataChanged(); + @Override + public void onResponse(@NonNull Call> call, @NonNull Response> response) { - } - else { + if(response.isSuccessful()) { - Log.e(TAG, String.valueOf(response.code())); + //remove loading view + prList.remove(prList.size() - 1); - } + List result = response.body(); - } + assert result != null; + if(result.size() > 0) { - @Override - public void onFailure(@NonNull Call> call, @NonNull Throwable t) { + pageSize = result.size(); + prList.addAll(result); - Log.e(TAG, t.toString()); + } + else { - } + Toasty.info(context, getString(R.string.noMoreData)); + adapter.setMoreDataAvailable(false); - }); - } + } - @Override - public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + adapter.notifyDataChanged(); - boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext())); + } + else { - inflater.inflate(R.menu.search_menu, menu); - super.onCreateOptionsMenu(menu, inflater); + Log.e(TAG, String.valueOf(response.code())); - MenuItem searchItem = menu.findItem(R.id.action_search); - androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView(); - searchView.setImeOptions(EditorInfo.IME_ACTION_DONE); - //searchView.setQueryHint(getContext().getString(R.string.strFilter)); + } - /*if(!connToInternet) { - return; - }*/ + } - searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() { + @Override + public void onFailure(@NonNull Call> call, @NonNull Throwable t) { - @Override - public boolean onQueryTextSubmit(String query) { - return false; - } + Log.e(TAG, t.toString()); - @Override - public boolean onQueryTextChange(String newText) { + } - adapter.getFilter().filter(newText); - return false; + }); + } - } + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - }); + this.menu = menu; + inflater.inflate(R.menu.search_menu, menu); + inflater.inflate(R.menu.filter_menu_pr, menu); + super.onCreateOptionsMenu(menu, inflater); - } + TinyDB tinyDb = new TinyDB(context); + + if(tinyDb.getString("repoPrState").equals("closed")) { + menu.getItem(1).setIcon(R.drawable.ic_filter_closed); + } + else { + menu.getItem(1).setIcon(R.drawable.ic_filter); + } + + MenuItem searchItem = menu.findItem(R.id.action_search); + androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView(); + searchView.setImeOptions(EditorInfo.IME_ACTION_DONE); + + searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() { + + @Override + public boolean onQueryTextSubmit(String query) { + + return false; + } + + @Override + public boolean onQueryTextChange(String newText) { + + filter(newText); + return false; + + } + + }); + + } + + private void filter(String text) { + + List arr = new ArrayList<>(); + + for(PullRequests d : prList) { + if(d.getTitle().toLowerCase().contains(text) || d.getBody().toLowerCase().contains(text)) { + arr.add(d); + } + } + + adapter.updateList(arr); + } } diff --git a/app/src/main/java/org/mian/gitnex/helpers/StaticGlobalVariables.java b/app/src/main/java/org/mian/gitnex/helpers/StaticGlobalVariables.java index 8bdc8c06..9a744e39 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/StaticGlobalVariables.java +++ b/app/src/main/java/org/mian/gitnex/helpers/StaticGlobalVariables.java @@ -6,13 +6,17 @@ package org.mian.gitnex.helpers; public interface StaticGlobalVariables { - // issues variables - String tagIssuesListOpen = "IssuesListOpenFragment - "; - String tagIssuesListClosed = "IssuesListClosedFragment - "; - int issuesPageInit = 1; + // generic values int resultLimitNewGiteaInstances = 25; // Gitea 1.12 and above int resultLimitOldGiteaInstances = 10; // Gitea 1.11 and below + + // issues variables + String tagIssuesList = "IssuesListFragment"; + int issuesPageInit = 1; String issuesRequestType = "issues"; - String issueStateClosed = "closed"; + + // pull request + String tagPullRequestsList = "PullRequestsListFragment"; + int prPageInit = 1; } diff --git a/app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java b/app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java index 6aeceba0..93595635 100644 --- a/app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java +++ b/app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java @@ -97,10 +97,7 @@ public interface ApiInterface { Call getUserRepository(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName); @GET("repos/{owner}/{repo}/issues") // get issues by repo - Call> getIssues(@Header("Authorization") String token, @Path("owner") String owner, @Path("repo") String repo, @Query("page") int page, @Query("limit") int limit, @Query("type") String requestType); - - @GET("repos/{owner}/{repo}/issues") // get closed issues by repo - Call> getClosedIssues(@Header("Authorization") String token, @Path("owner") String owner, @Path("repo") String repo, @Query("page") int page, @Query("state") String issueState, @Query("limit") int limit, @Query("type") String requestType); + Call> getIssues(@Header("Authorization") String token, @Path("owner") String owner, @Path("repo") String repo, @Query("page") int page, @Query("limit") int limit, @Query("type") String requestType, @Query("state") String issueState); @GET("repos/{owner}/{repo}/issues/{index}") // get issue by id Call getIssueByIndex(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("index") int issueIndex); diff --git a/app/src/main/res/drawable/ic_filter_closed.xml b/app/src/main/res/drawable/ic_filter_closed.xml new file mode 100644 index 00000000..bd7e5c94 --- /dev/null +++ b/app/src/main/res/drawable/ic_filter_closed.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/bottom_sheet_issues_filter.xml b/app/src/main/res/layout/bottom_sheet_issues_filter.xml new file mode 100644 index 00000000..1558e471 --- /dev/null +++ b/app/src/main/res/layout/bottom_sheet_issues_filter.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/bottom_sheet_pull_request_filter.xml b/app/src/main/res/layout/bottom_sheet_pull_request_filter.xml new file mode 100644 index 00000000..e1d9bb8d --- /dev/null +++ b/app/src/main/res/layout/bottom_sheet_pull_request_filter.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/filter_menu.xml b/app/src/main/res/menu/filter_menu.xml new file mode 100644 index 00000000..c016ab9f --- /dev/null +++ b/app/src/main/res/menu/filter_menu.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/filter_menu_pr.xml b/app/src/main/res/menu/filter_menu_pr.xml new file mode 100644 index 00000000..f2580e48 --- /dev/null +++ b/app/src/main/res/menu/filter_menu_pr.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file