Added F-Droid FOSS flavor

This commit is contained in:
Prathamesh More 2022-06-14 23:05:59 +05:30
parent bc39d3a462
commit 2a5e6d7756
42 changed files with 243 additions and 360 deletions

View file

@ -41,6 +41,15 @@ android {
versionNameSuffix ' DEBUG' versionNameSuffix ' DEBUG'
} }
} }
flavorDimensions "version"
productFlavors {
normal {
dimension "version"
}
fdroid {
dimension "version"
}
}
buildFeatures{ buildFeatures{
viewBinding true viewBinding true
@ -95,11 +104,11 @@ dependencies {
implementation 'androidx.core:core-ktx:1.8.0' implementation 'androidx.core:core-ktx:1.8.0'
implementation 'androidx.palette:palette-ktx:1.0.0' implementation 'androidx.palette:palette-ktx:1.0.0'
//Cast Dependencies
implementation 'androidx.mediarouter:mediarouter:1.3.0' implementation 'androidx.mediarouter:mediarouter:1.3.0'
implementation 'com.google.android.gms:play-services-cast-framework:21.0.1' //Cast Dependencies
normalImplementation 'com.google.android.gms:play-services-cast-framework:21.0.1'
//WebServer by NanoHttpd //WebServer by NanoHttpd
implementation "org.nanohttpd:nanohttpd:2.3.1" normalImplementation "org.nanohttpd:nanohttpd:2.3.1"
implementation "androidx.navigation:navigation-runtime-ktx:$navigation_version" implementation "androidx.navigation:navigation-runtime-ktx:$navigation_version"
implementation "androidx.navigation:navigation-fragment-ktx:$navigation_version" implementation "androidx.navigation:navigation-fragment-ktx:$navigation_version"
@ -117,8 +126,8 @@ dependencies {
implementation "androidx.core:core-splashscreen:1.0.0-rc01" implementation "androidx.core:core-splashscreen:1.0.0-rc01"
implementation 'com.google.android.play:feature-delivery:2.0.0' normalImplementation 'com.google.android.play:feature-delivery:2.0.0'
implementation 'com.google.android.play:review:2.0.0' normalImplementation 'com.google.android.play:review:2.0.0'
implementation "com.google.android.material:material:$mdc_version" implementation "com.google.android.material:material:$mdc_version"
@ -160,7 +169,7 @@ dependencies {
implementation 'org.eclipse.mylyn.github:org.eclipse.egit.github.core:2.1.5' implementation 'org.eclipse.mylyn.github:org.eclipse.egit.github.core:2.1.5'
implementation 'com.github.Adonai:jaudiotagger:2.3.15' implementation 'com.github.Adonai:jaudiotagger:2.3.15'
implementation 'com.anjlab.android.iab.v3:library:2.0.3' normalImplementation 'com.anjlab.android.iab.v3:library:2.0.3'
implementation 'com.r0adkll:slidableactivity:2.1.0' implementation 'com.r0adkll:slidableactivity:2.1.0'
implementation 'com.heinrichreimersoftware:material-intro:2.0.0' implementation 'com.heinrichreimersoftware:material-intro:2.0.0'
implementation 'com.github.dhaval2404:imagepicker:2.1' implementation 'com.github.dhaval2404:imagepicker:2.1'

View file

@ -0,0 +1,5 @@
package code.name.monkey.retromusic.activities.base
abstract class AbsCastActivity : AbsSlidingMusicPanelActivity() {
}

View file

@ -0,0 +1,9 @@
package code.name.monkey.retromusic.billing
class BillingManager {
fun release() {}
val isProVersion: Boolean
get() = true
}

View file

@ -0,0 +1,6 @@
package code.name.monkey.retromusic.cast
import android.content.Context
@Suppress("UNUSED_PARAMETER")
class RetroWebServer(context: Context)

View file

@ -0,0 +1,15 @@
@file:Suppress("UNUSED_PARAMETER", "unused")
package code.name.monkey.retromusic.extensions
import android.content.Context
import android.view.Menu
import androidx.fragment.app.FragmentActivity
fun Context.setUpMediaRouteButton(menu: Menu) {}
fun FragmentActivity.installLanguageAndRecreate(code: String) {}
fun Context.goToProVersion() {}
fun Context.installSplitCompat() {}

View file

@ -0,0 +1,47 @@
package code.name.monkey.retromusic.service
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.service.playback.Playback
// Empty CastPlayer implementation
class CastPlayer : Playback {
override val isInitialized: Boolean
get() = true
override val isPlaying: Boolean
get() = true
override val audioSessionId: Int
get() = 0
override fun setDataSource(
song: Song,
force: Boolean,
completion: (success: Boolean) -> Unit,
) {
}
override fun setNextDataSource(path: String?) {}
override var callbacks: Playback.PlaybackCallbacks? = null
override fun start() = true
override fun stop() {}
override fun release() {}
override fun pause(): Boolean = true
override fun duration() = 0
override fun position() = 0
override fun seek(whereto: Int) = whereto
override fun setVolume(vol: Float) = true
override fun setAudioSessionId(sessionId: Int) = true
override fun setCrossFadeDuration(duration: Int) {}
override fun setPlaybackSpeedPitch(speed: Float, pitch: Float) {}
}

View file

@ -0,0 +1,8 @@
package code.name.monkey.retromusic.util
import android.content.Context
@Suppress("UNUSED_PARAMETER")
object AppRater {
fun appLaunched(context: Context) {}
}

View file

@ -120,7 +120,6 @@
<activity android:name=".activities.tageditor.SongTagEditorActivity" /> <activity android:name=".activities.tageditor.SongTagEditorActivity" />
<activity android:name=".activities.SupportDevelopmentActivity" /> <activity android:name=".activities.SupportDevelopmentActivity" />
<activity android:name=".activities.LicenseActivity" /> <activity android:name=".activities.LicenseActivity" />
<activity android:name=".activities.PurchaseActivity" />
<activity android:name=".activities.bugreport.BugReportActivity" /> <activity android:name=".activities.bugreport.BugReportActivity" />
<activity android:name=".activities.ShareInstagramStory" /> <activity android:name=".activities.ShareInstagramStory" />
<activity android:name=".activities.DriveModeActivity" /> <activity android:name=".activities.DriveModeActivity" />

View file

@ -19,20 +19,17 @@ import androidx.preference.PreferenceManager
import cat.ereza.customactivityoncrash.config.CaocConfig import cat.ereza.customactivityoncrash.config.CaocConfig
import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.VersionUtils import code.name.monkey.appthemehelper.util.VersionUtils
import code.name.monkey.retromusic.Constants.PRO_VERSION_PRODUCT_ID
import code.name.monkey.retromusic.activities.ErrorActivity import code.name.monkey.retromusic.activities.ErrorActivity
import code.name.monkey.retromusic.activities.MainActivity import code.name.monkey.retromusic.activities.MainActivity
import code.name.monkey.retromusic.appshortcuts.DynamicShortcutManager import code.name.monkey.retromusic.appshortcuts.DynamicShortcutManager
import code.name.monkey.retromusic.extensions.showToast import code.name.monkey.retromusic.billing.BillingManager
import code.name.monkey.retromusic.helper.WallpaperAccentManager import code.name.monkey.retromusic.helper.WallpaperAccentManager
import com.anjlab.android.iab.v3.BillingProcessor
import com.anjlab.android.iab.v3.PurchaseInfo
import org.koin.android.ext.koin.androidContext import org.koin.android.ext.koin.androidContext
import org.koin.core.context.startKoin import org.koin.core.context.startKoin
class App : Application() { class App : Application() {
lateinit var billingProcessor: BillingProcessor lateinit var billingManager: BillingManager
private val wallpaperAccentManager = WallpaperAccentManager(this) private val wallpaperAccentManager = WallpaperAccentManager(this)
override fun onCreate() { override fun onCreate() {
@ -55,33 +52,18 @@ class App : Application() {
if (VersionUtils.hasNougatMR()) if (VersionUtils.hasNougatMR())
DynamicShortcutManager(this).initDynamicShortcuts() DynamicShortcutManager(this).initDynamicShortcuts()
// automatically restores purchases
billingProcessor = BillingProcessor(
this, BuildConfig.GOOGLE_PLAY_LICENSING_KEY,
object : BillingProcessor.IBillingHandler {
override fun onProductPurchased(productId: String, details: PurchaseInfo?) {}
override fun onPurchaseHistoryRestored() {
showToast(R.string.restored_previous_purchase_please_restart)
}
override fun onBillingError(errorCode: Int, error: Throwable?) {}
override fun onBillingInitialized() {}
})
// setting Error activity // setting Error activity
CaocConfig.Builder.create().errorActivity(ErrorActivity::class.java) CaocConfig.Builder.create().errorActivity(ErrorActivity::class.java)
.restartActivity(MainActivity::class.java).apply() .restartActivity(MainActivity::class.java).apply()
// Set Default values for now playing preferences // Set Default values for now playing preferences
// This will reduce start time for now playing settings fragment as Preference listener of AbsSlidingMusicPanelActivity won't be called // This will reduce startup time for now playing settings fragment as Preference listener of AbsSlidingMusicPanelActivity won't be called
PreferenceManager.setDefaultValues(this, R.xml.pref_now_playing_screen, false) PreferenceManager.setDefaultValues(this, R.xml.pref_now_playing_screen, false)
} }
override fun onTerminate() { override fun onTerminate() {
super.onTerminate() super.onTerminate()
billingProcessor.release() billingManager.release()
wallpaperAccentManager.release() wallpaperAccentManager.release()
} }
@ -93,9 +75,7 @@ class App : Application() {
} }
fun isProVersion(): Boolean { fun isProVersion(): Boolean {
return BuildConfig.DEBUG || instance?.billingProcessor!!.isPurchased( return BuildConfig.DEBUG || instance?.billingManager!!.isProVersion
PRO_VERSION_PRODUCT_ID
)
} }
} }
} }

View file

@ -14,41 +14,23 @@
*/ */
package code.name.monkey.retromusic.activities package code.name.monkey.retromusic.activities
import android.graphics.Paint
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.view.isVisible
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.BuildConfig
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.base.AbsThemeActivity import code.name.monkey.retromusic.activities.base.AbsThemeActivity
import code.name.monkey.retromusic.databinding.ActivityDonationBinding import code.name.monkey.retromusic.databinding.ActivityDonationBinding
import code.name.monkey.retromusic.databinding.ItemDonationOptionBinding import code.name.monkey.retromusic.extensions.setStatusBarColorAuto
import code.name.monkey.retromusic.extensions.* import code.name.monkey.retromusic.extensions.setTaskDescriptionColorAuto
import com.anjlab.android.iab.v3.BillingProcessor import code.name.monkey.retromusic.extensions.surfaceColor
import com.anjlab.android.iab.v3.PurchaseInfo
import com.anjlab.android.iab.v3.SkuDetails
class SupportDevelopmentActivity : AbsThemeActivity(), BillingProcessor.IBillingHandler { class SupportDevelopmentActivity : AbsThemeActivity() {
lateinit var binding: ActivityDonationBinding lateinit var binding: ActivityDonationBinding
companion object { companion object {
val TAG: String = SupportDevelopmentActivity::class.java.simpleName val TAG: String = SupportDevelopmentActivity::class.java.simpleName
const val DONATION_PRODUCT_IDS = R.array.donation_ids
} }
var billingProcessor: BillingProcessor? = null
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) { if (item.itemId == android.R.id.home) {
onBackPressed() onBackPressed()
@ -57,11 +39,6 @@ class SupportDevelopmentActivity : AbsThemeActivity(), BillingProcessor.IBilling
return super.onOptionsItemSelected(item) return super.onOptionsItemSelected(item)
} }
fun donate(i: Int) {
val ids = resources.getStringArray(DONATION_PRODUCT_IDS)
billingProcessor?.purchase(this, ids[i])
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityDonationBinding.inflate(layoutInflater) binding = ActivityDonationBinding.inflate(layoutInflater)
@ -72,148 +49,11 @@ class SupportDevelopmentActivity : AbsThemeActivity(), BillingProcessor.IBilling
setupToolbar() setupToolbar()
billingProcessor = BillingProcessor(this, BuildConfig.GOOGLE_PLAY_LICENSING_KEY, this)
TintHelper.setTint(binding.progress, accentColor())
binding.donation.setTextColor(accentColor())
} }
private fun setupToolbar() { private fun setupToolbar() {
val toolbarColor = surfaceColor() binding.toolbar.setBackgroundColor(surfaceColor())
binding.toolbar.setBackgroundColor(toolbarColor)
ToolbarContentTintHelper.colorBackButton(binding.toolbar) ToolbarContentTintHelper.colorBackButton(binding.toolbar)
setSupportActionBar(binding.toolbar) setSupportActionBar(binding.toolbar)
} }
override fun onBillingInitialized() {
loadSkuDetails()
}
private fun loadSkuDetails() {
binding.progressContainer.isVisible = true
binding.recyclerView.isVisible = false
val ids = resources.getStringArray(DONATION_PRODUCT_IDS)
billingProcessor!!.getPurchaseListingDetailsAsync(
ArrayList(listOf(*ids)),
object : BillingProcessor.ISkuDetailsResponseListener {
override fun onSkuDetailsResponse(skuDetails: MutableList<SkuDetails>?) {
if (skuDetails == null || skuDetails.isEmpty()) {
binding.progressContainer.isVisible = false
return
}
binding.progressContainer.isVisible = false
binding.recyclerView.apply {
itemAnimator = DefaultItemAnimator()
layoutManager = GridLayoutManager(this@SupportDevelopmentActivity, 2)
adapter = SkuDetailsAdapter(this@SupportDevelopmentActivity, skuDetails)
isVisible = true
}
}
override fun onSkuDetailsError(error: String?) {
Log.e(TAG, error.toString())
}
})
}
override fun onProductPurchased(productId: String, details: PurchaseInfo?) {
// loadSkuDetails();
showToast(R.string.thank_you)
}
override fun onBillingError(errorCode: Int, error: Throwable?) {
Log.e(TAG, "Billing error: code = $errorCode", error)
}
override fun onPurchaseHistoryRestored() {
// loadSkuDetails();
showToast(R.string.restored_previous_purchases)
}
override fun onDestroy() {
billingProcessor?.release()
super.onDestroy()
}
}
class SkuDetailsAdapter(
private var donationsDialog: SupportDevelopmentActivity,
objects: List<SkuDetails>,
) : RecyclerView.Adapter<SkuDetailsAdapter.ViewHolder>() {
private var skuDetailsList: List<SkuDetails> = ArrayList()
init {
skuDetailsList = objects
}
private fun getIcon(position: Int): Int {
return when (position) {
0 -> R.drawable.ic_cookie
1 -> R.drawable.ic_take_away
2 -> R.drawable.ic_take_away_coffe
3 -> R.drawable.ic_beer
4 -> R.drawable.ic_fast_food_meal
5 -> R.drawable.ic_popcorn
6 -> R.drawable.ic_card_giftcard
7 -> R.drawable.ic_food_croissant
else -> R.drawable.ic_card_giftcard
}
}
override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): ViewHolder {
return ViewHolder(
ItemDonationOptionBinding.inflate(
LayoutInflater.from(donationsDialog),
viewGroup,
false
)
)
}
override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) {
val skuDetails = skuDetailsList[i]
with(viewHolder.binding) {
itemTitle.text = skuDetails.title.replace("(Retro Music Player MP3 Player)", "")
.trim { it <= ' ' }
itemText.text = skuDetails.description
itemText.isVisible = false
itemPrice.text = skuDetails.priceText
itemImage.setImageResource(getIcon(i))
}
val purchased = donationsDialog.billingProcessor!!.isPurchased(skuDetails.productId)
val titleTextColor = if (purchased) ATHUtil.resolveColor(
donationsDialog,
android.R.attr.textColorHint
) else donationsDialog.textColorPrimary()
val contentTextColor =
if (purchased) titleTextColor else donationsDialog.textColorSecondary()
with(viewHolder.binding) {
itemTitle.setTextColor(titleTextColor)
itemText.setTextColor(contentTextColor)
itemPrice.setTextColor(titleTextColor)
strikeThrough(itemTitle, purchased)
strikeThrough(itemText, purchased)
strikeThrough(itemPrice, purchased)
}
viewHolder.itemView.isEnabled = !purchased
viewHolder.itemView.setOnClickListener { donationsDialog.donate(i) }
}
override fun getItemCount(): Int {
return skuDetailsList.size
}
class ViewHolder(val binding: ItemDonationOptionBinding) : RecyclerView.ViewHolder(binding.root)
companion object {
private fun strikeThrough(textView: TextView, strikeThrough: Boolean) {
textView.paintFlags =
if (strikeThrough) textView.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG
else textView.paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv()
}
}
} }

