diff --git a/Habitica/res/layout/activity_task_form.xml b/Habitica/res/layout/activity_task_form.xml
index a68c12a43..6ab5c2fcc 100644
--- a/Habitica/res/layout/activity_task_form.xml
+++ b/Habitica/res/layout/activity_task_form.xml
@@ -231,6 +231,7 @@
@@ -257,21 +258,7 @@
android:layout_marginTop="20dp"
android:orientation="vertical">
-
-
-
+
@@ -294,7 +281,34 @@
android:layout_marginTop="20dp"
android:orientation="vertical">
-
+
+
+
+
+
+
+
+ android:text="@string/repeatables_on_title"
+ android:id="@+id/repeatables_on_title"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+
+
+
@@ -325,8 +352,16 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
- android:is="@id+/summary"
- android:textAppearance="?android:attr/textAppearanceLarge" />
+ android:id="@+id/summaryTitle"
+ android:text="@string/repeatables_summary_title"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+
diff --git a/Habitica/res/layout/tasks_startdate.xml b/Habitica/res/layout/tasks_startdate.xml
new file mode 100644
index 000000000..7423d86e6
--- /dev/null
+++ b/Habitica/res/layout/tasks_startdate.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Habitica/res/values/strings.xml b/Habitica/res/values/strings.xml
index 31943442f..86d49d168 100644
--- a/Habitica/res/values/strings.xml
+++ b/Habitica/res/values/strings.xml
@@ -118,6 +118,16 @@
On Certain Days of the Week
Every X Days
+ Summary
+ Repeats
+ Repeats On
+ Daily
+ Weekly
+ Monthly
+ Yearly
+ Day of Month
+ Day of Week
+
Monday
Tuesday
Wednesday
diff --git a/Habitica/res/values/values.xml b/Habitica/res/values/values.xml
index 5b9a18efe..8619ffcc2 100644
--- a/Habitica/res/values/values.xml
+++ b/Habitica/res/values/values.xml
@@ -19,6 +19,18 @@
- @string/frequency_daily
+
+ - @string/repeatables_frequency_daily
+ - @string/repeatables_frequency_weekly
+ - @string/repeatables_frequency_monthly
+ - @string/repeatables_frequency_yearly
+
+
+
+ - @string/repeatables_frequency_day_of_month
+ - @string/repeatables_frequency_day_of_week
+
+
- @string/monday
- @string/tuesday
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.java
index 3fa63ec30..6afdaec17 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.java
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.java
@@ -1,10 +1,35 @@
package com.habitrpg.android.habitica.ui.activities;
+
+import com.habitrpg.android.habitica.R;
+import com.habitrpg.android.habitica.components.AppComponent;
+import com.habitrpg.android.habitica.events.TaskSaveEvent;
+import com.habitrpg.android.habitica.events.commands.DeleteTaskCommand;
+import com.habitrpg.android.habitica.helpers.FirstDayOfTheWeekHelper;
+import com.habitrpg.android.habitica.helpers.RemindersManager;
+import com.habitrpg.android.habitica.helpers.RemoteConfigManager;
+import com.habitrpg.android.habitica.helpers.TaskFilterHelper;
+import com.habitrpg.android.habitica.helpers.TaskAlarmManager;
+import com.habitrpg.android.habitica.ui.WrapContentRecyclerViewLayoutManager;
+import com.habitrpg.android.habitica.ui.adapter.tasks.CheckListAdapter;
+import com.habitrpg.android.habitica.ui.adapter.tasks.RemindersAdapter;
+import com.habitrpg.android.habitica.ui.helpers.MarkdownParser;
+import com.habitrpg.android.habitica.ui.helpers.SimpleItemTouchHelperCallback;
+import com.habitrpg.android.habitica.ui.helpers.ViewHelper;
+import com.raizlabs.android.dbflow.sql.builder.Condition;
+import com.raizlabs.android.dbflow.sql.language.Select;
+
+import net.pherth.android.emoji_library.EmojiEditText;
+import net.pherth.android.emoji_library.EmojiPopup;
+
+import org.greenrobot.eventbus.EventBus;
+
import android.app.DatePickerDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
@@ -17,10 +42,12 @@ import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.text.TextUtils;
+import android.util.TypedValue;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
+import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
@@ -28,9 +55,11 @@ import android.widget.Button;
import android.widget.CheckBox;
import android.widget.DatePicker;
import android.widget.EditText;
+import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.NumberPicker;
+import android.widget.RelativeLayout;
import android.widget.Spinner;
import android.widget.TableRow;
import android.widget.TextView;
@@ -138,6 +167,9 @@ public class TaskFormActivity extends BaseActivity implements AdapterView.OnItem
@BindView(R.id.task_weekdays_wrapper)
LinearLayout weekdayWrapper;
+ @BindView(R.id.frequency_title)
+ TextView frequencyTitleTextView;
+
@BindView(R.id.task_frequency_spinner)
Spinner dailyFrequencySpinner;
@@ -178,10 +210,31 @@ public class TaskFormActivity extends BaseActivity implements AdapterView.OnItem
@BindView(R.id.duedate_checkbox)
CheckBox dueDateCheckBox;
+ @BindView(R.id.startdate_text_title)
+ TextView startDateTitleTextView;
@BindView(R.id.startdate_text_edittext)
EditText startDatePickerText;
+ @BindView (R.id.repeatables_startdate_text_edittext)
+ EditText repeatablesStartDatePickerText;
DateEditTextListener startDateListener;
+ @BindView(R.id.repeatables)
+ LinearLayout repeatablesLayout;
+
+ @BindView(R.id.repeatables_on_title)
+ TextView reapeatablesOnTextView;
+ @BindView(R.id.task_repeatables_on_spinner)
+ Spinner repeatablesOnSpinner;
+
+ @BindView(R.id.task_repeatables_every_x_spinner)
+ NumberPicker repeatablesEveryXSpinner;
+
+ @BindView(R.id.task_repeatables_frequency_container)
+ LinearLayout repeatablesFrequencyContainer;
+
+ @BindView(R.id.summary)
+ TextView summaryTextView;
+
@BindView(R.id.duedate_text_edittext)
EditText dueDatePickerText;
DateEditTextListener dueDateListener;
@@ -192,6 +245,9 @@ public class TaskFormActivity extends BaseActivity implements AdapterView.OnItem
@BindView(R.id.task_tags_checklist)
LinearLayout tagsContainerLinearLayout;
+ @BindView(R.id.task_repeatables_frequency_spinner)
+ Spinner repeatablesFrequencySpinner;
+
@Inject
TaskFilterHelper taskFilterHelper;
@@ -404,6 +460,8 @@ public class TaskFormActivity extends BaseActivity implements AdapterView.OnItem
emojiToggle2.setOnClickListener(new emojiClickListener(newCheckListEditText));
}
+ enableRepeatables();
+
Observable.defer(() -> Observable.just(new Select().from(Tag.class)
.where(Condition.column("user_id").eq(this.userId))
.queryList())
@@ -420,7 +478,170 @@ public class TaskFormActivity extends BaseActivity implements AdapterView.OnItem
);
}
+ // @TODO: abstract business logic to Presenter and only modify view?
+ private void enableRepeatables()
+ {
+ if (!RemoteConfigManager.repeatablesAreEnabled()){
+ return;
+ }
+ if (!taskType.equals("daily")) {
+ repeatablesLayout.setVisibility(View.INVISIBLE);
+ ViewGroup.LayoutParams repeatablesLayoutParams = repeatablesLayout.getLayoutParams();
+ repeatablesLayoutParams.height = 0;
+ repeatablesLayout.setLayoutParams(repeatablesLayoutParams);
+ return;
+ };
+
+ startDateLayout.setVisibility(View.INVISIBLE);
+
+ ViewGroup.LayoutParams startDateLayoutParams = startDateLayout.getLayoutParams();
+ startDateLayoutParams.height = 0;
+ startDateLayout.setLayoutParams(startDateLayoutParams);
+
+ ViewGroup.LayoutParams startDatePickerTextParams = startDatePickerText.getLayoutParams();
+ startDatePickerTextParams.height = 0;
+ startDatePickerText.setLayoutParams(startDatePickerTextParams);
+
+ ViewGroup.LayoutParams startDateTitleTextViewParams = startDateTitleTextView.getLayoutParams();
+ startDateTitleTextViewParams.height = 0;
+ startDateTitleTextView.setLayoutParams(startDateTitleTextViewParams);
+
+ weekdayWrapper.setVisibility(View.INVISIBLE);
+ ViewGroup.LayoutParams weekdayWrapperParams = weekdayWrapper.getLayoutParams();
+ weekdayWrapperParams.height = 0;
+ weekdayWrapper.setLayoutParams(weekdayWrapperParams);
+
+ ViewGroup.LayoutParams frequencyTitleTextViewParams = frequencyTitleTextView.getLayoutParams();
+ frequencyTitleTextViewParams.height = 0;
+ frequencyTitleTextView.setLayoutParams(frequencyTitleTextViewParams);
+
+ ViewGroup.LayoutParams dailyFrequencySpinnerParams = dailyFrequencySpinner.getLayoutParams();
+ dailyFrequencySpinnerParams.height = 0;
+ dailyFrequencySpinner.setLayoutParams(dailyFrequencySpinnerParams);
+
+ startDateListener = new DateEditTextListener(repeatablesStartDatePickerText);
+
+ ArrayAdapter frequencyAdapter = ArrayAdapter.createFromResource(this,
+ R.array.repeatables_frequencies, android.R.layout.simple_spinner_item);
+ frequencyAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ this.repeatablesFrequencySpinner.setAdapter(frequencyAdapter);
+ this.repeatablesFrequencySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ generateSummary();
+ Resources r = getResources();
+
+ // @TODO: remove magic numbers
+
+ if (position == 2) {
+ ViewGroup.LayoutParams repeatablesOnSpinnerParams = repeatablesOnSpinner.getLayoutParams();
+ repeatablesOnSpinnerParams.height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 72, r.getDisplayMetrics());
+ repeatablesOnSpinner.setLayoutParams(repeatablesOnSpinnerParams);
+
+ ViewGroup.LayoutParams repeatablesOnTitleParams = reapeatablesOnTextView.getLayoutParams();
+ repeatablesOnTitleParams.height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30, r.getDisplayMetrics());
+ reapeatablesOnTextView.setLayoutParams(repeatablesOnTitleParams);
+
+ return;
+ }
+
+ if (position == 1) {
+ ViewGroup.LayoutParams repeatablesFrequencyContainerParams = repeatablesFrequencyContainer.getLayoutParams();
+ repeatablesFrequencyContainerParams.height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 172, r.getDisplayMetrics());
+ repeatablesFrequencyContainer.setLayoutParams(repeatablesFrequencyContainerParams);
+ return;
+ }
+
+ ViewGroup.LayoutParams repeatablesOnSpinnerParams = repeatablesOnSpinner.getLayoutParams();
+ repeatablesOnSpinnerParams.height = 0;
+ repeatablesOnSpinner.setLayoutParams(repeatablesOnSpinnerParams);
+
+ ViewGroup.LayoutParams repeatablesOnTitleParams = reapeatablesOnTextView.getLayoutParams();
+ repeatablesOnTitleParams.height = 0;
+ reapeatablesOnTextView.setLayoutParams(repeatablesOnTitleParams);
+
+ ViewGroup.LayoutParams repeatablesFrequencyContainerParams = repeatablesFrequencyContainer.getLayoutParams();
+ repeatablesFrequencyContainerParams.height = 0;
+ repeatablesFrequencyContainer.setLayoutParams(repeatablesFrequencyContainerParams);
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+
+ }
+ });
+
+ ArrayAdapter repeatablesOnAdapter = ArrayAdapter.createFromResource(this,
+ R.array.repeatables_on, android.R.layout.simple_spinner_item);
+ repeatablesOnAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ this.repeatablesOnSpinner.setAdapter(repeatablesOnAdapter);
+ this.repeatablesOnSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ generateSummary();
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+
+ }
+ });
+
+ setEveryXSpinner(repeatablesEveryXSpinner);
+ repeatablesEveryXSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
+ @Override
+ public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
+ generateSummary();
+ }
+ });
+
+ String[] weekdays = getResources().getStringArray(R.array.weekdays);
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
+ String dayOfTheWeek = sharedPreferences.getString("FirstDayOfTheWeek",
+ Integer.toString(Calendar.getInstance().getFirstDayOfWeek()));
+ firstDayOfTheWeekHelper =
+ FirstDayOfTheWeekHelper.newInstance(Integer.parseInt(dayOfTheWeek));
+ ArrayList weekdaysTemp = new ArrayList<>(Arrays.asList(weekdays));
+ Collections.rotate(weekdaysTemp, firstDayOfTheWeekHelper.getDailyTaskFormOffset());
+ weekdays = weekdaysTemp.toArray(new String[1]);
+
+ for (int i = 0; i < 7; i++) {
+ View weekdayRow = getLayoutInflater().inflate(R.layout.row_checklist, repeatablesFrequencyContainer, false);
+ CheckBox checkbox = (CheckBox) weekdayRow.findViewById(R.id.checkbox);
+ checkbox.setText(weekdays[i]);
+ checkbox.setChecked(true);
+ frequencyContainer.addView(weekdayRow);
+ }
+
+ generateSummary();
+ }
+
+ private void generateSummary () {
+ String frequency = repeatablesFrequencySpinner.getSelectedItem().toString();
+ String everyX = String.valueOf(repeatablesEveryXSpinner.getValue());
+ String frequencyQualifier = "";
+
+ switch (frequency) {
+ case "Daily":
+ frequencyQualifier = "day(s)";
+ break;
+ case "Weekly":
+ frequencyQualifier = "week(s)";
+ break;
+ case "Monthly":
+ frequencyQualifier = "month(s)";
+ break;
+ case "Yearly":
+ frequencyQualifier = "year(s)";
+ break;
+ }
+
+ String weekdays = "";
+
+ String summary = "Repeats " + frequency + " every " + everyX + " " + frequencyQualifier + " on " + weekdays;
+ summaryTextView.setText(summary);
+ }
@Override
protected void injectActivity(AppComponent component) {
@@ -564,6 +785,16 @@ public class TaskFormActivity extends BaseActivity implements AdapterView.OnItem
}
}
+ private void setEveryXSpinner(NumberPicker frequencyPicker) {
+// View dayRow = getLayoutInflater().inflate(R.layout.row_number_picker, this.frequencyContainer, false);
+// frequencyPicker = (NumberPicker) dayRow.findViewById(R.id.numberPicker);
+ frequencyPicker.setMinValue(1);
+ frequencyPicker.setMaxValue(366);
+// TextView tv = (TextView) dayRow.findViewById(R.id.label);
+// tv.setText(getResources().getString(R.string.frequency_daily));
+// this.frequencyContainer.addView(dayRow);
+ }
+
private void setDailyFrequencyViews() {
this.frequencyContainer.removeAllViews();
if (this.dailyFrequencySpinner.getSelectedItemPosition() == 0) {
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 000000000..3fcfe5803
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,3 @@
+org.gradle.configureondemand=true
+org.gradle.daemon=true
+org.gradle.jvmargs=-Xmx2048m
\ No newline at end of file