diff --git a/components/movies/MovieDetails.bs b/components/movies/MovieDetails.bs
index 574798c93..4719f9179 100644
--- a/components/movies/MovieDetails.bs
+++ b/components/movies/MovieDetails.bs
@@ -10,6 +10,7 @@ import "pkg:/source/enums/KeyCode.bs"
import "pkg:/source/enums/MediaStreamType.bs"
import "pkg:/source/enums/PersonType.bs"
import "pkg:/source/enums/String.bs"
+import "pkg:/source/enums/TaskControl.bs"
import "pkg:/source/enums/VideoType.bs"
import "pkg:/source/enums/ViewLoadStatus.bs"
@@ -48,6 +49,40 @@ sub init()
m.global.queueManager.callFunc("setLastKnownItemID", string.empty)
m.top.observeField("itemContent", "itemContentChanged")
+
+ m.loadItemsTask = createObject("roSGNode", "LoadItemsTask")
+ m.loadItemsTask.observeField("content", "onMyListLoaded")
+ m.loadItemsTask.itemsToLoad = "isInMyList"
+end sub
+
+sub onIsInMyListChanged()
+ myListButton = m.top.findNode("mylist-button")
+ if not isValid(myListButton) then return
+
+ if m.top.isInMyList
+ myListButton.text = tr("In My List")
+ myListButton.iconBlendColor = ColorPalette.RED
+ else
+ myListButton.text = tr("Add To My List")
+ myListButton.iconBlendColor = ColorPalette.WHITE
+ end if
+end sub
+
+sub onMyListLoaded()
+ isInMyListData = m.loadItemsTask.content
+ m.loadItemsTask.unobserveField("content")
+ m.loadItemsTask.content = []
+
+ myListButton = m.top.findNode("mylist-button")
+ if not isValid(myListButton) then return
+
+ ' Invalid data returned, remove button to prevent issues
+ if not isValidAndNotEmpty(isInMyListData)
+ m.buttonGrp.content.removeChild(myListButton)
+ return
+ end if
+
+ m.top.isInMyList = isInMyListData[0]
end sub
sub onMovieExtrasHasItems()
@@ -259,6 +294,9 @@ sub itemContentChanged()
itemData = item.json
m.top.id = itemData.id
+ m.loadItemsTask.itemId = m.top.id
+ m.loadItemsTask.control = TaskControl.RUN
+
if itemData.UserData.PlaybackPositionTicks > 0
playButton = m.top.findNode("play-button")
playButton.text = `Play / Resume from ${ticksToHuman(itemData.UserData.PlaybackPositionTicks)}`
diff --git a/components/movies/MovieDetails.xml b/components/movies/MovieDetails.xml
index 4df964dd4..3fb6e6b48 100644
--- a/components/movies/MovieDetails.xml
+++ b/components/movies/MovieDetails.xml
@@ -53,6 +53,7 @@
+
@@ -71,6 +72,7 @@
+
diff --git a/images/icons/plus.png b/images/icons/plus.png
new file mode 100644
index 000000000..3234b8f0b
Binary files /dev/null and b/images/icons/plus.png differ
diff --git a/source/MainActions.bs b/source/MainActions.bs
index f4ce0189c..2eeddaadc 100644
--- a/source/MainActions.bs
+++ b/source/MainActions.bs
@@ -106,6 +106,19 @@ namespace MainAction
movie.watched = not movie.watched
end sub
+ sub onMyListButtonClicked(activeScene as object)
+ movie = chainLookup(activeScene, "itemContent")
+ if not isValid(movie.id) then return
+
+ if activeScene.isInMyList
+ MainAction.removeItemFromMyList(movie.id)
+ else
+ MainAction.addItemToMyList(movie.id)
+ end if
+
+ activeScene.isInMyList = not activeScene.isInMyList
+ end sub
+
sub onFavoriteButtonClicked(activeScene as object)
movie = chainLookup(activeScene, "itemContent")
if not isChainValid(movie, "favorite") or not isValid(movie.id) then return
@@ -181,4 +194,76 @@ namespace MainAction
dialog.close = true
end if
end sub
+
+ ' Add item to user's My List playlist
+ sub addItemToMyList(itemID as string)
+ data = api.GetUserViews({ "userId": m.global.session.user.id })
+ if not isChainValid(data, "items") then return
+
+ myListPlaylist = invalid
+
+ for each item in data.LookupCI("items")
+ if isStringEqual(item.LookupCI("CollectionType"), "playlists")
+ myListPlaylist = api.items.Get({
+ "userid": m.global.session.user.id,
+ "includeItemTypes": "Playlist",
+ "nameStartsWith": "|My List|",
+ "parentId": item.LookupCI("id")
+ })
+ exit for
+ end if
+ end for
+
+ ' My list playlist exists. Add item to it
+ if isValid(myListPlaylist) and isValidAndNotEmpty(myListPlaylist.items)
+ api.playlists.Add(myListPlaylist.items[0].LookupCI("id"), {
+ ids: itemID,
+ userid: m.global.session.user.id
+ })
+ return
+ end if
+
+ ' My list playlist does not exist. Create it with this item
+ api.playlists.Create({
+ name: "|My List|",
+ ids: [itemID],
+ userid: m.global.session.user.id,
+ mediatype: "Unknown",
+ users: [
+ {
+ userid: m.global.session.user.id,
+ canedit: true
+ }
+ ],
+ ispublic: false
+ })
+ end sub
+
+ ' Remove item from user's My List playlist
+ sub removeItemFromMyList(itemID as string)
+
+ data = api.GetUserViews({ "userId": m.global.session.user.id })
+ if not isChainValid(data, "items") then return
+
+ myListPlaylist = invalid
+
+ for each item in data.LookupCI("items")
+ if isStringEqual(item.LookupCI("CollectionType"), "playlists")
+ myListPlaylist = api.items.Get({
+ "userid": m.global.session.user.id,
+ "includeItemTypes": "Playlist",
+ "nameStartsWith": "|My List|",
+ "parentId": item.LookupCI("id")
+ })
+ exit for
+ end if
+ end for
+
+ ' My list playlist exists. Remove item from it
+ if isValid(myListPlaylist) and isValidAndNotEmpty(myListPlaylist.items)
+ api.playlists.Remove(myListPlaylist.items[0].LookupCI("id"), {
+ entryIds: itemID
+ })
+ end if
+ end sub
end namespace
diff --git a/source/MainEventHandlers.bs b/source/MainEventHandlers.bs
index d5fb01bc0..d244592dc 100644
--- a/source/MainEventHandlers.bs
+++ b/source/MainEventHandlers.bs
@@ -1079,6 +1079,12 @@ sub onButtonSelectedEvent(msg)
return
end if
+ ' Toggle item in My List
+ if isStringEqual(btn, "mylist-button")
+ MainAction.onMyListButtonClicked(activeScene)
+ return
+ end if
+
' Toggle favorite state
if isStringEqual(btn, "favorite-button")
MainAction.onFavoriteButtonClicked(activeScene)
@@ -1313,82 +1319,23 @@ end sub
sub processLibraryItemPopup(selectedPopupButton as string, itemID as string)
' Add item to user's list
if isStringEqual(selectedPopupButton, "Add To My List")
- data = api.GetUserViews({ "userId": m.global.session.user.id })
- if not isChainValid(data, "items") then return
-
- myListPlaylist = invalid
-
- for each item in data.LookupCI("items")
- if isStringEqual(item.LookupCI("CollectionType"), "playlists")
- myListPlaylist = api.items.Get({
- "userid": m.global.session.user.id,
- "includeItemTypes": "Playlist",
- "nameStartsWith": "|My List|",
- "parentId": item.LookupCI("id")
- })
- exit for
- end if
- end for
-
- ' My list playlist exists. Add item to it
- if isValid(myListPlaylist) and isValidAndNotEmpty(myListPlaylist.items)
- api.playlists.Add(myListPlaylist.items[0].LookupCI("id"), {
- ids: itemID,
- userid: m.global.session.user.id
- })
- return
- end if
-
- ' My list playlist does not exist. Create it with this item
- api.playlists.Create({
- name: "|My List|",
- ids: [itemID],
- userid: m.global.session.user.id,
- mediatype: "Unknown",
- users: [
- {
- userid: m.global.session.user.id,
- canedit: true
- }
- ],
- ispublic: false
- })
+ MainAction.addItemToMyList(itemID)
return
end if
+ ' Remove item from user's list
if isStringEqual(selectedPopupButton, "Remove From My List")
- data = api.GetUserViews({ "userId": m.global.session.user.id })
- if not isChainValid(data, "items") then return
-
- myListPlaylist = invalid
-
- for each item in data.LookupCI("items")
- if isStringEqual(item.LookupCI("CollectionType"), "playlists")
- myListPlaylist = api.items.Get({
- "userid": m.global.session.user.id,
- "includeItemTypes": "Playlist",
- "nameStartsWith": "|My List|",
- "parentId": item.LookupCI("id")
- })
- exit for
- end if
- end for
+ MainAction.removeItemFromMyList(itemID)
- ' My list playlist exists. Remove item from it
- if isValid(myListPlaylist) and isValidAndNotEmpty(myListPlaylist.items)
- api.playlists.Remove(myListPlaylist.items[0].LookupCI("id"), {
- entryIds: itemID
- })
-
- activeScene = m.global.sceneManager.callFunc("getActiveScene")
- if not isValid(activeScene) then return
+ ' If we're in My List, remove item from the item grid
+ activeScene = m.global.sceneManager.callFunc("getActiveScene")
+ if not isValid(activeScene) then return
- if isStringEqual(activeScene.parentItem.collectionType, CollectionType.MYLIST)
- itemGrid = activeScene.findNode("itemGrid")
- if not isValid(itemGrid) then return
+ if isStringEqual(activeScene.parentItem.collectionType, CollectionType.MYLIST)
+ itemGrid = activeScene.findNode("itemGrid")
+ if not isValid(itemGrid) then return
- itemGrid.content.removeChildIndex(itemGrid.itemFocused)
- end if
+ itemGrid.content.removeChildIndex(itemGrid.itemFocused)
end if
return