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