Add support page
This commit is contained in:
parent
5d61ccc4fb
commit
070d580044
9 changed files with 206 additions and 33 deletions
|
@ -17,7 +17,6 @@ try {
|
||||||
keystoreProperties['storePassword'] = ""
|
keystoreProperties['storePassword'] = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
android {
|
android {
|
||||||
configurations.all {
|
configurations.all {
|
||||||
resolutionStrategy.force 'com.google.code.findbugs:jsr305:3.0.1'
|
resolutionStrategy.force 'com.google.code.findbugs:jsr305:3.0.1'
|
||||||
|
@ -101,6 +100,7 @@ dependencies {
|
||||||
implementation 'com.android.billingclient:billing:1.2'
|
implementation 'com.android.billingclient:billing:1.2'
|
||||||
implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
|
implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
|
||||||
implementation "androidx.core:core-ktx:1.1.0"
|
implementation "androidx.core:core-ktx:1.1.0"
|
||||||
|
implementation 'androidx.browser:browser:1.0.0'
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
def coroutines_version = "1.3.0-RC2"
|
def coroutines_version = "1.3.0-RC2"
|
||||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
|
||||||
|
@ -136,10 +136,10 @@ task jacocoTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest']) {
|
||||||
def kotlinDebugTree = fileTree(dir: "$project.buildDir/tmp/kotlin-classes/debug", excludes: fileFilter)
|
def kotlinDebugTree = fileTree(dir: "$project.buildDir/tmp/kotlin-classes/debug", excludes: fileFilter)
|
||||||
def mainSrc = "$project.projectDir/src/main/java"
|
def mainSrc = "$project.projectDir/src/main/java"
|
||||||
|
|
||||||
sourceDirectories = files([mainSrc])
|
sourceDirectories.setFrom(files([mainSrc]))
|
||||||
classDirectories = files([javaDebugTree, kotlinDebugTree])
|
classDirectories.setFrom(files([javaDebugTree, kotlinDebugTree]))
|
||||||
executionData = fileTree(dir: project.buildDir, includes: [
|
executionData.setFrom(fileTree(dir: project.buildDir, includes: [
|
||||||
'jacoco/testDebugUnitTest.exec',
|
'jacoco/testDebugUnitTest.exec',
|
||||||
'outputs/code-coverage/connected/*coverage.ec'
|
'outputs/code-coverage/connected/*coverage.ec'
|
||||||
])
|
]))
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,6 @@
|
||||||
android:theme="@style/AppTheme"
|
android:theme="@style/AppTheme"
|
||||||
tools:ignore="AllowBackup"
|
tools:ignore="AllowBackup"
|
||||||
tools:targetApi="n">
|
tools:targetApi="n">
|
||||||
<meta-data
|
|
||||||
android:name="com.google.android.gms.ads.APPLICATION_ID"
|
|
||||||
android:value="@string/admob_app_id" />
|
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".view.activity.SplashActivity"
|
android:name=".view.activity.SplashActivity"
|
||||||
android:theme="@style/AppTheme.Splash"
|
android:theme="@style/AppTheme.Splash"
|
||||||
|
@ -68,6 +64,8 @@
|
||||||
android:value=".view.activity.MainActivity" />
|
android:value=".view.activity.MainActivity" />
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<activity android:name=".view.activity.SupportActivity" />
|
||||||
|
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="firebase_crashlytics_collection_enabled"
|
android:name="firebase_crashlytics_collection_enabled"
|
||||||
android:value="false" />
|
android:value="false" />
|
||||||
|
|
|
@ -1,21 +1,61 @@
|
||||||
package com.wbrawner.simplemarkdown.view.activity
|
package com.wbrawner.simplemarkdown.view.activity
|
||||||
|
|
||||||
|
import android.content.ActivityNotFoundException
|
||||||
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.view.MenuItem
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.browser.customtabs.CustomTabsIntent
|
||||||
import com.android.billingclient.api.*
|
import com.android.billingclient.api.*
|
||||||
import java.util.*
|
import com.google.android.material.button.MaterialButton
|
||||||
|
import com.wbrawner.simplemarkdown.R
|
||||||
|
import kotlinx.android.synthetic.main.activity_support.*
|
||||||
|
|
||||||
|
|
||||||
class SupportActivity : AppCompatActivity(), BillingClientStateListener, PurchasesUpdatedListener {
|
class SupportActivity : AppCompatActivity(), BillingClientStateListener, PurchasesUpdatedListener {
|
||||||
private lateinit var billingClient: BillingClient
|
private lateinit var billingClient: BillingClient
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_support)
|
||||||
|
setSupportActionBar(toolbar)
|
||||||
|
setTitle(R.string.support_title)
|
||||||
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
billingClient = BillingClient.newBuilder(applicationContext)
|
billingClient = BillingClient.newBuilder(applicationContext)
|
||||||
.setListener(this)
|
.setListener(this)
|
||||||
.build()
|
.build()
|
||||||
billingClient.startConnection(this)
|
billingClient.startConnection(this)
|
||||||
|
githubButton.setOnClickListener {
|
||||||
|
CustomTabsIntent.Builder()
|
||||||
|
.addDefaultShareMenuItem()
|
||||||
|
.build()
|
||||||
|
.launchUrl(this@SupportActivity, Uri.parse("https://github.com/wbrawner/SimpleMarkdown"))
|
||||||
|
}
|
||||||
|
rateButton.setOnClickListener {
|
||||||
|
val playStoreIntent = Intent(Intent.ACTION_VIEW)
|
||||||
|
.apply {
|
||||||
|
data = Uri.parse("market://details?id=${packageName}")
|
||||||
|
addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY or
|
||||||
|
Intent.FLAG_ACTIVITY_NEW_DOCUMENT or
|
||||||
|
Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
startActivity(playStoreIntent)
|
||||||
|
} catch (ignored: ActivityNotFoundException) {
|
||||||
|
playStoreIntent.data = Uri.parse("https://play.google.com/store/apps/details?id=${packageName}")
|
||||||
|
startActivity(playStoreIntent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
|
if (item.itemId == android.R.id.home) {
|
||||||
|
finish()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBillingSetupFinished(responseCode: Int) {
|
override fun onBillingSetupFinished(responseCode: Int) {
|
||||||
|
@ -23,36 +63,47 @@ class SupportActivity : AppCompatActivity(), BillingClientStateListener, Purchas
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// The billing client is ready. You can query purchases here.
|
val skuDetails = SkuDetailsParams.newBuilder()
|
||||||
val skuList = ArrayList<String>()
|
.setSkusList(listOf("support_the_developer", "tip_coffee", "tip_beer"))
|
||||||
skuList.add("support_the_developer")
|
.setType(BillingClient.SkuType.INAPP)
|
||||||
val params = SkuDetailsParams.newBuilder()
|
.build()
|
||||||
params.setSkusList(skuList).setType(BillingClient.SkuType.INAPP)
|
billingClient.querySkuDetailsAsync(skuDetails) { skuDetailsResponseCode, skuDetailsList ->
|
||||||
billingClient.querySkuDetailsAsync(params.build()) { responseCode1, skuDetailsList ->
|
|
||||||
// Process the result.
|
// Process the result.
|
||||||
if (responseCode1 != BillingClient.BillingResponse.OK || skuDetailsList == null) {
|
if (skuDetailsResponseCode != BillingClient.BillingResponse.OK || skuDetailsList.isNullOrEmpty()) {
|
||||||
return@querySkuDetailsAsync
|
return@querySkuDetailsAsync
|
||||||
}
|
}
|
||||||
|
|
||||||
val skuDetails = skuDetailsList!!.get(0)
|
skuDetailsList.sortedBy { it.priceAmountMicros }.forEach { skuDetails ->
|
||||||
val sku = skuDetails.getSku()
|
val supportButton = MaterialButton(this@SupportActivity)
|
||||||
val price = skuDetails.getPrice()
|
supportButton.text = getString(
|
||||||
Log.d("SimpleMarkdown",
|
R.string.support_button_purchase,
|
||||||
"Got product with sku: " + sku + " and price: " + price + " " + skuDetails.getPriceCurrencyCode())
|
skuDetails.title,
|
||||||
val flowParams = BillingFlowParams.newBuilder()
|
skuDetails.price
|
||||||
.setSkuDetails(skuDetails)
|
)
|
||||||
.build()
|
supportButton.setOnClickListener {
|
||||||
val responseCode2 = billingClient.launchBillingFlow(this, flowParams)
|
val flowParams = BillingFlowParams.newBuilder()
|
||||||
|
.setSkuDetails(skuDetails)
|
||||||
|
.build()
|
||||||
|
billingClient.launchBillingFlow(this, flowParams)
|
||||||
|
}
|
||||||
|
supportButtons.addView(supportButton)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBillingServiceDisconnected() {
|
override fun onBillingServiceDisconnected() {
|
||||||
// TODO: Set a flag and just try again later
|
|
||||||
billingClient.startConnection(this)
|
billingClient.startConnection(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPurchasesUpdated(responseCode: Int, purchases: List<Purchase>?) {
|
override fun onPurchasesUpdated(responseCode: Int, purchases: List<Purchase>?) {
|
||||||
|
purchases?.forEach { purchase ->
|
||||||
|
billingClient.consumeAsync(purchase.purchaseToken) { _, _ ->
|
||||||
|
Toast.makeText(
|
||||||
|
this@SupportActivity,
|
||||||
|
getString(R.string.support_thank_you),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
9
app/src/main/res/drawable/ic_favorite_black_24dp.xml
Normal file
9
app/src/main/res/drawable/ic_favorite_black_24dp.xml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M12,21.35l-1.45,-1.32C5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3c1.74,0 3.41,0.81 4.5,2.09C13.09,3.81 14.76,3 16.5,3 19.58,3 22,5.42 22,8.5c0,3.78 -3.4,6.86 -8.55,11.54L12,21.35z" />
|
||||||
|
</vector>
|
9
app/src/main/res/drawable/ic_menu_black_24dp.xml
Normal file
9
app/src/main/res/drawable/ic_menu_black_24dp.xml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="@color/colorOnBackground"
|
||||||
|
android:pathData="M3,18h18v-2L3,16v2zM3,13h18v-2L3,11v2zM3,6v2h18L21,6L3,6z" />
|
||||||
|
</vector>
|
91
app/src/main/res/layout/activity_support.xml
Normal file
91
app/src/main/res/layout/activity_support.xml
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:fitsSystemWindows="true">
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clipChildren="false"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:padding="16dp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/bottomSheet"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/heartIcon"
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="100dp"
|
||||||
|
android:src="@drawable/ic_favorite_black_24dp"
|
||||||
|
android:tint="@color/colorAccent"
|
||||||
|
android:contentDescription="@string/description_heart"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/supportInfoText"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:text="@string/support_info"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textColor="@color/colorOnBackground"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/heartIcon" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/githubButton"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:backgroundTint="@color/colorBackgroundGitHub"
|
||||||
|
android:textColor="@color/colorWhite"
|
||||||
|
android:text="@string/action_view_github"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/supportInfoText" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/rateButton"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:backgroundTint="@color/colorBackgroundPlayStore"
|
||||||
|
android:textColor="@color/colorWhite"
|
||||||
|
android:text="@string/action_rate"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/githubButton" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/supportButtons"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/rateButton" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:id="@+id/bottomSheet"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:translationY="16dp"
|
||||||
|
app:cardCornerRadius="16dp"
|
||||||
|
app:cardElevation="4dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.Toolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:background="@color/colorBackground" />
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -5,4 +5,7 @@
|
||||||
<color name="colorAccent">#d32f2f</color>
|
<color name="colorAccent">#d32f2f</color>
|
||||||
<color name="colorBackground">#FFFFFF</color>
|
<color name="colorBackground">#FFFFFF</color>
|
||||||
<color name="colorOnBackground">#000000</color>
|
<color name="colorOnBackground">#000000</color>
|
||||||
|
<color name="colorBackgroundGitHub">#24292e</color>
|
||||||
|
<color name="colorWhite">#FFFFFFFF</color>
|
||||||
|
<color name="colorBackgroundPlayStore">#689f38</color>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
<string name="app_name">Simple Markdown</string>
|
<string name="app_name">Simple Markdown</string>
|
||||||
<string name="app_name_short">Markdown</string>
|
<string name="app_name_short">Markdown</string>
|
||||||
|
|
||||||
<string name="admob_app_id">ca-app-pub-3319579963502409~4576405307</string>
|
|
||||||
|
|
||||||
<string name="action_settings">Settings</string>
|
<string name="action_settings">Settings</string>
|
||||||
<string name="action_help">Help</string>
|
<string name="action_help">Help</string>
|
||||||
<string name="action_edit">Edit</string>
|
<string name="action_edit">Edit</string>
|
||||||
|
@ -65,6 +63,20 @@
|
||||||
<string name="prompt_save_changes">Would you like to save your changes?</string>
|
<string name="prompt_save_changes">Would you like to save your changes?</string>
|
||||||
<string name="action_discard">Discard</string>
|
<string name="action_discard">Discard</string>
|
||||||
<string name="action_save_as">Save as…</string>
|
<string name="action_save_as">Save as…</string>
|
||||||
|
<string name="support_info">SimpleMarkdown is a personal project of mine that I develop and
|
||||||
|
maintain in my free time. I very much appreciate any and all forms of support, whether
|
||||||
|
that be assistance with designing the app or icons, adding translations for other
|
||||||
|
languages, contributing to the code, or giving me a tip. If you have any troubles with
|
||||||
|
SimpleMarkdown, please don\'t hesitate to get in touch, and if you haven\'t already,
|
||||||
|
please rate the app on the Play Store.\n\nAlso please keep in mind that the in-app
|
||||||
|
purchases for the tips won\'t unlock any additional functionality in the app.
|
||||||
|
SimpleMarkdown is and always will be completely free and open source!</string>
|
||||||
|
<string name="action_view_github">View SimpleMarkdown on GitHub</string>
|
||||||
|
<string name="support_title">Support SimpleMarkdown</string>
|
||||||
|
<string name="support_button_purchase">%1$s – %2$s</string>
|
||||||
|
<string name="action_rate">Rate SimpleMarkdown</string>
|
||||||
|
<string name="support_thank_you">Thank you so much for your support!</string>
|
||||||
|
<string name="description_heart">Heart</string>
|
||||||
<string-array name="pref_entries_dark_mode">
|
<string-array name="pref_entries_dark_mode">
|
||||||
<item>@string/pref_value_light</item>
|
<item>@string/pref_value_light</item>
|
||||||
<item>@string/pref_value_dark</item>
|
<item>@string/pref_value_dark</item>
|
||||||
|
|
|
@ -10,7 +10,7 @@ buildscript {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.5.1'
|
classpath 'com.android.tools.build:gradle:3.5.2'
|
||||||
classpath 'com.google.gms:google-services:4.3.2'
|
classpath 'com.google.gms:google-services:4.3.2'
|
||||||
classpath 'io.fabric.tools:gradle:1.31.0'
|
classpath 'io.fabric.tools:gradle:1.31.0'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
|
|
Loading…
Reference in a new issue