diff --git a/app/build.gradle b/app/build.gradle
index 86c3f050..578f24e6 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -56,12 +56,13 @@ configurations {
dependencies {
def lifecycle_version = '2.3.1'
def markwon_version = '4.6.2'
- def work_version = "2.7.0-alpha03"
+ def work_version = "2.7.0-alpha04"
def acra = "5.7.0"
implementation fileTree(include: ['*.jar'], dir: 'libs')
- implementation 'androidx.appcompat:appcompat:1.3.0-rc01'
+ implementation 'androidx.appcompat:appcompat:1.4.0-alpha02'
implementation 'com.google.android.material:material:1.3.0'
+ implementation 'androidx.viewpager2:viewpager2:1.1.0-alpha01'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation "androidx.legacy:legacy-support-v4:1.0.0"
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
@@ -108,9 +109,9 @@ dependencies {
implementation "androidx.work:work-runtime:$work_version"
implementation "io.mikael:urlbuilder:2.0.9"
implementation "org.codeberg.gitnex-garage:emoji-java:v5.1.2"
- implementation "org.codeberg.gitnex:tea4j:1.0.10"
+ implementation "org.codeberg.gitnex:tea4j:1.0.16"
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5"
implementation 'androidx.biometric:biometric:1.1.0'
- implementation 'com.github.chrisvest:stormpot:2.4.1'
+ implementation 'com.github.chrisvest:stormpot:2.4.2'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 0eab7a1f..1cff1ec6 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -51,7 +51,7 @@
android:name=".activities.CreateNewUserActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
> call = RetrofitClient
.getApiInterface(ctx)
- .getOrgOwners(instanceToken);
+ .getOrgOwners(instanceToken, 1, 50);
call.enqueue(new Callback>() {
diff --git a/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java b/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java
index 53f79b2d..137a9367 100644
--- a/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java
+++ b/app/src/main/java/org/mian/gitnex/activities/IssueDetailActivity.java
@@ -1,6 +1,7 @@
package org.mian.gitnex.activities;
import android.app.Dialog;
+import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Typeface;
@@ -591,6 +592,17 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
viewBinding.issueTitle.setText(HtmlCompat.fromHtml(issueNumber_ + " " + EmojiParser.parseToUnicode(singleIssue.getTitle()), HtmlCompat.FROM_HTML_MODE_LEGACY));
String cleanIssueDescription = singleIssue.getBody().trim();
+ viewBinding.assigneeAvatar.setOnClickListener(loginId -> {
+ Intent intent = new Intent(ctx, ProfileActivity.class);
+ intent.putExtra("username", singleIssue.getUser().getLogin());
+ ctx.startActivity(intent);
+ });
+
+ viewBinding.assigneeAvatar.setOnLongClickListener(loginId -> {
+ AppUtil.copyToClipboard(ctx, singleIssue.getUser().getLogin(), ctx.getString(R.string.copyLoginIdToClipBoard, singleIssue.getUser().getLogin()));
+ return true;
+ });
+
Markdown.render(ctx, EmojiParser.parseToUnicode(cleanIssueDescription), viewBinding.issueDescription);
RelativeLayout.LayoutParams paramsDesc = (RelativeLayout.LayoutParams) viewBinding.issueDescription.getLayoutParams();
@@ -612,7 +624,20 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
viewBinding.frameAssignees.addView(assigneesView);
assigneesView.setLayoutParams(params1);
- if(!singleIssue.getAssignees().get(i).getFull_name().equals("")) {
+
+ int finalI = i;
+ assigneesView.setOnClickListener(loginId -> {
+ Intent intent = new Intent(ctx, ProfileActivity.class);
+ intent.putExtra("username", singleIssue.getAssignees().get(finalI).getLogin());
+ ctx.startActivity(intent);
+ });
+
+ assigneesView.setOnLongClickListener(loginId -> {
+ AppUtil.copyToClipboard(ctx, singleIssue.getAssignees().get(finalI).getLogin(), ctx.getString(R.string.copyLoginIdToClipBoard, singleIssue.getAssignees().get(finalI).getLogin()));
+ return true;
+ });
+
+ /*if(!singleIssue.getAssignees().get(i).getFull_name().equals("")) {
assigneesView.setOnClickListener(
new ClickListener(getString(R.string.assignedTo, singleIssue.getAssignees().get(i).getFull_name()), ctx));
@@ -621,7 +646,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
assigneesView.setOnClickListener(
new ClickListener(getString(R.string.assignedTo, singleIssue.getAssignees().get(i).getLogin()), ctx));
- }
+ }*/
}
}
else {
@@ -759,7 +784,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
viewBinding.issueMilestone.setVisibility(View.GONE);
}
- if(!singleIssue.getUser().getFull_name().equals("")) {
+ /*if(!singleIssue.getUser().getFull_name().equals("")) {
viewBinding.assigneeAvatar.setOnClickListener(
new ClickListener(ctx.getResources().getString(R.string.issueCreator) + singleIssue.getUser().getFull_name(), ctx));
@@ -768,7 +793,7 @@ public class IssueDetailActivity extends BaseActivity implements LabelsListAdapt
viewBinding.assigneeAvatar.setOnClickListener(
new ClickListener(ctx.getResources().getString(R.string.issueCreator) + singleIssue.getUser().getLogin(), ctx));
- }
+ }*/
viewBinding.progressBar.setVisibility(View.GONE);
}
diff --git a/app/src/main/java/org/mian/gitnex/activities/MainActivity.java b/app/src/main/java/org/mian/gitnex/activities/MainActivity.java
index 2168ecc4..d05717a9 100644
--- a/app/src/main/java/org/mian/gitnex/activities/MainActivity.java
+++ b/app/src/main/java/org/mian/gitnex/activities/MainActivity.java
@@ -44,7 +44,7 @@ import org.mian.gitnex.fragments.ExploreFragment;
import org.mian.gitnex.fragments.MyRepositoriesFragment;
import org.mian.gitnex.fragments.NotificationsFragment;
import org.mian.gitnex.fragments.OrganizationsFragment;
-import org.mian.gitnex.fragments.ProfileFragment;
+import org.mian.gitnex.fragments.MyProfileFragment;
import org.mian.gitnex.fragments.RepositoriesFragment;
import org.mian.gitnex.fragments.SettingsFragment;
import org.mian.gitnex.fragments.StarredRepositoriesFragment;
@@ -203,7 +203,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
else if(fragmentById instanceof NotificationsFragment) {
toolbarTitle.setText(R.string.pageTitleNotifications);
}
- else if(fragmentById instanceof ProfileFragment) {
+ else if(fragmentById instanceof MyProfileFragment) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile));
}
else if(fragmentById instanceof DraftsFragment) {
@@ -309,7 +309,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
userAvatar.setOnClickListener(v -> {
toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile));
- getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit();
+ getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyProfileFragment()).commit();
navigationView.setCheckedItem(R.id.nav_profile);
drawer.closeDrawers();
@@ -389,7 +389,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
return;
case "profile":
- getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit();
+ getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyProfileFragment()).commit();
navigationView.setCheckedItem(R.id.nav_profile);
return;
@@ -431,7 +431,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
case 4:
toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile));
- getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit();
+ getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyProfileFragment()).commit();
navigationView.setCheckedItem(R.id.nav_profile);
break;
@@ -569,7 +569,7 @@ public class MainActivity extends BaseActivity implements NavigationView.OnNavig
else if(id == R.id.nav_profile) {
toolbarTitle.setText(getResources().getString(R.string.pageTitleProfile));
- getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit();
+ getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MyProfileFragment()).commit();
}
else if(id == R.id.nav_repositories) {
diff --git a/app/src/main/java/org/mian/gitnex/activities/ProfileEmailActivity.java b/app/src/main/java/org/mian/gitnex/activities/MyProfileEmailActivity.java
similarity index 98%
rename from app/src/main/java/org/mian/gitnex/activities/ProfileEmailActivity.java
rename to app/src/main/java/org/mian/gitnex/activities/MyProfileEmailActivity.java
index ef47f0d4..23d51bc9 100644
--- a/app/src/main/java/org/mian/gitnex/activities/ProfileEmailActivity.java
+++ b/app/src/main/java/org/mian/gitnex/activities/MyProfileEmailActivity.java
@@ -30,7 +30,7 @@ import retrofit2.Callback;
* Author M M Arif
*/
-public class ProfileEmailActivity extends BaseActivity {
+public class MyProfileEmailActivity extends BaseActivity {
private View.OnClickListener onClickListener;
private EditText userEmail;
diff --git a/app/src/main/java/org/mian/gitnex/activities/ProfileActivity.java b/app/src/main/java/org/mian/gitnex/activities/ProfileActivity.java
new file mode 100644
index 00000000..93b65de1
--- /dev/null
+++ b/app/src/main/java/org/mian/gitnex/activities/ProfileActivity.java
@@ -0,0 +1,143 @@
+package org.mian.gitnex.activities;
+
+import android.content.Intent;
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+import androidx.annotation.NonNull;
+import androidx.appcompat.widget.Toolbar;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+import androidx.viewpager2.adapter.FragmentStateAdapter;
+import androidx.viewpager2.widget.ViewPager2;
+import com.google.android.material.tabs.TabLayout;
+import com.google.android.material.tabs.TabLayoutMediator;
+import org.mian.gitnex.R;
+import org.mian.gitnex.fragments.profile.DetailFragment;
+import org.mian.gitnex.fragments.profile.FollowersFragment;
+import org.mian.gitnex.fragments.profile.FollowingFragment;
+import org.mian.gitnex.fragments.profile.OrganizationsFragment;
+import org.mian.gitnex.fragments.profile.RepositoriesFragment;
+import org.mian.gitnex.fragments.profile.StarredRepositoriesFragment;
+import org.mian.gitnex.helpers.Toasty;
+import java.util.Objects;
+
+/**
+ * Author M M Arif
+ */
+
+public class ProfileActivity extends BaseActivity {
+
+ private String username;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_profile);
+ Intent profileIntent = getIntent();
+ Typeface myTypeface;
+
+ Toolbar toolbar = findViewById(R.id.toolbar);
+ TextView toolbarTitle = findViewById(R.id.toolbarTitle);
+
+ if(profileIntent.getStringExtra("username") != null && !Objects.equals(profileIntent.getStringExtra("username"), "")) {
+ username = profileIntent.getStringExtra("username");
+ }
+ else {
+ Toasty.warning(ctx, ctx.getResources().getString(R.string.userInvalidUserName));
+ finish();
+ }
+
+ setSupportActionBar(toolbar);
+ Objects.requireNonNull(getSupportActionBar()).setTitle(username);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+
+ ViewPager2 viewPager = findViewById(R.id.profileContainer);
+ viewPager.setOffscreenPageLimit(1);
+ TabLayout tabLayout = findViewById(R.id.tabs);
+
+ switch(tinyDB.getInt("customFontId", -1)) {
+ case 0:
+ myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/roboto.ttf");
+ break;
+ case 2:
+ myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/sourcecodeproregular.ttf");
+ break;
+ default:
+ myTypeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/manroperegular.ttf");
+ break;
+ }
+
+ toolbarTitle.setTypeface(myTypeface);
+ toolbarTitle.setText(username);
+
+ viewPager.setAdapter(new ViewPagerAdapter(this));
+
+ String[] tabTitles = {ctx.getResources().getString(R.string.tabTextInfo), ctx.getResources().getString(R.string.navRepos), ctx.getResources().getString(R.string.navStarredRepos), ctx.getResources().getString(R.string.navOrg), ctx.getResources().getString(R.string.profileTabFollowers), ctx.getResources().getString(R.string.profileTabFollowing)};
+ new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> tab.setText(tabTitles[position])).attach();
+
+ ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
+ int tabsCount = vg.getChildCount();
+
+ for (int j = 0; j < tabsCount; j++) {
+
+ ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
+ int tabChildCount = vgTab.getChildCount();
+
+ for (int i = 0; i < tabChildCount; i++) {
+ View tabViewChild = vgTab.getChildAt(i);
+ if (tabViewChild instanceof TextView) {
+ ((TextView) tabViewChild).setTypeface(myTypeface);
+ }
+ }
+ }
+ }
+
+ public class ViewPagerAdapter extends FragmentStateAdapter {
+
+ public ViewPagerAdapter(@NonNull FragmentActivity fa) { super(fa); }
+
+ @NonNull
+ @Override
+ public Fragment createFragment(int position) {
+ switch(position) {
+ case 0: // detail
+ return DetailFragment.newInstance(username);
+ case 1: // repos
+ return RepositoriesFragment.newInstance(username);
+ case 2: // starred repos
+ return StarredRepositoriesFragment.newInstance(username);
+ case 3: // organizations
+ return OrganizationsFragment.newInstance(username);
+ case 4: // followers
+ return FollowersFragment.newInstance(username);
+ case 5: // following
+ return FollowingFragment.newInstance(username);
+ }
+ return null;
+ }
+
+ @Override
+ public int getItemCount() {
+ return 6;
+ }
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+
+ int id = item.getItemId();
+
+ if(id == android.R.id.home) {
+ finish();
+ return true;
+ }
+ else {
+ return super.onOptionsItemSelected(item);
+ }
+ }
+}
diff --git a/app/src/main/java/org/mian/gitnex/adapters/AdminGetUsersAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/AdminGetUsersAdapter.java
index a01a1d3d..686883a5 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/AdminGetUsersAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/AdminGetUsersAdapter.java
@@ -1,6 +1,7 @@
package org.mian.gitnex.adapters;
import android.content.Context;
+import android.content.Intent;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
@@ -15,6 +16,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.amulyakhare.textdrawable.TextDrawable;
import org.gitnex.tea4j.models.UserInfo;
import org.mian.gitnex.R;
+import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.RoundedTransformation;
@@ -31,7 +33,7 @@ public class AdminGetUsersAdapter extends RecyclerView.Adapter usersListFull;
- static class UsersViewHolder extends RecyclerView.ViewHolder {
+ class UsersViewHolder extends RecyclerView.ViewHolder {
private String userLoginId;
@@ -52,10 +54,14 @@ public class AdminGetUsersAdapter extends RecyclerView.Adapter {
+ Intent intent = new Intent(context, ProfileActivity.class);
+ intent.putExtra("username", userLoginId);
+ context.startActivity(intent);
+ });
- Context context = loginId.getContext();
-
+ userAvatar.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
+ return true;
});
}
}
diff --git a/app/src/main/java/org/mian/gitnex/adapters/CollaboratorsAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/CollaboratorsAdapter.java
index 0f229011..6e90df0f 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/CollaboratorsAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/CollaboratorsAdapter.java
@@ -2,6 +2,7 @@ package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
+import android.content.Intent;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
@@ -11,6 +12,7 @@ import android.widget.ImageView;
import android.widget.TextView;
import org.gitnex.tea4j.models.Collaborators;
import org.mian.gitnex.R;
+import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.RoundedTransformation;
@@ -25,7 +27,7 @@ public class CollaboratorsAdapter extends BaseAdapter {
private final List collaboratorsList;
private final Context context;
- private static class ViewHolder {
+ private class ViewHolder {
private String userLoginId;
@@ -38,10 +40,14 @@ public class CollaboratorsAdapter extends BaseAdapter {
collaboratorName = v.findViewById(R.id.collaboratorName);
collaboratorAvatar.setOnClickListener(loginId -> {
+ Intent intent = new Intent(context, ProfileActivity.class);
+ intent.putExtra("username", userLoginId);
+ context.startActivity(intent);
+ });
- Context context = loginId.getContext();
-
+ collaboratorAvatar.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
+ return true;
});
}
}
diff --git a/app/src/main/java/org/mian/gitnex/adapters/ExploreIssuesAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/ExploreIssuesAdapter.java
index e24250c0..5067a22c 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/ExploreIssuesAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/ExploreIssuesAdapter.java
@@ -14,6 +14,7 @@ import androidx.recyclerview.widget.RecyclerView;
import org.gitnex.tea4j.models.Issues;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.IssueDetailActivity;
+import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.database.api.BaseApi;
import org.mian.gitnex.database.api.RepositoriesApi;
@@ -64,8 +65,6 @@ public class ExploreIssuesAdapter extends RecyclerView.Adapter {
-
- Context context = v.getContext();
Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", issue.getNumber());
@@ -99,10 +98,14 @@ public class ExploreIssuesAdapter extends RecyclerView.Adapter {
- Context context = v.getContext();
- String userLoginId = issue.getUser().getLogin();
+ Intent intent = new Intent(context, ProfileActivity.class);
+ intent.putExtra("username", issue.getUser().getLogin());
+ context.startActivity(intent);
+ });
- AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
+ issueAssigneeAvatar.setOnLongClickListener(loginId -> {
+ AppUtil.copyToClipboard(context, issue.getUser().getLogin(), context.getString(R.string.copyLoginIdToClipBoard, issue.getUser().getLogin()));
+ return true;
});
}
}
diff --git a/app/src/main/java/org/mian/gitnex/adapters/IssueCommentsAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/IssueCommentsAdapter.java
index 0ead649f..218984ac 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/IssueCommentsAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/IssueCommentsAdapter.java
@@ -20,6 +20,7 @@ import com.google.gson.JsonElement;
import com.vdurmont.emoji.EmojiParser;
import org.gitnex.tea4j.models.IssueComments;
import org.mian.gitnex.R;
+import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.fragments.BottomSheetReplyFragment;
@@ -87,10 +88,9 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter {
- final Context ctx = v.getContext();
final String loginUid = tinyDB.getString("loginUid");
- @SuppressLint("InflateParams") View vw = LayoutInflater.from(ctx).inflate(R.layout.bottom_sheet_issue_comments, null);
+ @SuppressLint("InflateParams") View vw = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_issue_comments, null);
TextView commentMenuEdit = vw.findViewById(R.id.commentMenuEdit);
TextView commentShare = vw.findViewById(R.id.issueCommentShare);
@@ -108,7 +108,7 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter {
tinyDB.putBoolean("commentEdited", true);
@@ -148,10 +148,10 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter {
@@ -195,27 +195,32 @@ public class IssueCommentsAdapter extends RecyclerView.Adapter {
- ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(ctx).getSystemService(Context.CLIPBOARD_SERVICE);
+ ClipboardManager clipboard = (ClipboardManager) Objects.requireNonNull(context).getSystemService(Context.CLIPBOARD_SERVICE);
assert clipboard != null;
ClipData clip = ClipData.newPlainText("Comment on issue #" + tinyDB.getString("issueNumber"), issueComment.getBody());
clipboard.setPrimaryClip(clip);
dialog.dismiss();
- Toasty.success(ctx, ctx.getString(R.string.copyIssueCommentToastMsg));
+ Toasty.success(context, context.getString(R.string.copyIssueCommentToastMsg));
});
commentMenuDelete.setOnClickListener(v1 -> {
- deleteIssueComment(ctx, issueComment.getId(), getAdapterPosition());
+ deleteIssueComment(context, issueComment.getId(), getAdapterPosition());
dialog.dismiss();
});
});
avatar.setOnClickListener(loginId -> {
+ Intent intent = new Intent(context, ProfileActivity.class);
+ intent.putExtra("username", userLoginId);
+ context.startActivity(intent);
+ });
- Context context = loginId.getContext();
+ avatar.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
+ return true;
});
}
}
diff --git a/app/src/main/java/org/mian/gitnex/adapters/IssuesAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/IssuesAdapter.java
index 70d948b1..252fa561 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/IssuesAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/IssuesAdapter.java
@@ -16,6 +16,7 @@ import com.vdurmont.emoji.EmojiParser;
import org.gitnex.tea4j.models.Issues;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.IssueDetailActivity;
+import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.ClickListener;
@@ -110,9 +111,6 @@ public class IssuesAdapter extends RecyclerView.Adapter
issueCreatedTime = itemView.findViewById(R.id.issueCreatedTime);
itemView.setOnClickListener(layoutView -> {
-
- Context context = layoutView.getContext();
-
Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", issue.getNumber());
@@ -123,12 +121,15 @@ public class IssuesAdapter extends RecyclerView.Adapter
});
issueAssigneeAvatar.setOnClickListener(v -> {
- Context context = v.getContext();
- String userLoginId = issue.getUser().getLogin();
-
- AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
+ Intent intent = new Intent(context, ProfileActivity.class);
+ intent.putExtra("username", issue.getUser().getLogin());
+ context.startActivity(intent);
});
+ issueAssigneeAvatar.setOnLongClickListener(loginId -> {
+ AppUtil.copyToClipboard(context, issue.getUser().getLogin(), context.getString(R.string.copyLoginIdToClipBoard, issue.getUser().getLogin()));
+ return true;
+ });
}
@SuppressLint("SetTextI18n")
diff --git a/app/src/main/java/org/mian/gitnex/adapters/MembersByOrgAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/MembersByOrgAdapter.java
index 00f284f1..897cca2f 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/MembersByOrgAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/MembersByOrgAdapter.java
@@ -2,6 +2,7 @@ package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
+import android.content.Intent;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
@@ -13,6 +14,7 @@ import android.widget.ImageView;
import android.widget.TextView;
import org.gitnex.tea4j.models.UserInfo;
import org.mian.gitnex.R;
+import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.RoundedTransformation;
@@ -29,7 +31,7 @@ public class MembersByOrgAdapter extends BaseAdapter implements Filterable {
private final Context context;
private final List membersListFull;
- private static class ViewHolder {
+ private class ViewHolder {
private String userLoginId;
@@ -42,10 +44,14 @@ public class MembersByOrgAdapter extends BaseAdapter implements Filterable {
memberName = v.findViewById(R.id.memberName);
memberAvatar.setOnClickListener(loginId -> {
+ Intent intent = new Intent(context, ProfileActivity.class);
+ intent.putExtra("username", userLoginId);
+ context.startActivity(intent);
+ });
- Context context = loginId.getContext();
-
+ memberAvatar.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
+ return true;
});
}
}
diff --git a/app/src/main/java/org/mian/gitnex/adapters/ProfileEmailsAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/MyProfileEmailsAdapter.java
similarity index 82%
rename from app/src/main/java/org/mian/gitnex/adapters/ProfileEmailsAdapter.java
rename to app/src/main/java/org/mian/gitnex/adapters/MyProfileEmailsAdapter.java
index 3757bcfc..dd867c5c 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/ProfileEmailsAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/MyProfileEmailsAdapter.java
@@ -18,7 +18,7 @@ import java.util.List;
* Author M M Arif
*/
-public class ProfileEmailsAdapter extends RecyclerView.Adapter {
+public class MyProfileEmailsAdapter extends RecyclerView.Adapter {
private final List emailsList;
private final Context context;
@@ -37,20 +37,20 @@ public class ProfileEmailsAdapter extends RecyclerView.Adapter emailsListMain) {
+ public MyProfileEmailsAdapter(Context ctx, List emailsListMain) {
this.context = ctx;
this.emailsList = emailsListMain;
}
@NonNull
@Override
- public ProfileEmailsAdapter.EmailsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ public MyProfileEmailsAdapter.EmailsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_profile_emails, parent, false);
- return new ProfileEmailsAdapter.EmailsViewHolder(v);
+ return new MyProfileEmailsAdapter.EmailsViewHolder(v);
}
@Override
- public void onBindViewHolder(@NonNull ProfileEmailsAdapter.EmailsViewHolder holder, int position) {
+ public void onBindViewHolder(@NonNull MyProfileEmailsAdapter.EmailsViewHolder holder, int position) {
Emails currentItem = emailsList.get(position);
diff --git a/app/src/main/java/org/mian/gitnex/adapters/ProfileFollowersAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/MyProfileFollowersAdapter.java
similarity index 72%
rename from app/src/main/java/org/mian/gitnex/adapters/ProfileFollowersAdapter.java
rename to app/src/main/java/org/mian/gitnex/adapters/MyProfileFollowersAdapter.java
index 5383ae16..19d5bd9c 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/ProfileFollowersAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/MyProfileFollowersAdapter.java
@@ -1,6 +1,7 @@
package org.mian.gitnex.adapters;
import android.content.Context;
+import android.content.Intent;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
@@ -11,6 +12,7 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.gitnex.tea4j.models.UserInfo;
import org.mian.gitnex.R;
+import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.RoundedTransformation;
@@ -20,12 +22,12 @@ import java.util.List;
* Author M M Arif
*/
-public class ProfileFollowersAdapter extends RecyclerView.Adapter {
+public class MyProfileFollowersAdapter extends RecyclerView.Adapter {
private final List followersList;
private final Context context;
- static class FollowersViewHolder extends RecyclerView.ViewHolder {
+ class FollowersViewHolder extends RecyclerView.ViewHolder {
private String userLoginId;
@@ -41,16 +43,20 @@ public class ProfileFollowersAdapter extends RecyclerView.Adapter {
-
- Context context = loginId.getContext();
+ itemView.setOnClickListener(loginId -> {
+ Intent intent = new Intent(context, ProfileActivity.class);
+ intent.putExtra("username", userLoginId);
+ context.startActivity(intent);
+ });
+ itemView.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
+ return true;
});
}
}
- public ProfileFollowersAdapter(Context ctx, List followersListMain) {
+ public MyProfileFollowersAdapter(Context ctx, List followersListMain) {
this.context = ctx;
this.followersList = followersListMain;
@@ -58,14 +64,14 @@ public class ProfileFollowersAdapter extends RecyclerView.Adapter {
+public class MyProfileFollowingAdapter extends RecyclerView.Adapter {
private final List followingList;
private final Context context;
- static class FollowingViewHolder extends RecyclerView.ViewHolder {
+ class FollowingViewHolder extends RecyclerView.ViewHolder {
private String userLoginId;
@@ -41,16 +43,20 @@ public class ProfileFollowingAdapter extends RecyclerView.Adapter {
-
- Context context = loginId.getContext();
+ itemView.setOnClickListener(loginId -> {
+ Intent intent = new Intent(context, ProfileActivity.class);
+ intent.putExtra("username", userLoginId);
+ context.startActivity(intent);
+ });
+ itemView.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
+ return true;
});
}
}
- public ProfileFollowingAdapter(Context ctx, List followingListMain) {
+ public MyProfileFollowingAdapter(Context ctx, List followingListMain) {
this.context = ctx;
this.followingList = followingListMain;
@@ -58,14 +64,14 @@ public class ProfileFollowingAdapter extends RecyclerView.Adapter prListMain) {
-
this.context = context;
this.prList = prListMain;
}
@@ -84,7 +84,6 @@ public class PullRequestsAdapter extends RecyclerView.Adapter {
-
- Context context = v.getContext();
-
Intent intent = new Intent(context, IssueDetailActivity.class);
intent.putExtra("issueNumber", pullRequest.getNumber());
intent.putExtra("prMergeable", pullRequest.isMergeable());
@@ -135,12 +131,15 @@ public class PullRequestsAdapter extends RecyclerView.Adapter {
- Context context = v.getContext();
- String userLoginId = pullRequest.getUser().getLogin();
-
- AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
+ Intent intent = new Intent(context, ProfileActivity.class);
+ intent.putExtra("username", pullRequest.getUser().getLogin());
+ context.startActivity(intent);
});
+ assigneeAvatar.setOnLongClickListener(loginId -> {
+ AppUtil.copyToClipboard(context, pullRequest.getUser().getLogin(), context.getString(R.string.copyLoginIdToClipBoard, pullRequest.getUser().getLogin()));
+ return true;
+ });
}
@SuppressLint("SetTextI18n")
@@ -176,38 +175,30 @@ public class PullRequestsAdapter extends RecyclerView.Adapter list) {
-
prList = list;
notifyDataSetChanged();
}
-
}
diff --git a/app/src/main/java/org/mian/gitnex/adapters/ReleasesAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/ReleasesAdapter.java
index a0bb8962..279b420f 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/ReleasesAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/ReleasesAdapter.java
@@ -1,6 +1,7 @@
package org.mian.gitnex.adapters;
import android.content.Context;
+import android.content.Intent;
import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
@@ -14,6 +15,7 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.gitnex.tea4j.models.Releases;
import org.mian.gitnex.R;
+import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.ClickListener;
@@ -35,6 +37,8 @@ public class ReleasesAdapter extends RecyclerView.Adapter {
+ Context context = loginId.getContext();
+
+ Intent intent = new Intent(context, ProfileActivity.class);
+ intent.putExtra("username", releases.getAuthor().getLogin());
+ context.startActivity(intent);
+ });
}
}
@@ -94,6 +106,7 @@ public class ReleasesAdapter extends RecyclerView.Adapter stargazersList;
private final Context context;
- private static class ViewHolder {
+ private class ViewHolder {
+
+ private UserInfo userInfo;
private final ImageView memberAvatar;
private final TextView memberName;
@@ -34,6 +38,17 @@ public class RepoStargazersAdapter extends BaseAdapter {
ViewHolder(View v) {
memberAvatar = v.findViewById(R.id.memberAvatar);
memberName = v.findViewById(R.id.memberName);
+
+ memberAvatar.setOnClickListener(loginId -> {
+ Intent intent = new Intent(context, ProfileActivity.class);
+ intent.putExtra("username", userInfo.getLogin());
+ context.startActivity(intent);
+ });
+
+ memberAvatar.setOnLongClickListener(loginId -> {
+ AppUtil.copyToClipboard(context, userInfo.getLogin(), context.getString(R.string.copyLoginIdToClipBoard, userInfo.getLogin()));
+ return true;
+ });
}
}
@@ -80,6 +95,7 @@ public class RepoStargazersAdapter extends BaseAdapter {
private void initData(RepoStargazersAdapter.ViewHolder viewHolder, int position) {
UserInfo currentItem = stargazersList.get(position);
+ viewHolder.userInfo = currentItem;
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
PicassoService.getInstance(context).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(180, 180).centerCrop().into(viewHolder.memberAvatar);
diff --git a/app/src/main/java/org/mian/gitnex/adapters/RepoWatchersAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/RepoWatchersAdapter.java
index 184a43a9..c340c502 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/RepoWatchersAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/RepoWatchersAdapter.java
@@ -2,6 +2,7 @@ package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
+import android.content.Intent;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.View;
@@ -11,6 +12,7 @@ import android.widget.ImageView;
import android.widget.TextView;
import org.gitnex.tea4j.models.UserInfo;
import org.mian.gitnex.R;
+import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.RoundedTransformation;
@@ -26,7 +28,9 @@ public class RepoWatchersAdapter extends BaseAdapter {
private final List watchersList;
private final Context context;
- private static class ViewHolder {
+ private class ViewHolder {
+
+ private UserInfo userInfo;
private final ImageView memberAvatar;
private final TextView memberName;
@@ -34,6 +38,17 @@ public class RepoWatchersAdapter extends BaseAdapter {
ViewHolder(View v) {
memberAvatar = v.findViewById(R.id.memberAvatar);
memberName = v.findViewById(R.id.memberName);
+
+ memberAvatar.setOnClickListener(loginId -> {
+ Intent intent = new Intent(context, ProfileActivity.class);
+ intent.putExtra("username", userInfo.getLogin());
+ context.startActivity(intent);
+ });
+
+ memberAvatar.setOnLongClickListener(loginId -> {
+ AppUtil.copyToClipboard(context, userInfo.getLogin(), context.getString(R.string.copyLoginIdToClipBoard, userInfo.getLogin()));
+ return true;
+ });
}
}
@@ -80,6 +95,7 @@ public class RepoWatchersAdapter extends BaseAdapter {
private void initData(RepoWatchersAdapter.ViewHolder viewHolder, int position) {
UserInfo currentItem = watchersList.get(position);
+ viewHolder.userInfo = currentItem;
int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
PicassoService.getInstance(context).get().load(currentItem.getAvatar()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(180, 180).centerCrop().into(viewHolder.memberAvatar);
diff --git a/app/src/main/java/org/mian/gitnex/adapters/TeamMembersByOrgAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/TeamMembersByOrgAdapter.java
index b818f515..392e17c1 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/TeamMembersByOrgAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/TeamMembersByOrgAdapter.java
@@ -2,6 +2,7 @@ package org.mian.gitnex.adapters;
import android.annotation.SuppressLint;
import android.content.Context;
+import android.content.Intent;
import android.graphics.Typeface;
import android.text.Html;
import android.view.LayoutInflater;
@@ -12,6 +13,7 @@ import android.widget.ImageView;
import android.widget.TextView;
import org.gitnex.tea4j.models.UserInfo;
import org.mian.gitnex.R;
+import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.RoundedTransformation;
@@ -27,7 +29,7 @@ public class TeamMembersByOrgAdapter extends BaseAdapter {
private final List teamMembersList;
private final Context context;
- private static class ViewHolder {
+ private class ViewHolder {
private String userLoginId;
@@ -40,10 +42,14 @@ public class TeamMembersByOrgAdapter extends BaseAdapter {
memberName = v.findViewById(R.id.memberName);
memberAvatar.setOnClickListener(loginId -> {
+ Intent intent = new Intent(context, ProfileActivity.class);
+ intent.putExtra("username", userLoginId);
+ context.startActivity(intent);
+ });
- Context context = loginId.getContext();
-
+ memberAvatar.setOnLongClickListener(loginId -> {
AppUtil.copyToClipboard(context, userLoginId, context.getString(R.string.copyLoginIdToClipBoard, userLoginId));
+ return true;
});
}
}
diff --git a/app/src/main/java/org/mian/gitnex/adapters/UserSearchAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/UserSearchAdapter.java
index 8f3b2999..921afd4f 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/UserSearchAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/UserSearchAdapter.java
@@ -1,6 +1,7 @@
package org.mian.gitnex.adapters;
import android.content.Context;
+import android.content.Intent;
import android.text.Html;
import android.util.Log;
import android.view.LayoutInflater;
@@ -16,6 +17,7 @@ import org.gitnex.tea4j.models.Collaborators;
import org.gitnex.tea4j.models.UserInfo;
import org.mian.gitnex.R;
import org.mian.gitnex.actions.CollaboratorActions;
+import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs;
@@ -42,7 +44,7 @@ public class UserSearchAdapter extends RecyclerView.Adapter {
-
- final Context context = v.getContext();
-
AlertDialog.Builder pBuilder = new AlertDialog.Builder(context);
pBuilder.setTitle(R.string.newTeamPermission);
@@ -89,9 +88,6 @@ public class UserSearchAdapter extends RecyclerView.Adapter {
-
- Context context = v.getContext();
-
AlertDialogs.collaboratorRemoveDialog(context, userInfo.getUsername(),
context.getResources().getString(R.string.removeCollaboratorTitle),
context.getResources().getString(R.string.removeCollaboratorMessage),
@@ -99,6 +95,16 @@ public class UserSearchAdapter extends RecyclerView.Adapter {
+ Intent intent = new Intent(context, ProfileActivity.class);
+ intent.putExtra("username", userInfo.getLogin());
+ context.startActivity(intent);
+ });
+
+ userAvatar.setOnLongClickListener(loginId -> {
+ AppUtil.copyToClipboard(context, userInfo.getLogin(), context.getString(R.string.copyLoginIdToClipBoard, userInfo.getLogin()));
+ return true;
+ });
}
}
diff --git a/app/src/main/java/org/mian/gitnex/adapters/UserSearchForTeamMemberAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/UserSearchForTeamMemberAdapter.java
index ad2ca677..9b2f0a72 100644
--- a/app/src/main/java/org/mian/gitnex/adapters/UserSearchForTeamMemberAdapter.java
+++ b/app/src/main/java/org/mian/gitnex/adapters/UserSearchForTeamMemberAdapter.java
@@ -1,6 +1,7 @@
package org.mian.gitnex.adapters;
import android.content.Context;
+import android.content.Intent;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
@@ -11,6 +12,7 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.gitnex.tea4j.models.UserInfo;
import org.mian.gitnex.R;
+import org.mian.gitnex.activities.ProfileActivity;
import org.mian.gitnex.clients.PicassoService;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AlertDialogs;
@@ -40,7 +42,7 @@ public class UserSearchForTeamMemberAdapter extends RecyclerView.Adapter {
-
- Context context = v.getContext();
-
AlertDialogs.addMemberDialog(context, userInfo.getLogin(),
context.getResources().getString(R.string.addTeamMemberTitle),
context.getResources().getString(R.string.addTeamMemberMessage),
@@ -71,15 +70,23 @@ public class UserSearchForTeamMemberAdapter extends RecyclerView.Adapter {
-
- Context context = v.getContext();
-
AlertDialogs.removeMemberDialog(context, userInfo.getLogin(),
context.getResources().getString(R.string.removeTeamMemberTitle),
context.getResources().getString(R.string.removeTeamMemberMessage),
context.getResources().getString(R.string.removeButton),
context.getResources().getString(R.string.cancelButton), Integer.parseInt(String.valueOf(teamId)));
});
+
+ userAvatar.setOnClickListener(loginId -> {
+ Intent intent = new Intent(context, ProfileActivity.class);
+ intent.putExtra("username", userInfo.getLogin());
+ context.startActivity(intent);
+ });
+
+ userAvatar.setOnLongClickListener(loginId -> {
+ AppUtil.copyToClipboard(context, userInfo.getLogin(), context.getString(R.string.copyLoginIdToClipBoard, userInfo.getLogin()));
+ return true;
+ });
}
}
diff --git a/app/src/main/java/org/mian/gitnex/adapters/profile/FollowersAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/profile/FollowersAdapter.java
new file mode 100644
index 00000000..0404b681
--- /dev/null
+++ b/app/src/main/java/org/mian/gitnex/adapters/profile/FollowersAdapter.java
@@ -0,0 +1,166 @@
+package org.mian.gitnex.adapters.profile;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.Intent;
+import android.text.Html;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+import org.gitnex.tea4j.models.UserInfo;
+import org.mian.gitnex.R;
+import org.mian.gitnex.activities.ProfileActivity;
+import org.mian.gitnex.clients.PicassoService;
+import org.mian.gitnex.helpers.AppUtil;
+import org.mian.gitnex.helpers.RoundedTransformation;
+import java.util.List;
+
+/**
+ * Author M M Arif
+ */
+
+public class FollowersAdapter extends RecyclerView.Adapter {
+
+ private final Context context;
+ private final int TYPE_LOAD = 0;
+ private List usersList;
+ private OnLoadMoreListener loadMoreListener;
+ private boolean isLoading = false, isMoreDataAvailable = true;
+
+ public FollowersAdapter(Context ctx, List usersListMain) {
+ this.context = ctx;
+ this.usersList = usersListMain;
+ }
+
+ @NonNull
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+
+ LayoutInflater inflater = LayoutInflater.from(context);
+
+ if(viewType == TYPE_LOAD) {
+ return new UsersHolder(inflater.inflate(R.layout.list_profile_followers_following, 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) {
+ ((UsersHolder) holder).bindData(usersList.get(position));
+ }
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if(usersList.get(position).getUsername() != null) {
+ return TYPE_LOAD;
+ }
+ else {
+ return 1;
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return usersList.size();
+ }
+
+ class UsersHolder extends RecyclerView.ViewHolder {
+
+ private UserInfo userInfo;
+
+ private final ImageView userAvatar;
+ private final TextView userFullName;
+ private final TextView userName;
+
+ UsersHolder(View itemView) {
+
+ super(itemView);
+ Context context = itemView.getContext();
+
+ userAvatar = itemView.findViewById(R.id.userAvatar);
+ userFullName = itemView.findViewById(R.id.userFullName);
+ userName = itemView.findViewById(R.id.userName);
+
+ itemView.setOnClickListener(loginId -> {
+ Intent intent = new Intent(context, ProfileActivity.class);
+ intent.putExtra("username", userInfo.getLogin());
+ context.startActivity(intent);
+ });
+
+ itemView.setOnLongClickListener(loginId -> {
+ AppUtil.copyToClipboard(context, userInfo.getLogin(), context.getString(R.string.copyLoginIdToClipBoard, userInfo.getLogin()));
+ return true;
+ });
+ }
+
+ @SuppressLint("SetTextI18n")
+ void bindData(UserInfo userInfo) {
+
+ this.userInfo = userInfo;
+ int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
+
+ //Locale locale = context.getResources().getConfiguration().locale;
+
+ if(!userInfo.getFullname().equals("")) {
+ userFullName.setText(Html.fromHtml(userInfo.getFullname()));
+ userName.setText(context.getResources().getString(R.string.usernameWithAt, userInfo.getUsername()));
+ }
+ else {
+ userFullName.setText(userInfo.getUsername());
+ userName.setVisibility(View.GONE);
+ }
+
+ PicassoService.getInstance(context)
+ .get()
+ .load(userInfo.getAvatar())
+ .placeholder(R.drawable.loader_animated)
+ .transform(new RoundedTransformation(imgRadius, 0))
+ .resize(120, 120)
+ .centerCrop()
+ .into(userAvatar);
+ }
+ }
+
+ 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;
+ }
+
+ public void updateList(List list) {
+ usersList = list;
+ notifyDataSetChanged();
+ }
+
+}
diff --git a/app/src/main/java/org/mian/gitnex/adapters/profile/FollowingAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/profile/FollowingAdapter.java
new file mode 100644
index 00000000..d572197a
--- /dev/null
+++ b/app/src/main/java/org/mian/gitnex/adapters/profile/FollowingAdapter.java
@@ -0,0 +1,166 @@
+package org.mian.gitnex.adapters.profile;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.Intent;
+import android.text.Html;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+import org.gitnex.tea4j.models.UserInfo;
+import org.mian.gitnex.R;
+import org.mian.gitnex.activities.ProfileActivity;
+import org.mian.gitnex.clients.PicassoService;
+import org.mian.gitnex.helpers.AppUtil;
+import org.mian.gitnex.helpers.RoundedTransformation;
+import java.util.List;
+
+/**
+ * Author M M Arif
+ */
+
+public class FollowingAdapter extends RecyclerView.Adapter {
+
+ private final Context context;
+ private final int TYPE_LOAD = 0;
+ private List usersList;
+ private OnLoadMoreListener loadMoreListener;
+ private boolean isLoading = false, isMoreDataAvailable = true;
+
+ public FollowingAdapter(Context ctx, List usersListMain) {
+ this.context = ctx;
+ this.usersList = usersListMain;
+ }
+
+ @NonNull
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+
+ LayoutInflater inflater = LayoutInflater.from(context);
+
+ if(viewType == TYPE_LOAD) {
+ return new UsersHolder(inflater.inflate(R.layout.list_profile_followers_following, 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) {
+ ((UsersHolder) holder).bindData(usersList.get(position));
+ }
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if(usersList.get(position).getUsername() != null) {
+ return TYPE_LOAD;
+ }
+ else {
+ return 1;
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return usersList.size();
+ }
+
+ class UsersHolder extends RecyclerView.ViewHolder {
+
+ private UserInfo userInfo;
+
+ private final ImageView userAvatar;
+ private final TextView userFullName;
+ private final TextView userName;
+
+ UsersHolder(View itemView) {
+
+ super(itemView);
+ Context context = itemView.getContext();
+
+ userAvatar = itemView.findViewById(R.id.userAvatar);
+ userFullName = itemView.findViewById(R.id.userFullName);
+ userName = itemView.findViewById(R.id.userName);
+
+ itemView.setOnClickListener(loginId -> {
+ Intent intent = new Intent(context, ProfileActivity.class);
+ intent.putExtra("username", userInfo.getLogin());
+ context.startActivity(intent);
+ });
+
+ itemView.setOnLongClickListener(loginId -> {
+ AppUtil.copyToClipboard(context, userInfo.getLogin(), context.getString(R.string.copyLoginIdToClipBoard, userInfo.getLogin()));
+ return true;
+ });
+ }
+
+ @SuppressLint("SetTextI18n")
+ void bindData(UserInfo userInfo) {
+
+ this.userInfo = userInfo;
+ int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
+
+ //Locale locale = context.getResources().getConfiguration().locale;
+
+ if(!userInfo.getFullname().equals("")) {
+ userFullName.setText(Html.fromHtml(userInfo.getFullname()));
+ userName.setText(context.getResources().getString(R.string.usernameWithAt, userInfo.getUsername()));
+ }
+ else {
+ userFullName.setText(userInfo.getUsername());
+ userName.setVisibility(View.GONE);
+ }
+
+ PicassoService
+ .getInstance(context)
+ .get()
+ .load(userInfo.getAvatar())
+ .placeholder(R.drawable.loader_animated)
+ .transform(new RoundedTransformation(imgRadius, 0))
+ .resize(120, 120)
+ .centerCrop()
+ .into(userAvatar);
+ }
+ }
+
+ 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;
+ }
+
+ public void updateList(List list) {
+ usersList = list;
+ notifyDataSetChanged();
+ }
+}
diff --git a/app/src/main/java/org/mian/gitnex/adapters/profile/OrganizationsAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/profile/OrganizationsAdapter.java
new file mode 100644
index 00000000..86d218a9
--- /dev/null
+++ b/app/src/main/java/org/mian/gitnex/adapters/profile/OrganizationsAdapter.java
@@ -0,0 +1,137 @@
+package org.mian.gitnex.adapters.profile;
+
+import android.annotation.SuppressLint;
+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 androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+import org.gitnex.tea4j.models.UserOrganizations;
+import org.mian.gitnex.R;
+import org.mian.gitnex.clients.PicassoService;
+import org.mian.gitnex.helpers.AppUtil;
+import org.mian.gitnex.helpers.RoundedTransformation;
+import java.util.List;
+
+/**
+ * Author M M Arif
+ */
+
+public class OrganizationsAdapter extends RecyclerView.Adapter {
+
+ private final Context context;
+ private final int TYPE_LOAD = 0;
+ private List organizationsList;
+ private RepositoriesAdapter.OnLoadMoreListener loadMoreListener;
+ private boolean isLoading = false, isMoreDataAvailable = true;
+
+ public OrganizationsAdapter(Context ctx, List organizationsListMain) {
+ this.context = ctx;
+ this.organizationsList = organizationsListMain;
+ }
+
+ @NonNull
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+
+ LayoutInflater inflater = LayoutInflater.from(context);
+
+ if(viewType == TYPE_LOAD) {
+ return new OrganizationsHolder(inflater.inflate(R.layout.list_organizations, 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) {
+ ((OrganizationsHolder) holder).bindData(organizationsList.get(position));
+ }
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if(organizationsList.get(position).getUsername() != null) {
+ return TYPE_LOAD;
+ }
+ else {
+ return 1;
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return organizationsList.size();
+ }
+
+ class OrganizationsHolder extends RecyclerView.ViewHolder {
+
+ private UserOrganizations userOrganizations;
+
+ private final ImageView image;
+ private final TextView orgName;
+ private final TextView orgDescription;
+
+ OrganizationsHolder(View itemView) {
+
+ super(itemView);
+ orgName = itemView.findViewById(R.id.orgName);
+ orgDescription = itemView.findViewById(R.id.orgDescription);
+ image = itemView.findViewById(R.id.imageAvatar);
+ }
+
+ @SuppressLint("SetTextI18n")
+ void bindData(UserOrganizations userOrganizations) {
+
+ this.userOrganizations = userOrganizations;
+ int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
+
+ orgName.setText(userOrganizations.getUsername());
+
+ PicassoService.getInstance(context).get().load(userOrganizations.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(image);
+
+ if (!userOrganizations.getDescription().equals("")) {
+ orgDescription.setText(userOrganizations.getDescription());
+ }
+ }
+ }
+
+ 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(RepositoriesAdapter.OnLoadMoreListener loadMoreListener) {
+ this.loadMoreListener = loadMoreListener;
+ }
+
+ public void updateList(List list) {
+ organizationsList = list;
+ notifyDataSetChanged();
+ }
+}
diff --git a/app/src/main/java/org/mian/gitnex/adapters/profile/RepositoriesAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/profile/RepositoriesAdapter.java
new file mode 100644
index 00000000..7e33b0b1
--- /dev/null
+++ b/app/src/main/java/org/mian/gitnex/adapters/profile/RepositoriesAdapter.java
@@ -0,0 +1,196 @@
+package org.mian.gitnex.adapters.profile;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.graphics.Typeface;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CheckBox;
+import android.widget.ImageView;
+import android.widget.TextView;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+import com.amulyakhare.textdrawable.TextDrawable;
+import com.amulyakhare.textdrawable.util.ColorGenerator;
+import org.gitnex.tea4j.models.UserRepositories;
+import org.mian.gitnex.R;
+import org.mian.gitnex.clients.PicassoService;
+import org.mian.gitnex.helpers.AppUtil;
+import org.mian.gitnex.helpers.ClickListener;
+import org.mian.gitnex.helpers.RoundedTransformation;
+import org.mian.gitnex.helpers.TimeHelper;
+import org.mian.gitnex.helpers.TinyDB;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Author M M Arif
+ */
+
+public class RepositoriesAdapter extends RecyclerView.Adapter {
+
+ private final Context context;
+ private final int TYPE_LOAD = 0;
+ private List reposList;
+ private OnLoadMoreListener loadMoreListener;
+ private boolean isLoading = false, isMoreDataAvailable = true;
+
+ public RepositoriesAdapter(Context ctx, List reposListMain) {
+ this.context = ctx;
+ this.reposList = reposListMain;
+ }
+
+ @NonNull
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+
+ LayoutInflater inflater = LayoutInflater.from(context);
+
+ if(viewType == TYPE_LOAD) {
+ return new RepositoriesAdapter.RepositoriesHolder(inflater.inflate(R.layout.list_repositories, parent, false));
+ }
+ else {
+ return new RepositoriesAdapter.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) {
+ ((RepositoriesAdapter.RepositoriesHolder) holder).bindData(reposList.get(position));
+ }
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if(reposList.get(position).getFullName() != null) {
+ return TYPE_LOAD;
+ }
+ else {
+ return 1;
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return reposList.size();
+ }
+
+ class RepositoriesHolder extends RecyclerView.ViewHolder {
+
+ private UserRepositories userRepositories;
+
+ private final ImageView avatar;
+ private final TextView repoName;
+ private final TextView orgName;
+ private final TextView repoDescription;
+ private CheckBox isRepoAdmin;
+ private final TextView repoStars;
+ private final TextView repoLastUpdated;
+
+ RepositoriesHolder(View itemView) {
+
+ super(itemView);
+ repoName = itemView.findViewById(R.id.repoName);
+ orgName = itemView.findViewById(R.id.orgName);
+ repoDescription = itemView.findViewById(R.id.repoDescription);
+ isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
+ avatar = itemView.findViewById(R.id.imageAvatar);
+ repoStars = itemView.findViewById(R.id.repoStars);
+ repoLastUpdated = itemView.findViewById(R.id.repoLastUpdated);
+ }
+
+ @SuppressLint("SetTextI18n")
+ void bindData(UserRepositories userRepositories) {
+
+ this.userRepositories = userRepositories;
+ TinyDB tinyDb = TinyDB.getInstance(context);
+ int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
+
+ Locale locale = context.getResources().getConfiguration().locale;
+ String timeFormat = tinyDb.getString("dateFormat");
+
+ orgName.setText(userRepositories.getFullName().split("/")[0]);
+ repoName.setText(userRepositories.getFullName().split("/")[1]);
+ repoStars.setText(userRepositories.getStars_count());
+
+ ColorGenerator generator = ColorGenerator.MATERIAL;
+ int color = generator.getColor(userRepositories.getName());
+ String firstCharacter = String.valueOf(userRepositories.getFullName().charAt(0));
+
+ TextDrawable drawable = TextDrawable.builder().beginConfig().useFont(Typeface.DEFAULT).fontSize(18).toUpperCase().width(28).height(28).endConfig().buildRoundRect(firstCharacter, color, 3);
+
+ if(userRepositories.getAvatar_url() != null) {
+ if(!userRepositories.getAvatar_url().equals("")) {
+ PicassoService
+ .getInstance(context).get().load(userRepositories.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(avatar);
+ }
+ else {
+ avatar.setImageDrawable(drawable);
+ }
+ }
+ else {
+ avatar.setImageDrawable(drawable);
+ }
+
+ if(userRepositories.getUpdated_at() != null) {
+
+ repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, TimeHelper.formatTime(userRepositories.getUpdated_at(), locale, timeFormat, context)));
+ if(timeFormat.equals("pretty")) {
+ repoLastUpdated.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(userRepositories.getUpdated_at()), context));
+ }
+ }
+ else {
+ repoLastUpdated.setVisibility(View.GONE);
+ }
+
+ if(!userRepositories.getDescription().equals("")) {
+ repoDescription.setText(userRepositories.getDescription());
+ }
+ else {
+ repoDescription.setText(context.getString(R.string.noDataDescription));
+ }
+
+ if(isRepoAdmin == null) {
+ isRepoAdmin = new CheckBox(context);
+ }
+ isRepoAdmin.setChecked(userRepositories.getPermissions().isAdmin());
+
+ }
+ }
+
+ 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;
+ }
+
+ public void updateList(List list) {
+ reposList = list;
+ notifyDataSetChanged();
+ }
+}
diff --git a/app/src/main/java/org/mian/gitnex/adapters/profile/StarredRepositoriesAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/profile/StarredRepositoriesAdapter.java
new file mode 100644
index 00000000..204a19be
--- /dev/null
+++ b/app/src/main/java/org/mian/gitnex/adapters/profile/StarredRepositoriesAdapter.java
@@ -0,0 +1,197 @@
+package org.mian.gitnex.adapters.profile;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.graphics.Typeface;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CheckBox;
+import android.widget.ImageView;
+import android.widget.TextView;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+import com.amulyakhare.textdrawable.TextDrawable;
+import com.amulyakhare.textdrawable.util.ColorGenerator;
+import org.gitnex.tea4j.models.UserRepositories;
+import org.mian.gitnex.R;
+import org.mian.gitnex.clients.PicassoService;
+import org.mian.gitnex.helpers.AppUtil;
+import org.mian.gitnex.helpers.ClickListener;
+import org.mian.gitnex.helpers.RoundedTransformation;
+import org.mian.gitnex.helpers.TimeHelper;
+import org.mian.gitnex.helpers.TinyDB;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Author M M Arif
+ */
+
+public class StarredRepositoriesAdapter extends RecyclerView.Adapter {
+
+ private final Context context;
+ private final int TYPE_LOAD = 0;
+ private List reposList;
+ private OnLoadMoreListener loadMoreListener;
+ private boolean isLoading = false, isMoreDataAvailable = true;
+
+ public StarredRepositoriesAdapter(Context ctx, List reposListMain) {
+ this.context = ctx;
+ this.reposList = reposListMain;
+ }
+
+ @NonNull
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+
+ LayoutInflater inflater = LayoutInflater.from(context);
+
+ if(viewType == TYPE_LOAD) {
+ return new StarredRepositoriesAdapter.StarredRepositoriesHolder(inflater.inflate(R.layout.list_repositories, parent, false));
+ }
+ else {
+ return new StarredRepositoriesAdapter.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) {
+ ((StarredRepositoriesAdapter.StarredRepositoriesHolder) holder).bindData(reposList.get(position));
+ }
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if(reposList.get(position).getFullName() != null) {
+ return TYPE_LOAD;
+ }
+ else {
+ return 1;
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return reposList.size();
+ }
+
+ class StarredRepositoriesHolder extends RecyclerView.ViewHolder {
+
+ private UserRepositories userRepositories;
+
+ private final ImageView avatar;
+ private final TextView repoName;
+ private final TextView orgName;
+ private final TextView repoDescription;
+ private CheckBox isRepoAdmin;
+ private final TextView repoStars;
+ private final TextView repoLastUpdated;
+
+ StarredRepositoriesHolder(View itemView) {
+
+ super(itemView);
+ repoName = itemView.findViewById(R.id.repoName);
+ orgName = itemView.findViewById(R.id.orgName);
+ repoDescription = itemView.findViewById(R.id.repoDescription);
+ isRepoAdmin = itemView.findViewById(R.id.repoIsAdmin);
+ avatar = itemView.findViewById(R.id.imageAvatar);
+ repoStars = itemView.findViewById(R.id.repoStars);
+ repoLastUpdated = itemView.findViewById(R.id.repoLastUpdated);
+ }
+
+ @SuppressLint("SetTextI18n")
+ void bindData(UserRepositories userRepositories) {
+
+ this.userRepositories = userRepositories;
+ TinyDB tinyDb = TinyDB.getInstance(context);
+ int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
+
+ Locale locale = context.getResources().getConfiguration().locale;
+ String timeFormat = tinyDb.getString("dateFormat");
+
+ orgName.setText(userRepositories.getFullName().split("/")[0]);
+ repoName.setText(userRepositories.getFullName().split("/")[1]);
+ repoStars.setText(userRepositories.getStars_count());
+
+ ColorGenerator generator = ColorGenerator.MATERIAL;
+ int color = generator.getColor(userRepositories.getName());
+ String firstCharacter = String.valueOf(userRepositories.getFullName().charAt(0));
+
+ TextDrawable drawable = TextDrawable.builder().beginConfig().useFont(Typeface.DEFAULT).fontSize(18).toUpperCase().width(28).height(28).endConfig().buildRoundRect(firstCharacter, color, 3);
+
+ if(userRepositories.getAvatar_url() != null) {
+ if(!userRepositories.getAvatar_url().equals("")) {
+ PicassoService
+ .getInstance(context).get().load(userRepositories.getAvatar_url()).placeholder(R.drawable.loader_animated).transform(new RoundedTransformation(imgRadius, 0)).resize(120, 120).centerCrop().into(avatar);
+ }
+ else {
+ avatar.setImageDrawable(drawable);
+ }
+ }
+ else {
+ avatar.setImageDrawable(drawable);
+ }
+
+ if(userRepositories.getUpdated_at() != null) {
+
+ repoLastUpdated.setText(context.getString(R.string.lastUpdatedAt, TimeHelper
+ .formatTime(userRepositories.getUpdated_at(), locale, timeFormat, context)));
+ if(timeFormat.equals("pretty")) {
+ repoLastUpdated.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(userRepositories.getUpdated_at()), context));
+ }
+ }
+ else {
+ repoLastUpdated.setVisibility(View.GONE);
+ }
+
+ if(!userRepositories.getDescription().equals("")) {
+ repoDescription.setText(userRepositories.getDescription());
+ }
+ else {
+ repoDescription.setText(context.getString(R.string.noDataDescription));
+ }
+
+ if(isRepoAdmin == null) {
+ isRepoAdmin = new CheckBox(context);
+ }
+ isRepoAdmin.setChecked(userRepositories.getPermissions().isAdmin());
+
+ }
+ }
+
+ 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;
+ }
+
+ public void updateList(List list) {
+ reposList = list;
+ notifyDataSetChanged();
+ }
+}
diff --git a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetProfileFragment.java b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetMyProfileFragment.java
similarity index 80%
rename from app/src/main/java/org/mian/gitnex/fragments/BottomSheetProfileFragment.java
rename to app/src/main/java/org/mian/gitnex/fragments/BottomSheetMyProfileFragment.java
index 19fce304..1551baa0 100644
--- a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetProfileFragment.java
+++ b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetMyProfileFragment.java
@@ -8,14 +8,14 @@ import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
-import org.mian.gitnex.activities.ProfileEmailActivity;
+import org.mian.gitnex.activities.MyProfileEmailActivity;
import org.mian.gitnex.databinding.BottomSheetProfileBinding;
/**
* Author M M Arif
*/
-public class BottomSheetProfileFragment extends BottomSheetDialogFragment {
+public class BottomSheetMyProfileFragment extends BottomSheetDialogFragment {
@Nullable
@Override
@@ -25,7 +25,7 @@ public class BottomSheetProfileFragment extends BottomSheetDialogFragment {
bottomSheetProfileBinding.addNewEmailAddress.setOnClickListener(v1 -> {
- startActivity(new Intent(getContext(), ProfileEmailActivity.class));
+ startActivity(new Intent(getContext(), MyProfileEmailActivity.class));
dismiss();
});
diff --git a/app/src/main/java/org/mian/gitnex/fragments/ProfileEmailsFragment.java b/app/src/main/java/org/mian/gitnex/fragments/MyProfileEmailsFragment.java
similarity index 90%
rename from app/src/main/java/org/mian/gitnex/fragments/ProfileEmailsFragment.java
rename to app/src/main/java/org/mian/gitnex/fragments/MyProfileEmailsFragment.java
index 90101c4e..e310e0aa 100644
--- a/app/src/main/java/org/mian/gitnex/fragments/ProfileEmailsFragment.java
+++ b/app/src/main/java/org/mian/gitnex/fragments/MyProfileEmailsFragment.java
@@ -18,7 +18,7 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import org.gitnex.tea4j.models.Emails;
-import org.mian.gitnex.adapters.ProfileEmailsAdapter;
+import org.mian.gitnex.adapters.MyProfileEmailsAdapter;
import org.mian.gitnex.databinding.FragmentProfileEmailsBinding;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.viewmodels.ProfileEmailsViewModel;
@@ -28,10 +28,10 @@ import java.util.List;
* Author M M Arif
*/
-public class ProfileEmailsFragment extends Fragment {
+public class MyProfileEmailsFragment extends Fragment {
private ProgressBar mProgressBar;
- private ProfileEmailsAdapter adapter;
+ private MyProfileEmailsAdapter adapter;
private RecyclerView mRecyclerView;
private TextView noDataEmails;
private static String repoNameF = "param2";
@@ -42,11 +42,11 @@ public class ProfileEmailsFragment extends Fragment {
private OnFragmentInteractionListener mListener;
- public ProfileEmailsFragment() {
+ public MyProfileEmailsFragment() {
}
- public static ProfileEmailsFragment newInstance(String param1, String param2) {
- ProfileEmailsFragment fragment = new ProfileEmailsFragment();
+ public static MyProfileEmailsFragment newInstance(String param1, String param2) {
+ MyProfileEmailsFragment fragment = new MyProfileEmailsFragment();
Bundle args = new Bundle();
args.putString(repoOwnerF, param1);
args.putString(repoNameF, param2);
@@ -102,7 +102,7 @@ public class ProfileEmailsFragment extends Fragment {
profileEmailModel.getEmailsList(instanceToken, getContext()).observe(getViewLifecycleOwner(), new Observer>() {
@Override
public void onChanged(@Nullable List emailsListMain) {
- adapter = new ProfileEmailsAdapter(getContext(), emailsListMain);
+ adapter = new MyProfileEmailsAdapter(getContext(), emailsListMain);
if(adapter.getItemCount() > 0) {
mRecyclerView.setAdapter(adapter);
noDataEmails.setVisibility(View.GONE);
diff --git a/app/src/main/java/org/mian/gitnex/fragments/ProfileFollowersFragment.java b/app/src/main/java/org/mian/gitnex/fragments/MyProfileFollowersFragment.java
similarity index 77%
rename from app/src/main/java/org/mian/gitnex/fragments/ProfileFollowersFragment.java
rename to app/src/main/java/org/mian/gitnex/fragments/MyProfileFollowersFragment.java
index 68d3ebaa..4f42ec81 100644
--- a/app/src/main/java/org/mian/gitnex/fragments/ProfileFollowersFragment.java
+++ b/app/src/main/java/org/mian/gitnex/fragments/MyProfileFollowersFragment.java
@@ -16,8 +16,8 @@ import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
-import org.mian.gitnex.adapters.ProfileFollowersAdapter;
-import org.mian.gitnex.databinding.FragmentProfileFollowersBinding;
+import org.mian.gitnex.adapters.MyProfileFollowersAdapter;
+import org.mian.gitnex.databinding.FragmentProfileFollowersFollowingBinding;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.viewmodels.ProfileFollowersViewModel;
@@ -25,10 +25,10 @@ import org.mian.gitnex.viewmodels.ProfileFollowersViewModel;
* Author M M Arif
*/
-public class ProfileFollowersFragment extends Fragment {
+public class MyProfileFollowersFragment extends Fragment {
private ProgressBar mProgressBar;
- private ProfileFollowersAdapter adapter;
+ private MyProfileFollowersAdapter adapter;
private RecyclerView mRecyclerView;
private TextView noDataFollowers;
private static String repoNameF = "param2";
@@ -39,11 +39,11 @@ public class ProfileFollowersFragment extends Fragment {
private OnFragmentInteractionListener mListener;
- public ProfileFollowersFragment() {
+ public MyProfileFollowersFragment() {
}
- public static ProfileFollowersFragment newInstance(String param1, String param2) {
- ProfileFollowersFragment fragment = new ProfileFollowersFragment();
+ public static MyProfileFollowersFragment newInstance(String param1, String param2) {
+ MyProfileFollowersFragment fragment = new MyProfileFollowersFragment();
Bundle args = new Bundle();
args.putString(repoOwnerF, param1);
args.putString(repoNameF, param2);
@@ -64,12 +64,12 @@ public class ProfileFollowersFragment extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- FragmentProfileFollowersBinding fragmentProfileFollowersBinding = FragmentProfileFollowersBinding.inflate(inflater, container, false);
+ FragmentProfileFollowersFollowingBinding fragmentProfileFollowersFollowingBinding = FragmentProfileFollowersFollowingBinding.inflate(inflater, container, false);
- final SwipeRefreshLayout swipeRefresh = fragmentProfileFollowersBinding.pullToRefresh;
+ final SwipeRefreshLayout swipeRefresh = fragmentProfileFollowersFollowingBinding.pullToRefresh;
- noDataFollowers = fragmentProfileFollowersBinding.noDataFollowers;
- mRecyclerView = fragmentProfileFollowersBinding.recyclerView;
+ noDataFollowers = fragmentProfileFollowersFollowingBinding.noData;
+ mRecyclerView = fragmentProfileFollowersFollowingBinding.recyclerView;
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL);
@@ -77,7 +77,7 @@ public class ProfileFollowersFragment extends Fragment {
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mRecyclerView.addItemDecoration(dividerItemDecoration);
- mProgressBar = fragmentProfileFollowersBinding.progressBar;
+ mProgressBar = fragmentProfileFollowersFollowingBinding.progressBar;
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
@@ -88,7 +88,7 @@ public class ProfileFollowersFragment extends Fragment {
fetchDataAsync(Authorization.get(getContext()));
- return fragmentProfileFollowersBinding.getRoot();
+ return fragmentProfileFollowersFollowingBinding.getRoot();
}
private void fetchDataAsync(String instanceToken) {
@@ -97,7 +97,7 @@ public class ProfileFollowersFragment extends Fragment {
pfModel.getFollowersList(instanceToken, getContext()).observe(getViewLifecycleOwner(), pfListMain -> {
- adapter = new ProfileFollowersAdapter(getContext(), pfListMain);
+ adapter = new MyProfileFollowersAdapter(getContext(), pfListMain);
if(adapter.getItemCount() > 0) {
mRecyclerView.setAdapter(adapter);
diff --git a/app/src/main/java/org/mian/gitnex/fragments/ProfileFollowingFragment.java b/app/src/main/java/org/mian/gitnex/fragments/MyProfileFollowingFragment.java
similarity index 75%
rename from app/src/main/java/org/mian/gitnex/fragments/ProfileFollowingFragment.java
rename to app/src/main/java/org/mian/gitnex/fragments/MyProfileFollowingFragment.java
index 7095e096..5aa9ce13 100644
--- a/app/src/main/java/org/mian/gitnex/fragments/ProfileFollowingFragment.java
+++ b/app/src/main/java/org/mian/gitnex/fragments/MyProfileFollowingFragment.java
@@ -16,8 +16,8 @@ import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
-import org.mian.gitnex.adapters.ProfileFollowingAdapter;
-import org.mian.gitnex.databinding.FragmentProfileFollowingBinding;
+import org.mian.gitnex.adapters.MyProfileFollowingAdapter;
+import org.mian.gitnex.databinding.FragmentProfileFollowersFollowingBinding;
import org.mian.gitnex.helpers.Authorization;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.viewmodels.ProfileFollowingViewModel;
@@ -26,25 +26,25 @@ import org.mian.gitnex.viewmodels.ProfileFollowingViewModel;
* Author M M Arif
*/
-public class ProfileFollowingFragment extends Fragment {
+public class MyProfileFollowingFragment extends Fragment {
private ProgressBar mProgressBar;
- private ProfileFollowingAdapter adapter;
+ private MyProfileFollowingAdapter adapter;
private RecyclerView mRecyclerView;
private TextView noDataFollowing;
- private static String repoNameF = "param2";
- private static String repoOwnerF = "param1";
+ private static final String repoNameF = "param2";
+ private static final String repoOwnerF = "param1";
private String repoName;
private String repoOwner;
private OnFragmentInteractionListener mListener;
- public ProfileFollowingFragment() {
+ public MyProfileFollowingFragment() {
}
- public static ProfileFollowingFragment newInstance(String param1, String param2) {
- ProfileFollowingFragment fragment = new ProfileFollowingFragment();
+ public static MyProfileFollowingFragment newInstance(String param1, String param2) {
+ MyProfileFollowingFragment fragment = new MyProfileFollowingFragment();
Bundle args = new Bundle();
args.putString(repoOwnerF, param1);
args.putString(repoNameF, param2);
@@ -65,14 +65,14 @@ public class ProfileFollowingFragment extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- FragmentProfileFollowingBinding fragmentProfileFollowingBinding = FragmentProfileFollowingBinding.inflate(inflater, container, false);
+ FragmentProfileFollowersFollowingBinding fragmentProfileFollowersFollowingBinding = FragmentProfileFollowersFollowingBinding.inflate(inflater, container, false);
TinyDB tinyDb = TinyDB.getInstance(getContext());
- final SwipeRefreshLayout swipeRefresh = fragmentProfileFollowingBinding.pullToRefresh;
+ final SwipeRefreshLayout swipeRefresh = fragmentProfileFollowersFollowingBinding.pullToRefresh;
- noDataFollowing = fragmentProfileFollowingBinding.noDataFollowing;
- mRecyclerView = fragmentProfileFollowingBinding.recyclerView;
+ noDataFollowing = fragmentProfileFollowersFollowingBinding.noData;
+ mRecyclerView = fragmentProfileFollowersFollowingBinding.recyclerView;
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL);
@@ -80,7 +80,7 @@ public class ProfileFollowingFragment extends Fragment {
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mRecyclerView.addItemDecoration(dividerItemDecoration);
- mProgressBar = fragmentProfileFollowingBinding.progressBar;
+ mProgressBar = fragmentProfileFollowersFollowingBinding.progressBar;
swipeRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
@@ -91,7 +91,7 @@ public class ProfileFollowingFragment extends Fragment {
fetchDataAsync(Authorization.get(getContext()));
- return fragmentProfileFollowingBinding.getRoot();
+ return fragmentProfileFollowersFollowingBinding.getRoot();
}
private void fetchDataAsync(String instanceToken) {
@@ -100,7 +100,7 @@ public class ProfileFollowingFragment extends Fragment {
pfModel.getFollowingList(instanceToken, getContext()).observe(getViewLifecycleOwner(), pfListMain -> {
- adapter = new ProfileFollowingAdapter(getContext(), pfListMain);
+ adapter = new MyProfileFollowingAdapter(getContext(), pfListMain);
if(adapter.getItemCount() > 0) {
mRecyclerView.setAdapter(adapter);
diff --git a/app/src/main/java/org/mian/gitnex/fragments/ProfileFragment.java b/app/src/main/java/org/mian/gitnex/fragments/MyProfileFragment.java
similarity index 86%
rename from app/src/main/java/org/mian/gitnex/fragments/ProfileFragment.java
rename to app/src/main/java/org/mian/gitnex/fragments/MyProfileFragment.java
index 4df62072..97e46874 100644
--- a/app/src/main/java/org/mian/gitnex/fragments/ProfileFragment.java
+++ b/app/src/main/java/org/mian/gitnex/fragments/MyProfileFragment.java
@@ -36,7 +36,7 @@ import jp.wasabeef.picasso.transformations.BlurTransformation;
* Author M M Arif
*/
-public class ProfileFragment extends Fragment {
+public class MyProfileFragment extends Fragment {
private Context ctx;
@@ -61,18 +61,14 @@ public class ProfileFragment extends Fragment {
TextView userLanguage = v.findViewById(R.id.userLanguage);
ImageView userLanguageIcon = v.findViewById(R.id.userLanguageIcon);
- ViewGroup aboutFrame = v.findViewById(R.id.aboutFrame);
-
String[] userLanguageCodes = tinyDb.getString("userLang").split("-");
if(userLanguageCodes.length >= 2) {
-
Locale locale = new Locale(userLanguageCodes[0], userLanguageCodes[1]);
userLanguage.setText(locale.getDisplayLanguage());
}
else {
-
- userLanguage.setText(R.string.notSupported);
+ userLanguage.setText(getResources().getConfiguration().locale.getDisplayLanguage());
}
userAvatar.setOnClickListener(loginId ->
@@ -112,7 +108,7 @@ public class ProfileFragment extends Fragment {
@Override public void onError(Exception e) {}
});
- ProfileFragment.SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager());
+ MyProfileFragment.SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager());
ViewPager mViewPager = v.findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
@@ -159,7 +155,6 @@ public class ProfileFragment extends Fragment {
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
return v;
-
}
public static class SectionsPagerAdapter extends FragmentStatePagerAdapter {
@@ -175,25 +170,23 @@ public class ProfileFragment extends Fragment {
switch (position) {
case 0: // followers
- return ProfileFollowersFragment.newInstance("repoOwner", "repoName");
+ return MyProfileFollowersFragment.newInstance("repoOwner", "repoName");
case 1: // following
- return ProfileFollowingFragment.newInstance("repoOwner", "repoName");
+ return MyProfileFollowingFragment.newInstance("repoOwner", "repoName");
case 2: // emails
- return ProfileEmailsFragment.newInstance("repoOwner", "repoName");
+ return MyProfileEmailsFragment.newInstance("repoOwner", "repoName");
}
return null;
-
}
@Override
public int getCount() {
return 3;
}
-
}
@Override
@@ -202,7 +195,6 @@ public class ProfileFragment extends Fragment {
menu.clear();
requireActivity().getMenuInflater().inflate(R.menu.profile_dotted_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
-
}
@Override
@@ -210,21 +202,18 @@ public class ProfileFragment extends Fragment {
int id = item.getItemId();
- switch (id) {
-
- case android.R.id.home:
- ((MainActivity)ctx).finish();
- return true;
-
- case R.id.profileMenu:
- BottomSheetProfileFragment bottomSheet = new BottomSheetProfileFragment();
- bottomSheet.show(getChildFragmentManager(), "profileBottomSheet");
- return true;
-
- default:
- return super.onOptionsItemSelected(item);
-
- }
+ if(id == android.R.id.home) {
+ ((MainActivity)ctx).finish();
+ return true;
+ }
+ else if(id == R.id.profileMenu) {
+ BottomSheetMyProfileFragment bottomSheet = new BottomSheetMyProfileFragment();
+ bottomSheet.show(getChildFragmentManager(), "profileBottomSheet");
+ return true;
+ }
+ else {
+ return super.onOptionsItemSelected(item);
+ }
}
}
diff --git a/app/src/main/java/org/mian/gitnex/fragments/RepositoriesFragment.java b/app/src/main/java/org/mian/gitnex/fragments/RepositoriesFragment.java
index 7cf70021..25149685 100644
--- a/app/src/main/java/org/mian/gitnex/fragments/RepositoriesFragment.java
+++ b/app/src/main/java/org/mian/gitnex/fragments/RepositoriesFragment.java
@@ -69,7 +69,6 @@ public class RepositoriesFragment extends Fragment {
createNewRepo = fragmentRepositoriesBinding.addNewRepo;
createNewRepo.setOnClickListener(view -> {
-
Intent intent = new Intent(view.getContext(), CreateRepoActivity.class);
startActivity(intent);
});
@@ -79,9 +78,9 @@ public class RepositoriesFragment extends Fragment {
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
if (dy > 0 && createNewRepo.isShown()) {
createNewRepo.setVisibility(View.GONE);
- } else if (dy < 0 ) {
+ }
+ else if (dy < 0 ) {
createNewRepo.setVisibility(View.VISIBLE);
-
}
}
@@ -135,7 +134,6 @@ public class RepositoriesFragment extends Fragment {
}
mProgressBar.setVisibility(View.GONE);
});
-
}
@Override
@@ -147,11 +145,6 @@ public class RepositoriesFragment extends Fragment {
MenuItem searchItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
- //searchView.setQueryHint(getContext().getString(R.string.strFilter));
-
- /*if(!connToInternet) {
- return;
- }*/
searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
@Override
@@ -167,7 +160,6 @@ public class RepositoriesFragment extends Fragment {
return false;
}
});
-
}
}
diff --git a/app/src/main/java/org/mian/gitnex/fragments/profile/DetailFragment.java b/app/src/main/java/org/mian/gitnex/fragments/profile/DetailFragment.java
new file mode 100644
index 00000000..8c389444
--- /dev/null
+++ b/app/src/main/java/org/mian/gitnex/fragments/profile/DetailFragment.java
@@ -0,0 +1,160 @@
+package org.mian.gitnex.fragments.profile;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
+import org.gitnex.tea4j.models.UserInfo;
+import org.mian.gitnex.R;
+import org.mian.gitnex.clients.PicassoService;
+import org.mian.gitnex.clients.RetrofitClient;
+import org.mian.gitnex.databinding.FragmentProfileDetailBinding;
+import org.mian.gitnex.helpers.AlertDialogs;
+import org.mian.gitnex.helpers.AppUtil;
+import org.mian.gitnex.helpers.Authorization;
+import org.mian.gitnex.helpers.ClickListener;
+import org.mian.gitnex.helpers.ColorInverter;
+import org.mian.gitnex.helpers.RoundedTransformation;
+import org.mian.gitnex.helpers.TimeHelper;
+import org.mian.gitnex.helpers.TinyDB;
+import org.mian.gitnex.helpers.Toasty;
+import java.util.Locale;
+import jp.wasabeef.picasso.transformations.BlurTransformation;
+import retrofit2.Call;
+import retrofit2.Callback;
+
+/**
+ * Author M M Arif
+ */
+
+public class DetailFragment extends Fragment {
+
+ private Context context;
+ private FragmentProfileDetailBinding binding;
+ Locale locale;
+ TinyDB tinyDb;
+
+ private static final String usernameBundle = "";
+ private String username;
+
+ public DetailFragment() {}
+
+ public static DetailFragment newInstance(String username) {
+ DetailFragment fragment = new DetailFragment();
+ Bundle args = new Bundle();
+ args.putString(usernameBundle, username);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (getArguments() != null) {
+ username = getArguments().getString(usernameBundle);
+ }
+ }
+
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+
+ binding = FragmentProfileDetailBinding.inflate(inflater, container, false);
+ context = getContext();
+ tinyDb = TinyDB.getInstance(context);
+ locale = getResources().getConfiguration().locale;
+
+ getProfileDetail(username);
+
+ return binding.getRoot();
+ }
+
+ public void getProfileDetail(String username) {
+
+ Call call = RetrofitClient
+ .getApiInterface(context)
+ .getUserProfile(Authorization.get(context), username);
+
+ call.enqueue(new Callback() {
+ @Override
+ public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) {
+
+ if(response.isSuccessful() && response.body() != null) {
+
+ switch(response.code()) {
+ case 200:
+ String username = !response.body().getFullname().isEmpty() ? response.body().getFullname() : response.body().getUsername();
+ String email = !response.body().getEmail().isEmpty() ? response.body().getEmail() : "";
+
+ int imgRadius = AppUtil.getPixelsFromDensity(context, 3);
+ String timeFormat = tinyDb.getString("dateFormat");
+
+ binding.userFullName.setText(username);
+ binding.userLogin.setText(getString(R.string.usernameWithAt, response.body().getLogin()));
+ binding.userEmail.setText(email);
+
+ String[] userLanguageCodes = response.body().getLang().split("-");
+
+ if(userLanguageCodes.length >= 2) {
+ Locale locale = new Locale(userLanguageCodes[0], userLanguageCodes[1]);
+ binding.userLang.setText(locale.getDisplayLanguage());
+ }
+ else {
+ binding.userLang.setText(locale.getDisplayLanguage());
+ }
+
+ PicassoService.getInstance(context).get()
+ .load(response.body().getAvatar())
+ .transform(new RoundedTransformation(imgRadius, 0))
+ .placeholder(R.drawable.loader_animated)
+ .resize(120, 120)
+ .centerCrop()
+ .into(binding.userAvatar);
+
+ PicassoService.getInstance(context).get()
+ .load(response.body().getAvatar())
+ .transform(new BlurTransformation(context))
+ .into(binding.userAvatarBackground, new com.squareup.picasso.Callback() {
+
+ @Override
+ public void onSuccess() {
+ int invertedColor = new ColorInverter().getImageViewContrastColor(binding.userAvatarBackground);
+
+ binding.userFullName.setTextColor(invertedColor);
+ binding.userLogin.setTextColor(invertedColor);
+ }
+
+ @Override public void onError(Exception e) {}
+ });
+
+ binding.userJoinedOn.setText(TimeHelper.formatTime(response.body().getCreated(), locale, timeFormat, context));
+ if(timeFormat.equals("pretty")) {
+ binding.userJoinedOn.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToastDateFormat(response.body().getCreated()), context));
+ }
+ break;
+
+ case 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));
+ break;
+
+ case 403:
+ Toasty.error(context, context.getString(R.string.authorizeError));
+ break;
+
+ default:
+ Toasty.error(context, getString(R.string.genericError));
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call call, @NonNull Throwable t) {
+ Toasty.error(context, context.getResources().getString(R.string.genericError));
+ }
+ });
+ }
+}
diff --git a/app/src/main/java/org/mian/gitnex/fragments/profile/FollowersFragment.java b/app/src/main/java/org/mian/gitnex/fragments/profile/FollowersFragment.java
new file mode 100644
index 00000000..d4ebef5a
--- /dev/null
+++ b/app/src/main/java/org/mian/gitnex/fragments/profile/FollowersFragment.java
@@ -0,0 +1,272 @@
+package org.mian.gitnex.fragments.profile;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.inputmethod.EditorInfo;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.recyclerview.widget.DividerItemDecoration;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import org.gitnex.tea4j.models.UserInfo;
+import org.mian.gitnex.R;
+import org.mian.gitnex.adapters.profile.FollowersAdapter;
+import org.mian.gitnex.clients.RetrofitClient;
+import org.mian.gitnex.databinding.FragmentProfileFollowersFollowingBinding;
+import org.mian.gitnex.helpers.AlertDialogs;
+import org.mian.gitnex.helpers.Authorization;
+import org.mian.gitnex.helpers.Constants;
+import org.mian.gitnex.helpers.SnackBar;
+import org.mian.gitnex.helpers.TinyDB;
+import org.mian.gitnex.helpers.Toasty;
+import org.mian.gitnex.helpers.Version;
+import java.util.ArrayList;
+import java.util.List;
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+/**
+ * Author M M Arif
+ */
+
+public class FollowersFragment extends Fragment {
+
+ private Context context;
+ private FragmentProfileFollowersFollowingBinding fragmentProfileFollowersFollowingBinding;
+
+ private List usersList;
+ private FollowersAdapter adapter;
+
+ private int pageSize;
+ private int resultLimit = Constants.resultLimitOldGiteaInstances;
+
+ private static final String usernameBundle = "";
+ private String username;
+
+ public FollowersFragment() {}
+
+ public static FollowersFragment newInstance(String username) {
+ FollowersFragment fragment = new FollowersFragment();
+ Bundle args = new Bundle();
+ args.putString(usernameBundle, username);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (getArguments() != null) {
+ username = getArguments().getString(usernameBundle);
+ }
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+
+ fragmentProfileFollowersFollowingBinding = FragmentProfileFollowersFollowingBinding.inflate(inflater, container, false);
+ setHasOptionsMenu(true);
+ context = getContext();
+
+ TinyDB tinyDb = TinyDB.getInstance(context);
+
+ // if gitea is 1.12 or higher use the new limit
+ if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
+ resultLimit = Constants.resultLimitNewGiteaInstances;
+ }
+
+ usersList = new ArrayList<>();
+
+ fragmentProfileFollowersFollowingBinding.pullToRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
+ fragmentProfileFollowersFollowingBinding.pullToRefresh.setRefreshing(false);
+ loadInitial(Authorization.get(context), username, resultLimit);
+ adapter.notifyDataChanged();
+ }, 200));
+
+ adapter = new FollowersAdapter(context, usersList);
+ adapter.setLoadMoreListener(() -> fragmentProfileFollowersFollowingBinding.recyclerView.post(() -> {
+ if(usersList.size() == resultLimit || pageSize == resultLimit) {
+ int page = (usersList.size() + resultLimit) / resultLimit;
+ loadMore(Authorization.get(context), username, page, resultLimit);
+ }
+ }));
+
+ DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(context, DividerItemDecoration.VERTICAL);
+ fragmentProfileFollowersFollowingBinding.recyclerView.setHasFixedSize(true);
+ fragmentProfileFollowersFollowingBinding.recyclerView.addItemDecoration(dividerItemDecoration);
+ fragmentProfileFollowersFollowingBinding.recyclerView.setLayoutManager(new LinearLayoutManager(context));
+ fragmentProfileFollowersFollowingBinding.recyclerView.setAdapter(adapter);
+
+ loadInitial(Authorization.get(context), username, resultLimit);
+
+ return fragmentProfileFollowersFollowingBinding.getRoot();
+ }
+
+ private void loadInitial(String token, String username, int resultLimit) {
+
+ Call> call = RetrofitClient
+ .getApiInterface(context)
+ .getUserFollowers(token, username, 1, resultLimit);
+
+ call.enqueue(new Callback>() {
+ @Override
+ public void onResponse(@NonNull Call> call, @NonNull Response> response) {
+
+ if(response.isSuccessful()) {
+
+ switch(response.code()) {
+ case 200:
+ assert response.body() != null;
+ if(response.body().size() > 0) {
+ usersList.clear();
+ usersList.addAll(response.body());
+ adapter.notifyDataChanged();
+ fragmentProfileFollowersFollowingBinding.noData.setVisibility(View.GONE);
+ }
+ else {
+ usersList.clear();
+ adapter.notifyDataChanged();
+ fragmentProfileFollowersFollowingBinding.noData.setVisibility(View.VISIBLE);
+ }
+ fragmentProfileFollowersFollowingBinding.progressBar.setVisibility(View.GONE);
+ break;
+
+ case 401:
+ AlertDialogs.authorizationTokenRevokedDialog(context, getResources().getString(R.string.alertDialogTokenRevokedTitle),
+ getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
+ getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
+ break;
+
+ case 403:
+ Toasty.error(context, context.getString(R.string.authorizeError));
+ break;
+
+ case 404:
+ fragmentProfileFollowersFollowingBinding.noData.setVisibility(View.VISIBLE);
+ fragmentProfileFollowersFollowingBinding.progressBar.setVisibility(View.GONE);
+ break;
+
+ default:
+ Toasty.error(context, getString(R.string.genericError));
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
+ Toasty.error(context, getString(R.string.genericError));
+ }
+ });
+ }
+
+ private void loadMore(String token, String username, int page, int resultLimit) {
+
+ fragmentProfileFollowersFollowingBinding.progressLoadMore.setVisibility(View.VISIBLE);
+
+ Call> call = RetrofitClient
+ .getApiInterface(context)
+ .getUserFollowers(token, username, page, resultLimit);
+
+ call.enqueue(new Callback>() {
+
+ @Override
+ public void onResponse(@NonNull Call> call, @NonNull Response> response) {
+
+ if(response.isSuccessful()) {
+
+ switch(response.code()) {
+ case 200:
+ List result = response.body();
+ assert result != null;
+ if(result.size() > 0) {
+ pageSize = result.size();
+ usersList.addAll(result);
+ }
+ else {
+ SnackBar.info(context, fragmentProfileFollowersFollowingBinding.getRoot(), getString(R.string.noMoreData));
+ adapter.setMoreDataAvailable(false);
+ }
+ adapter.notifyDataChanged();
+ fragmentProfileFollowersFollowingBinding.progressLoadMore.setVisibility(View.GONE);
+ break;
+
+ case 401:
+ AlertDialogs.authorizationTokenRevokedDialog(context, getResources().getString(R.string.alertDialogTokenRevokedTitle),
+ getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
+ getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
+ break;
+
+ case 403:
+ Toasty.error(context, context.getString(R.string.authorizeError));
+ break;
+
+ case 404:
+ fragmentProfileFollowersFollowingBinding.noData.setVisibility(View.VISIBLE);
+ fragmentProfileFollowersFollowingBinding.progressBar.setVisibility(View.GONE);
+ break;
+
+ default:
+ Toasty.error(context, getString(R.string.genericError));
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
+ Toasty.error(context, getString(R.string.genericError));
+ }
+ });
+ }
+
+ @Override
+ public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
+
+ inflater.inflate(R.menu.search_menu, menu);
+ super.onCreateOptionsMenu(menu, inflater);
+
+ MenuItem searchItem = menu.findItem(R.id.action_search);
+ androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
+ searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
+
+ searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
+
+ @Override
+ public boolean onQueryTextSubmit(String query) {
+ return false;
+ }
+
+ @Override
+ public boolean onQueryTextChange(String newText) {
+ filter(newText);
+ return false;
+ }
+ });
+ }
+
+ private void filter(String text) {
+
+ List arr = new ArrayList<>();
+
+ for(UserInfo d : usersList) {
+ if(d == null || d.getUsername() == null || d.getFullname() == null) {
+ continue;
+ }
+ if(d.getUsername().toLowerCase().contains(text) || d.getFullname().toLowerCase().contains(text)) {
+ arr.add(d);
+ }
+ }
+ adapter.updateList(arr);
+ }
+}
diff --git a/app/src/main/java/org/mian/gitnex/fragments/profile/FollowingFragment.java b/app/src/main/java/org/mian/gitnex/fragments/profile/FollowingFragment.java
new file mode 100644
index 00000000..82390c85
--- /dev/null
+++ b/app/src/main/java/org/mian/gitnex/fragments/profile/FollowingFragment.java
@@ -0,0 +1,273 @@
+package org.mian.gitnex.fragments.profile;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.inputmethod.EditorInfo;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.recyclerview.widget.DividerItemDecoration;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import org.gitnex.tea4j.models.UserInfo;
+import org.mian.gitnex.R;
+import org.mian.gitnex.adapters.profile.FollowersAdapter;
+import org.mian.gitnex.adapters.profile.FollowingAdapter;
+import org.mian.gitnex.clients.RetrofitClient;
+import org.mian.gitnex.databinding.FragmentProfileFollowersFollowingBinding;
+import org.mian.gitnex.helpers.AlertDialogs;
+import org.mian.gitnex.helpers.Authorization;
+import org.mian.gitnex.helpers.Constants;
+import org.mian.gitnex.helpers.SnackBar;
+import org.mian.gitnex.helpers.TinyDB;
+import org.mian.gitnex.helpers.Toasty;
+import org.mian.gitnex.helpers.Version;
+import java.util.ArrayList;
+import java.util.List;
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+/**
+ * Author M M Arif
+ */
+
+public class FollowingFragment extends Fragment {
+
+ private Context context;
+ private FragmentProfileFollowersFollowingBinding fragmentProfileFollowersFollowingBinding;
+
+ private List usersList;
+ private FollowingAdapter adapter;
+
+ private int pageSize;
+ private int resultLimit = Constants.resultLimitOldGiteaInstances;
+
+ private static final String usernameBundle = "";
+ private String username;
+
+ public FollowingFragment() {}
+
+ public static FollowingFragment newInstance(String username) {
+ FollowingFragment fragment = new FollowingFragment();
+ Bundle args = new Bundle();
+ args.putString(usernameBundle, username);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (getArguments() != null) {
+ username = getArguments().getString(usernameBundle);
+ }
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+
+ fragmentProfileFollowersFollowingBinding = FragmentProfileFollowersFollowingBinding.inflate(inflater, container, false);
+ setHasOptionsMenu(true);
+ context = getContext();
+
+ TinyDB tinyDb = TinyDB.getInstance(context);
+
+ // if gitea is 1.12 or higher use the new limit
+ if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
+ resultLimit = Constants.resultLimitNewGiteaInstances;
+ }
+
+ usersList = new ArrayList<>();
+
+ fragmentProfileFollowersFollowingBinding.pullToRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
+ fragmentProfileFollowersFollowingBinding.pullToRefresh.setRefreshing(false);
+ loadInitial(Authorization.get(context), username, resultLimit);
+ adapter.notifyDataChanged();
+ }, 200));
+
+ adapter = new FollowingAdapter(context, usersList);
+ adapter.setLoadMoreListener(() -> fragmentProfileFollowersFollowingBinding.recyclerView.post(() -> {
+ if(usersList.size() == resultLimit || pageSize == resultLimit) {
+ int page = (usersList.size() + resultLimit) / resultLimit;
+ loadMore(Authorization.get(context), username, page, resultLimit);
+ }
+ }));
+
+ DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(context, DividerItemDecoration.VERTICAL);
+ fragmentProfileFollowersFollowingBinding.recyclerView.setHasFixedSize(true);
+ fragmentProfileFollowersFollowingBinding.recyclerView.addItemDecoration(dividerItemDecoration);
+ fragmentProfileFollowersFollowingBinding.recyclerView.setLayoutManager(new LinearLayoutManager(context));
+ fragmentProfileFollowersFollowingBinding.recyclerView.setAdapter(adapter);
+
+ loadInitial(Authorization.get(context), username, resultLimit);
+
+ return fragmentProfileFollowersFollowingBinding.getRoot();
+ }
+
+ private void loadInitial(String token, String username, int resultLimit) {
+
+ Call> call = RetrofitClient
+ .getApiInterface(context)
+ .getUserFollowing(token, username, 1, resultLimit);
+
+ call.enqueue(new Callback>() {
+ @Override
+ public void onResponse(@NonNull Call> call, @NonNull Response> response) {
+
+ if(response.isSuccessful()) {
+
+ switch(response.code()) {
+ case 200:
+ assert response.body() != null;
+ if(response.body().size() > 0) {
+ usersList.clear();
+ usersList.addAll(response.body());
+ adapter.notifyDataChanged();
+ fragmentProfileFollowersFollowingBinding.noData.setVisibility(View.GONE);
+ }
+ else {
+ usersList.clear();
+ adapter.notifyDataChanged();
+ fragmentProfileFollowersFollowingBinding.noData.setVisibility(View.VISIBLE);
+ }
+ fragmentProfileFollowersFollowingBinding.progressBar.setVisibility(View.GONE);
+ break;
+
+ case 401:
+ AlertDialogs.authorizationTokenRevokedDialog(context, getResources().getString(R.string.alertDialogTokenRevokedTitle),
+ getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
+ getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
+ break;
+
+ case 403:
+ Toasty.error(context, context.getString(R.string.authorizeError));
+ break;
+
+ case 404:
+ fragmentProfileFollowersFollowingBinding.noData.setVisibility(View.VISIBLE);
+ fragmentProfileFollowersFollowingBinding.progressBar.setVisibility(View.GONE);
+ break;
+
+ default:
+ Toasty.error(context, getString(R.string.genericError));
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
+ Toasty.error(context, getString(R.string.genericError));
+ }
+ });
+ }
+
+ private void loadMore(String token, String username, int page, int resultLimit) {
+
+ fragmentProfileFollowersFollowingBinding.progressLoadMore.setVisibility(View.VISIBLE);
+
+ Call> call = RetrofitClient
+ .getApiInterface(context)
+ .getUserFollowing(token, username, page, resultLimit);
+
+ call.enqueue(new Callback>() {
+
+ @Override
+ public void onResponse(@NonNull Call> call, @NonNull Response> response) {
+
+ if(response.isSuccessful()) {
+
+ switch(response.code()) {
+ case 200:
+ List result = response.body();
+ assert result != null;
+ if(result.size() > 0) {
+ pageSize = result.size();
+ usersList.addAll(result);
+ }
+ else {
+ SnackBar.info(context, fragmentProfileFollowersFollowingBinding.getRoot(), getString(R.string.noMoreData));
+ adapter.setMoreDataAvailable(false);
+ }
+ adapter.notifyDataChanged();
+ fragmentProfileFollowersFollowingBinding.progressLoadMore.setVisibility(View.GONE);
+ break;
+
+ case 401:
+ AlertDialogs.authorizationTokenRevokedDialog(context, getResources().getString(R.string.alertDialogTokenRevokedTitle),
+ getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
+ getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
+ break;
+
+ case 403:
+ Toasty.error(context, context.getString(R.string.authorizeError));
+ break;
+
+ case 404:
+ fragmentProfileFollowersFollowingBinding.noData.setVisibility(View.VISIBLE);
+ fragmentProfileFollowersFollowingBinding.progressBar.setVisibility(View.GONE);
+ break;
+
+ default:
+ Toasty.error(context, getString(R.string.genericError));
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
+ Toasty.error(context, getString(R.string.genericError));
+ }
+ });
+ }
+
+ @Override
+ public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
+
+ inflater.inflate(R.menu.search_menu, menu);
+ super.onCreateOptionsMenu(menu, inflater);
+
+ MenuItem searchItem = menu.findItem(R.id.action_search);
+ androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
+ searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
+
+ searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
+
+ @Override
+ public boolean onQueryTextSubmit(String query) {
+ return false;
+ }
+
+ @Override
+ public boolean onQueryTextChange(String newText) {
+ filter(newText);
+ return false;
+ }
+ });
+ }
+
+ private void filter(String text) {
+
+ List arr = new ArrayList<>();
+
+ for(UserInfo d : usersList) {
+ if(d == null || d.getUsername() == null || d.getFullname() == null) {
+ continue;
+ }
+ if(d.getUsername().toLowerCase().contains(text) || d.getFullname().toLowerCase().contains(text)) {
+ arr.add(d);
+ }
+ }
+ adapter.updateList(arr);
+ }
+}
diff --git a/app/src/main/java/org/mian/gitnex/fragments/profile/OrganizationsFragment.java b/app/src/main/java/org/mian/gitnex/fragments/profile/OrganizationsFragment.java
new file mode 100644
index 00000000..1f5268e6
--- /dev/null
+++ b/app/src/main/java/org/mian/gitnex/fragments/profile/OrganizationsFragment.java
@@ -0,0 +1,274 @@
+package org.mian.gitnex.fragments.profile;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.inputmethod.EditorInfo;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.recyclerview.widget.DividerItemDecoration;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import org.gitnex.tea4j.models.UserOrganizations;
+import org.mian.gitnex.R;
+import org.mian.gitnex.adapters.profile.OrganizationsAdapter;
+import org.mian.gitnex.clients.RetrofitClient;
+import org.mian.gitnex.databinding.FragmentOrganizationsBinding;
+import org.mian.gitnex.helpers.AlertDialogs;
+import org.mian.gitnex.helpers.Authorization;
+import org.mian.gitnex.helpers.Constants;
+import org.mian.gitnex.helpers.SnackBar;
+import org.mian.gitnex.helpers.TinyDB;
+import org.mian.gitnex.helpers.Toasty;
+import org.mian.gitnex.helpers.Version;
+import java.util.ArrayList;
+import java.util.List;
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+/**
+ * Author M M Arif
+ */
+
+public class OrganizationsFragment extends Fragment {
+
+ private Context context;
+ private FragmentOrganizationsBinding fragmentOrganizationsBinding;
+
+ private List organizationsList;
+ private OrganizationsAdapter adapter;
+
+ private int pageSize;
+ private int resultLimit = Constants.resultLimitOldGiteaInstances;
+
+ private static final String usernameBundle = "";
+ private String username;
+
+ public OrganizationsFragment() {}
+
+ public static OrganizationsFragment newInstance(String username) {
+ OrganizationsFragment fragment = new OrganizationsFragment();
+ Bundle args = new Bundle();
+ args.putString(usernameBundle, username);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (getArguments() != null) {
+ username = getArguments().getString(usernameBundle);
+ }
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+
+ fragmentOrganizationsBinding = FragmentOrganizationsBinding.inflate(inflater, container, false);
+ setHasOptionsMenu(true);
+ context = getContext();
+
+ TinyDB tinyDb = TinyDB.getInstance(context);
+
+ // if gitea is 1.12 or higher use the new limit
+ if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
+ resultLimit = Constants.resultLimitNewGiteaInstances;
+ }
+
+ organizationsList = new ArrayList<>();
+
+ fragmentOrganizationsBinding.addNewOrganization.setVisibility(View.GONE);
+
+ fragmentOrganizationsBinding.pullToRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
+ fragmentOrganizationsBinding.pullToRefresh.setRefreshing(false);
+ loadInitial(Authorization.get(context), username, resultLimit);
+ adapter.notifyDataChanged();
+ }, 200));
+
+ adapter = new OrganizationsAdapter(context, organizationsList);
+ adapter.setLoadMoreListener(() -> fragmentOrganizationsBinding.recyclerView.post(() -> {
+ if(organizationsList.size() == resultLimit || pageSize == resultLimit) {
+ int page = (organizationsList.size() + resultLimit) / resultLimit;
+ loadMore(Authorization.get(context), username, page, resultLimit);
+ }
+ }));
+
+ DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(context, DividerItemDecoration.VERTICAL);
+ fragmentOrganizationsBinding.recyclerView.setHasFixedSize(true);
+ fragmentOrganizationsBinding.recyclerView.addItemDecoration(dividerItemDecoration);
+ fragmentOrganizationsBinding.recyclerView.setLayoutManager(new LinearLayoutManager(context));
+ fragmentOrganizationsBinding.recyclerView.setAdapter(adapter);
+
+ loadInitial(Authorization.get(context), username, resultLimit);
+
+ return fragmentOrganizationsBinding.getRoot();
+ }
+
+ private void loadInitial(String token, String username, int resultLimit) {
+
+ Call> call = RetrofitClient
+ .getApiInterface(context)
+ .getUserProfileOrganizations(token, username, 1, resultLimit);
+
+ call.enqueue(new Callback>() {
+ @Override
+ public void onResponse(@NonNull Call> call, @NonNull Response> response) {
+
+ if(response.isSuccessful()) {
+
+ switch(response.code()) {
+ case 200:
+ assert response.body() != null;
+ if(response.body().size() > 0) {
+ organizationsList.clear();
+ organizationsList.addAll(response.body());
+ adapter.notifyDataChanged();
+ fragmentOrganizationsBinding.noDataOrg.setVisibility(View.GONE);
+ }
+ else {
+ organizationsList.clear();
+ adapter.notifyDataChanged();
+ fragmentOrganizationsBinding.noDataOrg.setVisibility(View.VISIBLE);
+ }
+ fragmentOrganizationsBinding.progressBar.setVisibility(View.GONE);
+ break;
+
+ case 401:
+ AlertDialogs.authorizationTokenRevokedDialog(context, getResources().getString(R.string.alertDialogTokenRevokedTitle),
+ getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
+ getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
+ break;
+
+ case 403:
+ Toasty.error(context, context.getString(R.string.authorizeError));
+ break;
+
+ case 404:
+ fragmentOrganizationsBinding.noDataOrg.setVisibility(View.VISIBLE);
+ fragmentOrganizationsBinding.progressBar.setVisibility(View.GONE);
+ break;
+
+ default:
+ Toasty.error(context, getString(R.string.genericError));
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
+ Toasty.error(context, getString(R.string.genericError));
+ }
+ });
+ }
+
+ private void loadMore(String token, String username, int page, int resultLimit) {
+
+ fragmentOrganizationsBinding.progressLoadMore.setVisibility(View.VISIBLE);
+
+ Call> call = RetrofitClient
+ .getApiInterface(context)
+ .getUserProfileOrganizations(token, username, page, resultLimit);
+
+ call.enqueue(new Callback>() {
+
+ @Override
+ public void onResponse(@NonNull Call> call, @NonNull Response> response) {
+
+ if(response.isSuccessful()) {
+
+ switch(response.code()) {
+ case 200:
+ List result = response.body();
+ assert result != null;
+ if(result.size() > 0) {
+ pageSize = result.size();
+ organizationsList.addAll(result);
+ }
+ else {
+ SnackBar.info(context, fragmentOrganizationsBinding.getRoot(), getString(R.string.noMoreData));
+ adapter.setMoreDataAvailable(false);
+ }
+ adapter.notifyDataChanged();
+ fragmentOrganizationsBinding.progressLoadMore.setVisibility(View.GONE);
+ break;
+
+ case 401:
+ AlertDialogs.authorizationTokenRevokedDialog(context, getResources().getString(R.string.alertDialogTokenRevokedTitle),
+ getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
+ getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
+ break;
+
+ case 403:
+ Toasty.error(context, context.getString(R.string.authorizeError));
+ break;
+
+ case 404:
+ fragmentOrganizationsBinding.noDataOrg.setVisibility(View.VISIBLE);
+ fragmentOrganizationsBinding.progressBar.setVisibility(View.GONE);
+ break;
+
+ default:
+ Toasty.error(context, getString(R.string.genericError));
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
+ Toasty.error(context, getString(R.string.genericError));
+ }
+ });
+ }
+
+ @Override
+ public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
+
+ inflater.inflate(R.menu.search_menu, menu);
+ super.onCreateOptionsMenu(menu, inflater);
+
+ MenuItem searchItem = menu.findItem(R.id.action_search);
+ androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
+ searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
+
+ searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
+
+ @Override
+ public boolean onQueryTextSubmit(String query) {
+ return false;
+ }
+
+ @Override
+ public boolean onQueryTextChange(String newText) {
+ filter(newText);
+ return false;
+ }
+ });
+ }
+
+ private void filter(String text) {
+
+ List arr = new ArrayList<>();
+
+ for(UserOrganizations d : organizationsList) {
+ if(d == null || d.getUsername() == null || d.getDescription() == null) {
+ continue;
+ }
+ if(d.getUsername().toLowerCase().contains(text) || d.getDescription().toLowerCase().contains(text)) {
+ arr.add(d);
+ }
+ }
+ adapter.updateList(arr);
+ }
+}
diff --git a/app/src/main/java/org/mian/gitnex/fragments/profile/RepositoriesFragment.java b/app/src/main/java/org/mian/gitnex/fragments/profile/RepositoriesFragment.java
new file mode 100644
index 00000000..74d84d3a
--- /dev/null
+++ b/app/src/main/java/org/mian/gitnex/fragments/profile/RepositoriesFragment.java
@@ -0,0 +1,271 @@
+package org.mian.gitnex.fragments.profile;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.inputmethod.EditorInfo;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.recyclerview.widget.DividerItemDecoration;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import org.gitnex.tea4j.models.UserRepositories;
+import org.mian.gitnex.R;
+import org.mian.gitnex.adapters.profile.RepositoriesAdapter;
+import org.mian.gitnex.clients.RetrofitClient;
+import org.mian.gitnex.databinding.FragmentRepositoriesBinding;
+import org.mian.gitnex.helpers.AlertDialogs;
+import org.mian.gitnex.helpers.Authorization;
+import org.mian.gitnex.helpers.Constants;
+import org.mian.gitnex.helpers.SnackBar;
+import org.mian.gitnex.helpers.TinyDB;
+import org.mian.gitnex.helpers.Toasty;
+import org.mian.gitnex.helpers.Version;
+import java.util.ArrayList;
+import java.util.List;
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+/**
+ * Author M M Arif
+ */
+
+public class RepositoriesFragment extends Fragment {
+
+ private Context context;
+ private FragmentRepositoriesBinding fragmentRepositoriesBinding;
+
+ private List reposList;
+ private RepositoriesAdapter adapter;
+
+ private int pageSize;
+ private int resultLimit = Constants.resultLimitOldGiteaInstances;
+
+ private static final String usernameBundle = "";
+ private String username;
+
+ public RepositoriesFragment() {}
+
+ public static RepositoriesFragment newInstance(String username) {
+ RepositoriesFragment fragment = new RepositoriesFragment();
+ Bundle args = new Bundle();
+ args.putString(usernameBundle, username);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (getArguments() != null) {
+ username = getArguments().getString(usernameBundle);
+ }
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+
+ fragmentRepositoriesBinding = FragmentRepositoriesBinding.inflate(inflater, container, false);
+ setHasOptionsMenu(true);
+ context = getContext();
+
+ TinyDB tinyDb = TinyDB.getInstance(context);
+
+ // if gitea is 1.12 or higher use the new limit
+ if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
+ resultLimit = Constants.resultLimitNewGiteaInstances;
+ }
+
+ reposList = new ArrayList<>();
+
+ fragmentRepositoriesBinding.addNewRepo.setVisibility(View.GONE);
+
+ fragmentRepositoriesBinding.pullToRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
+ fragmentRepositoriesBinding.pullToRefresh.setRefreshing(false);
+ loadInitial(Authorization.get(context), username, resultLimit);
+ adapter.notifyDataChanged();
+ }, 200));
+
+ adapter = new RepositoriesAdapter(context, reposList);
+ adapter.setLoadMoreListener(() -> fragmentRepositoriesBinding.recyclerView.post(() -> {
+ if(reposList.size() == resultLimit || pageSize == resultLimit) {
+ int page = (reposList.size() + resultLimit) / resultLimit;
+ loadMore(Authorization.get(context), username, page, resultLimit);
+ }
+ }));
+
+ DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(context, DividerItemDecoration.VERTICAL);
+ fragmentRepositoriesBinding.recyclerView.setHasFixedSize(true);
+ fragmentRepositoriesBinding.recyclerView.addItemDecoration(dividerItemDecoration);
+ fragmentRepositoriesBinding.recyclerView.setLayoutManager(new LinearLayoutManager(context));
+ fragmentRepositoriesBinding.recyclerView.setAdapter(adapter);
+
+ loadInitial(Authorization.get(context), username, resultLimit);
+
+ return fragmentRepositoriesBinding.getRoot();
+ }
+
+ private void loadInitial(String token, String username, int resultLimit) {
+
+ Call> call = RetrofitClient
+ .getApiInterface(context).getUserProfileRepositories(token, username, 1, resultLimit);
+
+ call.enqueue(new Callback>() {
+ @Override
+ public void onResponse(@NonNull Call> call, @NonNull Response> response) {
+
+ if(response.isSuccessful()) {
+
+ switch(response.code()) {
+ case 200:
+ assert response.body() != null;
+ if(response.body().size() > 0) {
+ reposList.clear();
+ reposList.addAll(response.body());
+ adapter.notifyDataChanged();
+ fragmentRepositoriesBinding.noData.setVisibility(View.GONE);
+ }
+ else {
+ reposList.clear();
+ adapter.notifyDataChanged();
+ fragmentRepositoriesBinding.noData.setVisibility(View.VISIBLE);
+ }
+ fragmentRepositoriesBinding.progressBar.setVisibility(View.GONE);
+ break;
+
+ case 401:
+ AlertDialogs.authorizationTokenRevokedDialog(context, getResources().getString(R.string.alertDialogTokenRevokedTitle),
+ getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
+ getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
+ break;
+
+ case 403:
+ Toasty.error(context, context.getString(R.string.authorizeError));
+ break;
+
+ case 404:
+ fragmentRepositoriesBinding.noData.setVisibility(View.VISIBLE);
+ fragmentRepositoriesBinding.progressBar.setVisibility(View.GONE);
+ break;
+
+ default:
+ Toasty.error(context, getString(R.string.genericError));
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
+ Toasty.error(context, getString(R.string.genericError));
+ }
+ });
+ }
+
+ private void loadMore(String token, String username, int page, int resultLimit) {
+
+ fragmentRepositoriesBinding.progressLoadMore.setVisibility(View.VISIBLE);
+
+ Call> call = RetrofitClient.getApiInterface(context).getUserProfileRepositories(token, username, page, resultLimit);
+
+ call.enqueue(new Callback>() {
+
+ @Override
+ public void onResponse(@NonNull Call> call, @NonNull Response> response) {
+
+ if(response.isSuccessful()) {
+
+ switch(response.code()) {
+ case 200:
+ List result = response.body();
+ assert result != null;
+ if(result.size() > 0) {
+ pageSize = result.size();
+ reposList.addAll(result);
+ }
+ else {
+ SnackBar.info(context, fragmentRepositoriesBinding.getRoot(), getString(R.string.noMoreData));
+ adapter.setMoreDataAvailable(false);
+ }
+ adapter.notifyDataChanged();
+ fragmentRepositoriesBinding.progressLoadMore.setVisibility(View.GONE);
+ break;
+
+ case 401:
+ AlertDialogs.authorizationTokenRevokedDialog(context, getResources().getString(R.string.alertDialogTokenRevokedTitle),
+ getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
+ getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
+ break;
+
+ case 403:
+ Toasty.error(context, context.getString(R.string.authorizeError));
+ break;
+
+ case 404:
+ fragmentRepositoriesBinding.noData.setVisibility(View.VISIBLE);
+ fragmentRepositoriesBinding.progressBar.setVisibility(View.GONE);
+ break;
+
+ default:
+ Toasty.error(context, getString(R.string.genericError));
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
+ Toasty.error(context, getString(R.string.genericError));
+ }
+ });
+ }
+
+ @Override
+ public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
+
+ inflater.inflate(R.menu.search_menu, menu);
+ super.onCreateOptionsMenu(menu, inflater);
+
+ MenuItem searchItem = menu.findItem(R.id.action_search);
+ androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
+ searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
+
+ searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
+
+ @Override
+ public boolean onQueryTextSubmit(String query) {
+ return false;
+ }
+
+ @Override
+ public boolean onQueryTextChange(String newText) {
+ filter(newText);
+ return false;
+ }
+ });
+ }
+
+ private void filter(String text) {
+
+ List arr = new ArrayList<>();
+
+ for(UserRepositories d : reposList) {
+ if(d == null || d.getFullName() == null || d.getDescription() == null) {
+ continue;
+ }
+ if(d.getFullName().toLowerCase().contains(text) || d.getDescription().toLowerCase().contains(text)) {
+ arr.add(d);
+ }
+ }
+ adapter.updateList(arr);
+ }
+}
diff --git a/app/src/main/java/org/mian/gitnex/fragments/profile/StarredRepositoriesFragment.java b/app/src/main/java/org/mian/gitnex/fragments/profile/StarredRepositoriesFragment.java
new file mode 100644
index 00000000..38f7180d
--- /dev/null
+++ b/app/src/main/java/org/mian/gitnex/fragments/profile/StarredRepositoriesFragment.java
@@ -0,0 +1,273 @@
+package org.mian.gitnex.fragments.profile;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.inputmethod.EditorInfo;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.recyclerview.widget.DividerItemDecoration;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import org.gitnex.tea4j.models.UserRepositories;
+import org.mian.gitnex.R;
+import org.mian.gitnex.adapters.profile.StarredRepositoriesAdapter;
+import org.mian.gitnex.clients.RetrofitClient;
+import org.mian.gitnex.databinding.FragmentRepositoriesBinding;
+import org.mian.gitnex.helpers.AlertDialogs;
+import org.mian.gitnex.helpers.Authorization;
+import org.mian.gitnex.helpers.Constants;
+import org.mian.gitnex.helpers.SnackBar;
+import org.mian.gitnex.helpers.TinyDB;
+import org.mian.gitnex.helpers.Toasty;
+import org.mian.gitnex.helpers.Version;
+import java.util.ArrayList;
+import java.util.List;
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+/**
+ * Author M M Arif
+ */
+
+public class StarredRepositoriesFragment extends Fragment {
+
+ private Context context;
+ private FragmentRepositoriesBinding fragmentRepositoriesBinding;
+
+ private List reposList;
+ private StarredRepositoriesAdapter adapter;
+
+ private int pageSize;
+ private int resultLimit = Constants.resultLimitOldGiteaInstances;
+
+ private static final String usernameBundle = "";
+ private String username;
+
+ public StarredRepositoriesFragment() {}
+
+ public static StarredRepositoriesFragment newInstance(String username) {
+ StarredRepositoriesFragment fragment = new StarredRepositoriesFragment();
+ Bundle args = new Bundle();
+ args.putString(usernameBundle, username);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (getArguments() != null) {
+ username = getArguments().getString(usernameBundle);
+ }
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+
+ fragmentRepositoriesBinding = org.mian.gitnex.databinding.FragmentRepositoriesBinding.inflate(inflater, container, false);
+ setHasOptionsMenu(true);
+ context = getContext();
+ TinyDB tinyDb = TinyDB.getInstance(context);
+
+ // if gitea is 1.12 or higher use the new limit
+ if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) {
+ resultLimit = Constants.resultLimitNewGiteaInstances;
+ }
+
+ reposList = new ArrayList<>();
+
+ fragmentRepositoriesBinding.addNewRepo.setVisibility(View.GONE);
+
+ fragmentRepositoriesBinding.pullToRefresh.setOnRefreshListener(() -> new Handler(Looper.getMainLooper()).postDelayed(() -> {
+ fragmentRepositoriesBinding.pullToRefresh.setRefreshing(false);
+ loadInitial(Authorization.get(context), username, resultLimit);
+ adapter.notifyDataChanged();
+ }, 200));
+
+ adapter = new StarredRepositoriesAdapter(context, reposList);
+ adapter.setLoadMoreListener(() -> fragmentRepositoriesBinding.recyclerView.post(() -> {
+ if(reposList.size() == resultLimit || pageSize == resultLimit) {
+ int page = (reposList.size() + resultLimit) / resultLimit;
+ loadMore(Authorization.get(context), username, page, resultLimit);
+ }
+ }));
+
+ DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(context, DividerItemDecoration.VERTICAL);
+ fragmentRepositoriesBinding.recyclerView.setHasFixedSize(true);
+ fragmentRepositoriesBinding.recyclerView.addItemDecoration(dividerItemDecoration);
+ fragmentRepositoriesBinding.recyclerView.setLayoutManager(new LinearLayoutManager(context));
+ fragmentRepositoriesBinding.recyclerView.setAdapter(adapter);
+
+ loadInitial(Authorization.get(context), username, resultLimit);
+
+ return fragmentRepositoriesBinding.getRoot();
+ }
+
+ private void loadInitial(String token, String username, int resultLimit) {
+
+ Call> call = RetrofitClient
+ .getApiInterface(context)
+ .getUserProfileStarredRepositories(token, username, 1, resultLimit);
+
+ call.enqueue(new Callback>() {
+ @Override
+ public void onResponse(@NonNull Call> call, @NonNull Response> response) {
+
+ if(response.isSuccessful()) {
+
+ switch(response.code()) {
+ case 200:
+ assert response.body() != null;
+ if(response.body().size() > 0) {
+ reposList.clear();
+ reposList.addAll(response.body());
+ adapter.notifyDataChanged();
+ fragmentRepositoriesBinding.noData.setVisibility(View.GONE);
+ }
+ else {
+ reposList.clear();
+ adapter.notifyDataChanged();
+ fragmentRepositoriesBinding.noData.setVisibility(View.VISIBLE);
+ }
+ fragmentRepositoriesBinding.progressBar.setVisibility(View.GONE);
+ break;
+
+ case 401:
+ AlertDialogs.authorizationTokenRevokedDialog(context, getResources().getString(R.string.alertDialogTokenRevokedTitle),
+ getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
+ getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
+ break;
+
+ case 403:
+ Toasty.error(context, context.getString(R.string.authorizeError));
+ break;
+
+ case 404:
+ fragmentRepositoriesBinding.noData.setVisibility(View.VISIBLE);
+ fragmentRepositoriesBinding.progressBar.setVisibility(View.GONE);
+ break;
+
+ default:
+ Toasty.error(context, getString(R.string.genericError));
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
+ Toasty.error(context, getString(R.string.genericError));
+ }
+ });
+ }
+
+ private void loadMore(String token, String username, int page, int resultLimit) {
+
+ fragmentRepositoriesBinding.progressLoadMore.setVisibility(View.VISIBLE);
+
+ Call> call = RetrofitClient
+ .getApiInterface(context)
+ .getUserProfileStarredRepositories(token, username, page, resultLimit);
+
+ call.enqueue(new Callback>() {
+
+ @Override
+ public void onResponse(@NonNull Call> call, @NonNull Response> response) {
+
+ if(response.isSuccessful()) {
+
+ switch(response.code()) {
+ case 200:
+ List result = response.body();
+ assert result != null;
+ if(result.size() > 0) {
+ pageSize = result.size();
+ reposList.addAll(result);
+ }
+ else {
+ SnackBar.info(context, fragmentRepositoriesBinding.getRoot(), getString(R.string.noMoreData));
+ adapter.setMoreDataAvailable(false);
+ }
+ adapter.notifyDataChanged();
+ fragmentRepositoriesBinding.progressLoadMore.setVisibility(View.GONE);
+ break;
+
+ case 401:
+ AlertDialogs.authorizationTokenRevokedDialog(context, getResources().getString(R.string.alertDialogTokenRevokedTitle),
+ getResources().getString(R.string.alertDialogTokenRevokedMessage), getResources().getString(R.string.alertDialogTokenRevokedCopyNegativeButton),
+ getResources().getString(R.string.alertDialogTokenRevokedCopyPositiveButton));
+ break;
+
+ case 403:
+ Toasty.error(context, context.getString(R.string.authorizeError));
+ break;
+
+ case 404:
+ fragmentRepositoriesBinding.noData.setVisibility(View.VISIBLE);
+ fragmentRepositoriesBinding.progressBar.setVisibility(View.GONE);
+ break;
+
+ default:
+ Toasty.error(context, getString(R.string.genericError));
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call> call, @NonNull Throwable t) {
+ Toasty.error(context, getString(R.string.genericError));
+ }
+ });
+ }
+
+ @Override
+ public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
+
+ inflater.inflate(R.menu.search_menu, menu);
+ super.onCreateOptionsMenu(menu, inflater);
+
+ MenuItem searchItem = menu.findItem(R.id.action_search);
+ androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) searchItem.getActionView();
+ searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
+
+ searchView.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
+
+ @Override
+ public boolean onQueryTextSubmit(String query) {
+ return false;
+ }
+
+ @Override
+ public boolean onQueryTextChange(String newText) {
+ filter(newText);
+ return false;
+ }
+ });
+ }
+
+ private void filter(String text) {
+
+ List arr = new ArrayList<>();
+
+ for(UserRepositories d : reposList) {
+ if(d == null || d.getFullName() == null || d.getDescription() == null) {
+ continue;
+ }
+ if(d.getFullName().toLowerCase().contains(text) || d.getDescription().toLowerCase().contains(text)) {
+ arr.add(d);
+ }
+ }
+ adapter.updateList(arr);
+ }
+}
diff --git a/app/src/main/java/org/mian/gitnex/helpers/Constants.java b/app/src/main/java/org/mian/gitnex/helpers/Constants.java
index 3c06b35d..65519048 100644
--- a/app/src/main/java/org/mian/gitnex/helpers/Constants.java
+++ b/app/src/main/java/org/mian/gitnex/helpers/Constants.java
@@ -27,7 +27,6 @@ public class Constants {
public static final String tagMilestonesAdapter = "MilestonesAdapter";
public static final String draftsApi = "DraftsApi";
public static final String repositoriesApi = "RepositoriesApi";
- public static final String replyToIssueActivity = "ReplyToIssueActivity";
public static final String tagDraftsBottomSheet = "BottomSheetDraftsFragment";
public static final String userAccountsApi = "UserAccountsApi";
public static final String publicOrganizations = "PublicOrganizations";
diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/OrganizationListViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/OrganizationListViewModel.java
index e973e433..e6e53ea3 100644
--- a/app/src/main/java/org/mian/gitnex/viewmodels/OrganizationListViewModel.java
+++ b/app/src/main/java/org/mian/gitnex/viewmodels/OrganizationListViewModel.java
@@ -35,7 +35,7 @@ public class OrganizationListViewModel extends ViewModel {
Call> call = RetrofitClient
.getApiInterface(ctx)
- .getUserOrgs(token);
+ .getUserOrgs(token, 1, 50);
call.enqueue(new Callback>() {
diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/ProfileFollowersViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/ProfileFollowersViewModel.java
index 380b8d59..6dc1be94 100644
--- a/app/src/main/java/org/mian/gitnex/viewmodels/ProfileFollowersViewModel.java
+++ b/app/src/main/java/org/mian/gitnex/viewmodels/ProfileFollowersViewModel.java
@@ -33,7 +33,7 @@ public class ProfileFollowersViewModel extends ViewModel {
Call> call = RetrofitClient
.getApiInterface(ctx)
- .getFollowers(token);
+ .getFollowers(token, 1, 50);
call.enqueue(new Callback>() {
diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/ProfileFollowingViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/ProfileFollowingViewModel.java
index 146554e9..871d0a3a 100644
--- a/app/src/main/java/org/mian/gitnex/viewmodels/ProfileFollowingViewModel.java
+++ b/app/src/main/java/org/mian/gitnex/viewmodels/ProfileFollowingViewModel.java
@@ -33,7 +33,7 @@ public class ProfileFollowingViewModel extends ViewModel {
Call> call = RetrofitClient
.getApiInterface(ctx)
- .getFollowing(token);
+ .getFollowing(token, 1, 50);
call.enqueue(new Callback>() {
diff --git a/app/src/main/res/layout/activity_profile.xml b/app/src/main/res/layout/activity_profile.xml
new file mode 100644
index 00000000..7431dba1
--- /dev/null
+++ b/app/src/main/res/layout/activity_profile.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_profile.xml b/app/src/main/res/layout/fragment_profile.xml
index 0a98053c..ea65f0b3 100644
--- a/app/src/main/res/layout/fragment_profile.xml
+++ b/app/src/main/res/layout/fragment_profile.xml
@@ -9,7 +9,7 @@
android:orientation="vertical">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_profile_followers.xml b/app/src/main/res/layout/fragment_profile_followers_following.xml
similarity index 75%
rename from app/src/main/res/layout/fragment_profile_followers.xml
rename to app/src/main/res/layout/fragment_profile_followers_following.xml
index 26dac2bc..e027c6b9 100644
--- a/app/src/main/res/layout/fragment_profile_followers.xml
+++ b/app/src/main/res/layout/fragment_profile_followers_following.xml
@@ -19,15 +19,24 @@
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/fragment_repositories.xml b/app/src/main/res/layout/fragment_repositories.xml
index 91ca3bc7..d792ec3c 100644
--- a/app/src/main/res/layout/fragment_repositories.xml
+++ b/app/src/main/res/layout/fragment_repositories.xml
@@ -29,6 +29,15 @@
style="@style/Widget.MaterialComponents.LinearProgressIndicator"
app:indicatorColor="?attr/progressIndicatorColor" />
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 26c1ff99..0779def5 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -753,4 +753,5 @@
Indicates the progress of ongoing downloads
Updated %s
+ Joined