diff --git a/app/build.gradle b/app/build.gradle
index fc6e2cd1..e3f67773 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -116,6 +116,7 @@ dependencies {
compile 'com.commonsware.cwac:anddown:0.3.0'
compile 'com.github.GrenderG:Toasty:1.1.3'
compile 'uk.co.samuelwall:material-tap-target-prompt:1.9.2'
+ compile 'com.github.k0shk0sh:RetainedDateTimePickers:1.0.2'
apt 'org.projectlombok:lombok:1.12.6'
apt 'frankiesardo:icepick-processor:3.1.0'
apt 'com.jakewharton:butterknife-compiler:8.4.0'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index a8ede513..184c4d3b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -141,6 +141,10 @@
android:value=".ui.modules.main.MainView"/>
+
+
editPullRequest(@Path("owner") String owner, @Path("repo") String repo,
@Path("number") int number,
@Body IssueRequestModel issue);
+ @PATCH("repos/{owner}/{repo}/issues/{number}")
+ Observable editIssue(@Path("owner") String owner, @Path("repo") String repo,
+ @Path("number") int number,
+ @Body IssueRequestModel issue);
}
diff --git a/app/src/main/java/com/fastaccess/data/service/RepoService.java b/app/src/main/java/com/fastaccess/data/service/RepoService.java
index b194c676..21cd0f80 100644
--- a/app/src/main/java/com/fastaccess/data/service/RepoService.java
+++ b/app/src/main/java/com/fastaccess/data/service/RepoService.java
@@ -6,8 +6,10 @@ import com.fastaccess.data.dao.BranchesModel;
import com.fastaccess.data.dao.CommentRequestModel;
import com.fastaccess.data.dao.CommentsModel;
import com.fastaccess.data.dao.CommitModel;
+import com.fastaccess.data.dao.CreateMilestoneModel;
import com.fastaccess.data.dao.LabelModel;
import com.fastaccess.data.dao.MarkdownModel;
+import com.fastaccess.data.dao.MilestoneModel;
import com.fastaccess.data.dao.Pageable;
import com.fastaccess.data.dao.ReleasesModel;
import com.fastaccess.data.dao.RepoFilesModel;
@@ -110,4 +112,13 @@ public interface RepoService {
@GET("repos/{owner}/{repo}/branches")
Observable> getBranches(@NonNull @Path("owner") String owner, @NonNull @Path("repo") String repo);
+ @GET("repos/{owner}/{repo}/milestones")
+ Observable> getMilestones(@Path("owner") String owner, @Path("repo") String repo);
+
+ @POST("repos/{owner}/{repo}/milestones")
+ Observable createMilestone(@Path("owner") String owner, @Path("repo") String repo,
+ @Body CreateMilestoneModel create);
+
+ @GET("repos/{owner}/{repo}/assignees")
+ Observable> getAssignees(@Path("owner") String owner, @Path("repo") String repo);
}
diff --git a/app/src/main/java/com/fastaccess/helper/ParseDateFormat.java b/app/src/main/java/com/fastaccess/helper/ParseDateFormat.java
index f27529b9..206a5ed7 100644
--- a/app/src/main/java/com/fastaccess/helper/ParseDateFormat.java
+++ b/app/src/main/java/com/fastaccess/helper/ParseDateFormat.java
@@ -1,9 +1,11 @@
package com.fastaccess.helper;
+import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.format.DateUtils;
import java.text.DateFormat;
+import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
@@ -43,4 +45,22 @@ public class ParseDateFormat {
}
return "N/A";
}
+
+ public static String toGithubDate(@NonNull Date date) {
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
+ return simpleDateFormat.format(date);
+ }
+
+ public static String prettifyDate(long timestamp) {
+ return new SimpleDateFormat("dd-MM-yyyy", Locale.US).format(new Date(timestamp));
+ }
+
+ @Nullable public static Date getDateFromString(@NonNull String date) {
+ try {
+ return new SimpleDateFormat("dd-MM-yyyy", Locale.US).parse(date);
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/fastaccess/helper/PrefGetter.java b/app/src/main/java/com/fastaccess/helper/PrefGetter.java
index 647f962a..ddb0924a 100644
--- a/app/src/main/java/com/fastaccess/helper/PrefGetter.java
+++ b/app/src/main/java/com/fastaccess/helper/PrefGetter.java
@@ -92,6 +92,8 @@ public class PrefGetter {
return 5 * 60;
} else if (s.equals(context.getString(R.string.one_minute))) {
return 60;
+ } else if (s.equals(context.getString(R.string.turn_off))) {
+ return -1;
}
}
return 0;
diff --git a/app/src/main/java/com/fastaccess/provider/tasks/NotificationJobTask.java b/app/src/main/java/com/fastaccess/provider/tasks/NotificationJobTask.java
index a6fa6d9f..d55cc305 100644
--- a/app/src/main/java/com/fastaccess/provider/tasks/NotificationJobTask.java
+++ b/app/src/main/java/com/fastaccess/provider/tasks/NotificationJobTask.java
@@ -55,13 +55,17 @@ public class NotificationJobTask extends JobService {
}
public static void scheduleJob(@NonNull Context context) {
- scheduleJob(context, PrefGetter.getNotificationTaskDuration(context) == 0 ? (30 * 60) : PrefGetter.getNotificationTaskDuration(context),
- false);
+ int duration = PrefGetter.getNotificationTaskDuration(context);
+ scheduleJob(context, duration == 0 ? (30 * 60) : duration, false);
}
public static void scheduleJob(@NonNull Context context, int duration, boolean cancel) {
FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(context));
if (cancel) dispatcher.cancel(EVERY_30_MINS);
+ if (duration == -1) {
+ dispatcher.cancel(EVERY_30_MINS);
+ return;
+ }
Job.Builder builder = dispatcher
.newJobBuilder()
.setTag(EVERY_30_MINS)
diff --git a/app/src/main/java/com/fastaccess/ui/adapter/MilestonesAdapter.java b/app/src/main/java/com/fastaccess/ui/adapter/MilestonesAdapter.java
new file mode 100644
index 00000000..142be747
--- /dev/null
+++ b/app/src/main/java/com/fastaccess/ui/adapter/MilestonesAdapter.java
@@ -0,0 +1,31 @@
+package com.fastaccess.ui.adapter;
+
+import android.support.annotation.NonNull;
+import android.view.ViewGroup;
+
+import com.fastaccess.data.dao.MilestoneModel;
+import com.fastaccess.ui.adapter.viewholder.MilestonesViewHolder;
+import com.fastaccess.ui.widgets.recyclerview.BaseRecyclerAdapter;
+import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder;
+
+import java.util.ArrayList;
+
+/**
+ * Created by Kosh on 11 Nov 2016, 2:07 PM
+ */
+
+public class MilestonesAdapter extends BaseRecyclerAdapter> {
+
+ public MilestonesAdapter(@NonNull ArrayList eventsModels) {
+ super(eventsModels);
+ }
+
+ @Override protected MilestonesViewHolder viewHolder(ViewGroup parent, int viewType) {
+ return MilestonesViewHolder.newInstance(parent, this);
+ }
+
+ @Override protected void onBindView(MilestonesViewHolder holder, int position) {
+ holder.bind(getItem(position));
+ }
+}
diff --git a/app/src/main/java/com/fastaccess/ui/adapter/viewholder/MilestonesViewHolder.java b/app/src/main/java/com/fastaccess/ui/adapter/viewholder/MilestonesViewHolder.java
new file mode 100644
index 00000000..b49bdf84
--- /dev/null
+++ b/app/src/main/java/com/fastaccess/ui/adapter/viewholder/MilestonesViewHolder.java
@@ -0,0 +1,44 @@
+package com.fastaccess.ui.adapter.viewholder;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.fastaccess.R;
+import com.fastaccess.data.dao.MilestoneModel;
+import com.fastaccess.helper.ParseDateFormat;
+import com.fastaccess.ui.widgets.FontTextView;
+import com.fastaccess.ui.widgets.recyclerview.BaseRecyclerAdapter;
+import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder;
+
+import butterknife.BindView;
+
+/**
+ * Created by Kosh on 11 Nov 2016, 2:08 PM
+ */
+
+public class MilestonesViewHolder extends BaseViewHolder {
+
+ @BindView(R.id.title) FontTextView title;
+ @BindView(R.id.date) FontTextView date;
+ @BindView(R.id.notificationTitle) FontTextView notificationTitle;
+
+ private MilestonesViewHolder(@NonNull View itemView, @Nullable BaseRecyclerAdapter adapter) {
+ super(itemView, adapter);
+ }
+
+ public static MilestonesViewHolder newInstance(@NonNull ViewGroup viewGroup, @Nullable BaseRecyclerAdapter adapter) {
+ return new MilestonesViewHolder(getView(viewGroup, R.layout.notifications_row_item), adapter);
+ }
+
+ @Override public void bind(@NonNull MilestoneModel milestoneModel) {
+ title.setText(milestoneModel.getTitle());
+ notificationTitle.setText(milestoneModel.getDescription());
+ if (milestoneModel.getDueOn() != null) {
+ date.setText(ParseDateFormat.getTimeAgo(milestoneModel.getDueOn()));
+ } else {
+ date.setText(ParseDateFormat.getTimeAgo(milestoneModel.getCreatedAt()));
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/fastaccess/ui/base/BaseDialogFragment.java b/app/src/main/java/com/fastaccess/ui/base/BaseDialogFragment.java
index a1caf47e..1d4761ee 100644
--- a/app/src/main/java/com/fastaccess/ui/base/BaseDialogFragment.java
+++ b/app/src/main/java/com/fastaccess/ui/base/BaseDialogFragment.java
@@ -52,7 +52,6 @@ public abstract class BaseDialogFragment {
+ void onLoadMilestones(@NonNull String login, @NonNull String repo);
+
+ @NonNull ArrayList getMilestones();
+ }
+}
diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/extras/milestone/MilestonePresenter.java b/app/src/main/java/com/fastaccess/ui/modules/repos/extras/milestone/MilestonePresenter.java
new file mode 100644
index 00000000..9eb08da7
--- /dev/null
+++ b/app/src/main/java/com/fastaccess/ui/modules/repos/extras/milestone/MilestonePresenter.java
@@ -0,0 +1,46 @@
+package com.fastaccess.ui.modules.repos.extras.milestone;
+
+import android.support.annotation.NonNull;
+import android.view.View;
+
+import com.fastaccess.R;
+import com.fastaccess.data.dao.MilestoneModel;
+import com.fastaccess.provider.rest.RestProvider;
+import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
+
+import java.util.ArrayList;
+
+/**
+ * Created by Kosh on 04 Mar 2017, 9:41 PM
+ */
+
+public class MilestonePresenter extends BasePresenter implements MilestoneMvp.Presenter {
+ private ArrayList milestoneModels = new ArrayList<>();
+
+ @Override public void onItemClick(int position, View v, MilestoneModel item) {
+ if (getView() != null) getView().onMilestoneSelected(item);
+ }
+
+ @Override public void onItemLongClick(int position, View v, MilestoneModel item) {
+ onItemClick(position, v, item);
+ }
+
+ @Override public void onLoadMilestones(@NonNull String login, @NonNull String repo) {
+ makeRestCall(RestProvider.getRepoService().getMilestones(login, repo),
+ response -> {
+ if (response == null || response.getItems() == null || response.getItems().isEmpty()) {
+ sendToView(view -> view.showMessage(R.string.error, R.string.no_milestones));
+ return;
+ }
+ if (response.getItems() != null) {
+ milestoneModels.clear();
+ milestoneModels.addAll(response.getItems());
+ sendToView(MilestoneMvp.View::onNotifyAdapter);
+ }
+ });
+ }
+
+ @NonNull @Override public ArrayList getMilestones() {
+ return milestoneModels;
+ }
+}
diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/extras/milestone/MilestoneView.java b/app/src/main/java/com/fastaccess/ui/modules/repos/extras/milestone/MilestoneView.java
new file mode 100644
index 00000000..71669221
--- /dev/null
+++ b/app/src/main/java/com/fastaccess/ui/modules/repos/extras/milestone/MilestoneView.java
@@ -0,0 +1,131 @@
+package com.fastaccess.ui.modules.repos.extras.milestone;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.StringRes;
+import android.support.design.widget.AppBarLayout;
+import android.support.v7.widget.Toolbar;
+import android.view.View;
+
+import com.fastaccess.R;
+import com.fastaccess.data.dao.MilestoneModel;
+import com.fastaccess.helper.BundleConstant;
+import com.fastaccess.helper.Bundler;
+import com.fastaccess.ui.adapter.MilestonesAdapter;
+import com.fastaccess.ui.base.BaseFragment;
+import com.fastaccess.ui.modules.repos.extras.milestone.create.CreateMilestoneView;
+import com.fastaccess.ui.widgets.AppbarRefreshLayout;
+import com.fastaccess.ui.widgets.StateLayout;
+import com.fastaccess.ui.widgets.recyclerview.DynamicRecyclerView;
+
+import butterknife.BindView;
+
+/**
+ * Created by Kosh on 04 Mar 2017, 9:45 PM
+ */
+
+public class MilestoneView extends BaseFragment implements MilestoneMvp.View {
+ public static final String TAG = MilestoneView.class.getSimpleName();
+
+ @BindView(R.id.toolbar) Toolbar toolbar;
+ @BindView(R.id.toolbarShadow) View toolbarShadow;
+ @BindView(R.id.appbar) AppBarLayout appbar;
+ @BindView(R.id.recycler) DynamicRecyclerView recycler;
+ @BindView(R.id.refresh) AppbarRefreshLayout refresh;
+ @BindView(R.id.stateLayout) StateLayout stateLayout;
+ private MilestonesAdapter adapter;
+ private MilestoneMvp.OnMilestoneSelected onMilestoneSelected;
+
+ public static MilestoneView newInstance(@NonNull String login, @NonNull String repo) {
+ MilestoneView fragment = new MilestoneView();
+ fragment.setArguments(Bundler.start()
+ .put(BundleConstant.EXTRA, login)
+ .put(BundleConstant.ID, repo)
+ .end());
+ return fragment;
+ }
+
+ @Override public void onAttach(Context context) {
+ super.onAttach(context);
+ if (getParentFragment() != null && getParentFragment() instanceof MilestoneMvp.OnMilestoneSelected) {
+ onMilestoneSelected = (MilestoneMvp.OnMilestoneSelected) getParentFragment();
+ } else if (context instanceof MilestoneMvp.OnMilestoneSelected) {
+ onMilestoneSelected = (MilestoneMvp.OnMilestoneSelected) context;
+ } else {
+ throw new IllegalArgumentException(context.getClass().getSimpleName() + " must implement onMilestoneSelected");
+ }
+ }
+
+ @Override public void onDetach() {
+ onMilestoneSelected = null;
+ super.onDetach();
+ }
+
+ @Override public void onNotifyAdapter() {
+ hideProgress();
+ adapter.notifyDataSetChanged();
+ }
+
+ @Override public void onMilestoneSelected(@NonNull MilestoneModel milestoneModel) {
+ onMilestoneSelected.onMilestoneSelected(milestoneModel);
+ }
+
+ @Override protected int fragmentLayout() {
+ return R.layout.milestone_dialog_layout;
+ }
+
+ @Override protected void onFragmentCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+ if (getArguments() == null) {
+ return;
+ }
+ String login = getArguments().getString(BundleConstant.EXTRA);
+ String repo = getArguments().getString(BundleConstant.ID);
+ if (login == null || repo == null) {
+ return;
+ }
+ toolbar.setTitle(R.string.milestone);
+ toolbar.setOnMenuItemClickListener(item -> onAddMilestone());
+ toolbar.inflateMenu(R.menu.add_menu);
+ adapter = new MilestonesAdapter(getPresenter().getMilestones());
+ adapter.setListener(getPresenter());
+ recycler.setEmptyView(stateLayout, refresh);
+ recycler.setAdapter(adapter);
+ if (savedInstanceState == null || (getPresenter().getMilestones().isEmpty() && !getPresenter().isApiCalled())) {
+ getPresenter().onLoadMilestones(login, repo);
+ }
+ stateLayout.setOnReloadListener(v -> getPresenter().onLoadMilestones(login, repo));
+ refresh.setOnRefreshListener(() -> getPresenter().onLoadMilestones(login, repo));
+ }
+
+ @Override public void showProgress(@StringRes int resId) {
+ stateLayout.showProgress();
+ }
+
+ @Override public void hideProgress() {
+ refresh.setRefreshing(false);
+ stateLayout.hideProgress();
+ }
+
+ @Override public void showErrorMessage(@NonNull String msgRes) {
+ hideProgress();
+ stateLayout.showReload(adapter.getItemCount());
+ super.showErrorMessage(msgRes);
+ }
+
+ @NonNull @Override public MilestonePresenter providePresenter() {
+ return new MilestonePresenter();
+ }
+
+ @Override public void onMilestoneAdded(@NonNull MilestoneModel milestoneModel) {
+ adapter.addItem(milestoneModel, 0);
+ }
+
+ private boolean onAddMilestone() {
+ //noinspection ConstantConditions
+ CreateMilestoneView.newInstance(getArguments().getString(BundleConstant.EXTRA), getArguments().getString(BundleConstant.ID))
+ .show(getChildFragmentManager(), CreateMilestoneView.TAG);
+ return true;
+ }
+}
diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/extras/milestone/create/CreateMilestoneMvp.java b/app/src/main/java/com/fastaccess/ui/modules/repos/extras/milestone/create/CreateMilestoneMvp.java
new file mode 100644
index 00000000..5f8cbdce
--- /dev/null
+++ b/app/src/main/java/com/fastaccess/ui/modules/repos/extras/milestone/create/CreateMilestoneMvp.java
@@ -0,0 +1,29 @@
+package com.fastaccess.ui.modules.repos.extras.milestone.create;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import com.fastaccess.data.dao.MilestoneModel;
+import com.fastaccess.ui.base.mvp.BaseMvp;
+
+/**
+ * Created by Kosh on 04 Mar 2017, 10:47 PM
+ */
+
+public interface CreateMilestoneMvp {
+
+ interface OnMilestoneAdded {
+ void onMilestoneAdded(@NonNull MilestoneModel milestoneModel);
+ }
+
+ interface View extends BaseMvp.FAView {
+ void onShowTitleError(boolean isError);
+
+ void onMilestoneAdded(@NonNull MilestoneModel milestoneModel);
+ }
+
+ interface Presenter {
+ void onSubmit(@Nullable String title, @Nullable String dueOn,
+ @NonNull String login, @NonNull String repo);
+ }
+}
diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/extras/milestone/create/CreateMilestonePresenter.java b/app/src/main/java/com/fastaccess/ui/modules/repos/extras/milestone/create/CreateMilestonePresenter.java
new file mode 100644
index 00000000..50777403
--- /dev/null
+++ b/app/src/main/java/com/fastaccess/ui/modules/repos/extras/milestone/create/CreateMilestonePresenter.java
@@ -0,0 +1,43 @@
+package com.fastaccess.ui.modules.repos.extras.milestone.create;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import com.fastaccess.R;
+import com.fastaccess.data.dao.CreateMilestoneModel;
+import com.fastaccess.helper.InputHelper;
+import com.fastaccess.helper.ParseDateFormat;
+import com.fastaccess.provider.rest.RestProvider;
+import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
+
+import java.util.Date;
+
+/**
+ * Created by Kosh on 04 Mar 2017, 10:49 PM
+ */
+
+public class CreateMilestonePresenter extends BasePresenter implements CreateMilestoneMvp.Presenter {
+ @Override public void onSubmit(@Nullable String title, @Nullable String dueOn,
+ @NonNull String login, @NonNull String repo) {
+ if (getView() != null) {
+ boolean isEmptyTitle = InputHelper.isEmpty(title);
+ getView().onShowTitleError(isEmptyTitle);
+ if (!isEmptyTitle) {
+ CreateMilestoneModel createMilestoneModel = new CreateMilestoneModel();
+ createMilestoneModel.setTitle(title);
+ if (!InputHelper.isEmpty(dueOn)) {
+ Date date = ParseDateFormat.getDateFromString(dueOn);
+ if (date != null) createMilestoneModel.setDueOn(ParseDateFormat.toGithubDate(date));
+ }
+ makeRestCall(RestProvider.getRepoService().createMilestone(login, repo, createMilestoneModel),
+ milestoneModel -> {
+ if (milestoneModel != null) {
+ sendToView(view -> view.onMilestoneAdded(milestoneModel));
+ } else {
+ sendToView(view -> view.showMessage(R.string.error, R.string.error_creating_milestone));
+ }
+ });
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/extras/milestone/create/CreateMilestoneView.java b/app/src/main/java/com/fastaccess/ui/modules/repos/extras/milestone/create/CreateMilestoneView.java
new file mode 100644
index 00000000..21a1be94
--- /dev/null
+++ b/app/src/main/java/com/fastaccess/ui/modules/repos/extras/milestone/create/CreateMilestoneView.java
@@ -0,0 +1,110 @@
+package com.fastaccess.ui.modules.repos.extras.milestone.create;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.design.widget.TextInputEditText;
+import android.support.design.widget.TextInputLayout;
+import android.support.v7.widget.Toolbar;
+import android.view.MotionEvent;
+import android.view.View;
+
+import com.fastaccess.R;
+import com.fastaccess.data.dao.MilestoneModel;
+import com.fastaccess.datetimepicker.DatePickerFragmentDialog;
+import com.fastaccess.datetimepicker.callback.DatePickerCallback;
+import com.fastaccess.helper.BundleConstant;
+import com.fastaccess.helper.Bundler;
+import com.fastaccess.helper.InputHelper;
+import com.fastaccess.helper.ParseDateFormat;
+import com.fastaccess.ui.base.BaseDialogFragment;
+
+import butterknife.BindView;
+import butterknife.OnTouch;
+
+/**
+ * Created by Kosh on 04 Mar 2017, 10:40 PM
+ */
+
+public class CreateMilestoneView extends BaseDialogFragment
+ implements CreateMilestoneMvp.View, DatePickerCallback {
+
+ public static final String TAG = CreateMilestoneView.class.getSimpleName();
+
+ @BindView(R.id.toolbar) Toolbar toolbar;
+ @BindView(R.id.title) TextInputLayout title;
+ @BindView(R.id.dueOnEditText) TextInputEditText dueOnEditText;
+
+ private CreateMilestoneMvp.OnMilestoneAdded onMilestoneAdded;
+
+ public static CreateMilestoneView newInstance(@NonNull String login, @NonNull String repo) {
+ CreateMilestoneView fragment = new CreateMilestoneView();
+ fragment.setArguments(Bundler.start()
+ .put(BundleConstant.EXTRA, login)
+ .put(BundleConstant.ID, repo)
+ .end());
+ return fragment;
+ }
+
+ @Override public void onAttach(Context context) {
+ super.onAttach(context);
+ if (getParentFragment() instanceof CreateMilestoneMvp.OnMilestoneAdded) {
+ onMilestoneAdded = (CreateMilestoneMvp.OnMilestoneAdded) getParentFragment();
+ } else {
+ onMilestoneAdded = (CreateMilestoneMvp.OnMilestoneAdded) context;
+ }
+ }
+
+ @Override public void onDetach() {
+ onMilestoneAdded = null;
+ super.onDetach();
+ }
+
+ @Override protected int fragmentLayout() {
+ return R.layout.create_milestone_layout;
+ }
+
+ @Override protected void onFragmentCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+ String login = getArguments().getString(BundleConstant.EXTRA);
+ String repo = getArguments().getString(BundleConstant.ID);
+ if (login == null || repo == null) {
+ dismiss();
+ return;
+ }
+ toolbar.setTitle(R.string.create_milestone);
+ toolbar.setNavigationIcon(R.drawable.ic_back);
+ toolbar.inflateMenu(R.menu.add_menu);
+ toolbar.setOnMenuItemClickListener(item -> {
+ getPresenter().onSubmit(InputHelper.toString(title), InputHelper.toString(dueOnEditText), login, repo);
+ return true;
+ });
+ }
+
+ @NonNull @Override public CreateMilestonePresenter providePresenter() {
+ return new CreateMilestonePresenter();
+ }
+
+ @OnTouch(R.id.dueOnEditText) boolean onTouch(MotionEvent event) {
+ if (event.getAction() == MotionEvent.ACTION_UP) {
+ DatePickerFragmentDialog.newInstance().show(getChildFragmentManager(), "DatePickerFragmentDialog");
+ }
+ return false;
+ }
+
+ @Override public void onDateSet(long date) {
+ if (date > 0) {
+ dueOnEditText.setText(ParseDateFormat.prettifyDate(date));
+ }
+ }
+
+ @Override public void onShowTitleError(boolean isError) {
+ title.setError(isError ? getString(R.string.required_field) : null);
+ }
+
+ @Override public void onMilestoneAdded(@NonNull MilestoneModel milestoneModel) {
+ hideProgress();
+ onMilestoneAdded.onMilestoneAdded(milestoneModel);
+ dismiss();
+ }
+}
diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/extras/milestone/create/MilestoneActivityView.java b/app/src/main/java/com/fastaccess/ui/modules/repos/extras/milestone/create/MilestoneActivityView.java
new file mode 100644
index 00000000..70e9c153
--- /dev/null
+++ b/app/src/main/java/com/fastaccess/ui/modules/repos/extras/milestone/create/MilestoneActivityView.java
@@ -0,0 +1,76 @@
+package com.fastaccess.ui.modules.repos.extras.milestone.create;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import com.fastaccess.R;
+import com.fastaccess.data.dao.MilestoneModel;
+import com.fastaccess.helper.BundleConstant;
+import com.fastaccess.helper.Bundler;
+import com.fastaccess.ui.base.BaseActivity;
+import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
+import com.fastaccess.ui.modules.repos.extras.milestone.MilestoneMvp;
+import com.fastaccess.ui.modules.repos.extras.milestone.MilestoneView;
+
+import net.grandcentrix.thirtyinch.TiPresenter;
+
+/**
+ * Created by Kosh on 04 Mar 2017, 10:58 PM
+ */
+
+public class MilestoneActivityView extends BaseActivity implements MilestoneMvp.OnMilestoneSelected {
+
+ public static final int CREATE_MILESTONE_RQ = 200;
+
+ public static void startActivity(@NonNull Activity activity, @NonNull String login, @NonNull String repo) {
+ Intent intent = new Intent(activity, MilestoneActivityView.class);
+ intent.putExtras(Bundler.start()
+ .put(BundleConstant.EXTRA, login)
+ .put(BundleConstant.ID, repo)
+ .end());
+ activity.startActivityForResult(intent, CREATE_MILESTONE_RQ);
+ }
+
+ @Override protected int layout() {
+ return R.layout.single_container_layout;
+ }
+
+ @Override protected boolean isTransparent() {
+ return false;
+ }
+
+ @Override protected boolean canBack() {
+ return true;
+ }
+
+ @Override protected boolean isSecured() {
+ return false;
+ }
+
+ @NonNull @Override public TiPresenter providePresenter() {
+ return new BasePresenter();
+ }
+
+ @Override protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (savedInstanceState == null) {
+ Bundle bundle = getIntent().getExtras();
+ MilestoneView milestoneView = new MilestoneView();
+ milestoneView.setArguments(bundle);
+ getSupportFragmentManager()
+ .beginTransaction()
+ .replace(R.id.singleContainer, milestoneView, MilestoneView.TAG)
+ .commit();
+ }
+ }
+
+ @Override public void onMilestoneSelected(@NonNull MilestoneModel milestoneModel) {
+ Intent intent = new Intent();
+ intent.putExtras(Bundler.start().put(BundleConstant.ITEM, milestoneModel).end());
+ setResult(RESULT_OK, intent);
+ finish();
+ }
+}
diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/IssuePagerMvp.java b/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/IssuePagerMvp.java
index 475a9e95..3a3476ff 100644
--- a/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/IssuePagerMvp.java
+++ b/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/IssuePagerMvp.java
@@ -7,6 +7,7 @@ import android.support.annotation.Nullable;
import com.fastaccess.data.dao.IssueModel;
import com.fastaccess.data.dao.LabelModel;
+import com.fastaccess.data.dao.MilestoneModel;
import com.fastaccess.ui.base.mvp.BaseMvp;
import com.fastaccess.ui.modules.repos.labels.LabelsMvp;
@@ -28,7 +29,7 @@ interface IssuePagerMvp {
void onLabelsRetrieved(@NonNull List items);
- void onLabelsAdded();
+ void onUpdateTimeline();
void onUpdateMenu();
}
@@ -57,6 +58,8 @@ interface IssuePagerMvp {
void onLoadLabels();
+ void onPutMilestones(@NonNull MilestoneModel milestone);
+
void onPutLabels(@NonNull ArrayList labels);
String getLogin();
diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/IssuePagerPresenter.java b/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/IssuePagerPresenter.java
index 65129540..2cf15a3c 100644
--- a/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/IssuePagerPresenter.java
+++ b/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/IssuePagerPresenter.java
@@ -14,6 +14,7 @@ import com.fastaccess.data.dao.IssueRequestModel;
import com.fastaccess.data.dao.LabelListModel;
import com.fastaccess.data.dao.LabelModel;
import com.fastaccess.data.dao.LoginModel;
+import com.fastaccess.data.dao.MilestoneModel;
import com.fastaccess.data.dao.PullsIssuesParser;
import com.fastaccess.data.dao.UserModel;
import com.fastaccess.data.dao.types.IssueState;
@@ -191,12 +192,26 @@ class IssuePagerPresenter extends BasePresenter implements I
);
}
+ @Override public void onPutMilestones(@NonNull MilestoneModel milestone) {
+ issueModel.setMilestone(milestone);
+ IssueRequestModel issueRequestModel = IssueRequestModel.clone(issueModel, false);
+ makeRestCall(RestProvider.getIssueService().editIssue(login, repoId, issueNumber, issueRequestModel),
+ issue -> {
+ this.issueModel = issue;
+ issueModel.setLogin(login);
+ issueModel.setRepoId(repoId);
+ manageSubscription(issue.save().subscribe());
+ sendToView(IssuePagerMvp.View::onUpdateTimeline);
+ });
+
+ }
+
@Override public void onPutLabels(@NonNull ArrayList labels) {
makeRestCall(RestProvider.getIssueService().putLabels(login, repoId, issueNumber,
Stream.of(labels).filter(value -> value != null && value.getName() != null)
.map(LabelModel::getName).collect(Collectors.toList())),
labelModels -> {
- sendToView(IssuePagerMvp.View::onLabelsAdded);
+ sendToView(IssuePagerMvp.View::onUpdateTimeline);
LabelListModel listModel = new LabelListModel();
listModel.addAll(labels);
issueModel.setLabels(listModel);
diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/IssuePagerView.java b/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/IssuePagerView.java
index 51d5a34f..a087c2b8 100644
--- a/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/IssuePagerView.java
+++ b/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/IssuePagerView.java
@@ -16,6 +16,7 @@ import com.fastaccess.R;
import com.fastaccess.data.dao.FragmentPagerAdapterModel;
import com.fastaccess.data.dao.IssueModel;
import com.fastaccess.data.dao.LabelModel;
+import com.fastaccess.data.dao.MilestoneModel;
import com.fastaccess.data.dao.UserModel;
import com.fastaccess.data.dao.types.IssueState;
import com.fastaccess.helper.ActivityHelper;
@@ -26,6 +27,7 @@ import com.fastaccess.helper.Logger;
import com.fastaccess.helper.ParseDateFormat;
import com.fastaccess.ui.adapter.FragmentsPagerAdapter;
import com.fastaccess.ui.base.BaseActivity;
+import com.fastaccess.ui.modules.repos.extras.milestone.create.MilestoneActivityView;
import com.fastaccess.ui.modules.repos.issues.create.CreateIssueView;
import com.fastaccess.ui.modules.repos.issues.issue.details.comments.IssueCommentsView;
import com.fastaccess.ui.modules.repos.issues.issue.details.events.IssueDetailsView;
@@ -118,11 +120,17 @@ public class IssuePagerView extends BaseActivity labels);
+ void onPutMilestones(@NonNull MilestoneModel milestone);
+
String getLogin();
String getRepoId();
diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/PullRequestPagerPresenter.java b/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/PullRequestPagerPresenter.java
index 434f4e80..ff085bb0 100644
--- a/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/PullRequestPagerPresenter.java
+++ b/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/PullRequestPagerPresenter.java
@@ -15,6 +15,7 @@ import com.fastaccess.data.dao.LabelListModel;
import com.fastaccess.data.dao.LabelModel;
import com.fastaccess.data.dao.LoginModel;
import com.fastaccess.data.dao.MergeRequestModel;
+import com.fastaccess.data.dao.MilestoneModel;
import com.fastaccess.data.dao.PullRequestModel;
import com.fastaccess.data.dao.PullsIssuesParser;
import com.fastaccess.data.dao.UserModel;
@@ -195,7 +196,7 @@ class PullRequestPagerPresenter extends BasePresenter
Stream.of(labels).filter(value -> value != null && value.getName() != null)
.map(LabelModel::getName).collect(Collectors.toList())),
labelModels -> {
- sendToView(PullRequestPagerMvp.View::onLabelsAdded);
+ sendToView(PullRequestPagerMvp.View::onUpdateTimeline);
LabelListModel listModel = new LabelListModel();
listModel.addAll(labels);
pullRequest.setLabels(listModel);
@@ -203,8 +204,22 @@ class PullRequestPagerPresenter extends BasePresenter
});
}
+ @Override public void onPutMilestones(@NonNull MilestoneModel milestone) {
+ pullRequest.setMilestone(milestone);
+ IssueRequestModel issueRequestModel = IssueRequestModel.clone(pullRequest, false);
+ makeRestCall(RestProvider.getPullRequestSerice().editIssue(login, repoId, issueNumber, issueRequestModel),
+ pr -> {
+ this.pullRequest = pr;
+ pullRequest.setLogin(login);
+ pullRequest.setRepoId(repoId);
+ manageSubscription(pr.save().subscribe());
+ sendToView(PullRequestPagerMvp.View::onUpdateTimeline);
+ });
+
+ }
+
@Override public void onMerge() {
- if (isMergeable() && (isOwner() || isRepoOwner())) {//double the checking
+ if (isMergeable() && (isCollaborator() || isRepoOwner())) {//double the checking
MergeRequestModel mergeRequestModel = new MergeRequestModel();
// mergeRequestModel.setBase(String.valueOf(getPullRequest().getBase().getId()));
// mergeRequestModel.setHead(String.valueOf(getPullRequest().getHead().getId()));
diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/PullRequestPagerView.java b/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/PullRequestPagerView.java
index 59b81501..4c8b8605 100644
--- a/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/PullRequestPagerView.java
+++ b/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/PullRequestPagerView.java
@@ -14,8 +14,8 @@ import android.view.View;
import com.fastaccess.R;
import com.fastaccess.data.dao.FragmentPagerAdapterModel;
-import com.fastaccess.data.dao.IssueModel;
import com.fastaccess.data.dao.LabelModel;
+import com.fastaccess.data.dao.MilestoneModel;
import com.fastaccess.data.dao.PullRequestModel;
import com.fastaccess.data.dao.UserModel;
import com.fastaccess.data.dao.types.IssueState;
@@ -26,6 +26,7 @@ import com.fastaccess.helper.InputHelper;
import com.fastaccess.helper.Logger;
import com.fastaccess.ui.adapter.FragmentsPagerAdapter;
import com.fastaccess.ui.base.BaseActivity;
+import com.fastaccess.ui.modules.repos.extras.milestone.create.MilestoneActivityView;
import com.fastaccess.ui.modules.repos.issues.create.CreateIssueView;
import com.fastaccess.ui.modules.repos.issues.issue.details.comments.IssueCommentsView;
import com.fastaccess.ui.modules.repos.labels.LabelsView;
@@ -116,11 +117,17 @@ public class PullRequestPagerView extends BaseActivity extends BaseDialogFragment implements BaseViewHolder.OnItemClickListener {
+ public static final String TAG = ListDialogView.class.getSimpleName();
+
@BindView(R.id.title) FontTextView title;
@BindView(R.id.recycler) DynamicRecyclerView recycler;
@@ -89,4 +92,11 @@ public class ListDialogView extends BaseDialogFragment imp
.putParcelableArrayList(BundleConstant.ITEM, objects)
.end());
}
+
+ public void initArguments(@NonNull String title, @NonNull List objects) {
+ setArguments(Bundler.start()
+ .put(BundleConstant.EXTRA, title)
+ .putParcelableArrayList(BundleConstant.ITEM, (ArrayList extends Parcelable>) objects)
+ .end());
+ }
}
diff --git a/app/src/main/res/layouts/main_layouts/layout-land/repo_file_header_layout.xml b/app/src/main/res/layouts/main_layouts/layout-land/repo_file_header_layout.xml
index 2fd7c299..b666eaa7 100644
--- a/app/src/main/res/layouts/main_layouts/layout-land/repo_file_header_layout.xml
+++ b/app/src/main/res/layouts/main_layouts/layout-land/repo_file_header_layout.xml
@@ -25,7 +25,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
- android:contentDescription="@string/switch_branch"
+ android:contentDescription="@string/home"
android:padding="@dimen/spacing_normal"
android:src="@drawable/ic_home"/>
diff --git a/app/src/main/res/layouts/main_layouts/layout-large/repo_file_header_layout.xml b/app/src/main/res/layouts/main_layouts/layout-large/repo_file_header_layout.xml
index 2fd7c299..b666eaa7 100644
--- a/app/src/main/res/layouts/main_layouts/layout-large/repo_file_header_layout.xml
+++ b/app/src/main/res/layouts/main_layouts/layout-large/repo_file_header_layout.xml
@@ -25,7 +25,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
- android:contentDescription="@string/switch_branch"
+ android:contentDescription="@string/home"
android:padding="@dimen/spacing_normal"
android:src="@drawable/ic_home"/>
diff --git a/app/src/main/res/layouts/main_layouts/layout/create_milestone_layout.xml b/app/src/main/res/layouts/main_layouts/layout/create_milestone_layout.xml
new file mode 100644
index 00000000..00e89992
--- /dev/null
+++ b/app/src/main/res/layouts/main_layouts/layout/create_milestone_layout.xml
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layouts/main_layouts/layout/milestone_dialog_layout.xml b/app/src/main/res/layouts/main_layouts/layout/milestone_dialog_layout.xml
new file mode 100644
index 00000000..0a2d8abf
--- /dev/null
+++ b/app/src/main/res/layouts/main_layouts/layout/milestone_dialog_layout.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layouts/main_layouts/layout/repo_file_header_layout.xml b/app/src/main/res/layouts/main_layouts/layout/repo_file_header_layout.xml
index ad5e1dea..37f525e6 100644
--- a/app/src/main/res/layouts/main_layouts/layout/repo_file_header_layout.xml
+++ b/app/src/main/res/layouts/main_layouts/layout/repo_file_header_layout.xml
@@ -23,7 +23,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
- android:contentDescription="@string/switch_branch"
+ android:contentDescription="@string/home"
android:padding="@dimen/spacing_normal"
android:src="@drawable/ic_home"/>
diff --git a/app/src/main/res/layouts/other_layouts/layout/simple_footer_list_dialog.xml b/app/src/main/res/layouts/other_layouts/layout/simple_footer_list_dialog.xml
index 1c86c82a..a20c724e 100644
--- a/app/src/main/res/layouts/other_layouts/layout/simple_footer_list_dialog.xml
+++ b/app/src/main/res/layouts/other_layouts/layout/simple_footer_list_dialog.xml
@@ -25,6 +25,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
+ android:contentDescription="@string/back"
android:foreground="?selectableItemBackgroundBorderless"
android:padding="@dimen/spacing_normal"
android:scaleType="centerCrop"
@@ -46,6 +47,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
+ android:contentDescription="@string/done"
android:foreground="?selectableItemBackgroundBorderless"
android:padding="@dimen/spacing_normal"
android:scaleType="centerCrop"
diff --git a/app/src/main/res/layouts/other_layouts/layout/single_container_layout.xml b/app/src/main/res/layouts/other_layouts/layout/single_container_layout.xml
new file mode 100644
index 00000000..a115ab83
--- /dev/null
+++ b/app/src/main/res/layouts/other_layouts/layout/single_container_layout.xml
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/add_menu.xml b/app/src/main/res/menu/add_menu.xml
new file mode 100644
index 00000000..8c0e9adf
--- /dev/null
+++ b/app/src/main/res/menu/add_menu.xml
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml
index a0482748..5c9e5510 100644
--- a/app/src/main/res/values/arrays.xml
+++ b/app/src/main/res/values/arrays.xml
@@ -6,10 +6,12 @@
+ - @string/turn_off
- @string/one_minute
- @string/five_minutes
- @string/ten_minutes
- @string/twenty_minutes
- @string/thirty_minutes
+ Turn Off
\ 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 34182ca1..5a724480 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -219,4 +219,11 @@
Edit
Update Issue
Update Pull Request
+ No Milestones
+ Add
+ Done
+ Home
+ Create Milestone
+ Error creating milestone
+ Due On
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index e63522e3..849a25e8 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -22,6 +22,7 @@
- true
- @color/transparent
- true
+ - @style/DialogTheme
+
+