Merge pull request #827 from candry7731/Add-Loading-ux-to-movies-details-screen

loading spinner, Progress Dialog and movie details button animate
This commit is contained in:
1hitsong 2023-02-12 07:00:36 -05:00 committed by GitHub
commit 2cf133e27e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 64 additions and 10 deletions

View File

@ -19,6 +19,8 @@ sub init()
m.buttonGrp.setFocus(true)
m.top.lastFocus = m.buttonGrp
m.spinner = m.top.findNode("spinner")
m.trailerButton = m.top.findNode("trailer-button")
m.trailerButton.text = tr("Play Trailer")
@ -134,6 +136,8 @@ sub itemContentChanged()
setWatchedColor()
SetUpVideoOptions(itemData.mediaSources)
SetUpAudioOptions(itemData.mediaStreams)
m.buttonGrp.visible = true
m.spinner.visible = false
end sub

View File

@ -8,7 +8,7 @@
<Label id="releaseYear" />
<Label id="runtime" />
<Label id="officialRating" />
<LayoutGroup id="communityRatingGroup" layoutDirection="horiz" itemSpacings="[-5]">
<LayoutGroup id="communityRatingGroup" layoutDirection="horiz" itemSpacings="[-5]" visible="false">
<Poster id="star" uri="pkg:/images/sharp_star_white_18dp.png" height="32" width="32" blendColor="#cb272a" visible="false"/>
<Label id="communityRating" />
</LayoutGroup>
@ -29,7 +29,7 @@
<Label id="audio_codec" vertAlign="bottom" height="39" />
<label id="audio_codec_count" font="font:smallestSystemFont" vertAlign="top" color="#ceffff" />
</LayoutGroup>
<ButtonGroupHoriz id="buttons" itemSpacings="[10]">
<ButtonGroupHoriz id="buttons" itemSpacings="[10]" visible="false">
<Button text="Play" id="play-button" iconUri="" focusedIconUri="" maxWidth="175" minWidth="175" />
<Button text="Options" id="options-button" iconUri="" focusedIconUri="" maxWidth="250" minWidth="250" />
<Button text="Watched" id="watched-button" iconUri="" focusedIconUri="" maxWidth="350" minWidth="300" />
@ -41,6 +41,8 @@
</LayoutGroup>
</LayoutGroup>
<MovieOptions id="movieOptions" visible="false" />
<Spinner id="spinner" translation="[900, 450]" visible="true" />
<!-- "Cast and Crew" row -->
<extrasSlider id="movieExtras" />
</children>

View File

@ -1098,6 +1098,11 @@
<translation>If enabled, the number of unwatched episodes in a series/season will be removed.</translation>
<extracomment>Settings Menu - Description for option</extracomment>
</message>
<message>
<source>Loading trailer</source>
<translation>Loading trailer</translation>
<extracomment>Dialog title in Main.brs</extracomment>
</message>
<message>
<source>Next Episode Button Time</source>
<translation>Next Episode Button Time</translation>
@ -1110,3 +1115,4 @@
</message>
</context>
</TS>

View File

@ -381,6 +381,7 @@ sub Main (args as dynamic) as void
btn = getButton(msg)
group = sceneManager.callFunc("getActiveScene")
if btn <> invalid and btn.id = "play-button"
' Check if a specific Audio Stream was selected
audio_stream_idx = 1
if group.selectedAudioStreamIndex <> invalid
@ -393,7 +394,6 @@ sub Main (args as dynamic) as void
mediaSourceId = group.selectedVideoStreamId
end if
video_id = group.id
video = CreateVideoPlayerGroup(video_id, mediaSourceId, audio_stream_idx)
if video <> invalid and video.errorMsg <> "introaborted"
sceneManager.callFunc("pushScene", video)
@ -411,6 +411,9 @@ sub Main (args as dynamic) as void
end if
else if btn <> invalid and btn.id = "trailer-button"
dialog = createObject("roSGNode", "ProgressDialog")
dialog.title = tr("Loading trailer")
m.scene.dialog = dialog
audio_stream_idx = 1
mediaSourceId = invalid
video_id = group.id
@ -422,6 +425,7 @@ sub Main (args as dynamic) as void
video = CreateVideoPlayerGroup(video_id, mediaSourceId, audio_stream_idx, false, false)
if video <> invalid and video.errorMsg <> "introaborted"
sceneManager.callFunc("pushScene", video)
dialog.close = true
end if
if group.lastFocus <> invalid

View File

