diff --git a/components/ItemGrid2/GridItem.brs b/components/ItemGrid2/GridItem.brs
new file mode 100644
index 000000000..c857f3906
--- /dev/null
+++ b/components/ItemGrid2/GridItem.brs
@@ -0,0 +1,41 @@
+sub init()
+ m.itemPoster = m.top.findNode("itemPoster")
+ m.itemText = m.top.findNode("itemText")
+end sub
+
+sub itemContentChanged()
+
+ itemData = m.top.itemContent
+
+ if itemData = invalid then return
+
+ itemPoster = m.top.findNode("itemPoster")
+
+ if itemData.type = "Movie" then
+ itemPoster.uri = itemData.PosterUrl
+ m.itemText.text = itemData.Title
+ return
+ end if
+
+ print "Unhandled Item Type: " + itemData.type
+
+end sub
+
+'
+'Use FocusPercent to animate scaling of Poser Image
+sub focusChanging()
+ scaleFactor = 1 + (m.top.focusPercent * 0.17333)
+ m.itemPoster.scale = [scaleFactor, scaleFactor]
+end sub
+
+'
+'Display or hide title Visibility on focus change
+sub focusChanged()
+
+ if m.top.itemHasFocus = true then
+ m.itemText.visible = true
+ else
+ m.itemText.visible = false
+ end if
+
+end sub
diff --git a/components/ItemGrid2/GridItem.xml b/components/ItemGrid2/GridItem.xml
new file mode 100644
index 000000000..8fcf9fd99
--- /dev/null
+++ b/components/ItemGrid2/GridItem.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/ItemGrid2/ItemGrid2.brs b/components/ItemGrid2/ItemGrid2.brs
new file mode 100644
index 000000000..cc78bb3fc
--- /dev/null
+++ b/components/ItemGrid2/ItemGrid2.brs
@@ -0,0 +1,133 @@
+sub init()
+
+ m.itemGrid = m.top.findNode("itemGrid")
+ m.backdrop = m.top.findNode("backdrop")
+ m.newBackdrop = m.top.findNode("backdropTransition")
+
+ m.swapAnimation = m.top.findNode("backroundSwapAnimation")
+ m.swapAnimation.observeField("state", "swapDone")
+
+ m.loadedRows = 0
+ m.loadedItems = 0
+
+ m.data = CreateObject("roSGNode", "ContentNode")
+
+ m.itemGrid.content = m.data
+ m.itemGrid.setFocus(true)
+
+ m.itemGrid.observeField("itemFocused", "onItemFocused")
+ m.itemGrid.observeField("itemSelected", "onItemSelected")
+ m.newBackdrop.observeField("loadStatus", "newBGLoaded")
+
+ 'Background Image Queued for loading
+ m.queuedBGUri = ""
+
+ m.loadItemsTask = createObject("roSGNode", "LoadItemsTask2")
+
+end sub
+
+'
+'Load initial set of Data
+sub loadInitialItems()
+ m.loadItemsTask.itemId = m.top.itemId
+ m.loadItemsTask.observeField("content", "ItemDataLoaded")
+ m.loadItemsTask.itemType = "Movie"
+ m.loadItemsTask.control = "RUN"
+end sub
+
+'
+'Handle loaded data, and add to Grid
+sub ItemDataLoaded(msg)
+
+ itemData = msg.GetData()
+ data = msg.getField()
+
+ if itemData = invalid then
+ m.Loading = false
+ return
+ end if
+
+ for each item in itemData
+ m.data.appendChild(item)
+ end for
+
+ 'Update the stored counts
+ m.loadedItems = m.itemGrid.content.getChildCount()
+ m.loadedRows = m.loadedItems / m.itemGrid.numColumns
+ m.Loading = false
+end sub
+
+'
+'Set Background Image
+sub SetBackground(backgroundUri as string)
+
+ 'If a new image is being loaded, or transitioned to, store URL to load next
+ if m.swapAnimation.state <> "stopped" or m.newBackdrop.loadStatus = "loading" then
+ m.queuedBGUri = backgroundUri
+ return
+ end if
+
+ m.newBackdrop.uri = backgroundUri
+end sub
+
+'
+'Handle new item being focused
+sub onItemFocused()
+
+ focusedRow = CInt(m.itemGrid.itemFocused / m.itemGrid.numColumns) + 1
+
+ ' Set Background
+ itemInt = m.itemGrid.itemFocused
+
+ SetBackground(m.itemGrid.content.getChild(m.itemGrid.itemFocused).backdropUrl)
+
+ ' Load more data if focus is within last 3 rows, and there are more items to load
+ if focusedRow >= m.loadedRows - 3 and m.loadeditems < m.loadItemsTask.totalRecordCount then
+ loadMoreData()
+ end if
+end sub
+
+'
+'When Image Loading Status changes
+sub newBGLoaded()
+ 'If image load was sucessful, start the fade swap
+ if m.newBackdrop.loadStatus = "ready"
+ m.swapAnimation.control = "start"
+ end if
+end sub
+
+'
+'Swap Complete
+sub swapDone()
+
+ if m.swapAnimation.state = "stopped" then
+
+ 'Set main BG node image and hide transitioning node
+ m.backdrop.uri = m.newBackdrop.uri
+ m.backdrop.opacity = 0.25
+ m.newBackdrop.opacity = 0
+
+ 'If there is another one to load
+ if m.newBackdrop.uri <> m.queuedBGUri and m.queuedBGUri <> "" then
+ SetBackground(m.queuedBGUri)
+ m.queuedBGUri = ""
+ end if
+ end if
+end sub
+
+'
+'Load next set of items
+sub loadMoreData()
+
+ if m.Loading = true then return
+
+ m.Loading = true
+ m.loadItemsTask.startIndex = m.loadedItems
+ m.loadItemsTask.control = "RUN"
+end sub
+
+'
+'Item Selected
+sub onItemSelected()
+ m.top.selectedItem = m.itemGrid.content.getChild(m.itemGrid.itemSelected)
+end sub
\ No newline at end of file
diff --git a/components/ItemGrid2/ItemGrid2.xml b/components/ItemGrid2/ItemGrid2.xml
new file mode 100644
index 000000000..9070f7cd5
--- /dev/null
+++ b/components/ItemGrid2/ItemGrid2.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/ItemGrid2/LoadItemsTask2.brs b/components/ItemGrid2/LoadItemsTask2.brs
new file mode 100644
index 000000000..67533f736
--- /dev/null
+++ b/components/ItemGrid2/LoadItemsTask2.brs
@@ -0,0 +1,54 @@
+sub init()
+ m.top.functionName = "loadItems"
+end sub
+
+sub loadItems()
+
+ results = []
+
+ sort_order = get_user_setting("movie_sort_order", "Ascending")
+ sort_field = get_user_setting("movie_sort_field", "SortName")
+
+
+ params = {
+ limit: m.top.limit,
+ StartIndex: m.top.startIndex,
+ parentid: m.top.itemId,
+ SortBy: sort_field,
+ SortOrder: sort_order,
+ recursive: false
+ }
+
+ if m.top.ItemType <> "" then
+ params.append({ IncludeItemTypes: m.top.ItemType})
+ end if
+
+ url = Substitute("Users/{0}/Items/", get_setting("active_user"))
+ resp = APIRequest(url, params)
+ data = getJson(resp)
+
+ if data.TotalRecordCount <> invalid then
+ m.top.totalRecordCount = data.TotalRecordCount
+ end if
+
+ for each item in data.Items
+
+ tmp = invalid
+ if item.Type = "Movie" then
+ tmp = CreateObject("roSGNode", "MovieData")
+ else
+ print "Unknown Type: " item.Type
+
+ end if
+
+ if tmp <> invalid then
+
+ tmp.json = item
+ results.push(tmp)
+
+ end if
+ end for
+
+ m.top.content = results
+
+end sub
\ No newline at end of file
diff --git a/components/ItemGrid2/LoadItemsTask2.xml b/components/ItemGrid2/LoadItemsTask2.xml
new file mode 100644
index 000000000..a4e13cf58
--- /dev/null
+++ b/components/ItemGrid2/LoadItemsTask2.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/data/JFContentItem.xml b/components/data/JFContentItem.xml
new file mode 100644
index 000000000..aec8bc97b
--- /dev/null
+++ b/components/data/JFContentItem.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/data/MovieData.brs b/components/data/MovieData.brs
index ae6df0845..37df060e7 100644
--- a/components/data/MovieData.brs
+++ b/components/data/MovieData.brs
@@ -1,11 +1,27 @@
sub setFields()
+
+' print "Setting Fields in MovieData - " m.top.json.name
json = m.top.json
m.top.id = json.id
- m.top.title = json.name
- m.top.overview = json.overview
+ m.top.Title = json.name
+ m.top.Description = json.overview
m.top.favorite = json.UserData.isFavorite
m.top.watched = json.UserData.played
+ m.top.Type = "Movie"
+
+ if json.ProductionYear <> invalid then
+ m.top.SubTitle = json.ProductionYear
+ end if
+
+ if json.OfficialRating <> invalid and json.OfficialRating <> "" then
+ m.top.Rating = json.OfficialRating
+ if m.top.SubTitle <> "" then
+ m.top.SubTitle = m.top.SubTitle + " - " + m.top.Rating
+ else
+ m.top.SubTitle = m.top.Rating
+ end if
+ end if
setPoster()
setContainer()
@@ -15,9 +31,23 @@ sub setPoster()
if m.top.image <> invalid
m.top.posterURL = m.top.image.url
else
- m.top.posterURL = ""
- end if
+ if m.top.json.ImageTags.Primary <> invalid then
+
+ imgParams = { "maxHeight": 440, "maxWidth": 295, "Tag" : m.top.json.ImageTags.Primary }
+ m.top.posterURL = ImageURL(m.top.json.id, "Primary", imgParams)
+ else if m.top.json.BackdropImageTags <> invalid then
+ imgParams = { "maxHeight": 440, "Tag" : m.top.json.BackdropImageTags[0] }
+ m.top.posterURL = ImageURL(m.top.json.id, "Backdrop", imgParams)
+ end if
+
+ ' Add Backdrop Image
+ if m.top.json.BackdropImageTags <> invalid then
+ imgParams = { "maxHeight": 720, "maxWidth": 1280, "Tag" : m.top.json.BackdropImageTags[0] }
+ m.top.backdropURL = ImageURL(m.top.json.id, "Backdrop", imgParams)
+ end if
+
+ end if
end sub
sub setContainer()
diff --git a/components/data/MovieData.xml b/components/data/MovieData.xml
index 912841cef..18790cdc9 100644
--- a/components/data/MovieData.xml
+++ b/components/data/MovieData.xml
@@ -1,16 +1,13 @@
-
+
-
-
-
-
-
-
+
+
+
diff --git a/components/movies/Movies.brs b/components/movies/Movies.brs
deleted file mode 100644
index 2d379bc48..000000000
--- a/components/movies/Movies.brs
+++ /dev/null
@@ -1,14 +0,0 @@
-sub init()
-
-end sub
-
-function onKeyEvent(key as string, press as boolean) as boolean
- if not press then return false
-
- if key = "down"
- m.top.lastFocus = m.top.focusedChild
- m.top.findNode("paginator").setFocus(true)
- end if
-
- return false
-end function
\ No newline at end of file
diff --git a/components/movies/Movies.xml b/components/movies/Movies.xml
deleted file mode 100644
index 76ad96b3a..000000000
--- a/components/movies/Movies.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/images/PosterFailed.png b/images/PosterFailed.png
new file mode 100644
index 000000000..49c58baa3
Binary files /dev/null and b/images/PosterFailed.png differ
diff --git a/images/PosterLoading.png b/images/PosterLoading.png
new file mode 100644
index 000000000..88576e1b0
Binary files /dev/null and b/images/PosterLoading.png differ
diff --git a/source/Main.brs b/source/Main.brs
index 9869bfcbd..6ed8bc825 100644
--- a/source/Main.brs
+++ b/source/Main.brs
@@ -235,9 +235,7 @@ sub Main()
else if isNodeEvent(msg, "pageSelected")
group.pageNumber = msg.getRoSGNode().pageSelected
collectionType = group.subType()
- if collectionType = "Movies"
- MovieLister(group, m.page_size)
- else if collectionType = "Collections"
+ if collectionType = "Collections"
CollectionLister(group, m.page_size)
else if collectionType = "TVShows"
SeriesLister(group, m.page_size)
diff --git a/source/ShowScenes.brs b/source/ShowScenes.brs
index 37b003773..1a9dfa795 100644
--- a/source/ShowScenes.brs
+++ b/source/ShowScenes.brs
@@ -196,10 +196,10 @@ function CreateHomeGroup()
end function
function CreateMovieListGroup(libraryId)
- group = CreateObject("roSGNode", "Movies")
- group.id = libraryId
+ group = CreateObject("roSGNode", "ItemGrid2")
+ group.itemId = libraryId
- group.observeField("movieSelected", m.port)
+ group.observeField("selectedItem", m.port)
sidepanel = group.findNode("options")
movie_options = [
@@ -235,15 +235,7 @@ function CreateMovieListGroup(libraryId)
sidepanel.options = new_options
sidepanel.observeField("closeSidePanel", m.port)
- p = CreatePaginator()
- group.appendChild(p)
-
- group.pageNumber = 1
- p.currentPage = group.pageNumber
-
- MovieLister(group, m.page_size)
-
- return group
+ return group
end function
function CreateMovieDetailsGroup(movie)
@@ -397,22 +389,6 @@ function CreateVideoPlayerGroup(video_id)
return video
end function
-function MovieLister(group, page_size)
- sort_order = get_user_setting("movie_sort_order", "Ascending")
- sort_field = get_user_setting("movie_sort_field", "SortName")
-
- item_list = ItemList(group.id, {"limit": page_size,
- "StartIndex": page_size * (group.pageNumber - 1),
- "SortBy": sort_field,
- "SortOrder": sort_order,
- "IncludeItemTypes": "Movie"
- })
- group.objects = item_list
-
- p = group.findNode("paginator")
- p.maxPages = div_ceiling(group.objects.TotalRecordCount, page_size)
-end function
-
function SeriesLister(group, page_size)
sort_order = get_user_setting("series_sort_order", "Ascending")
sort_field = get_user_setting("series_sort_field", "SortName")