mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-04-29 22:24:29 +02:00
Chapter Overlay
This commit is contained in:
parent
034b8b15ae
commit
3c05521a5b
@ -132,6 +132,7 @@ import com.futo.platformplayer.views.behavior.TouchInterceptFrameLayout
|
|||||||
import com.futo.platformplayer.views.casting.CastView
|
import com.futo.platformplayer.views.casting.CastView
|
||||||
import com.futo.platformplayer.views.comments.AddCommentView
|
import com.futo.platformplayer.views.comments.AddCommentView
|
||||||
import com.futo.platformplayer.views.others.CreatorThumbnail
|
import com.futo.platformplayer.views.others.CreatorThumbnail
|
||||||
|
import com.futo.platformplayer.views.overlays.ChaptersOverlay
|
||||||
import com.futo.platformplayer.views.overlays.DescriptionOverlay
|
import com.futo.platformplayer.views.overlays.DescriptionOverlay
|
||||||
import com.futo.platformplayer.views.overlays.LiveChatOverlay
|
import com.futo.platformplayer.views.overlays.LiveChatOverlay
|
||||||
import com.futo.platformplayer.views.overlays.QueueEditorOverlay
|
import com.futo.platformplayer.views.overlays.QueueEditorOverlay
|
||||||
@ -147,6 +148,7 @@ import com.futo.platformplayer.views.pills.PillRatingLikesDislikes
|
|||||||
import com.futo.platformplayer.views.pills.RoundButton
|
import com.futo.platformplayer.views.pills.RoundButton
|
||||||
import com.futo.platformplayer.views.pills.RoundButtonGroup
|
import com.futo.platformplayer.views.pills.RoundButtonGroup
|
||||||
import com.futo.platformplayer.views.platform.PlatformIndicator
|
import com.futo.platformplayer.views.platform.PlatformIndicator
|
||||||
|
import com.futo.platformplayer.views.segments.ChaptersList
|
||||||
import com.futo.platformplayer.views.segments.CommentsList
|
import com.futo.platformplayer.views.segments.CommentsList
|
||||||
import com.futo.platformplayer.views.subscriptions.SubscribeButton
|
import com.futo.platformplayer.views.subscriptions.SubscribeButton
|
||||||
import com.futo.platformplayer.views.video.FutoVideoPlayer
|
import com.futo.platformplayer.views.video.FutoVideoPlayer
|
||||||
@ -195,6 +197,8 @@ class VideoDetailView : ConstraintLayout {
|
|||||||
private var _liveChat: LiveChatManager? = null;
|
private var _liveChat: LiveChatManager? = null;
|
||||||
private var _videoResumePositionMilliseconds : Long = 0L;
|
private var _videoResumePositionMilliseconds : Long = 0L;
|
||||||
|
|
||||||
|
private var _chapters: List<IChapter>? = null;
|
||||||
|
|
||||||
private val _player: FutoVideoPlayer;
|
private val _player: FutoVideoPlayer;
|
||||||
private val _cast: CastView;
|
private val _cast: CastView;
|
||||||
private val _playerProgress: PlayerControlView;
|
private val _playerProgress: PlayerControlView;
|
||||||
@ -263,6 +267,7 @@ class VideoDetailView : ConstraintLayout {
|
|||||||
private val _container_content_liveChat: LiveChatOverlay;
|
private val _container_content_liveChat: LiveChatOverlay;
|
||||||
private val _container_content_browser: WebviewOverlay;
|
private val _container_content_browser: WebviewOverlay;
|
||||||
private val _container_content_support: SupportOverlay;
|
private val _container_content_support: SupportOverlay;
|
||||||
|
private val _container_content_chapters: ChaptersOverlay;
|
||||||
|
|
||||||
private var _container_content_current: View;
|
private var _container_content_current: View;
|
||||||
|
|
||||||
@ -374,6 +379,7 @@ class VideoDetailView : ConstraintLayout {
|
|||||||
_container_content_liveChat = findViewById(R.id.videodetail_container_livechat);
|
_container_content_liveChat = findViewById(R.id.videodetail_container_livechat);
|
||||||
_container_content_support = findViewById(R.id.videodetail_container_support);
|
_container_content_support = findViewById(R.id.videodetail_container_support);
|
||||||
_container_content_browser = findViewById(R.id.videodetail_container_webview)
|
_container_content_browser = findViewById(R.id.videodetail_container_webview)
|
||||||
|
_container_content_chapters = findViewById(R.id.videodetail_container_chapters);
|
||||||
|
|
||||||
_addCommentView = findViewById(R.id.add_comment_view);
|
_addCommentView = findViewById(R.id.add_comment_view);
|
||||||
_commentsList = findViewById(R.id.comments_list);
|
_commentsList = findViewById(R.id.comments_list);
|
||||||
@ -686,6 +692,11 @@ class VideoDetailView : ConstraintLayout {
|
|||||||
_container_content_replies.onClose.subscribe { switchContentView(_container_content_main); };
|
_container_content_replies.onClose.subscribe { switchContentView(_container_content_main); };
|
||||||
_container_content_support.onClose.subscribe { switchContentView(_container_content_main); };
|
_container_content_support.onClose.subscribe { switchContentView(_container_content_main); };
|
||||||
_container_content_browser.onClose.subscribe { switchContentView(_container_content_main); };
|
_container_content_browser.onClose.subscribe { switchContentView(_container_content_main); };
|
||||||
|
_container_content_chapters.onClose.subscribe { switchContentView(_container_content_main); };
|
||||||
|
|
||||||
|
_container_content_chapters.onClick.subscribe {
|
||||||
|
handleSeek(it.timeStart.toLong() * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
_description_viewMore.setOnClickListener {
|
_description_viewMore.setOnClickListener {
|
||||||
switchContentView(_container_content_description);
|
switchContentView(_container_content_description);
|
||||||
@ -865,6 +876,21 @@ class VideoDetailView : ConstraintLayout {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
_chapters?.let {
|
||||||
|
if(it != null && it.size > 0)
|
||||||
|
RoundButton(context, R.drawable.ic_list, "Chapters", TAG_CHAPTERS) {
|
||||||
|
video?.let {
|
||||||
|
try {
|
||||||
|
_container_content_chapters.setChapters(_chapters);
|
||||||
|
switchContentView(_container_content_chapters);
|
||||||
|
}
|
||||||
|
catch(ex: Throwable) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else null
|
||||||
|
},
|
||||||
if(video?.isLive ?: false)
|
if(video?.isLive ?: false)
|
||||||
RoundButton(context, R.drawable.ic_chat, context.getString(R.string.live_chat), TAG_LIVECHAT) {
|
RoundButton(context, R.drawable.ic_chat, context.getString(R.string.live_chat), TAG_LIVECHAT) {
|
||||||
video?.let {
|
video?.let {
|
||||||
@ -1340,10 +1366,12 @@ class VideoDetailView : ConstraintLayout {
|
|||||||
val chapters = null ?: StatePlatform.instance.getContentChapters(video.url);
|
val chapters = null ?: StatePlatform.instance.getContentChapters(video.url);
|
||||||
_player.setChapters(chapters);
|
_player.setChapters(chapters);
|
||||||
_cast.setChapters(chapters);
|
_cast.setChapters(chapters);
|
||||||
|
_chapters = _player.getChapters();
|
||||||
} catch (ex: Throwable) {
|
} catch (ex: Throwable) {
|
||||||
Logger.e(TAG, "Failed to get chapters", ex);
|
Logger.e(TAG, "Failed to get chapters", ex);
|
||||||
_player.setChapters(null);
|
_player.setChapters(null);
|
||||||
_cast.setChapters(null);
|
_cast.setChapters(null);
|
||||||
|
_chapters = null;
|
||||||
|
|
||||||
/*withContext(Dispatchers.Main) {
|
/*withContext(Dispatchers.Main) {
|
||||||
UIDialogs.toast(context, "Failed to get chapters\n" + ex.message);
|
UIDialogs.toast(context, "Failed to get chapters\n" + ex.message);
|
||||||
@ -1382,6 +1410,10 @@ class VideoDetailView : ConstraintLayout {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fragment.lifecycleScope.launch(Dispatchers.Main) {
|
||||||
|
updateMoreButtons();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3077,6 +3109,7 @@ class VideoDetailView : ConstraintLayout {
|
|||||||
const val TAG_SHARE = "share";
|
const val TAG_SHARE = "share";
|
||||||
const val TAG_OVERLAY = "overlay";
|
const val TAG_OVERLAY = "overlay";
|
||||||
const val TAG_LIVECHAT = "livechat";
|
const val TAG_LIVECHAT = "livechat";
|
||||||
|
const val TAG_CHAPTERS = "chapters";
|
||||||
const val TAG_OPEN = "open";
|
const val TAG_OPEN = "open";
|
||||||
const val TAG_SEND_TO_DEVICE = "send_to_device";
|
const val TAG_SEND_TO_DEVICE = "send_to_device";
|
||||||
const val TAG_MORE = "MORE";
|
const val TAG_MORE = "MORE";
|
||||||
|
@ -0,0 +1,91 @@
|
|||||||
|
package com.futo.platformplayer.views.adapters
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
||||||
|
import com.futo.platformplayer.R
|
||||||
|
import com.futo.platformplayer.Settings
|
||||||
|
import com.futo.platformplayer.api.media.models.chapters.ChapterType
|
||||||
|
import com.futo.platformplayer.api.media.models.chapters.IChapter
|
||||||
|
import com.futo.platformplayer.api.media.models.comments.IPlatformComment
|
||||||
|
import com.futo.platformplayer.api.media.models.comments.LazyComment
|
||||||
|
import com.futo.platformplayer.api.media.models.comments.PolycentricPlatformComment
|
||||||
|
import com.futo.platformplayer.api.media.models.ratings.RatingLikeDislikes
|
||||||
|
import com.futo.platformplayer.api.media.models.ratings.RatingLikes
|
||||||
|
import com.futo.platformplayer.constructs.Event1
|
||||||
|
import com.futo.platformplayer.fixHtmlLinks
|
||||||
|
import com.futo.platformplayer.setPlatformPlayerLinkMovementMethod
|
||||||
|
import com.futo.platformplayer.states.StateApp
|
||||||
|
import com.futo.platformplayer.states.StatePolycentric
|
||||||
|
import com.futo.platformplayer.toHumanDuration
|
||||||
|
import com.futo.platformplayer.toHumanNowDiffString
|
||||||
|
import com.futo.platformplayer.toHumanNumber
|
||||||
|
import com.futo.platformplayer.toHumanTime
|
||||||
|
import com.futo.platformplayer.views.LoaderView
|
||||||
|
import com.futo.platformplayer.views.others.CreatorThumbnail
|
||||||
|
import com.futo.platformplayer.views.pills.PillButton
|
||||||
|
import com.futo.platformplayer.views.pills.PillRatingLikesDislikes
|
||||||
|
import com.futo.polycentric.core.ApiMethods
|
||||||
|
import com.futo.polycentric.core.Opinion
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class ChapterViewHolder : ViewHolder {
|
||||||
|
|
||||||
|
private val _layoutChapter: ConstraintLayout;
|
||||||
|
|
||||||
|
private val _containerChapter: ConstraintLayout;
|
||||||
|
|
||||||
|
private val _textTitle: TextView;
|
||||||
|
private val _textTimestamp: TextView;
|
||||||
|
private val _textMeta: TextView;
|
||||||
|
|
||||||
|
var onClick = Event1<IChapter>();
|
||||||
|
var chapter: IChapter? = null
|
||||||
|
private set;
|
||||||
|
|
||||||
|
constructor(viewGroup: ViewGroup) : super(LayoutInflater.from(viewGroup.context).inflate(R.layout.list_chapter, viewGroup, false)) {
|
||||||
|
_layoutChapter = itemView.findViewById(R.id.layout_chapter);
|
||||||
|
_containerChapter = itemView.findViewById(R.id.chapter_container);
|
||||||
|
|
||||||
|
_containerChapter.setOnClickListener {
|
||||||
|
chapter?.let {
|
||||||
|
onClick.emit(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_textTitle = itemView.findViewById(R.id.text_title);
|
||||||
|
_textTimestamp = itemView.findViewById(R.id.text_timestamp);
|
||||||
|
_textMeta = itemView.findViewById(R.id.text_meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bind(chapter: IChapter) {
|
||||||
|
_textTitle.text = chapter.name;
|
||||||
|
_textTimestamp.text = chapter.timeStart.toLong().toHumanTime(false);
|
||||||
|
|
||||||
|
if(chapter.type == ChapterType.NORMAL) {
|
||||||
|
_textMeta.isVisible = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_textMeta.isVisible = true;
|
||||||
|
when(chapter.type) {
|
||||||
|
ChapterType.SKIP -> _textMeta.text = "(Skip)";
|
||||||
|
ChapterType.SKIPPABLE -> _textMeta.text = "(Manual Skip)"
|
||||||
|
ChapterType.SKIPONCE -> _textMeta.text = "(Skip Once)"
|
||||||
|
else -> _textMeta.isVisible = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
this.chapter = chapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "CommentViewHolder";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
package com.futo.platformplayer.views.overlays
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.net.Uri
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
import com.futo.platformplayer.R
|
||||||
|
import com.futo.platformplayer.UIDialogs
|
||||||
|
import com.futo.platformplayer.activities.MainActivity
|
||||||
|
import com.futo.platformplayer.api.http.ManagedHttpClient
|
||||||
|
import com.futo.platformplayer.api.media.models.chapters.IChapter
|
||||||
|
import com.futo.platformplayer.api.media.models.comments.IPlatformComment
|
||||||
|
import com.futo.platformplayer.api.media.models.comments.PolycentricPlatformComment
|
||||||
|
import com.futo.platformplayer.api.media.structures.IPager
|
||||||
|
import com.futo.platformplayer.constructs.Event0
|
||||||
|
import com.futo.platformplayer.constructs.Event1
|
||||||
|
import com.futo.platformplayer.fixHtmlLinks
|
||||||
|
import com.futo.platformplayer.logging.Logger
|
||||||
|
import com.futo.platformplayer.states.StateApp
|
||||||
|
import com.futo.platformplayer.states.StatePlatform
|
||||||
|
import com.futo.platformplayer.states.StatePolycentric
|
||||||
|
import com.futo.platformplayer.toHumanNowDiffString
|
||||||
|
import com.futo.platformplayer.views.behavior.NonScrollingTextView
|
||||||
|
import com.futo.platformplayer.views.comments.AddCommentView
|
||||||
|
import com.futo.platformplayer.views.others.CreatorThumbnail
|
||||||
|
import com.futo.platformplayer.views.segments.ChaptersList
|
||||||
|
import com.futo.platformplayer.views.segments.CommentsList
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.jsonArray
|
||||||
|
import kotlinx.serialization.json.jsonObject
|
||||||
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
|
import userpackage.Protocol
|
||||||
|
|
||||||
|
class ChaptersOverlay : LinearLayout {
|
||||||
|
val onClose = Event0();
|
||||||
|
val onClick = Event1<IChapter>();
|
||||||
|
|
||||||
|
private val _topbar: OverlayTopbar;
|
||||||
|
private val _chaptersList: ChaptersList;
|
||||||
|
private var _onChapterClicked: ((chapter: IChapter) -> Unit)? = null;
|
||||||
|
private val _layoutItems: LinearLayout
|
||||||
|
|
||||||
|
constructor(context: Context, attrs: AttributeSet? = null) : super(context, attrs) {
|
||||||
|
inflate(context, R.layout.overlay_chapters, this)
|
||||||
|
_layoutItems = findViewById(R.id.layout_items)
|
||||||
|
_topbar = findViewById(R.id.topbar);
|
||||||
|
_chaptersList = findViewById(R.id.chapters_list);
|
||||||
|
_chaptersList.onChapterClick.subscribe(onClick::emit);
|
||||||
|
_topbar.onClose.subscribe(this, onClose::emit);
|
||||||
|
_topbar.setInfo(context.getString(R.string.chapters), "");
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setChapters(chapters: List<IChapter>?) {
|
||||||
|
_chaptersList?.setChapters(chapters ?: listOf());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun cleanup() {
|
||||||
|
_topbar.onClose.remove(this);
|
||||||
|
_onChapterClicked = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "ChaptersOverlay"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,103 @@
|
|||||||
|
package com.futo.platformplayer.views.segments
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.view.Gravity
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.futo.platformplayer.R
|
||||||
|
import com.futo.platformplayer.UIDialogs
|
||||||
|
import com.futo.platformplayer.api.media.models.chapters.IChapter
|
||||||
|
import com.futo.platformplayer.api.media.models.comments.IPlatformComment
|
||||||
|
import com.futo.platformplayer.api.media.models.comments.LazyComment
|
||||||
|
import com.futo.platformplayer.api.media.models.comments.PolycentricPlatformComment
|
||||||
|
import com.futo.platformplayer.api.media.models.video.IPlatformVideoDetails
|
||||||
|
import com.futo.platformplayer.api.media.structures.IAsyncPager
|
||||||
|
import com.futo.platformplayer.api.media.structures.IPager
|
||||||
|
import com.futo.platformplayer.constructs.Event1
|
||||||
|
import com.futo.platformplayer.constructs.TaskHandler
|
||||||
|
import com.futo.platformplayer.engine.exceptions.ScriptUnavailableException
|
||||||
|
import com.futo.platformplayer.logging.Logger
|
||||||
|
import com.futo.platformplayer.states.StateApp
|
||||||
|
import com.futo.platformplayer.states.StatePolycentric
|
||||||
|
import com.futo.platformplayer.views.adapters.ChapterViewHolder
|
||||||
|
import com.futo.platformplayer.views.adapters.CommentViewHolder
|
||||||
|
import com.futo.platformplayer.views.adapters.InsertedViewAdapterWithLoader
|
||||||
|
import com.futo.polycentric.core.fullyBackfillServersAnnounceExceptions
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import java.net.UnknownHostException
|
||||||
|
|
||||||
|
class ChaptersList : ConstraintLayout {
|
||||||
|
private val _llmReplies: LinearLayoutManager;
|
||||||
|
|
||||||
|
private val _adapterChapters: InsertedViewAdapterWithLoader<ChapterViewHolder>;
|
||||||
|
private val _recyclerChapters: RecyclerView;
|
||||||
|
private val _chapters: ArrayList<IChapter> = arrayListOf();
|
||||||
|
private val _prependedView: FrameLayout;
|
||||||
|
private var _readonly: Boolean = false;
|
||||||
|
private val _layoutScrollToTop: FrameLayout;
|
||||||
|
|
||||||
|
var onChapterClick = Event1<IChapter>();
|
||||||
|
var onCommentsLoaded = Event1<Int>();
|
||||||
|
|
||||||
|
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
|
||||||
|
LayoutInflater.from(context).inflate(R.layout.view_chapters_list, this, true);
|
||||||
|
|
||||||
|
_recyclerChapters = findViewById(R.id.recycler_chapters);
|
||||||
|
|
||||||
|
_layoutScrollToTop = findViewById(R.id.layout_scroll_to_top);
|
||||||
|
_layoutScrollToTop.setOnClickListener {
|
||||||
|
_recyclerChapters.smoothScrollToPosition(0)
|
||||||
|
}
|
||||||
|
_layoutScrollToTop.visibility = View.GONE
|
||||||
|
|
||||||
|
_prependedView = FrameLayout(context);
|
||||||
|
_prependedView.layoutParams = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
|
||||||
|
|
||||||
|
_adapterChapters = InsertedViewAdapterWithLoader(context, arrayListOf(_prependedView), arrayListOf(),
|
||||||
|
childCountGetter = { _chapters.size },
|
||||||
|
childViewHolderBinder = { viewHolder, position -> viewHolder.bind(_chapters[position]); },
|
||||||
|
childViewHolderFactory = { viewGroup, _ ->
|
||||||
|
val holder = ChapterViewHolder(viewGroup);
|
||||||
|
holder.onClick.subscribe { c -> onChapterClick.emit(c) };
|
||||||
|
return@InsertedViewAdapterWithLoader holder;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
_llmReplies = LinearLayoutManager(context);
|
||||||
|
_recyclerChapters.layoutManager = _llmReplies;
|
||||||
|
_recyclerChapters.adapter = _adapterChapters;
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addChapter(chapter: IChapter) {
|
||||||
|
_chapters.add(0, chapter);
|
||||||
|
_adapterChapters.notifyItemRangeInserted(_adapterChapters.childToParentPosition(0), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setPrependedView(view: View) {
|
||||||
|
_prependedView.removeAllViews();
|
||||||
|
_prependedView.addView(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setChapters(chapters: List<IChapter>) {
|
||||||
|
_chapters.clear();
|
||||||
|
_chapters.addAll(chapters);
|
||||||
|
_adapterChapters.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clear() {
|
||||||
|
_chapters.clear();
|
||||||
|
_adapterChapters.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "CommentsList";
|
||||||
|
}
|
||||||
|
}
|
@ -579,6 +579,12 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
<com.futo.platformplayer.views.overlays.ChaptersOverlay
|
||||||
|
android:id="@+id/videodetail_container_chapters"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
<com.futo.platformplayer.views.overlays.SupportOverlay
|
<com.futo.platformplayer.views.overlays.SupportOverlay
|
||||||
android:id="@+id/videodetail_container_support"
|
android:id="@+id/videodetail_container_support"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
|
81
app/src/main/res/layout/list_chapter.xml
Normal file
81
app/src/main/res/layout/list_chapter.xml
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/layout_chapter"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:layout_marginBottom="5dp"
|
||||||
|
android:layout_marginStart="14dp"
|
||||||
|
android:layout_marginEnd="14dp"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/chapter_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="2dp"
|
||||||
|
android:padding="15dp"
|
||||||
|
android:background="@drawable/background_1b_round_6dp"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:fontFamily="@font/inter_regular"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="14sp"
|
||||||
|
tools:text="Some chapter text" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_meta"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:fontFamily="@font/inter_regular"
|
||||||
|
android:textColor="@color/text_color_tinted"
|
||||||
|
android:textSize="11sp"
|
||||||
|
tools:text="test" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_timestamp"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:fontFamily="@font/inter_regular"
|
||||||
|
android:background="@drawable/background_thumbnail_duration"
|
||||||
|
android:paddingLeft="10dp"
|
||||||
|
android:paddingRight="10dp"
|
||||||
|
android:paddingTop="5dp"
|
||||||
|
android:paddingBottom="5dp"
|
||||||
|
android:textColor="@color/gray_ac"
|
||||||
|
android:textSize="14sp"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:text="1:23" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
34
app/src/main/res/layout/overlay_chapters.xml
Normal file
34
app/src/main/res/layout/overlay_chapters.xml
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout
|
||||||
|
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:background="@color/black"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:id="@+id/layout_items">
|
||||||
|
|
||||||
|
<com.futo.platformplayer.views.overlays.OverlayTopbar
|
||||||
|
android:id="@+id/topbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:paddingTop="5dp"
|
||||||
|
android:paddingBottom="5dp"
|
||||||
|
android:layout_marginBottom="5dp"
|
||||||
|
app:title="Chapters"
|
||||||
|
app:metadata="" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<com.futo.platformplayer.views.segments.ChaptersList
|
||||||
|
android:id="@+id/chapters_list"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginTop="12dp" />
|
||||||
|
</LinearLayout>
|
||||||
|
</FrameLayout>
|
31
app/src/main/res/layout/view_chapters_list.xml
Normal file
31
app/src/main/res/layout/view_chapters_list.xml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recycler_chapters"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom|center_horizontal"
|
||||||
|
android:layout_marginBottom="12dp"
|
||||||
|
android:paddingBottom="7dp"
|
||||||
|
android:paddingEnd="14dp"
|
||||||
|
android:paddingTop="7dp"
|
||||||
|
android:paddingStart="14dp"
|
||||||
|
android:background="@drawable/background_pill"
|
||||||
|
android:id="@+id/layout_scroll_to_top">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/scroll_to_top"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:fontFamily="@font/inter_regular"
|
||||||
|
android:textSize="14dp"/>
|
||||||
|
</FrameLayout>
|
||||||
|
</FrameLayout>
|
@ -665,6 +665,7 @@
|
|||||||
<string name="failed_to_load_post">Failed to load post.</string>
|
<string name="failed_to_load_post">Failed to load post.</string>
|
||||||
<string name="replies">replies</string>
|
<string name="replies">replies</string>
|
||||||
<string name="Replies">Replies</string>
|
<string name="Replies">Replies</string>
|
||||||
|
<string name="chapters">Chapters</string>
|
||||||
<string name="plugin_settings_saved">Plugin settings saved</string>
|
<string name="plugin_settings_saved">Plugin settings saved</string>
|
||||||
<string name="plugin_settings">Plugin settings</string>
|
<string name="plugin_settings">Plugin settings</string>
|
||||||
<string name="these_settings_are_defined_by_the_plugin">These settings are defined by the plugin</string>
|
<string name="these_settings_are_defined_by_the_plugin">These settings are defined by the plugin</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user