Merge branch 'unstable' into hevc-directplay-profile-version-override
This commit is contained in:
commit
58e91aeb76
20
.github/workflows/auto-close-stale-pr.yml
vendored
Normal file
20
.github/workflows/auto-close-stale-pr.yml
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
name: "Close stale Pull Requests"
|
||||
on:
|
||||
schedule:
|
||||
- cron: "30 1 * * *"
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@3de2653986ebd134983c79fe2be5d45cc3d9f4e1 # tag=v6
|
||||
with:
|
||||
days-before-issue-stale: -1
|
||||
days-before-issue-close: -1
|
||||
stale-pr-message: "This pull request has been inactive for 21 days and will be automatically closed in 7 days if there is no further activity."
|
||||
close-pr-message: "This pull request has been closed because it has been inactive for 28 days. You may submit a new pull request if desired."
|
||||
days-before-pr-stale: 21
|
||||
days-before-pr-close: 7
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
|
@ -8,8 +8,8 @@ jobs:
|
|||
run:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3
|
||||
- uses: actions/setup-node@2fddd8803e2f5c9604345a0b591c3020ee971a93 # tag=v3
|
||||
with:
|
||||
node-version: "14.12.0"
|
||||
- run: npm ci
|
||||
|
|
|
@ -19,6 +19,13 @@ Open up the new folder:
|
|||
cd jellyfin-roku
|
||||
```
|
||||
|
||||
Install Dependencies:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Method 1: Visual Studio Code
|
||||
We recommend using Visual Studio Code when working on this project. The [BrightScript Language extension](https://marketplace.visualstudio.com/items?itemName=RokuCommunity.brightscript) provides a rich debugging experience, including in-editor syntax checking, debugging/breakpoint support, variable inspection at runtime, auto-formatting, an integrated remote control mode, and [much more](https://rokucommunity.github.io/vscode-brightscript-language/features.html).
|
||||
|
|
|
@ -25,7 +25,17 @@ sub init()
|
|||
|
||||
m.itemGrid.observeField("itemFocused", "onItemFocused")
|
||||
m.itemGrid.observeField("itemSelected", "onItemSelected")
|
||||
m.itemGrid.observeField("AlphaSelected", "onItemAlphaSelected")
|
||||
m.itemGrid.observeField("alphaSelected", "onItemalphaSelected")
|
||||
|
||||
'Voice filter setup
|
||||
m.voiceBox = m.top.findNode("voiceBox")
|
||||
m.voiceBox.voiceEnabled = true
|
||||
m.voiceBox.active = true
|
||||
m.voiceBox.observeField("text", "onvoiceFilter")
|
||||
'set voice help text
|
||||
m.voiceBox.hintText = tr("Use voice remote to search")
|
||||
|
||||
'backdrop
|
||||
m.newBackdrop.observeField("loadStatus", "newBGLoaded")
|
||||
|
||||
'Background Image Queued for loading
|
||||
|
@ -45,19 +55,35 @@ sub init()
|
|||
|
||||
m.spinner = m.top.findNode("spinner")
|
||||
m.spinner.visible = true
|
||||
|
||||
m.Alpha = m.top.findNode("AlphaMenu")
|
||||
m.AlphaSelected = m.top.findNode("AlphaSelected")
|
||||
|
||||
'Get reset folder setting
|
||||
m.resetGrid = get_user_setting("itemgrid.reset") = "true"
|
||||
|
||||
'Check if device has voice remote
|
||||
devinfo = CreateObject("roDeviceInfo")
|
||||
m.deviFeature = devinfo.HasFeature("voice_remote")
|
||||
m.micButton = m.top.findNode("micButton")
|
||||
m.micButtonText = m.top.findNode("micButtonText")
|
||||
'Hide voice search if device does not have voice remote
|
||||
if m.deviFeature = false
|
||||
m.micButton.visible = false
|
||||
m.micButtonText.visible = false
|
||||
end if
|
||||
end sub
|
||||
|
||||
'
|
||||
'Load initial set of Data
|
||||
sub loadInitialItems()
|
||||
m.loadItemsTask.control = "stop"
|
||||
m.spinner.visible = true
|
||||
|
||||
if m.top.parentItem.json.Type = "CollectionFolder" 'or m.top.parentItem.json.Type = "Folder"
|
||||
m.top.HomeLibraryItem = m.top.parentItem.Id
|
||||
end if
|
||||
|
||||
if m.top.parentItem.backdropUrl <> invalid
|
||||
SetBackground(m.top.parentItem.backdropUrl)
|
||||
end if
|
||||
|
@ -66,6 +92,14 @@ sub loadInitialItems()
|
|||
if m.top.parentItem.collectionType = "livetv"
|
||||
' Translate between app and server nomenclature
|
||||
viewSetting = get_user_setting("display.livetv.landing")
|
||||
'Move mic to be visiable on TV Guide screen
|
||||
if m.deviFeature = true
|
||||
m.micButton.translation = "[1540, 92]"
|
||||
m.micButtonText.visible = true
|
||||
m.micButtonText.translation = "[1600,130]"
|
||||
m.micButtonText.font.size = 22
|
||||
m.micButtonText.text = tr("Search")
|
||||
end if
|
||||
if viewSetting = "guide"
|
||||
m.view = "tvGuide"
|
||||
else
|
||||
|
@ -112,24 +146,31 @@ sub loadInitialItems()
|
|||
end if
|
||||
updateTitle()
|
||||
|
||||
m.loadItemsTask.nameStartsWith = m.top.AlphaSelected
|
||||
m.loadItemsTask.nameStartsWith = m.top.alphaSelected
|
||||
m.loadItemsTask.searchTerm = m.voiceBox.text
|
||||
m.emptyText.visible = false
|
||||
m.loadItemsTask.sortField = m.sortField
|
||||
m.loadItemsTask.sortAscending = m.sortAscending
|
||||
m.loadItemsTask.filter = m.filter
|
||||
m.loadItemsTask.startIndex = 0
|
||||
|
||||
' Load Item Types
|
||||
if m.top.parentItem.collectionType = "movies"
|
||||
if getCollectionType() = "movies"
|
||||
m.loadItemsTask.itemType = "Movie"
|
||||
m.loadItemsTask.itemId = m.top.parentItem.Id
|
||||
else if m.top.parentItem.collectionType = "tvshows"
|
||||
else if getCollectionType() = "tvshows"
|
||||
m.loadItemsTask.itemType = "Series"
|
||||
m.loadItemsTask.itemId = m.top.parentItem.Id
|
||||
else if m.top.parentItem.collectionType = "music"
|
||||
else if getCollectionType() = "music"
|
||||
' Default Settings
|
||||
m.loadItemsTask.recursive = false
|
||||
m.itemGrid.itemSize = "[290, 290]"
|
||||
m.itemGrid.itemSpacing = "[ 0, 20]"
|
||||
|
||||
if m.voiceBox.text <> ""
|
||||
m.loadItemsTask.recursive = true
|
||||
else
|
||||
m.loadItemsTask.recursive = false
|
||||
m.itemGrid.itemSize = "[290, 290]"
|
||||
end if
|
||||
|
||||
m.loadItemsTask.itemType = "MusicArtist,MusicAlbum"
|
||||
m.loadItemsTask.itemId = m.top.parentItem.Id
|
||||
|
||||
|
@ -143,19 +184,21 @@ sub loadInitialItems()
|
|||
m.loadItemsTask.recursive = true
|
||||
end if
|
||||
else if m.top.parentItem.collectionType = "livetv"
|
||||
m.loadItemsTask.itemType = "LiveTV"
|
||||
|
||||
m.loadItemsTask.itemType = "TvChannel"
|
||||
m.loadItemsTask.itemId = " "
|
||||
' For LiveTV, we want to "Fit" the item images, not zoom
|
||||
m.top.imageDisplayMode = "scaleToFit"
|
||||
|
||||
if get_user_setting("display.livetv.landing") = "guide" and m.options.view <> "livetv"
|
||||
showTvGuide()
|
||||
end if
|
||||
else if m.top.parentItem.collectionType = "CollectionFolder" or m.top.parentItem.type = "CollectionFolder" or m.top.parentItem.collectionType = "boxsets" or m.top.parentItem.Type = "Boxset" or m.top.parentItem.Type = "Folder" or m.top.parentItem.Type = "Channel"
|
||||
' Non-recursive, to not show subfolder contents
|
||||
m.loadItemsTask.recursive = false
|
||||
else if m.top.parentItem.Type = "Channel"
|
||||
m.top.imageDisplayMode = "scaleToFit"
|
||||
else if m.top.parentItem.collectionType = "CollectionFolder" or m.top.parentItem.type = "CollectionFolder" or m.top.parentItem.collectionType = "boxsets" or m.top.parentItem.Type = "Boxset" or m.top.parentItem.Type = "Boxsets" or m.top.parentItem.Type = "Folder" or m.top.parentItem.Type = "Channel"
|
||||
if m.voiceBox.text <> ""
|
||||
m.loadItemsTask.recursive = true
|
||||
else
|
||||
' non recursive for collections (folders, boxsets, photo albums, etc)
|
||||
m.loadItemsTask.recursive = false
|
||||
end if
|
||||
else if m.top.parentItem.json.type = "Studio"
|
||||
m.loadItemsTask.itemId = m.top.parentItem.parentFolder
|
||||
m.loadItemsTask.itemType = "Series,Movie"
|
||||
|
@ -491,13 +534,33 @@ sub onItemSelected()
|
|||
m.top.selectedItem = m.itemGrid.content.getChild(m.itemGrid.itemSelected)
|
||||
end sub
|
||||
|
||||
sub onItemAlphaSelected()
|
||||
m.loadedRows = 0
|
||||
m.loadedItems = 0
|
||||
m.data = CreateObject("roSGNode", "ContentNode")
|
||||
m.itemGrid.content = m.data
|
||||
m.spinner.visible = true
|
||||
loadInitialItems()
|
||||
sub onItemalphaSelected()
|
||||
if m.top.alphaSelected <> ""
|
||||
m.loadedRows = 0
|
||||
m.loadedItems = 0
|
||||
m.data = CreateObject("roSGNode", "ContentNode")
|
||||
m.itemGrid.content = m.data
|
||||
m.loadItemsTask.searchTerm = ""
|
||||
m.VoiceBox.text = ""
|
||||
m.loadItemsTask.nameStartsWith = m.alpha.itemAlphaSelected
|
||||
m.spinner.visible = true
|
||||
loadInitialItems()
|
||||
end if
|
||||
end sub
|
||||
|
||||
sub onvoiceFilter()
|
||||
if m.VoiceBox.text <> ""
|
||||
m.loadedRows = 0
|
||||
m.loadedItems = 0
|
||||
m.data = CreateObject("roSGNode", "ContentNode")
|
||||
m.itemGrid.content = m.data
|
||||
m.top.alphaSelected = ""
|
||||
m.loadItemsTask.NameStartsWith = " "
|
||||
m.loadItemsTask.searchTerm = m.voiceBox.text
|
||||
m.loadItemsTask.recursive = true
|
||||
m.spinner.visible = true
|
||||
loadInitialItems()
|
||||
end if
|
||||
end sub
|
||||
|
||||
|
||||
|
@ -598,6 +661,7 @@ sub optionsClosed()
|
|||
if m.tvGuide <> invalid
|
||||
m.tvGuide.lastFocus.setFocus(true)
|
||||
end if
|
||||
|
||||
end sub
|
||||
|
||||
sub showTVGuide()
|
||||
|
@ -608,6 +672,7 @@ sub showTVGuide()
|
|||
m.tvGuide.observeField("focusedChannel", "onChannelFocused")
|
||||
end if
|
||||
m.tvGuide.filter = m.filter
|
||||
m.tvGuide.searchTerm = m.voiceBox.text
|
||||
m.top.appendChild(m.tvGuide)
|
||||
m.tvGuide.lastFocus.setFocus(true)
|
||||
end sub
|
||||
|
@ -629,6 +694,12 @@ end sub
|
|||
function onKeyEvent(key as string, press as boolean) as boolean
|
||||
if not press then return false
|
||||
topGrp = m.top.findNode("itemGrid")
|
||||
searchGrp = m.top.findNode("voiceBox")
|
||||
|
||||
if key = "left" and searchGrp.isinFocusChain()
|
||||
topGrp.setFocus(true)
|
||||
searchGrp.setFocus(false)
|
||||
end if
|
||||
if key = "options"
|
||||
if m.options.visible = true
|
||||
m.options.visible = false
|
||||
|
@ -655,9 +726,13 @@ function onKeyEvent(key as string, press as boolean) as boolean
|
|||
m.options.visible = false
|
||||
optionsClosed()
|
||||
return true
|
||||
else
|
||||
m.global.sceneManager.callfunc("popScene")
|
||||
m.loadItemsTask.control = "stop"
|
||||
return true
|
||||
end if
|
||||
else if key = "play" or key = "OK"
|
||||
markupGrid = m.top.getChild(2)
|
||||
markupGrid = m.top.findNode("itemGrid")
|
||||
itemToPlay = markupGrid.content.getChild(markupGrid.itemFocused)
|
||||
|
||||
if itemToPlay <> invalid and (itemToPlay.type = "Movie" or itemToPlay.type = "Episode")
|
||||
|
@ -673,9 +748,10 @@ function onKeyEvent(key as string, press as boolean) as boolean
|
|||
else if key = "left" and topGrp.isinFocusChain()
|
||||
m.top.alphaActive = true
|
||||
topGrp.setFocus(false)
|
||||
alpha = m.Alpha.getChild(0).findNode("Alphamenu")
|
||||
alpha = m.alpha.getChild(0).findNode("Alphamenu")
|
||||
alpha.setFocus(true)
|
||||
return true
|
||||
|
||||
else if key = "right" and m.Alpha.isinFocusChain()
|
||||
m.top.alphaActive = false
|
||||
m.Alpha.setFocus(false)
|
||||
|
@ -690,6 +766,20 @@ function onKeyEvent(key as string, press as boolean) as boolean
|
|||
end if
|
||||
end if
|
||||
|
||||
if key = "replay"
|
||||
m.spinner.visible = true
|
||||
m.loadItemsTask.searchTerm = ""
|
||||
m.loadItemsTask.nameStartsWith = ""
|
||||
m.voiceBox.text = ""
|
||||
m.top.alphaSelected = ""
|
||||
m.loadItemsTask.filter = "All"
|
||||
m.filter = "All"
|
||||
m.data = CreateObject("roSGNode", "ContentNode")
|
||||
m.itemGrid.content = m.data
|
||||
loadInitialItems()
|
||||
return true
|
||||
end if
|
||||
|
||||
return false
|
||||
end function
|
||||
|
||||
|
@ -699,9 +789,11 @@ sub updateTitle()
|
|||
else if m.filter = "Favorites"
|
||||
m.top.overhangTitle = m.top.parentItem.title + " " + tr("(Favorites)")
|
||||
end if
|
||||
|
||||
if m.top.AlphaSelected <> ""
|
||||
m.top.overhangTitle = m.top.parentItem.title + " " + tr("(Filtered)")
|
||||
if m.voiceBox.text <> ""
|
||||
m.top.overhangTitle = m.top.parentItem.title + tr(" (Filtered by ") + m.loadItemsTask.searchTerm + ")"
|
||||
end if
|
||||
if m.top.alphaSelected <> ""
|
||||
m.top.overhangTitle = m.top.parentItem.title + tr(" (Filtered by ") + m.loadItemsTask.nameStartsWith + ")"
|
||||
end if
|
||||
|
||||
if m.options.view = "Networks" or m.view = "Networks"
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<component name="ItemGrid" extends="JFGroup">
|
||||
<children>
|
||||
|
||||
<VoiceTextEditBox id="VoiceBox" visible="true" width = "40" translation = "[52, 120]" />
|
||||
<Rectangle id="VoiceBoxCover" height="240" width="100" color="0x262626ff" translation = "[25, 75]" />
|
||||
<poster id="backdrop"
|
||||
loadDisplayMode="scaleToFill"
|
||||
width="1920"
|
||||
|
@ -23,10 +24,12 @@
|
|||
vertFocusAnimationStyle = "fixed"
|
||||
itemSize = "[ 290, 425 ]"
|
||||
itemSpacing = "[ 0, 45 ]"
|
||||
drawFocusFeedback = "false" />
|
||||
<Label translation="[0,540]" id="emptyText" font="font:LargeSystemFont" width="1920" horizAlign="center" vertAlign="center" height="64" visible="false" />
|
||||
drawFocusFeedback = "false" />
|
||||
<Label id="micButtonText" font="font:SmallSystemFont" visible="false" />
|
||||
<Button id = "micButton" maxWidth = "20" translation = "[20, 120]" iconUri = "pkg:/images/icons/mic_icon.png"/>
|
||||
<Label translation="[0,540]" id="emptyText" font="font:LargeSystemFont" width="1910" horizAlign="center" vertAlign="center" height="64" visible="false" />
|
||||
<ItemGridOptions id="options" visible="false" />
|
||||
<Spinner id="spinner" translation="[920, 540]" />
|
||||
<Spinner id="spinner" translation="[900, 450]" />
|
||||
<Animation id="backroundSwapAnimation" duration="1" repeat="false" easeFunction="linear" >
|
||||
<FloatFieldInterpolator id = "fadeinLoading" key="[0.0, 1.0]" keyValue="[ 0.00, 0.25 ]" fieldToInterp="backdropTransition.opacity" />
|
||||
<FloatFieldInterpolator id = "fadeoutLoaded" key="[0.0, 1.0]" keyValue="[ 0.25, 0.00 ]" fieldToInterp="backdrop.opacity" />
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
sub init()
|
||||
|
||||
m.buttons = m.top.findNode("buttons")
|
||||
m.buttons.buttons = [tr("TAB_VIEW"), tr("TAB_SORT"), tr("TAB_FILTER")]
|
||||
m.buttons.buttons = [tr("View"), tr("Sort"), tr("Filter")]
|
||||
m.buttons.selectedIndex = 1
|
||||
m.buttons.setFocus(true)
|
||||
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
sub init()
|
||||
m.top.functionName = "loadItems"
|
||||
|
||||
m.top.limit = 60
|
||||
usersettingLimit = get_user_setting("itemgrid.Limit")
|
||||
|
||||
if usersettingLimit <> invalid
|
||||
m.top.limit = usersettingLimit
|
||||
end if
|
||||
end sub
|
||||
|
||||
sub loadItems()
|
||||
|
||||
results = []
|
||||
|
||||
sort_field = m.top.sortField
|
||||
|
@ -26,15 +32,30 @@ sub loadItems()
|
|||
StudioIds: m.top.studioIds,
|
||||
genreIds: m.top.genreIds
|
||||
}
|
||||
|
||||
' Handle special case when getting names starting with numeral
|
||||
if m.top.NameStartsWith <> ""
|
||||
if m.top.NameStartsWith = "#"
|
||||
params.NameLessThan = "A"
|
||||
if m.top.ItemType = "LiveTV" or m.top.ItemType = "TvChannel"
|
||||
params.searchterm = "A"
|
||||
params.append({ parentid: " " })
|
||||
else
|
||||
params.NameLessThan = "A"
|
||||
end if
|
||||
else
|
||||
params.NameStartsWith = m.top.nameStartsWith
|
||||
if m.top.ItemType = "LiveTV" or m.top.ItemType = "TvChannel"
|
||||
params.searchterm = m.top.nameStartsWith
|
||||
params.append({ parentid: " " })
|
||||
else
|
||||
params.NameStartsWith = m.top.nameStartsWith
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
|
||||
if m.top.searchTerm <> ""
|
||||
params.searchTerm = m.top.searchTerm
|
||||
end if
|
||||
|
||||
filter = m.top.filter
|
||||
if filter = "All" or filter = "all"
|
||||
' do nothing
|
||||
|
@ -67,11 +88,11 @@ sub loadItems()
|
|||
|
||||
for each item in data.Items
|
||||
tmp = invalid
|
||||
if item.Type = "Movie"
|
||||
if item.Type = "Movie" or item.Type = "MusicVideo"
|
||||
tmp = CreateObject("roSGNode", "MovieData")
|
||||
else if item.Type = "Series"
|
||||
tmp = CreateObject("roSGNode", "SeriesData")
|
||||
else if item.Type = "BoxSet"
|
||||
else if item.Type = "BoxSet" or item.Type = "ManualPlaylistsFolder"
|
||||
tmp = CreateObject("roSGNode", "CollectionData")
|
||||
else if item.Type = "TvChannel"
|
||||
tmp = CreateObject("roSGNode", "ChannelData")
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
<field id="nameStartsWith" type="string" value="" />
|
||||
<field id="recursive" type="boolean" value="true" />
|
||||
<field id="filter" type="string" value="All" />
|
||||
<field id="searchTerm" type="string" value="" />
|
||||
<field id="studioIds" type="string" value="" />
|
||||
<field id="genreIds" type="string" value="" />
|
||||
<field id="view" type="string" value="" />
|
||||
|
|
|
@ -2,130 +2,21 @@ sub init()
|
|||
m.playbackTimer = m.top.findNode("playbackTimer")
|
||||
m.bufferCheckTimer = m.top.findNode("bufferCheckTimer")
|
||||
m.top.observeField("state", "onState")
|
||||
m.top.observeField("position", "onPositionChanged")
|
||||
m.top.trickPlayBar.observeField("visible", "onTrickPlayBarVisibilityChange")
|
||||
m.playbackTimer.observeField("fire", "ReportPlayback")
|
||||
m.bufferPercentage = 0 ' Track whether content is being loaded
|
||||
m.playReported = false
|
||||
m.top.transcodeReasons = []
|
||||
m.bufferCheckTimer.duration = 10
|
||||
m.bufferCheckTimer.duration = 30
|
||||
|
||||
if get_user_setting("ui.design.hideclock") = "true"
|
||||
clockNode = findNodeBySubtype(m.top, "clock")
|
||||
if clockNode[0] <> invalid then clockNode[0].parent.removeChild(clockNode[0].node)
|
||||
end if
|
||||
|
||||
' Skip Intro Button
|
||||
m.skipIntroButton = m.top.findNode("skipIntro")
|
||||
m.skipIntroButton.text = tr("Skip Intro")
|
||||
m.introCompleted = false
|
||||
m.showskipIntroButtonAnimation = m.top.findNode("showskipIntroButton")
|
||||
m.hideskipIntroButtonAnimation = m.top.findNode("hideskipIntroButton")
|
||||
m.moveUpskipIntroButtonAnimation = m.top.findNode("moveUpskipIntroButton")
|
||||
m.moveDownskipIntroButtonAnimation = m.top.findNode("moveDownskipIntroButton")
|
||||
end sub
|
||||
|
||||
'
|
||||
' Checks if we have valid skip intro param data
|
||||
function haveSkipIntroParams() as boolean
|
||||
|
||||
' Intro data is invalid, skip
|
||||
if not isValid(m.top.skipIntroParams?.Valid)
|
||||
return false
|
||||
end if
|
||||
|
||||
' Returned intro data is not valid, return
|
||||
if not m.top.skipIntroParams.Valid
|
||||
return false
|
||||
end if
|
||||
|
||||
return true
|
||||
end function
|
||||
|
||||
'
|
||||
' Handles showing / hiding the skip intro button
|
||||
sub handleSkipIntro()
|
||||
' We've already shown the intro, return
|
||||
if m.introCompleted then return
|
||||
|
||||
' We don't have valid data, return
|
||||
if not haveSkipIntroParams() then return
|
||||
|
||||
' Check if it's time to hide the skip prompt
|
||||
if m.top.position >= m.top.skipIntroParams.HideSkipPromptAt
|
||||
if skipIntroButtonVisible()
|
||||
hideSkipIntro()
|
||||
end if
|
||||
return
|
||||
end if
|
||||
|
||||
' Check if it's time to show the skip prompt
|
||||
if m.top.position >= m.top.skipIntroParams.ShowSkipPromptAt
|
||||
if not skipIntroButtonVisible()
|
||||
showSkipIntro()
|
||||
end if
|
||||
return
|
||||
end if
|
||||
end sub
|
||||
|
||||
'
|
||||
' When Trick Playbar Visibility changes
|
||||
sub onTrickPlayBarVisibilityChange()
|
||||
' Skip Intro button isn't visible, return
|
||||
if not skipIntroButtonVisible() then return
|
||||
|
||||
' Trick Playbar is visible, move the skip intro button up and fade it out
|
||||
if m.top.trickPlayBar.visible
|
||||
m.moveUpskipIntroButtonAnimation.control = "start"
|
||||
|
||||
m.skipIntroButton.setFocus(false)
|
||||
m.top.setFocus(true)
|
||||
|
||||
return
|
||||
end if
|
||||
|
||||
' Trick Playbar is not visible, move the skip intro button down and fade it in
|
||||
m.moveDownskipIntroButtonAnimation.control = "start"
|
||||
m.skipIntroButton.setFocus(true)
|
||||
|
||||
end sub
|
||||
|
||||
'
|
||||
' When Video Player state changes
|
||||
sub onPositionChanged()
|
||||
' Check if content is episode
|
||||
if m.top.content.contenttype = 4
|
||||
handleSkipIntro()
|
||||
end if
|
||||
end sub
|
||||
|
||||
'
|
||||
' Returns if skip intro button is currently visible
|
||||
function skipIntroButtonVisible() as boolean
|
||||
return m.skipIntroButton.opacity > 0
|
||||
end function
|
||||
|
||||
'
|
||||
' Runs skip intro button animation and sets focus to button
|
||||
sub showSkipIntro()
|
||||
m.showskipIntroButtonAnimation.control = "start"
|
||||
m.skipIntroButton.setFocus(true)
|
||||
end sub
|
||||
|
||||
'
|
||||
' Runs hide intro button animation and sets focus back to video
|
||||
sub hideSkipIntro()
|
||||
m.top.trickPlayBar.unobserveField("visible")
|
||||
m.hideskipIntroButtonAnimation.control = "start"
|
||||
m.introCompleted = true
|
||||
m.skipIntroButton.setFocus(false)
|
||||
m.top.setFocus(true)
|
||||
end sub
|
||||
|
||||
'
|
||||
' When Video Player state changes
|
||||
sub onState(msg)
|
||||
|
||||
' When buffering, start timer to monitor buffering process
|
||||
if m.top.state = "buffering" and m.bufferCheckTimer <> invalid
|
||||
|
||||
|
@ -238,21 +129,14 @@ end sub
|
|||
|
||||
|
||||
function onKeyEvent(key as string, press as boolean) as boolean
|
||||
if key = "OK"
|
||||
if not m.top.trickPlayBar.visible
|
||||
if m.skipIntroButton.hasFocus()
|
||||
m.top.seek = m.top.skipIntroParams.IntroEnd
|
||||
hideSkipIntro()
|
||||
return true
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
|
||||
if not press then return false
|
||||
|
||||
if m.top.Subtitles.count() and key = "down"
|
||||
m.top.selectSubtitlePressed = true
|
||||
return true
|
||||
else if key = "up"
|
||||
m.top.selectPlaybackInfoPressed = true
|
||||
return true
|
||||
end if
|
||||
|
||||
return false
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<interface>
|
||||
<field id="backPressed" type="boolean" alwaysNotify="true" />
|
||||
<field id="selectSubtitlePressed" type="boolean" alwaysNotify="true" />
|
||||
<field id="selectPlaybackInfoPressed" type="boolean" alwaysNotify="true" />
|
||||
<field id="PlaySessionId" type="string" />
|
||||
<field id="Subtitles" type="array" />
|
||||
<field id="SelectedSubtitle" type="integer" />
|
||||
|
@ -17,35 +18,16 @@
|
|||
<field id="retryWithTranscoding" type="boolean" value="false" />
|
||||
<field id="isTranscoded" type="boolean" />
|
||||
<field id="transcodeReasons" type="array" />
|
||||
|
||||
|
||||
<field id="videoId" type="string" />
|
||||
<field id="mediaSourceId" type="string" />
|
||||
<field id="audioIndex" type="integer" />
|
||||
|
||||
<field id="skipIntroParams" type="assocarray" />
|
||||
</interface>
|
||||
<script type="text/brightscript" uri="JFVideo.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/utils/misc.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/utils/config.brs" />
|
||||
<children>
|
||||
<JFButton id="skipIntro" opacity="0" textColor="#f0f0f0" focusedTextColor="#202020" focusFootprintBitmapUri="pkg:/images/option-menu-bg.9.png" focusBitmapUri="pkg:/images/white.9.png" translation="[1575, 900]" />
|
||||
<timer id="playbackTimer" repeat="true" duration="30" />
|
||||
<timer id="bufferCheckTimer" repeat="true" />
|
||||
|
||||
<Animation id="moveUpskipIntroButton" duration=".1" repeat="false" easeFunction="linear">
|
||||
<Vector2DFieldInterpolator key="[0.0,1.0]" keyValue="[[1575, 900], [1575, 825]]" fieldToInterp="skipIntro.translation"/>
|
||||
<FloatFieldInterpolator key="[0.0, 1.0]" keyValue="[.9, .1]" fieldToInterp="skipIntro.opacity" />
|
||||
</Animation>
|
||||
<Animation id="moveDownskipIntroButton" duration=".1" repeat="false" easeFunction="linear">
|
||||
<Vector2DFieldInterpolator key="[0.0,1.0]" keyValue="[[1575, 825], [1575, 900]]" fieldToInterp="skipIntro.translation"/>
|
||||
<FloatFieldInterpolator key="[0.0, 1.0]" keyValue="[.1, .9]" fieldToInterp="skipIntro.opacity" />
|
||||
</Animation>
|
||||
|
||||
<Animation id="showskipIntroButton" duration="1.0" repeat="false" easeFunction="inQuad">
|
||||
<FloatFieldInterpolator key="[0.0, 1.0]" keyValue="[0.0, .9]" fieldToInterp="skipIntro.opacity" />
|
||||
</Animation>
|
||||
<Animation id="hideskipIntroButton" duration=".2" repeat="false" easeFunction="inQuad">
|
||||
<FloatFieldInterpolator key="[0.0, 1.0]" keyValue="[.9, 0]" fieldToInterp="skipIntro.opacity" />
|
||||
</Animation>
|
||||
</children>
|
||||
</component>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
sub init()
|
||||
m.title = m.top.findNode("title")
|
||||
m.staticTitle = m.top.findNode("staticTitle")
|
||||
m.series = m.top.findNode("Series")
|
||||
m.poster = m.top.findNode("poster")
|
||||
|
||||
m.backdrop = m.top.findNode("backdrop")
|
||||
|
@ -39,6 +40,8 @@ sub updateSize()
|
|||
m.staticTitle.height = m.title.height
|
||||
m.staticTitle.translation = m.title.translation
|
||||
|
||||
m.series.maxWidth = maxSize[0]
|
||||
|
||||
m.poster.width = int(maxSize[0]) - 4
|
||||
m.poster.height = int(maxSize[1]) - m.title.height 'Set poster height to available space
|
||||
|
||||
|
@ -54,9 +57,14 @@ sub itemContentChanged() as void
|
|||
|
||||
if itemData.json.lookup("Type") = "Episode" and itemData.json.IndexNumber <> invalid
|
||||
m.title.text = StrI(itemData.json.IndexNumber) + ". " + m.title.text
|
||||
|
||||
m.series.text = itemData.json.Series
|
||||
m.series.visible = true
|
||||
|
||||
else if itemData.json.lookup("Type") = "MusicAlbum"
|
||||
m.title.font = "font:SmallestSystemFont"
|
||||
m.staticTitle.font = "font:SmallestSystemFont"
|
||||
|
||||
end if
|
||||
m.staticTitle.text = m.title.text
|
||||
|
||||
|
@ -64,7 +72,7 @@ sub itemContentChanged() as void
|
|||
|
||||
if get_user_setting("ui.tvshows.blurunwatched") = "true"
|
||||
|
||||
if itemData.json.lookup("Type") = "Episode"
|
||||
if itemData.json.lookup("Type") = "Episode" and itemData.json.userdata <> invalid
|
||||
if not itemData.json.userdata.played
|
||||
imageUrl = imageUrl + "&blur=15"
|
||||
end if
|
||||
|
@ -82,6 +90,7 @@ sub focusChanged()
|
|||
|
||||
if m.top.itemHasFocus = true
|
||||
m.title.repeatCount = -1
|
||||
m.series.repeatCount = -1
|
||||
m.staticTitle.visible = false
|
||||
m.title.visible = true
|
||||
|
||||
|
@ -94,6 +103,7 @@ sub focusChanged()
|
|||
|
||||
else
|
||||
m.title.repeatCount = 0
|
||||
m.series.repeatCount = 0
|
||||
m.staticTitle.visible = true
|
||||
m.title.visible = false
|
||||
end if
|
||||
|
|
|
@ -2,6 +2,12 @@
|
|||
<component name="ListPoster" extends="Group">
|
||||
<children>
|
||||
<Rectangle id="backdrop" />
|
||||
<ScrollingLabel id="Series"
|
||||
horizAlign="center"
|
||||
font="font:SmallSystemFont"
|
||||
repeatCount="0"
|
||||
visible="false"
|
||||
/>
|
||||
<Poster id="poster" translation="[2,0]" loadDisplayMode="scaleToFit" />
|
||||
<ScrollingLabel id="title"
|
||||
horizAlign="center"
|
||||
|
|
|
@ -154,7 +154,7 @@ sub createDialogPallete()
|
|||
DialogSecondaryTextColor: "0xf8f8f8ff",
|
||||
DialogSecondaryItemColor: "0xcc7ecc4D",
|
||||
DialogInputFieldColor: "0x80FF8080",
|
||||
DialogKeyboardColor: "0x80FF804D",
|
||||
KeyboardDialogColor: "0x80FF804D",
|
||||
DialogFootprintColor: "0x80FF804D"
|
||||
}
|
||||
end sub
|
||||
|
|
|
@ -3,48 +3,25 @@ sub init()
|
|||
m.top.horizAlignment = "center"
|
||||
m.top.vertAlignment = "top"
|
||||
m.top.visible = false
|
||||
m.searchText = m.top.findNode("search_Key")
|
||||
m.searchText.textEditBox.hintText = tr("Search")
|
||||
m.searchText.keyGrid.keyDefinitionUri = "pkg:/components/data/CustomAddressKDF.json"
|
||||
m.searchText.textEditBox.voiceEnabled = true
|
||||
m.searchText.textEditBox.active = true
|
||||
m.searchText.ObserveField("text", "searchMedias")
|
||||
m.searchSelect = m.top.findNode("searchSelect")
|
||||
|
||||
'set lable text
|
||||
m.label = m.top.findNode("text")
|
||||
m.label.text = tr("Search now")
|
||||
|
||||
show_dialog()
|
||||
end sub
|
||||
|
||||
function onKeyEvent(key as string, press as boolean) as boolean
|
||||
if not press then return false
|
||||
|
||||
if key = "OK"
|
||||
' Make a Keyboard Dialog here
|
||||
show_dialog()
|
||||
return true
|
||||
sub searchMedias()
|
||||
m.top.search_values = m.searchText.text
|
||||
if m.top.search_values.len() > 1
|
||||
m.searchText.textEditBox.leadingEllipsis = true
|
||||
else
|
||||
m.searchText.textEditBox.leadingEllipsis = false
|
||||
end if
|
||||
|
||||
return false
|
||||
end function
|
||||
|
||||
function onDialogButton()
|
||||
d = m.top.getScene().dialog
|
||||
button_text = d.buttons[d.buttonSelected]
|
||||
|
||||
if button_text = tr("Search")
|
||||
m.top.search_value = d.text
|
||||
dismiss_dialog()
|
||||
return true
|
||||
else if button_text = tr("Cancel")
|
||||
dismiss_dialog()
|
||||
return true
|
||||
end if
|
||||
|
||||
return false
|
||||
end function
|
||||
|
||||
sub show_dialog()
|
||||
dialog = CreateObject("roSGNode", "KeyboardDialog")
|
||||
dialog.title = tr("Search")
|
||||
dialog.buttons = [tr("Search"), tr("Cancel")]
|
||||
|
||||
m.top.getScene().dialog = dialog
|
||||
|
||||
dialog.observeField("buttonselected", "onDialogButton")
|
||||
end sub
|
||||
|
||||
sub dismiss_dialog()
|
||||
m.top.getScene().dialog.close = true
|
||||
end sub
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<component name="SearchBox" extends="LayoutGroup">
|
||||
<children>
|
||||
<Label text="Search" />
|
||||
<TextEditBox id="search-input" width="800" maxTextLength="75" />
|
||||
<Label id = "text" text="" visible="false" />
|
||||
<DynamicMiniKeyboard id="search_Key" />
|
||||
</children>
|
||||
<interface>
|
||||
<field id="search_value" type="string" alwaysNotify="true" />
|
||||
<field id="search_values" type="string" alwaysNotify="true" />
|
||||
</interface>
|
||||
<script type="text/brightscript" uri="SearchBox.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/api/Items.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/api/baserequest.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/utils/config.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/api/Image.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/utils/deviceCapabilities.brs" />
|
||||
</component>
|
||||
|
|
|
@ -2,5 +2,5 @@ sub init()
|
|||
m.top.poster.uri = "pkg:/images/spinner.png"
|
||||
m.top.control = "start"
|
||||
m.top.clockwise = true
|
||||
m.top.spinInterval = 2
|
||||
m.top.spinInterval = 3
|
||||
end sub
|
||||
|
|
|
@ -8,7 +8,7 @@ sub init()
|
|||
m.name.vertAlign = "center"
|
||||
m.name.horizAlign = "center"
|
||||
|
||||
m.value.hintText = tr("Enter a value...")
|
||||
m.value.hintText = tr("Enter a username")
|
||||
m.value.maxTextLength = 120
|
||||
end sub
|
||||
|
||||
|
@ -17,6 +17,7 @@ sub itemContentChanged()
|
|||
|
||||
m.name.text = data.label
|
||||
if data.type = "password"
|
||||
m.value.hintText = tr("Enter a password")
|
||||
m.value.secureMode = true
|
||||
end if
|
||||
|
||||
|
|
|
@ -45,13 +45,18 @@ end function
|
|||
|
||||
|
||||
sub show_dialog(configField)
|
||||
dialog = createObject("roSGNode", "KeyboardDialog")
|
||||
dialog = createObject("roSGNode", "StandardKeyboardDialog")
|
||||
m.configField = configField
|
||||
dialog.title = "Enter the " + configField.label
|
||||
dialog.title = configField.label
|
||||
dialog.buttons = [tr("OK"), tr("Cancel")]
|
||||
m.greenPalette = createObject("roSGNode", "RSGPalette")
|
||||
m.greenPalette.colors = {
|
||||
DialogBackgroundColor: "#2A2B2A"
|
||||
}
|
||||
dialog.palette = m.greenPalette
|
||||
|
||||
if configField.type = "password"
|
||||
dialog.keyboard.textEditBox.secureMode = true
|
||||
dialog.textEditBox.secureMode = true
|
||||
end if
|
||||
|
||||
if configField.value <> ""
|
||||
|
|
|
@ -23,12 +23,18 @@ function onKeyEvent(key as string, press as boolean) as boolean
|
|||
else if key = "down" and submit.focusedChild = invalid
|
||||
submit.setFocus(true)
|
||||
return true
|
||||
else if key = "up" and submit.focusedChild <> invalid or quickConnect.focusedChild <> invalid
|
||||
else if key = "up" and submit.focusedChild <> invalid
|
||||
checkbox.setFocus(true)
|
||||
return true
|
||||
else if key = "up" and quickConnect.focusedChild <> invalid
|
||||
checkbox.setFocus(true)
|
||||
return true
|
||||
else if key = "up" and checkbox.focusedChild <> invalid
|
||||
list.setFocus(true)
|
||||
return true
|
||||
else if key = "right" and checkbox.focusedChild <> invalid
|
||||
quickConnect.setFocus(true)
|
||||
return true
|
||||
else if key = "right" and submit.focusedChild <> invalid
|
||||
quickConnect.setFocus(true)
|
||||
return true
|
||||
|
|
|
@ -29,9 +29,21 @@ function onKeyEvent(key as string, press as boolean) as boolean
|
|||
'user navigating up to the server picker from the input box (it's only focusable if it has items)
|
||||
else if key = "up" and m.serverUrlContainer.hasFocus() and m.servers.Count() > 0
|
||||
m.serverPicker.setFocus(true)
|
||||
else if key = "up" and m.serverUrlContainer.hasFocus() and m.servers.Count() = 0
|
||||
ScanForServers()
|
||||
else if key = "back" and m.serverUrlContainer.hasFocus() and m.servers.Count() > 0
|
||||
m.serverPicker.setFocus(true)
|
||||
else if key = "OK" and m.serverUrlContainer.hasFocus()
|
||||
ShowKeyboard()
|
||||
'focus the serverUrl input from submit button
|
||||
else if key = "back" and m.submit.hasFocus() and m.servers.Count() > 0
|
||||
m.serverPicker.setFocus(true)
|
||||
else if key = "back" and m.submit.hasFocus() and m.servers.Count() = 0
|
||||
m.serverUrlContainer.setFocus(true)
|
||||
else if key = "back" and m.serverUrlContainer.hasFocus() and m.servers.Count() = 0
|
||||
ScanForServers()
|
||||
else if key = "back" and m.serverPicker.hasFocus() and m.servers.Count() > 0
|
||||
ScanForServers()
|
||||
' On "back" with or without available local servers, will rescan for servers
|
||||
else if key = "up" and m.submit.hasFocus()
|
||||
m.serverUrlContainer.setFocus(true)
|
||||
'focus the submit button from serverUrl
|
||||
|
@ -60,6 +72,7 @@ sub ScanForServers()
|
|||
'run the task
|
||||
m.ssdpScanner.observeField("content", "ScanForServersComplete")
|
||||
m.ssdpScanner.control = "RUN"
|
||||
m.spinner.visible = true
|
||||
end sub
|
||||
|
||||
sub ScanForServersComplete(event)
|
||||
|
@ -107,10 +120,13 @@ sub ScanForServersComplete(event)
|
|||
end sub
|
||||
|
||||
sub ShowKeyboard()
|
||||
dialog = createObject("roSGNode", "KeyboardDialog")
|
||||
dialog = createObject("roSGNode", "StandardKeyboardDialog")
|
||||
dialog.title = tr("Enter the server name or ip address")
|
||||
dialog.buttons = [tr("OK"), tr("Cancel")]
|
||||
dialog.text = m.serverUrlTextbox.text
|
||||
greenPalette = createObject("roSGNode", "RSGPalette")
|
||||
greenPalette.colors = { DialogBackgroundColor: "#2A2B2A" }
|
||||
dialog.palette = greenPalette
|
||||
|
||||
m.top.getscene().dialog = dialog
|
||||
m.dialog = dialog
|
||||
|
|
96
components/data/CustomAddressKDF.json
Normal file
96
components/data/CustomAddressKDF.json
Normal file
|
@ -0,0 +1,96 @@
|
|||
{
|
||||
"keyboardWidthFHD": 374,
|
||||
"keyboardHeightFHD": 409,
|
||||
"keyboardWidthHD": 250,
|
||||
"keyboardHeightHD": 273,
|
||||
"sections": [
|
||||
{
|
||||
"grids": [
|
||||
{
|
||||
"rows": [
|
||||
{
|
||||
"keys": [
|
||||
{ "label": "a" },
|
||||
{ "label": "b" },
|
||||
{ "label": "c" },
|
||||
{ "label": "d" },
|
||||
{ "label": "e" },
|
||||
{ "label": "f" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"keys": [
|
||||
{ "label": "g" },
|
||||
{ "label": "h" },
|
||||
{ "label": "i" },
|
||||
{ "label": "j" },
|
||||
{ "label": "k" },
|
||||
{ "label": "l" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"keys": [
|
||||
{ "label": "m" },
|
||||
{ "label": "n" },
|
||||
{ "label": "o" },
|
||||
{ "label": "p" },
|
||||
{ "label": "q" },
|
||||
{ "label": "r" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"keys": [
|
||||
{ "label": "s" },
|
||||
{ "label": "t" },
|
||||
{ "label": "u" },
|
||||
{ "label": "v" },
|
||||
{ "label": "w" },
|
||||
{ "label": "x" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"keys": [
|
||||
{ "label": "y" },
|
||||
{ "label": "z" },
|
||||
{ "label": "1" },
|
||||
{ "label": "2" },
|
||||
{ "label": "3" },
|
||||
{ "label": "4" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"keys": [
|
||||
{ "label": "5" },
|
||||
{ "label": "6" },
|
||||
{ "label": "7" },
|
||||
{ "label": "8" },
|
||||
{ "label": "9" },
|
||||
{ "label": "0" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"keys": [
|
||||
{
|
||||
"icon": "theme:DKB_ClearKeyBitmap",
|
||||
"focusIcon": "theme:DKB_ClearKeyFocusBitmap",
|
||||
"strOut": "clear"
|
||||
},
|
||||
{
|
||||
"icon": "theme:DKB_SpaceKeyBitmap",
|
||||
"focusIcon": "theme:DKB_SpaceKeyFocusBitmap",
|
||||
"strOut": "space"
|
||||
},
|
||||
{
|
||||
"icon": "theme:DKB_DeleteKeyBitmap",
|
||||
"focusIcon": "theme:DKB_DeleteKeyFocusBitmap",
|
||||
"autoRepeat": 1,
|
||||
"strOut": "backspace"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -11,6 +11,7 @@
|
|||
<field id="type" type="string" value="Episode" />
|
||||
<field id="json" type="assocarray" onChange="setFields" />
|
||||
<field id="selectedAudioStreamIndex" type="integer" />
|
||||
<field id="favorite" type="boolean" />
|
||||
</interface>
|
||||
<script type="text/brightscript" uri="TVEpisodeData.brs" />
|
||||
</component>
|
||||
|
|
|
@ -54,6 +54,22 @@ sub loadItems()
|
|||
params["ImageTypeLimit"] = 1
|
||||
params["UserId"] = get_setting("active_user")
|
||||
|
||||
maxDaysInNextUp = get_user_setting("ui.details.maxdaysnextup", "365")
|
||||
if isValid(maxDaysInNextUp)
|
||||
maxDaysInNextUp = Val(maxDaysInNextUp)
|
||||
if maxDaysInNextUp > 0
|
||||
dateToday = CreateObject("roDateTime")
|
||||
dateCutoff = CreateObject("roDateTime")
|
||||
|
||||
dateCutoff.FromSeconds(dateToday.AsSeconds() - (maxDaysInNextUp * 86400))
|
||||
|
||||
params["NextUpDateCutoff"] = dateCutoff.ToISOString()
|
||||
params["EnableRewatching"] = false
|
||||
params["DisableFirstEpisode"] = false
|
||||
params["limit"] = 24
|
||||
end if
|
||||
end if
|
||||
|
||||
resp = APIRequest(url, params)
|
||||
data = getJson(resp)
|
||||
for each item in data.Items
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
<script type="text/brightscript" uri="pkg:/source/api/Items.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/api/baserequest.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/utils/config.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/utils/misc.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/utils/deviceCapabilities.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/api/Image.brs" />
|
||||
</component>
|
||||
|
|
|
@ -6,15 +6,41 @@ sub loadChannels()
|
|||
|
||||
results = []
|
||||
|
||||
sort_field = m.top.sortField
|
||||
|
||||
if m.top.sortAscending = true
|
||||
sort_order = "Ascending"
|
||||
else
|
||||
sort_order = "Descending"
|
||||
end if
|
||||
|
||||
params = {
|
||||
includeItemTypes: "LiveTvChannel",
|
||||
SortBy: sort_field,
|
||||
SortOrder: sort_order,
|
||||
recursive: m.top.recursive,
|
||||
UserId: get_setting("active_user")
|
||||
}
|
||||
|
||||
' Handle special case when getting names starting with numeral
|
||||
if m.top.NameStartsWith <> ""
|
||||
if m.top.NameStartsWith = "#"
|
||||
params.searchterm = "A"
|
||||
else
|
||||
params.searchterm = m.top.nameStartsWith
|
||||
end if
|
||||
end if
|
||||
|
||||
'Append voice search when there is text
|
||||
if m.top.searchTerm <> ""
|
||||
params.searchTerm = m.top.searchTerm
|
||||
end if
|
||||
|
||||
if m.top.filter = "Favorites"
|
||||
params.append({ isFavorite: true })
|
||||
end if
|
||||
|
||||
url = "LiveTv/Channels"
|
||||
url = Substitute("Users/{0}/Items/", get_setting("active_user"))
|
||||
|
||||
resp = APIRequest(url, params)
|
||||
data = getJson(resp)
|
||||
|
@ -39,7 +65,5 @@ sub loadChannels()
|
|||
results.push(channel)
|
||||
end if
|
||||
end for
|
||||
|
||||
m.top.channels = results
|
||||
|
||||
end sub
|
||||
|
|
|
@ -5,7 +5,11 @@
|
|||
<field id="limit" type="integer" value="" />
|
||||
<field id="startIndex" type="integer" value="0" />
|
||||
<field id="filter" type="string" value="All" />
|
||||
|
||||
<field id="searchTerm" type="string" value="" />
|
||||
<field id="sortField" type="string" value="SortName" />
|
||||
<field id="sortAscending" type="boolean" value="true" />
|
||||
<field id="nameStartsWith" type="string" value="" />
|
||||
<field id="recursive" type="boolean" value="true" />
|
||||
<!-- Total records available from server-->
|
||||
<field id="channels" type="array" />
|
||||
</interface>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
sub init()
|
||||
|
||||
m.EPGLaunchCompleteSignaled = false
|
||||
m.scheduleGrid = m.top.findNode("scheduleGrid")
|
||||
m.detailsPane = m.top.findNode("detailsPane")
|
||||
|
@ -7,7 +6,6 @@ sub init()
|
|||
m.detailsPane.observeField("watchSelectedChannel", "onWatchChannelSelected")
|
||||
m.detailsPane.observeField("recordSelectedChannel", "onRecordChannelSelected")
|
||||
m.detailsPane.observeField("recordSeriesSelectedChannel", "onRecordSeriesChannelSelected")
|
||||
|
||||
m.gridStartDate = CreateObject("roDateTime")
|
||||
m.scheduleGrid.contentStartTime = m.gridStartDate.AsSeconds() - 1800
|
||||
m.gridEndDate = createObject("roDateTime")
|
||||
|
@ -28,10 +26,11 @@ sub init()
|
|||
m.top.lastFocus = m.scheduleGrid
|
||||
|
||||
m.channelIndex = {}
|
||||
|
||||
m.spinner = m.top.findNode("spinner")
|
||||
end sub
|
||||
|
||||
sub channelFilterSet()
|
||||
print "Channel Filter set"
|
||||
m.scheduleGrid.jumpToChannel = 0
|
||||
if m.top.filter <> invalid and m.LoadChannelsTask.filter <> m.top.filter
|
||||
if m.LoadChannelsTask.state = "run" then m.LoadChannelsTask.control = "stop"
|
||||
|
@ -42,6 +41,19 @@ sub channelFilterSet()
|
|||
|
||||
end sub
|
||||
|
||||
'Voice Search set
|
||||
sub channelsearchTermSet()
|
||||
m.scheduleGrid.jumpToChannel = 0
|
||||
if m.top.searchTerm <> invalid and m.LoadChannelsTask.searchTerm <> m.top.searchTerm
|
||||
if m.LoadChannelsTask.state = "run" then m.LoadChannelsTask.control = "stop"
|
||||
|
||||
m.LoadChannelsTask.searchTerm = m.top.searchTerm
|
||||
m.spinner.visible = true
|
||||
m.LoadChannelsTask.control = "RUN"
|
||||
end if
|
||||
|
||||
end sub
|
||||
|
||||
' Initial list of channels loaded
|
||||
sub onChannelsLoaded()
|
||||
gridData = createObject("roSGNode", "ContentNode")
|
||||
|
@ -49,32 +61,36 @@ sub onChannelsLoaded()
|
|||
counter = 0
|
||||
channelIdList = ""
|
||||
|
||||
for each item in m.LoadChannelsTask.channels
|
||||
gridData.appendChild(item)
|
||||
m.channelIndex[item.Id] = counter
|
||||
counter = counter + 1
|
||||
channelIdList = channelIdList + item.Id + ","
|
||||
end for
|
||||
'if search returns channels
|
||||
if m.LoadChannelsTask.channels.count() > 0
|
||||
for each item in m.LoadChannelsTask.channels
|
||||
gridData.appendChild(item)
|
||||
m.channelIndex[item.Id] = counter
|
||||
counter = counter + 1
|
||||
channelIdList = channelIdList + item.Id + ","
|
||||
end for
|
||||
m.scheduleGrid.content = gridData
|
||||
|
||||
m.scheduleGrid.content = gridData
|
||||
m.LoadScheduleTask = createObject("roSGNode", "LoadScheduleTask")
|
||||
m.LoadScheduleTask.observeField("schedule", "onScheduleLoaded")
|
||||
|
||||
m.LoadScheduleTask = createObject("roSGNode", "LoadScheduleTask")
|
||||
m.LoadScheduleTask.observeField("schedule", "onScheduleLoaded")
|
||||
m.LoadScheduleTask.startTime = m.gridStartDate.ToISOString()
|
||||
m.LoadScheduleTask.endTime = m.gridEndDate.ToISOString()
|
||||
m.LoadScheduleTask.channelIds = channelIdList
|
||||
m.LoadScheduleTask.control = "RUN"
|
||||
|
||||
m.LoadScheduleTask.startTime = m.gridStartDate.ToISOString()
|
||||
m.LoadScheduleTask.endTime = m.gridEndDate.ToISOString()
|
||||
m.LoadScheduleTask.channelIds = channelIdList
|
||||
m.LoadScheduleTask.control = "RUN"
|
||||
m.LoadProgramDetailsTask = createObject("roSGNode", "LoadProgramDetailsTask")
|
||||
m.LoadProgramDetailsTask.observeField("programDetails", "onProgramDetailsLoaded")
|
||||
|
||||
m.LoadProgramDetailsTask = createObject("roSGNode", "LoadProgramDetailsTask")
|
||||
m.LoadProgramDetailsTask.observeField("programDetails", "onProgramDetailsLoaded")
|
||||
m.scheduleGrid.setFocus(true)
|
||||
if m.EPGLaunchCompleteSignaled = false
|
||||
m.top.signalBeacon("EPGLaunchComplete") ' Required Roku Performance monitoring
|
||||
m.EPGLaunchCompleteSignaled = true
|
||||
end if
|
||||
m.LoadChannelsTask.channels = []
|
||||
|
||||
m.scheduleGrid.setFocus(true)
|
||||
if m.EPGLaunchCompleteSignaled = false
|
||||
m.top.signalBeacon("EPGLaunchComplete") ' Required Roku Performance monitoring
|
||||
m.EPGLaunchCompleteSignaled = true
|
||||
end if
|
||||
m.LoadChannelsTask.channels = []
|
||||
|
||||
end sub
|
||||
|
||||
' When LoadScheduleTask completes (initial or more data) and we have a schedule to display
|
||||
|
@ -102,6 +118,7 @@ sub onScheduleLoaded()
|
|||
m.scheduleGrid.showLoadingDataFeedback = false
|
||||
m.scheduleGrid.setFocus(true)
|
||||
m.LoadScheduleTask.schedule = []
|
||||
m.spinner.visible = false
|
||||
end sub
|
||||
|
||||
sub onProgramFocused()
|
||||
|
@ -118,7 +135,9 @@ sub onProgramFocused()
|
|||
m.top.focusedChannel = channel
|
||||
|
||||
' Exit if Channels not yet loaded
|
||||
|
||||
if channel = invalid or channel.getChildCount() = 0
|
||||
|
||||
m.detailsPane.programDetails = invalid
|
||||
return
|
||||
end if
|
||||
|
@ -195,6 +214,22 @@ sub onWatchChannelSelected()
|
|||
m.top.watchChannel = m.detailsPane.channel
|
||||
end sub
|
||||
|
||||
' As user scrolls grid, check if more data requries to be loaded
|
||||
sub onGridScrolled()
|
||||
|
||||
' If we're within 12 hours of end of grid, load next 24hrs of data
|
||||
if m.scheduleGrid.leftEdgeTargetTime + (12 * 60 * 60) > m.gridEndDate.AsSeconds()
|
||||
|
||||
' Ensure the task is not already (still) running,
|
||||
if m.LoadScheduleTask.state <> "run"
|
||||
m.LoadScheduleTask.startTime = m.gridEndDate.ToISOString()
|
||||
m.gridEndDate.FromSeconds(m.gridEndDate.AsSeconds() + (24 * 60 * 60))
|
||||
m.LoadScheduleTask.endTime = m.gridEndDate.ToISOString()
|
||||
m.LoadScheduleTask.control = "RUN"
|
||||
end if
|
||||
end if
|
||||
end sub
|
||||
|
||||
' Handle user selecting "Record Channel" from Program Details
|
||||
sub onRecordChannelSelected()
|
||||
if m.detailsPane.recordSelectedChannel = false then return
|
||||
|
@ -242,27 +277,18 @@ sub onRecordOperationDone()
|
|||
end if
|
||||
end sub
|
||||
|
||||
' As user scrolls grid, check if more data requries to be loaded
|
||||
sub onGridScrolled()
|
||||
|
||||
' If we're within 12 hours of end of grid, load next 24hrs of data
|
||||
if m.scheduleGrid.leftEdgeTargetTime + (12 * 60 * 60) > m.gridEndDate.AsSeconds()
|
||||
|
||||
' Ensure the task is not already (still) running,
|
||||
if m.LoadScheduleTask.state <> "run"
|
||||
m.LoadScheduleTask.startTime = m.gridEndDate.ToISOString()
|
||||
m.gridEndDate.FromSeconds(m.gridEndDate.AsSeconds() + (24 * 60 * 60))
|
||||
m.LoadScheduleTask.endTime = m.gridEndDate.ToISOString()
|
||||
m.LoadScheduleTask.control = "RUN"
|
||||
end if
|
||||
end if
|
||||
end sub
|
||||
|
||||
function onKeyEvent(key as string, press as boolean) as boolean
|
||||
if not press then return false
|
||||
detailsGrp = m.top.findNode("detailsPane")
|
||||
gridGrp = m.top.findNode("scheduleGrid")
|
||||
|
||||
if key = "back" and m.detailsPane.isInFocusChain()
|
||||
if key = "back" and detailsGrp.isInFocusChain()
|
||||
focusProgramDetails(false)
|
||||
detailsGrp.setFocus(false)
|
||||
gridGrp.setFocus(true)
|
||||
return true
|
||||
else if key = "back"
|
||||
m.global.sceneManager.callFunc("popScene")
|
||||
return true
|
||||
end if
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
programTitleFocusedColor="#ffffff" iconFocusedColor="#ff0000"
|
||||
showPastTimeScreen="true" pastTimeScreenBlendColor="#555555"
|
||||
/>
|
||||
<Spinner id="spinner" translation="[900, 450]" />
|
||||
<Animation id="gridMoveAnimation" duration="1" repeat="false" easeFunction="outQuad" >
|
||||
<Vector2DFieldInterpolator id="gridMoveAnimationPosition" key="[0.0, 0.5]" fieldToInterp="scheduleGrid.translation" />
|
||||
</Animation>
|
||||
|
@ -20,6 +21,7 @@
|
|||
<field id="watchChannel" type="node" alwaysNotify="false" />
|
||||
<field id="focusedChannel" type="node" alwaysNotify="false" />
|
||||
<field id="filter" type="string" value="All" onChange="channelFilterSet" />
|
||||
<field id="searchTerm" type="string" value="" onChange="channelsearchTermSet" />
|
||||
</interface>
|
||||
<script type="text/brightscript" uri="schedule.brs" />
|
||||
</component>
|
||||
|
|
|
@ -46,8 +46,9 @@ sub itemContentChanged()
|
|||
m.top.findNode("moviePoster").uri = m.top.itemContent.posterURL
|
||||
|
||||
' Set default video source
|
||||
m.top.selectedVideoStreamId = itemData.MediaSources[0].id
|
||||
|
||||
if itemData.MediaSources <> invalid
|
||||
m.top.selectedVideoStreamId = itemData.MediaSources[0].id
|
||||
end if
|
||||
' Find first Audio Stream and set that as default
|
||||
SetDefaultAudioTrack(itemData)
|
||||
|
||||
|
|
|
@ -408,7 +408,7 @@ sub onMetaDataLoaded()
|
|||
if data <> invalid and data.count() > 0
|
||||
|
||||
' Use metadata to load backdrop image
|
||||
if isvalid(data?.json?.ArtistItems?[0].id)
|
||||
if isvalid(data?.json?.ArtistItems?[0]?.id)
|
||||
m.LoadBackdropImageTask.itemId = data.json.ArtistItems[0].id
|
||||
m.LoadBackdropImageTask.observeField("content", "onBackdropImageLoaded")
|
||||
m.LoadBackdropImageTask.control = "RUN"
|
||||
|
|
|
@ -1,3 +1,60 @@
|
|||
sub init()
|
||||
m.top.optionsAvailable = false
|
||||
m.searchSpinner = m.top.findnode("searchSpinner")
|
||||
m.searchSelect = m.top.findnode("searchSelect")
|
||||
m.searchTask = CreateObject("roSGNode", "SearchTask")
|
||||
|
||||
'set label text
|
||||
m.searchHelpText = m.top.findNode("SearchHelpText")
|
||||
m.searchHelpText.text = tr("You can search for Titles, People, Live TV Channels and more")
|
||||
|
||||
end sub
|
||||
|
||||
sub searchMedias()
|
||||
query = m.top.searchAlpha
|
||||
'if user deletes the search string hide the spinner
|
||||
if query.len() = 0
|
||||
m.searchSpinner.visible = false
|
||||
end if
|
||||
'if search task is running and user selectes another letter stop the search and load the next letter
|
||||
m.searchTask.control = "stop"
|
||||
if query <> invalid and query <> ""
|
||||
m.searchSpinner.visible = true
|
||||
end if
|
||||
m.searchTask.observeField("results", "loadResults")
|
||||
m.searchTask.query = query
|
||||
m.top.overhangTitle = tr("Search") + ": " + query
|
||||
m.searchTask.control = "RUN"
|
||||
|
||||
end sub
|
||||
|
||||
sub loadResults()
|
||||
m.searchTask.unobserveField("results")
|
||||
|
||||
m.searchSpinner.visible = false
|
||||
m.searchSelect.itemdata = m.searchTask.results
|
||||
m.searchSelect.query = m.top.SearchAlpha
|
||||
m.searchHelpText.visible = false
|
||||
m.searchAlphabox = m.top.findnode("searchResults")
|
||||
m.searchAlphabox.translation = "[470, 85]"
|
||||
end sub
|
||||
|
||||
function onKeyEvent(key as string, press as boolean) as boolean
|
||||
|
||||
m.searchAlphabox = m.top.findNode("search_Key")
|
||||
if m.searchAlphabox.textEditBox.hasFocus()
|
||||
m.searchAlphabox.textEditBox.translation = "[0, -150]"
|
||||
else
|
||||
m.searchAlphabox.textEditBox.translation = "[0, 0]"
|
||||
end if
|
||||
|
||||
if key = "left" and m.searchSelect.isinFocusChain() and (m.searchSelect.currFocusColumn = -1 or m.searchSelect.currFocusColumn = 0)
|
||||
m.searchAlphabox.setFocus(true)
|
||||
return true
|
||||
else if key = "right"
|
||||
m.searchSelect.setFocus(true)
|
||||
return true
|
||||
end if
|
||||
return false
|
||||
|
||||
end function
|
||||
|
|
|
@ -1,13 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<component name="SearchResults" extends="JFGroup">
|
||||
<component name="searchResults" extends="JFGroup">
|
||||
<children>
|
||||
<SearchBox id="SearchBox" visible="true" translation="[960, 145]" />
|
||||
<SearchRow id="SearchSelect" visible="false" />
|
||||
|
||||
<Rectangle width="1920" height="1080" color="#000000" opacity="0.75" />
|
||||
<LayoutGroup layoutDirection="horiz" id="SearchAlphabox" translation="[70, 120]">
|
||||
<SearchBox id="SearchBox" visible="true" focusable="true"/>
|
||||
</LayoutGroup>
|
||||
<LayoutGroup layoutDirection="vert" id="searchResults" translation="[470, 150]" >
|
||||
<Label id = "SearchHelpText" text=""/>
|
||||
<SearchRow id="searchSelect" visible="true" focusable="true"/>
|
||||
</LayoutGroup>
|
||||
<OptionsSlider id="options" />
|
||||
<Spinner id = "searchSpinner" visible="false" translation="[1050, 500]"/>
|
||||
</children>
|
||||
<interface>
|
||||
<field id="query" type="string" alwaysNotify="true" />
|
||||
<field id="selectedItem" type="node" alwaysNotify="true" />
|
||||
<field id="quickPlayNode" type="node" alwaysNotify="true" />
|
||||
<field id="imageDisplayMode" type="string" value="scaleToZoom" />
|
||||
<field id="searchAlpha" type="string" alias="SearchBox.search_values" alwaysNotify="true" onChange="searchMedias" />
|
||||
</interface>
|
||||
<script type="text/brightscript" uri="SearchResults.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/api/Items.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/api/baserequest.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/utils/config.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/api/Image.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/utils/deviceCapabilities.brs" />
|
||||
</component>
|
||||
|
|
|
@ -11,27 +11,28 @@ sub init()
|
|||
' TODO - Define a failed to load image background
|
||||
' m.top.failedBitmapURI
|
||||
|
||||
m.top.setFocus(true)
|
||||
end sub
|
||||
|
||||
sub updateSize()
|
||||
' In search results, rowSize only dictates how many are on screen at once
|
||||
m.top.rowSize = 5
|
||||
m.top.rowSize = 3
|
||||
|
||||
dimensions = m.top.getScene().currentDesignResolution
|
||||
|
||||
border = 75
|
||||
border = 50
|
||||
m.top.translation = [border, border + 115]
|
||||
|
||||
textHeight = 80
|
||||
itemWidth = (dimensions["width"] - border * 2) / m.top.rowSize
|
||||
itemHeight = itemWidth * 1.5 + textHeight
|
||||
itemWidth = (dimensions["width"] - border) / 6
|
||||
itemHeight = itemWidth + (textHeight / 2.3)
|
||||
|
||||
m.top.itemSize = [dimensions["width"] - border * 2, itemHeight]
|
||||
m.top.itemSpacing = [0, 50]
|
||||
m.top.itemSize = [1350, itemHeight] ' this is used for setting the row size
|
||||
m.top.itemSpacing = [0, 105]
|
||||
|
||||
m.top.rowItemSize = [itemWidth, itemHeight]
|
||||
m.top.rowItemSpacing = [0, 0]
|
||||
m.top.numRows = 2
|
||||
m.top.translation = "[12,18]"
|
||||
end sub
|
||||
|
||||
function getData()
|
||||
|
@ -45,16 +46,17 @@ function getData()
|
|||
' todo - Or get the old data? I can't remember...
|
||||
data = CreateObject("roSGNode", "ContentNode")
|
||||
' Do this to keep the ordering, AssociateArrays have no order
|
||||
type_array = ["Movie", "Series", "TvChannel", "Episode", "AlbumArtist", "Album", "Audio", "Person"]
|
||||
type_array = ["Movie", "Series", "TvChannel", "Episode", "MusicArtist", "MusicAlbum", "Audio", "Person", "PlaylistsFolder"]
|
||||
content_types = {
|
||||
"TvChannel": { "label": "Channels", "count": 0 },
|
||||
"Movie": { "label": "Movies", "count": 0 },
|
||||
"Series": { "label": "Shows", "count": 0 },
|
||||
"Episode": { "label": "Episodes", "count": 0 },
|
||||
"AlbumArtist": { "label": "Artists", "count": 0 },
|
||||
"Album": { "label": "Albums", "count": 0 },
|
||||
"MusicArtist": { "label": "Artists", "count": 0 },
|
||||
"MusicAlbum": { "label": "Albums", "count": 0 },
|
||||
"Audio": { "label": "Songs", "count": 0 },
|
||||
"Person": { "label": "People", "count": 0 }
|
||||
"Person": { "label": "People", "count": 0 },
|
||||
"PlaylistsFolder": { "label": "Playlist", "count": 0 }
|
||||
}
|
||||
|
||||
for each item in itemData.searchHints
|
||||
|
@ -84,3 +86,4 @@ sub addRow(data, title, type_filter)
|
|||
end if
|
||||
end for
|
||||
end sub
|
||||
|
||||
|
|
|
@ -4,7 +4,12 @@
|
|||
<field id="rowSize" type="int" />
|
||||
<field id="itemData" type="assocarray" onChange="getData" />
|
||||
<field id="query" type="string" />
|
||||
<field id="itemSelected" type="int" />
|
||||
<field id="itemSelected" type="node" alwaysNotify="true" />
|
||||
</interface>
|
||||
<script type="text/brightscript" uri="SearchRow.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/api/Items.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/api/baserequest.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/utils/config.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/api/Image.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/utils/deviceCapabilities.brs" />
|
||||
</component>
|
||||
|
|
9
components/search/SearchTask.brs
Normal file
9
components/search/SearchTask.brs
Normal file
|
@ -0,0 +1,9 @@
|
|||
sub init()
|
||||
m.top.functionName = "search"
|
||||
end sub
|
||||
|
||||
sub search()
|
||||
if m.top.query <> invalid and m.top.query <> ""
|
||||
m.top.results = searchMedia(m.top.query)
|
||||
end if
|
||||
end sub
|
14
components/search/SearchTask.xml
Normal file
14
components/search/SearchTask.xml
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
|
||||
<component name="SearchTask" extends="Task">
|
||||
<interface>
|
||||
<field id="query" type="string" />
|
||||
<field id="results" type="assocarray" />
|
||||
</interface>
|
||||
<script type="text/brightscript" uri="SearchTask.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/api/Items.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/api/baserequest.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/utils/config.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/api/Image.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/utils/deviceCapabilities.brs" />
|
||||
</component>
|
|
@ -12,6 +12,9 @@ sub init()
|
|||
m.path = m.top.findNode("path")
|
||||
|
||||
m.boolSetting = m.top.findNode("boolSetting")
|
||||
m.integerSetting = m.top.findNode("integerSetting")
|
||||
m.integerSetting.observeField("submit", "onKeyGridSubmit")
|
||||
m.integerSetting.observeField("escape", "onKeyGridEscape")
|
||||
|
||||
m.settingsMenu.setFocus(true)
|
||||
m.settingsMenu.observeField("itemFocused", "settingFocused")
|
||||
|
@ -24,6 +27,17 @@ sub init()
|
|||
LoadMenu({ children: m.configTree })
|
||||
end sub
|
||||
|
||||
sub onKeyGridSubmit()
|
||||
selectedSetting = m.userLocation.peek().children[m.settingsMenu.itemFocused]
|
||||
set_user_setting(selectedSetting.settingName, m.integerSetting.text)
|
||||
m.settingsMenu.setFocus(true)
|
||||
end sub
|
||||
|
||||
sub onKeyGridEscape()
|
||||
if m.integerSetting.escape = "left" or m.integerSetting.escape = "back"
|
||||
m.settingsMenu.setFocus(true)
|
||||
end if
|
||||
end sub
|
||||
|
||||
sub LoadMenu(configSection)
|
||||
|
||||
|
@ -58,8 +72,6 @@ sub LoadMenu(configSection)
|
|||
end for
|
||||
end sub
|
||||
|
||||
|
||||
|
||||
sub settingFocused()
|
||||
|
||||
selectedSetting = m.userLocation.peek().children[m.settingsMenu.itemFocused]
|
||||
|
@ -68,6 +80,7 @@ sub settingFocused()
|
|||
|
||||
' Hide Settings
|
||||
m.boolSetting.visible = false
|
||||
m.integerSetting.visible = false
|
||||
|
||||
if selectedSetting.type = invalid
|
||||
return
|
||||
|
@ -80,6 +93,12 @@ sub settingFocused()
|
|||
else
|
||||
m.boolSetting.checkedItem = 0
|
||||
end if
|
||||
else if selectedSetting.type = "integer"
|
||||
integerValue = get_user_setting(selectedSetting.settingName, selectedSetting.default)
|
||||
if isValid(integerValue)
|
||||
m.integerSetting.text = integerValue
|
||||
end if
|
||||
m.integerSetting.visible = true
|
||||
else
|
||||
print "Unknown setting type " + selectedSetting.type
|
||||
end if
|
||||
|
@ -91,11 +110,13 @@ sub settingSelected()
|
|||
|
||||
selectedItem = m.userLocation.peek().children[m.settingsMenu.itemFocused]
|
||||
|
||||
|
||||
if selectedItem.type <> invalid ' Show setting
|
||||
if selectedItem.type = "bool"
|
||||
m.boolSetting.setFocus(true)
|
||||
end if
|
||||
if selectedItem.type = "integer"
|
||||
m.integerSetting.setFocus(true)
|
||||
end if
|
||||
else if selectedItem.children <> invalid and selectedItem.children.Count() > 0 ' Show sub menu
|
||||
LoadMenu(selectedItem)
|
||||
m.settingsMenu.setFocus(true)
|
||||
|
|
|
@ -2,50 +2,39 @@
|
|||
<component name="Settings" extends="JFGroup">
|
||||
<children>
|
||||
|
||||
<Label id="path" translation = "[95,175]" font="font:SmallestBoldSystemFont" />
|
||||
<Label id="path" translation = "[95,175]" font="font:SmallestBoldSystemFont" />
|
||||
|
||||
<LabelList
|
||||
<LabelList
|
||||
translation = "[120,250]"
|
||||
id = "settingsMenu"
|
||||
itemSize = "[440,48]"
|
||||
vertFocusAnimationStyle = "floatingFocus"
|
||||
focusBitmapBlendColor = "#006fab"
|
||||
focusedColor = "#ffffff"
|
||||
itemSpacing = "[0,5]"
|
||||
/>
|
||||
itemSpacing = "[0,5]" />
|
||||
|
||||
<Poster
|
||||
translation = "[710,250]"
|
||||
id="testRectangle"
|
||||
width="880"
|
||||
height="700"
|
||||
uri="pkg:/images/white.9.png"
|
||||
blendColor = "#3f3f3f"
|
||||
/>
|
||||
<Poster
|
||||
translation = "[710,250]" id="testRectangle" width="880" height="700" uri="pkg:/images/white.9.png"
|
||||
blendColor = "#3f3f3f" />
|
||||
|
||||
<LayoutGroup
|
||||
translation = "[1150,275]"
|
||||
id="settingDetail"
|
||||
vertAlignment="top"
|
||||
horizAlignment="center"
|
||||
itemSpacings="[50]"
|
||||
>
|
||||
<LayoutGroup translation = "[1150,275]" id="settingDetail" vertAlignment="top" horizAlignment="center" itemSpacings="[50]">
|
||||
|
||||
<ScrollingLabel font="font:LargeSystemFont" id="settingTitle" maxWidth="750" />
|
||||
<ScrollingLabel font="font:LargeSystemFont" id="settingTitle" maxWidth="750" />
|
||||
|
||||
<Label id="settingDesc" width="750" wrap = "true" />
|
||||
<Label id="settingDesc" width="750" wrap = "true" />
|
||||
|
||||
<RadioButtonList id="boolSetting" vertFocusAnimationStyle="floatingFocus">
|
||||
<ContentNode role="content">
|
||||
<ContentNode title="Disabled" />
|
||||
<ContentNode title="Enabled" />
|
||||
</ContentNode>
|
||||
</RadioButtonList>
|
||||
|
||||
</LayoutGroup>
|
||||
<RadioButtonList id="boolSetting" vertFocusAnimationStyle="floatingFocus">
|
||||
<ContentNode role="content">
|
||||
<ContentNode title="Disabled" />
|
||||
<ContentNode title="Enabled" />
|
||||
</ContentNode>
|
||||
</RadioButtonList>
|
||||
</LayoutGroup>
|
||||
|
||||
<intkeyboard_integerKeyboard translation="[900, 520]" id="integerSetting" maxLength="3" domain="numeric" visible="false" />
|
||||
|
||||
</children>
|
||||
<script type="text/brightscript" uri="settings.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/utils/config.brs" />
|
||||
<script type="text/brightscript" uri="pkg:/source/utils/misc.brs" />
|
||||
</component>
|
BIN
images/icons/mic_icon.png
Normal file
BIN
images/icons/mic_icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
|
@ -112,9 +112,17 @@
|
|||
<source>Home</source>
|
||||
<translation>Основен</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a username</source>
|
||||
<translation>Въведете потребителско име</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a password</source>
|
||||
<translation>Въведете паролата</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a value...</source>
|
||||
<translation>Въведете стойност…</translation>
|
||||
<translation>Въведете стойност...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sort Field</source>
|
||||
|
|
|
@ -112,9 +112,17 @@
|
|||
<source>Home</source>
|
||||
<translation>Domů</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a username</source>
|
||||
<translation>Zadejte jméno</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a password</source>
|
||||
<translation>Zadejte heslo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a value...</source>
|
||||
<translation>Zadejte hodnotu…</translation>
|
||||
<translation>Zadejte hodnotu...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sort Field</source>
|
||||
|
@ -3302,7 +3310,7 @@
|
|||
<translation>Speciální funkce</translation>
|
||||
<message>
|
||||
<source>Press 'OK' to Close</source>
|
||||
<translation>Press 'OK' to Close</translation>
|
||||
<translation>Pro zavření stiskni 'OK'</translation>
|
||||
</message>
|
||||
</message>
|
||||
<message>
|
||||
|
@ -3402,5 +3410,104 @@
|
|||
<source>Save Credentials?</source>
|
||||
<translation>Uložit přihlašovací údaje?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<comment>Title of Tab for options to filter library content</comment>
|
||||
<source>TAB_FILTER</source>
|
||||
<translation>Filtr</translation>
|
||||
</message>
|
||||
<message>
|
||||
<comment>Title of Tab for options to sort library content</comment>
|
||||
<source>TAB_SORT</source>
|
||||
<translation>Třídit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<comment>Title of Tab for switching "views" when looking at a library</comment>
|
||||
<source>TAB_VIEW</source>
|
||||
<translation>Pohled</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>RUNTIME</source>
|
||||
<translation>Délka</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>RELEASE_DATE</source>
|
||||
<translation>Datum vydání</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PLAY_COUNT</source>
|
||||
<translation>Počet přehrání</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>OFFICIAL_RATING</source>
|
||||
<translation>Rodičovské hodnocení</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DATE_PLAYED</source>
|
||||
<translation>Datum přehrání</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DATE_ADDED</source>
|
||||
<translation>Datum přidání</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>CRITIC_RATING</source>
|
||||
<translation>Honocení kritiků</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>IMDB_RATING</source>
|
||||
<translation>Hodnocení IMDb</translation>
|
||||
</message>
|
||||
<message>
|
||||
<comment>Name or Title field of media item</comment>
|
||||
<source>TITLE</source>
|
||||
<translation>Název</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>Tato %1 neobsahuje žádné položky</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>On Now</source>
|
||||
<translation>Nyní</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete Saved</source>
|
||||
<translation>Smazat uložené</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save Credentials?</source>
|
||||
<translation>Uložit přihlašovací údaje?</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>Tato %1 neobsahuje žádné položky</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>CRITIC_RATING</source>
|
||||
<translation>Honocení kritiků</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>IMDB_RATING</source>
|
||||
<translation>Hodnocení IMDb</translation>
|
||||
</message>
|
||||
<message>
|
||||
<comment>Name or Title field of media item</comment>
|
||||
<source>TITLE</source>
|
||||
<translation>Název</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>On Now</source>
|
||||
<translation>Nyní</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete Saved</source>
|
||||
<translation>Smazat uložené</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save Credentials?</source>
|
||||
<translation>Uložit přihlašovací údaje?</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
|
|
@ -112,6 +112,14 @@
|
|||
<source>Home</source>
|
||||
<translation>Home</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a username</source>
|
||||
<translation>Benutzernamen eingeben</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a password</source>
|
||||
<translation>Passwort eingeben</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a value...</source>
|
||||
<translation>Wert eingeben…</translation>
|
||||
|
@ -5915,7 +5923,7 @@
|
|||
<translation>Extras</translation>
|
||||
<message>
|
||||
<source>Press 'OK' to Close</source>
|
||||
<translation>Press 'OK' to Close</translation>
|
||||
<translation>Drücke 'OK' zum Schliessen</translation>
|
||||
</message>
|
||||
</message>
|
||||
<message>
|
||||
|
@ -6136,5 +6144,839 @@
|
|||
<source>Change Server</source>
|
||||
<translation>Server wechseln</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Record Series</source>
|
||||
<translation>Serie aufnehmen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Record</source>
|
||||
<translation>Aufnehmen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>View Channel</source>
|
||||
<translation>Kanal anzeigen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>TV Guide</source>
|
||||
<translation>TV-Programm</translation>
|
||||
<extracomment>Menu option for showing Live TV Guide / Schedule</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Channels</source>
|
||||
<translation>Kanäle</translation>
|
||||
<extracomment>Menu option for showing Live TV Channel List</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Repeat</source>
|
||||
<translation>Wiederholung</translation>
|
||||
<extracomment>If TV Shows has previously been broadcasted</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Live</source>
|
||||
<translation>Live</translation>
|
||||
<extracomment>If TV Show is being broadcast live (not pre-recorded)</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Ends at</source>
|
||||
<translation>Endet am</translation>
|
||||
<extracomment>(Past Tense) For defining a day and time when a program ended (e.g. Ended Wednesday, 08:00) </extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Ended at</source>
|
||||
<translation>Endet um</translation>
|
||||
<extracomment>(Past Tense) For defining time when a program will ended (e.g. Ended at 08:00) </extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Starts</source>
|
||||
<translation>Beginnt am</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>Starts at</source>
|
||||
<translation>Beginnt um</translation>
|
||||
<extracomment>(Future Tense) For defining time when a program will start today (e.g. Starts at 08:00) </extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Started</source>
|
||||
<translation>Begann am</translation>
|
||||
<extracomment>(Past Tense) For defining a day and time when a program started (e.g. Started Wednesday, 08:00) </extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Started at</source>
|
||||
<translation>Begonnen um</translation>
|
||||
<extracomment>(Past Tense) For defining time when a program started today (e.g. Started at 08:00) </extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Saturday</source>
|
||||
<translation>Samstag</translation>
|
||||
<extracomment>Day of Week</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Friday</source>
|
||||
<translation>Freitag</translation>
|
||||
<extracomment>Day of Week</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Thursday</source>
|
||||
<translation>Donnerstag</translation>
|
||||
<extracomment>Day of Week</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Wednesday</source>
|
||||
<translation>Mittwoch</translation>
|
||||
<extracomment>Day of Week</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Tuesday</source>
|
||||
<translation>Dienstag</translation>
|
||||
<extracomment>Day of Week</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Monday</source>
|
||||
<translation>Montag</translation>
|
||||
<extracomment>Day of Week</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sunday</source>
|
||||
<translation>Sonntag</translation>
|
||||
<extracomment>Day of Week</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>tomorrow</source>
|
||||
<translation>morgen</translation>
|
||||
<extracomment>Next day</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>yesterday</source>
|
||||
<translation>gestern</translation>
|
||||
<extracomment>Previous day</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>today</source>
|
||||
<translation>heute</translation>
|
||||
<extracomment>Current day</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>TV Shows</source>
|
||||
<translation>Serien</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Movies</source>
|
||||
<translation>Filme</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Special Features</source>
|
||||
<translation>Extras</translation>
|
||||
<message>
|
||||
<source>Press 'OK' to Close</source>
|
||||
<translation>Drücke "OK" um zuschließen</translation>
|
||||
</message>
|
||||
</message>
|
||||
<message>
|
||||
<source>More Like This</source>
|
||||
<translation>Mehr wie dieses</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cast & Crew</source>
|
||||
<translation>Besetzung & Mitwirkende</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Age</source>
|
||||
<translation>Alter</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Died</source>
|
||||
<translation>gestorben</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Born</source>
|
||||
<translation>geboren</translation>
|
||||
</message>
|
||||
<message>
|
||||
<comment>Title of Tab for options to filter library content</comment>
|
||||
<source>TAB_FILTER</source>
|
||||
<translation>Filter</translation>
|
||||
</message>
|
||||
<message>
|
||||
<comment>Title of Tab for options to sort library content</comment>
|
||||
<source>TAB_SORT</source>
|
||||
<translation>Sortieren</translation>
|
||||
</message>
|
||||
<message>
|
||||
<comment>Title of Tab for switching "views" when looking at a library</comment>
|
||||
<source>TAB_VIEW</source>
|
||||
<translation>Ansicht</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>RUNTIME</source>
|
||||
<translation>Laufzeit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>RELEASE_DATE</source>
|
||||
<translation>Veröffentlichungsdatum</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PLAY_COUNT</source>
|
||||
<translation>Wiedergabeanzahl</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>OFFICIAL_RATING</source>
|
||||
<translation>Altersfreigabe</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DATE_PLAYED</source>
|
||||
<translation>Abgespielt am</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DATE_ADDED</source>
|
||||
<translation>Hinzugefügt am</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>CRITIC_RATING</source>
|
||||
<translation>Kritikerbewertung</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>IMDB_RATING</source>
|
||||
<translation>IMDb Bewertung</translation>
|
||||
</message>
|
||||
<message>
|
||||
<comment>Name or Title field of media item</comment>
|
||||
<source>TITLE</source>
|
||||
<translation>Name</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 Elemente</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unable to load Channel Data from the server</source>
|
||||
<translation>Kanaldaten können nicht vom Server geladen werden</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error loading Channel Data</source>
|
||||
<translation>Fehler beim Laden von Kanaldaten</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Loading Channel Data</source>
|
||||
<translation>Lade Kanaldaten</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>An error was encountered while playing this item.</source>
|
||||
<translation>Beim Abspielen dieses Elements ist ein Fehler aufgetreten.</translation>
|
||||
<extracomment>Dialog detail when error occurs during playback</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>There was an error retrieving the data for this item from the server.</source>
|
||||
<translation>Beim Abrufen der Daten für dieses Element vom Server ist ein Fehler aufgetreten.</translation>
|
||||
<extracomment>Dialog detail 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>Error Retrieving Content</source>
|
||||
<translation>Fehler beim Abrufen des Inhalts</translation>
|
||||
<extracomment>Dialog title when unable to load Content from Server</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>On Now</source>
|
||||
<translation>Läuft gerade</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete Saved</source>
|
||||
<translation>Gespeichertes verwerfen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save Credentials?</source>
|
||||
<translation>Anmeldedaten speichern?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sign Out</source>
|
||||
<translation>Abmelden</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Change Server</source>
|
||||
<translation>Server wechseln</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Pick a Jellyfin server from the local network</source>
|
||||
<translation>Wähle einen Jellyfin-Server aus dem lokalen Netzwerk aus:</translation>
|
||||
<extracomment>Instructions on initial app launch when the user is asked to pick a server from a list</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>The requested content does not exist on the server</source>
|
||||
<translation>Der gefragte Inhalt existiert nicht</translation>
|
||||
<extracomment>Content of message box when the requested content is not found on the server</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>%1 Besitzt keine Elemente</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unable to load Channel Data from the server</source>
|
||||
<translation>Die Kanaldaten könnten nicht abgerufen werden</translation>
|
||||
</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>Error Retrieving Content</source>
|
||||
<translation>Fehler beim Abrufen des Inhaltes</translation>
|
||||
<extracomment>Dialog title when unable to load Content from Server</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use generated splashscreen image as Jellyfin's home background. Jellyfin will need to be closed and reopened for change to take effect.</source>
|
||||
<translation>Nutze Jellyfin's Generierten Splashscreen als Bildschirmschoner Hintergrund. Jellyfin muss geschlossen und wieder geöffnet werden damit die Änderung in Kraft treten.</translation>
|
||||
<extracomment>Description for option in Setting Screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use the replay button to slowly animate to the first item in the folder. (If disabled, the folder will reset to the first item immediately).</source>
|
||||
<translation>Nutze die Wiederholungstaste um langsam das erste Element in dem Ordner zu animieren. (Falls deaktiviert, Wird der Ordner sofort zum ersten Element zurückgesetzt).</translation>
|
||||
<extracomment>Description for option in Setting Screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Always show the titles below the poster images. (If disabled, the title will be shown under the highlighted item only).</source>
|
||||
<translation>Zeige immer die Title der Poster an. (Falls deaktiviert, der Title wird nur dem ausgewählten Element angezeigt).</translation>
|
||||
<extracomment>Description for option in Setting Screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete Saved</source>
|
||||
<translation>Gespeichertes verwerfen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set the maximum amount of days a show should stay in the 'Next Up' list without watching it.</source>
|
||||
<translation>Legen Sie die maximale Anzahl an Tagen fest, an denen eine Sendung in der „Nächste Sendung“-Liste bleiben soll, ohne sie anzusehen.</translation>
|
||||
<extracomment>Settings Menu - Description for option</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Options for Home Page.</source>
|
||||
<translation>Einstellungen für die Startseite.</translation>
|
||||
<extracomment>Description for Home Page user settings.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Home Page</source>
|
||||
<translation>Startseite</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Settings relating to how the application looks.</source>
|
||||
<translation>Einstellungen zum Aussehen der Anwendung.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Settings relating to playback and supported codec and media types.</source>
|
||||
<translation>Einstellungen in Bezug auf Wiedergabe und unterstützte Codecs und Medientypen.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Play Trailer</source>
|
||||
<translation>Trailer abspielen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Skip Intro</source>
|
||||
<translation>Überspringe Intro</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Hides all clocks in Jellyfin. Jellyfin will need to be closed and reopened for change to take effect.</source>
|
||||
<translation>Blendet alle Uhren in Jellyfin aus. Jellyfin muss geschlossen und wieder geöffnet werden, damit die Änderung wirksam wird.</translation>
|
||||
<extracomment>Settings Menu - Description for option</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Hide Clock</source>
|
||||
<translation>Uhr ausblenden</translation>
|
||||
<extracomment>Option Title in user setting screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cinema Mode brings the theater experience straight to your living room with the ability to play custom intros before the main feature.</source>
|
||||
<translation>Kino Modus bringt dir ein Kinoerlebnis direkt zu dir in dein Wohnzimmer, mit der Fähigkeit eigene Intros abzuspielen.</translation>
|
||||
<extracomment>Settings Menu - Description for option</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cinema Mode</source>
|
||||
<translation>Kino Modus</translation>
|
||||
<extracomment>Settings Menu - Title for option</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use Splashscreen as Home Background</source>
|
||||
<translation>Splashscreen als Hintergrund für die Startseite verwenden</translation>
|
||||
<extracomment>Option Title in user setting screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Options that alter the design of Jellyfin.</source>
|
||||
<translation>Optionen, die das Design von Jellyfin verändern.</translation>
|
||||
<extracomment>Description for Design Elements user settings.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Design Elements</source>
|
||||
<translation>Designelemente</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use generated splashscreen image as Jellyfin's screensaver background. Jellyfin will need to be closed and reopened for change to take effect.</source>
|
||||
<translation>Nutze Jellyfin's Generierten Splashscreen als Bildschirmschoner Hintergrund. Jellyfin muss geschlossen und wieder geöffnet werden damit die Änderung in Kraft treten.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use Splashscreen as Screensaver Background</source>
|
||||
<translation>Splashscreen als Bildschirmschoner-Hintergrund verwenden</translation>
|
||||
<extracomment>Option Title in user setting screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Options for Jellyfin's screensaver.</source>
|
||||
<translation>Optionen für Jellyfin's Bildschirmschoner.</translation>
|
||||
<extracomment>Description for Screensaver user settings.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Screensaver</source>
|
||||
<translation>Bildschirmschoner</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>If enabled, images of unwatched episodes will be blurred.</source>
|
||||
<translation>Falls aktiviert, werden Bilder von nicht geschauten Folgen unkenntlich gemacht.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Blur Unwatched Episodes</source>
|
||||
<translation>Nicht geschaute Folgen unkenntlich machen</translation>
|
||||
<extracomment>Option Title in user setting screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Options for TV Shows.</source>
|
||||
<translation>Optionen für Serien.</translation>
|
||||
<extracomment>Description for TV Shows user settings.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Hides tagline text on details pages.</source>
|
||||
<translation>Blendet Slogan-Text auf Detailseiten aus.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Hide Taglines</source>
|
||||
<translation>Slogan ausblenden</translation>
|
||||
<extracomment>Option Title in user setting screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Options for Details pages.</source>
|
||||
<translation>Optionen für Detailseiten.</translation>
|
||||
<extracomment>Description for Details page user settings.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Details Page</source>
|
||||
<translation>Detailseite</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Return to Top</source>
|
||||
<translation>Zurück nach oben</translation>
|
||||
<extracomment>UI -> Media Grid -> Item Title in user setting screen.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Shows</source>
|
||||
<translation>Serien</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Studios</source>
|
||||
<translation>Studios</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Networks</source>
|
||||
<translation>Netzwerke</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>There was an error authenticating via Quick Connect.</source>
|
||||
<translation>Fehler beim Authentifizierung über Quick Connect.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(Dialog will close automatically)</source>
|
||||
<translation>(Der Dialog wird automatisch geschlossen)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Here is your Quick Connect code:</source>
|
||||
<translation>Hier ist dein Quick Connect Code:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Quick Connect</source>
|
||||
<translation>Quick Connect</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%1 of %2</source>
|
||||
<translation>%1 von %2</translation>
|
||||
<extracomment>Item position and count. %1 = current item. %2 = total number of items</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>You can search for Titles, People, Live TV Channels and more</source>
|
||||
<translation>Du kannst nach Titeln, Leuten, Live Fernsehen Känale und mehr suchen</translation>
|
||||
<extracomment>Help text in search results</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search now</source>
|
||||
<translation>Suche jetzt</translation>
|
||||
<extracomment>Help text in search Box</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use voice remote to search</source>
|
||||
<translation>Verwenden Sie die Sprachfernbedienung, um zu suchen</translation>
|
||||
<extracomment>Help text in search voice text box</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Go to episode</source>
|
||||
<translation>Zur Episode gehen</translation>
|
||||
<extracomment>Continue Watching Popup Menu - Navigate to the Episode Detail Page</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Go to season</source>
|
||||
<translation>Zur Staffel gehen</translation>
|
||||
<extracomment>Continue Watching Popup Menu - Navigate to the Season Page</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Go to series</source>
|
||||
<translation>Zur Serie gehen</translation>
|
||||
<extracomment>Continue Watching Popup Menu - Navigate to the Series Detail Page</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set Watched</source>
|
||||
<translation>Als gesehen markieren</translation>
|
||||
<extracomment>Button Text - When pressed, marks item as Warched</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set Favorite</source>
|
||||
<translation>Als Favorit markieren</translation>
|
||||
<extracomment>Button Text - When pressed, sets item as Favorite</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show item count in the library and index of selected item.</source>
|
||||
<translation>Zeigt die Anzahl der Elemente in der Bibliothek und den Index des ausgewählten Elements an.</translation>
|
||||
<extracomment>Description for option in Setting Screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Item Count</source>
|
||||
<translation>Anzahl</translation>
|
||||
<extracomment>UI -> Media Grid -> Item Count in user setting screen.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Item Titles</source>
|
||||
<translation>Artikel Namen</translation>
|
||||
<extracomment>UI -> Media Grid -> Item Title in user setting screen.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Media Grid options.</source>
|
||||
<translation>Medienraster Einstellungen.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Media Grid</source>
|
||||
<translation>Medienraster</translation>
|
||||
<extracomment>UI -> Media Grid section in user setting screen.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>User Interface</source>
|
||||
<translation>Benutzeroberfläche</translation>
|
||||
<extracomment>Title for User Interface section in user setting screen.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Disabled</source>
|
||||
<translation>Deaktiviert</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enabled</source>
|
||||
<translation>Aktiviert</translation>
|
||||
</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 type="unfinished">Unterstützung von Direkt Abspielen von MPEG-2 Inhalte (z.B., Live Fernsehen). Dadurch wird die Transcodierung von MPEG-2-Inhalten verhindert, aber es nutzt bedeutend mehr Bandbreite.</translation>
|
||||
<extracomment>Settings Menu - Description for option</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>MPEG-2 Support</source>
|
||||
<translation>MPEG-2 Unterstützung</translation>
|
||||
<extracomment>Settings Menu - Title for option</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Playback</source>
|
||||
<translation>Wiedergabe</translation>
|
||||
<extracomment>Title for Playback section in user setting screen.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Version</source>
|
||||
<translation>Version</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>An error was encountered while playing this item. Server did not provide required transcoding data.</source>
|
||||
<translation>Beim Abspielen des Titels ist ein Fehler aufgetreten. Der Server hat zur Transkodierung erforderliche Daten nicht zur Verfügung gestellt.</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>Error Getting Playback Information</source>
|
||||
<translation>Fehler beim Abrufen von Wiedergabe-Informationen</translation>
|
||||
<extracomment>Dialog Title: Received error from server when trying to get information about the selected item for playback</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>...or enter server URL manually:</source>
|
||||
<translation>Falls kein Server angezeigt wird, versuche die URL per Hand einzugeben:</translation>
|
||||
<extracomment>Instructions on initial app launch when the user is asked to manually enter a server URL</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter the server name or ip address</source>
|
||||
<translation>Gebe den Servernamen oder die IP-Adresse ein</translation>
|
||||
<extracomment>Title of KeyboardDialog when manually entering a server URL</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unknown</source>
|
||||
<translation>Unbekannt</translation>
|
||||
<extracomment>Title for a cast member for which we have no information for</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Not found</source>
|
||||
<translation>Nicht gefunden</translation>
|
||||
<extracomment>Title of message box when the requested content is not found on the server</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Connecting to Server</source>
|
||||
<translation>Verbindung zum Server wird hergestellt</translation>
|
||||
<extracomment>Message to display to user while client is attempting to connect to the server</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Close</source>
|
||||
<translation>Schließen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cancel Series Recording</source>
|
||||
<translation>Serienaufnahme abbrechen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cancel Recording</source>
|
||||
<translation>Aufnahme abbrechen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Record Series</source>
|
||||
<translation>Serie aufnehmen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Record</source>
|
||||
<translation>Aufnehmen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>View Channel</source>
|
||||
<translation>Kanal anzeigen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>TV Guide</source>
|
||||
<translation>Fernsehprogramm</translation>
|
||||
<extracomment>Menu option for showing Live TV Guide / Schedule</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Channels</source>
|
||||
<translation>Kanäle</translation>
|
||||
<extracomment>Menu option for showing Live TV Channel List</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Repeat</source>
|
||||
<translation>Wiederholung</translation>
|
||||
<extracomment>If TV Shows has previously been broadcasted</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Live</source>
|
||||
<translation>Live</translation>
|
||||
<extracomment>If TV Show is being broadcast live (not pre-recorded)</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Ends at</source>
|
||||
<translation>Endet am</translation>
|
||||
<extracomment>(Past Tense) For defining a day and time when a program ended (e.g. Ended Wednesday, 08:00) </extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Ended at</source>
|
||||
<translation>Endet um</translation>
|
||||
<extracomment>(Past Tense) For defining time when a program will ended (e.g. Ended at 08:00) </extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Starts</source>
|
||||
<translation>Beginnt am</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>Starts at</source>
|
||||
<translation>Beginnt um</translation>
|
||||
<extracomment>(Future Tense) For defining time when a program will start today (e.g. Starts at 08:00) </extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Started</source>
|
||||
<translation>Gestartet</translation>
|
||||
<extracomment>(Past Tense) For defining a day and time when a program started (e.g. Started Wednesday, 08:00) </extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Started at</source>
|
||||
<translation>Begonnen um</translation>
|
||||
<extracomment>(Past Tense) For defining time when a program started today (e.g. Started at 08:00) </extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Saturday</source>
|
||||
<translation>Samstag</translation>
|
||||
<extracomment>Day of Week</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Friday</source>
|
||||
<translation>Freitag</translation>
|
||||
<extracomment>Day of Week</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Thursday</source>
|
||||
<translation>Donnerstag</translation>
|
||||
<extracomment>Day of Week</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Wednesday</source>
|
||||
<translation>Mittwoch</translation>
|
||||
<extracomment>Day of Week</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Tuesday</source>
|
||||
<translation>Dienstag</translation>
|
||||
<extracomment>Day of Week</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Monday</source>
|
||||
<translation>Montag</translation>
|
||||
<extracomment>Day of Week</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sunday</source>
|
||||
<translation>Sonntag</translation>
|
||||
<extracomment>Day of Week</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>tomorrow</source>
|
||||
<translation>morgen</translation>
|
||||
<extracomment>Next day</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>yesterday</source>
|
||||
<translation>gestern</translation>
|
||||
<extracomment>Previous day</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>today</source>
|
||||
<translation>heute</translation>
|
||||
<extracomment>Current day</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>TV Shows</source>
|
||||
<translation>Serien</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Movies</source>
|
||||
<translation>Filme</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Special Features</source>
|
||||
<translation>Extras Features</translation>
|
||||
<message>
|
||||
<source>Press 'OK' to Close</source>
|
||||
<translation>Press 'OK' to Close</translation>
|
||||
</message>
|
||||
</message>
|
||||
<message>
|
||||
<source>More Like This</source>
|
||||
<translation>Mehr wie dieses</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cast & Crew</source>
|
||||
<translation>Besetzung & Mitwirkende</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Age</source>
|
||||
<translation>Alter</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Died</source>
|
||||
<translation>gestorben</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Born</source>
|
||||
<translation>geboren</translation>
|
||||
</message>
|
||||
<message>
|
||||
<comment>Title of Tab for options to filter library content</comment>
|
||||
<source>TAB_FILTER</source>
|
||||
<translation>Filter</translation>
|
||||
</message>
|
||||
<message>
|
||||
<comment>Title of Tab for options to sort library content</comment>
|
||||
<source>TAB_SORT</source>
|
||||
<translation>Sortieren</translation>
|
||||
</message>
|
||||
<message>
|
||||
<comment>Title of Tab for switching "views" when looking at a library</comment>
|
||||
<source>TAB_VIEW</source>
|
||||
<translation>Ansicht</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>RUNTIME</source>
|
||||
<translation>Laufzeit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>RELEASE_DATE</source>
|
||||
<translation>Veröffentlichungsdatum</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PLAY_COUNT</source>
|
||||
<translation>Wiedergabeanzahl</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>OFFICIAL_RATING</source>
|
||||
<translation>Altersfreigabe</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DATE_PLAYED</source>
|
||||
<translation>Abgespielt am</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DATE_ADDED</source>
|
||||
<translation>Hinzugefügt am</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>CRITIC_RATING</source>
|
||||
<translation>Kritikerbewertung</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>IMDB_RATING</source>
|
||||
<translation>IMDb Bewertung</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 von Kanaldaten</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Loading Channel Data</source>
|
||||
<translation>Lade Kanaldaten</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>An error was encountered while playing this item.</source>
|
||||
<translation>Ein Fehler ist aufgetreten beim Wiedergeben des Elementes.</translation>
|
||||
<extracomment>Dialog detail when error occurs during playback</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>There was an error retrieving the data for this item from the server.</source>
|
||||
<translation>Beim Abrufen der Daten ist ein Fehler aufgetreten.</translation>
|
||||
<extracomment>Dialog detail when unable to load Content from Server</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>On Now</source>
|
||||
<translation>Läuft gerade</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save Credentials?</source>
|
||||
<translation>Anmeldedaten speichern?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sign Out</source>
|
||||
<translation>Abmelden</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Change Server</source>
|
||||
<translation>Server wechseln</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
|
|
@ -113,8 +113,12 @@
|
|||
<translation>Home</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a value...</source>
|
||||
<translation>Enter a value…</translation>
|
||||
<source>Enter a username</source>
|
||||
<translation>Enter a username</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a password</source>
|
||||
<translation>Enter a password</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Name</source>
|
||||
|
@ -374,7 +378,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Pick a Jellyfin server from the local network</source>
|
||||
<translation>Pick a Jellyfin server from the local network</translation>
|
||||
<translation>Select an available Jellyfin server from your local network:</translation>
|
||||
<extracomment>Instructions on initial app launch when the user is asked to pick a server from a list</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
|
@ -384,7 +388,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>...or enter server URL manually:</source>
|
||||
<translation>…or enter server URL manually:</translation>
|
||||
<translation>If no server is listed above, you may also enter the server URL manually:</translation>
|
||||
<extracomment>Instructions on initial app launch when the user is asked to manually enter a server URL</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
|
@ -844,5 +848,379 @@
|
|||
<source>Save Credentials?</source>
|
||||
<translation>Save Credentials?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set the maximum amount of days a show should stay in the 'Next Up' list without watching it.</source>
|
||||
<translation>Set the maximum amount of days a show should stay in the 'Next Up' list without watching it.</translation>
|
||||
<extracomment>Settings Menu - Description for option</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Max Days Next Up</source>
|
||||
<translation>Max Days Next Up</translation>
|
||||
<extracomment>Option Title in user setting screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Options for Home Page.</source>
|
||||
<translation>Options for Home Page.</translation>
|
||||
<extracomment>Description for Home Page user settings.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Home Page</source>
|
||||
<translation>Home Page</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Settings relating to how the application looks.</source>
|
||||
<translation>Settings relating to how the application looks.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Settings relating to playback and supported codec and media types.</source>
|
||||
<translation>Settings relating to playback and supported codec and media types.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Play Trailer</source>
|
||||
<translation>Play Trailer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Skip Intro</source>
|
||||
<translation>Skip Intro</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Hides all clocks in Jellyfin. Jellyfin will need to be closed and reopened for change to take effect.</source>
|
||||
<translation>Hides all clocks in Jellyfin. Jellyfin will need to be closed and reopened for change to take effect.</translation>
|
||||
<extracomment>Settings Menu - Description for option</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Hide Clock</source>
|
||||
<translation>Hide Clock</translation>
|
||||
<extracomment>Option Title in user setting screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cinema Mode brings the theater experience straight to your living room with the ability to play custom intros before the main feature.</source>
|
||||
<translation>Cinema Mode brings the theatre experience straight to your living room with the ability to play custom intros before the main feature.</translation>
|
||||
<extracomment>Settings Menu - Description for option</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cinema Mode</source>
|
||||
<translation>Cinema Mode</translation>
|
||||
<extracomment>Settings Menu - Title for option</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use generated splashscreen image as Jellyfin's home background. Jellyfin will need to be closed and reopened for change to take effect.</source>
|
||||
<translation>Use generated splashscreen image as Jellyfin's home background. Jellyfin will need to be closed and reopened for change to take effect.</translation>
|
||||
<extracomment>Description for option in Setting Screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use Splashscreen as Home Background</source>
|
||||
<translation>Use Splashscreen as Home Background</translation>
|
||||
<extracomment>Option Title in user setting screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Options that alter the design of Jellyfin.</source>
|
||||
<translation>Options that alter the design of Jellyfin.</translation>
|
||||
<extracomment>Description for Design Elements user settings.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Design Elements</source>
|
||||
<translation>Design Elements</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use generated splashscreen image as Jellyfin's screensaver background. Jellyfin will need to be closed and reopened for change to take effect.</source>
|
||||
<translation>Use generated splashscreen image as Jellyfin's screensaver background. Jellyfin will need to be closed and reopened for change to take effect.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use Splashscreen as Screensaver Background</source>
|
||||
<translation>Use Splashscreen as Screensaver Background</translation>
|
||||
<extracomment>Option Title in user setting screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Options for Jellyfin's screensaver.</source>
|
||||
<translation>Options for Jellyfin's screensaver.</translation>
|
||||
<extracomment>Description for Screensaver user settings.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Screensaver</source>
|
||||
<translation>Screensaver</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>If enabled, images of unwatched episodes will be blurred.</source>
|
||||
<translation>If enabled, images of unwatched episodes will be blurred.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Blur Unwatched Episodes</source>
|
||||
<translation>Blur Unwatched Episodes</translation>
|
||||
<extracomment>Option Title in user setting screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Options for TV Shows.</source>
|
||||
<translation>Options for TV Shows.</translation>
|
||||
<extracomment>Description for TV Shows user settings.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Hides tagline text on details pages.</source>
|
||||
<translation>Hides tagline text on details pages.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Hide Taglines</source>
|
||||
<translation>Hide Taglines</translation>
|
||||
<extracomment>Option Title in user setting screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Options for Details pages.</source>
|
||||
<translation>Options for Details pages.</translation>
|
||||
<extracomment>Description for Details page user settings.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Details Page</source>
|
||||
<translation>Details Page</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use the replay button to slowly animate to the first item in the folder. (If disabled, the folder will reset to the first item immediately).</source>
|
||||
<translation>Use the replay button to slowly animate to the first item in the folder. (If disabled, the folder will reset to the first item immediately).</translation>
|
||||
<extracomment>Description for option in Setting Screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Return to Top</source>
|
||||
<translation>Return to Top</translation>
|
||||
<extracomment>UI -> Media Grid -> Item Title in user setting screen.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Shows</source>
|
||||
<translation>Shows</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Studios</source>
|
||||
<translation>Studios</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Networks</source>
|
||||
<translation>Networks</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>There was an error authenticating via Quick Connect.</source>
|
||||
<translation>There was an error authenticating via Quick Connect.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>(Dialog will close automatically)</source>
|
||||
<translation>(Dialog will close automatically)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Here is your Quick Connect code:</source>
|
||||
<translation>Here is your Quick Connect code:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Quick Connect</source>
|
||||
<translation>Quick Connect</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%1 of %2</source>
|
||||
<translation>%1 of %2</translation>
|
||||
<extracomment>Item position and count. %1 = current item. %2 = total number of items</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>You can search for Titles, People, Live TV Channels and more</source>
|
||||
<translation>You can search for Titles, People, Live TV Channels and more</translation>
|
||||
<extracomment>Help text in search results</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search now</source>
|
||||
<translation>Search now</translation>
|
||||
<extracomment>Help text in search Box</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use voice remote to search</source>
|
||||
<translation>Use voice remote to search</translation>
|
||||
<extracomment>Help text in search voice text box</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Go to episode</source>
|
||||
<translation>Go to episode</translation>
|
||||
<extracomment>Continue Watching Popup Menu - Navigate to the Episode Detail Page</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Go to season</source>
|
||||
<translation>Go to season</translation>
|
||||
<extracomment>Continue Watching Popup Menu - Navigate to the Season Page</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Go to series</source>
|
||||
<translation>Go to series</translation>
|
||||
<extracomment>Continue Watching Popup Menu - Navigate to the Series Detail Page</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set Watched</source>
|
||||
<translation>Set Watched</translation>
|
||||
<extracomment>Button Text - When pressed, marks item as Warched</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set Favorite</source>
|
||||
<translation>Set Favourite</translation>
|
||||
<extracomment>Button Text - When pressed, sets item as Favorite</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show item count in the library and index of selected item.</source>
|
||||
<translation>Show item count in the library and index of selected item.</translation>
|
||||
<extracomment>Description for option in Setting Screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Item Count</source>
|
||||
<translation>Item Count</translation>
|
||||
<extracomment>UI -> Media Grid -> Item Count in user setting screen.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Always show the titles below the poster images. (If disabled, the title will be shown under the highlighted item only).</source>
|
||||
<translation>Always show the titles below the poster images. (If disabled, the title will be shown under the highlighted item only).</translation>
|
||||
<extracomment>Description for option in Setting Screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Item Titles</source>
|
||||
<translation>Item Titles</translation>
|
||||
<extracomment>UI -> Media Grid -> Item Title in user setting screen.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Media Grid options.</source>
|
||||
<translation>Media Grid options.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Media Grid</source>
|
||||
<translation>Media Grid</translation>
|
||||
<extracomment>UI -> Media Grid section in user setting screen.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>User Interface</source>
|
||||
<translation>User Interface</translation>
|
||||
<extracomment>Title for User Interface section in user setting screen.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Disabled</source>
|
||||
<translation>Disabled</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enabled</source>
|
||||
<translation>Enabled</translation>
|
||||
</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>Support Direct Play of MPEG-2 content (e.g., Live TV). This will prevent transcoding of MPEG-2 content, but uses significantly more bandwidth.</translation>
|
||||
<extracomment>Settings Menu - Description for option</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>MPEG-2 Support</source>
|
||||
<translation>MPEG-2 Support</translation>
|
||||
<extracomment>Settings Menu - Title for option</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Playback</source>
|
||||
<translation>Playback</translation>
|
||||
<extracomment>Title for Playback section in user setting screen.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Version</source>
|
||||
<translation>Version</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>An error was encountered while playing this item. Server did not provide required transcoding data.</source>
|
||||
<translation>An error was encountered while playing this item. Server did not provide required transcoding data.</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>Error Getting Playback Information</source>
|
||||
<translation>Error Getting Playback Information</translation>
|
||||
<extracomment>Dialog Title: Received error from server when trying to get information about the selected item for playback</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>...or enter server URL manually:</source>
|
||||
<translation>If no server is listed above, you may also enter the server URL manually:</translation>
|
||||
<extracomment>Instructions on initial app launch when the user is asked to manually enter a server URL</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Pick a Jellyfin server from the local network</source>
|
||||
<translation>Select an available Jellyfin server from your local network:</translation>
|
||||
<extracomment>Instructions on initial app launch when the user is asked to pick a server from a list</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter the server name or ip address</source>
|
||||
<translation>Enter the server name or ip address</translation>
|
||||
<extracomment>Title of KeyboardDialog when manually entering a server URL</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unknown</source>
|
||||
<translation>Unknown</translation>
|
||||
<extracomment>Title for a cast member for which we have no information for</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Close</source>
|
||||
<translation>Close</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cancel Series Recording</source>
|
||||
<translation>Cancel Series Recording</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cancel Recording</source>
|
||||
<translation>Cancel Recording</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Record Series</source>
|
||||
<translation>Record Series</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Record</source>
|
||||
<translation>Record</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>View Channel</source>
|
||||
<translation>View Channel</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>TV Shows</source>
|
||||
<translation>TV Shows</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Movies</source>
|
||||
<translation>Movies</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Special Features</source>
|
||||
<translation>Special Features</translation>
|
||||
<message>
|
||||
<source>Press 'OK' to Close</source>
|
||||
<translation>Press 'OK' to Close</translation>
|
||||
</message>
|
||||
</message>
|
||||
<message>
|
||||
<source>More Like This</source>
|
||||
<translation>More Like This</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cast & Crew</source>
|
||||
<translation>Cast & Crew</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Age</source>
|
||||
<translation>Age</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Died</source>
|
||||
<translation>Died</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Born</source>
|
||||
<translation>Born</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a value...</source>
|
||||
<translation>Enter a value...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>On Now</source>
|
||||
<translation>On Now</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete Saved</source>
|
||||
<translation>Delete Saved</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save Credentials?</source>
|
||||
<translation>Save Credentials?</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
|
|
@ -125,8 +125,12 @@
|
|||
<translation>Home</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a value...</source>
|
||||
<translation>Enter a value…</translation>
|
||||
<source>Enter a username</source>
|
||||
<translation>Enter a username</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a password</source>
|
||||
<translation>Enter a password</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Name</source>
|
||||
|
@ -448,12 +452,12 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Pick a Jellyfin server from the local network</source>
|
||||
<translation>Pick a Jellyfin server from the local network</translation>
|
||||
<translation>Select an available Jellyfin server from your local network:</translation>
|
||||
<extracomment>Instructions on initial app launch when the user is asked to pick a server from a list</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>...or enter server URL manually:</source>
|
||||
<translation>…or enter server URL manually:</translation>
|
||||
<translation>If no server is listed above, you may also enter the server URL manually:</translation>
|
||||
<extracomment>Instructions on initial app launch when the user is asked to manually enter a server URL</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
|
@ -476,13 +480,13 @@
|
|||
<extracomment>Title for Playback section in user setting screen.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>MPEG 2 Support</source>
|
||||
<translation>MPEG 2 Support</translation>
|
||||
<source>MPEG-2 Support</source>
|
||||
<translation>MPEG-2 Support</translation>
|
||||
<extracomment>Settings Menu - Title for option</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>Support direct play of MPEG 2 content (e.g. Live TV). This will prevent transcoding of MPEG 2 content, but uses significantly more bandwidth</translation>
|
||||
<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>Support Direct Play of MPEG-2 content (e.g., Live TV). This will prevent transcoding of MPEG-2 content, but uses significantly more bandwidth.</translation>
|
||||
<extracomment>Settings Menu - Description for option</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
|
@ -504,8 +508,8 @@
|
|||
<extracomment>UI -> Media Grid section in user setting screen.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Media Grid Options</source>
|
||||
<translation>Media Grid Options</translation>
|
||||
<source>Media Grid options.</source>
|
||||
<translation>Media Grid options.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Item Titles</source>
|
||||
|
@ -513,8 +517,8 @@
|
|||
<extracomment>UI -> Media Grid -> Item Title in user setting screen.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Always show the titles below the poster images. (If disabled, title will be shown under hilighted item only)</source>
|
||||
<translation>Always show the titles below the poster images. (If disabled, title will be shown under hilighted item only)</translation>
|
||||
<source>Always show the titles below the poster images. (If disabled, the title will be shown under the highlighted item only).</source>
|
||||
<translation>Always show the titles below the poster images. (If disabled, the title will be shown under the highlighted item only).</translation>
|
||||
<extracomment>Description for option in Setting Screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
|
@ -523,8 +527,8 @@
|
|||
<extracomment>UI -> Media Grid -> Item Count in user setting screen.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show item count in the library, and index of selected item.</source>
|
||||
<translation>Show item count in the library, and index of selected item.</translation>
|
||||
<source>Show item count in the library and index of selected item.</source>
|
||||
<translation>Show item count in the library and index of selected item.</translation>
|
||||
<extracomment>Description for option in Setting Screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
|
@ -552,6 +556,21 @@
|
|||
<translation>Go to episode</translation>
|
||||
<extracomment>Continue Watching Popup Menu - Navigate to the Episode Detail Page</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use voice remote to search</source>
|
||||
<translation>Use voice remote to search</translation>
|
||||
<extracomment>Help text in search voice text box</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search now</source>
|
||||
<translation>Search now</translation>
|
||||
<extracomment>Help text in search Box</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>You can search for Titles, People, Live TV Channels and more</source>
|
||||
<translation>You can search for Titles, People, Live TV Channels and more</translation>
|
||||
<extracomment>Help text in search results</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>%1 of %2</source>
|
||||
<translation>%1 of %2</translation>
|
||||
|
@ -591,18 +610,18 @@
|
|||
<extracomment>UI -> Media Grid -> Item Title in user setting screen.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use the replay button to slowly animate to the first item in the folder. (If disabled, The folder will reset to the first item immediately)</source>
|
||||
<translation>Use the replay button to slowly animate to the first item in the folder. (If disabled, The folder will reset to the first item immediately)</translation>
|
||||
<source>Use the replay button to slowly animate to the first item in the folder. (If disabled, the folder will reset to the first item immediately).</source>
|
||||
<translation>Use the replay button to slowly animate to the first item in the folder. (If disabled, the folder will reset to the first item immediately).</translation>
|
||||
<extracomment>Description for option in Setting Screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Detail Page</source>
|
||||
<translation>Detail Page</translation>
|
||||
<source>Details Page</source>
|
||||
<translation>Details Page</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Options for details pages.</source>
|
||||
<translation>Options for details pages.</translation>
|
||||
<extracomment>Description for Detail Page user settings.</extracomment>
|
||||
<source>Options for Details pages.</source>
|
||||
<translation>Options for Details pages.</translation>
|
||||
<extracomment>Description for Details page user settings.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Hide Taglines</source>
|
||||
|
@ -624,8 +643,8 @@
|
|||
<extracomment>Option Title in user setting screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>If enabled, images for unwatched episodes will be blurred.</source>
|
||||
<translation>If enabled, images for unwatched episodes will be blurred.</translation>
|
||||
<source>If enabled, images of unwatched episodes will be blurred.</source>
|
||||
<translation>If enabled, images of unwatched episodes will be blurred.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Screensaver</source>
|
||||
|
@ -642,8 +661,8 @@
|
|||
<extracomment>Option Title in user setting screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use generated splashscreen image as Jellyfin's screensaver background.</source>
|
||||
<translation>Use generated splashscreen image as Jellyfin's screensaver background.</translation>
|
||||
<source>Use generated splashscreen image as Jellyfin's screensaver background. Jellyfin will need to be closed and reopened for change to take effect.</source>
|
||||
<translation>Use generated splashscreen image as Jellyfin's screensaver background. Jellyfin will need to be closed and reopened for change to take effect.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Design Elements</source>
|
||||
|
@ -660,18 +679,18 @@
|
|||
<extracomment>Option Title in user setting screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use generated splashscreen image as Jellyfin home background. Jellyfin will need to be closed and reopened for change to take effect.</source>
|
||||
<translation>Use generated splashscreen image as Jellyfin home background. Jellyfin will need to be closed and reopened for change to take effect.</translation>
|
||||
<source>Use generated splashscreen image as Jellyfin's home background. Jellyfin will need to be closed and reopened for change to take effect.</source>
|
||||
<translation>Use generated splashscreen image as Jellyfin's home background. Jellyfin will need to be closed and reopened for change to take effect.</translation>
|
||||
<extracomment>Description for option in Setting Screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cinema mode</source>
|
||||
<translation>Cinema mode</translation>
|
||||
<source>Cinema Mode</source>
|
||||
<translation>Cinema Mode</translation>
|
||||
<extracomment>Settings Menu - Title for option</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cinema mode brings the theater experience straight to your living room with the ability to play custom intros before the main feature.</source>
|
||||
<translation>Cinema mode brings the theater experience straight to your living room with the ability to play custom intros before the main feature.</translation>
|
||||
<source>Cinema Mode brings the theater experience straight to your living room with the ability to play custom intros before the main feature.</source>
|
||||
<translation>Cinema Mode brings the theater experience straight to your living room with the ability to play custom intros before the main feature.</translation>
|
||||
<extracomment>Settings Menu - Description for option</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
|
@ -684,10 +703,6 @@
|
|||
<translation>Hides all clocks in Jellyfin. Jellyfin will need to be closed and reopened for change to take effect.</translation>
|
||||
<extracomment>Settings Menu - Description for option</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Skip Intro</source>
|
||||
<translation>Skip Intro</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Play Trailer</source>
|
||||
<translation>Play Trailer</translation>
|
||||
|
@ -712,5 +727,109 @@
|
|||
<translation>Attempt Direct Play for HEVC media with unsupported profile levels (> 5.1) before falling back to trancoding if it fails.</translation>
|
||||
<extracomment>Settings Menu - Description for option</extracomment>
|
||||
</message>
|
||||
<source>Settings relating to playback and supported codec and media types.</source>
|
||||
<translation>Settings relating to playback and supported codec and media types.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Settings relating to how the application looks.</source>
|
||||
<translation>Settings relating to how the application looks.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Home Page</source>
|
||||
<translation>Home Page</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Options for Home Page.</source>
|
||||
<translation>Options for Home Page.</translation>
|
||||
<extracomment>Description for Home Page user settings.</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Max Days Next Up</source>
|
||||
<translation>Max Days Next Up</translation>
|
||||
<extracomment>Option Title in user setting screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set the maximum amount of days a show should stay in the 'Next Up' list without watching it.</source>
|
||||
<translation>Set the maximum amount of days a show should stay in the 'Next Up' list without watching it.</translation>
|
||||
<extracomment>Settings Menu - Description for option</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Playback Information</source>
|
||||
<translation>Playback Information</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Transcoding Information</source>
|
||||
<translation>Transcoding Information</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Reason</source>
|
||||
<translation>Reason</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Video Codec</source>
|
||||
<translation>Video Codec</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Audio Codec</source>
|
||||
<translation>Audio Codec</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>direct</source>
|
||||
<translation>direct</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Total Bitrate</source>
|
||||
<translation>Total Bitrate</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Audio Channels</source>
|
||||
<translation>Audio Channels</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Stream Information</source>
|
||||
<translation>Stream Information</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Codec</source>
|
||||
<translation>Codec</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Codec Tag</source>
|
||||
<translation>Codec Tag</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Level</source>
|
||||
<translation>Level</translation>
|
||||
<extracomment>Video profile level</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bit Rate</source>
|
||||
<translation>Bit Rate</translation>
|
||||
<extracomment>Video streaming bit rate</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Container</source>
|
||||
<translation>Container</translation>
|
||||
<extracomment>Video streaming container</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Size</source>
|
||||
<translation>Size</translation>
|
||||
<extracomment>Video size</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Video range type</source>
|
||||
<translation>Video range type</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Pixel format</source>
|
||||
<translation>Pixel format</translation>
|
||||
<extracomment>Video pixel format</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>WxH</source>
|
||||
<translation>WxH</translation>
|
||||
<extracomment>Video width x height</extracomment>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
|
|
@ -112,9 +112,17 @@
|
|||
<source>Home</source>
|
||||
<translation>Inicio</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a username</source>
|
||||
<translation>Ingresar nombre de usuario</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a password</source>
|
||||
<translation>Ingresar la contraseña</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a value...</source>
|
||||
<translation>Ingresar un valor…</translation>
|
||||
<translation>Ingresar un valor...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sort Field</source>
|
||||
|
|
|
@ -112,9 +112,17 @@
|
|||
<source>Home</source>
|
||||
<translation>Inicio</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a username</source>
|
||||
<translation>Ingres nombre de usuario</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a password</source>
|
||||
<translation>Ingres la contraseña</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a value...</source>
|
||||
<translation>Ingrese un valor…</translation>
|
||||
<translation>Ingres un valor...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sort Field</source>
|
||||
|
|
|
@ -113,8 +113,12 @@
|
|||
<translation>Inicio</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a value...</source>
|
||||
<translation>Enter a value...</translation>
|
||||
<source>Enter a username</source>
|
||||
<translation>Ingres nombre de usuario</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a password</source>
|
||||
<translation>Ingres la contraseña</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sort Field</source>
|
||||
|
@ -168,9 +172,17 @@
|
|||
<source>Audio</source>
|
||||
<translation>Audio</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a username</source>
|
||||
<translation>Ingresar nombre de usuario</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a password</source>
|
||||
<translation>Ingresar la contraseña</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a value...</source>
|
||||
<translation>Introduce un valor…</translation>
|
||||
<translation>Ingresar un valor...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sort Field</source>
|
||||
|
@ -1867,5 +1879,10 @@
|
|||
<source>Change Server</source>
|
||||
<translation>Cambiar de Servidor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<comment>Name or Title field of media item</comment>
|
||||
<source>TITLE</source>
|
||||
<translation>Nombre</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
|
|
@ -111,6 +111,14 @@
|
|||
<message>
|
||||
<source>Home</source>
|
||||
<translation>Accueil</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a username</source>
|
||||
<translation>Entrez votre nom d'utilisateur</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a password</source>
|
||||
<translation>Entrer le mot de passe</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a value...</source>
|
||||
|
@ -2700,5 +2708,22 @@
|
|||
<source>Save Credentials?</source>
|
||||
<translation>Enregistrer les identifiants ?</translation>
|
||||
</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>On Now</source>
|
||||
<translation>Maintenant</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete Saved</source>
|
||||
<translation>Supprimer les informations enregistrées</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save Credentials?</source>
|
||||
<translation>Enregistrer les identifiants ?</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
|
|
@ -112,6 +112,14 @@
|
|||
<source>Home</source>
|
||||
<translation>Accueil</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a username</source>
|
||||
<translation>Entrez votre nom d'utilisateur</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a password</source>
|
||||
<translation>Entrer le mot de passe</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a value...</source>
|
||||
<translation>Entrez une valeur…</translation>
|
||||
|
|
|
@ -112,6 +112,14 @@
|
|||
<source>Home</source>
|
||||
<translation>Kezdőlap</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a username</source>
|
||||
<translation>Adjon meg egy felhasználónevet</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a password</source>
|
||||
<translation>Írja be a jelszót</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a value...</source>
|
||||
<translation>Adj meg egy értéket…</translation>
|
||||
|
@ -6325,5 +6333,13 @@ elemeket</translation>
|
|||
<source>Save Credentials?</source>
|
||||
<translation>Mented a hitelesítő adatokat?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Delete Saved</source>
|
||||
<translation>Mentettek Törlése</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save Credentials?</source>
|
||||
<translation>Mented a hitelesítő adatokat?</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
|
|
@ -112,6 +112,14 @@
|
|||
<source>Home</source>
|
||||
<translation>Home</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a username</source>
|
||||
<translation>Inserisci il tuo cognome</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a password</source>
|
||||
<translation>Inserisci la password</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a value...</source>
|
||||
<translation>Inserire un valore…</translation>
|
||||
|
|
|
@ -112,6 +112,14 @@
|
|||
<source>Home</source>
|
||||
<translation>Mājas</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a username</source>
|
||||
<translation>Ievadiet lietotājvārdu</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a password</source>
|
||||
<translation>Ievadiet paroli</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a value...</source>
|
||||
<translation>Ievadi vērtību…</translation>
|
||||
|
|
|
@ -112,6 +112,14 @@
|
|||
<source>Home</source>
|
||||
<translation>Início</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a username</source>
|
||||
<translation>Insira nome de usuário</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a password</source>
|
||||
<translation>Insira um senha</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a value...</source>
|
||||
<translation>Insira um valor…</translation>
|
||||
|
|
|
@ -112,6 +112,14 @@
|
|||
<source>Home</source>
|
||||
<translation>Acasă</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a username</source>
|
||||
<translation>Introduceți un nume de utilizator</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a password</source>
|
||||
<translation>Introduceți o parolă</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a value...</source>
|
||||
<translation>Introduceți o valoare…</translation>
|
||||
|
|
|
@ -112,6 +112,14 @@
|
|||
<source>Home</source>
|
||||
<translation>Domov</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a username</source>
|
||||
<translation>Zadajte používateľské meno</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a password</source>
|
||||
<translation>Zadajte heslo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a value...</source>
|
||||
<translation>Zadajte hodnotu…</translation>
|
||||
|
|
|
@ -112,6 +112,14 @@
|
|||
<source>Home</source>
|
||||
<translation>Domov</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a username</source>
|
||||
<translation>Vnesite svoje uporabniško ime</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a password</source>
|
||||
<translation>Vnesite geslo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a value...</source>
|
||||
<translation>Vnesite vrednost…</translation>
|
||||
|
|
|
@ -112,9 +112,17 @@
|
|||
<source>Home</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a username</source>
|
||||
<translation>Faka igama lomsebenzisi</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a password</source>
|
||||
<translation>Faka iphasiwedi</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter a value...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Faka inani...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Sort Field</source>
|
||||
|
|
511
package-lock.json
generated
511
package-lock.json
generated
|
@ -7,18 +7,20 @@
|
|||
"": {
|
||||
"name": "jellyfin-roku",
|
||||
"version": "1.4.12",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-2.0",
|
||||
"dependencies": {
|
||||
"api": "npm:jellyfin-api-bs-client@^1.0.5",
|
||||
"bgv": "npm:button-group-vert@^1.0.1",
|
||||
"brighterscript-formatter": "^1.6.8",
|
||||
"intKeyboard": "npm:integer-keyboard@^1.0.12",
|
||||
"sob": "npm:slide-out-button@^1.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rokucommunity/bslint": "0.7.5",
|
||||
"brighterscript": "0.57.0",
|
||||
"brighterscript": "0.57.2",
|
||||
"rooibos-cli": "1.4.0",
|
||||
"ropm": "0.10.9"
|
||||
"ropm": "0.10.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@nodelib/fs.scandir": {
|
||||
|
@ -827,9 +829,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/brighterscript": {
|
||||
"version": "0.57.0",
|
||||
"resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-0.57.0.tgz",
|
||||
"integrity": "sha512-lv7/qIBLrF62fnukTQUR7OZlzKugMSDkSpdtMTZKElTCY/CqU3Kueprg+fKC4zuQeFdZlKnVrD5fpSYZiOhe2A==",
|
||||
"version": "0.57.2",
|
||||
"resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-0.57.2.tgz",
|
||||
"integrity": "sha512-idvz7lVLSN1mM/VoDt4/uJPFqdydSgCro2eIwT9vqV8z/1iNLpUtvXCWfeAbWxsbJkXWtmQq4GPkklCxc4OjrQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@rokucommunity/bslib": "^0.1.1",
|
||||
|
@ -3767,6 +3769,12 @@
|
|||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"node_modules/intKeyboard": {
|
||||
"name": "integer-keyboard",
|
||||
"version": "1.0.12",
|
||||
"resolved": "https://registry.npmjs.org/integer-keyboard/-/integer-keyboard-1.0.12.tgz",
|
||||
"integrity": "sha512-DSLyd/PvtEBfc4grICTxSLu94Yo/Vm6rNerRZRbbzRrP0HQ9pYaquoY2RD9x6gAmica43gsFimScNpuRYVe54w=="
|
||||
},
|
||||
"node_modules/invariant": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
|
@ -5228,14 +5236,14 @@
|
|||
}
|
||||
},
|
||||
"node_modules/ropm": {
|
||||
"version": "0.10.9",
|
||||
"resolved": "https://registry.npmjs.org/ropm/-/ropm-0.10.9.tgz",
|
||||
"integrity": "sha512-HuYCFi90rCsiBYe8+0I6ym2QGeWbmfZkSv3ubL/eAmZQoJl0ebGXcjg6P44IeOIR5tZRyJ6TDiiST+6m2GyUNg==",
|
||||
"version": "0.10.10",
|
||||
"resolved": "https://registry.npmjs.org/ropm/-/ropm-0.10.10.tgz",
|
||||
"integrity": "sha512-tkPuDwP/Mva9IXIuTf4pnH1DC27WLeLfu8QJ70WwaX9tepNMZeDi4eEQdWQ7kalXxxlwXGnG4jUaaA1B4v8zWw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@xml-tools/ast": "^5.0.5",
|
||||
"@xml-tools/parser": "1.0.10",
|
||||
"brighterscript": "^0.57.0",
|
||||
"brighterscript": "^0.57.2",
|
||||
"del": "6.0.0",
|
||||
"fs-extra": "9.1.0",
|
||||
"glob-all": "3.2.1",
|
||||
|
@ -5261,121 +5269,6 @@
|
|||
"chevrotain": "7.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-convert": "^1.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/anymatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
|
||||
"integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"normalize-path": "^3.0.0",
|
||||
"picomatch": "^2.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/binary-extensions": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
|
||||
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fill-range": "^7.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/brighterscript": {
|
||||
"version": "0.57.0",
|
||||
"resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-0.57.0.tgz",
|
||||
"integrity": "sha512-lv7/qIBLrF62fnukTQUR7OZlzKugMSDkSpdtMTZKElTCY/CqU3Kueprg+fKC4zuQeFdZlKnVrD5fpSYZiOhe2A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@rokucommunity/bslib": "^0.1.1",
|
||||
"@xml-tools/parser": "^1.0.7",
|
||||
"array-flat-polyfill": "^1.0.1",
|
||||
"chalk": "^2.4.2",
|
||||
"chevrotain": "^7.0.1",
|
||||
"chokidar": "^3.5.1",
|
||||
"clear": "^0.1.0",
|
||||
"cross-platform-clear-console": "^2.3.0",
|
||||
"debounce-promise": "^3.1.0",
|
||||
"eventemitter3": "^4.0.0",
|
||||
"fast-glob": "^3.2.11",
|
||||
"file-url": "^3.0.0",
|
||||
"fs-extra": "^8.0.0",
|
||||
"jsonc-parser": "^2.3.0",
|
||||
"long": "^3.2.0",
|
||||
"luxon": "^1.8.3",
|
||||
"minimatch": "^3.0.4",
|
||||
"moment": "^2.23.0",
|
||||
"p-settle": "^2.1.0",
|
||||
"parse-ms": "^2.1.0",
|
||||
"require-relative": "^0.8.7",
|
||||
"roku-deploy": "^3.8.1",
|
||||
"serialize-error": "^7.0.1",
|
||||
"source-map": "^0.7.3",
|
||||
"vscode-languageserver": "7.0.0",
|
||||
"vscode-languageserver-protocol": "3.16.0",
|
||||
"vscode-languageserver-textdocument": "^1.0.1",
|
||||
"vscode-uri": "^2.1.1",
|
||||
"xml2js": "^0.4.19",
|
||||
"yargs": "^16.2.0"
|
||||
},
|
||||
"bin": {
|
||||
"bsc": "dist/cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/brighterscript/node_modules/fs-extra": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
|
||||
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^4.0.0",
|
||||
"universalify": "^0.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6 <7 || >=8"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/chevrotain": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-7.1.1.tgz",
|
||||
|
@ -5385,45 +5278,6 @@
|
|||
"regexp-to-ast": "0.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/chokidar": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
|
||||
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"anymatch": "~3.1.2",
|
||||
"braces": "~3.0.2",
|
||||
"glob-parent": "~5.1.2",
|
||||
"is-binary-path": "~2.1.0",
|
||||
"is-glob": "~4.0.1",
|
||||
"normalize-path": "~3.0.0",
|
||||
"readdirp": "~3.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.10.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/fs-extra": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
|
||||
|
@ -5439,7 +5293,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==",
|
||||
|
@ -5451,7 +5305,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==",
|
||||
|
@ -5460,102 +5314,6 @@
|
|||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/glob-parent": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/is-binary-path": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
||||
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"binary-extensions": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/is-extglob": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/is-glob": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-extglob": "^2.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/is-number": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/normalize-path": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/source-map": {
|
||||
"version": "0.7.4",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
|
||||
"integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"has-flag": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-number": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ropm/node_modules/yargs": {
|
||||
"version": "16.2.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
|
||||
|
@ -7208,9 +6966,9 @@
|
|||
}
|
||||
},
|
||||
"brighterscript": {
|
||||
"version": "0.57.0",
|
||||
"resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-0.57.0.tgz",
|
||||
"integrity": "sha512-lv7/qIBLrF62fnukTQUR7OZlzKugMSDkSpdtMTZKElTCY/CqU3Kueprg+fKC4zuQeFdZlKnVrD5fpSYZiOhe2A==",
|
||||
"version": "0.57.2",
|
||||
"resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-0.57.2.tgz",
|
||||
"integrity": "sha512-idvz7lVLSN1mM/VoDt4/uJPFqdydSgCro2eIwT9vqV8z/1iNLpUtvXCWfeAbWxsbJkXWtmQq4GPkklCxc4OjrQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@rokucommunity/bslib": "^0.1.1",
|
||||
|
@ -9535,6 +9293,11 @@
|
|||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"intKeyboard": {
|
||||
"version": "npm:integer-keyboard@1.0.12",
|
||||
"resolved": "https://registry.npmjs.org/integer-keyboard/-/integer-keyboard-1.0.12.tgz",
|
||||
"integrity": "sha512-DSLyd/PvtEBfc4grICTxSLu94Yo/Vm6rNerRZRbbzRrP0HQ9pYaquoY2RD9x6gAmica43gsFimScNpuRYVe54w=="
|
||||
},
|
||||
"invariant": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||
|
@ -10665,14 +10428,14 @@
|
|||
}
|
||||
},
|
||||
"ropm": {
|
||||
"version": "0.10.9",
|
||||
"resolved": "https://registry.npmjs.org/ropm/-/ropm-0.10.9.tgz",
|
||||
"integrity": "sha512-HuYCFi90rCsiBYe8+0I6ym2QGeWbmfZkSv3ubL/eAmZQoJl0ebGXcjg6P44IeOIR5tZRyJ6TDiiST+6m2GyUNg==",
|
||||
"version": "0.10.10",
|
||||
"resolved": "https://registry.npmjs.org/ropm/-/ropm-0.10.10.tgz",
|
||||
"integrity": "sha512-tkPuDwP/Mva9IXIuTf4pnH1DC27WLeLfu8QJ70WwaX9tepNMZeDi4eEQdWQ7kalXxxlwXGnG4jUaaA1B4v8zWw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@xml-tools/ast": "^5.0.5",
|
||||
"@xml-tools/parser": "1.0.10",
|
||||
"brighterscript": "^0.57.0",
|
||||
"brighterscript": "^0.57.2",
|
||||
"del": "6.0.0",
|
||||
"fs-extra": "9.1.0",
|
||||
"glob-all": "3.2.1",
|
||||
|
@ -10692,102 +10455,6 @@
|
|||
"chevrotain": "7.1.1"
|
||||
}
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-convert": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"anymatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
|
||||
"integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"normalize-path": "^3.0.0",
|
||||
"picomatch": "^2.0.4"
|
||||
}
|
||||
},
|
||||
"binary-extensions": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
|
||||
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
|
||||
"dev": true
|
||||
},
|
||||
"braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fill-range": "^7.0.1"
|
||||
}
|
||||
},
|
||||
"brighterscript": {
|
||||
"version": "0.57.0",
|
||||
"resolved": "https://registry.npmjs.org/brighterscript/-/brighterscript-0.57.0.tgz",
|
||||
"integrity": "sha512-lv7/qIBLrF62fnukTQUR7OZlzKugMSDkSpdtMTZKElTCY/CqU3Kueprg+fKC4zuQeFdZlKnVrD5fpSYZiOhe2A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@rokucommunity/bslib": "^0.1.1",
|
||||
"@xml-tools/parser": "^1.0.7",
|
||||
"array-flat-polyfill": "^1.0.1",
|
||||
"chalk": "^2.4.2",
|
||||
"chevrotain": "^7.0.1",
|
||||
"chokidar": "^3.5.1",
|
||||
"clear": "^0.1.0",
|
||||
"cross-platform-clear-console": "^2.3.0",
|
||||
"debounce-promise": "^3.1.0",
|
||||
"eventemitter3": "^4.0.0",
|
||||
"fast-glob": "^3.2.11",
|
||||
"file-url": "^3.0.0",
|
||||
"fs-extra": "^8.0.0",
|
||||
"jsonc-parser": "^2.3.0",
|
||||
"long": "^3.2.0",
|
||||
"luxon": "^1.8.3",
|
||||
"minimatch": "^3.0.4",
|
||||
"moment": "^2.23.0",
|
||||
"p-settle": "^2.1.0",
|
||||
"parse-ms": "^2.1.0",
|
||||
"require-relative": "^0.8.7",
|
||||
"roku-deploy": "^3.8.1",
|
||||
"serialize-error": "^7.0.1",
|
||||
"source-map": "^0.7.3",
|
||||
"vscode-languageserver": "7.0.0",
|
||||
"vscode-languageserver-protocol": "3.16.0",
|
||||
"vscode-languageserver-textdocument": "^1.0.1",
|
||||
"vscode-uri": "^2.1.1",
|
||||
"xml2js": "^0.4.19",
|
||||
"yargs": "^16.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"fs-extra": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
|
||||
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^4.0.0",
|
||||
"universalify": "^0.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
}
|
||||
},
|
||||
"chevrotain": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-7.1.1.tgz",
|
||||
|
@ -10797,31 +10464,6 @@
|
|||
"regexp-to-ast": "0.5.0"
|
||||
}
|
||||
},
|
||||
"chokidar": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
|
||||
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"anymatch": "~3.1.2",
|
||||
"braces": "~3.0.2",
|
||||
"fsevents": "~2.3.2",
|
||||
"glob-parent": "~5.1.2",
|
||||
"is-binary-path": "~2.1.0",
|
||||
"is-glob": "~4.0.1",
|
||||
"normalize-path": "~3.0.0",
|
||||
"readdirp": "~3.6.0"
|
||||
}
|
||||
},
|
||||
"fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
|
||||
|
@ -10832,95 +10474,24 @@
|
|||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"jsonfile": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.6",
|
||||
"universalify": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"universalify": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
||||
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"glob-parent": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||
"jsonfile": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-glob": "^4.0.1"
|
||||
"graceful-fs": "^4.1.6",
|
||||
"universalify": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"is-binary-path": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
||||
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"binary-extensions": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"is-extglob": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
||||
"universalify": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
|
||||
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
|
||||
"dev": true
|
||||
},
|
||||
"is-glob": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-extglob": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"is-number": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"dev": true
|
||||
},
|
||||
"normalize-path": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||
"dev": true
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.7.4",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
|
||||
"integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
|
||||
"dev": true
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-number": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"yargs": {
|
||||
"version": "16.2.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
|
||||
|
|
10
package.json
10
package.json
|
@ -8,11 +8,12 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@rokucommunity/bslint": "0.7.5",
|
||||
"brighterscript": "0.57.0",
|
||||
"brighterscript": "0.57.2",
|
||||
"rooibos-cli": "1.4.0",
|
||||
"ropm": "0.10.9"
|
||||
"ropm": "0.10.10"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "npx ropm copy",
|
||||
"validate": "npx bsc --copy-to-staging=false --create-package=false",
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"lint": "bslint",
|
||||
|
@ -37,6 +38,7 @@
|
|||
"api": "npm:jellyfin-api-bs-client@^1.0.5",
|
||||
"bgv": "npm:button-group-vert@^1.0.1",
|
||||
"brighterscript-formatter": "^1.6.8",
|
||||
"sob": "npm:slide-out-button@^1.0.1"
|
||||
"sob": "npm:slide-out-button@^1.0.1",
|
||||
"intKeyboard": "npm:integer-keyboard@^1.0.12"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,19 @@
|
|||
"title": "User Interface",
|
||||
"description": "Settings relating to how the application looks.",
|
||||
"children": [
|
||||
{
|
||||
"title": "Home Page",
|
||||
"description": "Options for Home page.",
|
||||
"children": [
|
||||
{
|
||||
"title": "Max Days Next Up",
|
||||
"description": "Set the maximum amount of days a show should stay in the 'Next Up' list without watching it.",
|
||||
"settingName": "ui.details.maxdaysnextup",
|
||||
"type": "integer",
|
||||
"default": "365"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Details Page",
|
||||
"description": "Options for Details pages.",
|
||||
|
@ -49,8 +62,8 @@
|
|||
"default": "false"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
},
|
||||
{
|
||||
"title": "TV Shows",
|
||||
"description": "Options for TV Shows.",
|
||||
"children": [
|
||||
|
@ -62,8 +75,8 @@
|
|||
"default": "false"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
},
|
||||
{
|
||||
"title": "Screensaver",
|
||||
"description": "Options for Jellyfin's screensaver.",
|
||||
"children": [
|
||||
|
@ -75,7 +88,7 @@
|
|||
"default": "false"
|
||||
}
|
||||
]
|
||||
},
|
||||
},
|
||||
{
|
||||
"title": "Design Elements",
|
||||
"description": "Options that alter the design of Jellyfin.",
|
||||
|
@ -125,4 +138,4 @@
|
|||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
|
@ -9,7 +9,6 @@ sub Main (args as dynamic) as void
|
|||
|
||||
' Set global constants
|
||||
setConstants()
|
||||
|
||||
' Write screen tracker for screensaver
|
||||
WriteAsciiFile("tmp:/scene.temp", "")
|
||||
MoveFile("tmp:/scene.temp", "tmp:/scene")
|
||||
|
@ -250,8 +249,29 @@ sub Main (args as dynamic) as void
|
|||
' types: [ Series (Show), Episode, Movie, Audio, Person, Studio, MusicArtist ]
|
||||
if node.type = "Series"
|
||||
group = CreateSeriesDetailsGroup(node)
|
||||
else
|
||||
else if node.type = "Movie"
|
||||
group = CreateMovieDetailsGroup(node)
|
||||
else if node.type = "MusicArtist"
|
||||
group = CreateArtistView(node.json)
|
||||
else if node.type = "MusicAlbum"
|
||||
group = CreateAlbumView(node.json)
|
||||
else if node.type = "Audio"
|
||||
group = CreateAudioPlayerGroup([node.json])
|
||||
else if node.type = "Person"
|
||||
group = CreatePersonView(node)
|
||||
else if node.type = "TvChannel"
|
||||
group = CreateVideoPlayerGroup(node.id)
|
||||
sceneManager.callFunc("pushScene", group)
|
||||
else if node.type = "Episode"
|
||||
group = CreateVideoPlayerGroup(node.id)
|
||||
sceneManager.callFunc("pushScene", group)
|
||||
else if node.type = "Audio"
|
||||
selectedIndex = msg.getData()
|
||||
screenContent = msg.getRoSGNode()
|
||||
group = CreateAudioPlayerGroup([screenContent.albumData.items[node.id]])
|
||||
else
|
||||
' TODO - switch on more node types
|
||||
message_dialog("This type is not yet supported: " + node.type + ".")
|
||||
end if
|
||||
else if isNodeEvent(msg, "buttonSelected")
|
||||
' If a button is selected, we have some determining to do
|
||||
|
@ -334,8 +354,8 @@ sub Main (args as dynamic) as void
|
|||
end if
|
||||
group = CreateSearchPage()
|
||||
sceneManager.callFunc("pushScene", group)
|
||||
group.findNode("SearchBox").findNode("search-input").setFocus(true)
|
||||
group.findNode("SearchBox").findNode("search-input").active = true
|
||||
group.findNode("SearchBox").findNode("search_Key").setFocus(true)
|
||||
group.findNode("SearchBox").findNode("search_Key").active = true
|
||||
else if button.id = "change_server"
|
||||
unset_setting("server")
|
||||
unset_setting("port")
|
||||
|
@ -365,9 +385,19 @@ sub Main (args as dynamic) as void
|
|||
changeSubtitleDuringPlayback(trackSelected)
|
||||
end if
|
||||
end if
|
||||
else if isNodeEvent(msg, "selectPlaybackInfoPressed")
|
||||
node = m.scene.focusedChild
|
||||
if node.focusedChild <> invalid and node.focusedChild.isSubType("JFVideo")
|
||||
info = GetPlaybackInfo()
|
||||
show_dialog(tr("Playback Information"), info)
|
||||
end if
|
||||
else if isNodeEvent(msg, "state")
|
||||
node = msg.getRoSGNode()
|
||||
if node.state = "finished"
|
||||
if selectedItem.Type = "TvChannel" and node.state = "finished"
|
||||
video = CreateVideoPlayerGroup(node.id)
|
||||
m.global.sceneManager.callFunc("pushScene", video)
|
||||
m.global.sceneManager.callFunc("clearPreviousScene")
|
||||
else if node.state = "finished"
|
||||
node.control = "stop"
|
||||
|
||||
' If node allows retrying using Transcode Url, give that shot
|
||||
|
|
|
@ -446,12 +446,8 @@ end function
|
|||
|
||||
function CreateSearchPage()
|
||||
' Search + Results Page
|
||||
group = CreateObject("roSGNode", "SearchResults")
|
||||
|
||||
search = group.findNode("SearchBox")
|
||||
search.observeField("search_value", m.port)
|
||||
|
||||
options = group.findNode("SearchSelect")
|
||||
group = CreateObject("roSGNode", "searchResults")
|
||||
options = group.findNode("searchSelect")
|
||||
options.observeField("itemSelected", m.port)
|
||||
|
||||
return group
|
||||
|
@ -471,6 +467,7 @@ function CreateVideoPlayerGroup(video_id, mediaSourceId = invalid, audio_stream_
|
|||
if video = invalid then return invalid
|
||||
if video.errorMsg = "introaborted" then return video
|
||||
video.observeField("selectSubtitlePressed", m.port)
|
||||
video.observeField("selectPlaybackInfoPressed", m.port)
|
||||
video.observeField("state", m.port)
|
||||
|
||||
return video
|
||||
|
|
|
@ -45,11 +45,6 @@ sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -
|
|||
end if
|
||||
end if
|
||||
|
||||
if m.videotype = "Episode" or m.videotype = "Series"
|
||||
video.skipIntroParams = api_API().introskipper.get(video.id)
|
||||
video.content.contenttype = "episode"
|
||||
end if
|
||||
|
||||
video.content.title = meta.title
|
||||
video.showID = meta.showID
|
||||
|
||||
|
@ -175,18 +170,18 @@ sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -
|
|||
end if
|
||||
if meta.live then mediaSourceId = "" ' Don't send mediaSourceId for Live media
|
||||
|
||||
playbackInfo = ItemPostPlaybackInfo(video.id, mediaSourceId, audio_stream_idx, subtitle_idx, playbackPosition)
|
||||
m.playbackInfo = ItemPostPlaybackInfo(video.id, mediaSourceId, audio_stream_idx, subtitle_idx, playbackPosition)
|
||||
video.videoId = video.id
|
||||
video.mediaSourceId = mediaSourceId
|
||||
video.audioIndex = audio_stream_idx
|
||||
|
||||
if playbackInfo = invalid
|
||||
if m.playbackInfo = invalid
|
||||
video.content = invalid
|
||||
return
|
||||
end if
|
||||
|
||||
params = {}
|
||||
video.PlaySessionId = playbackInfo.PlaySessionId
|
||||
video.PlaySessionId = m.playbackInfo.PlaySessionId
|
||||
|
||||
if meta.live
|
||||
video.content.live = true
|
||||
|
@ -195,17 +190,17 @@ sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -
|
|||
|
||||
video.container = getContainerType(meta)
|
||||
|
||||
if playbackInfo.MediaSources[0] = invalid
|
||||
playbackInfo = meta.json
|
||||
if m.playbackInfo.MediaSources[0] = invalid
|
||||
m.playbackInfo = meta.json
|
||||
end if
|
||||
|
||||
subtitles = sortSubtitles(meta.id, playbackInfo.MediaSources[0].MediaStreams)
|
||||
subtitles = sortSubtitles(meta.id, m.playbackInfo.MediaSources[0].MediaStreams)
|
||||
video.Subtitles = subtitles["all"]
|
||||
|
||||
if meta.live
|
||||
video.transcodeParams = {
|
||||
"MediaSourceId": playbackInfo.MediaSources[0].Id,
|
||||
"LiveStreamId": playbackInfo.MediaSources[0].LiveStreamId,
|
||||
"MediaSourceId": m.playbackInfo.MediaSources[0].Id,
|
||||
"LiveStreamId": m.playbackInfo.MediaSources[0].LiveStreamId,
|
||||
"PlaySessionId": video.PlaySessionId
|
||||
}
|
||||
end if
|
||||
|
@ -214,7 +209,7 @@ sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -
|
|||
|
||||
' 'TODO: allow user selection of subtitle track before playback initiated, for now set to no subtitles
|
||||
|
||||
video.directPlaySupported = playbackInfo.MediaSources[0].SupportsDirectPlay
|
||||
video.directPlaySupported = m.playbackInfo.MediaSources[0].SupportsDirectPlay
|
||||
fully_external = false
|
||||
|
||||
|
||||
|
@ -223,7 +218,7 @@ sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -
|
|||
' artifacts. If the user preference is set, and the only reason the server says we need to
|
||||
' transcode is that the Encoding Level is not supported, then try to direct play but silently
|
||||
' fall back to the transcode if that fails.
|
||||
if playbackInfo.MediaSources[0].MediaStreams.Count() > 0
|
||||
if playbackInfo.MediaSources[0].MediaStreams.Count() > 0 and meta.live = false
|
||||
tryDirectPlay = get_user_setting("playback.tryDirect.h264ProfileLevel") = "true" and playbackInfo.MediaSources[0].MediaStreams[0].codec = "h264"
|
||||
tryDirectPlay = tryDirectPlay or (get_user_setting("playback.tryDirect.hevcProfileLevel") = "true" and playbackInfo.MediaSources[0].MediaStreams[0].codec = "hevc")
|
||||
if tryDirectPlay and playbackInfo.MediaSources[0].TranscodingUrl <> invalid and forceTranscoding = false
|
||||
|
@ -236,10 +231,10 @@ sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -
|
|||
end if
|
||||
|
||||
if video.directPlaySupported
|
||||
protocol = LCase(playbackInfo.MediaSources[0].Protocol)
|
||||
protocol = LCase(m.playbackInfo.MediaSources[0].Protocol)
|
||||
if protocol <> "file"
|
||||
uriRegex = CreateObject("roRegex", "^(.*:)//([A-Za-z0-9\-\.]+)(:[0-9]+)?(.*)$", "")
|
||||
uri = uriRegex.Match(playbackInfo.MediaSources[0].Path)
|
||||
uri = uriRegex.Match(m.playbackInfo.MediaSources[0].Path)
|
||||
' proto $1, host $2, port $3, the-rest $4
|
||||
localhost = CreateObject("roRegex", "^localhost$|^127(?:\.[0-9]+){0,2}\.[0-9]+$|^(?:0*\:)*?:?0*1$", "i")
|
||||
' https://stackoverflow.com/questions/8426171/what-regex-will-match-all-loopback-addresses
|
||||
|
@ -250,7 +245,7 @@ sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -
|
|||
video.content.url = buildURL(uri[4])
|
||||
else
|
||||
fully_external = true
|
||||
video.content.url = playbackInfo.MediaSources[0].Path
|
||||
video.content.url = m.playbackInfo.MediaSources[0].Path
|
||||
end if
|
||||
else:
|
||||
params.append({
|
||||
|
@ -267,15 +262,15 @@ sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -
|
|||
end if
|
||||
video.isTranscoded = false
|
||||
else
|
||||
if playbackInfo.MediaSources[0].TranscodingUrl = invalid
|
||||
if m.playbackInfo.MediaSources[0].TranscodingUrl = invalid
|
||||
' If server does not provide a transcode URL, display a message to the user
|
||||
m.global.sceneManager.callFunc("userMessage", tr("Error Getting Playback Information"), tr("An error was encountered while playing this item. Server did not provide required transcoding data."))
|
||||
video.content = invalid
|
||||
return
|
||||
end if
|
||||
' Get transcoding reason
|
||||
video.transcodeReasons = getTranscodeReasons(playbackInfo.MediaSources[0].TranscodingUrl)
|
||||
video.content.url = buildURL(playbackInfo.MediaSources[0].TranscodingUrl)
|
||||
video.transcodeReasons = getTranscodeReasons(m.playbackInfo.MediaSources[0].TranscodingUrl)
|
||||
video.content.url = buildURL(m.playbackInfo.MediaSources[0].TranscodingUrl)
|
||||
video.isTranscoded = true
|
||||
end if
|
||||
|
||||
|
@ -286,10 +281,6 @@ sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -
|
|||
' is enabled/will be enabled, indexed on the provided list of subtitles
|
||||
video.SelectedSubtitle = setupSubtitle(video, video.Subtitles, subtitle_idx)
|
||||
|
||||
video.content.SDBifUrl = api_API().jellyscrub.get(video.id)
|
||||
video.content.HDBifUrl = api_API().jellyscrub.get(video.id)
|
||||
video.content.FHDBifUrl = api_API().jellyscrub.get(video.id)
|
||||
|
||||
if not fully_external
|
||||
video.content = authorize_request(video.content)
|
||||
end if
|
||||
|
@ -348,9 +339,9 @@ function getTranscodeReasons(url as string) as object
|
|||
return []
|
||||
end function
|
||||
|
||||
'Opens dialog asking user if they want to resume video or start playback over
|
||||
'Opens dialog asking user if they want to resume video or start playback over only on the home screen
|
||||
function startPlayBackOver(time as longinteger) as integer
|
||||
if m.videotype = "Episode" or m.videotype = "Series"
|
||||
if m.scene.focusedChild.focusedChild.overhangTitle = tr("Home") and (m.videotype = "Episode" or m.videotype = "Series")
|
||||
return option_dialog([tr("Resume playing at ") + ticksToHuman(time) + ".", tr("Start over from the beginning."), tr("Watched"), tr("Go to series"), tr("Go to season"), tr("Go to episode")])
|
||||
else
|
||||
return option_dialog(["Resume playing at " + ticksToHuman(time) + ".", "Start over from the beginning."])
|
||||
|
@ -431,10 +422,10 @@ sub autoPlayNextEpisode(videoID as string, showID as string)
|
|||
data = getJson(resp)
|
||||
|
||||
if data <> invalid and data.Items.Count() = 2
|
||||
' remove finished video node
|
||||
m.global.sceneManager.callFunc("popScene")
|
||||
' setup new video node
|
||||
nextVideo = CreateVideoPlayerGroup(data.Items[1].Id, invalid, 1, false, false)
|
||||
' remove last video scene
|
||||
m.global.sceneManager.callFunc("clearPreviousScene")
|
||||
if nextVideo <> invalid
|
||||
m.global.sceneManager.callFunc("pushScene", nextVideo)
|
||||
else
|
||||
|
@ -448,3 +439,135 @@ sub autoPlayNextEpisode(videoID as string, showID as string)
|
|||
m.global.sceneManager.callFunc("popScene")
|
||||
end if
|
||||
end sub
|
||||
|
||||
' Returns an array of playback info to be displayed during playback.
|
||||
' In the future, with a custom playback info view, we can return an associated array.
|
||||
function GetPlaybackInfo()
|
||||
sessions = api_API().sessions.get()
|
||||
if sessions <> invalid and sessions.Count() > 0
|
||||
return GetTranscodingStats(sessions[0])
|
||||
end if
|
||||
|
||||
errMsg = tr("Unable to get playback information")
|
||||
return [errMsg]
|
||||
end function
|
||||
|
||||
function GetTranscodingStats(session)
|
||||
sessionStats = []
|
||||
|
||||
if isValid(session.TranscodingInfo) and session.TranscodingInfo.Count() > 0
|
||||
transcodingReasons = session.TranscodingInfo.TranscodeReasons
|
||||
videoCodec = session.TranscodingInfo.VideoCodec
|
||||
audioCodec = session.TranscodingInfo.AudioCodec
|
||||
totalBitrate = session.TranscodingInfo.Bitrate
|
||||
audioChannels = session.TranscodingInfo.AudioChannels
|
||||
|
||||
if isValid(transcodingReasons) and transcodingReasons.Count() > 0
|
||||
sessionStats.push("** " + tr("Transcoding Information") + " **")
|
||||
for each item in transcodingReasons
|
||||
sessionStats.push(tr("Reason") + ": " + item)
|
||||
end for
|
||||
end if
|
||||
|
||||
if isValid(videoCodec)
|
||||
data = tr("Video Codec") + ": " + videoCodec
|
||||
if session.TranscodingInfo.IsVideoDirect
|
||||
data = data + " (" + tr("direct") + ")"
|
||||
end if
|
||||
sessionStats.push(data)
|
||||
end if
|
||||
|
||||
if isValid(audioCodec)
|
||||
data = tr("Audio Codec") + ": " + audioCodec
|
||||
if session.TranscodingInfo.IsAudioDirect
|
||||
data = data + " (" + tr("direct") + ")"
|
||||
end if
|
||||
sessionStats.push(data)
|
||||
end if
|
||||
|
||||
if isValid(totalBitrate)
|
||||
data = tr("Total Bitrate") + ": " + getDisplayBitrate(totalBitrate)
|
||||
sessionStats.push(data)
|
||||
end if
|
||||
|
||||
if isValid(audioChannels)
|
||||
data = tr("Audio Channels") + ": " + Str(audioChannels)
|
||||
sessionStats.push(data)
|
||||
end if
|
||||
end if
|
||||
|
||||
if havePlaybackInfo()
|
||||
stream = m.playbackInfo.mediaSources[0].MediaStreams[0]
|
||||
sessionStats.push("** " + tr("Stream Information") + " **")
|
||||
if isValid(stream.Container)
|
||||
data = tr("Container") + ": " + stream.Container
|
||||
sessionStats.push(data)
|
||||
end if
|
||||
if isValid(stream.Size)
|
||||
data = tr("Size") + ": " + stream.Size
|
||||
sessionStats.push(data)
|
||||
end if
|
||||
if isValid(stream.BitRate)
|
||||
data = tr("Bit Rate") + ": " + getDisplayBitrate(stream.BitRate)
|
||||
sessionStats.push(data)
|
||||
end if
|
||||
if isValid(stream.Codec)
|
||||
data = tr("Codec") + ": " + stream.Codec
|
||||
sessionStats.push(data)
|
||||
end if
|
||||
if isValid(stream.CodecTag)
|
||||
data = tr("Codec Tag") + ": " + stream.CodecTag
|
||||
sessionStats.push(data)
|
||||
end if
|
||||
if isValid(stream.VideoRangeType)
|
||||
data = tr("Video range type") + ": " + stream.VideoRangeType
|
||||
sessionStats.push(data)
|
||||
end if
|
||||
if isValid(stream.PixelFormat)
|
||||
data = tr("Pixel format") + ": " + stream.PixelFormat
|
||||
sessionStats.push(data)
|
||||
end if
|
||||
if isValid(stream.Width) and isValid(stream.Height)
|
||||
data = tr("WxH") + ": " + Str(stream.Width) + " x " + Str(stream.Height)
|
||||
sessionStats.push(data)
|
||||
end if
|
||||
if isValid(stream.Level)
|
||||
data = tr("Level") + ": " + Str(stream.Level)
|
||||
sessionStats.push(data)
|
||||
end if
|
||||
end if
|
||||
|
||||
return sessionStats
|
||||
end function
|
||||
|
||||
function havePlaybackInfo()
|
||||
if not isValid(m.playbackInfo)
|
||||
return false
|
||||
end if
|
||||
|
||||
if not isValid(m.playbackInfo.mediaSources)
|
||||
return false
|
||||
end if
|
||||
|
||||
if m.playbackInfo.mediaSources.Count() <= 0
|
||||
return false
|
||||
end if
|
||||
|
||||
if not isValid(m.playbackInfo.mediaSources[0].MediaStreams)
|
||||
return false
|
||||
end if
|
||||
|
||||
if m.playbackInfo.mediaSources[0].MediaStreams.Count() <= 0
|
||||
return false
|
||||
end if
|
||||
|
||||
return true
|
||||
end function
|
||||
|
||||
function getDisplayBitrate(bitrate)
|
||||
if bitrate > 1000000
|
||||
return Str(Fix(bitrate / 1000000)) + " Mbps"
|
||||
else
|
||||
return Str(Fix(bitrate / 1000)) + " Kbps"
|
||||
end if
|
||||
end function
|
||||
|
|
|
@ -34,34 +34,40 @@ function ItemPostPlaybackInfo(id as string, mediaSourceId = "" as string, audioT
|
|||
end function
|
||||
|
||||
' Search across all libraries
|
||||
function SearchMedia(query as string)
|
||||
function searchMedia(query as string)
|
||||
' This appears to be done differently on the web now
|
||||
' For each potential type, a separate query is done:
|
||||
' varying item types, and artists, and people
|
||||
resp = APIRequest(Substitute("Users/{0}/Items", get_setting("active_user")), {
|
||||
"searchTerm": query,
|
||||
"IncludePeople": true,
|
||||
"IncludeMedia": true,
|
||||
"IncludeShows": true,
|
||||
"IncludeGenres": false,
|
||||
"IncludeStudios": false,
|
||||
"IncludeArtists": false,
|
||||
"IncludeItemTypes": "TvChannel,Movie,BoxSet,Series,Episode,Video",
|
||||
"EnableTotalRecordCount": false,
|
||||
"ImageTypeLimit": 1,
|
||||
"Recursive": true
|
||||
})
|
||||
|
||||
data = getJson(resp)
|
||||
results = []
|
||||
for each item in data.Items
|
||||
tmp = CreateObject("roSGNode", "SearchData")
|
||||
tmp.image = PosterImage(item.id)
|
||||
tmp.json = item
|
||||
results.push(tmp)
|
||||
end for
|
||||
data.SearchHints = results
|
||||
return data
|
||||
if query <> ""
|
||||
resp = APIRequest(Substitute("Search/Hints", get_setting("active_user")), {
|
||||
"searchTerm": query,
|
||||
"IncludePeople": true,
|
||||
"IncludeMedia": true,
|
||||
"IncludeShows": true,
|
||||
"IncludeGenres": true,
|
||||
"IncludeStudios": true,
|
||||
"IncludeArtists": true,
|
||||
"IncludeItemTypes": "LiveTvChannel,Movie,BoxSet,Series,Episode,Video,Person,Audio,MusicAlbum,MusicArtist,Playlist",
|
||||
"EnableTotalRecordCount": false,
|
||||
"ImageTypeLimit": 1,
|
||||
"Recursive": true,
|
||||
"limit": 100
|
||||
})
|
||||
|
||||
|
||||
data = getJson(resp)
|
||||
results = []
|
||||
for each item in data.SearchHints
|
||||
tmp = CreateObject("roSGNode", "SearchData")
|
||||
tmp.image = PosterImage(item.id)
|
||||
tmp.json = item
|
||||
results.push(tmp)
|
||||
end for
|
||||
data.SearchHints = results
|
||||
return data
|
||||
end if
|
||||
return []
|
||||
end function
|
||||
|
||||
' MetaData about an item
|
||||
|
@ -77,7 +83,7 @@ function ItemMetaData(id as string)
|
|||
imgParams.Append(param)
|
||||
end if
|
||||
end if
|
||||
if data.type = "Movie"
|
||||
if data.type = "Movie" or data.type = "MusicVideo"
|
||||
tmp = CreateObject("roSGNode", "MovieData")
|
||||
tmp.image = PosterImage(data.id, imgParams)
|
||||
tmp.json = data
|
||||
|
@ -94,7 +100,7 @@ function ItemMetaData(id as string)
|
|||
tmp.image = PosterImage(data.id, imgParams)
|
||||
tmp.json = data
|
||||
return tmp
|
||||
else if data.type = "BoxSet"
|
||||
else if data.type = "BoxSet" or data.type = "Playlist"
|
||||
tmp = CreateObject("roSGNode", "CollectionData")
|
||||
tmp.image = PosterImage(data.id, imgParams)
|
||||
tmp.json = data
|
||||
|
|
Loading…
Reference in New Issue
Block a user