Merge branch 'develop' of github.com:HabitRPG/habitrpg-android into chatrewrite

# Conflicts:
#	Habitica/res/values/strings.xml
#	Habitica/src/main/java/com/habitrpg/android/habitica/HabitDatabase.java
#	Habitica/src/main/java/com/habitrpg/android/habitica/NotificationPublisher.java
#	Habitica/src/main/java/com/habitrpg/android/habitica/models/tasks/Task.java
#	Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.java
#	Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.java
This commit is contained in:
Phillip Thelen 2017-05-09 12:29:24 +02:00
commit ba49430cd8
15 changed files with 1762 additions and 1170 deletions

View file

@ -1 +1,2 @@
ALTER TABLE Preferences ADD COLUMN dailyDueDefaultView bool;
ALTER TABLE Preferences ADD COLUMN dailyDueDefaultView bool;

View file

@ -0,0 +1 @@
ALTER TABLE Task ADD COLUMN isDue BOOLEAN;

View file

@ -33,21 +33,22 @@
android:focusable="true"
android:focusableInTouchMode="true" />
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:hintTextAppearance="@style/TextAppearance.AppCompat">
<net.pherth.android.emoji_library.EmojiEditText
android:id="@+id/task_text_edittext"
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:hint="@string/text"
android:textColor="@android:color/black"
android:inputType="textCapSentences" />
</android.support.design.widget.TextInputLayout>
</LinearLayout>
android:layout_height="match_parent"
app:hintTextAppearance="@style/TextAppearance.AppCompat">
<net.pherth.android.emoji_library.EmojiEditText
android:id="@+id/task_text_edittext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:hint="@string/text"
android:textColor="@android:color/black"
android:inputType="textCapSentences" />
</android.support.design.widget.TextInputLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="72dp"
@ -230,6 +231,7 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/frequency_title"
android:text="@string/frequency"
android:textAppearance="?android:attr/textAppearanceLarge" />
@ -256,21 +258,7 @@
android:layout_marginTop="20dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/start_date"
android:textAppearance="?android:attr/textAppearanceLarge" />
<EditText
android:id="@+id/startdate_text_edittext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:hint="@string/start_date"
android:textColor="@android:color/black"
android:focusable="false" />
<include layout="@layout/tasks_startdate" />
</LinearLayout>
@ -282,35 +270,99 @@
android:layout_marginTop="20dp"
android:orientation="vertical">
<include layout="@layout/tasks_duedate" />
</LinearLayout>
<LinearLayout
android:id="@+id/repeatables"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/frequency"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/due_date"
android:textAppearance="?android:attr/textAppearanceLarge" />
android:text="@string/start_date"
android:textAppearance="?android:attr/textAppearanceMedium" />
<LinearLayout
android:id="@+id/task_duedate_picker_layout"
<EditText
android:id="@+id/repeatables_startdate_text_edittext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal">
android:layout_gravity="center_horizontal"
android:hint="@string/start_date"
android:textColor="@android:color/black"
android:focusable="false" />
<CheckBox
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/todo_has_duedate"
android:id="@+id/duedate_checkbox" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/repeatables_title"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Spinner
android:id="@+id/task_repeatables_frequency_spinner"
android:layout_width="match_parent"
android:layout_height="72dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/repeatables_on_title"
android:id="@+id/repeatables_on_title"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Spinner
android:id="@+id/task_repeatables_on_spinner"
android:layout_width="match_parent"
android:layout_height="72dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/repeatEvery"
android:textAppearance="?android:attr/textAppearanceMedium" />
<NumberPicker
android:id="@+id/task_repeatables_every_x_spinner"
android:layout_width="match_parent"
android:layout_height="72dp" />
<LinearLayout
android:id="@+id/task_repeatables_frequency_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="@+id/duedate_text_edittext"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="4dp"
android:hint="@string/due_date"
android:textColor="@android:color/black"
android:focusable="false" />
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:id="@+id/summaryTitle"
android:text="@string/repeatables_summary_title"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:id="@+id/summary"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
<LinearLayout
@ -345,11 +397,11 @@
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="20dp"
android:id="@+id/task_tags_wrapper">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="20dp"
android:id="@+id/task_tags_wrapper">
<TextView
android:layout_width="wrap_content"

