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)