mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-04-19 19:14:51 +00:00
Monetization
This commit is contained in:
parent
d7f4dd65e8
commit
9d906025ea
37 changed files with 1045 additions and 205 deletions
|
@ -0,0 +1,20 @@
|
|||
package com.futo.platformplayer
|
||||
|
||||
import android.graphics.Rect
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
||||
class HorizontalSpaceItemDecoration(private val startSpace: Int, private val betweenSpace: Int, private val endSpace: Int) : RecyclerView.ItemDecoration() {
|
||||
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
|
||||
outRect.left = betweenSpace
|
||||
|
||||
val position = parent.getChildAdapterPosition(view)
|
||||
if (position == 0) {
|
||||
outRect.left = startSpace
|
||||
}
|
||||
|
||||
else if (position == state.itemCount - 1) {
|
||||
outRect.right = endSpace
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,11 +11,12 @@ import com.futo.platformplayer.R
|
|||
import com.futo.platformplayer.api.media.models.channels.IPlatformChannel
|
||||
import com.futo.platformplayer.fragment.mainactivity.main.PolycentricProfile
|
||||
import com.futo.platformplayer.logging.Logger
|
||||
import com.futo.platformplayer.views.SupportView
|
||||
import com.futo.platformplayer.views.buttons.BigButton
|
||||
|
||||
|
||||
class ChannelMonetizationFragment : Fragment, IChannelTabFragment {
|
||||
private var _buttonStore: BigButton? = null;
|
||||
private var _supportView: SupportView? = null
|
||||
|
||||
private var _lastChannel: IPlatformChannel? = null;
|
||||
private var _lastPolycentricProfile: PolycentricProfile? = null;
|
||||
|
@ -24,20 +25,7 @@ class ChannelMonetizationFragment : Fragment, IChannelTabFragment {
|
|||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
val view = inflater.inflate(R.layout.fragment_channel_monetization, container, false);
|
||||
_buttonStore = view.findViewById(R.id.button_store);
|
||||
|
||||
_buttonStore?.onClick?.subscribe {
|
||||
_lastPolycentricProfile?.systemState?.store?.let {
|
||||
try {
|
||||
val uri = Uri.parse(it);
|
||||
val intent = Intent(Intent.ACTION_VIEW)
|
||||
intent.data = uri
|
||||
startActivity(intent)
|
||||
} catch (e: Throwable) {
|
||||
Logger.e(TAG, "Failed to open URI: '${it}'.", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
_supportView = view.findViewById(R.id.support);
|
||||
|
||||
_lastChannel?.also {
|
||||
setChannel(it);
|
||||
|
@ -52,24 +40,16 @@ class ChannelMonetizationFragment : Fragment, IChannelTabFragment {
|
|||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView();
|
||||
_buttonStore = null;
|
||||
_supportView = null;
|
||||
}
|
||||
|
||||
override fun setChannel(channel: IPlatformChannel) {
|
||||
_lastChannel = channel;
|
||||
_buttonStore?.visibility = View.GONE;
|
||||
}
|
||||
|
||||
fun setPolycentricProfile(polycentricProfile: PolycentricProfile?, animate: Boolean) {
|
||||
_lastPolycentricProfile = polycentricProfile;
|
||||
|
||||
if (polycentricProfile == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (polycentricProfile.systemState.store.isNotEmpty()) {
|
||||
_buttonStore?.visibility = View.VISIBLE;
|
||||
}
|
||||
_lastPolycentricProfile = polycentricProfile
|
||||
_supportView?.setPolycentricProfile(polycentricProfile, animate)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -70,6 +70,7 @@ import com.futo.platformplayer.receivers.MediaControlReceiver
|
|||
import com.futo.platformplayer.states.*
|
||||
import com.futo.platformplayer.stores.FragmentedStorage
|
||||
import com.futo.platformplayer.stores.StringArrayStorage
|
||||
import com.futo.platformplayer.views.MonetizationView
|
||||
import com.futo.platformplayer.views.behavior.TouchInterceptFrameLayout
|
||||
import com.futo.platformplayer.views.casting.CastView
|
||||
import com.futo.platformplayer.views.comments.AddCommentView
|
||||
|
@ -79,6 +80,7 @@ import com.futo.platformplayer.views.overlays.DescriptionOverlay
|
|||
import com.futo.platformplayer.views.overlays.LiveChatOverlay
|
||||
import com.futo.platformplayer.views.overlays.QueueEditorOverlay
|
||||
import com.futo.platformplayer.views.overlays.RepliesOverlay
|
||||
import com.futo.platformplayer.views.overlays.SupportOverlay
|
||||
import com.futo.platformplayer.views.overlays.slideup.*
|
||||
import com.futo.platformplayer.views.pills.PillRatingLikesDislikes
|
||||
import com.futo.platformplayer.views.pills.RoundButton
|
||||
|
@ -191,6 +193,7 @@ class VideoDetailView : ConstraintLayout {
|
|||
private val _container_content_replies: RepliesOverlay;
|
||||
private val _container_content_description: DescriptionOverlay;
|
||||
private val _container_content_liveChat: LiveChatOverlay;
|
||||
private val _container_content_support: SupportOverlay;
|
||||
|
||||
private var _container_content_current: View;
|
||||
|
||||
|
@ -200,9 +203,7 @@ class VideoDetailView : ConstraintLayout {
|
|||
private val _imageDislikeIcon: ImageView;
|
||||
private val _imageLikeIcon: ImageView;
|
||||
|
||||
private val _buttonSupport: LinearLayout;
|
||||
private val _buttonStore: LinearLayout;
|
||||
private val _layoutMonetization: LinearLayout;
|
||||
private val _monetization: MonetizationView;
|
||||
|
||||
private val _buttonMore: RoundButton;
|
||||
|
||||
|
@ -292,6 +293,7 @@ class VideoDetailView : ConstraintLayout {
|
|||
_container_content_replies = findViewById(R.id.videodetail_container_replies);
|
||||
_container_content_description = findViewById(R.id.videodetail_container_description);
|
||||
_container_content_liveChat = findViewById(R.id.videodetail_container_livechat);
|
||||
_container_content_support = findViewById(R.id.videodetail_container_support)
|
||||
|
||||
_textComments = findViewById(R.id.text_comments);
|
||||
_addCommentView = findViewById(R.id.add_comment_view);
|
||||
|
@ -310,11 +312,7 @@ class VideoDetailView : ConstraintLayout {
|
|||
_imageLikeIcon = findViewById(R.id.image_like_icon);
|
||||
_imageDislikeIcon = findViewById(R.id.image_dislike_icon);
|
||||
|
||||
_buttonSupport = findViewById(R.id.button_support);
|
||||
_buttonStore = findViewById(R.id.button_store);
|
||||
_layoutMonetization = findViewById(R.id.layout_monetization);
|
||||
|
||||
_layoutMonetization.visibility = View.GONE;
|
||||
_monetization = findViewById(R.id.monetization);
|
||||
_player.attachPlayer();
|
||||
|
||||
|
||||
|
@ -327,16 +325,12 @@ class VideoDetailView : ConstraintLayout {
|
|||
fragment.navigate<VideoDetailFragment>(it.targetUrl);
|
||||
};
|
||||
|
||||
_buttonSupport.setOnClickListener {
|
||||
val author = video?.author ?: _searchVideo?.author;
|
||||
author?.let { fragment.navigate<ChannelFragment>(it).selectTab(2); };
|
||||
fragment.lifecycleScope.launch {
|
||||
delay(100);
|
||||
fragment.minimizeVideoDetail();
|
||||
};
|
||||
_monetization.onSupportTap.subscribe {
|
||||
_container_content_support.setPolycentricProfile(_polycentricProfile?.profile, false);
|
||||
switchContentView(_container_content_support);
|
||||
};
|
||||
|
||||
_buttonStore.setOnClickListener {
|
||||
_monetization.onStoreTap.subscribe {
|
||||
_polycentricProfile?.profile?.systemState?.store?.let {
|
||||
try {
|
||||
val uri = Uri.parse(it);
|
||||
|
@ -349,6 +343,13 @@ class VideoDetailView : ConstraintLayout {
|
|||
}
|
||||
};
|
||||
|
||||
_player.attachPlayer();
|
||||
|
||||
_container_content_liveChat.onRaidNow.subscribe {
|
||||
StatePlayer.instance.clearQueue();
|
||||
fragment.navigate<VideoDetailFragment>(it.targetUrl);
|
||||
};
|
||||
|
||||
StateApp.instance.preventPictureInPicture.subscribe(this) {
|
||||
Logger.i(TAG, "StateApp.instance.preventPictureInPicture.subscribe preventPictureInPicture = true");
|
||||
preventPictureInPicture = true;
|
||||
|
@ -545,6 +546,7 @@ class VideoDetailView : ConstraintLayout {
|
|||
_container_content_liveChat.onClose.subscribe { switchContentView(_container_content_main); };
|
||||
_container_content_queue.onClose.subscribe { switchContentView(_container_content_main); };
|
||||
_container_content_replies.onClose.subscribe { switchContentView(_container_content_main); };
|
||||
_container_content_support.onClose.subscribe { switchContentView(_container_content_main); };
|
||||
|
||||
_description_viewMore.setOnClickListener {
|
||||
switchContentView(_container_content_description);
|
||||
|
@ -847,6 +849,7 @@ class VideoDetailView : ConstraintLayout {
|
|||
_container_content_replies.cleanup();
|
||||
_container_content_queue.cleanup();
|
||||
_container_content_description.cleanup();
|
||||
_container_content_support.cleanup();
|
||||
StateCasting.instance.onActiveDevicePlayChanged.remove(this);
|
||||
StateCasting.instance.onActiveDeviceTimeChanged.remove(this);
|
||||
StateCasting.instance.onActiveDeviceConnectionStateChanged.remove(this);
|
||||
|
@ -2096,12 +2099,7 @@ class VideoDetailView : ConstraintLayout {
|
|||
_creatorThumbnail.setHarborAvailable(profile != null, animate);
|
||||
}
|
||||
|
||||
if (profile != null) {
|
||||
_channelName.text = cachedPolycentricProfile.profile.systemState.username;
|
||||
_layoutMonetization.visibility = View.VISIBLE;
|
||||
} else {
|
||||
_layoutMonetization.visibility = View.GONE;
|
||||
}
|
||||
_monetization.setPolycentricProfile(cachedPolycentricProfile, animate);
|
||||
}
|
||||
|
||||
fun setProgressBarOverlayed(isOverlayed: Boolean?) {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.futo.platformplayer.images;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.bumptech.glide.Priority;
|
||||
|
|
|
@ -39,7 +39,12 @@ class PolycentricCache {
|
|||
ContentType.USERNAME.value,
|
||||
ContentType.DESCRIPTION.value,
|
||||
ContentType.STORE.value,
|
||||
ContentType.SERVER.value
|
||||
ContentType.SERVER.value,
|
||||
ContentType.STORE_DATA.value,
|
||||
ContentType.PROMOTION_BANNER.value,
|
||||
ContentType.PROMOTION.value,
|
||||
ContentType.MEMBERSHIP_URLS.value,
|
||||
ContentType.DONATION_DESTINATIONS.value
|
||||
)
|
||||
).eventsList.map { e -> SignedEvent.fromProto(e) };
|
||||
|
||||
|
|
|
@ -0,0 +1,145 @@
|
|||
package com.futo.platformplayer.views
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.futo.platformplayer.R
|
||||
import com.futo.platformplayer.HorizontalSpaceItemDecoration
|
||||
import com.futo.platformplayer.api.http.ManagedHttpClient
|
||||
import com.futo.platformplayer.constructs.Event0
|
||||
import com.futo.platformplayer.constructs.TaskHandler
|
||||
import com.futo.platformplayer.logging.Logger
|
||||
import com.futo.platformplayer.polycentric.PolycentricCache
|
||||
import com.futo.platformplayer.states.StateApp
|
||||
import com.futo.platformplayer.views.AnyAdapterView.Companion.asAny
|
||||
import com.futo.platformplayer.views.adapters.viewholders.StoreItemViewHolder
|
||||
import com.futo.platformplayer.views.platform.PlatformIndicator
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
@Serializable
|
||||
data class StoreItem(
|
||||
val url: String,
|
||||
val name: String,
|
||||
val image: String
|
||||
);
|
||||
|
||||
class MonetizationView : LinearLayout {
|
||||
private val _buttonSupport: LinearLayout;
|
||||
private val _buttonStore: LinearLayout;
|
||||
private val _buttonMembership: LinearLayout;
|
||||
private val _platformIndicator: PlatformIndicator;
|
||||
|
||||
private val _textMerchandise: TextView;
|
||||
private val _recyclerMerchandise: RecyclerView;
|
||||
private val _loaderMerchandise: Loader;
|
||||
private val _layoutMerchandise: FrameLayout;
|
||||
private var _merchandiseAdapterView: AnyAdapterView<StoreItem, StoreItemViewHolder>? = null;
|
||||
|
||||
private val _root: LinearLayout;
|
||||
|
||||
private val _taskLoadMerchandise = TaskHandler<String, List<StoreItem>>(StateApp.instance.scopeGetter, { url ->
|
||||
val client = ManagedHttpClient();
|
||||
val result = client.get("https://storecache.grayjay.app/StoreData?url=$url")
|
||||
if (!result.isOk) {
|
||||
throw Exception("Failed to retrieve store data.");
|
||||
}
|
||||
|
||||
return@TaskHandler result.body?.let { Json.decodeFromString<List<StoreItem>>(it.string()); } ?: listOf();
|
||||
})
|
||||
.success { setMerchandise(it) }
|
||||
.exception<Throwable> {
|
||||
Logger.w(TAG, "Failed to load merchandise profile.", it);
|
||||
};
|
||||
|
||||
val onSupportTap = Event0();
|
||||
val onStoreTap = Event0();
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet? = null) : super(context, attrs) {
|
||||
inflate(context, R.layout.view_monetization, this);
|
||||
_buttonSupport = findViewById(R.id.button_support);
|
||||
_buttonStore = findViewById(R.id.button_store);
|
||||
_buttonMembership = findViewById(R.id.button_membership);
|
||||
_platformIndicator = findViewById(R.id.platform_indicator);
|
||||
|
||||
_textMerchandise = findViewById(R.id.text_merchandise);
|
||||
_recyclerMerchandise = findViewById(R.id.recycler_merchandise);
|
||||
_loaderMerchandise = findViewById(R.id.loader_merchandise);
|
||||
_layoutMerchandise = findViewById(R.id.layout_merchandise);
|
||||
|
||||
_root = findViewById(R.id.root);
|
||||
|
||||
_recyclerMerchandise.addItemDecoration(HorizontalSpaceItemDecoration(30, 16, 30))
|
||||
_merchandiseAdapterView = _recyclerMerchandise.asAny(orientation = RecyclerView.HORIZONTAL);
|
||||
|
||||
_buttonSupport.setOnClickListener { onSupportTap.emit(); }
|
||||
_buttonStore.setOnClickListener { onStoreTap.emit(); }
|
||||
_buttonMembership.visibility = View.GONE;
|
||||
setMerchandise(null);
|
||||
}
|
||||
|
||||
fun setPlatformMembership() {
|
||||
//TODO:
|
||||
}
|
||||
|
||||
private fun setMerchandise(items: List<StoreItem>?) {
|
||||
_loaderMerchandise.stop();
|
||||
|
||||
if (items == null) {
|
||||
_textMerchandise.visibility = View.GONE;
|
||||
_recyclerMerchandise.visibility = View.GONE;
|
||||
_layoutMerchandise.visibility = View.GONE;
|
||||
} else {
|
||||
_textMerchandise.visibility = View.VISIBLE;
|
||||
_recyclerMerchandise.visibility = View.VISIBLE;
|
||||
_layoutMerchandise.visibility = View.VISIBLE;
|
||||
_merchandiseAdapterView?.adapter?.setData(items.shuffled());
|
||||
}
|
||||
}
|
||||
|
||||
fun setPolycentricProfile(cachedPolycentricProfile: PolycentricCache.CachedPolycentricProfile?, animate: Boolean) {
|
||||
val profile = cachedPolycentricProfile?.profile;
|
||||
if (profile != null) {
|
||||
if (profile.systemState.store.isNotEmpty()) {
|
||||
_buttonStore.visibility = View.VISIBLE;
|
||||
} else {
|
||||
_buttonStore.visibility = View.GONE;
|
||||
}
|
||||
|
||||
_root.visibility = View.VISIBLE;
|
||||
} else {
|
||||
_root.visibility = View.GONE;
|
||||
}
|
||||
|
||||
setMerchandise(null);
|
||||
val storeData = profile?.systemState?.storeData;
|
||||
if (storeData != null) {
|
||||
try {
|
||||
val storeItems = Json.decodeFromString<List<StoreItem>>(storeData);
|
||||
setMerchandise(storeItems);
|
||||
} catch (_: Throwable) {
|
||||
try {
|
||||
val uri = Uri.parse(storeData);
|
||||
if (uri.isAbsolute) {
|
||||
_taskLoadMerchandise.run(storeData);
|
||||
_loaderMerchandise.start();
|
||||
} else {
|
||||
Logger.i(TAG, "Merchandise not loaded, not URL nor JSON")
|
||||
}
|
||||
} catch (_: Throwable) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TAG = "MonetizationView";
|
||||
}
|
||||
}
|
243
app/src/main/java/com/futo/platformplayer/views/SupportView.kt
Normal file
243
app/src/main/java/com/futo/platformplayer/views/SupportView.kt
Normal file
|
@ -0,0 +1,243 @@
|
|||
package com.futo.platformplayer.views
|
||||
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.net.Uri
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.request.target.CustomTarget
|
||||
import com.bumptech.glide.request.transition.Transition
|
||||
import com.futo.platformplayer.R
|
||||
import com.futo.platformplayer.dp
|
||||
import com.futo.platformplayer.fragment.mainactivity.main.PolycentricProfile
|
||||
import com.futo.platformplayer.images.GlideHelper.Companion.crossfade
|
||||
import com.futo.platformplayer.logging.Logger
|
||||
import com.futo.platformplayer.polycentric.PolycentricCache
|
||||
import com.futo.platformplayer.views.buttons.BigButton
|
||||
import com.futo.polycentric.core.toURLInfoSystemLinkUrl
|
||||
import com.google.android.material.imageview.ShapeableImageView
|
||||
import com.google.android.material.shape.CornerFamily
|
||||
import com.google.android.material.shape.ShapeAppearanceModel
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.json.Json
|
||||
import userpackage.Protocol.ImageManifest
|
||||
|
||||
class SupportView : LinearLayout {
|
||||
private val _layoutStore: LinearLayout
|
||||
private val _buttonPromotion: BigButton
|
||||
private val _layoutMemberships: LinearLayout
|
||||
private val _layoutMembershipEntries: LinearLayout
|
||||
private val _layoutPromotions: LinearLayout
|
||||
private val _layoutPromotionEntries: LinearLayout
|
||||
private val _layoutDonation: LinearLayout
|
||||
private val _layoutDonationEntries: LinearLayout
|
||||
private val _buttonStore: BigButton
|
||||
private val _imagePromotion: ShapeableImageView
|
||||
private var _textNoSupportOptionsSet: TextView
|
||||
private var _polycentricProfile: PolycentricProfile? = null
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet? = null) : super(context, attrs) {
|
||||
inflate(context, R.layout.view_support, this);
|
||||
|
||||
_layoutStore = findViewById(R.id.layout_store)
|
||||
_buttonStore = findViewById(R.id.button_store)
|
||||
_layoutMemberships = findViewById(R.id.layout_memberships)
|
||||
_layoutMembershipEntries = findViewById(R.id.layout_membership_entries)
|
||||
_layoutPromotions = findViewById(R.id.layout_promotions)
|
||||
_layoutPromotionEntries = findViewById(R.id.layout_promotion_entries)
|
||||
_layoutDonation = findViewById(R.id.layout_donation)
|
||||
_layoutDonationEntries = findViewById(R.id.layout_donation_entries)
|
||||
_buttonPromotion = findViewById(R.id.button_promotion)
|
||||
_imagePromotion = findViewById(R.id.image_promotion)
|
||||
_textNoSupportOptionsSet = findViewById(R.id.text_no_support_options_set)
|
||||
|
||||
_buttonPromotion.onClick.subscribe { openPromotion() }
|
||||
_imagePromotion.setOnClickListener { openPromotion() }
|
||||
_buttonStore.onClick.subscribe {
|
||||
val storeUrl = _polycentricProfile?.systemState?.store ?: return@subscribe
|
||||
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(storeUrl))
|
||||
context.startActivity(browserIntent)
|
||||
}
|
||||
}
|
||||
|
||||
private fun openPromotion() {
|
||||
val promotionUrl = _polycentricProfile?.systemState?.promotion ?: return
|
||||
val uri = Uri.parse(promotionUrl)
|
||||
if (!uri.isAbsolute && (uri.scheme == "https" || uri.scheme == "http")) {
|
||||
return
|
||||
}
|
||||
|
||||
val browserIntent = Intent(Intent.ACTION_VIEW, uri)
|
||||
context.startActivity(browserIntent)
|
||||
}
|
||||
|
||||
private fun setMemberships(urls: List<String>) {
|
||||
_layoutMembershipEntries.removeAllViews()
|
||||
for (url in urls) {
|
||||
val button = createMembershipButton(url)
|
||||
_layoutMembershipEntries.addView(button)
|
||||
}
|
||||
_layoutMemberships.visibility = if (urls.isEmpty()) View.GONE else View.VISIBLE
|
||||
}
|
||||
|
||||
private fun createMembershipButton(url: String): BigButton {
|
||||
val uri = Uri.parse(url)
|
||||
val name: String
|
||||
val iconDrawableId: Int
|
||||
|
||||
if (uri.host?.contains("patreon.com") == true) {
|
||||
name = "Patreon"
|
||||
iconDrawableId = R.drawable.patreon
|
||||
} else {
|
||||
name = uri.host.toString()
|
||||
iconDrawableId = R.drawable.ic_web_white
|
||||
}
|
||||
|
||||
return BigButton(context, name, "Become a member on $name", iconDrawableId) {
|
||||
val intent = Intent(Intent.ACTION_VIEW);
|
||||
intent.data = uri;
|
||||
context.startActivity(intent);
|
||||
}.apply {
|
||||
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
||||
};
|
||||
}
|
||||
|
||||
private fun setDonations(destinations: List<String>) {
|
||||
_layoutDonationEntries.removeAllViews()
|
||||
for (destination in destinations) {
|
||||
val button = createDonationButton(destination)
|
||||
_layoutDonationEntries.addView(button)
|
||||
}
|
||||
_layoutDonation.visibility = if (destinations.isEmpty()) View.GONE else View.VISIBLE
|
||||
}
|
||||
|
||||
private enum class CryptoType {
|
||||
BITCOIN, ETHEREUM, LITECOIN, RIPPLE, UNKNOWN
|
||||
}
|
||||
|
||||
private fun getCryptoType(address: String): CryptoType {
|
||||
val btcRegex = Regex("^(1|3)[1-9A-HJ-NP-Za-km-z]{25,34}$|^(bc1)[0-9a-zA-HJ-NP-Z]{39,59}$")
|
||||
val ethRegex = Regex("^(0x)[0-9a-fA-F]{40}$")
|
||||
val ltcRegex = Regex("^(L|M)[1-9A-HJ-NP-Za-km-z]{26,33}$|^(ltc1)[0-9a-zA-HJ-NP-Z]{39,59}$")
|
||||
val xrpRegex = Regex("^r[1-9A-HJ-NP-Za-km-z]{24,34}$")
|
||||
|
||||
return when {
|
||||
ltcRegex.matches(address) -> CryptoType.LITECOIN
|
||||
btcRegex.matches(address) -> CryptoType.BITCOIN
|
||||
ethRegex.matches(address) -> CryptoType.ETHEREUM
|
||||
xrpRegex.matches(address) -> CryptoType.RIPPLE
|
||||
else -> CryptoType.UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
private fun createDonationButton(destination: String): BigButton {
|
||||
val uri = Uri.parse(destination)
|
||||
|
||||
var action: (() -> Unit)? = null
|
||||
val (name, iconDrawableId, cryptoType) = if (uri.scheme == "http" || uri.scheme == "https") {
|
||||
val hostName = uri.host ?: ""
|
||||
|
||||
action = {
|
||||
val intent = Intent(Intent.ACTION_VIEW);
|
||||
intent.data = uri;
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
if (hostName.contains("paypal.com")) {
|
||||
Triple("Paypal", R.drawable.paypal, null) // Replace with your actual PayPal drawable resource
|
||||
} else {
|
||||
Triple(hostName, R.drawable.ic_web_white, null) // Replace with your generic web drawable resource
|
||||
}
|
||||
} else {
|
||||
action = {
|
||||
val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
val clip = ClipData.newPlainText("Donation Address", destination)
|
||||
clipboard.setPrimaryClip(clip)
|
||||
Toast.makeText(context, "Copied to clipboard", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
when (getCryptoType(destination)) {
|
||||
CryptoType.BITCOIN -> Triple("Bitcoin", R.drawable.bitcoin, CryptoType.BITCOIN)
|
||||
CryptoType.ETHEREUM -> Triple("Ethereum", R.drawable.ethereum, CryptoType.ETHEREUM)
|
||||
CryptoType.LITECOIN -> Triple("Litecoin", R.drawable.litecoin, CryptoType.LITECOIN)
|
||||
CryptoType.RIPPLE -> Triple("Ripple", R.drawable.ripple, CryptoType.RIPPLE)
|
||||
CryptoType.UNKNOWN -> Triple("Unknown", R.drawable.ic_paid, CryptoType.UNKNOWN)
|
||||
}
|
||||
}
|
||||
|
||||
return BigButton(context, name, destination.takeIf { cryptoType != null } ?: "Donate on $name", iconDrawableId, action).apply {
|
||||
layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
||||
};
|
||||
}
|
||||
|
||||
private fun setPromotions(url: String?, imageUrl: String?) {
|
||||
Logger.i(TAG, "setPromotions($url, $imageUrl)")
|
||||
|
||||
if (url != null) {
|
||||
_layoutPromotions.visibility = View.VISIBLE
|
||||
|
||||
if (imageUrl != null) {
|
||||
_buttonPromotion.visibility = View.GONE
|
||||
_imagePromotion.visibility = View.VISIBLE
|
||||
|
||||
Glide.with(_imagePromotion)
|
||||
.load(imageUrl)
|
||||
.crossfade()
|
||||
.into(_imagePromotion)
|
||||
} else {
|
||||
_buttonPromotion.setSecondaryText(url)
|
||||
_buttonPromotion.visibility = View.VISIBLE
|
||||
_imagePromotion.visibility = View.GONE
|
||||
}
|
||||
} else {
|
||||
_layoutPromotions.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
fun setPolycentricProfile(profile: PolycentricProfile?, animate: Boolean) {
|
||||
if (_polycentricProfile == profile) {
|
||||
return
|
||||
}
|
||||
|
||||
if (profile != null) {
|
||||
setDonations(profile.systemState.donationDestinations);
|
||||
setMemberships(profile.systemState.membershipUrls);
|
||||
|
||||
val imageManifest = profile.systemState.promotionBanner?.imageManifestsList?.firstOrNull()
|
||||
if (imageManifest != null) {
|
||||
val imageUrl = imageManifest.toURLInfoSystemLinkUrl(profile.system.toProto(), imageManifest.process, profile.systemState.servers.toList());
|
||||
setPromotions(profile.systemState.promotion, imageUrl);
|
||||
} else {
|
||||
setPromotions(null, null);
|
||||
}
|
||||
|
||||
if (profile.systemState.store.isNotEmpty()) {
|
||||
_layoutStore.visibility = View.VISIBLE
|
||||
} else {
|
||||
_layoutStore.visibility = View.GONE
|
||||
}
|
||||
|
||||
_textNoSupportOptionsSet.visibility = View.GONE
|
||||
} else {
|
||||
setDonations(listOf());
|
||||
setMemberships(listOf());
|
||||
setPromotions(null, null);
|
||||
_layoutStore.visibility = View.GONE
|
||||
_textNoSupportOptionsSet.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
_polycentricProfile = profile
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TAG = "SupportView";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package com.futo.platformplayer.views.adapters.viewholders
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.bumptech.glide.Glide
|
||||
import com.futo.platformplayer.R
|
||||
import com.futo.platformplayer.constructs.Event1
|
||||
import com.futo.platformplayer.images.GlideHelper.Companion.crossfade
|
||||
import com.futo.platformplayer.logging.Logger
|
||||
import com.futo.platformplayer.views.StoreItem
|
||||
import com.futo.platformplayer.views.adapters.AnyAdapter
|
||||
import com.google.android.material.imageview.ShapeableImageView
|
||||
|
||||
class StoreItemViewHolder(private val _viewGroup: ViewGroup) : AnyAdapter.AnyViewHolder<StoreItem>(
|
||||
LayoutInflater.from(_viewGroup.context).inflate(R.layout.view_store_item, _viewGroup, false)) {
|
||||
|
||||
private val _image: ShapeableImageView;
|
||||
private val _name: TextView;
|
||||
private var _storeItem: StoreItem? = null;
|
||||
|
||||
init {
|
||||
_image = _view.findViewById(R.id.image_item);
|
||||
_name = _view.findViewById(R.id.text_item);
|
||||
_view.findViewById<LinearLayout>(R.id.root).setOnClickListener {
|
||||
val s = _storeItem ?: return@setOnClickListener;
|
||||
|
||||
try {
|
||||
val uri = Uri.parse(s.url);
|
||||
val intent = Intent(Intent.ACTION_VIEW);
|
||||
intent.data = uri;
|
||||
_view.context.startActivity(intent);
|
||||
} catch (e: Throwable) {
|
||||
Logger.e(TAG, "Failed to open URI: '${it}'.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun bind(storeItem: StoreItem) {
|
||||
Glide.with(_image)
|
||||
.load(storeItem.image)
|
||||
.crossfade()
|
||||
.into(_image);
|
||||
|
||||
_name.text = storeItem.name;
|
||||
_storeItem = storeItem;
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "StoreItemViewHolder";
|
||||
}
|
||||
}
|
|
@ -69,6 +69,10 @@ open class BigButton : LinearLayout {
|
|||
_textSecondary.text = attrTextSecondary;
|
||||
}
|
||||
|
||||
fun setSecondaryText(text: String?) {
|
||||
_textSecondary.text = text
|
||||
}
|
||||
|
||||
fun withPrimaryText(text: String): BigButton {
|
||||
_textPrimary.text = text;
|
||||
return this;
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package com.futo.platformplayer.views.overlays
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.widget.LinearLayout
|
||||
import com.futo.platformplayer.R
|
||||
import com.futo.platformplayer.constructs.Event0
|
||||
import com.futo.platformplayer.fragment.mainactivity.main.PolycentricProfile
|
||||
import com.futo.platformplayer.views.SupportView
|
||||
|
||||
class SupportOverlay : LinearLayout {
|
||||
val onClose = Event0();
|
||||
|
||||
private val _topbar: OverlayTopbar;
|
||||
private val _support: SupportView;
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet? = null) : super(context, attrs) {
|
||||
inflate(context, R.layout.overlay_support, this)
|
||||
_topbar = findViewById(R.id.topbar);
|
||||
_support = findViewById(R.id.support);
|
||||
|
||||
_topbar.onClose.subscribe(this, onClose::emit);
|
||||
}
|
||||
|
||||
|
||||
fun setPolycentricProfile(profile: PolycentricProfile?, animate: Boolean) {
|
||||
_support.setPolycentricProfile(profile, animate)
|
||||
}
|
||||
|
||||
fun cleanup() {
|
||||
_topbar.onClose.remove(this);
|
||||
}
|
||||
}
|
6
app/src/main/res/drawable/background_membership.xml
Normal file
6
app/src/main/res/drawable/background_membership.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#232323" />
|
||||
<corners android:radius="5dp" />
|
||||
<padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
|
||||
</shape>
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#3A1448" />
|
||||
<corners android:radius="14dp" />
|
||||
<corners android:radius="5dp" />
|
||||
<padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
|
||||
</shape>
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#144826" />
|
||||
<corners android:radius="14dp" />
|
||||
<corners android:radius="5dp" />
|
||||
<padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
|
||||
</shape>
|
9
app/src/main/res/drawable/bitcoin.xml
Normal file
9
app/src/main/res/drawable/bitcoin.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="273.6dp"
|
||||
android:height="360dp"
|
||||
android:viewportWidth="273.6"
|
||||
android:viewportHeight="360">
|
||||
<path
|
||||
android:pathData="M217.02,167.04c18.63,-9.48 30.29,-26.18 27.57,-54.01c-3.67,-38.02 -36.53,-50.77 -78.01,-54.4l-0.01,-52.74h-32.14l-0.01,51.35c-8.46,0 -17.08,0.17 -25.66,0.34L108.76,5.9l-32.11,-0l-0.01,52.73c-6.96,0.14 -13.79,0.28 -20.47,0.28v-0.16l-44.33,-0.02l0.01,34.28c0,0 23.73,-0.45 23.34,-0.01c13.01,0.01 17.26,7.56 18.48,14.08l0.01,60.08v84.4c-0.57,4.09 -2.98,10.63 -12.08,10.64c0.41,0.36 -23.38,-0 -23.38,-0l-6.38,38.33h41.82c7.79,0.01 15.45,0.13 22.96,0.19l0.03,53.34l32.1,0.01l-0.01,-52.78c8.83,0.18 17.36,0.26 25.68,0.25l-0.01,52.53h32.14l0.02,-53.25c54.02,-3.1 91.84,-16.7 96.54,-67.39C266.92,192.61 247.69,174.4 217.02,167.04zM109.54,95.32c18.13,0 75.13,-5.77 75.14,32.06c-0.01,36.27 -57,32.03 -75.14,32.03V95.32zM109.52,262.45l0.01,-70.67c21.78,-0.01 90.08,-6.26 90.09,35.32C199.64,266.97 131.31,262.43 109.52,262.45z"
|
||||
android:fillColor="#ffffff"/>
|
||||
</vector>
|
5
app/src/main/res/drawable/divider_transparent_4dp.xml
Normal file
5
app/src/main/res/drawable/divider_transparent_4dp.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<size android:height="0dp"
|
||||
android:width="4dp"/>
|
||||
</shape>
|
5
app/src/main/res/drawable/divider_transparent_8dp.xml
Normal file
5
app/src/main/res/drawable/divider_transparent_8dp.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<size android:height="0dp"
|
||||
android:width="8dp"/>
|
||||
</shape>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<size android:height="20dp"
|
||||
android:width="0dp"/>
|
||||
</shape>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<size android:height="8dp"
|
||||
android:width="0dp"/>
|
||||
</shape>
|
9
app/src/main/res/drawable/ethereum.xml
Normal file
9
app/src/main/res/drawable/ethereum.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="800dp"
|
||||
android:height="800dp"
|
||||
android:viewportWidth="32"
|
||||
android:viewportHeight="32">
|
||||
<path
|
||||
android:pathData="M15.927,23.959l-9.823,-5.797 9.817,13.839 9.828,-13.839 -9.828,5.797zM16.073,0l-9.819,16.297 9.819,5.807 9.823,-5.801z"
|
||||
android:fillColor="#ffffff"/>
|
||||
</vector>
|
|
@ -2,8 +2,7 @@
|
|||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
android:viewportHeight="960">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M480,760Q546,760 593,713Q640,666 640,600L640,440Q640,374 593,327Q546,280 480,280Q414,280 367,327Q320,374 320,440L320,600Q320,666 367,713Q414,760 480,760ZM400,640L560,640L560,560L400,560L400,640ZM400,480L560,480L560,400L400,400L400,480ZM480,520Q480,520 480,520Q480,520 480,520L480,520Q480,520 480,520Q480,520 480,520Q480,520 480,520Q480,520 480,520L480,520Q480,520 480,520Q480,520 480,520ZM480,840Q415,840 359.5,808Q304,776 272,720L160,720L160,640L244,640Q241,620 240.5,600Q240,580 240,560L160,560L160,480L240,480Q240,460 240.5,440Q241,420 244,400L160,400L160,320L272,320Q286,297 303.5,277Q321,257 344,242L280,176L336,120L422,206Q450,197 479,197Q508,197 536,206L624,120L680,176L614,242Q637,257 655.5,276.5Q674,296 688,320L800,320L800,400L716,400Q719,420 719.5,440Q720,460 720,480L800,480L800,560L720,560Q720,580 719.5,600Q719,620 716,640L800,640L800,720L688,720Q656,776 600.5,808Q545,840 480,840Z"/>
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
android:viewportHeight="960">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M380,620L660,440L380,260L380,620ZM320,840L320,760L160,760Q127,760 103.5,736.5Q80,713 80,680L80,200Q80,167 103.5,143.5Q127,120 160,120L800,120Q833,120 856.5,143.5Q880,167 880,200L880,680Q880,713 856.5,736.5Q833,760 800,760L640,760L640,840L320,840ZM160,680L800,680Q800,680 800,680Q800,680 800,680L800,200Q800,200 800,200Q800,200 800,200L160,200Q160,200 160,200Q160,200 160,200L160,680Q160,680 160,680Q160,680 160,680ZM160,680Q160,680 160,680Q160,680 160,680L160,200Q160,200 160,200Q160,200 160,200L160,200Q160,200 160,200Q160,200 160,200L160,680Q160,680 160,680Q160,680 160,680L160,680Z"/>
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
android:viewportHeight="960">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M160,760L160,680L240,680L240,400Q240,317 290,252.5Q340,188 420,168L420,140Q420,115 437.5,97.5Q455,80 480,80Q505,80 522.5,97.5Q540,115 540,140L540,168Q620,188 670,252.5Q720,317 720,400L720,680L800,680L800,760L160,760ZM480,460L480,460L480,460L480,460Q480,460 480,460Q480,460 480,460Q480,460 480,460Q480,460 480,460ZM480,880Q447,880 423.5,856.5Q400,833 400,800L560,800Q560,833 536.5,856.5Q513,880 480,880ZM320,680L640,680L640,400Q640,334 593,287Q546,240 480,240Q414,240 367,287Q320,334 320,400L320,680Z"/>
|
||||
|
|
9
app/src/main/res/drawable/ic_star.xml
Normal file
9
app/src/main/res/drawable/ic_star.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M293,796.92L342.61,584.39L177.69,441.54L394.92,422.69L480,222.31L565.08,422.69L782.31,441.54L617.39,584.39L667,796.92L480,684.08L293,796.92Z"/>
|
||||
</vector>
|
9
app/src/main/res/drawable/litecoin.xml
Normal file
9
app/src/main/res/drawable/litecoin.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="82.6dp"
|
||||
android:height="82.6dp"
|
||||
android:viewportWidth="82.6"
|
||||
android:viewportHeight="82.6">
|
||||
<path
|
||||
android:pathData="M41.3,0A41.3,41.3 0,1 0,82.6 41.3h0A41.18,41.18 0,0 0,41.54 0ZM42,42.7 L37.7,57.2h23a1.16,1.16 0,0 1,1.2 1.12v0.38l-2,6.9a1.49,1.49 0,0 1,-1.5 1.1H23.2l5.9,-20.1 -6.6,2L24,44l6.6,-2 8.3,-28.2a1.51,1.51 0,0 1,1.5 -1.1h8.9a1.16,1.16 0,0 1,1.2 1.12v0.38L43.5,38l6.6,-2 -1.4,4.8Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
</vector>
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
12
app/src/main/res/drawable/patreon.xml
Normal file
12
app/src/main/res/drawable/patreon.xml
Normal file
|
@ -0,0 +1,12 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="180dp"
|
||||
android:height="180dp"
|
||||
android:viewportWidth="180"
|
||||
android:viewportHeight="180">
|
||||
<path
|
||||
android:pathData="M108.81,26.07c-26.47,0 -48,21.53 -48,48 0,26.39 21.53,47.85 48,47.85 26.39,0 47.85,-21.47 47.85,-47.85 0,-26.47 -21.47,-48 -47.85,-48"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M23.33,153.93V26.07h23.47v127.87z"
|
||||
android:fillColor="#ffffff"/>
|
||||
</vector>
|
15
app/src/main/res/drawable/paypal.xml
Normal file
15
app/src/main/res/drawable/paypal.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:viewportWidth="32"
|
||||
android:viewportHeight="32">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12,26H7c-0.8,0 -1.6,-0.4 -2.1,-1c-0.5,-0.6 -0.7,-1.4 -0.5,-2.2L8.7,4l0,0c0.3,-1.2 1.3,-2 2.6,-2h8.6c2.3,0 4.4,1 5.9,2.8c1.4,1.8 2,4.1 1.5,6.4c-0.8,4 -4.4,6.8 -8.5,6.8h-3.2c-0.5,0 -1,0.4 -1.1,0.9L13,25.2C12.9,25.7 12.5,26 12,26z"/>
|
||||
<path
|
||||
android:pathData="M12,26H7c-0.8,0 -1.6,-0.4 -2.1,-1c-0.5,-0.6 -0.7,-1.4 -0.5,-2.2L8.7,4l0,0c0.3,-1.2 1.3,-2 2.6,-2h8.6c2.3,0 4.4,1 5.9,2.8c1.4,1.8 2,4.1 1.5,6.4c-0.8,4 -4.4,6.8 -8.5,6.8h-3.2c-0.5,0 -1,0.4 -1.1,0.9L13,25.2C12.9,25.7 12.5,26 12,26z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M29.3,11.3c0,0.1 0,0.2 0,0.3c-1,4.9 -5.4,8.4 -10.4,8.4h-2.5l-1.4,5.7C14.6,27.1 13.4,28 12,28h-2c0.1,0.4 0.2,0.7 0.5,1c0.5,0.6 1.2,0.9 2,0.9H17c0.5,0 0.9,-0.3 1,-0.7l1.4,-5.5c0.1,-0.4 0.5,-0.6 0.9,-0.6h2.9c3.7,0 7,-2.5 7.7,-6C31.3,15 30.7,12.8 29.3,11.3z"
|
||||
android:fillColor="#ffffff"/>
|
||||
</vector>
|
9
app/src/main/res/drawable/ripple.xml
Normal file
9
app/src/main/res/drawable/ripple.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="800dp"
|
||||
android:height="800dp"
|
||||
android:viewportWidth="32"
|
||||
android:viewportHeight="32">
|
||||
<path
|
||||
android:pathData="M27.401,19.531c-1.131,-0.645 -2.407,-0.837 -3.672,-0.885 -1.052,-0.031 -2.631,-0.724 -2.631,-2.645 0,-1.432 1.156,-2.588 2.647,-2.645 1.265,-0.048 2.541,-0.24 3.671,-0.891 3.193,-1.844 4.292,-5.928 2.448,-9.125 -1.859,-3.199 -5.952,-4.287 -9.156,-2.437 -2.072,1.187 -3.348,3.401 -3.339,5.787 0,1.296 0.464,2.484 1.052,3.599 0.496,0.927 0.735,2.661 -0.948,3.635 -1.265,0.724 -2.843,0.272 -3.624,-0.989 -0.661,-1.068 -1.459,-2.063 -2.589,-2.708 -3.197,-1.849 -7.291,-0.751 -9.124,2.437 -1.839,3.199 -0.745,7.281 2.452,9.125 2.068,1.187 4.609,1.187 6.677,0 1.125,-0.647 1.923,-1.641 2.584,-2.708 0.541,-0.871 1.911,-1.985 3.624,-0.991 1.267,0.719 1.657,2.319 0.948,3.641 -0.583,1.093 -1.052,2.297 -1.052,3.593 0,3.688 2.991,6.672 6.677,6.677 3.688,0 6.672,-2.989 6.677,-6.677 0.011,-2.385 -1.255,-4.599 -3.323,-5.792z"
|
||||
android:fillColor="#ffffff"/>
|
||||
</vector>
|
|
@ -1,92 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
android:layout_margin="18dp">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.futo.platformplayer.views.buttons.BigButton
|
||||
android:id="@+id/button_store"
|
||||
<com.futo.platformplayer.views.SupportView
|
||||
android:id="@+id/support"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:buttonIcon="@drawable/ic_store"
|
||||
app:buttonText="@string/store"
|
||||
app:buttonSubText="@string/visit_my_store" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginTop="20dp"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16dp"
|
||||
android:textColor="@color/white"
|
||||
android:fontFamily="@font/inter_regular"
|
||||
android:text="@string/memberships" />
|
||||
|
||||
<com.google.android.flexbox.FlexboxLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:flexWrap="wrap"
|
||||
android:layout_marginTop="5dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14dp"
|
||||
android:textColor="#909090"
|
||||
android:fontFamily="@font/inter_light"
|
||||
android:text="@string/a_monthly_recurring_payment_with_often" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14dp"
|
||||
android:textColor="#909090"
|
||||
android:fontFamily="@font/inter_bold"
|
||||
android:text="@string/additional_perks" />
|
||||
</com.google.android.flexbox.FlexboxLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp">
|
||||
|
||||
<com.futo.platformplayer.views.buttons.BigButton
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16dp"
|
||||
android:textColor="@color/white"
|
||||
android:fontFamily="@font/inter_regular"
|
||||
android:text="@string/donation"
|
||||
android:layout_marginTop="20dp"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14dp"
|
||||
android:textColor="#909090"
|
||||
android:fontFamily="@font/inter_light"
|
||||
android:text="@string/a_one_time_payment_to_support_the_creator" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp">
|
||||
|
||||
<com.futo.platformplayer.views.buttons.BigButton
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
android:layout_height="match_parent" />
|
||||
</FrameLayout>
|
|
@ -445,65 +445,10 @@
|
|||
android:text="@string/click_to_read_more"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_monetization"
|
||||
<com.futo.platformplayer.views.MonetizationView
|
||||
android:id="@+id/monetization"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="14dp"
|
||||
android:layout_marginEnd="14dp"
|
||||
android:layout_marginTop="14dp">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/button_support"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:background="@drawable/background_support">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:src="@drawable/ic_paid" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@color/white"
|
||||
android:fontFamily="@font/inter_light"
|
||||
android:text="@string/support"
|
||||
android:textSize="14dp"
|
||||
android:includeFontPadding="false"
|
||||
android:layout_marginStart="6dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/button_store"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:layout_marginStart="8dp"
|
||||
android:background="@drawable/background_store">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:src="@drawable/ic_store" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@color/white"
|
||||
android:fontFamily="@font/inter_light"
|
||||
tools:text="Store"
|
||||
android:textSize="14dp"
|
||||
android:includeFontPadding="false"
|
||||
android:layout_marginStart="6dp" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<com.futo.platformplayer.views.videometa.UpNextView
|
||||
android:id="@+id/up_next"
|
||||
|
@ -602,6 +547,12 @@
|
|||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<com.futo.platformplayer.views.overlays.SupportOverlay
|
||||
android:id="@+id/videodetail_container_support"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</FrameLayout>
|
||||
<FrameLayout
|
||||
android:id="@+id/videodetail_loading_overlay"
|
||||
|
|
25
app/src/main/res/layout/overlay_support.xml
Normal file
25
app/src/main/res/layout/overlay_support.xml
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/black"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<com.futo.platformplayer.views.overlays.OverlayTopbar
|
||||
android:id="@+id/topbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
app:title="@string/support"
|
||||
app:metadata=""
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
|
||||
<com.futo.platformplayer.views.SupportView
|
||||
android:id="@+id/support"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/topbar"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
133
app/src/main/res/layout/view_monetization.xml
Normal file
133
app/src/main/res/layout/view_monetization.xml
Normal file
|
@ -0,0 +1,133 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
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:layout_gravity="bottom"
|
||||
android:orientation="vertical"
|
||||
android:id="@+id/root">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="14dp"
|
||||
android:layout_marginEnd="14dp"
|
||||
android:layout_marginTop="14dp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:showDividers="middle"
|
||||
android:divider="@drawable/divider_transparent_4dp">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/button_membership"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:background="@drawable/background_membership">
|
||||
|
||||
<com.futo.platformplayer.views.platform.PlatformIndicator
|
||||
android:id="@+id/platform_indicator"
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@color/white"
|
||||
android:fontFamily="@font/inter_light"
|
||||
android:text="@string/membership"
|
||||
android:textSize="14dp"
|
||||
android:includeFontPadding="false"
|
||||
android:layout_marginStart="6dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/button_support"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:background="@drawable/background_support">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:src="@drawable/ic_paid" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@color/white"
|
||||
android:fontFamily="@font/inter_light"
|
||||
android:text="@string/support"
|
||||
android:textSize="14dp"
|
||||
android:includeFontPadding="false"
|
||||
android:layout_marginStart="6dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/button_store"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:background="@drawable/background_store">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:src="@drawable/ic_store" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@color/white"
|
||||
android:fontFamily="@font/inter_light"
|
||||
android:text="@string/store"
|
||||
android:textSize="14dp"
|
||||
android:includeFontPadding="false"
|
||||
android:layout_marginStart="6dp" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_merchandise"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="14dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:fontFamily="@font/inter_medium"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="17dp"
|
||||
android:text="@string/merchandise" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/layout_merchandise"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="140dp"
|
||||
android:layout_marginTop="8dp">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_merchandise"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:layout_gravity="center" />
|
||||
|
||||
<com.futo.platformplayer.views.Loader
|
||||
android:id="@+id/loader_merchandise"
|
||||
android:layout_width="64dp"
|
||||
android:layout_height="64dp"
|
||||
android:layout_gravity="center"/>
|
||||
</FrameLayout>
|
||||
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
32
app/src/main/res/layout/view_store_item.xml
Normal file
32
app/src/main/res/layout/view_store_item.xml
Normal file
|
@ -0,0 +1,32 @@
|
|||
<LinearLayout 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="100dp"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:clickable="true"
|
||||
android:id="@+id/root"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/image_item"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="100dp"
|
||||
android:scaleType="centerCrop"
|
||||
app:shapeAppearanceOverlay="@style/roundedCorners_10dp"
|
||||
android:background="#E9E9E9"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_item"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="30dp"
|
||||
tools:text="BEAST ORIGINALS HOODIE - BLACK"
|
||||
android:fontFamily="@font/inter_regular"
|
||||
android:textColor="#888888"
|
||||
android:textSize="10dp"
|
||||
android:maxLines="2"
|
||||
android:layout_marginTop="8dp"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_horizontal"
|
||||
android:layout_gravity="center_horizontal"/>
|
||||
</LinearLayout>
|
191
app/src/main/res/layout/view_support.xml
Normal file
191
app/src/main/res/layout/view_support.xml
Normal file
|
@ -0,0 +1,191 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<LinearLayout android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:layout_margin="18dp"
|
||||
android:showDividers="middle"
|
||||
android:divider="@drawable/divider_transparent_vertical_20dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_no_support_options_set"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="13dp"
|
||||
android:textColor="#909090"
|
||||
android:fontFamily="@font/inter_light"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/this_creator_has_not_set_any_support_options_on_harbor_polycentric" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_store"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16dp"
|
||||
android:textColor="@color/white"
|
||||
android:fontFamily="@font/inter_regular"
|
||||
android:text="@string/store"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="13dp"
|
||||
android:textColor="#909090"
|
||||
android:fontFamily="@font/inter_light"
|
||||
android:text="@string/a_store_by_the_creator" />
|
||||
|
||||
<com.futo.platformplayer.views.buttons.BigButton
|
||||
android:id="@+id/button_store"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:buttonIcon="@drawable/ic_store"
|
||||
app:buttonText="@string/store"
|
||||
app:buttonSubText="@string/visit_my_store"
|
||||
android:layout_marginTop="8dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_memberships"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16dp"
|
||||
android:textColor="@color/white"
|
||||
android:fontFamily="@font/inter_regular"
|
||||
android:text="@string/memberships" />
|
||||
|
||||
<com.google.android.flexbox.FlexboxLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:flexWrap="wrap"
|
||||
android:layout_marginTop="5dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="13dp"
|
||||
android:textColor="#909090"
|
||||
android:fontFamily="@font/inter_light"
|
||||
android:text="@string/a_monthly_recurring_payment_with_often" />
|
||||
|
||||
<Space android:layout_width="4dp"
|
||||
android:layout_height="match_parent"></Space>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="13dp"
|
||||
android:textColor="#909090"
|
||||
android:fontFamily="@font/inter_bold"
|
||||
android:text="@string/additional_perks" />
|
||||
</com.google.android.flexbox.FlexboxLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_membership_entries"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:orientation="vertical"
|
||||
android:showDividers="middle"
|
||||
android:divider="@drawable/divider_transparent_vertical_8dp">
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_promotions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16dp"
|
||||
android:textColor="@color/white"
|
||||
android:fontFamily="@font/inter_regular"
|
||||
android:text="@string/promotions" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="13dp"
|
||||
android:textColor="#909090"
|
||||
android:fontFamily="@font/inter_light"
|
||||
android:text="@string/current_promotions_by_this_creator" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_promotion_entries"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center_horizontal">
|
||||
|
||||
<com.futo.platformplayer.views.buttons.BigButton
|
||||
android:id="@+id/button_promotion"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:buttonIcon="@drawable/ic_star"
|
||||
app:buttonText="Promotion"
|
||||
app:buttonSubText="URL"
|
||||
android:layout_marginTop="8dp" />
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/image_promotion"
|
||||
android:layout_width="300dp"
|
||||
android:layout_height="100dp"
|
||||
android:scaleType="centerCrop"
|
||||
android:contentDescription="@string/thumbnail"
|
||||
app:shapeAppearanceOverlay="@style/roundedCorners_10dp"
|
||||
app:srcCompat="@drawable/placeholder_video_thumbnail" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_donation"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16dp"
|
||||
android:textColor="@color/white"
|
||||
android:fontFamily="@font/inter_regular"
|
||||
android:text="@string/donation" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="13dp"
|
||||
android:textColor="#909090"
|
||||
android:fontFamily="@font/inter_light"
|
||||
android:text="@string/a_one_time_payment_to_support_the_creator" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_donation_entries"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:orientation="vertical"
|
||||
android:showDividers="middle"
|
||||
android:divider="@drawable/divider_transparent_vertical_8dp">
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
|
@ -79,6 +79,7 @@
|
|||
<string name="developer">Developer</string>
|
||||
<string name="remove_historical_suggestion">Remove historical suggestion</string>
|
||||
<string name="comments">Comments</string>
|
||||
<string name="merchandise">Merchandise</string>
|
||||
<string name="reached_the_end_of_the_playlist">Reached the end of the playlist</string>
|
||||
<string name="the_playlist_will_restart_after_the_video_is_finished">The playlist will restart after the video is finished</string>
|
||||
<string name="restart_now">Restart Now</string>
|
||||
|
@ -192,15 +193,19 @@
|
|||
<string name="i_already_paid">I Already Paid</string>
|
||||
<string name="memberships">Memberships</string>
|
||||
<string name="a_monthly_recurring_payment_with_often">A monthly recurring payment with often</string>
|
||||
<string name="additional_perks">additional perks.</string>
|
||||
<string name="additional_perks">additional perks</string>
|
||||
<string name="a_one_time_payment_to_support_the_creator">A one-time payment to support the creator</string>
|
||||
<string name="a_store_by_the_creator">A store by the creator</string>
|
||||
<string name="donation">Donation</string>
|
||||
<string name="promotions">Promotions</string>
|
||||
<string name="current_promotions_by_this_creator">Current promotions by this creator</string>
|
||||
<string name="downloading">Downloading</string>
|
||||
<string name="videos">Videos</string>
|
||||
<string name="clear_history">Clear history</string>
|
||||
<string name="nothing_to_import">Nothing to import</string>
|
||||
<string name="enabling_lots_of_sources_can_reduce_the_loading_speed_of_your_application">Enabling lots of sources can reduce the loading speed of your application.</string>
|
||||
<string name="support">Support</string>
|
||||
<string name="membership">Membership</string>
|
||||
<string name="store">Store</string>
|
||||
<string name="live_chat">Live Chat</string>
|
||||
<string name="remove">Remove</string>
|
||||
|
@ -625,6 +630,7 @@
|
|||
<string name="select_your_pins_in_order">Select your pins in order</string>
|
||||
<string name="more_options">More Options</string>
|
||||
<string name="save">Save</string>
|
||||
<string name="this_creator_has_not_set_any_support_options_on_harbor_polycentric">This creator has not set any support options on Harbor (Polycentric)</string>
|
||||
<string-array name="home_screen_array">
|
||||
<item>Recommendations</item>
|
||||
<item>Subscriptions</item>
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
<item name="cornerFamily">rounded</item>
|
||||
<item name="cornerSize">4dp</item>
|
||||
</style>
|
||||
<style name="roundedCorners_10dp" parent="">
|
||||
<item name="cornerFamily">rounded</item>
|
||||
<item name="cornerSize">10dp</item>
|
||||
</style>
|
||||
<style name="roundedCorners_16dp" parent="">
|
||||
<item name="cornerFamily">rounded</item>
|
||||
<item name="cornerSize">16dp</item>
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit d02bf3d8e38b3dda1672866b894aea6e35643b20
|
||||
Subproject commit 3fe81ffb3c730f0dc9f645149dc20c31284cd790
|
Loading…
Add table
Reference in a new issue