From aa758fe7a0fcf0b32afbde881e0ddbea441a5dee Mon Sep 17 00:00:00 2001 From: gooday Date: Mon, 2 Mar 2020 11:22:55 +0200 Subject: [PATCH] Coub added Resources conflicts fixed --- .../java/com/gapps/videonoapi/MainActivity.kt | 8 +- .../gapps/videonoapi/adapters/VideoAdapter.kt | 2 +- .../gapps/videonoapi/utils/ScrollListener.kt | 2 +- .../main/java/com/gapps/library/api/Const.kt | 71 ++++++++-------- .../com/gapps/library/api/VideoService.kt | 15 +++- .../models/api/DailymotionVideoInfoModel.kt | 23 ++++++ .../library/api/models/api/VideoInfoModel.kt | 14 ++++ .../api/models/video/VideoPreviewModel.kt | 1 + .../api/models/video/coub/CoubResponse.kt | 59 ++++++++++++++ .../api/models/video/rutube/RutubeResponse.kt | 16 ++-- .../bottom_dialog/BottomSheetDialogFixed.kt | 4 +- .../ui/bottom_menu/BottomVideoController.kt | 49 ++++++----- .../java/com/gapps/library/utils/Regex.kt | 7 ++ ...{ic_play_icon.png => ic_vna_play_icon.png} | Bin ...ntent_copy.xml => vna_ic_content_copy.xml} | 0 .../main/res/layout/layout_hc_video_view.xml | 77 ++++++++++-------- library/src/main/res/values-w600dp/dimens.xml | 2 +- library/src/main/res/values/colors.xml | 6 +- library/src/main/res/values/dimens.xml | 10 ++- library/src/main/res/values/strings.xml | 2 + 20 files changed, 253 insertions(+), 115 deletions(-) create mode 100644 library/src/main/java/com/gapps/library/api/models/api/DailymotionVideoInfoModel.kt create mode 100644 library/src/main/java/com/gapps/library/api/models/api/VideoInfoModel.kt create mode 100644 library/src/main/java/com/gapps/library/api/models/video/coub/CoubResponse.kt create mode 100644 library/src/main/java/com/gapps/library/utils/Regex.kt rename library/src/main/res/drawable/{ic_play_icon.png => ic_vna_play_icon.png} (100%) rename library/src/main/res/drawable/{ic_content_copy.xml => vna_ic_content_copy.xml} (100%) diff --git a/app/src/main/java/com/gapps/videonoapi/MainActivity.kt b/app/src/main/java/com/gapps/videonoapi/MainActivity.kt index 2da26fb..b2e2ac5 100644 --- a/app/src/main/java/com/gapps/videonoapi/MainActivity.kt +++ b/app/src/main/java/com/gapps/videonoapi/MainActivity.kt @@ -3,10 +3,10 @@ package com.gapps.videonoapi import android.content.* import android.net.Uri import android.os.Bundle +import android.widget.TextView import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView import com.gapps.library.api.VideoService import com.gapps.library.api.models.video.VideoPreviewModel import com.gapps.library.ui.bottom_menu.BottomVideoController @@ -26,7 +26,7 @@ class MainActivity : AppCompatActivity() { private val videoUrls = listOf( "https://www.youtube.com/watch?v=M4BSGZ07NNA", "https://music.youtube.com/watch?v=lFMOYjVCLUo", - "https://vimeo.com/333257472", + "https://vimeo.com/259411563", "https://rutube.ru/video/d70e62b44b8893e98e3e90a6e2c9fcd4/?pl_type=source&pl_id=18265", "https://www.facebook.com/UFC/videos/410056389868335/", "https://www.dailymotion.com/video/x5sxbmb", @@ -35,7 +35,8 @@ class MainActivity : AppCompatActivity() { "http://www.hulu.com/w/154323", "https://ustream.tv/channel/6540154", "https://ustream.tv/recorded/101541339", - "https://www.ted.com/talks/jill_bolte_taylor_my_stroke_of_insight" + "https://www.ted.com/talks/jill_bolte_taylor_my_stroke_of_insight", + "https://coub.com/view/um0um0" ) override fun onCreate(savedInstanceState: Bundle?) { @@ -108,6 +109,7 @@ class MainActivity : AppCompatActivity() { setSize(model.width, model.height) setTitle(title) setVideoUrl(initUrl) + setProgressView(TextView(this@MainActivity).apply { text = "Loading" }) show() } } diff --git a/app/src/main/java/com/gapps/videonoapi/adapters/VideoAdapter.kt b/app/src/main/java/com/gapps/videonoapi/adapters/VideoAdapter.kt index 0b83fd5..51b4f82 100644 --- a/app/src/main/java/com/gapps/videonoapi/adapters/VideoAdapter.kt +++ b/app/src/main/java/com/gapps/videonoapi/adapters/VideoAdapter.kt @@ -104,7 +104,7 @@ class VideoAdapter(private val videoService: VideoService, private val listener: icon_drop_down.visible() text_preview.visibleOrGone(video.videoTitle.isNullOrBlank().not()) - Picasso.get().load(video.thumbnailUrl).transform(FitThumbnailTransformation(context.getWidth(context.resources.getDimensionPixelSize(com.gapps.library.R.dimen.bv_dialog_width)))).into(image_preview) + Picasso.get().load(video.thumbnailUrl).transform(FitThumbnailTransformation(context.getWidth(context.resources.getDimensionPixelSize(com.gapps.library.R.dimen.vna_bv_dialog_width)))).into(image_preview) text_preview.text = video.videoTitle diff --git a/app/src/main/java/com/gapps/videonoapi/utils/ScrollListener.kt b/app/src/main/java/com/gapps/videonoapi/utils/ScrollListener.kt index 354a887..13258ff 100644 --- a/app/src/main/java/com/gapps/videonoapi/utils/ScrollListener.kt +++ b/app/src/main/java/com/gapps/videonoapi/utils/ScrollListener.kt @@ -4,7 +4,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView class ScrollListener(private val scrollValue: Float, private val action: (Boolean) -> Unit): RecyclerView.OnScrollListener() { - var totalDy = 0f + private var totalDy = 0f override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { super.onScrolled(recyclerView, dx, dy) diff --git a/library/src/main/java/com/gapps/library/api/Const.kt b/library/src/main/java/com/gapps/library/api/Const.kt index 8aefdcd..b9f159a 100644 --- a/library/src/main/java/com/gapps/library/api/Const.kt +++ b/library/src/main/java/com/gapps/library/api/Const.kt @@ -1,5 +1,7 @@ package com.gapps.library.api +import com.gapps.library.utils.getGroupValue + //Patterns //YouTube: https://regex101.com/r/nJzgG0/1 const val YOUTUBE_PATTERN = "(?:http(?:s)?:\\/\\/)?(?:www.)?(?:m.)?(?:music.)?youtu(?:be|.be)?(?:\\.com)?(?:(?:\\w*.?:\\/\\/)?\\w*.?\\w*-?.?\\w*\\/(?:embed|e|v|watch|.*\\/)?\\??(?:feature=\\w*\\.?\\w*)?&?(?:v=)?\\/?)([\\w\\d_-]{11})(?:\\S+)?" @@ -17,74 +19,70 @@ const val HULU_PATTERN = "(?:http[s]?:\\/\\/)?(?:www.)?hulu\\.(?:(?:com\\/\\S*(? const val USTREAM_PATTERN = "(?:http[s]?:\\/\\/)?(?:www\\.)?ustream.(?:com|tv)\\/(?:recorded|embed|channel)\\/?(?:([0-9]+)|(\\S+))(?:\\/\\S*)?" //Ted: https://regex101.com/r/Cbhu4d/2 const val TED_TALKS_PATTERN = "(?:http[s]?:\\/\\/)?(?:www|embed)?\\.?ted\\.com\\/talks\\/([_a-zA-Z0-9]+)\\S*" +//Coub: https://regex101.com/r/ZoQVLa/1 +const val COUB_PATTERN = "(?:http[s]?:\\/\\/)?(?:www)?\\.?coub\\.com\\/(?:embed|view|api)\\/([_a-zA-Z0-9]+)\\S*" //Base -private const val YOUTUBE_BASE_URL = "https://www.youtube.com" private const val VIMEO_BASE_URL = "http://vimeo.com" private const val FACEBOOK_BASE_URL = "https://apps.facebook.com" private const val DAILYMOTION_BASE_URL = "https://www.dailymotion.com" private const val WISTIA_BASE_URL = "https://fast.wistia.net" private const val RUTUBE_BASE_URL = "http://rutube.ru/api" private const val VZAAR_BASE_URL = "https://app.vzaar.com/" -private const val HULU_BASE_URL = "https://www.hulu.com/" +private const val HULU_BASE_URL = "https://www.hulu.com" private const val USTREAM_BASE_URL = "https://video.ibm.com/" -private const val TED_TALKS_BASE_URL = "https://www.ted.com/" +private const val TED_TALKS_BASE_URL = "https://www.ted.com" +private const val COUB_BASE_URL = "http://coub.com/" //Info -private const val OEMBED_INFO = "/oembed" -private const val VIMEO_INFO = "/api/v2/video/" -private const val FACEBOOK_INFO = "/plugins/video/oembed" -private const val DAILYMOTION_INFO = "/services/oembed/?url=https://www.dailymotion.com/video/" -private const val WISTIA_INFO = "/oembed?url=" -private const val USTREAM_INFO = "/oembed?url=" -private const val TED_TALKS_INFO = "services/v1/oembed.json?url=" -private const val VZAAR_INFO = "/videos/" -private const val HULU_INFO = "api/oembed.json?url=" -private const val FACEBOOK_VIDEOS = "?url=https://www.facebook.com/facebook/videos/" +private const val FACEBOOK_VIDEOS = "https://www.facebook.com/facebook/videos/" +private const val DAILYMOTION_VIDEOS = "https://www.dailymotion.com/video/" +private const val HULU_VIDEOS = "http://www.hulu.com/watch/" +private const val YOUTUBE_VIDEOS = "https://www.youtube.com/watch?v=" private const val FORMAT = "format" private const val FORMAT_JSON = "json" private const val URL = "url" fun String.getYoutubeInfoUrl(): String { - val id = YOUTUBE_PATTERN.toRegex().find(this)?.groups?.get(1)?.value - val url = "$YOUTUBE_BASE_URL/watch?v=$id" - return "$YOUTUBE_BASE_URL$OEMBED_INFO?$FORMAT=$FORMAT_JSON&$URL=$url" - + val id = YOUTUBE_PATTERN.getGroupValue(this, 1) + return "https://www.youtube.com/oembed?$FORMAT=$FORMAT_JSON&$URL=$YOUTUBE_VIDEOS$id" } fun String.getVimeoInfoUrl(): String { - val id = VIMEO_PATTERN.toRegex().find(this)?.groups?.get(1)?.value - return "$VIMEO_BASE_URL$VIMEO_INFO$id.$FORMAT_JSON" + val id = VIMEO_PATTERN.getGroupValue(this, 1) + return "$VIMEO_BASE_URL/api/v2/video/$id.$FORMAT_JSON" } - fun String.getFacebookInfoUrl(): String { - val id = FACEBOOK_PATTERN.toRegex().find(this)?.groups?.get(1)?.value - return "$FACEBOOK_BASE_URL$FACEBOOK_INFO.$FORMAT_JSON$FACEBOOK_VIDEOS$id" + val id = FACEBOOK_PATTERN.getGroupValue(this, 1) + return "$FACEBOOK_BASE_URL/plugins/video/oembed.$FORMAT_JSON?$URL=$FACEBOOK_VIDEOS$id" } fun String.getHuluInfoUrl(): String { - val id = HULU_PATTERN.toRegex().find(this)?.groups?.get(1)?.value - val url = "http://www.hulu.com/watch/$id" - return "$HULU_BASE_URL$HULU_INFO$url" + val id = HULU_PATTERN.getGroupValue(this, 1) + return "$HULU_BASE_URL/api/oembed.$FORMAT=$FORMAT_JSON&$URL=$HULU_VIDEOS$id" } fun String.getDailymotionInfoUrl(): String { - val id = DAILYMOTION_PATTERN.toRegex().find(this)?.groups?.get(1)?.value - return "$DAILYMOTION_BASE_URL$DAILYMOTION_INFO$id" + val id = DAILYMOTION_PATTERN.getGroupValue(this, 1) + return "$DAILYMOTION_BASE_URL/services/oembed/?$URL=$DAILYMOTION_VIDEOS$id" } fun String.getTedTalksInfoUrl(): String { - return "$TED_TALKS_BASE_URL$TED_TALKS_INFO$this" + return "$TED_TALKS_BASE_URL/services/v1/oembed.$FORMAT_JSON?$URL=$this" +} + +fun String.getCoubInfoUrl(): String { + return "$COUB_BASE_URL/api/oembed.$FORMAT_JSON?$URL=$this" } fun String.getWistiaInfoUrl(): String { - return "$WISTIA_BASE_URL$WISTIA_INFO$this" + return "$WISTIA_BASE_URL/oembed?$URL=$this" } fun String.getUstreamInfoUrl(): String { - val id = USTREAM_PATTERN.toRegex().find(this)?.groups?.get(1)?.value - val channelId = USTREAM_PATTERN.toRegex().find(this)?.groups?.get(2)?.value + val id = USTREAM_PATTERN.getGroupValue(this, 1) + val channelId = USTREAM_PATTERN.getGroupValue(this, 2) val url = if (id == null || this.contains("channel")) { "https://ustream.tv/channel/${channelId ?: id}" @@ -92,21 +90,20 @@ fun String.getUstreamInfoUrl(): String { "https://ustream.tv/recorded/$id" } - return "$USTREAM_BASE_URL$USTREAM_INFO$url" + return "$USTREAM_BASE_URL/oembed?$URL=$url" } fun String.getVzaarInfoUrl(): String { - val id = VZAAR_PATTERN.toRegex().find(this)?.groups?.get(1)?.value + val id = VZAAR_PATTERN.getGroupValue(this, 1) - return "$VZAAR_BASE_URL$VZAAR_INFO$id.$FORMAT_JSON" + return "$VZAAR_BASE_URL/videos/$id.$FORMAT_JSON" } - fun String.getRutubeInfoUrl(): String { - val id = RUTUBE_PATTERN.toRegex().find(this)?.groups?.get(1)?.value ?: "" + val id = RUTUBE_PATTERN.getGroupValue(this, 1) ?: "" return if (id.length < 32) { - "$RUTUBE_BASE_URL$OEMBED_INFO?$FORMAT=$FORMAT_JSON&$URL=$this" + "$RUTUBE_BASE_URL/oembed?$FORMAT=$FORMAT_JSON&$URL=$this" } else { "$RUTUBE_BASE_URL/video/$id/" } diff --git a/library/src/main/java/com/gapps/library/api/VideoService.kt b/library/src/main/java/com/gapps/library/api/VideoService.kt index fa8be81..83caf90 100644 --- a/library/src/main/java/com/gapps/library/api/VideoService.kt +++ b/library/src/main/java/com/gapps/library/api/VideoService.kt @@ -3,6 +3,7 @@ package com.gapps.library.api import android.util.Log import com.gapps.library.api.models.video.VideoPreviewModel import com.gapps.library.api.models.video.base.BaseVideoResponse +import com.gapps.library.api.models.video.coub.CoubResponse import com.gapps.library.api.models.video.dailymotion.DailymotionResponse import com.gapps.library.api.models.video.facebook.FacebookResponse import com.gapps.library.api.models.video.hulu.HuluResponse @@ -16,6 +17,7 @@ import com.gapps.library.api.models.video.youtube.YoutubeResponse import com.google.gson.GsonBuilder import com.google.gson.JsonElement import com.google.gson.JsonParser +import com.google.gson.JsonParser.parseString import kotlinx.coroutines.* import okhttp3.OkHttpClient import okhttp3.Request @@ -72,6 +74,9 @@ class VideoService( url.matches(TED_TALKS_PATTERN.toRegex()) -> { videoHelper.getTedTalksInfo(url, callback) } + url.matches(COUB_PATTERN.toRegex()) -> { + videoHelper.getCoubInfo(url, callback) + } else -> { callback.invoke(VideoPreviewModel.error(url, ERROR_1)) } @@ -98,6 +103,11 @@ class VideoService( getVideoInfo(url, url.getTedTalksInfoUrl(), TedTalksResponse::class.java, callback) } + + fun getCoubInfo(url: String, callback: (VideoPreviewModel) -> Unit) { + getVideoInfo(url, url.getCoubInfoUrl(), CoubResponse::class.java, callback) + } + fun getHuluInfo(url: String, callback: (VideoPreviewModel) -> Unit) { getVideoInfo(url, url.getHuluInfoUrl(), HuluResponse::class.java, callback) } @@ -127,7 +137,8 @@ class VideoService( } fun getYoutubeInfo(url: String, callback: (VideoPreviewModel) -> Unit) { - getVideoInfo(url, url.getYoutubeInfoUrl(), YoutubeResponse::class.java, callback) + val type = YoutubeResponse::class.java + getVideoInfo(url, url.getYoutubeInfoUrl(), type, callback) } private fun getVideoInfo(originalUrl: String?, finalUrl: String?, type: Type?, callback: (VideoPreviewModel) -> Unit) { @@ -180,7 +191,7 @@ class VideoService( return withContext(Dispatchers.IO) { val response = client.newCall(Request.Builder().url(url).build()).execute() val stringBody = response.body()?.string() ?: return@withContext null - val jsonObject = JsonParser().parse(stringBody) + val jsonObject = parseString(stringBody) return@withContext if (jsonObject.isJsonArray) { jsonObject.asJsonArray[0] diff --git a/library/src/main/java/com/gapps/library/api/models/api/DailymotionVideoInfoModel.kt b/library/src/main/java/com/gapps/library/api/models/api/DailymotionVideoInfoModel.kt new file mode 100644 index 0000000..3196867 --- /dev/null +++ b/library/src/main/java/com/gapps/library/api/models/api/DailymotionVideoInfoModel.kt @@ -0,0 +1,23 @@ +package com.gapps.library.api.models.api + +import com.gapps.library.api.DAILYMOTION_PATTERN +import com.gapps.library.api.models.video.dailymotion.DailymotionResponse +import com.gapps.library.utils.getGroupValue + +class DailymotionVideoInfoModel : VideoInfoModel { + override var pattern: String = DAILYMOTION_PATTERN + override val idPattern: String + get() = pattern + + override val type: Class = DailymotionResponse::class.java + + override fun parseVideoId(url: String?): String? { + return idPattern.getGroupValue(url, 1) + } + + override fun checkHostAffiliation(url: String?): Boolean { + url ?: return false + + return url.matches(pattern.toRegex()) + } +} \ No newline at end of file diff --git a/library/src/main/java/com/gapps/library/api/models/api/VideoInfoModel.kt b/library/src/main/java/com/gapps/library/api/models/api/VideoInfoModel.kt new file mode 100644 index 0000000..726f0f1 --- /dev/null +++ b/library/src/main/java/com/gapps/library/api/models/api/VideoInfoModel.kt @@ -0,0 +1,14 @@ +package com.gapps.library.api.models.api + +interface VideoInfoModel { + val pattern: String + val idPattern: String + val type: Class + + /** + * + */ + fun parseVideoId(url: String?): String? + + fun checkHostAffiliation(url: String?): Boolean +} \ No newline at end of file diff --git a/library/src/main/java/com/gapps/library/api/models/video/VideoPreviewModel.kt b/library/src/main/java/com/gapps/library/api/models/video/VideoPreviewModel.kt index 6f1796b..8cea65f 100644 --- a/library/src/main/java/com/gapps/library/api/models/video/VideoPreviewModel.kt +++ b/library/src/main/java/com/gapps/library/api/models/video/VideoPreviewModel.kt @@ -20,6 +20,7 @@ class VideoPreviewModel { const val RUTUBE = "Rutube" const val FACEBOOK = "Facebook" const val DAILYMOTION = "Dailymotion" + const val COUB = "Coub" const val WISTIA = "Wistia" const val VZAAR = "Vzaar" const val HULU = "Hulu" diff --git a/library/src/main/java/com/gapps/library/api/models/video/coub/CoubResponse.kt b/library/src/main/java/com/gapps/library/api/models/video/coub/CoubResponse.kt new file mode 100644 index 0000000..49b7e8b --- /dev/null +++ b/library/src/main/java/com/gapps/library/api/models/video/coub/CoubResponse.kt @@ -0,0 +1,59 @@ +package com.gapps.library.api.models.video.coub + + +import com.gapps.library.api.COUB_PATTERN +import com.gapps.library.api.FACEBOOK_PATTERN +import com.gapps.library.api.models.video.VideoPreviewModel +import com.gapps.library.api.models.video.base.BaseVideoResponse +import com.gapps.library.utils.getGroupValue +import com.google.gson.annotations.SerializedName + +data class CoubResponse( + @SerializedName("type") + val type: String = "", + @SerializedName("version") + val version: String = "", + @SerializedName("width") + val width: String = "", + @SerializedName("height") + val height: String = "", + @SerializedName("title") + val title: String = "", + @SerializedName("url") + val url: String = "", + @SerializedName("thumbnail_url") + val thumbnailUrl: String = "", + @SerializedName("thumbnail_width") + val thumbnailWidth: String = "", + @SerializedName("thumbnail_height") + val thumbnailHeight: String = "", + @SerializedName("author_name") + val authorName: String = "", + @SerializedName("channel_url") + val channelUrl: String = "", + @SerializedName("provider_name") + val providerName: String = "", + @SerializedName("provider_url") + val providerUrl: String = "", + @SerializedName("html") + val html: String = "" +): BaseVideoResponse{ + override fun toPreview(url: String?): VideoPreviewModel { + return VideoPreviewModel().apply { + this.thumbnailUrl = this@CoubResponse.thumbnailUrl + this.videoTitle = this@CoubResponse.title + this.url = url + this.videoHosting = VideoPreviewModel.DAILYMOTION + this.videoId = getVideoId(url) + this.linkToPlay = "https://coub.com/embed/${videoId}" + this.width = this@CoubResponse.width.toInt() + this.height = this@CoubResponse.height.toInt() + } + } + + override fun getVideoId(url: String?): String? { + url ?: return null + + return COUB_PATTERN.getGroupValue(url, 1) + } +} \ No newline at end of file diff --git a/library/src/main/java/com/gapps/library/api/models/video/rutube/RutubeResponse.kt b/library/src/main/java/com/gapps/library/api/models/video/rutube/RutubeResponse.kt index a562e82..ff6e33a 100644 --- a/library/src/main/java/com/gapps/library/api/models/video/rutube/RutubeResponse.kt +++ b/library/src/main/java/com/gapps/library/api/models/video/rutube/RutubeResponse.kt @@ -6,8 +6,12 @@ import com.gapps.library.api.models.video.base.BaseVideoResponse import com.google.gson.annotations.SerializedName data class RutubeResponse( - @SerializedName("action_reason") - val actionReason: Int = 0, + @SerializedName("title") + val title: String = "", + @SerializedName("thumbnail_url") + val thumbnailUrl: String = "", + @SerializedName("source_url") + val sourceUrl: String = "", @SerializedName("all_tags") val allTags: List = listOf(), @SerializedName("author") @@ -98,12 +102,6 @@ data class RutubeResponse( val shortDescription: String = "", @SerializedName("show") val show: Any? = Any(), - @SerializedName("source_url") - val sourceUrl: String = "", - @SerializedName("thumbnail_url") - val thumbnailUrl: String = "", - @SerializedName("title") - val title: String = "", @SerializedName("track_id") val trackId: Int = 0, @SerializedName("tv_show_id") @@ -128,7 +126,7 @@ data class RutubeResponse( return VideoPreviewModel().apply { this.videoTitle = this@RutubeResponse.title this.thumbnailUrl = this@RutubeResponse.thumbnailUrl - this.url = this@RutubeResponse.sourceUrl + this.url = url this.videoHosting = VideoPreviewModel.RUTUBE this.videoId = getVideoId() this.linkToPlay = "http://rutube.ru/play/embed/${this.videoId}" diff --git a/library/src/main/java/com/gapps/library/ui/bottom_dialog/BottomSheetDialogFixed.kt b/library/src/main/java/com/gapps/library/ui/bottom_dialog/BottomSheetDialogFixed.kt index 1bd7f88..c4a328c 100644 --- a/library/src/main/java/com/gapps/library/ui/bottom_dialog/BottomSheetDialogFixed.kt +++ b/library/src/main/java/com/gapps/library/ui/bottom_dialog/BottomSheetDialogFixed.kt @@ -18,10 +18,10 @@ class BottomSheetDialogFixed : BottomSheetDialog { findViewById(com.google.android.material.R.id.design_bottom_sheet)?.let { - val dialogWidth = context.resources.getDimensionPixelSize(R.dimen.bv_dialog_width) + val dialogWidth = context.resources.getDimensionPixelSize(R.dimen.vna_bv_dialog_width) it.layoutParams = it.layoutParams.apply { if (dialogWidth > 0) { - width = context.resources.getDimensionPixelSize(R.dimen.bv_dialog_width) + width = context.resources.getDimensionPixelSize(R.dimen.vna_bv_dialog_width) } } } diff --git a/library/src/main/java/com/gapps/library/ui/bottom_menu/BottomVideoController.kt b/library/src/main/java/com/gapps/library/ui/bottom_menu/BottomVideoController.kt index f672382..2e74c97 100644 --- a/library/src/main/java/com/gapps/library/ui/bottom_menu/BottomVideoController.kt +++ b/library/src/main/java/com/gapps/library/ui/bottom_menu/BottomVideoController.kt @@ -10,6 +10,7 @@ import android.os.Build import android.util.Log import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.view.WindowManager import android.webkit.WebChromeClient import android.webkit.WebResourceRequest @@ -17,7 +18,6 @@ import android.webkit.WebView import android.webkit.WebViewClient import android.widget.FrameLayout import android.widget.LinearLayout -import android.widget.ProgressBar import android.widget.TextView import androidx.annotation.ColorRes import androidx.appcompat.widget.AppCompatImageButton @@ -38,7 +38,8 @@ class BottomVideoController private constructor( private val titleText: String?, private val hostText: String?, private val playLink: String?, - private val size: Pair? + private val size: Pair?, + private val progressView: View? ) { companion object { var isVisible = false @@ -56,7 +57,8 @@ class BottomVideoController private constructor( builder.titleText, builder.hostText, builder.playLink, - builder.size + builder.size, + builder.progressView ) @SuppressLint("InflateParams", "SetJavaScriptEnabled") @@ -73,16 +75,16 @@ class BottomVideoController private constructor( val bottomSheetDialog = BottomSheetDialogFixed(context) val menuView = LayoutInflater.from(context).inflate(R.layout.layout_hc_video_view, null) - val menuContainer = menuView.findViewById(R.id.menu_container) - val videoView = menuView.findViewById(R.id.video_view) - val videoContainer = menuView.findViewById(R.id.video_container) - val progressBar = menuView.findViewById(R.id.video_progress) - val title = menuView.findViewById(R.id.text_url_preview_title) - val videoServiceType = menuView.findViewById(R.id.player_type) - val closeVideo = menuView.findViewById(R.id.close_video) - val openVideoIn = menuView.findViewById(R.id.open_video_in) - val copyLink = menuView.findViewById(R.id.copy_video_link) - val controlPanelOutline = menuView.findViewById(R.id.control_panel_outline) + val menuContainer = menuView.findViewById(R.id.vna_menu_container) + val videoView = menuView.findViewById(R.id.vna_video_view) + val videoContainer = menuView.findViewById(R.id.vna_video_container) + val progressBarContainer = menuView.findViewById(R.id.vna_video_progress_container) + val title = menuView.findViewById(R.id.vna_text_url_preview_title) + val videoServiceType = menuView.findViewById(R.id.vna_player_type) + val closeVideo = menuView.findViewById(R.id.vna_close_video) + val openVideoIn = menuView.findViewById(R.id.vna_open_video_in) + val copyLink = menuView.findViewById(R.id.vna_copy_video_link) + val controlPanelOutline = menuView.findViewById(R.id.vna_control_panel_outline) title.apply { this.setTextColor(ContextCompat.getColor(this.context, titleColor)) @@ -129,9 +131,14 @@ class BottomVideoController private constructor( val outlineColor = ColorUtils.setAlphaComponent(textColorInt, (255 * .1).toInt()) controlPanelOutline.background.colorFilter = PorterDuffColorFilter(outlineColor, PorterDuff.Mode.SRC_IN) - val videoViewWidth = context.getWidth(context.resources.getDimensionPixelSize(R.dimen.bv_dialog_width)) + val videoViewWidth = context.getWidth(context.resources.getDimensionPixelSize(R.dimen.vna_bv_dialog_width)) val videoViewHeight = getHeight(size?.first, size?.second, videoViewWidth) + if (progressView != null) { + progressBarContainer.removeAllViews() + progressBarContainer.addView(progressView) + } + videoContainer.apply { layoutParams.apply { this.width = videoViewWidth @@ -152,12 +159,12 @@ class BottomVideoController private constructor( override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) { super.onPageStarted(view, url, favicon) - progressBar.visibility = View.VISIBLE + progressBarContainer.visibility = View.VISIBLE } override fun onPageFinished(view: WebView?, url: String?) { super.onPageFinished(view, url) - progressBar.visibility = View.GONE + progressBarContainer.visibility = View.GONE } } @@ -165,7 +172,7 @@ class BottomVideoController private constructor( override fun getDefaultVideoPoster(): Bitmap? { return if (super.getDefaultVideoPoster() == null) { try { - BitmapFactory.decodeResource(context.resources, R.drawable.ic_play_icon) + BitmapFactory.decodeResource(context.resources, R.drawable.ic_vna_play_icon) } catch (e: Exception) { null } @@ -209,11 +216,11 @@ class BottomVideoController private constructor( private set @ColorRes - var titleColor = R.color.color_video_title_text + var titleColor = R.color.vna_color_video_title_text private set @ColorRes - var textColor = R.color.color_video_title_text + var textColor = R.color.vna_color_video_title_text private set @ColorRes @@ -235,11 +242,15 @@ class BottomVideoController private constructor( var size: Pair? = null private set + var progressView: View? = null + private set + fun setVideoUrl(url: String?) = apply { this.url = url } fun setTitle(title: String?) = apply { this.titleText = title } fun setHostText(host: String?) = apply { this.hostText = host } fun setPlayLink(url: String?) = apply { this.playLink = url } fun setSize(width: Int, height: Int) = apply { this.size = width.toFloat() to height.toFloat() } + fun setProgressView(view: View) = apply { this.progressView = view } fun setListener(listener: Listener) = apply { this.listener = listener } fun setTitleColor(@ColorRes color: Int) = apply { this.titleColor = color } diff --git a/library/src/main/java/com/gapps/library/utils/Regex.kt b/library/src/main/java/com/gapps/library/utils/Regex.kt new file mode 100644 index 0000000..efe7692 --- /dev/null +++ b/library/src/main/java/com/gapps/library/utils/Regex.kt @@ -0,0 +1,7 @@ +package com.gapps.library.utils + +fun String.getGroupValue(input: CharSequence?, groupIndex: Int): String? { + input ?: return null + + return this.toRegex().find(input)?.groups?.get(groupIndex)?.value +} \ No newline at end of file diff --git a/library/src/main/res/drawable/ic_play_icon.png b/library/src/main/res/drawable/ic_vna_play_icon.png similarity index 100% rename from library/src/main/res/drawable/ic_play_icon.png rename to library/src/main/res/drawable/ic_vna_play_icon.png diff --git a/library/src/main/res/drawable/ic_content_copy.xml b/library/src/main/res/drawable/vna_ic_content_copy.xml similarity index 100% rename from library/src/main/res/drawable/ic_content_copy.xml rename to library/src/main/res/drawable/vna_ic_content_copy.xml diff --git a/library/src/main/res/layout/layout_hc_video_view.xml b/library/src/main/res/layout/layout_hc_video_view.xml index fbf67b2..8d3acfc 100644 --- a/library/src/main/res/layout/layout_hc_video_view.xml +++ b/library/src/main/res/layout/layout_hc_video_view.xml @@ -2,82 +2,89 @@ + android:layout_height="@dimen/vna_web_view_default_height"> + android:layout_height="@dimen/vna_web_view_default_height" /> - + android:layout_gravity="center"> + + + + android:background="@color/vna_dialog_divider" /> + android:text="@string/vna_close" /> + android:tint="@color/vna_black_p50" + app:srcCompat="@drawable/vna_ic_content_copy" /> + android:text="@string/vna_open_in" /> \ No newline at end of file diff --git a/library/src/main/res/values-w600dp/dimens.xml b/library/src/main/res/values-w600dp/dimens.xml index 240b790..951e339 100644 --- a/library/src/main/res/values-w600dp/dimens.xml +++ b/library/src/main/res/values-w600dp/dimens.xml @@ -1,4 +1,4 @@ - 600dp + 600dp diff --git a/library/src/main/res/values/colors.xml b/library/src/main/res/values/colors.xml index 38c8ff1..2d73d17 100644 --- a/library/src/main/res/values/colors.xml +++ b/library/src/main/res/values/colors.xml @@ -1,7 +1,7 @@ - #ff1d1d26 - #80000000 - #ebebeb + #ff1d1d26 + #80000000 + #ebebeb \ No newline at end of file diff --git a/library/src/main/res/values/dimens.xml b/library/src/main/res/values/dimens.xml index a7ef746..17a0884 100644 --- a/library/src/main/res/values/dimens.xml +++ b/library/src/main/res/values/dimens.xml @@ -1,5 +1,11 @@ - 10dp - 0dp + 10dp + 0dp + 48dp + 35dp + 18dp + 14sp + 16sp + 195dp \ No newline at end of file diff --git a/library/src/main/res/values/strings.xml b/library/src/main/res/values/strings.xml index 8d49360..4d05932 100644 --- a/library/src/main/res/values/strings.xml +++ b/library/src/main/res/values/strings.xml @@ -1,3 +1,5 @@ library + open in… + close