Merge remote-tracking branch 'upstream/unstable' into post-task-device-profile
This commit is contained in:
commit
7c2537fabf
2
.github/workflows/build-dev.yml
vendored
2
.github/workflows/build-dev.yml
vendored
|
@ -12,7 +12,7 @@ jobs:
|
|||
dev:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
|
||||
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4
|
||||
- uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # v3
|
||||
with:
|
||||
node-version: "lts/*"
|
||||
|
|
6
.github/workflows/build-prod.yml
vendored
6
.github/workflows/build-prod.yml
vendored
|
@ -13,7 +13,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout master (the latest release)
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4
|
||||
with:
|
||||
ref: master
|
||||
- name: Install jq to parse json
|
||||
|
@ -33,7 +33,7 @@ jobs:
|
|||
- name: Save old Makefile version
|
||||
run: awk 'BEGIN { FS=" = " } /^VERSION/ { print "oldMakeVersion="$2; }' Makefile >> $GITHUB_ENV
|
||||
- name: Checkout PR branch
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4
|
||||
- name: Save new package.json version
|
||||
run: echo "newPackVersion=$(jq -r ".version" package.json)" >> $GITHUB_ENV
|
||||
- name: package.json version must be updated
|
||||
|
@ -61,7 +61,7 @@ jobs:
|
|||
prod:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
|
||||
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4
|
||||
- uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # v3
|
||||
with:
|
||||
node-version: "lts/*"
|
||||
|
|
2
.github/workflows/roku-analysis.yml
vendored
2
.github/workflows/roku-analysis.yml
vendored
|
@ -11,7 +11,7 @@ jobs:
|
|||
static:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4
|
||||
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4
|
||||
- uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # v3
|
||||
with:
|
||||
node-version: "lts/*"
|
||||
|
|
|
@ -53,6 +53,9 @@ sub itemContentChanged()
|
|||
if itemData.json.UserData.UnplayedItemCount > 0
|
||||
m.unplayedCount.visible = true
|
||||
m.unplayedEpisodeCount.text = itemData.json.UserData.UnplayedItemCount
|
||||
else
|
||||
m.unplayedCount.visible = false
|
||||
m.unplayedEpisodeCount.text = ""
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
|
|
|
@ -80,7 +80,6 @@ sub popScene()
|
|||
group = m.groups.pop()
|
||||
if group <> invalid
|
||||
groupType = group.subtype()
|
||||
|
||||
if groupType = "JFGroup"
|
||||
unregisterOverhangData(group)
|
||||
else if groupType = "JFVideo"
|
||||
|
|
|
@ -20,9 +20,6 @@ sub loadFromRegistry(id as string)
|
|||
end sub
|
||||
|
||||
sub saveToRegistry()
|
||||
set_user_setting("username", m.top.username)
|
||||
set_user_setting("token", m.top.token)
|
||||
|
||||
users = parseJson(get_setting("available_users", "[]"))
|
||||
this_user = invalid
|
||||
for each user in users
|
||||
|
@ -57,7 +54,9 @@ function setPreference(key as string, value as string)
|
|||
end function
|
||||
|
||||
sub setActive()
|
||||
set_setting("active_user", m.top.id)
|
||||
if m.global.session.user.settings["global.rememberme"]
|
||||
set_setting("active_user", m.top.id)
|
||||
end if
|
||||
end sub
|
||||
|
||||
sub setServer(hostname as string)
|
||||
|
|
|
@ -38,11 +38,13 @@ end sub
|
|||
sub trailerAvailableChanged()
|
||||
if m.top.trailerAvailable
|
||||
' add trailor button to button group
|
||||
trailerButton = CreateObject("roSGNode", "JFButton")
|
||||
trailerButton = CreateObject("roSGNode", "Button")
|
||||
trailerButton.id = "trailer-button"
|
||||
trailerButton.text = tr("Play Trailer")
|
||||
trailerButton.iconUri = ""
|
||||
trailerButton.focusedIconUri = ""
|
||||
trailerButton.maxWidth = "300"
|
||||
trailerButton.minWidth = "300"
|
||||
trailerButton.minWidth = "280"
|
||||
m.buttonGrp.appendChild(trailerButton)
|
||||
else
|
||||
' remove trailor button from button group
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import "pkg:/source/utils/config.brs"
|
||||
import "pkg:/source/utils/misc.brs"
|
||||
import "pkg:/source/roku_modules/log/LogMixin.brs"
|
||||
import "pkg:/source/api/sdk.bs"
|
||||
|
||||
sub init()
|
||||
m.log = log.Logger("Settings")
|
||||
m.top.overhangTitle = tr("Settings")
|
||||
m.top.optionsAvailable = false
|
||||
|
||||
m.userLocation = []
|
||||
|
@ -12,7 +12,6 @@ sub init()
|
|||
m.settingsMenu = m.top.findNode("settingsMenu")
|
||||
m.settingDetail = m.top.findNode("settingDetail")
|
||||
m.settingDesc = m.top.findNode("settingDesc")
|
||||
m.settingTitle = m.top.findNode("settingTitle")
|
||||
m.path = m.top.findNode("path")
|
||||
|
||||
m.boolSetting = m.top.findNode("boolSetting")
|
||||
|
@ -72,7 +71,7 @@ sub LoadMenu(configSection)
|
|||
end if
|
||||
|
||||
' Set Path display
|
||||
m.path.text = ""
|
||||
m.path.text = tr("Settings")
|
||||
for each level in m.userLocation
|
||||
if level.title <> invalid then m.path.text += " / " + tr(level.title)
|
||||
end for
|
||||
|
@ -82,7 +81,7 @@ sub settingFocused()
|
|||
|
||||
selectedSetting = m.userLocation.peek().children[m.settingsMenu.itemFocused]
|
||||
m.settingDesc.text = tr(selectedSetting.Description)
|
||||
m.settingTitle.text = tr(selectedSetting.Title)
|
||||
m.top.overhangTitle = tr(selectedSetting.Title)
|
||||
|
||||
' Hide Settings
|
||||
m.boolSetting.visible = false
|
||||
|
@ -160,14 +159,40 @@ end sub
|
|||
|
||||
|
||||
sub boolSettingChanged()
|
||||
|
||||
if m.boolSetting.focusedChild = invalid then return
|
||||
selectedSetting = m.userLocation.peek().children[m.settingsMenu.itemFocused]
|
||||
|
||||
if m.boolSetting.checkedItem
|
||||
set_user_setting(selectedSetting.settingName, "true")
|
||||
session.user.settings.Save(selectedSetting.settingName, "true")
|
||||
if Left(selectedSetting.settingName, 7) = "global."
|
||||
' global user setting
|
||||
' save to main registry block
|
||||
set_setting(selectedSetting.settingName, "true")
|
||||
' setting specific triggers
|
||||
if selectedSetting.settingName = "global.rememberme"
|
||||
print "m.global.session.user.id=", m.global.session.user.id
|
||||
set_setting("active_user", m.global.session.user.id)
|
||||
end if
|
||||
else
|
||||
' regular user setting
|
||||
' save to user specific registry block
|
||||
set_user_setting(selectedSetting.settingName, "true")
|
||||
end if
|
||||
else
|
||||
set_user_setting(selectedSetting.settingName, "false")
|
||||
session.user.settings.Save(selectedSetting.settingName, "false")
|
||||
if Left(selectedSetting.settingName, 7) = "global."
|
||||
' global user setting
|
||||
' save to main registry block
|
||||
set_setting(selectedSetting.settingName, "false")
|
||||
' setting specific triggers
|
||||
if selectedSetting.settingName = "global.rememberme"
|
||||
unset_setting("active_user")
|
||||
end if
|
||||
else
|
||||
' regular user setting
|
||||
' save to user specific registry block
|
||||
set_user_setting(selectedSetting.settingName, "false")
|
||||
end if
|
||||
end if
|
||||
end sub
|
||||
|
||||
|
|
|
@ -7,32 +7,35 @@
|
|||
<LabelList
|
||||
translation="[120,250]"
|
||||
id="settingsMenu"
|
||||
itemSize="[440,48]"
|
||||
itemSize="[510,54]"
|
||||
vertFocusAnimationStyle="floatingFocus"
|
||||
focusBitmapBlendColor="#006fab"
|
||||
focusedColor="#ffffff"
|
||||
itemSpacing="[0,5]" />
|
||||
itemSpacing="[0,9]"
|
||||
textVertAlign="center" />
|
||||
|
||||
<Poster
|
||||
translation="[710,250]" id="testRectangle" width="880" height="700" uri="pkg:/images/white.9.png"
|
||||
translation="[710,230]" id="testRectangle" width="1210" height="830" uri="pkg:/images/white.9.png"
|
||||
blendColor="#3f3f3f" />
|
||||
|
||||
<LayoutGroup translation="[1150,275]" id="settingDetail" vertAlignment="top" horizAlignment="center" itemSpacings="[50]">
|
||||
<LayoutGroup translation="[1278,270]" id="settingDetail" vertAlignment="top" horizAlignment="center" itemSpacings="[50]">
|
||||
<Label id="settingDesc"
|
||||
width="1065"
|
||||
wrap="true"
|
||||
horizAlign="center"
|
||||
translation="[750,270]" />
|
||||
|
||||
<ScrollingLabel font="font:LargeSystemFont" id="settingTitle" maxWidth="750" />
|
||||
|
||||
<Label id="settingDesc" width="750" wrap="true" />
|
||||
|
||||
<RadioButtonList id="boolSetting" vertFocusAnimationStyle="floatingFocus">
|
||||
<ContentNode role="content">
|
||||
<ContentNode title="Disabled" />
|
||||
<ContentNode title="Enabled" />
|
||||
</ContentNode>
|
||||
</RadioButtonList>
|
||||
<RadioButtonList id="radioSetting" vertFocusAnimationStyle="floatingFocus" />
|
||||
</LayoutGroup>
|
||||
|
||||
<RadioButtonList id="radioSetting" translation="[900, 450]" inheritParentTransform="false" vertFocusAnimationStyle="floatingFocus" />
|
||||
<intkeyboard_integerKeyboard translation="[900, 520]" id="integerSetting" maxLength="3" domain="numeric" visible="false" />
|
||||
<RadioButtonList id="boolSetting" vertFocusAnimationStyle="floatingFocus" translation="[1034, 510]">
|
||||
<ContentNode role="content">
|
||||
<ContentNode title="Disabled" />
|
||||
<ContentNode title="Enabled" />
|
||||
</ContentNode>
|
||||
</RadioButtonList>
|
||||
|
||||
<intkeyboard_integerKeyboard translation="[1034, 510]" id="integerSetting" maxLength="3" domain="numeric" visible="false" />
|
||||
|
||||
</children>
|
||||
</component>
|
|
@ -23,6 +23,9 @@ sub init()
|
|||
m.top.observeField("content", "onContentChange")
|
||||
m.top.observeField("selectedSubtitle", "onSubtitleChange")
|
||||
|
||||
' Custom Caption Function
|
||||
m.top.observeField("allowCaptions", "onAllowCaptionsChange")
|
||||
|
||||
m.playbackTimer.observeField("fire", "ReportPlayback")
|
||||
m.bufferPercentage = 0 ' Track whether content is being loaded
|
||||
m.playReported = false
|
||||
|
@ -51,6 +54,51 @@ sub init()
|
|||
m.top.trickPlayBar.filledBarBlendColor = m.global.constants.colors.blue
|
||||
end sub
|
||||
|
||||
' Only setup captain items if captions are allowed
|
||||
sub onAllowCaptionsChange()
|
||||
if not m.top.allowCaptions then return
|
||||
|
||||
m.captionGroup = m.top.findNode("captionGroup")
|
||||
m.captionGroup.createchildren(9, "LayoutGroup")
|
||||
m.captionTask = createObject("roSGNode", "captionTask")
|
||||
m.captionTask.observeField("currentCaption", "updateCaption")
|
||||
m.captionTask.observeField("useThis", "checkCaptionMode")
|
||||
m.top.observeField("subtitleTrack", "loadCaption")
|
||||
m.top.observeField("globalCaptionMode", "toggleCaption")
|
||||
|
||||
if m.global.session.user.settings["playback.subs.custom"]
|
||||
m.top.suppressCaptions = true
|
||||
toggleCaption()
|
||||
else
|
||||
m.top.suppressCaptions = false
|
||||
end if
|
||||
end sub
|
||||
|
||||
' Set caption url to server subtitle track
|
||||
sub loadCaption()
|
||||
if m.top.suppressCaptions
|
||||
m.captionTask.url = m.top.subtitleTrack
|
||||
end if
|
||||
end sub
|
||||
|
||||
' Toggles visibility of custom subtitles and sets captionTask's player state
|
||||
sub toggleCaption()
|
||||
m.captionTask.playerState = m.top.state + m.top.globalCaptionMode
|
||||
if LCase(m.top.globalCaptionMode) = "on"
|
||||
m.captionTask.playerState = m.top.state + m.top.globalCaptionMode + "w"
|
||||
m.captionGroup.visible = true
|
||||
else
|
||||
m.captionGroup.visible = false
|
||||
end if
|
||||
end sub
|
||||
|
||||
' Removes old subtitle lines and adds new subtitle lines
|
||||
sub updateCaption()
|
||||
m.captionGroup.removeChildrenIndex(m.captionGroup.getChildCount(), 0)
|
||||
m.captionGroup.appendChildren(m.captionTask.currentCaption)
|
||||
end sub
|
||||
|
||||
' Event handler for when selectedSubtitle changes
|
||||
sub onSubtitleChange()
|
||||
' Save the current video position
|
||||
m.global.queueManager.callFunc("setTopStartingPoint", int(m.top.position) * 10000000&)
|
||||
|
@ -114,7 +162,11 @@ sub onVideoContentLoaded()
|
|||
m.top.transcodeParams = videoContent[0].transcodeparams
|
||||
|
||||
if m.LoadMetaDataTask.isIntro
|
||||
' Disable trackplay bar for intro videos
|
||||
m.top.enableTrickPlay = false
|
||||
else
|
||||
' Allow custom captions for non intro videos
|
||||
m.top.allowCaptions = true
|
||||
end if
|
||||
|
||||
if isValid(m.top.audioIndex)
|
||||
|
@ -132,21 +184,12 @@ sub onContentChange()
|
|||
if not isValid(m.top.content) then return
|
||||
|
||||
m.top.observeField("position", "onPositionChanged")
|
||||
|
||||
' If video content type is not episode, remove position observer
|
||||
if m.top.content.contenttype <> 4
|
||||
m.top.unobserveField("position")
|
||||
end if
|
||||
end sub
|
||||
|
||||
sub onNextEpisodeDataLoaded()
|
||||
m.checkedForNextEpisode = true
|
||||
|
||||
m.top.observeField("position", "onPositionChanged")
|
||||
|
||||
if m.getNextEpisodeTask.nextEpisodeData.Items.count() <> 2
|
||||
m.top.unobserveField("position")
|
||||
end if
|
||||
end sub
|
||||
|
||||
'
|
||||
|
@ -189,16 +232,27 @@ end sub
|
|||
|
||||
' When Video Player state changes
|
||||
sub onPositionChanged()
|
||||
if isValid(m.captionTask)
|
||||
m.captionTask.currentPos = Int(m.top.position * 1000)
|
||||
end if
|
||||
|
||||
' Check if dialog is open
|
||||
m.dialog = m.top.getScene().findNode("dialogBackground")
|
||||
if not isValid(m.dialog)
|
||||
checkTimeToDisplayNextEpisode()
|
||||
' Do not show Next Episode button for intro videos
|
||||
if not m.LoadMetaDataTask.isIntro
|
||||
checkTimeToDisplayNextEpisode()
|
||||
end if
|
||||
end if
|
||||
end sub
|
||||
|
||||
'
|
||||
' When Video Player state changes
|
||||
sub onState(msg)
|
||||
if isValid(m.captionTask)
|
||||
m.captionTask.playerState = m.top.state + m.top.globalCaptionMode
|
||||
end if
|
||||
|
||||
' When buffering, start timer to monitor buffering process
|
||||
if m.top.state = "buffering" and m.bufferCheckTimer <> invalid
|
||||
|
||||
|
@ -319,11 +373,17 @@ function onKeyEvent(key as string, press as boolean) as boolean
|
|||
if not press then return false
|
||||
|
||||
if key = "down"
|
||||
m.top.selectSubtitlePressed = true
|
||||
return true
|
||||
' Do not show subtitle selection for intro videos
|
||||
if not m.LoadMetaDataTask.isIntro
|
||||
m.top.selectSubtitlePressed = true
|
||||
return true
|
||||
end if
|
||||
else if key = "up"
|
||||
m.top.selectPlaybackInfoPressed = true
|
||||
return true
|
||||
' Do not show playback info for intro videos
|
||||
if not m.LoadMetaDataTask.isIntro
|
||||
m.top.selectPlaybackInfoPressed = true
|
||||
return true
|
||||
end if
|
||||
else if key = "OK"
|
||||
' OK will play/pause depending on current state
|
||||
' return false to allow selection during seeking
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
<field id="PlaySessionId" type="string" />
|
||||
<field id="Subtitles" type="array" />
|
||||
<field id="SelectedSubtitle" type="integer" value="-1" alwaysNotify="true" />
|
||||
<field id="captionMode" type="string" />
|
||||
<field id="container" type="string" />
|
||||
<field id="directPlaySupported" type="boolean" />
|
||||
<field id="systemOverlay" type="boolean" value="false" />
|
||||
|
@ -24,9 +23,11 @@
|
|||
<field id="mediaSourceId" type="string" />
|
||||
<field id="fullSubtitleData" type="array" />
|
||||
<field id="audioIndex" type="integer" />
|
||||
<field id="allowCaptions" type="boolean" value="false" />
|
||||
</interface>
|
||||
|
||||
<children>
|
||||
<Group id="captionGroup" translation="[960,1020]" />
|
||||
<timer id="playbackTimer" repeat="true" duration="30" />
|
||||
<timer id="bufferCheckTimer" repeat="true" />
|
||||
|
||||
|
|
|
@ -11439,5 +11439,113 @@
|
|||
<translation>Aktivieren oder Deaktivieren von Direct Play für optionale Codecs</translation>
|
||||
<extracomment>Settings Menu - Title for settings group related to codec support</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error During Playback</source>
|
||||
<translation>Fehler während der Wiedergabe</translation>
|
||||
<extracomment>Dialog title when error occurs during playback</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sign Out</source>
|
||||
<translation>Abmelden</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>There was an error retrieving the data for this item from the server.</source>
|
||||
<translation>Fehler beim Laden dieses Eintrags vom Server.</translation>
|
||||
<extracomment>Dialog detail when unable to load Content from Server</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Loading Channel Data</source>
|
||||
<translation>Lade Kanaldaten</translation>
|
||||
</message>
|
||||
<message>
|
||||
<comment>Name or Title field of media item</comment>
|
||||
<source>TITLE</source>
|
||||
<translation>Name</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error loading Channel Data</source>
|
||||
<translation>Fehler beim Laden der Kanaldaten</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>On Now</source>
|
||||
<translation>Jetzt läuft</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>An error was encountered while playing this item.</source>
|
||||
<translation>Bei der Wiedergabe dieses Eintrags ist ein Fehler aufgetreten.</translation>
|
||||
<extracomment>Dialog detail when error occurs during playback</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unable to load Channel Data from the server</source>
|
||||
<translation>Kanaldaten konnten nicht vom Server geladen werden</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete Saved</source>
|
||||
<translation>Gespeicherte löschen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<comment>Message displayed in Item Grid when no item to display. %1 is container type (e.g. Boxset, Collection, Folder, etc)</comment>
|
||||
<source>NO_ITEMS</source>
|
||||
<translation>%1 enthält keine Einträge</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save Credentials?</source>
|
||||
<translation>Anmeldedaten speichern?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Change Server</source>
|
||||
<translation>Server wechseln</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>CRITIC_RATING</source>
|
||||
<translation>Kritikerbewertung</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>IMDB_RATING</source>
|
||||
<translation>IMDb-Bewertung</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DATE_PLAYED</source>
|
||||
<translation>Abspieldatum</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DATE_ADDED</source>
|
||||
<translation>Hinzugefügt am</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error Retrieving Content</source>
|
||||
<translation>Fehler beim Empfangen des Inhalts</translation>
|
||||
<extracomment>Dialog title when unable to load Content from Server</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sign Out</source>
|
||||
<translation>Abmelden</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>On Now</source>
|
||||
<translation>Jetzt läuft</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Change Server</source>
|
||||
<translation>Server wechseln</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error Retrieving Content</source>
|
||||
<translation>Fehler beim Empfangen des Inhalts</translation>
|
||||
<extracomment>Dialog title when unable to load Content from Server</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error During Playback</source>
|
||||
<translation>Fehler während der wiedergabe</translation>
|
||||
<extracomment>Dialog title when error occurs during playback</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete Saved</source>
|
||||
<translation>Gespeicherte löschen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save Credentials?</source>
|
||||
<translation>Zugangsdaten Speichern?</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
|
|
@ -1208,5 +1208,25 @@
|
|||
<translation>Disable the HEVC codec on this device. This may improve playback for some devices (ultra).</translation>
|
||||
<extracomment>User Setting - Setting description</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Global</source>
|
||||
<translation>Global</translation>
|
||||
<extracomment>User Setting - Setting title</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Global settings that affect everyone that uses this Roku device.</source>
|
||||
<translation>Global settings that affect everyone that uses this Roku device.</translation>
|
||||
<extracomment>User Setting - Setting description</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Remember Me?</source>
|
||||
<translation>Remember Me?</translation>
|
||||
<extracomment>User Setting - Setting title</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Remember the currently logged in user and try to log them in again next time you start the Jellyfin app.</source>
|
||||
<translation>Remember the currently logged in user and try to log them in again next time you start the Jellyfin app.</translation>
|
||||
<extracomment>User Setting - Setting description</extracomment>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
File diff suppressed because it is too large
Load Diff
|
@ -26,7 +26,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Favorite</source>
|
||||
<translation>Favoris</translation>
|
||||
<translation>Favori</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Loading...</source>
|
||||
|
@ -50,7 +50,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Please sign in</source>
|
||||
<translation>Se connecter</translation>
|
||||
<translation>Connectez-vous s'il vous plaît</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search</source>
|
||||
|
@ -118,7 +118,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Enter a password</source>
|
||||
<translation>Entrer le mot de passe</translation>
|
||||
<translation>Entrez le mot de passe</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a value...</source>
|
||||
|
@ -142,7 +142,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Sort Order</source>
|
||||
<translation>Trie par ordre</translation>
|
||||
<translation>Ordre de tri</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Descending</source>
|
||||
|
@ -166,7 +166,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Director</source>
|
||||
<translation>Direction</translation>
|
||||
<translation>Réalisateur</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Video</source>
|
||||
|
@ -174,7 +174,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Audio</source>
|
||||
<translation>Musiques</translation>
|
||||
<translation>Audio</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Server</source>
|
||||
|
@ -7426,5 +7426,494 @@
|
|||
<translation>Nombre d'éléments</translation>
|
||||
<extracomment>UI -> Media Grid -> Item Count in user setting screen.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error Retrieving Content</source>
|
||||
<translation>Erreur lors de la récupération du contenu</translation>
|
||||
<extracomment>Dialog title when unable to load Content from Server</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>There was an error retrieving the data for this item from the server.</source>
|
||||
<translation>Une erreur s'est produite lors de la récupération des données de cet élément sur le serveur.</translation>
|
||||
<extracomment>Dialog detail when unable to load Content from Server</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error loading Channel Data</source>
|
||||
<translation>Erreur lors du chargement des données de la chaîne</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unable to load Channel Data from the server</source>
|
||||
<translation>Impossible de charger les données de la chaîne depuis le serveur</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Press 'OK' to Close</source>
|
||||
<translation>Appuyez sur «OK» pour fermer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Monday</source>
|
||||
<translation>Lundi</translation>
|
||||
<extracomment>Day of Week</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Starts at</source>
|
||||
<translation>Commence à</translation>
|
||||
<extracomment>(Future Tense) For defining time when a program will start today (e.g. Starts at 08:00) </extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cancel Recording</source>
|
||||
<translation>Annuler l'enregistrement</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Connecting to Server</source>
|
||||
<translation>Connexion au serveur en cours</translation>
|
||||
<extracomment>Message to display to user while client is attempting to connect to the server</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter the server name or IP address</source>
|
||||
<translation>Entrez le nom du serveur ou son adresse IP</translation>
|
||||
<extracomment>Title of KeyboardDialog when manually entering a server URL</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Pick a Jellyfin server from the local network</source>
|
||||
<translation>Sélectionnez un serveur Jellyfin disponible sur votre réseau local :</translation>
|
||||
<extracomment>Instructions on initial app launch when the user is asked to pick a server from a list</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>An error was encountered while playing this item. Server did not provide required transcoding data.</source>
|
||||
<translation>Une erreur a été rencontrée lors de la lecture de cet élément. Le serveur n'a pas communiqué les informations nécessaires au transcodage.</translation>
|
||||
<extracomment>Content of message box when trying to play an item which requires transcoding, and the server did not provide transcode url</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enable or disable Direct Play for optional codecs</source>
|
||||
<translation>Activer ou désactiver DirectPlay pour les codecs optionnels</translation>
|
||||
<extracomment>Settings Menu - Title for settings group related to codec support</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Support Direct Play of MPEG-2 content (e.g., Live TV). This will prevent transcoding of MPEG-2 content, but uses significantly more bandwidth.</source>
|
||||
<translation>Utiliser DirectPlay pour les contenus en MPEG-2 (par ex. TV en direct). Cela évitera la conversion des contenus en MPEG-2 mais utilisera beaucoup plus de bande passante.</translation>
|
||||
<extracomment>Settings Menu - Description for option</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Support Direct Play of MPEG-4 content. This may need to be disabled for playback of DIVX encoded video files.</source>
|
||||
<translation>Utiliser DirectPlay pour les contenus en MPEG-4. Désactiver ce paramètres pourrait être nécessaire pour la lecture de fichiers vidéo encodés en DivX.</translation>
|
||||
<extracomment>Settings Menu - Description for option</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>** EXPERIMENTAL** Support Direct Play of AV1 content if this Roku device supports it.</source>
|
||||
<translation>** EXPERIMENTAL** Utiliser DirectPlay pour les contenus en AV1 si cet équipement Roku le supporte.</translation>
|
||||
<extracomment>Description of a setting - should we try to direct play experimental av1 codec</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>HEVC</source>
|
||||
<translation>HEVC</translation>
|
||||
<extracomment>Name of codec used in settings menu</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>H.264</source>
|
||||
<translation>H.264</translation>
|
||||
<extracomment>Name of codec used in settings menu</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>PLAY_COUNT</source>
|
||||
<translation>Nombre de vues</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Saturday</source>
|
||||
<translation>Samedi</translation>
|
||||
<extracomment>Day of Week</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Record Series</source>
|
||||
<translation>Enregistrer la série</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>...or enter server URL manually:</source>
|
||||
<translation>Si aucun serveur n'est dans la liste ci-dessus, vous pouvez aussi saisir l'URL du serveur manuellement :</translation>
|
||||
<extracomment>Instructions on initial app launch when the user is asked to manually enter a server URL</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Disabled</source>
|
||||
<translation>Désactivé</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Close</source>
|
||||
<translation>Fermer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Channels</source>
|
||||
<translation>Chaines</translation>
|
||||
<extracomment>Menu option for showing Live TV Channel List</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>An error was encountered while playing this item.</source>
|
||||
<translation>Une erreur s'est produite lors de la lecture de cet élément.</translation>
|
||||
<extracomment>Dialog detail when error occurs during playback</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error During Playback</source>
|
||||
<translation>Erreur lors de la lecture</translation>
|
||||
<extracomment>Dialog title when error occurs during playback</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save Credentials?</source>
|
||||
<translation>Enregistrer les identifiants ?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete Saved</source>
|
||||
<translation>Suppression enregistrée</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>On Now</source>
|
||||
<translation>En ce moment</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>TV Shows</source>
|
||||
<translation>Séries TV</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Friday</source>
|
||||
<translation>Vendredi</translation>
|
||||
<extracomment>Day of Week</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cast & Crew</source>
|
||||
<translation>Distribution</translation>
|
||||
</message>
|
||||
<message>
|
||||
<comment>Title of Tab for options to filter library content</comment>
|
||||
<source>TAB_FILTER</source>
|
||||
<translation>Filtre</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>yesterday</source>
|
||||
<translation>hier</translation>
|
||||
<extracomment>Previous day</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Additional Parts</source>
|
||||
<translation>Contenu additionnel</translation>
|
||||
<extracomment>Additional parts of a video</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Movies</source>
|
||||
<translation>Films</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Ends at</source>
|
||||
<translation>Fini</translation>
|
||||
<extracomment>(Past Tense) For defining a day and time when a program ended (e.g. Ended Wednesday, 08:00) </extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>View Channel</source>
|
||||
<translation>Voir la chaîne</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Died</source>
|
||||
<translation>Décès</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>TV Guide</source>
|
||||
<translation>Guide des programmes</translation>
|
||||
<extracomment>Menu option for showing Live TV Guide / Schedule</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Movies (Grid)</source>
|
||||
<translation>Films (Grille)</translation>
|
||||
<extracomment>Movie library view option</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Codec Support</source>
|
||||
<translation>Codecs supportés</translation>
|
||||
<extracomment>Settings Menu - Title for settings group related to codec support</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>User Interface</source>
|
||||
<translation>Interface utilisateur</translation>
|
||||
<extracomment>Title for User Interface section in user setting screen.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set Favorite</source>
|
||||
<translation>Marquer comme favori</translation>
|
||||
<extracomment>Button Text - When pressed, sets item as Favorite</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Go to series</source>
|
||||
<translation>Aller à la série</translation>
|
||||
<extracomment>Continue Watching Popup Menu - Navigate to the Series Detail Page</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>CRITIC_RATING</source>
|
||||
<translation>Notation des critiques</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>OFFICIAL_RATING</source>
|
||||
<translation>Classification parentale</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Born</source>
|
||||
<translation>Date de naissance</translation>
|
||||
</message>
|
||||
<message>
|
||||
<comment>Title of Tab for options to sort library content</comment>
|
||||
<source>TAB_SORT</source>
|
||||
<translation>Trier</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Movies (Presentation)</source>
|
||||
<translation>Films (Présentation)</translation>
|
||||
<extracomment>Movie library view option</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Started at</source>
|
||||
<translation>A commencé à</translation>
|
||||
<extracomment>(Past Tense) For defining time when a program started today (e.g. Started at 08:00) </extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Started</source>
|
||||
<translation>A commencé</translation>
|
||||
<extracomment>(Past Tense) For defining a day and time when a program started (e.g. Started Wednesday, 08:00) </extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Repeat</source>
|
||||
<translation>Rediffusion</translation>
|
||||
<extracomment>If TV Shows has previously been broadcasted</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cancel Series Recording</source>
|
||||
<translation>Annuler l'enregistrement de la série</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Media Grid</source>
|
||||
<translation>Grille de médias</translation>
|
||||
<extracomment>UI -> Media Grid section in user setting screen.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set Watched</source>
|
||||
<translation>Marquer comme vu</translation>
|
||||
<extracomment>Button Text - When pressed, marks item as Warched</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Special Features</source>
|
||||
<translation type="unfinished">Caractéristiques spécifiques</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sunday</source>
|
||||
<translation>Dimanche</translation>
|
||||
<extracomment>Day of Week</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Tuesday</source>
|
||||
<translation>Mardi</translation>
|
||||
<extracomment>Day of Week</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Wednesday</source>
|
||||
<translation>Mercredi</translation>
|
||||
<extracomment>Day of Week</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Thursday</source>
|
||||
<translation>Jeudi</translation>
|
||||
<extracomment>Day of Week</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Starts</source>
|
||||
<translation>Commence</translation>
|
||||
<extracomment>(Future Tense) For defining a day and time when a program will start (e.g. Starts Wednesday, 08:00) </extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Record</source>
|
||||
<translation>Enregistrer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Not found</source>
|
||||
<translation>Introuvable</translation>
|
||||
<extracomment>Title of message box when the requested content is not found on the server</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>The requested content does not exist on the server</source>
|
||||
<translation>Le contenu demandé n'existe pas sur le serveur</translation>
|
||||
<extracomment>Content of message box when the requested content is not found on the server</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error Getting Playback Information</source>
|
||||
<translation>Erreur lors de la récupération des informations de lecture</translation>
|
||||
<extracomment>Dialog Title: Received error from server when trying to get information about the selected item for playback</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Go to season</source>
|
||||
<translation>Aller à la saison</translation>
|
||||
<extracomment>Continue Watching Popup Menu - Navigate to the Season Page</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search now</source>
|
||||
<translation>Chercher</translation>
|
||||
<extracomment>Help text in search Box</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Studios</source>
|
||||
<translation>Studios</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>MPEG-2</source>
|
||||
<translation>MPEG-2</translation>
|
||||
<extracomment>Name of codec used in settings menu</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>MPEG-4</source>
|
||||
<translation>MPEG-4</translation>
|
||||
<extracomment>Name of codec used in settings menu</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>AV1</source>
|
||||
<translation>AV1</translation>
|
||||
<extracomment>Name of a setting - should we try to direct play experimental av1 codec</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Networks</source>
|
||||
<translation>Réseaux</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Version</source>
|
||||
<translation>Version</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use voice remote to search</source>
|
||||
<translation>Utilisez la télécommande vocale pour chercher</translation>
|
||||
<extracomment>Help text in search voice text box</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Loading Channel Data</source>
|
||||
<translation>Chargement des données de la chaîne</translation>
|
||||
</message>
|
||||
<message>
|
||||
<comment>Name or Title field of media item</comment>
|
||||
<source>TITLE</source>
|
||||
<translation>Titre</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>IMDB_RATING</source>
|
||||
<translation>Notation IMDb</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DATE_ADDED</source>
|
||||
<translation>Date d'ajout</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DATE_PLAYED</source>
|
||||
<translation>Date de lecture</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>RUNTIME</source>
|
||||
<translation>Durée</translation>
|
||||
</message>
|
||||
<message>
|
||||
<comment>Title of Tab for switching "views" when looking at a library</comment>
|
||||
<source>TAB_VIEW</source>
|
||||
<translation>Vue</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>More Like This</source>
|
||||
<translation>Contenu similaire</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>today</source>
|
||||
<translation>aujourd'hui</translation>
|
||||
<extracomment>Current day</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Ended at</source>
|
||||
<translation>A fini à</translation>
|
||||
<extracomment>(Past Tense) For defining time when a program will ended (e.g. Ended at 08:00) </extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Live</source>
|
||||
<translation>En direct</translation>
|
||||
<extracomment>If TV Show is being broadcast live (not pre-recorded)</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>RELEASE_DATE</source>
|
||||
<translation>Date de sortie</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unknown</source>
|
||||
<translation>Inconnu</translation>
|
||||
<extracomment>Title for a cast member for which we have no information for</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Playback</source>
|
||||
<translation>Lecture</translation>
|
||||
<extracomment>Title for Playback section in user setting screen.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enabled</source>
|
||||
<translation>Activé</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Age</source>
|
||||
<translation>Age</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>tomorrow</source>
|
||||
<translation>demain</translation>
|
||||
<extracomment>Next day</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<comment>Message displayed in Item Grid when no item to display. %1 is container type (e.g. Boxset, Collection, Folder, etc)</comment>
|
||||
<source>NO_ITEMS</source>
|
||||
<translation type="unfinished">Ce(tte) %1 ne contient pas d'éléments</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Item Count</source>
|
||||
<translation>Nombre d'éléments</translation>
|
||||
<extracomment>UI -> Media Grid -> Item Count in user setting screen.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Go to episode</source>
|
||||
<translation>Aller à l'épisode</translation>
|
||||
<extracomment>Continue Watching Popup Menu - Navigate to the Episode Detail Page</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Shows</source>
|
||||
<translation>Séries</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Quick Connect</source>
|
||||
<translation>Connexion Rapide</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show item count in the library and index of selected item.</source>
|
||||
<translation>Afficher le nombre d'éléments dans la librairie et l'index de l'élément sélectionné.</translation>
|
||||
<extracomment>Description for option in Setting Screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>(Dialog will close automatically)</source>
|
||||
<translation>(Cette fenêtre se fermera automatiquement)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Media Grid options.</source>
|
||||
<translation>Options de la grille Média</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>You can search for Titles, People, Live TV Channels and more</source>
|
||||
<translation>Vous pouvez rechercher des titres, personnes, chaînes TV et plus</translation>
|
||||
<extracomment>Help text in search results</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>%1 of %2</source>
|
||||
<translation>%1 sur %2</translation>
|
||||
<extracomment>Item position and count. %1 = current item. %2 = total number of items</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>There was an error authenticating via Quick Connect.</source>
|
||||
<translation>Une erreur s'est produite lors de la Connexion Rapide.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Here is your Quick Connect code:</source>
|
||||
<translation>Voici votre code de Connexion Rapide :</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Special Features</source>
|
||||
<translation>Fonctionnalités spéciales</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
|
|
@ -11268,5 +11268,18 @@
|
|||
<source>Direct playing</source>
|
||||
<translation>Közvetlen lejátszás</translation>
|
||||
</message>
|
||||
<message>
|
||||
<comment>Name or Title field of media item</comment>
|
||||
<source>TITLE</source>
|
||||
<translation>Név</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete Saved</source>
|
||||
<translation>Törlés mentve</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save Credentials?</source>
|
||||
<translation>Menti a bejelentkezési adatokat?</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
|
|
@ -2198,5 +2198,66 @@
|
|||
<source>Sign Out</source>
|
||||
<translation>Scollegamento</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error During Playback</source>
|
||||
<translation>Errore durante la riproduzione</translation>
|
||||
<extracomment>Dialog title when error occurs during playback</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>IMDB_RATING</source>
|
||||
<translation>Valutazione di IMDb</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>An error was encountered while playing this item.</source>
|
||||
<translation>È stato riscontrato un errore durante la riproduzione.</translation>
|
||||
<extracomment>Dialog detail when error occurs during playback</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<comment>Message displayed in Item Grid when no item to display. %1 is container type (e.g. Boxset, Collection, Folder, etc)</comment>
|
||||
<source>NO_ITEMS</source>
|
||||
<translation>Non ci sono elementi da visualizzare</translation>
|
||||
</message>
|
||||
<message>
|
||||
<comment>Name or Title field of media item</comment>
|
||||
<source>TITLE</source>
|
||||
<translation>Nome</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>There was an error retrieving the data for this item from the server.</source>
|
||||
<translation>C'è stato un errore nel recupero dei dati per questo elemento dal server.</translation>
|
||||
<extracomment>Dialog detail when unable to load Content from Server</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Loading Channel Data</source>
|
||||
<translation>Caricamento dati del canale</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error loading Channel Data</source>
|
||||
<translation>Errore nel caricamento dei dati del canale</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>CRITIC_RATING</source>
|
||||
<translation>Valutazione della critica</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DATE_ADDED</source>
|
||||
<translation>Data di aggiunta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DATE_PLAYED</source>
|
||||
<translation>Visto il</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save Credentials?</source>
|
||||
<translation>Salvare le credenziali?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Change Server</source>
|
||||
<translation>Cambia Server</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unable to load Channel Data from the server</source>
|
||||
<translation>Impossibile recuperare i dati del canale dal server</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
|
349
package-lock.json
generated
349
package-lock.json
generated
|
@ -12,7 +12,7 @@
|
|||
"dependencies": {
|
||||
"@rokucommunity/bslib": "0.1.1",
|
||||
"bgv": "npm:button-group-vert@1.0.2",
|
||||
"brighterscript-formatter": "1.6.32",
|
||||
"brighterscript-formatter": "1.6.33",
|
||||
"intKeyboard": "npm:integer-keyboard@1.0.12",
|
||||
"log": "npm:roku-log@0.11.1",
|
||||
"promises": "npm:@rokucommunity/promises@0.1.0",
|
||||
|
@ -21,18 +21,114 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@rokucommunity/bslint": "0.8.10",
|
||||
"brighterscript": "0.65.5",
|
||||
"brighterscript": "0.65.7",
|
||||
"jshint": "2.13.6",
|
||||
"markdownlint-cli2": "0.9.2",
|
||||
"rimraf": "5.0.1",
|
||||
"markdownlint-cli2": "0.10.0",
|
||||
"rimraf": "5.0.5",
|
||||
"roku-deploy": "3.10.3",
|
||||
"roku-log-bsc-plugin": "0.8.1",
|
||||
"rooibos-roku": "5.7.0",
|
||||
"ropm": "0.10.16",
|
||||
"ropm": "0.10.17",
|
||||
"spellchecker-cli": "6.1.1",
|
||||
"undent": "0.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/cliui": {
|
||||
"version": "8.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
||||
"integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"string-width": "^5.1.2",
|
||||
"string-width-cjs": "npm:string-width@^4.2.0",
|
||||
"strip-ansi": "^7.0.1",
|
||||
"strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
|
||||
"wrap-ansi": "^8.1.0",
|
||||
"wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/cliui/node_modules/ansi-regex": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
|
||||
"integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/cliui/node_modules/ansi-styles": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
|
||||
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/cliui/node_modules/emoji-regex": {
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
|
||||
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@isaacs/cliui/node_modules/string-width": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
|
||||
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"eastasianwidth": "^0.2.0",
|
||||
"emoji-regex": "^9.2.2",
|
||||
"strip-ansi": "^7.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/cliui/node_modules/strip-ansi": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
|
||||
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-regex": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
|
||||
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^6.1.0",
|
||||
"string-width": "^5.0.1",
|
||||
"strip-ansi": "^7.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
|
@ -535,9 +631,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/brighterscript": {
|
||||
"version": "0.65.5",
|
||||
"resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-0.65.5.tgz",
|
||||
"integrity": "sha512-xDkWIZhjTLhp6dVZ6lX7zWRyNvjdiAwZncJRnErSbqRhteNJFL7ic2UDJew9zCOYTQDrG7B85lpPpXc/1JlV+Q==",
|
||||
"version": "0.65.7",
|
||||
"resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-0.65.7.tgz",
|
||||
"integrity": "sha512-cmV0JzlYuKIKkMsbHR2FyaD2YugHeHESdMmUOtK61EsEUS895Y6yXftDVnFUwij7beLiZR6s1oRpMfiS7MJ40g==",
|
||||
"dependencies": {
|
||||
"@rokucommunity/bslib": "^0.1.1",
|
||||
"@xml-tools/parser": "^1.0.7",
|
||||
|
@ -577,11 +673,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/brighterscript-formatter": {
|
||||
"version": "1.6.32",
|
||||
"resolved": "https://registry.npmjs.org/brighterscript-formatter/-/brighterscript-formatter-1.6.32.tgz",
|
||||
"integrity": "sha512-7rbNmSsj2v8iv+iSWXczSg4hC7L1zxMEwo+jZcDaMDPu0TBt4zmmCpaT0WvvvYcE8fD9I1tJ4dlTaj61QnH0QQ==",
|
||||
"version": "1.6.33",
|
||||
"resolved": "https://registry.npmjs.org/brighterscript-formatter/-/brighterscript-formatter-1.6.33.tgz",
|
||||
"integrity": "sha512-XmirSAOBBHsprJvLOuh8nzXNiPQJXQa2NJ581OZdQrofFdBNPGH+yFhV6XXUZ+pA6fVLSxMxXA0toF83jtKjrA==",
|
||||
"dependencies": {
|
||||
"brighterscript": "^0.65.5",
|
||||
"brighterscript": "^0.65.7",
|
||||
"glob-all": "^3.3.0",
|
||||
"jsonc-parser": "^3.0.0",
|
||||
"source-map": "^0.7.3",
|
||||
|
@ -592,16 +688,6 @@
|
|||
"bsfmt": "dist/cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/brighterscript-formatter/node_modules/cliui": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
|
||||
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^6.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/brighterscript-formatter/node_modules/glob-all": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/glob-all/-/glob-all-3.3.1.tgz",
|
||||
|
@ -614,6 +700,21 @@
|
|||
"glob-all": "bin/glob-all"
|
||||
}
|
||||
},
|
||||
"node_modules/brighterscript-formatter/node_modules/glob-all/node_modules/cliui": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
|
||||
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^6.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/brighterscript-formatter/node_modules/glob-all/node_modules/y18n": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
|
||||
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
|
||||
},
|
||||
"node_modules/brighterscript-formatter/node_modules/glob-all/node_modules/yargs": {
|
||||
"version": "15.4.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
|
||||
|
@ -635,6 +736,18 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/brighterscript-formatter/node_modules/glob-all/node_modules/yargs-parser": {
|
||||
"version": "18.1.3",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
||||
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
||||
"dependencies": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/brighterscript-formatter/node_modules/jsonc-parser": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
|
||||
|
@ -653,23 +766,6 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/brighterscript-formatter/node_modules/y18n": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
|
||||
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
|
||||
},
|
||||
"node_modules/brighterscript-formatter/node_modules/yargs-parser": {
|
||||
"version": "18.1.3",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
||||
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
||||
"dependencies": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/brighterscript/node_modules/fs-extra": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
|
||||
|
@ -1266,6 +1362,12 @@
|
|||
"domelementtype": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/eastasianwidth": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
|
||||
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/ecc-jsbn": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
|
||||
|
@ -1992,12 +2094,12 @@
|
|||
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
|
||||
},
|
||||
"node_modules/jackspeak": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.1.0.tgz",
|
||||
"integrity": "sha512-DiEwVPqsieUzZBNxQ2cxznmFzfg/AMgJUjYw5xl6rSmCxAQXECcbSdwcLM6Ds6T09+SBfSNCGPhYUoQ96P4h7A==",
|
||||
"version": "2.3.5",
|
||||
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.5.tgz",
|
||||
"integrity": "sha512-Ratx+B8WeXLAtRJn26hrhY8S1+Jz6pxPMrkrdkgb/NstTNiqMhX0/oFVu5wX+g5n6JlEu2LPsDJmY8nRP4+alw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cliui": "^7.0.4"
|
||||
"@isaacs/cliui": "^8.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
|
@ -2318,9 +2420,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/markdownlint": {
|
||||
"version": "0.30.0",
|
||||
"resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.30.0.tgz",
|
||||
"integrity": "sha512-nInuFvI/rEzanAOArW5490Ez4EYpB5ODqVM0mcDYCPx9DKJWCQqCgejjiCvbSeE7sjbDscVtZmwr665qpF5xGA==",
|
||||
"version": "0.31.1",
|
||||
"resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.31.1.tgz",
|
||||
"integrity": "sha512-CKMR2hgcIBrYlIUccDCOvi966PZ0kJExDrUi1R+oF9PvqQmCrTqjOsgIvf2403OmJ+CWomuzDoylr6KbuMyvHA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"markdown-it": "13.0.1",
|
||||
|
@ -2331,17 +2433,17 @@
|
|||
}
|
||||
},
|
||||
"node_modules/markdownlint-cli2": {
|
||||
"version": "0.9.2",
|
||||
"resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.9.2.tgz",
|
||||
"integrity": "sha512-ndijEHIOikcs29W8068exHXlfkFviGFT/mPhREia7zSfQzHvTDkL2s+tWizvELjLHiKRO4KGTkkJyR3oeR8A5g==",
|
||||
"version": "0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.10.0.tgz",
|
||||
"integrity": "sha512-kVxjPyKFC+eW7iqcxiNI50RDzwugpXkEX5eQlDso/0IUs9M73jXYguLFHDzgi5KatcxU/57Fu8KoGtkFft9lfA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"globby": "13.2.2",
|
||||
"markdownlint": "0.30.0",
|
||||
"markdownlint": "0.31.1",
|
||||
"markdownlint-cli2-formatter-default": "0.0.4",
|
||||
"micromatch": "4.0.5",
|
||||
"strip-json-comments": "5.0.1",
|
||||
"yaml": "2.3.1"
|
||||
"yaml": "2.3.2"
|
||||
},
|
||||
"bin": {
|
||||
"markdownlint-cli2": "markdownlint-cli2.js",
|
||||
|
@ -3484,13 +3586,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/path-scurry": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.7.0.tgz",
|
||||
"integrity": "sha512-UkZUeDjczjYRE495+9thsgcVgsaCPkaw80slmfVFgllxY+IO8ubTsOpFVjDPROBqJdHfVPUFRHPBV/WciOVfWg==",
|
||||
"version": "1.10.1",
|
||||
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz",
|
||||
"integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lru-cache": "^9.0.0",
|
||||
"minipass": "^5.0.0"
|
||||
"lru-cache": "^9.1.1 || ^10.0.0",
|
||||
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
|
@ -4227,15 +4329,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/rimraf": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.1.tgz",
|
||||
"integrity": "sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg==",
|
||||
"version": "5.0.5",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz",
|
||||
"integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"glob": "^10.2.5"
|
||||
"glob": "^10.3.7"
|
||||
},
|
||||
"bin": {
|
||||
"rimraf": "dist/cjs/src/bin.js"
|
||||
"rimraf": "dist/esm/bin.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
|
@ -4254,19 +4356,19 @@
|
|||
}
|
||||
},
|
||||
"node_modules/rimraf/node_modules/glob": {
|
||||
"version": "10.2.5",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-10.2.5.tgz",
|
||||
"integrity": "sha512-Gj+dFYPZ5hc5dazjXzB0iHg2jKWJZYMjITXYPBRQ/xc2Buw7H0BINknRTwURJ6IC6MEFpYbLvtgVb3qD+DwyuA==",
|
||||
"version": "10.3.10",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz",
|
||||
"integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"foreground-child": "^3.1.0",
|
||||
"jackspeak": "^2.0.3",
|
||||
"minimatch": "^9.0.0",
|
||||
"minipass": "^5.0.0 || ^6.0.2",
|
||||
"path-scurry": "^1.7.0"
|
||||
"jackspeak": "^2.3.5",
|
||||
"minimatch": "^9.0.1",
|
||||
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
|
||||
"path-scurry": "^1.10.1"
|
||||
},
|
||||
"bin": {
|
||||
"glob": "dist/cjs/src/bin.js"
|
||||
"glob": "dist/esm/bin.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
|
@ -4276,9 +4378,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/rimraf/node_modules/minimatch": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz",
|
||||
"integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==",
|
||||
"version": "9.0.3",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
|
||||
"integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
|
@ -4432,14 +4534,14 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/ropm": {
|
||||
"version": "0.10.16",
|
||||
"resolved": "https://registry.npmjs.org/ropm/-/ropm-0.10.16.tgz",
|
||||
"integrity": "sha512-YZ49ie+dSRkyOz7RbXpku+neujhk6WfrFKUpda844W2kB0Xk/p4XtwirIdorVNtefBqEeQMXswwrVaWLNaL+vQ==",
|
||||
"version": "0.10.17",
|
||||
"resolved": "https://registry.npmjs.org/ropm/-/ropm-0.10.17.tgz",
|
||||
"integrity": "sha512-JFq/PAzrC3xVweRdTt4zAYCWWdSBzMg5MP9i302L+vi4eXLp4jDYGeYKZwSucZswWNGxVpSK3gW1paHpv7GVEw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@xml-tools/ast": "^5.0.5",
|
||||
"@xml-tools/parser": "1.0.10",
|
||||
"brighterscript": "^0.65.4",
|
||||
"brighterscript": "^0.65.5",
|
||||
"del": "6.0.0",
|
||||
"fs-extra": "9.1.0",
|
||||
"glob-all": "3.2.1",
|
||||
|
@ -4489,7 +4591,7 @@
|
|||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/fs-extra/node_modules/jsonfile": {
|
||||
"node_modules/ropm/node_modules/jsonfile": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
||||
|
@ -4501,7 +4603,7 @@
|
|||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/fs-extra/node_modules/universalify": {
|
||||
"node_modules/ropm/node_modules/universalify": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
||||
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
|
||||
|
@ -4510,45 +4612,6 @@
|
|||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/roku-deploy": {
|
||||
"version": "3.10.3",
|
||||
"resolved": "https://registry.npmjs.org/roku-deploy/-/roku-deploy-3.10.3.tgz",
|
||||
"integrity": "sha512-COJSQ638QklcM+8AN1nujFuzT04rTZLFuLSww35edm8w/y0l60oF/Iu7TQ46m75DwoGFzGFfomLEmA1ltQk9mA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"chalk": "^2.4.2",
|
||||
"dateformat": "^3.0.3",
|
||||
"dayjs": "^1.11.0",
|
||||
"fast-glob": "^3.2.12",
|
||||
"fs-extra": "^7.0.1",
|
||||
"is-glob": "^4.0.3",
|
||||
"jsonc-parser": "^2.3.0",
|
||||
"jszip": "^3.6.0",
|
||||
"micromatch": "^4.0.4",
|
||||
"moment": "^2.29.1",
|
||||
"parse-ms": "^2.1.0",
|
||||
"postman-request": "^2.88.1-postman.32",
|
||||
"temp-dir": "^2.0.0",
|
||||
"xml2js": "^0.5.0"
|
||||
},
|
||||
"bin": {
|
||||
"roku-deploy": "dist/cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/roku-deploy/node_modules/fs-extra": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
|
||||
"integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.1.2",
|
||||
"jsonfile": "^4.0.0",
|
||||
"universalify": "^0.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6 <7 || >=8"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/yargs": {
|
||||
"version": "16.2.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
|
||||
|
@ -4847,6 +4910,21 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/string-width-cjs": {
|
||||
"name": "string-width",
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/stringify-object": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz",
|
||||
|
@ -4872,6 +4950,19 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-ansi-cjs": {
|
||||
"name": "strip-ansi",
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-bom": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
|
||||
|
@ -5465,6 +5556,24 @@
|
|||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/wrap-ansi-cjs": {
|
||||
"name": "wrap-ansi",
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
|
@ -5505,9 +5614,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/yaml": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz",
|
||||
"integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==",
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.2.tgz",
|
||||
"integrity": "sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
|
|
10
package.json
10
package.json
|
@ -5,7 +5,7 @@
|
|||
"dependencies": {
|
||||
"@rokucommunity/bslib": "0.1.1",
|
||||
"bgv": "npm:button-group-vert@1.0.2",
|
||||
"brighterscript-formatter": "1.6.32",
|
||||
"brighterscript-formatter": "1.6.33",
|
||||
"intKeyboard": "npm:integer-keyboard@1.0.12",
|
||||
"log": "npm:roku-log@0.11.1",
|
||||
"promises": "npm:@rokucommunity/promises@0.1.0",
|
||||
|
@ -19,14 +19,14 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@rokucommunity/bslint": "0.8.10",
|
||||
"brighterscript": "0.65.5",
|
||||
"brighterscript": "0.65.7",
|
||||
"jshint": "2.13.6",
|
||||
"markdownlint-cli2": "0.9.2",
|
||||
"rimraf": "5.0.1",
|
||||
"markdownlint-cli2": "0.10.0",
|
||||
"rimraf": "5.0.5",
|
||||
"roku-deploy": "3.10.3",
|
||||
"roku-log-bsc-plugin": "0.8.1",
|
||||
"rooibos-roku": "5.7.0",
|
||||
"ropm": "0.10.16",
|
||||
"ropm": "0.10.17",
|
||||
"spellchecker-cli": "6.1.1",
|
||||
"undent": "0.1.0"
|
||||
},
|
||||
|
|
|
@ -1,4 +1,18 @@
|
|||
[
|
||||
{
|
||||
"title": "Global",
|
||||
"description": "Global settings that affect everyone that uses this Roku device.",
|
||||
"children": [
|
||||
{
|
||||
"title": "Remember Me?",
|
||||
"description": "Remember the currently logged in user and try to log them in again next time you start the Jellyfin app.",
|
||||
"settingName": "global.rememberme",
|
||||
"type": "bool",
|
||||
"default": "false"
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Playback",
|
||||
"description": "Settings relating to playback and supported codec and media types.",
|
||||
|
|
|
@ -63,7 +63,8 @@ sub Main (args as dynamic) as void
|
|||
end if
|
||||
|
||||
' Only show the Whats New popup the first time a user runs a new client version.
|
||||
if m.global.app.version <> get_setting("LastRunVersion")
|
||||
appLastRunVersion = get_setting("LastRunVersion")
|
||||
if m.global.app.version <> appLastRunVersion
|
||||
' Ensure the user hasn't disabled Whats New popups
|
||||
if m.global.session.user.settings["load.allowwhatsnew"] = true
|
||||
set_setting("LastRunVersion", m.global.app.version)
|
||||
|
@ -73,6 +74,34 @@ sub Main (args as dynamic) as void
|
|||
end if
|
||||
end if
|
||||
|
||||
' Registry migrations
|
||||
if isValid(appLastRunVersion) and not versionChecker(appLastRunVersion, "1.7.0")
|
||||
' last app version used less than 1.7.0
|
||||
' no longer saving raw password to registry
|
||||
' auth token and username are now stored in user settings and not global settings
|
||||
print "Running 1.7.0 registry migrations"
|
||||
' remove global settings
|
||||
unset_setting("token")
|
||||
unset_setting("username")
|
||||
unset_setting("password")
|
||||
' remove user settings
|
||||
unset_user_setting("password")
|
||||
' remove saved credentials from saved_servers
|
||||
saved = get_setting("saved_servers")
|
||||
if isValid(saved)
|
||||
savedServers = ParseJson(saved)
|
||||
if isValid(savedServers.serverList) and savedServers.serverList.Count() > 0
|
||||
newServers = { serverList: [] }
|
||||
for each item in savedServers.serverList
|
||||
item.Delete("username")
|
||||
item.Delete("password")
|
||||
newServers.serverList.Push(item)
|
||||
end for
|
||||
set_setting("saved_servers", FormatJson(newServers))
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
|
||||
' Handle input messages
|
||||
input = CreateObject("roInput")
|
||||
input.SetMessagePort(m.port)
|
||||
|
@ -198,25 +227,16 @@ sub Main (args as dynamic) as void
|
|||
|
||||
selectedItem.selectedAudioStreamIndex = audio_stream_idx
|
||||
|
||||
' If we are playing a playlist, always start at the beginning
|
||||
if m.global.queueManager.callFunc("getCount") > 1
|
||||
selectedItem.startingPoint = 0
|
||||
' Display playback options dialog
|
||||
if selectedItem.json.userdata.PlaybackPositionTicks > 0
|
||||
m.global.queueManager.callFunc("hold", selectedItem)
|
||||
playbackOptionDialog(selectedItem.json.userdata.PlaybackPositionTicks, selectedItem.json)
|
||||
else
|
||||
m.global.queueManager.callFunc("clear")
|
||||
m.global.queueManager.callFunc("push", selectedItem)
|
||||
m.global.queueManager.callFunc("playQueue")
|
||||
else
|
||||
' Display playback options dialog
|
||||
if selectedItem.json.userdata.PlaybackPositionTicks > 0
|
||||
m.global.queueManager.callFunc("hold", selectedItem)
|
||||
playbackOptionDialog(selectedItem.json.userdata.PlaybackPositionTicks, selectedItem.json)
|
||||
else
|
||||
m.global.queueManager.callFunc("clear")
|
||||
m.global.queueManager.callFunc("push", selectedItem)
|
||||
m.global.queueManager.callFunc("playQueue")
|
||||
end if
|
||||
end if
|
||||
|
||||
|
||||
else if selectedItemType = "Series"
|
||||
group = CreateSeriesDetailsGroup(selectedItem.json.id)
|
||||
else if selectedItemType = "Season"
|
||||
|
@ -521,7 +541,11 @@ sub Main (args as dynamic) as void
|
|||
group.findNode("SearchBox").findNode("search_Key").active = true
|
||||
else if button.id = "change_server"
|
||||
unset_setting("server")
|
||||
unset_setting("port")
|
||||
session.server.Delete()
|
||||
SignOut(false)
|
||||
sceneManager.callFunc("clearScenes")
|
||||
goto app_start
|
||||
else if button.id = "change_user"
|
||||
SignOut(false)
|
||||
sceneManager.callFunc("clearScenes")
|
||||
goto app_start
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
function LoginFlow(startOver = false as boolean)
|
||||
function LoginFlow()
|
||||
'Collect Jellyfin server and user information
|
||||
start_login:
|
||||
|
||||
|
@ -41,9 +41,11 @@ function LoginFlow(startOver = false as boolean)
|
|||
activeUser = get_setting("active_user")
|
||||
if activeUser = invalid
|
||||
print "No active user found in registry"
|
||||
user_select:
|
||||
SendPerformanceBeacon("AppDialogInitiate") ' Roku Performance monitoring - Dialog Starting
|
||||
publicUsers = GetPublicUsers()
|
||||
if publicUsers.count()
|
||||
numPubUsers = publicUsers.count()
|
||||
if numPubUsers > 0
|
||||
publicUsersNodes = []
|
||||
for each item in publicUsers
|
||||
user = CreateObject("roSGNode", "PublicUserData")
|
||||
|
@ -55,18 +57,57 @@ function LoginFlow(startOver = false as boolean)
|
|||
publicUsersNodes.push(user)
|
||||
end for
|
||||
userSelected = CreateUserSelectGroup(publicUsersNodes)
|
||||
|
||||
SendPerformanceBeacon("AppDialogComplete") ' Roku Performance monitoring - Dialog Closed
|
||||
if userSelected = "backPressed"
|
||||
SendPerformanceBeacon("AppDialogComplete") ' Roku Performance monitoring - Dialog Closed
|
||||
return LoginFlow(true)
|
||||
session.server.Delete()
|
||||
unset_setting("server")
|
||||
goto start_login
|
||||
else
|
||||
print "A public user was selected with username=" + userSelected
|
||||
session.user.Update("name", userSelected)
|
||||
regex = CreateObject("roRegex", "[^a-zA-Z0-9\ \-\_]", "")
|
||||
session.user.Update("friendlyName", regex.ReplaceAll(userSelected, ""))
|
||||
' save userid to session
|
||||
for each user in publicUsersNodes
|
||||
if user.name = userSelected
|
||||
session.user.Update("id", user.id)
|
||||
exit for
|
||||
end if
|
||||
end for
|
||||
' try to login with token from registry
|
||||
myToken = get_user_setting("token")
|
||||
if myToken <> invalid
|
||||
' check if token is valid
|
||||
print "Auth token found in registry for selected user"
|
||||
session.user.Update("authToken", myToken)
|
||||
print "Attempting to use API with auth token"
|
||||
currentUser = AboutMe()
|
||||
if currentUser = invalid
|
||||
print "Auth token is no longer valid - deleting token"
|
||||
unset_user_setting("token")
|
||||
unset_user_setting("username")
|
||||
else
|
||||
print "Success! Auth token is still valid"
|
||||
session.user.Login(currentUser)
|
||||
LoadUserPreferences()
|
||||
LoadUserAbilities()
|
||||
return true
|
||||
end if
|
||||
else
|
||||
print "No auth token found in registry for selected user"
|
||||
end if
|
||||
'Try to login without password. If the token is valid, we're done
|
||||
print "Attempting to login with no password"
|
||||
userData = get_token(userSelected, "")
|
||||
if isValid(userData)
|
||||
print "login success!"
|
||||
session.user.Login(userData)
|
||||
LoadUserPreferences()
|
||||
LoadUserAbilities()
|
||||
SendPerformanceBeacon("AppDialogComplete") ' Roku Performance monitoring - Dialog Closed
|
||||
return true
|
||||
else
|
||||
print "Auth failed. Password required"
|
||||
end if
|
||||
end if
|
||||
else
|
||||
|
@ -75,65 +116,52 @@ function LoginFlow(startOver = false as boolean)
|
|||
passwordEntry = CreateSigninGroup(userSelected)
|
||||
SendPerformanceBeacon("AppDialogComplete") ' Roku Performance monitoring - Dialog Closed
|
||||
if passwordEntry = "backPressed"
|
||||
m.global.sceneManager.callFunc("clearScenes")
|
||||
return LoginFlow(true)
|
||||
if numPubUsers > 0
|
||||
goto user_select
|
||||
else
|
||||
session.server.Delete()
|
||||
unset_setting("server")
|
||||
goto start_login
|
||||
end if
|
||||
end if
|
||||
else
|
||||
print "Active user found in registry"
|
||||
session.user.Update("id", activeUser)
|
||||
|
||||
myUsername = get_user_setting("username")
|
||||
myAuthToken = get_user_setting("token")
|
||||
if isValid(myAuthToken)
|
||||
if isValid(myAuthToken) and isValid(myUsername)
|
||||
print "Auth token found in registry"
|
||||
session.user.Update("authToken", myAuthToken)
|
||||
session.user.Update("name", myUsername)
|
||||
regex = CreateObject("roRegex", "[^a-zA-Z0-9\ \-\_]", "")
|
||||
session.user.Update("friendlyName", regex.ReplaceAll(myUsername, ""))
|
||||
print "Attempting to use API with auth token"
|
||||
currentUser = AboutMe()
|
||||
if currentUser = invalid
|
||||
print "Auth token is no longer valid - restart login flow"
|
||||
unset_user_setting("token")
|
||||
unset_setting("active_user")
|
||||
session.user.Logout()
|
||||
goto start_login
|
||||
print "Auth token is no longer valid"
|
||||
'Try to login without password. If the token is valid, we're done
|
||||
print "Attempting to login with no password"
|
||||
userData = get_token(userSelected, "")
|
||||
if isValid(userData)
|
||||
print "login success!"
|
||||
session.user.Login(userData)
|
||||
LoadUserPreferences()
|
||||
LoadUserAbilities()
|
||||
return true
|
||||
else
|
||||
print "Auth failed. Password required"
|
||||
print "delete token and restart login flow"
|
||||
unset_user_setting("token")
|
||||
unset_user_setting("username")
|
||||
goto start_login
|
||||
end if
|
||||
else
|
||||
print "Success! Auth token is still valid"
|
||||
session.user.Login(currentUser)
|
||||
end if
|
||||
else
|
||||
print "No auth token found in registry"
|
||||
myUsername = get_setting("username")
|
||||
myPassword = get_setting("password")
|
||||
userData = invalid
|
||||
|
||||
if isValid(myUsername) and isValid(myPassword)
|
||||
if myUsername <> ""
|
||||
print "Username and password found in registry. Attempting to login"
|
||||
userData = get_token(myUsername, myPassword)
|
||||
else
|
||||
print "Username in registry is an empty string"
|
||||
unset_setting("username")
|
||||
unset_setting("password")
|
||||
end if
|
||||
else if isValid(myUsername) and not isValid(myPassword)
|
||||
print "Username found in registry but no password"
|
||||
if myUsername <> ""
|
||||
print "Attempting to login with no password"
|
||||
userData = get_token(myUsername, "")
|
||||
else
|
||||
print "Username in registry is an empty string"
|
||||
unset_setting("username")
|
||||
end if
|
||||
|
||||
else if not isValid(myUsername) and not isValid(myPassword)
|
||||
print "Neither username nor password found in registry - restart login flow"
|
||||
unset_setting("active_user")
|
||||
session.user.Logout()
|
||||
goto start_login
|
||||
end if
|
||||
|
||||
if isValid(userData)
|
||||
print "login success!"
|
||||
session.user.Login(userData)
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
|
||||
|
@ -254,11 +282,6 @@ function CreateServerGroup()
|
|||
m.scene.dialog = dialog
|
||||
|
||||
serverUrl = standardize_jellyfin_url(screen.serverUrl)
|
||||
'If this is a different server from what we know, reset username/password setting
|
||||
if m.global.session.server.url <> serverUrl
|
||||
set_setting("username", "")
|
||||
set_setting("password", "")
|
||||
end if
|
||||
set_setting("server", serverUrl)
|
||||
|
||||
isConnected = session.server.UpdateURL(serverUrl)
|
||||
|
@ -362,25 +385,6 @@ function CreateSigninGroup(user = "")
|
|||
|
||||
group.findNode("prompt").text = tr("Sign In")
|
||||
|
||||
'Load in any saved server data and see if we can just log them in...
|
||||
server = m.global.session.server.url
|
||||
if isValid(server)
|
||||
server = LCase(server)'Saved server data is always lowercase
|
||||
end if
|
||||
saved = get_setting("saved_servers")
|
||||
if isValid(saved)
|
||||
savedServers = ParseJson(saved)
|
||||
for each item in savedServers.serverList
|
||||
if item.baseUrl = server and isValid(item.username) and isValid(item.password)
|
||||
userData = get_token(item.username, item.password)
|
||||
if isValid(userData)
|
||||
session.user.Login(userData)
|
||||
return "true"
|
||||
end if
|
||||
end if
|
||||
end for
|
||||
end if
|
||||
|
||||
config = group.findNode("configOptions")
|
||||
username_field = CreateObject("roSGNode", "ConfigData")
|
||||
username_field.label = tr("Username")
|
||||
|
@ -447,11 +451,10 @@ function CreateSigninGroup(user = "")
|
|||
activeUser = get_token(username.value, password.value)
|
||||
if isValid(activeUser)
|
||||
session.user.Login(activeUser)
|
||||
set_setting("username", username.value)
|
||||
set_setting("password", password.value)
|
||||
' save credentials
|
||||
if checkbox.checkedState[0] = true
|
||||
'Update our saved server list, so next time the user can just click and go
|
||||
UpdateSavedServerList()
|
||||
set_user_setting("token", activeUser.token)
|
||||
set_user_setting("username", username.value)
|
||||
end if
|
||||
return "true"
|
||||
end if
|
||||
|
@ -515,6 +518,7 @@ function CreateHomeGroup()
|
|||
new_options = []
|
||||
options_buttons = [
|
||||
{ "title": "Search", "id": "goto_search" },
|
||||
{ "title": "Change user", "id": "change_user" },
|
||||
{ "title": "Change server", "id": "change_server" },
|
||||
{ "title": "Sign out", "id": "sign_out" }
|
||||
]
|
||||
|
@ -862,34 +866,6 @@ function CreatePersonView(personData as object) as dynamic
|
|||
return person
|
||||
end function
|
||||
|
||||
sub UpdateSavedServerList()
|
||||
server = m.global.session.server.url
|
||||
username = get_setting("username")
|
||||
password = get_setting("password")
|
||||
|
||||
if server = invalid or username = invalid or password = invalid
|
||||
return
|
||||
end if
|
||||
|
||||
server = LCase(server)'Saved server data is always lowercase
|
||||
|
||||
saved = get_setting("saved_servers")
|
||||
if isValid(saved)
|
||||
savedServers = ParseJson(saved)
|
||||
if isValid(savedServers.serverList) and savedServers.serverList.Count() > 0
|
||||
newServers = { serverList: [] }
|
||||
for each item in savedServers.serverList
|
||||
if item.baseUrl = server
|
||||
item.username = username
|
||||
item.password = password
|
||||
end if
|
||||
newServers.serverList.Push(item)
|
||||
end for
|
||||
set_setting("saved_servers", FormatJson(newServers))
|
||||
end if
|
||||
end if
|
||||
end sub
|
||||
|
||||
'Opens dialog asking user if they want to resume video or start playback over only on the home screen
|
||||
sub playbackOptionDialog(time as longinteger, meta as object)
|
||||
|
||||
|
|
|
@ -203,12 +203,16 @@ function authRequest(request as object) as object
|
|||
|
||||
if m.global.session.user.id <> invalid
|
||||
auth = auth + ", UserId=" + QUOTE + m.global.session.user.id + QUOTE
|
||||
auth = auth + ", DeviceId=" + QUOTE + m.global.device.id + QUOTE
|
||||
if m.global.session.user.authToken <> invalid
|
||||
auth = auth + ", Token=" + QUOTE + m.global.session.user.authToken + QUOTE
|
||||
end if
|
||||
end if
|
||||
|
||||
if m.global.session.user <> invalid and m.global.session.user.friendlyName <> invalid
|
||||
auth = auth + ", DeviceId=" + QUOTE + m.global.device.id + m.global.session.user.friendlyName + QUOTE
|
||||
else
|
||||
auth = auth + ", DeviceId=" + QUOTE + m.global.device.uuid + QUOTE
|
||||
auth = auth + ", DeviceId=" + QUOTE + m.global.device.id + QUOTE
|
||||
end if
|
||||
|
||||
if m.global.session.user.authToken <> invalid
|
||||
auth = auth + ", Token=" + QUOTE + m.global.session.user.authToken + QUOTE
|
||||
end if
|
||||
|
||||
request.AddHeader("Authorization", auth)
|
||||
|
|
|
@ -32,28 +32,9 @@ function AboutMe(id = "" as string)
|
|||
end function
|
||||
|
||||
sub SignOut(deleteSavedEntry = true as boolean)
|
||||
if m.global.session.user.id <> invalid
|
||||
if m.global.session.user.id <> invalid and deleteSavedEntry = true
|
||||
unset_user_setting("token")
|
||||
unset_setting("username")
|
||||
unset_setting("password")
|
||||
if deleteSavedEntry = true
|
||||
'Also delete any credentials in the "saved servers" list
|
||||
saved = get_setting("saved_servers")
|
||||
server = m.global.session.server.url
|
||||
if server <> invalid
|
||||
server = LCase(server)
|
||||
savedServers = ParseJson(saved)
|
||||
newServers = { serverList: [] }
|
||||
for each item in savedServers.serverList
|
||||
if item.baseUrl = server
|
||||
item.username = ""
|
||||
item.password = ""
|
||||
end if
|
||||
newServers.serverList.Push(item)
|
||||
end for
|
||||
set_setting("saved_servers", FormatJson(newServers))
|
||||
end if
|
||||
end if
|
||||
unset_user_setting("username")
|
||||
end if
|
||||
unset_setting("active_user")
|
||||
session.user.Logout()
|
||||
|
|
|
@ -13,7 +13,7 @@ function getDeviceCapabilities() as object
|
|||
"Photo"
|
||||
],
|
||||
"SupportedCommands": [],
|
||||
"SupportsPersistentIdentifier": false,
|
||||
"SupportsPersistentIdentifier": true,
|
||||
"SupportsMediaControl": false,
|
||||
"SupportsContentUploading": false,
|
||||
"SupportsSync": false,
|
||||
|
|
|
@ -137,6 +137,10 @@ namespace session
|
|||
tmpSession.AddReplace("user", userData.json.User)
|
||||
tmpSession.user.AddReplace("authToken", userData.json.AccessToken)
|
||||
end if
|
||||
' remove special characters from name
|
||||
regex = CreateObject("roRegex", "[^a-zA-Z0-9\ \-\_]", "")
|
||||
friendlyName = regex.ReplaceAll(tmpSession.user.name, "")
|
||||
tmpSession.user.AddReplace("friendlyName", friendlyName)
|
||||
|
||||
tmpSession.user.AddReplace("settings", oldUserSettings)
|
||||
' update global user session
|
||||
|
@ -154,9 +158,11 @@ namespace session
|
|||
print "m.global.session.user.Policy = ", m.global.session.user.Policy
|
||||
print "m.global.session.user.settings = ", m.global.session.user.settings
|
||||
end if
|
||||
' ensure registry is updated
|
||||
set_user_setting("username", tmpSession.user.name)
|
||||
set_user_setting("token", tmpSession.user.authToken)
|
||||
|
||||
if m.global.session.user.settings["global.rememberme"]
|
||||
set_user_setting("token", tmpSession.user.authToken)
|
||||
set_user_setting("username", tmpSession.user.name)
|
||||
end if
|
||||
end sub
|
||||
|
||||
' Empty the global user session array and reload defaults
|
||||
|
@ -234,6 +240,20 @@ namespace session
|
|||
end for
|
||||
end if
|
||||
end for
|
||||
|
||||
' load globals
|
||||
session.user.settings.LoadGlobals()
|
||||
end sub
|
||||
|
||||
' Grab global vars from registry and overwrite defaults
|
||||
sub LoadGlobals()
|
||||
' search main registry block for all keys that start with "global."
|
||||
jfRegistry = RegistryReadAll("Jellyfin")
|
||||
for each item in jfRegistry
|
||||
if Left(item, 7) = "global."
|
||||
session.user.settings.Save(item, get_setting(item))
|
||||
end if
|
||||
end for
|
||||
end sub
|
||||
|
||||
' Saves the user setting to the global session.
|
||||
|
|
Loading…
Reference in New Issue
Block a user