Donation and other Actions Implemented

This commit is contained in:
shabinder 2021-01-02 19:23:10 +05:30
parent d91313370a
commit e056344d28
9 changed files with 122 additions and 34 deletions

View File

@ -5,6 +5,8 @@ plugins {
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
id 'kotlinx-serialization'
id 'com.google.gms.google-services'
id 'com.google.firebase.crashlytics'
}
kapt {
@ -127,9 +129,6 @@ dependencies {
implementation "com.squareup.retrofit2:converter-scalars:2.9.0"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.1"
//Glide-Image Loading
implementation "dev.chrisbanes.accompanist:accompanist-glide:0.4.1"
//Coil-Image Loading
implementation "dev.chrisbanes.accompanist:accompanist-coil:$coil_version"
implementation "dev.chrisbanes.accompanist:accompanist-insets:$coil_version"
@ -140,9 +139,16 @@ dependencies {
//Extras
implementation 'me.xdrop:fuzzywuzzy:1.3.1'
implementation 'com.mpatric:mp3agic:0.9.1'
implementation 'com.razorpay:checkout:1.6.4'
implementation "com.github.amitbd1508:AppUpdater:4.1.0"
implementation "androidx.tonyodev.fetch2:xfetch2:3.1.5"
implementation 'com.github.sealedtx:java-youtube-downloader:2.4.4'
//Crashlytics & Analytics
implementation platform('com.google.firebase:firebase-bom:26.2.0')
implementation 'com.google.firebase:firebase-crashlytics-ktx'
implementation 'com.google.firebase:firebase-analytics-ktx'
//Test
testImplementation 'junit:junit:4.13.1'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'

View File

@ -29,6 +29,11 @@ import androidx.lifecycle.ViewModelProvider
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.example.jetcaster.util.verticalGradientScrim
import com.github.javiersantos.appupdater.AppUpdater
import com.github.javiersantos.appupdater.enums.Display
import com.github.javiersantos.appupdater.enums.UpdateFrom
import com.razorpay.Checkout
import com.razorpay.PaymentResultListener
import com.shabinder.spotiflyer.models.DownloadStatus
import com.shabinder.spotiflyer.navigation.ComposeNavigation
import com.shabinder.spotiflyer.navigation.navigateToTrackList
@ -43,14 +48,13 @@ import dagger.hilt.android.AndroidEntryPoint
import dev.chrisbanes.accompanist.insets.ProvideWindowInsets
import dev.chrisbanes.accompanist.insets.statusBarsHeight
import kotlinx.coroutines.*
import okhttp3.Dispatcher
import javax.inject.Inject
/*
* This is App's God Activity
* */
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
class MainActivity : AppCompatActivity(), PaymentResultListener {
private lateinit var navController: NavHostController
private lateinit var updateUIReceiver: BroadcastReceiver
@ -98,13 +102,25 @@ class MainActivity : AppCompatActivity() {
}
private fun initialize() {
Checkout.preload(applicationContext)
requestStoragePermission()
disableDozeMode()
//checkIfLatestVersion()
checkIfLatestVersion()
createDirectories()
handleIntentFromExternalActivity()
}
private fun checkIfLatestVersion() {
AppUpdater(this,0).run {
setDisplay(Display.NOTIFICATION)
showAppUpdated(true)//true:Show App is Updated Dialog
setUpdateFrom(UpdateFrom.XML)
setUpdateXML("https://raw.githubusercontent.com/Shabinder/SpotiFlyer/master/app/src/main/res/xml/app_update.xml")
setCancelable(false)
start()
}
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
handleIntentFromExternalActivity(intent)
@ -208,7 +224,6 @@ class MainActivity : AppCompatActivity() {
val string = it.replace("\n".toRegex(), " ")
val link = filterLinkRegex.find(string)?.value.toString()
log("Intent Link",link)
sharedViewModel.updateLink(link)
navController.navigateToTrackList(link)
}
}
@ -227,6 +242,24 @@ class MainActivity : AppCompatActivity() {
init {
instance = this
}
override fun onPaymentError(errorCode: Int, response: String?) {
try{
showDialog("Payment Failed", "$response")
}catch (e: Exception){
log("Razorpay Payment","Exception in onPaymentSuccess $response")
}
}
override fun onPaymentSuccess(razorpayPaymentId: String?) {
try{
showDialog("Payment Successful", "ThankYou!")
}catch (e: Exception){
showDialog("Razorpay Payment, Error Occurred.")
log("Razorpay Payment","Exception in onPaymentSuccess, ${e.message}")
}
}
}
@Composable

View File

@ -36,7 +36,7 @@ data class TrackDetails(
var albumArtURL: String,
var source: Source,
var downloaded: DownloadStatus = DownloadStatus.NotDownloaded,
var progress: Int = 0,
var progress: Int = 2,//2 for visual progress bar hint
var outputFile: String,
var videoID:String? = null
):Parcelable

View File

@ -8,6 +8,7 @@ import androidx.navigation.compose.*
import androidx.navigation.compose.popUpTo
import com.shabinder.spotiflyer.ui.home.Home
import com.shabinder.spotiflyer.ui.tracklist.TrackList
import com.shabinder.spotiflyer.utils.sharedViewModel
@Composable
fun ComposeNavigation(navController: NavHostController) {
@ -36,6 +37,7 @@ fun ComposeNavigation(navController: NavHostController) {
}
fun NavController.navigateToTrackList(link:String, singleInstance: Boolean = true, inclusive:Boolean = false) {
sharedViewModel.updateLink(link)
navigate("track_list/$link") {
launchSingleTop = singleInstance
popUpTo(route = "home") {

View File

@ -1,5 +1,6 @@
package com.shabinder.spotiflyer.ui.home
import android.content.Intent
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
@ -30,15 +31,19 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.net.toUri
import androidx.navigation.NavController
import com.razorpay.Checkout
import com.shabinder.spotiflyer.R
import com.shabinder.spotiflyer.database.DownloadRecord
import com.shabinder.spotiflyer.navigation.navigateToTrackList
import com.shabinder.spotiflyer.ui.SpotiFlyerTypography
import com.shabinder.spotiflyer.ui.colorAccent
import com.shabinder.spotiflyer.ui.colorPrimary
import com.shabinder.spotiflyer.utils.mainActivity
import com.shabinder.spotiflyer.utils.openPlatform
import com.shabinder.spotiflyer.utils.sharedViewModel
import dev.chrisbanes.accompanist.glide.GlideImage
import com.shabinder.spotiflyer.utils.showDialog
import dev.chrisbanes.accompanist.coil.CoilImage
import org.json.JSONObject
@Composable
fun Home(navController: NavController, modifier: Modifier = Modifier) {
@ -137,7 +142,11 @@ fun AboutColumn(modifier: Modifier = Modifier) {
)
}
}
Row(modifier = modifier.fillMaxWidth().padding(vertical = 6.dp),verticalAlignment = Alignment.CenterVertically) {
Row(
modifier = modifier.fillMaxWidth().padding(vertical = 6.dp)
.clickable(onClick = { openPlatform("http://github.com/Shabinder/SpotiFlyer") }),
verticalAlignment = Alignment.CenterVertically
) {
Icon(Icons.Rounded.Flag.copy(defaultHeight = 32.dp,defaultWidth = 32.dp))
Spacer(modifier = Modifier.padding(start = 16.dp))
Column {
@ -151,7 +160,11 @@ fun AboutColumn(modifier: Modifier = Modifier) {
)
}
}
Row(modifier = modifier.fillMaxWidth().padding(vertical = 6.dp),verticalAlignment = Alignment.CenterVertically) {
Row(
modifier = modifier.fillMaxWidth().padding(vertical = 6.dp)
.clickable(onClick = { startPayment() }),
verticalAlignment = Alignment.CenterVertically
) {
Icon(Icons.Rounded.CardGiftcard.copy(defaultHeight = 32.dp,defaultWidth = 32.dp))
Spacer(modifier = Modifier.padding(start = 16.dp))
Column {
@ -165,7 +178,20 @@ fun AboutColumn(modifier: Modifier = Modifier) {
)
}
}
Row(modifier = modifier.fillMaxWidth().padding(vertical = 6.dp),verticalAlignment = Alignment.CenterVertically) {
Row(
modifier = modifier.fillMaxWidth().padding(vertical = 6.dp)
.clickable(onClick = {
val sendIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_TEXT, "Hey, checkout this excellent Music Downloader http://github.com/Shabinder/SpotiFlyer")
type = "text/plain"
}
val shareIntent = Intent.createChooser(sendIntent, null)
mainActivity.startActivity(shareIntent)
}),
verticalAlignment = Alignment.CenterVertically
) {
Icon(Icons.Rounded.Share.copy(defaultHeight = 32.dp,defaultWidth = 32.dp))
Spacer(modifier = Modifier.padding(start = 16.dp))
Column {
@ -224,7 +250,7 @@ fun HistoryColumn(
fun DownloadRecordItem(item: DownloadRecord,navController: NavController) {
Row(verticalAlignment = Alignment.CenterVertically,modifier = Modifier.fillMaxWidth().padding(end = 8.dp)) {
val imgUri = item.coverUrl.toUri().buildUpon().scheme("https").build()
GlideImage(
CoilImage(
data = imgUri,
//Loading Placeholder Makes Scrolling very stuttery
// loading = { Image(vectorResource(id = R.drawable.ic_song_placeholder)) },
@ -246,11 +272,43 @@ fun DownloadRecordItem(item: DownloadRecord,navController: NavController) {
}
Image(
imageVector = vectorResource(id = R.drawable.ic_share_open),
modifier = Modifier.clickable(onClick = { navController.navigateToTrackList(item.link) })
modifier = Modifier.clickable(onClick = {
navController.navigateToTrackList(item.link)
})
)
}
}
private fun startPayment() {
/*
* You need to pass current activity in order to let Razorpay create CheckoutActivity
* */
val co = Checkout().apply {
setKeyID("rzp_live_3ZQeoFYOxjmXye")
setImage(R.drawable.ic_launcher_foreground)
}
try {
val preFill = JSONObject()
val options = JSONObject().apply {
put("name","SpotiFlyer")
put("description","Thanks For the Donation!")
//You can omit the image option to fetch the image from dashboard
//put("image","https://github.com/Shabinder/SpotiFlyer/raw/master/app/SpotifyDownload.png")
put("currency","INR")
put("amount","4900")
put("prefill",preFill)
}
co.open(mainActivity,options)
}catch (e: Exception){
showDialog("Error in payment: "+ e.message)
e.printStackTrace()
}
}
@Composable
fun AuthenticationBanner(isAuthenticated: Boolean, modifier: Modifier) {

View File

@ -10,6 +10,7 @@ import kotlinx.coroutines.withContext
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import kotlinx.coroutines.delay
class HomeViewModel : ViewModel() {
@ -25,6 +26,7 @@ class HomeViewModel : ViewModel() {
fun getDownloadRecordList() {
viewModelScope.launch {
withContext(Dispatchers.IO){
delay(100) //TEMP
downloadRecordList = sharedViewModel.databaseDAO.getRecord()
}
}

View File

@ -2,38 +2,20 @@ package com.shabinder.spotiflyer.utils
import android.content.Context
import android.content.Intent
import android.graphics.drawable.Drawable
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.os.Build
import android.util.Log
import android.widget.ImageView
import android.widget.Toast
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.vectorResource
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.toBitmap
import androidx.core.net.toUri
import com.bumptech.glide.Glide
import com.bumptech.glide.RequestManager
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.Target
import com.shabinder.spotiflyer.MainActivity
import com.shabinder.spotiflyer.R
import com.shabinder.spotiflyer.models.TrackDetails
import com.shabinder.spotiflyer.models.spotify.Source
import com.shabinder.spotiflyer.worker.ForegroundService
import dev.chrisbanes.accompanist.glide.GlideImage
import dev.chrisbanes.accompanist.glide.GlideImageDefaults
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
import java.io.IOException
/**
* mainActivity Instance to use whereEver Needed , as Its God Activity.

View File

@ -117,8 +117,10 @@ class ForegroundService : Service(){
"query" -> {
val response = Intent().apply {
action = "query_result"
synchronized(allTracksStatus){
putExtra("tracks", allTracksStatus)
}
}
sendBroadcast(response)
}
}

View File

@ -23,6 +23,9 @@ buildscript {
classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version"
//Kotlinx-Serialization
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
//Crashlytics & Analytics
classpath 'com.google.gms:google-services:4.3.4'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}