diff --git a/Habitica/build.gradle b/Habitica/build.gradle
index 1a361209b..b29275a22 100644
--- a/Habitica/build.gradle
+++ b/Habitica/build.gradle
@@ -118,6 +118,7 @@ dependencies {
//Push Notifications
implementation 'com.google.firebase:firebase-core:16.0.7'
implementation 'com.google.firebase:firebase-messaging:17.4.0'
+ implementation 'com.google.firebase:firebase-config:16.3.0'
implementation 'com.google.android.gms:play-services-auth:16.0.1'
implementation 'io.realm:android-adapters:3.1.0'
implementation(project(':seeds-sdk')) {
@@ -147,7 +148,7 @@ android {
buildConfigField "String", "STORE", "\"google\""
multiDexEnabled true
- versionCode 2067
+ versionCode 2068
versionName "1.8"
}
diff --git a/Habitica/res/xml/remote_config_defaults.xml b/Habitica/res/xml/remote_config_defaults.xml
new file mode 100644
index 000000000..1788d298b
--- /dev/null
+++ b/Habitica/res/xml/remote_config_defaults.xml
@@ -0,0 +1,20 @@
+
+
+
+
+ maxChatLength
+ 3000
+
+
+ enableGiftOneGetOne
+ false
+
+
+ shopSpriteSuffix
+
+
+ spriteSubstitutions
+ {}
+
+
+
\ No newline at end of file
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/HabiticaBaseApplication.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/HabiticaBaseApplication.kt
index 97fa85347..df79bc2a2 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/HabiticaBaseApplication.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/HabiticaBaseApplication.kt
@@ -17,6 +17,8 @@ import com.amplitude.api.Amplitude
import com.amplitude.api.Identify
import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.imagepipeline.core.ImagePipelineConfig
+import com.google.firebase.remoteconfig.FirebaseRemoteConfig
+import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings
import com.habitrpg.android.habitica.api.HostConfig
import com.habitrpg.android.habitica.components.AppComponent
import com.habitrpg.android.habitica.data.ApiClient
@@ -79,6 +81,7 @@ abstract class HabiticaBaseApplication : MultiDexApplication() {
}
setupRealm()
setupDagger()
+ setupRemoteConfig()
refWatcher = LeakCanary.install(this)
setupInstabug()
createBillingAndCheckout()
@@ -200,6 +203,19 @@ abstract class HabiticaBaseApplication : MultiDexApplication() {
billing.notNull { checkout = Checkout.forApplication(it) }
}
+ private fun setupRemoteConfig() {
+ val remoteConfig = FirebaseRemoteConfig.getInstance()
+ val configSettings = FirebaseRemoteConfigSettings.Builder()
+ .setDeveloperModeEnabled(BuildConfig.DEBUG)
+ .build()
+ remoteConfig.setConfigSettings(configSettings)
+ remoteConfig.setDefaults(R.xml.remote_config_defaults)
+ remoteConfig.fetch(if (BuildConfig.DEBUG) 0 else 3600)
+ .addOnCompleteListener {
+ remoteConfig.activateFetched()
+ }
+ }
+
companion object {
var component: AppComponent? = null
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/RemoteConfigManager.java b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/RemoteConfigManager.java
deleted file mode 100644
index 7329ff2b9..000000000
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/RemoteConfigManager.java
+++ /dev/null
@@ -1,155 +0,0 @@
-package com.habitrpg.android.habitica.helpers;
-
-import android.content.Context;
-import android.os.AsyncTask;
-import androidx.preference.PreferenceManager;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.URL;
-import java.net.URLConnection;
-
-public class RemoteConfigManager {
-
- private Context context;
- private Boolean enableRepeatbles = false;
- private Boolean enableNewShops = false;
- private String shopSpriteSuffix = "";
- private Integer maxChatLength = 3000;
- private Boolean enableGiftOneGetOne = 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;
- }
-
- public Boolean newShopsEnabled() {
- return enableNewShops;
- }
-
- public String shopSpriteSuffix() {
- return shopSpriteSuffix;
- }
-
- public Integer maxChatLength() { return maxChatLength; }
-
- public boolean enableGiftOneGetOne() { return enableGiftOneGetOne; }
-
- private void loadFromPreferences () {
- String storedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
- .getString(REMOTE_STRING_KEY, "");
-
- if (storedPreferences.isEmpty()) {
- return;
- }
-
- parseConfig(storedPreferences);
- }
-
- private void parseConfig(String jsonString) {
- try {
- JSONObject obj = new JSONObject(jsonString);
- enableRepeatbles = obj.getBoolean("enableRepeatables");
- if (obj.has("enableNewShops")) {
- enableNewShops = obj.getBoolean("enableNewShops");
- }
- if (obj.has("shopSpriteSuffix")) {
- shopSpriteSuffix = obj.getString("shopSpriteSuffix");
- }
- if (obj.has("maxChatLength")) {
- maxChatLength = obj.getInt("maxChatLength");
- }
- if (obj.has("enableGiftOneGetOne")) {
- enableGiftOneGetOne = obj.getBoolean("enableGiftOneGetOne");
- }
- } catch (JSONException e) {
- e.printStackTrace();
- }
- }
-
-
- private class DownloadFileFromURL extends AsyncTask {
- 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();
-
- parseConfig(text.toString());
- }
-
- }
-}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/RemoteConfigManager.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/RemoteConfigManager.kt
new file mode 100644
index 000000000..a1b6b2713
--- /dev/null
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/RemoteConfigManager.kt
@@ -0,0 +1,45 @@
+package com.habitrpg.android.habitica.helpers
+
+import android.content.Context
+import android.os.AsyncTask
+import androidx.preference.PreferenceManager
+import com.google.firebase.remoteconfig.FirebaseRemoteConfig
+import com.google.gson.Gson
+import com.google.gson.JsonObject
+import com.google.gson.reflect.TypeToken
+import okhttp3.OkHttpClient
+import okhttp3.Request
+
+import org.json.JSONException
+import org.json.JSONObject
+import java.io.*
+
+class RemoteConfigManager {
+
+ private val remoteConfig = FirebaseRemoteConfig.getInstance()
+
+ fun repeatablesAreEnabled(): Boolean {
+ return true
+ }
+
+ fun newShopsEnabled(): Boolean {
+ return true
+ }
+
+ fun shopSpriteSuffix(): String {
+ return remoteConfig.getString("shopSpriteSuffix")
+ }
+
+ fun maxChatLength(): Long {
+ return remoteConfig.getLong("maxChatLength")
+ }
+
+ fun enableGiftOneGetOne(): Boolean {
+ return remoteConfig.getBoolean("enableGiftOneGetOne")
+ }
+
+ fun spriteSubstitutions(): Map> {
+ val type = object : TypeToken