diff --git a/app/src/main/java/org/mian/gitnex/actions/MilestoneActions.java b/app/src/main/java/org/mian/gitnex/actions/MilestoneActions.java index bf7a909e..cf0782fb 100644 --- a/app/src/main/java/org/mian/gitnex/actions/MilestoneActions.java +++ b/app/src/main/java/org/mian/gitnex/actions/MilestoneActions.java @@ -7,11 +7,9 @@ import com.google.gson.JsonElement; import org.mian.gitnex.R; import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.helpers.AlertDialogs; -import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.Toasty; import org.mian.gitnex.models.Milestones; import org.mian.gitnex.util.TinyDB; -import org.mian.gitnex.viewmodels.MilestonesViewModel; import retrofit2.Call; import retrofit2.Callback; @@ -51,7 +49,6 @@ public class MilestoneActions { if(response.isSuccessful()) { Toasty.info(ctx, ctx.getString(R.string.milestoneStatusUpdate)); - MilestonesViewModel.loadMilestonesList(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, token), repoOwner, repoName, "all", ctx); } else if(response.code() == 401) { @@ -110,7 +107,6 @@ public class MilestoneActions { if(response.isSuccessful()) { Toasty.info(ctx, ctx.getString(R.string.milestoneStatusUpdate)); - MilestonesViewModel.loadMilestonesList(instanceUrl, Authorization.returnAuthentication(ctx, loginUid, token), repoOwner, repoName, "all", ctx); } else if(response.code() == 401) { diff --git a/app/src/main/java/org/mian/gitnex/activities/CreateIssueActivity.java b/app/src/main/java/org/mian/gitnex/activities/CreateIssueActivity.java index 074133bf..60e0edd3 100644 --- a/app/src/main/java/org/mian/gitnex/activities/CreateIssueActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/CreateIssueActivity.java @@ -28,6 +28,8 @@ import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.Authorization; import org.mian.gitnex.helpers.MultiSelectDialog; +import org.mian.gitnex.helpers.StaticGlobalVariables; +import org.mian.gitnex.helpers.Version; import org.mian.gitnex.models.Collaborators; import org.mian.gitnex.models.CreateIssue; import org.mian.gitnex.models.Labels; @@ -62,6 +64,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis private boolean labelsFlag; final Context ctx = this; private Context appCtx; + private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances; List milestonesList = new ArrayList<>(); ArrayList listOfAssignees = new ArrayList<>(); @@ -93,6 +96,11 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis final String repoName = parts[1]; final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); + // if gitea is 1.12 or higher use the new limit + if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) { + resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances; + } + ImageView closeActivity = findViewById(R.id.close); assigneesList = findViewById(R.id.newIssueAssigneesList); newIssueLabels = findViewById(R.id.newIssueLabels); @@ -120,7 +128,7 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis newIssueMilestoneSpinner = findViewById(R.id.newIssueMilestoneSpinner); newIssueMilestoneSpinner.getBackground().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_ATOP); - getMilestones(instanceUrl, instanceToken, repoOwner, repoName, loginUid); + getMilestones(instanceUrl, instanceToken, repoOwner, repoName, loginUid, resultLimit); getLabels(instanceUrl, instanceToken, repoOwner, repoName, loginUid); getCollaborators(instanceUrl, instanceToken, repoOwner, repoName, loginUid, loginFullName); @@ -335,13 +343,13 @@ public class CreateIssueActivity extends BaseActivity implements View.OnClickLis }; } - private void getMilestones(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid) { + private void getMilestones(String instanceUrl, String instanceToken, String repoOwner, String repoName, String loginUid, int resultLimit) { String msState = "open"; Call> call = RetrofitClient .getInstance(instanceUrl, ctx) .getApiInterface() - .getMilestones(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, msState); + .getMilestones(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, 1, resultLimit, msState); call.enqueue(new Callback>() { diff --git a/app/src/main/java/org/mian/gitnex/activities/EditIssueActivity.java b/app/src/main/java/org/mian/gitnex/activities/EditIssueActivity.java index 4c7f84c4..d1e91c8a 100644 --- a/app/src/main/java/org/mian/gitnex/activities/EditIssueActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/EditIssueActivity.java @@ -28,7 +28,9 @@ import org.mian.gitnex.R; import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.helpers.AlertDialogs; import org.mian.gitnex.helpers.Authorization; +import org.mian.gitnex.helpers.StaticGlobalVariables; import org.mian.gitnex.helpers.Toasty; +import org.mian.gitnex.helpers.Version; import org.mian.gitnex.models.Collaborators; import org.mian.gitnex.models.CreateIssue; import org.mian.gitnex.models.Issues; @@ -50,6 +52,7 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe final Context ctx = this; private Context appCtx; private View.OnClickListener onClickListener; + private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances; private EditText editIssueTitle; private SocialAutoCompleteTextView editIssueDescription; @@ -93,6 +96,11 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe editIssueDescription = findViewById(R.id.editIssueDescription); editIssueDueDate = findViewById(R.id.editIssueDueDate); + // if gitea is 1.12 or higher use the new limit + if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) { + resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances; + } + editIssueTitle.requestFocus(); assert imm != null; imm.showSoftInput(editIssueTitle, InputMethodManager.SHOW_IMPLICIT); @@ -122,7 +130,7 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe } disableProcessButton(); - getIssue(instanceUrl, instanceToken, loginUid, repoOwner, repoName, issueIndex); + getIssue(instanceUrl, instanceToken, loginUid, repoOwner, repoName, issueIndex, resultLimit); } @@ -328,7 +336,7 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe } - private void getIssue(final String instanceUrl, final String instanceToken, final String loginUid, final String repoOwner, final String repoName, int issueIndex) { + private void getIssue(final String instanceUrl, final String instanceToken, final String loginUid, final String repoOwner, final String repoName, int issueIndex, int resultLimit) { Call call = RetrofitClient .getInstance(instanceUrl, ctx) @@ -357,7 +365,7 @@ public class EditIssueActivity extends BaseActivity implements View.OnClickListe Call> call_ = RetrofitClient .getInstance(instanceUrl, ctx) .getApiInterface() - .getMilestones(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, msState); + .getMilestones(Authorization.returnAuthentication(ctx, loginUid, instanceToken), repoOwner, repoName, 1, resultLimit, msState); final int finalMsId = msId; diff --git a/app/src/main/java/org/mian/gitnex/activities/RepoDetailActivity.java b/app/src/main/java/org/mian/gitnex/activities/RepoDetailActivity.java index e8f1d0c7..a341e94a 100644 --- a/app/src/main/java/org/mian/gitnex/activities/RepoDetailActivity.java +++ b/app/src/main/java/org/mian/gitnex/activities/RepoDetailActivity.java @@ -26,6 +26,7 @@ import com.google.gson.JsonElement; import org.mian.gitnex.R; import org.mian.gitnex.clients.RetrofitClient; import org.mian.gitnex.fragments.BottomSheetIssuesFilterFragment; +import org.mian.gitnex.fragments.BottomSheetMilestonesFilterFragment; import org.mian.gitnex.fragments.BottomSheetPullRequestFilterFragment; import org.mian.gitnex.fragments.BottomSheetRepoFragment; import org.mian.gitnex.fragments.BranchesFragment; @@ -51,7 +52,8 @@ import retrofit2.Callback; * Author M M Arif */ -public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoFragment.BottomSheetListener, BottomSheetIssuesFilterFragment.BottomSheetListener, BottomSheetPullRequestFilterFragment.BottomSheetListener { +public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoFragment.BottomSheetListener, BottomSheetIssuesFilterFragment.BottomSheetListener, + BottomSheetPullRequestFilterFragment.BottomSheetListener, BottomSheetMilestonesFilterFragment.BottomSheetListener { private TextView textViewBadgeIssue; private TextView textViewBadgePull; @@ -59,6 +61,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF private FragmentRefreshListener fragmentRefreshListener; private FragmentRefreshListenerPr fragmentRefreshListenerPr; + private FragmentRefreshListenerMilestone fragmentRefreshListenerMilestone; final Context ctx = this; private Context appCtx; @@ -97,6 +100,23 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF } + // milestones interface + public FragmentRefreshListenerMilestone getFragmentRefreshListenerMilestone() { + + return fragmentRefreshListenerMilestone; + } + + public void setFragmentRefreshListenerMilestone(FragmentRefreshListenerMilestone fragmentRefreshListenerMilestone) { + + this.fragmentRefreshListenerMilestone = fragmentRefreshListenerMilestone; + } + + public interface FragmentRefreshListenerMilestone { + + void onRefresh(String text); + + } + @Override protected int getLayoutResourceId() { @@ -121,6 +141,7 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF tinyDb.putString("repoIssuesState", "open"); tinyDb.putString("repoPrState", "open"); + tinyDb.putString("milestoneState", "open"); String appLocale = tinyDb.getString("locale"); AppUtil.setAppLocale(getResources(), appLocale); @@ -287,6 +308,10 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF BottomSheetPullRequestFilterFragment filterPrBottomSheet = new BottomSheetPullRequestFilterFragment(); filterPrBottomSheet.show(getSupportFragmentManager(), "repoFilterMenuPrBottomSheet"); return true; + case R.id.filterMilestone: + BottomSheetMilestonesFilterFragment filterMilestoneBottomSheet = new BottomSheetMilestonesFilterFragment(); + filterMilestoneBottomSheet.show(getSupportFragmentManager(), "repoFilterMenuMilestoneBottomSheet"); + return true; default: return super.onOptionsItemSelected(item); } @@ -348,6 +373,16 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF getFragmentRefreshListenerPr().onRefresh("closed"); } break; + case "openMilestone": + if(getFragmentRefreshListenerMilestone() != null) { + getFragmentRefreshListenerMilestone().onRefresh("open"); + } + break; + case "closedMilestone": + if(getFragmentRefreshListenerMilestone() != null) { + getFragmentRefreshListenerMilestone().onRefresh("closed"); + } + break; } } @@ -386,7 +421,8 @@ public class RepoDetailActivity extends BaseActivity implements BottomSheetRepoF case 5: // releases return ReleasesFragment.newInstance(repoOwner, repoName); case 6: // milestones - return MilestonesFragment.newInstance(repoOwner, repoName); + fragment = new MilestonesFragment(); + break; case 7: // labels return LabelsFragment.newInstance(repoOwner, repoName); case 8: // collaborators diff --git a/app/src/main/java/org/mian/gitnex/adapters/MilestonesAdapter.java b/app/src/main/java/org/mian/gitnex/adapters/MilestonesAdapter.java index bac50a9c..9807250e 100644 --- a/app/src/main/java/org/mian/gitnex/adapters/MilestonesAdapter.java +++ b/app/src/main/java/org/mian/gitnex/adapters/MilestonesAdapter.java @@ -6,35 +6,34 @@ import android.graphics.Color; import android.graphics.drawable.Drawable; import android.net.Uri; import android.text.Spanned; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.Filter; -import android.widget.Filterable; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; import com.amulyakhare.textdrawable.TextDrawable; import com.google.android.material.bottomsheet.BottomSheetDialog; import com.vdurmont.emoji.EmojiParser; import org.mian.gitnex.R; import org.mian.gitnex.actions.MilestoneActions; import org.mian.gitnex.helpers.ClickListener; +import org.mian.gitnex.helpers.StaticGlobalVariables; import org.mian.gitnex.helpers.TimeHelper; import org.mian.gitnex.models.Milestones; import org.mian.gitnex.util.TinyDB; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Locale; import java.util.Objects; -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; import io.noties.markwon.AbstractMarkwonPlugin; import io.noties.markwon.Markwon; import io.noties.markwon.core.CorePlugin; @@ -55,13 +54,57 @@ import io.noties.markwon.linkify.LinkifyPlugin; * Author M M Arif */ -public class MilestonesAdapter extends RecyclerView.Adapter implements Filterable { +public class MilestonesAdapter extends RecyclerView.Adapter { - private List milestonesList; - private Context mCtx; - private List milestonesListFull; + private Context context; + private final int TYPE_LOAD = 0; + private List dataList; + private OnLoadMoreListener loadMoreListener; + private boolean isLoading = false; + private boolean isMoreDataAvailable = true; + private String TAG = StaticGlobalVariables.tagMilestonesAdapter; - static class MilestonesViewHolder extends RecyclerView.ViewHolder { + public MilestonesAdapter(Context context, List dataListMain) { + + this.context = context; + this.dataList = dataListMain; + + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + + LayoutInflater inflater = LayoutInflater.from(context); + + if(viewType == TYPE_LOAD) { + return new MilestonesAdapter.DataHolder(inflater.inflate(R.layout.list_milestones, parent, false)); + } + else { + return new MilestonesAdapter.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) { + + ((MilestonesAdapter.DataHolder) holder).bindData(dataList.get(position)); + + } + + } + + class DataHolder extends RecyclerView.ViewHolder { private TextView milestoneId; private TextView msTitle; @@ -71,9 +114,10 @@ public class MilestonesAdapter extends RecyclerView.Adapter { @@ -94,269 +138,287 @@ public class MilestonesAdapter extends RecyclerView.Adapter { + closeMilestone.setOnClickListener(v12 -> { - MilestoneActions.closeMilestone(ctx, milestoneId_); - dialog.dismiss(); + MilestoneActions.closeMilestone(ctx, milestoneId_); + dialog.dismiss(); + updateAdapter(getAdapterPosition()); - }); + }); - openMilestone.setOnClickListener(v12 -> { + openMilestone.setOnClickListener(v12 -> { - MilestoneActions.openMilestone(ctx, milestoneId_); - dialog.dismiss(); + MilestoneActions.openMilestone(ctx, milestoneId_); + dialog.dismiss(); + updateAdapter(getAdapterPosition()); - }); + }); }); } - } - public MilestonesAdapter(Context mCtx, List milestonesMain) { - this.mCtx = mCtx; - this.milestonesList = milestonesMain; - milestonesListFull = new ArrayList<>(milestonesList); - } + @SuppressLint("SetTextI18n") + void bindData(Milestones dataModel) { - @NonNull - @Override - public MilestonesAdapter.MilestonesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_milestones, parent, false); - return new MilestonesAdapter.MilestonesViewHolder(v); - } + final TinyDB tinyDb = new TinyDB(context); + final String locale = tinyDb.getString("locale"); + final String timeFormat = tinyDb.getString("dateFormat"); - @Override - public void onBindViewHolder(@NonNull MilestonesAdapter.MilestonesViewHolder holder, int position) { + milestoneId.setText(String.valueOf(dataModel.getId())); + milestoneStatus.setText(dataModel.getState()); - final TinyDB tinyDb = new TinyDB(mCtx); - final String locale = tinyDb.getString("locale"); - final String timeFormat = tinyDb.getString("dateFormat"); + final Markwon markwon = Markwon.builder(Objects.requireNonNull(context)) + .usePlugin(CorePlugin.create()) + .usePlugin(ImagesPlugin.create(plugin -> { + plugin.addSchemeHandler(new SchemeHandler() { + @NonNull + @Override + public ImageItem handle(@NonNull String raw, @NonNull Uri uri) { - Milestones currentItem = milestonesList.get(position); + final int resourceId = context.getResources().getIdentifier( + raw.substring("drawable://".length()), + "drawable", + context.getPackageName()); - holder.milestoneId.setText(String.valueOf(currentItem.getId())); - holder.milestoneStatus.setText(currentItem.getState()); + final Drawable drawable = context.getDrawable(resourceId); - final Markwon markwon = Markwon.builder(Objects.requireNonNull(mCtx)) - .usePlugin(CorePlugin.create()) - .usePlugin(ImagesPlugin.create(plugin -> { - plugin.addSchemeHandler(new SchemeHandler() { - @NonNull + assert drawable != null; + return ImageItem.withResult(drawable); + } + + @NonNull + @Override + public Collection supportedSchemes() { + return Collections.singleton("drawable"); + } + }); + plugin.placeholderProvider(drawable -> null); + plugin.addMediaDecoder(GifMediaDecoder.create(false)); + plugin.addMediaDecoder(SvgMediaDecoder.create(context.getResources())); + plugin.addMediaDecoder(SvgMediaDecoder.create()); + plugin.defaultMediaDecoder(DefaultMediaDecoder.create(context.getResources())); + plugin.defaultMediaDecoder(DefaultMediaDecoder.create()); + })) + .usePlugin(new AbstractMarkwonPlugin() { @Override - public ImageItem handle(@NonNull String raw, @NonNull Uri uri) { - - final int resourceId = mCtx.getResources().getIdentifier( - raw.substring("drawable://".length()), - "drawable", - mCtx.getPackageName()); - - final Drawable drawable = mCtx.getDrawable(resourceId); - - assert drawable != null; - return ImageItem.withResult(drawable); + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder + .codeTextColor(tinyDb.getInt("codeBlockColor")) + .codeBackgroundColor(tinyDb.getInt("codeBlockBackground")) + .linkColor(context.getResources().getColor(R.color.lightBlue)); } + }) + .usePlugin(TablePlugin.create(context)) + .usePlugin(TaskListPlugin.create(context)) + .usePlugin(HtmlPlugin.create()) + .usePlugin(StrikethroughPlugin.create()) + .usePlugin(LinkifyPlugin.create()) + .build(); - @NonNull - @Override - public Collection supportedSchemes() { - return Collections.singleton("drawable"); - } - }); - plugin.placeholderProvider(drawable -> null); - plugin.addMediaDecoder(GifMediaDecoder.create(false)); - plugin.addMediaDecoder(SvgMediaDecoder.create(mCtx.getResources())); - plugin.addMediaDecoder(SvgMediaDecoder.create()); - plugin.defaultMediaDecoder(DefaultMediaDecoder.create(mCtx.getResources())); - plugin.defaultMediaDecoder(DefaultMediaDecoder.create()); - })) - .usePlugin(new AbstractMarkwonPlugin() { - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - builder - .codeTextColor(tinyDb.getInt("codeBlockColor")) - .codeBackgroundColor(tinyDb.getInt("codeBlockBackground")) - .linkColor(mCtx.getResources().getColor(R.color.lightBlue)); - } - }) - .usePlugin(TablePlugin.create(mCtx)) - .usePlugin(TaskListPlugin.create(mCtx)) - .usePlugin(HtmlPlugin.create()) - .usePlugin(StrikethroughPlugin.create()) - .usePlugin(LinkifyPlugin.create()) - .build(); + Spanned msTitle_ = markwon.toMarkdown(dataModel.getTitle()); + markwon.setParsedMarkdown(msTitle, msTitle_); - Spanned msTitle = markwon.toMarkdown(currentItem.getTitle()); - markwon.setParsedMarkdown(holder.msTitle, msTitle); + if(dataModel.getState().equals("open")) { - if(currentItem.getState().equals("open")) { + @SuppressLint("ResourceType") int color = Color.parseColor(context.getResources().getString(R.color.releaseStable)); + TextDrawable drawable = TextDrawable.builder() + .beginConfig() + //.useFont(Typeface.DEFAULT) + .textColor(context.getResources().getColor(R.color.white)) + .fontSize(30) + .toUpperCase() + .width(120) + .height(60) + .endConfig() + .buildRoundRect("open", color, 8); - @SuppressLint("ResourceType") int color = Color.parseColor(mCtx.getResources().getString(R.color.releaseStable)); - TextDrawable drawable = TextDrawable.builder() - .beginConfig() - //.useFont(Typeface.DEFAULT) - .textColor(mCtx.getResources().getColor(R.color.white)) - .fontSize(30) - .toUpperCase() - .width(120) - .height(60) - .endConfig() - .buildRoundRect("open", color, 8); + msStatus.setImageDrawable(drawable); - holder.msStatus.setImageDrawable(drawable); + } + else if(dataModel.getState().equals("closed")) { - } - else if(currentItem.getState().equals("closed")) { + @SuppressLint("ResourceType") int color = Color.parseColor(context.getResources().getString(R.color.colorRed)); + TextDrawable drawable = TextDrawable.builder() + .beginConfig() + //.useFont(Typeface.DEFAULT) + .textColor(context.getResources().getColor(R.color.white)) + .fontSize(30) + .toUpperCase() + .width(140) + .height(60) + .endConfig() + .buildRoundRect("closed", color, 8); - @SuppressLint("ResourceType") int color = Color.parseColor(mCtx.getResources().getString(R.color.colorRed)); - TextDrawable drawable = TextDrawable.builder() - .beginConfig() - //.useFont(Typeface.DEFAULT) - .textColor(mCtx.getResources().getColor(R.color.white)) - .fontSize(30) - .toUpperCase() - .width(140) - .height(60) - .endConfig() - .buildRoundRect("closed", color, 8); + msStatus.setImageDrawable(drawable); - holder.msStatus.setImageDrawable(drawable); + } - } - - if (!currentItem.getDescription().equals("")) { - final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(currentItem.getDescription())); - holder.msDescription.setText(bodyWithMD); - } - else { - holder.msDescription.setText(""); - } - - holder.msOpenIssues.setText(String.valueOf(currentItem.getOpen_issues())); - holder.msOpenIssues.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.milestoneOpenIssues, currentItem.getOpen_issues()), mCtx)); - - holder.msClosedIssues.setText(String.valueOf(currentItem.getClosed_issues())); - holder.msClosedIssues.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.milestoneClosedIssues, currentItem.getClosed_issues()), mCtx)); - - if ((currentItem.getOpen_issues() + currentItem.getClosed_issues()) > 0) { - - if (currentItem.getOpen_issues() == 0) { - holder.msProgress.setProgress(100); - holder.msProgress.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.milestoneCompletion, 100), mCtx)); + if (!dataModel.getDescription().equals("")) { + final CharSequence bodyWithMD = markwon.toMarkdown(EmojiParser.parseToUnicode(dataModel.getDescription())); + msDescription.setText(bodyWithMD); } else { - int msCompletion = 100 * currentItem.getClosed_issues() / (currentItem.getOpen_issues() + currentItem.getClosed_issues()); - holder.msProgress.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.milestoneCompletion, msCompletion), mCtx)); - holder.msProgress.setProgress(msCompletion); + msDescription.setText(""); + } + + msOpenIssues.setText(String.valueOf(dataModel.getOpen_issues())); + msOpenIssues.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneOpenIssues, dataModel.getOpen_issues()), context)); + + msClosedIssues.setText(String.valueOf(dataModel.getClosed_issues())); + msClosedIssues.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneClosedIssues, dataModel.getClosed_issues()), context)); + + if ((dataModel.getOpen_issues() + dataModel.getClosed_issues()) > 0) { + + if (dataModel.getOpen_issues() == 0) { + msProgress.setProgress(100); + msProgress.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneCompletion, 100), context)); + } + else { + int msCompletion = 100 * dataModel.getClosed_issues() / (dataModel.getOpen_issues() + dataModel.getClosed_issues()); + msProgress.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneCompletion, msCompletion), context)); + msProgress.setProgress(msCompletion); + } + + } + else { + msProgress.setProgress(0); + msProgress.setOnClickListener(new ClickListener(context.getResources().getString(R.string.milestoneCompletion, 0), context)); + } + + if(dataModel.getDue_on() != null) { + + if (timeFormat.equals("normal") || timeFormat.equals("pretty")) { + + DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", new Locale(locale)); + Date date = null; + try { + date = formatter.parse(dataModel.getDue_on()); + } + catch (ParseException e) { + Log.e(TAG, e.toString()); + } + assert date != null; + String dueDate = formatter.format(date); + + if(date.before(new Date())) { + msDueDate.setTextColor(context.getResources().getColor(R.color.darkRed)); + } + + msDueDate.setText(dueDate); + msDueDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToast(dataModel.getDue_on()), context)); + + } + else if (timeFormat.equals("normal1")) { + + SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", new Locale(locale)); + Date date1 = null; + try { + date1 = formatter.parse(dataModel.getDue_on()); + } + catch (ParseException e) { + Log.e(TAG, e.toString()); + } + assert date1 != null; + String dueDate = formatter.format(date1); + msDueDate.setText(dueDate); + + } + + } + else { + msDueDate.setText(""); } } - else { - holder.msProgress.setProgress(0); - holder.msProgress.setOnClickListener(new ClickListener(mCtx.getResources().getString(R.string.milestoneCompletion, 0), mCtx)); - } - if(currentItem.getDue_on() != null) { + } - if (timeFormat.equals("normal") || timeFormat.equals("pretty")) { - DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", new Locale(locale)); - Date date = null; - try { - date = formatter.parse(currentItem.getDue_on()); - } catch (ParseException e) { - e.printStackTrace(); - } - assert date != null; - String dueDate = formatter.format(date); + private void updateAdapter(int position) { - if(date.before(new Date())) { - holder.msDueDate.setTextColor(mCtx.getResources().getColor(R.color.darkRed)); - } + dataList.remove(position); + notifyItemRemoved(position); + notifyItemRangeChanged(position, dataList.size()); - holder.msDueDate.setText(mCtx.getResources().getString(R.string.dueDate, dueDate)); - holder.msDueDate.setOnClickListener(new ClickListener(TimeHelper.customDateFormatForToast(currentItem.getDue_on()), mCtx)); + } - } else if (timeFormat.equals("normal1")) { - SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy", new Locale(locale)); - Date date1 = null; - try { - date1 = formatter.parse(currentItem.getDue_on()); - } catch (ParseException e) { - e.printStackTrace(); - } - assert date1 != null; - String dueDate = formatter.format(date1); - holder.msDueDate.setText(mCtx.getResources().getString(R.string.dueDate, dueDate)); - } + @Override + public int getItemViewType(int position) { + if(dataList.get(position).getTitle() != null) { + return TYPE_LOAD; } else { - holder.msDueDate.setText(""); + return 1; } } @Override public int getItemCount() { - return milestonesList.size(); + + return dataList.size(); + } - @Override - public Filter getFilter() { - return milestoneFilter; + static class LoadHolder extends RecyclerView.ViewHolder { + + LoadHolder(View itemView) { + + super(itemView); + } + } - private Filter milestoneFilter = new Filter() { + public void setMoreDataAvailable(boolean moreDataAvailable) { - @Override - protected FilterResults performFiltering(CharSequence constraint) { - List filteredList = new ArrayList<>(); + isMoreDataAvailable = moreDataAvailable; - if (constraint == null || constraint.length() == 0) { - filteredList.addAll(milestonesListFull); - } else { - String filterPattern = constraint.toString().toLowerCase().trim(); + } - for (Milestones item : milestonesListFull) { - if (item.getTitle().toLowerCase().contains(filterPattern) || item.getDescription().toLowerCase().contains(filterPattern)) { - filteredList.add(item); - } - } - } + public void notifyDataChanged() { - FilterResults results = new FilterResults(); - results.values = filteredList; + notifyDataSetChanged(); + isLoading = false; - return results; - } + } - @Override - protected void publishResults(CharSequence constraint, FilterResults results) { - milestonesList.clear(); - milestonesList.addAll((List) results.values); - notifyDataSetChanged(); - } + public interface OnLoadMoreListener { - }; + void onLoadMore(); + + } + + public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) { + + this.loadMoreListener = loadMoreListener; + + } + + public void updateList(List list) { + + dataList = list; + notifyDataSetChanged(); + } } diff --git a/app/src/main/java/org/mian/gitnex/fragments/BottomSheetMilestonesFilterFragment.java b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetMilestonesFilterFragment.java new file mode 100644 index 00000000..4bcc41b2 --- /dev/null +++ b/app/src/main/java/org/mian/gitnex/fragments/BottomSheetMilestonesFilterFragment.java @@ -0,0 +1,64 @@ +package org.mian.gitnex.fragments; + +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; +import org.mian.gitnex.R; + +/** + * Author M M Arif + */ + +public class BottomSheetMilestonesFilterFragment extends BottomSheetDialogFragment { + + private BottomSheetMilestonesFilterFragment.BottomSheetListener bmListener; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + + View v = inflater.inflate(R.layout.bottom_sheet_milestones_filter, container, false); + + TextView openMilestone = v.findViewById(R.id.openMilestone); + TextView closedMilestone = v.findViewById(R.id.closedMilestone); + + openMilestone.setOnClickListener(v1 -> { + bmListener.onButtonClicked("openMilestone"); + dismiss(); + }); + + closedMilestone.setOnClickListener(v12 -> { + bmListener.onButtonClicked("closedMilestone"); + dismiss(); + }); + + return v; + } + + public interface BottomSheetListener { + + void onButtonClicked(String text); + + } + + @Override + public void onAttach(@NonNull Context context) { + + super.onAttach(context); + + try { + bmListener = (BottomSheetMilestonesFilterFragment.BottomSheetListener) context; + } + catch(ClassCastException e) { + Log.e("MilestonesFilterBs", e.toString()); + } + } + +} diff --git a/app/src/main/java/org/mian/gitnex/fragments/MilestonesFragment.java b/app/src/main/java/org/mian/gitnex/fragments/MilestonesFragment.java index d94594ec..6801e437 100644 --- a/app/src/main/java/org/mian/gitnex/fragments/MilestonesFragment.java +++ b/app/src/main/java/org/mian/gitnex/fragments/MilestonesFragment.java @@ -1,17 +1,9 @@ package org.mian.gitnex.fragments; -import android.net.Uri; +import android.content.Context; import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.lifecycle.Observer; -import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.DividerItemDecoration; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import android.os.Handler; +import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -19,17 +11,27 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; -import android.widget.ProgressBar; -import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; import org.mian.gitnex.R; +import org.mian.gitnex.activities.RepoDetailActivity; import org.mian.gitnex.adapters.MilestonesAdapter; +import org.mian.gitnex.clients.AppApiService; +import org.mian.gitnex.databinding.FragmentMilestonesBinding; import org.mian.gitnex.helpers.Authorization; +import org.mian.gitnex.helpers.StaticGlobalVariables; +import org.mian.gitnex.helpers.Toasty; +import org.mian.gitnex.helpers.Version; +import org.mian.gitnex.interfaces.ApiInterface; import org.mian.gitnex.models.Milestones; -import org.mian.gitnex.util.AppUtil; import org.mian.gitnex.util.TinyDB; -import org.mian.gitnex.viewmodels.MilestonesViewModel; +import java.util.ArrayList; import java.util.List; import java.util.Objects; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; /** * Author M M Arif @@ -37,89 +39,113 @@ import java.util.Objects; public class MilestonesFragment extends Fragment { - private ProgressBar mProgressBar; + private FragmentMilestonesBinding viewBinding; + + private Menu menu; + private List dataList; private MilestonesAdapter adapter; - private RecyclerView mRecyclerView; - private TextView noDataMilestone; - private static String repoNameF = "param2"; - private static String repoOwnerF = "param1"; - - private String repoName; - private String repoOwner; - private String msState = "all"; - - private OnFragmentInteractionListener mListener; - - public MilestonesFragment() { - } - - public static MilestonesFragment newInstance(String param1, String param2) { - MilestonesFragment fragment = new MilestonesFragment(); - Bundle args = new Bundle(); - args.putString(repoOwnerF, param1); - args.putString(repoNameF, param2); - fragment.setArguments(args); - return fragment; - } + private ApiInterface api; + private Context ctx; + private int pageSize = StaticGlobalVariables.milestonesPageInit; + private String TAG = StaticGlobalVariables.tagMilestonesFragment; + private int resultLimit = StaticGlobalVariables.resultLimitOldGiteaInstances; @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - if (getArguments() != null) { - repoName = getArguments().getString(repoNameF); - repoOwner = getArguments().getString(repoOwnerF); - } - } + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - final View v = inflater.inflate(R.layout.fragment_milestones, container, false); + viewBinding = FragmentMilestonesBinding.inflate(inflater, container, false); setHasOptionsMenu(true); + ctx = getContext(); TinyDB tinyDb = new TinyDB(getContext()); + String repoFullName = tinyDb.getString("repoFullName"); + String[] parts = repoFullName.split("/"); + final String repoOwner = parts[0]; + final String repoName = parts[1]; final String instanceUrl = tinyDb.getString("instanceUrl"); final String loginUid = tinyDb.getString("loginUid"); final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); - final String locale = tinyDb.getString("locale"); - final String timeFormat = tinyDb.getString("dateFormat"); - noDataMilestone = v.findViewById(R.id.noDataMilestone); - final SwipeRefreshLayout swipeRefresh = v.findViewById(R.id.pullToRefresh); + viewBinding.recyclerView.setHasFixedSize(true); + viewBinding.recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); - mRecyclerView = v.findViewById(R.id.recyclerView); - mRecyclerView.setHasFixedSize(true); - mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + // if gitea is 1.12 or higher use the new limit + if(new Version(tinyDb.getString("giteaVersion")).higherOrEqual("1.12.0")) { + resultLimit = StaticGlobalVariables.resultLimitNewGiteaInstances; + } - DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(), - DividerItemDecoration.VERTICAL); - mRecyclerView.addItemDecoration(dividerItemDecoration); + dataList = new ArrayList<>(); + adapter = new MilestonesAdapter(ctx, dataList); - mProgressBar = v.findViewById(R.id.progress_bar); + adapter.setLoadMoreListener(() -> viewBinding.recyclerView.post(() -> { + + if(dataList.size() == resultLimit || pageSize == resultLimit) { + + int page = (dataList.size() + resultLimit) / resultLimit; + loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, resultLimit, tinyDb.getString("milestoneState")); - swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { - @Override - public void onRefresh() { - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - swipeRefresh.setRefreshing(false); - MilestonesViewModel.loadMilestonesList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, msState, getContext()); - } - }, 50); } + + })); + + viewBinding.recyclerView.setHasFixedSize(true); + viewBinding.recyclerView.setLayoutManager(new LinearLayoutManager(ctx)); + viewBinding.recyclerView.setAdapter(adapter); + + viewBinding.pullToRefresh.setOnRefreshListener(() -> new Handler().postDelayed(() -> { + + dataList.clear(); + viewBinding.pullToRefresh.setRefreshing(false); + loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, resultLimit, tinyDb.getString("milestoneState")); + adapter.updateList(dataList); + + }, 50)); + + ((RepoDetailActivity) Objects.requireNonNull(getActivity())).setFragmentRefreshListenerMilestone(milestoneState -> { + + if(milestoneState.equals("closed")) { + menu.getItem(1).setIcon(R.drawable.ic_filter_closed); + } + else { + menu.getItem(1).setIcon(R.drawable.ic_filter); + } + + dataList.clear(); + + adapter = new MilestonesAdapter(ctx, dataList); + adapter.setLoadMoreListener(() -> viewBinding.recyclerView.post(() -> { + + if(dataList.size() == resultLimit || pageSize == resultLimit) { + + int page = (dataList.size() + resultLimit) / resultLimit; + loadMore(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, page, resultLimit, milestoneState); + + } + + })); + + tinyDb.putString("milestoneState", milestoneState); + + viewBinding.progressBar.setVisibility(View.VISIBLE); + viewBinding.noDataMilestone.setVisibility(View.GONE); + + loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, resultLimit, milestoneState); + viewBinding.recyclerView.setAdapter(adapter); + }); - fetchDataAsync(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName); + api = AppApiService.createService(ApiInterface.class, instanceUrl, ctx); + loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, resultLimit, tinyDb.getString("milestoneState")); + + return viewBinding.getRoot(); - return v; } @Override public void onResume() { + super.onResume(); - final TinyDB tinyDb = new TinyDB(getContext()); - final String instanceUrl = tinyDb.getString("instanceUrl"); + TinyDB tinyDb = new TinyDB(getContext()); final String loginUid = tinyDb.getString("loginUid"); String repoFullName = tinyDb.getString("repoFullName"); String[] parts = repoFullName.split("/"); @@ -128,82 +154,168 @@ public class MilestonesFragment extends Fragment { final String instanceToken = "token " + tinyDb.getString(loginUid + "-token"); if(tinyDb.getBoolean("milestoneCreated")) { - MilestonesViewModel.loadMilestonesList(instanceUrl, Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, msState, getContext()); + + loadInitial(Authorization.returnAuthentication(getContext(), loginUid, instanceToken), repoOwner, repoName, resultLimit, tinyDb.getString("milestoneState")); tinyDb.putBoolean("milestoneCreated", false); + } + } - public void onButtonPressed(Uri uri) { - if (mListener != null) { - mListener.onFragmentInteraction(uri); - } - } + private void loadInitial(String token, String repoOwner, String repoName, int resultLimit, String milestoneState) { - @Override - public void onDetach() { - super.onDetach(); - mListener = null; - } + Call> call = api.getMilestones(token, repoOwner, repoName, 1, resultLimit, milestoneState); - public interface OnFragmentInteractionListener { - void onFragmentInteraction(Uri uri); - } + call.enqueue(new Callback>() { - private void fetchDataAsync(String instanceUrl, String instanceToken, String owner, String repo) { - - MilestonesViewModel msModel = new ViewModelProvider(this).get(MilestonesViewModel.class); - - msModel.getMilestonesList(instanceUrl, instanceToken, owner, repo, msState, getContext()).observe(getViewLifecycleOwner(), new Observer>() { @Override - public void onChanged(@Nullable List msListMain) { - adapter = new MilestonesAdapter(getContext(), msListMain); - if(adapter.getItemCount() > 0) { - mRecyclerView.setAdapter(adapter); - noDataMilestone.setVisibility(View.GONE); + public void onResponse(@NonNull Call> call, @NonNull Response> response) { + + if(response.isSuccessful()) { + + assert response.body() != null; + if(response.body().size() > 0) { + + dataList.clear(); + dataList.addAll(response.body()); + adapter.notifyDataChanged(); + viewBinding.noDataMilestone.setVisibility(View.GONE); + + } + else { + + dataList.clear(); + adapter.notifyDataChanged(); + viewBinding.noDataMilestone.setVisibility(View.VISIBLE); + + } + + viewBinding.progressBar.setVisibility(View.GONE); + } else { - adapter.notifyDataSetChanged(); - mRecyclerView.setAdapter(adapter); - noDataMilestone.setVisibility(View.VISIBLE); + Log.e(TAG, String.valueOf(response.code())); } - mProgressBar.setVisibility(View.GONE); + } + + @Override + public void onFailure(@NonNull Call> call, @NonNull Throwable t) { + + Log.e(TAG, t.toString()); + } + }); } + private void loadMore(String token, String repoOwner, String repoName, int page, int resultLimit, String milestoneState) { + + //add loading progress view + dataList.add(new Milestones("load")); + adapter.notifyItemInserted((dataList.size() - 1)); + + Call> call = api.getMilestones(token, repoOwner, repoName, page, resultLimit, milestoneState); + + call.enqueue(new Callback>() { + + @Override + public void onResponse(@NonNull Call> call, @NonNull Response> response) { + + if(response.isSuccessful()) { + + //remove loading view + dataList.remove(dataList.size() - 1); + + List result = response.body(); + + assert result != null; + if(result.size() > 0) { + + pageSize = result.size(); + dataList.addAll(result); + + } + else { + + Toasty.info(ctx, getString(R.string.noMoreData)); + adapter.setMoreDataAvailable(false); + + } + + adapter.notifyDataChanged(); + + } + else { + + Log.e(TAG, String.valueOf(response.code())); + + } + + } + + @Override + public void onFailure(@NonNull Call> call, @NonNull Throwable t) { + + Log.e(TAG, t.toString()); + + } + + }); + } + @Override public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - boolean connToInternet = AppUtil.haveNetworkConnection(Objects.requireNonNull(getContext())); - + this.menu = menu; inflater.inflate(R.menu.search_menu, menu); + inflater.inflate(R.menu.filter_menu_milestone, menu); super.onCreateOptionsMenu(menu, inflater); + TinyDB tinyDb = new TinyDB(ctx); + + if(tinyDb.getString("milestoneState").equals("closed")) { + menu.getItem(1).setIcon(R.drawable.ic_filter_closed); + } + else { + menu.getItem(1).setIcon(R.drawable.ic_filter); + } + 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 public boolean onQueryTextSubmit(String query) { + return false; } @Override public boolean onQueryTextChange(String newText) { - if(mRecyclerView.getAdapter() != null) { - adapter.getFilter().filter(newText); - } + + filter(newText); return false; + } + }); } + private void filter(String text) { + + List arr = new ArrayList<>(); + + for(Milestones d : dataList) { + if(d.getTitle().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/StaticGlobalVariables.java b/app/src/main/java/org/mian/gitnex/helpers/StaticGlobalVariables.java index 9a744e39..9e989b1e 100644 --- a/app/src/main/java/org/mian/gitnex/helpers/StaticGlobalVariables.java +++ b/app/src/main/java/org/mian/gitnex/helpers/StaticGlobalVariables.java @@ -10,13 +10,20 @@ public interface StaticGlobalVariables { int resultLimitNewGiteaInstances = 25; // Gitea 1.12 and above int resultLimitOldGiteaInstances = 10; // Gitea 1.11 and below - // issues variables + // tags + String tagMilestonesFragment = "MilestonesFragment"; + String tagPullRequestsList = "PullRequestsListFragment"; String tagIssuesList = "IssuesListFragment"; + String tagMilestonesAdapter = "MilestonesAdapter"; + + // issues variables int issuesPageInit = 1; String issuesRequestType = "issues"; // pull request - String tagPullRequestsList = "PullRequestsListFragment"; int prPageInit = 1; + // milestone + int milestonesPageInit = 1; + } diff --git a/app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java b/app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java index 019d583c..a10ca154 100644 --- a/app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java +++ b/app/src/main/java/org/mian/gitnex/interfaces/ApiInterface.java @@ -109,7 +109,7 @@ public interface ApiInterface { Call replyCommentToIssue(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Path("index") int issueIndex, @Body Issues jsonStr); @GET("repos/{owner}/{repo}/milestones") // get milestones by repo - Call> getMilestones(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Query("state") String state); + Call> getMilestones(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName, @Query("page") int page, @Query("limit") int limit, @Query("state") String state); @GET("repos/{owner}/{repo}/branches") // get branches Call> getBranches(@Header("Authorization") String token, @Path("owner") String ownerName, @Path("repo") String repoName); diff --git a/app/src/main/java/org/mian/gitnex/viewmodels/MilestonesViewModel.java b/app/src/main/java/org/mian/gitnex/viewmodels/MilestonesViewModel.java deleted file mode 100644 index 4cd132f2..00000000 --- a/app/src/main/java/org/mian/gitnex/viewmodels/MilestonesViewModel.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.mian.gitnex.viewmodels; - -import android.content.Context; -import android.util.Log; -import org.mian.gitnex.clients.RetrofitClient; -import org.mian.gitnex.models.Milestones; -import java.util.List; -import androidx.annotation.NonNull; -import androidx.lifecycle.LiveData; -import androidx.lifecycle.MutableLiveData; -import androidx.lifecycle.ViewModel; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; - -/** - * Author M M Arif - */ - -public class MilestonesViewModel extends ViewModel { - - private static MutableLiveData> milestonesList; - - public LiveData> getMilestonesList(String instanceUrl, String token, String owner, String repo, String msState, Context ctx) { - - milestonesList = new MutableLiveData<>(); - loadMilestonesList(instanceUrl, token, owner, repo, msState, ctx); - - return milestonesList; - } - - public static void loadMilestonesList(String instanceUrl, String token, String owner, String repo, String msState, Context ctx) { - - Call> call = RetrofitClient - .getInstance(instanceUrl, ctx) - .getApiInterface() - .getMilestones(token, owner, repo, msState); - - call.enqueue(new Callback>() { - - @Override - public void onResponse(@NonNull Call> call, @NonNull Response> response) { - - if(response.isSuccessful()) { - milestonesList.postValue(response.body()); - } - else { - Log.i("onResponse", String.valueOf(response.code())); - } - - } - - @Override - public void onFailure(@NonNull Call> call, Throwable t) { - Log.i("onFailure", t.toString()); - } - - }); - - } - -} diff --git a/app/src/main/res/layout/bottom_sheet_issues_filter.xml b/app/src/main/res/layout/bottom_sheet_issues_filter.xml index 1558e471..87101f07 100644 --- a/app/src/main/res/layout/bottom_sheet_issues_filter.xml +++ b/app/src/main/res/layout/bottom_sheet_issues_filter.xml @@ -22,7 +22,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" - android:text="@string/tabIssueOpen" + android:text="@string/isOpen" android:drawableStart="@drawable/ic_issue_open" android:drawablePadding="24dp" android:textColor="?attr/primaryTextColor" @@ -34,7 +34,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" - android:text="@string/tabIssueClosed" + android:text="@string/isClosed" android:drawableStart="@drawable/ic_done" android:drawablePadding="24dp" android:textColor="?attr/primaryTextColor" diff --git a/app/src/main/res/layout/bottom_sheet_milestones_filter.xml b/app/src/main/res/layout/bottom_sheet_milestones_filter.xml new file mode 100644 index 00000000..13f3784d --- /dev/null +++ b/app/src/main/res/layout/bottom_sheet_milestones_filter.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/bottom_sheet_pull_request_filter.xml b/app/src/main/res/layout/bottom_sheet_pull_request_filter.xml index e1d9bb8d..b49c6234 100644 --- a/app/src/main/res/layout/bottom_sheet_pull_request_filter.xml +++ b/app/src/main/res/layout/bottom_sheet_pull_request_filter.xml @@ -22,7 +22,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" - android:text="@string/tabIssueOpen" + android:text="@string/isOpen" android:drawableStart="@drawable/ic_merge" android:drawablePadding="24dp" android:textColor="?attr/primaryTextColor" @@ -34,7 +34,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" - android:text="@string/tabIssueClosed" + android:text="@string/isClosed" android:drawableStart="@drawable/ic_done" android:drawablePadding="24dp" android:textColor="?attr/primaryTextColor" diff --git a/app/src/main/res/menu/filter_menu_milestone.xml b/app/src/main/res/menu/filter_menu_milestone.xml new file mode 100644 index 00000000..220affe8 --- /dev/null +++ b/app/src/main/res/menu/filter_menu_milestone.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 73361813..c5f98a00 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -179,9 +179,7 @@ Opened\u0020 Due Date Status: open - open Status: closed - closed Creator :\u0020 Assignees Type: Issue @@ -553,6 +551,8 @@ public Default View in Browser + Open + Closed We cannot reach the server at the moment, please check your server status and try again @@ -646,9 +646,6 @@ Open Milestone Milestone status updated successfully - Open - Closed - We cannot reach the server, please check your server status Crash Reports