View file

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/due_date"
android:textAppearance="?android:attr/textAppearanceLarge" />
<LinearLayout
android:id="@+id/task_duedate_picker_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal">
<CheckBox
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/todo_has_duedate"
android:id="@+id/duedate_checkbox" />
<EditText
android:id="@+id/duedate_text_edittext"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="4dp"
android:hint="@string/due_date"
android:textColor="@android:color/black"
android:focusable="false" />
</LinearLayout>
</LinearLayout>

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/start_date"
android:id="@+id/startdate_text_title"
android:textAppearance="?android:attr/textAppearanceLarge" />
<EditText
android:id="@+id/startdate_text_edittext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:hint="@string/start_date"
android:textColor="@android:color/black"
android:focusable="false" />
</LinearLayout>

View file

@ -77,6 +77,9 @@
<string name="about.give_us_feedback">Send us Feedback!</string>
<string name="about.bugreport">Report a Bug</string>
<string name="about.source_code">Source Code</string>
<string name="repeatEvery">Repeat Every</string>
<!-- Network Errors -->
<string name="network_error_title">Connection Error</string>
@ -115,6 +118,17 @@
<string name="frequency">Frequency</string>
<string name="frequency_weekly">On Certain Days of the Week</string>
<string name="frequency_daily">Every X Days</string>
<string name="repeatables_summary_title">Summary</string>
<string name="repeatables_title">Repeats</string>
<string name="repeatables_on_title">Repeats On</string>
<string name="repeatables_frequency_daily">Daily</string>
<string name="repeatables_frequency_weekly">Weekly</string>
<string name="repeatables_frequency_monthly">Monthly</string>
<string name="repeatables_frequency_yearly">Yearly</string>
<string name="repeatables_frequency_day_of_month">Day of Month</string>
<string name="repeatables_frequency_day_of_week">Day of Week</string>
<string name="monday">Monday</string>
<string name="tuesday">Tuesday</string>
@ -569,6 +583,8 @@
<string name="reload_content">Reload Content</string>
<string name="dailyDueDefaultView">Set Dailies default to due tab</string>
<string name="dailyDueDefaultViewDescription">With this option set, the Dailies tasks will default to due instead of all</string>
<string name="repeat_summary">"Repeats %1$s every %2$s %3$s %4$s"</string>
<string name="no_billing_gems">Your device does not have any of the supported payment methods. Please use the habitica website if you want to purchase gems.</string>
<string name="no_billing_subscriptions">Your device does not have any of the supported payment methods. Please use the habitica website if you want to purchase a subscription.</string>
<string name="save">Save</string>

View file

@ -19,6 +19,18 @@
<item>@string/frequency_daily</item>
</string-array>
<string-array name="repeatables_frequencies">
<item>@string/repeatables_frequency_daily</item>
<item>@string/repeatables_frequency_weekly</item>
<item>@string/repeatables_frequency_monthly</item>
<item>@string/repeatables_frequency_yearly</item>
</string-array>
<string-array name="repeatables_on">
<item>@string/repeatables_frequency_day_of_month</item>
<item>@string/repeatables_frequency_day_of_week</item>
</string-array>
<string-array name="weekdays">
<item>@string/monday</item>
<item>@string/tuesday</item>

View file

