mirror of
https://github.com/TwidereProject/Twidere-Android
synced 2025-02-17 04:00:48 +01:00
improved extra features dialog
This commit is contained in:
parent
9b5d0e7c64
commit
f9f058042b
@ -183,6 +183,7 @@ public interface TwidereConstants extends SharedPreferenceConstants, IntentConst
|
||||
int REQUEST_SETTINGS = 19;
|
||||
int REQUEST_OPEN_DOCUMENT = 20;
|
||||
int REQUEST_REQUEST_PERMISSIONS = 30;
|
||||
int REQUEST_PURCHASE_EXTRA_FEATURES = 41;
|
||||
|
||||
int TABLE_ID_ACCOUNTS = 1;
|
||||
int TABLE_ID_STATUSES = 12;
|
||||
|
@ -134,9 +134,9 @@ public class ParcelableStatus implements Parcelable, Comparable<ParcelableStatus
|
||||
public String in_reply_to_status_id;
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "in_reply_to_user_id", typeConverter = UserKeyConverter.class)
|
||||
@CursorField(value = Statuses.IN_REPLY_TO_USER_ID, converter = UserKeyCursorFieldConverter.class)
|
||||
@CursorField(value = Statuses.IN_REPLY_TO_USER_KEY, converter = UserKeyCursorFieldConverter.class)
|
||||
@Nullable
|
||||
public UserKey in_reply_to_user_id;
|
||||
public UserKey in_reply_to_user_key;
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "my_retweet_id")
|
||||
@CursorField(Statuses.MY_RETWEET_ID)
|
||||
@ -413,7 +413,7 @@ public class ParcelableStatus implements Parcelable, Comparable<ParcelableStatus
|
||||
", favorite_count=" + favorite_count +
|
||||
", reply_count=" + reply_count +
|
||||
", in_reply_to_status_id='" + in_reply_to_status_id + '\'' +
|
||||
", in_reply_to_user_id=" + in_reply_to_user_id +
|
||||
", in_reply_to_user_id=" + in_reply_to_user_key +
|
||||
", my_retweet_id='" + my_retweet_id + '\'' +
|
||||
", quoted_id='" + quoted_id + '\'' +
|
||||
", quoted_timestamp=" + quoted_timestamp +
|
||||
|
@ -782,7 +782,7 @@ public interface TwidereDataStore {
|
||||
|
||||
String IN_REPLY_TO_STATUS_ID = "in_reply_to_status_id";
|
||||
|
||||
String IN_REPLY_TO_USER_ID = "in_reply_to_user_id";
|
||||
String IN_REPLY_TO_USER_KEY = "in_reply_to_user_id";
|
||||
|
||||
String IN_REPLY_TO_USER_NAME = "in_reply_to_user_name";
|
||||
|
||||
|
@ -2,6 +2,7 @@ import fr.avianey.androidsvgdrawable.gradle.SvgDrawableTask
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: 'androidsvgdrawable'
|
||||
|
||||
@ -90,6 +91,7 @@ dependencies {
|
||||
kapt 'com.hannesdorfmann.parcelableplease:processor:1.0.2'
|
||||
kapt 'com.google.dagger:dagger-compiler:2.8'
|
||||
kapt 'com.github.mariotaku.ObjectCursor:processor:0.9.12'
|
||||
kapt 'nz.bradcampbell:paperparcel-compiler:2.0.0-beta2'
|
||||
|
||||
compile project(':twidere.component.common')
|
||||
compile project(':twidere.component.nyan')
|
||||
@ -177,6 +179,7 @@ dependencies {
|
||||
compile 'nl.komponents.kovenant:kovenant-android:3.3.0'
|
||||
compile 'nl.komponents.kovenant:kovenant-functional:3.3.0'
|
||||
compile 'nl.komponents.kovenant:kovenant-combine:3.3.0'
|
||||
compile 'nz.bradcampbell:paperparcel:2.0.0-beta2'
|
||||
}
|
||||
|
||||
task svgToDrawable(type: SvgDrawableTask) {
|
||||
|
@ -2,25 +2,23 @@ package org.mariotaku.twidere.util.premium
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import org.mariotaku.twidere.R
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2016/12/25.
|
||||
*/
|
||||
|
||||
class DummyExtraFeaturesService : ExtraFeaturesService() {
|
||||
override val introductionLayout: Int = R.layout.card_item_extra_features_purchase_introduction
|
||||
|
||||
override val dashboardLayouts: IntArray = throw UnsupportedOperationException()
|
||||
override fun getDashboardLayouts() = intArrayOf()
|
||||
|
||||
override fun isSupported(): Boolean = false
|
||||
|
||||
override fun isEnabled(): Boolean = false
|
||||
override fun isEnabled(feature: String): Boolean = false
|
||||
|
||||
override fun destroyPurchase(): Boolean = false
|
||||
|
||||
override fun createPurchaseIntent(context: Context): Intent = throw UnsupportedOperationException()
|
||||
override fun createPurchaseIntent(context: Context, feature: String): Intent? = null
|
||||
|
||||
override fun createRestorePurchaseIntent(context: Context): Intent? = null
|
||||
override fun createRestorePurchaseIntent(context: Context, feature: String): Intent? = null
|
||||
|
||||
}
|
||||
|
@ -1,51 +0,0 @@
|
||||
package org.mariotaku.twidere.model.premium;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2016/12/25.
|
||||
*/
|
||||
|
||||
@ParcelablePlease
|
||||
public class GooglePurchaseResult implements PurchaseResult, Parcelable {
|
||||
@Override
|
||||
public boolean isValid(Context context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean load(Context context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean save(Context context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
GooglePurchaseResultParcelablePlease.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final Creator<GooglePurchaseResult> CREATOR = new Creator<GooglePurchaseResult>() {
|
||||
public GooglePurchaseResult createFromParcel(Parcel source) {
|
||||
GooglePurchaseResult target = new GooglePurchaseResult();
|
||||
GooglePurchaseResultParcelablePlease.readFromParcel(target, source);
|
||||
return target;
|
||||
}
|
||||
|
||||
public GooglePurchaseResult[] newArray(int size) {
|
||||
return new GooglePurchaseResult[size];
|
||||
}
|
||||
};
|
||||
}
|
@ -13,23 +13,21 @@ import nl.komponents.kovenant.ui.alwaysUi
|
||||
import nl.komponents.kovenant.ui.failUi
|
||||
import nl.komponents.kovenant.ui.successUi
|
||||
import org.mariotaku.twidere.Constants
|
||||
import org.mariotaku.twidere.constant.EXTRA_CURRENCY
|
||||
import org.mariotaku.twidere.constant.EXTRA_PRICE
|
||||
import org.mariotaku.twidere.constant.IntentConstants.INTENT_PACKAGE_PREFIX
|
||||
import org.mariotaku.twidere.constant.RESULT_NOT_PURCHASED
|
||||
import org.mariotaku.twidere.constant.RESULT_SERVICE_UNAVAILABLE
|
||||
import org.mariotaku.twidere.activity.premium.AbsExtraFeaturePurchaseActivity
|
||||
import org.mariotaku.twidere.fragment.ProgressDialogFragment
|
||||
import org.mariotaku.twidere.util.premium.GooglePlayExtraFeaturesService
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2016/12/25.
|
||||
*/
|
||||
|
||||
class GooglePlayInAppPurchaseActivity : BaseActivity(), BillingProcessor.IBillingHandler {
|
||||
class GooglePlayInAppPurchaseActivity : AbsExtraFeaturePurchaseActivity(),
|
||||
BillingProcessor.IBillingHandler {
|
||||
|
||||
private lateinit var billingProcessor: BillingProcessor
|
||||
|
||||
private val productId: String get() = intent.getStringExtra(EXTRA_PRODUCT_ID)
|
||||
private val productId: String get() = GooglePlayExtraFeaturesService.getProductId(requestingFeature)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
@ -79,16 +77,14 @@ class GooglePlayInAppPurchaseActivity : BaseActivity(), BillingProcessor.IBillin
|
||||
getProductDetailsAndFinish()
|
||||
}
|
||||
else -> {
|
||||
setResult(getResultCode(billingResponse))
|
||||
finish()
|
||||
finishWithError(getResultCode(billingResponse))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handlePurchased(sku: SkuDetails, transaction: TransactionDetails) {
|
||||
val data = Intent().putExtra(EXTRA_PRICE, sku.priceValue).putExtra(EXTRA_CURRENCY, sku.currency)
|
||||
setResult(RESULT_OK, data)
|
||||
finish()
|
||||
val result = PurchaseResult(requestingFeature, sku.priceValue, sku.currency)
|
||||
finishWithResult(result)
|
||||
}
|
||||
|
||||
|
||||
@ -143,6 +139,5 @@ class GooglePlayInAppPurchaseActivity : BaseActivity(), BillingProcessor.IBillin
|
||||
private const val TAG_PURCHASE_PROCESS = "get_purchase_process"
|
||||
|
||||
const val EXTRA_PRODUCT_ID = "product_id"
|
||||
const val ACTION_RESTORE_PURCHASE = "${INTENT_PACKAGE_PREFIX}RESTORE_PURCHASE"
|
||||
}
|
||||
}
|
||||
|
@ -6,19 +6,18 @@ import com.anjlab.android.iab.v3.BillingProcessor
|
||||
import org.mariotaku.twidere.Constants.GOOGLE_PLAY_LICENCING_PUBKEY
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.activity.GooglePlayInAppPurchaseActivity
|
||||
import org.mariotaku.twidere.activity.premium.AbsExtraFeaturePurchaseActivity
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2016/12/25.
|
||||
*/
|
||||
|
||||
class GooglePlayExtraFeaturesService() : ExtraFeaturesService() {
|
||||
private val EXTRA_FEATURE_PRODUCT_ID = "twidere.extra.features"
|
||||
private val PRODUCT_ID_EXTRA_FEATURES_PACK = "twidere.extra.features"
|
||||
|
||||
private lateinit var bp: BillingProcessor
|
||||
|
||||
override val dashboardLayouts: IntArray = intArrayOf(R.layout.card_item_extra_features_sync_status)
|
||||
|
||||
override val introductionLayout: Int = R.layout.card_item_extra_features_purchase_introduction
|
||||
override fun getDashboardLayouts() = intArrayOf(R.layout.card_item_extra_features_sync_status)
|
||||
|
||||
override fun init(context: Context) {
|
||||
super.init(context)
|
||||
@ -31,26 +30,42 @@ class GooglePlayExtraFeaturesService() : ExtraFeaturesService() {
|
||||
|
||||
override fun isSupported(): Boolean = true
|
||||
|
||||
override fun isEnabled(): Boolean {
|
||||
val details = bp.getPurchaseTransactionDetails(EXTRA_FEATURE_PRODUCT_ID) ?: return false
|
||||
return bp.isValidTransactionDetails(details)
|
||||
override fun isEnabled(feature: String): Boolean {
|
||||
if (bp.hasValidTransaction(PRODUCT_ID_EXTRA_FEATURES_PACK)) return true
|
||||
val productId = getProductId(feature) ?: return false
|
||||
return bp.hasValidTransaction(productId)
|
||||
}
|
||||
|
||||
override fun destroyPurchase(): Boolean {
|
||||
return bp.consumePurchase(EXTRA_FEATURE_PRODUCT_ID)
|
||||
return bp.consumePurchase(PRODUCT_ID_EXTRA_FEATURES_PACK)
|
||||
}
|
||||
|
||||
override fun createPurchaseIntent(context: Context): Intent {
|
||||
return Intent(context, GooglePlayInAppPurchaseActivity::class.java).apply {
|
||||
putExtra(GooglePlayInAppPurchaseActivity.EXTRA_PRODUCT_ID, EXTRA_FEATURE_PRODUCT_ID)
|
||||
override fun createPurchaseIntent(context: Context, feature: String): Intent? {
|
||||
return AbsExtraFeaturePurchaseActivity.purchaseIntent(context,
|
||||
GooglePlayInAppPurchaseActivity::class.java, feature)
|
||||
}
|
||||
|
||||
override fun createRestorePurchaseIntent(context: Context, feature: String): Intent? {
|
||||
return AbsExtraFeaturePurchaseActivity.restorePurchaseIntent(context,
|
||||
GooglePlayInAppPurchaseActivity::class.java, feature)
|
||||
}
|
||||
|
||||
private fun BillingProcessor.hasValidTransaction(productId: String): Boolean {
|
||||
val details = getPurchaseTransactionDetails(productId) ?: return false
|
||||
return isValidTransactionDetails(details)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun getProductId(feature: String): String {
|
||||
return when (feature) {
|
||||
FEATURE_FEATURES_PACK -> "twidere.extra.features"
|
||||
FEATURE_SYNC_DATA -> "twidere.extra.feature.data_sync"
|
||||
FEATURE_FILTERS_IMPORT -> "twidere.extra.feature.filter_import"
|
||||
FEATURE_FILTERS_SUBSCRIPTION -> "twidere.extra.feature.filter_subscription"
|
||||
FEATURE_SCHEDULE_STATUS -> "twidere.extra.feature.schedule_status"
|
||||
else -> throw UnsupportedOperationException(feature)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun createRestorePurchaseIntent(context: Context): Intent? {
|
||||
return Intent(context, GooglePlayInAppPurchaseActivity::class.java).apply {
|
||||
action = GooglePlayInAppPurchaseActivity.ACTION_RESTORE_PURCHASE
|
||||
putExtra(GooglePlayInAppPurchaseActivity.EXTRA_PRODUCT_ID, EXTRA_FEATURE_PRODUCT_ID)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,16 +0,0 @@
|
||||
package org.mariotaku.twidere.model.premium;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2016/12/25.
|
||||
*/
|
||||
|
||||
public interface PurchaseResult extends Parcelable {
|
||||
boolean save(Context context);
|
||||
|
||||
boolean load(Context context);
|
||||
|
||||
boolean isValid(Context context);
|
||||
}
|
@ -27,12 +27,8 @@ class PremiumDashboardActivity : BaseActivity() {
|
||||
extraFeaturesService = ExtraFeaturesService.newInstance(this)
|
||||
setContentView(R.layout.activity_premium_dashboard)
|
||||
if (extraFeaturesService.isSupported()) {
|
||||
if (extraFeaturesService.isEnabled()) {
|
||||
extraFeaturesService.dashboardLayouts.forEach { layout ->
|
||||
View.inflate(this, layout, cardsContainer)
|
||||
}
|
||||
} else {
|
||||
View.inflate(this, extraFeaturesService.introductionLayout, cardsContainer)
|
||||
extraFeaturesService.getDashboardLayouts().forEach { layout ->
|
||||
View.inflate(this, layout, cardsContainer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,67 @@
|
||||
package org.mariotaku.twidere.activity.premium
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import org.mariotaku.twidere.activity.BaseActivity
|
||||
import org.mariotaku.twidere.constant.IntentConstants
|
||||
import paperparcel.PaperParcel
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2017/1/8.
|
||||
*/
|
||||
|
||||
abstract class AbsExtraFeaturePurchaseActivity : BaseActivity() {
|
||||
protected val requestingFeature: String get() = intent.getStringExtra(EXTRA_REQUESTING_FEATURE)
|
||||
|
||||
protected fun finishWithError(code: Int) {
|
||||
setResult(code)
|
||||
finish()
|
||||
}
|
||||
|
||||
protected fun finishWithResult(result: PurchaseResult) {
|
||||
setResult(RESULT_OK, Intent().putExtra(EXTRA_PURCHASE_RESULT, result))
|
||||
finish()
|
||||
}
|
||||
|
||||
@PaperParcel
|
||||
data class PurchaseResult(val feature: String, val price: Double, val currency: String) : Parcelable {
|
||||
companion object {
|
||||
@JvmField val CREATOR = PaperParcelAbsExtraFeaturePurchaseActivity_PurchaseResult.CREATOR
|
||||
}
|
||||
|
||||
override fun describeContents() = 0
|
||||
|
||||
override fun writeToParcel(dest: Parcel, flags: Int) {
|
||||
PaperParcelAbsExtraFeaturePurchaseActivity_PurchaseResult.writeToParcel(this, dest, flags)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val RESULT_SERVICE_UNAVAILABLE = 1
|
||||
const val RESULT_INTERNAL_ERROR = 6
|
||||
const val RESULT_NOT_PURCHASED = 8
|
||||
|
||||
const val EXTRA_PURCHASE_RESULT = "purchase_result"
|
||||
const val EXTRA_REQUESTING_FEATURE = "requesting_feature"
|
||||
|
||||
const val ACTION_RESTORE_PURCHASE = "${IntentConstants.INTENT_PACKAGE_PREFIX}RESTORE_PURCHASE"
|
||||
|
||||
@JvmStatic
|
||||
fun <T : AbsExtraFeaturePurchaseActivity> purchaseIntent(context: Context, cls: Class<T>, feature: String): Intent {
|
||||
val intent = Intent(context, cls)
|
||||
intent.putExtra(EXTRA_REQUESTING_FEATURE, feature)
|
||||
return intent
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun <T : AbsExtraFeaturePurchaseActivity> restorePurchaseIntent(context: Context, cls: Class<T>, feature: String): Intent {
|
||||
val intent = Intent(context, cls)
|
||||
intent.action = ACTION_RESTORE_PURCHASE
|
||||
intent.putExtra(EXTRA_REQUESTING_FEATURE, feature)
|
||||
return intent
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package org.mariotaku.twidere.constant
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2017/1/1.
|
||||
*/
|
||||
const val RESULT_SERVICE_UNAVAILABLE = 1
|
||||
const val RESULT_INTERNAL_ERROR = 6
|
||||
const val RESULT_NOT_PURCHASED = 8
|
||||
|
||||
const val EXTRA_PRICE = "price"
|
||||
const val EXTRA_CURRENCY = "currency"
|
@ -80,7 +80,9 @@ import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallb
|
||||
import org.mariotaku.twidere.view.ShapedImageView
|
||||
import java.util.*
|
||||
|
||||
class AccountsDashboardFragment : BaseSupportFragment(), LoaderCallbacks<AccountsInfo>, OnSharedPreferenceChangeListener, OnClickListener, KeyboardShortcutCallback, NavigationView.OnNavigationItemSelectedListener {
|
||||
class AccountsDashboardFragment : BaseSupportFragment(), LoaderCallbacks<AccountsInfo>,
|
||||
OnSharedPreferenceChangeListener, OnClickListener, KeyboardShortcutCallback,
|
||||
NavigationView.OnNavigationItemSelectedListener {
|
||||
|
||||
private val systemWindowsInsets = Rect()
|
||||
|
||||
@ -342,6 +344,7 @@ class AccountsDashboardFragment : BaseSupportFragment(), LoaderCallbacks<Account
|
||||
|
||||
menu.setItemAvailability(R.id.favorites, useStarsForLikes)
|
||||
menu.setItemAvailability(R.id.likes, !useStarsForLikes)
|
||||
menu.setItemAvailability(R.id.premium_features, extraFeaturesService.isSupported())
|
||||
var hasLists = false
|
||||
var hasGroups = false
|
||||
var hasPublicTimeline = false
|
||||
|
@ -27,6 +27,7 @@ import com.squareup.otto.Bus
|
||||
import org.mariotaku.twidere.fragment.iface.IBaseFragment
|
||||
import org.mariotaku.twidere.util.*
|
||||
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
|
||||
import org.mariotaku.twidere.util.premium.ExtraFeaturesService
|
||||
import javax.inject.Inject
|
||||
|
||||
open class BaseSupportFragment : Fragment(), IBaseFragment<BaseSupportFragment> {
|
||||
@ -56,6 +57,8 @@ open class BaseSupportFragment : Fragment(), IBaseFragment<BaseSupportFragment>
|
||||
lateinit var errorInfoStore: ErrorInfoStore
|
||||
@Inject
|
||||
lateinit var validator: TwidereValidator
|
||||
@Inject
|
||||
lateinit var extraFeaturesService: ExtraFeaturesService
|
||||
|
||||
private val actionHelper = IBaseFragment.ActionHelper(this)
|
||||
|
||||
@ -84,6 +87,7 @@ open class BaseSupportFragment : Fragment(), IBaseFragment<BaseSupportFragment>
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
extraFeaturesService.release()
|
||||
super.onDestroy()
|
||||
DebugModeUtils.watchReferenceLeak(this)
|
||||
}
|
||||
|
@ -2,8 +2,13 @@ package org.mariotaku.twidere.fragment
|
||||
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.FragmentManager
|
||||
import android.support.v7.app.AlertDialog
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import org.mariotaku.ktextension.Bundle
|
||||
import org.mariotaku.ktextension.set
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_REQUEST_CODE
|
||||
import org.mariotaku.twidere.model.analyzer.PurchaseConfirm
|
||||
@ -20,6 +25,9 @@ class ExtraFeaturesIntroductionDialogFragment : BaseDialogFragment() {
|
||||
|
||||
private lateinit var extraFeaturesService: ExtraFeaturesService
|
||||
|
||||
val feature: String get() = arguments.getString(EXTRA_FEATURE)
|
||||
val requestCode: Int get() = arguments.getInt(EXTRA_REQUEST_CODE, 0)
|
||||
|
||||
override fun onDestroy() {
|
||||
extraFeaturesService.release()
|
||||
super.onDestroy()
|
||||
@ -31,21 +39,13 @@ class ExtraFeaturesIntroductionDialogFragment : BaseDialogFragment() {
|
||||
builder.setTitle(R.string.title_extra_features)
|
||||
builder.setView(R.layout.dialog_extra_features_introduction)
|
||||
builder.setPositiveButton(R.string.action_purchase) { dialog, which ->
|
||||
val requestCode = arguments?.getInt(EXTRA_REQUEST_CODE) ?: 0
|
||||
val purchaseIntent = extraFeaturesService.createPurchaseIntent(context)
|
||||
if (requestCode == 0) {
|
||||
startActivity(purchaseIntent)
|
||||
} else if (parentFragment != null) {
|
||||
parentFragment.startActivityForResult(purchaseIntent, requestCode)
|
||||
} else {
|
||||
activity.startActivityForResult(purchaseIntent, requestCode)
|
||||
}
|
||||
startPurchase(feature)
|
||||
Analyzer.log(PurchaseConfirm(PurchaseFinished.NAME_EXTRA_FEATURES))
|
||||
}
|
||||
builder.setNegativeButton(R.string.action_later) { dialog, which ->
|
||||
|
||||
}
|
||||
val restorePurchaseIntent = extraFeaturesService.createRestorePurchaseIntent(context)
|
||||
val restorePurchaseIntent = extraFeaturesService.createRestorePurchaseIntent(context, feature)
|
||||
if (restorePurchaseIntent != null) {
|
||||
builder.setNeutralButton(R.string.action_restore_purchase) { dialog, which ->
|
||||
startActivity(restorePurchaseIntent)
|
||||
@ -59,10 +59,43 @@ class ExtraFeaturesIntroductionDialogFragment : BaseDialogFragment() {
|
||||
} else {
|
||||
View.GONE
|
||||
}
|
||||
val description = ExtraFeaturesService.getIntroduction(context, feature)
|
||||
val featureIcon = it.findViewById(R.id.featureIcon) as ImageView
|
||||
val featureDescription = it.findViewById(R.id.featureDescription) as TextView
|
||||
featureIcon.setImageResource(description.icon)
|
||||
featureDescription.text = description.description
|
||||
it.findViewById(R.id.buyFeaturesPack).setOnClickListener {
|
||||
startPurchase(ExtraFeaturesService.FEATURE_FEATURES_PACK)
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
if (savedInstanceState == null) {
|
||||
Analyzer.log(PurchaseIntroduction(PurchaseFinished.NAME_EXTRA_FEATURES, "introduction dialog"))
|
||||
}
|
||||
return dialog
|
||||
}
|
||||
|
||||
private fun startPurchase(feature: String) {
|
||||
val purchaseIntent = extraFeaturesService.createPurchaseIntent(context, feature)
|
||||
if (requestCode == 0) {
|
||||
startActivity(purchaseIntent)
|
||||
} else if (parentFragment != null) {
|
||||
parentFragment.startActivityForResult(purchaseIntent, requestCode)
|
||||
} else {
|
||||
activity.startActivityForResult(purchaseIntent, requestCode)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val EXTRA_FEATURE = "feature"
|
||||
fun show(fm: FragmentManager, feature: String, requestCode: Int = 0): ExtraFeaturesIntroductionDialogFragment {
|
||||
val df = ExtraFeaturesIntroductionDialogFragment()
|
||||
df.arguments = Bundle {
|
||||
this[EXTRA_FEATURE] = feature
|
||||
this[EXTRA_REQUEST_CODE] = requestCode
|
||||
}
|
||||
df.show(fm, "extra_features_introduction")
|
||||
return df
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -297,6 +297,6 @@ abstract class BaseFiltersFragment : AbsContentListViewFragment<SimpleCursorAdap
|
||||
internal const val REQUEST_ADD_USER_SELECT_ACCOUNT = 201
|
||||
internal const val REQUEST_IMPORT_BLOCKS_SELECT_ACCOUNT = 202
|
||||
internal const val REQUEST_IMPORT_MUTES_SELECT_ACCOUNT = 203
|
||||
internal const val REQUEST_PURCHASE_EXTRA_FEATURES = 211
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import org.mariotaku.kpreferences.KPreferences
|
||||
import org.mariotaku.ktextension.Bundle
|
||||
import org.mariotaku.ktextension.setItemAvailability
|
||||
import org.mariotaku.sqliteqb.library.Expression
|
||||
import org.mariotaku.twidere.R
|
||||
@ -23,7 +22,6 @@ import org.mariotaku.twidere.activity.AccountSelectorActivity
|
||||
import org.mariotaku.twidere.activity.LinkHandlerActivity
|
||||
import org.mariotaku.twidere.activity.UserListSelectorActivity
|
||||
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_HOST
|
||||
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_REQUEST_CODE
|
||||
import org.mariotaku.twidere.constant.nameFirstKey
|
||||
import org.mariotaku.twidere.fragment.ExtraFeaturesIntroductionDialogFragment
|
||||
import org.mariotaku.twidere.model.ParcelableUser
|
||||
@ -40,8 +38,6 @@ import javax.inject.Inject
|
||||
|
||||
class FilteredUsersFragment : BaseFiltersFragment() {
|
||||
|
||||
private lateinit var extraFeaturesService: ExtraFeaturesService
|
||||
|
||||
public override val contentColumns: Array<String>
|
||||
get() = TwidereDataStore.Filters.Users.COLUMNS
|
||||
|
||||
@ -50,13 +46,8 @@ class FilteredUsersFragment : BaseFiltersFragment() {
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
extraFeaturesService = ExtraFeaturesService.newInstance(context)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
extraFeaturesService.release()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
when (requestCode) {
|
||||
@ -93,7 +84,7 @@ class FilteredUsersFragment : BaseFiltersFragment() {
|
||||
}
|
||||
REQUEST_PURCHASE_EXTRA_FEATURES -> {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
Analyzer.log(PurchaseFinished.create(PurchaseFinished.NAME_EXTRA_FEATURES, data))
|
||||
Analyzer.log(PurchaseFinished.create(data!!))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -129,14 +120,12 @@ class FilteredUsersFragment : BaseFiltersFragment() {
|
||||
else -> return false
|
||||
}
|
||||
|
||||
if (!isExtraFeatures || extraFeaturesService.isEnabled()) {
|
||||
if (!isExtraFeatures || extraFeaturesService.isEnabled(ExtraFeaturesService.FEATURE_FILTERS_IMPORT)) {
|
||||
startActivityForResult(intent, requestCode)
|
||||
} else {
|
||||
val df = ExtraFeaturesIntroductionDialogFragment()
|
||||
df.arguments = Bundle {
|
||||
putInt(EXTRA_REQUEST_CODE, REQUEST_PURCHASE_EXTRA_FEATURES)
|
||||
}
|
||||
df.show(childFragmentManager, "extra_features_introduction")
|
||||
ExtraFeaturesIntroductionDialogFragment.show(childFragmentManager,
|
||||
feature = ExtraFeaturesService.FEATURE_FILTERS_IMPORT,
|
||||
requestCode = REQUEST_PURCHASE_EXTRA_FEATURES)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -1,88 +0,0 @@
|
||||
package org.mariotaku.twidere.fragment.premium
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import kotlinx.android.synthetic.main.fragment_extra_features_introduction.*
|
||||
import kotlinx.android.synthetic.main.layout_extra_features_introduction.*
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.constant.RESULT_NOT_PURCHASED
|
||||
import org.mariotaku.twidere.constant.RESULT_SERVICE_UNAVAILABLE
|
||||
import org.mariotaku.twidere.fragment.BaseSupportFragment
|
||||
import org.mariotaku.twidere.model.analyzer.PurchaseConfirm
|
||||
import org.mariotaku.twidere.model.analyzer.PurchaseFinished
|
||||
import org.mariotaku.twidere.model.analyzer.PurchaseIntroduction
|
||||
import org.mariotaku.twidere.util.Analyzer
|
||||
import org.mariotaku.twidere.util.premium.ExtraFeaturesService
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2016/12/25.
|
||||
*/
|
||||
|
||||
class ExtraFeaturesIntroductionCardFragment : BaseSupportFragment() {
|
||||
|
||||
lateinit var extraFeaturesService: ExtraFeaturesService
|
||||
|
||||
private val REQUEST_PURCHASE: Int = 301
|
||||
private val REQUEST_RESTORE_PURCHASE: Int = 302
|
||||
|
||||
// MARK: Fragment lifecycle
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
extraFeaturesService = ExtraFeaturesService.newInstance(context)
|
||||
purchaseButton.setOnClickListener {
|
||||
Analyzer.log(PurchaseConfirm(PurchaseFinished.NAME_EXTRA_FEATURES))
|
||||
startActivityForResult(extraFeaturesService.createPurchaseIntent(context), REQUEST_PURCHASE)
|
||||
}
|
||||
val restorePurchaseIntent = extraFeaturesService.createRestorePurchaseIntent(context)
|
||||
if (restorePurchaseIntent != null) {
|
||||
restorePurchaseHint.visibility = View.VISIBLE
|
||||
restorePurchaseButton.visibility = View.VISIBLE
|
||||
restorePurchaseButton.setOnClickListener {
|
||||
startActivityForResult(restorePurchaseIntent, REQUEST_RESTORE_PURCHASE)
|
||||
}
|
||||
} else {
|
||||
restorePurchaseHint.visibility = View.GONE
|
||||
restorePurchaseButton.visibility = View.GONE
|
||||
restorePurchaseButton.setOnClickListener(null)
|
||||
}
|
||||
if (savedInstanceState == null) {
|
||||
Analyzer.log(PurchaseIntroduction(PurchaseFinished.NAME_EXTRA_FEATURES, "enhanced features dashboard"))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
when (requestCode) {
|
||||
REQUEST_PURCHASE -> {
|
||||
when (resultCode) {
|
||||
Activity.RESULT_OK -> {
|
||||
Analyzer.log(PurchaseFinished.create(PurchaseFinished.NAME_EXTRA_FEATURES, data))
|
||||
activity?.recreate()
|
||||
}
|
||||
}
|
||||
}
|
||||
REQUEST_RESTORE_PURCHASE -> {
|
||||
when (resultCode) {
|
||||
Activity.RESULT_OK -> {
|
||||
activity?.recreate()
|
||||
}
|
||||
RESULT_NOT_PURCHASED -> {
|
||||
Toast.makeText(context, R.string.message_extra_features_not_purchased, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
RESULT_SERVICE_UNAVAILABLE -> {
|
||||
Toast.makeText(context, R.string.message_network_error, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_extra_features_introduction, container, false)
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package org.mariotaku.twidere.fragment.premium
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.Dialog
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
@ -10,27 +11,40 @@ import android.view.ViewGroup
|
||||
import kotlinx.android.synthetic.main.fragment_extra_features_sync_status.*
|
||||
import org.mariotaku.kpreferences.get
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.TwidereConstants.REQUEST_PURCHASE_EXTRA_FEATURES
|
||||
import org.mariotaku.twidere.activity.FragmentContentActivity
|
||||
import org.mariotaku.twidere.constant.dataSyncProviderInfoKey
|
||||
import org.mariotaku.twidere.fragment.BaseDialogFragment
|
||||
import org.mariotaku.twidere.fragment.BaseSupportFragment
|
||||
import org.mariotaku.twidere.fragment.ExtraFeaturesIntroductionDialogFragment
|
||||
import org.mariotaku.twidere.fragment.sync.SyncSettingsFragment
|
||||
import org.mariotaku.twidere.model.analyzer.PurchaseFinished
|
||||
import org.mariotaku.twidere.util.Analyzer
|
||||
import org.mariotaku.twidere.util.premium.ExtraFeaturesService
|
||||
import org.mariotaku.twidere.util.sync.SyncProviderInfoFactory
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2016/12/28.
|
||||
*/
|
||||
|
||||
class ExtraFeaturesSyncStatusFragment : BaseSupportFragment() {
|
||||
class SyncStatusFragment : BaseSupportFragment() {
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
updateSyncSettingActions()
|
||||
connectButton.setOnClickListener {
|
||||
if (!extraFeaturesService.isEnabled(ExtraFeaturesService.FEATURE_SYNC_DATA)) {
|
||||
showExtraFeaturesIntroduction()
|
||||
return@setOnClickListener
|
||||
}
|
||||
val df = ConnectNetworkStorageSelectionDialogFragment()
|
||||
df.show(childFragmentManager, "connect_to_storage")
|
||||
}
|
||||
settingsButton.setOnClickListener {
|
||||
if (!extraFeaturesService.isEnabled(ExtraFeaturesService.FEATURE_SYNC_DATA)) {
|
||||
showExtraFeaturesIntroduction()
|
||||
return@setOnClickListener
|
||||
}
|
||||
val intent = Intent(context, FragmentContentActivity::class.java)
|
||||
intent.putExtra(FragmentContentActivity.EXTRA_FRAGMENT, SyncSettingsFragment::class.java.name)
|
||||
intent.putExtra(FragmentContentActivity.EXTRA_TITLE, getString(R.string.title_sync_settings))
|
||||
@ -43,6 +57,11 @@ class ExtraFeaturesSyncStatusFragment : BaseSupportFragment() {
|
||||
REQUEST_CONNECT_NETWORK_STORAGE -> {
|
||||
updateSyncSettingActions()
|
||||
}
|
||||
REQUEST_PURCHASE_EXTRA_FEATURES -> {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
Analyzer.log(PurchaseFinished.create(data!!))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,6 +70,12 @@ class ExtraFeaturesSyncStatusFragment : BaseSupportFragment() {
|
||||
updateSyncSettingActions()
|
||||
}
|
||||
|
||||
private fun showExtraFeaturesIntroduction() {
|
||||
ExtraFeaturesIntroductionDialogFragment.show(childFragmentManager,
|
||||
feature = ExtraFeaturesService.FEATURE_SYNC_DATA,
|
||||
requestCode = REQUEST_PURCHASE_EXTRA_FEATURES)
|
||||
}
|
||||
|
||||
private fun updateSyncSettingActions() {
|
||||
if (preferences[dataSyncProviderInfoKey] == null) {
|
||||
statusText.text = getText(R.string.message_sync_data_connect_hint)
|
@ -1,8 +1,7 @@
|
||||
package org.mariotaku.twidere.model.analyzer
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import org.mariotaku.twidere.constant.*
|
||||
import org.mariotaku.twidere.activity.premium.AbsExtraFeaturePurchaseActivity
|
||||
import org.mariotaku.twidere.util.Analyzer
|
||||
|
||||
/**
|
||||
@ -18,22 +17,12 @@ data class PurchaseFinished(val productName: String) : Analyzer.Event {
|
||||
companion object {
|
||||
const val NAME_EXTRA_FEATURES = "Enhanced Features"
|
||||
|
||||
internal fun getFailReason(resultCode: Int): String {
|
||||
return when (resultCode) {
|
||||
Activity.RESULT_CANCELED -> "cancelled"
|
||||
RESULT_SERVICE_UNAVAILABLE -> "service unavailable"
|
||||
RESULT_INTERNAL_ERROR -> "internal error"
|
||||
RESULT_NOT_PURCHASED -> "not purchased"
|
||||
else -> "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
fun create(name: String, data: Intent?): PurchaseFinished {
|
||||
val result = PurchaseFinished(name)
|
||||
if (data != null) {
|
||||
result.price = data.getDoubleExtra(EXTRA_PRICE, Double.NaN)
|
||||
result.currency = data.getStringExtra(EXTRA_CURRENCY)
|
||||
}
|
||||
fun create(data: Intent): PurchaseFinished {
|
||||
val purchaseResult: AbsExtraFeaturePurchaseActivity.PurchaseResult
|
||||
= data.getParcelableExtra(AbsExtraFeaturePurchaseActivity.EXTRA_PURCHASE_RESULT)
|
||||
val result = PurchaseFinished(purchaseResult.feature)
|
||||
result.price = purchaseResult.price
|
||||
result.currency = purchaseResult.currency
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ object ParcelableStatusUtils {
|
||||
result.in_reply_to_name = getInReplyToName(status)
|
||||
result.in_reply_to_screen_name = status.inReplyToScreenName
|
||||
result.in_reply_to_status_id = status.inReplyToStatusId
|
||||
result.in_reply_to_user_id = getInReplyToUserId(status, accountKey)
|
||||
result.in_reply_to_user_key = getInReplyToUserId(status, accountKey)
|
||||
|
||||
val user = status.user
|
||||
result.user_key = UserKeyUtils.fromUser(user)
|
||||
@ -280,8 +280,8 @@ object ParcelableStatusUtils {
|
||||
status.retweet_user_nickname = manager.getUserNickname(status.retweeted_by_user_key!!)
|
||||
}
|
||||
|
||||
if (status.in_reply_to_user_id != null) {
|
||||
status.in_reply_to_user_nickname = manager.getUserNickname(status.in_reply_to_user_id!!)
|
||||
if (status.in_reply_to_user_key != null) {
|
||||
status.in_reply_to_user_nickname = manager.getUserNickname(status.in_reply_to_user_key!!)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,7 @@ import org.mariotaku.twidere.util.imageloader.URLFileNameGenerator
|
||||
import org.mariotaku.twidere.util.media.TwidereMediaDownloader
|
||||
import org.mariotaku.twidere.util.media.UILFileCache
|
||||
import org.mariotaku.twidere.util.net.TwidereDns
|
||||
import org.mariotaku.twidere.util.premium.ExtraFeaturesService
|
||||
import org.mariotaku.twidere.util.refresh.AutoRefreshController
|
||||
import org.mariotaku.twidere.util.refresh.JobSchedulerAutoRefreshController
|
||||
import org.mariotaku.twidere.util.refresh.LegacyAutoRefreshController
|
||||
@ -247,7 +248,7 @@ class ApplicationModule(private val application: Application) {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun syncController(kPreferences: KPreferences): SyncController {
|
||||
fun syncController(): SyncController {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
return JobSchedulerSyncController(application)
|
||||
}
|
||||
@ -262,7 +263,7 @@ class ApplicationModule(private val application: Application) {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun taskCreator(kPreferences: KPreferences, syncPreferences: SyncPreferences, bus: Bus): TaskServiceRunner {
|
||||
fun taskCreator(kPreferences: KPreferences, bus: Bus): TaskServiceRunner {
|
||||
return TaskServiceRunner(application, kPreferences, bus)
|
||||
}
|
||||
|
||||
@ -280,6 +281,12 @@ class ApplicationModule(private val application: Application) {
|
||||
return HotMobiLogger(application)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun extraFeaturesService(): ExtraFeaturesService {
|
||||
return ExtraFeaturesService.newInstance(application)
|
||||
}
|
||||
|
||||
private fun createDiskCache(dirName: String, preferences: SharedPreferencesWrapper): DiskCache {
|
||||
val cacheDir = Utils.getExternalCacheDir(application, dirName)
|
||||
val fallbackCacheDir = Utils.getInternalCacheDir(application, dirName)
|
||||
|
@ -3,6 +3,7 @@ package org.mariotaku.twidere.util.premium
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.support.annotation.CallSuper
|
||||
import org.mariotaku.twidere.R
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
@ -12,9 +13,7 @@ import java.util.*
|
||||
abstract class ExtraFeaturesService {
|
||||
protected lateinit var context: Context
|
||||
|
||||
abstract val introductionLayout: Int
|
||||
|
||||
abstract val dashboardLayouts: IntArray
|
||||
abstract fun getDashboardLayouts(): IntArray
|
||||
|
||||
@CallSuper
|
||||
protected open fun init(context: Context) {
|
||||
@ -26,25 +25,46 @@ abstract class ExtraFeaturesService {
|
||||
|
||||
abstract fun isSupported(): Boolean
|
||||
|
||||
abstract fun isEnabled(): Boolean
|
||||
abstract fun isEnabled(feature: String): Boolean
|
||||
|
||||
/**
|
||||
* For debug purpose only, this will remove purchased product
|
||||
*/
|
||||
abstract fun destroyPurchase(): Boolean
|
||||
|
||||
abstract fun createPurchaseIntent(context: Context): Intent
|
||||
abstract fun createPurchaseIntent(context: Context, feature: String): Intent?
|
||||
|
||||
abstract fun createRestorePurchaseIntent(context: Context): Intent?
|
||||
abstract fun createRestorePurchaseIntent(context: Context, feature: String): Intent?
|
||||
|
||||
data class Introduction(val icon: Int, val description: String)
|
||||
|
||||
companion object {
|
||||
|
||||
const val FEATURE_FEATURES_PACK = "features_pack"
|
||||
const val FEATURE_FILTERS_IMPORT = "import_filters"
|
||||
const val FEATURE_FILTERS_SUBSCRIPTION = "filters_subscriptions"
|
||||
const val FEATURE_SYNC_DATA = "sync_data"
|
||||
const val FEATURE_SCHEDULE_STATUS = "schedule_status"
|
||||
|
||||
fun newInstance(context: Context): ExtraFeaturesService {
|
||||
val instance = ServiceLoader.load(ExtraFeaturesService::class.java).first()
|
||||
instance.init(context)
|
||||
return instance
|
||||
}
|
||||
|
||||
fun getIntroduction(context: Context, feature: String): Introduction {
|
||||
return when (feature) {
|
||||
FEATURE_FEATURES_PACK -> Introduction(R.drawable.ic_action_infinity, "")
|
||||
FEATURE_FILTERS_IMPORT -> Introduction(R.drawable.ic_action_speaker_muted,
|
||||
context.getString(R.string.extra_feature_description_filters_import))
|
||||
FEATURE_SYNC_DATA -> Introduction(R.drawable.ic_action_refresh,
|
||||
context.getString(R.string.extra_feature_description_sync_data))
|
||||
FEATURE_FILTERS_SUBSCRIPTION -> Introduction(R.drawable.ic_action_speaker_muted,
|
||||
context.getString(R.string.extra_feature_description_filters_subscription))
|
||||
FEATURE_SCHEDULE_STATUS -> Introduction(R.drawable.ic_action_time,
|
||||
context.getString(R.string.extra_feature_description_schedule_status))
|
||||
else -> throw UnsupportedOperationException(feature)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -128,6 +128,7 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
|
||||
val twitter = adapter.twitterWrapper
|
||||
val linkify = adapter.twidereLinkify
|
||||
val formatter = adapter.bidiFormatter
|
||||
val colorNameManager = adapter.userColorNameManager
|
||||
val nameFirst = adapter.nameFirst
|
||||
val showCardActions = isCardActionsShown
|
||||
|
||||
@ -154,7 +155,7 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
|
||||
|
||||
statusContentUpperSpace.visibility = View.GONE
|
||||
} else if (status.retweet_id != null) {
|
||||
val retweetedBy = UserColorNameManager.decideDisplayName(status.retweet_user_nickname,
|
||||
val retweetedBy = colorNameManager.getDisplayName(status.retweeted_by_user_key!!,
|
||||
status.retweeted_by_user_name, status.retweeted_by_user_screen_name, nameFirst)
|
||||
statusInfoLabel.text = context.getString(R.string.name_retweeted, formatter.unicodeWrap(retweetedBy))
|
||||
statusInfoIcon.setImageResource(R.drawable.ic_activity_action_retweet)
|
||||
@ -162,8 +163,8 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
|
||||
statusInfoIcon.visibility = View.VISIBLE
|
||||
|
||||
statusContentUpperSpace.visibility = View.GONE
|
||||
} else if (status.in_reply_to_status_id != null && status.in_reply_to_user_id != null && displayInReplyTo) {
|
||||
val inReplyTo = UserColorNameManager.decideDisplayName(status.in_reply_to_user_nickname,
|
||||
} else if (status.in_reply_to_status_id != null && status.in_reply_to_user_key != null && displayInReplyTo) {
|
||||
val inReplyTo = colorNameManager.getDisplayName(status.in_reply_to_user_key!!,
|
||||
status.in_reply_to_name, status.in_reply_to_screen_name, nameFirst)
|
||||
statusInfoLabel.text = context.getString(R.string.in_reply_to_name, formatter.unicodeWrap(inReplyTo))
|
||||
statusInfoIcon.setImageResource(R.drawable.ic_activity_action_reply)
|
||||
@ -189,9 +190,10 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
|
||||
quotedNameView.visibility = View.VISIBLE
|
||||
quotedTextView.visibility = View.VISIBLE
|
||||
|
||||
quotedNameView.setName(UserColorNameManager.decideNickname(status.quoted_user_nickname,
|
||||
val quoted_user_key = status.quoted_user_key!!
|
||||
quotedNameView.setName(colorNameManager.getUserNickname(quoted_user_key,
|
||||
status.quoted_user_name))
|
||||
quotedNameView.setScreenName("@" + status.quoted_user_screen_name)
|
||||
quotedNameView.setScreenName("@${status.quoted_user_screen_name}")
|
||||
|
||||
var quotedDisplayEnd = -1
|
||||
if (status.extras.quoted_display_text_range != null) {
|
||||
@ -220,8 +222,9 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
|
||||
quotedTextView.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
if (status.quoted_user_color != 0) {
|
||||
quotedView.drawStart(status.quoted_user_color)
|
||||
val quoted_user_color = colorNameManager.getUserColor(quoted_user_key)
|
||||
if (quoted_user_color != 0) {
|
||||
quotedView.drawStart(quoted_user_color)
|
||||
} else {
|
||||
quotedView.drawStart(ThemeUtils.getColorFromAttribute(context, R.attr.quoteIndicatorBackgroundColor, 0))
|
||||
}
|
||||
@ -289,7 +292,8 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
|
||||
} else {
|
||||
timeView.setTime(status.timestamp)
|
||||
}
|
||||
nameView.setName(UserColorNameManager.decideNickname(status.user_nickname, status.user_name))
|
||||
|
||||
nameView.setName(colorNameManager.getUserNickname(status.user_key, status.user_name))
|
||||
nameView.setScreenName("@${status.user_screen_name}")
|
||||
|
||||
if (adapter.profileImageEnabled) {
|
||||
|
@ -852,8 +852,8 @@
|
||||
<string name="extra_features_description">Unterstütze Twidere und erhalte erweiterte Funktionen</string>
|
||||
<!-- Enhanced (paid) features title -->
|
||||
<string name="extra_features_restore_purchase_hint">Wenn du die erweiterten Funktionen bereits erworben hast, kannst du \"Wiederherstellen\" verwenden um diese wiederherzustellen.</string>
|
||||
<string name="extra_features_name_sync_data">Synchronisieren von Daten wie Filter und Entwürfe</string>
|
||||
<string name="extra_features_name_import_filter_list">Importiere Filterliste von blockierten/stummgeschalteten</string>
|
||||
<string name="extra_feature_description_sync_data">Synchronisieren von Daten wie Filter und Entwürfe</string>
|
||||
<string name="extra_feature_description_filters_import">Importiere Filterliste von blockierten/stummgeschalteten</string>
|
||||
<string name="title_error_invalid_account">Ungültiges Konto</string>
|
||||
<string name="message_error_invalid_account">Einige Kontodaten sind beschädigt, Twidere entfernt diese Konten um einen Absturz zu verhindern.</string>
|
||||
<string name="title_premium_features_name">Twidere ∞</string>
|
||||
|
@ -851,7 +851,7 @@
|
||||
<string name="extra_features_description">Soutenez Twidere et accédez à des fonctionnalités avancées</string>
|
||||
<!-- Enhanced (paid) features title -->
|
||||
<string name="extra_features_restore_purchase_hint">Si vous avez déjà acheté des fonctionnalités avancées, vous pouvez utiliser \'Restaurer\' pour importer vos achats.</string>
|
||||
<string name="extra_features_name_sync_data">Synchroniser les données tel que les filtres et brouillons</string>
|
||||
<string name="extra_feature_description_sync_data">Synchroniser les données tel que les filtres et brouillons</string>
|
||||
<string name="title_error_invalid_account">Compte non valide</string>
|
||||
<string name="message_error_invalid_account">Certaines données de compte sont corrompues, Twidere va supprimer ces comptes pour éviter de planter.</string>
|
||||
<string name="title_premium_features_name">Twidere ∞</string>
|
||||
|
@ -852,8 +852,8 @@
|
||||
<string name="extra_features_description">支持 Twidere 并获得增强功能</string>
|
||||
<!-- Enhanced (paid) features title -->
|
||||
<string name="extra_features_restore_purchase_hint">如果你已经购买增强功能,可以使用“恢复”来恢复购买。</string>
|
||||
<string name="extra_features_name_sync_data">同步数据,如过滤器和草稿</string>
|
||||
<string name="extra_features_name_import_filter_list">从被隐藏/阻止的用户导入过滤列表</string>
|
||||
<string name="extra_feature_description_sync_data">同步数据,如过滤器和草稿</string>
|
||||
<string name="extra_feature_description_filters_import">从被隐藏/阻止的用户导入过滤列表</string>
|
||||
<string name="title_error_invalid_account">帐号无效</string>
|
||||
<string name="message_error_invalid_account">一些帐号数据已损坏,Twidere 将删除这些帐户以避免崩溃。</string>
|
||||
<string name="title_premium_features_name">Twidere ∞</string>
|
||||
|
@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.v7.widget.CardView
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardBackgroundColor="?cardItemBackgroundColor"
|
||||
tools:showIn="@layout/activity_premium_dashboard">
|
||||
|
||||
<fragment
|
||||
android:id="@+id/extra_features_introduction"
|
||||
class="org.mariotaku.twidere.fragment.premium.ExtraFeaturesIntroductionCardFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:layout="@layout/fragment_extra_features_introduction"/>
|
||||
</android.support.v7.widget.CardView>
|
@ -9,7 +9,7 @@
|
||||
|
||||
<fragment
|
||||
android:id="@+id/extra_features_sync_status"
|
||||
class="org.mariotaku.twidere.fragment.premium.ExtraFeaturesSyncStatusFragment"
|
||||
class="org.mariotaku.twidere.fragment.premium.SyncStatusFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:layout="@layout/fragment_extra_features_sync_status"/>
|
||||
|
@ -1,11 +1,60 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
|
||||
<TableLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/element_spacing_normal">
|
||||
|
||||
<include layout="@layout/layout_extra_features_introduction"/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/element_spacing_normal"
|
||||
android:text="@string/extra_features_description"
|
||||
android:textAppearance="?android:textAppearanceMedium"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
</FrameLayout>
|
||||
<TableRow android:layout_margin="@dimen/element_spacing_normal">
|
||||
|
||||
<org.mariotaku.twidere.view.IconActionView
|
||||
android:id="@+id/featureIcon"
|
||||
android:layout_width="@dimen/element_size_small"
|
||||
android:layout_height="@dimen/element_size_small"
|
||||
app:iabColor="?android:textColorSecondary"
|
||||
tools:src="@drawable/ic_action_refresh"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/featureDescription"
|
||||
android:layout_marginLeft="@dimen/element_spacing_normal"
|
||||
android:layout_marginStart="@dimen/element_spacing_normal"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="@dimen/element_size_small"
|
||||
android:textSize="15sp"
|
||||
tools:text="@string/extra_feature_description_sync_data"/>
|
||||
</TableRow>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/element_spacing_normal"
|
||||
android:text="@string/extra_features_pack_description"
|
||||
android:textAppearance="?android:textAppearanceMedium"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/buyFeaturesPack"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/action_purchase_features_pack"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/restorePurchaseHint"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/element_spacing_normal"
|
||||
android:text="@string/extra_features_restore_purchase_hint"
|
||||
android:textAppearance="?android:textAppearanceMedium"
|
||||
android:textSize="16sp"/>
|
||||
</TableLayout>
|
||||
|
@ -1,54 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/element_spacing_normal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/element_spacing_normal"
|
||||
android:text="@string/title_extra_features"
|
||||
android:textAppearance="?android:textAppearanceMedium"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
<include layout="@layout/layout_extra_features_introduction"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="end">
|
||||
|
||||
<Button
|
||||
android:id="@+id/restorePurchaseButton"
|
||||
style="?borderlessButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:text="@string/action_restore_purchase"
|
||||
android:textAllCaps="true"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?colorAccent"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
<Space
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/purchaseButton"
|
||||
style="?borderlessButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:text="@string/action_purchase"
|
||||
android:textAllCaps="true"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?colorAccent"
|
||||
android:textStyle="bold"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
@ -1,63 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TableLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:showIn="@layout/fragment_extra_features_introduction">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/element_spacing_normal"
|
||||
android:text="@string/extra_features_description"
|
||||
android:textAppearance="?android:textAppearanceMedium"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
<TableRow android:layout_margin="@dimen/element_spacing_normal">
|
||||
|
||||
<org.mariotaku.twidere.view.IconActionView
|
||||
android:layout_width="@dimen/element_size_small"
|
||||
android:layout_height="@dimen/element_size_small"
|
||||
android:src="@drawable/ic_action_refresh"
|
||||
app:iabColor="?android:textColorSecondary"/>
|
||||
|
||||
<TextView
|
||||
android:layout_marginLeft="@dimen/element_spacing_normal"
|
||||
android:layout_marginStart="@dimen/element_spacing_normal"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="@dimen/element_size_small"
|
||||
android:text="@string/extra_features_name_sync_data"
|
||||
android:textSize="15sp"/>
|
||||
</TableRow>
|
||||
|
||||
<TableRow android:layout_margin="@dimen/element_spacing_normal">
|
||||
|
||||
<org.mariotaku.twidere.view.IconActionView
|
||||
android:layout_width="@dimen/element_size_small"
|
||||
android:layout_height="@dimen/element_size_small"
|
||||
android:src="@drawable/ic_action_speaker_muted"
|
||||
app:iabColor="?android:textColorSecondary"/>
|
||||
|
||||
<TextView
|
||||
android:layout_marginLeft="@dimen/element_spacing_normal"
|
||||
android:layout_marginStart="@dimen/element_spacing_normal"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="@dimen/element_size_small"
|
||||
android:text="@string/extra_features_name_import_filter_list"
|
||||
android:textSize="15sp"/>
|
||||
</TableRow>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/restorePurchaseHint"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/element_spacing_normal"
|
||||
android:text="@string/extra_features_restore_purchase_hint"
|
||||
android:textAppearance="?android:textAppearanceMedium"
|
||||
android:textSize="16sp"/>
|
||||
</TableLayout>
|
||||
|
||||
|
||||
|
@ -856,10 +856,13 @@
|
||||
<string name="action_restore_purchase">Restore</string>
|
||||
<!-- Enhanced (paid) features description -->
|
||||
<string name="extra_features_description">Support Twidere and get enhanced features</string>
|
||||
<string name="extra_features_pack_description">Or buy features pack to get all features (including features in future releases)</string>
|
||||
<!-- Enhanced (paid) features title -->
|
||||
<string name="extra_features_restore_purchase_hint">If you\'ve already purchased enhanced features, you can use \'Restore\' to restore purchase.</string>
|
||||
<string name="extra_features_name_sync_data">Sync data like filters and drafts</string>
|
||||
<string name="extra_features_name_import_filter_list">Import filter list from blocks/mutes</string>
|
||||
<string name="extra_feature_description_sync_data">Sync data with Dropbox, Google Drive etc</string>
|
||||
<string name="extra_feature_description_filters_import">Import filter list from blocks/mutes</string>
|
||||
<string name="extra_feature_description_filters_subscription">Filters list subscription</string>
|
||||
<string name="extra_feature_description_schedule_status">Schedule tweet (send later)</string>
|
||||
<string name="title_error_invalid_account">Invalid account</string>
|
||||
<string name="message_error_invalid_account">Some account data are corrupted, Twidere will remove those accounts to prevent crash.</string>
|
||||
<string name="title_premium_features_name">Twidere ∞</string>
|
||||
@ -890,4 +893,5 @@
|
||||
<string name="title_sync_settings">Sync settings</string>
|
||||
<string name="message_sync_disconnect_from_name_confirm">Disconnect from <xliff:g example="ownCloud" id="name">%s</xliff:g>?</string>
|
||||
<string name="message_sync_last_synced_time">Last synced: <xliff:g example="2017/1/1 12:00" id="time">%s</xliff:g></string>
|
||||
<string name="action_purchase_features_pack">Buy features pack</string>
|
||||
</resources>
|
Loading…
x
Reference in New Issue
Block a user