/* * Copyright (c) Double Symmetry GmbH * Commercial use requires a license. See https://rntp.dev/pricing */ package com.doublesymmetry.trackplayer import android.content.Context import android.graphics.drawable.Drawable import android.util.TypedValue import android.view.ContextThemeWrapper import androidx.core.graphics.drawable.DrawableCompat import androidx.mediarouter.app.MediaRouteButton import androidx.mediarouter.media.MediaRouteSelector import com.doublesymmetry.trackplayer.models.PlayerConfig import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.uimanager.SimpleViewManager import com.facebook.react.uimanager.ThemedReactContext import com.facebook.react.uimanager.annotations.ReactProp import com.google.android.gms.cast.CastMediaControlIntent import com.google.android.gms.cast.framework.CastButtonFactory class CastButtonManager(private val reactContext: ReactApplicationContext) : SimpleViewManager() { override fun getName() = "TrackPlayerCastButton" override fun createViewInstance(context: ThemedReactContext): MediaRouteButton { val appId = PlayerConfig().load(reactContext).castReceiverAppId ?: CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID val button = MediaRouteButton(context) val selector = MediaRouteSelector.Builder() .addControlCategory(CastMediaControlIntent.categoryForCast(appId)) .build() button.setRouteSelector(selector) try { CastButtonFactory.setUpMediaRouteButton(reactContext, button) } catch (_: Exception) { } return button } @ReactProp(name = "tintColor", customType = "Color") fun setTintColor(button: MediaRouteButton, color: Int?) { if (color == null) return tintedRemoteIndicator(button.context, color)?.let { button.setRemoteIndicatorDrawable(it) } } companion object { /** * Builds the default Cast icon tinted with [color]. MediaRouteButton has no * public tint setter, so we resolve its drawable from the MediaRouteButton * style, tint a mutable copy, and swap it back in. Returns null if the * drawable can't be resolved. */ internal fun tintedRemoteIndicator(context: Context, color: Int): Drawable? { val themed = ContextThemeWrapper(context, androidx.mediarouter.R.style.Theme_MediaRouter) val styleRes = TypedValue().let { value -> themed.theme.resolveAttribute( androidx.mediarouter.R.attr.mediaRouteButtonStyle, value, true ) value.resourceId } if (styleRes == 0) return null val attrs = themed.obtainStyledAttributes( styleRes, androidx.mediarouter.R.styleable.MediaRouteButton ) val drawable = attrs.getDrawable( androidx.mediarouter.R.styleable.MediaRouteButton_externalRouteEnabledDrawable ) attrs.recycle() return drawable?.mutate()?.also { DrawableCompat.setTint(it, color) } } } }