diff --git a/components/config/ConfigScene.xml b/components/config/ConfigScene.xml
index 31836cd3..ff409711 100644
--- a/components/config/ConfigScene.xml
+++ b/components/config/ConfigScene.xml
@@ -19,8 +19,10 @@
translation="[150, 450]" />
+ translation="[150, 580]" />
diff --git a/components/liveTv/ProgramDetails.brs b/components/liveTv/ProgramDetails.brs
index b2dd03d7..99d71e3b 100644
--- a/components/liveTv/ProgramDetails.brs
+++ b/components/liveTv/ProgramDetails.brs
@@ -115,23 +115,28 @@ sub programUpdated()
day = getRelativeDayName(startDate)
+ ' Get Start Date in local timezone for display to user
+ localStartDate = createObject("roDateTime")
+ localStartDate.FromISO8601String(prog.StartDate)
+ localStartDate.ToLocalTime()
+
if startDate.AsSeconds() < now.AsSeconds() and endDate.AsSeconds() > now.AsSeconds() then
if day = "today" then
- m.broadcastDetails.text = tr("Started at") + " " + formatTime(startDate)
+ m.broadcastDetails.text = tr("Started at") + " " + formatTime(localStartDate)
else
- m.broadcastDetails.text = tr("Started") + " " + tr(day) + ", " + formatTime(startDate)
+ m.broadcastDetails.text = tr("Started") + " " + tr(day) + ", " + formatTime(localStartDate)
end if
else if startDate.AsSeconds() > now.AsSeconds()
if day = "today" then
- m.broadcastDetails.text = tr("Starts at") + " " + formatTime(startDate)
+ m.broadcastDetails.text = tr("Starts at") + " " + formatTime(localStartDate)
else
- m.broadcastDetails.text = tr("Starts") + " " + tr(day) + ", " + formatTime(startDate)
+ m.broadcastDetails.text = tr("Starts") + " " + tr(day) + ", " + formatTime(localStartDate)
end if
else
if day = "today" then
- m.broadcastDetails.text = tr("Ended at") + " " + formatTime(endDate)
+ m.broadcastDetails.text = tr("Ended at") + " " + formatTime(localStartDate)
else
- m.broadcastDetails.text = tr("Ended") + " " + tr(day) + ", " + formatTime(endDate)
+ m.broadcastDetails.text = tr("Ended") + " " + tr(day) + ", " + formatTime(localStartDate)
end if
end if
diff --git a/locale/default/translations.ts b/locale/default/translations.ts
index 030625ae..435cfda2 100644
--- a/locale/default/translations.ts
+++ b/locale/default/translations.ts
@@ -300,6 +300,11 @@
TV GuideMenu option for showing Live TV Guide / Schedule
+
+
+ Connecting to Server
+ Message to display to user while client is attempting to connect to the server
+
diff --git a/locale/en_GB/translations.ts b/locale/en_GB/translations.ts
index 06556a23..cb4c2f98 100644
--- a/locale/en_GB/translations.ts
+++ b/locale/en_GB/translations.ts
@@ -414,6 +414,10 @@
TV GuideMenu option for showing Live TV Guide / Schedule
-
+
+
+ Connecting to Server
+ Message to display to user while client is attempting to connect to the server
+
diff --git a/locale/en_US/translations.ts b/locale/en_US/translations.ts
index 2b9f03e8..5bacdfc0 100644
--- a/locale/en_US/translations.ts
+++ b/locale/en_US/translations.ts
@@ -414,6 +414,10 @@
TV GuideMenu option for showing Live TV Guide / Schedule
-
+
+
+ Connecting to Server
+ Message to display to user while client is attempting to connect to the server
+
diff --git a/source/Main.brs b/source/Main.brs
index df5b61cb..67ef0149 100644
--- a/source/Main.brs
+++ b/source/Main.brs
@@ -441,7 +441,21 @@ function LoginFlow(startOver = false as boolean)
end if
'Collect Jellyfin server and user information
start_login:
- if get_setting("server") = invalid or ServerInfo() = invalid or startOver = true then
+
+ if get_setting("server") = invalid then startOver = true
+
+ if not startOver then
+ ' Show Connecting to Server spinner
+ dialog = createObject("roSGNode", "ProgressDialog")
+ dialog.title = tr("Connecting to Server")
+ m.scene.dialog = dialog
+
+ serverInfoResult = ServerInfo()
+
+ dialog.close = true
+ end if
+
+ if startOver or serverInfoResult.Error then
print "Get server details"
SendPerformanceBeacon("AppDialogInitiate") ' Roku Performance monitoring - Dialog Starting
serverSelection = CreateServerGroup()
diff --git a/source/ShowScenes.brs b/source/ShowScenes.brs
index d0622dc9..8564258e 100644
--- a/source/ShowScenes.brs
+++ b/source/ShowScenes.brs
@@ -34,11 +34,11 @@ function CreateServerGroup()
if node = "submit"
'Append default ports
maxSlashes = 0
- if left(server_hostname.value,8) = "https://" or left(server_hostname.value,7) = "http://" then maxSlashes = 2
+ if left(lcase(server_hostname.value),8) = "https://" or left(lcase(server_hostname.value),7) = "http://" then maxSlashes = 2
'Check to make sure entry has no extra slashes before adding default ports.
if Instr(0, server_hostname.value, "/") = maxSlashes then
if server_hostname.value.len() > 5 and mid(server_hostname.value, server_hostname.value.len()-4,1) <> ":" and mid(server_hostname.value, server_hostname.value.len()-5,1) <> ":" then
- if left(server_hostname.value ,5) = "https" then
+ if left(lcase(server_hostname.value) ,5) = "https" then
server_hostname.value = server_hostname.value + ":8920"
else
server_hostname.value = server_hostname.value + ":8096"
@@ -46,19 +46,41 @@ function CreateServerGroup()
end if
end if
'Append http:// to server
- if left(server_hostname.value,4) <> "http" then server_hostname.value = "http://" + server_hostname.value
+ if left(lcase(server_hostname.value),4) <> "http" then server_hostname.value = "http://" + server_hostname.value
'If this is a different server from what we know, reset username/password setting
if get_setting("server") <> server_hostname.value then
set_setting("username", "")
set_setting("password", "")
- endif
+ end if
set_setting("server", server_hostname.value)
- if ServerInfo() = invalid then
+
+ ' Show Connecting to Server spinner
+ dialog = createObject("roSGNode", "ProgressDialog")
+ dialog.title = tr("Connecting to Server")
+ m.scene.dialog = dialog
+
+ serverInfoResult = ServerInfo()
+
+ dialog.close = true
+
+ if serverInfoResult = invalid then
' Maybe don't unset setting, but offer as a prompt
' Server not found, is it online? New values / Retry
print "Server not found, is it online? New values / Retry"
group.findNode("alert").text = tr("Server not found, is it online?")
SignOut()
+ else if serverInfoResult.Error <> invalid and serverInfoResult.Error
+ ' If server redirected received, update the URL
+ if serverInfoResult.UpdatedUrl <> invalid then
+ server_hostname.value = serverInfoResult.UpdatedUrl
+ end if
+ ' Display Error Message to user
+ message = tr("Error: ")
+ if serverInfoResult.ErrorCode <> invalid then
+ message = message + "[" + serverInfoResult.ErrorCode.toStr() + "] "
+ end if
+ group.findNode("alert").text = message + tr(serverInfoResult.ErrorMessage)
+ SignOut()
else
group.visible = false
return "true"
diff --git a/source/api/userauth.brs b/source/api/userauth.brs
index ba44365d..29d78536 100644
--- a/source/api/userauth.brs
+++ b/source/api/userauth.brs
@@ -58,8 +58,54 @@ end function
function ServerInfo()
url = "System/Info/Public"
- resp = APIRequest(url)
- return getJson(resp)
+ req = APIRequest(url)
+
+ req.setMessagePort(CreateObject("roMessagePort"))
+ req.AsyncGetToString()
+
+ ' wait 15 seconds for a server response
+ resp = wait(35000, req.GetMessagePort())
+
+ ' handle unknown errors
+ if type(resp) <> "roUrlEvent"
+ return { "Error": true, "ErrorMessage": "Unknown" }
+ end if
+
+ ' check for a location redirect header in the response
+ headers = resp.GetResponseHeaders()
+ if headers <> invalid and headers.location <> invalid then
+
+ ' only follow redirect if it the API Endpoint path is the same (/System/Info/Public)
+ ' set the server to new location and try again
+ if right(headers.location, 19) = "/System/Info/Public" then
+ set_setting("server", left(headers.location, len(headers.location) - 19))
+ info = ServerInfo()
+ if info.Error then
+ info.UpdatedUrl = left(headers.location, len(headers.location) - 19)
+ info.ErrorMessage = info.ErrorMessage + " (Note: Server redirected us to " + info.UpdatedUrl + ")"
+ end if
+ return info
+ end if
+ end if
+
+ ' handle any non 200 responses, returning the error code and message
+ if resp.GetResponseCode() <> 200 then
+ return { "Error": true, "ErrorCode": resp.GetResponseCode(), "ErrorMessage": resp.GetFailureReason() }
+ end if
+
+ ' return the parsed response string
+ responseString = resp.GetString()
+ if responseString <> invalid and responseString <> "" then
+ result = ParseJson(responseString)
+ if result <> invalid then
+ result.Error = false
+ return result
+ end if
+ end if
+
+ ' otherwise return error message
+ return { "Error": true, "ErrorMessage": "Does not appear to be a Jellyfin Server" }
+
end function
function GetPublicUsers()