@ -46,7 +46,7 @@ public class NotificationPublisher extends BroadcastReceiver {
taskRepository.getTasks(Task.TYPE_DAILY, userId).subscribe(dailies -> {
boolean showNotifications = false;
for (Task task : dailies) {
if (task.isDue(0)) {
if (task.checkIfDue(0)) {
showNotifications = true;
break;
}
@ -100,4 +100,4 @@ public class NotificationPublisher extends BroadcastReceiver {
notification.flags |= Notification.FLAG_AUTO_CANCEL | Notification.FLAG_SHOW_LIGHTS;
return notification;
}
}
}

View file

@ -0,0 +1,136 @@
package com.habitrpg.android.habitica.helpers;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Environment;
import android.support.v7.preference.PreferenceManager;
import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import bolts.Bolts;
/**
* Created by keith holliday on 4/7/2017.
*/
public class RemoteConfigManager {
private Context context;
private Boolean enableRepeatbles = false;
private String REMOTE_STRING_KEY = "remote-string";
public RemoteConfigManager(Context context) {
this.context = context;
loadFromPreferences();
new DownloadFileFromURL().execute("https://s3.amazonaws.com/habitica-assets/mobileApp/endpoint/config-android.json");
}
public Boolean repeatablesAreEnabled () {
return enableRepeatbles;
}
private void loadFromPreferences () {
String storedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
.getString(REMOTE_STRING_KEY, "");
if (storedPreferences.isEmpty()) {
return;
}
try {
JSONObject obj = new JSONObject(storedPreferences);
enableRepeatbles = obj.getBoolean("enableRepeatbles");
} catch (JSONException e) {
e.printStackTrace();
}
}
class DownloadFileFromURL extends AsyncTask<String, String, String> {
private String filename = "config.json";
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(String ...fileUrl) {
int count;
try {
URL url = new URL(fileUrl[0]);
URLConnection conection = url.openConnection();
conection.connect();
int lenghtOfFile = conection.getContentLength();
InputStream input = new BufferedInputStream(url.openStream(),
8192);
OutputStream output = context.openFileOutput(filename, Context.MODE_PRIVATE);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress("" + (int) ((total * 100) / lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String file_url) {
File file = new File(context.getFilesDir(), filename);
StringBuilder text = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
text.append('\n');
}
br.close();
}
catch (IOException e) {
e.printStackTrace();
}
PreferenceManager.getDefaultSharedPreferences(context)
.edit().putString(REMOTE_STRING_KEY, text.toString()).apply();
try {
JSONObject obj = new JSONObject(text.toString());
enableRepeatbles = obj.getBoolean("enableRepeatbles");
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}

View file

@ -74,6 +74,16 @@ public class Task extends RealmObject implements Parcelable {
@SerializedName("_id")
String id;
public Boolean isDue;
// These do need to be local columns because all logic is stored in
// is due for now
@Ignore
public List<Integer> daysOfMonth = new ArrayList<>();
@Ignore
public List<Integer> weeksOfMonth = new ArrayList<>();
/**
* @return the id
*/
@ -430,7 +440,7 @@ public class Task extends RealmObject implements Parcelable {
return R.color.best_10;
}
public Boolean isDue(int offset) {
public Boolean checkIfDue(int offset) {
if (this.getCompleted()) {
return true;
}
@ -470,7 +480,10 @@ public class Task extends RealmObject implements Parcelable {
}
public Boolean isDisplayedActive(int offset) {
return this.isDue(offset) && !this.completed;
if (this.isDue != null && !this.completed) {
return this.isDue;
}
return this.checkIfDue(offset) && !this.completed;
}
public Boolean isChecklistDisplayActive(int offset) {

View file

@ -12,6 +12,7 @@ import com.habitrpg.android.habitica.executors.JobExecutor;
import com.habitrpg.android.habitica.executors.PostExecutionThread;
import com.habitrpg.android.habitica.executors.ThreadExecutor;
import com.habitrpg.android.habitica.executors.UIThread;
import com.habitrpg.android.habitica.helpers.RemoteConfigManager;
import com.habitrpg.android.habitica.helpers.SoundFileLoader;
import com.habitrpg.android.habitica.helpers.SoundManager;
import com.habitrpg.android.habitica.helpers.TaskAlarmManager;
@ -100,4 +101,10 @@ public class AppModule {
PushNotificationManager pushNotificationManager(ApiClient apiClient, SharedPreferences sharedPreferences, Context context) {
return new PushNotificationManager(apiClient, sharedPreferences, context);
}
@Provides
@Singleton
RemoteConfigManager providesRemoteConfiigManager(Context context) {
return new RemoteConfigManager(context);
}
}

View file

@ -62,6 +62,7 @@ import com.habitrpg.android.habitica.events.commands.OpenMenuItemCommand;
import com.habitrpg.android.habitica.events.commands.TaskCheckedCommand;
import com.habitrpg.android.habitica.helpers.AmplitudeManager;
import com.habitrpg.android.habitica.helpers.LanguageHelper;
import com.habitrpg.android.habitica.helpers.RemoteConfigManager;
import com.habitrpg.android.habitica.helpers.RxErrorHandler;
import com.habitrpg.android.habitica.helpers.SoundManager;
import com.habitrpg.android.habitica.helpers.TaskAlarmManager;
@ -198,6 +199,8 @@ public class MainActivity extends BaseActivity implements TutorialView.OnTutoria
@Inject
TaskAlarmManager taskAlarmManager;
@Inject
RemoteConfigManager remoteConfigManager;
// endregion

View file

@ -5,7 +5,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.2'
classpath 'com.android.tools.build:gradle:2.3.1'
classpath 'com.android.databinding:dataBinder:1.0-rc4'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
classpath 'com.google.gms:google-services:3.0.0'

3
gradle.properties Normal file
View file

@ -0,0 +1,3 @@
org.gradle.configureondemand=true
org.gradle.daemon=true
org.gradle.jvmargs=-Xmx2048m