@ -331,6 +331,7 @@ function CreateHomeGroup()
end function
function CreateMovieDetailsGroup(movie)
startLoadingSpinner()
group = CreateObject("roSGNode", "MovieDetails")
group.overhangTitle = movie.title
group.optionsAvailable = false
@ -353,15 +354,17 @@ function CreateMovieDetailsGroup(movie)
extras = group.findNode("extrasGrid")
extras.observeField("selectedItem", m.port)
extras.callFunc("loadParts", movie.json)
stopLoadingSpinner()
return group
end function
function CreateSeriesDetailsGroup(series)
startLoadingSpinner()
' Get season data early in the function so we can check number of seasons.
seasonData = TVSeasons(series.id)
' Divert to season details if user setting goStraightToEpisodeListing is enabled and only one season exists.
if get_user_setting("ui.tvshows.goStraightToEpisodeListing") = "true" and seasonData.Items.Count() = 1
stopLoadingSpinner()
return CreateSeasonDetailsGroupByID(series.id, seasonData.Items[0].id)
end if
group = CreateObject("roSGNode", "TVShowDetails")
@ -376,7 +379,7 @@ function CreateSeriesDetailsGroup(series)
extras = group.findNode("extrasGrid")
extras.observeField("selectedItem", m.port)
extras.callFunc("loadParts", group.itemcontent.json)
stopLoadingSpinner()
return group
end function
@ -446,6 +449,7 @@ function CreateAlbumView(album)
end function
function CreateSeasonDetailsGroup(series, season)
startLoadingSpinner()
group = CreateObject("roSGNode", "TVEpisodes")
group.optionsAvailable = false
m.global.sceneManager.callFunc("pushScene", group)
@ -456,10 +460,13 @@ function CreateSeasonDetailsGroup(series, season)
group.observeField("episodeSelected", m.port)
group.observeField("quickPlayNode", m.port)
stopLoadingSpinner()
return group
end function
function CreateSeasonDetailsGroupByID(seriesID, seasonID)
startLoadingSpinner()
group = CreateObject("roSGNode", "TVEpisodes")
group.optionsAvailable = false
m.global.sceneManager.callFunc("pushScene", group)
@ -469,7 +476,7 @@ function CreateSeasonDetailsGroupByID(seriesID, seasonID)
group.observeField("episodeSelected", m.port)
group.observeField("quickPlayNode", m.port)
stopLoadingSpinner()
return group
end function
@ -513,7 +520,7 @@ sub CreateSidePanel(buttons, options)
end sub
function CreateVideoPlayerGroup(video_id, mediaSourceId = invalid, audio_stream_idx = 1, forceTranscoding = false, showIntro = true, allowResumeDialog = true)
startMediaLoadingSpinner()
' Video is Playing
video = VideoPlayer(video_id, mediaSourceId, audio_stream_idx, defaultSubtitleTrackFromVid(video_id), forceTranscoding, showIntro, allowResumeDialog)
@ -522,17 +529,18 @@ function CreateVideoPlayerGroup(video_id, mediaSourceId = invalid, audio_stream_
video.observeField("selectSubtitlePressed", m.port)
video.observeField("selectPlaybackInfoPressed", m.port)
video.observeField("state", m.port)
stopLoadingSpinner()
return video
end function
function CreatePersonView(personData as object) as object
startLoadingSpinner()
person = CreateObject("roSGNode", "PersonDetails")
m.global.SceneManager.callFunc("pushScene", person)
info = ItemMetaData(personData.id)
person.itemContent = info
stopLoadingSpinner()
person.setFocus(true)
person.observeField("selectedItem", m.port)
person.findNode("favorite-button").observeField("buttonSelected", m.port)

View File

@ -9,6 +9,7 @@ function VideoPlayer(id, mediaSourceId = invalid, audio_stream_idx = 1, subtitle
end if
if video.content = invalid
stopLoadingSpinner()
return invalid
end if
jellyfin_blue = "#00a4dcFF"
@ -59,7 +60,9 @@ sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -
playbackPosition = meta.json.UserData.PlaybackPositionTicks
if allowResumeDialog
if playbackPosition > 0
stopLoadingSpinner()
dialogResult = startPlayBackOver(playbackPosition)
startMediaLoadingSpinner()
'Dialog returns -1 when back pressed, 0 for resume, and 1 for start over
if dialogResult = -1
'User pressed back, return invalid and don't load video
@ -98,6 +101,7 @@ sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -
for each item in data.Items
m.tmp = item
end for
stopLoadingSpinner()
'Create Series Scene
CreateSeriesDetailsGroup(m.tmp)
video.content = invalid
@ -135,6 +139,7 @@ sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -
for each item in data.Items
m.Series_tmp = item
end for
stopLoadingSpinner()
'Create Season Scene
CreateSeasonDetailsGroup(m.Series_tmp, m.Season_tmp)
video.content = invalid
@ -151,6 +156,7 @@ sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -
for each item in data.Items
m.episode_id = item
end for
stopLoadingSpinner()
'Create Episode Scene
CreateMovieDetailsGroup(m.episode_id)
video.content = invalid
@ -313,7 +319,6 @@ sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -
if not fully_external
video.content = authorize_request(video.content)
end if
end sub
function PlayIntroVideo(video_id, audio_stream_idx) as boolean

View File

@ -281,3 +281,28 @@ function findNodeBySubtype(node, subtype)
return foundNodes
end function
sub startLoadingSpinner()
m.spinner = createObject("roSGNode", "Spinner")
m.spinner.translation = "[900, 450]"
m.spinner.visible = true
m.scene.appendChild(m.spinner)
end sub
sub startMediaLoadingSpinner()
dialog = createObject("roSGNode", "ProgressDialog")
dialog.id = "invisibiledialog"
dialog.visible = false
m.scene.dialog = dialog
startLoadingSpinner()
end sub
sub stopLoadingSpinner()
if isValid(m.spinner)
m.spinner.visible = false
end if
if isValid(m.scene?.dialog)
m.scene.dialog.close = true
end if
end sub