diff --git a/playlet-lib/src/components/ContentNode/ActionContentNode.xml b/playlet-lib/src/components/ContentNode/ActionContentNode.xml new file mode 100644 index 00000000..9643fc02 --- /dev/null +++ b/playlet-lib/src/components/ContentNode/ActionContentNode.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/playlet-lib/src/components/ContentNode/ChannelContentNode.xml b/playlet-lib/src/components/ContentNode/ChannelContentNode.xml index b5d706d9..72a8eeea 100644 --- a/playlet-lib/src/components/ContentNode/ChannelContentNode.xml +++ b/playlet-lib/src/components/ContentNode/ChannelContentNode.xml @@ -2,6 +2,6 @@ - + \ No newline at end of file diff --git a/playlet-lib/src/components/ContentNode/LoadingContentNode.xml b/playlet-lib/src/components/ContentNode/LoadingContentNode.xml index d4bca40c..dba4624f 100644 --- a/playlet-lib/src/components/ContentNode/LoadingContentNode.xml +++ b/playlet-lib/src/components/ContentNode/LoadingContentNode.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/playlet-lib/src/components/ContentNode/PlaylistContentNode.xml b/playlet-lib/src/components/ContentNode/PlaylistContentNode.xml index f8fcd28d..5981a50c 100644 --- a/playlet-lib/src/components/ContentNode/PlaylistContentNode.xml +++ b/playlet-lib/src/components/ContentNode/PlaylistContentNode.xml @@ -29,7 +29,5 @@ - - \ No newline at end of file diff --git a/playlet-lib/src/components/ContentNode/VideoContentNode.xml b/playlet-lib/src/components/ContentNode/VideoContentNode.xml index 81082ab7..3607fea9 100644 --- a/playlet-lib/src/components/ContentNode/VideoContentNode.xml +++ b/playlet-lib/src/components/ContentNode/VideoContentNode.xml @@ -13,10 +13,9 @@ + - - \ No newline at end of file diff --git a/playlet-lib/src/components/Dialog/LoginDialog.bs b/playlet-lib/src/components/Dialog/LoginDialog.bs new file mode 100644 index 00000000..3c8993d4 --- /dev/null +++ b/playlet-lib/src/components/Dialog/LoginDialog.bs @@ -0,0 +1,39 @@ +import "pkg:/source/utils/Types.bs" +import "pkg:/source/asyncTask/asyncTask.bs" +import "pkg:/components/Screens/WebAppScreen/GenerateQrCodeTask.bs" +import "pkg:/source/utils/StringUtils.bs" + +function Init() + m.urlLabel = m.top.findNode("urlLabel") + m.qrCode = m.top.findNode("QrCodePoster") + + m.top.width = "920" + m.top.observeFieldScoped("buttonSelected", FuncName(Close)) +end function + +function OnNodeReady() + address = m.webserver@.GetServerAddress(invalid) + isValidIp = not StringUtils.IsNullOrEmpty(address) + if isValidIp + m.top.url = `${address}/invidious/login` + else + m.urlLabel.text = "No IP address found" + end if + + m.invidious.observeFieldScoped("authToken", FuncName(OnAuthTokenChange)) +end function + +function Close() + m.top.close = true +end function + +function OnUrlSet() + url = m.top.url + + m.urlLabel.text = url + StartAsyncTask(GenerateQrCodeTask, { qrPoster: m.qrCode, text: url }) +end function + +function OnAuthTokenChange() + Close() +end function diff --git a/playlet-lib/src/components/Dialog/LoginDialog.xml b/playlet-lib/src/components/Dialog/LoginDialog.xml new file mode 100644 index 00000000..2d751623 --- /dev/null +++ b/playlet-lib/src/components/Dialog/LoginDialog.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/playlet-lib/src/components/EcpArgs.bs b/playlet-lib/src/components/EcpArgs.bs index ef8f9a69..b1f45316 100644 --- a/playlet-lib/src/components/EcpArgs.bs +++ b/playlet-lib/src/components/EcpArgs.bs @@ -39,6 +39,11 @@ function ProcessArguments(args as object) as void end if if not StringUtils.IsNullOrEmpty(args.videoId) - VideoUtils.PlayVideo(args) + node = CreateObject("roSGNode", "VideoContentNode") + node.videoId = args.videoId + if args.timestamp <> invalid + node.timestamp = args.timestamp + end if + VideoUtils.PlayVideo(node) end if end function diff --git a/playlet-lib/src/components/PlaylistView/PlaylistView.bs b/playlet-lib/src/components/PlaylistView/PlaylistView.bs index f386783c..ef684dde 100644 --- a/playlet-lib/src/components/PlaylistView/PlaylistView.bs +++ b/playlet-lib/src/components/PlaylistView/PlaylistView.bs @@ -92,7 +92,7 @@ function OnItemSelected(event as object) if not VideoUtils.IsVideoPlayerOpen() Close() end if - VideoUtils.PlayVideo({ content: video }) + VideoUtils.PlayVideo(video) end if end function diff --git a/playlet-lib/src/components/Services/Invidious/InvidiousService.bs b/playlet-lib/src/components/Services/Invidious/InvidiousService.bs index 6088148f..854da6c8 100644 --- a/playlet-lib/src/components/Services/Invidious/InvidiousService.bs +++ b/playlet-lib/src/components/Services/Invidious/InvidiousService.bs @@ -27,6 +27,8 @@ namespace Invidious const TOKEN_TIMESPAN = 60 * 60 * 24 * 365 * 2 '2 years + const ERROR_NOT_AUTHENTICATED = "Not authenticated" + class InvidiousService public node as object @@ -176,7 +178,7 @@ namespace Invidious if authToken = invalid return { success: false, - error: "Not authenticated" + error: ERROR_NOT_AUTHENTICATED } end if request.Url(authToken.instance + endpoint.url) diff --git a/playlet-lib/src/components/Services/Invidious/InvidiousToContentNode.bs b/playlet-lib/src/components/Services/Invidious/InvidiousToContentNode.bs index b0e07e03..746be9ab 100644 --- a/playlet-lib/src/components/Services/Invidious/InvidiousToContentNode.bs +++ b/playlet-lib/src/components/Services/Invidious/InvidiousToContentNode.bs @@ -1,3 +1,6 @@ +import "pkg:/source/utils/TimeUtils.bs" +import "pkg:/components/VideoFeed/FeedLoadState.bs" + namespace InvidiousContent function ToRowCellContentNode(item as object, instance as string) as object @@ -29,7 +32,7 @@ namespace InvidiousContent end if end function - function ToVideoContentNode(node as object, item as object, instance as string) as object + function ToVideoContentNode(node as object, item as object, instance as dynamic) as object if node = invalid node = CreateObject("roSGNode", "VideoContentNode") end if @@ -43,13 +46,15 @@ namespace InvidiousContent node.liveNow = VideoIsLive(item) VideoSetPremiereTimestampText(node, item) SetIfExists(node, "publishedText", item, "publishedText") - node.thumbnail = VideoGetThumbnail(item, instance) ?? "pkg:/images/thumbnail-missing.jpg" + if not StringUtils.IsNullOrEmpty(instance) + node.thumbnail = VideoGetThumbnail(item, instance) ?? "pkg:/images/thumbnail-missing.jpg" + end if SetIfExists(node, "title", item, "title") + SetIfExists(node, "timestamp", item, "timestamp") SetIfExists(node, "videoId", item, "videoId") node.viewCountText = VideoGetViewCountText(item) SetIfExists(node, "index", item, "index") - node.HDItemWidth = "350" return node end function @@ -93,7 +98,6 @@ namespace InvidiousContent PlaylistSetThumbnail(node, "thumbnail", item, instance) PlaylistSetThumbnail(node, "thumbnailBackground", item, instance, "maxres") - node.HDItemWidth = "350" return node end function @@ -101,7 +105,6 @@ namespace InvidiousContent node = CreateObject("roSGNode", "ChannelContentNode") node.type = "channel" - node.HDItemWidth = "200" return node end function diff --git a/playlet-lib/src/components/VideoFeed/VideoRowCell/ActionRowCell.bs b/playlet-lib/src/components/VideoFeed/VideoRowCell/ActionRowCell.bs new file mode 100644 index 00000000..f8066175 --- /dev/null +++ b/playlet-lib/src/components/VideoFeed/VideoRowCell/ActionRowCell.bs @@ -0,0 +1,13 @@ +function Init() + m.label = m.top.findNode("label") +end function + +function OnContentSet() as void + content = m.top.itemContent + + if content = invalid + return + end if + + m.label.text = content.title +end function diff --git a/playlet-lib/src/components/VideoFeed/VideoRowCell/ActionRowCell.xml b/playlet-lib/src/components/VideoFeed/VideoRowCell/ActionRowCell.xml new file mode 100644 index 00000000..751b58b0 --- /dev/null +++ b/playlet-lib/src/components/VideoFeed/VideoRowCell/ActionRowCell.xml @@ -0,0 +1,19 @@ + + + + + + + + + + \ No newline at end of file diff --git a/playlet-lib/src/components/VideoFeed/VideoRowCell/ChannelRowCell.xml b/playlet-lib/src/components/VideoFeed/VideoRowCell/ChannelRowCell.xml index 2ddbb5de..3b9b1418 100644 --- a/playlet-lib/src/components/VideoFeed/VideoRowCell/ChannelRowCell.xml +++ b/playlet-lib/src/components/VideoFeed/VideoRowCell/ChannelRowCell.xml @@ -3,6 +3,7 @@ + + + + + \ No newline at end of file diff --git a/playlet-lib/src/components/VideoFeed/VideoRowCell/VideoRowCell.xml b/playlet-lib/src/components/VideoFeed/VideoRowCell/VideoRowCell.xml index 040d831e..a263f889 100644 --- a/playlet-lib/src/components/VideoFeed/VideoRowCell/VideoRowCell.xml +++ b/playlet-lib/src/components/VideoFeed/VideoRowCell/VideoRowCell.xml @@ -3,6 +3,7 @@ + 0 + isLoading = true + while isLoading and contentNode.getChildCount() > 0 lastIndex = contentNode.getChildCount() - 1 - isPlaceHolder = contentNode.getChild(lastIndex).isPlaceHolder = true - if isPlaceHolder = true + child = contentNode.getChild(lastIndex) + isLoading = IsString(child.type) and child.type = "loading" + if isLoading = true contentNode.removeChildIndex(lastIndex) end if end while diff --git a/playlet-lib/src/components/VideoPlayer/VideoPlayer.bs b/playlet-lib/src/components/VideoPlayer/VideoPlayer.bs index d731370b..c5052365 100644 --- a/playlet-lib/src/components/VideoPlayer/VideoPlayer.bs +++ b/playlet-lib/src/components/VideoPlayer/VideoPlayer.bs @@ -7,6 +7,7 @@ import "pkg:/components/VideoPlayer/MarkVideoWatchedTask.bs" import "pkg:/components/Dialog/DialogUtils.bs" import "pkg:/source/utils/ErrorUtils.bs" import "pkg:/components/VideoPlayer/SponsorBlock.bs" +import "pkg:/components/Services/Invidious/InvidiousToContentNode.bs" function Init() m.log = new log.Logger("VideoPlayer") @@ -59,25 +60,6 @@ function PlayWithContent(contentNode as object) StartVideoContentTask(videoContentNode) end function -function PlayWithArgs(args as object) - videoContentNode = CreateObject("roSGNode", "ContentNode") - - if not StringUtils.IsNullOrEmpty(args.videoId) - videoContentNode.AddFields({ videoId: args.videoId }) - end if - if IsInt(args.timestamp) - videoContentNode.AddFields({ timestamp: args.timestamp }) - end if - if not StringUtils.IsNullOrEmpty(args.title) - videoContentNode.title = args.title - end if - if not StringUtils.IsNullOrEmpty(args.author) - videoContentNode.secondaryTitle = args.author - end if - - StartVideoContentTask(videoContentNode) -end function - function StartVideoContentTask(videoContentNode as object) if m.videoContentTask <> invalid m.videoContentTask.cancel = true @@ -226,9 +208,11 @@ function OnVideoPlayerStateChange() as void end function function PlayNext(recommendedVideos as object) as boolean + ' TODO:P0 playQueue should return content node videoArgs = m.playQueue@.Dequeue(invalid) if videoArgs <> invalid and not StringUtils.IsNullOrEmpty(videoArgs.videoId) - VideoUtils.PlayVideo(videoArgs) + node = InvidiousContent.ToVideoContentNode(invalid, videoArgs, invalid) + VideoUtils.PlayVideo(node) return true end if @@ -251,7 +235,8 @@ function PlayNextRecommendedVideo(recommendedVideos as object) as boolean end if if not m.container@.watchedVideosContain(videoId) m.log.info(`Playing next recommended video (${videoId})`) - VideoUtils.PlayVideo(metadata) + node = InvidiousContent.ToVideoContentNode(invalid, metadata, invalid) + VideoUtils.PlayVideo(node) return true end if end for diff --git a/playlet-lib/src/components/VideoPlayer/VideoPlayer.xml b/playlet-lib/src/components/VideoPlayer/VideoPlayer.xml index 72f98428..e76b5169 100644 --- a/playlet-lib/src/components/VideoPlayer/VideoPlayer.xml +++ b/playlet-lib/src/components/VideoPlayer/VideoPlayer.xml @@ -12,7 +12,6 @@ - diff --git a/playlet-lib/src/components/VideoPlayer/VideoUtils.bs b/playlet-lib/src/components/VideoPlayer/VideoUtils.bs index ee51eb93..35e8198c 100644 --- a/playlet-lib/src/components/VideoPlayer/VideoUtils.bs +++ b/playlet-lib/src/components/VideoPlayer/VideoUtils.bs @@ -2,8 +2,7 @@ import "pkg:/source/utils/FocusManagement.bs" import "pkg:/source/utils/StringUtils.bs" namespace VideoUtils - ' TODO:P0 only support content node - function PlayVideo(args as object) as void + function PlayVideo(contentNode as object) as void CloseVideo(false) container = GetVideoContainer() @@ -11,13 +10,7 @@ namespace VideoUtils videoPlayer.id = "VideoPlayer" videoPlayer@.BindNode(invalid) - if args.content <> invalid - videoPlayer@.PlayWithContent(args.content) - else if not StringUtils.IsNullOrEmpty(args.videoId) - videoPlayer@.PlayWithArgs(args) - else - return - end if + videoPlayer@.PlayWithContent(contentNode) if container.fullscreen NodeSetFocus(videoPlayer, true) diff --git a/playlet-lib/src/components/Web/PlayletWebServer/Middleware/PlayerRouter.bs b/playlet-lib/src/components/Web/PlayletWebServer/Middleware/PlayerRouter.bs index ea201c75..d93c3c84 100644 --- a/playlet-lib/src/components/Web/PlayletWebServer/Middleware/PlayerRouter.bs +++ b/playlet-lib/src/components/Web/PlayletWebServer/Middleware/PlayerRouter.bs @@ -1,4 +1,5 @@ import "pkg:/components/VideoPlayer/VideoUtils.bs" +import "pkg:/components/Services/Invidious/InvidiousToContentNode.bs" namespace Http @@ -28,7 +29,9 @@ namespace Http payload.timestamp = payload.timestamp.toInt() end if - VideoUtils.PlayVideo(payload) + node = InvidiousContent.ToVideoContentNode(invalid, payload, invalid) + VideoUtils.PlayVideo(node) + response.Default(204, "OK") return true end function)