61
app/src/main/AndroidManifest.xml
Normal file
61
app/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.mian.gitnex">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/app_logo"
|
||||
android:label="@string/app_name"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:roundIcon="@mipmap/app_logo_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity android:name=".activities.AdminGetUsersActivity"></activity>
|
||||
<activity
|
||||
android:name=".activities.AddRemoveAssigneesActivity"
|
||||
android:theme="@style/Theme.AppCompat.Light.Dialog" />
|
||||
<activity android:name=".activities.CreateReleaseActivity" />
|
||||
<activity android:name=".activities.EditIssueActivity" />
|
||||
<activity android:name=".activities.CreateNewUserActivity" />
|
||||
<activity
|
||||
android:name=".activities.AddRemoveLabelsActivity"
|
||||
android:theme="@style/Theme.AppCompat.Light.Dialog" />
|
||||
<activity android:name=".activities.ProfileEmailActivity" />
|
||||
<activity android:name=".activities.AddCollaboratorToRepositoryActivity" />
|
||||
<activity android:name=".activities.CreateTeamByOrgActivity" />
|
||||
<activity android:name=".activities.OrgTeamMembersActivity" />
|
||||
<activity
|
||||
android:name=".activities.OrgDetailActivity"
|
||||
android:label="@string/title_activity_org_detail"
|
||||
android:theme="@style/AppTheme.NoActionBar" />
|
||||
<activity android:name=".activities.SponsorsActivity" />
|
||||
<activity android:name=".activities.CreditsActivity" />
|
||||
<activity android:name=".activities.CreateLabelActivity" />
|
||||
<activity android:name=".activities.CreateIssueActivity" />
|
||||
<activity android:name=".activities.NewMilestoneActivity" />
|
||||
<activity android:name=".activities.ReplyToIssueActivity" />
|
||||
<activity
|
||||
android:name=".activities.IssueDetailActivity"
|
||||
android:windowSoftInputMode="adjustNothing" />
|
||||
<activity
|
||||
android:name=".activities.RepoDetailActivity"
|
||||
android:label="@string/title_activity_repo_detail"
|
||||
android:theme="@style/AppTheme.NoActionBar" />
|
||||
<activity android:name=".activities.MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activities.LoginActivity"
|
||||
android:launchMode="singleTask" />
|
||||
<activity android:name=".activities.NewRepoActivity" />
|
||||
<activity android:name=".activities.NewOrganizationActivity" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
BIN
app/src/main/app_logo-web.png
Normal file
BIN
app/src/main/app_logo-web.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
@@ -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;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user