@@ -0,0 +1,161 @@
 | 
			
		||||
package org.mian.gitnex.actions;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.activities.AddCollaboratorToRepositoryActivity;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.helpers.AlertDialogs;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.helpers.Toasty;
 | 
			
		||||
import org.mian.gitnex.models.Collaborators;
 | 
			
		||||
import org.mian.gitnex.models.Permission;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import retrofit2.Call;
 | 
			
		||||
import retrofit2.Callback;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class CollaboratorActions {
 | 
			
		||||
 | 
			
		||||
    public static void deleteCollaborator(final Context context, final String searchKeyword, String userName) {
 | 
			
		||||
 | 
			
		||||
        final TinyDB tinyDb = new TinyDB(context);
 | 
			
		||||
        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];
 | 
			
		||||
 | 
			
		||||
        Call<Collaborators> call;
 | 
			
		||||
 | 
			
		||||
        call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .deleteCollaborator(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName, userName);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<Collaborators>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<Collaborators> call, @NonNull retrofit2.Response<Collaborators> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.isSuccessful()) {
 | 
			
		||||
                    if(response.code() == 204) {
 | 
			
		||||
 | 
			
		||||
                        Toasty.info(context, context.getString(R.string.removeCollaboratorToastText));
 | 
			
		||||
                        ((AddCollaboratorToRepositoryActivity)context).finish();
 | 
			
		||||
                        //Log.i("addCollaboratorSearch", addCollaboratorSearch.getText().toString());
 | 
			
		||||
                        //tinyDb.putBoolean("updateDataSet", true);
 | 
			
		||||
                        //AddCollaboratorToRepositoryActivity usersSearchData = new AddCollaboratorToRepositoryActivity();
 | 
			
		||||
                        //usersSearchData.loadUserSearchList(instanceUrl, instanceToken, searchKeyword, context);
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 401) {
 | 
			
		||||
 | 
			
		||||
                    AlertDialogs.authorizationTokenRevokedDialog(context, context.getResources().getString(R.string.alertDialogTokenRevokedTitle),
 | 
			
		||||
                            context.getResources().getString(R.string.alertDialogTokenRevokedMessage),
 | 
			
		||||
                            context.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
 | 
			
		||||
                            context.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 403) {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(context, context.getString(R.string.authorizeError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 404) {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(context, context.getString(R.string.apiNotFound));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(context, context.getString(R.string.genericError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<Collaborators> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void addCollaborator(final Context context, String permission, String userName) {
 | 
			
		||||
 | 
			
		||||
        final TinyDB tinyDb = new TinyDB(context);
 | 
			
		||||
        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];
 | 
			
		||||
 | 
			
		||||
        Permission permissionString = new Permission(permission);
 | 
			
		||||
        Call<Permission> call;
 | 
			
		||||
 | 
			
		||||
        call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .addCollaborator(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName, userName, permissionString);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<Permission>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<Permission> call, @NonNull retrofit2.Response<Permission> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.isSuccessful()) {
 | 
			
		||||
                    if(response.code() == 204) {
 | 
			
		||||
 | 
			
		||||
                        Toasty.info(context, context.getString(R.string.addCollaboratorToastText));
 | 
			
		||||
                        ((AddCollaboratorToRepositoryActivity)context).finish();
 | 
			
		||||
                        //AddCollaboratorToRepositoryActivity usersSearchData = new AddCollaboratorToRepositoryActivity();
 | 
			
		||||
                        //usersSearchData.loadUserSearchList(instanceUrl, instanceToken, searchKeyword, context);
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 401) {
 | 
			
		||||
 | 
			
		||||
                    AlertDialogs.authorizationTokenRevokedDialog(context, context.getResources().getString(R.string.alertDialogTokenRevokedTitle),
 | 
			
		||||
                            context.getResources().getString(R.string.alertDialogTokenRevokedMessage),
 | 
			
		||||
                            context.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
 | 
			
		||||
                            context.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 403) {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(context, context.getString(R.string.authorizeError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 404) {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(context, context.getString(R.string.apiNotFound));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(context, context.getString(R.string.genericError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<Permission> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										164
									
								
								app/src/main/java/org/mian/gitnex/actions/IssueActions.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								app/src/main/java/org/mian/gitnex/actions/IssueActions.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,164 @@
 | 
			
		||||
package org.mian.gitnex.actions;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import com.google.gson.JsonElement;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.activities.ReplyToIssueActivity;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.helpers.AlertDialogs;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.helpers.Toasty;
 | 
			
		||||
import org.mian.gitnex.models.UpdateIssueState;
 | 
			
		||||
import org.mian.gitnex.models.IssueComments;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import retrofit2.Call;
 | 
			
		||||
import retrofit2.Callback;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class IssueActions {
 | 
			
		||||
 | 
			
		||||
    public static void editIssueComment(final Context context, final int commentId, final String commentBody) {
 | 
			
		||||
 | 
			
		||||
        final TinyDB tinyDb = new TinyDB(context);
 | 
			
		||||
        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];
 | 
			
		||||
 | 
			
		||||
        IssueComments commentBodyJson = new IssueComments(commentBody);
 | 
			
		||||
        Call<IssueComments> call;
 | 
			
		||||
 | 
			
		||||
        call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .patchIssueComment(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName, commentId, commentBodyJson);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<IssueComments>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<IssueComments> call, @NonNull retrofit2.Response<IssueComments> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.isSuccessful()) {
 | 
			
		||||
                    if(response.code() == 200) {
 | 
			
		||||
 | 
			
		||||
                        tinyDb.putBoolean("commentEdited", true);
 | 
			
		||||
                        Toasty.info(context, context.getString(R.string.editCommentUpdatedText));
 | 
			
		||||
                        ((ReplyToIssueActivity)context).finish();
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 401) {
 | 
			
		||||
 | 
			
		||||
                    AlertDialogs.authorizationTokenRevokedDialog(context, context.getResources().getString(R.string.alertDialogTokenRevokedTitle),
 | 
			
		||||
                            context.getResources().getString(R.string.alertDialogTokenRevokedMessage),
 | 
			
		||||
                            context.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
 | 
			
		||||
                            context.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 403) {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(context, context.getString(R.string.authorizeError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 404) {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(context, context.getString(R.string.apiNotFound));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(context, context.getString(R.string.genericError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<IssueComments> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void closeReopenIssue(final Context context, final int issueIndex, final String issueState) {
 | 
			
		||||
 | 
			
		||||
        final TinyDB tinyDb = new TinyDB(context);
 | 
			
		||||
        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];
 | 
			
		||||
 | 
			
		||||
        UpdateIssueState issueStatJson = new UpdateIssueState(issueState);
 | 
			
		||||
        Call<JsonElement> call;
 | 
			
		||||
 | 
			
		||||
        call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .closeReopenIssue(Authorization.returnAuthentication(context, loginUid, instanceToken), repoOwner, repoName, issueIndex, issueStatJson);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<JsonElement>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.isSuccessful()) {
 | 
			
		||||
                    if(response.code() == 201) {
 | 
			
		||||
 | 
			
		||||
                        tinyDb.putBoolean("resumeIssues", true);
 | 
			
		||||
                        tinyDb.putBoolean("resumeClosedIssues", true);
 | 
			
		||||
                        if(issueState.equals("closed")) {
 | 
			
		||||
                            Toasty.info(context, context.getString(R.string.issueStateClosed));
 | 
			
		||||
                        }
 | 
			
		||||
                        else if(issueState.equals("open")) {
 | 
			
		||||
                            Toasty.info(context, context.getString(R.string.issueStateReopened));
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 401) {
 | 
			
		||||
 | 
			
		||||
                    AlertDialogs.authorizationTokenRevokedDialog(context, context.getResources().getString(R.string.alertDialogTokenRevokedTitle),
 | 
			
		||||
                            context.getResources().getString(R.string.alertDialogTokenRevokedMessage),
 | 
			
		||||
                            context.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
 | 
			
		||||
                            context.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 403) {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(context, context.getString(R.string.authorizeError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 404) {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(context, context.getString(R.string.apiNotFound));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(context, context.getString(R.string.genericError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,144 @@
 | 
			
		||||
package org.mian.gitnex.activities;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import androidx.recyclerview.widget.DividerItemDecoration;
 | 
			
		||||
import androidx.recyclerview.widget.LinearLayoutManager;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import retrofit2.Call;
 | 
			
		||||
import retrofit2.Callback;
 | 
			
		||||
import retrofit2.Response;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.KeyEvent;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.inputmethod.EditorInfo;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.ProgressBar;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.adapters.UserSearchAdapter;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.models.UserSearch;
 | 
			
		||||
import org.mian.gitnex.models.UserInfo;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class AddCollaboratorToRepositoryActivity extends AppCompatActivity {
 | 
			
		||||
 | 
			
		||||
    private View.OnClickListener onClickListener;
 | 
			
		||||
    final Context ctx = this;
 | 
			
		||||
    private TextView addCollaboratorSearch;
 | 
			
		||||
    private TextView noData;
 | 
			
		||||
    private ProgressBar mProgressBar;
 | 
			
		||||
 | 
			
		||||
    private RecyclerView mRecyclerView;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        setContentView(R.layout.activity_add_collaborator_to_repository);
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
 | 
			
		||||
        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 instanceToken = "token " + tinyDb.getString(loginUid + "-token");
 | 
			
		||||
 | 
			
		||||
        ImageView closeActivity = findViewById(R.id.close);
 | 
			
		||||
        addCollaboratorSearch = findViewById(R.id.addCollaboratorSearch);
 | 
			
		||||
        mRecyclerView = findViewById(R.id.recyclerViewUserSearch);
 | 
			
		||||
        mProgressBar = findViewById(R.id.progress_bar);
 | 
			
		||||
        noData = findViewById(R.id.noData);
 | 
			
		||||
 | 
			
		||||
        initCloseListener();
 | 
			
		||||
        closeActivity.setOnClickListener(onClickListener);
 | 
			
		||||
 | 
			
		||||
        addCollaboratorSearch.setOnEditorActionListener(new TextView.OnEditorActionListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
 | 
			
		||||
                if (actionId == EditorInfo.IME_ACTION_SEND) {
 | 
			
		||||
                    if(!addCollaboratorSearch.getText().toString().equals("")) {
 | 
			
		||||
                        loadUserSearchList(instanceUrl, instanceToken, addCollaboratorSearch.getText().toString(), getApplicationContext(), loginUid);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void loadUserSearchList(String instanceUrl, String token, String searchKeyword, final Context context, String loginUid) {
 | 
			
		||||
 | 
			
		||||
        Call<UserSearch> call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .getUserBySearch(Authorization.returnAuthentication(getApplicationContext(), loginUid, token), searchKeyword, 10);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<UserSearch>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<UserSearch> call, @NonNull Response<UserSearch> response) {
 | 
			
		||||
 | 
			
		||||
                if (response.isSuccessful()) {
 | 
			
		||||
                    assert response.body() != null;
 | 
			
		||||
                    getUsersList(response.body().getData(), context);
 | 
			
		||||
                } else {
 | 
			
		||||
                    Log.i("onResponse", String.valueOf(response.code()));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<UserSearch> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.i("onFailure", t.getMessage());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void getUsersList(List<UserInfo> dataList, Context context) {
 | 
			
		||||
 | 
			
		||||
        UserSearchAdapter adapter = new UserSearchAdapter(dataList, context);
 | 
			
		||||
 | 
			
		||||
        mRecyclerView.setHasFixedSize(true);
 | 
			
		||||
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
 | 
			
		||||
        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
 | 
			
		||||
                DividerItemDecoration.VERTICAL);
 | 
			
		||||
        mRecyclerView.addItemDecoration(dividerItemDecoration);
 | 
			
		||||
 | 
			
		||||
        mProgressBar.setVisibility(View.VISIBLE);
 | 
			
		||||
 | 
			
		||||
        if(adapter.getItemCount() > 0) {
 | 
			
		||||
            mRecyclerView.setAdapter(adapter);
 | 
			
		||||
            noData.setVisibility(View.GONE);
 | 
			
		||||
            mProgressBar.setVisibility(View.GONE);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            noData.setVisibility(View.VISIBLE);
 | 
			
		||||
            mProgressBar.setVisibility(View.GONE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void initCloseListener() {
 | 
			
		||||
        onClickListener = new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                finish();
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,290 @@
 | 
			
		||||
package org.mian.gitnex.activities;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.graphics.Color;
 | 
			
		||||
import android.graphics.drawable.ColorDrawable;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.Window;
 | 
			
		||||
import com.google.gson.JsonElement;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.helpers.AlertDialogs;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.helpers.MultiSelectDialog;
 | 
			
		||||
import org.mian.gitnex.helpers.Toasty;
 | 
			
		||||
import org.mian.gitnex.models.Collaborators;
 | 
			
		||||
import org.mian.gitnex.models.Issues;
 | 
			
		||||
import org.mian.gitnex.models.MultiSelectModel;
 | 
			
		||||
import org.mian.gitnex.models.UpdateIssueAssignee;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import retrofit2.Call;
 | 
			
		||||
import retrofit2.Callback;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class AddRemoveAssigneesActivity extends AppCompatActivity {
 | 
			
		||||
 | 
			
		||||
    private ArrayList<MultiSelectModel> listOfCollaborators = new ArrayList<>();
 | 
			
		||||
    private ArrayList<Integer> issueAssigneesIds = new ArrayList<>();
 | 
			
		||||
    private Boolean assigneesFlag = false;
 | 
			
		||||
    private MultiSelectDialog multiSelectDialogAssignees;
 | 
			
		||||
    final Context ctx = this;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
 | 
			
		||||
        setContentView(R.layout.activity_add_remove_assignees);
 | 
			
		||||
 | 
			
		||||
        getWindow().getDecorView().setBackground(new ColorDrawable(Color.TRANSPARENT));
 | 
			
		||||
 | 
			
		||||
        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");
 | 
			
		||||
        final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
 | 
			
		||||
 | 
			
		||||
        getAssignees(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void getAssignees(final String instanceUrl, final String instanceToken, final String repoOwner, final String repoName, final int issueIndex, final String loginUid) {
 | 
			
		||||
 | 
			
		||||
        final TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
 | 
			
		||||
        Call<List<Collaborators>> call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<List<Collaborators>>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull final Call<List<Collaborators>> call, @NonNull final retrofit2.Response<List<Collaborators>> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.isSuccessful()) {
 | 
			
		||||
                    if(response.code() == 200) {
 | 
			
		||||
 | 
			
		||||
                        final List<Collaborators> collaboratorsList_ = response.body();
 | 
			
		||||
 | 
			
		||||
                        assert collaboratorsList_ != null;
 | 
			
		||||
                        if(collaboratorsList_.size() > 0) {
 | 
			
		||||
                            for (int i = 0; i < collaboratorsList_.size(); i++) {
 | 
			
		||||
 | 
			
		||||
                                listOfCollaborators.add(new MultiSelectModel(collaboratorsList_.get(i).getId(), collaboratorsList_.get(i).getUsername().trim()));
 | 
			
		||||
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        // get current issue assignees
 | 
			
		||||
                        Call<Issues> callSingleIssueAssignees = RetrofitClient
 | 
			
		||||
                                .getInstance(instanceUrl)
 | 
			
		||||
                                .getApiInterface()
 | 
			
		||||
                                .getIssueByIndex(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex);
 | 
			
		||||
 | 
			
		||||
                        callSingleIssueAssignees.enqueue(new Callback<Issues>() {
 | 
			
		||||
 | 
			
		||||
                            @Override
 | 
			
		||||
                            public void onResponse(@NonNull Call<Issues> call, @NonNull retrofit2.Response<Issues> response) {
 | 
			
		||||
 | 
			
		||||
                                if(response.code() == 200) {
 | 
			
		||||
 | 
			
		||||
                                    Issues issueAssigneesList = response.body();
 | 
			
		||||
 | 
			
		||||
                                    assert issueAssigneesList != null;
 | 
			
		||||
                                    if (issueAssigneesList.getAssignees() != null) {
 | 
			
		||||
                                        if (issueAssigneesList.getAssignees().size() > 0) {
 | 
			
		||||
                                            for (int i = 0; i < issueAssigneesList.getAssignees().size(); i++) {
 | 
			
		||||
 | 
			
		||||
                                                issueAssigneesIds.add(issueAssigneesList.getAssignees().get(i).getId());
 | 
			
		||||
 | 
			
		||||
                                                if(issueAssigneesList.getAssignees().get(i).getUsername().equals(loginUid)) {
 | 
			
		||||
                                                    listOfCollaborators.add(new MultiSelectModel(issueAssigneesList.getAssignees().get(i).getId(), issueAssigneesList.getAssignees().get(i).getUsername().trim()));
 | 
			
		||||
                                                }
 | 
			
		||||
 | 
			
		||||
                                            }
 | 
			
		||||
                                            assigneesFlag = true;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                    else {
 | 
			
		||||
                                        listOfCollaborators.add(new MultiSelectModel(tinyDb.getInt("userId"), loginUid));
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
                                    if(assigneesFlag) {
 | 
			
		||||
 | 
			
		||||
                                        multiSelectDialogAssignees = new MultiSelectDialog()
 | 
			
		||||
                                                .title(getResources().getString(R.string.newIssueSelectAssigneesListTitle))
 | 
			
		||||
                                                .titleSize(25)
 | 
			
		||||
                                                .positiveText(getResources().getString(R.string.saveButton))
 | 
			
		||||
                                                .negativeText(getResources().getString(R.string.cancelButton))
 | 
			
		||||
                                                .setMinSelectionLimit(0)
 | 
			
		||||
                                                .preSelectIDsList(issueAssigneesIds)
 | 
			
		||||
                                                .setMaxSelectionLimit(listOfCollaborators.size())
 | 
			
		||||
                                                .multiSelectList(listOfCollaborators)
 | 
			
		||||
                                                .onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
 | 
			
		||||
                                                    @Override
 | 
			
		||||
                                                    public void onSelected(ArrayList<Integer> selectedIds, ArrayList<String> selectedNames, String dataString) {
 | 
			
		||||
 | 
			
		||||
                                                        Log.i("selectedNames", String.valueOf(selectedNames));
 | 
			
		||||
 | 
			
		||||
                                                        updateIssueAssignees(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, loginUid, issueIndex, selectedNames);
 | 
			
		||||
                                                        tinyDb.putBoolean("singleIssueUpdate", true);
 | 
			
		||||
                                                        CloseActivity();
 | 
			
		||||
                                                    }
 | 
			
		||||
 | 
			
		||||
                                                    @Override
 | 
			
		||||
                                                    public void onCancel() {
 | 
			
		||||
                                                        CloseActivity();
 | 
			
		||||
                                                    }
 | 
			
		||||
                                                });
 | 
			
		||||
 | 
			
		||||
                                    }
 | 
			
		||||
                                    else {
 | 
			
		||||
 | 
			
		||||
                                        multiSelectDialogAssignees = new MultiSelectDialog()
 | 
			
		||||
                                                .title(getResources().getString(R.string.newIssueSelectAssigneesListTitle))
 | 
			
		||||
                                                .titleSize(25)
 | 
			
		||||
                                                .positiveText(getResources().getString(R.string.saveButton))
 | 
			
		||||
                                                .negativeText(getResources().getString(R.string.cancelButton))
 | 
			
		||||
                                                .setMinSelectionLimit(0)
 | 
			
		||||
                                                .setMaxSelectionLimit(listOfCollaborators.size())
 | 
			
		||||
                                                .multiSelectList(listOfCollaborators)
 | 
			
		||||
                                                .onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
 | 
			
		||||
                                                    @Override
 | 
			
		||||
                                                    public void onSelected(ArrayList<Integer> selectedIds, ArrayList<String> selectedNames, String dataString) {
 | 
			
		||||
 | 
			
		||||
                                                        updateIssueAssignees(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, loginUid, issueIndex, selectedNames);
 | 
			
		||||
                                                        tinyDb.putBoolean("singleIssueUpdate", true);
 | 
			
		||||
                                                        CloseActivity();
 | 
			
		||||
 | 
			
		||||
                                                    }
 | 
			
		||||
 | 
			
		||||
                                                    @Override
 | 
			
		||||
                                                    public void onCancel() {
 | 
			
		||||
                                                        CloseActivity();
 | 
			
		||||
                                                    }
 | 
			
		||||
                                                });
 | 
			
		||||
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
                                    multiSelectDialogAssignees.show(getSupportFragmentManager(), "issueMultiSelectDialog");
 | 
			
		||||
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            @Override
 | 
			
		||||
                            public void onFailure(@NonNull Call<Issues> call, @NonNull Throwable t) {
 | 
			
		||||
                                Log.e("onFailure", t.toString());
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                        });
 | 
			
		||||
                        // get current issue assignees
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                    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 if(response.code() == 403) {
 | 
			
		||||
 | 
			
		||||
                        Toasty.info(ctx, ctx.getString(R.string.authorizeError));
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                    else if(response.code() == 404) {
 | 
			
		||||
 | 
			
		||||
                        Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                    else {
 | 
			
		||||
 | 
			
		||||
                        Toasty.info(getApplicationContext(), getString(R.string.genericError));
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void CloseActivity() {
 | 
			
		||||
        this.finish();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void updateIssueAssignees(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String loginUid, int issueIndex, List<String> issueAssigneesList) {
 | 
			
		||||
 | 
			
		||||
        UpdateIssueAssignee updateAssigneeJson = new UpdateIssueAssignee(issueAssigneesList);
 | 
			
		||||
 | 
			
		||||
        Call<JsonElement> call3;
 | 
			
		||||
 | 
			
		||||
        call3 = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .patchIssueAssignee(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, updateAssigneeJson);
 | 
			
		||||
 | 
			
		||||
        call3.enqueue(new Callback<JsonElement>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response2) {
 | 
			
		||||
 | 
			
		||||
                if(response2.code() == 201) {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(ctx, ctx.getString(R.string.assigneesUpdated));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response2.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 if(response2.code() == 403) {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(ctx, ctx.getString(R.string.authorizeError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response2.code() == 404) {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.genericError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,303 @@
 | 
			
		||||
package org.mian.gitnex.activities;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import retrofit2.Call;
 | 
			
		||||
import retrofit2.Callback;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.graphics.Color;
 | 
			
		||||
import android.graphics.drawable.ColorDrawable;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.Window;
 | 
			
		||||
import com.google.gson.JsonElement;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.helpers.AlertDialogs;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.helpers.MultiSelectDialog;
 | 
			
		||||
import org.mian.gitnex.helpers.Toasty;
 | 
			
		||||
import org.mian.gitnex.models.Labels;
 | 
			
		||||
import org.mian.gitnex.models.MultiSelectModel;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class AddRemoveLabelsActivity extends AppCompatActivity {
 | 
			
		||||
 | 
			
		||||
    private ArrayList<MultiSelectModel> listOfLabels = new ArrayList<>();
 | 
			
		||||
    private ArrayList<Integer> issueLabelIds = new ArrayList<>();
 | 
			
		||||
    private Boolean labelsFlag = false;
 | 
			
		||||
    private MultiSelectDialog multiSelectDialogLabels;
 | 
			
		||||
    final Context ctx = this;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
 | 
			
		||||
        setContentView(R.layout.activity_add_remove_labels);
 | 
			
		||||
 | 
			
		||||
        getWindow().getDecorView().setBackground(new ColorDrawable(Color.TRANSPARENT));
 | 
			
		||||
 | 
			
		||||
        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");
 | 
			
		||||
        final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
 | 
			
		||||
 | 
			
		||||
        getLabels(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void getLabels(final String instanceUrl, final String instanceToken, final String repoOwner, final String repoName, final int issueIndex, final String loginUid) {
 | 
			
		||||
 | 
			
		||||
        final TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
 | 
			
		||||
        Call<List<Labels>> call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .getlabels(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<List<Labels>>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<List<Labels>> call, @NonNull retrofit2.Response<List<Labels>> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.isSuccessful()) {
 | 
			
		||||
                    if(response.code() == 200) {
 | 
			
		||||
 | 
			
		||||
                        List<Labels> labelsList_ = response.body();
 | 
			
		||||
 | 
			
		||||
                        assert labelsList_ != null;
 | 
			
		||||
                        if(labelsList_.size() > 0) {
 | 
			
		||||
                            for (int i = 0; i < labelsList_.size(); i++) {
 | 
			
		||||
 | 
			
		||||
                                listOfLabels.add(new MultiSelectModel(labelsList_.get(i).getId(), labelsList_.get(i).getName().trim()));
 | 
			
		||||
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        // get current issue labels
 | 
			
		||||
                        Call<List<Labels>> callSingleIssueLabels = RetrofitClient
 | 
			
		||||
                                .getInstance(instanceUrl)
 | 
			
		||||
                                .getApiInterface()
 | 
			
		||||
                                .getIssueLabels(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex);
 | 
			
		||||
 | 
			
		||||
                        callSingleIssueLabels.enqueue(new Callback<List<Labels>>() {
 | 
			
		||||
 | 
			
		||||
                            @Override
 | 
			
		||||
                            public void onResponse(@NonNull Call<List<Labels>> call, @NonNull retrofit2.Response<List<Labels>> response) {
 | 
			
		||||
 | 
			
		||||
                                if(response.code() == 200) {
 | 
			
		||||
 | 
			
		||||
                                    List<Labels> issueLabelsList = response.body();
 | 
			
		||||
 | 
			
		||||
                                    assert issueLabelsList != null;
 | 
			
		||||
                                    if(issueLabelsList.size() > 0) {
 | 
			
		||||
                                        for (int i = 0; i < issueLabelsList.size(); i++) {
 | 
			
		||||
 | 
			
		||||
                                            issueLabelIds.add(issueLabelsList.get(i).getId());
 | 
			
		||||
 | 
			
		||||
                                        }
 | 
			
		||||
                                        labelsFlag = true;
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
                                    if(labelsFlag) {
 | 
			
		||||
 | 
			
		||||
                                        multiSelectDialogLabels = new MultiSelectDialog()
 | 
			
		||||
                                                .title(getResources().getString(R.string.newIssueSelectLabelsListTitle))
 | 
			
		||||
                                                .titleSize(25)
 | 
			
		||||
                                                .positiveText(getResources().getString(R.string.saveButton))
 | 
			
		||||
                                                .negativeText(getResources().getString(R.string.cancelButton))
 | 
			
		||||
                                                .setMinSelectionLimit(0)
 | 
			
		||||
                                                .preSelectIDsList(issueLabelIds)
 | 
			
		||||
                                                .setMaxSelectionLimit(listOfLabels.size())
 | 
			
		||||
                                                .multiSelectList(listOfLabels)
 | 
			
		||||
                                                .onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
 | 
			
		||||
                                                    @Override
 | 
			
		||||
                                                    public void onSelected(ArrayList<Integer> selectedIds, ArrayList<String> selectedNames, String dataString) {
 | 
			
		||||
 | 
			
		||||
                                                        String labelIds = selectedIds.toString();
 | 
			
		||||
                                                        int[] integers;
 | 
			
		||||
                                                        if (selectedIds.size() > 0) {
 | 
			
		||||
 | 
			
		||||
                                                            String[] items = labelIds.replaceAll("\\[", "").replaceAll("\\]", "").replaceAll("\\s", "").split(",");
 | 
			
		||||
                                                            integers = new int[items.length];
 | 
			
		||||
                                                            for (int i = 0; i < integers.length; i++) {
 | 
			
		||||
                                                                integers[i] = Integer.parseInt(items[i]);
 | 
			
		||||
                                                            }
 | 
			
		||||
 | 
			
		||||
                                                        }
 | 
			
		||||
                                                        else {
 | 
			
		||||
                                                            integers = new int[0];
 | 
			
		||||
                                                        }
 | 
			
		||||
 | 
			
		||||
                                                        updateIssueLabels(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, integers, loginUid);
 | 
			
		||||
                                                        tinyDb.putBoolean("singleIssueUpdate", true);
 | 
			
		||||
                                                        CloseActivity();
 | 
			
		||||
                                                    }
 | 
			
		||||
 | 
			
		||||
                                                    @Override
 | 
			
		||||
                                                    public void onCancel() {
 | 
			
		||||
                                                        CloseActivity();
 | 
			
		||||
                                                    }
 | 
			
		||||
                                                });
 | 
			
		||||
 | 
			
		||||
                                    }
 | 
			
		||||
                                    else {
 | 
			
		||||
 | 
			
		||||
                                        multiSelectDialogLabels = new MultiSelectDialog()
 | 
			
		||||
                                                .title(getResources().getString(R.string.newIssueSelectLabelsListTitle))
 | 
			
		||||
                                                .titleSize(25)
 | 
			
		||||
                                                .positiveText(getResources().getString(R.string.saveButton))
 | 
			
		||||
                                                .negativeText(getResources().getString(R.string.cancelButton))
 | 
			
		||||
                                                .setMinSelectionLimit(0)
 | 
			
		||||
                                                .setMaxSelectionLimit(listOfLabels.size())
 | 
			
		||||
                                                .multiSelectList(listOfLabels)
 | 
			
		||||
                                                .onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
 | 
			
		||||
                                                    @Override
 | 
			
		||||
                                                    public void onSelected(ArrayList<Integer> selectedIds, ArrayList<String> selectedNames, String dataString) {
 | 
			
		||||
 | 
			
		||||
                                                        String labelIds = selectedIds.toString();
 | 
			
		||||
                                                        int[] integers;
 | 
			
		||||
                                                        if (selectedIds.size() > 0) {
 | 
			
		||||
 | 
			
		||||
                                                            String[] items = labelIds.replaceAll("\\[", "").replaceAll("\\]", "").replaceAll("\\s", "").split(",");
 | 
			
		||||
                                                            integers = new int[items.length];
 | 
			
		||||
                                                            for (int i = 0; i < integers.length; i++) {
 | 
			
		||||
                                                                integers[i] = Integer.parseInt(items[i]);
 | 
			
		||||
                                                            }
 | 
			
		||||
 | 
			
		||||
                                                        }
 | 
			
		||||
                                                        else {
 | 
			
		||||
                                                            integers = new int[0];
 | 
			
		||||
                                                        }
 | 
			
		||||
 | 
			
		||||
                                                        updateIssueLabels(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, integers, loginUid);
 | 
			
		||||
                                                        tinyDb.putBoolean("singleIssueUpdate", true);
 | 
			
		||||
                                                        CloseActivity();
 | 
			
		||||
 | 
			
		||||
                                                    }
 | 
			
		||||
 | 
			
		||||
                                                    @Override
 | 
			
		||||
                                                    public void onCancel() {
 | 
			
		||||
                                                        CloseActivity();
 | 
			
		||||
                                                    }
 | 
			
		||||
                                                });
 | 
			
		||||
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
                                    multiSelectDialogLabels.show(getSupportFragmentManager(), "issueMultiSelectDialog");
 | 
			
		||||
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            @Override
 | 
			
		||||
                            public void onFailure(@NonNull Call<List<Labels>> call, @NonNull Throwable t) {
 | 
			
		||||
                                Log.e("onFailure", t.toString());
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                        });
 | 
			
		||||
                        // get current issue labels
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                    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 if(response.code() == 403) {
 | 
			
		||||
 | 
			
		||||
                        Toasty.info(ctx, ctx.getString(R.string.authorizeError));
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                    else if(response.code() == 404) {
 | 
			
		||||
 | 
			
		||||
                        Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                    else {
 | 
			
		||||
 | 
			
		||||
                        Toasty.info(getApplicationContext(), getString(R.string.genericError));
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<List<Labels>> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void updateIssueLabels(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, int issueIndex, int[] issueLabels, String loginUid) {
 | 
			
		||||
 | 
			
		||||
        Labels patchIssueLabels = new Labels(issueLabels);
 | 
			
		||||
 | 
			
		||||
        Call<JsonElement> call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .updateIssueLabels(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, patchIssueLabels);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<JsonElement>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.code() == 200) {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(ctx, ctx.getString(R.string.labelsUpdated));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                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 if(response.code() == 403) {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(ctx, ctx.getString(R.string.authorizeError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 404) {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.genericError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void CloseActivity() {
 | 
			
		||||
        this.finish();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,200 @@
 | 
			
		||||
package org.mian.gitnex.activities;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.Nullable;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import androidx.appcompat.widget.Toolbar;
 | 
			
		||||
import androidx.lifecycle.Observer;
 | 
			
		||||
import androidx.lifecycle.ViewModelProviders;
 | 
			
		||||
import androidx.recyclerview.widget.DividerItemDecoration;
 | 
			
		||||
import androidx.recyclerview.widget.LinearLayoutManager;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
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.TextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.adapters.AdminGetUsersAdapter;
 | 
			
		||||
import org.mian.gitnex.fragments.AdminUsersBottomSheetFragment;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.models.UserInfo;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import org.mian.gitnex.viewmodels.AdminGetUsersViewModel;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class AdminGetUsersActivity extends AppCompatActivity implements AdminUsersBottomSheetFragment.BottomSheetListener {
 | 
			
		||||
 | 
			
		||||
    private View.OnClickListener onClickListener;
 | 
			
		||||
    final Context ctx = this;
 | 
			
		||||
    private AdminGetUsersAdapter adapter;
 | 
			
		||||
    private RecyclerView mRecyclerView;
 | 
			
		||||
    private TextView noDataUsers;
 | 
			
		||||
    private Boolean searchFilter = false;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        setContentView(R.layout.activity_admin_get_users);
 | 
			
		||||
 | 
			
		||||
        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");
 | 
			
		||||
 | 
			
		||||
        ImageView closeActivity = findViewById(R.id.close);
 | 
			
		||||
        noDataUsers = findViewById(R.id.noDataUsers);
 | 
			
		||||
        mRecyclerView = findViewById(R.id.recyclerView);
 | 
			
		||||
 | 
			
		||||
        final SwipeRefreshLayout swipeRefresh = findViewById(R.id.pullToRefresh);
 | 
			
		||||
 | 
			
		||||
        Toolbar toolbar = findViewById(R.id.toolbar);
 | 
			
		||||
        setSupportActionBar(toolbar);
 | 
			
		||||
 | 
			
		||||
        initCloseListener();
 | 
			
		||||
        closeActivity.setOnClickListener(onClickListener);
 | 
			
		||||
 | 
			
		||||
        mRecyclerView.setHasFixedSize(true);
 | 
			
		||||
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
 | 
			
		||||
 | 
			
		||||
        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
 | 
			
		||||
                DividerItemDecoration.VERTICAL);
 | 
			
		||||
        mRecyclerView.addItemDecoration(dividerItemDecoration);
 | 
			
		||||
 | 
			
		||||
        swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onRefresh() {
 | 
			
		||||
                new Handler().postDelayed(new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        swipeRefresh.setRefreshing(false);
 | 
			
		||||
                        AdminGetUsersViewModel.loadUsersList(getApplicationContext(), instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken));
 | 
			
		||||
                    }
 | 
			
		||||
                }, 500);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        fetchDataAsync(getApplicationContext(), instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken));
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void fetchDataAsync(Context ctx, String instanceUrl, String instanceToken) {
 | 
			
		||||
 | 
			
		||||
        AdminGetUsersViewModel usersModel = ViewModelProviders.of(this).get(AdminGetUsersViewModel.class);
 | 
			
		||||
 | 
			
		||||
        usersModel.getUsersList(ctx, instanceUrl, instanceToken).observe(this, new Observer<List<UserInfo>>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onChanged(@Nullable List<UserInfo> usersListMain) {
 | 
			
		||||
                adapter = new AdminGetUsersAdapter(getApplicationContext(), usersListMain);
 | 
			
		||||
                if(adapter.getItemCount() > 0) {
 | 
			
		||||
                    mRecyclerView.setVisibility(View.VISIBLE);
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noDataUsers.setVisibility(View.GONE);
 | 
			
		||||
                    searchFilter = true;
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    //adapter.notifyDataSetChanged();
 | 
			
		||||
                    //mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    mRecyclerView.setVisibility(View.GONE);
 | 
			
		||||
                    noDataUsers.setVisibility(View.VISIBLE);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean onCreateOptionsMenu(final Menu menu) {
 | 
			
		||||
 | 
			
		||||
        final MenuInflater inflater = getMenuInflater();
 | 
			
		||||
        inflater.inflate(R.menu.generic_nav_dotted_menu, menu);
 | 
			
		||||
 | 
			
		||||
        new Handler().postDelayed(new Runnable() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                if(searchFilter) {
 | 
			
		||||
 | 
			
		||||
                    boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getApplicationContext()));
 | 
			
		||||
 | 
			
		||||
                    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);
 | 
			
		||||
 | 
			
		||||
                    if(!connToInternet) {
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public boolean onQueryTextSubmit(String query) {
 | 
			
		||||
                            return true;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public boolean onQueryTextChange(String newText) {
 | 
			
		||||
                            adapter.getFilter().filter(newText);
 | 
			
		||||
                            return false;
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }, 500);
 | 
			
		||||
 | 
			
		||||
        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.genericMenu:
 | 
			
		||||
                AdminUsersBottomSheetFragment bottomSheet = new AdminUsersBottomSheetFragment();
 | 
			
		||||
                bottomSheet.show(getSupportFragmentManager(), "usersBottomSheet");
 | 
			
		||||
                return true;
 | 
			
		||||
            default:
 | 
			
		||||
                return super.onOptionsItemSelected(item);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onButtonClicked(String text) {
 | 
			
		||||
 | 
			
		||||
        switch (text) {
 | 
			
		||||
            case "newUser":
 | 
			
		||||
                startActivity(new Intent(AdminGetUsersActivity.this, CreateNewUserActivity.class));
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void initCloseListener() {
 | 
			
		||||
        onClickListener = new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                finish();
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,575 @@
 | 
			
		||||
package org.mian.gitnex.activities;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import retrofit2.Call;
 | 
			
		||||
import retrofit2.Callback;
 | 
			
		||||
import retrofit2.Response;
 | 
			
		||||
import android.app.DatePickerDialog;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.graphics.PorterDuff;
 | 
			
		||||
import android.graphics.drawable.GradientDrawable;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.widget.ArrayAdapter;
 | 
			
		||||
import android.widget.Button;
 | 
			
		||||
import android.widget.DatePicker;
 | 
			
		||||
import android.widget.EditText;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.Spinner;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import com.google.gson.JsonElement;
 | 
			
		||||
import com.hendraanggrian.appcompat.socialview.Mention;
 | 
			
		||||
import com.hendraanggrian.appcompat.widget.MentionArrayAdapter;
 | 
			
		||||
import com.hendraanggrian.appcompat.widget.SocialAutoCompleteTextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.helpers.AlertDialogs;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.helpers.MultiSelectDialog;
 | 
			
		||||
import org.mian.gitnex.models.Collaborators;
 | 
			
		||||
import org.mian.gitnex.models.CreateIssue;
 | 
			
		||||
import org.mian.gitnex.models.Labels;
 | 
			
		||||
import org.mian.gitnex.models.Milestones;
 | 
			
		||||
import org.mian.gitnex.models.MultiSelectModel;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import org.mian.gitnex.helpers.Toasty;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Calendar;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class CreateIssueActivity extends AppCompatActivity implements View.OnClickListener {
 | 
			
		||||
 | 
			
		||||
    private View.OnClickListener onClickListener;
 | 
			
		||||
    MultiSelectDialog multiSelectDialog;
 | 
			
		||||
    MultiSelectDialog multiSelectDialogLabels;
 | 
			
		||||
    private TextView assigneesList;
 | 
			
		||||
    private TextView newIssueLabels;
 | 
			
		||||
    private TextView newIssueDueDate;
 | 
			
		||||
    private Spinner newIssueMilestoneSpinner;
 | 
			
		||||
    private EditText newIssueTitle;
 | 
			
		||||
    private SocialAutoCompleteTextView newIssueDescription;
 | 
			
		||||
    private Button createNewIssueButton;
 | 
			
		||||
    private TextView labelsIdHolder;
 | 
			
		||||
    private boolean assigneesFlag;
 | 
			
		||||
    private boolean labelsFlag;
 | 
			
		||||
    final Context ctx = this;
 | 
			
		||||
 | 
			
		||||
    List<Milestones> milestonesList = new ArrayList<>();
 | 
			
		||||
    ArrayList<MultiSelectModel> listOfAssignees = new ArrayList<>();
 | 
			
		||||
    ArrayList<MultiSelectModel> listOfLabels= new ArrayList<>();
 | 
			
		||||
    private ArrayAdapter<Mention> defaultMentionAdapter;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        setContentView(R.layout.activity_create_issue);
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
 | 
			
		||||
        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");
 | 
			
		||||
 | 
			
		||||
        ImageView closeActivity = findViewById(R.id.close);
 | 
			
		||||
        assigneesList = findViewById(R.id.newIssueAssigneesList);
 | 
			
		||||
        newIssueLabels = findViewById(R.id.newIssueLabels);
 | 
			
		||||
        newIssueDueDate = findViewById(R.id.newIssueDueDate);
 | 
			
		||||
        createNewIssueButton = findViewById(R.id.createNewIssueButton);
 | 
			
		||||
        newIssueTitle = findViewById(R.id.newIssueTitle);
 | 
			
		||||
        newIssueDescription = findViewById(R.id.newIssueDescription);
 | 
			
		||||
        labelsIdHolder = findViewById(R.id.labelsIdHolder);
 | 
			
		||||
 | 
			
		||||
        defaultMentionAdapter = new MentionArrayAdapter<>(this);
 | 
			
		||||
        loadCollaboratorsList();
 | 
			
		||||
 | 
			
		||||
        newIssueDescription.setMentionAdapter(defaultMentionAdapter);
 | 
			
		||||
 | 
			
		||||
        initCloseListener();
 | 
			
		||||
        closeActivity.setOnClickListener(onClickListener);
 | 
			
		||||
 | 
			
		||||
        assigneesList.setOnClickListener(this);
 | 
			
		||||
        newIssueLabels.setOnClickListener(this);
 | 
			
		||||
        newIssueDueDate.setOnClickListener(this);
 | 
			
		||||
 | 
			
		||||
        newIssueMilestoneSpinner = findViewById(R.id.newIssueMilestoneSpinner);
 | 
			
		||||
        newIssueMilestoneSpinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
 | 
			
		||||
        getMilestones(instanceUrl, instanceToken, repoOwner, repoName, loginUid);
 | 
			
		||||
 | 
			
		||||
        getLabels(instanceUrl, instanceToken, repoOwner, repoName, loginUid);
 | 
			
		||||
        getCollaborators(instanceUrl, instanceToken, repoOwner, repoName, loginUid);
 | 
			
		||||
 | 
			
		||||
        disableProcessButton();
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
 | 
			
		||||
            createNewIssueButton.setEnabled(false);
 | 
			
		||||
            GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
            shape.setCornerRadius( 8 );
 | 
			
		||||
            shape.setColor(getResources().getColor(R.color.hintColor));
 | 
			
		||||
            createNewIssueButton.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
 | 
			
		||||
            createNewIssueButton.setOnClickListener(this);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void processNewIssue() {
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
        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");
 | 
			
		||||
 | 
			
		||||
        Milestones mModel = (Milestones) newIssueMilestoneSpinner.getSelectedItem();
 | 
			
		||||
 | 
			
		||||
        int newIssueMilestoneIdForm = mModel.getId();
 | 
			
		||||
        String newIssueTitleForm = newIssueTitle.getText().toString();
 | 
			
		||||
        String newIssueDescriptionForm = newIssueDescription.getText().toString();
 | 
			
		||||
        String newIssueAssigneesListForm = assigneesList.getText().toString();
 | 
			
		||||
        //String newIssueLabelsForm = newIssueLabels.getText().toString();
 | 
			
		||||
        String newIssueDueDateForm = newIssueDueDate.getText().toString();
 | 
			
		||||
        String newIssueLabelsIdHolderForm = labelsIdHolder.getText().toString();
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (newIssueTitleForm.equals("")) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.issueTitleEmpty));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /*if (newIssueDescriptionForm.equals("")) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.issueDescriptionEmpty));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }*/
 | 
			
		||||
 | 
			
		||||
        if (newIssueDueDateForm.equals("")) {
 | 
			
		||||
            newIssueDueDateForm = null;
 | 
			
		||||
        } else {
 | 
			
		||||
            newIssueDueDateForm = (AppUtil.customDateCombine(AppUtil.customDateFormat(newIssueDueDateForm)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        List<String> newIssueAssigneesListForm_ = new ArrayList<>(Arrays.asList(newIssueAssigneesListForm.split(",")));
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < newIssueAssigneesListForm_.size(); i++) {
 | 
			
		||||
            newIssueAssigneesListForm_.set(i, newIssueAssigneesListForm_.get(i).trim());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        int[] integers;
 | 
			
		||||
        if (!newIssueLabelsIdHolderForm.equals("")) {
 | 
			
		||||
 | 
			
		||||
            String[] items = newIssueLabelsIdHolderForm.replaceAll("\\[", "").replaceAll("\\]", "").replaceAll("\\s", "").split(",");
 | 
			
		||||
            integers = new int[items.length];
 | 
			
		||||
            for (int i = 0; i < integers.length; i++) {
 | 
			
		||||
                integers[i] = Integer.parseInt(items[i]);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            integers = new int[0];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //Log.i("FormData", String.valueOf(newIssueLabelsForm));
 | 
			
		||||
        disableProcessButton();
 | 
			
		||||
        createNewIssueFunc(instanceUrl, instanceToken, repoOwner, repoName, loginUid, newIssueDescriptionForm, newIssueDueDateForm, newIssueMilestoneIdForm, newIssueTitleForm, newIssueAssigneesListForm_, integers);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void loadCollaboratorsList() {
 | 
			
		||||
 | 
			
		||||
        final 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];
 | 
			
		||||
 | 
			
		||||
        Call<List<Collaborators>> call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<List<Collaborators>>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<List<Collaborators>> call, @NonNull Response<List<Collaborators>> response) {
 | 
			
		||||
 | 
			
		||||
                if (response.isSuccessful()) {
 | 
			
		||||
 | 
			
		||||
                    assert response.body() != null;
 | 
			
		||||
                    String fullName = "";
 | 
			
		||||
                    for (int i = 0; i < response.body().size(); i++) {
 | 
			
		||||
                        if(!response.body().get(i).getFull_name().equals("")) {
 | 
			
		||||
                            fullName = response.body().get(i).getFull_name();
 | 
			
		||||
                        }
 | 
			
		||||
                        defaultMentionAdapter.add(
 | 
			
		||||
                                new Mention(response.body().get(i).getUsername(), fullName, response.body().get(i).getAvatar_url()));
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                } else {
 | 
			
		||||
 | 
			
		||||
                    Log.i("onResponse", String.valueOf(response.code()));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.i("onFailure", t.getMessage());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void createNewIssueFunc(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String loginUid, String newIssueDescriptionForm, String newIssueDueDateForm, int newIssueMilestoneIdForm, String newIssueTitleForm, List<String> newIssueAssigneesListForm, int[] newIssueLabelsForm) {
 | 
			
		||||
 | 
			
		||||
        CreateIssue createNewIssueJson = new CreateIssue(loginUid, newIssueDescriptionForm, false, newIssueDueDateForm, newIssueMilestoneIdForm, newIssueTitleForm, newIssueAssigneesListForm, newIssueLabelsForm);
 | 
			
		||||
 | 
			
		||||
        Call<JsonElement> call3;
 | 
			
		||||
 | 
			
		||||
        call3 = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .createNewIssue(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, createNewIssueJson);
 | 
			
		||||
 | 
			
		||||
        call3.enqueue(new Callback<JsonElement>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response2) {
 | 
			
		||||
 | 
			
		||||
                if(response2.isSuccessful()) {
 | 
			
		||||
                    if(response2.code() == 201) {
 | 
			
		||||
 | 
			
		||||
                        //Log.i("isSuccessful1", String.valueOf(response2.body()));
 | 
			
		||||
                        TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
                        tinyDb.putBoolean("resumeIssues", true);
 | 
			
		||||
 | 
			
		||||
                        Toasty.info(getApplicationContext(), getString(R.string.issueCreated));
 | 
			
		||||
                        enableProcessButton();
 | 
			
		||||
                        finish();
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response2.code() == 401) {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedMessage),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.issueCreatedError));
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    //Log.i("isSuccessful2", String.valueOf(response2.body()));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
                enableProcessButton();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void initCloseListener() {
 | 
			
		||||
        onClickListener = new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                finish();
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void getMilestones(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) {
 | 
			
		||||
 | 
			
		||||
        Call<List<Milestones>> call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .getMilestones(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<List<Milestones>>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<List<Milestones>> call, @NonNull retrofit2.Response<List<Milestones>> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.isSuccessful()) {
 | 
			
		||||
                    if(response.code() == 200) {
 | 
			
		||||
 | 
			
		||||
                        List<Milestones> milestonesList_ = response.body();
 | 
			
		||||
 | 
			
		||||
                        milestonesList.add(new Milestones(0,"No milestone"));
 | 
			
		||||
                        assert milestonesList_ != null;
 | 
			
		||||
                        if(milestonesList_.size() > 0) {
 | 
			
		||||
                            for (int i = 0; i < milestonesList_.size(); i++) {
 | 
			
		||||
 | 
			
		||||
                                //String mStone = getString(R.string.spinnerMilestoneText, milestonesList_.get(i).getTitle(), milestonesList_.get(i).getState());
 | 
			
		||||
                                if(milestonesList_.get(i).getState().equals(getString(R.string.issueStatusOpen))) {
 | 
			
		||||
                                    Milestones data = new Milestones(
 | 
			
		||||
                                            milestonesList_.get(i).getId(),
 | 
			
		||||
                                            milestonesList_.get(i).getTitle()
 | 
			
		||||
                                    );
 | 
			
		||||
                                    milestonesList.add(data);
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        ArrayAdapter<Milestones> adapter = new ArrayAdapter<>(getApplicationContext(),
 | 
			
		||||
                                R.layout.spinner_item, milestonesList);
 | 
			
		||||
 | 
			
		||||
                        adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
 | 
			
		||||
                        newIssueMilestoneSpinner.setAdapter(adapter);
 | 
			
		||||
                        enableProcessButton();
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<List<Milestones>> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void getCollaborators(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) {
 | 
			
		||||
 | 
			
		||||
        Call<List<Collaborators>> call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<List<Collaborators>>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<List<Collaborators>> call, @NonNull retrofit2.Response<List<Collaborators>> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.isSuccessful()) {
 | 
			
		||||
                    if(response.code() == 200) {
 | 
			
		||||
 | 
			
		||||
                        List<Collaborators> assigneesList_ = response.body();
 | 
			
		||||
 | 
			
		||||
                        assert assigneesList_ != null;
 | 
			
		||||
                        if(assigneesList_.size() > 0) {
 | 
			
		||||
                            for (int i = 0; i < assigneesList_.size(); i++) {
 | 
			
		||||
 | 
			
		||||
                                /*String assigneesCopy;
 | 
			
		||||
                                if(!assigneesList_.get(i).getFull_name().equals("")) {
 | 
			
		||||
                                    assigneesCopy = getString(R.string.dialogAssignessText, assigneesList_.get(i).getFull_name(), assigneesList_.get(i).getLogin());
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    assigneesCopy = assigneesList_.get(i).getLogin();
 | 
			
		||||
                                }*/
 | 
			
		||||
                                listOfAssignees.add(new MultiSelectModel(assigneesList_.get(i).getId(), assigneesList_.get(i).getLogin().trim()));
 | 
			
		||||
 | 
			
		||||
                            }
 | 
			
		||||
                            assigneesFlag = true;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        multiSelectDialog = new MultiSelectDialog()
 | 
			
		||||
                                .title(getResources().getString(R.string.newIssueSelectAssigneesListTitle))
 | 
			
		||||
                                .titleSize(25)
 | 
			
		||||
                                .positiveText(getResources().getString(R.string.okButton))
 | 
			
		||||
                                .negativeText(getResources().getString(R.string.cancelButton))
 | 
			
		||||
                                .setMinSelectionLimit(0)
 | 
			
		||||
                                .setMaxSelectionLimit(listOfAssignees.size())
 | 
			
		||||
                                .multiSelectList(listOfAssignees)
 | 
			
		||||
                                .onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
 | 
			
		||||
                                    @Override
 | 
			
		||||
                                    public void onSelected(ArrayList<Integer> selectedIds, ArrayList<String> selectedNames, String dataString) {
 | 
			
		||||
 | 
			
		||||
                                        assigneesList.setText(dataString);
 | 
			
		||||
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
                                    @Override
 | 
			
		||||
                                    public void onCancel() {
 | 
			
		||||
                                        //Log.d("multiSelect","Dialog cancelled");
 | 
			
		||||
 | 
			
		||||
                                    }
 | 
			
		||||
                                });
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void getLabels(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) {
 | 
			
		||||
 | 
			
		||||
        Call<List<Labels>> call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .getlabels(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<List<Labels>>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<List<Labels>> call, @NonNull retrofit2.Response<List<Labels>> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.isSuccessful()) {
 | 
			
		||||
                    if(response.code() == 200) {
 | 
			
		||||
 | 
			
		||||
                        List<Labels> labelsList_ = response.body();
 | 
			
		||||
 | 
			
		||||
                        assert labelsList_ != null;
 | 
			
		||||
                        if(labelsList_.size() > 0) {
 | 
			
		||||
                            for (int i = 0; i < labelsList_.size(); i++) {
 | 
			
		||||
 | 
			
		||||
                                listOfLabels.add(new MultiSelectModel(labelsList_.get(i).getId(), labelsList_.get(i).getName().trim()));
 | 
			
		||||
 | 
			
		||||
                            }
 | 
			
		||||
                            labelsFlag = true;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        multiSelectDialogLabels = new MultiSelectDialog()
 | 
			
		||||
                                .title(getResources().getString(R.string.newIssueSelectLabelsListTitle))
 | 
			
		||||
                                .titleSize(25)
 | 
			
		||||
                                .positiveText(getResources().getString(R.string.okButton))
 | 
			
		||||
                                .negativeText(getResources().getString(R.string.cancelButton))
 | 
			
		||||
                                .setMinSelectionLimit(0)
 | 
			
		||||
                                .setMaxSelectionLimit(listOfLabels.size())
 | 
			
		||||
                                .multiSelectList(listOfLabels)
 | 
			
		||||
                                .onSubmit(new MultiSelectDialog.SubmitCallbackListener() {
 | 
			
		||||
                                    @Override
 | 
			
		||||
                                    public void onSelected(ArrayList<Integer> selectedIds, ArrayList<String> selectedNames, String dataString) {
 | 
			
		||||
 | 
			
		||||
                                        newIssueLabels.setText(dataString.trim());
 | 
			
		||||
                                        labelsIdHolder.setText(selectedIds.toString());
 | 
			
		||||
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
                                    @Override
 | 
			
		||||
                                    public void onCancel() {
 | 
			
		||||
                                        //Log.d("multiSelect","Dialog cancelled");
 | 
			
		||||
 | 
			
		||||
                                    }
 | 
			
		||||
                                });
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<List<Labels>> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onClick(View v) {
 | 
			
		||||
        if (v == assigneesList) {
 | 
			
		||||
            if(assigneesFlag) {
 | 
			
		||||
                multiSelectDialog.show(getSupportFragmentManager(), "multiSelectDialog");
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                Toasty.info(getApplicationContext(), getResources().getString(R.string.noAssigneesFound));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (v == newIssueLabels) {
 | 
			
		||||
            if(labelsFlag) {
 | 
			
		||||
                multiSelectDialogLabels.show(getSupportFragmentManager(), "multiSelectDialogLabels");
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                Toasty.info(getApplicationContext(), getResources().getString(R.string.noLabelsFound));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (v == newIssueDueDate) {
 | 
			
		||||
 | 
			
		||||
            final Calendar c = Calendar.getInstance();
 | 
			
		||||
            int mYear = c.get(Calendar.YEAR);
 | 
			
		||||
            final int mMonth = c.get(Calendar.MONTH);
 | 
			
		||||
            final int mDay = c.get(Calendar.DAY_OF_MONTH);
 | 
			
		||||
 | 
			
		||||
            DatePickerDialog datePickerDialog = new DatePickerDialog(this,
 | 
			
		||||
                    new DatePickerDialog.OnDateSetListener() {
 | 
			
		||||
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void onDateSet(DatePicker view, int year,
 | 
			
		||||
                                              int monthOfYear, int dayOfMonth) {
 | 
			
		||||
 | 
			
		||||
                            newIssueDueDate.setText(getString(R.string.setDueDate, year, (monthOfYear + 1), dayOfMonth));
 | 
			
		||||
 | 
			
		||||
                        }
 | 
			
		||||
                    }, mYear, mMonth, mDay);
 | 
			
		||||
            datePickerDialog.show();
 | 
			
		||||
        }
 | 
			
		||||
        else if(v == createNewIssueButton) {
 | 
			
		||||
            processNewIssue();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void disableProcessButton() {
 | 
			
		||||
 | 
			
		||||
        createNewIssueButton.setEnabled(false);
 | 
			
		||||
        GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
        shape.setCornerRadius( 8 );
 | 
			
		||||
        shape.setColor(getResources().getColor(R.color.hintColor));
 | 
			
		||||
        createNewIssueButton.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void enableProcessButton() {
 | 
			
		||||
 | 
			
		||||
        createNewIssueButton.setEnabled(true);
 | 
			
		||||
        GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
        shape.setCornerRadius( 8 );
 | 
			
		||||
        shape.setColor(getResources().getColor(R.color.btnBackground));
 | 
			
		||||
        createNewIssueButton.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,435 @@
 | 
			
		||||
package org.mian.gitnex.activities;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.ColorInt;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import androidx.core.content.ContextCompat;
 | 
			
		||||
import retrofit2.Call;
 | 
			
		||||
import retrofit2.Callback;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.graphics.Color;
 | 
			
		||||
import android.graphics.drawable.GradientDrawable;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.widget.Button;
 | 
			
		||||
import android.widget.EditText;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import com.pes.androidmaterialcolorpickerdialog.ColorPicker;
 | 
			
		||||
import com.pes.androidmaterialcolorpickerdialog.ColorPickerCallback;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.helpers.AlertDialogs;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.helpers.Toasty;
 | 
			
		||||
import org.mian.gitnex.models.CreateLabel;
 | 
			
		||||
import org.mian.gitnex.models.Labels;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import org.mian.gitnex.viewmodels.LabelsViewModel;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class CreateLabelActivity extends AppCompatActivity {
 | 
			
		||||
 | 
			
		||||
    private View.OnClickListener onClickListener;
 | 
			
		||||
    private TextView colorPicker;
 | 
			
		||||
    private EditText labelName;
 | 
			
		||||
    private Button createLabelButton;
 | 
			
		||||
    final Context ctx = this;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        setContentView(R.layout.activity_create_label);
 | 
			
		||||
 | 
			
		||||
        final TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
        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");
 | 
			
		||||
 | 
			
		||||
        if(getIntent().getStringExtra("labelAction") != null && getIntent().getStringExtra("labelAction").equals("delete")) {
 | 
			
		||||
 | 
			
		||||
            deleteLabel(instanceUrl, instanceToken, repoOwner, repoName, Integer.valueOf(getIntent().getStringExtra("labelId")), loginUid);
 | 
			
		||||
            finish();
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
 | 
			
		||||
        ImageView closeActivity = findViewById(R.id.close);
 | 
			
		||||
        colorPicker = findViewById(R.id.colorPicker);
 | 
			
		||||
        labelName = findViewById(R.id.labelName);
 | 
			
		||||
        createLabelButton = findViewById(R.id.createLabelButton);
 | 
			
		||||
 | 
			
		||||
        final ColorPicker cp = new ColorPicker(CreateLabelActivity.this, 235, 113, 33);
 | 
			
		||||
 | 
			
		||||
        initCloseListener();
 | 
			
		||||
        closeActivity.setOnClickListener(onClickListener);
 | 
			
		||||
        colorPicker.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            public void onClick(View v) {
 | 
			
		||||
                cp.show();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        cp.setCallback(new ColorPickerCallback() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onColorChosen(@ColorInt int color) {
 | 
			
		||||
 | 
			
		||||
                //Log.i("#Hex no alpha", String.format("#%06X", (0xFFFFFF & color)));
 | 
			
		||||
                colorPicker.setBackgroundColor(color);
 | 
			
		||||
                tinyDb.putString("labelColor", String.format("#%06X", (0xFFFFFF & color)));
 | 
			
		||||
                cp.dismiss();
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if(getIntent().getStringExtra("labelAction") != null && getIntent().getStringExtra("labelAction").equals("edit")) {
 | 
			
		||||
 | 
			
		||||
            labelName.setText(getIntent().getStringExtra("labelTitle"));
 | 
			
		||||
            int labelColor_ = Color.parseColor("#" + getIntent().getStringExtra("labelColor"));
 | 
			
		||||
            colorPicker.setBackgroundColor(labelColor_);
 | 
			
		||||
            tinyDb.putString("labelColorDefault", "#" + getIntent().getStringExtra("labelColor"));
 | 
			
		||||
 | 
			
		||||
            TextView toolbar_title = findViewById(R.id.toolbar_title);
 | 
			
		||||
            toolbar_title.setText(getResources().getString(R.string.pageTitleLabelUpdate));
 | 
			
		||||
            createLabelButton.setText(getResources().getString(R.string.newUpdateButtonCopy));
 | 
			
		||||
 | 
			
		||||
            createLabelButton.setOnClickListener(updateLabelListener);
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
 | 
			
		||||
            createLabelButton.setEnabled(false);
 | 
			
		||||
            GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
            shape.setCornerRadius( 8 );
 | 
			
		||||
            shape.setColor(getResources().getColor(R.color.hintColor));
 | 
			
		||||
            createLabelButton.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
 | 
			
		||||
            createLabelButton.setOnClickListener(createLabelListener);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private View.OnClickListener createLabelListener = new View.OnClickListener() {
 | 
			
		||||
        public void onClick(View v) {
 | 
			
		||||
            processCreateLabel();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    private View.OnClickListener updateLabelListener = new View.OnClickListener() {
 | 
			
		||||
        public void onClick(View v) {
 | 
			
		||||
            processUpdateLabel();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    private void processUpdateLabel() {
 | 
			
		||||
 | 
			
		||||
        final TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
        AppUtil appUtil = new AppUtil();
 | 
			
		||||
        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");
 | 
			
		||||
 | 
			
		||||
        String updateLabelName = labelName.getText().toString();
 | 
			
		||||
 | 
			
		||||
        String updateLabelColor;
 | 
			
		||||
        if(tinyDb.getString("labelColor").isEmpty()) {
 | 
			
		||||
            updateLabelColor = tinyDb.getString("labelColorDefault");
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            updateLabelColor = tinyDb.getString("labelColor");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(updateLabelName.equals("")) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.labelEmptyError));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!appUtil.checkStrings(updateLabelName)) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.labelNameError));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        disableProcessButton();
 | 
			
		||||
        patchLabel(instanceUrl, instanceToken, repoOwner, repoName, updateLabelName, updateLabelColor, Integer.valueOf(getIntent().getStringExtra("labelId")), loginUid);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void processCreateLabel() {
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
        AppUtil appUtil = new AppUtil();
 | 
			
		||||
        TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
        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");
 | 
			
		||||
 | 
			
		||||
        String newLabelName = labelName.getText().toString();
 | 
			
		||||
        String newLabelColor;
 | 
			
		||||
        if(tinyDb.getString("labelColor").isEmpty()) {
 | 
			
		||||
            newLabelColor = String.format("#%06X", (0xFFFFFF & ContextCompat.getColor(getApplicationContext(), R.color.releasePre)));
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            newLabelColor = tinyDb.getString("labelColor");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(newLabelName.equals("")) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.labelEmptyError));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!appUtil.checkStrings(newLabelName)) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.labelNameError));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        disableProcessButton();
 | 
			
		||||
        createNewLabel(instanceUrl, instanceToken, repoOwner, repoName, newLabelName, newLabelColor, loginUid);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void createNewLabel(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String newLabelName, String newLabelColor, String loginUid) {
 | 
			
		||||
 | 
			
		||||
        CreateLabel createLabelFunc = new CreateLabel(newLabelName, newLabelColor);
 | 
			
		||||
        final TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
 | 
			
		||||
        Call<CreateLabel> call;
 | 
			
		||||
 | 
			
		||||
        call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .createLabel(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, createLabelFunc);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<CreateLabel>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<CreateLabel> call, @NonNull retrofit2.Response<CreateLabel> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.code() == 201) {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.labelCreated));
 | 
			
		||||
                    tinyDb.putString("labelColor", "");
 | 
			
		||||
                    tinyDb.putBoolean("labelsRefresh", true);
 | 
			
		||||
                    finish();
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 401) {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedMessage),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    tinyDb.putString("labelColor", "");
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.labelGeneralError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<CreateLabel> call, @NonNull Throwable t) {
 | 
			
		||||
                tinyDb.putString("labelColor", "");
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
                enableProcessButton();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void patchLabel(final String instanceUrl, final String instanceToken, String repoOwner, String repoName, String updateLabelName, String updateLabelColor, int labelId, String loginUid) {
 | 
			
		||||
 | 
			
		||||
        CreateLabel createLabelFunc = new CreateLabel(updateLabelName, updateLabelColor);
 | 
			
		||||
        final TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
 | 
			
		||||
        Call<CreateLabel> call;
 | 
			
		||||
 | 
			
		||||
        call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .patchLabel(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, labelId, createLabelFunc);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<CreateLabel>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<CreateLabel> call, @NonNull retrofit2.Response<CreateLabel> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.isSuccessful()) {
 | 
			
		||||
                    if(response.code() == 200) {
 | 
			
		||||
 | 
			
		||||
                        Toasty.info(getApplicationContext(), getString(R.string.labelUpdated));
 | 
			
		||||
                        tinyDb.putString("labelColor", "");
 | 
			
		||||
                        tinyDb.putBoolean("labelsRefresh", true);
 | 
			
		||||
                        tinyDb.putString("labelColorDefault", "");
 | 
			
		||||
                        getIntent().removeExtra("labelAction");
 | 
			
		||||
                        getIntent().removeExtra("labelId");
 | 
			
		||||
                        getIntent().removeExtra("labelTitle");
 | 
			
		||||
                        getIntent().removeExtra("labelColor");
 | 
			
		||||
                        finish();
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 401) {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedMessage),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    tinyDb.putString("labelColor", "");
 | 
			
		||||
                    tinyDb.putString("labelColorDefault", "");
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.labelGeneralError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<CreateLabel> call, @NonNull Throwable t) {
 | 
			
		||||
                tinyDb.putString("labelColor", "");
 | 
			
		||||
                tinyDb.putString("labelColorDefault", "");
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
                enableProcessButton();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void initCloseListener() {
 | 
			
		||||
        onClickListener = new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                getIntent().removeExtra("labelAction");
 | 
			
		||||
                getIntent().removeExtra("labelId");
 | 
			
		||||
                getIntent().removeExtra("labelTitle");
 | 
			
		||||
                getIntent().removeExtra("labelColor");
 | 
			
		||||
                finish();
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void deleteLabel(final String instanceUrl, final String instanceToken, final String repoOwner, final String repoName, int labelId, String loginUid) {
 | 
			
		||||
 | 
			
		||||
        Call<Labels> call;
 | 
			
		||||
 | 
			
		||||
        call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .deleteLabel(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, labelId);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<Labels>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<Labels> call, @NonNull retrofit2.Response<Labels> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.isSuccessful()) {
 | 
			
		||||
                    if(response.code() == 204) {
 | 
			
		||||
 | 
			
		||||
                        Toasty.info(getApplicationContext(), getString(R.string.labelDeleteText));
 | 
			
		||||
                        LabelsViewModel.loadLabelsList(instanceUrl, instanceToken, repoOwner, repoName);
 | 
			
		||||
                        getIntent().removeExtra("labelAction");
 | 
			
		||||
                        getIntent().removeExtra("labelId");
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                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 {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.labelDeleteErrorText));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<Labels> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void disableProcessButton() {
 | 
			
		||||
 | 
			
		||||
        createLabelButton.setEnabled(false);
 | 
			
		||||
        GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
        shape.setCornerRadius( 8 );
 | 
			
		||||
        shape.setColor(getResources().getColor(R.color.hintColor));
 | 
			
		||||
        createLabelButton.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void enableProcessButton() {
 | 
			
		||||
 | 
			
		||||
        createLabelButton.setEnabled(true);
 | 
			
		||||
        GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
        shape.setCornerRadius( 8 );
 | 
			
		||||
        shape.setColor(getResources().getColor(R.color.btnBackground));
 | 
			
		||||
        createLabelButton.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,226 @@
 | 
			
		||||
package org.mian.gitnex.activities;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import retrofit2.Call;
 | 
			
		||||
import retrofit2.Callback;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.graphics.drawable.GradientDrawable;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.util.Patterns;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.widget.Button;
 | 
			
		||||
import android.widget.EditText;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.helpers.AlertDialogs;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.helpers.Toasty;
 | 
			
		||||
import org.mian.gitnex.models.UserInfo;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class CreateNewUserActivity extends AppCompatActivity {
 | 
			
		||||
 | 
			
		||||
    private View.OnClickListener onClickListener;
 | 
			
		||||
    private EditText fullName;
 | 
			
		||||
    private EditText userUserName;
 | 
			
		||||
    private EditText userEmail;
 | 
			
		||||
    private EditText userPassword;
 | 
			
		||||
    private Button createUserButton;
 | 
			
		||||
    final Context ctx = this;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        setContentView(R.layout.activity_create_new_user);
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
 | 
			
		||||
        ImageView closeActivity = findViewById(R.id.close);
 | 
			
		||||
        createUserButton = findViewById(R.id.createUserButton);
 | 
			
		||||
        fullName = findViewById(R.id.fullName);
 | 
			
		||||
        userUserName = findViewById(R.id.userUserName);
 | 
			
		||||
        userEmail = findViewById(R.id.userEmail);
 | 
			
		||||
        userPassword = findViewById(R.id.userPassword);
 | 
			
		||||
 | 
			
		||||
        initCloseListener();
 | 
			
		||||
        closeActivity.setOnClickListener(onClickListener);
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
 | 
			
		||||
            disableProcessButton();
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
 | 
			
		||||
            createUserButton.setOnClickListener(createNewUserListener);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void processCreateNewUser() {
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
        AppUtil appUtil = new AppUtil();
 | 
			
		||||
        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 newFullName = fullName.getText().toString().trim();
 | 
			
		||||
        String newUserName = userUserName.getText().toString().trim();
 | 
			
		||||
        String newUserEmail = userEmail.getText().toString().trim();
 | 
			
		||||
        String newUserPassword = userPassword.getText().toString();
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(newFullName.equals("") || newUserName.equals("") | newUserEmail.equals("") || newUserPassword.equals("")) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.emptyFields));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!appUtil.checkStrings(newFullName)) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.userInvalidFullName));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!appUtil.checkStringsWithAlphaNumeric(newUserName)) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.userInvalidUserName));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!Patterns.EMAIL_ADDRESS.matcher(newUserEmail).matches()) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.userInvalidEmail));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        disableProcessButton();
 | 
			
		||||
        createNewUser(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), newFullName, newUserName, newUserEmail, newUserPassword);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void createNewUser(final String instanceUrl, final String instanceToken, String newFullName, String newUserName, String newUserEmail, String newUserPassword) {
 | 
			
		||||
 | 
			
		||||
        UserInfo createUser = new UserInfo(newUserEmail, newFullName, newUserName, newUserPassword, newUserName, 0, true);
 | 
			
		||||
 | 
			
		||||
        Call<UserInfo> call;
 | 
			
		||||
 | 
			
		||||
        call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .createNewUser(instanceToken, createUser);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<UserInfo>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<UserInfo> call, @NonNull retrofit2.Response<UserInfo> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.code() == 201) {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.userCreatedText));
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    finish();
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 401) {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedMessage),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 403) {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    Toasty.info(ctx, ctx.getString(R.string.authorizeError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 404) {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 422) {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    Toasty.info(ctx, ctx.getString(R.string.userExistsError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.genericError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<UserInfo> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
                enableProcessButton();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private View.OnClickListener createNewUserListener = new View.OnClickListener() {
 | 
			
		||||
        public void onClick(View v) {
 | 
			
		||||
            processCreateNewUser();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    private void initCloseListener() {
 | 
			
		||||
        onClickListener = new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                finish();
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void disableProcessButton() {
 | 
			
		||||
 | 
			
		||||
        createUserButton.setEnabled(false);
 | 
			
		||||
        GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
        shape.setCornerRadius( 8 );
 | 
			
		||||
        shape.setColor(getResources().getColor(R.color.hintColor));
 | 
			
		||||
        createUserButton.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void enableProcessButton() {
 | 
			
		||||
 | 
			
		||||
        createUserButton.setEnabled(true);
 | 
			
		||||
        GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
        shape.setCornerRadius( 8 );
 | 
			
		||||
        shape.setColor(getResources().getColor(R.color.btnBackground));
 | 
			
		||||
        createUserButton.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,310 @@
 | 
			
		||||
package org.mian.gitnex.activities;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import retrofit2.Call;
 | 
			
		||||
import retrofit2.Callback;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.graphics.PorterDuff;
 | 
			
		||||
import android.graphics.drawable.GradientDrawable;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.widget.AdapterView;
 | 
			
		||||
import android.widget.ArrayAdapter;
 | 
			
		||||
import android.widget.Button;
 | 
			
		||||
import android.widget.CheckBox;
 | 
			
		||||
import android.widget.EditText;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.Spinner;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.helpers.AlertDialogs;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.helpers.Toasty;
 | 
			
		||||
import org.mian.gitnex.models.Branches;
 | 
			
		||||
import org.mian.gitnex.models.Releases;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class CreateReleaseActivity extends AppCompatActivity {
 | 
			
		||||
 | 
			
		||||
    private View.OnClickListener onClickListener;
 | 
			
		||||
    public ImageView closeActivity;
 | 
			
		||||
    private EditText releaseTagName;
 | 
			
		||||
    private Spinner releaseBranch;
 | 
			
		||||
    private EditText releaseTitle;
 | 
			
		||||
    private EditText releaseContent;
 | 
			
		||||
    private CheckBox releaseType;
 | 
			
		||||
    private CheckBox releaseDraft;
 | 
			
		||||
    private Button createNewRelease;
 | 
			
		||||
    final Context ctx = this;
 | 
			
		||||
 | 
			
		||||
    List<Branches> branchesList = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        setContentView(R.layout.activity_create_release);
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
 | 
			
		||||
        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];
 | 
			
		||||
 | 
			
		||||
        closeActivity = findViewById(R.id.close);
 | 
			
		||||
        releaseTagName = findViewById(R.id.releaseTagName);
 | 
			
		||||
        releaseTitle = findViewById(R.id.releaseTitle);
 | 
			
		||||
        releaseContent = findViewById(R.id.releaseContent);
 | 
			
		||||
        releaseType = findViewById(R.id.releaseType);
 | 
			
		||||
        releaseDraft = findViewById(R.id.releaseDraft);
 | 
			
		||||
 | 
			
		||||
        initCloseListener();
 | 
			
		||||
        closeActivity.setOnClickListener(onClickListener);
 | 
			
		||||
 | 
			
		||||
        releaseBranch = findViewById(R.id.releaseBranch);
 | 
			
		||||
        releaseBranch.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
 | 
			
		||||
        getBranches(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
 | 
			
		||||
        releaseBranch.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
 | 
			
		||||
                Branches branch = (Branches) parent.getSelectedItem();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onNothingSelected(AdapterView<?> parent) {
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        createNewRelease = findViewById(R.id.createNewRelease);
 | 
			
		||||
        disableProcessButton();
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
 | 
			
		||||
            disableProcessButton();
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
 | 
			
		||||
            createNewRelease.setOnClickListener(createReleaseListener);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private View.OnClickListener createReleaseListener = new View.OnClickListener() {
 | 
			
		||||
        public void onClick(View v) {
 | 
			
		||||
            processNewRelease();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    private void processNewRelease() {
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
 | 
			
		||||
        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 newReleaseTagName = releaseTagName.getText().toString();
 | 
			
		||||
        String newReleaseTitle = releaseTitle.getText().toString();
 | 
			
		||||
        String newReleaseContent = releaseContent.getText().toString();
 | 
			
		||||
        String newReleaseBranch = releaseBranch.getSelectedItem().toString();
 | 
			
		||||
        boolean newReleaseType = releaseType.isChecked();
 | 
			
		||||
        boolean newReleaseDraft = releaseDraft.isChecked();
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(newReleaseTagName.equals("")) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.tagNameErrorEmpty));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(newReleaseTitle.equals("")) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.titleErrorEmpty));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        disableProcessButton();
 | 
			
		||||
        createNewReleaseFunc(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, newReleaseTagName, newReleaseTitle, newReleaseContent, newReleaseBranch, newReleaseType, newReleaseDraft);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void createNewReleaseFunc(final String instanceUrl, final String token, String repoOwner, String repoName, String newReleaseTagName, String newReleaseTitle, String newReleaseContent, String newReleaseBranch, boolean newReleaseType, boolean newReleaseDraft) {
 | 
			
		||||
 | 
			
		||||
        Releases createReleaseJson = new Releases(newReleaseContent, newReleaseDraft, newReleaseTitle, newReleaseType, newReleaseTagName, newReleaseBranch);
 | 
			
		||||
 | 
			
		||||
        Call<Releases> call;
 | 
			
		||||
 | 
			
		||||
        call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .createNewRelease(token, repoOwner, repoName, createReleaseJson);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<Releases>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<Releases> call, @NonNull retrofit2.Response<Releases> response) {
 | 
			
		||||
 | 
			
		||||
                if (response.code() == 201) {
 | 
			
		||||
 | 
			
		||||
                    TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
                    tinyDb.putBoolean("updateReleases", true);
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.releaseCreatedText));
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    finish();
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 401) {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                     AlertDialogs.authorizationTokenRevokedDialog(ctx, ctx.getResources().getString(R.string.alertDialogTokenRevokedTitle),
 | 
			
		||||
                             ctx.getResources().getString(R.string.alertDialogTokenRevokedMessage),
 | 
			
		||||
                             ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
 | 
			
		||||
                             ctx.getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 403) {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    Toasty.info(ctx, ctx.getString(R.string.authorizeError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 404) {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    Toasty.info(ctx, ctx.getString(R.string.genericError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<Releases> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
                enableProcessButton();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void getBranches(String instanceUrl, String instanceToken, final String repoOwner, final String repoName) {
 | 
			
		||||
 | 
			
		||||
        Call<List<Branches>> call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .getBranches(instanceToken, repoOwner, repoName);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<List<Branches>>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<List<Branches>> call, @NonNull retrofit2.Response<List<Branches>> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.isSuccessful()) {
 | 
			
		||||
                    if(response.code() == 200) {
 | 
			
		||||
 | 
			
		||||
                        List<Branches> branchesList_ = response.body();
 | 
			
		||||
 | 
			
		||||
                        assert branchesList_ != null;
 | 
			
		||||
                        if(branchesList_.size() > 0) {
 | 
			
		||||
                            for (int i = 0; i < branchesList_.size(); i++) {
 | 
			
		||||
 | 
			
		||||
                                Branches data = new Branches(
 | 
			
		||||
                                        branchesList_.get(i).getName()
 | 
			
		||||
                                );
 | 
			
		||||
                                branchesList.add(data);
 | 
			
		||||
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        ArrayAdapter<Branches> adapter = new ArrayAdapter<>(getApplicationContext(),
 | 
			
		||||
                                R.layout.spinner_item, branchesList);
 | 
			
		||||
 | 
			
		||||
                        adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
 | 
			
		||||
                        releaseBranch.setAdapter(adapter);
 | 
			
		||||
                        enableProcessButton();
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                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));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<List<Branches>> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void initCloseListener() {
 | 
			
		||||
        onClickListener = new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                finish();
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void disableProcessButton() {
 | 
			
		||||
 | 
			
		||||
        createNewRelease.setEnabled(false);
 | 
			
		||||
        GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
        shape.setCornerRadius( 8 );
 | 
			
		||||
        shape.setColor(getResources().getColor(R.color.hintColor));
 | 
			
		||||
        createNewRelease.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void enableProcessButton() {
 | 
			
		||||
 | 
			
		||||
        createNewRelease.setEnabled(true);
 | 
			
		||||
        GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
        shape.setCornerRadius( 8 );
 | 
			
		||||
        shape.setColor(getResources().getColor(R.color.btnBackground));
 | 
			
		||||
        createNewRelease.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,378 @@
 | 
			
		||||
package org.mian.gitnex.activities;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.app.AlertDialog;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import retrofit2.Call;
 | 
			
		||||
import retrofit2.Callback;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.DialogInterface;
 | 
			
		||||
import android.graphics.drawable.GradientDrawable;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.widget.Button;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.helpers.AlertDialogs;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.helpers.Toasty;
 | 
			
		||||
import org.mian.gitnex.models.Teams;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class CreateTeamByOrgActivity extends AppCompatActivity implements View.OnClickListener {
 | 
			
		||||
 | 
			
		||||
    final Context ctx = CreateTeamByOrgActivity.this;
 | 
			
		||||
    private View.OnClickListener onClickListener;
 | 
			
		||||
    private TextView teamName;
 | 
			
		||||
    private TextView teamDesc;
 | 
			
		||||
    private TextView teamPermission;
 | 
			
		||||
    private TextView teamPermissionDetail;
 | 
			
		||||
    private TextView teamAccessControls;
 | 
			
		||||
    private TextView teamAccessControlsArray;
 | 
			
		||||
    private Button createTeamButton;
 | 
			
		||||
    private String[] permissionList = {"Read", "Write", "Admin"};
 | 
			
		||||
    public int permissionSelectedChoice = -1;
 | 
			
		||||
 | 
			
		||||
    private String[] accessControlsList = new String[] {
 | 
			
		||||
            "Code",
 | 
			
		||||
            "Issues",
 | 
			
		||||
            "Pull Request",
 | 
			
		||||
            "Releases",
 | 
			
		||||
            "Wiki",
 | 
			
		||||
            "External Wiki",
 | 
			
		||||
            "External Issues"
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    private List<String> pushAccessList;
 | 
			
		||||
 | 
			
		||||
    private boolean[] selectedAccessControlsTrueFalse = new boolean[]{
 | 
			
		||||
            false,
 | 
			
		||||
            false,
 | 
			
		||||
            false,
 | 
			
		||||
            false,
 | 
			
		||||
            false,
 | 
			
		||||
            false,
 | 
			
		||||
            false
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        setContentView(R.layout.activity_create_team_by_org);
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
 | 
			
		||||
        ImageView closeActivity = findViewById(R.id.close);
 | 
			
		||||
        teamName = findViewById(R.id.teamName);
 | 
			
		||||
        teamDesc = findViewById(R.id.teamDesc);
 | 
			
		||||
        teamPermission = findViewById(R.id.teamPermission);
 | 
			
		||||
        teamPermissionDetail = findViewById(R.id.teamPermissionDetail);
 | 
			
		||||
        teamAccessControls = findViewById(R.id.teamAccessControls);
 | 
			
		||||
        teamAccessControlsArray = findViewById(R.id.teamAccessControlsArray);
 | 
			
		||||
        createTeamButton = findViewById(R.id.createTeamButton);
 | 
			
		||||
 | 
			
		||||
        initCloseListener();
 | 
			
		||||
        closeActivity.setOnClickListener(onClickListener);
 | 
			
		||||
 | 
			
		||||
        teamPermission.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
 | 
			
		||||
                AlertDialog.Builder pBuilder = new AlertDialog.Builder(ctx, R.style.confirmDialog);
 | 
			
		||||
 | 
			
		||||
                pBuilder.setTitle(R.string.newTeamPermission);
 | 
			
		||||
                if(permissionSelectedChoice != -1) {
 | 
			
		||||
                    pBuilder.setCancelable(true);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    pBuilder.setCancelable(false);
 | 
			
		||||
                }
 | 
			
		||||
                pBuilder.setSingleChoiceItems(permissionList, permissionSelectedChoice, new DialogInterface.OnClickListener() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void onClick(DialogInterface dialogInterface, int i) {
 | 
			
		||||
 | 
			
		||||
                        permissionSelectedChoice = i;
 | 
			
		||||
                        teamPermission.setText(permissionList[i]);
 | 
			
		||||
 | 
			
		||||
                        if(permissionList[i].equals("Read")) {
 | 
			
		||||
                            teamPermissionDetail.setVisibility(View.VISIBLE);
 | 
			
		||||
                            teamPermissionDetail.setText(R.string.newTeamPermissionRead);
 | 
			
		||||
                        }
 | 
			
		||||
                        else if(permissionList[i].equals("Write")) {
 | 
			
		||||
                            teamPermissionDetail.setVisibility(View.VISIBLE);
 | 
			
		||||
                            teamPermissionDetail.setText(R.string.newTeamPermissionWrite);
 | 
			
		||||
                        }
 | 
			
		||||
                        else if(permissionList[i].equals("Admin")) {
 | 
			
		||||
                            teamPermissionDetail.setVisibility(View.VISIBLE);
 | 
			
		||||
                            teamPermissionDetail.setText(R.string.newTeamPermissionAdmin);
 | 
			
		||||
                        }
 | 
			
		||||
                        else {
 | 
			
		||||
                            teamPermissionDetail.setVisibility(View.GONE);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        dialogInterface.dismiss();
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                AlertDialog pDialog = pBuilder.create();
 | 
			
		||||
                pDialog.show();
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        teamAccessControls.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
                teamAccessControls.setText("");
 | 
			
		||||
                teamAccessControlsArray.setText("");
 | 
			
		||||
                pushAccessList = Arrays.asList(accessControlsList);
 | 
			
		||||
 | 
			
		||||
                AlertDialog.Builder aDialogBuilder = new AlertDialog.Builder(ctx, R.style.confirmDialog);
 | 
			
		||||
 | 
			
		||||
                aDialogBuilder.setMultiChoiceItems(accessControlsList, selectedAccessControlsTrueFalse, new DialogInterface.OnMultiChoiceClickListener() {
 | 
			
		||||
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void onClick(DialogInterface dialog, int which, boolean isChecked) {
 | 
			
		||||
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                    })
 | 
			
		||||
                    .setCancelable(false)
 | 
			
		||||
                    .setTitle(R.string.newTeamAccessControls)
 | 
			
		||||
                    .setPositiveButton(R.string.okButton, new DialogInterface.OnClickListener() {
 | 
			
		||||
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void onClick(DialogInterface dialog, int which) {
 | 
			
		||||
 | 
			
		||||
                            int selectedVal = 0;
 | 
			
		||||
                            while(selectedVal < selectedAccessControlsTrueFalse.length)
 | 
			
		||||
                            {
 | 
			
		||||
                                boolean value = selectedAccessControlsTrueFalse[selectedVal];
 | 
			
		||||
 | 
			
		||||
                                String repoCode = "";
 | 
			
		||||
                                if(selectedVal == 0) {
 | 
			
		||||
                                    repoCode = "repo.code";
 | 
			
		||||
                                }
 | 
			
		||||
                                if(selectedVal == 1) {
 | 
			
		||||
                                    repoCode = "repo.issues";
 | 
			
		||||
                                }
 | 
			
		||||
                                if(selectedVal == 2) {
 | 
			
		||||
                                    repoCode = "repo.pulls";
 | 
			
		||||
                                }
 | 
			
		||||
                                if(selectedVal == 3) {
 | 
			
		||||
                                    repoCode = "repo.releases";
 | 
			
		||||
                                }
 | 
			
		||||
                                if(selectedVal == 4) {
 | 
			
		||||
                                    repoCode = "repo.wiki";
 | 
			
		||||
                                }
 | 
			
		||||
                                if(selectedVal == 5) {
 | 
			
		||||
                                    repoCode = "repo.ext_wiki";
 | 
			
		||||
                                }
 | 
			
		||||
                                if(selectedVal == 6) {
 | 
			
		||||
                                    repoCode = "repo.ext_issues";
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                if(value){
 | 
			
		||||
                                    teamAccessControls.setText(getString(R.string.newTeamPermissionValues, teamAccessControls.getText(), pushAccessList.get(selectedVal)));
 | 
			
		||||
                                    teamAccessControlsArray.setText(getString(R.string.newTeamPermissionValuesFinal, teamAccessControlsArray.getText(), repoCode));
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                selectedVal++;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            String data = String.valueOf(teamAccessControls.getText());
 | 
			
		||||
                            if(!data.equals("")) {
 | 
			
		||||
                                teamAccessControls.setText(data.substring(0, data.length() - 2));
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            String dataArray = String.valueOf(teamAccessControlsArray.getText());
 | 
			
		||||
                            if(!dataArray.equals("")) {
 | 
			
		||||
                                teamAccessControlsArray.setText(dataArray.substring(0, dataArray.length() - 2));
 | 
			
		||||
                            }
 | 
			
		||||
                            //Log.i("orgName", String.valueOf(teamAccessControlsArray.getText()));
 | 
			
		||||
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                AlertDialog aDialog = aDialogBuilder.create();
 | 
			
		||||
                aDialog.show();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        createTeamButton.setEnabled(false);
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
 | 
			
		||||
            createTeamButton.setEnabled(false);
 | 
			
		||||
            GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
            shape.setCornerRadius( 8 );
 | 
			
		||||
            shape.setColor(getResources().getColor(R.color.hintColor));
 | 
			
		||||
            createTeamButton.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
 | 
			
		||||
            createTeamButton.setEnabled(true);
 | 
			
		||||
            createTeamButton.setOnClickListener(this);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void processCreateTeam() {
 | 
			
		||||
 | 
			
		||||
        AppUtil appUtil = new AppUtil();
 | 
			
		||||
        final 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");
 | 
			
		||||
        final String orgName = tinyDb.getString("orgName");;
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
        String newTeamName = teamName.getText().toString();
 | 
			
		||||
        String newTeamDesc = teamDesc.getText().toString();
 | 
			
		||||
        String newTeamPermission = teamPermission.getText().toString().toLowerCase();
 | 
			
		||||
        String newTeamAccessControls = teamAccessControlsArray.getText().toString();
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (newTeamName.equals("")) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.teamNameEmpty));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!appUtil.checkStringsWithAlphaNumericDashDotUnderscore(newTeamName)) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.teamNameError));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!newTeamDesc.equals("")) {
 | 
			
		||||
 | 
			
		||||
            if(!appUtil.checkStrings(newTeamDesc)) {
 | 
			
		||||
                Toasty.info(getApplicationContext(), getString(R.string.teamDescError));
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(newTeamDesc.length() > 100) {
 | 
			
		||||
                Toasty.info(getApplicationContext(), getString(R.string.teamDescLimit));
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (newTeamPermission.equals("")) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.teamPermissionEmpty));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        List<String> newTeamAccessControls_ = new ArrayList<>(Arrays.asList(newTeamAccessControls.split(",")));
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < newTeamAccessControls_.size(); i++) {
 | 
			
		||||
            newTeamAccessControls_.set(i, newTeamAccessControls_.get(i).trim());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        createNewTeamCall(instanceUrl, instanceToken, orgName, newTeamName, newTeamDesc, newTeamPermission, newTeamAccessControls_, loginUid);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void createNewTeamCall(final String instanceUrl, final String instanceToken, String orgName, String newTeamName, String newTeamDesc, String newTeamPermission, List<String> newTeamAccessControls, String loginUid) {
 | 
			
		||||
 | 
			
		||||
        Teams createNewTeamJson = new Teams(newTeamName, newTeamDesc, newTeamPermission, newTeamAccessControls);
 | 
			
		||||
 | 
			
		||||
        Call<Teams> call3;
 | 
			
		||||
 | 
			
		||||
        call3 = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .createTeamsByOrg(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), orgName, createNewTeamJson);
 | 
			
		||||
 | 
			
		||||
        call3.enqueue(new Callback<Teams>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<Teams> call, @NonNull retrofit2.Response<Teams> response2) {
 | 
			
		||||
 | 
			
		||||
                if(response2.isSuccessful()) {
 | 
			
		||||
                    if(response2.code() == 201) {
 | 
			
		||||
 | 
			
		||||
                        TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
                        tinyDb.putBoolean("resumeTeams", true);
 | 
			
		||||
 | 
			
		||||
                        Toasty.info(getApplicationContext(), getString(R.string.teamCreated));
 | 
			
		||||
                        finish();
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response2.code() == 404) {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.apiNotFound));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response2.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 {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.teamCreatedError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<Teams> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onClick(View v) {
 | 
			
		||||
        if(v == createTeamButton) {
 | 
			
		||||
            processCreateTeam();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void initCloseListener() {
 | 
			
		||||
        onClickListener = new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                finish();
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,43 @@
 | 
			
		||||
package org.mian.gitnex.activities;
 | 
			
		||||
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.text.method.LinkMovementMethod;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class CreditsActivity extends AppCompatActivity {
 | 
			
		||||
 | 
			
		||||
    private View.OnClickListener onClickListener;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        setContentView(R.layout.activity_credits);
 | 
			
		||||
 | 
			
		||||
        TextView creditKasun = findViewById(R.id.creditKasun);
 | 
			
		||||
        ImageView closeActivity = findViewById(R.id.close);
 | 
			
		||||
 | 
			
		||||
        creditKasun.setMovementMethod(LinkMovementMethod.getInstance());
 | 
			
		||||
 | 
			
		||||
        initCloseListener();
 | 
			
		||||
        closeActivity.setOnClickListener(onClickListener);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void initCloseListener() {
 | 
			
		||||
        onClickListener = new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                finish();
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,367 @@
 | 
			
		||||
package org.mian.gitnex.activities;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import retrofit2.Call;
 | 
			
		||||
import retrofit2.Callback;
 | 
			
		||||
import retrofit2.Response;
 | 
			
		||||
import android.annotation.SuppressLint;
 | 
			
		||||
import android.app.DatePickerDialog;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.graphics.drawable.GradientDrawable;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.widget.ArrayAdapter;
 | 
			
		||||
import android.widget.Button;
 | 
			
		||||
import android.widget.DatePicker;
 | 
			
		||||
import android.widget.EditText;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.Spinner;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import com.google.gson.JsonElement;
 | 
			
		||||
import com.hendraanggrian.appcompat.socialview.Mention;
 | 
			
		||||
import com.hendraanggrian.appcompat.widget.MentionArrayAdapter;
 | 
			
		||||
import com.hendraanggrian.appcompat.widget.SocialAutoCompleteTextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.helpers.AlertDialogs;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.helpers.Toasty;
 | 
			
		||||
import org.mian.gitnex.models.Collaborators;
 | 
			
		||||
import org.mian.gitnex.models.CreateIssue;
 | 
			
		||||
import org.mian.gitnex.models.Issues;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.text.DateFormat;
 | 
			
		||||
import java.text.SimpleDateFormat;
 | 
			
		||||
import java.util.Calendar;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class EditIssueActivity extends AppCompatActivity implements View.OnClickListener {
 | 
			
		||||
 | 
			
		||||
    final Context ctx = this;
 | 
			
		||||
    private View.OnClickListener onClickListener;
 | 
			
		||||
 | 
			
		||||
    private EditText editIssueTitle;
 | 
			
		||||
    private SocialAutoCompleteTextView editIssueDescription;
 | 
			
		||||
    private TextView editIssueDueDate;
 | 
			
		||||
    private Button editIssueButton;
 | 
			
		||||
    private Spinner editIssueMilestoneSpinner;
 | 
			
		||||
 | 
			
		||||
    private ArrayAdapter<Mention> defaultMentionAdapter;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        setContentView(R.layout.activity_edit_issue);
 | 
			
		||||
 | 
			
		||||
        final 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];
 | 
			
		||||
        final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
 | 
			
		||||
 | 
			
		||||
        ImageView closeActivity = findViewById(R.id.close);
 | 
			
		||||
        editIssueButton = findViewById(R.id.editIssueButton);
 | 
			
		||||
        TextView toolbar_title = findViewById(R.id.toolbar_title);
 | 
			
		||||
        editIssueTitle = findViewById(R.id.editIssueTitle);
 | 
			
		||||
        editIssueDescription = findViewById(R.id.editIssueDescription);
 | 
			
		||||
        editIssueDueDate = findViewById(R.id.editIssueDueDate);
 | 
			
		||||
 | 
			
		||||
        defaultMentionAdapter = new MentionArrayAdapter<>(this);
 | 
			
		||||
        loadCollaboratorsList();
 | 
			
		||||
 | 
			
		||||
        editIssueDescription.setMentionAdapter(defaultMentionAdapter);
 | 
			
		||||
 | 
			
		||||
        initCloseListener();
 | 
			
		||||
        closeActivity.setOnClickListener(onClickListener);
 | 
			
		||||
 | 
			
		||||
        editIssueDueDate.setOnClickListener(this);
 | 
			
		||||
        editIssueButton.setOnClickListener(this);
 | 
			
		||||
 | 
			
		||||
        if(!tinyDb.getString("issueNumber").isEmpty()) {
 | 
			
		||||
            toolbar_title.setText(getString(R.string.editIssueNavHeader, String.valueOf(issueIndex)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        disableProcessButton();
 | 
			
		||||
        getIssue(instanceUrl, instanceToken, loginUid, repoOwner, repoName, issueIndex);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void loadCollaboratorsList() {
 | 
			
		||||
 | 
			
		||||
        final 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];
 | 
			
		||||
 | 
			
		||||
        Call<List<Collaborators>> call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<List<Collaborators>>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<List<Collaborators>> call, @NonNull Response<List<Collaborators>> response) {
 | 
			
		||||
 | 
			
		||||
                if (response.isSuccessful()) {
 | 
			
		||||
 | 
			
		||||
                    assert response.body() != null;
 | 
			
		||||
                    String fullName = "";
 | 
			
		||||
                    for (int i = 0; i < response.body().size(); i++) {
 | 
			
		||||
                        if(!response.body().get(i).getFull_name().equals("")) {
 | 
			
		||||
                            fullName = response.body().get(i).getFull_name();
 | 
			
		||||
                        }
 | 
			
		||||
                        defaultMentionAdapter.add(
 | 
			
		||||
                                new Mention(response.body().get(i).getUsername(), fullName, response.body().get(i).getAvatar_url()));
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                } else {
 | 
			
		||||
 | 
			
		||||
                    Log.i("onResponse", String.valueOf(response.code()));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.i("onFailure", t.getMessage());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void initCloseListener() {
 | 
			
		||||
        onClickListener = new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                finish();
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void processEditIssue() {
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
        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");
 | 
			
		||||
        final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        String editIssueTitleForm = editIssueTitle.getText().toString();
 | 
			
		||||
        String editIssueDescriptionForm = editIssueDescription.getText().toString();
 | 
			
		||||
        String editIssueDueDateForm = editIssueDueDate.getText().toString();
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (editIssueTitleForm.equals("")) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.issueTitleEmpty));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /*if (editIssueDescriptionForm.equals("")) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.issueDescriptionEmpty));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }*/
 | 
			
		||||
 | 
			
		||||
        if (editIssueDueDateForm.equals("")) {
 | 
			
		||||
            editIssueDueDateForm = null;
 | 
			
		||||
        } else {
 | 
			
		||||
            editIssueDueDateForm = (AppUtil.customDateCombine(AppUtil.customDateFormat(editIssueDueDateForm)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //Log.i("editIssueDueDateForm", String.valueOf(editIssueDueDateForm));
 | 
			
		||||
        disableProcessButton();
 | 
			
		||||
        editIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid, editIssueTitleForm, editIssueDescriptionForm, editIssueDueDateForm);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void editIssue(String instanceUrl, String instanceToken, String repoOwner, String repoName, int issueIndex, String loginUid, String title, String description, String dueDate) {
 | 
			
		||||
 | 
			
		||||
        final TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
 | 
			
		||||
        CreateIssue issueData = new CreateIssue(title, description, dueDate);
 | 
			
		||||
 | 
			
		||||
        Call<JsonElement> call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .patchIssue(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, issueData);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<JsonElement>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.code() == 201) {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.editIssueSuccessMessage));
 | 
			
		||||
                    tinyDb.putBoolean("issueEdited", true);
 | 
			
		||||
                    tinyDb.putBoolean("resumeIssues", true);
 | 
			
		||||
                    finish();
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 401) {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedMessage),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.genericError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
                enableProcessButton();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
        if (v == editIssueDueDate) {
 | 
			
		||||
 | 
			
		||||
            final Calendar c = Calendar.getInstance();
 | 
			
		||||
            int mYear = c.get(Calendar.YEAR);
 | 
			
		||||
            final int mMonth = c.get(Calendar.MONTH);
 | 
			
		||||
            final int mDay = c.get(Calendar.DAY_OF_MONTH);
 | 
			
		||||
 | 
			
		||||
            DatePickerDialog datePickerDialog = new DatePickerDialog(this,
 | 
			
		||||
                    new DatePickerDialog.OnDateSetListener() {
 | 
			
		||||
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void onDateSet(DatePicker view, int year,
 | 
			
		||||
                                              int monthOfYear, int dayOfMonth) {
 | 
			
		||||
 | 
			
		||||
                            editIssueDueDate.setText(getString(R.string.setDueDate, year, (monthOfYear + 1), dayOfMonth));
 | 
			
		||||
 | 
			
		||||
                        }
 | 
			
		||||
                    }, mYear, mMonth, mDay);
 | 
			
		||||
            datePickerDialog.show();
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        else if(v == editIssueButton) {
 | 
			
		||||
            processEditIssue();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void getIssue(String instanceUrl, String instanceToken, String loginUid, String repoOwner, String repoName, int issueIndex) {
 | 
			
		||||
 | 
			
		||||
        Call<Issues> call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .getIssueByIndex(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<Issues>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<Issues> call, @NonNull retrofit2.Response<Issues> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.code() == 200) {
 | 
			
		||||
 | 
			
		||||
                    assert response.body() != null;
 | 
			
		||||
                    editIssueTitle.setText(response.body().getTitle());
 | 
			
		||||
                    editIssueDescription.setText(response.body().getBody());
 | 
			
		||||
 | 
			
		||||
                    if(response.body().getDue_date() != null) {
 | 
			
		||||
 | 
			
		||||
                        @SuppressLint("SimpleDateFormat") DateFormat formatter = new SimpleDateFormat("yyyy-M-dd");
 | 
			
		||||
                        String dueDate = formatter.format(response.body().getDue_date());
 | 
			
		||||
                        editIssueDueDate.setText(dueDate);
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                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 {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.genericError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<Issues> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void disableProcessButton() {
 | 
			
		||||
 | 
			
		||||
        editIssueButton.setEnabled(false);
 | 
			
		||||
        GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
        shape.setCornerRadius( 8 );
 | 
			
		||||
        shape.setColor(getResources().getColor(R.color.hintColor));
 | 
			
		||||
        editIssueButton.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void enableProcessButton() {
 | 
			
		||||
 | 
			
		||||
        editIssueButton.setEnabled(true);
 | 
			
		||||
        GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
        shape.setCornerRadius( 8 );
 | 
			
		||||
        shape.setColor(getResources().getColor(R.color.btnBackground));
 | 
			
		||||
        editIssueButton.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,501 @@
 | 
			
		||||
package org.mian.gitnex.activities;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.annotation.Nullable;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import androidx.appcompat.widget.Toolbar;
 | 
			
		||||
import androidx.lifecycle.Observer;
 | 
			
		||||
import androidx.lifecycle.ViewModelProviders;
 | 
			
		||||
import androidx.recyclerview.widget.DividerItemDecoration;
 | 
			
		||||
import androidx.recyclerview.widget.LinearLayoutManager;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 | 
			
		||||
import okhttp3.OkHttpClient;
 | 
			
		||||
import retrofit2.Call;
 | 
			
		||||
import retrofit2.Callback;
 | 
			
		||||
import retrofit2.Response;
 | 
			
		||||
import ru.noties.markwon.AbstractMarkwonPlugin;
 | 
			
		||||
import ru.noties.markwon.Markwon;
 | 
			
		||||
import ru.noties.markwon.core.CorePlugin;
 | 
			
		||||
import ru.noties.markwon.core.MarkwonTheme;
 | 
			
		||||
import ru.noties.markwon.ext.strikethrough.StrikethroughPlugin;
 | 
			
		||||
import ru.noties.markwon.ext.tables.TablePlugin;
 | 
			
		||||
import ru.noties.markwon.ext.tasklist.TaskListPlugin;
 | 
			
		||||
import ru.noties.markwon.html.HtmlPlugin;
 | 
			
		||||
import ru.noties.markwon.image.ImagesPlugin;
 | 
			
		||||
import ru.noties.markwon.image.gif.GifPlugin;
 | 
			
		||||
import ru.noties.markwon.image.okhttp.OkHttpImagesPlugin;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.graphics.Color;
 | 
			
		||||
import android.graphics.Typeface;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.Gravity;
 | 
			
		||||
import android.view.Menu;
 | 
			
		||||
import android.view.MenuInflater;
 | 
			
		||||
import android.view.MenuItem;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.widget.HorizontalScrollView;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.LinearLayout;
 | 
			
		||||
import android.widget.RelativeLayout;
 | 
			
		||||
import android.widget.ScrollView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import com.amulyakhare.textdrawable.TextDrawable;
 | 
			
		||||
import com.squareup.picasso.Picasso;
 | 
			
		||||
import com.vdurmont.emoji.EmojiParser;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.adapters.IssueCommentsAdapter;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.fragments.SingleIssueBottomSheetFragment;
 | 
			
		||||
import org.mian.gitnex.helpers.AlertDialogs;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.helpers.TimeHelper;
 | 
			
		||||
import org.mian.gitnex.helpers.UserMentions;
 | 
			
		||||
import org.mian.gitnex.models.IssueComments;
 | 
			
		||||
import org.mian.gitnex.models.Issues;
 | 
			
		||||
import org.mian.gitnex.helpers.ColorInverter;
 | 
			
		||||
import org.mian.gitnex.helpers.RoundedTransformation;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import org.mian.gitnex.helpers.ClickListener;
 | 
			
		||||
import org.mian.gitnex.viewmodels.IssueCommentsViewModel;
 | 
			
		||||
import org.ocpsoft.prettytime.PrettyTime;
 | 
			
		||||
import java.text.DateFormat;
 | 
			
		||||
import java.text.SimpleDateFormat;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class IssueDetailActivity extends AppCompatActivity {
 | 
			
		||||
 | 
			
		||||
    public ImageView closeActivity;
 | 
			
		||||
    private View.OnClickListener onClickListener;
 | 
			
		||||
    private IssueCommentsAdapter adapter;
 | 
			
		||||
    private RecyclerView mRecyclerView;
 | 
			
		||||
    private ImageView assigneeAvatar;
 | 
			
		||||
    private TextView issueTitle;
 | 
			
		||||
    private TextView issueDescription;
 | 
			
		||||
    private TextView issueMilestone;
 | 
			
		||||
    private TextView issueDueDate;
 | 
			
		||||
    private TextView issueCreatedTime;
 | 
			
		||||
    private HorizontalScrollView labelsScrollView;
 | 
			
		||||
    private HorizontalScrollView assigneesScrollView;
 | 
			
		||||
    private ScrollView scrollViewComments;
 | 
			
		||||
    private TextView issueModified;
 | 
			
		||||
    final Context ctx = this;
 | 
			
		||||
    private LinearLayout labelsLayout;
 | 
			
		||||
    private LinearLayout assigneesLayout;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        setContentView(R.layout.activity_issue_detail);
 | 
			
		||||
 | 
			
		||||
        final 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];
 | 
			
		||||
        final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
 | 
			
		||||
 | 
			
		||||
        final SwipeRefreshLayout swipeRefresh = findViewById(R.id.pullToRefresh);
 | 
			
		||||
 | 
			
		||||
        closeActivity = findViewById(R.id.close);
 | 
			
		||||
        assigneeAvatar = findViewById(R.id.assigneeAvatar);
 | 
			
		||||
        issueTitle = findViewById(R.id.issueTitle);
 | 
			
		||||
        issueDescription = findViewById(R.id.issueDescription);
 | 
			
		||||
        issueMilestone = findViewById(R.id.issueMilestone);
 | 
			
		||||
        issueDueDate = findViewById(R.id.issueDueDate);
 | 
			
		||||
        issueCreatedTime = findViewById(R.id.issueCreatedTime);
 | 
			
		||||
        labelsScrollView = findViewById(R.id.labelsScrollView);
 | 
			
		||||
        assigneesScrollView = findViewById(R.id.assigneesScrollView);
 | 
			
		||||
        scrollViewComments = findViewById(R.id.scrollViewComments);
 | 
			
		||||
        issueModified = findViewById(R.id.issueModified);
 | 
			
		||||
        labelsLayout = findViewById(R.id.frameLabels);
 | 
			
		||||
        assigneesLayout = findViewById(R.id.frameAssignees);
 | 
			
		||||
 | 
			
		||||
        Toolbar toolbar = findViewById(R.id.toolbar);
 | 
			
		||||
        setSupportActionBar(toolbar);
 | 
			
		||||
        Objects.requireNonNull(getSupportActionBar()).setTitle(repoName);
 | 
			
		||||
        getSupportActionBar().setDisplayHomeAsUpEnabled(false);
 | 
			
		||||
 | 
			
		||||
        initCloseListener();
 | 
			
		||||
        closeActivity.setOnClickListener(onClickListener);
 | 
			
		||||
 | 
			
		||||
        mRecyclerView = findViewById(R.id.recyclerView);
 | 
			
		||||
        mRecyclerView.setHasFixedSize(true);
 | 
			
		||||
        mRecyclerView.setNestedScrollingEnabled(false);
 | 
			
		||||
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
 | 
			
		||||
 | 
			
		||||
        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
 | 
			
		||||
                DividerItemDecoration.VERTICAL);
 | 
			
		||||
        mRecyclerView.addItemDecoration(dividerItemDecoration);
 | 
			
		||||
 | 
			
		||||
        swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onRefresh() {
 | 
			
		||||
                new Handler().postDelayed(new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        swipeRefresh.setRefreshing(false);
 | 
			
		||||
                        IssueCommentsViewModel.loadIssueComments(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex);
 | 
			
		||||
                    }
 | 
			
		||||
                }, 500);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        getSingleIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid);
 | 
			
		||||
        fetchDataAsync(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean onCreateOptionsMenu(Menu menu) {
 | 
			
		||||
        MenuInflater inflater = getMenuInflater();
 | 
			
		||||
        inflater.inflate(R.menu.generic_nav_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.genericMenu:
 | 
			
		||||
                SingleIssueBottomSheetFragment bottomSheet = new SingleIssueBottomSheetFragment();
 | 
			
		||||
                bottomSheet.show(getSupportFragmentManager(), "singleIssueBottomSheet");
 | 
			
		||||
                return true;
 | 
			
		||||
            default:
 | 
			
		||||
                return super.onOptionsItemSelected(item);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onResume() {
 | 
			
		||||
        super.onResume();
 | 
			
		||||
        final 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");
 | 
			
		||||
        final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
 | 
			
		||||
 | 
			
		||||
        if(tinyDb.getBoolean("commentPosted")) {
 | 
			
		||||
            scrollViewComments.post(new Runnable() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void run() {
 | 
			
		||||
                    IssueCommentsViewModel.loadIssueComments(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex);
 | 
			
		||||
 | 
			
		||||
                    new Handler().postDelayed(new Runnable() {
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void run() {
 | 
			
		||||
                            scrollViewComments.fullScroll(ScrollView.FOCUS_DOWN);
 | 
			
		||||
                        }
 | 
			
		||||
                    }, 1000);
 | 
			
		||||
 | 
			
		||||
                    tinyDb.putBoolean("commentPosted", false);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(tinyDb.getBoolean("commentEdited")) {
 | 
			
		||||
            scrollViewComments.post(new Runnable() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void run() {
 | 
			
		||||
                    IssueCommentsViewModel.loadIssueComments(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex);
 | 
			
		||||
                    tinyDb.putBoolean("commentEdited", false);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(tinyDb.getBoolean("singleIssueUpdate")) {
 | 
			
		||||
 | 
			
		||||
            new Handler().postDelayed(new Runnable() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void run() {
 | 
			
		||||
                    assigneesLayout.removeAllViews();
 | 
			
		||||
                    labelsLayout.removeAllViews();
 | 
			
		||||
                    getSingleIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid);
 | 
			
		||||
                    tinyDb.putBoolean("singleIssueUpdate", false);
 | 
			
		||||
                }
 | 
			
		||||
            }, 500);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(tinyDb.getBoolean("issueEdited")) {
 | 
			
		||||
 | 
			
		||||
            new Handler().postDelayed(new Runnable() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void run() {
 | 
			
		||||
                    assigneesLayout.removeAllViews();
 | 
			
		||||
                    labelsLayout.removeAllViews();
 | 
			
		||||
                    getSingleIssue(instanceUrl, instanceToken, repoOwner, repoName, issueIndex, loginUid);
 | 
			
		||||
                    tinyDb.putBoolean("issueEdited", false);
 | 
			
		||||
                }
 | 
			
		||||
            }, 500);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo, int index, String loginUid) {
 | 
			
		||||
 | 
			
		||||
        IssueCommentsViewModel issueCommentsModel = ViewModelProviders.of(this).get(IssueCommentsViewModel.class);
 | 
			
		||||
 | 
			
		||||
        issueCommentsModel.getIssueCommentList(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), owner, repo, index).observe(this, new Observer<List<IssueComments>>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onChanged(@Nullable List<IssueComments> issueCommentsMain) {
 | 
			
		||||
                adapter = new IssueCommentsAdapter(getApplicationContext(), issueCommentsMain);
 | 
			
		||||
                mRecyclerView.setAdapter(adapter);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void getSingleIssue(String instanceUrl, String instanceToken, String repoOwner, String repoName, int issueIndex, String loginUid) {
 | 
			
		||||
 | 
			
		||||
        final TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
        Call<Issues> call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .getIssueByIndex(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<Issues>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<Issues> call, @NonNull Response<Issues> response) {
 | 
			
		||||
 | 
			
		||||
                if (response.isSuccessful()) {
 | 
			
		||||
                    if (response.code() == 200) {
 | 
			
		||||
 | 
			
		||||
                        Issues singleIssue = response.body();
 | 
			
		||||
                        assert singleIssue != null;
 | 
			
		||||
 | 
			
		||||
                        final Markwon markwon = Markwon.builder(Objects.requireNonNull(getApplicationContext()))
 | 
			
		||||
                                .usePlugin(CorePlugin.create())
 | 
			
		||||
                                .usePlugin(OkHttpImagesPlugin.create(new OkHttpClient()))
 | 
			
		||||
                                .usePlugin(ImagesPlugin.createWithAssets(getApplicationContext()))
 | 
			
		||||
                                .usePlugin(new AbstractMarkwonPlugin() {
 | 
			
		||||
                                    @Override
 | 
			
		||||
                                    public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
 | 
			
		||||
                                        builder
 | 
			
		||||
                                                .codeTextColor(tinyDb.getInt("codeBlockColor"))
 | 
			
		||||
                                                .codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
 | 
			
		||||
                                                .linkColor(getApplicationContext().getResources().getColor(R.color.lightBlue));
 | 
			
		||||
                                    }
 | 
			
		||||
                                })
 | 
			
		||||
                                .usePlugin(TablePlugin.create(getApplicationContext()))
 | 
			
		||||
                                .usePlugin(TaskListPlugin.create(getApplicationContext()))
 | 
			
		||||
                                .usePlugin(HtmlPlugin.create())
 | 
			
		||||
                                .usePlugin(GifPlugin.create())
 | 
			
		||||
                                .usePlugin(StrikethroughPlugin.create())
 | 
			
		||||
                                .build();
 | 
			
		||||
 | 
			
		||||
                        TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
                        final String locale = tinyDb.getString("locale");
 | 
			
		||||
                        final String timeFormat = tinyDb.getString("dateFormat");
 | 
			
		||||
                        tinyDb.putString("issueState", singleIssue.getState());
 | 
			
		||||
                        tinyDb.putString("issueTitle", singleIssue.getTitle());
 | 
			
		||||
 | 
			
		||||
                        Picasso.get().load(singleIssue.getUser().getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(assigneeAvatar);
 | 
			
		||||
                        issueTitle.setText(getString(R.string.issueTitleWithId, singleIssue.getNumber(), singleIssue.getTitle()));
 | 
			
		||||
                        String cleanIssueDescription = singleIssue.getBody().trim();
 | 
			
		||||
                        final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueDescription));
 | 
			
		||||
                        issueDescription.setText(UserMentions.UserMentionsFunc(getApplicationContext(), bodyWithMD, cleanIssueDescription));
 | 
			
		||||
 | 
			
		||||
                        RelativeLayout.LayoutParams paramsDesc = (RelativeLayout.LayoutParams)issueDescription.getLayoutParams();
 | 
			
		||||
 | 
			
		||||
                        LinearLayout.LayoutParams params1 = new LinearLayout.LayoutParams(80, 80);
 | 
			
		||||
                        params1.setMargins(15, 0, 0, 0);
 | 
			
		||||
 | 
			
		||||
                        if(singleIssue.getAssignees() != null) {
 | 
			
		||||
                            assigneesScrollView.setVisibility(View.VISIBLE);
 | 
			
		||||
                            for (int i = 0; i < singleIssue.getAssignees().size(); i++) {
 | 
			
		||||
 | 
			
		||||
                                ImageView assigneesView = new ImageView(getApplicationContext());
 | 
			
		||||
 | 
			
		||||
                                Picasso.get().load(singleIssue.getAssignees().get(i).getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(80, 80).centerCrop().into(assigneesView);
 | 
			
		||||
 | 
			
		||||
                                assigneesLayout.addView(assigneesView);
 | 
			
		||||
                                assigneesView.setLayoutParams(params1);
 | 
			
		||||
                                if (!singleIssue.getAssignees().get(i).getFull_name().equals("")) {
 | 
			
		||||
                                    assigneesView.setOnClickListener(new ClickListener(getString(R.string.assignedTo, singleIssue.getAssignees().get(i).getFull_name()), getApplicationContext()));
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    assigneesView.setOnClickListener(new ClickListener(getString(R.string.assignedTo, singleIssue.getAssignees().get(i).getLogin()), getApplicationContext()));
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        else {
 | 
			
		||||
                            assigneesScrollView.setVisibility(View.GONE);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
 | 
			
		||||
                        params.setMargins(0, 0, 15, 0);
 | 
			
		||||
 | 
			
		||||
                        if(singleIssue.getLabels() != null) {
 | 
			
		||||
                            labelsScrollView.setVisibility(View.VISIBLE);
 | 
			
		||||
                            int width = 33;
 | 
			
		||||
                            for (int i = 0; i < singleIssue.getLabels().size(); i++) {
 | 
			
		||||
 | 
			
		||||
                                String labelColor = singleIssue.getLabels().get(i).getColor();
 | 
			
		||||
                                String labelName = singleIssue.getLabels().get(i).getName();
 | 
			
		||||
                                int color = Color.parseColor("#" + labelColor);
 | 
			
		||||
 | 
			
		||||
                                ImageView labelsView = new ImageView(getApplicationContext());
 | 
			
		||||
                                labelsLayout.setOrientation(LinearLayout.HORIZONTAL);
 | 
			
		||||
                                labelsLayout.setGravity(Gravity.START | Gravity.TOP);
 | 
			
		||||
                                labelsView.setLayoutParams(params);
 | 
			
		||||
 | 
			
		||||
                                TextDrawable drawable = TextDrawable.builder()
 | 
			
		||||
                                        .beginConfig()
 | 
			
		||||
                                        .useFont(Typeface.DEFAULT)
 | 
			
		||||
                                        .textColor(new ColorInverter().getContrastColor(color))
 | 
			
		||||
                                        .fontSize(36)
 | 
			
		||||
                                        .width((width * labelName.length()) - ((width / 4) * labelName.length()))
 | 
			
		||||
                                        .height(60)
 | 
			
		||||
                                        .endConfig()
 | 
			
		||||
                                        .buildRoundRect(labelName, color, 8);
 | 
			
		||||
                                labelsView.setImageDrawable(drawable);
 | 
			
		||||
 | 
			
		||||
                                labelsLayout.addView(labelsView);
 | 
			
		||||
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        else {
 | 
			
		||||
                            labelsScrollView.setVisibility(View.GONE);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if(singleIssue.getDue_date() != null) {
 | 
			
		||||
 | 
			
		||||
                            if (timeFormat.equals("normal") || timeFormat.equals("pretty")) {
 | 
			
		||||
                                DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", new Locale(locale));
 | 
			
		||||
                                String dueDate = formatter.format(singleIssue.getDue_date());
 | 
			
		||||
                                issueDueDate.setText(getString(R.string.dueDate, dueDate));
 | 
			
		||||
                                issueDueDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(singleIssue.getDue_date()), getApplicationContext()));
 | 
			
		||||
                            } else if (timeFormat.equals("normal1")) {
 | 
			
		||||
                                DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", new Locale(locale));
 | 
			
		||||
                                String dueDate = formatter.format(singleIssue.getDue_date());
 | 
			
		||||
                                issueDueDate.setText(getString(R.string.dueDate, dueDate));
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                        }
 | 
			
		||||
                        else {
 | 
			
		||||
 | 
			
		||||
                            issueDueDate.setVisibility(View.GONE);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        String edited;
 | 
			
		||||
 | 
			
		||||
                        if(!singleIssue.getUpdated_at().equals(singleIssue.getCreated_at())) {
 | 
			
		||||
                            edited = getString(R.string.colorfulBulletSpan) + getString(R.string.modifiedText);
 | 
			
		||||
                            issueModified.setVisibility(View.VISIBLE);
 | 
			
		||||
                            issueModified.setText(edited);
 | 
			
		||||
                            issueModified.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(singleIssue.getUpdated_at()), ctx));
 | 
			
		||||
                        }
 | 
			
		||||
                        else {
 | 
			
		||||
                            issueModified.setVisibility(View.INVISIBLE);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if((singleIssue.getDue_date() == null && singleIssue.getMilestone() == null) && singleIssue.getAssignees() != null) {
 | 
			
		||||
                            paramsDesc.setMargins(0, 35, 0, 0);
 | 
			
		||||
                            issueDescription.setLayoutParams(paramsDesc);
 | 
			
		||||
                        }
 | 
			
		||||
                        else if(singleIssue.getDue_date() == null && singleIssue.getMilestone() == null) {
 | 
			
		||||
                            paramsDesc.setMargins(0, 55, 0, 0);
 | 
			
		||||
                            issueDescription.setLayoutParams(paramsDesc);
 | 
			
		||||
                        }
 | 
			
		||||
                        else if(singleIssue.getAssignees() == null) {
 | 
			
		||||
                            paramsDesc.setMargins(0, 35, 0, 0);
 | 
			
		||||
                            issueDescription.setLayoutParams(paramsDesc);
 | 
			
		||||
                        }
 | 
			
		||||
                        else {
 | 
			
		||||
                            paramsDesc.setMargins(0, 15, 0, 0);
 | 
			
		||||
                            issueDescription.setLayoutParams(paramsDesc);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        switch (timeFormat) {
 | 
			
		||||
                            case "pretty": {
 | 
			
		||||
                                PrettyTime prettyTime = new PrettyTime(new Locale(locale));
 | 
			
		||||
                                String createdTime = prettyTime.format(singleIssue.getCreated_at());
 | 
			
		||||
                                issueCreatedTime.setText(getString(R.string.createdTime, createdTime));
 | 
			
		||||
                                issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(singleIssue.getCreated_at()), getApplicationContext()));
 | 
			
		||||
                                break;
 | 
			
		||||
                            }
 | 
			
		||||
                            case "normal": {
 | 
			
		||||
                                DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
 | 
			
		||||
                                String createdTime = formatter.format(singleIssue.getCreated_at());
 | 
			
		||||
                                issueCreatedTime.setText(getString(R.string.createdTime, createdTime));
 | 
			
		||||
                                break;
 | 
			
		||||
                            }
 | 
			
		||||
                            case "normal1": {
 | 
			
		||||
                                DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
 | 
			
		||||
                                String createdTime = formatter.format(singleIssue.getCreated_at());
 | 
			
		||||
                                issueCreatedTime.setText(getString(R.string.createdTime, createdTime));
 | 
			
		||||
                                break;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if(singleIssue.getMilestone() != null) {
 | 
			
		||||
                            issueMilestone.setText(getString(R.string.issueMilestone, singleIssue.getMilestone().getTitle()));
 | 
			
		||||
                        }
 | 
			
		||||
                        else {
 | 
			
		||||
                            issueMilestone.setVisibility(View.GONE);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (!singleIssue.getUser().getFull_name().equals("")) {
 | 
			
		||||
                            assigneeAvatar.setOnClickListener(new ClickListener(getApplicationContext().getResources().getString(R.string.issueCreator) + singleIssue.getUser().getFull_name(), getApplicationContext()));
 | 
			
		||||
                        } else {
 | 
			
		||||
                            assigneeAvatar.setOnClickListener(new ClickListener(getApplicationContext().getResources().getString(R.string.issueCreator) + singleIssue.getUser().getLogin(), getApplicationContext()));
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                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));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<Issues> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void initCloseListener() {
 | 
			
		||||
        onClickListener = new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                finish();
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										436
									
								
								app/src/main/java/org/mian/gitnex/activities/LoginActivity.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										436
									
								
								app/src/main/java/org/mian/gitnex/activities/LoginActivity.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,436 @@
 | 
			
		||||
package org.mian.gitnex.activities;
 | 
			
		||||
 | 
			
		||||
import android.annotation.SuppressLint;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import android.content.res.Resources;
 | 
			
		||||
import android.graphics.drawable.GradientDrawable;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.Gravity;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.widget.AdapterView;
 | 
			
		||||
import android.widget.ArrayAdapter;
 | 
			
		||||
import android.widget.Button;
 | 
			
		||||
import android.widget.EditText;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.Spinner;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import com.tooltip.Tooltip;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.helpers.Toasty;
 | 
			
		||||
import org.mian.gitnex.models.UserTokens;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.net.URI;
 | 
			
		||||
import java.net.URISyntaxException;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import okhttp3.Credentials;
 | 
			
		||||
import okhttp3.Headers;
 | 
			
		||||
import retrofit2.Call;
 | 
			
		||||
import retrofit2.Callback;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class LoginActivity extends AppCompatActivity implements View.OnClickListener {
 | 
			
		||||
 | 
			
		||||
    private Button login_button;
 | 
			
		||||
    private EditText instance_url, login_uid, login_passwd, otpCode;
 | 
			
		||||
    private Spinner protocolSpinner;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        setContentView(R.layout.activity_login);
 | 
			
		||||
 | 
			
		||||
        TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
 | 
			
		||||
        login_button = findViewById(R.id.login_button);
 | 
			
		||||
        instance_url = findViewById(R.id.instance_url);
 | 
			
		||||
        login_uid = findViewById(R.id.login_uid);
 | 
			
		||||
        login_passwd = findViewById(R.id.login_passwd);
 | 
			
		||||
        otpCode = findViewById(R.id.otpCode);
 | 
			
		||||
        ImageView info_button = findViewById(R.id.info);
 | 
			
		||||
        final TextView viewTextGiteaVersion = findViewById(R.id.appVersion);
 | 
			
		||||
        protocolSpinner = findViewById(R.id.httpsSpinner);
 | 
			
		||||
 | 
			
		||||
        viewTextGiteaVersion.setText(AppUtil.getAppVersion(getApplicationContext()));
 | 
			
		||||
 | 
			
		||||
        Resources res = getResources();
 | 
			
		||||
        String[] allProtocols = res.getStringArray(R.array.protocolValues);
 | 
			
		||||
 | 
			
		||||
        final ArrayAdapter<String> adapterProtocols = new ArrayAdapter<String>(Objects.requireNonNull(getApplicationContext()),
 | 
			
		||||
                R.layout.spinner_item, allProtocols);
 | 
			
		||||
 | 
			
		||||
        adapterProtocols.setDropDownViewResource(R.layout.spinner_dropdown_item);
 | 
			
		||||
        protocolSpinner.setAdapter(adapterProtocols);
 | 
			
		||||
 | 
			
		||||
        protocolSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
 | 
			
		||||
            public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
 | 
			
		||||
 | 
			
		||||
                String value = getResources().getStringArray(R.array.protocolValues)[pos];
 | 
			
		||||
                if(value.toLowerCase().equals("http")) {
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getResources().getString(R.string.protocolError));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
            public void onNothingSelected(AdapterView<?> parent) {
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        info_button.setOnClickListener(infoListener);
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //login_button.setOnClickListener(this);
 | 
			
		||||
        if(!tinyDb.getString("instanceUrlRaw").isEmpty()) {
 | 
			
		||||
            instance_url.setText(tinyDb.getString("instanceUrlRaw"));
 | 
			
		||||
        }
 | 
			
		||||
        if(!tinyDb.getString("loginUid").isEmpty()) {
 | 
			
		||||
            login_uid.setText(tinyDb.getString("loginUid"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(tinyDb.getBoolean("loggedInMode")) {
 | 
			
		||||
 | 
			
		||||
            startActivity(new Intent(LoginActivity.this, MainActivity.class));
 | 
			
		||||
            finish();
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        login_button.setOnClickListener(loginListener);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
        switch(v.getId()) {
 | 
			
		||||
 | 
			
		||||
            case R.id.login_button:
 | 
			
		||||
                login();
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private View.OnClickListener loginListener = new View.OnClickListener() {
 | 
			
		||||
        public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
            disableProcessButton();
 | 
			
		||||
            login_button.setText(R.string.processingText);
 | 
			
		||||
            login();
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    private View.OnClickListener infoListener = new View.OnClickListener() {
 | 
			
		||||
        public void onClick(View v) {
 | 
			
		||||
        new Tooltip.Builder(v)
 | 
			
		||||
            .setText(R.string.urlInfoTooltip)
 | 
			
		||||
            .setTextColor(getResources().getColor(R.color.white))
 | 
			
		||||
            .setBackgroundColor(getResources().getColor(R.color.tooltipBackground))
 | 
			
		||||
            .setCancelable(true)
 | 
			
		||||
            .setDismissOnClick(true)
 | 
			
		||||
            .setPadding(30)
 | 
			
		||||
            .setCornerRadius(R.dimen.tooltipCornor)
 | 
			
		||||
            .setGravity(Gravity.BOTTOM)
 | 
			
		||||
            .show();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    @SuppressLint("ResourceAsColor")
 | 
			
		||||
    private void login() {
 | 
			
		||||
 | 
			
		||||
        TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
        AppUtil appUtil = new AppUtil();
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(LoginActivity.this);
 | 
			
		||||
 | 
			
		||||
        String instanceUrl = instance_url.getText().toString().trim();
 | 
			
		||||
        String loginUid = login_uid.getText().toString();
 | 
			
		||||
        String loginPass = login_passwd.getText().toString();
 | 
			
		||||
        String protocol = protocolSpinner.getSelectedItem().toString();
 | 
			
		||||
        String loginOTP_ = otpCode.getText().toString().trim();
 | 
			
		||||
 | 
			
		||||
        if(instanceUrl.contains("@")) {
 | 
			
		||||
 | 
			
		||||
            String[] urlForHttpAuth = instanceUrl.split("@");
 | 
			
		||||
 | 
			
		||||
            tinyDb.putString("basicAuthPassword", loginPass);
 | 
			
		||||
            tinyDb.putBoolean("basicAuthFlag", true);
 | 
			
		||||
 | 
			
		||||
            instanceUrl = urlForHttpAuth[1];
 | 
			
		||||
            loginUid = urlForHttpAuth[0];
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        String instanceHost;
 | 
			
		||||
        if(AppUtil.httpCheck(instanceUrl)) {
 | 
			
		||||
 | 
			
		||||
            URI uri = null;
 | 
			
		||||
            try {
 | 
			
		||||
                uri = new URI(instanceUrl);
 | 
			
		||||
            } catch (URISyntaxException e) {
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
            }
 | 
			
		||||
            assert uri != null;
 | 
			
		||||
            instanceHost = uri.getHost();
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            instanceHost = instanceUrl;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(protocol.toLowerCase().equals("https")) {
 | 
			
		||||
            instanceUrl = "https://" + instanceHost + "/api/v1/";
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            instanceUrl = "http://" + instanceHost + "/api/v1/";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        tinyDb.putString("instanceUrlRaw", instanceHost);
 | 
			
		||||
        tinyDb.putString("loginUid", loginUid);
 | 
			
		||||
        tinyDb.putString("instanceUrl", instanceUrl);
 | 
			
		||||
 | 
			
		||||
        if(connToInternet) {
 | 
			
		||||
 | 
			
		||||
            if(instance_url.getText().toString().equals("")) {
 | 
			
		||||
 | 
			
		||||
                Toasty.info(getApplicationContext(), getString(R.string.emptyFieldURL));
 | 
			
		||||
                enableProcessButton();
 | 
			
		||||
                login_button.setText(R.string.btnLogin);
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
            if(loginUid.equals("")) {
 | 
			
		||||
 | 
			
		||||
                Toasty.info(getApplicationContext(), getString(R.string.emptyFieldUsername));
 | 
			
		||||
                enableProcessButton();
 | 
			
		||||
                login_button.setText(R.string.btnLogin);
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
            if(login_passwd.getText().toString().equals("")) {
 | 
			
		||||
 | 
			
		||||
                Toasty.info(getApplicationContext(), getString(R.string.emptyFieldPassword));
 | 
			
		||||
                enableProcessButton();
 | 
			
		||||
                login_button.setText(R.string.btnLogin);
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            int loginOTP = 0;
 | 
			
		||||
            if(loginOTP_.length() == 6) {
 | 
			
		||||
 | 
			
		||||
                if(appUtil.checkIntegers(loginOTP_)) {
 | 
			
		||||
 | 
			
		||||
                    loginOTP = Integer.valueOf(loginOTP_);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.loginOTPTypeError));
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    login_button.setText(R.string.btnLogin);
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            letTheUserIn(instanceUrl, loginUid, loginPass, loginOTP);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.checkNetConnection));
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void letTheUserIn(final String instanceUrl, final String loginUid, final String loginPass, final int loginOTP) {
 | 
			
		||||
 | 
			
		||||
        final String credential = Credentials.basic(loginUid, loginPass);
 | 
			
		||||
 | 
			
		||||
        Call<List<UserTokens>> call;
 | 
			
		||||
        if(loginOTP != 0) {
 | 
			
		||||
            call = RetrofitClient
 | 
			
		||||
                    .getInstance(instanceUrl)
 | 
			
		||||
                    .getApiInterface()
 | 
			
		||||
                    .getUserTokensWithOTP(credential, loginOTP, loginUid);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            call = RetrofitClient
 | 
			
		||||
                    .getInstance(instanceUrl)
 | 
			
		||||
                    .getApiInterface()
 | 
			
		||||
                    .getUserTokens(credential, loginUid);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<List<UserTokens>>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<List<UserTokens>> call, @NonNull retrofit2.Response<List<UserTokens>> response) {
 | 
			
		||||
 | 
			
		||||
                List<UserTokens> userTokens = response.body();
 | 
			
		||||
                final TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
                Headers responseHeaders = response.headers();
 | 
			
		||||
 | 
			
		||||
                if (response.isSuccessful()) {
 | 
			
		||||
 | 
			
		||||
                    if (response.code() == 200) {
 | 
			
		||||
 | 
			
		||||
                        boolean setTokenFlag = false;
 | 
			
		||||
 | 
			
		||||
                        assert userTokens != null;
 | 
			
		||||
                        if (userTokens.size() > 0) {
 | 
			
		||||
                            for (int i = 0; i < userTokens.size(); i++) {
 | 
			
		||||
                                if (userTokens.get(i).getSha1().equals(tinyDb.getString(loginUid + "-token"))) {
 | 
			
		||||
                                    setTokenFlag = true;
 | 
			
		||||
                                    break;
 | 
			
		||||
                                }
 | 
			
		||||
                                //Log.i("Tokens: ", userTokens.get(i).getSha1());
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if(tinyDb.getString(loginUid + "-token").isEmpty() || !setTokenFlag) {
 | 
			
		||||
 | 
			
		||||
                            UserTokens createUserToken = new UserTokens("gitnex-app-token");
 | 
			
		||||
 | 
			
		||||
                            Call<UserTokens> callCreateToken;
 | 
			
		||||
                            if(loginOTP != 0) {
 | 
			
		||||
                                callCreateToken = RetrofitClient
 | 
			
		||||
                                        .getInstance(instanceUrl)
 | 
			
		||||
                                        .getApiInterface()
 | 
			
		||||
                                        .createNewTokenWithOTP(credential, loginOTP, loginUid, createUserToken);
 | 
			
		||||
                            }
 | 
			
		||||
                            else {
 | 
			
		||||
                                callCreateToken = RetrofitClient
 | 
			
		||||
                                        .getInstance(instanceUrl)
 | 
			
		||||
                                        .getApiInterface()
 | 
			
		||||
                                        .createNewToken(credential, loginUid, createUserToken);
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            callCreateToken.enqueue(new Callback<UserTokens>() {
 | 
			
		||||
 | 
			
		||||
                                @Override
 | 
			
		||||
                                public void onResponse(@NonNull Call<UserTokens> callCreateToken, @NonNull retrofit2.Response<UserTokens> responseCreate) {
 | 
			
		||||
 | 
			
		||||
                                    if (responseCreate.isSuccessful()) {
 | 
			
		||||
 | 
			
		||||
                                        if(responseCreate.code() == 201) {
 | 
			
		||||
 | 
			
		||||
                                            UserTokens newToken = responseCreate.body();
 | 
			
		||||
                                            assert newToken != null;
 | 
			
		||||
                                            //Log.i("Tokens-NEW", "new:" + newToken.getSha1());
 | 
			
		||||
 | 
			
		||||
                                            if (!newToken.getSha1().equals("")) {
 | 
			
		||||
 | 
			
		||||
                                                tinyDb.remove("loginPass");
 | 
			
		||||
                                                tinyDb.putBoolean("loggedInMode", true);
 | 
			
		||||
                                                tinyDb.putString(loginUid + "-token", newToken.getSha1());
 | 
			
		||||
                                                //Log.i("Tokens", "new:" + newToken.getSha1() + " old:" + tinyDb.getString(loginUid + "-token"));
 | 
			
		||||
 | 
			
		||||
                                                startActivity(new Intent(LoginActivity.this, MainActivity.class));
 | 
			
		||||
                                                finish();
 | 
			
		||||
 | 
			
		||||
                                            }
 | 
			
		||||
 | 
			
		||||
                                        }
 | 
			
		||||
 | 
			
		||||
                                    }
 | 
			
		||||
                                    else if(responseCreate.code() == 500) {
 | 
			
		||||
 | 
			
		||||
                                        String toastError = getResources().getString(R.string.genericApiStatusError) + String.valueOf(responseCreate.code());
 | 
			
		||||
                                        Toasty.info(getApplicationContext(), toastError);
 | 
			
		||||
                                        enableProcessButton();
 | 
			
		||||
                                        login_button.setText(R.string.btnLogin);
 | 
			
		||||
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                @Override
 | 
			
		||||
                                public void onFailure(@NonNull Call<UserTokens> createUserToken, Throwable t) {
 | 
			
		||||
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                            });
 | 
			
		||||
                        }
 | 
			
		||||
                        else {
 | 
			
		||||
 | 
			
		||||
                            //Log.i("Current Token", tinyDb.getString(loginUid + "-token"));
 | 
			
		||||
                            tinyDb.putBoolean("loggedInMode", true);
 | 
			
		||||
                            startActivity(new Intent(LoginActivity.this, MainActivity.class));
 | 
			
		||||
                            finish();
 | 
			
		||||
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 500) {
 | 
			
		||||
 | 
			
		||||
                    String toastError = getResources().getString(R.string.genericApiStatusError) + String.valueOf(response.code());
 | 
			
		||||
                    Toasty.info(getApplicationContext(), toastError);
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    login_button.setText(R.string.btnLogin);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
 | 
			
		||||
                    String toastError = getResources().getString(R.string.genericApiStatusError) + String.valueOf(response.code());
 | 
			
		||||
                    //Log.i("error message else4", String.valueOf(response.code()));
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(getApplicationContext(), toastError);
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    login_button.setText(R.string.btnLogin);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<List<UserTokens>> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure-login", t.toString());
 | 
			
		||||
                Toasty.info(getApplicationContext(), getResources().getString(R.string.malformedJson));
 | 
			
		||||
                enableProcessButton();
 | 
			
		||||
                login_button.setText(R.string.btnLogin);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void disableProcessButton() {
 | 
			
		||||
 | 
			
		||||
        login_button.setEnabled(false);
 | 
			
		||||
        GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
        shape.setCornerRadius( 8 );
 | 
			
		||||
        shape.setColor(getResources().getColor(R.color.hintColor));
 | 
			
		||||
        login_button.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void enableProcessButton() {
 | 
			
		||||
 | 
			
		||||
        login_button.setEnabled(true);
 | 
			
		||||
        GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
        shape.setCornerRadius( 8 );
 | 
			
		||||
        shape.setColor(getResources().getColor(R.color.btnBackground));
 | 
			
		||||
        login_button.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										411
									
								
								app/src/main/java/org/mian/gitnex/activities/MainActivity.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										411
									
								
								app/src/main/java/org/mian/gitnex/activities/MainActivity.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,411 @@
 | 
			
		||||
package org.mian.gitnex.activities;
 | 
			
		||||
 | 
			
		||||
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.core.view.GravityCompat;
 | 
			
		||||
import androidx.drawerlayout.widget.DrawerLayout;
 | 
			
		||||
import androidx.appcompat.app.ActionBarDrawerToggle;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.MenuItem;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import com.squareup.picasso.NetworkPolicy;
 | 
			
		||||
import com.squareup.picasso.Picasso;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.fragments.AboutFragment;
 | 
			
		||||
import org.mian.gitnex.fragments.MyRepositoriesFragment;
 | 
			
		||||
import org.mian.gitnex.fragments.NavSubMenuBottomSheetFragment;
 | 
			
		||||
import org.mian.gitnex.fragments.OrganizationsFragment;
 | 
			
		||||
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.Toasty;
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
 | 
			
		||||
 | 
			
		||||
    private DrawerLayout drawer;
 | 
			
		||||
    private TextView userFullName;
 | 
			
		||||
    private TextView userEmail;
 | 
			
		||||
    private ImageView userAvatar;
 | 
			
		||||
    final Context ctx = this;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle 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());
 | 
			
		||||
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        setContentView(R.layout.activity_main);
 | 
			
		||||
 | 
			
		||||
        if(!tinyDb.getBoolean("loggedInMode")) {
 | 
			
		||||
            logout();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        androidx.appcompat.widget.Toolbar toolbar = findViewById(R.id.toolbar);
 | 
			
		||||
        setSupportActionBar(toolbar);
 | 
			
		||||
 | 
			
		||||
        drawer = findViewById(R.id.drawer_layout);
 | 
			
		||||
        NavigationView navigationView = findViewById(R.id.nav_view);
 | 
			
		||||
        navigationView.setNavigationItemSelectedListener(this);
 | 
			
		||||
        final View hView =  navigationView.getHeaderView(0);
 | 
			
		||||
 | 
			
		||||
        ImageView navSubMenu = hView.findViewById(R.id.navSubMenu);
 | 
			
		||||
        navSubMenu.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            public void onClick(View v) {
 | 
			
		||||
                NavSubMenuBottomSheetFragment bottomSheet = new NavSubMenuBottomSheetFragment();
 | 
			
		||||
                bottomSheet.show(getSupportFragmentManager(), "adminMenuBottomSheet");
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar,
 | 
			
		||||
                R.string.navigation_drawer_open, R.string.navigation_drawer_close);
 | 
			
		||||
        toggle.getDrawerArrowDrawable().setColor(getResources().getColor(R.color.white));
 | 
			
		||||
        drawer.addDrawerListener(toggle);
 | 
			
		||||
 | 
			
		||||
        drawer.addDrawerListener(new DrawerLayout.DrawerListener() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onDrawerOpened(@NonNull View drawerView) {
 | 
			
		||||
 | 
			
		||||
                boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
                if(!connToInternet) {
 | 
			
		||||
 | 
			
		||||
                    if(!tinyDb.getBoolean("noConnection")) {
 | 
			
		||||
                        Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    tinyDb.putBoolean("noConnection", true);
 | 
			
		||||
 | 
			
		||||
                    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);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    userFullName = hView.findViewById(R.id.userFullname);
 | 
			
		||||
                    if (!userFullNameNav.equals("")) {
 | 
			
		||||
                        userFullName.setText(userFullNameNav);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    userAvatar = hView.findViewById(R.id.userAvatar);
 | 
			
		||||
                    if (!userAvatarNav.equals("")) {
 | 
			
		||||
                        Picasso.get().load(userAvatarNav).networkPolicy(NetworkPolicy.OFFLINE).transform(new RoundedTransformation(100, 0)).resize(180, 180).centerCrop().into(userAvatar);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                } else {
 | 
			
		||||
 | 
			
		||||
                    displayUserInfo(instanceUrl, instanceToken, loginUid);
 | 
			
		||||
                    tinyDb.putBoolean("noConnection", false);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @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) {
 | 
			
		||||
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
 | 
			
		||||
                        new MyRepositoriesFragment()).commit();
 | 
			
		||||
                navigationView.setCheckedItem(R.id.nav_home);
 | 
			
		||||
            }
 | 
			
		||||
            else if(tinyDb.getInt("homeScreenId") == 1) {
 | 
			
		||||
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
 | 
			
		||||
                        new StarredRepositoriesFragment()).commit();
 | 
			
		||||
                navigationView.setCheckedItem(R.id.nav_starred_repos);
 | 
			
		||||
            }
 | 
			
		||||
            else if(tinyDb.getInt("homeScreenId") == 2) {
 | 
			
		||||
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
 | 
			
		||||
                        new OrganizationsFragment()).commit();
 | 
			
		||||
                navigationView.setCheckedItem(R.id.nav_organizations);
 | 
			
		||||
            }
 | 
			
		||||
            else if(tinyDb.getInt("homeScreenId") == 3) {
 | 
			
		||||
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
 | 
			
		||||
                        new RepositoriesFragment()).commit();
 | 
			
		||||
                navigationView.setCheckedItem(R.id.nav_repositories);
 | 
			
		||||
            }
 | 
			
		||||
            else if(tinyDb.getInt("homeScreenId") == 4) {
 | 
			
		||||
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
 | 
			
		||||
                        new ProfileFragment()).commit();
 | 
			
		||||
                navigationView.setCheckedItem(R.id.nav_profile);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                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);
 | 
			
		||||
            tinyDb.putBoolean("noConnection", false);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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:
 | 
			
		||||
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
 | 
			
		||||
                        new MyRepositoriesFragment()).commit();
 | 
			
		||||
                break;
 | 
			
		||||
            case R.id.nav_organizations:
 | 
			
		||||
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
 | 
			
		||||
                        new OrganizationsFragment()).commit();
 | 
			
		||||
                break;
 | 
			
		||||
            case R.id.nav_profile:
 | 
			
		||||
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
 | 
			
		||||
                        new ProfileFragment()).commit();
 | 
			
		||||
                break;
 | 
			
		||||
            case R.id.nav_repositories:
 | 
			
		||||
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
 | 
			
		||||
                        new RepositoriesFragment()).commit();
 | 
			
		||||
                break;
 | 
			
		||||
            case R.id.nav_settings:
 | 
			
		||||
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
 | 
			
		||||
                        new SettingsFragment()).commit();
 | 
			
		||||
                break;
 | 
			
		||||
            case R.id.nav_logout:
 | 
			
		||||
                logout();
 | 
			
		||||
                overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
 | 
			
		||||
                break;
 | 
			
		||||
            case R.id.nav_about:
 | 
			
		||||
                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:
 | 
			
		||||
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
 | 
			
		||||
                        new StarredRepositoriesFragment()).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 void logout() {
 | 
			
		||||
 | 
			
		||||
        TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
        tinyDb.putBoolean("loggedInMode", false);
 | 
			
		||||
        tinyDb.remove("basicAuthPassword");
 | 
			
		||||
        tinyDb.putBoolean("basicAuthFlag", false);
 | 
			
		||||
        //tinyDb.clear();
 | 
			
		||||
        finish();
 | 
			
		||||
        startActivity(new Intent(MainActivity.this, LoginActivity.class));
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void displayUserInfo(String instanceUrl, String token, String loginUid) {
 | 
			
		||||
 | 
			
		||||
        final TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
 | 
			
		||||
        Call<UserInfo> call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .getUserInfo(Authorization.returnAuthentication(getApplicationContext(), loginUid, token));
 | 
			
		||||
 | 
			
		||||
        NavigationView navigationView = findViewById(R.id.nav_view);
 | 
			
		||||
        final View hView =  navigationView.getHeaderView(0);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<UserInfo>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<UserInfo> call, @NonNull retrofit2.Response<UserInfo> response) {
 | 
			
		||||
 | 
			
		||||
                UserInfo userDetails = response.body();
 | 
			
		||||
 | 
			
		||||
                if (response.isSuccessful()) {
 | 
			
		||||
 | 
			
		||||
                    if (response.code() == 200) {
 | 
			
		||||
 | 
			
		||||
                        assert userDetails != null;
 | 
			
		||||
                        tinyDb.putString("userLogin", userDetails.getLogin());
 | 
			
		||||
                        tinyDb.putInt("userId", userDetails.getId());
 | 
			
		||||
                        if(!userDetails.getFullname().equals("")) {
 | 
			
		||||
                            tinyDb.putString("userFullname", userDetails.getFullname());
 | 
			
		||||
                        }
 | 
			
		||||
                        else {
 | 
			
		||||
                            tinyDb.putString("userFullname", "...");
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        tinyDb.putString("userEmail", userDetails.getEmail());
 | 
			
		||||
                        tinyDb.putString("userAvatar", userDetails.getAvatar());
 | 
			
		||||
                        if(userDetails.getLang() != null) {
 | 
			
		||||
                            tinyDb.putString("userLang", userDetails.getLang());
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            tinyDb.putString("userLang", "...");
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        userAvatar = hView.findViewById(R.id.userAvatar);
 | 
			
		||||
                        if (!Objects.requireNonNull(userDetails).getAvatar().equals("")) {
 | 
			
		||||
                            Picasso.get().load(userDetails.getAvatar()).transform(new RoundedTransformation(100, 0)).resize(180, 180).centerCrop().into(userAvatar);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            userAvatar.setImageResource(R.mipmap.ic_launcher_round);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        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<UserInfo> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,242 @@
 | 
			
		||||
package org.mian.gitnex.activities;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import retrofit2.Call;
 | 
			
		||||
import retrofit2.Callback;
 | 
			
		||||
import android.app.DatePickerDialog;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.graphics.drawable.GradientDrawable;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.widget.Button;
 | 
			
		||||
import android.widget.DatePicker;
 | 
			
		||||
import android.widget.EditText;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.helpers.AlertDialogs;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.helpers.Toasty;
 | 
			
		||||
import org.mian.gitnex.models.Milestones;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.util.Calendar;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class NewMilestoneActivity extends AppCompatActivity implements View.OnClickListener {
 | 
			
		||||
 | 
			
		||||
    private EditText milestoneDueDate;
 | 
			
		||||
    private View.OnClickListener onClickListener;
 | 
			
		||||
    private EditText milestoneTitle;
 | 
			
		||||
    private EditText milestoneDescription;
 | 
			
		||||
    private Button createNewMilestoneButton;
 | 
			
		||||
    final Context ctx = this;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        setContentView(R.layout.activity_new_milestone);
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
 | 
			
		||||
        milestoneDueDate = findViewById(R.id.milestoneDueDate);
 | 
			
		||||
        ImageView closeActivity = findViewById(R.id.close);
 | 
			
		||||
        createNewMilestoneButton = findViewById(R.id.createNewMilestoneButton);
 | 
			
		||||
        milestoneTitle = findViewById(R.id.milestoneTitle);
 | 
			
		||||
        milestoneDescription = findViewById(R.id.milestoneDescription);
 | 
			
		||||
 | 
			
		||||
        initCloseListener();
 | 
			
		||||
        closeActivity.setOnClickListener(onClickListener);
 | 
			
		||||
        milestoneDueDate.setOnClickListener(this);
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
 | 
			
		||||
            createNewMilestoneButton.setEnabled(false);
 | 
			
		||||
            GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
            shape.setCornerRadius( 8 );
 | 
			
		||||
            shape.setColor(getResources().getColor(R.color.hintColor));
 | 
			
		||||
            createNewMilestoneButton.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
 | 
			
		||||
            createNewMilestoneButton.setOnClickListener(createMilestoneListener);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private View.OnClickListener createMilestoneListener = new View.OnClickListener() {
 | 
			
		||||
        public void onClick(View v) {
 | 
			
		||||
            processNewMilestone();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    private void processNewMilestone() {
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
        AppUtil appUtil = new AppUtil();
 | 
			
		||||
        TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
        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");
 | 
			
		||||
        //String appLocale = tinyDb.getString("locale");
 | 
			
		||||
 | 
			
		||||
        String newMilestoneTitle = milestoneTitle.getText().toString();
 | 
			
		||||
        String newMilestoneDescription = milestoneDescription.getText().toString();
 | 
			
		||||
        String newMilestoneDueDate = milestoneDueDate.getText().toString();
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(newMilestoneTitle.equals("")) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.milestoneNameErrorEmpty));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!newMilestoneDescription.equals("")) {
 | 
			
		||||
            if (appUtil.charactersLength(newMilestoneDescription) > 255) {
 | 
			
		||||
 | 
			
		||||
                Toasty.info(getApplicationContext(), getString(R.string.milestoneDescError));
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(newMilestoneDueDate.equals("")) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.milestoneDateEmpty));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        disableProcessButton();
 | 
			
		||||
        String finalMilestoneDueDate = (AppUtil.customDateCombine(AppUtil.customDateFormat(newMilestoneDueDate)));
 | 
			
		||||
        createNewMilestone(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, newMilestoneTitle, newMilestoneDescription, finalMilestoneDueDate);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void createNewMilestone(final String instanceUrl, final String token, String repoOwner, String repoName, String newMilestoneTitle, String newMilestoneDescription, String newMilestoneDueDate) {
 | 
			
		||||
 | 
			
		||||
        Milestones createMilestone = new Milestones(newMilestoneDescription, newMilestoneTitle, newMilestoneDueDate);
 | 
			
		||||
 | 
			
		||||
        Call<Milestones> call;
 | 
			
		||||
 | 
			
		||||
        call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .createMilestone(token, repoOwner, repoName, createMilestone);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<Milestones>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<Milestones> call, @NonNull retrofit2.Response<Milestones> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.isSuccessful()) {
 | 
			
		||||
                    if(response.code() == 201) {
 | 
			
		||||
 | 
			
		||||
                        TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
                        tinyDb.putBoolean("milestoneCreated", true);
 | 
			
		||||
                        Toasty.info(getApplicationContext(), getString(R.string.milestoneCreated));
 | 
			
		||||
                        enableProcessButton();
 | 
			
		||||
                        finish();
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 401) {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedMessage),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.milestoneCreatedError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<Milestones> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
                enableProcessButton();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
        if (v == milestoneDueDate) {
 | 
			
		||||
 | 
			
		||||
            final Calendar c = Calendar.getInstance();
 | 
			
		||||
            int mYear = c.get(Calendar.YEAR);
 | 
			
		||||
            final int mMonth = c.get(Calendar.MONTH);
 | 
			
		||||
            final int mDay = c.get(Calendar.DAY_OF_MONTH);
 | 
			
		||||
 | 
			
		||||
            DatePickerDialog datePickerDialog = new DatePickerDialog(this,
 | 
			
		||||
                    new DatePickerDialog.OnDateSetListener() {
 | 
			
		||||
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void onDateSet(DatePicker view, int year,
 | 
			
		||||
                                              int monthOfYear, int dayOfMonth) {
 | 
			
		||||
 | 
			
		||||
                            milestoneDueDate.setText(getString(R.string.setDueDate, year, (monthOfYear + 1), dayOfMonth));
 | 
			
		||||
 | 
			
		||||
                        }
 | 
			
		||||
                    }, mYear, mMonth, mDay);
 | 
			
		||||
            datePickerDialog.show();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void initCloseListener() {
 | 
			
		||||
        onClickListener = new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                finish();
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void disableProcessButton() {
 | 
			
		||||
 | 
			
		||||
        createNewMilestoneButton.setEnabled(false);
 | 
			
		||||
        GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
        shape.setCornerRadius( 8 );
 | 
			
		||||
        shape.setColor(getResources().getColor(R.color.hintColor));
 | 
			
		||||
        createNewMilestoneButton.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void enableProcessButton() {
 | 
			
		||||
 | 
			
		||||
        createNewMilestoneButton.setEnabled(true);
 | 
			
		||||
        GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
        shape.setCornerRadius( 8 );
 | 
			
		||||
        shape.setColor(getResources().getColor(R.color.btnBackground));
 | 
			
		||||
        createNewMilestoneButton.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,220 @@
 | 
			
		||||
package org.mian.gitnex.activities;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.graphics.drawable.GradientDrawable;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.widget.Button;
 | 
			
		||||
import android.widget.EditText;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.helpers.AlertDialogs;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.helpers.Toasty;
 | 
			
		||||
import org.mian.gitnex.models.UserOrganizations;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import retrofit2.Call;
 | 
			
		||||
import retrofit2.Callback;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class NewOrganizationActivity extends AppCompatActivity {
 | 
			
		||||
 | 
			
		||||
    public ImageView closeActivity;
 | 
			
		||||
    private View.OnClickListener onClickListener;
 | 
			
		||||
    private Button createOrganizationButton;
 | 
			
		||||
 | 
			
		||||
    private EditText orgName;
 | 
			
		||||
    private EditText orgDesc;
 | 
			
		||||
    final Context ctx = this;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        setContentView(R.layout.activity_new_organization);
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
 | 
			
		||||
        closeActivity = findViewById(R.id.close);
 | 
			
		||||
        orgName = findViewById(R.id.newOrganizationName);
 | 
			
		||||
        orgDesc = findViewById(R.id.newOrganizationDescription);
 | 
			
		||||
 | 
			
		||||
        initCloseListener();
 | 
			
		||||
        closeActivity.setOnClickListener(onClickListener);
 | 
			
		||||
 | 
			
		||||
        createOrganizationButton = findViewById(R.id.createNewOrganizationButton);
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
 | 
			
		||||
            createOrganizationButton.setEnabled(false);
 | 
			
		||||
            GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
            shape.setCornerRadius( 8 );
 | 
			
		||||
            shape.setColor(getResources().getColor(R.color.hintColor));
 | 
			
		||||
            createOrganizationButton.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
 | 
			
		||||
            createOrganizationButton.setOnClickListener(createOrgListener);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void initCloseListener() {
 | 
			
		||||
        onClickListener = new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                finish();
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private View.OnClickListener createOrgListener = new View.OnClickListener() {
 | 
			
		||||
        public void onClick(View v) {
 | 
			
		||||
            processNewOrganization();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    private void processNewOrganization() {
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
        AppUtil appUtil = new AppUtil();
 | 
			
		||||
        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 newOrgName = orgName.getText().toString();
 | 
			
		||||
        String newOrgDesc = orgDesc.getText().toString();
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!newOrgDesc.equals("")) {
 | 
			
		||||
            if (appUtil.charactersLength(newOrgDesc) > 255) {
 | 
			
		||||
 | 
			
		||||
                Toasty.info(getApplicationContext(), getString(R.string.orgDescError));
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(newOrgName.equals("")) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.orgNameErrorEmpty));
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        else if(!appUtil.checkStrings(newOrgName)) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.orgNameErrorInvalid));
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
 | 
			
		||||
            disableProcessButton();
 | 
			
		||||
            createNewOrganization(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), newOrgName, newOrgDesc);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void createNewOrganization(final String instanceUrl, final String token, String orgName, String orgDesc) {
 | 
			
		||||
 | 
			
		||||
        UserOrganizations createOrganization = new UserOrganizations(orgName, null, orgDesc, null, null);
 | 
			
		||||
 | 
			
		||||
        Call<UserOrganizations> call = RetrofitClient
 | 
			
		||||
            .getInstance(instanceUrl)
 | 
			
		||||
            .getApiInterface()
 | 
			
		||||
            .createNewOrganization(token, createOrganization);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<UserOrganizations>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<UserOrganizations> call, @NonNull retrofit2.Response<UserOrganizations> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.code() == 201) {
 | 
			
		||||
 | 
			
		||||
                    TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
                    tinyDb.putBoolean("orgCreated", true);
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.orgCreated));
 | 
			
		||||
                    finish();
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 401) {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedMessage),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 409) {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.orgExistsError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 422) {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.orgExistsError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
 | 
			
		||||
                    if(response.code() == 404) {
 | 
			
		||||
                        enableProcessButton();
 | 
			
		||||
                        Toasty.info(getApplicationContext(), getString(R.string.apiNotFound));
 | 
			
		||||
                    }
 | 
			
		||||
                    else {
 | 
			
		||||
                        enableProcessButton();
 | 
			
		||||
                        Toasty.info(getApplicationContext(), getString(R.string.orgCreatedError));
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<UserOrganizations> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
                enableProcessButton();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void disableProcessButton() {
 | 
			
		||||
 | 
			
		||||
        createOrganizationButton.setEnabled(false);
 | 
			
		||||
        GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
        shape.setCornerRadius( 8 );
 | 
			
		||||
        shape.setColor(getResources().getColor(R.color.hintColor));
 | 
			
		||||
        createOrganizationButton.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void enableProcessButton() {
 | 
			
		||||
 | 
			
		||||
        createOrganizationButton.setEnabled(true);
 | 
			
		||||
        GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
        shape.setCornerRadius( 8 );
 | 
			
		||||
        shape.setColor(getResources().getColor(R.color.btnBackground));
 | 
			
		||||
        createOrganizationButton.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,314 @@
 | 
			
		||||
package org.mian.gitnex.activities;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.graphics.PorterDuff;
 | 
			
		||||
import android.graphics.drawable.GradientDrawable;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.widget.AdapterView;
 | 
			
		||||
import android.widget.ArrayAdapter;
 | 
			
		||||
import android.widget.Button;
 | 
			
		||||
import android.widget.CheckBox;
 | 
			
		||||
import android.widget.EditText;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.Spinner;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.helpers.AlertDialogs;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.helpers.Toasty;
 | 
			
		||||
import org.mian.gitnex.models.OrgOwner;
 | 
			
		||||
import org.mian.gitnex.models.OrganizationRepository;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import retrofit2.Call;
 | 
			
		||||
import retrofit2.Callback;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class NewRepoActivity extends AppCompatActivity {
 | 
			
		||||
 | 
			
		||||
    public ImageView closeActivity;
 | 
			
		||||
    private View.OnClickListener onClickListener;
 | 
			
		||||
    private Spinner spinner;
 | 
			
		||||
    private Button createRepo;
 | 
			
		||||
    private EditText repoName;
 | 
			
		||||
    private EditText repoDesc;
 | 
			
		||||
    private CheckBox repoAccess;
 | 
			
		||||
    final Context ctx = this;
 | 
			
		||||
 | 
			
		||||
    List<OrgOwner> orgsList = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        setContentView(R.layout.activity_new_repo);
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
 | 
			
		||||
        TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
        final String instanceUrl = tinyDb.getString("instanceUrl");
 | 
			
		||||
        final String loginUid = tinyDb.getString("loginUid");
 | 
			
		||||
        final String userLogin = tinyDb.getString("userLogin");
 | 
			
		||||
        final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
 | 
			
		||||
 | 
			
		||||
        closeActivity = findViewById(R.id.close);
 | 
			
		||||
        repoName = findViewById(R.id.newRepoName);
 | 
			
		||||
        repoDesc = findViewById(R.id.newRepoDescription);
 | 
			
		||||
        repoAccess = findViewById(R.id.newRepoPrivate);
 | 
			
		||||
 | 
			
		||||
        initCloseListener();
 | 
			
		||||
        closeActivity.setOnClickListener(onClickListener);
 | 
			
		||||
 | 
			
		||||
        spinner = findViewById(R.id.ownerSpinner);
 | 
			
		||||
        spinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP);
 | 
			
		||||
        getOrgs(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), userLogin);
 | 
			
		||||
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
 | 
			
		||||
                OrgOwner user = (OrgOwner) parent.getSelectedItem();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onNothingSelected(AdapterView<?> parent) {
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        createRepo = findViewById(R.id.createNewRepoButton);
 | 
			
		||||
        disableProcessButton();
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
 | 
			
		||||
            disableProcessButton();
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
 | 
			
		||||
            createRepo.setOnClickListener(createRepoListener);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private View.OnClickListener createRepoListener = new View.OnClickListener() {
 | 
			
		||||
        public void onClick(View v) {
 | 
			
		||||
            processNewRepo();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    private void processNewRepo() {
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
        AppUtil appUtil = new AppUtil();
 | 
			
		||||
        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 newRepoName = repoName.getText().toString();
 | 
			
		||||
        String newRepoDesc = repoDesc.getText().toString();
 | 
			
		||||
        String repoOwner = spinner.getSelectedItem().toString();
 | 
			
		||||
        boolean newRepoAccess = repoAccess.isChecked();
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!newRepoDesc.equals("")) {
 | 
			
		||||
            if (appUtil.charactersLength(newRepoDesc) > 255) {
 | 
			
		||||
 | 
			
		||||
                Toasty.info(getApplicationContext(), getString(R.string.repoDescError));
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(newRepoName.equals("")) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.repoNameErrorEmpty));
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        else if(!appUtil.checkStrings(newRepoName)) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.repoNameErrorInvalid));
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
 | 
			
		||||
            //Log.i("repoOwner", String.valueOf(repoOwner));
 | 
			
		||||
            disableProcessButton();
 | 
			
		||||
            createNewRepository(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), loginUid, newRepoName, newRepoDesc, repoOwner, newRepoAccess);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void createNewRepository(final String instanceUrl, final String token, String loginUid, String repoName, String repoDesc, String repoOwner, boolean isPrivate) {
 | 
			
		||||
 | 
			
		||||
        OrganizationRepository createRepository = new OrganizationRepository(true, repoDesc, null, null, repoName, isPrivate, "Default");
 | 
			
		||||
 | 
			
		||||
        Call<OrganizationRepository> call;
 | 
			
		||||
        if(repoOwner.equals(loginUid)) {
 | 
			
		||||
 | 
			
		||||
            call = RetrofitClient
 | 
			
		||||
                    .getInstance(instanceUrl)
 | 
			
		||||
                    .getApiInterface()
 | 
			
		||||
                    .createNewUserRepository(token, createRepository);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
 | 
			
		||||
            call = RetrofitClient
 | 
			
		||||
                    .getInstance(instanceUrl)
 | 
			
		||||
                    .getApiInterface()
 | 
			
		||||
                    .createNewUserOrgRepository(token, repoOwner, createRepository);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<OrganizationRepository>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<OrganizationRepository> call, @NonNull retrofit2.Response<OrganizationRepository> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.code() == 201) {
 | 
			
		||||
 | 
			
		||||
                    TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
                    tinyDb.putBoolean("repoCreated", true);
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.repoCreated));
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    finish();
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 401) {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedMessage),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 409) {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.repoExistsError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.repoCreatedError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<OrganizationRepository> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
                enableProcessButton();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void getOrgs(String instanceUrl, String instanceToken, final String userLogin) {
 | 
			
		||||
 | 
			
		||||
        Call<List<OrgOwner>> call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .getOrgOwners(instanceToken);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<List<OrgOwner>>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<List<OrgOwner>> call, @NonNull retrofit2.Response<List<OrgOwner>> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.isSuccessful()) {
 | 
			
		||||
                    if(response.code() == 200) {
 | 
			
		||||
 | 
			
		||||
                        List<OrgOwner> orgsList_ = response.body();
 | 
			
		||||
 | 
			
		||||
                        orgsList.add(new OrgOwner(userLogin));
 | 
			
		||||
                        assert orgsList_ != null;
 | 
			
		||||
                        if(orgsList_.size() > 0) {
 | 
			
		||||
                            for (int i = 0; i < orgsList_.size(); i++) {
 | 
			
		||||
 | 
			
		||||
                                OrgOwner data = new OrgOwner(
 | 
			
		||||
                                        orgsList_.get(i).getUsername()
 | 
			
		||||
                                );
 | 
			
		||||
                                orgsList.add(data);
 | 
			
		||||
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        ArrayAdapter<OrgOwner> adapter = new ArrayAdapter<>(getApplicationContext(),
 | 
			
		||||
                                R.layout.spinner_item, orgsList);
 | 
			
		||||
 | 
			
		||||
                        adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
 | 
			
		||||
                        spinner.setAdapter(adapter);
 | 
			
		||||
                        enableProcessButton();
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 401) {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedMessage),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<List<OrgOwner>> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
                enableProcessButton();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void initCloseListener() {
 | 
			
		||||
        onClickListener = new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                finish();
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void disableProcessButton() {
 | 
			
		||||
 | 
			
		||||
        createRepo.setEnabled(false);
 | 
			
		||||
        GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
        shape.setCornerRadius( 8 );
 | 
			
		||||
        shape.setColor(getResources().getColor(R.color.hintColor));
 | 
			
		||||
        createRepo.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void enableProcessButton() {
 | 
			
		||||
 | 
			
		||||
        createRepo.setEnabled(true);
 | 
			
		||||
        GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
        shape.setCornerRadius( 8 );
 | 
			
		||||
        shape.setColor(getResources().getColor(R.color.btnBackground));
 | 
			
		||||
        createRepo.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,134 @@
 | 
			
		||||
package org.mian.gitnex.activities;
 | 
			
		||||
 | 
			
		||||
import com.google.android.material.tabs.TabLayout;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import androidx.appcompat.widget.Toolbar;
 | 
			
		||||
import androidx.fragment.app.Fragment;
 | 
			
		||||
import androidx.fragment.app.FragmentManager;
 | 
			
		||||
import androidx.fragment.app.FragmentPagerAdapter;
 | 
			
		||||
import androidx.viewpager.widget.ViewPager;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.view.Menu;
 | 
			
		||||
import android.view.MenuInflater;
 | 
			
		||||
import android.view.MenuItem;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.fragments.MembersByOrgFragment;
 | 
			
		||||
import org.mian.gitnex.fragments.OrgBottomSheetFragment;
 | 
			
		||||
import org.mian.gitnex.fragments.OrganizationInfoFragment;
 | 
			
		||||
import org.mian.gitnex.fragments.RepositoriesByOrgFragment;
 | 
			
		||||
import org.mian.gitnex.fragments.TeamsByOrgFragment;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class OrgDetailActivity extends AppCompatActivity implements OrgBottomSheetFragment.BottomSheetListener {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        setContentView(R.layout.activity_org_detail);
 | 
			
		||||
 | 
			
		||||
        TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
        String orgName = tinyDb.getString("orgName");
 | 
			
		||||
 | 
			
		||||
        Toolbar toolbar = findViewById(R.id.toolbar);
 | 
			
		||||
        setSupportActionBar(toolbar);
 | 
			
		||||
        Objects.requireNonNull(getSupportActionBar()).setTitle(orgName);
 | 
			
		||||
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
 | 
			
		||||
 | 
			
		||||
        OrgDetailActivity.SectionsPagerAdapter mSectionsPagerAdapter = new OrgDetailActivity.SectionsPagerAdapter(getSupportFragmentManager());
 | 
			
		||||
 | 
			
		||||
        ViewPager mViewPager = findViewById(R.id.container);
 | 
			
		||||
        mViewPager.setAdapter(mSectionsPagerAdapter);
 | 
			
		||||
 | 
			
		||||
        TabLayout tabLayout = findViewById(R.id.tabs);
 | 
			
		||||
 | 
			
		||||
        mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
 | 
			
		||||
        tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @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:
 | 
			
		||||
                OrgBottomSheetFragment bottomSheet = new OrgBottomSheetFragment();
 | 
			
		||||
                bottomSheet.show(getSupportFragmentManager(), "orgBottomSheet");
 | 
			
		||||
                return true;
 | 
			
		||||
            default:
 | 
			
		||||
                return super.onOptionsItemSelected(item);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onButtonClicked(String text) {
 | 
			
		||||
 | 
			
		||||
        switch (text) {
 | 
			
		||||
            case "team":
 | 
			
		||||
                startActivity(new Intent(OrgDetailActivity.this, CreateTeamByOrgActivity.class));
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
        //Log.i("clicked", text);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class SectionsPagerAdapter extends FragmentPagerAdapter {
 | 
			
		||||
 | 
			
		||||
        SectionsPagerAdapter(FragmentManager fm) {
 | 
			
		||||
            super(fm);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @NonNull
 | 
			
		||||
        @Override
 | 
			
		||||
        public Fragment getItem(int position) {
 | 
			
		||||
 | 
			
		||||
            TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
            String orgName;
 | 
			
		||||
            if(getIntent().getStringExtra("orgName") != null || !getIntent().getStringExtra("orgName").equals("")) {
 | 
			
		||||
                orgName = getIntent().getStringExtra("orgName");
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                orgName = tinyDb.getString("orgName");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Fragment fragment = null;
 | 
			
		||||
            switch (position) {
 | 
			
		||||
                case 0: // info
 | 
			
		||||
                    return OrganizationInfoFragment.newInstance(orgName);
 | 
			
		||||
                case 1: // repos
 | 
			
		||||
                    return RepositoriesByOrgFragment.newInstance(orgName);
 | 
			
		||||
                case 2: // teams
 | 
			
		||||
                    return TeamsByOrgFragment.newInstance(orgName);
 | 
			
		||||
                case 3: // members
 | 
			
		||||
                    return MembersByOrgFragment.newInstance(orgName);
 | 
			
		||||
            }
 | 
			
		||||
            return fragment;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public int getCount() {
 | 
			
		||||
            return 4;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,102 @@
 | 
			
		||||
package org.mian.gitnex.activities;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.Nullable;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import androidx.lifecycle.Observer;
 | 
			
		||||
import androidx.lifecycle.ViewModelProviders;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.widget.GridView;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.adapters.TeamMembersByOrgAdapter;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.models.UserInfo;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import org.mian.gitnex.viewmodels.TeamMembersByOrgViewModel;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class OrgTeamMembersActivity extends AppCompatActivity {
 | 
			
		||||
 | 
			
		||||
    private TextView noDataMembers;
 | 
			
		||||
    private View.OnClickListener onClickListener;
 | 
			
		||||
    private TeamMembersByOrgAdapter adapter;
 | 
			
		||||
    private GridView mGridView;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        setContentView(R.layout.activity_org_team_members);
 | 
			
		||||
 | 
			
		||||
        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");
 | 
			
		||||
 | 
			
		||||
        ImageView closeActivity = findViewById(R.id.close);
 | 
			
		||||
        TextView toolbarTitle = findViewById(R.id.toolbar_title);
 | 
			
		||||
        noDataMembers = findViewById(R.id.noDataMembers);
 | 
			
		||||
        mGridView = findViewById(R.id.gridView);
 | 
			
		||||
 | 
			
		||||
        initCloseListener();
 | 
			
		||||
        closeActivity.setOnClickListener(onClickListener);
 | 
			
		||||
 | 
			
		||||
        if(getIntent().getStringExtra("teamTitle") != null && !getIntent().getStringExtra("teamTitle").equals("")) {
 | 
			
		||||
            toolbarTitle.setText(getIntent().getStringExtra("teamTitle"));
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            toolbarTitle.setText(R.string.orgTeamMembers);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        String teamId;
 | 
			
		||||
        if(getIntent().getStringExtra("teamId") != null && !getIntent().getStringExtra("teamId").equals("")){
 | 
			
		||||
            teamId = getIntent().getStringExtra("teamId");
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            teamId = "0";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        getIntent().getStringExtra("teamId");
 | 
			
		||||
        Log.i("teamId", getIntent().getStringExtra("teamId"));
 | 
			
		||||
 | 
			
		||||
        fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), Integer.valueOf(teamId));
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void fetchDataAsync(String instanceUrl, String instanceToken, int teamId) {
 | 
			
		||||
 | 
			
		||||
        TeamMembersByOrgViewModel teamMembersModel = ViewModelProviders.of(this).get(TeamMembersByOrgViewModel.class);
 | 
			
		||||
 | 
			
		||||
        teamMembersModel.getMembersByOrgList(instanceUrl, instanceToken, teamId).observe(this, new Observer<List<UserInfo>>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onChanged(@Nullable List<UserInfo> teamMembersListMain) {
 | 
			
		||||
                adapter = new TeamMembersByOrgAdapter(getApplicationContext(), teamMembersListMain);
 | 
			
		||||
                if(adapter.getCount() > 0) {
 | 
			
		||||
                    mGridView.setAdapter(adapter);
 | 
			
		||||
                    noDataMembers.setVisibility(View.GONE);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    adapter.notifyDataSetChanged();
 | 
			
		||||
                    mGridView.setAdapter(adapter);
 | 
			
		||||
                    noDataMembers.setVisibility(View.VISIBLE);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void initCloseListener() {
 | 
			
		||||
        onClickListener = new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                finish();
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,208 @@
 | 
			
		||||
package org.mian.gitnex.activities;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import retrofit2.Call;
 | 
			
		||||
import retrofit2.Callback;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.graphics.drawable.GradientDrawable;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.util.Patterns;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.widget.Button;
 | 
			
		||||
import android.widget.EditText;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import com.google.gson.JsonElement;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.helpers.AlertDialogs;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.helpers.Toasty;
 | 
			
		||||
import org.mian.gitnex.models.AddEmail;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class ProfileEmailActivity extends AppCompatActivity {
 | 
			
		||||
 | 
			
		||||
    private View.OnClickListener onClickListener;
 | 
			
		||||
    private EditText userEmail;
 | 
			
		||||
    final Context ctx = this;
 | 
			
		||||
    private Button addEmailButton;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        setContentView(R.layout.activity_profile_email);
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
 | 
			
		||||
        ImageView closeActivity = findViewById(R.id.close);
 | 
			
		||||
        userEmail = findViewById(R.id.userEmail);
 | 
			
		||||
        addEmailButton = findViewById(R.id.addEmailButton);
 | 
			
		||||
 | 
			
		||||
        initCloseListener();
 | 
			
		||||
        closeActivity.setOnClickListener(onClickListener);
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
 | 
			
		||||
            disableProcessButton();
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
 | 
			
		||||
            addEmailButton.setOnClickListener(addEmailListener);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private View.OnClickListener addEmailListener = new View.OnClickListener() {
 | 
			
		||||
        public void onClick(View v) {
 | 
			
		||||
            processAddNewEmail();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    private void processAddNewEmail() {
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
        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 newUserEmail = userEmail.getText().toString().trim();
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(newUserEmail.equals("")) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.emailErrorEmpty));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        else if(!Patterns.EMAIL_ADDRESS.matcher(newUserEmail).matches()) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.emailErrorInvalid));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        List<String> newEmailList = new ArrayList<>(Arrays.asList(newUserEmail.split(",")));
 | 
			
		||||
 | 
			
		||||
        disableProcessButton();
 | 
			
		||||
        addNewEmail(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), newEmailList);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void addNewEmail(final String instanceUrl, final String token, List<String> newUserEmail) {
 | 
			
		||||
 | 
			
		||||
        AddEmail addEmailFunc = new AddEmail(newUserEmail);
 | 
			
		||||
        final TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
 | 
			
		||||
        Call<JsonElement> call;
 | 
			
		||||
 | 
			
		||||
        call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .addNewEmail(token, addEmailFunc);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<JsonElement>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<JsonElement> call, @NonNull retrofit2.Response<JsonElement> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.code() == 201) {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.emailAddedText));
 | 
			
		||||
                    tinyDb.putBoolean("emailsRefresh", true);
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    finish();
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 401) {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedMessage),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 403) {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    Toasty.info(ctx, ctx.getString(R.string.authorizeError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 404) {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    Toasty.info(ctx, ctx.getString(R.string.apiNotFound));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 422) {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    Toasty.info(ctx, ctx.getString(R.string.emailErrorInUse));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.labelGeneralError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<JsonElement> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
                enableProcessButton();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void initCloseListener() {
 | 
			
		||||
        onClickListener = new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                finish();
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void disableProcessButton() {
 | 
			
		||||
 | 
			
		||||
        addEmailButton.setEnabled(false);
 | 
			
		||||
        GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
        shape.setCornerRadius( 8 );
 | 
			
		||||
        shape.setColor(getResources().getColor(R.color.hintColor));
 | 
			
		||||
        addEmailButton.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void enableProcessButton() {
 | 
			
		||||
 | 
			
		||||
        addEmailButton.setEnabled(true);
 | 
			
		||||
        GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
        shape.setCornerRadius( 8 );
 | 
			
		||||
        shape.setColor(getResources().getColor(R.color.btnBackground));
 | 
			
		||||
        addEmailButton.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,278 @@
 | 
			
		||||
package org.mian.gitnex.activities;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import retrofit2.Call;
 | 
			
		||||
import retrofit2.Callback;
 | 
			
		||||
import retrofit2.Response;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.graphics.drawable.GradientDrawable;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.widget.ArrayAdapter;
 | 
			
		||||
import android.widget.Button;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import com.hendraanggrian.appcompat.socialview.Mention;
 | 
			
		||||
import com.hendraanggrian.appcompat.widget.MentionArrayAdapter;
 | 
			
		||||
import com.hendraanggrian.appcompat.widget.SocialAutoCompleteTextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.actions.IssueActions;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.helpers.AlertDialogs;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.helpers.Toasty;
 | 
			
		||||
import org.mian.gitnex.models.Collaborators;
 | 
			
		||||
import org.mian.gitnex.models.Issues;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class ReplyToIssueActivity extends AppCompatActivity {
 | 
			
		||||
 | 
			
		||||
    public ImageView closeActivity;
 | 
			
		||||
    private View.OnClickListener onClickListener;
 | 
			
		||||
 | 
			
		||||
    final Context ctx = this;
 | 
			
		||||
 | 
			
		||||
    private SocialAutoCompleteTextView addComment;
 | 
			
		||||
    private ArrayAdapter<Mention> defaultMentionAdapter;
 | 
			
		||||
    private Button replyButton;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        setContentView(R.layout.activity_reply_to_issue);
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
        TinyDB tinyDb = new TinyDB(getApplicationContext());
 | 
			
		||||
 | 
			
		||||
        addComment = findViewById(R.id.addComment);
 | 
			
		||||
        addComment.setShowSoftInputOnFocus(true);
 | 
			
		||||
 | 
			
		||||
        defaultMentionAdapter = new MentionArrayAdapter<>(this);
 | 
			
		||||
        loadCollaboratorsList();
 | 
			
		||||
 | 
			
		||||
        addComment.setMentionAdapter(defaultMentionAdapter);
 | 
			
		||||
 | 
			
		||||
        closeActivity = findViewById(R.id.close);
 | 
			
		||||
        TextView toolbar_title = findViewById(R.id.toolbar_title);
 | 
			
		||||
 | 
			
		||||
        if(!tinyDb.getString("issueTitle").isEmpty()) {
 | 
			
		||||
            toolbar_title.setText(tinyDb.getString("issueTitle"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        initCloseListener();
 | 
			
		||||
        closeActivity.setOnClickListener(onClickListener);
 | 
			
		||||
 | 
			
		||||
        replyButton = findViewById(R.id.replyButton);
 | 
			
		||||
 | 
			
		||||
        if(getIntent().getStringExtra("commentAction") != null && getIntent().getStringExtra("commentAction").equals("edit")) {
 | 
			
		||||
 | 
			
		||||
            addComment.setText(getIntent().getStringExtra("commentBody"));
 | 
			
		||||
            final String commentId = getIntent().getStringExtra("commentId");
 | 
			
		||||
 | 
			
		||||
            toolbar_title.setText(getResources().getString(R.string.editCommentTitle));
 | 
			
		||||
            replyButton.setText(getResources().getString(R.string.editCommentButtonText));
 | 
			
		||||
 | 
			
		||||
            replyButton.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
                public void onClick(View v) {
 | 
			
		||||
                    IssueActions.editIssueComment(ctx, Integer.valueOf(commentId), addComment.getText().toString());
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
 | 
			
		||||
            disableProcessButton();
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
 | 
			
		||||
            replyButton.setOnClickListener(replyToIssue);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void loadCollaboratorsList() {
 | 
			
		||||
 | 
			
		||||
        final 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];
 | 
			
		||||
 | 
			
		||||
        Call<List<Collaborators>> call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .getCollaborators(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<List<Collaborators>>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<List<Collaborators>> call, @NonNull Response<List<Collaborators>> response) {
 | 
			
		||||
 | 
			
		||||
                if (response.isSuccessful()) {
 | 
			
		||||
 | 
			
		||||
                    assert response.body() != null;
 | 
			
		||||
                    String fullName = "";
 | 
			
		||||
                    for (int i = 0; i < response.body().size(); i++) {
 | 
			
		||||
                        if(!response.body().get(i).getFull_name().equals("")) {
 | 
			
		||||
                            fullName = response.body().get(i).getFull_name();
 | 
			
		||||
                        }
 | 
			
		||||
                        defaultMentionAdapter.add(
 | 
			
		||||
                                new Mention(response.body().get(i).getUsername(), fullName, response.body().get(i).getAvatar_url()));
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                } else {
 | 
			
		||||
 | 
			
		||||
                    Log.i("onResponse", String.valueOf(response.code()));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<List<Collaborators>> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.i("onFailure", t.getMessage());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void initCloseListener() {
 | 
			
		||||
        onClickListener = new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                finish();
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private View.OnClickListener replyToIssue = new View.OnClickListener() {
 | 
			
		||||
        public void onClick(View v) {
 | 
			
		||||
            processNewCommentReply();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    private void processNewCommentReply() {
 | 
			
		||||
 | 
			
		||||
        String newReplyDT = addComment.getText().toString();
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getApplicationContext());
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getResources().getString(R.string.checkNetConnection));
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(newReplyDT.equals("")) {
 | 
			
		||||
 | 
			
		||||
            Toasty.info(getApplicationContext(), getString(R.string.commentEmptyError));
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
 | 
			
		||||
            disableProcessButton();
 | 
			
		||||
            replyComment(newReplyDT);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void replyComment(String newReplyDT) {
 | 
			
		||||
 | 
			
		||||
        final 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];
 | 
			
		||||
        final int issueIndex = Integer.parseInt(tinyDb.getString("issueNumber"));
 | 
			
		||||
 | 
			
		||||
        Issues issueComment = new Issues(newReplyDT);
 | 
			
		||||
 | 
			
		||||
        Call<Issues> call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .replyCommentToIssue(Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName, issueIndex, issueComment);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<Issues>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<Issues> call, @NonNull retrofit2.Response<Issues> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.code() == 201) {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.commentSuccess));
 | 
			
		||||
                    tinyDb.putBoolean("commentPosted", true);
 | 
			
		||||
                    tinyDb.putBoolean("resumeIssues", true);
 | 
			
		||||
                    finish();
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 401) {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    AlertDialogs.authorizationTokenRevokedDialog(ctx, getResources().getString(R.string.alertDialogTokenRevokedTitle),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedMessage),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
 | 
			
		||||
                            getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
 | 
			
		||||
                    enableProcessButton();
 | 
			
		||||
                    Toasty.info(getApplicationContext(), getString(R.string.commentError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<Issues> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
                enableProcessButton();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void disableProcessButton() {
 | 
			
		||||
 | 
			
		||||
        replyButton.setEnabled(false);
 | 
			
		||||
        GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
        shape.setCornerRadius( 8 );
 | 
			
		||||
        shape.setColor(getResources().getColor(R.color.hintColor));
 | 
			
		||||
        replyButton.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void enableProcessButton() {
 | 
			
		||||
 | 
			
		||||
        replyButton.setEnabled(true);
 | 
			
		||||
        GradientDrawable shape =  new GradientDrawable();
 | 
			
		||||
        shape.setCornerRadius( 8 );
 | 
			
		||||
        shape.setColor(getResources().getColor(R.color.btnBackground));
 | 
			
		||||
        replyButton.setBackground(shape);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,245 @@
 | 
			
		||||
package org.mian.gitnex.activities;
 | 
			
		||||
 | 
			
		||||
import com.google.android.material.tabs.TabLayout;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
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.content.Intent;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
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.widget.TextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.fragments.BranchesFragment;
 | 
			
		||||
import org.mian.gitnex.fragments.ClosedIssuesFragment;
 | 
			
		||||
import org.mian.gitnex.fragments.CollaboratorsFragment;
 | 
			
		||||
import org.mian.gitnex.fragments.IssuesFragment;
 | 
			
		||||
import org.mian.gitnex.fragments.LabelsFragment;
 | 
			
		||||
import org.mian.gitnex.fragments.MilestonesFragment;
 | 
			
		||||
import org.mian.gitnex.fragments.ReleasesFragment;
 | 
			
		||||
import org.mian.gitnex.fragments.RepoBottomSheetFragment;
 | 
			
		||||
import org.mian.gitnex.fragments.RepoInfoFragment;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.models.UserRepositories;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class RepoDetailActivity extends AppCompatActivity implements RepoBottomSheetFragment.BottomSheetListener {
 | 
			
		||||
 | 
			
		||||
    private TextView textViewBadge;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        setContentView(R.layout.activity_repo_detail);
 | 
			
		||||
 | 
			
		||||
        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);
 | 
			
		||||
        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);
 | 
			
		||||
 | 
			
		||||
        mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
 | 
			
		||||
        tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
 | 
			
		||||
 | 
			
		||||
        if(tinyDb.getBoolean("enableCounterIssueBadge")) {
 | 
			
		||||
 | 
			
		||||
            View tabHeader = LayoutInflater.from(this).inflate(R.layout.badge, null);
 | 
			
		||||
            textViewBadge = tabHeader.findViewById(R.id.counterBadge);
 | 
			
		||||
            if(!tinyDb.getString("issuesCounter").isEmpty()) {
 | 
			
		||||
                getRepoInfo(instanceUrl, Authorization.returnAuthentication(getApplicationContext(), loginUid, instanceToken), repoOwner, repoName1);
 | 
			
		||||
            }
 | 
			
		||||
            Objects.requireNonNull(tabLayout.getTabAt(1)).setCustomView(tabHeader);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @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:
 | 
			
		||||
                RepoBottomSheetFragment bottomSheet = new RepoBottomSheetFragment();
 | 
			
		||||
                bottomSheet.show(getSupportFragmentManager(), "repoBottomSheet");
 | 
			
		||||
                return true;
 | 
			
		||||
            default:
 | 
			
		||||
                return super.onOptionsItemSelected(item);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onButtonClicked(String text) {
 | 
			
		||||
 | 
			
		||||
        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, NewMilestoneActivity.class));
 | 
			
		||||
                break;
 | 
			
		||||
            case "addCollaborator":
 | 
			
		||||
                startActivity(new Intent(RepoDetailActivity.this, AddCollaboratorToRepositoryActivity.class));
 | 
			
		||||
                break;
 | 
			
		||||
            case "createRelease":
 | 
			
		||||
                startActivity(new Intent(RepoDetailActivity.this, CreateReleaseActivity.class));
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
 | 
			
		||||
 | 
			
		||||
        SectionsPagerAdapter(FragmentManager fm) {
 | 
			
		||||
            super(fm);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @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: // issues
 | 
			
		||||
                    fragment = new IssuesFragment();
 | 
			
		||||
                    break;
 | 
			
		||||
                case 2: // closed issues
 | 
			
		||||
                    fragment = new ClosedIssuesFragment();
 | 
			
		||||
                    break;
 | 
			
		||||
                case 3: // milestones
 | 
			
		||||
                    return MilestonesFragment.newInstance(repoOwner, repoName);
 | 
			
		||||
                case 4: // labels
 | 
			
		||||
                    return LabelsFragment.newInstance(repoOwner, repoName);
 | 
			
		||||
                case 5: // branches
 | 
			
		||||
                    return BranchesFragment.newInstance(repoOwner, repoName);
 | 
			
		||||
                case 6: // releases
 | 
			
		||||
                    return ReleasesFragment.newInstance(repoOwner, repoName);
 | 
			
		||||
                case 7: // collaborators
 | 
			
		||||
                    return CollaboratorsFragment.newInstance(repoOwner, repoName);
 | 
			
		||||
            }
 | 
			
		||||
            return fragment;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public int getCount() {
 | 
			
		||||
            return 8;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void getRepoInfo(String instanceUrl, String token, final String owner, String repo) {
 | 
			
		||||
 | 
			
		||||
        Call<UserRepositories> call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .getUserRepository(token, owner, repo);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<UserRepositories>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<UserRepositories> call, @NonNull retrofit2.Response<UserRepositories> response) {
 | 
			
		||||
 | 
			
		||||
                UserRepositories repoInfo = response.body();
 | 
			
		||||
 | 
			
		||||
                if (response.isSuccessful()) {
 | 
			
		||||
 | 
			
		||||
                    if (response.code() == 200) {
 | 
			
		||||
 | 
			
		||||
                        assert repoInfo != null;
 | 
			
		||||
                        textViewBadge.setText(repoInfo.getOpen_issues_count());
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    Log.e("onFailure", String.valueOf(response.code()));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<UserRepositories> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,37 @@
 | 
			
		||||
package org.mian.gitnex.activities;
 | 
			
		||||
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class SponsorsActivity extends AppCompatActivity {
 | 
			
		||||
 | 
			
		||||
    private View.OnClickListener onClickListener;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        setContentView(R.layout.activity_sponsors);
 | 
			
		||||
 | 
			
		||||
        ImageView closeActivity = findViewById(R.id.close);
 | 
			
		||||
 | 
			
		||||
        initCloseListener();
 | 
			
		||||
        closeActivity.setOnClickListener(onClickListener);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void initCloseListener() {
 | 
			
		||||
        onClickListener = new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                finish();
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,145 @@
 | 
			
		||||
package org.mian.gitnex.adapters;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
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.TextView;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import com.amulyakhare.textdrawable.TextDrawable;
 | 
			
		||||
import com.squareup.picasso.Picasso;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.helpers.RoundedTransformation;
 | 
			
		||||
import org.mian.gitnex.models.UserInfo;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class AdminGetUsersAdapter extends RecyclerView.Adapter<AdminGetUsersAdapter.UsersViewHolder> implements Filterable {
 | 
			
		||||
 | 
			
		||||
    private List<UserInfo> usersList;
 | 
			
		||||
    private Context mCtx;
 | 
			
		||||
    private List<UserInfo> usersListFull;
 | 
			
		||||
 | 
			
		||||
    static class UsersViewHolder extends RecyclerView.ViewHolder {
 | 
			
		||||
 | 
			
		||||
        private ImageView userAvatar;
 | 
			
		||||
        private TextView userFullName;
 | 
			
		||||
        private TextView userEmail;
 | 
			
		||||
        private ImageView userRole;
 | 
			
		||||
        private TextView userName;
 | 
			
		||||
 | 
			
		||||
        private UsersViewHolder(View itemView) {
 | 
			
		||||
            super(itemView);
 | 
			
		||||
 | 
			
		||||
            userAvatar = itemView.findViewById(R.id.userAvatar);
 | 
			
		||||
            userFullName = itemView.findViewById(R.id.userFullName);
 | 
			
		||||
            userName = itemView.findViewById(R.id.userName);
 | 
			
		||||
            userEmail = itemView.findViewById(R.id.userEmail);
 | 
			
		||||
            userRole = itemView.findViewById(R.id.userRole);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public AdminGetUsersAdapter(Context mCtx, List<UserInfo> usersListMain) {
 | 
			
		||||
        this.mCtx = mCtx;
 | 
			
		||||
        this.usersList = usersListMain;
 | 
			
		||||
        usersListFull = new ArrayList<>(usersList);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
    @Override
 | 
			
		||||
    public AdminGetUsersAdapter.UsersViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
 | 
			
		||||
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.admin_users_list, parent, false);
 | 
			
		||||
        return new AdminGetUsersAdapter.UsersViewHolder(v);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onBindViewHolder(@NonNull AdminGetUsersAdapter.UsersViewHolder holder, int position) {
 | 
			
		||||
 | 
			
		||||
        UserInfo currentItem = usersList.get(position);
 | 
			
		||||
 | 
			
		||||
        if(!currentItem.getFullname().equals("")) {
 | 
			
		||||
            holder.userFullName.setText(currentItem.getFullname());
 | 
			
		||||
            holder.userName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            holder.userFullName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
 | 
			
		||||
            holder.userName.setVisibility(View.GONE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!currentItem.getEmail().equals("")) {
 | 
			
		||||
            holder.userEmail.setText(currentItem.getEmail());
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            holder.userEmail.setVisibility(View.GONE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(currentItem.getIs_admin()) {
 | 
			
		||||
            holder.userRole.setVisibility(View.VISIBLE);
 | 
			
		||||
            TextDrawable drawable = TextDrawable.builder()
 | 
			
		||||
                    .beginConfig()
 | 
			
		||||
                    .textColor(mCtx.getResources().getColor(R.color.white))
 | 
			
		||||
                    .fontSize(44)
 | 
			
		||||
                    .width(180)
 | 
			
		||||
                    .height(60)
 | 
			
		||||
                    .endConfig()
 | 
			
		||||
                    .buildRoundRect(mCtx.getResources().getString(R.string.userRoleAdmin).toLowerCase(), mCtx.getResources().getColor(R.color.releasePre), 8);
 | 
			
		||||
            holder.userRole.setImageDrawable(drawable);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            holder.userRole.setVisibility(View.GONE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(100, 0)).resize(140, 140).centerCrop().into(holder.userAvatar);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getItemCount() {
 | 
			
		||||
        return usersList.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Filter getFilter() {
 | 
			
		||||
        return usersFilter;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Filter usersFilter = new Filter() {
 | 
			
		||||
        @Override
 | 
			
		||||
        protected FilterResults performFiltering(CharSequence constraint) {
 | 
			
		||||
            List<UserInfo> filteredList = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
            if (constraint == null || constraint.length() == 0) {
 | 
			
		||||
                filteredList.addAll(usersListFull);
 | 
			
		||||
            } else {
 | 
			
		||||
                String filterPattern = constraint.toString().toLowerCase().trim();
 | 
			
		||||
 | 
			
		||||
                for (UserInfo item : usersListFull) {
 | 
			
		||||
                    if (item.getEmail().toLowerCase().contains(filterPattern) || item.getFullname().toLowerCase().contains(filterPattern) || item.getUsername().toLowerCase().contains(filterPattern)) {
 | 
			
		||||
                        filteredList.add(item);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            FilterResults results = new FilterResults();
 | 
			
		||||
            results.values = filteredList;
 | 
			
		||||
 | 
			
		||||
            return results;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        protected void publishResults(CharSequence constraint, FilterResults results) {
 | 
			
		||||
            usersList.clear();
 | 
			
		||||
            usersList.addAll((List) results.values);
 | 
			
		||||
            notifyDataSetChanged();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,80 @@
 | 
			
		||||
package org.mian.gitnex.adapters;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.helpers.UrlHelper;
 | 
			
		||||
import org.mian.gitnex.models.Branches;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class BranchesAdapter extends RecyclerView.Adapter<BranchesAdapter.BranchesViewHolder> {
 | 
			
		||||
 | 
			
		||||
    private List<Branches> branchesList;
 | 
			
		||||
    private Context mCtx;
 | 
			
		||||
 | 
			
		||||
    static class BranchesViewHolder extends RecyclerView.ViewHolder {
 | 
			
		||||
 | 
			
		||||
        private TextView branchNameTv;
 | 
			
		||||
        private TextView branchCommitAuthor;
 | 
			
		||||
        private TextView branchCommitHash;
 | 
			
		||||
 | 
			
		||||
        private BranchesViewHolder(View itemView) {
 | 
			
		||||
            super(itemView);
 | 
			
		||||
 | 
			
		||||
            branchNameTv = itemView.findViewById(R.id.branchName);
 | 
			
		||||
            branchCommitAuthor = itemView.findViewById(R.id.branchCommitAuthor);
 | 
			
		||||
            branchCommitHash = itemView.findViewById(R.id.branchCommitHash);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public BranchesAdapter(Context mCtx, List<Branches> branchesMain) {
 | 
			
		||||
        this.mCtx = mCtx;
 | 
			
		||||
        this.branchesList = branchesMain;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
    @Override
 | 
			
		||||
    public BranchesAdapter.BranchesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
 | 
			
		||||
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.branches_list, parent, false);
 | 
			
		||||
        return new BranchesAdapter.BranchesViewHolder(v);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onBindViewHolder(@NonNull BranchesAdapter.BranchesViewHolder holder, int position) {
 | 
			
		||||
 | 
			
		||||
        final TinyDB tinyDb = new TinyDB(mCtx);
 | 
			
		||||
        final String instanceUrl = tinyDb.getString("instanceUrl");
 | 
			
		||||
 | 
			
		||||
        Branches currentItem = branchesList.get(position);
 | 
			
		||||
        holder.branchNameTv.setText(currentItem.getName());
 | 
			
		||||
 | 
			
		||||
        if(currentItem.getCommit().getAuthor().getName() != null || !currentItem.getCommit().getAuthor().getName().equals("")) {
 | 
			
		||||
            holder.branchCommitAuthor.setText(mCtx.getResources().getString(R.string.commitAuthor, currentItem.getCommit().getAuthor().getName()));
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            holder.branchCommitAuthor.setText(mCtx.getResources().getString(R.string.commitAuthor, currentItem.getCommit().getAuthor().getUsername()));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        holder.branchCommitHash.setText(mCtx.getResources().getString(R.string.commitHash, UrlHelper.cleanUrl(instanceUrl), currentItem.getCommit().getUrl()));
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getItemCount() {
 | 
			
		||||
        return branchesList.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,343 @@
 | 
			
		||||
package org.mian.gitnex.adapters;
 | 
			
		||||
 | 
			
		||||
import android.annotation.SuppressLint;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.graphics.Color;
 | 
			
		||||
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.TextView;
 | 
			
		||||
import com.squareup.picasso.Picasso;
 | 
			
		||||
import com.vdurmont.emoji.EmojiParser;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.activities.IssueDetailActivity;
 | 
			
		||||
import org.mian.gitnex.helpers.ClickListener;
 | 
			
		||||
import org.mian.gitnex.helpers.RoundedTransformation;
 | 
			
		||||
import org.mian.gitnex.helpers.TimeHelper;
 | 
			
		||||
import org.mian.gitnex.helpers.UserMentions;
 | 
			
		||||
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.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import okhttp3.OkHttpClient;
 | 
			
		||||
import ru.noties.markwon.AbstractMarkwonPlugin;
 | 
			
		||||
import ru.noties.markwon.Markwon;
 | 
			
		||||
import ru.noties.markwon.core.CorePlugin;
 | 
			
		||||
import ru.noties.markwon.core.MarkwonTheme;
 | 
			
		||||
import ru.noties.markwon.ext.strikethrough.StrikethroughPlugin;
 | 
			
		||||
import ru.noties.markwon.ext.tables.TablePlugin;
 | 
			
		||||
import ru.noties.markwon.ext.tables.TableTheme;
 | 
			
		||||
import ru.noties.markwon.ext.tasklist.TaskListPlugin;
 | 
			
		||||
import ru.noties.markwon.html.HtmlPlugin;
 | 
			
		||||
import ru.noties.markwon.image.ImagesPlugin;
 | 
			
		||||
import ru.noties.markwon.image.gif.GifPlugin;
 | 
			
		||||
import ru.noties.markwon.image.okhttp.OkHttpImagesPlugin;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class ClosedIssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {
 | 
			
		||||
 | 
			
		||||
    private Context context;
 | 
			
		||||
    private final int TYPE_LOAD = 0;
 | 
			
		||||
    private List<Issues> issuesList;
 | 
			
		||||
    private List<Issues> issuesListFull;
 | 
			
		||||
    private ClosedIssuesAdapter.OnLoadMoreListener loadMoreListener;
 | 
			
		||||
    private boolean isLoading = false, isMoreDataAvailable = true;
 | 
			
		||||
 | 
			
		||||
    public ClosedIssuesAdapter(Context context, List<Issues> issuesListMain) {
 | 
			
		||||
 | 
			
		||||
        this.context = context;
 | 
			
		||||
        this.issuesList = issuesListMain;
 | 
			
		||||
        issuesListFull = new ArrayList<>(issuesList);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
    @Override
 | 
			
		||||
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
 | 
			
		||||
 | 
			
		||||
        LayoutInflater inflater = LayoutInflater.from(context);
 | 
			
		||||
 | 
			
		||||
        if(viewType == TYPE_LOAD){
 | 
			
		||||
            return new ClosedIssuesAdapter.IssuesHolder(inflater.inflate(R.layout.repo_detail_issues_list, parent,false));
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            return new ClosedIssuesAdapter.LoadHolder(inflater.inflate(R.layout.row_load,parent,false));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
 | 
			
		||||
 | 
			
		||||
        if(position >= getItemCount()-1 && isMoreDataAvailable && !isLoading && loadMoreListener!=null) {
 | 
			
		||||
 | 
			
		||||
            isLoading = true;
 | 
			
		||||
            loadMoreListener.onLoadMore();
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(getItemViewType(position) == TYPE_LOAD) {
 | 
			
		||||
 | 
			
		||||
            ((ClosedIssuesAdapter.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;
 | 
			
		||||
        private TextView issueTitle;
 | 
			
		||||
        private TextView issueDescription;
 | 
			
		||||
        //private ImageView issueState;
 | 
			
		||||
        private TextView issueCreatedTime;
 | 
			
		||||
        private TextView issueCommentsCount;
 | 
			
		||||
        private ImageView issueType;
 | 
			
		||||
 | 
			
		||||
        IssuesHolder(View itemView) {
 | 
			
		||||
 | 
			
		||||
            super(itemView);
 | 
			
		||||
 | 
			
		||||
            issueNumber = itemView.findViewById(R.id.issueNumber);
 | 
			
		||||
            issueAssigneeAvatar = itemView.findViewById(R.id.assigneeAvatar);
 | 
			
		||||
            issueTitle = itemView.findViewById(R.id.issueTitle);
 | 
			
		||||
            issueDescription = itemView.findViewById(R.id.issueDescription);
 | 
			
		||||
            issueCommentsCount = itemView.findViewById(R.id.issueCommentsCount);
 | 
			
		||||
            //issueState = itemView.findViewById(R.id.issueStatus);
 | 
			
		||||
            issueCreatedTime = itemView.findViewById(R.id.issueCreatedTime);
 | 
			
		||||
            issueType = itemView.findViewById(R.id.issueType);
 | 
			
		||||
 | 
			
		||||
            issueTitle.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
                    Context context = v.getContext();
 | 
			
		||||
                    //Log.i("issueNumber", issueNumber.getText().toString());
 | 
			
		||||
 | 
			
		||||
                    Intent intent = new Intent(context, IssueDetailActivity.class);
 | 
			
		||||
                    intent.putExtra("issueNumber", issueNumber.getText());
 | 
			
		||||
 | 
			
		||||
                    TinyDB tinyDb = new TinyDB(context);
 | 
			
		||||
                    tinyDb.putString("issueNumber", issueNumber.getText().toString());
 | 
			
		||||
                    context.startActivity(intent);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
            issueDescription.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
                    Context context = v.getContext();
 | 
			
		||||
                    //Log.i("issueNumber", issueNumber.getText().toString());
 | 
			
		||||
 | 
			
		||||
                    Intent intent = new Intent(context, IssueDetailActivity.class);
 | 
			
		||||
                    intent.putExtra("issueNumber", issueNumber.getText());
 | 
			
		||||
 | 
			
		||||
                    TinyDB tinyDb = new TinyDB(context);
 | 
			
		||||
                    tinyDb.putString("issueNumber", issueNumber.getText().toString());
 | 
			
		||||
                    context.startActivity(intent);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @SuppressLint("SetTextI18n")
 | 
			
		||||
        void bindData(Issues issuesModel){
 | 
			
		||||
 | 
			
		||||
            final TinyDB tinyDb = new TinyDB(context);
 | 
			
		||||
            final String locale = tinyDb.getString("locale");
 | 
			
		||||
            final String timeFormat = tinyDb.getString("dateFormat");
 | 
			
		||||
 | 
			
		||||
            final Markwon markwon = Markwon.builder(Objects.requireNonNull(context))
 | 
			
		||||
                    .usePlugin(CorePlugin.create())
 | 
			
		||||
                    .usePlugin(OkHttpImagesPlugin.create(new OkHttpClient()))
 | 
			
		||||
                    .usePlugin(ImagesPlugin.createWithAssets(context))
 | 
			
		||||
                    .usePlugin(new AbstractMarkwonPlugin() {
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
 | 
			
		||||
                            builder
 | 
			
		||||
                                    .codeTextColor(tinyDb.getInt("codeBlockColor"))
 | 
			
		||||
                                    .codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
 | 
			
		||||
                                    .linkColor(context.getResources().getColor(R.color.lightBlue));
 | 
			
		||||
                        }
 | 
			
		||||
                    })
 | 
			
		||||
                    .usePlugin(TablePlugin.create(context))
 | 
			
		||||
                    .usePlugin(TaskListPlugin.create(context))
 | 
			
		||||
                    .usePlugin(HtmlPlugin.create())
 | 
			
		||||
                    .usePlugin(GifPlugin.create())
 | 
			
		||||
                    .usePlugin(StrikethroughPlugin.create())
 | 
			
		||||
                    .build();
 | 
			
		||||
 | 
			
		||||
            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(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getLogin(), context));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (issuesModel.getUser().getAvatar_url() != null) {
 | 
			
		||||
                Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(issueAssigneeAvatar);
 | 
			
		||||
            } else {
 | 
			
		||||
                Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(issueAssigneeAvatar);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (issuesModel.getPull_request() == null) {
 | 
			
		||||
                issueType.setImageResource(R.drawable.ic_issues);
 | 
			
		||||
                issueType.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueTypeIssue), context));
 | 
			
		||||
            } else {
 | 
			
		||||
                issueType.setImageResource(R.drawable.ic_merge);
 | 
			
		||||
                issueType.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueTypePullRequest), context));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            issueTitle.setText(context.getResources().getString(R.string.hash) + issuesModel.getNumber() + " " + issuesModel.getTitle());
 | 
			
		||||
            issueNumber.setText(String.valueOf(issuesModel.getNumber()));
 | 
			
		||||
            issueCommentsCount.setText(String.valueOf(issuesModel.getComments()));
 | 
			
		||||
 | 
			
		||||
            if (!issuesModel.getBody().equals("")) {
 | 
			
		||||
                String cleanIssueDescription = issuesModel.getBody().trim();
 | 
			
		||||
                issueDescription.setVisibility(View.VISIBLE);
 | 
			
		||||
                final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueDescription));
 | 
			
		||||
                issueDescription.setText(UserMentions.UserMentionsFunc(context, bodyWithMD, cleanIssueDescription));
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                issueDescription.setText("");
 | 
			
		||||
                issueDescription.setVisibility(View.GONE);
 | 
			
		||||
            }
 | 
			
		||||
            /*if (issuesModel.getState().equals("open")) {
 | 
			
		||||
                issueState.setImageResource(R.drawable.ic_issue_open);
 | 
			
		||||
                issueState.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueStatusTextOpen), context));
 | 
			
		||||
            } else {
 | 
			
		||||
                issueState.setImageResource(R.drawable.ic_issue_closed);
 | 
			
		||||
                issueState.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueStatusTextClosed), context));
 | 
			
		||||
            }*/
 | 
			
		||||
 | 
			
		||||
            switch (timeFormat) {
 | 
			
		||||
                case "pretty": {
 | 
			
		||||
                    PrettyTime prettyTime = new PrettyTime(new Locale(locale));
 | 
			
		||||
                    String createdTime = prettyTime.format(issuesModel.getCreated_at());
 | 
			
		||||
                    issueCreatedTime.setText(createdTime);
 | 
			
		||||
                    issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(issuesModel.getCreated_at()), context));
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                case "normal": {
 | 
			
		||||
                    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 '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
 | 
			
		||||
                    String createdTime = formatter.format(issuesModel.getCreated_at());
 | 
			
		||||
                    issueCreatedTime.setText(createdTime);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static class LoadHolder extends RecyclerView.ViewHolder {
 | 
			
		||||
 | 
			
		||||
        LoadHolder(View itemView) {
 | 
			
		||||
            super(itemView);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setMoreDataAvailable(boolean moreDataAvailable) {
 | 
			
		||||
 | 
			
		||||
        isMoreDataAvailable = moreDataAvailable;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void notifyDataChanged() {
 | 
			
		||||
 | 
			
		||||
        notifyDataSetChanged();
 | 
			
		||||
        isLoading = false;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public interface OnLoadMoreListener {
 | 
			
		||||
 | 
			
		||||
        void onLoadMore();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setLoadMoreListener(ClosedIssuesAdapter.OnLoadMoreListener loadMoreListener) {
 | 
			
		||||
 | 
			
		||||
        this.loadMoreListener = loadMoreListener;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Filter getFilter() {
 | 
			
		||||
        return issuesFilter;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Filter issuesFilter = new Filter() {
 | 
			
		||||
        @Override
 | 
			
		||||
        protected FilterResults performFiltering(CharSequence constraint) {
 | 
			
		||||
            List<Issues> filteredList = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
            if (constraint == null || constraint.length() == 0) {
 | 
			
		||||
                filteredList.addAll(issuesList);
 | 
			
		||||
            } else {
 | 
			
		||||
                String filterPattern = constraint.toString().toLowerCase().trim();
 | 
			
		||||
 | 
			
		||||
                for (Issues item : issuesList) {
 | 
			
		||||
                    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) {
 | 
			
		||||
            issuesList.clear();
 | 
			
		||||
            issuesList.addAll((List) results.values);
 | 
			
		||||
            notifyDataSetChanged();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,91 @@
 | 
			
		||||
package org.mian.gitnex.adapters;
 | 
			
		||||
 | 
			
		||||
import android.annotation.SuppressLint;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.BaseAdapter;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import com.squareup.picasso.Picasso;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.models.Collaborators;
 | 
			
		||||
import org.mian.gitnex.helpers.RoundedTransformation;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class CollaboratorsAdapter extends BaseAdapter  {
 | 
			
		||||
 | 
			
		||||
    private List<Collaborators> collaboratorsList;
 | 
			
		||||
    private Context mCtx;
 | 
			
		||||
 | 
			
		||||
    private class ViewHolder {
 | 
			
		||||
 | 
			
		||||
        private ImageView collaboratorAvatar;
 | 
			
		||||
        private TextView collaboratorName;
 | 
			
		||||
 | 
			
		||||
        ViewHolder(View v) {
 | 
			
		||||
            collaboratorAvatar  = v.findViewById(R.id.collaboratorAvatar);
 | 
			
		||||
            collaboratorName  = v.findViewById(R.id.collaboratorName);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public CollaboratorsAdapter(Context mCtx, List<Collaborators> collaboratorsListMain) {
 | 
			
		||||
        this.mCtx = mCtx;
 | 
			
		||||
        this.collaboratorsList = collaboratorsListMain;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getCount() {
 | 
			
		||||
        return collaboratorsList.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Object getItem(int position) {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public long getItemId(int position) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressLint("InflateParams")
 | 
			
		||||
    @Override
 | 
			
		||||
    public View getView(int position, View finalView, ViewGroup parent) {
 | 
			
		||||
 | 
			
		||||
        ViewHolder viewHolder = null;
 | 
			
		||||
 | 
			
		||||
        if (finalView == null) {
 | 
			
		||||
            finalView = LayoutInflater.from(mCtx).inflate(R.layout.collaborators_list, null);
 | 
			
		||||
            viewHolder = new ViewHolder(finalView);
 | 
			
		||||
            finalView.setTag(viewHolder);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            viewHolder = (ViewHolder) finalView.getTag();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        initData(viewHolder, position);
 | 
			
		||||
        return finalView;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void initData(ViewHolder viewHolder, int position) {
 | 
			
		||||
 | 
			
		||||
        Collaborators currentItem = collaboratorsList.get(position);
 | 
			
		||||
        Picasso.get().load(currentItem.getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(viewHolder.collaboratorAvatar);
 | 
			
		||||
 | 
			
		||||
        if(!currentItem.getFull_name().equals("")) {
 | 
			
		||||
            viewHolder.collaboratorName.setText(currentItem.getFull_name());
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            viewHolder.collaboratorName.setText(currentItem.getLogin());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,244 @@
 | 
			
		||||
package org.mian.gitnex.adapters;
 | 
			
		||||
 | 
			
		||||
import android.annotation.SuppressLint;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.graphics.Color;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.MenuItem;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import com.squareup.picasso.Picasso;
 | 
			
		||||
import com.vdurmont.emoji.EmojiParser;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.activities.ReplyToIssueActivity;
 | 
			
		||||
import org.mian.gitnex.helpers.UserMentions;
 | 
			
		||||
import org.mian.gitnex.helpers.TimeHelper;
 | 
			
		||||
import org.mian.gitnex.models.IssueComments;
 | 
			
		||||
import org.mian.gitnex.helpers.RoundedTransformation;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import org.mian.gitnex.helpers.ClickListener;
 | 
			
		||||
import org.ocpsoft.prettytime.PrettyTime;
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.text.DateFormat;
 | 
			
		||||
import java.text.SimpleDateFormat;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.view.ContextThemeWrapper;
 | 
			
		||||
import androidx.appcompat.widget.PopupMenu;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import okhttp3.OkHttpClient;
 | 
			
		||||
import ru.noties.markwon.AbstractMarkwonPlugin;
 | 
			
		||||
import ru.noties.markwon.Markwon;
 | 
			
		||||
import ru.noties.markwon.core.CorePlugin;
 | 
			
		||||
import ru.noties.markwon.core.MarkwonTheme;
 | 
			
		||||
import ru.noties.markwon.ext.strikethrough.StrikethroughPlugin;
 | 
			
		||||
import ru.noties.markwon.ext.tables.TablePlugin;
 | 
			
		||||
import ru.noties.markwon.ext.tables.TableTheme;
 | 
			
		||||
import ru.noties.markwon.ext.tasklist.TaskListPlugin;
 | 
			
		||||
import ru.noties.markwon.html.HtmlPlugin;
 | 
			
		||||
import ru.noties.markwon.image.ImagesPlugin;
 | 
			
		||||
import ru.noties.markwon.image.gif.GifPlugin;
 | 
			
		||||
import ru.noties.markwon.image.okhttp.OkHttpImagesPlugin;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class IssueCommentsAdapter extends RecyclerView.Adapter<IssueCommentsAdapter.IssueCommentViewHolder> {
 | 
			
		||||
 | 
			
		||||
    private List<IssueComments> issuesComments;
 | 
			
		||||
    private Context mCtx;
 | 
			
		||||
 | 
			
		||||
    static class IssueCommentViewHolder extends RecyclerView.ViewHolder {
 | 
			
		||||
 | 
			
		||||
        private TextView issueNumber;
 | 
			
		||||
        private TextView commendId;
 | 
			
		||||
        private ImageView issueCommenterAvatar;
 | 
			
		||||
        private TextView issueComment;
 | 
			
		||||
        private TextView issueCommentDate;
 | 
			
		||||
        private ImageView commentsOptionsMenu;
 | 
			
		||||
        private TextView commendBodyRaw;
 | 
			
		||||
        private TextView commentModified;
 | 
			
		||||
 | 
			
		||||
        private IssueCommentViewHolder(View itemView) {
 | 
			
		||||
            super(itemView);
 | 
			
		||||
 | 
			
		||||
            issueNumber = itemView.findViewById(R.id.issueNumber);
 | 
			
		||||
            commendId = itemView.findViewById(R.id.commendId);
 | 
			
		||||
            issueCommenterAvatar = itemView.findViewById(R.id.issueCommenterAvatar);
 | 
			
		||||
            issueComment = itemView.findViewById(R.id.issueComment);
 | 
			
		||||
            issueCommentDate = itemView.findViewById(R.id.issueCommentDate);
 | 
			
		||||
            commentsOptionsMenu = itemView.findViewById(R.id.commentsOptionsMenu);
 | 
			
		||||
            commendBodyRaw = itemView.findViewById(R.id.commendBodyRaw);
 | 
			
		||||
            commentModified = itemView.findViewById(R.id.commentModified);
 | 
			
		||||
 | 
			
		||||
            commentsOptionsMenu.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
                    final Context context = v.getContext();
 | 
			
		||||
                    Context context_ = new ContextThemeWrapper(context, R.style.popupMenuStyle);
 | 
			
		||||
 | 
			
		||||
                    PopupMenu popupMenu = new PopupMenu(context_, v);
 | 
			
		||||
                    popupMenu.inflate(R.menu.issue_comment_menu);
 | 
			
		||||
 | 
			
		||||
                    Object menuHelper;
 | 
			
		||||
                    Class[] argTypes;
 | 
			
		||||
                    try {
 | 
			
		||||
 | 
			
		||||
                        Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
 | 
			
		||||
                        fMenuHelper.setAccessible(true);
 | 
			
		||||
                        menuHelper = fMenuHelper.get(popupMenu);
 | 
			
		||||
                        argTypes = new Class[] { boolean.class };
 | 
			
		||||
                        menuHelper.getClass().getDeclaredMethod("setForceShowIcon",
 | 
			
		||||
                                argTypes).invoke(menuHelper, true);
 | 
			
		||||
 | 
			
		||||
                    } catch (Exception e) {
 | 
			
		||||
 | 
			
		||||
                        popupMenu.show();
 | 
			
		||||
                        return;
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public boolean onMenuItemClick(MenuItem item) {
 | 
			
		||||
                            switch (item.getItemId()) {
 | 
			
		||||
                                case R.id.commentMenuEdit:
 | 
			
		||||
 | 
			
		||||
                                    Intent intent = new Intent(context, ReplyToIssueActivity.class);
 | 
			
		||||
                                    intent.putExtra("commentId", commendId.getText());
 | 
			
		||||
                                    intent.putExtra("commentAction", "edit");
 | 
			
		||||
                                    intent.putExtra("commentBody", commendBodyRaw.getText());
 | 
			
		||||
                                    context.startActivity(intent);
 | 
			
		||||
                                    break;
 | 
			
		||||
 | 
			
		||||
                                case R.id.commentMenuDelete:
 | 
			
		||||
 | 
			
		||||
                                    break;
 | 
			
		||||
 | 
			
		||||
                            }
 | 
			
		||||
                            return false;
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                    popupMenu.show();
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public IssueCommentsAdapter(Context mCtx, List<IssueComments> issuesCommentsMain) {
 | 
			
		||||
        this.mCtx = mCtx;
 | 
			
		||||
        this.issuesComments = issuesCommentsMain;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
    @Override
 | 
			
		||||
    public IssueCommentsAdapter.IssueCommentViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
 | 
			
		||||
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.issue_comments, parent, false);
 | 
			
		||||
        return new IssueCommentsAdapter.IssueCommentViewHolder(v);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressLint("SetTextI18n")
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onBindViewHolder(@NonNull IssueCommentsAdapter.IssueCommentViewHolder holder, int position) {
 | 
			
		||||
 | 
			
		||||
        final TinyDB tinyDb = new TinyDB(mCtx);
 | 
			
		||||
        final String locale = tinyDb.getString("locale");
 | 
			
		||||
        final String timeFormat = tinyDb.getString("dateFormat");
 | 
			
		||||
        final String loginUid = tinyDb.getString("loginUid");
 | 
			
		||||
 | 
			
		||||
        IssueComments currentItem = issuesComments.get(position);
 | 
			
		||||
 | 
			
		||||
        if(!loginUid.equals(currentItem.getUser().getUsername())) {
 | 
			
		||||
            holder.commentsOptionsMenu.setVisibility(View.INVISIBLE);
 | 
			
		||||
        }
 | 
			
		||||
        holder.commendId.setText(String.valueOf(currentItem.getId()));
 | 
			
		||||
        holder.commendBodyRaw.setText(currentItem.getBody());
 | 
			
		||||
 | 
			
		||||
        if (!currentItem.getUser().getFull_name().equals("")) {
 | 
			
		||||
            holder.issueCommenterAvatar.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.issueCommenter) + currentItem.getUser().getFull_name(), mCtx));
 | 
			
		||||
        } else {
 | 
			
		||||
            holder.issueCommenterAvatar.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.issueCommenter) + currentItem.getUser().getLogin(), mCtx));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (currentItem.getUser().getAvatar_url() != null) {
 | 
			
		||||
            Picasso.get().load(currentItem.getUser().getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(holder.issueCommenterAvatar);
 | 
			
		||||
        } else {
 | 
			
		||||
            Picasso.get().load(currentItem.getUser().getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(holder.issueCommenterAvatar);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        String cleanIssueComments = currentItem.getBody().trim();
 | 
			
		||||
 | 
			
		||||
        final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx))
 | 
			
		||||
                .usePlugin(CorePlugin.create())
 | 
			
		||||
                .usePlugin(OkHttpImagesPlugin.create(new OkHttpClient()))
 | 
			
		||||
                .usePlugin(ImagesPlugin.create(mCtx))
 | 
			
		||||
                .usePlugin(new AbstractMarkwonPlugin() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
 | 
			
		||||
                        builder
 | 
			
		||||
                                .codeTextColor(tinyDb.getInt("codeBlockColor"))
 | 
			
		||||
                                .codeBackgroundColor(tinyDb.getInt("codeBlockBackground"));
 | 
			
		||||
                    }
 | 
			
		||||
                })
 | 
			
		||||
                .usePlugin(TablePlugin.create(mCtx))
 | 
			
		||||
                .usePlugin(TaskListPlugin.create(mCtx))
 | 
			
		||||
                .usePlugin(HtmlPlugin.create())
 | 
			
		||||
                .usePlugin(GifPlugin.create())
 | 
			
		||||
                .usePlugin(StrikethroughPlugin.create())
 | 
			
		||||
                .build();
 | 
			
		||||
 | 
			
		||||
        final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueComments));
 | 
			
		||||
        holder.issueComment.setText(UserMentions.UserMentionsFunc(mCtx, bodyWithMD, cleanIssueComments));
 | 
			
		||||
 | 
			
		||||
        String edited;
 | 
			
		||||
 | 
			
		||||
        if(!currentItem.getUpdated_at().equals(currentItem.getCreated_at())) {
 | 
			
		||||
            edited = mCtx.getResources().getString(R.string.colorfulBulletSpan) + mCtx.getResources().getString(R.string.modifiedText);
 | 
			
		||||
            holder.commentModified.setVisibility(View.VISIBLE);
 | 
			
		||||
            holder.commentModified.setText(edited);
 | 
			
		||||
            holder.commentModified.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getUpdated_at()), mCtx));
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            holder.commentModified.setVisibility(View.INVISIBLE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        switch (timeFormat) {
 | 
			
		||||
            case "pretty": {
 | 
			
		||||
                PrettyTime prettyTime = new PrettyTime(new Locale(locale));
 | 
			
		||||
                String createdTime = prettyTime.format(currentItem.getCreated_at());
 | 
			
		||||
                holder.issueCommentDate.setText(createdTime);
 | 
			
		||||
                holder.issueCommentDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(currentItem.getCreated_at()), mCtx));
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case "normal": {
 | 
			
		||||
                DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + mCtx.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
 | 
			
		||||
                String createdTime = formatter.format(currentItem.getCreated_at());
 | 
			
		||||
                holder.issueCommentDate.setText(createdTime);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case "normal1": {
 | 
			
		||||
                DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + mCtx.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
 | 
			
		||||
                String createdTime = formatter.format(currentItem.getCreated_at());
 | 
			
		||||
                holder.issueCommentDate.setText(createdTime);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getItemCount() {
 | 
			
		||||
        return issuesComments.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										343
									
								
								app/src/main/java/org/mian/gitnex/adapters/IssuesAdapter.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										343
									
								
								app/src/main/java/org/mian/gitnex/adapters/IssuesAdapter.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,343 @@
 | 
			
		||||
package org.mian.gitnex.adapters;
 | 
			
		||||
 | 
			
		||||
import android.annotation.SuppressLint;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.graphics.Color;
 | 
			
		||||
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.TextView;
 | 
			
		||||
import com.squareup.picasso.Picasso;
 | 
			
		||||
import com.vdurmont.emoji.EmojiParser;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.activities.IssueDetailActivity;
 | 
			
		||||
import org.mian.gitnex.helpers.ClickListener;
 | 
			
		||||
import org.mian.gitnex.helpers.RoundedTransformation;
 | 
			
		||||
import org.mian.gitnex.helpers.TimeHelper;
 | 
			
		||||
import org.mian.gitnex.helpers.UserMentions;
 | 
			
		||||
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.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import okhttp3.OkHttpClient;
 | 
			
		||||
import ru.noties.markwon.AbstractMarkwonPlugin;
 | 
			
		||||
import ru.noties.markwon.Markwon;
 | 
			
		||||
import ru.noties.markwon.core.CorePlugin;
 | 
			
		||||
import ru.noties.markwon.core.MarkwonTheme;
 | 
			
		||||
import ru.noties.markwon.ext.strikethrough.StrikethroughPlugin;
 | 
			
		||||
import ru.noties.markwon.ext.tables.TablePlugin;
 | 
			
		||||
import ru.noties.markwon.ext.tables.TableTheme;
 | 
			
		||||
import ru.noties.markwon.ext.tasklist.TaskListPlugin;
 | 
			
		||||
import ru.noties.markwon.html.HtmlPlugin;
 | 
			
		||||
import ru.noties.markwon.image.ImagesPlugin;
 | 
			
		||||
import ru.noties.markwon.image.gif.GifPlugin;
 | 
			
		||||
import ru.noties.markwon.image.okhttp.OkHttpImagesPlugin;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class IssuesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {
 | 
			
		||||
 | 
			
		||||
    private Context context;
 | 
			
		||||
    private final int TYPE_LOAD = 0;
 | 
			
		||||
    private List<Issues> issuesList;
 | 
			
		||||
    private List<Issues> issuesListFull;
 | 
			
		||||
    private OnLoadMoreListener loadMoreListener;
 | 
			
		||||
    private boolean isLoading = false, isMoreDataAvailable = true;
 | 
			
		||||
 | 
			
		||||
    public IssuesAdapter(Context context, List<Issues> issuesListMain) {
 | 
			
		||||
 | 
			
		||||
        this.context = context;
 | 
			
		||||
        this.issuesList = issuesListMain;
 | 
			
		||||
        issuesListFull = new ArrayList<>(issuesList);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
    @Override
 | 
			
		||||
    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.repo_detail_issues_list, parent,false));
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            return new LoadHolder(inflater.inflate(R.layout.row_load,parent,false));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
 | 
			
		||||
 | 
			
		||||
        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;
 | 
			
		||||
        private TextView issueTitle;
 | 
			
		||||
        private TextView issueDescription;
 | 
			
		||||
        //private ImageView issueState;
 | 
			
		||||
        private TextView issueCreatedTime;
 | 
			
		||||
        private TextView issueCommentsCount;
 | 
			
		||||
        private ImageView issueType;
 | 
			
		||||
 | 
			
		||||
        IssuesHolder(View itemView) {
 | 
			
		||||
 | 
			
		||||
            super(itemView);
 | 
			
		||||
 | 
			
		||||
            issueNumber = itemView.findViewById(R.id.issueNumber);
 | 
			
		||||
            issueAssigneeAvatar = itemView.findViewById(R.id.assigneeAvatar);
 | 
			
		||||
            issueTitle = itemView.findViewById(R.id.issueTitle);
 | 
			
		||||
            issueDescription = itemView.findViewById(R.id.issueDescription);
 | 
			
		||||
            issueCommentsCount = itemView.findViewById(R.id.issueCommentsCount);
 | 
			
		||||
            //issueState = itemView.findViewById(R.id.issueStatus);
 | 
			
		||||
            issueCreatedTime = itemView.findViewById(R.id.issueCreatedTime);
 | 
			
		||||
            issueType = itemView.findViewById(R.id.issueType);
 | 
			
		||||
 | 
			
		||||
            issueTitle.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
                    Context context = v.getContext();
 | 
			
		||||
                    //Log.i("issueNumber", issueNumber.getText().toString());
 | 
			
		||||
 | 
			
		||||
                    Intent intent = new Intent(context, IssueDetailActivity.class);
 | 
			
		||||
                    intent.putExtra("issueNumber", issueNumber.getText());
 | 
			
		||||
 | 
			
		||||
                    TinyDB tinyDb = new TinyDB(context);
 | 
			
		||||
                    tinyDb.putString("issueNumber", issueNumber.getText().toString());
 | 
			
		||||
                    context.startActivity(intent);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
            issueDescription.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
                    Context context = v.getContext();
 | 
			
		||||
                    //Log.i("issueNumber", issueNumber.getText().toString());
 | 
			
		||||
 | 
			
		||||
                    Intent intent = new Intent(context, IssueDetailActivity.class);
 | 
			
		||||
                    intent.putExtra("issueNumber", issueNumber.getText());
 | 
			
		||||
 | 
			
		||||
                    TinyDB tinyDb = new TinyDB(context);
 | 
			
		||||
                    tinyDb.putString("issueNumber", issueNumber.getText().toString());
 | 
			
		||||
                    context.startActivity(intent);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @SuppressLint("SetTextI18n")
 | 
			
		||||
        void bindData(Issues issuesModel){
 | 
			
		||||
 | 
			
		||||
            final TinyDB tinyDb = new TinyDB(context);
 | 
			
		||||
            final String locale = tinyDb.getString("locale");
 | 
			
		||||
            final String timeFormat = tinyDb.getString("dateFormat");
 | 
			
		||||
 | 
			
		||||
            final Markwon markwon = Markwon.builder(Objects.requireNonNull(context))
 | 
			
		||||
                    .usePlugin(CorePlugin.create())
 | 
			
		||||
                    .usePlugin(OkHttpImagesPlugin.create(new OkHttpClient()))
 | 
			
		||||
                    .usePlugin(ImagesPlugin.createWithAssets(context))
 | 
			
		||||
                    .usePlugin(new AbstractMarkwonPlugin() {
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
 | 
			
		||||
                            builder
 | 
			
		||||
                                    .codeTextColor(tinyDb.getInt("codeBlockColor"))
 | 
			
		||||
                                    .codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
 | 
			
		||||
                                    .linkColor(context.getResources().getColor(R.color.lightBlue));
 | 
			
		||||
                        }
 | 
			
		||||
                    })
 | 
			
		||||
                    .usePlugin(TablePlugin.create(context))
 | 
			
		||||
                    .usePlugin(TaskListPlugin.create(context))
 | 
			
		||||
                    .usePlugin(HtmlPlugin.create())
 | 
			
		||||
                    .usePlugin(GifPlugin.create())
 | 
			
		||||
                    .usePlugin(StrikethroughPlugin.create())
 | 
			
		||||
                    .build();
 | 
			
		||||
 | 
			
		||||
            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(context.getResources().getString(R.string.issueCreator) + issuesModel.getUser().getLogin(), context));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (issuesModel.getUser().getAvatar_url() != null) {
 | 
			
		||||
                Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(issueAssigneeAvatar);
 | 
			
		||||
            } else {
 | 
			
		||||
                Picasso.get().load(issuesModel.getUser().getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(issueAssigneeAvatar);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (issuesModel.getPull_request() == null) {
 | 
			
		||||
                issueType.setImageResource(R.drawable.ic_issues);
 | 
			
		||||
                issueType.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueTypeIssue), context));
 | 
			
		||||
            } else {
 | 
			
		||||
                issueType.setImageResource(R.drawable.ic_merge);
 | 
			
		||||
                issueType.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueTypePullRequest), context));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            issueTitle.setText(context.getResources().getString(R.string.hash) + issuesModel.getNumber() + " " + issuesModel.getTitle());
 | 
			
		||||
            issueNumber.setText(String.valueOf(issuesModel.getNumber()));
 | 
			
		||||
            issueCommentsCount.setText(String.valueOf(issuesModel.getComments()));
 | 
			
		||||
 | 
			
		||||
            if (!issuesModel.getBody().equals("")) {
 | 
			
		||||
                String cleanIssueDescription = issuesModel.getBody().trim();
 | 
			
		||||
                issueDescription.setVisibility(View.VISIBLE);
 | 
			
		||||
                final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(cleanIssueDescription));
 | 
			
		||||
                issueDescription.setText(UserMentions.UserMentionsFunc(context, bodyWithMD, cleanIssueDescription));
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                issueDescription.setText("");
 | 
			
		||||
                issueDescription.setVisibility(View.GONE);
 | 
			
		||||
            }
 | 
			
		||||
            /*if (issuesModel.getState().equals("open")) {
 | 
			
		||||
                issueState.setImageResource(R.drawable.ic_issue_open);
 | 
			
		||||
                issueState.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueStatusTextOpen), context));
 | 
			
		||||
            } else {
 | 
			
		||||
                issueState.setImageResource(R.drawable.ic_issue_closed);
 | 
			
		||||
                issueState.setOnClickListener(new ClickListener(context.getResources().getString(R.string.issueStatusTextClosed), context));
 | 
			
		||||
            }*/
 | 
			
		||||
 | 
			
		||||
            switch (timeFormat) {
 | 
			
		||||
                case "pretty": {
 | 
			
		||||
                    PrettyTime prettyTime = new PrettyTime(new Locale(locale));
 | 
			
		||||
                    String createdTime = prettyTime.format(issuesModel.getCreated_at());
 | 
			
		||||
                    issueCreatedTime.setText(createdTime);
 | 
			
		||||
                    issueCreatedTime.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(issuesModel.getCreated_at()), context));
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                case "normal": {
 | 
			
		||||
                    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 '" + context.getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
 | 
			
		||||
                    String createdTime = formatter.format(issuesModel.getCreated_at());
 | 
			
		||||
                    issueCreatedTime.setText(createdTime);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static class LoadHolder extends RecyclerView.ViewHolder {
 | 
			
		||||
 | 
			
		||||
        LoadHolder(View itemView) {
 | 
			
		||||
            super(itemView);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setMoreDataAvailable(boolean moreDataAvailable) {
 | 
			
		||||
 | 
			
		||||
        isMoreDataAvailable = moreDataAvailable;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void notifyDataChanged() {
 | 
			
		||||
 | 
			
		||||
        notifyDataSetChanged();
 | 
			
		||||
        isLoading = false;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public interface OnLoadMoreListener {
 | 
			
		||||
 | 
			
		||||
        void onLoadMore();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
 | 
			
		||||
 | 
			
		||||
        this.loadMoreListener = loadMoreListener;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Filter getFilter() {
 | 
			
		||||
        return issuesFilter;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Filter issuesFilter = new Filter() {
 | 
			
		||||
        @Override
 | 
			
		||||
        protected FilterResults performFiltering(CharSequence constraint) {
 | 
			
		||||
            List<Issues> filteredList = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
            if (constraint == null || constraint.length() == 0) {
 | 
			
		||||
                filteredList.addAll(issuesList);
 | 
			
		||||
            } else {
 | 
			
		||||
                String filterPattern = constraint.toString().toLowerCase().trim();
 | 
			
		||||
 | 
			
		||||
                for (Issues item : issuesList) {
 | 
			
		||||
                    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) {
 | 
			
		||||
            issuesList.clear();
 | 
			
		||||
            issuesList.addAll((List) results.values);
 | 
			
		||||
            notifyDataSetChanged();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										177
									
								
								app/src/main/java/org/mian/gitnex/adapters/LabelsAdapter.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								app/src/main/java/org/mian/gitnex/adapters/LabelsAdapter.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,177 @@
 | 
			
		||||
package org.mian.gitnex.adapters;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.graphics.Color;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.MenuItem;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import com.amulyakhare.textdrawable.TextDrawable;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.activities.CreateLabelActivity;
 | 
			
		||||
import org.mian.gitnex.helpers.AlertDialogs;
 | 
			
		||||
import org.mian.gitnex.helpers.ColorInverter;
 | 
			
		||||
import org.mian.gitnex.helpers.LabelWidthCalculator;
 | 
			
		||||
import org.mian.gitnex.models.Labels;
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.view.ContextThemeWrapper;
 | 
			
		||||
import androidx.appcompat.widget.PopupMenu;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class LabelsAdapter extends RecyclerView.Adapter<LabelsAdapter.LabelsViewHolder>  {
 | 
			
		||||
 | 
			
		||||
    private List<Labels> labelsList;
 | 
			
		||||
    final private Context mCtx;
 | 
			
		||||
    private ArrayList<Integer> labelsArray = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
    static class LabelsViewHolder extends RecyclerView.ViewHolder {
 | 
			
		||||
 | 
			
		||||
        private TextView labelTitle;
 | 
			
		||||
        private TextView labelId;
 | 
			
		||||
        private TextView labelColor;
 | 
			
		||||
        private ImageView labelsView;
 | 
			
		||||
        private ImageView labelsOptionsMenu;
 | 
			
		||||
 | 
			
		||||
        private LabelsViewHolder(View itemView) {
 | 
			
		||||
            super(itemView);
 | 
			
		||||
 | 
			
		||||
            labelsView = itemView.findViewById(R.id.labelsView);
 | 
			
		||||
            labelsOptionsMenu = itemView.findViewById(R.id.labelsOptionsMenu);
 | 
			
		||||
            labelTitle = itemView.findViewById(R.id.labelTitle);
 | 
			
		||||
            labelId = itemView.findViewById(R.id.labelId);
 | 
			
		||||
            labelColor = itemView.findViewById(R.id.labelColor);
 | 
			
		||||
 | 
			
		||||
            labelsOptionsMenu.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
                    final Context context = v.getContext();
 | 
			
		||||
                    Context context_ = new ContextThemeWrapper(context, R.style.popupMenuStyle);
 | 
			
		||||
 | 
			
		||||
                    PopupMenu popupMenu = new PopupMenu(context_, v);
 | 
			
		||||
                    popupMenu.inflate(R.menu.labels_menu);
 | 
			
		||||
 | 
			
		||||
                    Object menuHelper;
 | 
			
		||||
                    Class[] argTypes;
 | 
			
		||||
                    try {
 | 
			
		||||
 | 
			
		||||
                        Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
 | 
			
		||||
                        fMenuHelper.setAccessible(true);
 | 
			
		||||
                        menuHelper = fMenuHelper.get(popupMenu);
 | 
			
		||||
                        argTypes = new Class[] { boolean.class };
 | 
			
		||||
                        menuHelper.getClass().getDeclaredMethod("setForceShowIcon",
 | 
			
		||||
                                argTypes).invoke(menuHelper, true);
 | 
			
		||||
 | 
			
		||||
                    } catch (Exception e) {
 | 
			
		||||
 | 
			
		||||
                        popupMenu.show();
 | 
			
		||||
                        return;
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public boolean onMenuItemClick(MenuItem item) {
 | 
			
		||||
                            switch (item.getItemId()) {
 | 
			
		||||
                                case R.id.labelMenuEdit:
 | 
			
		||||
 | 
			
		||||
                                    Intent intent = new Intent(context, CreateLabelActivity.class);
 | 
			
		||||
                                    intent.putExtra("labelId", labelId.getText());
 | 
			
		||||
                                    intent.putExtra("labelTitle", labelTitle.getText());
 | 
			
		||||
                                    intent.putExtra("labelColor", labelColor.getText());
 | 
			
		||||
                                    intent.putExtra("labelAction", "edit");
 | 
			
		||||
                                    context.startActivity(intent);
 | 
			
		||||
                                    break;
 | 
			
		||||
 | 
			
		||||
                                case R.id.labelMenuDelete:
 | 
			
		||||
 | 
			
		||||
                                    AlertDialogs.labelDeleteDialog(context, labelTitle.getText().toString(), labelId.getText().toString(),
 | 
			
		||||
                                            context.getResources().getString(R.string.labelDeleteTitle),
 | 
			
		||||
                                            context.getResources().getString(R.string.labelDeleteMessage),
 | 
			
		||||
                                            context.getResources().getString(R.string.labelDeletePositiveButton),
 | 
			
		||||
                                            context.getResources().getString(R.string.labelDeleteNegativeButton));
 | 
			
		||||
                                    break;
 | 
			
		||||
 | 
			
		||||
                            }
 | 
			
		||||
                            return false;
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                    popupMenu.show();
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public LabelsAdapter(Context mCtx, List<Labels> labelsMain) {
 | 
			
		||||
        this.mCtx = mCtx;
 | 
			
		||||
        this.labelsList = labelsMain;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
    @Override
 | 
			
		||||
    public LabelsAdapter.LabelsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
 | 
			
		||||
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.labels_list, parent, false);
 | 
			
		||||
        return new LabelsAdapter.LabelsViewHolder(v);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onBindViewHolder(@NonNull LabelsAdapter.LabelsViewHolder holder, int position) {
 | 
			
		||||
 | 
			
		||||
        Labels currentItem = labelsList.get(position);
 | 
			
		||||
        int width = 33;
 | 
			
		||||
 | 
			
		||||
        holder.labelTitle.setText(currentItem.getName());
 | 
			
		||||
        holder.labelId.setText(String.valueOf(currentItem.getId()));
 | 
			
		||||
        holder.labelColor.setText(currentItem.getColor());
 | 
			
		||||
 | 
			
		||||
        String labelColor = currentItem.getColor();
 | 
			
		||||
        String labelName = currentItem.getName();
 | 
			
		||||
        int color = Color.parseColor("#" + labelColor);
 | 
			
		||||
 | 
			
		||||
        TextDrawable drawable = TextDrawable.builder()
 | 
			
		||||
                .beginConfig()
 | 
			
		||||
                //.useFont(Typeface.DEFAULT)
 | 
			
		||||
                .textColor(new ColorInverter().getContrastColor(color))
 | 
			
		||||
                .fontSize(36)
 | 
			
		||||
                .width(LabelWidthCalculator.customWidth(getMaxLabelLength()))
 | 
			
		||||
                .height(60)
 | 
			
		||||
                .endConfig()
 | 
			
		||||
                .buildRoundRect(labelName, color, 8);
 | 
			
		||||
        holder.labelsView.setImageDrawable(drawable);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private int getMaxLabelLength() {
 | 
			
		||||
 | 
			
		||||
        for(int i = 0; i < labelsList.size(); i++) {
 | 
			
		||||
 | 
			
		||||
            Labels labelItem = labelsList.get(i);
 | 
			
		||||
            labelsArray.add(labelItem.getName().length());
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return Collections.max(labelsArray);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getItemCount() {
 | 
			
		||||
        return labelsList.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,133 @@
 | 
			
		||||
package org.mian.gitnex.adapters;
 | 
			
		||||
 | 
			
		||||
import android.annotation.SuppressLint;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.BaseAdapter;
 | 
			
		||||
import android.widget.Filter;
 | 
			
		||||
import android.widget.Filterable;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import com.squareup.picasso.Picasso;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.helpers.RoundedTransformation;
 | 
			
		||||
import org.mian.gitnex.models.UserInfo;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class MembersByOrgAdapter extends BaseAdapter implements Filterable {
 | 
			
		||||
 | 
			
		||||
    private List<UserInfo> membersList;
 | 
			
		||||
    private Context mCtx;
 | 
			
		||||
    private List<UserInfo> membersListFull;
 | 
			
		||||
 | 
			
		||||
    private class ViewHolder {
 | 
			
		||||
 | 
			
		||||
        private ImageView memberAvatar;
 | 
			
		||||
        private TextView memberName;
 | 
			
		||||
 | 
			
		||||
        ViewHolder(View v) {
 | 
			
		||||
            memberAvatar  = v.findViewById(R.id.memberAvatar);
 | 
			
		||||
            memberName  = v.findViewById(R.id.memberName);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MembersByOrgAdapter(Context mCtx, List<UserInfo> membersListMain) {
 | 
			
		||||
        this.mCtx = mCtx;
 | 
			
		||||
        this.membersList = membersListMain;
 | 
			
		||||
        membersListFull = new ArrayList<>(membersList);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getCount() {
 | 
			
		||||
        return membersList.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Object getItem(int position) {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public long getItemId(int position) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressLint("InflateParams")
 | 
			
		||||
    @Override
 | 
			
		||||
    public View getView(int position, View finalView, ViewGroup parent) {
 | 
			
		||||
 | 
			
		||||
        MembersByOrgAdapter.ViewHolder viewHolder = null;
 | 
			
		||||
 | 
			
		||||
        if (finalView == null) {
 | 
			
		||||
            finalView = LayoutInflater.from(mCtx).inflate(R.layout.members_by_org_list, null);
 | 
			
		||||
            viewHolder = new MembersByOrgAdapter.ViewHolder(finalView);
 | 
			
		||||
            finalView.setTag(viewHolder);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            viewHolder = (MembersByOrgAdapter.ViewHolder) finalView.getTag();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        initData(viewHolder, position);
 | 
			
		||||
        return finalView;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void initData(MembersByOrgAdapter.ViewHolder viewHolder, int position) {
 | 
			
		||||
 | 
			
		||||
        UserInfo currentItem = membersList.get(position);
 | 
			
		||||
        Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(viewHolder.memberAvatar);
 | 
			
		||||
 | 
			
		||||
        if(!currentItem.getFullname().equals("")) {
 | 
			
		||||
            viewHolder.memberName.setText(currentItem.getFullname());
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            viewHolder.memberName.setText(currentItem.getLogin());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Filter getFilter() {
 | 
			
		||||
        return membersFilter;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Filter membersFilter = new Filter() {
 | 
			
		||||
        @Override
 | 
			
		||||
        protected FilterResults performFiltering(CharSequence constraint) {
 | 
			
		||||
            List<UserInfo> filteredList = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
            if (constraint == null || constraint.length() == 0) {
 | 
			
		||||
                filteredList.addAll(membersListFull);
 | 
			
		||||
            } else {
 | 
			
		||||
                String filterPattern = constraint.toString().toLowerCase().trim();
 | 
			
		||||
 | 
			
		||||
                for (UserInfo item : membersListFull) {
 | 
			
		||||
                    if (item.getFullname().toLowerCase().contains(filterPattern) || item.getLogin().toLowerCase().contains(filterPattern)) {
 | 
			
		||||
                        filteredList.add(item);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            FilterResults results = new FilterResults();
 | 
			
		||||
            results.values = filteredList;
 | 
			
		||||
 | 
			
		||||
            return results;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        protected void publishResults(CharSequence constraint, FilterResults results) {
 | 
			
		||||
            membersList.clear();
 | 
			
		||||
            membersList.addAll((List) results.values);
 | 
			
		||||
            notifyDataSetChanged();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,265 @@
 | 
			
		||||
package org.mian.gitnex.adapters;
 | 
			
		||||
 | 
			
		||||
import android.annotation.SuppressLint;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.graphics.Color;
 | 
			
		||||
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.TextView;
 | 
			
		||||
import com.amulyakhare.textdrawable.TextDrawable;
 | 
			
		||||
import com.vdurmont.emoji.EmojiParser;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.helpers.ClickListener;
 | 
			
		||||
import org.mian.gitnex.helpers.TimeHelper;
 | 
			
		||||
import org.mian.gitnex.models.Milestones;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.text.DateFormat;
 | 
			
		||||
import java.text.ParseException;
 | 
			
		||||
import java.text.SimpleDateFormat;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import okhttp3.OkHttpClient;
 | 
			
		||||
import ru.noties.markwon.AbstractMarkwonPlugin;
 | 
			
		||||
import ru.noties.markwon.Markwon;
 | 
			
		||||
import ru.noties.markwon.core.CorePlugin;
 | 
			
		||||
import ru.noties.markwon.core.MarkwonTheme;
 | 
			
		||||
import ru.noties.markwon.ext.strikethrough.StrikethroughPlugin;
 | 
			
		||||
import ru.noties.markwon.ext.tables.TablePlugin;
 | 
			
		||||
import ru.noties.markwon.ext.tables.TableTheme;
 | 
			
		||||
import ru.noties.markwon.ext.tasklist.TaskListPlugin;
 | 
			
		||||
import ru.noties.markwon.html.HtmlPlugin;
 | 
			
		||||
import ru.noties.markwon.image.ImagesPlugin;
 | 
			
		||||
import ru.noties.markwon.image.gif.GifPlugin;
 | 
			
		||||
import ru.noties.markwon.image.okhttp.OkHttpImagesPlugin;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class MilestonesAdapter extends RecyclerView.Adapter<MilestonesAdapter.MilestonesViewHolder> implements Filterable {
 | 
			
		||||
 | 
			
		||||
    private List<Milestones> milestonesList;
 | 
			
		||||
    private Context mCtx;
 | 
			
		||||
    private List<Milestones> milestonesListFull;
 | 
			
		||||
 | 
			
		||||
    static class MilestonesViewHolder extends RecyclerView.ViewHolder {
 | 
			
		||||
 | 
			
		||||
        private TextView msTitle;
 | 
			
		||||
        private TextView msDescription;
 | 
			
		||||
        private TextView msOpenIssues;
 | 
			
		||||
        private TextView msClosedIssues;
 | 
			
		||||
        private TextView msDueDate;
 | 
			
		||||
        private ImageView msStatus;
 | 
			
		||||
 | 
			
		||||
        private MilestonesViewHolder(View itemView) {
 | 
			
		||||
            super(itemView);
 | 
			
		||||
 | 
			
		||||
            msTitle = itemView.findViewById(R.id.milestoneTitle);
 | 
			
		||||
            msStatus = itemView.findViewById(R.id.milestoneState);
 | 
			
		||||
            msDescription = itemView.findViewById(R.id.milestoneDescription);
 | 
			
		||||
            msOpenIssues = itemView.findViewById(R.id.milestoneIssuesOpen);
 | 
			
		||||
            msClosedIssues = itemView.findViewById(R.id.milestoneIssuesClosed);
 | 
			
		||||
            msDueDate = itemView.findViewById(R.id.milestoneDueDate);
 | 
			
		||||
 | 
			
		||||
            /*issueTitle.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
                    Context context = v.getContext();
 | 
			
		||||
                    Log.i("issueNumber", issueNumber.getText().toString());
 | 
			
		||||
 | 
			
		||||
                    Intent intent = new Intent(context, IssueDetailActivity.class);
 | 
			
		||||
                    intent.putExtra("issueNumber", issueNumber.getText());
 | 
			
		||||
 | 
			
		||||
                    TinyDB tinyDb = new TinyDB(context);
 | 
			
		||||
                    tinyDb.putString("issueNumber", issueNumber.getText().toString());
 | 
			
		||||
                    context.startActivity(intent);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            });*/
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MilestonesAdapter(Context mCtx, List<Milestones> milestonesMain) {
 | 
			
		||||
        this.mCtx = mCtx;
 | 
			
		||||
        this.milestonesList = milestonesMain;
 | 
			
		||||
        milestonesListFull = new ArrayList<>(milestonesList);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
    @Override
 | 
			
		||||
    public MilestonesAdapter.MilestonesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
 | 
			
		||||
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.milestones_list, parent, false);
 | 
			
		||||
        return new MilestonesAdapter.MilestonesViewHolder(v);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onBindViewHolder(@NonNull MilestonesAdapter.MilestonesViewHolder holder, int position) {
 | 
			
		||||
 | 
			
		||||
        final TinyDB tinyDb = new TinyDB(mCtx);
 | 
			
		||||
        final String locale = tinyDb.getString("locale");
 | 
			
		||||
        final String timeFormat = tinyDb.getString("dateFormat");
 | 
			
		||||
 | 
			
		||||
        Milestones currentItem = milestonesList.get(position);
 | 
			
		||||
 | 
			
		||||
        final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx))
 | 
			
		||||
                .usePlugin(CorePlugin.create())
 | 
			
		||||
                .usePlugin(OkHttpImagesPlugin.create(new OkHttpClient()))
 | 
			
		||||
                .usePlugin(ImagesPlugin.createWithAssets(mCtx))
 | 
			
		||||
                .usePlugin(new AbstractMarkwonPlugin() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
 | 
			
		||||
                        builder
 | 
			
		||||
                                .codeTextColor(tinyDb.getInt("codeBlockColor"))
 | 
			
		||||
                                .codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
 | 
			
		||||
                                .linkColor(mCtx.getResources().getColor(R.color.lightBlue));
 | 
			
		||||
                    }
 | 
			
		||||
                })
 | 
			
		||||
                .usePlugin(TablePlugin.create(mCtx))
 | 
			
		||||
                .usePlugin(TaskListPlugin.create(mCtx))
 | 
			
		||||
                .usePlugin(HtmlPlugin.create())
 | 
			
		||||
                .usePlugin(GifPlugin.create())
 | 
			
		||||
                .usePlugin(StrikethroughPlugin.create())
 | 
			
		||||
                .build();
 | 
			
		||||
 | 
			
		||||
        holder.msTitle.setText(currentItem.getTitle());
 | 
			
		||||
        //holder.msStatus.setText(currentItem.getState());
 | 
			
		||||
 | 
			
		||||
        if(currentItem.getState().equals("open")) {
 | 
			
		||||
 | 
			
		||||
            @SuppressLint("ResourceType") int color = Color.parseColor(mCtx.getResources().getString(R.color.releaseStable));
 | 
			
		||||
            TextDrawable drawable = TextDrawable.builder()
 | 
			
		||||
                    .beginConfig()
 | 
			
		||||
                    //.useFont(Typeface.DEFAULT)
 | 
			
		||||
                    .textColor(mCtx.getResources().getColor(R.color.white))
 | 
			
		||||
                    .fontSize(30)
 | 
			
		||||
                    .toUpperCase()
 | 
			
		||||
                    .width(120)
 | 
			
		||||
                    .height(60)
 | 
			
		||||
                    .endConfig()
 | 
			
		||||
                    .buildRoundRect("open", color, 8);
 | 
			
		||||
 | 
			
		||||
            holder.msStatus.setImageDrawable(drawable);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        else if(currentItem.getState().equals("closed")) {
 | 
			
		||||
 | 
			
		||||
            @SuppressLint("ResourceType") int color = Color.parseColor(mCtx.getResources().getString(R.color.colorRed));
 | 
			
		||||
            TextDrawable drawable = TextDrawable.builder()
 | 
			
		||||
                    .beginConfig()
 | 
			
		||||
                    //.useFont(Typeface.DEFAULT)
 | 
			
		||||
                    .textColor(mCtx.getResources().getColor(R.color.white))
 | 
			
		||||
                    .fontSize(30)
 | 
			
		||||
                    .toUpperCase()
 | 
			
		||||
                    .width(140)
 | 
			
		||||
                    .height(60)
 | 
			
		||||
                    .endConfig()
 | 
			
		||||
                    .buildRoundRect("closed", color, 8);
 | 
			
		||||
 | 
			
		||||
            holder.msStatus.setImageDrawable(drawable);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!currentItem.getDescription().equals("")) {
 | 
			
		||||
            final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(currentItem.getDescription()));
 | 
			
		||||
            holder.msDescription.setText(bodyWithMD);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            holder.msDescription.setVisibility(View.GONE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        holder.msOpenIssues.setText(String.valueOf(currentItem.getOpen_issues()));
 | 
			
		||||
        holder.msOpenIssues.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.milestoneOpenIssues, currentItem.getOpen_issues()), mCtx));
 | 
			
		||||
 | 
			
		||||
        holder.msClosedIssues.setText(String.valueOf(currentItem.getClosed_issues()));
 | 
			
		||||
        holder.msClosedIssues.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.milestoneClosedIssues, currentItem.getClosed_issues()), mCtx));
 | 
			
		||||
 | 
			
		||||
        if(currentItem.getDue_on() != null) {
 | 
			
		||||
 | 
			
		||||
            if (timeFormat.equals("normal") || timeFormat.equals("pretty")) {
 | 
			
		||||
                DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", new Locale(locale));
 | 
			
		||||
                Date date = null;
 | 
			
		||||
                try {
 | 
			
		||||
                    date = formatter.parse(currentItem.getDue_on());
 | 
			
		||||
                } catch (ParseException e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
                String dueDate = formatter.format(date);
 | 
			
		||||
                assert date != null;
 | 
			
		||||
                if(date.before(new Date())) {
 | 
			
		||||
                    holder.msDueDate.setTextColor(mCtx.getResources().getColor(R.color.darkRed));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                holder.msDueDate.setText(dueDate);
 | 
			
		||||
                holder.msDueDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToast(currentItem.getDue_on()), mCtx));
 | 
			
		||||
 | 
			
		||||
            } else if (timeFormat.equals("normal1")) {
 | 
			
		||||
                SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", new Locale(locale));
 | 
			
		||||
                Date date1 = null;
 | 
			
		||||
                try {
 | 
			
		||||
                    date1 = formatter.parse(currentItem.getDue_on());
 | 
			
		||||
                } catch (ParseException e) {
 | 
			
		||||
                    e.printStackTrace();
 | 
			
		||||
                }
 | 
			
		||||
                String dueDate = formatter.format(date1);
 | 
			
		||||
                holder.msDueDate.setText(dueDate);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            holder.msDueDate.setVisibility(View.INVISIBLE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getItemCount() {
 | 
			
		||||
        return milestonesList.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Filter getFilter() {
 | 
			
		||||
        return milestoneFilter;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Filter milestoneFilter = new Filter() {
 | 
			
		||||
        @Override
 | 
			
		||||
        protected FilterResults performFiltering(CharSequence constraint) {
 | 
			
		||||
            List<Milestones> filteredList = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
            if (constraint == null || constraint.length() == 0) {
 | 
			
		||||
                filteredList.addAll(milestonesListFull);
 | 
			
		||||
            } else {
 | 
			
		||||
                String filterPattern = constraint.toString().toLowerCase().trim();
 | 
			
		||||
 | 
			
		||||
                for (Milestones item : milestonesListFull) {
 | 
			
		||||
                    if (item.getTitle().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) {
 | 
			
		||||
                        filteredList.add(item);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            FilterResults results = new FilterResults();
 | 
			
		||||
            results.values = filteredList;
 | 
			
		||||
 | 
			
		||||
            return results;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        protected void publishResults(CharSequence constraint, FilterResults results) {
 | 
			
		||||
            milestonesList.clear();
 | 
			
		||||
            milestonesList.addAll((List) results.values);
 | 
			
		||||
            notifyDataSetChanged();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,190 @@
 | 
			
		||||
package org.mian.gitnex.adapters;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.res.ColorStateList;
 | 
			
		||||
import android.graphics.Typeface;
 | 
			
		||||
import android.text.Spannable;
 | 
			
		||||
import android.text.SpannableString;
 | 
			
		||||
import android.text.style.TextAppearanceSpan;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.LinearLayout;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.helpers.MultiSelectDialog;
 | 
			
		||||
import org.mian.gitnex.models.MultiSelectModel;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.widget.AppCompatCheckBox;
 | 
			
		||||
import androidx.core.content.ContextCompat;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author com.github.abumoallim, modified by M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class MutliSelectAdapter extends RecyclerView.Adapter<MutliSelectAdapter.MultiSelectDialogViewHolder> {
 | 
			
		||||
 | 
			
		||||
    private ArrayList<MultiSelectModel> mDataSet;
 | 
			
		||||
    private String mSearchQuery = "";
 | 
			
		||||
    private Context mContext;
 | 
			
		||||
 | 
			
		||||
    public MutliSelectAdapter(ArrayList<MultiSelectModel> dataSet, Context context) {
 | 
			
		||||
        this.mDataSet = dataSet;
 | 
			
		||||
        this.mContext = context;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
    @Override
 | 
			
		||||
    public MultiSelectDialogViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
 | 
			
		||||
 | 
			
		||||
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.multi_select_item, parent, false);
 | 
			
		||||
        return new MultiSelectDialogViewHolder(view);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onBindViewHolder(@NonNull final MultiSelectDialogViewHolder holder, int position) {
 | 
			
		||||
 | 
			
		||||
        if (!mSearchQuery.equals("") && mSearchQuery.length() > 1) {
 | 
			
		||||
            setHighlightedText(position, holder.dialog_name_item);
 | 
			
		||||
        } else {
 | 
			
		||||
            holder.dialog_name_item.setText(mDataSet.get(position).getName());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (mDataSet.get(position).getSelected()) {
 | 
			
		||||
 | 
			
		||||
            if (!MultiSelectDialog.selectedIdsForCallback.contains(mDataSet.get(position).getId())) {
 | 
			
		||||
                MultiSelectDialog.selectedIdsForCallback.add(mDataSet.get(position).getId());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (checkForSelection(mDataSet.get(position).getId())) {
 | 
			
		||||
            holder.dialog_item_checkbox.setChecked(true);
 | 
			
		||||
        } else {
 | 
			
		||||
            holder.dialog_item_checkbox.setChecked(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /*holder.dialog_item_checkbox.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                if (holder.dialog_item_checkbox.isChecked()) {
 | 
			
		||||
                    MultiSelectDialog.selectedIdsForCallback.add(mDataSet.get(holder.getAdapterPosition()).getId());
 | 
			
		||||
                    holder.dialog_item_checkbox.setChecked(true);
 | 
			
		||||
                } else {
 | 
			
		||||
                    removeFromSelection(mDataSet.get(holder.getAdapterPosition()).getId());
 | 
			
		||||
                    holder.dialog_item_checkbox.setChecked(false);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });*/
 | 
			
		||||
 | 
			
		||||
        holder.main_container.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                if (!holder.dialog_item_checkbox.isChecked()) {
 | 
			
		||||
                    MultiSelectDialog.selectedIdsForCallback.add(mDataSet.get(holder.getAdapterPosition()).getId());
 | 
			
		||||
                    holder.dialog_item_checkbox.setChecked(true);
 | 
			
		||||
                    mDataSet.get(holder.getAdapterPosition()).setSelected(true);
 | 
			
		||||
                    notifyItemChanged(holder.getAdapterPosition());
 | 
			
		||||
                } else {
 | 
			
		||||
                    removeFromSelection(mDataSet.get(holder.getAdapterPosition()).getId());
 | 
			
		||||
                    holder.dialog_item_checkbox.setChecked(false);
 | 
			
		||||
                    mDataSet.get(holder.getAdapterPosition()).setSelected(false);
 | 
			
		||||
                    notifyItemChanged(holder.getAdapterPosition());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void setHighlightedText(int position, TextView textview) {
 | 
			
		||||
 | 
			
		||||
        String name = mDataSet.get(position).getName();
 | 
			
		||||
        SpannableString str = new SpannableString(name);
 | 
			
		||||
        int endLength = name.toLowerCase().indexOf(mSearchQuery) + mSearchQuery.length();
 | 
			
		||||
        ColorStateList highlightedColor = new ColorStateList(new int[][]{new int[]{}}, new int[]{ContextCompat.getColor(mContext, R.color.colorAccent)});
 | 
			
		||||
        TextAppearanceSpan textAppearanceSpan = new TextAppearanceSpan(null, Typeface.NORMAL, -1, highlightedColor, null);
 | 
			
		||||
        str.setSpan(textAppearanceSpan, name.toLowerCase().indexOf(mSearchQuery), endLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
 | 
			
		||||
        textview.setText(str);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void removeFromSelection(Integer id) {
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < MultiSelectDialog.selectedIdsForCallback.size(); i++) {
 | 
			
		||||
            if (id.equals(MultiSelectDialog.selectedIdsForCallback.get(i))) {
 | 
			
		||||
                MultiSelectDialog.selectedIdsForCallback.remove(i);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean checkForSelection(Integer id) {
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < MultiSelectDialog.selectedIdsForCallback.size(); i++) {
 | 
			
		||||
            if (id.equals(MultiSelectDialog.selectedIdsForCallback.get(i))) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*//get selected name string separated by coma
 | 
			
		||||
    public String getDataString() {
 | 
			
		||||
        String data = "";
 | 
			
		||||
        for (int i = 0; i < mDataSet.size(); i++) {
 | 
			
		||||
            if (checkForSelection(mDataSet.get(i).getId())) {
 | 
			
		||||
                data = data + ", " + mDataSet.get(i).getName();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (data.length() > 0) {
 | 
			
		||||
            return data.substring(1);
 | 
			
		||||
        } else {
 | 
			
		||||
            return "";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    //get selected name ararylist
 | 
			
		||||
    public ArrayList<String> getSelectedNameList() {
 | 
			
		||||
        ArrayList<String> names = new ArrayList<>();
 | 
			
		||||
        for (int i = 0; i < mDataSet.size(); i++) {
 | 
			
		||||
            if (checkForSelection(mDataSet.get(i).getId())) {
 | 
			
		||||
                names.add(mDataSet.get(i).getName());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        //  return names.toArray(new String[names.size()]);
 | 
			
		||||
        return names;
 | 
			
		||||
    }*/
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getItemCount() {
 | 
			
		||||
        return mDataSet.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setData(ArrayList<MultiSelectModel> data, String query, MutliSelectAdapter mutliSelectAdapter) {
 | 
			
		||||
 | 
			
		||||
        this.mDataSet = data;
 | 
			
		||||
        this.mSearchQuery = query;
 | 
			
		||||
        mutliSelectAdapter.notifyDataSetChanged();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class MultiSelectDialogViewHolder extends RecyclerView.ViewHolder {
 | 
			
		||||
 | 
			
		||||
        private TextView dialog_name_item;
 | 
			
		||||
        private AppCompatCheckBox dialog_item_checkbox;
 | 
			
		||||
        private LinearLayout main_container;
 | 
			
		||||
 | 
			
		||||
        MultiSelectDialogViewHolder(View view) {
 | 
			
		||||
 | 
			
		||||
            super(view);
 | 
			
		||||
            dialog_name_item = view.findViewById(R.id.dialog_item_name);
 | 
			
		||||
            dialog_item_checkbox = view.findViewById(R.id.dialog_item_checkbox);
 | 
			
		||||
            main_container = view.findViewById(R.id.main_container);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,168 @@
 | 
			
		||||
package org.mian.gitnex.adapters;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.graphics.Typeface;
 | 
			
		||||
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.TextView;
 | 
			
		||||
import com.amulyakhare.textdrawable.TextDrawable;
 | 
			
		||||
import com.amulyakhare.textdrawable.util.ColorGenerator;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.activities.RepoDetailActivity;
 | 
			
		||||
import org.mian.gitnex.models.UserRepositories;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class MyReposListAdapter extends RecyclerView.Adapter<MyReposListAdapter.MyReposViewHolder> implements Filterable {
 | 
			
		||||
 | 
			
		||||
    private List<UserRepositories> reposList;
 | 
			
		||||
    private Context mCtx;
 | 
			
		||||
    private List<UserRepositories> reposListFull;
 | 
			
		||||
 | 
			
		||||
    static class MyReposViewHolder extends RecyclerView.ViewHolder {
 | 
			
		||||
 | 
			
		||||
        private ImageView imageMy;
 | 
			
		||||
        private TextView mTextView1My;
 | 
			
		||||
        private TextView mTextView2My;
 | 
			
		||||
        private TextView fullNameMy;
 | 
			
		||||
        private ImageView repoPrivatePublicMy;
 | 
			
		||||
        private TextView repoStarsMy;
 | 
			
		||||
        private TextView repoWatchersMy;
 | 
			
		||||
        private TextView repoOpenIssuesCountMy;
 | 
			
		||||
 | 
			
		||||
        private MyReposViewHolder(View itemView) {
 | 
			
		||||
            super(itemView);
 | 
			
		||||
            mTextView1My = itemView.findViewById(R.id.repoNameMy);
 | 
			
		||||
            mTextView2My = itemView.findViewById(R.id.repoDescriptionMy);
 | 
			
		||||
            imageMy = itemView.findViewById(R.id.imageAvatarMy);
 | 
			
		||||
            fullNameMy = itemView.findViewById(R.id.repoFullNameMy);
 | 
			
		||||
            repoPrivatePublicMy = itemView.findViewById(R.id.imageRepoTypeMy);
 | 
			
		||||
            repoStarsMy = itemView.findViewById(R.id.repoStarsMy);
 | 
			
		||||
            repoWatchersMy = itemView.findViewById(R.id.repoWatchersMy);
 | 
			
		||||
            repoOpenIssuesCountMy = itemView.findViewById(R.id.repoOpenIssuesCountMy);
 | 
			
		||||
 | 
			
		||||
            itemView.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
                    Context context = v.getContext();
 | 
			
		||||
 | 
			
		||||
                    Intent intent = new Intent(context, RepoDetailActivity.class);
 | 
			
		||||
                    intent.putExtra("repoFullName", fullNameMy.getText().toString());
 | 
			
		||||
 | 
			
		||||
                    TinyDB tinyDb = new TinyDB(context);
 | 
			
		||||
                    tinyDb.putString("repoFullName", fullNameMy.getText().toString());
 | 
			
		||||
                    tinyDb.putBoolean("resumeIssues", true);
 | 
			
		||||
                    context.startActivity(intent);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MyReposListAdapter(Context mCtx, List<UserRepositories> reposListMain) {
 | 
			
		||||
        this.mCtx = mCtx;
 | 
			
		||||
        this.reposList = reposListMain;
 | 
			
		||||
        reposListFull = new ArrayList<>(reposList);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
    @Override
 | 
			
		||||
    public MyReposListAdapter.MyReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
 | 
			
		||||
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_repos_list, parent, false);
 | 
			
		||||
        return new MyReposListAdapter.MyReposViewHolder(v);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onBindViewHolder(@NonNull MyReposListAdapter.MyReposViewHolder holder, int position) {
 | 
			
		||||
 | 
			
		||||
        UserRepositories currentItem = reposList.get(position);
 | 
			
		||||
        holder.mTextView2My.setVisibility(View.GONE);
 | 
			
		||||
 | 
			
		||||
        ColorGenerator generator = ColorGenerator.MATERIAL;
 | 
			
		||||
        int color = generator.getColor(currentItem.getName());
 | 
			
		||||
        String charac = String.valueOf(currentItem.getName().charAt(0));
 | 
			
		||||
 | 
			
		||||
        TextDrawable drawable = TextDrawable.builder()
 | 
			
		||||
                .beginConfig()
 | 
			
		||||
                .useFont(Typeface.DEFAULT)
 | 
			
		||||
                .fontSize(16)
 | 
			
		||||
                .toUpperCase()
 | 
			
		||||
                .width(28)
 | 
			
		||||
                .height(28)
 | 
			
		||||
                .endConfig()
 | 
			
		||||
                .buildRound(charac, color);
 | 
			
		||||
 | 
			
		||||
        holder.imageMy.setImageDrawable(drawable);
 | 
			
		||||
        holder.mTextView1My.setText(currentItem.getName());
 | 
			
		||||
        if (!currentItem.getDescription().equals("")) {
 | 
			
		||||
            holder.mTextView2My.setVisibility(View.VISIBLE);
 | 
			
		||||
            holder.mTextView2My.setText(currentItem.getDescription());
 | 
			
		||||
        }
 | 
			
		||||
        holder.fullNameMy.setText(currentItem.getFullname());
 | 
			
		||||
        if(currentItem.getPrivateFlag()) {
 | 
			
		||||
            holder.repoPrivatePublicMy.setImageResource(R.drawable.ic_lock_bold);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            holder.repoPrivatePublicMy.setImageResource(R.drawable.ic_public);
 | 
			
		||||
        }
 | 
			
		||||
        holder.repoStarsMy.setText(currentItem.getStars_count());
 | 
			
		||||
        holder.repoWatchersMy.setText(currentItem.getWatchers_count());
 | 
			
		||||
        holder.repoOpenIssuesCountMy.setText(currentItem.getOpen_issues_count());
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getItemCount() {
 | 
			
		||||
        return reposList.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Filter getFilter() {
 | 
			
		||||
        return myReposFilter;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Filter myReposFilter = new Filter() {
 | 
			
		||||
        @Override
 | 
			
		||||
        protected FilterResults performFiltering(CharSequence constraint) {
 | 
			
		||||
            List<UserRepositories> filteredList = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
            if (constraint == null || constraint.length() == 0) {
 | 
			
		||||
                filteredList.addAll(reposListFull);
 | 
			
		||||
            } else {
 | 
			
		||||
                String filterPattern = constraint.toString().toLowerCase().trim();
 | 
			
		||||
 | 
			
		||||
                for (UserRepositories item : reposListFull) {
 | 
			
		||||
                    if (item.getFullname().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) {
 | 
			
		||||
                        filteredList.add(item);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            FilterResults results = new FilterResults();
 | 
			
		||||
            results.values = filteredList;
 | 
			
		||||
 | 
			
		||||
            return results;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        protected void publishResults(CharSequence constraint, FilterResults results) {
 | 
			
		||||
            reposList.clear();
 | 
			
		||||
            reposList.addAll((List) results.values);
 | 
			
		||||
            notifyDataSetChanged();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,133 @@
 | 
			
		||||
package org.mian.gitnex.adapters;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
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.TextView;
 | 
			
		||||
import com.squareup.picasso.Picasso;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.activities.OrgDetailActivity;
 | 
			
		||||
import org.mian.gitnex.models.UserOrganizations;
 | 
			
		||||
import org.mian.gitnex.helpers.RoundedTransformation;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class OrganizationsListAdapter extends RecyclerView.Adapter<OrganizationsListAdapter.OrganizationsViewHolder> implements Filterable {
 | 
			
		||||
 | 
			
		||||
    private List<UserOrganizations> orgList;
 | 
			
		||||
    private Context mCtx;
 | 
			
		||||
    private List<UserOrganizations> orgListFull;
 | 
			
		||||
 | 
			
		||||
    static class OrganizationsViewHolder extends RecyclerView.ViewHolder {
 | 
			
		||||
 | 
			
		||||
        private ImageView image;
 | 
			
		||||
        private TextView mTextView1;
 | 
			
		||||
        private TextView mTextView2;
 | 
			
		||||
 | 
			
		||||
        private OrganizationsViewHolder(View itemView) {
 | 
			
		||||
            super(itemView);
 | 
			
		||||
            mTextView1 = itemView.findViewById(R.id.orgUsername);
 | 
			
		||||
            mTextView2 = itemView.findViewById(R.id.orgDescription);
 | 
			
		||||
            image = itemView.findViewById(R.id.imageAvatar);
 | 
			
		||||
 | 
			
		||||
            itemView.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
                    Context context = v.getContext();
 | 
			
		||||
                    Intent intent = new Intent(context, OrgDetailActivity.class);
 | 
			
		||||
                    intent.putExtra("orgName", mTextView1.getText().toString());
 | 
			
		||||
 | 
			
		||||
                    TinyDB tinyDb = new TinyDB(context);
 | 
			
		||||
                    tinyDb.putString("orgName", mTextView1.getText().toString());
 | 
			
		||||
                    context.startActivity(intent);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public OrganizationsListAdapter(Context mCtx, List<UserOrganizations> orgsListMain) {
 | 
			
		||||
        this.mCtx = mCtx;
 | 
			
		||||
        this.orgList = orgsListMain;
 | 
			
		||||
        orgListFull = new ArrayList<>(orgList);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
    @Override
 | 
			
		||||
    public OrganizationsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
 | 
			
		||||
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.organizations_list, parent, false);
 | 
			
		||||
        return new OrganizationsViewHolder(v);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onBindViewHolder(@NonNull OrganizationsViewHolder holder, int position) {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        UserOrganizations currentItem = orgList.get(position);
 | 
			
		||||
        holder.mTextView2.setVisibility(View.GONE);
 | 
			
		||||
 | 
			
		||||
        Picasso.get().load(currentItem.getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(holder.image);
 | 
			
		||||
        holder.mTextView1.setText(currentItem.getUsername());
 | 
			
		||||
        if (!currentItem.getDescription().equals("")) {
 | 
			
		||||
            holder.mTextView2.setVisibility(View.VISIBLE);
 | 
			
		||||
            holder.mTextView2.setText(currentItem.getDescription());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getItemCount() {
 | 
			
		||||
        return orgList.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Filter getFilter() {
 | 
			
		||||
        return orgFilter;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Filter orgFilter = new Filter() {
 | 
			
		||||
        @Override
 | 
			
		||||
        protected FilterResults performFiltering(CharSequence constraint) {
 | 
			
		||||
            List<UserOrganizations> filteredList = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
            if (constraint == null || constraint.length() == 0) {
 | 
			
		||||
                filteredList.addAll(orgListFull);
 | 
			
		||||
            } else {
 | 
			
		||||
                String filterPattern = constraint.toString().toLowerCase().trim();
 | 
			
		||||
 | 
			
		||||
                for (UserOrganizations item : orgListFull) {
 | 
			
		||||
                    if (item.getUsername().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) {
 | 
			
		||||
                        filteredList.add(item);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            FilterResults results = new FilterResults();
 | 
			
		||||
            results.values = filteredList;
 | 
			
		||||
 | 
			
		||||
            return results;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        protected void publishResults(CharSequence constraint, FilterResults results) {
 | 
			
		||||
            orgList.clear();
 | 
			
		||||
            orgList.addAll((List) results.values);
 | 
			
		||||
            notifyDataSetChanged();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,80 @@
 | 
			
		||||
package org.mian.gitnex.adapters;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import com.amulyakhare.textdrawable.TextDrawable;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.models.Emails;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class ProfileEmailsAdapter extends RecyclerView.Adapter<ProfileEmailsAdapter.EmailsViewHolder> {
 | 
			
		||||
 | 
			
		||||
    private List<Emails> emailsList;
 | 
			
		||||
    private Context mCtx;
 | 
			
		||||
 | 
			
		||||
    static class EmailsViewHolder extends RecyclerView.ViewHolder {
 | 
			
		||||
 | 
			
		||||
        private ImageView emailPrimary;
 | 
			
		||||
        private TextView userEmail;
 | 
			
		||||
 | 
			
		||||
        private EmailsViewHolder(View itemView) {
 | 
			
		||||
            super(itemView);
 | 
			
		||||
 | 
			
		||||
            emailPrimary = itemView.findViewById(R.id.emailPrimary);
 | 
			
		||||
            userEmail = itemView.findViewById(R.id.userEmail);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ProfileEmailsAdapter(Context mCtx, List<Emails> emailsListMain) {
 | 
			
		||||
        this.mCtx = mCtx;
 | 
			
		||||
        this.emailsList = emailsListMain;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
    @Override
 | 
			
		||||
    public ProfileEmailsAdapter.EmailsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
 | 
			
		||||
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.profile_emails_list, parent, false);
 | 
			
		||||
        return new ProfileEmailsAdapter.EmailsViewHolder(v);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onBindViewHolder(@NonNull ProfileEmailsAdapter.EmailsViewHolder holder, int position) {
 | 
			
		||||
 | 
			
		||||
        Emails currentItem = emailsList.get(position);
 | 
			
		||||
 | 
			
		||||
        holder.userEmail.setText(currentItem.getEmail());
 | 
			
		||||
 | 
			
		||||
        if(currentItem.getPrimary()) {
 | 
			
		||||
            TextDrawable drawable = TextDrawable.builder()
 | 
			
		||||
                    .beginConfig()
 | 
			
		||||
                    .textColor(mCtx.getResources().getColor(R.color.white))
 | 
			
		||||
                    .fontSize(36)
 | 
			
		||||
                    .width(220)
 | 
			
		||||
                    .height(60)
 | 
			
		||||
                    .endConfig()
 | 
			
		||||
                    .buildRoundRect(mCtx.getResources().getString(R.string.emailTypeText), mCtx.getResources().getColor(R.color.tooltipBackground), 8);
 | 
			
		||||
            holder.emailPrimary.setImageDrawable(drawable);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            holder.emailPrimary.setVisibility(View.GONE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getItemCount() {
 | 
			
		||||
        return emailsList.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,78 @@
 | 
			
		||||
package org.mian.gitnex.adapters;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import com.squareup.picasso.Picasso;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.helpers.RoundedTransformation;
 | 
			
		||||
import org.mian.gitnex.models.UserInfo;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class ProfileFollowersAdapter extends RecyclerView.Adapter<ProfileFollowersAdapter.FollowersViewHolder> {
 | 
			
		||||
 | 
			
		||||
    private List<UserInfo> followersList;
 | 
			
		||||
    private Context mCtx;
 | 
			
		||||
 | 
			
		||||
    static class FollowersViewHolder extends RecyclerView.ViewHolder {
 | 
			
		||||
 | 
			
		||||
        private ImageView userAvatar;
 | 
			
		||||
        private TextView userFullName;
 | 
			
		||||
        private TextView userName;
 | 
			
		||||
 | 
			
		||||
        private FollowersViewHolder(View itemView) {
 | 
			
		||||
            super(itemView);
 | 
			
		||||
 | 
			
		||||
            userAvatar = itemView.findViewById(R.id.userAvatar);
 | 
			
		||||
            userFullName = itemView.findViewById(R.id.userFullName);
 | 
			
		||||
            userName = itemView.findViewById(R.id.userName);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ProfileFollowersAdapter(Context mCtx, List<UserInfo> followersListMain) {
 | 
			
		||||
        this.mCtx = mCtx;
 | 
			
		||||
        this.followersList = followersListMain;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
    @Override
 | 
			
		||||
    public ProfileFollowersAdapter.FollowersViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
 | 
			
		||||
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.profile_followers_list, parent, false);
 | 
			
		||||
        return new ProfileFollowersAdapter.FollowersViewHolder(v);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onBindViewHolder(@NonNull ProfileFollowersAdapter.FollowersViewHolder holder, int position) {
 | 
			
		||||
 | 
			
		||||
        UserInfo currentItem = followersList.get(position);
 | 
			
		||||
 | 
			
		||||
        if(!currentItem.getFullname().equals("")) {
 | 
			
		||||
            holder.userFullName.setText(currentItem.getFullname());
 | 
			
		||||
            holder.userName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            holder.userFullName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
 | 
			
		||||
            holder.userName.setVisibility(View.GONE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(100, 0)).resize(140, 140).centerCrop().into(holder.userAvatar);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getItemCount() {
 | 
			
		||||
        return followersList.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,77 @@
 | 
			
		||||
package org.mian.gitnex.adapters;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import com.squareup.picasso.Picasso;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.helpers.RoundedTransformation;
 | 
			
		||||
import org.mian.gitnex.models.UserInfo;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class ProfileFollowingAdapter extends RecyclerView.Adapter<ProfileFollowingAdapter.FollowingViewHolder> {
 | 
			
		||||
 | 
			
		||||
    private List<UserInfo> followingList;
 | 
			
		||||
    private Context mCtx;
 | 
			
		||||
 | 
			
		||||
    static class FollowingViewHolder extends RecyclerView.ViewHolder {
 | 
			
		||||
 | 
			
		||||
        private ImageView userAvatar;
 | 
			
		||||
        private TextView userFullName;
 | 
			
		||||
        private TextView userName;
 | 
			
		||||
 | 
			
		||||
        private FollowingViewHolder(View itemView) {
 | 
			
		||||
            super(itemView);
 | 
			
		||||
 | 
			
		||||
            userAvatar = itemView.findViewById(R.id.userAvatar);
 | 
			
		||||
            userFullName = itemView.findViewById(R.id.userFullName);
 | 
			
		||||
            userName = itemView.findViewById(R.id.userName);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ProfileFollowingAdapter(Context mCtx, List<UserInfo> followingListMain) {
 | 
			
		||||
        this.mCtx = mCtx;
 | 
			
		||||
        this.followingList = followingListMain;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
    @Override
 | 
			
		||||
    public ProfileFollowingAdapter.FollowingViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
 | 
			
		||||
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.profile_following_list, parent, false);
 | 
			
		||||
        return new ProfileFollowingAdapter.FollowingViewHolder(v);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onBindViewHolder(@NonNull ProfileFollowingAdapter.FollowingViewHolder holder, int position) {
 | 
			
		||||
 | 
			
		||||
        UserInfo currentItem = followingList.get(position);
 | 
			
		||||
 | 
			
		||||
        if(!currentItem.getFullname().equals("")) {
 | 
			
		||||
            holder.userFullName.setText(currentItem.getFullname());
 | 
			
		||||
            holder.userName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            holder.userFullName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
 | 
			
		||||
            holder.userName.setVisibility(View.GONE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(100, 0)).resize(140, 140).centerCrop().into(holder.userAvatar);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getItemCount() {
 | 
			
		||||
        return followingList.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										152
									
								
								app/src/main/java/org/mian/gitnex/adapters/ReleasesAdapter.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								app/src/main/java/org/mian/gitnex/adapters/ReleasesAdapter.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,152 @@
 | 
			
		||||
package org.mian.gitnex.adapters;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.graphics.Color;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import com.amulyakhare.textdrawable.TextDrawable;
 | 
			
		||||
import com.vdurmont.emoji.EmojiParser;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.models.Releases;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import okhttp3.OkHttpClient;
 | 
			
		||||
import ru.noties.markwon.AbstractMarkwonPlugin;
 | 
			
		||||
import ru.noties.markwon.Markwon;
 | 
			
		||||
import ru.noties.markwon.core.CorePlugin;
 | 
			
		||||
import ru.noties.markwon.core.MarkwonTheme;
 | 
			
		||||
import ru.noties.markwon.ext.strikethrough.StrikethroughPlugin;
 | 
			
		||||
import ru.noties.markwon.ext.tables.TablePlugin;
 | 
			
		||||
import ru.noties.markwon.ext.tasklist.TaskListPlugin;
 | 
			
		||||
import ru.noties.markwon.html.HtmlPlugin;
 | 
			
		||||
import ru.noties.markwon.image.ImagesPlugin;
 | 
			
		||||
import ru.noties.markwon.image.gif.GifPlugin;
 | 
			
		||||
import ru.noties.markwon.image.okhttp.OkHttpImagesPlugin;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class ReleasesAdapter extends RecyclerView.Adapter<ReleasesAdapter.ReleasesViewHolder> {
 | 
			
		||||
 | 
			
		||||
    private List<Releases> releasesList;
 | 
			
		||||
    private Context mCtx;
 | 
			
		||||
 | 
			
		||||
    static class ReleasesViewHolder extends RecyclerView.ViewHolder {
 | 
			
		||||
 | 
			
		||||
        private ImageView releaseType;
 | 
			
		||||
        private TextView releaseTitle;
 | 
			
		||||
        private TextView releaseDescription;
 | 
			
		||||
        private TextView releaseDownload;
 | 
			
		||||
        private TextView releaseZipDownload;
 | 
			
		||||
        private TextView releaseTarDownload;
 | 
			
		||||
        private TextView releaseTag;
 | 
			
		||||
 | 
			
		||||
        private ReleasesViewHolder(View itemView) {
 | 
			
		||||
            super(itemView);
 | 
			
		||||
 | 
			
		||||
            releaseType = itemView.findViewById(R.id.releaseType);
 | 
			
		||||
            releaseTitle = itemView.findViewById(R.id.releaseTitle);
 | 
			
		||||
            releaseDescription = itemView.findViewById(R.id.releaseDescription);
 | 
			
		||||
            releaseZipDownload = itemView.findViewById(R.id.releaseZipDownload);
 | 
			
		||||
            releaseTarDownload = itemView.findViewById(R.id.releaseTarDownload);
 | 
			
		||||
            releaseTag = itemView.findViewById(R.id.releaseTag);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ReleasesAdapter(Context mCtx, List<Releases> releasesMain) {
 | 
			
		||||
        this.mCtx = mCtx;
 | 
			
		||||
        this.releasesList = releasesMain;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
    @Override
 | 
			
		||||
    public ReleasesAdapter.ReleasesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
 | 
			
		||||
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.releases_list, parent, false);
 | 
			
		||||
        return new ReleasesAdapter.ReleasesViewHolder(v);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onBindViewHolder(@NonNull ReleasesAdapter.ReleasesViewHolder holder, int position) {
 | 
			
		||||
 | 
			
		||||
        Releases currentItem = releasesList.get(position);
 | 
			
		||||
 | 
			
		||||
        holder.releaseTitle.setText(currentItem.getName());
 | 
			
		||||
 | 
			
		||||
        if(!currentItem.getTag_name().equals("")) {
 | 
			
		||||
            holder.releaseTag.setText(mCtx.getResources().getString(R.string.releaseTag, currentItem.getTag_name()));
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            holder.releaseTag.setVisibility(View.GONE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(currentItem.isPrerelease()) {
 | 
			
		||||
            TextDrawable drawable = TextDrawable.builder()
 | 
			
		||||
                    .beginConfig()
 | 
			
		||||
                    //.useFont(Typeface.DEFAULT)
 | 
			
		||||
                    .textColor(mCtx.getResources().getColor(R.color.white))
 | 
			
		||||
                    .fontSize(34)
 | 
			
		||||
                    .width(260)
 | 
			
		||||
                    .height(60)
 | 
			
		||||
                    .endConfig()
 | 
			
		||||
                    .buildRoundRect(mCtx.getResources().getString(R.string.releaseTypePre), mCtx.getResources().getColor(R.color.releasePre), 8);
 | 
			
		||||
            holder.releaseType.setImageDrawable(drawable);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            TextDrawable drawable = TextDrawable.builder()
 | 
			
		||||
                    .beginConfig()
 | 
			
		||||
                    //.useFont(Typeface.DEFAULT)
 | 
			
		||||
                    .textColor(mCtx.getResources().getColor(R.color.white))
 | 
			
		||||
                    .fontSize(34)
 | 
			
		||||
                    .width(260)
 | 
			
		||||
                    .height(60)
 | 
			
		||||
                    .endConfig()
 | 
			
		||||
                    .buildRoundRect(mCtx.getResources().getString(R.string.releaseTypeStable), mCtx.getResources().getColor(R.color.releaseStable), 8);
 | 
			
		||||
            holder.releaseType.setImageDrawable(drawable);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx))
 | 
			
		||||
                .usePlugin(CorePlugin.create())
 | 
			
		||||
                .usePlugin(OkHttpImagesPlugin.create(new OkHttpClient()))
 | 
			
		||||
                .usePlugin(ImagesPlugin.createWithAssets(mCtx))
 | 
			
		||||
                .usePlugin(new AbstractMarkwonPlugin() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
 | 
			
		||||
                        builder
 | 
			
		||||
                                .codeTextColor(Color.GREEN)
 | 
			
		||||
                                .codeBackgroundColor(Color.BLACK)
 | 
			
		||||
                                .linkColor(mCtx.getResources().getColor(R.color.lightBlue));
 | 
			
		||||
                    }
 | 
			
		||||
                })
 | 
			
		||||
                .usePlugin(TablePlugin.create(mCtx))
 | 
			
		||||
                .usePlugin(TaskListPlugin.create(mCtx))
 | 
			
		||||
                .usePlugin(HtmlPlugin.create())
 | 
			
		||||
                .usePlugin(GifPlugin.create())
 | 
			
		||||
                .usePlugin(StrikethroughPlugin.create())
 | 
			
		||||
                .build();
 | 
			
		||||
 | 
			
		||||
        final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(currentItem.getBody()));
 | 
			
		||||
 | 
			
		||||
        if(!currentItem.getBody().equals("")) {
 | 
			
		||||
            holder.releaseDescription.setText(bodyWithMD);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            holder.releaseDescription.setVisibility(View.GONE);
 | 
			
		||||
        }
 | 
			
		||||
        holder.releaseZipDownload.setText(currentItem.getZipball_url());
 | 
			
		||||
        holder.releaseTarDownload.setText(currentItem.getTarball_url());
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getItemCount() {
 | 
			
		||||
        return releasesList.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										169
									
								
								app/src/main/java/org/mian/gitnex/adapters/ReposListAdapter.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								app/src/main/java/org/mian/gitnex/adapters/ReposListAdapter.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,169 @@
 | 
			
		||||
package org.mian.gitnex.adapters;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.graphics.Typeface;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
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.TextView;
 | 
			
		||||
import com.amulyakhare.textdrawable.TextDrawable;
 | 
			
		||||
import com.amulyakhare.textdrawable.util.ColorGenerator;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.activities.RepoDetailActivity;
 | 
			
		||||
import org.mian.gitnex.models.UserRepositories;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class ReposListAdapter extends RecyclerView.Adapter<ReposListAdapter.ReposViewHolder> implements Filterable {
 | 
			
		||||
 | 
			
		||||
    private List<UserRepositories> reposList;
 | 
			
		||||
    private Context mCtx;
 | 
			
		||||
    private List<UserRepositories> reposListFull;
 | 
			
		||||
 | 
			
		||||
    static class ReposViewHolder extends RecyclerView.ViewHolder {
 | 
			
		||||
 | 
			
		||||
        private ImageView image;
 | 
			
		||||
        private TextView mTextView1;
 | 
			
		||||
        private TextView mTextView2;
 | 
			
		||||
        private TextView fullName;
 | 
			
		||||
        private ImageView repoPrivatePublic;
 | 
			
		||||
        private TextView repoStars;
 | 
			
		||||
        private TextView repoWatchers;
 | 
			
		||||
        private TextView repoOpenIssuesCount;
 | 
			
		||||
 | 
			
		||||
        private ReposViewHolder(View itemView) {
 | 
			
		||||
            super(itemView);
 | 
			
		||||
            mTextView1 = itemView.findViewById(R.id.repoName);
 | 
			
		||||
            mTextView2 = itemView.findViewById(R.id.repoDescription);
 | 
			
		||||
            image = itemView.findViewById(R.id.imageAvatar);
 | 
			
		||||
            fullName = itemView.findViewById(R.id.repoFullName);
 | 
			
		||||
            repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
 | 
			
		||||
            repoStars = itemView.findViewById(R.id.repoStars);
 | 
			
		||||
            repoWatchers = itemView.findViewById(R.id.repoWatchers);
 | 
			
		||||
            repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount);
 | 
			
		||||
 | 
			
		||||
            itemView.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
                    Context context = v.getContext();
 | 
			
		||||
                    TextView repoFullName = (TextView) v.findViewById(R.id.repoFullName);
 | 
			
		||||
 | 
			
		||||
                    Intent intent = new Intent(context, RepoDetailActivity.class);
 | 
			
		||||
                    intent.putExtra("repoFullName", repoFullName.getText().toString());
 | 
			
		||||
 | 
			
		||||
                    TinyDB tinyDb = new TinyDB(context);
 | 
			
		||||
                    tinyDb.putString("repoFullName", repoFullName.getText().toString());
 | 
			
		||||
                    tinyDb.putBoolean("resumeIssues", true);
 | 
			
		||||
                    context.startActivity(intent);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ReposListAdapter(Context mCtx, List<UserRepositories> reposListMain) {
 | 
			
		||||
        this.mCtx = mCtx;
 | 
			
		||||
        this.reposList = reposListMain;
 | 
			
		||||
        reposListFull = new ArrayList<>(reposList);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
    @Override
 | 
			
		||||
    public ReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
 | 
			
		||||
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.repos_list, parent, false);
 | 
			
		||||
        return new ReposViewHolder(v);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onBindViewHolder(@NonNull ReposViewHolder holder, int position) {
 | 
			
		||||
 | 
			
		||||
        UserRepositories currentItem = reposList.get(position);
 | 
			
		||||
        holder.mTextView2.setVisibility(View.GONE);
 | 
			
		||||
 | 
			
		||||
        ColorGenerator generator = ColorGenerator.MATERIAL;
 | 
			
		||||
        int color = generator.getColor(currentItem.getName());
 | 
			
		||||
        String charac = String.valueOf(currentItem.getName().charAt(0));
 | 
			
		||||
 | 
			
		||||
        TextDrawable drawable = TextDrawable.builder()
 | 
			
		||||
                .beginConfig()
 | 
			
		||||
                .useFont(Typeface.DEFAULT)
 | 
			
		||||
                .fontSize(16)
 | 
			
		||||
                .toUpperCase()
 | 
			
		||||
                .width(28)
 | 
			
		||||
                .height(28)
 | 
			
		||||
                .endConfig()
 | 
			
		||||
                .buildRound(charac, color);
 | 
			
		||||
 | 
			
		||||
        holder.image.setImageDrawable(drawable);
 | 
			
		||||
        holder.mTextView1.setText(currentItem.getName());
 | 
			
		||||
        if (!currentItem.getDescription().equals("")) {
 | 
			
		||||
            holder.mTextView2.setVisibility(View.VISIBLE);
 | 
			
		||||
            holder.mTextView2.setText(currentItem.getDescription());
 | 
			
		||||
        }
 | 
			
		||||
        holder.fullName.setText(currentItem.getFullname());
 | 
			
		||||
        if(currentItem.getPrivateFlag()) {
 | 
			
		||||
            holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock_bold);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            holder.repoPrivatePublic.setImageResource(R.drawable.ic_public);
 | 
			
		||||
        }
 | 
			
		||||
        holder.repoStars.setText(currentItem.getStars_count());
 | 
			
		||||
        holder.repoWatchers.setText(currentItem.getWatchers_count());
 | 
			
		||||
        holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getItemCount() {
 | 
			
		||||
        return reposList.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Filter getFilter() {
 | 
			
		||||
        return reposFilter;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Filter reposFilter = new Filter() {
 | 
			
		||||
        @Override
 | 
			
		||||
        protected FilterResults performFiltering(CharSequence constraint) {
 | 
			
		||||
            List<UserRepositories> filteredList = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
            if (constraint == null || constraint.length() == 0) {
 | 
			
		||||
                filteredList.addAll(reposListFull);
 | 
			
		||||
            } else {
 | 
			
		||||
                String filterPattern = constraint.toString().toLowerCase().trim();
 | 
			
		||||
 | 
			
		||||
                for (UserRepositories item : reposListFull) {
 | 
			
		||||
                    if (item.getFullname().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) {
 | 
			
		||||
                        filteredList.add(item);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            FilterResults results = new FilterResults();
 | 
			
		||||
            results.values = filteredList;
 | 
			
		||||
 | 
			
		||||
            return results;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        protected void publishResults(CharSequence constraint, FilterResults results) {
 | 
			
		||||
            reposList.clear();
 | 
			
		||||
            reposList.addAll((List) results.values);
 | 
			
		||||
            notifyDataSetChanged();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,170 @@
 | 
			
		||||
package org.mian.gitnex.adapters;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.graphics.Typeface;
 | 
			
		||||
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.TextView;
 | 
			
		||||
import com.amulyakhare.textdrawable.TextDrawable;
 | 
			
		||||
import com.amulyakhare.textdrawable.util.ColorGenerator;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.activities.RepoDetailActivity;
 | 
			
		||||
import org.mian.gitnex.models.UserRepositories;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class RepositoriesByOrgAdapter extends RecyclerView.Adapter<RepositoriesByOrgAdapter.OrgReposViewHolder> implements Filterable {
 | 
			
		||||
 | 
			
		||||
    private List<UserRepositories> reposList;
 | 
			
		||||
    private Context mCtx;
 | 
			
		||||
    private List<UserRepositories> reposListFull;
 | 
			
		||||
 | 
			
		||||
    static class OrgReposViewHolder extends RecyclerView.ViewHolder {
 | 
			
		||||
 | 
			
		||||
        private ImageView image;
 | 
			
		||||
        private TextView mTextView1;
 | 
			
		||||
        private TextView mTextView2;
 | 
			
		||||
        private TextView fullName;
 | 
			
		||||
        private ImageView repoPrivatePublic;
 | 
			
		||||
        private TextView repoStars;
 | 
			
		||||
        private TextView repoWatchers;
 | 
			
		||||
        private TextView repoOpenIssuesCount;
 | 
			
		||||
 | 
			
		||||
        private OrgReposViewHolder(View itemView) {
 | 
			
		||||
            super(itemView);
 | 
			
		||||
            mTextView1 = itemView.findViewById(R.id.repoName);
 | 
			
		||||
            mTextView2 = itemView.findViewById(R.id.repoDescription);
 | 
			
		||||
            image = itemView.findViewById(R.id.imageAvatar);
 | 
			
		||||
            fullName = itemView.findViewById(R.id.repoFullName);
 | 
			
		||||
            repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
 | 
			
		||||
            repoStars = itemView.findViewById(R.id.repoStars);
 | 
			
		||||
            repoWatchers = itemView.findViewById(R.id.repoWatchers);
 | 
			
		||||
            repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount);
 | 
			
		||||
 | 
			
		||||
            itemView.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
                    Context context = v.getContext();
 | 
			
		||||
 | 
			
		||||
                    Intent intent = new Intent(context, RepoDetailActivity.class);
 | 
			
		||||
                    intent.putExtra("repoFullName", fullName.getText().toString());
 | 
			
		||||
 | 
			
		||||
                    TinyDB tinyDb = new TinyDB(context);
 | 
			
		||||
                    tinyDb.putString("repoFullName", fullName.getText().toString());
 | 
			
		||||
                    tinyDb.putBoolean("resumeIssues", true);
 | 
			
		||||
                    context.startActivity(intent);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public RepositoriesByOrgAdapter(Context mCtx, List<UserRepositories> reposListMain) {
 | 
			
		||||
        this.mCtx = mCtx;
 | 
			
		||||
        this.reposList = reposListMain;
 | 
			
		||||
        reposListFull = new ArrayList<>(reposList);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
    @Override
 | 
			
		||||
    public RepositoriesByOrgAdapter.OrgReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
 | 
			
		||||
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.repositories_by_org_list, parent, false);
 | 
			
		||||
        return new RepositoriesByOrgAdapter.OrgReposViewHolder(v);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onBindViewHolder(@NonNull RepositoriesByOrgAdapter.OrgReposViewHolder holder, int position) {
 | 
			
		||||
 | 
			
		||||
        UserRepositories currentItem = reposList.get(position);
 | 
			
		||||
        holder.mTextView2.setVisibility(View.GONE);
 | 
			
		||||
 | 
			
		||||
        ColorGenerator generator = ColorGenerator.MATERIAL;
 | 
			
		||||
        int color = generator.getColor(currentItem.getName());
 | 
			
		||||
        String charac = String.valueOf(currentItem.getName().charAt(0));
 | 
			
		||||
 | 
			
		||||
        TextDrawable drawable = TextDrawable.builder()
 | 
			
		||||
                .beginConfig()
 | 
			
		||||
                .useFont(Typeface.DEFAULT)
 | 
			
		||||
                .fontSize(16)
 | 
			
		||||
                .toUpperCase()
 | 
			
		||||
                .width(28)
 | 
			
		||||
                .height(28)
 | 
			
		||||
                .endConfig()
 | 
			
		||||
                .buildRound(charac, color);
 | 
			
		||||
 | 
			
		||||
        holder.image.setImageDrawable(drawable);
 | 
			
		||||
        holder.mTextView1.setText(currentItem.getName());
 | 
			
		||||
        if (!currentItem.getDescription().equals("")) {
 | 
			
		||||
            holder.mTextView2.setVisibility(View.VISIBLE);
 | 
			
		||||
            holder.mTextView2.setText(currentItem.getDescription());
 | 
			
		||||
        }
 | 
			
		||||
        holder.fullName.setText(currentItem.getFullname());
 | 
			
		||||
        if(currentItem.getPrivateFlag()) {
 | 
			
		||||
            holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock_bold);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            holder.repoPrivatePublic.setImageResource(R.drawable.ic_public);
 | 
			
		||||
        }
 | 
			
		||||
        holder.repoStars.setText(currentItem.getStars_count());
 | 
			
		||||
        holder.repoWatchers.setText(currentItem.getWatchers_count());
 | 
			
		||||
        holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getItemCount() {
 | 
			
		||||
        return reposList.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Filter getFilter() {
 | 
			
		||||
        return orgReposFilter;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Filter orgReposFilter = new Filter() {
 | 
			
		||||
        @Override
 | 
			
		||||
        protected FilterResults performFiltering(CharSequence constraint) {
 | 
			
		||||
            List<UserRepositories> filteredList = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
            if (constraint == null || constraint.length() == 0) {
 | 
			
		||||
                filteredList.addAll(reposListFull);
 | 
			
		||||
            } else {
 | 
			
		||||
                String filterPattern = constraint.toString().toLowerCase().trim();
 | 
			
		||||
 | 
			
		||||
                for (UserRepositories item : reposListFull) {
 | 
			
		||||
                    if (item.getFullname().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) {
 | 
			
		||||
                        filteredList.add(item);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            FilterResults results = new FilterResults();
 | 
			
		||||
            results.values = filteredList;
 | 
			
		||||
 | 
			
		||||
            return results;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        protected void publishResults(CharSequence constraint, FilterResults results) {
 | 
			
		||||
            reposList.clear();
 | 
			
		||||
            reposList.addAll((List) results.values);
 | 
			
		||||
            notifyDataSetChanged();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,170 @@
 | 
			
		||||
package org.mian.gitnex.adapters;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.graphics.Typeface;
 | 
			
		||||
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.TextView;
 | 
			
		||||
import com.amulyakhare.textdrawable.TextDrawable;
 | 
			
		||||
import com.amulyakhare.textdrawable.util.ColorGenerator;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.activities.RepoDetailActivity;
 | 
			
		||||
import org.mian.gitnex.models.UserRepositories;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class StarredReposListAdapter extends RecyclerView.Adapter<StarredReposListAdapter.StarredReposViewHolder> implements Filterable {
 | 
			
		||||
 | 
			
		||||
    private List<UserRepositories> reposList;
 | 
			
		||||
    private Context mCtx;
 | 
			
		||||
    private List<UserRepositories> reposListFull;
 | 
			
		||||
 | 
			
		||||
    static class StarredReposViewHolder extends RecyclerView.ViewHolder {
 | 
			
		||||
 | 
			
		||||
        private ImageView image;
 | 
			
		||||
        private TextView mTextView1;
 | 
			
		||||
        private TextView mTextView2;
 | 
			
		||||
        private TextView fullName;
 | 
			
		||||
        private ImageView repoPrivatePublic;
 | 
			
		||||
        private TextView repoStars;
 | 
			
		||||
        private TextView repoWatchers;
 | 
			
		||||
        private TextView repoOpenIssuesCount;
 | 
			
		||||
 | 
			
		||||
        private StarredReposViewHolder(View itemView) {
 | 
			
		||||
            super(itemView);
 | 
			
		||||
            mTextView1 = itemView.findViewById(R.id.repoName);
 | 
			
		||||
            mTextView2 = itemView.findViewById(R.id.repoDescription);
 | 
			
		||||
            image = itemView.findViewById(R.id.imageAvatar);
 | 
			
		||||
            fullName = itemView.findViewById(R.id.repoFullName);
 | 
			
		||||
            repoPrivatePublic = itemView.findViewById(R.id.imageRepoType);
 | 
			
		||||
            repoStars = itemView.findViewById(R.id.repoStars);
 | 
			
		||||
            repoWatchers = itemView.findViewById(R.id.repoWatchers);
 | 
			
		||||
            repoOpenIssuesCount = itemView.findViewById(R.id.repoOpenIssuesCount);
 | 
			
		||||
 | 
			
		||||
            itemView.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
                    Context context = v.getContext();
 | 
			
		||||
 | 
			
		||||
                    Intent intent = new Intent(context, RepoDetailActivity.class);
 | 
			
		||||
                    intent.putExtra("repoFullName", fullName.getText().toString());
 | 
			
		||||
 | 
			
		||||
                    TinyDB tinyDb = new TinyDB(context);
 | 
			
		||||
                    tinyDb.putString("repoFullName", fullName.getText().toString());
 | 
			
		||||
                    tinyDb.putBoolean("resumeIssues", true);
 | 
			
		||||
                    context.startActivity(intent);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public StarredReposListAdapter(Context mCtx, List<UserRepositories> reposListMain) {
 | 
			
		||||
        this.mCtx = mCtx;
 | 
			
		||||
        this.reposList = reposListMain;
 | 
			
		||||
        reposListFull = new ArrayList<>(reposList);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
    @Override
 | 
			
		||||
    public StarredReposListAdapter.StarredReposViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
 | 
			
		||||
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.starred_repos_list, parent, false);
 | 
			
		||||
        return new StarredReposListAdapter.StarredReposViewHolder(v);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onBindViewHolder(@NonNull StarredReposListAdapter.StarredReposViewHolder holder, int position) {
 | 
			
		||||
 | 
			
		||||
        UserRepositories currentItem = reposList.get(position);
 | 
			
		||||
        holder.mTextView2.setVisibility(View.GONE);
 | 
			
		||||
 | 
			
		||||
        ColorGenerator generator = ColorGenerator.MATERIAL;
 | 
			
		||||
        int color = generator.getColor(currentItem.getName());
 | 
			
		||||
        String charac = String.valueOf(currentItem.getName().charAt(0));
 | 
			
		||||
 | 
			
		||||
        TextDrawable drawable = TextDrawable.builder()
 | 
			
		||||
                .beginConfig()
 | 
			
		||||
                .useFont(Typeface.DEFAULT)
 | 
			
		||||
                .fontSize(16)
 | 
			
		||||
                .toUpperCase()
 | 
			
		||||
                .width(28)
 | 
			
		||||
                .height(28)
 | 
			
		||||
                .endConfig()
 | 
			
		||||
                .buildRound(charac, color);
 | 
			
		||||
 | 
			
		||||
        holder.image.setImageDrawable(drawable);
 | 
			
		||||
        holder.mTextView1.setText(currentItem.getName());
 | 
			
		||||
        if (!currentItem.getDescription().equals("")) {
 | 
			
		||||
            holder.mTextView2.setVisibility(View.VISIBLE);
 | 
			
		||||
            holder.mTextView2.setText(currentItem.getDescription());
 | 
			
		||||
        }
 | 
			
		||||
        holder.fullName.setText(currentItem.getFullname());
 | 
			
		||||
        if(currentItem.getPrivateFlag()) {
 | 
			
		||||
            holder.repoPrivatePublic.setImageResource(R.drawable.ic_lock_bold);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            holder.repoPrivatePublic.setImageResource(R.drawable.ic_public);
 | 
			
		||||
        }
 | 
			
		||||
        holder.repoStars.setText(currentItem.getStars_count());
 | 
			
		||||
        holder.repoWatchers.setText(currentItem.getWatchers_count());
 | 
			
		||||
        holder.repoOpenIssuesCount.setText(currentItem.getOpen_issues_count());
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getItemCount() {
 | 
			
		||||
        return reposList.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Filter getFilter() {
 | 
			
		||||
        return starredReposFilter;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Filter starredReposFilter = new Filter() {
 | 
			
		||||
        @Override
 | 
			
		||||
        protected FilterResults performFiltering(CharSequence constraint) {
 | 
			
		||||
            List<UserRepositories> filteredList = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
            if (constraint == null || constraint.length() == 0) {
 | 
			
		||||
                filteredList.addAll(reposListFull);
 | 
			
		||||
            } else {
 | 
			
		||||
                String filterPattern = constraint.toString().toLowerCase().trim();
 | 
			
		||||
 | 
			
		||||
                for (UserRepositories item : reposListFull) {
 | 
			
		||||
                    if (item.getFullname().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) {
 | 
			
		||||
                        filteredList.add(item);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            FilterResults results = new FilterResults();
 | 
			
		||||
            results.values = filteredList;
 | 
			
		||||
 | 
			
		||||
            return results;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        protected void publishResults(CharSequence constraint, FilterResults results) {
 | 
			
		||||
            reposList.clear();
 | 
			
		||||
            reposList.addAll((List) results.values);
 | 
			
		||||
            notifyDataSetChanged();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,91 @@
 | 
			
		||||
package org.mian.gitnex.adapters;
 | 
			
		||||
 | 
			
		||||
import android.annotation.SuppressLint;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.BaseAdapter;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import com.squareup.picasso.Picasso;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.helpers.RoundedTransformation;
 | 
			
		||||
import org.mian.gitnex.models.UserInfo;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class TeamMembersByOrgAdapter extends BaseAdapter {
 | 
			
		||||
 | 
			
		||||
    private List<UserInfo> teamMembersList;
 | 
			
		||||
    private Context mCtx;
 | 
			
		||||
 | 
			
		||||
    private class ViewHolder {
 | 
			
		||||
 | 
			
		||||
        private ImageView memberAvatar;
 | 
			
		||||
        private TextView memberName;
 | 
			
		||||
 | 
			
		||||
        ViewHolder(View v) {
 | 
			
		||||
            memberAvatar  = v.findViewById(R.id.memberAvatar);
 | 
			
		||||
            memberName  = v.findViewById(R.id.memberName);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public TeamMembersByOrgAdapter(Context mCtx, List<UserInfo> membersListMain) {
 | 
			
		||||
        this.mCtx = mCtx;
 | 
			
		||||
        this.teamMembersList = membersListMain;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getCount() {
 | 
			
		||||
        return teamMembersList.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Object getItem(int position) {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public long getItemId(int position) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressLint("InflateParams")
 | 
			
		||||
    @Override
 | 
			
		||||
    public View getView(int position, View finalView, ViewGroup parent) {
 | 
			
		||||
 | 
			
		||||
        TeamMembersByOrgAdapter.ViewHolder viewHolder = null;
 | 
			
		||||
 | 
			
		||||
        if (finalView == null) {
 | 
			
		||||
            finalView = LayoutInflater.from(mCtx).inflate(R.layout.members_by_team_by_org_list, null);
 | 
			
		||||
            viewHolder = new TeamMembersByOrgAdapter.ViewHolder(finalView);
 | 
			
		||||
            finalView.setTag(viewHolder);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            viewHolder = (TeamMembersByOrgAdapter.ViewHolder) finalView.getTag();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        initData(viewHolder, position);
 | 
			
		||||
        return finalView;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void initData(TeamMembersByOrgAdapter.ViewHolder viewHolder, int position) {
 | 
			
		||||
 | 
			
		||||
        UserInfo currentItem = teamMembersList.get(position);
 | 
			
		||||
        Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(viewHolder.memberAvatar);
 | 
			
		||||
 | 
			
		||||
        if(!currentItem.getFullname().equals("")) {
 | 
			
		||||
            viewHolder.memberName.setText(currentItem.getFullname());
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            viewHolder.memberName.setText(currentItem.getLogin());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,133 @@
 | 
			
		||||
package org.mian.gitnex.adapters;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.Filter;
 | 
			
		||||
import android.widget.Filterable;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.activities.OrgTeamMembersActivity;
 | 
			
		||||
import org.mian.gitnex.models.Teams;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class TeamsByOrgAdapter extends RecyclerView.Adapter<TeamsByOrgAdapter.OrgTeamsViewHolder> implements Filterable {
 | 
			
		||||
 | 
			
		||||
    private List<Teams> teamList;
 | 
			
		||||
    private Context mCtx;
 | 
			
		||||
    private List<Teams> teamListFull;
 | 
			
		||||
 | 
			
		||||
    static class OrgTeamsViewHolder extends RecyclerView.ViewHolder {
 | 
			
		||||
 | 
			
		||||
        private TextView teamTitle;
 | 
			
		||||
        private TextView teamId;
 | 
			
		||||
        private TextView teamDescription;
 | 
			
		||||
        private TextView teamPermission;
 | 
			
		||||
 | 
			
		||||
        private OrgTeamsViewHolder(View itemView) {
 | 
			
		||||
            super(itemView);
 | 
			
		||||
            teamTitle = itemView.findViewById(R.id.teamTitle);
 | 
			
		||||
            teamId = itemView.findViewById(R.id.teamId);
 | 
			
		||||
            teamDescription = itemView.findViewById(R.id.teamDescription);
 | 
			
		||||
            teamPermission = itemView.findViewById(R.id.teamPermission);
 | 
			
		||||
 | 
			
		||||
            itemView.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
                    Context context = v.getContext();
 | 
			
		||||
 | 
			
		||||
                    Intent intent = new Intent(context, OrgTeamMembersActivity.class);
 | 
			
		||||
                    intent.putExtra("teamTitle", teamTitle.getText().toString());
 | 
			
		||||
                    intent.putExtra("teamId", teamId.getText().toString());
 | 
			
		||||
                    context.startActivity(intent);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public TeamsByOrgAdapter(Context mCtx, List<Teams> teamListMain) {
 | 
			
		||||
        this.mCtx = mCtx;
 | 
			
		||||
        this.teamList = teamListMain;
 | 
			
		||||
        teamListFull = new ArrayList<>(teamList);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
    @Override
 | 
			
		||||
    public TeamsByOrgAdapter.OrgTeamsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
 | 
			
		||||
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.teams_by_org_list, parent, false);
 | 
			
		||||
        return new TeamsByOrgAdapter.OrgTeamsViewHolder(v);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onBindViewHolder(@NonNull TeamsByOrgAdapter.OrgTeamsViewHolder holder, int position) {
 | 
			
		||||
 | 
			
		||||
        Teams currentItem = teamList.get(position);
 | 
			
		||||
        holder.teamId.setText(String.valueOf(currentItem.getId()));
 | 
			
		||||
        holder.teamTitle.setText(currentItem.getName());
 | 
			
		||||
        if (!currentItem.getDescription().equals("")) {
 | 
			
		||||
            holder.teamDescription.setVisibility(View.VISIBLE);
 | 
			
		||||
            holder.teamDescription.setText(currentItem.getDescription());
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            holder.teamDescription.setVisibility(View.GONE);
 | 
			
		||||
            holder.teamDescription.setText("");
 | 
			
		||||
        }
 | 
			
		||||
        holder.teamPermission.setText(mCtx.getResources().getString(R.string.teamPermission, currentItem.getPermission()));
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getItemCount() {
 | 
			
		||||
        return teamList.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Filter getFilter() {
 | 
			
		||||
        return orgTeamsFilter;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Filter orgTeamsFilter = new Filter() {
 | 
			
		||||
        @Override
 | 
			
		||||
        protected FilterResults performFiltering(CharSequence constraint) {
 | 
			
		||||
            List<Teams> filteredList = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
            if (constraint == null || constraint.length() == 0) {
 | 
			
		||||
                filteredList.addAll(teamListFull);
 | 
			
		||||
            } else {
 | 
			
		||||
                String filterPattern = constraint.toString().toLowerCase().trim();
 | 
			
		||||
 | 
			
		||||
                for (Teams item : teamListFull) {
 | 
			
		||||
                    if (item.getName().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) {
 | 
			
		||||
                        filteredList.add(item);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            FilterResults results = new FilterResults();
 | 
			
		||||
            results.values = filteredList;
 | 
			
		||||
 | 
			
		||||
            return results;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        protected void publishResults(CharSequence constraint, FilterResults results) {
 | 
			
		||||
            teamList.clear();
 | 
			
		||||
            teamList.addAll((List) results.values);
 | 
			
		||||
            notifyDataSetChanged();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,207 @@
 | 
			
		||||
package org.mian.gitnex.adapters;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.DialogInterface;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.ListView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import com.squareup.picasso.Picasso;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.actions.CollaboratorActions;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.helpers.AlertDialogs;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.helpers.RoundedTransformation;
 | 
			
		||||
import org.mian.gitnex.models.Collaborators;
 | 
			
		||||
import org.mian.gitnex.models.UserInfo;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.app.AlertDialog;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import retrofit2.Call;
 | 
			
		||||
import retrofit2.Callback;
 | 
			
		||||
import retrofit2.Response;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class UserSearchAdapter extends RecyclerView.Adapter<UserSearchAdapter.UserSearchViewHolder> {
 | 
			
		||||
 | 
			
		||||
    private List<UserInfo> usersSearchList;
 | 
			
		||||
    private Context mCtx;
 | 
			
		||||
 | 
			
		||||
    public UserSearchAdapter(List<UserInfo> dataList, Context mCtx) {
 | 
			
		||||
        this.mCtx = mCtx;
 | 
			
		||||
        this.usersSearchList = dataList;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static class UserSearchViewHolder extends RecyclerView.ViewHolder {
 | 
			
		||||
 | 
			
		||||
        private ImageView userAvatar;
 | 
			
		||||
        private TextView userFullName;
 | 
			
		||||
        private TextView userName;
 | 
			
		||||
        private TextView userNameMain;
 | 
			
		||||
        private ImageView addCollaboratorButtonAdd;
 | 
			
		||||
        private ImageView addCollaboratorButtonRemove;
 | 
			
		||||
 | 
			
		||||
        private String[] permissionList = {"Read", "Write", "Admin"};
 | 
			
		||||
        final private int permissionSelectedChoice = 0;
 | 
			
		||||
 | 
			
		||||
        private UserSearchViewHolder(View itemView) {
 | 
			
		||||
            super(itemView);
 | 
			
		||||
            userAvatar = itemView.findViewById(R.id.userAvatar);
 | 
			
		||||
            userFullName = itemView.findViewById(R.id.userFullName);
 | 
			
		||||
            userName = itemView.findViewById(R.id.userName);
 | 
			
		||||
            userNameMain = itemView.findViewById(R.id.userNameMain);
 | 
			
		||||
            addCollaboratorButtonAdd = itemView.findViewById(R.id.addCollaboratorButtonAdd);
 | 
			
		||||
            addCollaboratorButtonRemove = itemView.findViewById(R.id.addCollaboratorButtonRemove);
 | 
			
		||||
 | 
			
		||||
            addCollaboratorButtonAdd.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
                    final Context context = v.getContext();
 | 
			
		||||
 | 
			
		||||
                    AlertDialog.Builder pBuilder = new AlertDialog.Builder(context, R.style.confirmDialog);
 | 
			
		||||
 | 
			
		||||
                    pBuilder.setTitle(R.string.newTeamPermission);
 | 
			
		||||
                    pBuilder.setSingleChoiceItems(permissionList, permissionSelectedChoice, new DialogInterface.OnClickListener() {
 | 
			
		||||
                            @Override
 | 
			
		||||
                            public void onClick(DialogInterface dialogInterface, int i) {
 | 
			
		||||
 | 
			
		||||
                            }
 | 
			
		||||
                        })
 | 
			
		||||
                            .setCancelable(false)
 | 
			
		||||
                            .setNegativeButton(R.string.cancelButton, null)
 | 
			
		||||
                            .setPositiveButton(R.string.addButton, new DialogInterface.OnClickListener() {
 | 
			
		||||
 | 
			
		||||
                                @Override
 | 
			
		||||
                                public void onClick(DialogInterface dialog, int which) {
 | 
			
		||||
 | 
			
		||||
                                    ListView lw = ((AlertDialog)dialog).getListView();
 | 
			
		||||
                                    Object checkedItem = lw.getAdapter().getItem(lw.getCheckedItemPosition());
 | 
			
		||||
 | 
			
		||||
                                    CollaboratorActions.addCollaborator(context,  String.valueOf(checkedItem).toLowerCase(), userNameMain.getText().toString());
 | 
			
		||||
 | 
			
		||||
                                }
 | 
			
		||||
                            });
 | 
			
		||||
 | 
			
		||||
                    AlertDialog pDialog = pBuilder.create();
 | 
			
		||||
                    pDialog.show();
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            addCollaboratorButtonRemove.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
                    Context context = v.getContext();
 | 
			
		||||
 | 
			
		||||
                    AlertDialogs.collaboratorRemoveDialog(context, userNameMain.getText().toString(),
 | 
			
		||||
                            context.getResources().getString(R.string.removeCollaboratorTitle),
 | 
			
		||||
                            context.getResources().getString(R.string.removeCollaboratorMessage),
 | 
			
		||||
                            context.getResources().getString(R.string.removeButton),
 | 
			
		||||
                            context.getResources().getString(R.string.cancelButton), "fa");
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
    @Override
 | 
			
		||||
    public UserSearchAdapter.UserSearchViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
 | 
			
		||||
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.collaborators_list_search, parent, false);
 | 
			
		||||
        return new UserSearchAdapter.UserSearchViewHolder(v);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onBindViewHolder(@NonNull final UserSearchAdapter.UserSearchViewHolder holder, int position) {
 | 
			
		||||
 | 
			
		||||
        final UserInfo currentItem = usersSearchList.get(position);
 | 
			
		||||
 | 
			
		||||
        holder.userNameMain.setText(currentItem.getUsername());
 | 
			
		||||
 | 
			
		||||
        if (!currentItem.getFullname().equals("")) {
 | 
			
		||||
            holder.userFullName.setText(currentItem.getFullname());
 | 
			
		||||
            holder.userName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            holder.userFullName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
 | 
			
		||||
            holder.userName.setText(mCtx.getResources().getString(R.string.usernameWithAt, currentItem.getUsername()));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!currentItem.getAvatar().equals("")) {
 | 
			
		||||
            Picasso.get().load(currentItem.getAvatar()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(holder.userAvatar);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(getItemCount() > 0) {
 | 
			
		||||
 | 
			
		||||
            TinyDB tinyDb = new TinyDB(mCtx);
 | 
			
		||||
            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");
 | 
			
		||||
 | 
			
		||||
            Call<Collaborators> call = RetrofitClient
 | 
			
		||||
                    .getInstance(instanceUrl)
 | 
			
		||||
                    .getApiInterface()
 | 
			
		||||
                    .checkRepoCollaborator(Authorization.returnAuthentication(mCtx, loginUid, instanceToken), repoOwner, repoName, currentItem.getUsername());
 | 
			
		||||
 | 
			
		||||
            call.enqueue(new Callback<Collaborators>() {
 | 
			
		||||
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onResponse(@NonNull Call<Collaborators> call, @NonNull Response<Collaborators> response) {
 | 
			
		||||
 | 
			
		||||
                    if(response.code() == 204) {
 | 
			
		||||
                        if(!currentItem.getUsername().equals(loginUid) && !currentItem.getUsername().equals(repoOwner)) {
 | 
			
		||||
                            holder.addCollaboratorButtonRemove.setVisibility(View.VISIBLE);
 | 
			
		||||
                        }
 | 
			
		||||
                        else {
 | 
			
		||||
                            holder.addCollaboratorButtonRemove.setVisibility(View.GONE);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    else if(response.code() == 404) {
 | 
			
		||||
                        if(!currentItem.getUsername().equals(loginUid) && !currentItem.getUsername().equals(repoOwner)) {
 | 
			
		||||
                            holder.addCollaboratorButtonAdd.setVisibility(View.VISIBLE);
 | 
			
		||||
                        }
 | 
			
		||||
                        else {
 | 
			
		||||
                            holder.addCollaboratorButtonAdd.setVisibility(View.GONE);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    else {
 | 
			
		||||
                        holder.addCollaboratorButtonRemove.setVisibility(View.GONE);
 | 
			
		||||
                        holder.addCollaboratorButtonAdd.setVisibility(View.GONE);
 | 
			
		||||
                        Log.i("onResponse", String.valueOf(response.code()));
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onFailure(@NonNull Call<Collaborators> call, @NonNull Throwable t) {
 | 
			
		||||
                    Log.i("onFailure", t.getMessage());
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getItemCount() {
 | 
			
		||||
        return usersSearchList.size();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										33
									
								
								app/src/main/java/org/mian/gitnex/clients/IssuesService.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								app/src/main/java/org/mian/gitnex/clients/IssuesService.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
package org.mian.gitnex.clients;
 | 
			
		||||
 | 
			
		||||
import okhttp3.OkHttpClient;
 | 
			
		||||
import okhttp3.logging.HttpLoggingInterceptor;
 | 
			
		||||
import retrofit2.Retrofit;
 | 
			
		||||
import retrofit2.converter.gson.GsonConverterFactory;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class IssuesService {
 | 
			
		||||
 | 
			
		||||
    public static <S> S createService(Class<S> serviceClass, String instanceURL) {
 | 
			
		||||
 | 
			
		||||
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
 | 
			
		||||
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
 | 
			
		||||
 | 
			
		||||
        OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
 | 
			
		||||
 | 
			
		||||
        httpClient.addInterceptor(logging);
 | 
			
		||||
 | 
			
		||||
        Retrofit retrofit = new Retrofit.Builder()
 | 
			
		||||
                .baseUrl(instanceURL)
 | 
			
		||||
                .addConverterFactory(GsonConverterFactory.create())
 | 
			
		||||
                //.client(httpClient.build())
 | 
			
		||||
                .build();
 | 
			
		||||
 | 
			
		||||
        return retrofit.create(serviceClass);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,44 @@
 | 
			
		||||
package org.mian.gitnex.clients;
 | 
			
		||||
 | 
			
		||||
import org.mian.gitnex.interfaces.ApiInterface;
 | 
			
		||||
import okhttp3.OkHttpClient;
 | 
			
		||||
import okhttp3.logging.HttpLoggingInterceptor;
 | 
			
		||||
import retrofit2.Retrofit;
 | 
			
		||||
import retrofit2.converter.gson.GsonConverterFactory;
 | 
			
		||||
import retrofit2.converter.scalars.ScalarsConverterFactory;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class RetrofitClient {
 | 
			
		||||
 | 
			
		||||
    private Retrofit retrofit;
 | 
			
		||||
 | 
			
		||||
    private RetrofitClient(String instanceUrl) {
 | 
			
		||||
 | 
			
		||||
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
 | 
			
		||||
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
 | 
			
		||||
 | 
			
		||||
        OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
 | 
			
		||||
 | 
			
		||||
        httpClient.addInterceptor(logging);
 | 
			
		||||
 | 
			
		||||
        retrofit = new Retrofit.Builder()
 | 
			
		||||
                .baseUrl(instanceUrl)
 | 
			
		||||
                .addConverterFactory(ScalarsConverterFactory.create())
 | 
			
		||||
                .addConverterFactory(GsonConverterFactory.create())
 | 
			
		||||
                //.client(httpClient.build())
 | 
			
		||||
                .build();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static synchronized RetrofitClient getInstance(String instanceUrl) {
 | 
			
		||||
        return new RetrofitClient(instanceUrl);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ApiInterface getApiInterface() {
 | 
			
		||||
        return retrofit.create(ApiInterface.class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										188
									
								
								app/src/main/java/org/mian/gitnex/fragments/AboutFragment.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								app/src/main/java/org/mian/gitnex/fragments/AboutFragment.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,188 @@
 | 
			
		||||
package org.mian.gitnex.fragments;
 | 
			
		||||
 | 
			
		||||
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 android.util.Log;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.Button;
 | 
			
		||||
import android.widget.LinearLayout;
 | 
			
		||||
import android.widget.ProgressBar;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.activities.CreditsActivity;
 | 
			
		||||
import org.mian.gitnex.activities.MainActivity;
 | 
			
		||||
import org.mian.gitnex.activities.SponsorsActivity;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.models.GiteaVersion;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import retrofit2.Response;
 | 
			
		||||
import retrofit2.Call;
 | 
			
		||||
import retrofit2.Callback;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class AboutFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private TextView viewTextGiteaVersion;
 | 
			
		||||
    private ProgressBar mProgressBar;
 | 
			
		||||
    private LinearLayout pageContent;
 | 
			
		||||
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        View v = inflater.inflate(R.layout.fragment_about, container, false);
 | 
			
		||||
        ((MainActivity) Objects.requireNonNull(getActivity())).setActionBarTitle(getResources().getString(R.string.pageTitleAbout));
 | 
			
		||||
 | 
			
		||||
        TinyDB tinyDb = new TinyDB(getContext());
 | 
			
		||||
        String instanceUrl = tinyDb.getString("instanceUrl");
 | 
			
		||||
 | 
			
		||||
        final TextView appVerBuild;
 | 
			
		||||
        final TextView donationLink;
 | 
			
		||||
        final TextView donationLinkPatreon;
 | 
			
		||||
        final TextView creditsButton;
 | 
			
		||||
        final TextView sponsorsButton;
 | 
			
		||||
        final TextView appWebsite;
 | 
			
		||||
        final TextView appRepo;
 | 
			
		||||
 | 
			
		||||
        pageContent = v.findViewById(R.id.aboutFrame);
 | 
			
		||||
        pageContent.setVisibility(View.GONE);
 | 
			
		||||
 | 
			
		||||
        mProgressBar = v.findViewById(R.id.progress_bar);
 | 
			
		||||
 | 
			
		||||
        appVerBuild = v.findViewById(R.id.appVerBuild);
 | 
			
		||||
        viewTextGiteaVersion = v.findViewById(R.id.giteaVersion);
 | 
			
		||||
        creditsButton = v.findViewById(R.id.creditsButton);
 | 
			
		||||
        donationLink = v.findViewById(R.id.donationLink);
 | 
			
		||||
        donationLinkPatreon = v.findViewById(R.id.donationLinkPatreon);
 | 
			
		||||
        sponsorsButton = v.findViewById(R.id.sponsorsButton);
 | 
			
		||||
        appWebsite = v.findViewById(R.id.appWebsite);
 | 
			
		||||
        appRepo = v.findViewById(R.id.appRepo);
 | 
			
		||||
 | 
			
		||||
        appVerBuild.setText(getString(R.string.appVerBuild, AppUtil.getAppVersion(Objects.requireNonNull(getContext())), AppUtil.getAppBuildNo(getContext())));
 | 
			
		||||
 | 
			
		||||
        donationLink.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            public void onClick(View v) {
 | 
			
		||||
                Intent intent = new Intent();
 | 
			
		||||
                intent.setAction(Intent.ACTION_VIEW);
 | 
			
		||||
                intent.addCategory(Intent.CATEGORY_BROWSABLE);
 | 
			
		||||
                intent.setData(Uri.parse(getResources().getString(R.string.supportLink)));
 | 
			
		||||
                startActivity(intent);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        donationLinkPatreon.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            public void onClick(View v) {
 | 
			
		||||
                Intent intent = new Intent();
 | 
			
		||||
                intent.setAction(Intent.ACTION_VIEW);
 | 
			
		||||
                intent.addCategory(Intent.CATEGORY_BROWSABLE);
 | 
			
		||||
                intent.setData(Uri.parse(getResources().getString(R.string.supportLinkPatreon)));
 | 
			
		||||
                startActivity(intent);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        appWebsite.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            public void onClick(View v) {
 | 
			
		||||
                Intent intent = new Intent();
 | 
			
		||||
                intent.setAction(Intent.ACTION_VIEW);
 | 
			
		||||
                intent.addCategory(Intent.CATEGORY_BROWSABLE);
 | 
			
		||||
                intent.setData(Uri.parse(getResources().getString(R.string.appWebsiteLink)));
 | 
			
		||||
                startActivity(intent);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        appRepo.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            public void onClick(View v) {
 | 
			
		||||
                Intent intent = new Intent();
 | 
			
		||||
                intent.setAction(Intent.ACTION_VIEW);
 | 
			
		||||
                intent.addCategory(Intent.CATEGORY_BROWSABLE);
 | 
			
		||||
                intent.setData(Uri.parse(getResources().getString(R.string.appRepoLink)));
 | 
			
		||||
                startActivity(intent);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        creditsButton.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            public void onClick(View v) {
 | 
			
		||||
                startActivity(new Intent(getContext(), CreditsActivity.class));
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        sponsorsButton.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            public void onClick(View v) {
 | 
			
		||||
                startActivity(new Intent(getContext(), SponsorsActivity.class));
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(getContext());
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
 | 
			
		||||
            mProgressBar.setVisibility(View.GONE);
 | 
			
		||||
            pageContent.setVisibility(View.VISIBLE);
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
 | 
			
		||||
            giteaVer(instanceUrl);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void giteaVer(String instanceUrl) {
 | 
			
		||||
 | 
			
		||||
        TinyDB tinyDb = new TinyDB(getContext());
 | 
			
		||||
        final String loginUid = tinyDb.getString("loginUid");
 | 
			
		||||
        final String instanceToken = "token " + tinyDb.getString(loginUid + "-token");
 | 
			
		||||
 | 
			
		||||
        Call<GiteaVersion> call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .getGiteaVersion(Authorization.returnAuthentication(getContext(), loginUid, instanceToken));
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<GiteaVersion>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<GiteaVersion> call, @NonNull Response<GiteaVersion> response) {
 | 
			
		||||
 | 
			
		||||
                if (response.isSuccessful()) {
 | 
			
		||||
                    if (response.code() == 200) {
 | 
			
		||||
 | 
			
		||||
                        GiteaVersion version = response.body();
 | 
			
		||||
                        assert version != null;
 | 
			
		||||
                        String commit = getResources().getString(R.string.commitPage) + version.getVersion();
 | 
			
		||||
                        viewTextGiteaVersion.setText(commit);
 | 
			
		||||
                        mProgressBar.setVisibility(View.GONE);
 | 
			
		||||
                        pageContent.setVisibility(View.VISIBLE);
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
 | 
			
		||||
                    String commit = getResources().getString(R.string.commitPage);
 | 
			
		||||
                    viewTextGiteaVersion.setText(commit);
 | 
			
		||||
                    mProgressBar.setVisibility(View.GONE);
 | 
			
		||||
                    pageContent.setVisibility(View.VISIBLE);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<GiteaVersion> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,56 @@
 | 
			
		||||
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 AdminUsersBottomSheetFragment extends BottomSheetDialogFragment {
 | 
			
		||||
 | 
			
		||||
    private AdminUsersBottomSheetFragment.BottomSheetListener bmListener;
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
 | 
			
		||||
        View v = inflater.inflate(R.layout.admin_users_bottom_sheet_layout, container, false);
 | 
			
		||||
 | 
			
		||||
        TextView createNewUser = v.findViewById(R.id.createNewUser);
 | 
			
		||||
 | 
			
		||||
        createNewUser.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View v) {
 | 
			
		||||
                bmListener.onButtonClicked("newUser");
 | 
			
		||||
                dismiss();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public interface BottomSheetListener {
 | 
			
		||||
        void onButtonClicked(String text);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onAttach(@NonNull Context context) {
 | 
			
		||||
        super.onAttach(context);
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            bmListener = (AdminUsersBottomSheetFragment.BottomSheetListener) context;
 | 
			
		||||
        } catch (ClassCastException e) {
 | 
			
		||||
            throw new ClassCastException(context.toString()
 | 
			
		||||
                    + " must implement BottomSheetListener");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,149 @@
 | 
			
		||||
package org.mian.gitnex.fragments;
 | 
			
		||||
 | 
			
		||||
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.ViewModelProviders;
 | 
			
		||||
import androidx.recyclerview.widget.DividerItemDecoration;
 | 
			
		||||
import androidx.recyclerview.widget.LinearLayoutManager;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.ProgressBar;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.adapters.BranchesAdapter;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.models.Branches;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import org.mian.gitnex.viewmodels.BranchesViewModel;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class BranchesFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private ProgressBar mProgressBar;
 | 
			
		||||
    private BranchesAdapter adapter;
 | 
			
		||||
    private RecyclerView mRecyclerView;
 | 
			
		||||
    private TextView noDataBranches;
 | 
			
		||||
    private static String repoNameF = "param2";
 | 
			
		||||
    private static String repoOwnerF = "param1";
 | 
			
		||||
 | 
			
		||||
    private String repoName;
 | 
			
		||||
    private String repoOwner;
 | 
			
		||||
 | 
			
		||||
    private OnFragmentInteractionListener mListener;
 | 
			
		||||
 | 
			
		||||
    public BranchesFragment() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static BranchesFragment newInstance(String param1, String param2) {
 | 
			
		||||
        BranchesFragment fragment = new BranchesFragment();
 | 
			
		||||
        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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
 | 
			
		||||
                             Bundle savedInstanceState) {
 | 
			
		||||
        View v = inflater.inflate(R.layout.fragment_branches, container, false);
 | 
			
		||||
 | 
			
		||||
        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");
 | 
			
		||||
        final String locale = tinyDb.getString("locale");
 | 
			
		||||
        final String timeFormat = tinyDb.getString("dateFormat");
 | 
			
		||||
        noDataBranches = v.findViewById(R.id.noDataBranches);
 | 
			
		||||
 | 
			
		||||
        final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh);
 | 
			
		||||
 | 
			
		||||
        mRecyclerView = v.findViewById(R.id.recyclerView);
 | 
			
		||||
        mRecyclerView.setHasFixedSize(true);
 | 
			
		||||
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
 | 
			
		||||
 | 
			
		||||
        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
 | 
			
		||||
                DividerItemDecoration.VERTICAL);
 | 
			
		||||
        mRecyclerView.addItemDecoration(dividerItemDecoration);
 | 
			
		||||
 | 
			
		||||
        mProgressBar = v.findViewById(R.id.progress_bar);
 | 
			
		||||
 | 
			
		||||
        swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onRefresh() {
 | 
			
		||||
                new Handler().postDelayed(new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        swipeRefresh.setRefreshing(false);
 | 
			
		||||
                        BranchesViewModel.loadBranchesList(instanceUrl, instanceToken, repoOwner, repoName);
 | 
			
		||||
                    }
 | 
			
		||||
                }, 50);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName);
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) {
 | 
			
		||||
 | 
			
		||||
        BranchesViewModel branchesModel = ViewModelProviders.of(this).get(BranchesViewModel.class);
 | 
			
		||||
 | 
			
		||||
        branchesModel.getBranchesList(instanceUrl, instanceToken, owner, repo).observe(this, new Observer<List<Branches>>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onChanged(@Nullable List<Branches> branchesListMain) {
 | 
			
		||||
                adapter = new BranchesAdapter(getContext(), branchesListMain);
 | 
			
		||||
                if(adapter.getItemCount() > 0) {
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noDataBranches.setVisibility(View.GONE);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    adapter.notifyDataSetChanged();
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noDataBranches.setVisibility(View.VISIBLE);
 | 
			
		||||
                }
 | 
			
		||||
                mProgressBar.setVisibility(View.GONE);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,290 @@
 | 
			
		||||
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.adapters.ClosedIssuesAdapter;
 | 
			
		||||
import org.mian.gitnex.clients.IssuesService;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.helpers.Toasty;
 | 
			
		||||
import org.mian.gitnex.interfaces.ApiInterface;
 | 
			
		||||
import org.mian.gitnex.models.Issues;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
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 retrofit2.Call;
 | 
			
		||||
import retrofit2.Callback;
 | 
			
		||||
import retrofit2.Response;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class ClosedIssuesFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private ProgressBar mProgressBarClosed;
 | 
			
		||||
    private RecyclerView recyclerViewClosed;
 | 
			
		||||
    private List<Issues> issuesListClosed;
 | 
			
		||||
    private ClosedIssuesAdapter adapterClosed;
 | 
			
		||||
    private ApiInterface apiClosed;
 | 
			
		||||
    private String TAG = "closedIssuesListFragment - ";
 | 
			
		||||
    private Context context;
 | 
			
		||||
    private int pageSize = 1;
 | 
			
		||||
    private TextView noDataIssuesClosed;
 | 
			
		||||
    private String issueState = "closed";
 | 
			
		||||
 | 
			
		||||
    @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());
 | 
			
		||||
        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");
 | 
			
		||||
 | 
			
		||||
        final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefreshClosed);
 | 
			
		||||
 | 
			
		||||
        context = getContext();
 | 
			
		||||
        recyclerViewClosed = v.findViewById(R.id.recyclerViewClosed);
 | 
			
		||||
        issuesListClosed = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
        mProgressBarClosed = v.findViewById(R.id.progress_barClosed);
 | 
			
		||||
        noDataIssuesClosed = v.findViewById(R.id.noDataIssuesClosed);
 | 
			
		||||
 | 
			
		||||
        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, issueState);
 | 
			
		||||
                        adapterClosed.notifyDataChanged();
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                }, 200);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        adapterClosed = new ClosedIssuesAdapter(getContext(), issuesListClosed);
 | 
			
		||||
        adapterClosed.setLoadMoreListener(new ClosedIssuesAdapter.OnLoadMoreListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onLoadMore() {
 | 
			
		||||
 | 
			
		||||
                recyclerViewClosed.post(new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        if(issuesListClosed.size() == 10 || pageSize == 10) {
 | 
			
		||||
 | 
			
		||||
                            int page = (issuesListClosed.size() + 10) / 10;
 | 
			
		||||
                            loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, issueState);
 | 
			
		||||
 | 
			
		||||
                        }
 | 
			
		||||
                        /*else {
 | 
			
		||||
 | 
			
		||||
                            Toasty.info(context, getString(R.string.noMoreData));
 | 
			
		||||
 | 
			
		||||
                        }*/
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerViewClosed.getContext(),
 | 
			
		||||
                DividerItemDecoration.VERTICAL);
 | 
			
		||||
        recyclerViewClosed.setHasFixedSize(true);
 | 
			
		||||
        recyclerViewClosed.addItemDecoration(dividerItemDecoration);
 | 
			
		||||
        recyclerViewClosed.setLayoutManager(new LinearLayoutManager(context));
 | 
			
		||||
        recyclerViewClosed.setAdapter(adapterClosed);
 | 
			
		||||
 | 
			
		||||
        apiClosed = IssuesService.createService(ApiInterface.class, instanceUrl);
 | 
			
		||||
        loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, issueState);
 | 
			
		||||
 | 
			
		||||
        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("resumeClosedIssues")) {
 | 
			
		||||
 | 
			
		||||
            loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, issueState);
 | 
			
		||||
            tinyDb.putBoolean("resumeClosedIssues", false);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void loadInitial(String token, String repoOwner, String repoName, String issueState) {
 | 
			
		||||
 | 
			
		||||
        Call<List<Issues>> call = apiClosed.getClosedIssues(token, repoOwner, repoName,  1, issueState);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<List<Issues>>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.isSuccessful()) {
 | 
			
		||||
 | 
			
		||||
                    assert response.body() != null;
 | 
			
		||||
                    if(response.body().size() > 0) {
 | 
			
		||||
 | 
			
		||||
                        issuesListClosed.clear();
 | 
			
		||||
                        issuesListClosed.addAll(response.body());
 | 
			
		||||
                        adapterClosed.notifyDataChanged();
 | 
			
		||||
                        noDataIssuesClosed.setVisibility(View.GONE);
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                    else {
 | 
			
		||||
                        issuesListClosed.clear();
 | 
			
		||||
                        adapterClosed.notifyDataChanged();
 | 
			
		||||
                        noDataIssuesClosed.setVisibility(View.VISIBLE);
 | 
			
		||||
                    }
 | 
			
		||||
                    mProgressBarClosed.setVisibility(View.GONE);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    Log.e(TAG, String.valueOf(response.code()));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<List<Issues>> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e(TAG, t.getMessage());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void loadMore(String token, String repoOwner, String repoName, int page, String issueState){
 | 
			
		||||
 | 
			
		||||
        //add loading progress view
 | 
			
		||||
        issuesListClosed.add(new Issues("load"));
 | 
			
		||||
        adapterClosed.notifyItemInserted((issuesListClosed.size() - 1));
 | 
			
		||||
 | 
			
		||||
        Call<List<Issues>> call = apiClosed.getClosedIssues(token, repoOwner, repoName, page, issueState);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<List<Issues>>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.isSuccessful()){
 | 
			
		||||
 | 
			
		||||
                    //remove loading view
 | 
			
		||||
                    issuesListClosed.remove(issuesListClosed.size()-1);
 | 
			
		||||
 | 
			
		||||
                    List<Issues> result = response.body();
 | 
			
		||||
 | 
			
		||||
                    assert result != null;
 | 
			
		||||
                    if(result.size() > 0) {
 | 
			
		||||
 | 
			
		||||
                        pageSize = result.size();
 | 
			
		||||
                        issuesListClosed.addAll(result);
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                    else {
 | 
			
		||||
 | 
			
		||||
                        Toasty.info(context, getString(R.string.noMoreData));
 | 
			
		||||
                        adapterClosed.setMoreDataAvailable(false);
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    adapterClosed.notifyDataChanged();
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
 | 
			
		||||
                    Log.e(TAG, String.valueOf(response.code()));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<List<Issues>> call, @NonNull Throwable t) {
 | 
			
		||||
 | 
			
		||||
                Log.e(TAG, t.getMessage());
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
 | 
			
		||||
 | 
			
		||||
        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);
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public boolean onQueryTextSubmit(String query) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public boolean onQueryTextChange(String newText) {
 | 
			
		||||
 | 
			
		||||
                adapterClosed.getFilter().filter(newText);
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,117 @@
 | 
			
		||||
package org.mian.gitnex.fragments;
 | 
			
		||||
 | 
			
		||||
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.ViewModelProviders;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.GridView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.adapters.CollaboratorsAdapter;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.models.Collaborators;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import org.mian.gitnex.viewmodels.CollaboratorsViewModel;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class CollaboratorsFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private CollaboratorsAdapter adapter;
 | 
			
		||||
    private GridView mGridView;
 | 
			
		||||
    private TextView noDataCollaborators;
 | 
			
		||||
    private static String repoNameF = "param2";
 | 
			
		||||
    private static String repoOwnerF = "param1";
 | 
			
		||||
 | 
			
		||||
    private String repoName;
 | 
			
		||||
    private String repoOwner;
 | 
			
		||||
 | 
			
		||||
    private OnFragmentInteractionListener mListener;
 | 
			
		||||
 | 
			
		||||
    public CollaboratorsFragment() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static CollaboratorsFragment newInstance(String param1, String param2) {
 | 
			
		||||
        CollaboratorsFragment fragment = new CollaboratorsFragment();
 | 
			
		||||
        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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
 | 
			
		||||
                             Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        View v = inflater.inflate(R.layout.fragment_collaborators, container, false);
 | 
			
		||||
        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");
 | 
			
		||||
        noDataCollaborators = v.findViewById(R.id.noDataCollaborators);
 | 
			
		||||
 | 
			
		||||
        mGridView = v.findViewById(R.id.gridView);
 | 
			
		||||
 | 
			
		||||
        fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName);
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) {
 | 
			
		||||
 | 
			
		||||
        CollaboratorsViewModel collaboratorsModel = ViewModelProviders.of(this).get(CollaboratorsViewModel.class);
 | 
			
		||||
 | 
			
		||||
        collaboratorsModel.getCollaboratorsList(instanceUrl, instanceToken, owner, repo).observe(this, new Observer<List<Collaborators>>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onChanged(@Nullable List<Collaborators> collaboratorsListMain) {
 | 
			
		||||
                adapter = new CollaboratorsAdapter(getContext(), collaboratorsListMain);
 | 
			
		||||
                if(adapter.getCount() > 0) {
 | 
			
		||||
                    mGridView.setAdapter(adapter);
 | 
			
		||||
                    noDataCollaborators.setVisibility(View.GONE);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    adapter.notifyDataSetChanged();
 | 
			
		||||
                    mGridView.setAdapter(adapter);
 | 
			
		||||
                    noDataCollaborators.setVisibility(View.VISIBLE);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										289
									
								
								app/src/main/java/org/mian/gitnex/fragments/IssuesFragment.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										289
									
								
								app/src/main/java/org/mian/gitnex/fragments/IssuesFragment.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,289 @@
 | 
			
		||||
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 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 org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.adapters.IssuesAdapter;
 | 
			
		||||
import org.mian.gitnex.clients.IssuesService;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.helpers.Toasty;
 | 
			
		||||
import org.mian.gitnex.interfaces.ApiInterface;
 | 
			
		||||
import org.mian.gitnex.models.Issues;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class IssuesFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private ProgressBar mProgressBar;
 | 
			
		||||
    private RecyclerView recyclerView;
 | 
			
		||||
    private List<Issues> issuesList;
 | 
			
		||||
    private IssuesAdapter adapter;
 | 
			
		||||
    private ApiInterface api;
 | 
			
		||||
    private String TAG = "IssuesListFragment - ";
 | 
			
		||||
    private Context context;
 | 
			
		||||
    private int pageSize = 1;
 | 
			
		||||
    private TextView noDataIssues;
 | 
			
		||||
 | 
			
		||||
    @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());
 | 
			
		||||
        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");
 | 
			
		||||
 | 
			
		||||
        final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh);
 | 
			
		||||
 | 
			
		||||
        context = getContext();
 | 
			
		||||
        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 SwipeRefreshLayout.OnRefreshListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onRefresh() {
 | 
			
		||||
                new Handler().postDelayed(new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
 | 
			
		||||
                        swipeRefresh.setRefreshing(false);
 | 
			
		||||
                        loadInitial(instanceToken, repoOwner, repoName);
 | 
			
		||||
                        adapter.notifyDataChanged();
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                }, 200);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        adapter = new IssuesAdapter(getContext(), issuesList);
 | 
			
		||||
        adapter.setLoadMoreListener(new IssuesAdapter.OnLoadMoreListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onLoadMore() {
 | 
			
		||||
 | 
			
		||||
                recyclerView.post(new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        if(issuesList.size() == 10 || pageSize == 10) {
 | 
			
		||||
 | 
			
		||||
                            int page = (issuesList.size() + 10) / 10;
 | 
			
		||||
                            loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page);
 | 
			
		||||
 | 
			
		||||
                        }
 | 
			
		||||
                        /*else {
 | 
			
		||||
 | 
			
		||||
                            Toasty.info(context, getString(R.string.noMoreData));
 | 
			
		||||
 | 
			
		||||
                        }*/
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
 | 
			
		||||
                DividerItemDecoration.VERTICAL);
 | 
			
		||||
        recyclerView.setHasFixedSize(true);
 | 
			
		||||
        recyclerView.addItemDecoration(dividerItemDecoration);
 | 
			
		||||
        recyclerView.setLayoutManager(new LinearLayoutManager(context));
 | 
			
		||||
        recyclerView.setAdapter(adapter);
 | 
			
		||||
 | 
			
		||||
        api = IssuesService.createService(ApiInterface.class, instanceUrl);
 | 
			
		||||
        loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName);
 | 
			
		||||
 | 
			
		||||
        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);
 | 
			
		||||
            tinyDb.putBoolean("resumeIssues", false);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void loadInitial(String token, String repoOwner, String repoName) {
 | 
			
		||||
 | 
			
		||||
        Call<List<Issues>> call = api.getIssues(token, repoOwner, repoName,  1);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<List<Issues>>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> 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<List<Issues>> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e(TAG, t.getMessage());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void loadMore(String token, String repoOwner, String repoName, int page){
 | 
			
		||||
 | 
			
		||||
        //add loading progress view
 | 
			
		||||
        issuesList.add(new Issues("load"));
 | 
			
		||||
        adapter.notifyItemInserted((issuesList.size() - 1));
 | 
			
		||||
 | 
			
		||||
        Call<List<Issues>> call = api.getIssues(token, repoOwner, repoName, page);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<List<Issues>>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<List<Issues>> call, @NonNull Response<List<Issues>> response) {
 | 
			
		||||
 | 
			
		||||
                if(response.isSuccessful()){
 | 
			
		||||
 | 
			
		||||
                    //remove loading view
 | 
			
		||||
                    issuesList.remove(issuesList.size()-1);
 | 
			
		||||
 | 
			
		||||
                    List<Issues> 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<List<Issues>> call, @NonNull Throwable t) {
 | 
			
		||||
 | 
			
		||||
                Log.e(TAG, t.getMessage());
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
 | 
			
		||||
 | 
			
		||||
        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);
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public boolean onQueryTextSubmit(String query) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public boolean onQueryTextChange(String newText) {
 | 
			
		||||
 | 
			
		||||
                adapter.getFilter().filter(newText);
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										166
									
								
								app/src/main/java/org/mian/gitnex/fragments/LabelsFragment.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								app/src/main/java/org/mian/gitnex/fragments/LabelsFragment.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,166 @@
 | 
			
		||||
package org.mian.gitnex.fragments;
 | 
			
		||||
 | 
			
		||||
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.ViewModelProviders;
 | 
			
		||||
import androidx.recyclerview.widget.DividerItemDecoration;
 | 
			
		||||
import androidx.recyclerview.widget.LinearLayoutManager;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.ProgressBar;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.adapters.LabelsAdapter;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.models.Labels;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import org.mian.gitnex.viewmodels.LabelsViewModel;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class LabelsFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private ProgressBar mProgressBar;
 | 
			
		||||
    private RecyclerView mRecyclerView;
 | 
			
		||||
    private LabelsAdapter adapter;
 | 
			
		||||
    private TextView noData;
 | 
			
		||||
    private static String repoNameF = "param2";
 | 
			
		||||
    private static String repoOwnerF = "param1";
 | 
			
		||||
 | 
			
		||||
    private String repoName;
 | 
			
		||||
    private String repoOwner;
 | 
			
		||||
 | 
			
		||||
    private OnFragmentInteractionListener mListener;
 | 
			
		||||
 | 
			
		||||
    public LabelsFragment() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static LabelsFragment newInstance(String param1, String param2) {
 | 
			
		||||
        LabelsFragment fragment = new LabelsFragment();
 | 
			
		||||
        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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        final View v = inflater.inflate(R.layout.fragment_labels, 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");
 | 
			
		||||
        final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh);
 | 
			
		||||
        noData = v.findViewById(R.id.noData);
 | 
			
		||||
 | 
			
		||||
        mRecyclerView = v.findViewById(R.id.recyclerView);
 | 
			
		||||
        mRecyclerView.setHasFixedSize(true);
 | 
			
		||||
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
 | 
			
		||||
 | 
			
		||||
        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
 | 
			
		||||
                DividerItemDecoration.VERTICAL);
 | 
			
		||||
        mRecyclerView.addItemDecoration(dividerItemDecoration);
 | 
			
		||||
 | 
			
		||||
        mProgressBar = v.findViewById(R.id.progress_bar);
 | 
			
		||||
 | 
			
		||||
        swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onRefresh() {
 | 
			
		||||
                new Handler().postDelayed(new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        swipeRefresh.setRefreshing(false);
 | 
			
		||||
                        LabelsViewModel.loadLabelsList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName);
 | 
			
		||||
                    }
 | 
			
		||||
                }, 200);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName);
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onResume() {
 | 
			
		||||
        super.onResume();
 | 
			
		||||
        final TinyDB tinyDb = new TinyDB(getContext());
 | 
			
		||||
        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("labelsRefresh")) {
 | 
			
		||||
            LabelsViewModel.loadLabelsList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName);
 | 
			
		||||
            tinyDb.putBoolean("labelsRefresh", 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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) {
 | 
			
		||||
 | 
			
		||||
        LabelsViewModel labelsModel = ViewModelProviders.of(this).get(LabelsViewModel.class);
 | 
			
		||||
 | 
			
		||||
        labelsModel.getLabelsList(instanceUrl, instanceToken, owner, repo).observe(this, new Observer<List<Labels>>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onChanged(@Nullable List<Labels> labelsListMain) {
 | 
			
		||||
                adapter = new LabelsAdapter(getContext(), labelsListMain);
 | 
			
		||||
                if(adapter.getItemCount() > 0) {
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noData.setVisibility(View.GONE);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    adapter.notifyDataSetChanged();
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noData.setVisibility(View.VISIBLE);
 | 
			
		||||
                }
 | 
			
		||||
                mProgressBar.setVisibility(View.GONE);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,150 @@
 | 
			
		||||
package org.mian.gitnex.fragments;
 | 
			
		||||
 | 
			
		||||
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.ViewModelProviders;
 | 
			
		||||
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.GridView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.adapters.MembersByOrgAdapter;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.models.UserInfo;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import org.mian.gitnex.viewmodels.MembersByOrgViewModel;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class MembersByOrgFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private RepositoriesByOrgFragment.OnFragmentInteractionListener mListener;
 | 
			
		||||
 | 
			
		||||
    private TextView noDataMembers;
 | 
			
		||||
    private static String orgNameF = "param2";
 | 
			
		||||
    private String orgName;
 | 
			
		||||
    private MembersByOrgAdapter adapter;
 | 
			
		||||
    private GridView mGridView;
 | 
			
		||||
 | 
			
		||||
    public MembersByOrgFragment() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static MembersByOrgFragment newInstance(String param1) {
 | 
			
		||||
        MembersByOrgFragment fragment = new MembersByOrgFragment();
 | 
			
		||||
        Bundle args = new Bundle();
 | 
			
		||||
        args.putString(orgNameF, param1);
 | 
			
		||||
        fragment.setArguments(args);
 | 
			
		||||
        return fragment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        if (getArguments() != null) {
 | 
			
		||||
            orgName = getArguments().getString(orgNameF);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
 | 
			
		||||
                             Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        View v = inflater.inflate(R.layout.fragment_members_by_org, 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");
 | 
			
		||||
        noDataMembers = v.findViewById(R.id.noDataMembers);
 | 
			
		||||
 | 
			
		||||
        mGridView = v.findViewById(R.id.gridView);
 | 
			
		||||
 | 
			
		||||
        fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), orgName);
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void fetchDataAsync(String instanceUrl, String instanceToken, String owner) {
 | 
			
		||||
 | 
			
		||||
        MembersByOrgViewModel membersModel = ViewModelProviders.of(this).get(MembersByOrgViewModel.class);
 | 
			
		||||
 | 
			
		||||
        membersModel.getMembersList(instanceUrl, instanceToken, owner).observe(this, new Observer<List<UserInfo>>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onChanged(@Nullable List<UserInfo> membersListMain) {
 | 
			
		||||
                adapter = new MembersByOrgAdapter(getContext(), membersListMain);
 | 
			
		||||
                if(adapter.getCount() > 0) {
 | 
			
		||||
                    mGridView.setAdapter(adapter);
 | 
			
		||||
                    noDataMembers.setVisibility(View.GONE);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    adapter.notifyDataSetChanged();
 | 
			
		||||
                    mGridView.setAdapter(adapter);
 | 
			
		||||
                    noDataMembers.setVisibility(View.VISIBLE);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
 | 
			
		||||
 | 
			
		||||
        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);
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public boolean onQueryTextSubmit(String query) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public boolean onQueryTextChange(String newText) {
 | 
			
		||||
                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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,205 @@
 | 
			
		||||
package org.mian.gitnex.fragments;
 | 
			
		||||
 | 
			
		||||
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.ViewModelProviders;
 | 
			
		||||
import androidx.recyclerview.widget.DividerItemDecoration;
 | 
			
		||||
import androidx.recyclerview.widget.LinearLayoutManager;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.Menu;
 | 
			
		||||
import android.view.MenuInflater;
 | 
			
		||||
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.adapters.MilestonesAdapter;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.models.Milestones;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import org.mian.gitnex.viewmodels.MilestonesViewModel;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class MilestonesFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private ProgressBar mProgressBar;
 | 
			
		||||
    private MilestonesAdapter adapter;
 | 
			
		||||
    private RecyclerView mRecyclerView;
 | 
			
		||||
    private TextView noDataMilestone;
 | 
			
		||||
    private static String repoNameF = "param2";
 | 
			
		||||
    private static String repoOwnerF = "param1";
 | 
			
		||||
 | 
			
		||||
    private String repoName;
 | 
			
		||||
    private String repoOwner;
 | 
			
		||||
 | 
			
		||||
    private OnFragmentInteractionListener mListener;
 | 
			
		||||
 | 
			
		||||
    public MilestonesFragment() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static MilestonesFragment newInstance(String param1, String param2) {
 | 
			
		||||
        MilestonesFragment fragment = new MilestonesFragment();
 | 
			
		||||
        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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
 | 
			
		||||
                             Bundle savedInstanceState) {
 | 
			
		||||
        final View v = inflater.inflate(R.layout.fragment_milestones, 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");
 | 
			
		||||
        final String locale = tinyDb.getString("locale");
 | 
			
		||||
        final String timeFormat = tinyDb.getString("dateFormat");
 | 
			
		||||
        noDataMilestone = v.findViewById(R.id.noDataMilestone);
 | 
			
		||||
 | 
			
		||||
        final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh);
 | 
			
		||||
 | 
			
		||||
        mRecyclerView = v.findViewById(R.id.recyclerView);
 | 
			
		||||
        mRecyclerView.setHasFixedSize(true);
 | 
			
		||||
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
 | 
			
		||||
 | 
			
		||||
        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
 | 
			
		||||
                DividerItemDecoration.VERTICAL);
 | 
			
		||||
        mRecyclerView.addItemDecoration(dividerItemDecoration);
 | 
			
		||||
 | 
			
		||||
        mProgressBar = v.findViewById(R.id.progress_bar);
 | 
			
		||||
 | 
			
		||||
        swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onRefresh() {
 | 
			
		||||
                new Handler().postDelayed(new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        swipeRefresh.setRefreshing(false);
 | 
			
		||||
                        MilestonesViewModel.loadMilestonesList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName);
 | 
			
		||||
                    }
 | 
			
		||||
                }, 50);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName);
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onResume() {
 | 
			
		||||
        super.onResume();
 | 
			
		||||
        final TinyDB tinyDb = new TinyDB(getContext());
 | 
			
		||||
        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("milestoneCreated")) {
 | 
			
		||||
            MilestonesViewModel.loadMilestonesList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName);
 | 
			
		||||
            tinyDb.putBoolean("milestoneCreated", 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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) {
 | 
			
		||||
 | 
			
		||||
        MilestonesViewModel msModel = ViewModelProviders.of(this).get(MilestonesViewModel.class);
 | 
			
		||||
 | 
			
		||||
        msModel.getMilestonesList(instanceUrl, instanceToken, owner, repo).observe(this, new Observer<List<Milestones>>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onChanged(@Nullable List<Milestones> msListMain) {
 | 
			
		||||
                adapter = new MilestonesAdapter(getContext(), msListMain);
 | 
			
		||||
                if(adapter.getItemCount() > 0) {
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noDataMilestone.setVisibility(View.GONE);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    adapter.notifyDataSetChanged();
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noDataMilestone.setVisibility(View.VISIBLE);
 | 
			
		||||
                }
 | 
			
		||||
                mProgressBar.setVisibility(View.GONE);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
 | 
			
		||||
 | 
			
		||||
        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);
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public boolean onQueryTextSubmit(String query) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public boolean onQueryTextChange(String newText) {
 | 
			
		||||
                adapter.getFilter().filter(newText);
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,241 @@
 | 
			
		||||
package org.mian.gitnex.fragments;
 | 
			
		||||
 | 
			
		||||
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.ViewModelProviders;
 | 
			
		||||
import androidx.recyclerview.widget.DividerItemDecoration;
 | 
			
		||||
import androidx.recyclerview.widget.LinearLayoutManager;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.Menu;
 | 
			
		||||
import android.view.MenuInflater;
 | 
			
		||||
import android.view.MenuItem;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.view.inputmethod.EditorInfo;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.ProgressBar;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.activities.MainActivity;
 | 
			
		||||
import org.mian.gitnex.activities.NewRepoActivity;
 | 
			
		||||
import org.mian.gitnex.adapters.MyReposListAdapter;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.models.UserRepositories;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import org.mian.gitnex.viewmodels.MyRepositoriesViewModel;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class MyRepositoriesFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private static final String ARG_PARAM1 = "param1";
 | 
			
		||||
    private static final String ARG_PARAM2 = "param2";
 | 
			
		||||
    private ProgressBar mProgressBar;
 | 
			
		||||
    private RecyclerView mRecyclerView;
 | 
			
		||||
    private MyReposListAdapter adapter;
 | 
			
		||||
    private ImageView createNewRepo;
 | 
			
		||||
    private TextView noDataMyRepo;
 | 
			
		||||
 | 
			
		||||
    private String mParam1;
 | 
			
		||||
    private String mParam2;
 | 
			
		||||
 | 
			
		||||
    private OnFragmentInteractionListener mListener;
 | 
			
		||||
 | 
			
		||||
    public MyRepositoriesFragment() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static MyRepositoriesFragment newInstance(String param1, String param2) {
 | 
			
		||||
        MyRepositoriesFragment fragment = new MyRepositoriesFragment();
 | 
			
		||||
        Bundle args = new Bundle();
 | 
			
		||||
        args.putString(ARG_PARAM1, param1);
 | 
			
		||||
        args.putString(ARG_PARAM2, param2);
 | 
			
		||||
        fragment.setArguments(args);
 | 
			
		||||
        return fragment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        if (getArguments() != null) {
 | 
			
		||||
            mParam1 = getArguments().getString(ARG_PARAM1);
 | 
			
		||||
            mParam2 = getArguments().getString(ARG_PARAM2);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
 | 
			
		||||
                             Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
 | 
			
		||||
 | 
			
		||||
        final View v = inflater.inflate(R.layout.fragment_my_repositories, container, false);
 | 
			
		||||
        setHasOptionsMenu(true);
 | 
			
		||||
        ((MainActivity) Objects.requireNonNull(getActivity())).setActionBarTitle(getResources().getString(R.string.pageTitleMyRepos));
 | 
			
		||||
 | 
			
		||||
        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");
 | 
			
		||||
 | 
			
		||||
        final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh);
 | 
			
		||||
 | 
			
		||||
        noDataMyRepo = v.findViewById(R.id.noDataMyRepo);
 | 
			
		||||
        mProgressBar = v.findViewById(R.id.progress_bar);
 | 
			
		||||
        mRecyclerView = v.findViewById(R.id.recyclerView);
 | 
			
		||||
        mRecyclerView.setHasFixedSize(true);
 | 
			
		||||
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
 | 
			
		||||
 | 
			
		||||
        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
 | 
			
		||||
                DividerItemDecoration.VERTICAL);
 | 
			
		||||
        mRecyclerView.addItemDecoration(dividerItemDecoration);
 | 
			
		||||
 | 
			
		||||
        createNewRepo = v.findViewById(R.id.addNewRepo);
 | 
			
		||||
 | 
			
		||||
        createNewRepo.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                Intent intent = new Intent(view.getContext(), NewRepoActivity.class);
 | 
			
		||||
                startActivity(intent);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
 | 
			
		||||
                if (dy > 0 && createNewRepo.isShown()) {
 | 
			
		||||
                    createNewRepo.setVisibility(View.GONE);
 | 
			
		||||
                } else if (dy < 0 ) {
 | 
			
		||||
                    createNewRepo.setVisibility(View.VISIBLE);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
 | 
			
		||||
                super.onScrollStateChanged(recyclerView, newState);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if(connToInternet) {
 | 
			
		||||
 | 
			
		||||
            swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onRefresh() {
 | 
			
		||||
                    new Handler().postDelayed(new Runnable() {
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void run() {
 | 
			
		||||
                            swipeRefresh.setRefreshing(false);
 | 
			
		||||
                            MyRepositoriesViewModel.loadMyReposList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), loginUid);
 | 
			
		||||
                        }
 | 
			
		||||
                    }, 50);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), loginUid);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            mProgressBar.setVisibility(View.GONE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onResume() {
 | 
			
		||||
        super.onResume();
 | 
			
		||||
        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");
 | 
			
		||||
 | 
			
		||||
        MyRepositoriesViewModel.loadMyReposList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), loginUid);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void fetchDataAsync(String instanceUrl, String instanceToken, String username) {
 | 
			
		||||
 | 
			
		||||
        MyRepositoriesViewModel myRepoModel = ViewModelProviders.of(this).get(MyRepositoriesViewModel.class);
 | 
			
		||||
 | 
			
		||||
        myRepoModel.getCurrentUserRepositories(instanceUrl, instanceToken, username).observe(this, new Observer<List<UserRepositories>>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onChanged(@Nullable List<UserRepositories> myReposListMain) {
 | 
			
		||||
                adapter = new MyReposListAdapter(getContext(), myReposListMain);
 | 
			
		||||
                if(adapter.getItemCount() > 0) {
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noDataMyRepo.setVisibility(View.GONE);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    adapter.notifyDataSetChanged();
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noDataMyRepo.setVisibility(View.VISIBLE);
 | 
			
		||||
                }
 | 
			
		||||
                mProgressBar.setVisibility(View.GONE);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
 | 
			
		||||
 | 
			
		||||
        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);
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public boolean onQueryTextSubmit(String query) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public boolean onQueryTextChange(String newText) {
 | 
			
		||||
                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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,39 @@
 | 
			
		||||
package org.mian.gitnex.fragments;
 | 
			
		||||
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.activities.AdminGetUsersActivity;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.annotation.Nullable;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class NavSubMenuBottomSheetFragment extends BottomSheetDialogFragment {
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
 | 
			
		||||
        View v = inflater.inflate(R.layout.nav_sub_menu_bottom_sheet_layout, container, false);
 | 
			
		||||
 | 
			
		||||
        TextView adminUsers = v.findViewById(R.id.adminUsers);
 | 
			
		||||
 | 
			
		||||
        adminUsers.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View v) {
 | 
			
		||||
                startActivity(new Intent(getContext(), AdminGetUsersActivity.class));
 | 
			
		||||
                dismiss();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,56 @@
 | 
			
		||||
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 com.google.android.material.bottomsheet.BottomSheetDialogFragment;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.annotation.Nullable;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class OrgBottomSheetFragment extends BottomSheetDialogFragment {
 | 
			
		||||
 | 
			
		||||
    private OrgBottomSheetFragment.BottomSheetListener bmListener;
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
 | 
			
		||||
        View v = inflater.inflate(R.layout.org_bottom_sheet_layout, container, false);
 | 
			
		||||
 | 
			
		||||
        TextView createTeam = v.findViewById(R.id.createTeam);
 | 
			
		||||
 | 
			
		||||
        createTeam.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View v) {
 | 
			
		||||
                bmListener.onButtonClicked("team");
 | 
			
		||||
                dismiss();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public interface BottomSheetListener {
 | 
			
		||||
        void onButtonClicked(String text);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onAttach(@NonNull Context context) {
 | 
			
		||||
        super.onAttach(context);
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            bmListener = (OrgBottomSheetFragment.BottomSheetListener) context;
 | 
			
		||||
        } catch (ClassCastException e) {
 | 
			
		||||
            throw new ClassCastException(context.toString()
 | 
			
		||||
                    + " must implement BottomSheetListener");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,146 @@
 | 
			
		||||
package org.mian.gitnex.fragments;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.fragment.app.Fragment;
 | 
			
		||||
import retrofit2.Call;
 | 
			
		||||
import retrofit2.Callback;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.ProgressBar;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import com.squareup.picasso.Picasso;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.helpers.RoundedTransformation;
 | 
			
		||||
import org.mian.gitnex.models.Organization;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class OrganizationInfoFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private Context ctx = getContext();
 | 
			
		||||
    private ProgressBar mProgressBar;
 | 
			
		||||
    private static String orgNameF = "param1";
 | 
			
		||||
 | 
			
		||||
    private String orgName;
 | 
			
		||||
    private ImageView orgAvatar;
 | 
			
		||||
    private TextView orgDescInfo;
 | 
			
		||||
    private TextView orgWebsiteInfo;
 | 
			
		||||
    private TextView orgLocationInfo;
 | 
			
		||||
 | 
			
		||||
    private RepoInfoFragment.OnFragmentInteractionListener mListener;
 | 
			
		||||
 | 
			
		||||
    public OrganizationInfoFragment() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static OrganizationInfoFragment newInstance(String param1) {
 | 
			
		||||
        OrganizationInfoFragment fragment = new OrganizationInfoFragment();
 | 
			
		||||
        Bundle args = new Bundle();
 | 
			
		||||
        args.putString(orgNameF, param1);
 | 
			
		||||
        fragment.setArguments(args);
 | 
			
		||||
        return fragment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        if (getArguments() != null) {
 | 
			
		||||
            orgName = getArguments().getString(orgNameF);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
 | 
			
		||||
                             Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        View v = inflater.inflate(R.layout.fragment_organization_info, container, false);
 | 
			
		||||
 | 
			
		||||
        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);
 | 
			
		||||
        orgAvatar = v.findViewById(R.id.orgAvatar);
 | 
			
		||||
        TextView orgNameInfo = v.findViewById(R.id.orgNameInfo);
 | 
			
		||||
        orgDescInfo = v.findViewById(R.id.orgDescInfo);
 | 
			
		||||
        orgWebsiteInfo = v.findViewById(R.id.orgWebsiteInfo);
 | 
			
		||||
        orgLocationInfo = v.findViewById(R.id.orgLocationInfo);
 | 
			
		||||
 | 
			
		||||
        orgNameInfo.setText(orgName);
 | 
			
		||||
 | 
			
		||||
        getOrgInfo(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), orgName);
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void getOrgInfo(String instanceUrl, String token, final String owner) {
 | 
			
		||||
 | 
			
		||||
        Call<Organization> call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .getOrganization(token, owner);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<Organization>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<Organization> call, @NonNull retrofit2.Response<Organization> response) {
 | 
			
		||||
 | 
			
		||||
                Organization orgInfo = response.body();
 | 
			
		||||
 | 
			
		||||
                if (response.isSuccessful()) {
 | 
			
		||||
 | 
			
		||||
                    if (response.code() == 200) {
 | 
			
		||||
 | 
			
		||||
                        assert orgInfo != null;
 | 
			
		||||
                        Picasso.get().load(orgInfo.getAvatar_url()).transform(new RoundedTransformation(100, 0)).resize(200, 200).centerCrop().into(orgAvatar);
 | 
			
		||||
                        orgDescInfo.setText(orgInfo.getDescription());
 | 
			
		||||
                        orgWebsiteInfo.setText(orgInfo.getWebsite());
 | 
			
		||||
                        orgLocationInfo.setText(orgInfo.getLocation());
 | 
			
		||||
 | 
			
		||||
                        mProgressBar.setVisibility(View.GONE);
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    Log.e("onFailure", String.valueOf(response.code()));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<Organization> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,196 @@
 | 
			
		||||
package org.mian.gitnex.fragments;
 | 
			
		||||
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.annotation.Nullable;
 | 
			
		||||
import androidx.fragment.app.Fragment;
 | 
			
		||||
import androidx.lifecycle.Observer;
 | 
			
		||||
import androidx.lifecycle.ViewModelProviders;
 | 
			
		||||
import androidx.recyclerview.widget.DividerItemDecoration;
 | 
			
		||||
import androidx.recyclerview.widget.LinearLayoutManager;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.Menu;
 | 
			
		||||
import android.view.MenuInflater;
 | 
			
		||||
import android.view.MenuItem;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.view.inputmethod.EditorInfo;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.ProgressBar;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.activities.MainActivity;
 | 
			
		||||
import org.mian.gitnex.activities.NewOrganizationActivity;
 | 
			
		||||
import org.mian.gitnex.adapters.OrganizationsListAdapter;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.viewmodels.OrganizationListViewModel;
 | 
			
		||||
import org.mian.gitnex.models.UserOrganizations;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class OrganizationsFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private ProgressBar mProgressBar;
 | 
			
		||||
    private OrganizationsListAdapter adapter;
 | 
			
		||||
    private RecyclerView mRecyclerView;
 | 
			
		||||
    private ImageView createNewOrganization;
 | 
			
		||||
    private TextView noDataOrg;
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        ((MainActivity) Objects.requireNonNull(getActivity())).setActionBarTitle(getResources().getString(R.string.pageTitleOrganizations));
 | 
			
		||||
        final View v = inflater.inflate(R.layout.fragment_organizations, container, false);
 | 
			
		||||
        setHasOptionsMenu(true);
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
 | 
			
		||||
 | 
			
		||||
        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");
 | 
			
		||||
 | 
			
		||||
        final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh);
 | 
			
		||||
 | 
			
		||||
        mProgressBar = v.findViewById(R.id.progress_bar);
 | 
			
		||||
        noDataOrg = v.findViewById(R.id.noDataOrg);
 | 
			
		||||
        mRecyclerView = v.findViewById(R.id.recyclerView);
 | 
			
		||||
        mRecyclerView.setHasFixedSize(true);
 | 
			
		||||
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
 | 
			
		||||
 | 
			
		||||
        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
 | 
			
		||||
                DividerItemDecoration.VERTICAL);
 | 
			
		||||
        mRecyclerView.addItemDecoration(dividerItemDecoration);
 | 
			
		||||
 | 
			
		||||
        createNewOrganization = v.findViewById(R.id.addNewOrganization);
 | 
			
		||||
 | 
			
		||||
        createNewOrganization.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                Intent intent = new Intent(view.getContext(), NewOrganizationActivity.class);
 | 
			
		||||
                startActivity(intent);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
 | 
			
		||||
                if (dy > 0 && createNewOrganization.isShown()) {
 | 
			
		||||
                    createNewOrganization.setVisibility(View.GONE);
 | 
			
		||||
                } else if (dy < 0 ) {
 | 
			
		||||
                    createNewOrganization.setVisibility(View.VISIBLE);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
 | 
			
		||||
                super.onScrollStateChanged(recyclerView, newState);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if(connToInternet) {
 | 
			
		||||
            swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onRefresh() {
 | 
			
		||||
                    new Handler().postDelayed(new Runnable() {
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void run() {
 | 
			
		||||
                            swipeRefresh.setRefreshing(false);
 | 
			
		||||
                            OrganizationListViewModel.loadOrgsList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken));
 | 
			
		||||
                        }
 | 
			
		||||
                    }, 50);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken));
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            mProgressBar.setVisibility(View.GONE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onResume(){
 | 
			
		||||
        super.onResume();
 | 
			
		||||
        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(tinyDb.getBoolean("orgCreated")) {
 | 
			
		||||
            OrganizationListViewModel.loadOrgsList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken));
 | 
			
		||||
            tinyDb.putBoolean("orgCreated", false);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void fetchDataAsync(String instanceUrl, String instanceToken) {
 | 
			
		||||
 | 
			
		||||
        OrganizationListViewModel orgModel = ViewModelProviders.of(this).get(OrganizationListViewModel.class);
 | 
			
		||||
 | 
			
		||||
        orgModel.getUserOrgs(instanceUrl, instanceToken).observe(this, new Observer<List<UserOrganizations>>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onChanged(@Nullable List<UserOrganizations> orgsListMain) {
 | 
			
		||||
                adapter = new OrganizationsListAdapter(getContext(), orgsListMain);
 | 
			
		||||
                if(adapter.getItemCount() > 0) {
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noDataOrg.setVisibility(View.GONE);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    adapter.notifyDataSetChanged();
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noDataOrg.setVisibility(View.VISIBLE);
 | 
			
		||||
                }
 | 
			
		||||
                mProgressBar.setVisibility(View.GONE);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
 | 
			
		||||
 | 
			
		||||
        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);
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public boolean onQueryTextSubmit(String query) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public boolean onQueryTextChange(String newText) {
 | 
			
		||||
                adapter.getFilter().filter(newText);
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,39 @@
 | 
			
		||||
package org.mian.gitnex.fragments;
 | 
			
		||||
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.activities.ProfileEmailActivity;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.annotation.Nullable;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class ProfileBottomSheetFragment extends BottomSheetDialogFragment {
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
 | 
			
		||||
        View v = inflater.inflate(R.layout.profile_bottom_sheet_layout, container, false);
 | 
			
		||||
 | 
			
		||||
        TextView addNewEmailAddress = v.findViewById(R.id.addNewEmailAddress);
 | 
			
		||||
 | 
			
		||||
        addNewEmailAddress.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View v) {
 | 
			
		||||
                startActivity(new Intent(getContext(), ProfileEmailActivity.class));
 | 
			
		||||
                dismiss();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,148 @@
 | 
			
		||||
package org.mian.gitnex.fragments;
 | 
			
		||||
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import androidx.annotation.Nullable;
 | 
			
		||||
import androidx.fragment.app.Fragment;
 | 
			
		||||
import androidx.lifecycle.Observer;
 | 
			
		||||
import androidx.lifecycle.ViewModelProviders;
 | 
			
		||||
import androidx.recyclerview.widget.DividerItemDecoration;
 | 
			
		||||
import androidx.recyclerview.widget.LinearLayoutManager;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.ProgressBar;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.adapters.ProfileEmailsAdapter;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.models.Emails;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import org.mian.gitnex.viewmodels.ProfileEmailsViewModel;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class ProfileEmailsFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private ProgressBar mProgressBar;
 | 
			
		||||
    private ProfileEmailsAdapter adapter;
 | 
			
		||||
    private RecyclerView mRecyclerView;
 | 
			
		||||
    private TextView noDataEmails;
 | 
			
		||||
    private static String repoNameF = "param2";
 | 
			
		||||
    private static String repoOwnerF = "param1";
 | 
			
		||||
 | 
			
		||||
    private String repoName;
 | 
			
		||||
    private String repoOwner;
 | 
			
		||||
 | 
			
		||||
    private OnFragmentInteractionListener mListener;
 | 
			
		||||
 | 
			
		||||
    public ProfileEmailsFragment() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static ProfileEmailsFragment newInstance(String param1, String param2) {
 | 
			
		||||
        ProfileEmailsFragment fragment = new ProfileEmailsFragment();
 | 
			
		||||
        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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
 | 
			
		||||
                             Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        final View v = inflater.inflate(R.layout.fragment_profile_emails, container, false);
 | 
			
		||||
 | 
			
		||||
        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");
 | 
			
		||||
 | 
			
		||||
        final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh);
 | 
			
		||||
 | 
			
		||||
        noDataEmails = v.findViewById(R.id.noDataEmails);
 | 
			
		||||
        mRecyclerView = v.findViewById(R.id.recyclerView);
 | 
			
		||||
 | 
			
		||||
        mRecyclerView.setHasFixedSize(true);
 | 
			
		||||
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
 | 
			
		||||
 | 
			
		||||
        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
 | 
			
		||||
                DividerItemDecoration.VERTICAL);
 | 
			
		||||
        mRecyclerView.addItemDecoration(dividerItemDecoration);
 | 
			
		||||
 | 
			
		||||
        mProgressBar = v.findViewById(R.id.progress_bar);
 | 
			
		||||
 | 
			
		||||
        swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onRefresh() {
 | 
			
		||||
                new Handler().postDelayed(new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        swipeRefresh.setRefreshing(false);
 | 
			
		||||
                        ProfileEmailsViewModel.loadEmailsList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken));
 | 
			
		||||
                    }
 | 
			
		||||
                }, 200);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken));
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void fetchDataAsync(String instanceUrl, String instanceToken) {
 | 
			
		||||
 | 
			
		||||
        ProfileEmailsViewModel profileEmailModel = ViewModelProviders.of(this).get(ProfileEmailsViewModel.class);
 | 
			
		||||
 | 
			
		||||
        profileEmailModel.getEmailsList(instanceUrl, instanceToken).observe(this, new Observer<List<Emails>>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onChanged(@Nullable List<Emails> emailsListMain) {
 | 
			
		||||
                adapter = new ProfileEmailsAdapter(getContext(), emailsListMain);
 | 
			
		||||
                if(adapter.getItemCount() > 0) {
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noDataEmails.setVisibility(View.GONE);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    adapter.notifyDataSetChanged();
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noDataEmails.setVisibility(View.VISIBLE);
 | 
			
		||||
                }
 | 
			
		||||
                mProgressBar.setVisibility(View.GONE);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,147 @@
 | 
			
		||||
package org.mian.gitnex.fragments;
 | 
			
		||||
 | 
			
		||||
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.ViewModelProviders;
 | 
			
		||||
import androidx.recyclerview.widget.DividerItemDecoration;
 | 
			
		||||
import androidx.recyclerview.widget.LinearLayoutManager;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.ProgressBar;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.adapters.ProfileFollowersAdapter;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.models.UserInfo;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import org.mian.gitnex.viewmodels.ProfileFollowersViewModel;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class ProfileFollowersFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private ProgressBar mProgressBar;
 | 
			
		||||
    private ProfileFollowersAdapter adapter;
 | 
			
		||||
    private RecyclerView mRecyclerView;
 | 
			
		||||
    private TextView noDataFollowers;
 | 
			
		||||
    private static String repoNameF = "param2";
 | 
			
		||||
    private static String repoOwnerF = "param1";
 | 
			
		||||
 | 
			
		||||
    private String repoName;
 | 
			
		||||
    private String repoOwner;
 | 
			
		||||
 | 
			
		||||
    private OnFragmentInteractionListener mListener;
 | 
			
		||||
 | 
			
		||||
    public ProfileFollowersFragment() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static ProfileFollowersFragment newInstance(String param1, String param2) {
 | 
			
		||||
        ProfileFollowersFragment fragment = new ProfileFollowersFragment();
 | 
			
		||||
        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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
 | 
			
		||||
                             Bundle savedInstanceState) {
 | 
			
		||||
        final View v = inflater.inflate(R.layout.fragment_profile_followers, container, false);
 | 
			
		||||
 | 
			
		||||
        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");
 | 
			
		||||
 | 
			
		||||
        final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh);
 | 
			
		||||
 | 
			
		||||
        noDataFollowers = v.findViewById(R.id.noDataFollowers);
 | 
			
		||||
        mRecyclerView = v.findViewById(R.id.recyclerView);
 | 
			
		||||
 | 
			
		||||
        mRecyclerView.setHasFixedSize(true);
 | 
			
		||||
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
 | 
			
		||||
 | 
			
		||||
        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
 | 
			
		||||
                DividerItemDecoration.VERTICAL);
 | 
			
		||||
        mRecyclerView.addItemDecoration(dividerItemDecoration);
 | 
			
		||||
 | 
			
		||||
        mProgressBar = v.findViewById(R.id.progress_bar);
 | 
			
		||||
 | 
			
		||||
        swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onRefresh() {
 | 
			
		||||
                new Handler().postDelayed(new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        swipeRefresh.setRefreshing(false);
 | 
			
		||||
                        ProfileFollowersViewModel.loadFollowersList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken));
 | 
			
		||||
                    }
 | 
			
		||||
                }, 200);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken));
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void fetchDataAsync(String instanceUrl, String instanceToken) {
 | 
			
		||||
 | 
			
		||||
        ProfileFollowersViewModel pfModel = ViewModelProviders.of(this).get(ProfileFollowersViewModel.class);
 | 
			
		||||
 | 
			
		||||
        pfModel.getFollowersList(instanceUrl, instanceToken).observe(this, new Observer<List<UserInfo>>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onChanged(@Nullable List<UserInfo> pfListMain) {
 | 
			
		||||
                adapter = new ProfileFollowersAdapter(getContext(), pfListMain);
 | 
			
		||||
                if(adapter.getItemCount() > 0) {
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noDataFollowers.setVisibility(View.GONE);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    adapter.notifyDataSetChanged();
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noDataFollowers.setVisibility(View.VISIBLE);
 | 
			
		||||
                }
 | 
			
		||||
                mProgressBar.setVisibility(View.GONE);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,147 @@
 | 
			
		||||
package org.mian.gitnex.fragments;
 | 
			
		||||
 | 
			
		||||
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.ViewModelProviders;
 | 
			
		||||
import androidx.recyclerview.widget.DividerItemDecoration;
 | 
			
		||||
import androidx.recyclerview.widget.LinearLayoutManager;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.ProgressBar;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.adapters.ProfileFollowingAdapter;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.models.UserInfo;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import org.mian.gitnex.viewmodels.ProfileFollowingViewModel;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class ProfileFollowingFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private ProgressBar mProgressBar;
 | 
			
		||||
    private ProfileFollowingAdapter adapter;
 | 
			
		||||
    private RecyclerView mRecyclerView;
 | 
			
		||||
    private TextView noDataFollowing;
 | 
			
		||||
    private static String repoNameF = "param2";
 | 
			
		||||
    private static String repoOwnerF = "param1";
 | 
			
		||||
 | 
			
		||||
    private String repoName;
 | 
			
		||||
    private String repoOwner;
 | 
			
		||||
 | 
			
		||||
    private OnFragmentInteractionListener mListener;
 | 
			
		||||
 | 
			
		||||
    public ProfileFollowingFragment() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static ProfileFollowingFragment newInstance(String param1, String param2) {
 | 
			
		||||
        ProfileFollowingFragment fragment = new ProfileFollowingFragment();
 | 
			
		||||
        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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
 | 
			
		||||
                             Bundle savedInstanceState) {
 | 
			
		||||
        final View v = inflater.inflate(R.layout.fragment_profile_following, container, false);
 | 
			
		||||
 | 
			
		||||
        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");
 | 
			
		||||
 | 
			
		||||
        final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh);
 | 
			
		||||
 | 
			
		||||
        noDataFollowing = v.findViewById(R.id.noDataFollowing);
 | 
			
		||||
        mRecyclerView = v.findViewById(R.id.recyclerView);
 | 
			
		||||
 | 
			
		||||
        mRecyclerView.setHasFixedSize(true);
 | 
			
		||||
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
 | 
			
		||||
 | 
			
		||||
        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
 | 
			
		||||
                DividerItemDecoration.VERTICAL);
 | 
			
		||||
        mRecyclerView.addItemDecoration(dividerItemDecoration);
 | 
			
		||||
 | 
			
		||||
        mProgressBar = v.findViewById(R.id.progress_bar);
 | 
			
		||||
 | 
			
		||||
        swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onRefresh() {
 | 
			
		||||
                new Handler().postDelayed(new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        swipeRefresh.setRefreshing(false);
 | 
			
		||||
                        ProfileFollowingViewModel.loadFollowingList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken));
 | 
			
		||||
                    }
 | 
			
		||||
                }, 200);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken));
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void fetchDataAsync(String instanceUrl, String instanceToken) {
 | 
			
		||||
 | 
			
		||||
        ProfileFollowingViewModel pfModel = ViewModelProviders.of(this).get(ProfileFollowingViewModel.class);
 | 
			
		||||
 | 
			
		||||
        pfModel.getFollowingList(instanceUrl, instanceToken).observe(this, new Observer<List<UserInfo>>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onChanged(@Nullable List<UserInfo> pfListMain) {
 | 
			
		||||
                adapter = new ProfileFollowingAdapter(getContext(), pfListMain);
 | 
			
		||||
                if(adapter.getItemCount() > 0) {
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noDataFollowing.setVisibility(View.GONE);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    adapter.notifyDataSetChanged();
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noDataFollowing.setVisibility(View.VISIBLE);
 | 
			
		||||
                }
 | 
			
		||||
                mProgressBar.setVisibility(View.GONE);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										125
									
								
								app/src/main/java/org/mian/gitnex/fragments/ProfileFragment.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								app/src/main/java/org/mian/gitnex/fragments/ProfileFragment.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,125 @@
 | 
			
		||||
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.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.ImageView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import com.google.android.material.tabs.TabLayout;
 | 
			
		||||
import com.squareup.picasso.Picasso;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.activities.MainActivity;
 | 
			
		||||
import org.mian.gitnex.helpers.RoundedTransformation;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class ProfileFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private Context ctx = getContext();
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        View v = inflater.inflate(R.layout.fragment_profile, container, false);
 | 
			
		||||
        ((MainActivity) Objects.requireNonNull(getActivity())).setActionBarTitle(getResources().getString(R.string.pageTitleProfile));
 | 
			
		||||
        setHasOptionsMenu(true);
 | 
			
		||||
 | 
			
		||||
        TinyDB tinyDb = new TinyDB(getContext());
 | 
			
		||||
 | 
			
		||||
        TextView userFullName = v.findViewById(R.id.userFullName);
 | 
			
		||||
        ImageView userAvatar = v.findViewById(R.id.userAvatar);
 | 
			
		||||
        TextView userLogin = v.findViewById(R.id.userLogin);
 | 
			
		||||
        TextView userEmail = v.findViewById(R.id.userEmail);
 | 
			
		||||
 | 
			
		||||
        userFullName.setText(tinyDb.getString("userFullname"));
 | 
			
		||||
        Picasso.get().load(tinyDb.getString("userAvatar")).transform(new RoundedTransformation(100, 0)).resize(180, 180).centerCrop().into(userAvatar);
 | 
			
		||||
        userLogin.setText(getString(R.string.usernameWithAt, tinyDb.getString("userLogin")));
 | 
			
		||||
        userEmail.setText(tinyDb.getString("userEmail"));
 | 
			
		||||
 | 
			
		||||
        ProfileFragment.SectionsPagerAdapter mSectionsPagerAdapter = new ProfileFragment.SectionsPagerAdapter(getFragmentManager());
 | 
			
		||||
 | 
			
		||||
        ViewPager mViewPager = v.findViewById(R.id.container);
 | 
			
		||||
        mViewPager.setAdapter(mSectionsPagerAdapter);
 | 
			
		||||
 | 
			
		||||
        TabLayout tabLayout = v.findViewById(R.id.tabs);
 | 
			
		||||
 | 
			
		||||
        mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
 | 
			
		||||
        tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
 | 
			
		||||
 | 
			
		||||
        SectionsPagerAdapter(FragmentManager fm) {
 | 
			
		||||
            super(fm);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @NonNull
 | 
			
		||||
        @Override
 | 
			
		||||
        public Fragment getItem(int position) {
 | 
			
		||||
 | 
			
		||||
            Fragment fragment = null;
 | 
			
		||||
            switch (position) {
 | 
			
		||||
                case 0: // followers
 | 
			
		||||
                    return ProfileFollowersFragment.newInstance("repoOwner", "repoName");
 | 
			
		||||
                case 1: // following
 | 
			
		||||
                    return ProfileFollowingFragment.newInstance("repoOwner", "repoName");
 | 
			
		||||
                case 2: // emails
 | 
			
		||||
                    return ProfileEmailsFragment.newInstance("repoOwner", "repoName");
 | 
			
		||||
            }
 | 
			
		||||
            return fragment;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public int getCount() {
 | 
			
		||||
            return 3;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
 | 
			
		||||
        menu.clear();
 | 
			
		||||
        Objects.requireNonNull(getActivity()).getMenuInflater().inflate(R.menu.profile_dotted_menu, menu);
 | 
			
		||||
        super.onCreateOptionsMenu(menu, inflater);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
 | 
			
		||||
 | 
			
		||||
        int id = item.getItemId();
 | 
			
		||||
 | 
			
		||||
        switch (id) {
 | 
			
		||||
            case android.R.id.home:
 | 
			
		||||
                ((MainActivity)ctx).finish();
 | 
			
		||||
                return true;
 | 
			
		||||
            case R.id.profileMenu:
 | 
			
		||||
                ProfileBottomSheetFragment bottomSheet = new ProfileBottomSheetFragment();
 | 
			
		||||
                assert getFragmentManager() != null;
 | 
			
		||||
                bottomSheet.show(getFragmentManager(), "profileBottomSheet");
 | 
			
		||||
                return true;
 | 
			
		||||
            default:
 | 
			
		||||
                return super.onOptionsItemSelected(item);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,165 @@
 | 
			
		||||
package org.mian.gitnex.fragments;
 | 
			
		||||
 | 
			
		||||
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.ViewModelProviders;
 | 
			
		||||
import androidx.recyclerview.widget.DividerItemDecoration;
 | 
			
		||||
import androidx.recyclerview.widget.LinearLayoutManager;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.ProgressBar;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.adapters.ReleasesAdapter;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.models.Releases;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import org.mian.gitnex.viewmodels.ReleasesViewModel;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class ReleasesFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private ProgressBar mProgressBar;
 | 
			
		||||
    private ReleasesAdapter adapter;
 | 
			
		||||
    private RecyclerView mRecyclerView;
 | 
			
		||||
    private TextView noDataReleases;
 | 
			
		||||
    private static String repoNameF = "param2";
 | 
			
		||||
    private static String repoOwnerF = "param1";
 | 
			
		||||
 | 
			
		||||
    private String repoName;
 | 
			
		||||
    private String repoOwner;
 | 
			
		||||
 | 
			
		||||
    private OnFragmentInteractionListener mListener;
 | 
			
		||||
 | 
			
		||||
    public ReleasesFragment() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static ReleasesFragment newInstance(String param1, String param2) {
 | 
			
		||||
        ReleasesFragment fragment = new ReleasesFragment();
 | 
			
		||||
        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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
 | 
			
		||||
                             Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        View v = inflater.inflate(R.layout.fragment_releases, container, false);
 | 
			
		||||
 | 
			
		||||
        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");
 | 
			
		||||
        noDataReleases = v.findViewById(R.id.noDataReleases);
 | 
			
		||||
 | 
			
		||||
        final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh);
 | 
			
		||||
 | 
			
		||||
        mRecyclerView = v.findViewById(R.id.recyclerView);
 | 
			
		||||
        mRecyclerView.setHasFixedSize(true);
 | 
			
		||||
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
 | 
			
		||||
 | 
			
		||||
        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
 | 
			
		||||
                DividerItemDecoration.VERTICAL);
 | 
			
		||||
        mRecyclerView.addItemDecoration(dividerItemDecoration);
 | 
			
		||||
 | 
			
		||||
        mProgressBar = v.findViewById(R.id.progress_bar);
 | 
			
		||||
 | 
			
		||||
        swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onRefresh() {
 | 
			
		||||
                new Handler().postDelayed(new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        swipeRefresh.setRefreshing(false);
 | 
			
		||||
                        ReleasesViewModel.loadReleasesList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName);
 | 
			
		||||
                    }
 | 
			
		||||
                }, 50);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName);
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onResume() {
 | 
			
		||||
 | 
			
		||||
        super.onResume();
 | 
			
		||||
        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(tinyDb.getBoolean("updateReleases")) {
 | 
			
		||||
            ReleasesViewModel.loadReleasesList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName);
 | 
			
		||||
            tinyDb.putBoolean("updateReleases", 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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) {
 | 
			
		||||
 | 
			
		||||
        ReleasesViewModel releasesModel = ViewModelProviders.of(this).get(ReleasesViewModel.class);
 | 
			
		||||
 | 
			
		||||
        releasesModel.getReleasesList(instanceUrl, instanceToken, owner, repo).observe(this, new Observer<List<Releases>>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onChanged(@Nullable List<Releases> releasesListMain) {
 | 
			
		||||
                adapter = new ReleasesAdapter(getContext(), releasesListMain);
 | 
			
		||||
                if(adapter.getItemCount() > 0) {
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noDataReleases.setVisibility(View.GONE);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    adapter.notifyDataSetChanged();
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noDataReleases.setVisibility(View.VISIBLE);
 | 
			
		||||
                }
 | 
			
		||||
                mProgressBar.setVisibility(View.GONE);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,92 @@
 | 
			
		||||
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 com.google.android.material.bottomsheet.BottomSheetDialogFragment;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.annotation.Nullable;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class RepoBottomSheetFragment extends BottomSheetDialogFragment {
 | 
			
		||||
 | 
			
		||||
    private BottomSheetListener bmListener;
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
 | 
			
		||||
        View v = inflater.inflate(R.layout.repo_bottom_sheet_layout, container, false);
 | 
			
		||||
 | 
			
		||||
        TextView createLabel = v.findViewById(R.id.createLabel);
 | 
			
		||||
        TextView createIssue = v.findViewById(R.id.createNewIssue);
 | 
			
		||||
        TextView createMilestone = v.findViewById(R.id.createNewMilestone);
 | 
			
		||||
        TextView addCollaborator = v.findViewById(R.id.addCollaborator);
 | 
			
		||||
        TextView createRelease = v.findViewById(R.id.createRelease);
 | 
			
		||||
 | 
			
		||||
        createLabel.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View v) {
 | 
			
		||||
                bmListener.onButtonClicked("label");
 | 
			
		||||
                dismiss();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        createIssue.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View v) {
 | 
			
		||||
                bmListener.onButtonClicked("newIssue");
 | 
			
		||||
                dismiss();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        createMilestone.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View v) {
 | 
			
		||||
                bmListener.onButtonClicked("newMilestone");
 | 
			
		||||
                dismiss();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        addCollaborator.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View v) {
 | 
			
		||||
                bmListener.onButtonClicked("addCollaborator");
 | 
			
		||||
                dismiss();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        createRelease.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View v) {
 | 
			
		||||
                bmListener.onButtonClicked("createRelease");
 | 
			
		||||
                dismiss();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public interface BottomSheetListener {
 | 
			
		||||
        void onButtonClicked(String text);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onAttach(@NonNull Context context) {
 | 
			
		||||
        super.onAttach(context);
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            bmListener = (BottomSheetListener) context;
 | 
			
		||||
        } catch (ClassCastException e) {
 | 
			
		||||
            throw new ClassCastException(context.toString()
 | 
			
		||||
                    + " must implement BottomSheetListener");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,359 @@
 | 
			
		||||
package org.mian.gitnex.fragments;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.graphics.Color;
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.fragment.app.Fragment;
 | 
			
		||||
import okhttp3.OkHttpClient;
 | 
			
		||||
import retrofit2.Call;
 | 
			
		||||
import retrofit2.Callback;
 | 
			
		||||
import ru.noties.markwon.AbstractMarkwonPlugin;
 | 
			
		||||
import ru.noties.markwon.Markwon;
 | 
			
		||||
import ru.noties.markwon.core.CorePlugin;
 | 
			
		||||
import ru.noties.markwon.core.MarkwonTheme;
 | 
			
		||||
import ru.noties.markwon.ext.strikethrough.StrikethroughPlugin;
 | 
			
		||||
import ru.noties.markwon.ext.tables.TablePlugin;
 | 
			
		||||
import ru.noties.markwon.ext.tables.TableTheme;
 | 
			
		||||
import ru.noties.markwon.ext.tasklist.TaskListPlugin;
 | 
			
		||||
import ru.noties.markwon.html.HtmlPlugin;
 | 
			
		||||
import ru.noties.markwon.image.ImagesPlugin;
 | 
			
		||||
import ru.noties.markwon.image.gif.GifPlugin;
 | 
			
		||||
import ru.noties.markwon.image.okhttp.OkHttpImagesPlugin;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.LinearLayout;
 | 
			
		||||
import android.widget.ProgressBar;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.clients.RetrofitClient;
 | 
			
		||||
import org.mian.gitnex.helpers.AlertDialogs;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.helpers.ClickListener;
 | 
			
		||||
import org.mian.gitnex.helpers.TimeHelper;
 | 
			
		||||
import org.mian.gitnex.helpers.Toasty;
 | 
			
		||||
import org.mian.gitnex.models.UserRepositories;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import org.ocpsoft.prettytime.PrettyTime;
 | 
			
		||||
import java.text.DateFormat;
 | 
			
		||||
import java.text.SimpleDateFormat;
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class RepoInfoFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private Context ctx = getContext();
 | 
			
		||||
    private ProgressBar mProgressBar;
 | 
			
		||||
    private LinearLayout pageContent;
 | 
			
		||||
    private static String repoNameF = "param2";
 | 
			
		||||
    private static String repoOwnerF = "param1";
 | 
			
		||||
 | 
			
		||||
    private String repoName;
 | 
			
		||||
    private String repoOwner;
 | 
			
		||||
    private TextView repoNameInfo;
 | 
			
		||||
    private TextView repoOwnerInfo;
 | 
			
		||||
    private TextView repoDescriptionInfo;
 | 
			
		||||
    private TextView repoWebsiteInfo;
 | 
			
		||||
    private TextView repoSizeInfo;
 | 
			
		||||
    private TextView repoDefaultBranchInfo;
 | 
			
		||||
    private TextView repoSshUrlInfo;
 | 
			
		||||
    private TextView repoCloneUrlInfo;
 | 
			
		||||
    private TextView repoRepoUrlInfo;
 | 
			
		||||
    private TextView repoForksCountInfo;
 | 
			
		||||
    private TextView repoCreatedAtInfo;
 | 
			
		||||
    private TextView repoFileContents;
 | 
			
		||||
    private LinearLayout repoMetaFrame;
 | 
			
		||||
    private ImageView repoMetaDataExpandCollapse;
 | 
			
		||||
    private ImageView repoFilenameExpandCollapse;
 | 
			
		||||
    private LinearLayout fileContentsFrameHeader;
 | 
			
		||||
    private LinearLayout fileContentsFrame;
 | 
			
		||||
 | 
			
		||||
    private OnFragmentInteractionListener mListener;
 | 
			
		||||
 | 
			
		||||
    public RepoInfoFragment() {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static RepoInfoFragment newInstance(String param1, String param2) {
 | 
			
		||||
        RepoInfoFragment fragment = new RepoInfoFragment();
 | 
			
		||||
        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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        View v = inflater.inflate(R.layout.fragment_repo_info, container, false);
 | 
			
		||||
 | 
			
		||||
        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");
 | 
			
		||||
        final String locale = tinyDb.getString("locale");
 | 
			
		||||
        final String timeFormat = tinyDb.getString("dateFormat");
 | 
			
		||||
 | 
			
		||||
        pageContent = v.findViewById(R.id.repoInfoLayout);
 | 
			
		||||
        pageContent.setVisibility(View.GONE);
 | 
			
		||||
 | 
			
		||||
        mProgressBar = v.findViewById(R.id.progress_bar);
 | 
			
		||||
        repoNameInfo = v.findViewById(R.id.repoNameInfo);
 | 
			
		||||
        repoOwnerInfo = v.findViewById(R.id.repoOwnerInfo);
 | 
			
		||||
        repoDescriptionInfo = v.findViewById(R.id.repoDescriptionInfo);
 | 
			
		||||
        repoWebsiteInfo = v.findViewById(R.id.repoWebsiteInfo);
 | 
			
		||||
        repoSizeInfo = v.findViewById(R.id.repoSizeInfo);
 | 
			
		||||
        repoDefaultBranchInfo = v.findViewById(R.id.repoDefaultBranchInfo);
 | 
			
		||||
        repoSshUrlInfo = v.findViewById(R.id.repoSshUrlInfo);
 | 
			
		||||
        repoCloneUrlInfo = v.findViewById(R.id.repoCloneUrlInfo);
 | 
			
		||||
        repoRepoUrlInfo = v.findViewById(R.id.repoRepoUrlInfo);
 | 
			
		||||
        repoForksCountInfo = v.findViewById(R.id.repoForksCountInfo);
 | 
			
		||||
        repoCreatedAtInfo = v.findViewById(R.id.repoCreatedAtInfo);
 | 
			
		||||
        repoFileContents = v.findViewById(R.id.repoFileContents);
 | 
			
		||||
        TextView repoFilename = v.findViewById(R.id.repoFilename);
 | 
			
		||||
        repoMetaFrame = v.findViewById(R.id.repoMetaFrame);
 | 
			
		||||
        TextView repoMetaData = v.findViewById(R.id.repoMetaData);
 | 
			
		||||
        repoMetaDataExpandCollapse = v.findViewById(R.id.repoMetaDataExpandCollapse);
 | 
			
		||||
        repoFilenameExpandCollapse = v.findViewById(R.id.repoFilenameExpandCollapse);
 | 
			
		||||
        fileContentsFrameHeader = v.findViewById(R.id.fileContentsFrameHeader);
 | 
			
		||||
        fileContentsFrame = v.findViewById(R.id.fileContentsFrame);
 | 
			
		||||
 | 
			
		||||
        repoMetaFrame.setVisibility(View.GONE);
 | 
			
		||||
 | 
			
		||||
        getRepoInfo(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, locale, timeFormat);
 | 
			
		||||
        getFileContents(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, getResources().getString(R.string.defaultFilename));
 | 
			
		||||
 | 
			
		||||
        repoFilename.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            public void onClick(View v) {
 | 
			
		||||
                collapseExpandView();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        repoMetaData.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            public void onClick(View v) {
 | 
			
		||||
                collapseExpandViewMeta();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void collapseExpandView() {
 | 
			
		||||
 | 
			
		||||
        if (repoFileContents.getVisibility() == View.GONE) {
 | 
			
		||||
            repoFilenameExpandCollapse.setImageResource(R.drawable.ic_arrow_up);
 | 
			
		||||
            repoFileContents.setVisibility(View.VISIBLE);
 | 
			
		||||
            //Animation slide_down = AnimationUtils.loadAnimation(getContext(), R.anim.slide_down);
 | 
			
		||||
            //fileContentsFrame.startAnimation(slide_down);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            repoFilenameExpandCollapse.setImageResource(R.drawable.ic_arrow_down);
 | 
			
		||||
            repoFileContents.setVisibility(View.GONE);
 | 
			
		||||
            //Animation slide_up = AnimationUtils.loadAnimation(getContext(), R.anim.slide_up);
 | 
			
		||||
            //fileContentsFrame.startAnimation(slide_up);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void collapseExpandViewMeta() {
 | 
			
		||||
        if (repoMetaFrame.getVisibility() == View.GONE) {
 | 
			
		||||
            repoMetaDataExpandCollapse.setImageResource(R.drawable.ic_arrow_up);
 | 
			
		||||
            repoMetaFrame.setVisibility(View.VISIBLE);
 | 
			
		||||
            //Animation slide_down = AnimationUtils.loadAnimation(getContext(), R.anim.slide_down);
 | 
			
		||||
            //repoMetaFrame.startAnimation(slide_down);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            repoMetaDataExpandCollapse.setImageResource(R.drawable.ic_arrow_down);
 | 
			
		||||
            repoMetaFrame.setVisibility(View.GONE);
 | 
			
		||||
            //Animation slide_up = AnimationUtils.loadAnimation(getContext(), R.anim.slide_up);
 | 
			
		||||
            //repoMetaFrame.startAnimation(slide_up);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void getRepoInfo(String instanceUrl, String token, final String owner, String repo, final String locale, final String timeFormat) {
 | 
			
		||||
 | 
			
		||||
        Call<UserRepositories> call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .getUserRepository(token, owner, repo);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<UserRepositories>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<UserRepositories> call, @NonNull retrofit2.Response<UserRepositories> response) {
 | 
			
		||||
 | 
			
		||||
                UserRepositories repoInfo = response.body();
 | 
			
		||||
 | 
			
		||||
                if (response.isSuccessful()) {
 | 
			
		||||
 | 
			
		||||
                    if (response.code() == 200) {
 | 
			
		||||
 | 
			
		||||
                        assert repoInfo != null;
 | 
			
		||||
                        repoNameInfo.setText(repoInfo.getName());
 | 
			
		||||
                        repoOwnerInfo.setText(owner);
 | 
			
		||||
                        repoDescriptionInfo.setText(repoInfo.getDescription());
 | 
			
		||||
                        repoWebsiteInfo.setText(repoInfo.getWebsite());
 | 
			
		||||
                        repoSizeInfo.setText(AppUtil.formatFileSize(repoInfo.getSize()));
 | 
			
		||||
                        repoDefaultBranchInfo.setText(repoInfo.getDefault_branch());
 | 
			
		||||
                        repoSshUrlInfo.setText(repoInfo.getSsh_url());
 | 
			
		||||
                        repoCloneUrlInfo.setText(repoInfo.getClone_url());
 | 
			
		||||
                        repoRepoUrlInfo.setText(repoInfo.getHtml_url());
 | 
			
		||||
                        repoForksCountInfo.setText(repoInfo.getForks_count());
 | 
			
		||||
 | 
			
		||||
                        switch (timeFormat) {
 | 
			
		||||
                            case "pretty": {
 | 
			
		||||
                                PrettyTime prettyTime = new PrettyTime(new Locale(locale));
 | 
			
		||||
                                String createdTime = prettyTime.format(repoInfo.getCreated_at());
 | 
			
		||||
                                repoCreatedAtInfo.setText(createdTime);
 | 
			
		||||
                                repoCreatedAtInfo.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(repoInfo.getCreated_at()), getContext()));
 | 
			
		||||
                                break;
 | 
			
		||||
                            }
 | 
			
		||||
                            case "normal": {
 | 
			
		||||
                                DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd '" + getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
 | 
			
		||||
                                String createdTime = formatter.format(repoInfo.getCreated_at());
 | 
			
		||||
                                repoCreatedAtInfo.setText(createdTime);
 | 
			
		||||
                                break;
 | 
			
		||||
                            }
 | 
			
		||||
                            case "normal1": {
 | 
			
		||||
                                DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy '" + getResources().getString(R.string.timeAtText) + "' HH:mm", new Locale(locale));
 | 
			
		||||
                                String createdTime = formatter.format(repoInfo.getCreated_at());
 | 
			
		||||
                                repoCreatedAtInfo.setText(createdTime);
 | 
			
		||||
                                break;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        mProgressBar.setVisibility(View.GONE);
 | 
			
		||||
                        pageContent.setVisibility(View.VISIBLE);
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    Log.e("onFailure", String.valueOf(response.code()));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<UserRepositories> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void getFileContents(String instanceUrl, String token, final String owner, String repo, final String filename) {
 | 
			
		||||
 | 
			
		||||
        final TinyDB tinyDb = new TinyDB(getContext());
 | 
			
		||||
 | 
			
		||||
        Call<String> call = RetrofitClient
 | 
			
		||||
                .getInstance(instanceUrl)
 | 
			
		||||
                .getApiInterface()
 | 
			
		||||
                .getFileContents(token, owner, repo, filename);
 | 
			
		||||
 | 
			
		||||
        call.enqueue(new Callback<String>() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onResponse(@NonNull Call<String> call, @NonNull retrofit2.Response<String> response) {
 | 
			
		||||
 | 
			
		||||
                if (response.code() == 200) {
 | 
			
		||||
 | 
			
		||||
                    final Markwon markwon = Markwon.builder(Objects.requireNonNull(getContext()))
 | 
			
		||||
                            .usePlugin(CorePlugin.create())
 | 
			
		||||
                            .usePlugin(OkHttpImagesPlugin.create(new OkHttpClient()))
 | 
			
		||||
                            .usePlugin(ImagesPlugin.createWithAssets(getContext()))
 | 
			
		||||
                            .usePlugin(new AbstractMarkwonPlugin() {
 | 
			
		||||
                                @Override
 | 
			
		||||
                                public void configureTheme(@NonNull MarkwonTheme.Builder builder) {
 | 
			
		||||
                                    builder
 | 
			
		||||
                                            .codeTextColor(tinyDb.getInt("codeBlockColor"))
 | 
			
		||||
                                            .codeBackgroundColor(tinyDb.getInt("codeBlockBackground"))
 | 
			
		||||
                                            .linkColor(getResources().getColor(R.color.lightBlue));
 | 
			
		||||
                                }
 | 
			
		||||
                            })
 | 
			
		||||
                            .usePlugin(TablePlugin.create(getContext()))
 | 
			
		||||
                            .usePlugin(TaskListPlugin.create(getContext()))
 | 
			
		||||
                            .usePlugin(HtmlPlugin.create())
 | 
			
		||||
                            .usePlugin(GifPlugin.create())
 | 
			
		||||
                            .usePlugin(StrikethroughPlugin.create())
 | 
			
		||||
                            .build();
 | 
			
		||||
 | 
			
		||||
                    CharSequence bodyWithMD = null;
 | 
			
		||||
                    if (response.body() != null) {
 | 
			
		||||
                        bodyWithMD = markwon.toMarkdown(response.body());
 | 
			
		||||
                    }
 | 
			
		||||
                    repoFileContents.setText(bodyWithMD);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                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 if(response.code() == 403) {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(ctx, ctx.getString(R.string.authorizeError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else if(response.code() == 404) {
 | 
			
		||||
 | 
			
		||||
                    fileContentsFrameHeader.setVisibility(View.GONE);
 | 
			
		||||
                    fileContentsFrame.setVisibility(View.GONE);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
 | 
			
		||||
                    Toasty.info(getContext(), getString(R.string.genericError));
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
 | 
			
		||||
                Log.e("onFailure", t.toString());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,193 @@
 | 
			
		||||
package org.mian.gitnex.fragments;
 | 
			
		||||
 | 
			
		||||
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.ViewModelProviders;
 | 
			
		||||
import androidx.recyclerview.widget.DividerItemDecoration;
 | 
			
		||||
import androidx.recyclerview.widget.LinearLayoutManager;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.Menu;
 | 
			
		||||
import android.view.MenuInflater;
 | 
			
		||||
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.adapters.RepositoriesByOrgAdapter;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.models.UserRepositories;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import org.mian.gitnex.viewmodels.RepositoriesByOrgViewModel;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class RepositoriesByOrgFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private OnFragmentInteractionListener mListener;
 | 
			
		||||
 | 
			
		||||
    private ProgressBar mProgressBar;
 | 
			
		||||
    private RepositoriesByOrgAdapter adapter;
 | 
			
		||||
    private RecyclerView mRecyclerView;
 | 
			
		||||
    private TextView noData;
 | 
			
		||||
    private static String orgNameF = "param2";
 | 
			
		||||
    private String orgName;
 | 
			
		||||
 | 
			
		||||
    public RepositoriesByOrgFragment() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static RepositoriesByOrgFragment newInstance(String param1) {
 | 
			
		||||
        RepositoriesByOrgFragment fragment = new RepositoriesByOrgFragment();
 | 
			
		||||
        Bundle args = new Bundle();
 | 
			
		||||
        args.putString(orgNameF, param1);
 | 
			
		||||
        fragment.setArguments(args);
 | 
			
		||||
        return fragment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        if (getArguments() != null) {
 | 
			
		||||
            orgName = getArguments().getString(orgNameF);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
 | 
			
		||||
                             Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        View v = inflater.inflate(R.layout.fragment_repositories_by_org, 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");
 | 
			
		||||
        noData = v.findViewById(R.id.noData);
 | 
			
		||||
 | 
			
		||||
        final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh);
 | 
			
		||||
 | 
			
		||||
        mRecyclerView = v.findViewById(R.id.recyclerView);
 | 
			
		||||
        mRecyclerView.setHasFixedSize(true);
 | 
			
		||||
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
 | 
			
		||||
 | 
			
		||||
        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
 | 
			
		||||
                DividerItemDecoration.VERTICAL);
 | 
			
		||||
        mRecyclerView.addItemDecoration(dividerItemDecoration);
 | 
			
		||||
 | 
			
		||||
        mProgressBar = v.findViewById(R.id.progress_bar);
 | 
			
		||||
 | 
			
		||||
        swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onRefresh() {
 | 
			
		||||
                new Handler().postDelayed(new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        swipeRefresh.setRefreshing(false);
 | 
			
		||||
                        RepositoriesByOrgViewModel.loadOrgRepos(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), orgName);
 | 
			
		||||
                    }
 | 
			
		||||
                }, 200);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), orgName);
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onResume() {
 | 
			
		||||
 | 
			
		||||
        super.onResume();
 | 
			
		||||
        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");
 | 
			
		||||
 | 
			
		||||
        RepositoriesByOrgViewModel.loadOrgRepos(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), orgName);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void fetchDataAsync(String instanceUrl, String instanceToken, String owner) {
 | 
			
		||||
 | 
			
		||||
        RepositoriesByOrgViewModel orgRepoModel = ViewModelProviders.of(this).get(RepositoriesByOrgViewModel.class);
 | 
			
		||||
 | 
			
		||||
        orgRepoModel.getRepositoriesByOrg(instanceUrl, instanceToken, owner).observe(this, new Observer<List<UserRepositories>>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onChanged(@Nullable List<UserRepositories> orgReposListMain) {
 | 
			
		||||
                adapter = new RepositoriesByOrgAdapter(getContext(), orgReposListMain);
 | 
			
		||||
                if(adapter.getItemCount() > 0) {
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noData.setVisibility(View.GONE);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    adapter.notifyDataSetChanged();
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noData.setVisibility(View.VISIBLE);
 | 
			
		||||
                }
 | 
			
		||||
                mProgressBar.setVisibility(View.GONE);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
 | 
			
		||||
 | 
			
		||||
        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);
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public boolean onQueryTextSubmit(String query) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public boolean onQueryTextChange(String newText) {
 | 
			
		||||
                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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,199 @@
 | 
			
		||||
package org.mian.gitnex.fragments;
 | 
			
		||||
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.annotation.Nullable;
 | 
			
		||||
import androidx.fragment.app.Fragment;
 | 
			
		||||
import androidx.lifecycle.Observer;
 | 
			
		||||
import androidx.lifecycle.ViewModelProviders;
 | 
			
		||||
import androidx.recyclerview.widget.DividerItemDecoration;
 | 
			
		||||
import androidx.recyclerview.widget.LinearLayoutManager;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
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.ImageView;
 | 
			
		||||
import android.widget.ProgressBar;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.activities.MainActivity;
 | 
			
		||||
import org.mian.gitnex.activities.NewRepoActivity;
 | 
			
		||||
import org.mian.gitnex.adapters.ReposListAdapter;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.models.UserRepositories;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import org.mian.gitnex.viewmodels.RepositoriesListViewModel;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class RepositoriesFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private ProgressBar mProgressBar;
 | 
			
		||||
    private RecyclerView mRecyclerView;
 | 
			
		||||
    private ReposListAdapter adapter;
 | 
			
		||||
    private ImageView createNewRepo;
 | 
			
		||||
    private TextView noDataRepo;
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
 | 
			
		||||
 | 
			
		||||
        final View v = inflater.inflate(R.layout.fragment_repositories, container, false);
 | 
			
		||||
        setHasOptionsMenu(true);
 | 
			
		||||
        ((MainActivity) Objects.requireNonNull(getActivity())).setActionBarTitle(getResources().getString(R.string.pageTitleRepositories));
 | 
			
		||||
 | 
			
		||||
        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");
 | 
			
		||||
 | 
			
		||||
        final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh);
 | 
			
		||||
 | 
			
		||||
        noDataRepo = v.findViewById(R.id.noData);
 | 
			
		||||
        mProgressBar = v.findViewById(R.id.progress_bar);
 | 
			
		||||
        mRecyclerView = v.findViewById(R.id.recyclerView);
 | 
			
		||||
        mRecyclerView.setHasFixedSize(true);
 | 
			
		||||
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
 | 
			
		||||
 | 
			
		||||
        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
 | 
			
		||||
                DividerItemDecoration.VERTICAL);
 | 
			
		||||
        mRecyclerView.addItemDecoration(dividerItemDecoration);
 | 
			
		||||
 | 
			
		||||
        createNewRepo = v.findViewById(R.id.addNewRepo);
 | 
			
		||||
 | 
			
		||||
        createNewRepo.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                Intent intent = new Intent(view.getContext(), NewRepoActivity.class);
 | 
			
		||||
                startActivity(intent);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
 | 
			
		||||
                if (dy > 0 && createNewRepo.isShown()) {
 | 
			
		||||
                    createNewRepo.setVisibility(View.GONE);
 | 
			
		||||
                } else if (dy < 0 ) {
 | 
			
		||||
                    createNewRepo.setVisibility(View.VISIBLE);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
 | 
			
		||||
                super.onScrollStateChanged(recyclerView, newState);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if(connToInternet) {
 | 
			
		||||
 | 
			
		||||
            swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onRefresh() {
 | 
			
		||||
                    new Handler().postDelayed(new Runnable() {
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void run() {
 | 
			
		||||
                            swipeRefresh.setRefreshing(false);
 | 
			
		||||
                            RepositoriesListViewModel.loadReposList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken));
 | 
			
		||||
                        }
 | 
			
		||||
                    }, 50);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken));
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            mProgressBar.setVisibility(View.GONE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onResume() {
 | 
			
		||||
        super.onResume();
 | 
			
		||||
        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(tinyDb.getBoolean("repoCreated")) {
 | 
			
		||||
            RepositoriesListViewModel.loadReposList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken));
 | 
			
		||||
            tinyDb.putBoolean("repoCreated", false);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void fetchDataAsync(String instanceUrl, String instanceToken) {
 | 
			
		||||
 | 
			
		||||
        RepositoriesListViewModel repoModel = ViewModelProviders.of(this).get(RepositoriesListViewModel.class);
 | 
			
		||||
 | 
			
		||||
        repoModel.getUserRepositories(instanceUrl, instanceToken).observe(this, new Observer<List<UserRepositories>>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onChanged(@Nullable List<UserRepositories> reposListMain) {
 | 
			
		||||
                adapter = new ReposListAdapter(getContext(), reposListMain);
 | 
			
		||||
                if(adapter.getItemCount() > 0) {
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noDataRepo.setVisibility(View.GONE);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    adapter.notifyDataSetChanged();
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noDataRepo.setVisibility(View.VISIBLE);
 | 
			
		||||
                }
 | 
			
		||||
                mProgressBar.setVisibility(View.GONE);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
 | 
			
		||||
 | 
			
		||||
        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);
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public boolean onQueryTextSubmit(String query) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public boolean onQueryTextChange(String newText) {
 | 
			
		||||
                adapter.getFilter().filter(newText);
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,345 @@
 | 
			
		||||
package org.mian.gitnex.fragments;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.DialogInterface;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.CompoundButton;
 | 
			
		||||
import android.widget.LinearLayout;
 | 
			
		||||
import android.widget.Switch;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.activities.MainActivity;
 | 
			
		||||
import org.mian.gitnex.helpers.Toasty;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.annotation.Nullable;
 | 
			
		||||
import androidx.appcompat.app.AlertDialog;
 | 
			
		||||
import androidx.fragment.app.Fragment;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class SettingsFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private Context ctx = null;
 | 
			
		||||
 | 
			
		||||
    private static String[] langList = {"English", "French", "German", "Russian"};
 | 
			
		||||
    private static int langSelectedChoice = 0;
 | 
			
		||||
 | 
			
		||||
    private static String[] timeList = {"Pretty", "Normal"};
 | 
			
		||||
    private static int timeSelectedChoice = 0;
 | 
			
		||||
 | 
			
		||||
    private static String[] codeBlockList = {"Green - Black", "White - Black", "Grey - Black", "White - Grey", "Dark - White"};
 | 
			
		||||
    private static int codeBlockSelectedChoice = 0;
 | 
			
		||||
 | 
			
		||||
    private static String[] homeScreenList = {"My Repositories", "Starred Repositories", "Organizations", "Repositories", "Profile"};
 | 
			
		||||
    private static int homeScreenSelectedChoice = 0;
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        ((MainActivity) Objects.requireNonNull(getActivity())).setActionBarTitle(getResources().getString(R.string.pageTitleSettings));
 | 
			
		||||
        View v = inflater.inflate(R.layout.fragment_settings, container, false);
 | 
			
		||||
        final TinyDB tinyDb = new TinyDB(getContext());
 | 
			
		||||
 | 
			
		||||
        final TextView tvLanguageSelected = v.findViewById(R.id.tvLanguageSelected); // setter for en, fr
 | 
			
		||||
        final TextView tvDateTimeSelected = v.findViewById(R.id.tvDateTimeSelected); // setter for time
 | 
			
		||||
        final TextView codeBlockSelected = v.findViewById(R.id.codeBlockSelected); // setter for code block
 | 
			
		||||
        final TextView homeScreenSelected = v.findViewById(R.id.homeScreenSelected); // setter for home screen
 | 
			
		||||
 | 
			
		||||
        LinearLayout langFrame = v.findViewById(R.id.langFrame);
 | 
			
		||||
        LinearLayout timeFrame = v.findViewById(R.id.timeFrame);
 | 
			
		||||
        LinearLayout codeBlockFrame = v.findViewById(R.id.codeBlockFrame);
 | 
			
		||||
        LinearLayout homeScreenFrame = v.findViewById(R.id.homeScreenFrame);
 | 
			
		||||
 | 
			
		||||
        Switch issuesSwitch =  v.findViewById(R.id.switchIssuesBadge);
 | 
			
		||||
        TextView helpTranslate = v.findViewById(R.id.helpTranslate);
 | 
			
		||||
 | 
			
		||||
        helpTranslate.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            public void onClick(View v) {
 | 
			
		||||
                Intent intent = new Intent();
 | 
			
		||||
                intent.setAction(Intent.ACTION_VIEW);
 | 
			
		||||
                intent.addCategory(Intent.CATEGORY_BROWSABLE);
 | 
			
		||||
                intent.setData(Uri.parse(getResources().getString(R.string.appRepoContributingLink)));
 | 
			
		||||
                startActivity(intent);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if(!tinyDb.getString("localeStr").isEmpty()) {
 | 
			
		||||
            tvLanguageSelected.setText(tinyDb.getString("localeStr"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!tinyDb.getString("timeStr").isEmpty()) {
 | 
			
		||||
            tvDateTimeSelected.setText(tinyDb.getString("timeStr"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!tinyDb.getString("codeBlockStr").isEmpty()) {
 | 
			
		||||
            codeBlockSelected.setText(tinyDb.getString("codeBlockStr"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!tinyDb.getString("homeScreenStr").isEmpty()) {
 | 
			
		||||
            homeScreenSelected.setText(tinyDb.getString("homeScreenStr"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(langSelectedChoice == 0) {
 | 
			
		||||
            langSelectedChoice = tinyDb.getInt("langId");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(timeSelectedChoice == 0) {
 | 
			
		||||
            timeSelectedChoice = tinyDb.getInt("timeId");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(codeBlockSelectedChoice == 0) {
 | 
			
		||||
            codeBlockSelectedChoice = tinyDb.getInt("codeBlockId");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(homeScreenSelectedChoice == 0) {
 | 
			
		||||
            homeScreenSelectedChoice = tinyDb.getInt("homeScreenId");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(tinyDb.getBoolean("enableCounterIssueBadge")) {
 | 
			
		||||
            issuesSwitch.setChecked(true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // issues badge switcher
 | 
			
		||||
        issuesSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
 | 
			
		||||
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
 | 
			
		||||
                if (isChecked) {
 | 
			
		||||
                    tinyDb.putBoolean("enableCounterIssueBadge", true);
 | 
			
		||||
                    tinyDb.putString("enableCounterIssueBadgeInit", "yes");
 | 
			
		||||
                    Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
 | 
			
		||||
                } else {
 | 
			
		||||
                    tinyDb.putBoolean("enableCounterIssueBadge", false);
 | 
			
		||||
                    tinyDb.putString("enableCounterIssueBadgeInit", "yes");
 | 
			
		||||
                    Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // home screen dialog
 | 
			
		||||
        homeScreenFrame.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
 | 
			
		||||
                AlertDialog.Builder hsBuilder = new AlertDialog.Builder(ctx, R.style.confirmDialog);
 | 
			
		||||
 | 
			
		||||
                hsBuilder.setTitle(R.string.settingshomeScreenSelectorDialogTitle);
 | 
			
		||||
                if(homeScreenSelectedChoice != -1) {
 | 
			
		||||
                    hsBuilder.setCancelable(true);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    hsBuilder.setCancelable(false);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                hsBuilder.setSingleChoiceItems(homeScreenList, homeScreenSelectedChoice, new DialogInterface.OnClickListener() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void onClick(DialogInterface dialogInterfaceHomeScreen, int i) {
 | 
			
		||||
 | 
			
		||||
                        homeScreenSelectedChoice = i;
 | 
			
		||||
                        homeScreenSelected.setText(homeScreenList[i]);
 | 
			
		||||
                        tinyDb.putString("homeScreenStr", homeScreenList[i]);
 | 
			
		||||
                        tinyDb.putInt("homeScreenId", i);
 | 
			
		||||
 | 
			
		||||
                        dialogInterfaceHomeScreen.dismiss();
 | 
			
		||||
                        Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                AlertDialog hsDialog = hsBuilder.create();
 | 
			
		||||
                hsDialog.show();
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // code block dialog
 | 
			
		||||
        codeBlockFrame.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
 | 
			
		||||
                AlertDialog.Builder cBuilder = new AlertDialog.Builder(ctx, R.style.confirmDialog);
 | 
			
		||||
 | 
			
		||||
                cBuilder.setTitle(R.string.settingsCodeBlockSelectorDialogTitle);
 | 
			
		||||
                if(codeBlockSelectedChoice != -1) {
 | 
			
		||||
                    cBuilder.setCancelable(true);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    cBuilder.setCancelable(false);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                cBuilder.setSingleChoiceItems(codeBlockList, codeBlockSelectedChoice, new DialogInterface.OnClickListener() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void onClick(DialogInterface dialogInterfaceCodeBlock, int i) {
 | 
			
		||||
 | 
			
		||||
                        codeBlockSelectedChoice = i;
 | 
			
		||||
                        codeBlockSelected.setText(codeBlockList[i]);
 | 
			
		||||
                        tinyDb.putString("codeBlockStr", codeBlockList[i]);
 | 
			
		||||
                        tinyDb.putInt("codeBlockId", i);
 | 
			
		||||
 | 
			
		||||
                        switch (codeBlockList[i]) {
 | 
			
		||||
                            case "Green - Black":
 | 
			
		||||
                                tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorLightGreen));
 | 
			
		||||
                                tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.black));
 | 
			
		||||
                                break;
 | 
			
		||||
                            case "White - Black":
 | 
			
		||||
                                tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.white));
 | 
			
		||||
                                tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.black));
 | 
			
		||||
                                break;
 | 
			
		||||
                            case "Grey - Black":
 | 
			
		||||
                                tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorAccent));
 | 
			
		||||
                                tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.black));
 | 
			
		||||
                                break;
 | 
			
		||||
                            case "White - Grey":
 | 
			
		||||
                                tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.white));
 | 
			
		||||
                                tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.colorAccent));
 | 
			
		||||
                                break;
 | 
			
		||||
                            case "Dark - White":
 | 
			
		||||
                                tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorPrimary));
 | 
			
		||||
                                tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.white));
 | 
			
		||||
                                break;
 | 
			
		||||
                            default:
 | 
			
		||||
                                tinyDb.putInt("codeBlockColor", getResources().getColor(R.color.colorLightGreen));
 | 
			
		||||
                                tinyDb.putInt("codeBlockBackground", getResources().getColor(R.color.black));
 | 
			
		||||
                                break;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        dialogInterfaceCodeBlock.dismiss();
 | 
			
		||||
                        Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                AlertDialog cDialog = cBuilder.create();
 | 
			
		||||
                cDialog.show();
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // language dialog
 | 
			
		||||
        langFrame.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
 | 
			
		||||
                AlertDialog.Builder lBuilder = new AlertDialog.Builder(ctx, R.style.confirmDialog);
 | 
			
		||||
 | 
			
		||||
                lBuilder.setTitle(R.string.settingsLanguageSelectorDialogTitle);
 | 
			
		||||
                if(langSelectedChoice != -1) {
 | 
			
		||||
                    lBuilder.setCancelable(true);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    lBuilder.setCancelable(false);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                lBuilder.setSingleChoiceItems(langList, langSelectedChoice, new DialogInterface.OnClickListener() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void onClick(DialogInterface dialogInterface, int i) {
 | 
			
		||||
 | 
			
		||||
                        langSelectedChoice = i;
 | 
			
		||||
                        tvLanguageSelected.setText(langList[i]);
 | 
			
		||||
                        tinyDb.putString("localeStr", langList[i]);
 | 
			
		||||
                        tinyDb.putInt("langId", i);
 | 
			
		||||
 | 
			
		||||
                        switch (langList[i]) {
 | 
			
		||||
                            case "English":
 | 
			
		||||
                                tinyDb.putString("locale", "en");
 | 
			
		||||
                                break;
 | 
			
		||||
                            case "French":
 | 
			
		||||
                                tinyDb.putString("locale", "fr");
 | 
			
		||||
                                break;
 | 
			
		||||
                            case "German":
 | 
			
		||||
                                tinyDb.putString("locale", "de");
 | 
			
		||||
                                break;
 | 
			
		||||
                            case "Russian":
 | 
			
		||||
                                tinyDb.putString("locale", "ru");
 | 
			
		||||
                                break;
 | 
			
		||||
                            default:
 | 
			
		||||
                                tinyDb.putString("locale", "en");
 | 
			
		||||
                                break;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        dialogInterface.dismiss();
 | 
			
		||||
                        Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
 | 
			
		||||
                        Objects.requireNonNull(getActivity()).recreate();
 | 
			
		||||
                        getActivity().overridePendingTransition(0, 0);
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
                lBuilder.setNegativeButton(getString(R.string.cancelButton), new DialogInterface.OnClickListener() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void onClick(DialogInterface dialog, int which) {
 | 
			
		||||
                        dialog.dismiss();
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                AlertDialog lDialog = lBuilder.create();
 | 
			
		||||
                lDialog.show();
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // time n date dialog
 | 
			
		||||
        timeFrame.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
 | 
			
		||||
                AlertDialog.Builder tBuilder = new AlertDialog.Builder(ctx, R.style.confirmDialog);
 | 
			
		||||
 | 
			
		||||
                tBuilder.setTitle(R.string.settingsTimeSelectorDialogTitle);
 | 
			
		||||
                if(timeSelectedChoice != -1) {
 | 
			
		||||
                    tBuilder.setCancelable(true);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    tBuilder.setCancelable(false);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                tBuilder.setSingleChoiceItems(timeList, timeSelectedChoice, new DialogInterface.OnClickListener() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void onClick(DialogInterface dialogInterfaceTime, int i) {
 | 
			
		||||
 | 
			
		||||
                        timeSelectedChoice = i;
 | 
			
		||||
                        tvDateTimeSelected.setText(timeList[i]);
 | 
			
		||||
                        tinyDb.putString("timeStr", timeList[i]);
 | 
			
		||||
                        tinyDb.putInt("timeId", i);
 | 
			
		||||
 | 
			
		||||
                        switch (timeList[i]) {
 | 
			
		||||
                            case "Pretty":
 | 
			
		||||
                                tinyDb.putString("dateFormat", "pretty");
 | 
			
		||||
                                break;
 | 
			
		||||
                            case "Normal":
 | 
			
		||||
                                tinyDb.putString("dateFormat", "normal");
 | 
			
		||||
                                break;
 | 
			
		||||
                            default:
 | 
			
		||||
                                tinyDb.putString("dateFormat", "pretty");
 | 
			
		||||
                                break;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        dialogInterfaceTime.dismiss();
 | 
			
		||||
                        Toasty.info(getContext(), getResources().getString(R.string.settingsSave));
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                AlertDialog tDialog = tBuilder.create();
 | 
			
		||||
                tDialog.show();
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onAttach(@NonNull Context context) {
 | 
			
		||||
        super.onAttach(context);
 | 
			
		||||
        ctx = context;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,115 @@
 | 
			
		||||
package org.mian.gitnex.fragments;
 | 
			
		||||
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.actions.IssueActions;
 | 
			
		||||
import org.mian.gitnex.activities.AddRemoveAssigneesActivity;
 | 
			
		||||
import org.mian.gitnex.activities.AddRemoveLabelsActivity;
 | 
			
		||||
import org.mian.gitnex.activities.EditIssueActivity;
 | 
			
		||||
import org.mian.gitnex.activities.ReplyToIssueActivity;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.annotation.Nullable;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class SingleIssueBottomSheetFragment extends BottomSheetDialogFragment {
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        View v = inflater.inflate(R.layout.single_issue_bottom_sheet_layout, container, false);
 | 
			
		||||
 | 
			
		||||
        final TinyDB tinyDB = new TinyDB(getContext());
 | 
			
		||||
 | 
			
		||||
        TextView replyToIssue = v.findViewById(R.id.replyToIssue);
 | 
			
		||||
        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);
 | 
			
		||||
 | 
			
		||||
        replyToIssue.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
                startActivity(new Intent(getContext(), ReplyToIssueActivity.class));
 | 
			
		||||
                dismiss();
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        editIssue.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
                startActivity(new Intent(getContext(), EditIssueActivity.class));
 | 
			
		||||
                dismiss();
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        editLabels.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
                startActivity(new Intent(getContext(), AddRemoveLabelsActivity.class));
 | 
			
		||||
                dismiss();
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        addRemoveAssignees.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
                startActivity(new Intent(getContext(), AddRemoveAssigneesActivity.class));
 | 
			
		||||
                dismiss();
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if(tinyDB.getString("issueState").equals("open")) { // close issue
 | 
			
		||||
 | 
			
		||||
            reOpenIssue.setVisibility(View.GONE);
 | 
			
		||||
 | 
			
		||||
            closeIssue.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
                    IssueActions.closeReopenIssue(getContext(), Integer.valueOf(tinyDB.getString("issueNumber")), "closed");
 | 
			
		||||
                    dismiss();
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        else if(tinyDB.getString("issueState").equals("closed")) {
 | 
			
		||||
 | 
			
		||||
            closeIssue.setVisibility(View.GONE);
 | 
			
		||||
 | 
			
		||||
            reOpenIssue.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onClick(View v) {
 | 
			
		||||
 | 
			
		||||
                    IssueActions.closeReopenIssue(getContext(), Integer.valueOf(tinyDB.getString("issueNumber")), "open");
 | 
			
		||||
                    dismiss();
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,236 @@
 | 
			
		||||
package org.mian.gitnex.fragments;
 | 
			
		||||
 | 
			
		||||
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.ViewModelProviders;
 | 
			
		||||
import androidx.recyclerview.widget.DividerItemDecoration;
 | 
			
		||||
import androidx.recyclerview.widget.LinearLayoutManager;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.Menu;
 | 
			
		||||
import android.view.MenuInflater;
 | 
			
		||||
import android.view.MenuItem;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.view.inputmethod.EditorInfo;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.ProgressBar;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.activities.MainActivity;
 | 
			
		||||
import org.mian.gitnex.activities.NewRepoActivity;
 | 
			
		||||
import org.mian.gitnex.adapters.StarredReposListAdapter;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.models.UserRepositories;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import org.mian.gitnex.viewmodels.StarredRepositoriesViewModel;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class StarredRepositoriesFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private static final String ARG_PARAM1 = "param1";
 | 
			
		||||
    private static final String ARG_PARAM2 = "param2";
 | 
			
		||||
    private ProgressBar mProgressBar;
 | 
			
		||||
    private RecyclerView mRecyclerView;
 | 
			
		||||
    private StarredReposListAdapter adapter;
 | 
			
		||||
    private ImageView createNewRepo;
 | 
			
		||||
    private TextView noData;
 | 
			
		||||
 | 
			
		||||
    private OnFragmentInteractionListener mListener;
 | 
			
		||||
 | 
			
		||||
    public StarredRepositoriesFragment() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static StarredRepositoriesFragment newInstance(String param1, String param2) {
 | 
			
		||||
        StarredRepositoriesFragment fragment = new StarredRepositoriesFragment();
 | 
			
		||||
        Bundle args = new Bundle();
 | 
			
		||||
        args.putString(ARG_PARAM1, param1);
 | 
			
		||||
        args.putString(ARG_PARAM2, param2);
 | 
			
		||||
        fragment.setArguments(args);
 | 
			
		||||
        return fragment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        if (getArguments() != null) {
 | 
			
		||||
            String mParam1 = getArguments().getString(ARG_PARAM1);
 | 
			
		||||
            String mParam2 = getArguments().getString(ARG_PARAM2);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
 | 
			
		||||
                             Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        View v = inflater.inflate(R.layout.fragment_starred_repositories, container, false);
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
 | 
			
		||||
        setHasOptionsMenu(true);
 | 
			
		||||
        ((MainActivity) Objects.requireNonNull(getActivity())).setActionBarTitle(getResources().getString(R.string.pageTitleStarredRepos));
 | 
			
		||||
 | 
			
		||||
        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");
 | 
			
		||||
 | 
			
		||||
        final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh);
 | 
			
		||||
 | 
			
		||||
        noData = v.findViewById(R.id.noData);
 | 
			
		||||
        mProgressBar = v.findViewById(R.id.progress_bar);
 | 
			
		||||
        mRecyclerView = v.findViewById(R.id.recyclerView);
 | 
			
		||||
        mRecyclerView.setHasFixedSize(true);
 | 
			
		||||
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
 | 
			
		||||
 | 
			
		||||
        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
 | 
			
		||||
                DividerItemDecoration.VERTICAL);
 | 
			
		||||
        mRecyclerView.addItemDecoration(dividerItemDecoration);
 | 
			
		||||
 | 
			
		||||
        createNewRepo = v.findViewById(R.id.addNewRepo);
 | 
			
		||||
 | 
			
		||||
        createNewRepo.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                Intent intent = new Intent(view.getContext(), NewRepoActivity.class);
 | 
			
		||||
                startActivity(intent);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
 | 
			
		||||
                if (dy > 0 && createNewRepo.isShown()) {
 | 
			
		||||
                    createNewRepo.setVisibility(View.GONE);
 | 
			
		||||
                } else if (dy < 0 ) {
 | 
			
		||||
                    createNewRepo.setVisibility(View.VISIBLE);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
 | 
			
		||||
                super.onScrollStateChanged(recyclerView, newState);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if(connToInternet) {
 | 
			
		||||
 | 
			
		||||
            swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void onRefresh() {
 | 
			
		||||
                    new Handler().postDelayed(new Runnable() {
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void run() {
 | 
			
		||||
                            swipeRefresh.setRefreshing(false);
 | 
			
		||||
                            StarredRepositoriesViewModel.loadStarredReposList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken));
 | 
			
		||||
                        }
 | 
			
		||||
                    }, 50);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken));
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            mProgressBar.setVisibility(View.GONE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onResume() {
 | 
			
		||||
        super.onResume();
 | 
			
		||||
        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");
 | 
			
		||||
 | 
			
		||||
        StarredRepositoriesViewModel.loadStarredReposList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken));
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void fetchDataAsync(String instanceUrl, String instanceToken) {
 | 
			
		||||
 | 
			
		||||
        StarredRepositoriesViewModel starredRepoModel = ViewModelProviders.of(this).get(StarredRepositoriesViewModel.class);
 | 
			
		||||
 | 
			
		||||
        starredRepoModel.getUserStarredRepositories(instanceUrl, instanceToken).observe(this, new Observer<List<UserRepositories>>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onChanged(@Nullable List<UserRepositories> starredReposListMain) {
 | 
			
		||||
                adapter = new StarredReposListAdapter(getContext(), starredReposListMain);
 | 
			
		||||
                if(adapter.getItemCount() > 0) {
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noData.setVisibility(View.GONE);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    adapter.notifyDataSetChanged();
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noData.setVisibility(View.VISIBLE);
 | 
			
		||||
                }
 | 
			
		||||
                mProgressBar.setVisibility(View.GONE);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
 | 
			
		||||
 | 
			
		||||
        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);
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public boolean onQueryTextSubmit(String query) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public boolean onQueryTextChange(String newText) {
 | 
			
		||||
                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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,194 @@
 | 
			
		||||
package org.mian.gitnex.fragments;
 | 
			
		||||
 | 
			
		||||
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.ViewModelProviders;
 | 
			
		||||
import androidx.recyclerview.widget.DividerItemDecoration;
 | 
			
		||||
import androidx.recyclerview.widget.LinearLayoutManager;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.Menu;
 | 
			
		||||
import android.view.MenuInflater;
 | 
			
		||||
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.adapters.TeamsByOrgAdapter;
 | 
			
		||||
import org.mian.gitnex.helpers.Authorization;
 | 
			
		||||
import org.mian.gitnex.models.Teams;
 | 
			
		||||
import org.mian.gitnex.util.AppUtil;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import org.mian.gitnex.viewmodels.TeamsByOrgViewModel;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class TeamsByOrgFragment extends Fragment {
 | 
			
		||||
 | 
			
		||||
    private RepositoriesByOrgFragment.OnFragmentInteractionListener mListener;
 | 
			
		||||
 | 
			
		||||
    private ProgressBar mProgressBar;
 | 
			
		||||
    private RecyclerView mRecyclerView;
 | 
			
		||||
    private TextView noDataTeams;
 | 
			
		||||
    private static String orgNameF = "param2";
 | 
			
		||||
    private String orgName;
 | 
			
		||||
    private TeamsByOrgAdapter adapter;
 | 
			
		||||
 | 
			
		||||
    public TeamsByOrgFragment() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static TeamsByOrgFragment newInstance(String param1) {
 | 
			
		||||
        TeamsByOrgFragment fragment = new TeamsByOrgFragment();
 | 
			
		||||
        Bundle args = new Bundle();
 | 
			
		||||
        args.putString(orgNameF, param1);
 | 
			
		||||
        fragment.setArguments(args);
 | 
			
		||||
        return fragment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
        super.onCreate(savedInstanceState);
 | 
			
		||||
        if (getArguments() != null) {
 | 
			
		||||
            orgName = getArguments().getString(orgNameF);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
 | 
			
		||||
                             Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        View v = inflater.inflate(R.layout.fragment_teams_by_org, 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");
 | 
			
		||||
        noDataTeams = v.findViewById(R.id.noDataTeams);
 | 
			
		||||
 | 
			
		||||
        final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh);
 | 
			
		||||
 | 
			
		||||
        mRecyclerView = v.findViewById(R.id.recyclerView);
 | 
			
		||||
        mRecyclerView.setHasFixedSize(true);
 | 
			
		||||
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
 | 
			
		||||
 | 
			
		||||
        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
 | 
			
		||||
                DividerItemDecoration.VERTICAL);
 | 
			
		||||
        mRecyclerView.addItemDecoration(dividerItemDecoration);
 | 
			
		||||
 | 
			
		||||
        mProgressBar = v.findViewById(R.id.progress_bar);
 | 
			
		||||
 | 
			
		||||
        swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onRefresh() {
 | 
			
		||||
                new Handler().postDelayed(new Runnable() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        swipeRefresh.setRefreshing(false);
 | 
			
		||||
                        TeamsByOrgViewModel.loadTeamsByOrgList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), orgName);
 | 
			
		||||
                    }
 | 
			
		||||
                }, 200);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), orgName);
 | 
			
		||||
 | 
			
		||||
        return v;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onResume() {
 | 
			
		||||
        super.onResume();
 | 
			
		||||
        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(tinyDb.getBoolean("resumeTeams")) {
 | 
			
		||||
            TeamsByOrgViewModel.loadTeamsByOrgList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), orgName);
 | 
			
		||||
            tinyDb.putBoolean("resumeTeams", false);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void fetchDataAsync(String instanceUrl, String instanceToken, String owner) {
 | 
			
		||||
 | 
			
		||||
        TeamsByOrgViewModel teamModel = ViewModelProviders.of(this).get(TeamsByOrgViewModel.class);
 | 
			
		||||
 | 
			
		||||
        teamModel.getTeamsByOrg(instanceUrl, instanceToken, owner).observe(this, new Observer<List<Teams>>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onChanged(@Nullable List<Teams> orgTeamsListMain) {
 | 
			
		||||
                adapter = new TeamsByOrgAdapter(getContext(), orgTeamsListMain);
 | 
			
		||||
                if(adapter.getItemCount() > 0) {
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noDataTeams.setVisibility(View.GONE);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    adapter.notifyDataSetChanged();
 | 
			
		||||
                    mRecyclerView.setAdapter(adapter);
 | 
			
		||||
                    noDataTeams.setVisibility(View.VISIBLE);
 | 
			
		||||
                }
 | 
			
		||||
                mProgressBar.setVisibility(View.GONE);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
 | 
			
		||||
 | 
			
		||||
        boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext()));
 | 
			
		||||
 | 
			
		||||
        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);
 | 
			
		||||
 | 
			
		||||
        if(!connToInternet) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public boolean onQueryTextSubmit(String query) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public boolean onQueryTextChange(String newText) {
 | 
			
		||||
                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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										88
									
								
								app/src/main/java/org/mian/gitnex/helpers/AlertDialogs.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								app/src/main/java/org/mian/gitnex/helpers/AlertDialogs.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,88 @@
 | 
			
		||||
package org.mian.gitnex.helpers;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.DialogInterface;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.activities.CreateLabelActivity;
 | 
			
		||||
import org.mian.gitnex.activities.LoginActivity;
 | 
			
		||||
import org.mian.gitnex.actions.CollaboratorActions;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import androidx.appcompat.app.AlertDialog;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class AlertDialogs {
 | 
			
		||||
 | 
			
		||||
    public static void authorizationTokenRevokedDialog(final Context context, String title, String message, String copyNegativeButton, String copyPositiveButton) {
 | 
			
		||||
 | 
			
		||||
        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context, R.style.confirmDialog);
 | 
			
		||||
 | 
			
		||||
        alertDialogBuilder
 | 
			
		||||
                .setTitle(title)
 | 
			
		||||
                .setMessage(message)
 | 
			
		||||
                .setCancelable(true)
 | 
			
		||||
                .setIcon(R.drawable.ic_warning)
 | 
			
		||||
                .setNegativeButton(copyNegativeButton, new DialogInterface.OnClickListener() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void onClick(DialogInterface dialog, int which) {
 | 
			
		||||
                        dialog.dismiss();
 | 
			
		||||
                    }
 | 
			
		||||
                })
 | 
			
		||||
                .setPositiveButton(copyPositiveButton, new DialogInterface.OnClickListener() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void onClick(DialogInterface dialog, int which) {
 | 
			
		||||
 | 
			
		||||
                        final TinyDB tinyDb = new TinyDB(context);
 | 
			
		||||
                        tinyDb.putBoolean("loggedInMode", false);
 | 
			
		||||
                        tinyDb.remove("basicAuthPassword");
 | 
			
		||||
                        tinyDb.putBoolean("basicAuthFlag", false);
 | 
			
		||||
                        Intent intent = new Intent(context, LoginActivity.class);
 | 
			
		||||
                        context.startActivity(intent);
 | 
			
		||||
                        dialog.dismiss();
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
        AlertDialog alertDialog = alertDialogBuilder.create();
 | 
			
		||||
 | 
			
		||||
        alertDialog.show();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void labelDeleteDialog(final Context context, final String labelTitle, final String labelId, String title, String message, String positiveButton, String negativeButton) {
 | 
			
		||||
 | 
			
		||||
        new AlertDialog.Builder(context, R.style.confirmDialog)
 | 
			
		||||
            .setTitle(title + labelTitle)
 | 
			
		||||
            .setMessage(message)
 | 
			
		||||
            .setIcon(R.drawable.ic_delete)
 | 
			
		||||
            .setPositiveButton(positiveButton, new DialogInterface.OnClickListener() {
 | 
			
		||||
                public void onClick(DialogInterface dialog, int whichButton) {
 | 
			
		||||
 | 
			
		||||
                    Intent intent = new Intent(context, CreateLabelActivity.class);
 | 
			
		||||
                    intent.putExtra("labelId", labelId);
 | 
			
		||||
                    intent.putExtra("labelAction", "delete");
 | 
			
		||||
                    context.startActivity(intent);
 | 
			
		||||
 | 
			
		||||
                }})
 | 
			
		||||
            .setNegativeButton(negativeButton, null).show();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void collaboratorRemoveDialog(final Context context, final String userNameMain, String title, String message, String positiveButton, String negativeButton, final String searchKeyword) {
 | 
			
		||||
 | 
			
		||||
        new AlertDialog.Builder(context, R.style.confirmDialog)
 | 
			
		||||
                .setTitle(title + userNameMain)
 | 
			
		||||
                .setMessage(message)
 | 
			
		||||
                .setIcon(R.drawable.ic_warning)
 | 
			
		||||
                .setPositiveButton(positiveButton, new DialogInterface.OnClickListener() {
 | 
			
		||||
                    public void onClick(DialogInterface dialog, int whichButton) {
 | 
			
		||||
 | 
			
		||||
                        CollaboratorActions.deleteCollaborator(context,  searchKeyword, userNameMain);
 | 
			
		||||
 | 
			
		||||
                    }})
 | 
			
		||||
                .setNegativeButton(negativeButton, null).show();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								app/src/main/java/org/mian/gitnex/helpers/Authorization.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								app/src/main/java/org/mian/gitnex/helpers/Authorization.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
package org.mian.gitnex.helpers;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import org.mian.gitnex.util.TinyDB;
 | 
			
		||||
import okhttp3.Credentials;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class Authorization {
 | 
			
		||||
 | 
			
		||||
    public static String returnAuthentication(Context context, String loginUid, String token) {
 | 
			
		||||
 | 
			
		||||
        TinyDB tinyDb = new TinyDB(context);
 | 
			
		||||
 | 
			
		||||
        String credential;
 | 
			
		||||
 | 
			
		||||
        if(tinyDb.getBoolean("basicAuthFlag")) {
 | 
			
		||||
 | 
			
		||||
            if (!tinyDb.getString("basicAuthPassword").isEmpty()) {
 | 
			
		||||
 | 
			
		||||
                credential = Credentials.basic(loginUid, tinyDb.getString("basicAuthPassword"));
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
 | 
			
		||||
                credential = token;
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
 | 
			
		||||
            credential = token;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return credential;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								app/src/main/java/org/mian/gitnex/helpers/ClickListener.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								app/src/main/java/org/mian/gitnex/helpers/ClickListener.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
package org.mian.gitnex.helpers;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import android.widget.Toast;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class ClickListener implements View.OnClickListener {
 | 
			
		||||
 | 
			
		||||
    private String infoText;
 | 
			
		||||
    private Context mCtx;
 | 
			
		||||
 | 
			
		||||
    public ClickListener(String infoText, Context mCtx) {
 | 
			
		||||
        this.infoText = infoText;
 | 
			
		||||
        this.mCtx = mCtx;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onClick(View v)
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        LayoutInflater inflater1 = LayoutInflater.from(mCtx);
 | 
			
		||||
        View layout = inflater1.inflate(R.layout.custom_toast,
 | 
			
		||||
                (ViewGroup) v.findViewById(R.id.custom_toast_container));
 | 
			
		||||
 | 
			
		||||
        TextView text = layout.findViewById(R.id.toastText);
 | 
			
		||||
        text.setText(infoText);
 | 
			
		||||
 | 
			
		||||
        Toast toast = new Toast(mCtx.getApplicationContext());
 | 
			
		||||
        toast.setDuration(Toast.LENGTH_LONG);
 | 
			
		||||
        toast.setView(layout);
 | 
			
		||||
        toast.show();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										27
									
								
								app/src/main/java/org/mian/gitnex/helpers/ColorInverter.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								app/src/main/java/org/mian/gitnex/helpers/ColorInverter.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
package org.mian.gitnex.helpers;
 | 
			
		||||
 | 
			
		||||
import android.graphics.Color;
 | 
			
		||||
import androidx.annotation.ColorInt;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class ColorInverter {
 | 
			
		||||
 | 
			
		||||
    @ColorInt
 | 
			
		||||
    public int getContrastColor(@ColorInt int color) {
 | 
			
		||||
 | 
			
		||||
        double a = 1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255;
 | 
			
		||||
 | 
			
		||||
        int d;
 | 
			
		||||
        if (a < 0.5) {
 | 
			
		||||
            d = 0; // black
 | 
			
		||||
        } else {
 | 
			
		||||
            d = 255; // white
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return Color.rgb(d, d, d);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,78 @@
 | 
			
		||||
package org.mian.gitnex.helpers;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class LabelWidthCalculator {
 | 
			
		||||
 | 
			
		||||
    public static int customWidth(int labelLength) {
 | 
			
		||||
 | 
			
		||||
        int width = 33;
 | 
			
		||||
 | 
			
		||||
        if(labelLength == 20) {
 | 
			
		||||
            width = ((width * labelLength) - 150);
 | 
			
		||||
        }
 | 
			
		||||
        else if(labelLength == 19) {
 | 
			
		||||
            width = ((width * labelLength) - 140);
 | 
			
		||||
        }
 | 
			
		||||
        else if(labelLength == 18) {
 | 
			
		||||
            width = ((width * labelLength) - 130);
 | 
			
		||||
        }
 | 
			
		||||
        else if(labelLength == 17) {
 | 
			
		||||
            width = ((width * labelLength) - 120);
 | 
			
		||||
        }
 | 
			
		||||
        else if(labelLength == 16) {
 | 
			
		||||
            width = ((width * labelLength) - 110);
 | 
			
		||||
        }
 | 
			
		||||
        else if(labelLength == 15) {
 | 
			
		||||
            width = ((width * labelLength) - 100);
 | 
			
		||||
        }
 | 
			
		||||
        else if(labelLength == 14) {
 | 
			
		||||
            width = ((width * labelLength) - 90);
 | 
			
		||||
        }
 | 
			
		||||
        else if(labelLength == 13) {
 | 
			
		||||
            width = ((width * labelLength) - 80);
 | 
			
		||||
        }
 | 
			
		||||
        else if(labelLength == 12) {
 | 
			
		||||
            width = ((width * labelLength) - 70);
 | 
			
		||||
        }
 | 
			
		||||
        else if(labelLength == 11) {
 | 
			
		||||
            width = ((width * labelLength) - 60);
 | 
			
		||||
        }
 | 
			
		||||
        else if(labelLength == 10) {
 | 
			
		||||
            width = ((width * labelLength) - 50);
 | 
			
		||||
        }
 | 
			
		||||
        else if(labelLength == 9) {
 | 
			
		||||
            width = ((width * labelLength) - 40);
 | 
			
		||||
        }
 | 
			
		||||
        else if(labelLength == 8) {
 | 
			
		||||
            width = ((width * labelLength) - 30);
 | 
			
		||||
        }
 | 
			
		||||
        else if(labelLength == 7) {
 | 
			
		||||
            width = ((width * labelLength) - 20);
 | 
			
		||||
        }
 | 
			
		||||
        else if(labelLength == 6) {
 | 
			
		||||
            width = ((width * labelLength) - 10);
 | 
			
		||||
        }
 | 
			
		||||
        else if(labelLength == 5) {
 | 
			
		||||
            width = ((width * labelLength) - 10);
 | 
			
		||||
        }
 | 
			
		||||
        else if(labelLength == 4) {
 | 
			
		||||
            width = ((width * labelLength) - 10);
 | 
			
		||||
        }
 | 
			
		||||
        else if(labelLength == 3) {
 | 
			
		||||
            width = ((width * labelLength) - 10);
 | 
			
		||||
        }
 | 
			
		||||
        else if(labelLength == 2) {
 | 
			
		||||
            width = ((width * labelLength));
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            width = (width * labelLength - 5);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return width;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										317
									
								
								app/src/main/java/org/mian/gitnex/helpers/MultiSelectDialog.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										317
									
								
								app/src/main/java/org/mian/gitnex/helpers/MultiSelectDialog.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,317 @@
 | 
			
		||||
package org.mian.gitnex.helpers;
 | 
			
		||||
 | 
			
		||||
import android.annotation.SuppressLint;
 | 
			
		||||
import android.app.Dialog;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.util.TypedValue;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.view.Window;
 | 
			
		||||
import android.view.WindowManager;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import android.widget.Toast;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import org.mian.gitnex.adapters.MutliSelectAdapter;
 | 
			
		||||
import org.mian.gitnex.models.MultiSelectModel;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.app.AppCompatDialogFragment;
 | 
			
		||||
import androidx.appcompat.widget.SearchView;
 | 
			
		||||
import androidx.recyclerview.widget.LinearLayoutManager;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author com.github.abumoallim, modified by M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class MultiSelectDialog extends AppCompatDialogFragment implements SearchView.OnQueryTextListener, View.OnClickListener {
 | 
			
		||||
 | 
			
		||||
    public static ArrayList<Integer> selectedIdsForCallback = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
    public ArrayList<MultiSelectModel> mainListOfAdapter = new ArrayList<>();
 | 
			
		||||
    private MutliSelectAdapter mutliSelectAdapter;
 | 
			
		||||
    //Default Values
 | 
			
		||||
    private String title;
 | 
			
		||||
    private float titleSize = 25;
 | 
			
		||||
    private String positiveText = "DONE";
 | 
			
		||||
    private String negativeText = "CANCEL";
 | 
			
		||||
    private TextView dialogTitle, dialogSubmit, dialogCancel;
 | 
			
		||||
    private ArrayList<Integer> previouslySelectedIdsList = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
    private ArrayList<Integer> tempPreviouslySelectedIdsList = new ArrayList<>();
 | 
			
		||||
    private ArrayList<MultiSelectModel> tempMainListOfAdapter = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
    private SubmitCallbackListener submitCallbackListener;
 | 
			
		||||
 | 
			
		||||
    private int minSelectionLimit = 1;
 | 
			
		||||
    private String minSelectionMessage = null;
 | 
			
		||||
    private int maxSelectionLimit = 0;
 | 
			
		||||
    private String maxSelectionMessage = null;
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
    @Override
 | 
			
		||||
    public Dialog onCreateDialog(Bundle savedInstanceState) {
 | 
			
		||||
 | 
			
		||||
        final Dialog dialog = new Dialog(Objects.requireNonNull(getActivity()));
 | 
			
		||||
        Objects.requireNonNull(dialog.getWindow()).requestFeature(Window.FEATURE_NO_TITLE);
 | 
			
		||||
        dialog.getWindow().setFlags(
 | 
			
		||||
                WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN,
 | 
			
		||||
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
 | 
			
		||||
 | 
			
		||||
        dialog.setContentView(R.layout.custom_multi_select);
 | 
			
		||||
        dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
 | 
			
		||||
 | 
			
		||||
        RecyclerViewEmptySupport mrecyclerView =  dialog.findViewById(R.id.recycler_view);
 | 
			
		||||
        SearchView searchView =  dialog.findViewById(R.id.search_view);
 | 
			
		||||
        dialogTitle =  dialog.findViewById(R.id.title);
 | 
			
		||||
        dialogSubmit =  dialog.findViewById(R.id.done);
 | 
			
		||||
        dialogCancel =  dialog.findViewById(R.id.cancel);
 | 
			
		||||
 | 
			
		||||
        mrecyclerView.setEmptyView(dialog.findViewById(R.id.list_empty1));
 | 
			
		||||
        @SuppressLint("WrongConstant") LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
 | 
			
		||||
        mrecyclerView.setLayoutManager(layoutManager);
 | 
			
		||||
 | 
			
		||||
        dialogSubmit.setOnClickListener(this);
 | 
			
		||||
        dialogCancel.setOnClickListener(this);
 | 
			
		||||
 | 
			
		||||
        settingValues();
 | 
			
		||||
 | 
			
		||||
        mainListOfAdapter = setCheckedIDS(mainListOfAdapter, previouslySelectedIdsList);
 | 
			
		||||
        mutliSelectAdapter = new MutliSelectAdapter(mainListOfAdapter, getContext());
 | 
			
		||||
        mrecyclerView.setAdapter(mutliSelectAdapter);
 | 
			
		||||
 | 
			
		||||
        searchView.setOnQueryTextListener(this);
 | 
			
		||||
        searchView.onActionViewExpanded();
 | 
			
		||||
        searchView.clearFocus();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        return dialog;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MultiSelectDialog title(String title) {
 | 
			
		||||
        this.title = title;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MultiSelectDialog titleSize(float titleSize) {
 | 
			
		||||
        this.titleSize = titleSize;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MultiSelectDialog positiveText(@NonNull String message) {
 | 
			
		||||
        this.positiveText = message;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MultiSelectDialog negativeText(@NonNull String message) {
 | 
			
		||||
        this.negativeText = message;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MultiSelectDialog preSelectIDsList(ArrayList<Integer> list) {
 | 
			
		||||
        this.previouslySelectedIdsList = list;
 | 
			
		||||
        this.tempPreviouslySelectedIdsList = new ArrayList<>(previouslySelectedIdsList);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MultiSelectDialog multiSelectList(ArrayList<MultiSelectModel> list) {
 | 
			
		||||
        this.mainListOfAdapter = list;
 | 
			
		||||
        this.tempMainListOfAdapter = new ArrayList<>(mainListOfAdapter);
 | 
			
		||||
        if(maxSelectionLimit == 0)
 | 
			
		||||
            maxSelectionLimit = list.size();
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MultiSelectDialog setMaxSelectionLimit(int limit){
 | 
			
		||||
        this.maxSelectionLimit = limit;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MultiSelectDialog setMaxSelectionMessage(String message) {
 | 
			
		||||
        this.maxSelectionMessage = message;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MultiSelectDialog setMinSelectionLimit(int limit){
 | 
			
		||||
        this.minSelectionLimit = limit;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MultiSelectDialog setMinSelectionMessage(String message) {
 | 
			
		||||
        this.minSelectionMessage = message;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MultiSelectDialog onSubmit(@NonNull SubmitCallbackListener callback) {
 | 
			
		||||
        this.submitCallbackListener = callback;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void settingValues() {
 | 
			
		||||
        dialogTitle.setText(title);
 | 
			
		||||
        dialogTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, titleSize);
 | 
			
		||||
        dialogSubmit.setText(positiveText.toUpperCase());
 | 
			
		||||
        dialogCancel.setText(negativeText.toUpperCase());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private ArrayList<MultiSelectModel> setCheckedIDS(ArrayList<MultiSelectModel> multiselectdata, ArrayList<Integer> listOfIdsSelected) {
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < multiselectdata.size(); i++) {
 | 
			
		||||
            multiselectdata.get(i).setSelected(false);
 | 
			
		||||
            for (int j = 0; j < listOfIdsSelected.size(); j++) {
 | 
			
		||||
                if (listOfIdsSelected.get(j) == (multiselectdata.get(i).getId())) {
 | 
			
		||||
                    multiselectdata.get(i).setSelected(true);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return multiselectdata;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private ArrayList<MultiSelectModel> filter(ArrayList<MultiSelectModel> models, String query) {
 | 
			
		||||
 | 
			
		||||
        query = query.toLowerCase();
 | 
			
		||||
        final ArrayList<MultiSelectModel> filteredModelList = new ArrayList<>();
 | 
			
		||||
        if (query.equals("") | query.isEmpty()) {
 | 
			
		||||
            filteredModelList.addAll(models);
 | 
			
		||||
            return filteredModelList;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (MultiSelectModel model : models) {
 | 
			
		||||
            final String name = model.getName().toLowerCase();
 | 
			
		||||
            if (name.contains(query)) {
 | 
			
		||||
                filteredModelList.add(model);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return filteredModelList;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean onQueryTextSubmit(String query) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean onQueryTextChange(String newText) {
 | 
			
		||||
 | 
			
		||||
        selectedIdsForCallback = previouslySelectedIdsList;
 | 
			
		||||
        mainListOfAdapter = setCheckedIDS(mainListOfAdapter, selectedIdsForCallback);
 | 
			
		||||
        ArrayList<MultiSelectModel> filteredlist = filter(mainListOfAdapter, newText);
 | 
			
		||||
        mutliSelectAdapter.setData(filteredlist, newText.toLowerCase(), mutliSelectAdapter);
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onClick(View view) {
 | 
			
		||||
 | 
			
		||||
        if (view.getId() == R.id.done) {
 | 
			
		||||
            ArrayList<Integer> callBackListOfIds = selectedIdsForCallback;
 | 
			
		||||
 | 
			
		||||
            if (callBackListOfIds.size() >= minSelectionLimit) {
 | 
			
		||||
                if (callBackListOfIds.size() <= maxSelectionLimit) {
 | 
			
		||||
 | 
			
		||||
                    //to remember last selected ids which were successfully done
 | 
			
		||||
                    tempPreviouslySelectedIdsList = new ArrayList<>(callBackListOfIds);
 | 
			
		||||
 | 
			
		||||
                    if(submitCallbackListener !=null) {
 | 
			
		||||
                        submitCallbackListener.onSelected(callBackListOfIds, getSelectNameList(), getSelectedDataString());
 | 
			
		||||
                    }
 | 
			
		||||
                    dismiss();
 | 
			
		||||
                } else {
 | 
			
		||||
                    String youCan = getResources().getString(R.string.you_can_only_select_upto);
 | 
			
		||||
                    String options = getResources().getString(R.string.options);
 | 
			
		||||
                    String option = getResources().getString(R.string.option);
 | 
			
		||||
                    String message = "";
 | 
			
		||||
 | 
			
		||||
                    if(this.maxSelectionMessage != null) {
 | 
			
		||||
                        message = maxSelectionMessage;
 | 
			
		||||
                    }
 | 
			
		||||
                    else {
 | 
			
		||||
                        if (maxSelectionLimit > 1)
 | 
			
		||||
                            message = youCan + " " + maxSelectionLimit + " " + options;
 | 
			
		||||
                        else
 | 
			
		||||
                            message = youCan + " " + maxSelectionLimit + " " + option;
 | 
			
		||||
                    }
 | 
			
		||||
                    Toast.makeText(getActivity(), message, Toast.LENGTH_LONG).show();
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                String pleaseSelect = getResources().getString(R.string.please_select_atleast);
 | 
			
		||||
                String options = getResources().getString(R.string.options);
 | 
			
		||||
                String option = getResources().getString(R.string.option);
 | 
			
		||||
                String message = "";
 | 
			
		||||
 | 
			
		||||
                if(this.minSelectionMessage != null) {
 | 
			
		||||
                    message = minSelectionMessage;
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    if (minSelectionLimit > 1)
 | 
			
		||||
                        message = pleaseSelect + " " + minSelectionLimit + " " + options;
 | 
			
		||||
                    else
 | 
			
		||||
                        message = pleaseSelect + " " + minSelectionLimit + " " + option;
 | 
			
		||||
                }
 | 
			
		||||
                Toast.makeText(getActivity(), message, Toast.LENGTH_LONG).show();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (view.getId() == R.id.cancel) {
 | 
			
		||||
            if(submitCallbackListener!=null){
 | 
			
		||||
                selectedIdsForCallback.clear();
 | 
			
		||||
                selectedIdsForCallback.addAll(tempPreviouslySelectedIdsList);
 | 
			
		||||
                submitCallbackListener.onCancel();
 | 
			
		||||
            }
 | 
			
		||||
            dismiss();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String getSelectedDataString() {
 | 
			
		||||
 | 
			
		||||
        String data = "";
 | 
			
		||||
        for (int i = 0; i < tempMainListOfAdapter.size(); i++) {
 | 
			
		||||
            if (checkForSelection(tempMainListOfAdapter.get(i).getId())) {
 | 
			
		||||
                data = data + ", " + tempMainListOfAdapter.get(i).getName();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (data.length() > 0) {
 | 
			
		||||
            return data.substring(1);
 | 
			
		||||
        } else {
 | 
			
		||||
            return "";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private ArrayList<String> getSelectNameList() {
 | 
			
		||||
 | 
			
		||||
        ArrayList<String> names = new ArrayList<>();
 | 
			
		||||
        for(int i=0;i<tempMainListOfAdapter.size();i++){
 | 
			
		||||
            if(checkForSelection(tempMainListOfAdapter.get(i).getId())){
 | 
			
		||||
                names.add(tempMainListOfAdapter.get(i).getName());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return names;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean checkForSelection(Integer id) {
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < MultiSelectDialog.selectedIdsForCallback.size(); i++) {
 | 
			
		||||
            if (id.equals(MultiSelectDialog.selectedIdsForCallback.get(i))) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
   /* public void setCallbackListener(SubmitCallbackListener submitCallbackListener) {
 | 
			
		||||
        this.submitCallbackListener = submitCallbackListener;
 | 
			
		||||
    }*/
 | 
			
		||||
 | 
			
		||||
    public interface SubmitCallbackListener {
 | 
			
		||||
        void onSelected(ArrayList<Integer> selectedIds, ArrayList<String> selectedNames, String commonSeperatedData);
 | 
			
		||||
        void onCancel();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,77 @@
 | 
			
		||||
package org.mian.gitnex.helpers;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.util.AttributeSet;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author com.github.abumoallim, modified by M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class RecyclerViewEmptySupport extends RecyclerView {
 | 
			
		||||
 | 
			
		||||
    private View emptyView;
 | 
			
		||||
 | 
			
		||||
    final private AdapterDataObserver observer = new AdapterDataObserver() {
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void onChanged() {
 | 
			
		||||
            checkIfEmpty();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void onItemRangeInserted(int positionStart, int itemCount) {
 | 
			
		||||
            checkIfEmpty();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void onItemRangeRemoved(int positionStart, int itemCount) {
 | 
			
		||||
            checkIfEmpty();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    public RecyclerViewEmptySupport(Context context) {
 | 
			
		||||
        super(context);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public RecyclerViewEmptySupport(Context context, AttributeSet attrs) {
 | 
			
		||||
        super(context, attrs);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public RecyclerViewEmptySupport(Context context, AttributeSet attrs, int defStyle) {
 | 
			
		||||
        super(context, attrs, defStyle);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void checkIfEmpty() {
 | 
			
		||||
 | 
			
		||||
        if (emptyView != null && getAdapter() != null) {
 | 
			
		||||
            final boolean emptyViewVisible = getAdapter().getItemCount() == 0;
 | 
			
		||||
            emptyView.setVisibility(emptyViewVisible ? VISIBLE : GONE);
 | 
			
		||||
            setVisibility(emptyViewVisible ? GONE : VISIBLE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void setAdapter(Adapter adapter) {
 | 
			
		||||
 | 
			
		||||
        final Adapter oldAdapter = getAdapter();
 | 
			
		||||
        if (oldAdapter != null) {
 | 
			
		||||
            oldAdapter.unregisterAdapterDataObserver(observer);
 | 
			
		||||
        }
 | 
			
		||||
        super.setAdapter(adapter);
 | 
			
		||||
        if (adapter != null) {
 | 
			
		||||
            adapter.registerAdapterDataObserver(observer);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        checkIfEmpty();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setEmptyView(View emptyView) {
 | 
			
		||||
        this.emptyView = emptyView;
 | 
			
		||||
        checkIfEmpty();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,49 @@
 | 
			
		||||
package org.mian.gitnex.helpers;
 | 
			
		||||
 | 
			
		||||
import android.graphics.Bitmap;
 | 
			
		||||
import android.graphics.BitmapShader;
 | 
			
		||||
import android.graphics.Canvas;
 | 
			
		||||
import android.graphics.Paint;
 | 
			
		||||
import android.graphics.RectF;
 | 
			
		||||
import android.graphics.Shader;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class RoundedTransformation implements com.squareup.picasso.Transformation {
 | 
			
		||||
    private final int radius;
 | 
			
		||||
    private final int margin; // dp
 | 
			
		||||
 | 
			
		||||
    // radius is corner radius in dp
 | 
			
		||||
    // margin is the board in dp
 | 
			
		||||
    public RoundedTransformation(final int radius, final int margin) {
 | 
			
		||||
        this.radius = radius;
 | 
			
		||||
        this.margin = margin;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Bitmap transform(final Bitmap source) {
 | 
			
		||||
        final Paint paint = new Paint();
 | 
			
		||||
        paint.setAntiAlias(true);
 | 
			
		||||
        paint.setShader(new BitmapShader(source, Shader.TileMode.CLAMP,
 | 
			
		||||
                Shader.TileMode.CLAMP));
 | 
			
		||||
 | 
			
		||||
        Bitmap output = Bitmap.createBitmap(source.getWidth(),
 | 
			
		||||
                source.getHeight(), Bitmap.Config.ARGB_8888);
 | 
			
		||||
        Canvas canvas = new Canvas(output);
 | 
			
		||||
        canvas.drawRoundRect(new RectF(margin, margin, source.getWidth()
 | 
			
		||||
                - margin, source.getHeight() - margin), radius, radius, paint);
 | 
			
		||||
 | 
			
		||||
        if (source != output) {
 | 
			
		||||
            source.recycle();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return output;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String key() {
 | 
			
		||||
        return "rounded";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										35
									
								
								app/src/main/java/org/mian/gitnex/helpers/TimeHelper.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								app/src/main/java/org/mian/gitnex/helpers/TimeHelper.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
package org.mian.gitnex.helpers;
 | 
			
		||||
 | 
			
		||||
import java.text.DateFormat;
 | 
			
		||||
import java.text.ParseException;
 | 
			
		||||
import java.text.SimpleDateFormat;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
 | 
			
		||||
public class TimeHelper {
 | 
			
		||||
 | 
			
		||||
    public static String customDateFormatForToast(String customDate) {
 | 
			
		||||
 | 
			
		||||
        String[] parts = customDate.split("\\+");
 | 
			
		||||
        String part1 = parts[0] + "Z";
 | 
			
		||||
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH);
 | 
			
		||||
        Date createdTime = null;
 | 
			
		||||
        try {
 | 
			
		||||
            createdTime = formatter.parse(part1);
 | 
			
		||||
        } catch (ParseException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        DateFormat format = DateFormat.getDateTimeInstance();
 | 
			
		||||
        return format.format(createdTime);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static String customDateFormatForToastDateFormat(Date customDate) {
 | 
			
		||||
 | 
			
		||||
        DateFormat format = DateFormat.getDateTimeInstance();
 | 
			
		||||
        return format.format(customDate);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								app/src/main/java/org/mian/gitnex/helpers/Toasty.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								app/src/main/java/org/mian/gitnex/helpers/Toasty.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
package org.mian.gitnex.helpers;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.view.LayoutInflater;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import android.widget.Toast;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class Toasty {
 | 
			
		||||
 | 
			
		||||
    public static void info(Context context, String message) {
 | 
			
		||||
 | 
			
		||||
        LayoutInflater inflater = LayoutInflater.from(context);
 | 
			
		||||
        View view = inflater.inflate( context.getResources().getLayout(R.layout.custom_toast), null );
 | 
			
		||||
 | 
			
		||||
        TextView text = view.findViewById(R.id.toastText);
 | 
			
		||||
        text.setText(message);
 | 
			
		||||
 | 
			
		||||
        Toast toast = new Toast(context);
 | 
			
		||||
        toast.setDuration(Toast.LENGTH_LONG);
 | 
			
		||||
        toast.setView(view);
 | 
			
		||||
        toast.show();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								app/src/main/java/org/mian/gitnex/helpers/UrlHelper.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								app/src/main/java/org/mian/gitnex/helpers/UrlHelper.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
package org.mian.gitnex.helpers;
 | 
			
		||||
 | 
			
		||||
import java.net.URI;
 | 
			
		||||
import java.net.URISyntaxException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class UrlHelper {
 | 
			
		||||
 | 
			
		||||
    public static String cleanUrl(String url) {
 | 
			
		||||
 | 
			
		||||
        URI uri = null;
 | 
			
		||||
        try {
 | 
			
		||||
            uri = new URI(url);
 | 
			
		||||
        } catch (URISyntaxException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        assert uri != null;
 | 
			
		||||
        String urlProtocol = uri.getScheme();
 | 
			
		||||
        String urlHost = uri.getHost();
 | 
			
		||||
        int urlPort = uri.getPort();
 | 
			
		||||
 | 
			
		||||
        String urlFinal = null;
 | 
			
		||||
        if(urlPort > 0) {
 | 
			
		||||
            urlFinal = urlProtocol + "://" + urlHost + ":" + urlPort;
 | 
			
		||||
        }
 | 
			
		||||
        else if(urlProtocol != null) {
 | 
			
		||||
            urlFinal = urlProtocol + "://" + urlHost;
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            urlFinal = urlHost;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return urlFinal;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										35
									
								
								app/src/main/java/org/mian/gitnex/helpers/UserMentions.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								app/src/main/java/org/mian/gitnex/helpers/UserMentions.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
package org.mian.gitnex.helpers;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.text.Spannable;
 | 
			
		||||
import android.text.SpannableString;
 | 
			
		||||
import android.text.style.ForegroundColorSpan;
 | 
			
		||||
import org.mian.gitnex.R;
 | 
			
		||||
import java.util.regex.Matcher;
 | 
			
		||||
import java.util.regex.Pattern;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class UserMentions {
 | 
			
		||||
 | 
			
		||||
    public static Spannable UserMentionsFunc(Context mCtx, CharSequence bodyWithMD, String currentItemBody) {
 | 
			
		||||
 | 
			
		||||
        Spannable bodyWithMentions = new SpannableString(bodyWithMD);
 | 
			
		||||
        Pattern pattern = Pattern.compile("@\\w+");
 | 
			
		||||
        Matcher matcher = pattern.matcher(bodyWithMD);
 | 
			
		||||
 | 
			
		||||
        while (matcher.find())
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
            int indexStart = String.valueOf(bodyWithMD).indexOf(matcher.group());
 | 
			
		||||
            int indexEnd = indexStart + matcher.group().length();
 | 
			
		||||
            bodyWithMentions.setSpan(new ForegroundColorSpan(mCtx.getResources().getColor(R.color.colorDarkGreen)), indexStart, indexEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        return bodyWithMentions;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										207
									
								
								app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										207
									
								
								app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,207 @@
 | 
			
		||||
package org.mian.gitnex.interfaces;
 | 
			
		||||
 | 
			
		||||
import com.google.gson.JsonElement;
 | 
			
		||||
import org.mian.gitnex.models.AddEmail;
 | 
			
		||||
import org.mian.gitnex.models.Branches;
 | 
			
		||||
import org.mian.gitnex.models.UpdateIssueAssignee;
 | 
			
		||||
import org.mian.gitnex.models.UpdateIssueState;
 | 
			
		||||
import org.mian.gitnex.models.Collaborators;
 | 
			
		||||
import org.mian.gitnex.models.CreateIssue;
 | 
			
		||||
import org.mian.gitnex.models.CreateLabel;
 | 
			
		||||
import org.mian.gitnex.models.Emails;
 | 
			
		||||
import org.mian.gitnex.models.GiteaVersion;
 | 
			
		||||
import org.mian.gitnex.models.IssueComments;
 | 
			
		||||
import org.mian.gitnex.models.Issues;
 | 
			
		||||
import org.mian.gitnex.models.Labels;
 | 
			
		||||
import org.mian.gitnex.models.Milestones;
 | 
			
		||||
import org.mian.gitnex.models.OrgOwner;
 | 
			
		||||
import org.mian.gitnex.models.Organization;
 | 
			
		||||
import org.mian.gitnex.models.OrganizationRepository;
 | 
			
		||||
import org.mian.gitnex.models.Permission;
 | 
			
		||||
import org.mian.gitnex.models.Releases;
 | 
			
		||||
import org.mian.gitnex.models.Teams;
 | 
			
		||||
import org.mian.gitnex.models.UserInfo;
 | 
			
		||||
import org.mian.gitnex.models.UserOrganizations;
 | 
			
		||||
import org.mian.gitnex.models.UserRepositories;
 | 
			
		||||
import org.mian.gitnex.models.UserSearch;
 | 
			
		||||
import org.mian.gitnex.models.UserTokens;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import retrofit2.Call;
 | 
			
		||||
import retrofit2.http.Body;
 | 
			
		||||
import retrofit2.http.DELETE;
 | 
			
		||||
import retrofit2.http.GET;
 | 
			
		||||
import retrofit2.http.Header;
 | 
			
		||||
import retrofit2.http.PATCH;
 | 
			
		||||
import retrofit2.http.POST;
 | 
			
		||||
import retrofit2.http.PUT;
 | 
			
		||||
import retrofit2.http.Path;
 | 
			
		||||
import retrofit2.http.Query;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public interface ApiInterface {
 | 
			
		||||
 | 
			
		||||
    @GET("version") // gitea version API
 | 
			
		||||
    Call<GiteaVersion> getGiteaVersion(@Header("Authorization") String token);
 | 
			
		||||
 | 
			
		||||
    @GET("user") // username, full name, email
 | 
			
		||||
    Call<UserInfo> getUserInfo(@Header("Authorization") String token);
 | 
			
		||||
 | 
			
		||||
    @GET("users/{username}/tokens") // get user token
 | 
			
		||||
    Call<List<UserTokens>> getUserTokens(@Header("Authorization") String authorization, @Path("username") String loginUid);
 | 
			
		||||
 | 
			
		||||
    @GET("users/{username}/tokens") // get user token with 2fa otp
 | 
			
		||||
    Call<List<UserTokens>> getUserTokensWithOTP(@Header("Authorization") String authorization, @Header("X-Gitea-OTP") int loginOTP, @Path("username") String loginUid);
 | 
			
		||||
 | 
			
		||||
    @POST("users/{username}/tokens") // create new token
 | 
			
		||||
    Call<UserTokens> createNewToken(@Header("Authorization") String authorization, @Path("username") String loginUid, @Body UserTokens jsonStr);
 | 
			
		||||
 | 
			
		||||
    @POST("users/{username}/tokens") // create new token with 2fa otp
 | 
			
		||||
    Call<UserTokens> createNewTokenWithOTP(@Header("Authorization") String authorization, @Header("X-Gitea-OTP") int loginOTP, @Path("username") String loginUid, @Body UserTokens jsonStr);
 | 
			
		||||
 | 
			
		||||
    @GET("user/orgs") // get user organizations
 | 
			
		||||
    Call<List<UserOrganizations>> getUserOrgs(@Header("Authorization") String token);
 | 
			
		||||
 | 
			
		||||
    @POST("orgs") // create new organization
 | 
			
		||||
    Call<UserOrganizations> createNewOrganization(@Header("Authorization") String token, @Body UserOrganizations jsonStr);
 | 
			
		||||
 | 
			
		||||
    @POST("org/{org}/repos") // create new repository under org
 | 
			
		||||
    Call<OrganizationRepository> createNewUserOrgRepository(@Header("Authorization") String token, @Path("org") String orgName, @Body OrganizationRepository jsonStr);
 | 
			
		||||
 | 
			
		||||
    @GET("user/orgs") // get user organizations
 | 
			
		||||
    Call<List<OrgOwner>> getOrgOwners(@Header("Authorization") String token);
 | 
			
		||||
 | 
			
		||||
    @GET("user/repos") // get user repositories
 | 
			
		||||
    Call<List<UserRepositories>> getUserRepositories(@Header("Authorization") String token);
 | 
			
		||||
 | 
			
		||||
    @POST("user/repos") // create new repository
 | 
			
		||||
    Call<OrganizationRepository> createNewUserRepository(@Header("Authorization") String token, @Body OrganizationRepository jsonStr);
 | 
			
		||||
 | 
			
		||||
    @GET("repos/{owner}/{repo}") // get repo information
 | 
			
		||||
    Call<UserRepositories> getUserRepository(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName);
 | 
			
		||||
 | 
			
		||||
    @GET("repos/{owner}/{repo}/issues") // get issues by repo
 | 
			
		||||
    Call<List<Issues>> getIssues(@Header("Authorization") String token, @Path("owner") String owner, @Path("repo") String repo, @Query("page") int page);
 | 
			
		||||
 | 
			
		||||
    @GET("repos/{owner}/{repo}/issues") // get closed issues by repo
 | 
			
		||||
    Call<List<Issues>> getClosedIssues(@Header("Authorization") String token, @Path("owner") String owner, @Path("repo") String repo, @Query("page") int page, @Query("state") String issueState);
 | 
			
		||||
 | 
			
		||||
    @GET("repos/{owner}/{repo}/issues/{index}") // get issue by id
 | 
			
		||||
    Call<Issues> getIssueByIndex(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("index") int issueIndex);
 | 
			
		||||
 | 
			
		||||
    @GET("repos/{owner}/{repo}/issues/{index}/comments") // get issue comments
 | 
			
		||||
    Call<List<IssueComments>> getIssueComments(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("index") int issueIndex);
 | 
			
		||||
 | 
			
		||||
    @POST("repos/{owner}/{repo}/issues/{index}/comments") // reply to issue
 | 
			
		||||
    Call<Issues> replyCommentToIssue(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("index") int issueIndex, @Body Issues jsonStr);
 | 
			
		||||
 | 
			
		||||
    @GET("repos/{owner}/{repo}/milestones") // get milestones by repo
 | 
			
		||||
    Call<List<Milestones>> getMilestones(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName);
 | 
			
		||||
 | 
			
		||||
    @GET("repos/{owner}/{repo}/branches") // get branches
 | 
			
		||||
    Call<List<Branches>> getBranches(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName);
 | 
			
		||||
 | 
			
		||||
    @GET("repos/{owner}/{repo}/releases") // get releases
 | 
			
		||||
    Call<List<Releases>> getReleases(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName);
 | 
			
		||||
 | 
			
		||||
    @GET("repos/{owner}/{repo}/collaborators") // get collaborators list
 | 
			
		||||
    Call<List<Collaborators>> getCollaborators(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName);
 | 
			
		||||
 | 
			
		||||
    @POST("repos/{owner}/{repo}/milestones") // create new milestone
 | 
			
		||||
    Call<Milestones> createMilestone(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Body Milestones jsonStr);
 | 
			
		||||
 | 
			
		||||
    @POST("repos/{owner}/{repo}/issues") // create new issue
 | 
			
		||||
    Call<JsonElement> createNewIssue(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Body CreateIssue jsonStr);
 | 
			
		||||
 | 
			
		||||
    @GET("repos/{owner}/{repo}/labels") // get labels list
 | 
			
		||||
    Call<List<Labels>> getlabels(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName);
 | 
			
		||||
 | 
			
		||||
    @GET("users/{username}/repos") // get current logged in user repositories
 | 
			
		||||
    Call<List<UserRepositories>> getCurrentUserRepositories(@Header("Authorization") String token, @Path("username") String username);
 | 
			
		||||
 | 
			
		||||
    @POST("repos/{owner}/{repo}/labels") // create label
 | 
			
		||||
    Call<CreateLabel> createLabel(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Body CreateLabel jsonStr);
 | 
			
		||||
 | 
			
		||||
    @DELETE("repos/{owner}/{repo}/labels/{index}") // delete a label
 | 
			
		||||
    Call<Labels> deleteLabel(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("index") int labelIndex);
 | 
			
		||||
 | 
			
		||||
    @PATCH("repos/{owner}/{repo}/labels/{index}") // update / patch a label
 | 
			
		||||
    Call<CreateLabel> patchLabel(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("index") int labelIndex, @Body CreateLabel jsonStr);
 | 
			
		||||
 | 
			
		||||
    @GET("user/starred") // get user starred repositories
 | 
			
		||||
    Call<List<UserRepositories>> getUserStarredRepos(@Header("Authorization") String token);
 | 
			
		||||
 | 
			
		||||
    @GET("orgs/{orgName}/repos") // get repositories by org
 | 
			
		||||
    Call<List<UserRepositories>> getReposByOrg(@Header("Authorization") String token, @Path("orgName") String orgName);
 | 
			
		||||
 | 
			
		||||
    @GET("orgs/{orgName}/teams") // get teams by org
 | 
			
		||||
    Call<List<Teams>> getTeamsByOrg(@Header("Authorization") String token, @Path("orgName") String orgName);
 | 
			
		||||
 | 
			
		||||
    @GET("orgs/{orgName}/members") // get members by org
 | 
			
		||||
    Call<List<UserInfo>> getMembersByOrg(@Header("Authorization") String token, @Path("orgName") String orgName);
 | 
			
		||||
 | 
			
		||||
    @GET("teams/{teamIndex}/members") // get team members by org
 | 
			
		||||
    Call<List<UserInfo>> getTeamMembersByOrg(@Header("Authorization") String token, @Path("teamIndex") int teamIndex);
 | 
			
		||||
 | 
			
		||||
    @POST("orgs/{orgName}/teams") // create new team
 | 
			
		||||
    Call<Teams> createTeamsByOrg(@Header("Authorization") String token, @Path("orgName") String orgName, @Body Teams jsonStr);
 | 
			
		||||
 | 
			
		||||
    @GET("users/search") // search users
 | 
			
		||||
    Call<UserSearch> getUserBySearch(@Header("Authorization") String token, @Query("q") String searchKeyword, @Query("limit") int limit);
 | 
			
		||||
 | 
			
		||||
    @GET("repos/{owner}/{repo}/collaborators/{collaborator}") // check collaborator in repo
 | 
			
		||||
    Call<Collaborators> checkRepoCollaborator(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("collaborator") String repoCollaborator);
 | 
			
		||||
 | 
			
		||||
    @DELETE("repos/{owner}/{repo}/collaborators/{username}") // delete a collaborator from repository
 | 
			
		||||
    Call<Collaborators> deleteCollaborator(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("username") String username);
 | 
			
		||||
 | 
			
		||||
    @PUT("repos/{owner}/{repo}/collaborators/{username}") // add a collaborator to repository
 | 
			
		||||
    Call<Permission> addCollaborator(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("username") String username, @Body Permission jsonStr);
 | 
			
		||||
 | 
			
		||||
    @PATCH("repos/{owner}/{repo}/issues/comments/{commentId}") // edit a comment
 | 
			
		||||
    Call<IssueComments> patchIssueComment(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("commentId") int commentId, @Body IssueComments jsonStr);
 | 
			
		||||
 | 
			
		||||
    @GET("user/followers") // get user followers
 | 
			
		||||
    Call<List<UserInfo>> getFollowers(@Header("Authorization") String token);
 | 
			
		||||
 | 
			
		||||
    @GET("user/following") // get following
 | 
			
		||||
    Call<List<UserInfo>> getFollowing(@Header("Authorization") String token);
 | 
			
		||||
 | 
			
		||||
    @POST("user/emails") // add new email
 | 
			
		||||
    Call<JsonElement> addNewEmail(@Header("Authorization") String token, @Body AddEmail jsonStr);
 | 
			
		||||
 | 
			
		||||
    @GET("user/emails") // get user emails
 | 
			
		||||
    Call<List<Emails>> getUserEmails(@Header("Authorization") String token);
 | 
			
		||||
 | 
			
		||||
    @GET("repos/{owner}/{repo}/issues/{index}/labels") // get issue labels
 | 
			
		||||
    Call<List<Labels>> getIssueLabels(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("index") int issueIndex);
 | 
			
		||||
 | 
			
		||||
    @PUT("repos/{owner}/{repo}/issues/{index}/labels") // replace an issue's labels
 | 
			
		||||
    Call<JsonElement> updateIssueLabels(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("index") int issueIndex, @Body Labels jsonStr);
 | 
			
		||||
 | 
			
		||||
    @GET("repos/{owner}/{repo}/raw/{filename}") // get file contents
 | 
			
		||||
    Call<String> getFileContents(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("filename") String filename);
 | 
			
		||||
 | 
			
		||||
    @POST("admin/users") // create new user
 | 
			
		||||
    Call<UserInfo> createNewUser(@Header("Authorization") String token, @Body UserInfo jsonStr);
 | 
			
		||||
 | 
			
		||||
    @PATCH("repos/{owner}/{repo}/issues/{issueIndex}") // patch issue data
 | 
			
		||||
    Call<JsonElement> patchIssue(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("issueIndex") int issueIndex, @Body CreateIssue jsonStr);
 | 
			
		||||
 | 
			
		||||
    @GET("orgs/{orgName}") // get an organization
 | 
			
		||||
    Call<Organization> getOrganization(@Header("Authorization") String token, @Path("orgName") String orgName);
 | 
			
		||||
 | 
			
		||||
    @PATCH("repos/{owner}/{repo}/issues/{issueIndex}") // close / reopen issue
 | 
			
		||||
    Call<JsonElement> closeReopenIssue(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("issueIndex") int issueIndex, @Body UpdateIssueState jsonStr);
 | 
			
		||||
 | 
			
		||||
    @POST("repos/{owner}/{repo}/releases") // create new release
 | 
			
		||||
    Call<Releases> createNewRelease(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Body Releases jsonStr);
 | 
			
		||||
 | 
			
		||||
    @PATCH("repos/{owner}/{repo}/issues/{issueIndex}") // patch issue assignees
 | 
			
		||||
    Call<JsonElement> patchIssueAssignee(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("issueIndex") int issueIndex, @Body UpdateIssueAssignee jsonStr);
 | 
			
		||||
 | 
			
		||||
    @GET("admin/users") // get all users
 | 
			
		||||
    Call<List<UserInfo>> adminGetUsers(@Header("Authorization") String token);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								app/src/main/java/org/mian/gitnex/models/AddEmail.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								app/src/main/java/org/mian/gitnex/models/AddEmail.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
package org.mian.gitnex.models;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class AddEmail {
 | 
			
		||||
 | 
			
		||||
    private List<String> emails;
 | 
			
		||||
 | 
			
		||||
    public AddEmail(List<String> emails) {
 | 
			
		||||
        this.emails = emails;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										80
									
								
								app/src/main/java/org/mian/gitnex/models/Branches.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								app/src/main/java/org/mian/gitnex/models/Branches.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
			
		||||
package org.mian.gitnex.models;
 | 
			
		||||
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class Branches {
 | 
			
		||||
 | 
			
		||||
    private String name;
 | 
			
		||||
 | 
			
		||||
    private commitObject commit;
 | 
			
		||||
 | 
			
		||||
    public Branches(String name) {
 | 
			
		||||
        this.name = name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getName() {
 | 
			
		||||
        return name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class commitObject {
 | 
			
		||||
 | 
			
		||||
        private String id;
 | 
			
		||||
        private String message;
 | 
			
		||||
        private String url;
 | 
			
		||||
        private Date timestamp;
 | 
			
		||||
 | 
			
		||||
        private authorObject author;
 | 
			
		||||
 | 
			
		||||
        public class authorObject {
 | 
			
		||||
 | 
			
		||||
            private String name;
 | 
			
		||||
            private String email;
 | 
			
		||||
            private String username;
 | 
			
		||||
 | 
			
		||||
            public String getName() {
 | 
			
		||||
                return name;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public String getEmail() {
 | 
			
		||||
                return email;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public String getUsername() {
 | 
			
		||||
                return username;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getId() {
 | 
			
		||||
            return id;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getMessage() {
 | 
			
		||||
            return message;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public authorObject getAuthor() {
 | 
			
		||||
            return author;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getUrl() {
 | 
			
		||||
            return url;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Date getTimestamp() {
 | 
			
		||||
            return timestamp;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public commitObject getCommit() {
 | 
			
		||||
        return commit;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return name;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										44
									
								
								app/src/main/java/org/mian/gitnex/models/Collaborators.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								app/src/main/java/org/mian/gitnex/models/Collaborators.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
package org.mian.gitnex.models;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class Collaborators {
 | 
			
		||||
 | 
			
		||||
    private int id;
 | 
			
		||||
    private String login;
 | 
			
		||||
    private String full_name;
 | 
			
		||||
    private String email;
 | 
			
		||||
    private String avatar_url;
 | 
			
		||||
    private String language;
 | 
			
		||||
    private String username;
 | 
			
		||||
 | 
			
		||||
    public int getId() {
 | 
			
		||||
        return id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getLogin() {
 | 
			
		||||
        return login;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getFull_name() {
 | 
			
		||||
        return full_name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getEmail() {
 | 
			
		||||
        return email;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getAvatar_url() {
 | 
			
		||||
        return avatar_url;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getLanguage() {
 | 
			
		||||
        return language;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getUsername() {
 | 
			
		||||
        return username;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								app/src/main/java/org/mian/gitnex/models/CreateIssue.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								app/src/main/java/org/mian/gitnex/models/CreateIssue.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
package org.mian.gitnex.models;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class CreateIssue {
 | 
			
		||||
 | 
			
		||||
    private String assignee;
 | 
			
		||||
    private String body;
 | 
			
		||||
    private boolean closed;
 | 
			
		||||
    private String due_date;
 | 
			
		||||
    private int milestone;
 | 
			
		||||
    private String title;
 | 
			
		||||
 | 
			
		||||
    private List<String> assignees;
 | 
			
		||||
    private int[] labels;
 | 
			
		||||
 | 
			
		||||
    public CreateIssue(String assignee, String body, boolean closed, String due_date, int milestone, String title, List<String> assignees, int[] labels) {
 | 
			
		||||
        this.assignee = assignee;
 | 
			
		||||
        this.body = body;
 | 
			
		||||
        this.closed = closed;
 | 
			
		||||
        this.due_date = due_date;
 | 
			
		||||
        this.milestone = milestone;
 | 
			
		||||
        this.title = title;
 | 
			
		||||
        this.assignees = assignees;
 | 
			
		||||
        this.labels = labels;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public CreateIssue(String title, String body, String due_date) {
 | 
			
		||||
        this.title = title;
 | 
			
		||||
        this.body = body;
 | 
			
		||||
        this.due_date = due_date;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private class Assignees {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private class Labels {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								app/src/main/java/org/mian/gitnex/models/CreateLabel.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								app/src/main/java/org/mian/gitnex/models/CreateLabel.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
package org.mian.gitnex.models;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class CreateLabel {
 | 
			
		||||
 | 
			
		||||
    private String name;
 | 
			
		||||
    private String color;
 | 
			
		||||
 | 
			
		||||
    public CreateLabel(String name, String color) {
 | 
			
		||||
        this.name = name;
 | 
			
		||||
        this.color = color;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								app/src/main/java/org/mian/gitnex/models/Emails.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								app/src/main/java/org/mian/gitnex/models/Emails.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
package org.mian.gitnex.models;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class Emails {
 | 
			
		||||
 | 
			
		||||
    private String email;
 | 
			
		||||
    private Boolean verified;
 | 
			
		||||
    private Boolean primary;
 | 
			
		||||
 | 
			
		||||
    public String getEmail() {
 | 
			
		||||
        return email;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Boolean getVerified() {
 | 
			
		||||
        return verified;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Boolean getPrimary() {
 | 
			
		||||
        return primary;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								app/src/main/java/org/mian/gitnex/models/GiteaVersion.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								app/src/main/java/org/mian/gitnex/models/GiteaVersion.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
package org.mian.gitnex.models;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class GiteaVersion {
 | 
			
		||||
 | 
			
		||||
    private String version;
 | 
			
		||||
 | 
			
		||||
    public String getVersion() {
 | 
			
		||||
        return version;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										101
									
								
								app/src/main/java/org/mian/gitnex/models/IssueComments.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								app/src/main/java/org/mian/gitnex/models/IssueComments.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,101 @@
 | 
			
		||||
package org.mian.gitnex.models;
 | 
			
		||||
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class IssueComments {
 | 
			
		||||
 | 
			
		||||
    private int id;
 | 
			
		||||
    private String html_url;
 | 
			
		||||
    private String pull_request_url;
 | 
			
		||||
    private String issue_url;
 | 
			
		||||
    private String body;
 | 
			
		||||
    private Date created_at;
 | 
			
		||||
    private Date created_date;
 | 
			
		||||
    private Date updated_at;
 | 
			
		||||
 | 
			
		||||
    private userObject user;
 | 
			
		||||
 | 
			
		||||
    public IssueComments(String body) {
 | 
			
		||||
        this.body = body;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class userObject {
 | 
			
		||||
 | 
			
		||||
        private int id;
 | 
			
		||||
        private String login;
 | 
			
		||||
        private String full_name;
 | 
			
		||||
        private String email;
 | 
			
		||||
        private String avatar_url;
 | 
			
		||||
        private String language;
 | 
			
		||||
        private String username;
 | 
			
		||||
 | 
			
		||||
        public int getId() {
 | 
			
		||||
            return id;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getLogin() {
 | 
			
		||||
            return login;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getFull_name() {
 | 
			
		||||
            return full_name;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getEmail() {
 | 
			
		||||
            return email;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getAvatar_url() {
 | 
			
		||||
            return avatar_url;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getLanguage() {
 | 
			
		||||
            return language;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getUsername() {
 | 
			
		||||
            return username;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getId() {
 | 
			
		||||
        return id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getHtml_url() {
 | 
			
		||||
        return html_url;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getPull_request_url() {
 | 
			
		||||
        return pull_request_url;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getIssue_url() {
 | 
			
		||||
        return issue_url;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getBody() {
 | 
			
		||||
        return body;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Date getCreated_at() {
 | 
			
		||||
        return created_at;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Date getCreated_date() {
 | 
			
		||||
        return created_date;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public userObject getUser() {
 | 
			
		||||
        return user;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Date getUpdated_at() {
 | 
			
		||||
        return updated_at;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										303
									
								
								app/src/main/java/org/mian/gitnex/models/Issues.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										303
									
								
								app/src/main/java/org/mian/gitnex/models/Issues.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,303 @@
 | 
			
		||||
package org.mian.gitnex.models;
 | 
			
		||||
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class Issues {
 | 
			
		||||
 | 
			
		||||
    private int id;
 | 
			
		||||
    private String url;
 | 
			
		||||
    private int number;
 | 
			
		||||
    private String title;
 | 
			
		||||
    private String body;
 | 
			
		||||
    private String state;
 | 
			
		||||
    private int comments;
 | 
			
		||||
    private Date created_at;
 | 
			
		||||
    private Date updated_at;
 | 
			
		||||
    private Date due_date;
 | 
			
		||||
    private Date closed_at;
 | 
			
		||||
 | 
			
		||||
    private userObject user;
 | 
			
		||||
    private List<labelsObject> labels;
 | 
			
		||||
    private pullRequestObject pull_request;
 | 
			
		||||
    private milestoneObject milestone;
 | 
			
		||||
    private assigneeObject assignee;
 | 
			
		||||
    private List<assigneesObject> assignees;
 | 
			
		||||
 | 
			
		||||
    public Issues(String body) {
 | 
			
		||||
        this.body = body;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class userObject {
 | 
			
		||||
 | 
			
		||||
        private int id;
 | 
			
		||||
        private String login;
 | 
			
		||||
        private String full_name;
 | 
			
		||||
        private String email;
 | 
			
		||||
        private String avatar_url;
 | 
			
		||||
        private String language;
 | 
			
		||||
        private String username;
 | 
			
		||||
 | 
			
		||||
        public int getId() {
 | 
			
		||||
            return id;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getLogin() {
 | 
			
		||||
            return login;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getFull_name() {
 | 
			
		||||
            return full_name;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getEmail() {
 | 
			
		||||
            return email;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getAvatar_url() {
 | 
			
		||||
            return avatar_url;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getLanguage() {
 | 
			
		||||
            return language;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getUsername() {
 | 
			
		||||
            return username;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class labelsObject {
 | 
			
		||||
 | 
			
		||||
        private int id;
 | 
			
		||||
        private String name;
 | 
			
		||||
        private String color;
 | 
			
		||||
        private String url;
 | 
			
		||||
 | 
			
		||||
        public int getId() {
 | 
			
		||||
            return id;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getName() {
 | 
			
		||||
            return name;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getColor() {
 | 
			
		||||
            return color;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getUrl() {
 | 
			
		||||
            return url;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class pullRequestObject {
 | 
			
		||||
 | 
			
		||||
        private String merged;
 | 
			
		||||
        private String merged_at;
 | 
			
		||||
 | 
			
		||||
        public String getMerged() {
 | 
			
		||||
            return merged;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getMerged_at() {
 | 
			
		||||
            return merged_at;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class milestoneObject {
 | 
			
		||||
 | 
			
		||||
        private int id;
 | 
			
		||||
        private String title;
 | 
			
		||||
        private String description;
 | 
			
		||||
        private String state;
 | 
			
		||||
        private String open_issues;
 | 
			
		||||
        private String closed_issues;
 | 
			
		||||
        private String closed_at;
 | 
			
		||||
        private String due_on;
 | 
			
		||||
 | 
			
		||||
        public int getId() {
 | 
			
		||||
            return id;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getTitle() {
 | 
			
		||||
            return title;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getDescription() {
 | 
			
		||||
            return description;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getState() {
 | 
			
		||||
            return state;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getOpen_issues() {
 | 
			
		||||
            return open_issues;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getClosed_issues() {
 | 
			
		||||
            return closed_issues;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getClosed_at() {
 | 
			
		||||
            return closed_at;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getDue_on() {
 | 
			
		||||
            return due_on;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class assigneeObject {
 | 
			
		||||
 | 
			
		||||
        private int id;
 | 
			
		||||
        private String login;
 | 
			
		||||
        private String full_name;
 | 
			
		||||
        private String email;
 | 
			
		||||
        private String avatar_url;
 | 
			
		||||
        private String language;
 | 
			
		||||
        private String username;
 | 
			
		||||
 | 
			
		||||
        public int getId() {
 | 
			
		||||
            return id;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getLogin() {
 | 
			
		||||
            return login;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getFull_name() {
 | 
			
		||||
            return full_name;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getEmail() {
 | 
			
		||||
            return email;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getAvatar_url() {
 | 
			
		||||
            return avatar_url;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getLanguage() {
 | 
			
		||||
            return language;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getUsername() {
 | 
			
		||||
            return username;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class assigneesObject {
 | 
			
		||||
 | 
			
		||||
        private int id;
 | 
			
		||||
        private String login;
 | 
			
		||||
        private String full_name;
 | 
			
		||||
        private String email;
 | 
			
		||||
        private String avatar_url;
 | 
			
		||||
        private String language;
 | 
			
		||||
        private String username;
 | 
			
		||||
 | 
			
		||||
        public int getId() {
 | 
			
		||||
            return id;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getLogin() {
 | 
			
		||||
            return login;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getFull_name() {
 | 
			
		||||
            return full_name;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getEmail() {
 | 
			
		||||
            return email;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getAvatar_url() {
 | 
			
		||||
            return avatar_url;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getLanguage() {
 | 
			
		||||
            return language;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public String getUsername() {
 | 
			
		||||
            return username;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getId() {
 | 
			
		||||
        return id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getUrl() {
 | 
			
		||||
        return url;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getNumber() {
 | 
			
		||||
        return number;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getTitle() {
 | 
			
		||||
        return title;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getBody() {
 | 
			
		||||
        return body;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getState() {
 | 
			
		||||
        return state;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getComments() {
 | 
			
		||||
        return comments;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Date getCreated_at() {
 | 
			
		||||
        return created_at;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Date getUpdated_at() {
 | 
			
		||||
        return updated_at;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Date getDue_date() {
 | 
			
		||||
        return due_date;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Date getClosed_at() {
 | 
			
		||||
        return closed_at;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public userObject getUser() {
 | 
			
		||||
        return user;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<labelsObject> getLabels() {
 | 
			
		||||
        return labels;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public pullRequestObject getPull_request() {
 | 
			
		||||
        return pull_request;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public milestoneObject getMilestone() {
 | 
			
		||||
        return milestone;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public assigneeObject getAssignee() {
 | 
			
		||||
        return assignee;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<assigneesObject> getAssignees() {
 | 
			
		||||
        return assignees;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										39
									
								
								app/src/main/java/org/mian/gitnex/models/Labels.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								app/src/main/java/org/mian/gitnex/models/Labels.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
package org.mian.gitnex.models;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Author M M Arif
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class Labels {
 | 
			
		||||
 | 
			
		||||
    private int id;
 | 
			
		||||
    private String name;
 | 
			
		||||
    private String color;
 | 
			
		||||
    private String url;
 | 
			
		||||
    private int[] labels;
 | 
			
		||||
 | 
			
		||||
    public Labels(String name, String color) {
 | 
			
		||||
        this.name = name;
 | 
			
		||||
        this.color = color;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Labels(int[] labels) {
 | 
			
		||||
        this.labels = labels;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getId() {
 | 
			
		||||
        return id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getName() {
 | 
			
		||||
        return name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getColor() {
 | 
			
		||||
        return color;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getUrl() {
 | 
			
		||||
        return url;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user