Merge remote-tracking branch 'remotes/main/master' into self-signed
# Conflicts: # app/build.gradle # app/src/main/AndroidManifest.xml # app/src/main/res/values/strings.xml
This commit is contained in:
		@@ -0,0 +1,325 @@
 | 
			
		||||
package org.mian.gitnex.activities;
 | 
			
		||||
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
import android.text.method.ScrollingMovementMethod;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.Menu;
 | 
			
		||||
import android.view.MenuInflater;
 | 
			
		||||
import android.view.MenuItem;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.inputmethod.EditorInfo;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.ProgressBar;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.annotation.Nullable;
 | 
			
		||||
import androidx.appcompat.widget.Toolbar;
 | 
			
		||||
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 org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.items.CommitsItems;
 | 
			
		||||
import org.mian.gitnex.models.Commits;
 | 
			
		||||
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;
 | 
			
		||||
import static com.mikepenz.fastadapter.adapters.ItemAdapter.items;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class CommitsActivity extends BaseActivity implements ItemFilterListener<CommitsItems> {
 | 
			
		||||
 | 
			
		||||
    private View.OnClickListener onClickListener;
 | 
			
		||||
    private TextView noData;
 | 
			
		||||
    private ProgressBar progressBar;
 | 
			
		||||
    private SwipeRefreshLayout swipeRefreshLayout;
 | 
			
		||||
    private String TAG = "CommitsActivity - ";
 | 
			
		||||
    private int resultLimit = 50;
 | 
			
		||||
    private boolean loadNextFlag = false;
 | 
			
		||||
 | 
			
		||||
    private List<CommitsItems> items = new ArrayList<>();
 | 
			
		||||
    private FastItemAdapter<CommitsItems> fastItemAdapter;
 | 
			
		||||
    private ItemAdapter footerAdapter;
 | 
			
		||||
    private EndlessRecyclerOnScrollListener endlessRecyclerOnScrollListener;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected int getLayoutResourceId(){
 | 
			
		||||
        return R.layout.activity_commits;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        Toolbar toolbar = findViewById(R.id.toolbar);
 | 
			
		||||
        setSupportActionBar(toolbar);
 | 
			
		||||
 | 
			
		||||
        TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
        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];
 | 
			
		||||
 | 
			
		||||
        String branchName = getIntent().getStringExtra("branchName");
 | 
			
		||||
 | 
			
		||||
        TextView toolbar_title = findViewById(R.id.toolbar_title);
 | 
			
		||||
        toolbar_title.setMovementMethod(new ScrollingMovementMethod());
 | 
			
		||||
        toolbar_title.setText(branchName);
 | 
			
		||||
 | 
			
		||||
        ImageView closeActivity = findViewById(R.id.close);
 | 
			
		||||
        noData = findViewById(R.id.noDataCommits);
 | 
			
		||||
        progressBar = findViewById(R.id.progress_bar);
 | 
			
		||||
        swipeRefreshLayout = findViewById(R.id.pullToRefresh);
 | 
			
		||||
 | 
			
		||||
        RecyclerView recyclerView = findViewById(R.id.recyclerView);
 | 
			
		||||
        recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
 | 
			
		||||
        recyclerView.setHasFixedSize(true);
 | 
			
		||||
 | 
			
		||||
        initCloseListener();
 | 
			
		||||
        closeActivity.setOnClickListener(onClickListener);
 | 
			
		||||
 | 
			
		||||
        fastItemAdapter = new FastItemAdapter<>();
 | 
			
		||||
        fastItemAdapter.withSelectable(true);
 | 
			
		||||
 | 
			
		||||
        footerAdapter = items();
 | 
			
		||||
        //noinspection unchecked
 | 
			
		||||
        fastItemAdapter.addAdapter(1, footerAdapter);
 | 
			
		||||
 | 
			
		||||
        fastItemAdapter.getItemFilter().withFilterPredicate((IItemAdapter.Predicate<CommitsItems>) (item, constraint) -> item.getCommitTitle().toLowerCase().contains(Objects.requireNonNull(constraint).toString().toLowerCase()));
 | 
			
		||||
 | 
			
		||||
        fastItemAdapter.getItemFilter().withItemFilterListener(this);
 | 
			
		||||
 | 
			
		||||
        recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
 | 
			
		||||
        recyclerView.setItemAnimator(new DefaultItemAnimator());
 | 
			
		||||
        recyclerView.setAdapter(fastItemAdapter);
 | 
			
		||||
 | 
			
		||||
        endlessRecyclerOnScrollListener = new EndlessRecyclerOnScrollListener(footerAdapter) {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onLoadMore(final int currentPage) {
 | 
			
		||||
 | 
			
		||||
                loadNext(instanceUrl, instanceToken, repoOwner, repoName, currentPage, branchName);
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        swipeRefreshLayout.setOnRefreshListener(() -> {
 | 
			
		||||
 | 
			
		||||
            progressBar.setVisibility(View.VISIBLE);
 | 
			
		||||
            fastItemAdapter.clear();
 | 
			
		||||
            endlessRecyclerOnScrollListener.resetPageCount();
 | 
			
		||||
            swipeRefreshLayout.setRefreshing(false);
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        recyclerView.addOnScrollListener(endlessRecyclerOnScrollListener);
 | 
			
		||||
 | 
			
		||||
        loadInitial(instanceUrl, instanceToken, repoOwner, repoName, branchName);
 | 
			
		||||
 | 
			
		||||
        assert savedInstanceState != null;
 | 
			
		||||
        fastItemAdapter.withSavedInstanceState(savedInstanceState);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void loadInitial(String instanceUrl, String token, String repoOwner, String repoName, String branchName) {
 | 
			
		||||
 | 
			
		||||
        Call<List<Commits>> call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl, getApplicationContext())
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .getRepositoryCommits(token, repoOwner, repoName,  1, branchName);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<List<Commits>>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<List<Commits>> call, @NonNull Response<List<Commits>> 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 CommitsItems(getApplicationContext()).withNewItems(response.body().get(i).getCommit().getMessage(), response.body().get(i).getHtml_url(),
 | 
			
		||||
                                    response.body().get(i).getCommit().getCommitter().getName(), response.body().get(i).getCommit().getCommitter().getDate()));
 | 
			
		||||
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        fastItemAdapter.add(items);
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                    else {
 | 
			
		||||
 | 
			
		||||
                        noData.setVisibility(View.VISIBLE);
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    progressBar.setVisibility(View.GONE);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
 | 
			
		||||
                    Log.e(TAG, String.valueOf(response.code()));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<List<Commits>> call, @NonNull Throwable t) {
 | 
			
		||||
 | 
			
		||||
                Log.e(TAG, t.toString());
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void loadNext(String instanceUrl, String token, String repoOwner, String repoName, final int currentPage, String branchName) {
 | 
			
		||||
 | 
			
		||||
        footerAdapter.clear();
 | 
			
		||||
        //noinspection unchecked
 | 
			
		||||
        footerAdapter.add(new ProgressItem().withEnabled(false));
 | 
			
		||||
        Handler handler = new Handler();
 | 
			
		||||
 | 
			
		||||
        handler.postDelayed(() -> {
 | 
			
		||||
 | 
			
		||||
            Call<List<Commits>> call = RetrofitClient
 | 
			
		||||
                    .getInstance(instanceUrl, getApplicationContext())
 | 
			
		||||
                    .getApiInterface()
 | 
			
		||||
                    .getRepositoryCommits(token, repoOwner, repoName, currentPage + 1, branchName);
 | 
			
		||||
 | 
			
		||||
            call.enqueue(new Callback<List<Commits>>() {
 | 
			
		||||
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onResponse(@NonNull Call<List<Commits>> call, @NonNull Response<List<Commits>> 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 CommitsItems(getApplicationContext()).withNewItems(response.body().get(i).getCommit().getMessage(),
 | 
			
		||||
                                        response.body().get(i).getHtml_url(), response.body().get(i).getCommit().getCommitter().getName(),
 | 
			
		||||
                                        response.body().get(i).getCommit().getCommitter().getDate()));
 | 
			
		||||
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            footerAdapter.clear();
 | 
			
		||||
 | 
			
		||||
                        }
 | 
			
		||||
                        else {
 | 
			
		||||
 | 
			
		||||
                            footerAdapter.clear();
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        progressBar.setVisibility(View.GONE);
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                    else {
 | 
			
		||||
 | 
			
		||||
                        Log.e(TAG, String.valueOf(response.code()));
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onFailure(@NonNull Call<List<Commits>> call, @NonNull Throwable t) {
 | 
			
		||||
 | 
			
		||||
                    Log.e(TAG, t.toString());
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        }, 1000);
 | 
			
		||||
 | 
			
		||||
        if(!loadNextFlag) {
 | 
			
		||||
 | 
			
		||||
            footerAdapter.clear();
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean onCreateOptionsMenu(Menu menu) {
 | 
			
		||||
 | 
			
		||||
        MenuInflater inflater = getMenuInflater();
 | 
			
		||||
        inflater.inflate(R.menu.search_menu, menu);
 | 
			
		||||
 | 
			
		||||
        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();
 | 
			
		||||
        return super.onCreateOptionsMenu(menu);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void itemsFiltered(@Nullable CharSequence constraint, @Nullable List<CommitsItems> results) {
 | 
			
		||||
        endlessRecyclerOnScrollListener.disable();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onReset() {
 | 
			
		||||
        endlessRecyclerOnScrollListener.enable();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void initCloseListener() {
 | 
			
		||||
        onClickListener = view -> {
 | 
			
		||||
            getIntent().removeExtra("branchName");
 | 
			
		||||
            finish();
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -23,6 +23,7 @@ import androidx.appcompat.app.AlertDialog;
 | 
			
		||||
import com.tooltip.Tooltip;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.helpers.NetworkObserver;
 | 
			
		||||
import org.mian.gitnex.helpers.Toasty;
 | 
			
		||||
import org.mian.gitnex.helpers.VersionCheck;
 | 
			
		||||
import org.mian.gitnex.models.GiteaVersion;
 | 
			
		||||
@@ -65,7 +66,7 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
 | 
			
		||||
        TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
        NetworkObserver networkMonitor = new NetworkObserver(this);
 | 
			
		||||
 | 
			
		||||
        loginButton = findViewById(R.id.login_button);
 | 
			
		||||
        instanceUrlET = findViewById(R.id.instance_url);
 | 
			
		||||
@@ -105,30 +106,39 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
 | 
			
		||||
 | 
			
		||||
        info_button.setOnClickListener(infoListener);
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
        loginMethod.setOnCheckedChangeListener((group, checkedId) -> {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
 | 
			
		||||
            return;
 | 
			
		||||
            if(checkedId == R.id.loginToken) {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
                loginUidET.setVisibility(View.GONE);
 | 
			
		||||
                loginPassword.setVisibility(View.GONE);
 | 
			
		||||
                otpCode.setVisibility(View.GONE);
 | 
			
		||||
                otpInfo.setVisibility(View.GONE);
 | 
			
		||||
                loginTokenCode.setVisibility(View.VISIBLE);
 | 
			
		||||
 | 
			
		||||
        loginMethod.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onCheckedChanged(RadioGroup group, int checkedId) {
 | 
			
		||||
                if(checkedId == R.id.loginUsernamePassword){
 | 
			
		||||
                    loginUidET.setVisibility(View.VISIBLE);
 | 
			
		||||
                    loginPassword.setVisibility(View.VISIBLE);
 | 
			
		||||
                    otpCode.setVisibility(View.VISIBLE);
 | 
			
		||||
                    otpInfo.setVisibility(View.VISIBLE);
 | 
			
		||||
                    loginTokenCode.setVisibility(View.GONE);
 | 
			
		||||
                } else {
 | 
			
		||||
                    loginUidET.setVisibility(View.GONE);
 | 
			
		||||
                    loginPassword.setVisibility(View.GONE);
 | 
			
		||||
                    otpCode.setVisibility(View.GONE);
 | 
			
		||||
                    otpInfo.setVisibility(View.GONE);
 | 
			
		||||
                    loginTokenCode.setVisibility(View.VISIBLE);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
 | 
			
		||||
                loginUidET.setVisibility(View.VISIBLE);
 | 
			
		||||
                loginPassword.setVisibility(View.VISIBLE);
 | 
			
		||||
                otpCode.setVisibility(View.VISIBLE);
 | 
			
		||||
                otpInfo.setVisibility(View.VISIBLE);
 | 
			
		||||
                loginTokenCode.setVisibility(View.GONE);
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        networkMonitor.onInternetStateListener(isAvailable -> {
 | 
			
		||||
 | 
			
		||||
            if(isAvailable) {
 | 
			
		||||
                enableProcessButton();
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                disableProcessButton();
 | 
			
		||||
                Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        //login_button.setOnClickListener(this);
 | 
			
		||||
 
 | 
			
		||||
@@ -270,17 +270,18 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF
 | 
			
		||||
                case 4: // pull requests
 | 
			
		||||
                    fragment = new PullRequestsFragment();
 | 
			
		||||
                    break;
 | 
			
		||||
                case 5: // milestones
 | 
			
		||||
                    return MilestonesFragment.newInstance(repoOwner, repoName);
 | 
			
		||||
                case 6: // labels
 | 
			
		||||
                    return LabelsFragment.newInstance(repoOwner, repoName);
 | 
			
		||||
                case 7: // branches
 | 
			
		||||
                case 5: // branches
 | 
			
		||||
                    return BranchesFragment.newInstance(repoOwner, repoName);
 | 
			
		||||
                case 8: // releases
 | 
			
		||||
                case 6: // releases
 | 
			
		||||
                    return ReleasesFragment.newInstance(repoOwner, repoName);
 | 
			
		||||
                case 7: // milestones
 | 
			
		||||
                    return MilestonesFragment.newInstance(repoOwner, repoName);
 | 
			
		||||
                case 8: // labels
 | 
			
		||||
                    return LabelsFragment.newInstance(repoOwner, repoName);
 | 
			
		||||
                case 9: // collaborators
 | 
			
		||||
                    return CollaboratorsFragment.newInstance(repoOwner, repoName);
 | 
			
		||||
            }
 | 
			
		||||
            assert fragment != null;
 | 
			
		||||
            return fragment;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user