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'
}
}
flavorDimensions "version"
productFlavors {
normal {
dimension "version"
}
fdroid {
dimension "version"
}
}
buildFeatures{
viewBinding true
@ -95,11 +104,11 @@ dependencies {
implementation 'androidx.core:core-ktx:1.8.0'
implementation 'androidx.palette:palette-ktx:1.0.0'
//Cast Dependencies
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
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-fragment-ktx:$navigation_version"
@ -117,8 +126,8 @@ dependencies {
implementation "androidx.core:core-splashscreen:1.0.0-rc01"
implementation 'com.google.android.play:feature-delivery:2.0.0'
implementation 'com.google.android.play:review:2.0.0'
normalImplementation 'com.google.android.play:feature-delivery:2.0.0'
normalImplementation 'com.google.android.play:review:2.0.0'
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 '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.heinrichreimersoftware:material-intro:2.0.0'
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.SupportDevelopmentActivity" />
<activity android:name=".activities.LicenseActivity" />
<activity android:name=".activities.PurchaseActivity" />
<activity android:name=".activities.bugreport.BugReportActivity" />
<activity android:name=".activities.ShareInstagramStory" />
<activity android:name=".activities.DriveModeActivity" />

View file

@ -19,20 +19,17 @@ import androidx.preference.PreferenceManager
import cat.ereza.customactivityoncrash.config.CaocConfig
import code.name.monkey.appthemehelper.ThemeStore
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.MainActivity
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 com.anjlab.android.iab.v3.BillingProcessor
import com.anjlab.android.iab.v3.PurchaseInfo
import org.koin.android.ext.koin.androidContext
import org.koin.core.context.startKoin
class App : Application() {
lateinit var billingProcessor: BillingProcessor
lateinit var billingManager: BillingManager
private val wallpaperAccentManager = WallpaperAccentManager(this)
override fun onCreate() {
@ -55,33 +52,18 @@ class App : Application() {
if (VersionUtils.hasNougatMR())
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
CaocConfig.Builder.create().errorActivity(ErrorActivity::class.java)
.restartActivity(MainActivity::class.java).apply()
// 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)
}
override fun onTerminate() {
super.onTerminate()
billingProcessor.release()
billingManager.release()
wallpaperAccentManager.release()
}
@ -93,9 +75,7 @@ class App : Application() {
}
fun isProVersion(): Boolean {
return BuildConfig.DEBUG || instance?.billingProcessor!!.isPurchased(
PRO_VERSION_PRODUCT_ID
)
return BuildConfig.DEBUG || instance?.billingManager!!.isProVersion
}
}
}

View file

@ -14,41 +14,23 @@
*/
package code.name.monkey.retromusic.activities
import android.graphics.Paint
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
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.retromusic.BuildConfig
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.base.AbsThemeActivity
import code.name.monkey.retromusic.databinding.ActivityDonationBinding
import code.name.monkey.retromusic.databinding.ItemDonationOptionBinding
import code.name.monkey.retromusic.extensions.*
import com.anjlab.android.iab.v3.BillingProcessor
import com.anjlab.android.iab.v3.PurchaseInfo
import com.anjlab.android.iab.v3.SkuDetails
import code.name.monkey.retromusic.extensions.setStatusBarColorAuto
import code.name.monkey.retromusic.extensions.setTaskDescriptionColorAuto
import code.name.monkey.retromusic.extensions.surfaceColor
class SupportDevelopmentActivity : AbsThemeActivity(), BillingProcessor.IBillingHandler {
class SupportDevelopmentActivity : AbsThemeActivity() {
lateinit var binding: ActivityDonationBinding
companion object {
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 {
if (item.itemId == android.R.id.home) {
onBackPressed()
@ -57,11 +39,6 @@ class SupportDevelopmentActivity : AbsThemeActivity(), BillingProcessor.IBilling
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?) {
super.onCreate(savedInstanceState)
binding = ActivityDonationBinding.inflate(layoutInflater)
@ -72,148 +49,11 @@ class SupportDevelopmentActivity : AbsThemeActivity(), BillingProcessor.IBilling
setupToolbar()
billingProcessor = BillingProcessor(this, BuildConfig.GOOGLE_PLAY_LICENSING_KEY, this)
TintHelper.setTint(binding.progress, accentColor())
binding.donation.setTextColor(accentColor())
}
private fun setupToolbar() {
val toolbarColor = surfaceColor()
binding.toolbar.setBackgroundColor(toolbarColor)
binding.toolbar.setBackgroundColor(surfaceColor())
ToolbarContentTintHelper.colorBackButton(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.theme.getNightMode
import code.name.monkey.retromusic.util.theme.getThemeResValue
import com.google.android.play.core.splitcompat.SplitCompat
import java.util.*
abstract class AbsThemeActivity : ATHToolbarActivity(), Runnable {
@ -105,6 +104,6 @@ abstract class AbsThemeActivity : ATHToolbarActivity(), Runnable {
Locale.forLanguageTag(code)
}
super.attachBaseContext(LanguageContextWrapper.wrap(newBase, locale))
SplitCompat.install(this)
installSplitCompat()
}
}

View file

@ -95,7 +95,7 @@ class SleepTimerDialog : DialogFragment() {
shouldFinishLastSong.isVisible = false
timerUpdater.start()
setPositiveButton(android.R.string.ok, null)
setNegativeButton(R.string.cast_stop) { _, _ ->
setNegativeButton(R.string.action_cancel) { _, _ ->
timerUpdater.cancel()
val previous = makeTimerPendingIntent(PendingIntent.FLAG_NO_CREATE)
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.R
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.fragments.GridStyle
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.isActive
import com.afollestad.materialcab.createCab
import com.google.android.gms.cast.framework.CastButtonFactory
class AlbumsFragment : AbsRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridLayoutManager>(),
IAlbumClickListener, ICabHolder {
@ -169,7 +169,7 @@ class AlbumsFragment : AbsRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridL
setupLayoutMenu(layoutItem.subMenu)
setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu)
//Setting up cast button
CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.action_cast)
requireContext().setUpMediaRouteButton(menu)
}
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.R
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.fragments.GridStyle
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.isActive
import com.afollestad.materialcab.createCab
import com.google.android.gms.cast.framework.CastButtonFactory
class ArtistsFragment : AbsRecyclerViewCustomGridSizeFragment<ArtistAdapter, GridLayoutManager>(),
IArtistClickListener, IAlbumArtistClickListener, ICabHolder {
@ -180,7 +180,7 @@ class ArtistsFragment : AbsRecyclerViewCustomGridSizeFragment<ArtistAdapter, Gri
setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu)
setupAlbumArtistMenu(menu)
//Setting up cast button
CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.action_cast)
requireContext().setUpMediaRouteButton(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.R
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.base.AbsRecyclerViewFragment
import code.name.monkey.retromusic.interfaces.IGenreClickListener
import code.name.monkey.retromusic.model.Genre
import code.name.monkey.retromusic.util.RetroUtil
import com.google.android.gms.cast.framework.CastButtonFactory
import com.google.android.material.transition.MaterialSharedAxis
class
@ -67,7 +67,7 @@ GenresFragment : AbsRecyclerViewFragment<GenreAdapter, LinearLayoutManager>(),
menu.removeItem(R.id.action_sort_order)
menu.findItem(R.id.action_settings).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
//Setting up cast button
CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.action_cast)
requireContext().setUpMediaRouteButton(menu)
}
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.dialogs.CreatePlaylistDialog
import code.name.monkey.retromusic.dialogs.ImportPlaylistDialog
import code.name.monkey.retromusic.extensions.accentColor
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.extensions.*
import code.name.monkey.retromusic.fragments.ReloadType
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
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.util.PreferenceUtil
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.transition.MaterialFadeThrough
import com.google.android.material.transition.MaterialSharedAxis
@ -212,7 +208,7 @@ class HomeFragment :
ATHToolbarActivity.getToolbarBackgroundColor(binding.toolbar)
)
//Setting up cast button
CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.action_cast)
requireContext().setUpMediaRouteButton(menu)
}
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.dialogs.CreatePlaylistDialog
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.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.model.CategoryInfo
import code.name.monkey.retromusic.util.PreferenceUtil
import com.google.android.gms.cast.framework.CastButtonFactory
class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) {
@ -99,7 +99,7 @@ class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) {
getToolbarBackgroundColor(binding.toolbar)
)
//Setting up cast button
CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.action_cast)
requireContext().setUpMediaRouteButton(menu)
}
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.adapter.playlist.PlaylistAdapter
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.base.AbsRecyclerViewCustomGridSizeFragment
import code.name.monkey.retromusic.helper.SortOrder.PlaylistSortOrder
import code.name.monkey.retromusic.interfaces.IPlaylistClickListener
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroUtil
import com.google.android.gms.cast.framework.CastButtonFactory
import com.google.android.material.transition.MaterialSharedAxis
class PlaylistsFragment :
@ -85,7 +85,7 @@ class PlaylistsFragment :
setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu)
MenuCompat.setGroupDividerEnabled(menu, true)
//Setting up cast button
CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.action_cast)
requireContext().setUpMediaRouteButton(menu)
}
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.retromusic.R
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.preferences.*
import code.name.monkey.retromusic.util.NavigationUtil
@ -39,7 +40,7 @@ abstract class AbsSettingsFragment : ATEPreferenceFragmentCompat() {
internal fun showProToastAndNavigate(message: String) {
showToast(getString(R.string.message_pro_feature, message))
NavigationUtil.goToProVersion(requireActivity())
requireContext().goToProVersion()
}
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.databinding.FragmentMainSettingsBinding
import code.name.monkey.retromusic.extensions.drawAboveSystemBarsWithPadding
import code.name.monkey.retromusic.extensions.goToProVersion
import code.name.monkey.retromusic.util.NavigationUtil
class MainSettingsFragment : Fragment(), View.OnClickListener {
@ -77,11 +78,11 @@ class MainSettingsFragment : Fragment(), View.OnClickListener {
binding.buyProContainer.apply {
isGone = App.isProVersion()
setOnClickListener {
NavigationUtil.goToProVersion(requireContext())
requireContext().goToProVersion()
}
}
binding.buyPremium.setOnClickListener {
NavigationUtil.goToProVersion(requireContext())
requireContext().goToProVersion()
}
ThemeStore.accentColor(requireContext()).let {
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.LAST_ADDED_CUTOFF
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.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 java.util.*
/**
* @author Hemanth S (h4h13).
@ -58,21 +56,7 @@ class OtherSettingsFragment : AbsSettingsFragment() {
val languagePreference: Preference? = findPreference(LANGUAGE_NAME)
languagePreference?.setOnPreferenceChangeListener { prefs, newValue ->
setSummary(prefs, newValue)
val code = 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()
}
requireActivity().installLanguageAndRecreate(newValue.toString())
true
}
}

View file

@ -21,6 +21,7 @@ import androidx.annotation.LayoutRes
import androidx.recyclerview.widget.GridLayoutManager
import code.name.monkey.retromusic.R
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.fragments.GridStyle
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.isActive
import com.afollestad.materialcab.createCab
import com.google.android.gms.cast.framework.CastButtonFactory
class SongsFragment : AbsRecyclerViewCustomGridSizeFragment<SongAdapter, GridLayoutManager>(),
ICabHolder {
@ -136,7 +136,7 @@ class SongsFragment : AbsRecyclerViewCustomGridSizeFragment<SongAdapter, GridLay
setupLayoutMenu(layoutItem.subMenu)
setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu)
//Setting up cast button
CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.action_cast)
requireContext().setUpMediaRouteButton(menu)
}
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.model.Song
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.util.getExternalStorageDirectory
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.inject
import java.io.File
@ -456,8 +456,8 @@ object MusicPlayerRemote : KoinComponent {
.dropLastWhile { it.isEmpty() }.toTypedArray()[1]
}
fun switchToRemotePlayback(castSession: CastSession) {
musicService?.switchToRemotePlayback(castSession)
fun switchToRemotePlayback(castPlayer: CastPlayer) {
musicService?.switchToRemotePlayback(castPlayer)
}
fun switchToLocalPlayback() {

View file

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

View file

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

View file

@ -15,10 +15,10 @@
package code.name.monkey.retromusic.service
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.os.PowerManager
import android.os.PowerManager.WakeLock
@ -62,8 +62,7 @@ class MediaButtonIntentReceiver : MediaButtonReceiver() {
private var mClickCounter = 0
private var mLastClickTime: Long = 0
@SuppressLint("HandlerLeak") // false alarm, handler is already static
private val mHandler = object : Handler() {
private val mHandler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
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.Target
import com.bumptech.glide.request.transition.Transition
import com.google.android.gms.cast.framework.CastSession
import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers.Default
import kotlinx.coroutines.Dispatchers.IO
@ -1171,8 +1170,8 @@ class MusicService : MediaBrowserServiceCompat(),
playbackManager.switchToLocalPlayback(this::restorePlaybackState)
}
fun switchToRemotePlayback(castSession: CastSession) {
playbackManager.switchToRemotePlayback(castSession, this::restorePlaybackState)
fun switchToRemotePlayback(castPlayer: CastPlayer) {
playbackManager.switchToRemotePlayback(castPlayer, this::restorePlaybackState)
}
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.playbackPitch
import code.name.monkey.retromusic.util.PreferenceUtil.playbackSpeed
import com.google.android.gms.cast.framework.CastSession
class PlaybackManager(val context: Context) {
@ -160,11 +159,11 @@ class PlaybackManager(val context: Context) {
}
fun switchToRemotePlayback(
castSession: CastSession,
castPlayer: CastPlayer,
onChange: (wasPlaying: Boolean, progress: Int) -> Unit,
) {
playbackLocation = PlaybackLocation.REMOTE
switchToPlayback(CastPlayer(castSession), onChange)
switchToPlayback(castPlayer, onChange)
}
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) {
activity.startActivity(
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"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
@ -31,52 +30,5 @@
android:overScrollMode="@integer/overScrollMode"
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.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
import android.content.res.ColorStateList
@ -22,7 +8,7 @@ import android.view.MenuItem
import code.name.monkey.appthemehelper.util.MaterialUtil
import code.name.monkey.retromusic.App
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.activities.base.AbsThemeActivity
import code.name.monkey.retromusic.databinding.ActivityProVersionBinding
@ -58,7 +44,7 @@ class PurchaseActivity : AbsThemeActivity(), BillingProcessor.IBillingHandler {
restorePurchase()
}
binding.purchaseButton.setOnClickListener {
billingProcessor.purchase(this@PurchaseActivity, PRO_VERSION_PRODUCT_ID)
billingProcessor.purchase(this@PurchaseActivity, Constants.PRO_VERSION_PRODUCT_ID)
}
binding.bannerContainer.backgroundTintList =
ColorStateList.valueOf(accentColor())

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.RetroWebServer
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.CastSession
import com.google.android.gms.common.ConnectionResult
@ -37,7 +38,7 @@ abstract class AbsCastActivity : AbsSlidingMusicPanelActivity() {
override fun onSessionStarted(castSession: CastSession, p1: String) {
invalidateOptionsMenu()
mCastSession = castSession
MusicPlayerRemote.switchToRemotePlayback(castSession)
MusicPlayerRemote.switchToRemotePlayback(CastPlayer(castSession))
}
override fun onSessionEnded(castSession: CastSession, p1: Int) {
@ -53,7 +54,7 @@ abstract class AbsCastActivity : AbsSlidingMusicPanelActivity() {
invalidateOptionsMenu()
mCastSession = castSession
webServer.start()
MusicPlayerRemote.switchToRemotePlayback(castSession)
MusicPlayerRemote.switchToRemotePlayback(CastPlayer(castSession))
}
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 LAUNCHES_UNTIL_PROMPT = 5//Min number of launches
@JvmStatic
fun appLaunched(context: Activity) {
val prefs = context.getSharedPreferences(APP_RATING, 0)
if (prefs.getBoolean(DO_NOT_SHOW_AGAIN, false)) {