diff --git a/Habitica/build.gradle b/Habitica/build.gradle index db0f4deb2..1afb2b14a 100644 --- a/Habitica/build.gradle +++ b/Habitica/build.gradle @@ -148,7 +148,7 @@ android { buildConfigField "String", "STORE", "\"google\"" multiDexEnabled true - versionCode 2046 + versionCode 2051 versionName "1.7" } @@ -175,7 +175,7 @@ android { } release { signingConfig signingConfigs.release - debuggable true + debuggable false multiDexEnabled true minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' diff --git a/Habitica/res/layout/drawer_main.xml b/Habitica/res/layout/drawer_main.xml index 776615b41..f0d4f450e 100644 --- a/Habitica/res/layout/drawer_main.xml +++ b/Habitica/res/layout/drawer_main.xml @@ -61,13 +61,14 @@ android:layout_width="45dp" android:layout_height="match_parent" android:layout_marginLeft="16dp"> - + android:layout_centerVertical="true" + android:clickable="false" /> - pendingGifts = new HashMap<>(); private static final String PURCHASED_PRODUCTS_KEY = "PURCHASED_PRODUCTS"; + private static final String PENDING_GIFTS_KEY = "PENDING_GIFTS"; private final ApiClient apiClient; private Set purchasedOrderList = new HashSet<>(); + public static Map pendingGifts = new HashMap<>(); private SharedPreferences preferences; public HabiticaPurchaseVerifier(Context context, ApiClient apiClient) { preferences = PreferenceManager.getDefaultSharedPreferences(context); preferences.getStringSet(PURCHASED_PRODUCTS_KEY, purchasedOrderList); + pendingGifts = loadPendingGifts(); this.apiClient = apiClient; } @@ -173,5 +177,33 @@ public class HabiticaPurchaseVerifier extends BasePurchaseVerifier { SharedPreferences.Editor edit = preferences.edit(); edit.putStringSet(PURCHASED_PRODUCTS_KEY, purchasedOrderList); edit.apply(); + + savePendingGifts(); + } + + private void savePendingGifts(){ + JSONObject jsonObject = new JSONObject(pendingGifts); + String jsonString = jsonObject.toString(); + SharedPreferences.Editor editor = preferences.edit(); + editor.remove(PENDING_GIFTS_KEY).apply(); + editor.putString(PENDING_GIFTS_KEY, jsonString); + editor.commit(); + } + + private Map loadPendingGifts() { + Map outputMap = new HashMap<>(); + try{ + String jsonString = preferences.getString(PENDING_GIFTS_KEY, (new JSONObject()).toString()); + JSONObject jsonObject = new JSONObject(jsonString); + Iterator keysItr = jsonObject.keys(); + while(keysItr.hasNext()) { + String key = keysItr.next(); + String value = (String) jsonObject.get(key); + outputMap.put(key, value); + } + }catch(Exception e){ + e.printStackTrace(); + } + return outputMap; } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/api/HostConfig.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/api/HostConfig.kt index 093bfd7af..95c73cfed 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/api/HostConfig.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/api/HostConfig.kt @@ -16,8 +16,8 @@ import com.habitrpg.android.habitica.R class HostConfig { var address: String var port: String - var api: String? = null - var user: String? = null + var api: String + var user: String constructor(sharedPreferences: SharedPreferences, context: Context) { val prefs = PreferenceManager.getDefaultSharedPreferences(context) @@ -25,10 +25,15 @@ class HostConfig { if (BuildConfig.DEBUG) { this.address = BuildConfig.BASE_URL } else { - this.address = sharedPreferences.getString("server_url", null) ?: context.getString(R.string.base_url) + val address = sharedPreferences.getString("server_url", null) + if (address != null && address.isNotEmpty()) { + this.address = address + } else { + this.address = context.getString(R.string.base_url) + } } - this.api = prefs.getString("APIToken", null) - this.user = prefs.getString(context.getString(R.string.SP_userID), "") + this.api = prefs.getString("APIToken", null) ?: "" + this.user = prefs.getString(context.getString(R.string.SP_userID), null) ?: "" } constructor(address: String, port: String, api: String, user: String) { @@ -39,7 +44,7 @@ class HostConfig { } fun hasAuthentication(): Boolean { - return user?.isNotEmpty() == true && api?.length ?: 0 > 0 + return user.isNotEmpty() && api.isNotEmpty() } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt index 1d14dfbd4..42598ec2b 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt @@ -111,7 +111,7 @@ class ApiClientImpl//private OnHabitsAPIResult mResultListener; .addNetworkInterceptor { chain -> val original = chain.request() var builder: Request.Builder = original.newBuilder() - if (this.hostConfig.user != null) { + if (this.hostConfig.hasAuthentication()) { builder = builder .header("x-api-key", this.hostConfig.api) .header("x-api-user", this.hostConfig.user) @@ -279,8 +279,8 @@ class ApiClientImpl//private OnHabitsAPIResult mResultListener; } override fun updateAuthenticationCredentials(userID: String?, apiToken: String?) { - this.hostConfig.user = userID - this.hostConfig.api = apiToken + this.hostConfig.user = userID ?: "" + this.hostConfig.api = apiToken ?: "" crashlyticsProxy.setUserIdentifier(this.hostConfig.user) crashlyticsProxy.setUserName(this.hostConfig.user) Amplitude.getInstance().userId = this.hostConfig.user diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GemPurchaseActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GemPurchaseActivity.kt index 2a939080f..c71cbcc39 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GemPurchaseActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GemPurchaseActivity.kt @@ -60,8 +60,6 @@ class GemPurchaseActivity : BaseActivity(), InAppMessageListener { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setupCheckout() - Seeds.sharedInstance() .simpleInit(this, this, "https://dash.playseeds.com", getString(R.string.seeds_app_key)).isLoggingEnabled = true Seeds.sharedInstance().requestInAppMessage(getString(R.string.seeds_interstitial_gems)) @@ -78,11 +76,30 @@ class GemPurchaseActivity : BaseActivity(), InAppMessageListener { setViewPagerAdapter() + compositeSubscription.add(userRepository.getUser().subscribe(Consumer { user -> + for (test in user.abTests ?: emptyList()) { + if (test.name == "subscriptionPageOrder") { + if (test.group == "subscriptionFirst") { + showSubscriptionPageFirst = true + viewPager.adapter?.notifyDataSetChanged() + return@Consumer + } + } + } + showSubscriptionPageFirst = false + viewPager.adapter?.notifyDataSetChanged() + }, RxErrorHandler.handleEmptyError())) + } + + override fun onResume() { + super.onResume() + setupCheckout() + activityCheckout?.destroyPurchaseFlow() activityCheckout?.createPurchaseFlow(object : RequestListener { override fun onSuccess(purchase: Purchase) { - if (PurchaseTypes.allGemTypes.contains(purchase.sku)) { + if (PurchaseTypes.allGemTypes.contains(purchase.sku) || PurchaseTypes.allSubscriptionNoRenewTypes.contains(purchase.sku)) { billingRequests?.consume(purchase.token, object : RequestListener { override fun onSuccess(o: Any) { //EventBus.getDefault().post(new BoughtGemsEvent(GEMS_TO_ADD)); @@ -121,25 +138,11 @@ class GemPurchaseActivity : BaseActivity(), InAppMessageListener { override fun onReady(billingRequests: BillingRequests, s: String, b: Boolean) {} }) - - compositeSubscription.add(userRepository.getUser().subscribe(Consumer { user -> - for (test in user.abTests ?: emptyList()) { - if (test.name == "subscriptionPageOrder") { - if (test.group == "subscriptionFirst") { - showSubscriptionPageFirst = true - viewPager.adapter?.notifyDataSetChanged() - return@Consumer - } - } - } - showSubscriptionPageFirst = false - viewPager.adapter?.notifyDataSetChanged() - }, RxErrorHandler.handleEmptyError())) } - public override fun onDestroy() { + public override fun onPause() { activityCheckout?.stop() - super.onDestroy() + super.onPause() } override fun onOptionsItemSelected(item: MenuItem): Boolean { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftIAPActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftIAPActivity.kt index b2b99b516..7badf3b47 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftIAPActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftIAPActivity.kt @@ -27,6 +27,9 @@ import com.habitrpg.android.habitica.ui.views.subscriptions.SubscriptionOptionVi import io.reactivex.functions.Consumer import org.solovyev.android.checkout.* import javax.inject.Inject +import android.content.Intent + + class GiftIAPActivity: BaseActivity() { @@ -95,6 +98,10 @@ class GiftIAPActivity: BaseActivity() { usernameTextView.text = "@${it.username}" giftedUserID = it.id }, RxErrorHandler.handleEmptyError())) + } + + override fun onResume() { + super.onResume() setupCheckout() @@ -105,6 +112,7 @@ class GiftIAPActivity: BaseActivity() { if (PurchaseTypes.allSubscriptionNoRenewTypes.contains(purchase.sku)) { billingRequests?.consume(purchase.token, object : RequestListener { override fun onSuccess(o: Any) { + finish() } override fun onError(i: Int, e: Exception) { @@ -128,19 +136,24 @@ class GiftIAPActivity: BaseActivity() { override fun onReady(billingRequests: BillingRequests, s: String, b: Boolean) {} }) + this.subscription1MonthView?.setOnPurchaseClickListener(View.OnClickListener { selectSubscription(PurchaseTypes.Subscription1MonthNoRenew) }) + this.subscription3MonthView?.setOnPurchaseClickListener(View.OnClickListener { selectSubscription(PurchaseTypes.Subscription3MonthNoRenew) }) + this.subscription6MonthView?.setOnPurchaseClickListener(View.OnClickListener { selectSubscription(PurchaseTypes.Subscription6MonthNoRenew) }) + this.subscription12MonthView?.setOnPurchaseClickListener(View.OnClickListener { selectSubscription(PurchaseTypes.Subscription12MonthNoRenew) }) } - override fun onCreateView(name: String?, context: Context?, attrs: AttributeSet?): View? { - val view = super.onCreateView(name, context, attrs) - - this.subscription1MonthView?.setOnPurchaseClickListener(View.OnClickListener { selectSubscription(PurchaseTypes.Subscription1Month) }) - this.subscription3MonthView?.setOnPurchaseClickListener(View.OnClickListener { selectSubscription(PurchaseTypes.Subscription3Month) }) - this.subscription6MonthView?.setOnPurchaseClickListener(View.OnClickListener { selectSubscription(PurchaseTypes.Subscription6Month) }) - this.subscription12MonthView?.setOnPurchaseClickListener(View.OnClickListener { selectSubscription(PurchaseTypes.Subscription12Month) }) - - return view + override fun onPause() { + activityCheckout?.stop() + super.onPause() } + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + activityCheckout?.onActivityResult(requestCode, resultCode, data) + + } + + private fun updateButtonLabel(sku: Sku, price: String, subscriptions: Inventory.Product) { val matchingView = buttonForSku(sku) if (matchingView != null) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/AboutFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/AboutFragment.kt index cbbcdd1eb..31422e776 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/AboutFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/AboutFragment.kt @@ -6,22 +6,23 @@ import android.net.Uri import android.os.Build import android.os.Bundle import android.view.Gravity -import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.view.animation.AccelerateInterpolator import android.widget.Toast import androidx.core.net.toUri import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.components.AppComponent import com.habitrpg.android.habitica.extensions.notNull import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils import com.plattysoft.leonids.ParticleSystem import kotlinx.android.synthetic.main.fragment_about.* -import android.view.animation.AccelerateInterpolator - -class AboutFragment : Fragment() { +class AboutFragment : BaseMainFragment() { + override fun injectFragment(component: AppComponent) { + } internal var userId = "" private val androidSourceCodeLink = "https://github.com/HabitRPG/habitrpg-android/" diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxMessageListFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxMessageListFragment.kt index 96b3f677b..e227ee9c7 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxMessageListFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxMessageListFragment.kt @@ -137,7 +137,7 @@ class InboxMessageListFragment : BaseMainFragment(), androidx.swiperefreshlayout } } - fun setReceivingUser(chatRoomUser: String, replyToUserUUID: String) { + private fun setReceivingUser(chatRoomUser: String, replyToUserUUID: String) { this.chatRoomUser = chatRoomUser this.replyToUserUUID = replyToUserUUID } @@ -179,4 +179,8 @@ class InboxMessageListFragment : BaseMainFragment(), androidx.swiperefreshlayout .setNegativeButton(android.R.string.no, null).show() } } + + override fun customTitle(): String { + return chatRoomUser ?: "" + } }