View file

@ -31,7 +31,6 @@ import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.maybeShowAnnoyingToasts import code.name.monkey.retromusic.util.maybeShowAnnoyingToasts
import code.name.monkey.retromusic.util.theme.getNightMode import code.name.monkey.retromusic.util.theme.getNightMode
import code.name.monkey.retromusic.util.theme.getThemeResValue import code.name.monkey.retromusic.util.theme.getThemeResValue
import com.google.android.play.core.splitcompat.SplitCompat
import java.util.* import java.util.*
abstract class AbsThemeActivity : ATHToolbarActivity(), Runnable { abstract class AbsThemeActivity : ATHToolbarActivity(), Runnable {
@ -105,6 +104,6 @@ abstract class AbsThemeActivity : ATHToolbarActivity(), Runnable {
Locale.forLanguageTag(code) Locale.forLanguageTag(code)
} }
super.attachBaseContext(LanguageContextWrapper.wrap(newBase, locale)) super.attachBaseContext(LanguageContextWrapper.wrap(newBase, locale))
SplitCompat.install(this) installSplitCompat()
} }
} }

View file

@ -95,7 +95,7 @@ class SleepTimerDialog : DialogFragment() {
shouldFinishLastSong.isVisible = false shouldFinishLastSong.isVisible = false
timerUpdater.start() timerUpdater.start()
setPositiveButton(android.R.string.ok, null) setPositiveButton(android.R.string.ok, null)
setNegativeButton(R.string.cast_stop) { _, _ -> setNegativeButton(R.string.action_cancel) { _, _ ->
timerUpdater.cancel() timerUpdater.cancel()
val previous = makeTimerPendingIntent(PendingIntent.FLAG_NO_CREATE) val previous = makeTimerPendingIntent(PendingIntent.FLAG_NO_CREATE)
if (previous != null) { if (previous != null) {

View file

@ -24,6 +24,7 @@ import androidx.recyclerview.widget.GridLayoutManager
import code.name.monkey.retromusic.EXTRA_ALBUM_ID import code.name.monkey.retromusic.EXTRA_ALBUM_ID
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.album.AlbumAdapter import code.name.monkey.retromusic.adapter.album.AlbumAdapter
import code.name.monkey.retromusic.extensions.setUpMediaRouteButton
import code.name.monkey.retromusic.extensions.surfaceColor import code.name.monkey.retromusic.extensions.surfaceColor
import code.name.monkey.retromusic.fragments.GridStyle import code.name.monkey.retromusic.fragments.GridStyle
import code.name.monkey.retromusic.fragments.ReloadType import code.name.monkey.retromusic.fragments.ReloadType
@ -41,7 +42,6 @@ import com.afollestad.materialcab.attached.AttachedCab
import com.afollestad.materialcab.attached.destroy import com.afollestad.materialcab.attached.destroy
import com.afollestad.materialcab.attached.isActive import com.afollestad.materialcab.attached.isActive
import com.afollestad.materialcab.createCab import com.afollestad.materialcab.createCab
import com.google.android.gms.cast.framework.CastButtonFactory
class AlbumsFragment : AbsRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridLayoutManager>(), class AlbumsFragment : AbsRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridLayoutManager>(),
IAlbumClickListener, ICabHolder { IAlbumClickListener, ICabHolder {
@ -169,7 +169,7 @@ class AlbumsFragment : AbsRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridL
setupLayoutMenu(layoutItem.subMenu) setupLayoutMenu(layoutItem.subMenu)
setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu) setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu)
//Setting up cast button //Setting up cast button
CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.action_cast) requireContext().setUpMediaRouteButton(menu)
} }
private fun setUpSortOrderMenu( private fun setUpSortOrderMenu(

View file

@ -25,6 +25,7 @@ import code.name.monkey.retromusic.EXTRA_ARTIST_ID
import code.name.monkey.retromusic.EXTRA_ARTIST_NAME import code.name.monkey.retromusic.EXTRA_ARTIST_NAME
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.artist.ArtistAdapter import code.name.monkey.retromusic.adapter.artist.ArtistAdapter
import code.name.monkey.retromusic.extensions.setUpMediaRouteButton
import code.name.monkey.retromusic.extensions.surfaceColor import code.name.monkey.retromusic.extensions.surfaceColor
import code.name.monkey.retromusic.fragments.GridStyle import code.name.monkey.retromusic.fragments.GridStyle
import code.name.monkey.retromusic.fragments.ReloadType import code.name.monkey.retromusic.fragments.ReloadType
@ -43,7 +44,6 @@ import com.afollestad.materialcab.attached.AttachedCab
import com.afollestad.materialcab.attached.destroy import com.afollestad.materialcab.attached.destroy
import com.afollestad.materialcab.attached.isActive import com.afollestad.materialcab.attached.isActive
import com.afollestad.materialcab.createCab import com.afollestad.materialcab.createCab
import com.google.android.gms.cast.framework.CastButtonFactory
class ArtistsFragment : AbsRecyclerViewCustomGridSizeFragment<ArtistAdapter, GridLayoutManager>(), class ArtistsFragment : AbsRecyclerViewCustomGridSizeFragment<ArtistAdapter, GridLayoutManager>(),
IArtistClickListener, IAlbumArtistClickListener, ICabHolder { IArtistClickListener, IAlbumArtistClickListener, ICabHolder {
@ -180,7 +180,7 @@ class ArtistsFragment : AbsRecyclerViewCustomGridSizeFragment<ArtistAdapter, Gri
setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu) setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu)
setupAlbumArtistMenu(menu) setupAlbumArtistMenu(menu)
//Setting up cast button //Setting up cast button
CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.action_cast) requireContext().setUpMediaRouteButton(menu)
} }
private fun setupAlbumArtistMenu(menu: Menu) { private fun setupAlbumArtistMenu(menu: Menu) {

View file

@ -26,12 +26,12 @@ import androidx.recyclerview.widget.LinearLayoutManager
import code.name.monkey.retromusic.EXTRA_GENRE import code.name.monkey.retromusic.EXTRA_GENRE
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.GenreAdapter import code.name.monkey.retromusic.adapter.GenreAdapter
import code.name.monkey.retromusic.extensions.setUpMediaRouteButton
import code.name.monkey.retromusic.fragments.ReloadType import code.name.monkey.retromusic.fragments.ReloadType
import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewFragment import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewFragment
import code.name.monkey.retromusic.interfaces.IGenreClickListener import code.name.monkey.retromusic.interfaces.IGenreClickListener
import code.name.monkey.retromusic.model.Genre import code.name.monkey.retromusic.model.Genre
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.RetroUtil
import com.google.android.gms.cast.framework.CastButtonFactory
import com.google.android.material.transition.MaterialSharedAxis import com.google.android.material.transition.MaterialSharedAxis
class class
@ -67,7 +67,7 @@ GenresFragment : AbsRecyclerViewFragment<GenreAdapter, LinearLayoutManager>(),
menu.removeItem(R.id.action_sort_order) menu.removeItem(R.id.action_sort_order)
menu.findItem(R.id.action_settings).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM) menu.findItem(R.id.action_settings).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
//Setting up cast button //Setting up cast button
CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.action_cast) requireContext().setUpMediaRouteButton(menu)
} }
override fun onResume() { override fun onResume() {

View file

@ -35,10 +35,7 @@ import code.name.monkey.retromusic.adapter.HomeAdapter
import code.name.monkey.retromusic.databinding.FragmentHomeBinding import code.name.monkey.retromusic.databinding.FragmentHomeBinding
import code.name.monkey.retromusic.dialogs.CreatePlaylistDialog import code.name.monkey.retromusic.dialogs.CreatePlaylistDialog
import code.name.monkey.retromusic.dialogs.ImportPlaylistDialog import code.name.monkey.retromusic.dialogs.ImportPlaylistDialog
import code.name.monkey.retromusic.extensions.accentColor import code.name.monkey.retromusic.extensions.*
import code.name.monkey.retromusic.extensions.dip
import code.name.monkey.retromusic.extensions.drawNextToNavbar
import code.name.monkey.retromusic.extensions.elevatedAccentColor
import code.name.monkey.retromusic.fragments.ReloadType import code.name.monkey.retromusic.fragments.ReloadType
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.glide.GlideApp import code.name.monkey.retromusic.glide.GlideApp
@ -48,7 +45,6 @@ import code.name.monkey.retromusic.interfaces.IScrollHelper
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.PreferenceUtil.userName import code.name.monkey.retromusic.util.PreferenceUtil.userName
import com.google.android.gms.cast.framework.CastButtonFactory
import com.google.android.material.shape.MaterialShapeDrawable import com.google.android.material.shape.MaterialShapeDrawable
import com.google.android.material.transition.MaterialFadeThrough import com.google.android.material.transition.MaterialFadeThrough
import com.google.android.material.transition.MaterialSharedAxis import com.google.android.material.transition.MaterialSharedAxis
@ -212,7 +208,7 @@ class HomeFragment :
ATHToolbarActivity.getToolbarBackgroundColor(binding.toolbar) ATHToolbarActivity.getToolbarBackgroundColor(binding.toolbar)
) )
//Setting up cast button //Setting up cast button
CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.action_cast) requireContext().setUpMediaRouteButton(menu)
} }
override fun scrollToTop() { override fun scrollToTop() {

View file

@ -30,11 +30,11 @@ import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.databinding.FragmentLibraryBinding import code.name.monkey.retromusic.databinding.FragmentLibraryBinding
import code.name.monkey.retromusic.dialogs.CreatePlaylistDialog import code.name.monkey.retromusic.dialogs.CreatePlaylistDialog
import code.name.monkey.retromusic.dialogs.ImportPlaylistDialog import code.name.monkey.retromusic.dialogs.ImportPlaylistDialog
import code.name.monkey.retromusic.extensions.setUpMediaRouteButton
import code.name.monkey.retromusic.extensions.whichFragment import code.name.monkey.retromusic.extensions.whichFragment
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.model.CategoryInfo import code.name.monkey.retromusic.model.CategoryInfo
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import com.google.android.gms.cast.framework.CastButtonFactory
class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) { class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) {
@ -99,7 +99,7 @@ class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) {
getToolbarBackgroundColor(binding.toolbar) getToolbarBackgroundColor(binding.toolbar)
) )
//Setting up cast button //Setting up cast button
CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.action_cast) requireContext().setUpMediaRouteButton(menu)
} }
override fun onMenuItemSelected(item: MenuItem): Boolean { override fun onMenuItemSelected(item: MenuItem): Boolean {

View file

@ -24,13 +24,13 @@ import code.name.monkey.retromusic.EXTRA_PLAYLIST
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.playlist.PlaylistAdapter import code.name.monkey.retromusic.adapter.playlist.PlaylistAdapter
import code.name.monkey.retromusic.db.PlaylistWithSongs import code.name.monkey.retromusic.db.PlaylistWithSongs
import code.name.monkey.retromusic.extensions.setUpMediaRouteButton
import code.name.monkey.retromusic.fragments.ReloadType import code.name.monkey.retromusic.fragments.ReloadType
import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewCustomGridSizeFragment import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewCustomGridSizeFragment
import code.name.monkey.retromusic.helper.SortOrder.PlaylistSortOrder import code.name.monkey.retromusic.helper.SortOrder.PlaylistSortOrder
import code.name.monkey.retromusic.interfaces.IPlaylistClickListener import code.name.monkey.retromusic.interfaces.IPlaylistClickListener
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.RetroUtil
import com.google.android.gms.cast.framework.CastButtonFactory
import com.google.android.material.transition.MaterialSharedAxis import com.google.android.material.transition.MaterialSharedAxis
class PlaylistsFragment : class PlaylistsFragment :
@ -85,7 +85,7 @@ class PlaylistsFragment :
setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu) setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu)
MenuCompat.setGroupDividerEnabled(menu, true) MenuCompat.setGroupDividerEnabled(menu, true)
//Setting up cast button //Setting up cast button
CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.action_cast) requireContext().setUpMediaRouteButton(menu)
} }
override fun onMenuItemSelected(item: MenuItem): Boolean { override fun onMenuItemSelected(item: MenuItem): Boolean {

View file

@ -26,6 +26,7 @@ import androidx.preference.PreferenceManager
import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEPreferenceFragmentCompat import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEPreferenceFragmentCompat
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.extensions.dip import code.name.monkey.retromusic.extensions.dip
import code.name.monkey.retromusic.extensions.goToProVersion
import code.name.monkey.retromusic.extensions.showToast import code.name.monkey.retromusic.extensions.showToast
import code.name.monkey.retromusic.preferences.* import code.name.monkey.retromusic.preferences.*
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
@ -39,7 +40,7 @@ abstract class AbsSettingsFragment : ATEPreferenceFragmentCompat() {
internal fun showProToastAndNavigate(message: String) { internal fun showProToastAndNavigate(message: String) {
showToast(getString(R.string.message_pro_feature, message)) showToast(getString(R.string.message_pro_feature, message))
NavigationUtil.goToProVersion(requireActivity()) requireContext().goToProVersion()
} }
internal fun setSummary(preference: Preference, value: Any?) { internal fun setSummary(preference: Preference, value: Any?) {

View file

@ -27,6 +27,7 @@ import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.databinding.FragmentMainSettingsBinding import code.name.monkey.retromusic.databinding.FragmentMainSettingsBinding
import code.name.monkey.retromusic.extensions.drawAboveSystemBarsWithPadding import code.name.monkey.retromusic.extensions.drawAboveSystemBarsWithPadding
import code.name.monkey.retromusic.extensions.goToProVersion
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
class MainSettingsFragment : Fragment(), View.OnClickListener { class MainSettingsFragment : Fragment(), View.OnClickListener {
@ -77,11 +78,11 @@ class MainSettingsFragment : Fragment(), View.OnClickListener {
binding.buyProContainer.apply { binding.buyProContainer.apply {
isGone = App.isProVersion() isGone = App.isProVersion()
setOnClickListener { setOnClickListener {
NavigationUtil.goToProVersion(requireContext()) requireContext().goToProVersion()
} }
} }
binding.buyPremium.setOnClickListener { binding.buyPremium.setOnClickListener {
NavigationUtil.goToProVersion(requireContext()) requireContext().goToProVersion()
} }
ThemeStore.accentColor(requireContext()).let { ThemeStore.accentColor(requireContext()).let {
binding.buyPremium.setTextColor(it) binding.buyPremium.setTextColor(it)

View file

@ -21,12 +21,10 @@ import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEListPreference
import code.name.monkey.retromusic.LANGUAGE_NAME import code.name.monkey.retromusic.LANGUAGE_NAME
import code.name.monkey.retromusic.LAST_ADDED_CUTOFF import code.name.monkey.retromusic.LAST_ADDED_CUTOFF
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.extensions.installLanguageAndRecreate
import code.name.monkey.retromusic.fragments.LibraryViewModel import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.ReloadType.HomeSections import code.name.monkey.retromusic.fragments.ReloadType.HomeSections
import com.google.android.play.core.splitinstall.SplitInstallManagerFactory
import com.google.android.play.core.splitinstall.SplitInstallRequest
import org.koin.androidx.viewmodel.ext.android.sharedViewModel import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import java.util.*
/** /**
* @author Hemanth S (h4h13). * @author Hemanth S (h4h13).
@ -58,21 +56,7 @@ class OtherSettingsFragment : AbsSettingsFragment() {
val languagePreference: Preference? = findPreference(LANGUAGE_NAME) val languagePreference: Preference? = findPreference(LANGUAGE_NAME)
languagePreference?.setOnPreferenceChangeListener { prefs, newValue -> languagePreference?.setOnPreferenceChangeListener { prefs, newValue ->
setSummary(prefs, newValue) setSummary(prefs, newValue)
val code = newValue.toString() requireActivity().installLanguageAndRecreate(newValue.toString())
val manager = SplitInstallManagerFactory.create(requireContext())
if (code != "auto") {
// Try to download language resources
val request =
SplitInstallRequest.newBuilder().addLanguage(Locale.forLanguageTag(code))
.build()
manager.startInstall(request)
// Recreate the activity on download complete
.addOnCompleteListener {
restartActivity()
}
} else {
requireActivity().recreate()
}
true true
} }
} }

View file

@ -21,6 +21,7 @@ import androidx.annotation.LayoutRes
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.song.SongAdapter import code.name.monkey.retromusic.adapter.song.SongAdapter
import code.name.monkey.retromusic.extensions.setUpMediaRouteButton
import code.name.monkey.retromusic.extensions.surfaceColor import code.name.monkey.retromusic.extensions.surfaceColor
import code.name.monkey.retromusic.fragments.GridStyle import code.name.monkey.retromusic.fragments.GridStyle
import code.name.monkey.retromusic.fragments.ReloadType import code.name.monkey.retromusic.fragments.ReloadType
@ -35,7 +36,6 @@ import com.afollestad.materialcab.attached.AttachedCab
import com.afollestad.materialcab.attached.destroy import com.afollestad.materialcab.attached.destroy
import com.afollestad.materialcab.attached.isActive import com.afollestad.materialcab.attached.isActive
import com.afollestad.materialcab.createCab import com.afollestad.materialcab.createCab
import com.google.android.gms.cast.framework.CastButtonFactory
class SongsFragment : AbsRecyclerViewCustomGridSizeFragment<SongAdapter, GridLayoutManager>(), class SongsFragment : AbsRecyclerViewCustomGridSizeFragment<SongAdapter, GridLayoutManager>(),
ICabHolder { ICabHolder {
@ -136,7 +136,7 @@ class SongsFragment : AbsRecyclerViewCustomGridSizeFragment<SongAdapter, GridLay
setupLayoutMenu(layoutItem.subMenu) setupLayoutMenu(layoutItem.subMenu)
setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu) setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu)
//Setting up cast button //Setting up cast button
CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.action_cast) requireContext().setUpMediaRouteButton(menu)
} }
private fun setUpSortOrderMenu(sortOrderMenu: SubMenu) { private fun setUpSortOrderMenu(sortOrderMenu: SubMenu) {

View file

@ -27,10 +27,10 @@ import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.extensions.showToast import code.name.monkey.retromusic.extensions.showToast
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.repository.SongRepository import code.name.monkey.retromusic.repository.SongRepository
import code.name.monkey.retromusic.service.CastPlayer
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.util.getExternalStorageDirectory import code.name.monkey.retromusic.util.getExternalStorageDirectory
import code.name.monkey.retromusic.util.logE import code.name.monkey.retromusic.util.logE
import com.google.android.gms.cast.framework.CastSession
import org.koin.core.component.KoinComponent import org.koin.core.component.KoinComponent
import org.koin.core.component.inject import org.koin.core.component.inject
import java.io.File import java.io.File
@ -456,8 +456,8 @@ object MusicPlayerRemote : KoinComponent {
.dropLastWhile { it.isEmpty() }.toTypedArray()[1] .dropLastWhile { it.isEmpty() }.toTypedArray()[1]
} }
fun switchToRemotePlayback(castSession: CastSession) { fun switchToRemotePlayback(castPlayer: CastPlayer) {
musicService?.switchToRemotePlayback(castSession) musicService?.switchToRemotePlayback(castPlayer)
} }
fun switchToLocalPlayback() { fun switchToLocalPlayback() {

View file

@ -81,7 +81,7 @@ class AlbumCoverStylePreferenceDialog : DialogFragment(),
if (isAlbumCoverStyle(coverStyle)) { if (isAlbumCoverStyle(coverStyle)) {
val result = getString(coverStyle.titleRes) + " theme is Pro version feature." val result = getString(coverStyle.titleRes) + " theme is Pro version feature."
showToast(result) showToast(result)
NavigationUtil.goToProVersion(requireActivity()) requireContext().goToProVersion()
} else { } else {
PreferenceUtil.albumCoverStyle = coverStyle PreferenceUtil.albumCoverStyle = coverStyle
} }

View file

@ -91,7 +91,7 @@ class NowPlayingScreenPreferenceDialog : DialogFragment(), ViewPager.OnPageChang
val result = val result =
"${getString(nowPlayingScreen.titleRes)} theme is Pro version feature." "${getString(nowPlayingScreen.titleRes)} theme is Pro version feature."
showToast(result) showToast(result)
NavigationUtil.goToProVersion(requireContext()) requireContext().goToProVersion()
} else { } else {
PreferenceUtil.nowPlayingScreen = nowPlayingScreen PreferenceUtil.nowPlayingScreen = nowPlayingScreen
} }

View file

@ -15,10 +15,10 @@
package code.name.monkey.retromusic.service package code.name.monkey.retromusic.service
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Handler import android.os.Handler
import android.os.Looper
import android.os.Message import android.os.Message
import android.os.PowerManager import android.os.PowerManager
import android.os.PowerManager.WakeLock import android.os.PowerManager.WakeLock
@ -62,8 +62,7 @@ class MediaButtonIntentReceiver : MediaButtonReceiver() {
private var mClickCounter = 0 private var mClickCounter = 0
private var mLastClickTime: Long = 0 private var mLastClickTime: Long = 0
@SuppressLint("HandlerLeak") // false alarm, handler is already static private val mHandler = object : Handler(Looper.getMainLooper()) {
private val mHandler = object : Handler() {
override fun handleMessage(msg: Message) { override fun handleMessage(msg: Message) {
when (msg.what) { when (msg.what) {

View file

@ -86,7 +86,6 @@ import code.name.monkey.retromusic.volume.OnAudioVolumeChangedListener
import com.bumptech.glide.request.target.CustomTarget import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.target.Target import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.Transition import com.bumptech.glide.request.transition.Transition
import com.google.android.gms.cast.framework.CastSession
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers.Default import kotlinx.coroutines.Dispatchers.Default
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
@ -1171,8 +1170,8 @@ class MusicService : MediaBrowserServiceCompat(),
playbackManager.switchToLocalPlayback(this::restorePlaybackState) playbackManager.switchToLocalPlayback(this::restorePlaybackState)
} }
fun switchToRemotePlayback(castSession: CastSession) { fun switchToRemotePlayback(castPlayer: CastPlayer) {
playbackManager.switchToRemotePlayback(castSession, this::restorePlaybackState) playbackManager.switchToRemotePlayback(castPlayer, this::restorePlaybackState)
} }
private fun restorePlaybackState(wasPlaying: Boolean, progress: Int) { private fun restorePlaybackState(wasPlaying: Boolean, progress: Int) {

View file

@ -8,7 +8,6 @@ import code.name.monkey.retromusic.service.playback.Playback
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.PreferenceUtil.playbackPitch import code.name.monkey.retromusic.util.PreferenceUtil.playbackPitch
import code.name.monkey.retromusic.util.PreferenceUtil.playbackSpeed import code.name.monkey.retromusic.util.PreferenceUtil.playbackSpeed
import com.google.android.gms.cast.framework.CastSession
class PlaybackManager(val context: Context) { class PlaybackManager(val context: Context) {
@ -160,11 +159,11 @@ class PlaybackManager(val context: Context) {
} }
fun switchToRemotePlayback( fun switchToRemotePlayback(
castSession: CastSession, castPlayer: CastPlayer,
onChange: (wasPlaying: Boolean, progress: Int) -> Unit, onChange: (wasPlaying: Boolean, progress: Int) -> Unit,
) { ) {
playbackLocation = PlaybackLocation.REMOTE playbackLocation = PlaybackLocation.REMOTE
switchToPlayback(CastPlayer(castSession), onChange) switchToPlayback(castPlayer, onChange)
} }
private fun switchToPlayback( private fun switchToPlayback(

View file

@ -39,12 +39,6 @@ object NavigationUtil {
) )
} }
fun goToProVersion(context: Context) {
context.startActivity(
Intent(context, PurchaseActivity::class.java), null
)
}
fun goToSupportDevelopment(activity: Activity) { fun goToSupportDevelopment(activity: Activity) {
activity.startActivity( activity.startActivity(
Intent(activity, SupportDevelopmentActivity::class.java), null Intent(activity, SupportDevelopmentActivity::class.java), null

View file

@ -1,33 +0,0 @@
package code.name.monkey.retromusic.util
import android.content.Context
import android.content.Intent
import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.activities.PurchaseActivity
object PremiumShow {
private const val PREF_NAME = "premium_show"
private const val LAUNCH_COUNT = "launch_count"
private const val DATE_FIRST_LAUNCH = "date_first_launch"
@JvmStatic
fun launch(context: Context) {
val pref = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
if (App.isProVersion()) {
return
}
val prefEditor = pref.edit()
val launchCount = pref.getLong(LAUNCH_COUNT, 0) + 1
prefEditor.putLong(LAUNCH_COUNT, launchCount)
var dateLaunched = pref.getLong(DATE_FIRST_LAUNCH, 0)
if (dateLaunched == 0L) {
dateLaunched = System.currentTimeMillis()
prefEditor.putLong(DATE_FIRST_LAUNCH, dateLaunched)
}
if (System.currentTimeMillis() >= dateLaunched + 2 * 24 * 60 * 60 * 1000) {
context.startActivity(Intent(context, PurchaseActivity::class.java), null)
}
prefEditor.apply()
}
}

View file

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fitsSystemWindows="true"> android:fitsSystemWindows="true">
@ -31,52 +30,5 @@
android:overScrollMode="@integer/overScrollMode" android:overScrollMode="@integer/overScrollMode"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"> app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/donation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:text="@string/donation_header"
android:textAppearance="@style/TextViewSubtitle2"
android:textColor="?attr/colorAccent" />
<LinearLayout
android:id="@+id/progressContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:padding="12dp">
<ProgressBar
android:id="@+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true" />
<com.google.android.material.textview.MaterialTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="start"
android:paddingLeft="16dp"
android:text="@string/loading_products"
android:textAppearance="@style/TextViewCaption"
tools:ignore="RtlHardcoded,RtlSymmetry" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="6dp"
android:paddingEnd="6dp"
android:scrollbarStyle="outsideOverlay" />
</LinearLayout>
</androidx.core.widget.NestedScrollView> </androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="code.name.monkey.retromusic">
<application tools:ignore="MissingApplicationIcon">
<activity android:name=".activities.PurchaseActivity"/>
</application>
</manifest>

View file

@ -1,17 +1,3 @@
/*
* Copyright (c) 2020 Hemanth Savarla.
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
*/
package code.name.monkey.retromusic.activities package code.name.monkey.retromusic.activities
import android.content.res.ColorStateList import android.content.res.ColorStateList
@ -22,7 +8,7 @@ import android.view.MenuItem
import code.name.monkey.appthemehelper.util.MaterialUtil import code.name.monkey.appthemehelper.util.MaterialUtil
import code.name.monkey.retromusic.App import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.BuildConfig import code.name.monkey.retromusic.BuildConfig
import code.name.monkey.retromusic.Constants.PRO_VERSION_PRODUCT_ID import code.name.monkey.retromusic.Constants
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.base.AbsThemeActivity import code.name.monkey.retromusic.activities.base.AbsThemeActivity
import code.name.monkey.retromusic.databinding.ActivityProVersionBinding import code.name.monkey.retromusic.databinding.ActivityProVersionBinding
@ -58,7 +44,7 @@ class PurchaseActivity : AbsThemeActivity(), BillingProcessor.IBillingHandler {
restorePurchase() restorePurchase()
} }
binding.purchaseButton.setOnClickListener { binding.purchaseButton.setOnClickListener {
billingProcessor.purchase(this@PurchaseActivity, PRO_VERSION_PRODUCT_ID) billingProcessor.purchase(this@PurchaseActivity, Constants.PRO_VERSION_PRODUCT_ID)
} }
binding.bannerContainer.backgroundTintList = binding.bannerContainer.backgroundTintList =
ColorStateList.valueOf(accentColor()) ColorStateList.valueOf(accentColor())
@ -116,4 +102,4 @@ class PurchaseActivity : AbsThemeActivity(), BillingProcessor.IBillingHandler {
companion object { companion object {
private const val TAG: String = "PurchaseActivity" private const val TAG: String = "PurchaseActivity"
} }
} }

View file

@ -3,6 +3,7 @@ package code.name.monkey.retromusic.activities.base
import code.name.monkey.retromusic.cast.RetroSessionManagerListener import code.name.monkey.retromusic.cast.RetroSessionManagerListener
import code.name.monkey.retromusic.cast.RetroWebServer import code.name.monkey.retromusic.cast.RetroWebServer
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.service.CastPlayer
import com.google.android.gms.cast.framework.CastContext import com.google.android.gms.cast.framework.CastContext
import com.google.android.gms.cast.framework.CastSession import com.google.android.gms.cast.framework.CastSession
import com.google.android.gms.common.ConnectionResult import com.google.android.gms.common.ConnectionResult
@ -37,7 +38,7 @@ abstract class AbsCastActivity : AbsSlidingMusicPanelActivity() {
override fun onSessionStarted(castSession: CastSession, p1: String) { override fun onSessionStarted(castSession: CastSession, p1: String) {
invalidateOptionsMenu() invalidateOptionsMenu()
mCastSession = castSession mCastSession = castSession
MusicPlayerRemote.switchToRemotePlayback(castSession) MusicPlayerRemote.switchToRemotePlayback(CastPlayer(castSession))
} }
override fun onSessionEnded(castSession: CastSession, p1: Int) { override fun onSessionEnded(castSession: CastSession, p1: Int) {
@ -53,7 +54,7 @@ abstract class AbsCastActivity : AbsSlidingMusicPanelActivity() {
invalidateOptionsMenu() invalidateOptionsMenu()
mCastSession = castSession mCastSession = castSession
webServer.start() webServer.start()
MusicPlayerRemote.switchToRemotePlayback(castSession) MusicPlayerRemote.switchToRemotePlayback(CastPlayer(castSession))
} }
override fun onSessionSuspended(castSession: CastSession, p1: Int) { override fun onSessionSuspended(castSession: CastSession, p1: Int) {

View file

@ -0,0 +1,37 @@
package code.name.monkey.retromusic.billing
import android.content.Context
import code.name.monkey.retromusic.BuildConfig
import code.name.monkey.retromusic.Constants
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.extensions.showToast
import com.anjlab.android.iab.v3.BillingProcessor
import com.anjlab.android.iab.v3.PurchaseInfo
class BillingManager(context: Context) {
private val billingProcessor: BillingProcessor
init {
// automatically restores purchases
billingProcessor = BillingProcessor(
context, BuildConfig.GOOGLE_PLAY_LICENSING_KEY,
object : BillingProcessor.IBillingHandler {
override fun onProductPurchased(productId: String, details: PurchaseInfo?) {}
override fun onPurchaseHistoryRestored() {
context.showToast(R.string.restored_previous_purchase_please_restart)
}
override fun onBillingError(errorCode: Int, error: Throwable?) {}
override fun onBillingInitialized() {}
})
}
fun release() {
billingProcessor.release()
}
val isProVersion: Boolean
get() = billingProcessor.isPurchased(Constants.PRO_VERSION_PRODUCT_ID)
}

View file

@ -0,0 +1,42 @@
package code.name.monkey.retromusic.extensions
import android.content.Context
import android.content.Intent
import android.view.Menu
import androidx.fragment.app.FragmentActivity
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.PurchaseActivity
import com.google.android.gms.cast.framework.CastButtonFactory
import com.google.android.play.core.splitcompat.SplitCompat
import com.google.android.play.core.splitinstall.SplitInstallManagerFactory
import com.google.android.play.core.splitinstall.SplitInstallRequest
import java.util.*
fun Context.setUpMediaRouteButton(menu: Menu) {
CastButtonFactory.setUpMediaRouteButton(this, menu, R.id.action_cast)
}
fun FragmentActivity.installLanguageAndRecreate(code: String) {
val manager = SplitInstallManagerFactory.create(this)
if (code != "auto") {
// Try to download language resources
val request =
SplitInstallRequest.newBuilder().addLanguage(Locale.forLanguageTag(code))
.build()
manager.startInstall(request)
// Recreate the activity on download complete
.addOnCompleteListener {
recreate()
}
} else {
recreate()
}
}
fun Context.goToProVersion() {
startActivity(Intent(this, PurchaseActivity::class.java))
}
fun Context.installSplitCompat() {
SplitCompat.install(this)
}

View file

@ -28,7 +28,6 @@ object AppRater {
private const val DAYS_UNTIL_PROMPT = 3//Min number of days private const val DAYS_UNTIL_PROMPT = 3//Min number of days
private const val LAUNCHES_UNTIL_PROMPT = 5//Min number of launches private const val LAUNCHES_UNTIL_PROMPT = 5//Min number of launches
@JvmStatic
fun appLaunched(context: Activity) { fun appLaunched(context: Activity) {
val prefs = context.getSharedPreferences(APP_RATING, 0) val prefs = context.getSharedPreferences(APP_RATING, 0)
if (prefs.getBoolean(DO_NOT_SHOW_AGAIN, false)) { if (prefs.getBoolean(DO_NOT_SHOW_AGAIN, false)) {