diff --git a/app/build.gradle b/app/build.gradle
index 4695bd6..b4d4c64 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -17,7 +17,6 @@ try {
keystoreProperties['storePassword'] = ""
}
-
android {
configurations.all {
resolutionStrategy.force 'com.google.code.findbugs:jsr305:3.0.1'
@@ -101,6 +100,7 @@ dependencies {
implementation 'com.android.billingclient:billing:1.2'
implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
implementation "androidx.core:core-ktx:1.1.0"
+ implementation 'androidx.browser:browser:1.0.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
def coroutines_version = "1.3.0-RC2"
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 mainSrc = "$project.projectDir/src/main/java"
- sourceDirectories = files([mainSrc])
- classDirectories = files([javaDebugTree, kotlinDebugTree])
- executionData = fileTree(dir: project.buildDir, includes: [
+ sourceDirectories.setFrom(files([mainSrc]))
+ classDirectories.setFrom(files([javaDebugTree, kotlinDebugTree]))
+ executionData.setFrom(fileTree(dir: project.buildDir, includes: [
'jacoco/testDebugUnitTest.exec',
'outputs/code-coverage/connected/*coverage.ec'
- ])
+ ]))
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index defe2b9..44868d3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -18,10 +18,6 @@
android:theme="@style/AppTheme"
tools:ignore="AllowBackup"
tools:targetApi="n">
-
-
+
+
diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/SupportActivity.kt b/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/SupportActivity.kt
index 00985ec..9951497 100644
--- a/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/SupportActivity.kt
+++ b/app/src/main/java/com/wbrawner/simplemarkdown/view/activity/SupportActivity.kt
@@ -1,21 +1,61 @@
package com.wbrawner.simplemarkdown.view.activity
+import android.content.ActivityNotFoundException
+import android.content.Intent
+import android.net.Uri
import android.os.Bundle
-import android.util.Log
+import android.view.MenuItem
+import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
+import androidx.browser.customtabs.CustomTabsIntent
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 {
private lateinit var billingClient: BillingClient
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_support)
+ setSupportActionBar(toolbar)
+ setTitle(R.string.support_title)
+ supportActionBar?.setDisplayHomeAsUpEnabled(true)
billingClient = BillingClient.newBuilder(applicationContext)
.setListener(this)
.build()
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) {
@@ -23,36 +63,47 @@ class SupportActivity : AppCompatActivity(), BillingClientStateListener, Purchas
return
}
- // The billing client is ready. You can query purchases here.
- val skuList = ArrayList()
- skuList.add("support_the_developer")
- val params = SkuDetailsParams.newBuilder()
- params.setSkusList(skuList).setType(BillingClient.SkuType.INAPP)
- billingClient.querySkuDetailsAsync(params.build()) { responseCode1, skuDetailsList ->
+ val skuDetails = SkuDetailsParams.newBuilder()
+ .setSkusList(listOf("support_the_developer", "tip_coffee", "tip_beer"))
+ .setType(BillingClient.SkuType.INAPP)
+ .build()
+ billingClient.querySkuDetailsAsync(skuDetails) { skuDetailsResponseCode, skuDetailsList ->
// Process the result.
- if (responseCode1 != BillingClient.BillingResponse.OK || skuDetailsList == null) {
+ if (skuDetailsResponseCode != BillingClient.BillingResponse.OK || skuDetailsList.isNullOrEmpty()) {
return@querySkuDetailsAsync
}
- val skuDetails = skuDetailsList!!.get(0)
- val sku = skuDetails.getSku()
- val price = skuDetails.getPrice()
- Log.d("SimpleMarkdown",
- "Got product with sku: " + sku + " and price: " + price + " " + skuDetails.getPriceCurrencyCode())
- val flowParams = BillingFlowParams.newBuilder()
- .setSkuDetails(skuDetails)
- .build()
- val responseCode2 = billingClient.launchBillingFlow(this, flowParams)
+ skuDetailsList.sortedBy { it.priceAmountMicros }.forEach { skuDetails ->
+ val supportButton = MaterialButton(this@SupportActivity)
+ supportButton.text = getString(
+ R.string.support_button_purchase,
+ skuDetails.title,
+ skuDetails.price
+ )
+ supportButton.setOnClickListener {
+ val flowParams = BillingFlowParams.newBuilder()
+ .setSkuDetails(skuDetails)
+ .build()
+ billingClient.launchBillingFlow(this, flowParams)
+ }
+ supportButtons.addView(supportButton)
+ }
}
}
override fun onBillingServiceDisconnected() {
- // TODO: Set a flag and just try again later
billingClient.startConnection(this)
}
override fun onPurchasesUpdated(responseCode: Int, purchases: List?) {
-
+ purchases?.forEach { purchase ->
+ billingClient.consumeAsync(purchase.purchaseToken) { _, _ ->
+ Toast.makeText(
+ this@SupportActivity,
+ getString(R.string.support_thank_you),
+ Toast.LENGTH_SHORT
+ ).show()
+ }
+ }
}
-
}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_favorite_black_24dp.xml b/app/src/main/res/drawable/ic_favorite_black_24dp.xml
new file mode 100644
index 0000000..17cea92
--- /dev/null
+++ b/app/src/main/res/drawable/ic_favorite_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_menu_black_24dp.xml b/app/src/main/res/drawable/ic_menu_black_24dp.xml
new file mode 100644
index 0000000..bdceee4
--- /dev/null
+++ b/app/src/main/res/drawable/ic_menu_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/layout/activity_support.xml b/app/src/main/res/layout/activity_support.xml
new file mode 100644
index 0000000..e2d812b
--- /dev/null
+++ b/app/src/main/res/layout/activity_support.xml
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 776578d..afeaf77 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -5,4 +5,7 @@
#d32f2f
#FFFFFF
#000000
+ #24292e
+ #FFFFFFFF
+ #689f38
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index c5d8808..499ba52 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -2,8 +2,6 @@
Simple Markdown
Markdown
- ca-app-pub-3319579963502409~4576405307
-
Settings
Help
Edit
@@ -65,6 +63,20 @@
Would you like to save your changes?
Discard
Save as…
+ 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!
+ View SimpleMarkdown on GitHub
+ Support SimpleMarkdown
+ %1$s – %2$s
+ Rate SimpleMarkdown
+ Thank you so much for your support!
+ Heart
- @string/pref_value_light
- @string/pref_value_dark
diff --git a/build.gradle b/build.gradle
index ca0c53d..b8fecd6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -10,7 +10,7 @@ buildscript {
}
}
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 'io.fabric.tools:gradle:1.31.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"