├── .settings
├── org.eclipse.wst.jsdt.ui.superType.name
└── org.eclipse.wst.jsdt.ui.superType.container
├── widget.info
├── images
├── Logo.png
├── album.png
├── bg1.jpg
├── done.png
├── arrowUp.png
├── artist.png
├── loading.png
├── missing.png
├── server.png
├── splash.jpg
├── unaired.png
├── arrowDown.png
├── cc-50x40.png
├── collection.png
├── film-54x60.png
├── help_blue.png
├── help_green.png
├── help_red.png
├── SeasonBlank.png
├── ShowNoImage.png
├── arrowUpDown.png
├── film-93x105.png
├── fresh-40x40.png
├── help_yellow.png
├── return-34x36.png
├── rotten-40x40.png
├── usernoimage.png
├── Live-TV-108x98.png
├── MediaInfo
│ ├── blank.png
│ ├── res_480.png
│ ├── res_540.png
│ ├── res_576.png
│ ├── res_720.png
│ ├── res_SD.png
│ ├── aspect_133.png
│ ├── aspect_166.png
│ ├── aspect_178.png
│ ├── aspect_185.png
│ ├── aspect_235.png
│ ├── aspect_240.png
│ ├── channels_1.png
│ ├── channels_2.png
│ ├── channels_3.png
│ ├── channels_4.png
│ ├── channels_5.png
│ ├── channels_6.png
│ ├── channels_7.png
│ ├── channels_8.png
│ ├── codec_ac3.png
│ ├── codec_divx.png
│ ├── codec_dts.png
│ ├── codec_flac.png
│ ├── codec_h264.png
│ ├── codec_h265.png
│ ├── codec_mp3.png
│ ├── codec_pcm.png
│ ├── codec_vc1.png
│ ├── codec_wma.png
│ ├── codec_xvid.png
│ ├── fullscreen.png
│ ├── media_3d.png
│ ├── media_SBS.png
│ ├── media_TAB.png
│ ├── media_dvd.png
│ ├── media_m2ts.png
│ ├── media_mp4.png
│ ├── res_1080.png
│ ├── widescreen.png
│ ├── codec_aac-2.png
│ ├── codec_dtses.png
│ ├── codec_dtshra.png
│ ├── codec_dtsma.png
│ ├── codec_mpeg2.png
│ ├── codec_vorbis.png
│ ├── media_avi-2.png
│ ├── media_bluray.png
│ ├── media_mkv-2.png
│ ├── codec_ddtruehd.png
│ └── codec_mpeg4visual.png
├── ShowPosterBlank.png
├── favorite-36x33.png
├── favorite-45x41.png
├── menu
│ ├── Film-46x37.png
│ ├── Home-46x37.png
│ ├── Play-46x37.png
│ ├── Stop-46x37.png
│ ├── TV-46x37.png
│ ├── Folder-46x37.png
│ ├── Guide-46x37.png
│ ├── Logout-46x37.png
│ ├── Movies-46x37.png
│ ├── Music-46x37.png
│ ├── Person-46x37.png
│ ├── Photos-46x37.png
│ ├── Resume-46x37.png
│ ├── Search-46x37.png
│ ├── photos-54x54.png
│ ├── AddToList-56x37.png
│ ├── AddToList-60x37.png
│ ├── Channels-46x37.png
│ ├── Live_TV-46x37.png
│ ├── Playlists-46x37.png
│ ├── Settings-46x37.png
│ ├── Collections-46x37.png
│ ├── Favourites-46x37.png
│ ├── Home_Movies-46x37.png
│ ├── Recordings-46x37.png
│ └── Media_Folders-46x37.png
├── qualityflyout.png
├── sliderPosition.png
├── star_full-46x40.png
├── star_half-46x40.png
├── loginusernoimage.png
├── star_empty-46x40.png
├── trailerBackground.png
├── EmptyFolder-122x98.png
├── ShowPosterBlankSmaller.png
└── musicplayer
│ ├── play-29x37.png
│ ├── stop-37x37.png
│ ├── pause-32x37.png
│ ├── skip-next-36x37.png
│ ├── fast-forward-53x37.png
│ ├── fast-rewind-54x37.png
│ ├── pause-active-32x37.png
│ ├── play-active-29x37.png
│ ├── stop-active-37x37.png
│ ├── pause-selected-32x37.png
│ ├── play-selected-29x37.png
│ ├── skip-previous-36x37.png
│ ├── stop-selected-37x37.png
│ ├── skip-next-active-36x37.png
│ ├── skip-next-selected-36x37.png
│ ├── fast-forward-selected-53x37.png
│ ├── fast-rewind-selected-54x37.png
│ ├── skip-previous-active-36x37.png
│ └── skip-previous-selected-36x37.png
├── icon
├── MB3_85_70.png
├── MB3_95_78.png
├── MB3_106_87.png
└── MB3_115_95.png
├── README.md
├── .project
├── app
└── javascript
│ ├── Support
│ ├── polyfill.js
│ ├── ServerVersion.js
│ ├── GuiNotifications.js
│ ├── FileLog.js
│ ├── srt-parser.js
│ ├── GuiHelper.js
│ └── File.js
│ ├── Gui
│ ├── GuiPage_Contributors.js
│ ├── GuiImagePlayer
│ │ ├── GuiImagePlayer_Screensaver.js
│ │ └── GuiImagePlayer.js
│ ├── GuiPage_Servers.js
│ ├── GuiPage_NewServer.js
│ ├── GuiUsers_Manual.js
│ ├── GuiPage_SettingsLog.js
│ ├── GuiPlayer
│ │ └── GuiPlayer_Transcoding.js
│ ├── GuiPage_CastMember.js
│ ├── GuiPage_AddToPlaylist.js
│ ├── GuiMainMenu.js
│ ├── GuiDisplayOneItem.js
│ ├── GuiPage_Music.js
│ └── GuiPage_Search.js
│ └── Main.js
├── LICENSE
└── config.xml
/.settings/org.eclipse.wst.jsdt.ui.superType.name:
--------------------------------------------------------------------------------
1 | Global
--------------------------------------------------------------------------------
/widget.info:
--------------------------------------------------------------------------------
1 | Use Alpha Blending? = Yes
2 | Screen Resolution = 1920x1080
--------------------------------------------------------------------------------
/.settings/org.eclipse.wst.jsdt.ui.superType.container:
--------------------------------------------------------------------------------
1 | org.eclipse.wst.jsdt.launching.JRE_CONTAINER
--------------------------------------------------------------------------------
/images/Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/Logo.png
--------------------------------------------------------------------------------
/images/album.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/album.png
--------------------------------------------------------------------------------
/images/bg1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/bg1.jpg
--------------------------------------------------------------------------------
/images/done.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/done.png
--------------------------------------------------------------------------------
/icon/MB3_85_70.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/icon/MB3_85_70.png
--------------------------------------------------------------------------------
/icon/MB3_95_78.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/icon/MB3_95_78.png
--------------------------------------------------------------------------------
/images/arrowUp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/arrowUp.png
--------------------------------------------------------------------------------
/images/artist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/artist.png
--------------------------------------------------------------------------------
/images/loading.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/loading.png
--------------------------------------------------------------------------------
/images/missing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/missing.png
--------------------------------------------------------------------------------
/images/server.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/server.png
--------------------------------------------------------------------------------
/images/splash.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/splash.jpg
--------------------------------------------------------------------------------
/images/unaired.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/unaired.png
--------------------------------------------------------------------------------
/icon/MB3_106_87.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/icon/MB3_106_87.png
--------------------------------------------------------------------------------
/icon/MB3_115_95.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/icon/MB3_115_95.png
--------------------------------------------------------------------------------
/images/arrowDown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/arrowDown.png
--------------------------------------------------------------------------------
/images/cc-50x40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/cc-50x40.png
--------------------------------------------------------------------------------
/images/collection.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/collection.png
--------------------------------------------------------------------------------
/images/film-54x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/film-54x60.png
--------------------------------------------------------------------------------
/images/help_blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/help_blue.png
--------------------------------------------------------------------------------
/images/help_green.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/help_green.png
--------------------------------------------------------------------------------
/images/help_red.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/help_red.png
--------------------------------------------------------------------------------
/images/SeasonBlank.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/SeasonBlank.png
--------------------------------------------------------------------------------
/images/ShowNoImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/ShowNoImage.png
--------------------------------------------------------------------------------
/images/arrowUpDown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/arrowUpDown.png
--------------------------------------------------------------------------------
/images/film-93x105.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/film-93x105.png
--------------------------------------------------------------------------------
/images/fresh-40x40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/fresh-40x40.png
--------------------------------------------------------------------------------
/images/help_yellow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/help_yellow.png
--------------------------------------------------------------------------------
/images/return-34x36.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/return-34x36.png
--------------------------------------------------------------------------------
/images/rotten-40x40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/rotten-40x40.png
--------------------------------------------------------------------------------
/images/usernoimage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/usernoimage.png
--------------------------------------------------------------------------------
/images/Live-TV-108x98.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/Live-TV-108x98.png
--------------------------------------------------------------------------------
/images/MediaInfo/blank.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/blank.png
--------------------------------------------------------------------------------
/images/ShowPosterBlank.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/ShowPosterBlank.png
--------------------------------------------------------------------------------
/images/favorite-36x33.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/favorite-36x33.png
--------------------------------------------------------------------------------
/images/favorite-45x41.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/favorite-45x41.png
--------------------------------------------------------------------------------
/images/menu/Film-46x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/Film-46x37.png
--------------------------------------------------------------------------------
/images/menu/Home-46x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/Home-46x37.png
--------------------------------------------------------------------------------
/images/menu/Play-46x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/Play-46x37.png
--------------------------------------------------------------------------------
/images/menu/Stop-46x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/Stop-46x37.png
--------------------------------------------------------------------------------
/images/menu/TV-46x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/TV-46x37.png
--------------------------------------------------------------------------------
/images/qualityflyout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/qualityflyout.png
--------------------------------------------------------------------------------
/images/sliderPosition.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/sliderPosition.png
--------------------------------------------------------------------------------
/images/star_full-46x40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/star_full-46x40.png
--------------------------------------------------------------------------------
/images/star_half-46x40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/star_half-46x40.png
--------------------------------------------------------------------------------
/images/MediaInfo/res_480.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/res_480.png
--------------------------------------------------------------------------------
/images/MediaInfo/res_540.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/res_540.png
--------------------------------------------------------------------------------
/images/MediaInfo/res_576.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/res_576.png
--------------------------------------------------------------------------------
/images/MediaInfo/res_720.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/res_720.png
--------------------------------------------------------------------------------
/images/MediaInfo/res_SD.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/res_SD.png
--------------------------------------------------------------------------------
/images/loginusernoimage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/loginusernoimage.png
--------------------------------------------------------------------------------
/images/menu/Folder-46x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/Folder-46x37.png
--------------------------------------------------------------------------------
/images/menu/Guide-46x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/Guide-46x37.png
--------------------------------------------------------------------------------
/images/menu/Logout-46x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/Logout-46x37.png
--------------------------------------------------------------------------------
/images/menu/Movies-46x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/Movies-46x37.png
--------------------------------------------------------------------------------
/images/menu/Music-46x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/Music-46x37.png
--------------------------------------------------------------------------------
/images/menu/Person-46x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/Person-46x37.png
--------------------------------------------------------------------------------
/images/menu/Photos-46x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/Photos-46x37.png
--------------------------------------------------------------------------------
/images/menu/Resume-46x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/Resume-46x37.png
--------------------------------------------------------------------------------
/images/menu/Search-46x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/Search-46x37.png
--------------------------------------------------------------------------------
/images/menu/photos-54x54.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/photos-54x54.png
--------------------------------------------------------------------------------
/images/star_empty-46x40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/star_empty-46x40.png
--------------------------------------------------------------------------------
/images/trailerBackground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/trailerBackground.png
--------------------------------------------------------------------------------
/images/EmptyFolder-122x98.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/EmptyFolder-122x98.png
--------------------------------------------------------------------------------
/images/MediaInfo/aspect_133.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/aspect_133.png
--------------------------------------------------------------------------------
/images/MediaInfo/aspect_166.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/aspect_166.png
--------------------------------------------------------------------------------
/images/MediaInfo/aspect_178.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/aspect_178.png
--------------------------------------------------------------------------------
/images/MediaInfo/aspect_185.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/aspect_185.png
--------------------------------------------------------------------------------
/images/MediaInfo/aspect_235.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/aspect_235.png
--------------------------------------------------------------------------------
/images/MediaInfo/aspect_240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/aspect_240.png
--------------------------------------------------------------------------------
/images/MediaInfo/channels_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/channels_1.png
--------------------------------------------------------------------------------
/images/MediaInfo/channels_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/channels_2.png
--------------------------------------------------------------------------------
/images/MediaInfo/channels_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/channels_3.png
--------------------------------------------------------------------------------
/images/MediaInfo/channels_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/channels_4.png
--------------------------------------------------------------------------------
/images/MediaInfo/channels_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/channels_5.png
--------------------------------------------------------------------------------
/images/MediaInfo/channels_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/channels_6.png
--------------------------------------------------------------------------------
/images/MediaInfo/channels_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/channels_7.png
--------------------------------------------------------------------------------
/images/MediaInfo/channels_8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/channels_8.png
--------------------------------------------------------------------------------
/images/MediaInfo/codec_ac3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/codec_ac3.png
--------------------------------------------------------------------------------
/images/MediaInfo/codec_divx.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/codec_divx.png
--------------------------------------------------------------------------------
/images/MediaInfo/codec_dts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/codec_dts.png
--------------------------------------------------------------------------------
/images/MediaInfo/codec_flac.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/codec_flac.png
--------------------------------------------------------------------------------
/images/MediaInfo/codec_h264.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/codec_h264.png
--------------------------------------------------------------------------------
/images/MediaInfo/codec_h265.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/codec_h265.png
--------------------------------------------------------------------------------
/images/MediaInfo/codec_mp3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/codec_mp3.png
--------------------------------------------------------------------------------
/images/MediaInfo/codec_pcm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/codec_pcm.png
--------------------------------------------------------------------------------
/images/MediaInfo/codec_vc1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/codec_vc1.png
--------------------------------------------------------------------------------
/images/MediaInfo/codec_wma.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/codec_wma.png
--------------------------------------------------------------------------------
/images/MediaInfo/codec_xvid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/codec_xvid.png
--------------------------------------------------------------------------------
/images/MediaInfo/fullscreen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/fullscreen.png
--------------------------------------------------------------------------------
/images/MediaInfo/media_3d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/media_3d.png
--------------------------------------------------------------------------------
/images/MediaInfo/media_SBS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/media_SBS.png
--------------------------------------------------------------------------------
/images/MediaInfo/media_TAB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/media_TAB.png
--------------------------------------------------------------------------------
/images/MediaInfo/media_dvd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/media_dvd.png
--------------------------------------------------------------------------------
/images/MediaInfo/media_m2ts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/media_m2ts.png
--------------------------------------------------------------------------------
/images/MediaInfo/media_mp4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/media_mp4.png
--------------------------------------------------------------------------------
/images/MediaInfo/res_1080.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/res_1080.png
--------------------------------------------------------------------------------
/images/MediaInfo/widescreen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/widescreen.png
--------------------------------------------------------------------------------
/images/menu/AddToList-56x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/AddToList-56x37.png
--------------------------------------------------------------------------------
/images/menu/AddToList-60x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/AddToList-60x37.png
--------------------------------------------------------------------------------
/images/menu/Channels-46x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/Channels-46x37.png
--------------------------------------------------------------------------------
/images/menu/Live_TV-46x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/Live_TV-46x37.png
--------------------------------------------------------------------------------
/images/menu/Playlists-46x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/Playlists-46x37.png
--------------------------------------------------------------------------------
/images/menu/Settings-46x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/Settings-46x37.png
--------------------------------------------------------------------------------
/images/MediaInfo/codec_aac-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/codec_aac-2.png
--------------------------------------------------------------------------------
/images/MediaInfo/codec_dtses.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/codec_dtses.png
--------------------------------------------------------------------------------
/images/MediaInfo/codec_dtshra.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/codec_dtshra.png
--------------------------------------------------------------------------------
/images/MediaInfo/codec_dtsma.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/codec_dtsma.png
--------------------------------------------------------------------------------
/images/MediaInfo/codec_mpeg2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/codec_mpeg2.png
--------------------------------------------------------------------------------
/images/MediaInfo/codec_vorbis.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/codec_vorbis.png
--------------------------------------------------------------------------------
/images/MediaInfo/media_avi-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/media_avi-2.png
--------------------------------------------------------------------------------
/images/MediaInfo/media_bluray.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/media_bluray.png
--------------------------------------------------------------------------------
/images/MediaInfo/media_mkv-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/media_mkv-2.png
--------------------------------------------------------------------------------
/images/ShowPosterBlankSmaller.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/ShowPosterBlankSmaller.png
--------------------------------------------------------------------------------
/images/menu/Collections-46x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/Collections-46x37.png
--------------------------------------------------------------------------------
/images/menu/Favourites-46x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/Favourites-46x37.png
--------------------------------------------------------------------------------
/images/menu/Home_Movies-46x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/Home_Movies-46x37.png
--------------------------------------------------------------------------------
/images/menu/Recordings-46x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/Recordings-46x37.png
--------------------------------------------------------------------------------
/images/musicplayer/play-29x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/musicplayer/play-29x37.png
--------------------------------------------------------------------------------
/images/musicplayer/stop-37x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/musicplayer/stop-37x37.png
--------------------------------------------------------------------------------
/images/MediaInfo/codec_ddtruehd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/codec_ddtruehd.png
--------------------------------------------------------------------------------
/images/menu/Media_Folders-46x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/menu/Media_Folders-46x37.png
--------------------------------------------------------------------------------
/images/musicplayer/pause-32x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/musicplayer/pause-32x37.png
--------------------------------------------------------------------------------
/images/MediaInfo/codec_mpeg4visual.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/MediaInfo/codec_mpeg4visual.png
--------------------------------------------------------------------------------
/images/musicplayer/skip-next-36x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/musicplayer/skip-next-36x37.png
--------------------------------------------------------------------------------
/images/musicplayer/fast-forward-53x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/musicplayer/fast-forward-53x37.png
--------------------------------------------------------------------------------
/images/musicplayer/fast-rewind-54x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/musicplayer/fast-rewind-54x37.png
--------------------------------------------------------------------------------
/images/musicplayer/pause-active-32x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/musicplayer/pause-active-32x37.png
--------------------------------------------------------------------------------
/images/musicplayer/play-active-29x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/musicplayer/play-active-29x37.png
--------------------------------------------------------------------------------
/images/musicplayer/stop-active-37x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/musicplayer/stop-active-37x37.png
--------------------------------------------------------------------------------
/images/musicplayer/pause-selected-32x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/musicplayer/pause-selected-32x37.png
--------------------------------------------------------------------------------
/images/musicplayer/play-selected-29x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/musicplayer/play-selected-29x37.png
--------------------------------------------------------------------------------
/images/musicplayer/skip-previous-36x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/musicplayer/skip-previous-36x37.png
--------------------------------------------------------------------------------
/images/musicplayer/stop-selected-37x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/musicplayer/stop-selected-37x37.png
--------------------------------------------------------------------------------
/images/musicplayer/skip-next-active-36x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/musicplayer/skip-next-active-36x37.png
--------------------------------------------------------------------------------
/images/musicplayer/skip-next-selected-36x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/musicplayer/skip-next-selected-36x37.png
--------------------------------------------------------------------------------
/images/musicplayer/fast-forward-selected-53x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/musicplayer/fast-forward-selected-53x37.png
--------------------------------------------------------------------------------
/images/musicplayer/fast-rewind-selected-54x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/musicplayer/fast-rewind-selected-54x37.png
--------------------------------------------------------------------------------
/images/musicplayer/skip-previous-active-36x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/musicplayer/skip-previous-active-36x37.png
--------------------------------------------------------------------------------
/images/musicplayer/skip-previous-selected-36x37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jellyfin-archive/jellyfin-samsungtv/HEAD/images/musicplayer/skip-previous-selected-36x37.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SamsungSmartTV
2 |
3 | Warning: This app is a legacy program meant for older Samsung Smart TVs running Orsay (pre-2015), which has since been replaced by Tizen. It may be possible to use this app by side-loading, but it is considered unsupported (we are unable to help you with it).
4 |
5 | You may also wish to try a web browser with Jellyfin, wherever possible.
6 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | Emby
4 |
5 |
6 |
7 |
8 |
9 |
10 | org.eclipse.wst.jsdt.core.javascriptValidator
11 |
12 |
13 |
14 |
15 |
16 | org.eclipse.wst.jsdt.core.jsNature
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/javascript/Support/polyfill.js:
--------------------------------------------------------------------------------
1 | if (!Array.prototype.findIndex) {
2 | Array.prototype.findIndex = function(predicate, thisArg) {
3 | if (typeof predicate !== 'function') {
4 | throw new TypeError('predicate must be a function');
5 | }
6 |
7 | var lastIndex = -1;
8 | if (!Array.prototype.some.call(this, function(val, index, arr) {
9 | return predicate.call(thisArg, val, lastIndex = index, arr);
10 | })) {
11 | return -1;
12 | }
13 | return lastIndex;
14 | };
15 | }
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Media Browser
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | icon/MB3_106_87.png
7 | icon/MB3_115_95.png
8 | icon/MB3_85_70.png
9 | icon/MB3_95_78.png
10 | Videos
11 | n
12 | 2.2.5b
13 |
14 | y
15 | user
16 | y
17 | n
18 | n
19 | n
20 | y
21 | Emby
22 | Emby for Samsung Smart TV
23 | 1920
24 | 1080
25 |
26 | ChessDragon136
27 | emby.media/community
28 | emby.media
29 |
30 |
31 |
--------------------------------------------------------------------------------
/app/javascript/Support/ServerVersion.js:
--------------------------------------------------------------------------------
1 | var ServerVersion = {
2 | ServerInfo : null
3 | }
4 |
5 | ServerVersion.start = function() {
6 | document.getElementById("pageContent").innerHTML = "
\
7 |
The Samsung app requires a later version of the Server - Please update it and restart the app
";
8 |
9 | document.getElementById("ServerVersion").focus();
10 | }
11 |
12 | ServerVersion.checkServerVersion = function() {
13 | var url = Server.getCustomURL("/System/Info/Public?format=json");
14 | this.ServerInfo = Server.getContent(url);
15 | if (this.ServerInfo == null) { return; }
16 |
17 | var requiredServerVersion = Main.getRequiredServerVersion();
18 | var currentServerVersion = this.ServerInfo.Version;
19 |
20 | if (currentServerVersion >= requiredServerVersion) {
21 | return true;
22 | } else {
23 | return false;
24 | }
25 | }
26 |
27 | ServerVersion.keyDown = function() {
28 | var keyCode = event.keyCode;
29 | alert("Key pressed: " + keyCode);
30 |
31 | if (document.getElementById("Notifications").style.visibility == "") {
32 | document.getElementById("Notifications").style.visibility = "hidden";
33 | document.getElementById("NotificationText").innerHTML = "";
34 | widgetAPI.blockNavigation(event);
35 | //Change keycode so it does nothing!
36 | keyCode = "VOID";
37 | }
38 |
39 | switch(keyCode) {
40 | default:
41 | widgetAPI.sendExitEvent();
42 | break;
43 | }
44 | }
--------------------------------------------------------------------------------
/app/javascript/Support/GuiNotifications.js:
--------------------------------------------------------------------------------
1 | var GuiNotifications = {
2 | timeout : null
3 | }
4 |
5 | GuiNotifications.setNotification = function (Message, Title,alterHeight) {
6 | //Clear any existing message
7 | clearInterval(this.timeout);
8 | document.getElementById("Notifications").style.visibility = "hidden";
9 | document.getElementById("NotificationText").innerHTML = "";
10 | document.getElementById("NotificationText").className="notification highlight"+Main.highlightColour+"Boarder";
11 |
12 | //Code to move based on screen (fix for GuiPage_IP)
13 | if (alterHeight == true) {
14 | document.getElementById("Notifications").style.top = "620px";
15 | document.getElementById("Notifications").style.left = "430px";
16 | } else {
17 | document.getElementById("Notifications").style.top = "390px";
18 | document.getElementById("Notifications").style.left = "710px";
19 | }
20 |
21 | /* if (Message.length > 30) {
22 | var brpoint = 30;
23 | newmessage = "";
24 | while (brpoint < Message.length) {
25 | temphold = Message.substring((brpoint-30),brpoint+4);
26 | if (temphold.indexOf("
") == -1) {
27 | newmessage += Message.substring((brpoint-30),brpoint) + "
";
28 | } else {
29 | newmessage += Message.substring((brpoint-30),brpoint);
30 | }
31 | alert(newmessage);
32 | brpoint = brpoint + 30;
33 | }
34 | newmessage += Message.substring((brpoint-30), Message.length);
35 | Message = newmessage;
36 | }*/
37 |
38 | document.getElementById("NotificationText").innerHTML = "
" + Title + "
"+Message+"
";
39 | document.getElementById("Notifications").style.visibility ="";
40 |
41 | if (Title != "Test Mode") {
42 | this.timeout = setTimeout(function(){
43 | document.getElementById("Notifications").style.visibility = "hidden";
44 | document.getElementById("NotificationText").innerHTML = "";
45 | }, 5000);
46 | }
47 | }
--------------------------------------------------------------------------------
/app/javascript/Support/FileLog.js:
--------------------------------------------------------------------------------
1 | var FileLog = {
2 | };
3 |
4 | FileLog.deleteFile = function() {
5 | var fileSystemObj = new FileSystem();
6 | fileSystemObj.deleteCommonFile(curWidget.id + '/MB3_Log.txt');
7 | }
8 |
9 | FileLog.loadFile = function(returnContents) {
10 | var fileSystemObj = new FileSystem();
11 |
12 | var bValid = fileSystemObj.isValidCommonPath(curWidget.id);
13 | if (!bValid) {
14 | fileSystemObj.createCommonDir(curWidget.id);
15 | var fileObj = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Log.txt', 'a+');
16 | fileSystemObj.closeCommonFile(fileObj);
17 | }
18 |
19 | var openRead = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Log.txt', 'r');
20 | if (!openRead) {
21 | fileSystemObj.createCommonDir(curWidget.id);
22 | var fileObj = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Log.txt', 'a+');
23 | fileSystemObj.closeCommonFile(fileObj);
24 | return null;
25 | } else {
26 | var strLine = "";
27 | var arrayFile = new Array();
28 | while ((strLine=openRead.readLine())) {
29 | arrayFile.push(strLine);
30 | }
31 | fileSystemObj.closeCommonFile(openRead);
32 | if (returnContents) {
33 | return arrayFile;
34 | } else {
35 | return null;
36 | }
37 | }
38 | };
39 |
40 | FileLog.write = function (toWrite,noDate) {
41 |
42 | var writeDate = (noDate == undefined) ? true : false;
43 | toWrite = (writeDate == true) ? FileLog.getTimeStamp() + " " + toWrite : toWrite;
44 | alert(toWrite);
45 | var fileSystemObj = new FileSystem();
46 | var openWrite = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Log.txt', 'a+');
47 | if (openWrite) {
48 | openWrite.writeLine(toWrite);
49 | fileSystemObj.closeCommonFile(openWrite);
50 | }
51 | }
52 |
53 | FileLog.empty = function () {
54 | var fileSystemObj = new FileSystem();
55 | var openWrite = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Log.txt', 'w');
56 | if (openWrite) {
57 | fileSystemObj.closeCommonFile(openWrite);
58 | }
59 | }
60 |
61 | FileLog.getTimeStamp = function () {
62 | var date = new Date();
63 | var day = (date.getDate() + 1 < 10) ? "0" + (date.getDate() + 1) : date.getDate() + 1;
64 | var month = (date.getMonth() + 1 < 10) ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
65 | var year = date.getFullYear();
66 |
67 | var h=date.getHours();
68 | var offset = File.getTVProperty("ClockOffset");
69 | h = h+offset;
70 | if (h<0) {h = h + 24;};
71 | if (h>23){h = h - 24;};
72 | if (h<10) {h = "0" + h;};
73 | var m=date.getMinutes();
74 | if (m<10) {m = "0" + m;};
75 | return day + "/" + month + "/" + year + " " + h+':'+m;
76 | }
--------------------------------------------------------------------------------
/app/javascript/Support/srt-parser.js:
--------------------------------------------------------------------------------
1 | var parser = (function() {
2 | var pItems = {};
3 |
4 | /**
5 | * Converts SubRip subtitles into array of objects
6 | * [{
7 | * id: `Number of subtitle`
8 | * startTime: `Start time of subtitle`
9 | * endTime: `End time of subtitle
10 | * text: `Text of subtitle`
11 | * }]
12 | *
13 | * @param {String} data SubRip suntitles string
14 | * @param {Boolean} ms Optional: use milliseconds for startTime and endTime
15 | * @return {Array}
16 | */
17 | pItems.fromSrt = function(data, ms) {
18 | var useMs = ms ? true : false;
19 |
20 | var regex = /(\d+)(\r?\n|\r)(\d{2}:\d{2}:\d{2},\d+) --> (\d{2}:\d{2}:\d{2},\d+)/g;
21 | data = data.split(regex);
22 | data.shift();
23 |
24 | var items = [];
25 | for (var i = 0; i < data.length; i += 5) {
26 | items.push({
27 | id: data[i],
28 | startTime: useMs ? timeMs(data[i + 2]) : data[i + 2],
29 | endTime: useMs ? timeMs(data[i + 3]) : data[i + 3],
30 | text: data[i + 4].replace(/\r?\n$|\r$/,'')
31 | });
32 | }
33 |
34 | return items;
35 | };
36 |
37 | /**
38 | * Converts Array of objects created by this module to SubRip subtitles
39 | * @param {Array} data
40 | * @return {String} SubRip subtitles string
41 | */
42 | pItems.toSrt = function(data) {
43 | if (!data instanceof Array) return '';
44 | var res = '';
45 |
46 | for (var i = 0; i < data.length; i++) {
47 | var s = data[i];
48 |
49 | if (!isNaN(s.startTime) && !isNaN(s.endTime)) {
50 | s.startTime = msTime(parseInt(s.startTime, 10));
51 | s.endTime = msTime(parseInt(s.endTime, 10));
52 | }
53 |
54 | res += s.id + '\r\n';
55 | res += s.startTime + ' --> ' + s.endTime + '\r\n';
56 | res += s.text.replace('\n', '\r\n') + '\r\n\r\n';
57 | }
58 |
59 | return res;
60 | };
61 |
62 | var timeMs = function(val) {
63 | var regex = /(\d+):(\d{2}):(\d{2}),(\d{3})/;
64 | var parts = regex.exec(val);
65 |
66 | if (parts === null) {
67 | return 0;
68 | }
69 |
70 | for (var i = 1; i < 5; i++) {
71 | parts[i] = parseInt(parts[i], 10);
72 | if (isNaN(parts[i])) parts[i] = 0;
73 | }
74 |
75 | // hours + minutes + seconds + ms
76 | return parts[1] * 3600000 + parts[2] * 60000 + parts[3] * 1000 + parts[4];
77 | };
78 |
79 | var msTime = function(val) {
80 | var measures = [ 3600000, 60000, 1000 ];
81 | var time = [];
82 |
83 | for (var i in measures) {
84 | var res = (val / measures[i] >> 0).toString();
85 |
86 | if (res.length < 2) res = '0' + res;
87 | val %= measures[i];
88 | time.push(res);
89 | }
90 |
91 | var ms = val.toString();
92 | if (ms.length < 3) {
93 | for (i = 0; i <= 3 - ms.length; i++) ms = '0' + ms;
94 | }
95 |
96 | return time.join(':') + ',' + ms;
97 | };
98 |
99 | return pItems;
100 | })();
101 |
102 | // ignore exports for browser
103 | if (typeof exports === 'object') {
104 | module.exports = parser;
105 | }
--------------------------------------------------------------------------------
/app/javascript/Gui/GuiPage_Contributors.js:
--------------------------------------------------------------------------------
1 | var GuiPage_Contributors = {
2 | MainDevs : ["ChessDragon136","cmcg"],
3 | ContribDevs : ["Cragjagged","DrWatson","im85288","arcticwaters","SamES"],
4 | DonateSupport : ["c0m3r","Cbers","crashkelly","DaN","FrostByte","gbone8106","ginganinja","grimfandango","fc7","shorty1483","paulsalter","fluffykiwi","oleg","MongooseMan","SilentAssassin","gogreenpower","Ultroman","Spaceboy","JeremyG","strugglez"]
5 | }
6 |
7 | GuiPage_Contributors.onFocus = function() {
8 | GuiHelper.setControlButtons(null,null,null,GuiMusicPlayer.Status == "PLAYING" || GuiMusicPlayer.Status == "PAUSED" ? "Music" : null,"Return");
9 | }
10 |
11 | GuiPage_Contributors.start = function() {
12 | alert("Page Enter : GuiPage_Contributors");
13 |
14 | document.getElementById("Counter").innerHTML = Main.version;
15 | document.getElementById("guiReturnButton").style.visibility = "";
16 | document.getElementById("guiReturnButton").innerHTML = "Return";
17 |
18 | document.getElementById("pageContent").innerHTML = "
About:
";
19 |
20 | var htmlToAdd = "Emby for Samsung Smart TVs is a free, opensource community project. A broad range of Smarthub devices are supported due to the generously donated time and efforts of, among others, the following people.
";
21 | htmlToAdd += "Feedback on this and other Emby products is gratefully received at emby.media/community.
"
22 | htmlToAdd += "
Main Developers ";
23 | for (var index = 0; index < this.MainDevs.length; index++) {
24 | if (index % 6 == 0) {
25 | htmlToAdd += " ";
26 | }
27 | htmlToAdd += "" + this.MainDevs[index] + " ";
28 | if (index+1 % 6 == 0) {
29 | htmlToAdd += " ";
30 | }
31 | }
32 | htmlToAdd += "
";
33 | htmlToAdd += "
Contributing Developers ";
34 | for (var index = 0; index < this.ContribDevs.length; index++) {
35 | if (index % 6 == 0) {
36 | htmlToAdd += " ";
37 | }
38 | htmlToAdd += "" + this.ContribDevs[index] + " ";
39 | if (index+1 % 6 == 0) {
40 | htmlToAdd += " ";
41 | }
42 | }
43 | htmlToAdd += "
";
44 | htmlToAdd += "
Donators, supporters and valued beta testers. ";
45 | for (var index = 0; index < this.DonateSupport.length; index++) {
46 | if (index % 7 == 0) {
47 | htmlToAdd += " ";
48 | }
49 | htmlToAdd += "" + this.DonateSupport[index] + " ";
50 | if (index+1 % 7 == 0) {
51 | htmlToAdd += " ";
52 | }
53 | }
54 |
55 | document.getElementById("ContentAbout").innerHTML = htmlToAdd + "
";
56 |
57 | //Set Focus for Key Events
58 | document.getElementById("GuiPage_Contributors").focus();
59 | }
60 |
61 |
62 | GuiPage_Contributors.keyDown = function() {
63 | var keyCode = event.keyCode;
64 | alert("Key pressed: " + keyCode);
65 |
66 | if (document.getElementById("Notifications").style.visibility == "") {
67 | document.getElementById("Notifications").style.visibility = "hidden";
68 | document.getElementById("NotificationText").innerHTML = "";
69 | widgetAPI.blockNavigation(event);
70 | //Change keycode so it does nothing!
71 | keyCode = "VOID";
72 | }
73 |
74 | //Update Screensaver Timer
75 | Support.screensaver();
76 |
77 | //If screensaver is running
78 | if (Main.getIsScreensaverRunning()) {
79 | //Update Main.js isScreensaverRunning - Sets to True
80 | Main.setIsScreensaverRunning();
81 |
82 | //End Screensaver
83 | GuiImagePlayer_Screensaver.stopScreensaver();
84 |
85 | //Change keycode so it does nothing!
86 | keyCode = "VOID";
87 | }
88 |
89 | switch(keyCode) {
90 | case tvKey.KEY_LEFT:
91 | alert("LEFT");
92 | this.openMenu();
93 | break;
94 | case tvKey.KEY_RETURN:
95 | alert("RETURN");
96 | widgetAPI.blockNavigation(event);
97 | Support.processReturnURLHistory();
98 | break;
99 | case tvKey.KEY_BLUE:
100 | GuiMusicPlayer.showMusicPlayer("GuiPage_Contributors");
101 | break;
102 | case tvKey.KEY_TOOLS:
103 | widgetAPI.blockNavigation(event);
104 | this.openMenu();
105 | break;
106 | case tvKey.KEY_EXIT:
107 | alert ("EXIT KEY");
108 | widgetAPI.sendExitEvent();
109 | break;
110 | }
111 | }
112 |
113 | GuiPage_Contributors.openMenu = function() {
114 | Support.updateURLHistory("GuiPage_Contributors",null,null,null,null,null,null,null);
115 | GuiMainMenu.requested("GuiPage_Contributors",null);
116 | }
--------------------------------------------------------------------------------
/app/javascript/Gui/GuiImagePlayer/GuiImagePlayer_Screensaver.js:
--------------------------------------------------------------------------------
1 | var GuiImagePlayer_Screensaver = {
2 | ImageViewer : null,
3 | newItemData : null,
4 | imagesToUse : "MetaData",
5 |
6 | Timeout : null,
7 |
8 | images : [],
9 | overlay : [],
10 | imageIdx : 0, // Image index
11 | effectIdx : 0, // Transition effect index
12 | effectNames : ['FADE1', 'FADE2', 'BLIND', 'SPIRAL','CHECKER', 'LINEAR', 'STAIRS', 'WIPE', 'RANDOM'],
13 | }
14 |
15 | GuiImagePlayer_Screensaver.kill = function() {
16 | if (this.ImageViewer != null) {
17 | this.ImageViewer.destroy();
18 | }
19 | }
20 |
21 | GuiImagePlayer_Screensaver.start = function() {
22 | this.imagesToUse = File.getUserProperty("ScreensaverImages");
23 | alert(this.imagesToUse);
24 | this.images = []
25 | this.overlay = []
26 | this.imageIdx = 0
27 | //alert("imagestouse - " + this.imagesToUse)
28 | //Update Main.js isScreensaverRunning - Sets to True
29 | Main.setIsScreensaverRunning();
30 |
31 | //Hide helper page if shown
32 | GuiHelper.keyDown();
33 |
34 | //Hide the trailer PiP window if shown
35 | if (Main.getModelYear() != "D") {
36 | sf.service.VideoPlayer.stop();
37 | sf.service.VideoPlayer.hide();
38 | }
39 |
40 | Support.styleSubtitles("GuiImagePlayer_ScreensaverOverlay")
41 |
42 | if (this.imagesToUse == "Media") {
43 | var randomImageURL = Server.getItemTypeURL("&SortBy=Random&MediaTypes=Photo&Recursive=true&CollapseBoxSetItems=false&Limit=1000");
44 | var randomImageData = Server.getContent(randomImageURL);
45 | if (randomImageData == null) { return; }
46 |
47 | for (var index = 0; index < randomImageData.Items.length; index++) {
48 | //Only add images with higher res
49 | if (randomImageData.Items[index].Width >= 1920 && randomImageData.Items[index].Height >= 1080){
50 | var imgsrc = Server.getScreenSaverImageURL(randomImageData.Items[index].Id,"Primary",1920,1080);
51 | this.images.push(imgsrc);
52 | if (randomImageData.Items[index].PremiereDate !== undefined) {
53 | this.overlay.push(Support.formatDateTime(randomImageData.Items[index].PremiereDate,1))
54 | } else {
55 | this.overlay.push(""); //Need to push something to keep indexes matched up!
56 | }
57 |
58 | }
59 | }
60 | } else {
61 | var randomImageURL = Server.getItemTypeURL("&SortBy=Random&IncludeItemTypes=Series,Movie&Recursive=true&CollapseBoxSetItems=false&Limit=1000");
62 | var randomImageData = Server.getContent(randomImageURL);
63 | if (randomImageData == null) { return; }
64 |
65 | for (var index = 0; index < randomImageData.Items.length; index++) {
66 | if (randomImageData.Items[index].BackdropImageTags.length > 0) {
67 | var imgsrc = Server.getScreenSaverImageURL(randomImageData.Items[index ].Id,"Backdrop",1920,1080);
68 | this.images.push(imgsrc);
69 | if (randomImageData.Items[index].Name !== undefined) {
70 | this.overlay.push(randomImageData.Items[index].Name)
71 | } else {
72 | this.overlay.push(""); //Need to push something to keep indexes matched up!
73 | }
74 |
75 | }
76 | }
77 | }
78 |
79 | //Hide Page Contents
80 | document.getElementById("everything").style.visibility="hidden";
81 |
82 | //Initialte new instance, set Frame Area & Set Notifications
83 | this.ImageViewer = new CImageViewer('Common ImageViewer');
84 | this.ImageViewer.setFrameArea(0, 0, Main.width, Main.height);
85 |
86 | this.ImageViewer.setOnNetworkError(function() {
87 | GuiNotifications.setNotification("Network Error");
88 | });
89 |
90 | this.ImageViewer.setOnRenderError(function() {
91 | GuiNotifications.setNotification("Render Error");
92 | });
93 |
94 | //Start Slide Show
95 | this.ImageViewer.show();
96 | this.setSlideshowMode();
97 | }
98 |
99 | // Set Slideshow mode
100 | // You can use Transtion effect
101 | GuiImagePlayer_Screensaver.setSlideshowMode = function() {
102 | this.ImageViewer.startSlideshow();
103 | this.ImageViewer.setOnBufferingComplete(function(){
104 | GuiImagePlayer_Screensaver.ImageViewer.showNow();
105 | });
106 | this.ImageViewer.setOnRenderingComplete(function(){
107 | clearTimeout(GuiImagePlayer_Screensaver.Timeout);
108 | if (GuiImagePlayer_Screensaver.imagesToUse == "Media") {
109 | Support.setImagePlayerOverlay(GuiImagePlayer_Screensaver.overlay[GuiImagePlayer_Screensaver.imageIdx], GuiImagePlayer.overlayFormat);
110 | } else {
111 | Support.setImagePlayerOverlay(GuiImagePlayer_Screensaver.overlay[GuiImagePlayer_Screensaver.imageIdx], 2);
112 | }
113 |
114 | GuiImagePlayer_Screensaver.Timeout = setTimeout(function(){
115 | GuiImagePlayer_Screensaver.imageIdx = GuiImagePlayer_Screensaver.imageIdx+1;
116 | if (GuiImagePlayer_Screensaver.imageIdx >= GuiImagePlayer_Screensaver.images.length ) {
117 | GuiImagePlayer_Screensaver.imageIdx = 0;
118 | }
119 | GuiImagePlayer_Screensaver.ImageViewer.prepareNext(GuiImagePlayer_Screensaver.images[GuiImagePlayer_Screensaver.imageIdx], GuiImagePlayer_Screensaver.ImageViewer.Effect.FADE1);
120 | }, File.getUserProperty("ScreensaverImageTime"));
121 | });
122 |
123 | this.ImageViewer.stop();
124 | this.playImage();
125 | }
126 |
127 | // Play image - only called once in slideshow!
128 | //SS calls play -> BufferComplete, then the showNow will call RendComplete which starts timer for next image
129 | GuiImagePlayer_Screensaver.playImage = function() {
130 | var url = GuiImagePlayer_Screensaver.images[GuiImagePlayer_Screensaver.imageIdx];
131 | GuiImagePlayer_Screensaver.ImageViewer.play(url, 1920, 1080);
132 | }
133 |
134 | GuiImagePlayer_Screensaver.stopScreensaver = function() {
135 | clearTimeout(this.Timeout);
136 | this.Timeout = null;
137 | this.images = [];
138 | this.ImageViewer.endSlideshow();
139 | this.ImageViewer.hide();
140 | widgetAPI.blockNavigation(event);
141 | GuiImagePlayer_Screensaver.kill();
142 | document.getElementById("GuiImagePlayer_ScreensaverOverlay").innerHTML = "";
143 | //Show Page Contents
144 | document.getElementById("everything").style.visibility="";
145 | }
--------------------------------------------------------------------------------
/app/javascript/Gui/GuiPage_Servers.js:
--------------------------------------------------------------------------------
1 | var GuiPage_Servers = {
2 | ServerData : null,
3 |
4 | selectedItem : 0,
5 | topLeftItem : 0,
6 | isAddButton : false,
7 | MAXCOLUMNCOUNT : 3,
8 | MAXROWCOUNT : 1
9 | }
10 |
11 | GuiPage_Servers.getMaxDisplay = function() {
12 | return this.MAXCOLUMNCOUNT * this.MAXROWCOUNT;
13 | }
14 |
15 | GuiPage_Servers.start = function(runAutoLogin) {
16 | alert("Page Enter : GuiPage_Servers");
17 | GuiHelper.setControlButtons("Default ",null,null,"Delete","Exit");
18 |
19 | //Reset Properties
20 | this.selectedItem = 0;
21 | this.topLeftItem = 0;
22 | this.isAddButton = false;
23 |
24 | //Load Data
25 | this.ServerData = JSON.parse(File.loadFile());
26 | if (this.ServerData.Servers.length == 0) {
27 | //Should never happen - Redirect to
28 | GuiPage_NewServer.start();
29 | } else {
30 | Support.removeSplashScreen();
31 |
32 | //Change Display
33 | document.getElementById("pageContent").innerHTML = "
" +
35 | "
Add a New Server
" +
36 | "
" +
37 | "
Use the RED button to set the selected server as the default auto connect server
" +
38 | "
Use the BLUE button to delete the selected server
";
39 |
40 | this.updateDisplayedUsers();
41 | this.updateSelectedUser();
42 |
43 | //Set Backdrop
44 | Support.fadeImage("images/bg1.jpg");
45 |
46 | //Set focus to element in Index that defines keydown method! This enables keys to work :D
47 | document.getElementById("GuiPage_Servers").focus();
48 | }
49 |
50 | }
51 |
52 | GuiPage_Servers.updateDisplayedUsers = function() {
53 | var htmltoadd = "";
54 | for (var index = this.topLeftItem; index < (Math.min(this.topLeftItem + this.getMaxDisplay(),this.ServerData.Servers.length)); index++) {
55 | htmltoadd += "
";
56 | }
57 |
58 | //Set Content to Server Data
59 | document.getElementById("GuiPage_Servers_allusers").innerHTML = htmltoadd;
60 | }
61 |
62 | //Function sets CSS Properties so show which user is selected
63 | GuiPage_Servers.updateSelectedUser = function () {
64 | Support.updateSelectedNEW(this.ServerData.Servers,this.selectedItem,this.topLeftItem,
65 | Math.min(this.topLeftItem + GuiPage_Servers.getMaxDisplay(),this.ServerData.Servers.length),"User Selected highlight1Boarder","User","");
66 | }
67 |
68 | //Function executes on the selection of a user - should log user in or generate error message on screen
69 | GuiPage_Servers.processSelectedUser = function () {
70 | if (this.isAddButton == true) {
71 | GuiPage_NewServer.start();
72 | } else {
73 | File.setServerEntry(this.selectedItem);
74 | Server.testConnectionSettings(this.ServerData.Servers[this.selectedItem].Path,true);
75 | }
76 | }
77 |
78 | GuiPage_Servers.keyDown = function()
79 | {
80 | var keyCode = event.keyCode;
81 | alert("Key pressed: " + keyCode);
82 |
83 | if (document.getElementById("Notifications").style.visibility == "") {
84 | document.getElementById("Notifications").style.visibility = "hidden";
85 | document.getElementById("NotificationText").innerHTML = "";
86 | widgetAPI.blockNavigation(event);
87 | //Change keycode so it does nothing!
88 | keyCode = "VOID";
89 | }
90 |
91 | switch(keyCode)
92 | {
93 | case tvKey.KEY_RETURN:
94 | alert("RETURN");
95 | widgetAPI.sendReturnEvent();
96 | break;
97 | case tvKey.KEY_LEFT:
98 | alert("LEFT");
99 | this.selectedItem--;
100 | if (this.selectedItem < 0) {
101 | this.selectedItem = this.ServerData.Servers.length - 1;
102 | if(this.ServerData.Servers.length > this.MAXCOLUMNCOUNT) {
103 | this.topLeftItem = (this.selectedItem-2);
104 | this.updateDisplayedUsers();
105 | } else {
106 | this.topLeftItem = 0;
107 | }
108 | } else {
109 | if (this.selectedItem < this.topLeftItem) {
110 | this.topLeftItem--;
111 | if (this.topLeftItem < 0) {
112 | this.topLeftItem = 0;
113 | }
114 | this.updateDisplayedUsers();
115 | }
116 | }
117 | this.updateSelectedUser();
118 | break;
119 | case tvKey.KEY_RIGHT:
120 | alert("RIGHT");
121 | this.selectedItem++;
122 | if (this.selectedItem >= this.ServerData.Servers.length) {
123 | this.selectedItem = 0;
124 | this.topLeftItem = 0;
125 | this.updateDisplayedUsers();
126 | } else {
127 | if (this.selectedItem >= this.topLeftItem+this.getMaxDisplay() ) {
128 | this.topLeftItem++;
129 | this.updateDisplayedUsers();
130 | }
131 | }
132 | this.updateSelectedUser();
133 | break;
134 | case tvKey.KEY_DOWN:
135 | this.isAddButton = true;
136 | document.getElementById(this.ServerData.Servers[this.selectedItem].Id).className = "User";
137 | document.getElementById("GuiPage_Servers_addnew").style.border = "2px solid red";
138 | break;
139 | case tvKey.KEY_UP:
140 | this.isAddButton = false;
141 | document.getElementById(this.ServerData.Servers[this.selectedItem].Id).className = "User Selected";
142 | document.getElementById("GuiPage_Servers_addnew").style.border = "2px solid black";
143 | break;
144 | case tvKey.KEY_ENTER:
145 | case tvKey.KEY_PANEL_ENTER:
146 | alert("ENTER");
147 | GuiPage_Servers.processSelectedUser();
148 | break;
149 | case tvKey.KEY_RED:
150 | File.setDefaultServer(this.selectedItem);
151 | break;
152 | case tvKey.KEY_YELLOW:
153 | File.deleteSettingsFile();
154 | widgetAPI.sendExitEvent();
155 | case tvKey.KEY_BLUE:
156 | File.deleteServer(this.selectedItem);
157 | break;
158 | case tvKey.KEY_EXIT:
159 | alert ("EXIT KEY");
160 | widgetAPI.sendExitEvent();
161 | break;
162 | default:
163 | alert("Unhandled key");
164 | break;
165 | }
166 | };
--------------------------------------------------------------------------------
/app/javascript/Gui/GuiPage_NewServer.js:
--------------------------------------------------------------------------------
1 | var GuiPage_NewServer = {
2 | elementIds : [ "1","2","3","4","port","host"],
3 | inputs : [ null,null,null,null,null],
4 | ready : [ false,false,false,false,false],
5 |
6 | }
7 |
8 | GuiPage_NewServer.start = function() {
9 | alert("Page Enter : GuiPage_NewServer");
10 | GuiHelper.setControlButtons(null,null,null,null,"Return");
11 |
12 | //Insert html into page
13 | document.getElementById("pageContent").innerHTML = "
\
14 |
Enter the IP address & port number of your Emby server. (You can leave the port blank for 8096)
\
15 |
\ \
20 |
OR
\
21 |
Enter your server hostname here without http:// and including : and port number.
\
22 |
\
23 |
";
24 |
25 | //Set Backdrop
26 | Support.fadeImage("images/bg1.jpg");
27 | Support.removeSplashScreen();
28 |
29 | //Prepare all input elements for IME
30 | GuiPage_NewServer.createInputObjects();
31 | pluginAPI.registIMEKey();
32 | }
33 |
34 | //Prepare all input elements for IME on Load!
35 | GuiPage_NewServer.createInputObjects = function() {
36 | var previousIndex = 0;
37 | var nextIndex = 0;
38 | for (var index in this.elementIds) {
39 | previousIndex = index - 1;
40 | if (previousIndex < 0) {
41 | previousIndex = GuiPage_NewServer.inputs.length - 1;
42 | }
43 |
44 | nextIndex = (previousIndex + 2) % GuiPage_NewServer.inputs.length;
45 | GuiPage_NewServer.inputs[index] = new GuiPage_NewServer_Input(this.elementIds[index],this.elementIds[previousIndex], this.elementIds[nextIndex]);
46 | }
47 | }
48 |
49 | //Function to check if IME is ready, and when so sets focus on first element in array
50 | GuiPage_NewServer.ready = function(id) {
51 | var ready = true;
52 |
53 | for (var i in GuiPage_NewServer.elementIds) {
54 | if (GuiPage_NewServer.elementIds[i] == id) {
55 | GuiPage_NewServer.ready[i] = true;
56 | }
57 |
58 | if (GuiPage_NewServer.ready[i] == false) {
59 | ready = false;
60 | }
61 | }
62 |
63 | if (ready) {
64 | document.getElementById(GuiPage_NewServer.elementIds[0]).focus();
65 | }
66 | }
67 |
68 | //Function to delete all the contents of the boxes
69 | GuiPage_NewServer.deleteAllBoxes = function(currentId) {
70 | for (var index = 0;index < GuiPage_NewServer.elementIds.length;index++) {
71 | document.getElementById(GuiPage_NewServer.elementIds[index]).value="";
72 | }
73 | }
74 |
75 | //IME Key Handler
76 | var GuiPage_NewServer_Input = function(id,previousId, nextId) {
77 | var imeReady = function(imeObject) {
78 | installFocusKeyCallbacks();
79 | GuiPage_NewServer.ready(id);
80 | }
81 |
82 | var ime = new IMEShell(id, imeReady,'en');
83 | ime.setKeypadPos(1300,90);
84 | ime.setMode('_num');
85 |
86 | var previousElement = document.getElementById(previousId);
87 | var nextElement = document.getElementById(nextId);
88 |
89 | var installFocusKeyCallbacks = function () {
90 | ime.setKeyFunc(tvKey.KEY_ENTER, function (keyCode) {
91 | alert("Enter key pressed");
92 |
93 | GuiNotifications.setNotification("Please Wait","Checking Details",true);
94 |
95 | //Get content from 4 boxes
96 | var IP1 = document.getElementById('1').value;
97 | var IP2 = document.getElementById('2').value;
98 | var IP3 = document.getElementById('3').value;
99 | var IP4 = document.getElementById('4').value;
100 |
101 | var host = document.getElementById('host').value;
102 |
103 | if (IP1 == "" || IP2 == "" || IP3 == "" || IP4 == "" ) {
104 | //Check if host is empty
105 | if (host == "") {
106 | //not valid
107 | GuiNotifications.setNotification("Please re-enter your server details.","Incorrect Details",true);
108 | } else {
109 | document.getElementById("pageContent").focus();
110 | //Timeout required to allow notification command above to be displayed
111 | setTimeout(function(){Server.testConnectionSettings(host,false);}, 1000);
112 | }
113 | } else {
114 | var Port = document.getElementById('port').value;
115 | if (Port == "") {
116 | Port = "8096";
117 | }
118 |
119 | var ip = IP1 + '.' + IP2 + '.' + IP3 + '.' + IP4 + ':' + Port;
120 | document.getElementById("pageContent").focus();
121 | //Timeout required to allow notification command above to be displayed
122 | setTimeout(function(){Server.testConnectionSettings(ip,false);}, 1000);
123 |
124 | }
125 | });
126 | ime.setKeyFunc(tvKey.KEY_LEFT, function (keyCode) {
127 | previousElement.focus();
128 | return false;
129 | });
130 | ime.setKeyFunc(tvKey.KEY_RIGHT, function (keyCode) {
131 | nextElement.focus();
132 | return false;
133 | });
134 | ime.setKeyFunc(tvKey.KEY_UP, function (keyCode) {
135 | document.getElementById("1").focus();
136 | return false;
137 | });
138 | ime.setKeyFunc(tvKey.KEY_DOWN, function (keyCode) {
139 | document.getElementById("host").focus();
140 | return false;
141 | });
142 | ime.setKeyFunc(tvKey.KEY_BLUE, function (keyCode) {
143 | ime.setString(""); //Clears the currently focused Input - REQUIRED
144 | GuiPage_NewServer.deleteAllBoxes();
145 | return false;
146 | });
147 | ime.setKeyFunc(tvKey.KEY_RETURN, function (keyCode) {
148 | widgetAPI.blockNavigation(event);
149 | var fileJson = JSON.parse(File.loadFile());
150 | if (fileJson.Servers.length > 0) {
151 | document.getElementById("pageContent").focus();
152 | GuiPage_Servers.start();
153 | } else {
154 | widgetAPI.sendReturnEvent();
155 | }
156 | return false;
157 | });
158 | ime.setKeyFunc(tvKey.KEY_EXIT, function (keyCode) {
159 | widgetAPI.sendExitEvent();
160 | return false;
161 | });
162 | }
163 | }
--------------------------------------------------------------------------------
/app/javascript/Gui/GuiUsers_Manual.js:
--------------------------------------------------------------------------------
1 | var GuiUsers_Manual = {
2 | UserData : null,
3 | selectedItem : 0, //0 = User, 1 = Password
4 | rememberPassword : false
5 | }
6 |
7 | GuiUsers_Manual.start = function() {
8 | alert("Page Enter : GuiUsers_Manual");
9 | GuiHelper.setControlButtons(null,null,null,null,"Return");
10 |
11 | //Reset Properties
12 | this.selectedItem = 0;
13 | this.rememberPassword = false;
14 |
15 | document.getElementById("NotificationText").innerHTML = "";
16 | document.getElementById("Notifications").style.visibility = "hidden";
17 |
18 | //Load Data
19 | var url = Server.getServerAddr() + "/Users/Public?format=json";
20 | this.UserData = Server.getContent(url);
21 | if (this.UserData == null) { return; }
22 |
23 | //Change Display
24 | document.getElementById("pageContent").innerHTML = "
\
25 |
Username
\
26 |
\
27 |
Password
\
28 |
\
29 |
Remember Password :
" + this.rememberPassword + " \
30 |
";
31 |
32 | new GuiUsers_Manual_Input("user");
33 | }
34 |
35 | GuiUsers_Manual.IMEAuthenticate = function(user, password) {
36 | var authenticateSuccess = Server.Authenticate(null, user, password);
37 | if (authenticateSuccess) {
38 | document.getElementById("NoKeyInput").focus();
39 |
40 | //Check if this user is already in the DB.
41 | var userInFile = false;
42 | var fileJson = JSON.parse(File.loadFile());
43 | for (var index = 0; index < fileJson.Servers[File.getServerEntry()].Users.length; index++) {
44 | if (fileJson.Servers[File.getServerEntry()].Users[index].UserName == user) {
45 | userInFile = true;
46 | File.setUserEntry(index);
47 | }
48 | }
49 |
50 | //Otherwise add them.
51 | if (userInFile == false) {
52 | alert("Need to add the user to the DB");
53 | //Add Username & Password to DB - Save password only if rememberPassword = true
54 | if (this.rememberPassword == true) {
55 | File.addUser(Server.UserID,user,password,this.rememberPassword);
56 | } else {
57 | File.addUser(Server.UserID,user,"",this.rememberPassword);
58 | }
59 | }
60 |
61 | //Change Focus and call function in GuiMain to initiate the page!
62 | GuiMainMenu.start();
63 | } else {
64 |
65 | alert ("Authentication Failed");
66 | document.getElementById("user").focus();
67 | GuiNotifications.setNotification("Wrong username, bad password or network error.","Logon Error",true);
68 | }
69 | }
70 |
71 | //////////////////////////////////////////////////////////////////
72 | // Input method for entering user password. //
73 | //////////////////////////////////////////////////////////////////
74 | var GuiUsers_Manual_Input = function(id) {
75 | var imeReady = function(imeObject) {
76 | installFocusKeyCallbacks();
77 | document.getElementById(id).focus();
78 | }
79 |
80 | var ime = new IMEShell(id, imeReady,'en');
81 | ime.setKeypadPos(1300,90);
82 |
83 | var installFocusKeyCallbacks = function () {
84 | ime.setKeyFunc(tvKey.KEY_ENTER, function (keyCode) {
85 | alert("Enter key pressed");
86 | if (GuiUsers_Manual.selectedItem == 0) {
87 | //Set IME to Password field
88 | GuiUsers_Manual.selectedItem++;
89 | new GuiUsers_Manual_Input("pass");
90 | document.getElementById("pass").focus;
91 | } else {
92 | //Process Login Here
93 | var usr = document.getElementById("user").value;
94 | var pwd = document.getElementById("pass").value;
95 | GuiUsers_Manual.IMEAuthenticate(usr,pwd);
96 | }
97 | });
98 |
99 | ime.setKeyFunc(tvKey.KEY_DOWN, function (keyCode) {
100 | alert("Down key pressed");
101 | if (GuiUsers_Manual.selectedItem == 0) {
102 | //Set IME to Password field
103 | GuiUsers_Manual.selectedItem++;
104 | new GuiUsers_Manual_Input("pass");
105 | document.getElementById("pass").focus;
106 | } else {
107 | document.getElementById("guiUsers_rempwd").style.color = "red";
108 | document.getElementById("GuiUsers_Manual_Pwd").focus();
109 | }
110 | });
111 |
112 | ime.setKeyFunc(tvKey.KEY_UP, function (keyCode) {
113 | alert("Up key pressed");
114 | if (GuiUsers_Manual.selectedItem == 1) {
115 | //Set IME to Username field
116 | GuiUsers_Manual.selectedItem--;
117 | new GuiUsers_Manual_Input("user");
118 | document.getElementById("user").focus;
119 | }
120 | });
121 |
122 | //Keycode to abort login from password screen
123 | ime.setKeyFunc(tvKey.KEY_RETURN, function (keyCode) {
124 | widgetAPI.blockNavigation(event);
125 | var fileJson = JSON.parse(File.loadFile());
126 | if (fileJson.Servers.length > 0) {
127 | document.getElementById("pageContent").focus();
128 | GuiUsers.start();
129 | }
130 | });
131 |
132 | ime.setKeyFunc(tvKey.KEY_EXIT, function (keyCode) {
133 | document.getElementById("NoKeyInput").focus();
134 | widgetAPI.sendExitEvent();
135 | });
136 | }
137 | };
138 |
139 | GuiUsers_Manual.keyDownPassword = function() {
140 | var keyCode = event.keyCode;
141 | alert("Key pressed: " + keyCode);
142 |
143 | if (document.getElementById("Notifications").style.visibility == "") {
144 | document.getElementById("Notifications").style.visibility = "hidden";
145 | document.getElementById("NotificationText").innerHTML = "";
146 | widgetAPI.blockNavigation(event);
147 | //Change keycode so it does nothing!
148 | keyCode = "VOID";
149 | }
150 |
151 | switch(keyCode)
152 | {
153 | case tvKey.KEY_RETURN:
154 | case tvKey.KEY_PANEL_RETURN:
155 | alert("RETURN");
156 | widgetAPI.sendReturnEvent();
157 | break;
158 | case tvKey.KEY_UP:
159 | if (document.getElementById("guiUsers_rempwd").style.color == "red") {
160 | document.getElementById("guiUsers_rempwd").style.color = "#f9f9f9";
161 | document.getElementById("pass").focus();
162 | } else {
163 | this.rememberPassword = (this.rememberPassword == false) ? true : false;
164 | document.getElementById("guiUsers_rempwdvalue").innerHTML = this.rememberPassword;
165 | }
166 | break;
167 | case tvKey.KEY_DOWN:
168 | if (document.getElementById("guiUsers_rempwdvalue").style.color == "red") {
169 | this.rememberPassword = (this.rememberPassword == false) ? true : false;
170 | document.getElementById("guiUsers_rempwdvalue").innerHTML = this.rememberPassword;
171 | }
172 | break;
173 | case tvKey.KEY_RIGHT:
174 | alert("RIGHT");
175 | if (document.getElementById("guiUsers_rempwd").style.color == "red") {
176 | document.getElementById("guiUsers_rempwd").style.color = "green";
177 | document.getElementById("guiUsers_rempwdvalue").style.color = "red";
178 | }
179 | break;
180 | case tvKey.KEY_LEFT:
181 | alert("LEFT");
182 | if (document.getElementById("guiUsers_rempwdvalue").style.color == "red") {
183 | document.getElementById("guiUsers_rempwd").style.color = "red";
184 | document.getElementById("guiUsers_rempwdvalue").style.color = "#f9f9f9";
185 | }
186 | break;
187 | case tvKey.KEY_ENTER:
188 | case tvKey.KEY_PANEL_ENTER:
189 | alert("ENTER");
190 | if (document.getElementById("guiUsers_rempwdvalue").style.color == "red") {
191 | document.getElementById("guiUsers_rempwd").style.color = "red";
192 | document.getElementById("guiUsers_rempwdvalue").style.color = "#f9f9f9";
193 | } else {
194 | document.getElementById("guiUsers_rempwd").style.color = "green";
195 | document.getElementById("guiUsers_rempwdvalue").style.color = "red";
196 | }
197 | break;
198 | case tvKey.KEY_EXIT:
199 | alert ("EXIT KEY");
200 | widgetAPI.sendExitEvent();
201 | break;
202 | default:
203 | alert("Unhandled key");
204 | break;
205 | }
206 | };
--------------------------------------------------------------------------------
/app/javascript/Gui/GuiPage_SettingsLog.js:
--------------------------------------------------------------------------------
1 | var GuiPage_SettingsLog = {
2 | logArray : null,
3 | selectedBannerItem : 0,
4 | topLeftItem : 0,
5 |
6 | MAXCOLUMNCOUNT : 1,
7 | MAXROWCOUNT : 20,
8 |
9 | bannerItems : ["User Settings","Server Settings","TV Settings","Log","About"],
10 | }
11 |
12 | GuiPage_SettingsLog.onFocus = function() {
13 | GuiHelper.setControlButtons("Clear Log",null,null,GuiMusicPlayer.Status == "PLAYING" || GuiMusicPlayer.Status == "PAUSED" ? "Music" : null,"Return");
14 | }
15 |
16 | GuiPage_SettingsLog.getMaxDisplay = function() {
17 | return this.MAXCOLUMNCOUNT * this.MAXROWCOUNT;
18 | }
19 |
20 | GuiPage_SettingsLog.start = function() {
21 | alert("Page Enter : GuiPage_SettingsLog");
22 |
23 | //Reset Vars
24 | this.selectedBannerItem = 3; //match Logs
25 |
26 | //Load Data
27 | this.logArray = FileLog.loadFile(true);
28 | this.topLeftItem = this.logArray.length - GuiPage_SettingsLog.getMaxDisplay();
29 | this.topLeftItem = (this.topLeftItem < 0) ? 0 : this.topLeftItem;
30 |
31 | //Load Settings
32 | document.getElementById("pageContent").className = "";
33 | document.getElementById("pageContent").innerHTML = "
Log
\ \
34 |
";// +
35 | /*"
" +
36 | "
" +
37 | "
" +
38 | "
";*/
39 |
40 | //Create Banner Items
41 | for (var index = 0; index < this.bannerItems.length; index++) {
42 | if (index != this.bannerItems.length-1) {
43 | document.getElementById("bannerSelection").innerHTML += "
"+this.bannerItems[index].replace(/_/g, ' ')+"
";
44 | } else {
45 | document.getElementById("bannerSelection").innerHTML += "
"+this.bannerItems[index].replace(/_/g, ' ')+"
";
46 | }
47 | }
48 |
49 | //Update Displayed
50 | //this.setText();
51 | this.updateDisplayedItems();
52 | this.updateSelectedBannerItems();
53 | document.getElementById("GuiPage_SettingsLog").focus();
54 | }
55 |
56 | GuiPage_SettingsLog.updateDisplayedItems = function() {
57 | var htmlToAdd = "
";
58 | for (var index = this.topLeftItem; index < Math.min(this.topLeftItem + this.getMaxDisplay(),this.logArray.length); index++) {
59 | htmlToAdd += "" + this.logArray[index] + " ";
60 | }
61 | document.getElementById("guiPage_Settings_Settings").innerHTML = htmlToAdd + "
";
62 | }
63 |
64 | GuiPage_SettingsLog.updateSelectedBannerItems = function() {
65 | for (var index = 0; index < this.bannerItems.length; index++) {
66 | if (index == this.selectedBannerItem) {
67 | if (index != this.bannerItems.length-1) { //Don't put padding on the last one.
68 | document.getElementById("bannerItem"+index).className = "bannerItem bannerItemPadding highlight"+Main.highlightColour+"Text";
69 | } else {
70 | document.getElementById("bannerItem"+index).className = "bannerItem highlight"+Main.highlightColour+"Text";
71 | }
72 | } else {
73 | if (index != this.bannerItems.length-1) { //Don't put padding on the last one.
74 | if (index == 3) {
75 | document.getElementById("bannerItem"+index).className = "bannerItem bannerItemPadding offWhite";
76 | } else {
77 | document.getElementById("bannerItem"+index).className = "bannerItem bannerItemPadding";
78 | }
79 | } else {
80 | if (index == 3) {
81 | document.getElementById("bannerItem"+index).className = "bannerItem offWhite";
82 | } else {
83 | document.getElementById("bannerItem"+index).className = "bannerItem";
84 | }
85 | }
86 | }
87 | }
88 | document.getElementById("Counter").innerHTML = (this.selectedBannerItem + 1) + "/" + (this.bannerItems.length);
89 | }
90 |
91 | GuiPage_SettingsLog.keyDown = function() {
92 | var keyCode = event.keyCode;
93 | alert("Key pressed: " + keyCode);
94 |
95 | if (document.getElementById("Notifications").style.visibility == "") {
96 | document.getElementById("Notifications").style.visibility = "hidden";
97 | document.getElementById("NotificationText").innerHTML = "";
98 | widgetAPI.blockNavigation(event);
99 | //Change keycode so it does nothing!
100 | keyCode = "VOID";
101 | }
102 |
103 | //Update Screensaver Timer
104 | Support.screensaver();
105 |
106 | //If screensaver is running
107 | if (Main.getIsScreensaverRunning()) {
108 | //Update Main.js isScreensaverRunning - Sets to True
109 | Main.setIsScreensaverRunning();
110 |
111 | //End Screensaver
112 | GuiImagePlayer_Screensaver.stopScreensaver();
113 |
114 | //Change keycode so it does nothing!
115 | keyCode = "VOID";
116 | }
117 |
118 | switch(keyCode) {
119 | //Need Logout Key
120 | case tvKey.KEY_UP:
121 | this.processUpKey();
122 | break;
123 | case tvKey.KEY_DOWN:
124 | this.processDownKey();
125 | break;
126 | case tvKey.KEY_LEFT:
127 | this.processLeftKey();
128 | break;
129 | case tvKey.KEY_RIGHT:
130 | this.processRightKey();
131 | break;
132 | case tvKey.KEY_RETURN:
133 | widgetAPI.blockNavigation(event);
134 | Support.processReturnURLHistory();
135 | break;
136 | case tvKey.KEY_ENTER:
137 | case tvKey.KEY_PANEL_ENTER:
138 | this.processSelectedItem();
139 | break;
140 | case tvKey.KEY_RED:
141 | FileLog.empty();
142 | FileLog.write("---------------------------------------------------------------------",true);
143 | FileLog.write("Log File Emptied by User")
144 | GuiPage_SettingsLog.start(); //relead
145 | break;
146 | case tvKey.KEY_BLUE:
147 | GuiMusicPlayer.showMusicPlayer("GuiPage_SettingsLog","bannerItem"+this.selectedBannerItem,"bannerItem bannerItemPadding highlight"+Main.highlightColour+"Text");
148 | break;
149 | case tvKey.KEY_TOOLS:
150 | widgetAPI.blockNavigation(event);
151 | GuiMainMenu.requested("GuiPage_SettingsLog",null);
152 | break;
153 | case tvKey.KEY_EXIT:
154 | widgetAPI.sendExitEvent();
155 | break;
156 | }
157 | }
158 |
159 | GuiPage_SettingsLog.processUpKey = function() {
160 | this.topLeftItem = this.topLeftItem - this.MAXCOLUMNCOUNT;
161 | if (this.topLeftItem == -1) {
162 | this.topLeftItem = 0;
163 | } else {
164 | this.updateDisplayedItems();
165 | }
166 | }
167 |
168 | GuiPage_SettingsLog.processDownKey = function() {
169 | this.topLeftItem = this.topLeftItem + this.MAXCOLUMNCOUNT;
170 | if (this.topLeftItem > this.logArray.length - this.getMaxDisplay()) {
171 | this.topLeftItem = this.topLeftItem - this.MAXCOLUMNCOUNT;
172 | } else {
173 | this.updateDisplayedItems();
174 | }
175 | }
176 |
177 | GuiPage_SettingsLog.processLeftKey = function() {
178 | this.selectedBannerItem--;
179 | if (this.selectedBannerItem < 0) {
180 | this.selectedBannerItem = 0;
181 | this.openMenu();
182 | } else {
183 | this.updateSelectedBannerItems();
184 | }
185 | }
186 |
187 | GuiPage_SettingsLog.openMenu = function() {
188 | document.getElementById("bannerItem0").className = "bannerItem bannerItemPadding";
189 | GuiMainMenu.requested("GuiPage_SettingsLog","bannerItem0","bannerItem bannerItemPadding green");
190 | }
191 |
192 | GuiPage_SettingsLog.processRightKey = function() {
193 | this.selectedBannerItem++;
194 | if (this.selectedBannerItem >= this.bannerItems.length) {
195 | this.selectedBannerItem--;
196 | } else {
197 | this.updateSelectedBannerItems();
198 | }
199 | }
200 |
201 | GuiPage_SettingsLog.processSelectedItem = function() {
202 | if (this.bannerItems[this.selectedBannerItem] == "About") {
203 | Support.updateURLHistory("GuiPage_Settings",null,null,null,null,0,0,null);
204 | GuiPage_Contributors.start();
205 | } else if (this.bannerItems[this.selectedBannerItem] != "Log") {
206 | GuiPage_Settings.start(this.bannerItems[this.selectedBannerItem]);
207 | }
208 | }
209 |
210 | GuiPage_SettingsLog.setText = function() {
211 | document.getElementById("guiPage_Settings_Overview_Title").innerHTML = "Log Viewer";
212 | document.getElementById("guiPage_Settings_Overview_Content").innerHTML = "Press the up arrow to navigate to earlier entries in the log, and down to view later entries. The log opens at the last items in the log.
Press the red button to clear the log.";
213 | }
214 |
215 |
--------------------------------------------------------------------------------
/app/javascript/Main.js:
--------------------------------------------------------------------------------
1 | var widgetAPI = new Common.API.Widget();
2 | var pluginAPI = new Common.API.Plugin();
3 | var tvKey = new Common.API.TVKeyValue();
4 |
5 | var Main =
6 | {
7 | version : "v2.2.5b",
8 | requiredServerVersion : "10.3.2",
9 | requiredDevServerVersion : "3.0.5507.2131",
10 |
11 | //TV Series Version
12 | modelYear : null,
13 | width : 1920,
14 | height : 1080,
15 | backdropWidth : 1920,
16 | backdropHeight : 1080,
17 | posterWidth : 473,
18 | posterHeight : 267,
19 | seriesPosterWidth : 180,
20 | seriesPosterHeight : 270,
21 | seriesPosterLargeWidth : 235,
22 | seriesPosterLargeHeight : 350,
23 |
24 | forceDeleteSettings : false,
25 | highlightColour : 1,
26 |
27 | enableMusic : true,
28 | enableLiveTV : true,
29 | enableCollections : true,
30 | enableChannels : true,
31 | enableImageCache : true,
32 |
33 | enableScreensaver : true,
34 | isScreensaverRunning : false,
35 | };
36 |
37 | Main.getModelYear = function() {
38 | return this.modelYear;
39 | };
40 |
41 | Main.isMusicEnabled = function() {
42 | return this.enableMusic;
43 | };
44 |
45 | Main.isLiveTVEnabled = function() {
46 | return this.enableLiveTV;
47 | };
48 |
49 | Main.isCollectionsEnabled = function() {
50 | return this.enableCollections;
51 | };
52 |
53 | Main.isChannelsEnabled = function() {
54 | return this.enableChannels;
55 | };
56 |
57 | Main.isScreensaverEnabled = function() {
58 | return this.enableScreensaver;
59 | };
60 |
61 | Main.isImageCaching = function() {
62 | return this.enableImageCache;
63 | };
64 |
65 | Main.getRequiredServerVersion = function() {
66 | return this.requiredServerVersion;
67 | };
68 |
69 | Main.getVersion = function() {
70 | return this.version;
71 | };
72 |
73 | Main.getIsScreensaverRunning = function() {
74 | return this.isScreensaverRunning;
75 | };
76 |
77 | Main.setIsScreensaverRunning = function() {
78 | if (this.isScreensaverRunning == false) {
79 | this.isScreensaverRunning = true;
80 | } else {
81 | this.isScreensaverRunning = false;
82 | }
83 | };
84 |
85 | Main.onLoad = function()
86 | {
87 | //Support.removeSplashScreen();
88 | //Setup Logging
89 | FileLog.loadFile(false); // doesn't return contents, done to ensure file exists
90 | FileLog.write("---------------------------------------------------------------------",true);
91 | FileLog.write("Emby Application Started");
92 |
93 | if (Main.isImageCaching()) {
94 | var fileSystemObj = new FileSystem();
95 | fileSystemObj.deleteCommonFile(curWidget.id + '/cache.json');
96 | Support.imageCachejson = JSON.parse('{"Images":[]}');
97 | }
98 |
99 | document.getElementById("splashscreen_version").innerHTML = Main.version;
100 |
101 | //Turn ON screensaver
102 | pluginAPI.setOnScreenSaver();
103 | FileLog.write("Screensaver enabled.");
104 | Support.clock();
105 | widgetAPI.sendReadyEvent();
106 | window.onShow = Main.initKeys();
107 |
108 | //Set DeviceID & Device Name
109 | var NNaviPlugin = document.getElementById("pluginObjectNNavi");
110 | var pluginNetwork = document.getElementById("pluginObjectNetwork");
111 | var pluginTV = document.getElementById("pluginObjectTV");
112 | FileLog.write("Plugins initialised.");
113 |
114 | var ProductType = pluginNetwork.GetActiveType();
115 | FileLog.write("Product type is "+ProductType);
116 | var phyConnection = pluginNetwork.CheckPhysicalConnection(ProductType); //returns -1
117 | FileLog.write("Check physical connection returned "+phyConnection);
118 | var http = pluginNetwork.CheckHTTP(ProductType); //returns -1
119 | FileLog.write("Check HTTP returned "+http);
120 | var gateway = pluginNetwork.CheckGateway(ProductType); //returns -1
121 | FileLog.write("Check gateway returned "+gateway);
122 |
123 | //Get the model year - Used for transcoding
124 | if (pluginTV.GetProductCode(0).substring(0,2) == "HT" || pluginTV.GetProductCode(0).substring(0,2) == "BD"){
125 | this.modelYear = pluginTV.GetProductCode(0).substring(3,4);
126 |
127 | } else if (pluginTV.GetProductCode(0).substring(4,7) == "H52") {
128 | this.modelYear = "F";
129 | } else if (pluginTV.GetProductCode(0).substring(4,7) == "J43") {
130 | this.modelYear = "F";
131 | } else if (pluginTV.GetProductCode(0).substring(4,7) == "J52") {
132 | this.modelYear = "F";
133 | } else if (pluginTV.GetProductCode(0).substring(4,7) == "J53") {
134 | this.modelYear = "F";
135 | } else if (pluginTV.GetProductCode(0).substring(4,7) == "J62") {
136 | this.modelYear = "F";
137 | } else if (pluginTV.GetProductCode(0).substring(4,7) == "J55") {
138 | this.modelYear = "H";
139 | } else if (pluginTV.GetProductCode(0).substring(4,7) == "J63") {
140 | this.modelYear = "H";
141 | } else if (pluginTV.GetProductCode(0).substring(4,7) == "J64") {
142 | this.modelYear = "H";
143 | } else if (pluginTV.GetProductCode(0).substring(4,6) == "HU") {
144 | this.modelYear = "HU";
145 | } else if (pluginTV.GetProductCode(0).substring(4,7) == "K85") {
146 | this.modelYear = "HU";
147 | } else {
148 | this.modelYear = pluginTV.GetProductCode(0).substring(4,5);
149 | }
150 | FileLog.write("Model Year is " + this.modelYear);
151 |
152 | if (phyConnection && http && gateway) {
153 | var MAC = pluginNetwork.GetMAC(1);
154 | if (MAC == false || MAC == null) { //Set mac to fake
155 | MAC = "0123456789ab" ;
156 | }
157 | FileLog.write("MAC address is "+MAC);
158 | Server.setDevice ("Samsung " + pluginTV.GetProductCode(0));
159 | Server.setDeviceID(NNaviPlugin.GetDUID(MAC));
160 |
161 | //Load Settings File - Check if file needs to be deleted due to development
162 | var fileJson = JSON.parse(File.loadFile());
163 | var version = File.checkVersion(fileJson);
164 | if (version == "Undefined" ) {
165 | //Delete Settings file and reload
166 | File.deleteSettingsFile();
167 | fileJson = JSON.parse(File.loadFile());
168 | } else if (version != this.version) {
169 | if (this.forceDeleteSettings == true) {
170 | //Delete Settings file and reload
171 | File.deleteSettingsFile();
172 | fileJson = JSON.parse(File.loadFile());
173 | } else {
174 | //Update version in settings file to current version
175 | fileJson.Version = this.version;
176 | } File.writeAll(fileJson);
177 | }
178 |
179 | //Allow Evo Kit owners to override the model year.
180 | if (fileJson.TV.ModelOverride != "None") {
181 | switch(fileJson.TV.ModelOverride){
182 | case "SEK1000":
183 | this.modelYear = "F";
184 | break;
185 | case "SEK2000":
186 | this.modelYear = "H";
187 | break;
188 | case "SEK2500":
189 | this.modelYear = "H";
190 | break;
191 | }
192 | FileLog.write("Model Year Override: " + this.modelYear);
193 | }
194 |
195 | //Check if Server exists
196 | if (fileJson.Servers.length > 1) {
197 | //If no default show user Servers page (Can set default on that page)
198 | var foundDefault = false;
199 | for (var index = 0; index < fileJson.Servers.length; index++) {
200 | if (fileJson.Servers[index].Default == true) {
201 | foundDefault = true;
202 | FileLog.write("Default server found.");
203 | File.setServerEntry(index);
204 | Server.testConnectionSettings(fileJson.Servers[index].Path,true);
205 | break;
206 | }
207 | }
208 | if (foundDefault == false) {
209 | FileLog.write("Multiple servers defined. Loading the select server page.");
210 | GuiPage_Servers.start();
211 | }
212 | } else if (fileJson.Servers.length == 1) {
213 | //If 1 server auto login with that
214 | FileLog.write("Emby server name found in settings. Auto-connecting.");
215 | File.setServerEntry(0);
216 | Server.testConnectionSettings(fileJson.Servers[0].Path,true);
217 | } else {
218 | //No Server Defined - Load GuiPage_IP
219 | FileLog.write("No server defined. Loading the new server page.");
220 | GuiPage_NewServer.start();
221 | }
222 | } else {
223 | document.getElementById("pageContent").innerHTML = "You have no network connectivity to the TV - Please check the settings on the TV";
224 | }
225 | };
226 |
227 | Main.initKeys = function() {
228 | pluginAPI.registKey(tvKey.KEY_TOOLS);
229 | pluginAPI.registKey(tvKey.KEY_3D);
230 | FileLog.write("Key handlers initialised.");
231 | };
232 |
233 | Main.onUnload = function()
234 | {
235 | //Write Cache to disk
236 | ImageCache.writeAll(Support.imageCachejson);
237 | Support.screensaverOff();
238 | GuiImagePlayer.kill();
239 | GuiMusicPlayer.stopOnAppExit();
240 | GuiPlayer.stopOnAppExit();
241 | pluginAPI.unregistKey(tvKey.KEY_TOOLS);
242 | pluginAPI.unregistKey(tvKey.KEY_3D);
243 | };
244 |
--------------------------------------------------------------------------------
/app/javascript/Support/GuiHelper.js:
--------------------------------------------------------------------------------
1 | var GuiHelper = {
2 | helpPage : null
3 | }
4 |
5 | //------------------------------------------------------------------------------------------------
6 | //GUIHelper isn't its own window, it just controls the help contents at the bottom of the screen
7 | //------------------------------------------------------------------------------------------------
8 | GuiHelper.toggleHelp = function(helpPage) {
9 | this.helpPage = helpPage;
10 | if (document.getElementById("GuiImagePlayer_ScreensaverOverlay").style.visibility == ""){
11 | document.getElementById("GuiImagePlayer_ScreensaverOverlay").style.visibility = "hidden";
12 | }
13 | GuiHelper.setHelpPage(helpPage);
14 |
15 | //Unhide help window
16 | document.getElementById("Help").style.visibility = "";
17 |
18 | //Set focus
19 | document.getElementById("GuiHelper").focus();
20 | }
21 |
22 | GuiHelper.keyDown = function() {
23 | var keyCode;
24 | if (event) {
25 | keyCode = event.keyCode;
26 | } else {
27 | return;
28 | }
29 |
30 | switch(keyCode) {
31 | case tvKey.KEY_YELLOW:
32 | case tvKey.KEY_RETURN:
33 |
34 | //Stops Return causing the app to exit when closing help text.
35 | widgetAPI.blockNavigation(event);
36 |
37 | if (document.getElementById("GuiImagePlayer_ScreensaverOverlay").style.visibility == "hidden"){
38 | document.getElementById("GuiImagePlayer_ScreensaverOverlay").style.visibility = "";
39 | }
40 |
41 | //If required for Screensaver call in GuiImagePlayer_Screensaver
42 | if (document.getElementById("Help").style.visibility == "") {
43 | //Hide help window
44 | document.getElementById("Help").style.visibility = "hidden";
45 |
46 | //Set focus back to original page
47 | document.getElementById(this.helpPage).focus();
48 | }
49 | break;
50 | }
51 | }
52 |
53 | GuiHelper.setHelpPage = function(helpPage) {
54 | //switch (helpPage) {
55 | //case "GuiPage_IP":
56 | // document.getElementById("Help").innerHTML = "Welcome to a IP";
57 | // break;
58 | //case "GuiUsers":
59 | // document.getElementById("Help").innerHTML = "Welcome to a User";
60 | // break;
61 | //case "GuiDisplayOneItem":
62 | // document.getElementById("Help").innerHTML = this.generateDisplayOneItemHelp();
63 | // break;
64 | //default:
65 | //document.getElementById("Help").innerHTML = "Welcome to a page with no help written!";
66 | document.getElementById("HelpTitle").innerHTML = "Help Page";
67 | document.getElementById("HelpContent").innerHTML = this.generateDisplayOneItemHelp();
68 | // break;
69 | //}
70 | }
71 |
72 | GuiHelper.generateDisplayOneItemHelp = function() {
73 | if (this.helpPage == "GuiImagePlayer") {
74 | var htmlToAdd = "Return, Stop - Ends slideshow and returns the user to the previous screen.
" +
75 | "Left, Right - Move 1 image backwards or forwards.
" +
76 | "Pause - Pause slideshow.
" +
77 | "Play - Resume slideshow.
" +
78 | "Red - Mark photo as a favourite.
" +
79 | "Green - Toggle Date/Time overlay; None | Date | Date : Time
" +
80 | "Yellow - Show this help message.
" +
81 | "Blue - When music is playing, show the music player controls. ";
82 | } else {
83 | var htmlToAdd = "Tools - Show the main menu.
" +
84 | "Return - Returns the user to the previous screen.
" +
85 | "Up, Down, Left, Right - Navigation Control.
" +
86 | "Enter - Select the highlighted item.
" +
87 | "Red - Add or remove an item on the favourites page.
" +
88 | "Green - Mark a video item as watched or unwatched.
" +
89 | "Yellow - Show this help message.
" +
90 | "Blue - When music is playing, show the music player controls.
" +
91 | "Ch. Up/Down - Skips one page of content. ";
92 | }
93 | return htmlToAdd;
94 |
95 | }
96 |
97 | GuiHelper.setControlButtons = function(redText,greenText,yellowText,blueText,returnText) {
98 | //Displays the coloured remote control buttons on screen to indicate their current function.
99 | //Each parameter is the button text. A null value means the button is hidden, 0 means don't change it.
100 | //The position value is calculated to group the visible buttons on the right.
101 | //The offset allows for longer labels.
102 |
103 | //Get the current text if needed.
104 | if (redText == 0){
105 | redText = document.getElementById("guiRedButton").innerHTML;
106 | if (redText == "") {
107 | redText = null;
108 | }
109 | }
110 | if (greenText == 0){
111 | greenText = document.getElementById("guiGreenButton").innerHTML;
112 | if (greenText == "") {
113 | greenText = null;
114 | }
115 | }
116 | if (yellowText == 0){
117 | yellowText = document.getElementById("guiYellowButton").innerHTML;
118 | if (yellowText == "") {
119 | yellowText = null;
120 | }
121 | }
122 | if (blueText == 0){
123 | blueText = document.getElementById("guiBlueButton").innerHTML;
124 | if (blueText == "") {
125 | blueText = null;
126 | }
127 | }
128 | if (returnText == 0){
129 | returnText = document.getElementById("guiReturnButton").innerHTML;
130 | if (returnText == "") {
131 | returnText = null;
132 | }
133 | }
134 |
135 | //Calculate an offset value if the label is longer than 5 characters.
136 | var redOffset = 0;
137 | if (redText != null){
138 | redOffset = (redText.length > 5) ? (redText.length *6)+5 : 0;
139 | }
140 |
141 | var greenOffset = 0;
142 | if (greenText != null){
143 | greenOffset = (greenText.length > 5) ? (greenText.length *6)+5 : 0;
144 | }
145 |
146 | var yellowOffset = 0;
147 | if (yellowText != null){
148 | yellowOffset = (yellowText.length > 5) ? (yellowText.length *6)+5 : 0;
149 | }
150 |
151 | var blueOffset = 0;
152 | if (blueText != null){
153 | blueOffset = (blueText.length > 5) ? (blueText.length *6)+5 : 0;
154 | }
155 |
156 | var returnOffset = 0;
157 | if (returnText != null){
158 | returnOffset = (returnText.length > 5) ? (returnText.length *6)+5 : 0;
159 | }
160 |
161 | //Add the offset values to item's standard position.
162 | var redPos = (redText == null) ? 0 : 602;
163 | redPos = redPos + redOffset + greenOffset + yellowOffset + blueOffset + returnOffset;
164 | var greenPos = (greenText == null) ? 0 : 468;
165 | greenPos = greenPos + greenOffset + yellowOffset + blueOffset + returnOffset;
166 | var yellowPos = (yellowText == null) ? 0 : 322;
167 | yellowPos = yellowPos + yellowOffset + blueOffset + returnOffset;
168 | var bluePos = (blueText == null) ? 0 : 185;
169 | bluePos = bluePos + blueOffset + returnOffset;
170 | var returnPos = (returnText == null) ? 0 : 75;
171 | returnPos = returnPos + returnOffset;
172 |
173 | //This section moves the items right if some are not being displayed.
174 | if (returnText == null){
175 | bluePos = bluePos -90;
176 | yellowPos = yellowPos -90;
177 | greenPos = greenPos -90;
178 | redPos = redPos -90;
179 | }
180 | if (blueText == null){
181 | yellowPos = yellowPos -150;
182 | greenPos = greenPos -150;
183 | redPos = redPos -150;
184 | }
185 | if (yellowText == null){
186 | greenPos = greenPos -130;
187 | redPos = redPos -130;
188 | }
189 | if (greenText == null){
190 | redPos = redPos -150;
191 | }
192 |
193 | //Set control button visibility, inner text and position.
194 | if (redText == null){
195 | document.getElementById("guiRedButton").style.visibility = "hidden";
196 | document.getElementById("guiRedButton").innerHTML = null;
197 | } else {
198 | document.getElementById("guiRedButton").style.visibility = "";
199 | document.getElementById("guiRedButton").innerHTML = redText;
200 | document.getElementById("guiRedButton").style.right = redPos + "px";
201 | }
202 | if (greenText == null){
203 | document.getElementById("guiGreenButton").style.visibility = "hidden";
204 | document.getElementById("guiGreenButton").innerHTML = null;
205 | } else {
206 | document.getElementById("guiGreenButton").style.visibility = "";
207 | document.getElementById("guiGreenButton").innerHTML = greenText;
208 | document.getElementById("guiGreenButton").style.right = greenPos + "px";
209 | }
210 | if (yellowText == null){
211 | document.getElementById("guiYellowButton").style.visibility = "hidden";
212 | document.getElementById("guiYellowButton").innerHTML = null;
213 | } else {
214 | document.getElementById("guiYellowButton").style.visibility = "";
215 | document.getElementById("guiYellowButton").innerHTML = yellowText;
216 | document.getElementById("guiYellowButton").style.right = yellowPos + "px";
217 | }
218 | if (blueText == null){
219 | document.getElementById("guiBlueButton").style.visibility = "hidden";
220 | document.getElementById("guiBlueButton").innerHTML = null;
221 | } else {
222 | document.getElementById("guiBlueButton").style.visibility = "";
223 | document.getElementById("guiBlueButton").innerHTML = blueText;
224 | document.getElementById("guiBlueButton").style.right = bluePos + "px";
225 | }
226 | if (returnText == null){
227 | document.getElementById("guiReturnButton").style.visibility = "hidden";
228 | document.getElementById("guiReturnButton").innerHTML = null;
229 | } else {
230 | document.getElementById("guiReturnButton").style.visibility = "";
231 | document.getElementById("guiReturnButton").innerHTML = returnText;
232 | document.getElementById("guiReturnButton").style.right = returnPos + "px";
233 | }
234 | };
235 |
236 |
--------------------------------------------------------------------------------
/app/javascript/Gui/GuiImagePlayer/GuiImagePlayer.js:
--------------------------------------------------------------------------------
1 | var GuiImagePlayer = {
2 | ImageViewer : null,
3 | newItemData : null,
4 |
5 | Timeout : null,
6 | infoTimer : null,
7 | Paused : false,
8 |
9 | overlayFormat : 0, // 0 - date, 1 - date:time, 2 - off
10 |
11 | photos : [],
12 |
13 | images : [],
14 | overlay : [],
15 | imageIdx : 0, // Image index
16 | effectIdx : 0, // Transition effect index
17 | effectNames : ['FADE1', 'FADE2', 'BLIND', 'SPIRAL','CHECKER', 'LINEAR', 'STAIRS', 'WIPE', 'RANDOM']
18 | }
19 |
20 | //ImageViewer.destroy doesn't work. Set it to null instead.
21 | GuiImagePlayer.kill = function() {
22 | if (this.ImageViewer != null) {
23 | this.ImageViewer = null;
24 | }
25 | }
26 |
27 | GuiImagePlayer.start = function(ItemData,selectedItem,isPhotoCollection) {
28 | alert("Page Enter : GuiImagePlayer");
29 |
30 | //Show colour buttons on screen for a few seconds when a slideshow starts.
31 | document.getElementById("GuiImagePlayer_ScreensaverOverlay").style.visibility="hidden";
32 | document.getElementById("guiButtonShade").style.visibility = "";
33 | GuiHelper.setControlButtons("Favourite","Date/Time","Help",GuiMusicPlayer.Status == "PLAYING" || GuiMusicPlayer.Status == "PAUSED" ? "Music" : null,"Return");
34 | this.infoTimer = setTimeout(function(){
35 | GuiHelper.setControlButtons(null,null,null,null,null);
36 | document.getElementById("Clock").style.visibility = "hidden";
37 | document.getElementById("guiButtonShade").style.visibility = "hidden";
38 | document.getElementById("GuiImagePlayer_ScreensaverOverlay").style.visibility="";
39 | }, 6000);
40 |
41 | //Turn off screensaver
42 | Support.screensaverOff();
43 |
44 | var url = "";
45 | if (isPhotoCollection) {
46 | url = Server.getChildItemsURL(ItemData.Items[selectedItem].Id,"&Recursive=true&SortBy=Random&SortOrder=Ascending&IncludeItemTypes=Photo&fields=SortName,Overview&Limit=2500");
47 | } else {
48 | url = Server.getChildItemsURL(ItemData.Items[selectedItem].ParentId,"&SortBy=SortName&SortOrder=Ascending&IncludeItemTypes=Photo&fields=SortName,Overview&Limit=2500");
49 | }
50 |
51 | var result = Server.getContent(url);
52 | if (result == null) { return; }
53 | this.newItemData = result; //Misleading I know!
54 |
55 | Support.styleSubtitles("GuiImagePlayer_ScreensaverOverlay")
56 |
57 | //Create ARRAY of all URL's!
58 | //Order from starting selectedItem!
59 | imageIdx = 0;
60 | for (var index = 0; index < result.Items.length; index++) {
61 | //Dont use server function here to prevent these large images caching!
62 | var temp = Server.getServerAddr() + "/Items/"+ this.newItemData.Items[index].Id +"/Images/Primary/0?maxwidth=1920&maxheight=1080&quality=90";
63 | this.images.push(temp);
64 |
65 | if (this.newItemData.Items[index].PremiereDate !== undefined) {
66 | this.overlay.push(Support.formatDateTime(this.newItemData.Items[index].PremiereDate,1))
67 | } else {
68 | this.overlay.push(""); //Need to push something to keep indexes matched up!
69 | }
70 | if (result.Items[index].Id == ItemData.Items[selectedItem].Id) {
71 | this.imageIdx = index;
72 | }
73 | }
74 |
75 | //Initialte new instance, set Frame Area & Set Notifications
76 | this.ImageViewer = new CImageViewer('Common ImageViewer');
77 | this.ImageViewer.setFrameArea(0, 0, Main.width, Main.height);
78 |
79 | this.ImageViewer.setOnNetworkError(function() {
80 | GuiNotifications.setNotification("Network Error");
81 | });
82 |
83 | this.ImageViewer.setOnRenderError(function() {
84 | GuiNotifications.setNotification("Render Error");
85 | });
86 |
87 |
88 | //Set Focus for Key Events
89 | document.getElementById("GuiImagePlayer").focus();
90 |
91 | //Start Slide Show
92 | this.ImageViewer.show();
93 | this.setSlideshowMode();
94 | //this.setNormalMode();
95 | }
96 |
97 | // Set normal mode
98 | // You can play images on the area you set.
99 | GuiImagePlayer.setNormalMode = function() {
100 |
101 | sf.service.ImageViewer.setPosition({
102 | left: 0,
103 | top: 0,
104 | width: 1920,
105 | height: 1080,
106 | });
107 |
108 | sf.service.ImageViewer.show();
109 |
110 | for (var i=0; i < this.newItemData.Items.length; i++){
111 | //Dont use server function here to prevent these large images caching!
112 | var ImageUrl = Server.getServerAddr() + "/Items/"+ this.newItemData.Items[i].Id +"/Images/Primary/0?maxwidth=1920&maxheight=1080&quality=90";
113 | this.photos[i] = {
114 | url: ImageUrl,
115 | width: 1920,
116 | height: 1080,
117 | filename: this.newItemData.Items[i].name,
118 | date: '2011/06/24'
119 | }
120 | }
121 |
122 | // Draw the image in the specified area defined by "setPosition" function.
123 | sf.service.ImageViewer.draw(this.photos[0]);
124 |
125 |
126 | //this.ImageViewer.endSlideshow();
127 | //playImage();
128 | }
129 |
130 | // Set Slideshow mode
131 | // You can use Transtion effect
132 | GuiImagePlayer.setSlideshowMode = function() {
133 | this.ImageViewer.startSlideshow();
134 | this.ImageViewer.setOnBufferingComplete(function(){
135 | GuiImagePlayer.ImageViewer.showNow();
136 | });
137 | this.ImageViewer.setOnRenderingComplete(function(){
138 | clearTimeout(GuiImagePlayer.Timeout);
139 | Support.setImagePlayerOverlay(GuiImagePlayer.overlay[GuiImagePlayer.imageIdx], GuiImagePlayer.overlayFormat);
140 | GuiImagePlayer.Timeout = setTimeout(function(){
141 | if (GuiImagePlayer.Paused == false) {
142 | GuiImagePlayer.imageIdx = GuiImagePlayer.imageIdx+1;
143 | if (GuiImagePlayer.imageIdx >= GuiImagePlayer.newItemData.Items.length ) {
144 | GuiImagePlayer.imageIdx = 0;
145 | }
146 | GuiImagePlayer.prepImage(GuiImagePlayer.imageIdx);
147 | }
148 | }, File.getUserProperty("ImagePlayerImageTime"));
149 | });
150 |
151 | this.ImageViewer.stop();
152 | this.playImage();
153 | }
154 |
155 | //Prepare next image
156 | GuiImagePlayer.prepImage = function(imageIdx) {
157 | this.ImageViewer.prepareNext(GuiImagePlayer.images[imageIdx], this.ImageViewer.Effect.FADE1);
158 | }
159 |
160 | // Play image - only called once in slideshow!
161 | //SS calls play -> BufferComplete, then the showNow will call RendComplete which starts timer for next image
162 | GuiImagePlayer.playImage = function() {
163 | var url = GuiImagePlayer.images[GuiImagePlayer.imageIdx];
164 | GuiImagePlayer.ImageViewer.play(url, 1920, 1080);
165 | }
166 |
167 |
168 | GuiImagePlayer.keyDown = function() {
169 | var keyCode = event.keyCode;
170 | alert("Key pressed: " + keyCode);
171 |
172 | if (document.getElementById("Notifications").style.visibility == "") {
173 | document.getElementById("Notifications").style.visibility = "hidden";
174 | document.getElementById("NotificationText").innerHTML = "";
175 | widgetAPI.blockNavigation(event);
176 | //Change keycode so it does nothing!
177 | keyCode = "VOID";
178 | }
179 |
180 | switch(keyCode){
181 | case tvKey.KEY_STOP:
182 | case tvKey.KEY_RETURN:
183 | alert("RETURN");
184 | clearTimeout(this.infoTimer);
185 | clearTimeout(this.Timeout);
186 | this.Timeout = null;
187 | this.images = [];
188 | this.overlay = [];
189 | document.getElementById("GuiImagePlayer_ScreensaverOverlay").innerHTML = "";
190 | document.getElementById("guiButtonShade").style.visibility = "hidden";
191 | document.getElementById("Clock").style.visibility = "";
192 | this.ImageViewer.endSlideshow();
193 | this.ImageViewer.hide();
194 | widgetAPI.blockNavigation(event);
195 | GuiImagePlayer.kill();
196 |
197 | //Turn On Screensaver
198 | Support.screensaverOn();
199 | Support.screensaver();
200 |
201 | Support.processReturnURLHistory();
202 | break;
203 | case tvKey.KEY_RIGHT:
204 | alert("RIGHT");
205 | this.imageIdx++;
206 | if (this.imageIdx == this.images.length) {
207 | this.imageIdx = 0;
208 | }
209 | GuiImagePlayer.prepImage(GuiImagePlayer.imageIdx);
210 | break;
211 | case tvKey.KEY_LEFT:
212 | alert("LEFT");
213 | this.imageIdx--;
214 | if (this.imageIdx < 0) {
215 | this.imageIdx = this.images.length-1;
216 | }
217 | GuiImagePlayer.prepImage(GuiImagePlayer.imageIdx);
218 | break;
219 | case tvKey.KEY_PAUSE:
220 | alert("PAUSE")
221 | this.Paused = true
222 | break;
223 | case tvKey.KEY_PLAY:
224 | alert("PLAY")
225 | this.Paused = false
226 | GuiImagePlayer.prepImage(GuiImagePlayer.imageIdx);
227 | break;
228 | case tvKey.KEY_RED:
229 | if (this.newItemData.Items[this.imageIdx].UserData.IsFavorite == true) {
230 | Server.deleteFavourite(this.newItemData.Items[this.imageIdx].Id);
231 | this.newItemData.Items[this.imageIdx].UserData.IsFavorite = false;
232 | GuiNotifications.setNotification ("Item has been removed from
favourites","Favourites");
233 | } else {
234 | Server.setFavourite(this.newItemData.Items[this.imageIdx].Id);
235 | this.newItemData.Items[this.imageIdx].UserData.IsFavorite = true;
236 | GuiNotifications.setNotification ("Item has been added to
favourites","Favourites");
237 | }
238 | break;
239 | case tvKey.KEY_GREEN:
240 | if (this.overlayFormat == 2) {
241 | this.overlayFormat = 0;
242 | } else {
243 | this.overlayFormat = this.overlayFormat + 1;
244 | }
245 | Support.setImagePlayerOverlay(this.overlay[this.imageIdx], this.overlayFormat);
246 | break;
247 | case tvKey.KEY_YELLOW:
248 | GuiHelper.toggleHelp("GuiImagePlayer");
249 | break;
250 | case tvKey.KEY_BLUE:
251 | GuiMusicPlayer.showMusicPlayer("GuiImagePlayer");
252 | break;
253 | }
254 | }
255 |
256 |
--------------------------------------------------------------------------------
/app/javascript/Gui/GuiPlayer/GuiPlayer_Transcoding.js:
--------------------------------------------------------------------------------
1 | /*
2 | Render Error 1 : Unsupported container
3 | Render Error 2 : Unsupported video codec
4 | Render Error 3 : Unsupported audio codec
5 | Render Error 4 : Unsupported video resolution
6 | Render Error 6 : Corrupt Stream
7 | */
8 |
9 | var GuiPlayer_Transcoding = {
10 | //File Information
11 | MediaSource : null,
12 | videoIndex : 0,
13 | audioIndex : 0,
14 |
15 | //Bitrate check
16 | bitRateToUse : null,
17 |
18 | //Boolean that conclude if all Video or All Audio elements will play without transcode
19 | isVideo : true,
20 | isAudio : true,
21 |
22 | //All Video Elements
23 | isCodec : null,
24 | isResolution : null,
25 | isContainer : null,
26 | isBitRate : null,
27 | isLevel : null,
28 | isFrameRate : null,
29 | isProfile : null,
30 |
31 | //All Audio elements
32 | isAudioCodec : null,
33 | isAudioContainer : null,
34 | isAudioChannel : null
35 | }
36 |
37 | //--------------------------------------------------------------------------------------
38 | GuiPlayer_Transcoding.start = function(showId, MediaSource,MediaSourceIndex, videoIndex, audioIndex, isFirstAudioIndex, subtitleIndex) {
39 | //Set Class Vars
40 | this.MediaSource = MediaSource;
41 | this.videoIndex = videoIndex;
42 | this.audioIndex = audioIndex;
43 |
44 | //Check Video & Audio Compatibility
45 | this.checkCodec(videoIndex);
46 | this.checkAudioCodec(audioIndex);
47 |
48 | var streamparams = "";
49 | var transcodeStatus = "";
50 |
51 | //If audiocheck failed convert to AAC OR AC3 depending on setting
52 | //If audiocheck ok convert to AAC or dont convert & leave as original codec
53 |
54 | var fileAudioCodec = this.MediaSource.MediaStreams[this.audioIndex].Codec.toLowerCase();
55 | var streamAudioCodec = "aac"; //Default, supported by all tv's (?)
56 | var convertAACtoDolby = false;
57 | if (File.getTVProperty("Dolby") && File.getTVProperty("AACtoDolby") && fileAudioCodec == "aac") {
58 | convertAACtoDolby = true;
59 | }
60 | if (this.isAudio == false) {
61 | streamAudioCodec = (File.getTVProperty("Dolby") && File.getTVProperty("AACtoDolby")) ? "ac3" : "aac";
62 | } else {
63 | streamAudioCodec = (File.getTVProperty("Dolby") && File.getTVProperty("AACtoDolby") && fileAudioCodec == "aac") ? "ac3" : "aac";
64 | }
65 | if (this.isVideo && this.isAudio && convertAACtoDolby == false) {
66 | if (isFirstAudioIndex == true) {
67 | transcodeStatus = "Direct Play";
68 | streamparams = '/Stream.'+this.MediaSource.Container+'?static=true&MediaSourceId='+this.MediaSource.Id + '&api_key=' + Server.getAuthToken();
69 | } else {
70 | transcodeStatus = "Stream Copy - Audio Not First Track";
71 | streamparams = '/Stream.ts?VideoStreamIndex='+this.videoIndex+'&AudioStreamIndex='+this.audioIndex+'&VideoCodec=copy&AudioCodec='+ streamAudioCodec +'&MediaSourceId='+this.MediaSource.Id + '&api_key=' + Server.getAuthToken();
72 | }
73 | } else if (this.isVideo == false) {
74 | transcodeStatus = "Transcoding Audio & Video";
75 | streamparams = '/Stream.ts?VideoStreamIndex='+this.videoIndex+'&AudioStreamIndex='+this.audioIndex+'&VideoCodec=h264&Profile=high&Level=41&MaxVideoBitDepth=8&MaxWidth=1920&VideoBitrate='+this.bitRateToUse+'&AudioCodec=' + streamAudioCodec +'&AudioBitrate=360000&MaxAudioChannels=6&MediaSourceId='+this.MediaSource.Id + '&api_key=' + Server.getAuthToken();
76 | } else if (this.isVideo == true && (this.isAudio == false || convertAACtoDolby == true)) {
77 | transcodeStatus = "Transcoding Audio";
78 | streamparams = '/Stream.ts?VideoStreamIndex='+this.videoIndex+'&AudioStreamIndex='+this.audioIndex+'&VideoCodec=copy&AudioCodec='+ streamAudioCodec +'&audioBitrate=360000&MaxAudioChannels=6&MediaSourceId='+this.MediaSource.Id + '&api_key=' + Server.getAuthToken();
79 | }
80 | var url = Server.getServerAddr() + '/Videos/' + showId + streamparams + '&DeviceId='+Server.getDeviceID();
81 | FileLog.write("Video : Transcode Status : " + transcodeStatus);
82 | FileLog.write("Video : URL : " + url);
83 |
84 | //Return results to Versions
85 | //MediaSourceId,Url,transcodeStatus,videoIndex,audioIndex
86 | return [MediaSourceIndex,url,transcodeStatus,videoIndex,audioIndex,subtitleIndex];
87 | }
88 |
89 | GuiPlayer_Transcoding.checkCodec = function() {
90 | var codec = this.MediaSource.MediaStreams[this.videoIndex].Codec.toLowerCase();
91 | var codecParams = GuiPlayer_TranscodeParams.getParameters(codec,this.MediaSource.MediaStreams[this.videoIndex].Width);
92 |
93 | this.isCodec = codecParams[0];
94 | this.isContainer = this.checkContainer(codecParams[1]);
95 | this.isResolution = this.checkResolution(codecParams[2]);
96 | this.isBitRate = this.checkBitRate(codecParams[3]);
97 | this.isFrameRate = this.checkFrameRate(codecParams[4]);
98 | this.isLevel = this.checkLevel(codecParams[5]);
99 | this.isProfile = this.checkProfile(codecParams[6]);
100 |
101 | //Results
102 | FileLog.write("Video : Video File Analysis Results");
103 | FileLog.write("Video : Codec Compatibility: " + this.isCodec + " : " + this.MediaSource.MediaStreams[this.videoIndex].Codec);
104 | FileLog.write("Video : Container Compatibility: " + this.isContainer + " : " + this.MediaSource.Container);
105 | FileLog.write("Video : Resolution Compatibility: " + this.isResolution + " : " +this.MediaSource.MediaStreams[this.videoIndex].Width + "x" + this.MediaSource.MediaStreams[this.videoIndex].Height);
106 | FileLog.write("Video : BitRate Compatibility: " + this.isBitRate + " : " + this.MediaSource.MediaStreams[this.videoIndex].BitRate + " : " + this.bitRateToUse);
107 | FileLog.write("Video : FrameRate Compatibility: " + this.isFrameRate + " : " + this.MediaSource.MediaStreams[this.videoIndex].AverageFrameRate);
108 | FileLog.write("Video : Level Compatibility: " + this.isLevel + " : " + this.MediaSource.MediaStreams[this.videoIndex].Level);
109 | FileLog.write("Video : Profile Compatibility: " + this.isProfile + " : " + this.MediaSource.MediaStreams[this.videoIndex].Profile);
110 |
111 | //Put it all together
112 | if (this.isCodec && this.isContainer && this.isResolution && this.isBitRate && this.isFrameRate && this.isLevel && this.isProfile) { //
113 | this.isVideo = true;
114 | } else {
115 | this.isVideo = false;
116 | }
117 | }
118 |
119 | GuiPlayer_Transcoding.checkAudioCodec = function() {
120 | var audiocodec = this.MediaSource.MediaStreams[this.audioIndex].Codec.toLowerCase();
121 | var audiocodecParams = GuiPlayer_TranscodeParams.getAudioParameters(audiocodec);
122 |
123 | this.isAudioCodec = audiocodecParams[0];
124 | this.isAudioContainer = this.checkContainer(audiocodecParams[1]);
125 | this.isAudioChannel = this.checkAudioChannels(audiocodecParams[2]);
126 |
127 | //Results
128 | FileLog.write("Video : Audio File Analysis Results");
129 | FileLog.write("Video : Codec Compatibility: " + this.isAudioCodec + " : " + this.MediaSource.MediaStreams[this.audioIndex].Codec);
130 | FileLog.write("Video : Container Compatibility: " + this.isAudioContainer + " : " + this.MediaSource.Container);
131 | FileLog.write("Video : Channel Compatibility: " + this.isAudioChannel + " : " + this.MediaSource.MediaStreams[this.audioIndex].Channels);
132 |
133 | //Put it all together
134 | if (this.isAudioCodec && this.isAudioChannel) {
135 | this.isAudio = true;
136 | } else {
137 | this.isAudio = false;
138 | }
139 | }
140 |
141 | GuiPlayer_Transcoding.checkAudioChannels = function(maxChannels) {
142 | if (maxChannels == null) {
143 | return false;
144 | } else {
145 | if (this.MediaSource.MediaStreams[this.audioIndex].Channels <= maxChannels) {
146 | return true;
147 | } else {
148 | return false;
149 | }
150 | }
151 | }
152 |
153 | GuiPlayer_Transcoding.checkResolution = function(maxResolution) {
154 | if (maxResolution == null) {
155 | return false;
156 | } else if (this.MediaSource.MediaStreams[this.videoIndex].Width <= maxResolution[0] && this.MediaSource.MediaStreams[this.videoIndex].Height <= maxResolution[1]) {
157 | return true;
158 | } else {
159 | return false;
160 | }
161 | }
162 |
163 | GuiPlayer_Transcoding.checkContainer = function(supportedContainers) {
164 | if (supportedContainers == null) {
165 | return false
166 | } else {
167 | var isContainer = false;
168 | for (var index = 0; index < supportedContainers.length; index++) {
169 | if (this.MediaSource.Container.toLowerCase() == supportedContainers[index]) {
170 | isContainer = true;
171 | break;
172 | }
173 | }
174 | return isContainer;
175 | }
176 | }
177 |
178 | GuiPlayer_Transcoding.checkBitRate = function(maxBitRate) {
179 | //Get Bitrate from Settings File
180 | var maxBitRateSetting = File.getTVProperty("Bitrate")*1024*1024;
181 |
182 | // MCB - Ignore bitrate in file
183 | this.bitRateToUse = maxBitRateSetting;
184 |
185 | if (this.MediaSource.MediaStreams[this.videoIndex].BitRate > maxBitRateSetting) {
186 | return false;
187 | } else {
188 | return true;
189 | }
190 | }
191 |
192 | GuiPlayer_Transcoding.checkFrameRate = function(maxFrameRate) {
193 | if (maxFrameRate == null) {
194 | return false;
195 | } else if (this.MediaSource.MediaStreams[this.videoIndex].AverageFrameRate <= maxFrameRate) {
196 | return true;
197 | } else {
198 | return false;
199 | }
200 | }
201 |
202 | GuiPlayer_Transcoding.checkLevel = function(maxLevel) {
203 | var level = this.MediaSource.MediaStreams[this.videoIndex].Level;
204 | if (maxLevel == null) {
205 | return false;
206 | } if (maxLevel == true) {
207 | return true;
208 | } else {
209 | var level = this.MediaSource.MediaStreams[this.videoIndex].Level;
210 | level = (level < 10) ? level * 10 : level; //If only 1 long, multiply by 10 to make it correct!
211 | if (level <= maxLevel && level >= 0) {
212 | return true;
213 | } else {
214 | return false;
215 | }
216 | }
217 | }
218 |
219 | GuiPlayer_Transcoding.checkProfile = function(supportedProfiles) {
220 | if (supportedProfiles == null) {
221 | return false;
222 | } if (supportedProfiles == true) {
223 | return true;
224 | } else {
225 | var profile = false;
226 | for (var index = 0; index < supportedProfiles.length; index++) {
227 | if (this.MediaSource.MediaStreams[this.videoIndex].Profile == supportedProfiles[index]) {
228 | profile = true;
229 | break;
230 | }
231 | }
232 | return profile;
233 | }
234 | }
--------------------------------------------------------------------------------
/app/javascript/Gui/GuiPage_CastMember.js:
--------------------------------------------------------------------------------
1 | var GuiPage_CastMember = {
2 | CastData : null,
3 | ItemData : null,
4 |
5 | selectedItem : 0,
6 | topLeftItem : 0,
7 | MAXCOLUMNCOUNT : 9,
8 | MAXROWCOUNT : 1,
9 | }
10 |
11 | GuiPage_CastMember.getMaxDisplay = function() {
12 | return this.MAXCOLUMNCOUNT * this.MAXROWCOUNT;
13 | }
14 |
15 | GuiPage_CastMember.start = function(title,url,selectedItem,topLeftItem) {
16 | alert("Page Enter : GuiPage_CastMember");
17 | GuiHelper.setControlButtons(null,null,null,GuiMusicPlayer.Status == "PLAYING" || GuiMusicPlayer.Status == "PAUSED" ? "Music" : null,"Return");
18 |
19 | //Save Start Params
20 | this.startParams = [title,url];
21 |
22 | //Reset Values
23 | this.selectedItem = selectedItem;
24 | this.topLeftItem = topLeftItem;
25 |
26 | //Load Data
27 | this.CastData = Server.getContent(url);
28 | if (this.CastData == null) { return; }
29 | var Itemurl = Server.getItemTypeURL("&SortBy=SortName&SortOrder=Ascending&Recursive=true&Limit=100&ExcludeLocationTypes=Virtual&fields=ParentId&Person=" + this.CastData.Name.replace(/ /g, '+'));
30 | this.ItemData = Server.getContent(Itemurl);
31 | if (this.ItemData == null) { Support.processReturnURLHistory(); }
32 |
33 | document.getElementById("pageContent").className = "";
34 | document.getElementById("pageContent").innerHTML = "
\
35 |
\
36 |
\
37 |
\
38 |
";
39 | document.getElementById("Counter").innerHTML = "1/1";
40 |
41 | //Add cast member name and image.
42 | document.getElementById("GuiPage_CastMember_Name").innerHTML = this.CastData.Name;
43 | var imgsrc = Server.getImageURL(this.CastData.Id,"Primary",350,480,0,false,0);
44 | document.getElementById("GuiPage_CastMember_Poster").style.backgroundImage = "url("+imgsrc +")";
45 |
46 | var detailsHtml = "";
47 | if (this.CastData.PremiereDate && Main.getModelYear() != "D"){
48 | var birthday = new Date(this.CastData.PremiereDate);
49 | detailsHtml += "Born: "+birthday.toDateString() + "";
50 | }
51 | if (this.CastData.ProductionLocations){
52 | var birthPlace = this.CastData.ProductionLocations;
53 | if (birthPlace != ""){
54 | detailsHtml += "Born in "+this.CastData.ProductionLocations + "";
55 | }
56 | }
57 | if (this.CastData.EndDate && Main.getModelYear() != "D"){
58 | var deathday = new Date(this.CastData.EndDate);
59 | detailsHtml += "Died: "+deathday.toDateString() + "";
60 | }
61 | document.getElementById("GuiPage_CastMember_Details").innerHTML = detailsHtml;
62 |
63 | //Person bio
64 | var bio = "";
65 | if (this.CastData.Overview){
66 | bio += this.CastData.Overview;
67 | }
68 | document.getElementById("GuiPage_CastMember_Bio").innerHTML = bio;
69 |
70 | //Set Overview Scroller
71 | Support.scrollingText("GuiPage_CastMember_Bio");
72 |
73 | if (this.ItemData.Items.length > 0) {
74 | //Display first 12 series
75 | this.updateDisplayedItems();
76 |
77 | //Update Selected Collection CSS
78 | this.updateSelectedItems();
79 |
80 | //Set Focus for Key Events
81 | document.getElementById("GuiPage_CastMember").focus();
82 | } else {
83 | //Cannot happen as link can only be generated from a Cast member - thus at minimum it will return 1 result (itself)
84 | document.getElementById("GuiPage_CastMember").focus();
85 | }
86 | }
87 |
88 | GuiPage_CastMember.updateDisplayedItems = function() {
89 | var htmlToAdd = "";
90 | var htmlToAdd2 ="";
91 | for (var index = this.topLeftItem;index < Math.min(this.topLeftItem + this.getMaxDisplay(),this.ItemData.Items.length); index++) {
92 | var imgsrc = "images/menu/Play-46x37.png";
93 | if (this.ItemData.Items[index].Type == "Episode"){
94 | if (this.ItemData.Items[index].ImageTags.Primary) {
95 | imgsrc = Server.getImageURL(this.ItemData.Items[index].Id,"Primary",180,100,null,null,null,index);
96 | }
97 | } else {
98 | if (this.ItemData.Items[index].ImageTags.Thumb) {
99 | imgsrc = Server.getImageURL(this.ItemData.Items[index].Id,"Thumb",180,100,null,null,null,index);
100 | } else if (this.ItemData.Items[index].ImageTags.Primary) {
101 | imgsrc = Server.getImageURL(this.ItemData.Items[index].Id,"Primary",180,100,null,null,null,index);
102 | }
103 | }
104 | htmlToAdd += "
"+this.ItemData.Items[index].Name+"
";
105 | }
106 | document.getElementById("GuiPage_CastMember_List").innerHTML = htmlToAdd;
107 | }
108 |
109 | //Function sets CSS Properties so show which user is selected
110 | GuiPage_CastMember.updateSelectedItems = function () {
111 | for (var index = this.topLeftItem; index < Math.min(this.topLeftItem + this.getMaxDisplay(),this.ItemData.Items.length); index++){
112 | if (index == this.selectedItem) {
113 | document.getElementById(this.ItemData.Items[index].Id).className = "GuiPage_CastMember_ListSingle highlight"+Main.highlightColour+"Background";
114 | //Set Background based on Type:
115 | switch (this.ItemData.Items[index].Type) {
116 | case "Episode":
117 | if (this.ItemData.Items[index].ParentBackdropItemId) {
118 | var imgsrc = Server.getBackgroundImageURL(this.ItemData.Items[index].ParentBackdropItemId,"Backdrop",Main.backdropWidth,Main.backdropHeight,0,false,0,this.ItemData.Items[index].ParentBackdropImageTags.length);
119 | Support.fadeImage(imgsrc);
120 | }
121 | break;
122 | case "Movie":
123 | case "Series":
124 | if (this.ItemData.Items[index].BackdropImageTags.length > 0) {
125 | var imgsrc = Server.getBackgroundImageURL(this.ItemData.Items[index].Id,"Backdrop",Main.backdropWidth,Main.backdropHeight,0,false,0,this.ItemData.Items[index].BackdropImageTags.length);
126 | Support.fadeImage(imgsrc);
127 | }
128 | break;
129 | case "Photo":
130 | if (this.ItemData.Items[index].ImageTags.Primary.length > 0) {
131 | var imgsrc = Server.getImageURL(this.ItemData.Items[index].Id,"Primary",Main.backdropWidth,Main.backdropHeight,0,false,0);
132 | Support.fadeImage(imgsrc);
133 | }
134 | break;
135 | default:
136 | break;
137 | }
138 |
139 | } else {
140 | document.getElementById(this.ItemData.Items[index].Id).className = "GuiPage_CastMember_ListSingle";
141 | }
142 | }
143 | document.getElementById("Counter").innerHTML = (this.selectedItem + 1) + "/" + this.ItemData.Items.length;
144 | }
145 |
146 | GuiPage_CastMember.keyDown = function()
147 | {
148 | var keyCode = event.keyCode;
149 | alert("Key pressed: " + keyCode);
150 |
151 | if (document.getElementById("Notifications").style.visibility == "") {
152 | document.getElementById("Notifications").style.visibility = "hidden";
153 | document.getElementById("NotificationText").innerHTML = "";
154 | widgetAPI.blockNavigation(event);
155 | //Change keycode so it does nothing!
156 | keyCode = "VOID";
157 | }
158 |
159 | //Update Screensaver Timer
160 | Support.screensaver();
161 |
162 | //If screensaver is running
163 | if (Main.getIsScreensaverRunning()) {
164 | //Update Main.js isScreensaverRunning - Sets to True
165 | Main.setIsScreensaverRunning();
166 |
167 | //End Screensaver
168 | GuiImagePlayer_Screensaver.stopScreensaver();
169 |
170 | //Change keycode so it does nothing!
171 | keyCode = "VOID";
172 | }
173 |
174 | switch(keyCode)
175 | {
176 | case tvKey.KEY_LEFT:
177 | alert("LEFT");
178 | this.openMenu();
179 | break;
180 | case tvKey.KEY_UP:
181 | alert("UP");
182 | this.processUpKey();
183 | break;
184 | case tvKey.KEY_DOWN:
185 | alert("RIGHT");
186 | this.processDownKey();
187 | break;
188 | case tvKey.KEY_RETURN:
189 | alert("RETURN");
190 | widgetAPI.blockNavigation(event);
191 | Support.processReturnURLHistory();
192 | break;
193 | case tvKey.KEY_ENTER:
194 | case tvKey.KEY_PANEL_ENTER:
195 | alert("ENTER");
196 | this.processSelectedItem();
197 | break;
198 | case tvKey.KEY_PLAY:
199 | this.playSelectedItem();
200 | break;
201 | case tvKey.KEY_YELLOW:
202 | //Favourites
203 | break;
204 | case tvKey.KEY_BLUE:
205 | GuiMusicPlayer.showMusicPlayer("GuiPage_CastMember",this.ItemData.Items[this.selectedItem].Id,document.getElementById(this.ItemData.Items[this.selectedItem].Id).className);
206 | break;
207 | case tvKey.KEY_TOOLS:
208 | widgetAPI.blockNavigation(event);
209 | Support.updateURLHistory("GuiPage_CastMember",this.startParams[0],this.startParams[1],null,null,this.selectedItem,this.topLeftItem,null);
210 | document.getElementById(this.ItemData.Items[this.selectedItem].Id).className = "SeasonTitle";
211 | GuiMainMenu.requested("GuiPage_CastMember",this.ItemData.Items[this.selectedItem].Id,"EpisodeListSingle highlight"+Main.highlightColour+"Background");
212 | break;
213 | case tvKey.KEY_EXIT:
214 | alert ("EXIT KEY");
215 | widgetAPI.sendExitEvent();
216 | break;
217 | }
218 | }
219 |
220 | GuiPage_CastMember.openMenu = function() {
221 | Support.updateURLHistory("GuiPage_CastMember",null,null,null,null,null,null,null);
222 | GuiMainMenu.requested("GuiPage_CastMember",null);
223 | }
224 |
225 | GuiPage_CastMember.processSelectedItem = function() {
226 | Support.processSelectedItem("GuiPage_CastMember",this.ItemData,this.startParams,this.selectedItem,this.topLeftItem,null,null)
227 | }
228 |
229 | GuiPage_CastMember.playSelectedItem = function () {
230 | if (this.ItemData.Items[this.selectedItem].MediaType == "Video") {
231 | Support.updateURLHistory("GuiPage_CastMember",this.startParams[0],this.startParams[1],null,null,this.selectedItem,this.topLeftItem,null);
232 | var url = Server.getItemInfoURL(this.ItemData.Items[this.selectedItem].Id);
233 | GuiPlayer.start("PLAY",url,this.ItemData.Items[this.selectedItem].UserData.PlaybackPositionTicks / 10000);
234 | }
235 | }
236 |
237 | GuiPage_CastMember.processUpKey = function() {
238 | this.selectedItem--;
239 | if (this.selectedItem < 0) {
240 | this.selectedItem = 0;
241 | } else {
242 | if (this.selectedItem < this.topLeftItem) {
243 | this.topLeftItem = this.selectedItem;
244 | if (this.topLeftItem < 0) {
245 | this.topLeftItem = 0;
246 | }
247 | this.updateDisplayedItems();
248 | }
249 | this.updateSelectedItems();
250 | }
251 |
252 | }
253 |
254 | GuiPage_CastMember.processDownKey = function() {
255 | this.selectedItem++;
256 | if (this.selectedItem >= this.ItemData.Items.length) {
257 | this.selectedItem--;
258 | } else {
259 | if (this.selectedItem >= this.topLeftItem+this.getMaxDisplay() ) {
260 | this.topLeftItem++;
261 | this.updateDisplayedItems();
262 | }
263 | }
264 | this.updateSelectedItems();
265 | }
266 |
267 | GuiPage_CastMember.returnFromMusicPlayer = function() {
268 | this.selectedItem = 0;
269 | this.updateDisplayedItems();
270 | this.updateSelectedItems();
271 | }
--------------------------------------------------------------------------------
/app/javascript/Gui/GuiPage_AddToPlaylist.js:
--------------------------------------------------------------------------------
1 | var GuiPage_AddToPlaylist = {
2 | ItemData : null,
3 | ItemData2 : null,
4 |
5 | hasItemInPlaylist : [],
6 |
7 | selectedItem : 0,
8 | topLeftItem : 0,
9 |
10 | itemId : "",
11 | playedFromPage : "",
12 | mediaType : "",
13 |
14 | MAXCOLUMNCOUNT : 1,
15 | MAXROWCOUNT : 5
16 | }
17 |
18 | GuiPage_AddToPlaylist.onFocus = function() {
19 | GuiHelper.setControlButtons(null,null,null,GuiMusicPlayer.Status == "PLAYING" || GuiMusicPlayer.Status == "PAUSED" ? "Music" : null,"Return");
20 | }
21 |
22 | GuiPage_AddToPlaylist.getMaxDisplay = function() {
23 | return this.MAXCOLUMNCOUNT * this.MAXROWCOUNT;
24 | }
25 |
26 | GuiPage_AddToPlaylist.start=function(itemId, playedFromPage, mediaType) {
27 | alert("Page Enter : GuiPage_AddToPlaylist");
28 |
29 | //Update page called from
30 | this.playedFromPage = playedFromPage;
31 | this.mediaType = mediaType;
32 | this.selectedItem = 0;
33 | this.topLeftItem = 0;
34 | this.itemId = itemId;
35 |
36 | //Get data from Server
37 | var url = Server.getItemTypeURL("/SortBy=SortName&SortOrder=Ascending&IncludeItemTypes=Playlist&Recursive=true&MediaTypes=" + mediaType);
38 | this.ItemData = Server.getContent(url);
39 | if (this.ItemData == null) { Support.processReturnURLHistory(); }
40 |
41 | //Set window size based on item count
42 | if (this.ItemData.Items.length < 6){
43 | document.getElementById("guiPlayListContainer").style.height = (this.ItemData.Items.length*40)+400 +"px";
44 | } else {
45 | document.getElementById("guiPlayListContainer").style.height = "560px";
46 | }
47 |
48 | //Create IME - Send it the name of the thing to focus.
49 | new GuiPage_AddToPlaylist_Input("guiPlayListNew");
50 |
51 | if (this.ItemData.Items.length == 0) {
52 | document.getElementById("guiPlayListExisting").innerHTML = "
You have no existing "+ this.mediaType.toLowerCase() +" playlists.
";
53 | Support.screensaverOff(); // Must turn off as not possible to catch keys!
54 | } else {
55 | for (var index = 0; index < this.ItemData.Items.length; index++) {
56 | url2 = Server.getCustomURL("/Playlists/" + this.ItemData.Items[index].Id+"/Items?format=json&userId="+Server.getUserID());
57 | this.ItemData2 = Server.getContent(url2);
58 | if (this.ItemData2 == null) { return; }
59 |
60 | this.hasItemInPlaylist[index] = false;
61 | for (var index2 = 0; index2 < this.ItemData2.Items.length; index2++) {
62 | if (this.ItemData2.Items[index2].Id == itemId) {
63 | this.hasItemInPlaylist[index] = true;
64 | break;
65 | }
66 | }
67 | }
68 |
69 | this.updateDisplayedItems();
70 | this.updateSelectedItems();
71 | }
72 |
73 | //Display Playlist Div
74 | document.getElementById("guiPlayListContainer").style.visibility = "";
75 | }
76 |
77 | GuiPage_AddToPlaylist.updateDisplayedItems = function() {
78 | var htmlToAdd = "
Playlist Exists in Playlist ";
79 | for (var index = this.topLeftItem; index < Math.min(this.topLeftItem + this.getMaxDisplay(),this.ItemData.Items.length);index++) {
80 | var existsInPlaylist = (this.hasItemInPlaylist[index] == true) ? "Yes" : "No";
81 | htmlToAdd += ""+ this.ItemData.Items[index].Name + " "+existsInPlaylist+" ";
82 | }
83 | document.getElementById("guiPlayListExisting").innerHTML = htmlToAdd + "
";
84 | }
85 |
86 | GuiPage_AddToPlaylist.updateSelectedItems = function() {
87 | for (var index = this.topLeftItem; index < Math.min(this.topLeftItem + this.getMaxDisplay(),this.ItemData.Items.length);index++) {
88 | if (index == this.selectedItem) {
89 | document.getElementById(this.ItemData.Items[index].Id).style.color = "#27a436";
90 | } else {
91 | document.getElementById(this.ItemData.Items[index].Id).style.color = "#f9f9f9";
92 | }
93 | }
94 | }
95 |
96 | GuiPage_AddToPlaylist.keyDown = function() {
97 | var keyCode = event.keyCode;
98 | alert("Key pressed: " + keyCode);
99 |
100 | if (document.getElementById("Notifications").style.visibility == "") {
101 | document.getElementById("Notifications").style.visibility = "hidden";
102 | document.getElementById("NotificationText").innerHTML = "";
103 | widgetAPI.blockNavigation(event);
104 | //Change keycode so it does nothing!
105 | keyCode = "VOID";
106 | }
107 |
108 | //Update Screensaver Timer
109 | Support.screensaver();
110 |
111 | //If screensaver is running
112 | if (Main.getIsScreensaverRunning()) {
113 | //Update Main.js isScreensaverRunning - Sets to True
114 | Main.setIsScreensaverRunning();
115 |
116 | //End Screensaver
117 | GuiImagePlayer_Screensaver.stopScreensaver();
118 |
119 | //Change keycode so it does nothing!
120 | keyCode = "VOID";
121 | }
122 |
123 | switch(keyCode) {
124 | case tvKey.KEY_UP:
125 | this.processUpKey();
126 | break;
127 | case tvKey.KEY_DOWN:
128 | this.processDownKey();
129 | break;
130 | case tvKey.KEY_ENTER:
131 | case tvKey.KEY_PANEL_ENTER:
132 | this.processSelectedItem();
133 | break;
134 | case tvKey.KEY_RETURN:
135 | alert("RETURN");
136 | widgetAPI.blockNavigation(event);
137 | document.getElementById("guiPlayListContainer").style.visibility = "hidden";
138 | document.getElementById(this.playedFromPage).focus();
139 | break;
140 | case tvKey.KEY_EXIT:
141 | alert ("EXIT KEY");
142 | widgetAPI.sendExitEvent();
143 | break;
144 | default:
145 | break;
146 | }
147 | }
148 |
149 | GuiPage_AddToPlaylist.processSelectedItem = function() {
150 | if (this.hasItemInPlaylist[this.selectedItem] == false) {
151 | //Send update to server
152 | Server.addToPlaylist(this.ItemData.Items[this.selectedItem].Id,this.itemId);
153 |
154 | //Don't get a refresh from server, assumes communication works.
155 | this.hasItemInPlaylist[this.selectedItem] = true;
156 | this.updateDisplayedItems();
157 | this.updateSelectedItems();
158 | document.getElementById("guiPlayListResult").innerHTML = "
The "+ this.mediaType.toLowerCase() +" was added to the playlist.
";
159 | } else {
160 | return;
161 | }
162 | //Close
163 | setTimeout(function(){
164 | document.getElementById("guiPlayListContainer").style.visibility = "hidden";
165 | document.getElementById("guiPlayListResult").innerHTML = "";
166 | document.getElementById(GuiPage_AddToPlaylist.playedFromPage).focus();
167 | }, 2000);
168 | }
169 |
170 | GuiPage_AddToPlaylist.processUpKey = function() {
171 | this.selectedItem = this.selectedItem - this.MAXCOLUMNCOUNT;
172 | if (this.selectedItem < 0) {
173 | this.selectedItem = 0;
174 | } else {
175 | if (this.selectedItem < this.topLeftItem) {
176 | if (this.topLeftItem - this.MAXCOLUMNCOUNT < 0) {
177 | this.topLeftItem = 0;
178 | } else {
179 | this.topLeftItem = this.topLeftItem - this.MAXCOLUMNCOUNT;
180 | }
181 | this.updateDisplayedItems();
182 | }
183 | this.updateSelectedItems();
184 | }
185 | }
186 |
187 | GuiPage_AddToPlaylist.processDownKey = function() {
188 | if (this.selectedItem == this.ItemData.Items.length - 1) {
189 | document.getElementById(this.ItemData.Items[this.selectedItem].Id).style.color = "#f9f9f9";
190 | Support.screensaverOff(); // Must turn off as not possible to catch keys!
191 | document.getElementById("guiPlayListNew").focus();
192 | } else {
193 | this.selectedItem = this.selectedItem + this.MAXCOLUMNCOUNT;
194 | if (this.selectedItem >= this.ItemData.Items.length) {
195 | this.selectedItem = (this.ItemData.Items.length-1);
196 | if (this.selectedItem >= (this.topLeftItem + this.getMaxDisplay())) {
197 | this.topLeftItem = this.topLeftItem + this.getMaxDisplay();
198 | this.updateDisplayedItems();
199 | }
200 | } else {
201 | if (this.selectedItem >= (this.topLeftItem + this.getMaxDisplay())) {
202 | this.topLeftItem = this.topLeftItem + this.MAXCOLUMNCOUNT;
203 | this.updateDisplayedItems();
204 | }
205 | }
206 | this.updateSelectedItems();
207 | }
208 | }
209 |
210 |
211 | //////////////////////////////////////////////////////////////////
212 | // Input method for entering new playlist name. //
213 | //////////////////////////////////////////////////////////////////
214 | var GuiPage_AddToPlaylist_Input = function(id) {
215 | var imeReady = function(imeObject) {
216 | installFocusKeyCallbacks();
217 | document.getElementById(id).focus();
218 | }
219 |
220 | var ime = new IMEShell("guiPlayListNew", imeReady,this);
221 | ime.setKeypadPos(1360,180);
222 | ime.setKeypadChangeFunc('qwerty',onSwitchToQwerty);
223 | ime.setKeypadChangeFunc('12key',onSwitchTo12key);
224 |
225 | function onSwitchToQwerty(arg){
226 | alert("IME selected:"+arg);
227 | document.getElementById("guiPlayListContainer").className = "playlistContainerQwerty";
228 | }
229 |
230 | function onSwitchTo12key(arg){
231 | alert("IME selected:"+arg);
232 | document.getElementById("guiPlayListContainer").className = "playlistContainer12key";
233 | }
234 |
235 | var installFocusKeyCallbacks = function () {
236 | ime.setKeyFunc(tvKey.KEY_ENTER, function (keyCode) {
237 | alert("Enter key pressed");
238 |
239 | var playlist = document.getElementById("guiPlayListNew").value;
240 | if (playlist == "") {
241 | document.getElementById("guiPlayListResult").innerHTML = "
Enter a playlist name or press Return to cancel.
";
242 | setTimeout(function(){
243 | document.getElementById("guiPlayListResult").innerHTML = "";
244 | }, 3000);
245 | return;
246 | }
247 | ime.setString("");
248 |
249 | //Check playlist name doesnt already exist!
250 |
251 | //Sent Server Request
252 | Server.createPlaylist(playlist,GuiPage_AddToPlaylist.itemId, GuiPage_AddToPlaylist.mediaType);
253 |
254 | document.getElementById("guiPlayListResult").innerHTML = "
The playlist was created.
";
255 |
256 | //Close
257 | setTimeout(function(){
258 | document.getElementById("guiPlayListContainer").style.visibility = "hidden";
259 | document.getElementById("guiPlayListResult").innerHTML = "";
260 | document.getElementById(GuiPage_AddToPlaylist.playedFromPage).focus();
261 | }, 2000);
262 |
263 | //Reload page!
264 | //GuiPage_AddToPlaylist.start(GuiPage_AddToPlaylist.itemId,GuiPage_AddToPlaylist.playedFromPage,GuiPage_AddToPlaylist.mediaType);
265 |
266 | });
267 |
268 | ime.setKeyFunc(tvKey.KEY_UP, function (keyCode) {
269 | Support.screensaver();
270 |
271 | if (GuiPage_AddToPlaylist.ItemData.Items.length > 0 ) {
272 | GuiPage_AddToPlaylist.updateSelectedItems();
273 | document.getElementById("GuiPage_AddToPlaylist").focus();
274 | }
275 | });
276 |
277 | ime.setKeyFunc(tvKey.KEY_RETURN, function (keyCode) {
278 | widgetAPI.blockNavigation(event);
279 | //Handle Return
280 | Support.screensaver();
281 | document.getElementById("guiPlayListContainer").style.visibility = "hidden";
282 | document.getElementById(GuiPage_AddToPlaylist.playedFromPage).focus();
283 | });
284 |
285 | ime.setKeyFunc(tvKey.KEY_EXIT, function (keyCode) {
286 | widgetAPI.sendExitEvent();
287 | });
288 | }
289 | }
--------------------------------------------------------------------------------
/app/javascript/Gui/GuiMainMenu.js:
--------------------------------------------------------------------------------
1 | var GuiMainMenu = {
2 | menuItems : [],
3 | menuItemsHomePages : [],
4 |
5 | pageSelected : "",
6 | selectedDivId : 0,
7 | selectedDivClass : "",
8 |
9 | testModeCount : 0,
10 | testModeTimeout : null,
11 |
12 | isMusicPlaying : false,
13 |
14 | clockVar : null
15 | }
16 |
17 | GuiMainMenu.getSelectedMainMenuItem = function() {
18 | return this.selectedMainMenuItem;
19 | }
20 |
21 | //Entry Point from User Menu - ONLY RUN ONCE PER USER LOGIN
22 | GuiMainMenu.start = function() {
23 | //Generate Menu based on whether there is any of (Folders, TV, Movies, .....)
24 | this.menuItems.length = 0;
25 | this.menuItemsHomePages.length = 0;
26 |
27 | //Generate main menu items
28 | this.menuItemsHomePages = Support.generateTopMenu();
29 | this.menuItems = Support.generateMainMenu();
30 |
31 | //Get user details.
32 | //document.getElementById("menuUserName").innerHTML = "
"+Server.getUserName()+"
";
33 | var userURL = Server.getServerAddr() + "/Users/" + Server.getUserID() + "?format=json&Fields=PrimaryImageTag";
34 | var UserData = Server.getContent(userURL);
35 | if (UserData == null) { return; }
36 |
37 | //User Image
38 | if (UserData.PrimaryImageTag) {
39 | var imgsrc = Server.getImageURL(UserData.Id,"UsersPrimary",70,70,0,false,0);
40 | document.getElementById("menuUserImage").style.backgroundImage = "url(" + imgsrc + ")";
41 | } else {
42 | document.getElementById("menuUserImage").style.backgroundImage = "url(images/loginusernoimage.png)";
43 | }
44 |
45 | //Add menu entries
46 | var htmlToAdd = "";
47 | for (var index = 0; index < this.menuItems.length;index++) {
48 | htmlToAdd += "";
49 | }
50 | document.getElementById("menuItems").innerHTML = htmlToAdd;
51 |
52 | //Add settings and logout
53 | htmlToAdd = "";
54 | this.menuItems.push("Search");
55 | htmlToAdd += "";
56 | this.menuItems.push("Settings");
57 | htmlToAdd += "";
58 | this.menuItems.push("Log_Out");
59 | htmlToAdd += "";
60 | document.getElementById("menuItems").innerHTML += htmlToAdd;
61 |
62 | //Turn On Screensaver
63 | Support.screensaverOn();
64 | Support.screensaver();
65 |
66 | //Validate and update home page URL's
67 | //Convert views in http format to viewnames for settings in versions <=2.1.3
68 | var url1 = File.getUserProperty("View1");
69 | if (url1.substring(0,4) == "http") {
70 | alert("Converting View1");
71 | File.setUserProperty("View1","TVNextUp");
72 | File.setUserProperty("View1Name","Next Up");
73 | }
74 |
75 | var url2 = File.getUserProperty("View2");
76 | if (url2) {
77 | if (url2.substring(0,4) == "http") {
78 | alert("Converting View2");
79 | File.setUserProperty("View2","LatestMovies");
80 | File.setUserProperty("View2Name","Latest Movies");
81 | }
82 | }
83 |
84 | //Initialise view URL's
85 | Support.initViewUrls();
86 |
87 | //Set the page highlight colour
88 | Main.highlightColour = File.getUserProperty("HighlightColour");
89 |
90 | //Load Home Page
91 | Support.processHomePageMenu("Home");
92 | }
93 |
94 | //Entry Point when called from any page displaying the menu
95 | GuiMainMenu.requested = function(pageSelected, selectedDivId, selectedDivClass) {
96 | //Reset Menus
97 | this.selectedMainMenuItem = 0;
98 | this.selectedSubMenuItem = 0;
99 |
100 | //UnSelect Selected Item on whatever page is loaded
101 | this.pageSelected = pageSelected;
102 | this.selectedDivId = selectedDivId;
103 |
104 | //Unhighlights the page's selected content
105 | if (this.selectedDivId != null) {
106 | if (selectedDivClass === undefined) {
107 | this.selectedDivClass = "UNDEFINED";
108 | } else {
109 | this.selectedDivClass = selectedDivClass;
110 | }
111 | document.getElementById(selectedDivId).className = document.getElementById(selectedDivId).className.replace("GuiPage_Setting_Changing arrowUpDown","");
112 | document.getElementById(selectedDivId).className = document.getElementById(selectedDivId).className.replace("highlight"+Main.highlightColour+"Background","");
113 | document.getElementById(selectedDivId).className = document.getElementById(selectedDivId).className.replace("highlight"+Main.highlightColour+"Text","");
114 | document.getElementById(selectedDivId).className = document.getElementById(selectedDivId).className.replace("seriesSelected","");
115 | document.getElementById(selectedDivId).className = document.getElementById(selectedDivId).className.replace("Selected","");
116 | }
117 |
118 | //Show Menu
119 | document.getElementById("menu").style.visibility = "";
120 | document.getElementById("menu").style.left = "0px";
121 | document.getElementById("page").style.left = "350px";
122 |
123 | //Show submenu dependant on selectedMainMenuItem
124 | this.updateSelectedItems();
125 |
126 | //Set Focus
127 | document.getElementById("GuiMainMenu").focus();
128 | }
129 |
130 | GuiMainMenu.updateSelectedItems = function () {
131 | for (var index = 0; index < this.menuItems.length; index++){
132 | if (index == this.selectedMainMenuItem) {
133 | document.getElementById(this.menuItems[index]).className = "menu-item highlight"+Main.highlightColour+"Background";
134 | } else {
135 | document.getElementById(this.menuItems[index]).className = "menu-item";
136 | }
137 | }
138 | }
139 |
140 | //-------------------------------------------------------------
141 | // Main Menu Key Handling
142 | //-------------------------------------------------------------
143 | GuiMainMenu.keyDown = function()
144 | {
145 | var keyCode = event.keyCode;
146 | alert("Key pressed: " + keyCode);
147 |
148 | if (document.getElementById("Notifications").style.visibility == "") {
149 | document.getElementById("Notifications").style.visibility = "hidden";
150 | document.getElementById("NotificationText").innerHTML = "";
151 | widgetAPI.blockNavigation(event);
152 | //Change keycode so it does nothing!
153 | keyCode = "VOID";
154 | }
155 |
156 | //Update Screensaver Timer
157 | Support.screensaver();
158 |
159 | //If screensaver is running
160 | if (Main.getIsScreensaverRunning()) {
161 | //Update Main.js isScreensaverRunning - Sets to True
162 | Main.setIsScreensaverRunning();
163 |
164 | //End Screensaver
165 | GuiImagePlayer_Screensaver.stopScreensaver();
166 |
167 | //Change keycode so it does nothing!
168 | keyCode = "VOID";
169 | }
170 |
171 | switch(keyCode)
172 | {
173 | case tvKey.KEY_UP:
174 | alert("Up");
175 | this.processUpKey();
176 | break;
177 | case tvKey.KEY_DOWN:
178 | alert("DOWN");
179 | this.processDownKey();
180 | break;
181 | case tvKey.KEY_ENTER:
182 | case tvKey.KEY_PANEL_ENTER:
183 | alert("ENTER");
184 | this.processSelectedItems();
185 | break;
186 | case tvKey.KEY_PLAY:
187 | this.playSelectedItem();
188 | break;
189 | case tvKey.KEY_RIGHT:
190 | case tvKey.KEY_RETURN:
191 | case tvKey.KEY_TOOLS:
192 | widgetAPI.blockNavigation(event);
193 | //Allows blocking of return from menu if page has no selectable items
194 | this.processReturnKey();
195 | break;
196 | case tvKey.KEY_RED:
197 | //this.toggleTestMode();
198 | break;
199 | case tvKey.KEY_EXIT:
200 | alert ("EXIT KEY");
201 | widgetAPI.sendExitEvent();
202 | break;
203 | }
204 | }
205 |
206 | GuiMainMenu.processSelectedItems = function() {
207 |
208 | //Selecting home when you came from home just closes the menu.
209 | if (this.menuItems[this.selectedMainMenuItem] == "Home" &&
210 | (this.pageSelected == "GuiPage_HomeOneItem" || this.pageSelected == "GuiPage_HomeTwoItems")) {
211 | this.processReturnKey();
212 | return;
213 | }
214 |
215 | //If a trailer was paused when we arrived in the menu, stop it now.
216 | if (GuiPage_ItemDetails.trailerState == sf.service.VideoPlayer.STATE_PAUSED) {
217 | sf.service.VideoPlayer.stop();
218 | }
219 |
220 | //Close the menu
221 | document.getElementById("menu").style.visibility = "none";
222 | document.getElementById("menu").style.left = "-350px";
223 | document.getElementById("page").style.left = "0px";
224 |
225 | setTimeout(function(){
226 | Support.processHomePageMenu(GuiMainMenu.menuItems[GuiMainMenu.selectedMainMenuItem]);
227 | }, 200);
228 | }
229 |
230 | GuiMainMenu.playSelectedItem = function() {
231 | //Pressing play on Photos in the main menu plays a random slideshow.
232 | if (this.menuItems[this.selectedMainMenuItem] == "Photos") {
233 |
234 | //Close the menu
235 | document.getElementById("menu").style.visibility = "none";
236 | document.getElementById("menu").style.left = "-350px";
237 | document.getElementById("page").style.left = "0px";
238 |
239 | var userViews = Server.getUserViews();
240 | for (var i = 0; i < userViews.Items.length; i++){
241 | if (userViews.Items[i].CollectionType == "photos"){
242 | GuiImagePlayer.start(userViews,i,true);
243 | }
244 | }
245 | }
246 | }
247 |
248 | GuiMainMenu.processReturnKey = function() {
249 | if (this.pageSelected != null) {
250 | //As I don't want the settings page in the URL History I need to prevent popping it here (as its not added on leaving the settings page
251 | if (this.pageSelected != "GuiPage_Settings") {
252 | Support.removeLatestURL();
253 | }
254 |
255 | //Cheap way to unhighlight all items!
256 | this.selectedMainMenuItem = -1;
257 | this.updateSelectedItems();
258 | this.selectedMainMenuItem = 0;
259 |
260 | //Close the menu
261 | document.getElementById("menu").style.visibility = "none";
262 | document.getElementById("menu").style.left = "-350px";
263 | document.getElementById("page").style.left = "0px";
264 |
265 | if (this.pageSelected == "GuiMusicPlayer") {
266 | GuiMusicPlayer.showMusicPlayer(this.selectedDivId);
267 | }
268 |
269 | //Set Page GUI elements Correct & Set Focus
270 | if (this.selectedDivId != null) {
271 | if (this.selectedDivClass == "UNDEFINED") {
272 | document.getElementById(this.selectedDivId).className = document.getElementById(this.selectedDivId).className + " Selected";
273 | } else {
274 | document.getElementById(this.selectedDivId).className = this.selectedDivClass;
275 | }
276 | }
277 |
278 | //If a trailer was playing, set it going again.
279 | if (GuiPage_ItemDetails.trailerState == sf.service.VideoPlayer.STATE_PAUSED) {
280 | setTimeout(function(){
281 | sf.service.VideoPlayer.show();
282 | sf.service.VideoPlayer.resume();
283 | }, 300);
284 | }
285 |
286 | document.getElementById(this.pageSelected).focus();
287 | }
288 | }
289 |
290 | GuiMainMenu.processUpKey = function() {
291 | this.selectedMainMenuItem--;
292 | if (this.selectedMainMenuItem < 0) {
293 | this.selectedMainMenuItem = this.menuItems.length-1;
294 | }
295 | this.updateSelectedItems();
296 | }
297 |
298 | GuiMainMenu.processDownKey = function() {
299 | this.selectedMainMenuItem++;
300 | if (this.selectedMainMenuItem >= this.menuItems.length) {
301 | this.selectedMainMenuItem = 0;
302 | }
303 | this.updateSelectedItems();
304 | }
305 |
306 | GuiMainMenu.toggleTestMode = function() {
307 | if (this.testModeCount < 2) {
308 | this.testModeCount++;
309 | clearTimeout (this.testModeTimeout);
310 | this.testModeTimeout = setTimeout(function() {
311 | GuiMainMenu.testModeCount = 0;
312 | },3000)
313 | } else {
314 | clearTimeout (this.testModeTimeout);
315 | Main.setTestMode();
316 | GuiNotifications.setNotification("Test mode is now: " + Main.getTestMode(),"Test Mode");
317 | this.testModeCount = 0;
318 | }
319 | }
--------------------------------------------------------------------------------
/app/javascript/Gui/GuiDisplayOneItem.js:
--------------------------------------------------------------------------------
1 | var GuiDisplayOneItem = {
2 | ItemData : null,
3 | ItemIndexData : null,
4 |
5 | selectedItem : 0,
6 | topLeftItem : 0,
7 | MAXCOLUMNCOUNT : 4,
8 | MAXROWCOUNT : 3,
9 |
10 | indexSeekPos : -1,
11 | isResume : false,
12 | genreType : "",
13 |
14 | startParams : [],
15 | isLatest : false,
16 | backdropTimeout : null
17 | }
18 |
19 | GuiDisplayOneItem.onFocus = function() {
20 | GuiHelper.setControlButtons(null,null,null,GuiMusicPlayer.Status == "PLAYING" || GuiMusicPlayer.Status == "PAUSED" ? "Music" : null,"Return");
21 | }
22 |
23 | GuiDisplayOneItem.getMaxDisplay = function() {
24 | return this.MAXCOLUMNCOUNT * this.MAXROWCOUNT;
25 | }
26 |
27 | GuiDisplayOneItem.start = function(title,url,selectedItem,topLeftItem) {
28 | alert("Page Enter : GuiDisplayOneItem");
29 |
30 | //Save Start Params
31 | this.startParams = [title,url];
32 |
33 | //Reset Values
34 | this.indexSeekPos = -1;
35 | this.selectedItem = selectedItem;
36 | this.topLeftItem = topLeftItem;
37 | this.genreType = null;
38 |
39 | //Load Data
40 | this.ItemData = Server.getContent(url + "&Limit="+File.getTVProperty("ItemPaging"));
41 | if (this.ItemData == null) { Support.processReturnURLHistory(); }
42 | //Once we've browsed the channels down to a content folder we should display them using GuiDisplay_Series.
43 | if (this.ItemData.TotalRecordCount >0){
44 | if (this.ItemData.Items[0].Type == "ChannelVideoItem" ||
45 | this.ItemData.Items[0].Type == "ChannelAudioItem" ||
46 | this.ItemData.Items[0].Type == "Trailer" ||
47 | this.ItemData.Items[0].Type == "AudioPodcast") {
48 | GuiDisplay_Series.start("All "+this.ItemData.Items[0].Type,url,selectedItem,topLeftItem,this.ItemData);
49 | return;
50 | }
51 | }
52 |
53 | //Setup display width height based on title
54 | switch (title) {
55 | case "Collections":
56 | case "Channels":
57 | this.MAXCOLUMNCOUNT = 3;
58 | this.MAXROWCOUNT = 2;
59 | break;
60 | case "Music":
61 | case "Albums":
62 | case "Artists":
63 | this.MAXCOLUMNCOUNT = 6;
64 | this.MAXROWCOUNT = 3;
65 | break;
66 | default:
67 | this.MAXCOLUMNCOUNT = 4;
68 | this.MAXROWCOUNT = 3;
69 | break;
70 | }
71 |
72 | //Set Page Content
73 | document.getElementById("pageContent").innerHTML = "
"+title+"
" +
74 | "
";
75 |
76 | //Set Top
77 | GuiDisplayOneItem.setPadding(title);
78 |
79 | if (this.ItemData.Items.length > 0) {
80 | //Set isResume based on title - used in UpdateDisplayedItems
81 | this.isResume = (title == "Resume") ? true : false;
82 |
83 | //Alter to only allow indexing on certain pages??
84 | //this.ItemIndexData = Support.processIndexing(this.ItemData.Items);
85 |
86 | //Display first XX series
87 | this.updateDisplayedItems();
88 |
89 | //Update Selected Collection CSS
90 | this.updateSelectedItems();
91 |
92 | //Set Focus for Key Events
93 | document.getElementById("GuiDisplayOneItem").focus();
94 | } else {
95 | //Set message to user
96 | document.getElementById("Counter").innerHTML = "";
97 | document.getElementById("Content").style.fontSize="40px";
98 | document.getElementById("Content").innerHTML = "Huh.. Looks like I have no content to show you in this view I'm afraid
Press return to get back to the previous screen";
99 |
100 | document.getElementById("NoItems").focus();
101 | }
102 | }
103 |
104 | GuiDisplayOneItem.updateDisplayedItems = function() {
105 | Support.updateDisplayedItems(this.ItemData.Items,this.selectedItem,this.topLeftItem,
106 | Math.min(this.topLeftItem + this.getMaxDisplay(),this.ItemData.Items.length),"Content","",this.isResume,this.genreType,true);
107 | }
108 |
109 | //Function sets CSS Properties so show which user is selected
110 | GuiDisplayOneItem.updateSelectedItems = function () {
111 | if (this.MAXCOLUMNCOUNT == 3) {
112 | //Add Collections Class to add more margin
113 | Support.updateSelectedNEW(this.ItemData.Items,this.selectedItem,this.topLeftItem,
114 | Math.min(this.topLeftItem + this.getMaxDisplay(),this.ItemData.Items.length),"Series Collection Selected highlight"+Main.highlightColour+"Boarder","Series Collection","");
115 | } else {
116 | Support.updateSelectedNEW(this.ItemData.Items,this.selectedItem,this.topLeftItem,
117 | Math.min(this.topLeftItem + this.getMaxDisplay(),this.ItemData.Items.length),"Series Selected highlight"+Main.highlightColour+"Boarder","Series","");
118 | }
119 | }
120 |
121 | GuiDisplayOneItem.keyDown = function() {
122 | var keyCode = event.keyCode;
123 | alert("GuiDisplayOneItem: Key pressed: " + keyCode);
124 |
125 | if (document.getElementById("Notifications").style.visibility == "") {
126 | document.getElementById("Notifications").style.visibility = "hidden";
127 | document.getElementById("NotificationText").innerHTML = "";
128 | widgetAPI.blockNavigation(event);
129 | //Change keycode so it does nothing!
130 | keyCode = "VOID";
131 | }
132 |
133 | //Update Screensaver Timer
134 | Support.screensaver();
135 |
136 | //If screensaver is running
137 | if (Main.getIsScreensaverRunning()) {
138 | //Update Main.js isScreensaverRunning - Sets to True
139 | Main.setIsScreensaverRunning();
140 |
141 | //End Screensaver
142 | GuiImagePlayer_Screensaver.stopScreensaver();
143 |
144 | //Change keycode so it does nothing!
145 | keyCode = "VOID";
146 | }
147 |
148 | switch(keyCode) {
149 | //Need Logout Key
150 | case tvKey.KEY_LEFT:
151 | alert("LEFT");
152 | this.processLeftKey();
153 | break;
154 | case tvKey.KEY_RIGHT:
155 | alert("RIGHT");
156 | this.processRightKey();
157 | break;
158 | case tvKey.KEY_UP:
159 | alert("UP");
160 | this.processUpKey();
161 | break;
162 | case tvKey.KEY_DOWN:
163 | alert("DOWN");
164 | this.processDownKey();
165 | break;
166 | case tvKey.KEY_PANEL_CH_UP:
167 | case tvKey.KEY_CH_UP:
168 | this.processChannelUpKey();
169 | break;
170 | case tvKey.KEY_PANEL_CH_DOWN:
171 | case tvKey.KEY_CH_DOWN:
172 | this.processChannelDownKey();
173 | break;
174 | case tvKey.KEY_RETURN:
175 | alert("RETURN");
176 | widgetAPI.blockNavigation(event);
177 | Support.processReturnURLHistory();
178 | break;
179 | case tvKey.KEY_ENTER:
180 | case tvKey.KEY_PANEL_ENTER:
181 | alert("ENTER");
182 | this.processSelectedItem();
183 | break;
184 | case tvKey.KEY_PLAY:
185 | this.playSelectedItem();
186 | break;
187 | case tvKey.KEY_GREEN:
188 | //Watched - May not be needed on this page
189 | break;
190 | case tvKey.KEY_YELLOW:
191 | //Favourites - May not be needed on this page
192 | break;
193 | case tvKey.KEY_BLUE:
194 | GuiMusicPlayer.showMusicPlayer("GuiDisplayOneItem",this.ItemData.Items[this.selectedItem].Id,document.getElementById(this.ItemData.Items[this.selectedItem].Id).className);
195 | break;
196 | case tvKey.KEY_TOOLS:
197 | widgetAPI.blockNavigation(event);
198 | this.openMenu();
199 | break;
200 | case tvKey.KEY_EXIT:
201 | alert ("EXIT KEY");
202 | widgetAPI.sendExitEvent();
203 | break;
204 | }
205 | }
206 |
207 | GuiDisplayOneItem.processSelectedItem = function() {
208 | clearTimeout(this.backdropTimeout);
209 | Support.processSelectedItem("GuiDisplayOneItem",this.ItemData,this.startParams,this.selectedItem,this.topLeftItem,null,this.genreType,this.isLatest);
210 | }
211 |
212 | GuiDisplayOneItem.playSelectedItem = function () {
213 | clearTimeout(this.backdropTimeout);
214 | Support.playSelectedItem("GuiDisplayOneItem",this.ItemData,this.startParams,this.selectedItem,this.topLeftItem,null);
215 | }
216 |
217 | GuiDisplayOneItem.openMenu = function() {
218 | Support.updateURLHistory("GuiDisplayOneItem",this.startParams[0],this.startParams[1],null,null,this.selectedItem,this.topLeftItem,null);
219 | GuiMainMenu.requested("GuiDisplayOneItem",this.ItemData.Items[this.selectedItem].Id);
220 | }
221 |
222 | GuiDisplayOneItem.processLeftKey = function() {
223 | if (this.selectedItem % this.MAXCOLUMNCOUNT == 0){
224 | this.openMenu(); //Going left from anywhere in the first column.
225 | } else {
226 | this.selectedItem--;
227 | if (this.selectedItem == -1) {
228 | this.selectedItem = 0;
229 | this.openMenu();
230 | } else {
231 | if (this.selectedItem < this.topLeftItem) {
232 | this.topLeftItem = this.selectedItem - (this.getMaxDisplay() - 1);
233 | if (this.topLeftItem < 0) {
234 | this.topLeftItem = 0;
235 | }
236 | this.updateDisplayedItems();
237 | }
238 | }
239 | this.updateSelectedItems();
240 | }
241 | }
242 |
243 | GuiDisplayOneItem.processRightKey = function() {
244 | this.selectedItem++;
245 | if (this.selectedItem >= this.ItemData.Items.length) {
246 | this.selectedItem--;
247 | } else {
248 | if (this.selectedItem >= this.topLeftItem+this.getMaxDisplay() ) {
249 | this.topLeftItem = this.selectedItem;
250 | this.updateDisplayedItems();
251 | }
252 | }
253 | this.updateSelectedItems();
254 | }
255 |
256 | GuiDisplayOneItem.processUpKey = function() {
257 | this.selectedItem = this.selectedItem - this.MAXCOLUMNCOUNT;
258 | if (this.selectedItem < 0) {
259 | //Check User Setting
260 | this.selectedItem = this.selectedItem + this.MAXCOLUMNCOUNT;
261 | } else {
262 | if (this.selectedItem < this.topLeftItem) {
263 | if (this.topLeftItem - this.MAXCOLUMNCOUNT < 0) {
264 | this.topLeftItem = 0;
265 | } else {
266 | this.topLeftItem = this.topLeftItem - this.MAXCOLUMNCOUNT;
267 | }
268 | this.updateDisplayedItems();
269 | }
270 | }
271 | this.updateSelectedItems();
272 | }
273 |
274 | GuiDisplayOneItem.processDownKey = function() {
275 | this.selectedItem = this.selectedItem + this.MAXCOLUMNCOUNT;
276 | if (this.selectedItem >= this.ItemData.Items.length) {
277 | this.selectedItem = (this.ItemData.Items.length-1);
278 | if (this.selectedItem >= (this.topLeftItem + this.getMaxDisplay())) {
279 | this.topLeftItem = this.topLeftItem + this.getMaxDisplay();
280 | this.updateDisplayedItems();
281 | }
282 | } else {
283 | if (this.selectedItem >= (this.topLeftItem + this.getMaxDisplay())) {
284 | this.topLeftItem = this.topLeftItem + this.MAXCOLUMNCOUNT;
285 | this.updateDisplayedItems();
286 | }
287 | }
288 | this.updateSelectedItems();
289 | }
290 |
291 | GuiDisplayOneItem.processChannelUpKey = function() {
292 | this.selectedItem = this.selectedItem - this.getMaxDisplay();
293 | if (this.selectedItem < 0) {
294 | this.selectedItem = 0;
295 | this.topLeftItem = 0;
296 | this.updateDisplayedItems();
297 | } else {
298 | if (this.topLeftItem - this.getMaxDisplay() < 0) {
299 | this.topLeftItem = 0;
300 | } else {
301 | this.topLeftItem = this.topLeftItem - this.getMaxDisplay();
302 | }
303 | this.updateDisplayedItems();
304 | }
305 | this.updateSelectedItems();
306 | }
307 |
308 | GuiDisplayOneItem.processChannelDownKey = function() {
309 | this.selectedItem = this.selectedItem + this.getMaxDisplay();
310 | if (this.selectedItem >= this.ItemData.Items.length) {
311 | this.selectedItem = (this.ItemData.Items.length-1);
312 | if (this.selectedItem >= this.topLeftItem + this.getMaxDisplay()) {
313 | this.topLeftItem = this.topLeftItem + this.getMaxDisplay();
314 | }
315 | this.updateDisplayedItems();
316 | } else {
317 | this.topLeftItem = this.topLeftItem + this.getMaxDisplay();
318 | this.updateDisplayedItems();
319 | }
320 | this.updateSelectedItems();
321 | }
322 |
323 | GuiDisplayOneItem.processIndexing = function() {
324 | var indexLetter = this.ItemIndexData[0];
325 | var indexPos = this.ItemIndexData[1];
326 |
327 | this.indexSeekPos++;
328 | if (this.indexSeekPos >= indexPos.length) {
329 | this.indexSeekPos = 0;
330 | this.topLeftItem = 0;
331 | }
332 |
333 | this.selectedItem = indexPos[this.indexSeekPos];
334 | this.topLeftItem = this.selectedItem;
335 |
336 | this.updateDisplayedItems();
337 | this.updateSelectedItems();
338 | }
339 |
340 | GuiDisplayOneItem.setPadding = function(title) {
341 | switch (title) {
342 | case "Media Folders":
343 | case "Collections":
344 | if (this.ItemData.Items.length <= this.MAXCOLUMNCOUNT) {
345 | document.getElementById("Center").style.top = "220px";
346 | } else {
347 | document.getElementById("Center").style.top = "180px";
348 | }
349 | break;
350 | case "Music":
351 | case "Albums":
352 | case "Artists":
353 | break;
354 | default:
355 | if (this.ItemData.Items.length > this.MAXCOLUMNCOUNT * 2) {
356 | //3 Rows
357 | document.getElementById("Center").style.top = "120px";
358 | } else if (this.ItemData.Items.length > this.MAXCOLUMNCOUNT) {
359 | //2 Rows
360 | document.getElementById("Center").style.top = "220px";
361 | } else {
362 | //1 Row
363 | document.getElementById("Center").style.top = "180px";
364 | }
365 | break;
366 | }
367 | }
368 |
369 | GuiDisplayOneItem.returnFromMusicPlayer = function() {
370 | this.selectedItem = 0;
371 | this.updateDisplayedItems();
372 | this.updateSelectedItems();
373 | }
--------------------------------------------------------------------------------
/app/javascript/Support/File.js:
--------------------------------------------------------------------------------
1 | var File = {
2 | ServerEntry : null,
3 | UserEntry : null
4 | };
5 |
6 | File.getServerEntry = function() {
7 | return this.ServerEntry;
8 | };
9 |
10 | File.setServerEntry = function(serverEntry) {
11 | this.ServerEntry = serverEntry;
12 | };
13 |
14 | File.getUserEntry = function() {
15 | return this.UserEntry;
16 | };
17 |
18 | File.setUserEntry = function(userEntry) {
19 | this.UserEntry = userEntry;
20 | };
21 |
22 | File.deleteOldSettingsFile = function() {
23 | var fileSystemObj = new FileSystem();
24 | fileSystemObj.deleteCommonFile(curWidget.id + '/MB3_Settings.xml');
25 | };
26 |
27 | File.deleteSettingsFile = function() {
28 | var fileSystemObj = new FileSystem();
29 | fileSystemObj.deleteCommonFile(curWidget.id + '/MB3_Settings.json');
30 | };
31 |
32 | File.loadFile = function() {
33 | var fileSystemObj = new FileSystem();
34 |
35 | var bValid = fileSystemObj.isValidCommonPath(curWidget.id);
36 | if (!bValid) {
37 | fileSystemObj.createCommonDir(curWidget.id);
38 | var fileObj = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Settings.json', 'w');
39 | var contentToWrite = '{"Version":"'+Main.getVersion()+'","Servers":[],"TV":{}}';
40 | fileObj.writeLine(contentToWrite);
41 | fileSystemObj.closeCommonFile(fileObj);
42 | }
43 |
44 | var openRead = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Settings.json', 'r');
45 | if (!openRead) {
46 | fileSystemObj.createCommonDir(curWidget.id);
47 | var fileObj = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Settings.json', 'w');
48 | var contentToWrite = '{"Version":"'+Main.getVersion()+'","Servers":[],"TV":{}}';
49 | fileObj.writeLine(contentToWrite);
50 | fileSystemObj.closeCommonFile(fileObj);
51 | return contentToWrite;
52 | } else {
53 | var fileContents = openRead.readAll();
54 | fileSystemObj.closeCommonFile(openRead);
55 | return fileContents;
56 | }
57 | };
58 |
59 | File.checkVersion = function(fileContent) {
60 | if (fileContent.Version === undefined) {
61 | return "Undefined"
62 | } else {
63 | return fileContent.Version;
64 | }
65 | };
66 |
67 | File.saveServerToFile = function(Id,Name,ServerIP) {
68 | var fileSystemObj = new FileSystem();
69 | var openRead = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Settings.json', 'r');
70 | if (openRead) {
71 | var fileJson = JSON.parse(openRead.readLine()); //Read line as only 1 and skips line break!
72 | fileSystemObj.closeCommonFile(openRead);
73 |
74 | var serverExists = false;
75 | for (var index = 0; index < fileJson.Servers.length; index++) {
76 | if (Id == fileJson.Servers[index].Id) {
77 | this.ServerEntry = index;
78 | serverExists = true;
79 | alert ("Server already exists in file - not adding - Server Entry: " + this.ServerEntry);
80 | }
81 | }
82 |
83 | if (serverExists == false) {
84 | this.ServerEntry = fileJson.Servers.length
85 | fileJson.Servers[fileJson.Servers.length] = {"Id":Id,"Name":Name,"Path":ServerIP,"Default":false,"Users":[]};
86 | var openWrite = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Settings.json', 'w');
87 | if (openWrite) {
88 | openWrite.writeLine(JSON.stringify(fileJson));
89 | fileSystemObj.closeCommonFile(openWrite);
90 | alert ("Server added to file - Server Entry: " + this.ServerEntry);
91 | }
92 | }
93 | }
94 | };
95 |
96 | File.setDefaultServer = function (defaultIndex) {
97 | var fileJson = JSON.parse(File.loadFile());
98 | for (var index = 0; index < fileJson.Servers.length; index++) {
99 | if (fileJson.Servers[defaultIndex].Id == fileJson.Servers[index].Id ) {
100 | fileJson.Servers[index].Default = true;
101 | } else {
102 | fileJson.Servers[index].Default = false;
103 | }
104 | }
105 |
106 | var fileSystemObj = new FileSystem();
107 | var openWrite = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Settings.json', 'w');
108 | if (openWrite) {
109 | openWrite.writeLine(JSON.stringify(fileJson));
110 | fileSystemObj.closeCommonFile(openWrite);
111 | }
112 | GuiNotifications.setNotification(fileJson.Servers[defaultIndex].Name + " is now your default Server and will be logged in autiomatically from now on.","Default Server Changed",true);
113 | };
114 |
115 | File.deleteServer = function (index) {
116 | var fileSystemObj = new FileSystem();
117 | var openRead = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Settings.json', 'r');
118 | if (openRead) {
119 | var fileJson = JSON.parse(openRead.readLine()); //Read line as only 1 and skips line break!
120 | fileSystemObj.closeCommonFile(openRead);
121 |
122 | fileJson.Servers.splice(index);
123 |
124 | var openWrite = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Settings.json', 'w');
125 | if (openWrite) {
126 | openWrite.writeLine(JSON.stringify(fileJson));
127 | fileSystemObj.closeCommonFile(openWrite);
128 | }
129 |
130 | if (fileJson.Servers.length == 0) {
131 | GuiPage_NewServer.start();
132 | } else {
133 | GuiPage_Servers.start();
134 | }
135 | }
136 | };
137 |
138 | File.addUser = function (UserId, Name, Password, rememberPassword) {
139 | var fileSystemObj = new FileSystem();
140 | var openRead = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Settings.json', 'r');
141 | if (openRead) {
142 | var fileJson = JSON.parse(openRead.readLine()); //Read line as only 1 and skips line break!
143 | fileSystemObj.closeCommonFile(openRead);
144 |
145 | //Check if user doesn't already exist - if does, alter password and save!
146 | var userFound = false;
147 | for (var index = 0; index < fileJson.Servers[this.ServerEntry].Users.length; index++) {
148 | if (fileJson.Servers[this.ServerEntry].Users[index].UserId == UserId) {
149 | userFound = true;
150 | this.UserEntry = index;
151 | fileJson.Servers[this.ServerEntry].Users[index].Password = Password;
152 | fileJson.Servers[this.ServerEntry].Users[index].RememberPassword = rememberPassword;
153 | break;
154 | }
155 | }
156 | if (userFound == false) {
157 | this.UserEntry = fileJson.Servers[this.ServerEntry].Users.length;
158 | //view1 = Server.getServerAddr() + "/Shows/NextUp?format=json&UserId="+Server.getUserID()+"&IncludeItemTypes=Episode&ExcludeLocationTypes=Virtual&Limit=24&Fields=PrimaryImageAspectRatio,SeriesInfo,DateCreated,SyncInfo,SortName&ImageTypeLimit=1&EnableImageTypes=Primary,Backdrop,Banner,Thumb";
159 | //view2 = Server.getCustomURL("/Users/" + Server.getUserID() + "/Items/Latest?format=json&IncludeItemTypes=Movie"+Server.getMoviesViewQueryPart()+"&IsFolder=false&fields=ParentId,SortName,Overview,Genres,RunTimeTicks");
160 | fileJson.Servers[this.ServerEntry].Users[this.UserEntry] = {"UserId":UserId,"UserName":Name.toLowerCase(),"Password":Password,"RememberPassword":rememberPassword,"Default":false,"HighlightColour":1,"ContinueWatching":true,"View1":"TVNextUp","View1Name":"Next Up","View2":"LatestMovies","View2Name":"Latest Movies"};
161 |
162 | }
163 |
164 | var openWrite = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Settings.json', 'w');
165 | if (openWrite) {
166 | openWrite.writeLine(JSON.stringify(fileJson));
167 | fileSystemObj.closeCommonFile(openWrite);
168 | }
169 | }
170 | };
171 |
172 | File.deleteUser = function (index) {
173 | var fileSystemObj = new FileSystem();
174 | var openRead = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Settings.json', 'r');
175 | if (openRead) {
176 | var fileJson = JSON.parse(openRead.readLine()); //Read line as only 1 and skips line break!
177 | fileSystemObj.closeCommonFile(openRead);
178 |
179 | fileJson.Servers[this.ServerEntry].Users.splice(index);
180 |
181 | var openWrite = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Settings.json', 'w');
182 | if (openWrite) {
183 | openWrite.writeLine(JSON.stringify(fileJson));
184 | fileSystemObj.closeCommonFile(openWrite);
185 | }
186 | }
187 | };
188 |
189 | File.deleteAllUsers = function (index) {
190 | var fileSystemObj = new FileSystem();
191 | var openRead = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Settings.json', 'r');
192 | if (openRead) {
193 | var fileJson = JSON.parse(openRead.readLine()); //Read line as only 1 and skips line break!
194 | fileSystemObj.closeCommonFile(openRead);
195 |
196 | fileJson.Servers[this.ServerEntry].Users = [];
197 |
198 | var openWrite = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Settings.json', 'w');
199 | if (openWrite) {
200 | openWrite.writeLine(JSON.stringify(fileJson));
201 | fileSystemObj.closeCommonFile(openWrite);
202 | }
203 | }
204 | };
205 |
206 | File.deleteUserPasswords = function () {
207 | var fileSystemObj = new FileSystem();
208 | var openRead = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Settings.json', 'r');
209 | if (openRead) {
210 | var fileJson = JSON.parse(openRead.readLine()); //Read line as only 1 and skips line break!
211 | fileSystemObj.closeCommonFile(openRead);
212 |
213 | for (var index = 0; index < fileJson.Servers[this.ServerEntry].Users.length; index++) {
214 | fileJson.Servers[this.ServerEntry].Users[index].Password = ""; // Do this so that users with no password are unaffected!
215 | }
216 |
217 | var openWrite = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Settings.json', 'w');
218 | if (openWrite) {
219 | openWrite.writeLine(JSON.stringify(fileJson));
220 | fileSystemObj.closeCommonFile(openWrite);
221 | }
222 | }
223 | };
224 |
225 | File.updateUserSettings = function (altered) {
226 | var fileSystemObj = new FileSystem();
227 | var openRead = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Settings.json', 'r');
228 | if (openRead) {
229 | var fileJson = JSON.parse(openRead.readLine()); //Read line as only 1 and skips line break!
230 | fileSystemObj.closeCommonFile(openRead);
231 |
232 | fileJson.Servers[this.ServerEntry].Users[this.UserEntry] = altered;
233 |
234 | var openWrite = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Settings.json', 'w');
235 | if (openWrite) {
236 | openWrite.writeLine(JSON.stringify(fileJson));
237 | fileSystemObj.closeCommonFile(openWrite);
238 | }
239 | }
240 | };
241 |
242 |
243 | File.updateServerSettings = function (altered) {
244 | var fileSystemObj = new FileSystem();
245 | var openRead = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Settings.json', 'r');
246 | if (openRead) {
247 | var fileJson = JSON.parse(openRead.readLine()); //Read line as only 1 and skips line break!
248 | fileSystemObj.closeCommonFile(openRead);
249 |
250 | fileJson.Servers[this.ServerEntry] = altered;
251 |
252 | var openWrite = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Settings.json', 'w');
253 | if (openWrite) {
254 | openWrite.writeLine(JSON.stringify(fileJson));
255 | fileSystemObj.closeCommonFile(openWrite);
256 | }
257 | }
258 | };
259 |
260 | File.writeAll = function (toWrite) {
261 | var fileSystemObj = new FileSystem();
262 | var openWrite = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Settings.json', 'w');
263 | if (openWrite) {
264 | openWrite.writeLine(JSON.stringify(toWrite));
265 | fileSystemObj.closeCommonFile(openWrite);
266 | }
267 | };
268 |
269 | //---------------------------------------------------------------------------------------------------------------------------------
270 | //- GET FUNCTIONS
271 | //---------------------------------------------------------------------------------------------------------------------------------
272 |
273 | File.getUserProperty = function(property) {
274 | var fileSystemObj = new FileSystem();
275 | var openRead = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Settings.json', 'r');
276 | if (openRead) {
277 | var fileJson = JSON.parse(openRead.readLine()); //Read line as only 1 and skips line break!
278 | fileSystemObj.closeCommonFile(openRead);
279 | if (!fileJson.Servers[this.ServerEntry].Users[this.UserEntry]) { //In case we're not logged in yet.
280 | return null;
281 | }
282 | if (fileJson.Servers[this.ServerEntry].Users[this.UserEntry][property] === undefined) {
283 | //Get System Default
284 | for (var index = 0; index < GuiPage_Settings.Settings.length; index++) {
285 | if (GuiPage_Settings.Settings[index] == property) {
286 | //Write setting here?
287 | fileJson.Servers[this.ServerEntry].Users[this.UserEntry][property] = GuiPage_Settings.SettingsDefaults[index];
288 | File.writeAll(fileJson);
289 | break;
290 | }
291 | }
292 | }
293 | return fileJson.Servers[this.ServerEntry].Users[this.UserEntry][property];
294 | }
295 | };
296 |
297 | File.getTVProperty = function(property) {
298 | var fileSystemObj = new FileSystem();
299 | var openRead = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Settings.json', 'r');
300 | if (openRead) {
301 | var fileJson = JSON.parse(openRead.readLine()); //Read line as only 1 and skips line break!
302 | fileSystemObj.closeCommonFile(openRead);
303 |
304 | if (fileJson.TV === undefined) {
305 | fileJson.TV = {};
306 | File.writeAll (fileJson);
307 | }
308 |
309 | if (fileJson.TV[property] === undefined) {
310 | //Get System Default
311 | for (var index = 0; index < GuiPage_Settings.TVSettings.length; index++) {
312 | if (GuiPage_Settings.TVSettings[index] == property) {
313 | //Write setting here?
314 | fileJson.TV[property] = GuiPage_Settings.TVSettingsDefaults[index];
315 | File.writeAll(fileJson);
316 | break;
317 | }
318 | }
319 | }
320 | return fileJson.TV[property];
321 | }
322 | };
323 |
324 | //---------------------------------------------------------------------------------------------------------------------------------
325 | //- SET FUNCTIONS
326 | //---------------------------------------------------------------------------------------------------------------------------------
327 |
328 | File.setUserProperty = function(property,value) {
329 | var fileSystemObj = new FileSystem();
330 | var openRead = fileSystemObj.openCommonFile(curWidget.id + '/MB3_Settings.json', 'r');
331 | if (openRead) {
332 | var fileJson = JSON.parse(openRead.readLine()); //Read line as only 1 and skips line break!
333 | fileSystemObj.closeCommonFile(openRead);
334 |
335 | if (fileJson.Servers[this.ServerEntry].Users[this.UserEntry][property] !== undefined) {
336 | fileJson.Servers[this.ServerEntry].Users[this.UserEntry][property] = value;
337 | File.writeAll(fileJson);
338 | }
339 | return
340 | }
341 | };
--------------------------------------------------------------------------------
/app/javascript/Gui/GuiPage_Music.js:
--------------------------------------------------------------------------------
1 | var GuiPage_Music = {
2 | AlbumData : null,
3 |
4 | selectedItem : 0, //Vertical
5 | topLeftItem : 0,
6 |
7 | selectedItem2 : 0, //Horizontal
8 |
9 | MAXCOLUMNCOUNT : 1,
10 | MAXROWCOUNT : 12,
11 |
12 | startParams : [],
13 |
14 | topMenuItems : ["PlayAll","QueueAll","ShuffleAll","InstantMix"],
15 | playItems : ["Play_","Queue_","Mix_"]
16 | }
17 |
18 | GuiPage_Music.onFocus = function() {
19 | this.updateSelectedItems();
20 | GuiHelper.setControlButtons(null,null,null,GuiMusicPlayer.Status == "PLAYING" || GuiMusicPlayer.Status == "PAUSED" ? "Music" : null,"Return");
21 | }
22 |
23 | GuiPage_Music.getMaxDisplay = function() {
24 | return this.MAXCOLUMNCOUNT * this.MAXROWCOUNT;
25 | }
26 |
27 | GuiPage_Music.start = function(title,url,type) { //Type is either MusicAlbum or MusicArtist
28 | alert("Page Enter : GuiPage_Music");
29 |
30 | //Save Start Params
31 | this.startParams = [title,url];
32 |
33 | //Reset Vars
34 | this.topLeftItem = 0;
35 | this.selectedItem = -1;
36 | this.selectedItem2 = 0;
37 |
38 | //Load Data
39 | this.AlbumData = Server.getContent(url);
40 | if (this.AlbumData == null) { return; }
41 |
42 | //Set PageContent
43 | document.getElementById("pageContent").innerHTML = "
\
45 |
\
46 |
\
47 |
Play All
\
48 |
Queue All
\
49 |
Shuffle
\
50 |
Instant Mix
\
51 |
\
52 |
";
53 | document.getElementById("Counter").innerHTML = "1/" + this.topMenuItems.length;
54 |
55 | //Get Episode Poster
56 | if (this.AlbumData.Items[0].AlbumPrimaryImageTag) {
57 | var imgsrc = Server.getImageURL(this.AlbumData.Items[0].AlbumId,"Primary",650,650,0,false,0);
58 | document.getElementById("guiMusic_Poster").style.backgroundImage = "url("+imgsrc + ")";
59 | } else {
60 | document.getElementById("guiMusic_Poster").style.backgroundImage = "url(images/collection.png)";
61 | }
62 |
63 | //Set Page Title
64 | if (type == "MusicAlbum") {
65 | if (this.AlbumData.Items[0].AlbumArtist){
66 | document.getElementById("guiMusic_Title").innerHTML = this.AlbumData.Items[0].AlbumArtist;
67 | }
68 | if (this.AlbumData.Items[0].Album){
69 | document.getElementById("guiMusic_Subtitle").innerHTML = this.AlbumData.Items[0].Album;
70 | }
71 | } else if (type == "MusicArtist") {
72 | if (this.AlbumData.Items[0].AlbumArtist){
73 | document.getElementById("guiMusic_Title").innerHTML = this.AlbumData.Items[0].AlbumArtist;
74 | }
75 | }
76 |
77 | //Get Page Items
78 | this.updateDisplayedItems();
79 |
80 | //Update Selected Item
81 | this.updateSelectedItems();
82 |
83 | //Set Focus for Key Events
84 | document.getElementById("GuiPage_Music").focus();
85 | }
86 |
87 | GuiPage_Music.updateDisplayedItems = function() {
88 | var htmlToAdd = "
";
89 | for (var index = this.topLeftItem; index < Math.min(this.topLeftItem + this.getMaxDisplay(),this.AlbumData.Items.length); index++){
90 | if (this.AlbumData.Items[index].ParentIndexNumber && this.AlbumData.Items[index].IndexNumber) {
91 | TrackDetails = this.AlbumData.Items[index].ParentIndexNumber+"." + this.AlbumData.Items[index].IndexNumber;
92 | } else if (this.AlbumData.Items[index].IndexNumber) {
93 | TrackDetails = this.AlbumData.Items[index].IndexNumber;
94 | } else {
95 | TrackDetails = "?";
96 | }
97 |
98 | //Truncate long song names.
99 | var songName = this.AlbumData.Items[index].Name;
100 | if (songName.length > 43){
101 | songName = songName.substring(0,40) + "...";
102 | }
103 |
104 | htmlToAdd += "Play Queue Mix " +
105 | ""+TrackDetails+ " " + songName + " " +
106 | ""+Support.convertTicksToTimeSingle(this.AlbumData.Items[index].RunTimeTicks/10000,true)+" ";
107 | }
108 | document.getElementById("GuiPage_Music_Options").innerHTML = htmlToAdd + "
";
109 | }
110 |
111 | //Function sets CSS Properties so show which user is selected
112 | GuiPage_Music.updateSelectedItems = function () {
113 | if (this.selectedItem == -1) {
114 | //Highlight the selected global item (PlayAll, Shuffle etc.)
115 | for (var index = 0; index < this.topMenuItems.length; index++) {
116 | if (index == this.selectedItem2) {
117 | document.getElementById(this.topMenuItems[index]).className = "guiMusic_Global highlight"+Main.highlightColour+"Background";
118 | } else {
119 | document.getElementById(this.topMenuItems[index]).className = "guiMusic_Global";
120 | }
121 | }
122 | } else {
123 | //Reset the global items.
124 | for (var index = 0; index < this.topMenuItems.length; index++) {
125 | document.getElementById(this.topMenuItems[index]).className = "guiMusic_Global";
126 | }
127 |
128 | //Highlight the selected list item.
129 | for (var index = this.topLeftItem; index < Math.min(this.topLeftItem + this.getMaxDisplay(),this.AlbumData.Items.length); index++){
130 | if (index == this.selectedItem) {
131 | for (var index2 = 0; index2 < this.playItems.length; index2++) {
132 | if (index2 == this.selectedItem2) {
133 | document.getElementById(this.playItems[index2]+this.AlbumData.Items[index].Id).className = "guiMusic_TableTd highlight"+Main.highlightColour+"Background";
134 | } else {
135 | document.getElementById(this.playItems[index2]+this.AlbumData.Items[index].Id).className = "guiMusic_TableTd";
136 | }
137 | }
138 | } else {
139 | document.getElementById(this.AlbumData.Items[index].Id).className = "guiMusic_TableTd";
140 | for (var index2 = 0; index2 < this.playItems.length; index2++) {
141 | document.getElementById(this.playItems[index2]+this.AlbumData.Items[index].Id).className = "guiMusic_TableTd";
142 | }
143 | }
144 | }
145 | }
146 |
147 | //Set Counter to be album count or x/3 for top part
148 | if (this.selectedItem == -1) {
149 | document.getElementById("Counter").innerHTML = (this.selectedItem2 + 1) + "/" + this.topMenuItems.length;
150 | } else {
151 | document.getElementById("Counter").innerHTML = (this.selectedItem + 1) + "/" + this.AlbumData.Items.length;
152 | }
153 |
154 | }
155 |
156 | GuiPage_Music.keyDown = function() {
157 | var keyCode = event.keyCode;
158 | alert("Key pressed: " + keyCode);
159 |
160 | //Update Screensaver Timer
161 | Support.screensaver();
162 |
163 | //If screensaver is running
164 | if (Main.getIsScreensaverRunning()) {
165 | //Update Main.js isScreensaverRunning - Sets to True
166 | Main.setIsScreensaverRunning();
167 |
168 | //End Screensaver
169 | GuiImagePlayer_Screensaver.stopScreensaver();
170 |
171 | //Change keycode so it does nothing!
172 | keyCode = "VOID";
173 | }
174 |
175 | switch(keyCode) {
176 | case tvKey.KEY_LEFT:
177 | this.processLeftKey();
178 | break;
179 | case tvKey.KEY_RIGHT:
180 | this.processRightKey();
181 | break;
182 | case tvKey.KEY_UP:
183 | this.processUpKey();
184 | break;
185 | case tvKey.KEY_DOWN:
186 | this.processDownKey();
187 | break;
188 | case tvKey.KEY_RETURN:
189 | alert("RETURN");
190 | widgetAPI.blockNavigation(event);
191 | Support.processReturnURLHistory();
192 | break;
193 | case tvKey.KEY_ENTER:
194 | case tvKey.KEY_PANEL_ENTER:
195 | alert("ENTER");
196 | this.processSelectedItem();
197 | break;
198 | case tvKey.KEY_TOOLS:
199 | widgetAPI.blockNavigation(event);
200 | this.openMenu();
201 | break;
202 | case tvKey.KEY_YELLOW:
203 | //Favourites - May not be needed on this page
204 | break;
205 | case tvKey.KEY_BLUE:
206 | if (this.selectedItem == -1) {
207 | GuiMusicPlayer.showMusicPlayer("GuiPage_Music",this.topMenuItems[this.selectedItem2],"guiMusic_Global highlight"+Main.highlightColour+"Background");
208 | } else {
209 | GuiMusicPlayer.showMusicPlayer("GuiPage_Music",this.playItems[this.selectedItem2]+this.AlbumData.Items[this.selectedItem].Id,"guiMusic_TableTd highlight"+Main.highlightColour+"Background");
210 | }
211 | break;
212 | case tvKey.KEY_EXIT:
213 | alert ("EXIT KEY");
214 | widgetAPI.sendExitEvent();
215 | break;
216 | }
217 | }
218 |
219 | GuiPage_Music.openMenu = function() {
220 | Support.updateURLHistory("GuiPage_Music",this.startParams[0],this.startParams[1],null,null,this.selectedItem,this.topLeftItem,true);
221 |
222 | if (this.selectedItem == -1) {
223 | GuiMainMenu.requested("GuiPage_Music",this.topMenuItems[this.selectedItem2],"guiMusic_Global highlight"+Main.highlightColour+"Background");
224 | } else {
225 | GuiMainMenu.requested("GuiPage_Music",this.playItems[this.selectedItem2]+this.AlbumData.Items[this.selectedItem].Id,"guiMusic_TableTd highlight"+Main.highlightColour+"Background");
226 | }
227 | }
228 |
229 | GuiPage_Music.processUpKey = function() {
230 | this.selectedItem--;
231 | if (this.selectedItem < -1) {
232 | this.selectedItem = -1;
233 | } else {
234 | if (this.selectedItem == -1 && this.selectedItem2 >= 3) {
235 | this.selectedItem2 = 2;
236 | }
237 | if (this.selectedItem == -1) {
238 | document.getElementById(this.AlbumData.Items[0].Id).style.color = "white";
239 | for (var index = 0; index < this.playItems.length; index++) {
240 | document.getElementById(this.playItems[index]+this.AlbumData.Items[0].Id).className = "guiMusic_TableTd";
241 | }
242 | }
243 | if (this.selectedItem < this.topLeftItem) {
244 | if (this.topLeftItem - this.MAXCOLUMNCOUNT < 0) {
245 | this.topLeftItem = 0;
246 | } else {
247 | this.topLeftItem = this.topLeftItem - this.MAXCOLUMNCOUNT;
248 | }
249 | this.updateDisplayedItems();
250 | }
251 | this.updateSelectedItems();
252 | }
253 | }
254 |
255 | GuiPage_Music.processDownKey = function() {
256 | this.selectedItem++;
257 | if (this.selectedItem == 0) {
258 | this.selectedItem2 = 0;
259 | }
260 | if (this.selectedItem >= this.AlbumData.Items.length) {
261 | this.selectedItem--;
262 | if (this.selectedItem >= (this.topLeftItem + this.getMaxDisplay())) {
263 | this.topLeftItem = this.topLeftItem + this.getMaxDisplay();
264 | this.updateDisplayedItems();
265 | }
266 | } else {
267 | if (this.selectedItem >= (this.topLeftItem + this.getMaxDisplay())) {
268 | this.topLeftItem++;
269 | this.updateDisplayedItems();
270 | }
271 | }
272 | this.updateSelectedItems();
273 | }
274 |
275 | GuiPage_Music.processLeftKey = function() {
276 | this.selectedItem2--;
277 | if (this.selectedItem2 == -1) {
278 | this.selectedItem2 = 0;
279 | this.openMenu();
280 | } else {
281 | this.updateSelectedItems();
282 | }
283 | }
284 |
285 | GuiPage_Music.processRightKey = function() {
286 | this.selectedItem2++;
287 | if (this.selectedItem == -1) {
288 | if (this.selectedItem2 > this.topMenuItems.length-1) {
289 | this.selectedItem2--;
290 | } else {
291 | this.updateSelectedItems();
292 | }
293 | } else {
294 | if (this.selectedItem2 > this.playItems.length-1) {
295 | this.selectedItem2--;
296 | } else {
297 | this.updateSelectedItems();
298 | }
299 | }
300 | }
301 |
302 | GuiPage_Music.processSelectedItem = function() {
303 | if (this.selectedItem == -1) {
304 | //Is Top Menu Bar
305 | switch (this.selectedItem2) {
306 | case 0:
307 | //Play All
308 | document.getElementById(this.topMenuItems[this.selectedItem2]).className = document.getElementById(this.topMenuItems[this.selectedItem2]).className.replace("highlight"+Main.highlightColour+"Background","");
309 | GuiMusicPlayer.start("Album",this.startParams[1] + "&Fields=MediaSources","GuiPage_Music",false);
310 | break;
311 | case 1:
312 | //Queue All
313 | GuiMusicPlayer.start("Album",this.startParams[1] + "&Fields=MediaSources","GuiPage_Music",true);
314 | break;
315 | case 2:
316 | //Shuffle
317 | document.getElementById(this.topMenuItems[this.selectedItem2]).className = document.getElementById(this.topMenuItems[this.selectedItem2]).className.replace("highlight"+Main.highlightColour+"Background","");
318 | var url = this.startParams[1].replace("SortBy=SortName","SortBy=Random")
319 | GuiMusicPlayer.start("Album",url + "&Fields=MediaSources","GuiPage_Music",false);
320 | break;
321 | case 3:
322 | //Instant Mix
323 | document.getElementById(this.topMenuItems[this.selectedItem2]).className = document.getElementById(this.topMenuItems[this.selectedItem2]).className.replace("highlight"+Main.highlightColour+"Background","");
324 | var url = Server.getCustomURL("/Albums/"+this.AlbumData.Items[0].AlbumId + "/InstantMix?format=json&Limit=50&UserId="+Server.getUserID());
325 | GuiMusicPlayer.start("Album",url + "&Fields=MediaSources","GuiPage_Music",false);
326 | break;
327 | }
328 | } else {
329 | switch (this.selectedItem2) {
330 | case 0:
331 | //Play
332 | document.getElementById(this.playItems[this.selectedItem2]+this.AlbumData.Items[this.selectedItem].Id).className = document.getElementById(this.playItems[this.selectedItem2]+this.AlbumData.Items[this.selectedItem].Id).className.replace("highlight"+Main.highlightColour+"Background","");
333 | var url = Server.getItemInfoURL(this.AlbumData.Items[this.selectedItem].Id);
334 | GuiMusicPlayer.start("Song",url,"GuiPage_Music",false);
335 | break;
336 | case 1:
337 | //Queue
338 | var url = Server.getItemInfoURL(this.AlbumData.Items[this.selectedItem].Id);
339 | GuiMusicPlayer.start("Song",url,"GuiPage_Music",true);
340 | break;
341 | case 2:
342 | //Mix
343 | document.getElementById(this.playItems[this.selectedItem2]+this.AlbumData.Items[this.selectedItem].Id).className = document.getElementById(this.playItems[this.selectedItem2]+this.AlbumData.Items[this.selectedItem].Id).className.replace("highlight"+Main.highlightColour+"Background","");
344 | var url = Server.getCustomURL("/Songs/"+this.AlbumData.Items[this.selectedItem].Id + "/InstantMix?format=json&Limit=50&UserId="+Server.getUserID());
345 | GuiMusicPlayer.start("Album",url + "&Fields=MediaSources","GuiPage_Music",false);
346 | break;
347 | }
348 | }
349 |
350 | //Genre Instant Mix
351 | //http://192.168.1.108:28067/emby/MusicGenres/Anime/InstantMix?UserId=4b4c128121aa642086bb225659a7d471&Fields=MediaSources%2CChapters&Limit=50
352 | //Artist Instant Mix
353 | //Artist/NameID/InstatnMix?
354 | }
--------------------------------------------------------------------------------
/app/javascript/Gui/GuiPage_Search.js:
--------------------------------------------------------------------------------
1 | var GuiPage_Search = {
2 | ItemData : null,
3 | startParams : [],
4 |
5 | selectedItem : 0,
6 | selectedItem2 : 0,
7 | topLeftItem : 0,
8 | MAXCOLUMNCOUNT : 1,
9 | MAXROWCOUNT : 12,
10 |
11 | playItems : ["Play_","View_"]
12 | }
13 |
14 | GuiPage_Search.onFocus = function() {
15 | GuiHelper.setControlButtons(null,null,null,GuiMusicPlayer.Status == "PLAYING" || GuiMusicPlayer.Status == "PAUSED" ? "Music" : null,"Return");
16 | }
17 |
18 | GuiPage_Search.getMaxDisplay = function() {
19 | return this.MAXCOLUMNCOUNT * this.MAXROWCOUNT;
20 | }
21 |
22 | GuiPage_Search.start = function(title, url) {
23 | alert("Page Enter : GuiPage_Search");
24 |
25 | //Reset Properties
26 | this.ItemData = null;
27 | this.selectedItem = 0;
28 | this.selectedItem2 = 0;
29 | this.startParams = [],
30 |
31 | //Change Display
32 | document.getElementById("pageContent").innerHTML = "
Search
\
33 | \
34 |
";
35 |
36 | //Allows time for innerhtml to execute before creating ime
37 | setTimeout(function () {
38 | //Create IME
39 | new GuiPage_Search_Input();
40 |
41 | if (title !== undefined && url !== undefined && title != null && url != null) {
42 | GuiPage_Search.ItemData = Server.getContent(url);
43 | if (GuiPage_Search.ItemData == null) { return; }
44 |
45 | document.getElementById("ResultsTitle").innerHTML = title;
46 |
47 | if (GuiPage_Search.ItemData.SearchHints.length > 0) {
48 | GuiPage_Search.startParams[0] = title;
49 | GuiPage_Search.startParams[1] = url;
50 | GuiPage_Search.updateDisplayedItems();
51 | GuiPage_Search.updateSelectedItems();
52 | document.getElementById("GuiPage_Search").focus();
53 | } else {
54 | //Must turn off as cannot catch keys during IME!
55 | Support.screensaverOff();
56 | document.getElementById("searchInput").focus();
57 | }
58 | } else {
59 | //Must turn off as cannot catch keys during IME!
60 | Support.screensaverOff();
61 | document.getElementById("searchInput").focus();
62 | }
63 | }, 500);
64 | }
65 |
66 | GuiPage_Search.updateDisplayedItems = function() {
67 | htmlToAdd = "
";
68 | var epName = "";
69 | for (var index = this.topLeftItem; index < Math.min(this.topLeftItem + this.getMaxDisplay(),this.ItemData.SearchHints.length); index++){
70 | epName = (this.ItemData.SearchHints[index].Type == "Episode") ? Support.getNameFormat(null,this.ItemData.SearchHints[index].ParentIndexNumber,null,this.ItemData.SearchHints[index].IndexNumber) + " - " + this.ItemData.SearchHints[index].Name : this.ItemData.SearchHints[index].Name;
71 | htmlToAdd += "Play View " +
72 | "" + epName + " " + this.ItemData.SearchHints[index].Type + " ";
73 | }
74 | document.getElementById("Results").innerHTML = htmlToAdd + "
";
75 | }
76 |
77 | //Function sets CSS Properties so show which user is selected
78 | GuiPage_Search.updateSelectedItems = function () {
79 | //Highlight the selected list item.
80 | for (var index = this.topLeftItem; index < Math.min(this.topLeftItem + this.getMaxDisplay(),this.ItemData.SearchHints.length); index++){
81 | if (index == this.selectedItem) {
82 | for (var index2 = 0; index2 < this.playItems.length; index2++) {
83 | if (index2 == this.selectedItem2) {
84 | document.getElementById(this.playItems[index2]+this.ItemData.SearchHints[index].ItemId).className = "guiMusic_TableTd highlight"+Main.highlightColour+"Background";
85 | } else {
86 | document.getElementById(this.playItems[index2]+this.ItemData.SearchHints[index].ItemId).className = "guiMusic_TableTd";
87 | }
88 | }
89 | } else {
90 | document.getElementById(this.ItemData.SearchHints[index].ItemId).className = "guiMusic_TableTd";
91 | for (var index2 = 0; index2 < this.playItems.length; index2++) {
92 | document.getElementById(this.playItems[index2]+this.ItemData.SearchHints[index].ItemId).className = "guiMusic_TableTd";
93 | }
94 | }
95 | }
96 |
97 | //Set Counter to be album count or x/3 for top part
98 | document.getElementById("Counter").innerHTML = (this.selectedItem + 1) + "/" + this.ItemData.SearchHints.length;
99 | }
100 |
101 | GuiPage_Search.processSelectedItem = function() {
102 | Support.updateURLHistory("GuiPage_Search",this.startParams[0],this.startParams[1],null,null,0,0,null);
103 | switch (this.ItemData.SearchHints[this.selectedItem].Type) {
104 | case "Episode":
105 | case "Movie":
106 | if (this.playItems[this.selectedItem2] == "Play_") {
107 | //Play URL
108 | var url = Server.getItemInfoURL(this.ItemData.SearchHints[this.selectedItem].ItemId,"&ExcludeLocationTypes=Virtual");
109 | GuiPlayer.start("PLAY",url,0,"GuiPage_Search");
110 | } else if (this.playItems[this.selectedItem2] == "View_") {
111 | //Display Item Page
112 | var url = Server.getItemInfoURL(this.ItemData.SearchHints[this.selectedItem].ItemId,null);
113 | GuiPage_ItemDetails.start(this.ItemData.SearchHints[this.selectedItem].Name,url,0);
114 | }
115 | break;
116 | case "Series":
117 | if (this.playItems[this.selectedItem2] == "Play_") {
118 | //Play URL
119 | var url= Server.getChildItemsURL(this.ItemData.SearchHints[this.selectedItem].ItemId,"&ExcludeLocationTypes=Virtual&IncludeItemTypes=Episode&Recursive=true&SortBy=SortName&SortOrder=Ascending&Fields=ParentId,SortName,MediaSources")
120 | GuiPlayer.start("PlayAll",url,0,"GuiPage_Search");
121 | } else if (this.playItems[this.selectedItem2] == "View_") {
122 | //Display Item Page
123 | var url = Server.getItemInfoURL(this.ItemData.SearchHints[this.selectedItem].ItemId,null);
124 | GuiTV_Show.start(this.ItemData.SearchHints[this.selectedItem].Name,url,0,0);
125 | }
126 | break;
127 | default:
128 | Support.removeLatestURL();
129 | GuiNotifications.setNotification(this.ItemData.SearchHints[this.selectedItem].Type + " hasn't been implemented in search yet.", "To Be Done")
130 | }
131 | }
132 |
133 | //////////////////////////////////////////////////////////////////
134 | //Input method for entering user password //
135 | //////////////////////////////////////////////////////////////////
136 | var GuiPage_Search_Input = function() {
137 | var imeReady = function(imeObject) {
138 | installFocusKeyCallbacks();
139 | }
140 |
141 | var ime = new IMEShell("searchInput", imeReady,'en');
142 | ime.setKeypadPos(1300,90);
143 |
144 | var installFocusKeyCallbacks = function () {
145 | ime.setKeyFunc(tvKey.KEY_ENTER, function (keyCode) {
146 | alert("Enter key pressed");
147 | var searchString = document.getElementById("searchInput").value;
148 | if (searchString != "") {
149 | //Load Data
150 | var url = Server.getSearchURL(searchString);
151 | GuiPage_Search.ItemData = Server.getContent(url);
152 | if (GuiPage_Search.ItemData == null) { return; }
153 |
154 | document.getElementById("ResultsTitle").innerHTML = GuiPage_Search.ItemData.TotalRecordCount + " Results for: " + searchString;
155 | ime.setString("");
156 |
157 | if (GuiPage_Search.ItemData.SearchHints.length > 0) {
158 |
159 | //Turn On Screensaver
160 | Support.screensaverOn();
161 | Support.screensaver();
162 |
163 | GuiPage_Search.startParams[0] = document.getElementById("ResultsTitle").innerHTML;
164 | GuiPage_Search.startParams[1] = url;
165 | GuiPage_Search.selectedItem = 0;
166 | GuiPage_Search.updateDisplayedItems();
167 | GuiPage_Search.updateSelectedItems();
168 | document.getElementById("GuiPage_Search").focus();
169 | }
170 | }
171 | });
172 |
173 | ime.setKeyFunc(tvKey.KEY_DOWN, function (keyCode) {
174 | alert ("Down Key IME: " + GuiPage_Search.ItemData.TotalRecordCount);
175 | if (GuiPage_Search.ItemData.TotalRecordCount > 0) {
176 | //Turn On Screensaver
177 | Support.screensaverOn();
178 | Support.screensaver();
179 |
180 | GuiPage_Search.selectedItem = 0;
181 | GuiPage_Search.selectedItem2 = 0;
182 | GuiPage_Search.updateSelectedItems();
183 |
184 | setTimeout(function () {
185 | document.getElementById("GuiPage_Search").focus();
186 | },500)
187 |
188 | }
189 | });
190 |
191 | ime.setKeyFunc(tvKey.KEY_INFO, function (keyCode) {
192 | GuiHelper.toggleHelp("GuiPage_Search");
193 | });
194 |
195 | ime.setKeyFunc(tvKey.KEY_RETURN, function (keyCode) {
196 | widgetAPI.blockNavigation(event);
197 | document.getElementById("NoKeyInput").focus();
198 | Support.processReturnURLHistory();
199 | });
200 |
201 | ime.setKeyFunc(tvKey.KEY_EXIT, function (keyCode) {
202 | document.getElementById("NoKeyInput").focus();
203 | widgetAPI.sendExitEvent();
204 | });
205 | }
206 | };
207 |
208 |
209 | GuiPage_Search.keyDown = function() {
210 | var keyCode = event.keyCode;
211 | alert("Key pressed: " + keyCode);
212 |
213 | if (document.getElementById("Notifications").style.visibility == "") {
214 | document.getElementById("Notifications").style.visibility = "hidden";
215 | document.getElementById("NotificationText").innerHTML = "";
216 | widgetAPI.blockNavigation(event);
217 | //Change keycode so it does nothing!
218 | keyCode = "VOID";
219 | }
220 |
221 | //Update Screensaver Timer
222 | Support.screensaver();
223 |
224 | //If screensaver is running
225 | if (Main.getIsScreensaverRunning()) {
226 | //Update Main.js isScreensaverRunning - Sets to True
227 | Main.setIsScreensaverRunning();
228 |
229 | //End Screensaver
230 | GuiImagePlayer_Screensaver.stopScreensaver();
231 |
232 | //Change keycode so it does nothing!
233 | keyCode = "VOID";
234 | }
235 |
236 | switch(keyCode) {
237 | case tvKey.KEY_LEFT:
238 | this.processLeftKey();
239 | break;
240 | case tvKey.KEY_RIGHT:
241 | this.processRightKey();
242 | break;
243 | case tvKey.KEY_UP:
244 | this.processUpKey();
245 | break;
246 | case tvKey.KEY_DOWN:
247 | this.processDownKey();
248 | break;
249 | case tvKey.KEY_PANEL_CH_UP:
250 | case tvKey.KEY_CH_UP:
251 | this.processChannelUpKey();
252 | break;
253 | case tvKey.KEY_PANEL_CH_DOWN:
254 | case tvKey.KEY_CH_DOWN:
255 | this.processChannelDownKey();
256 | break;
257 | case tvKey.KEY_RETURN:
258 | alert("RETURN");
259 | widgetAPI.blockNavigation(event);
260 | Support.processReturnURLHistory();
261 | break;
262 | case tvKey.KEY_ENTER:
263 | case tvKey.KEY_PANEL_ENTER:
264 | alert("ENTER");
265 | this.processSelectedItem();
266 | break;
267 | case tvKey.KEY_TOOLS:
268 | widgetAPI.blockNavigation(event);
269 | this.openMenu(true);
270 | break;
271 | case tvKey.KEY_YELLOW:
272 | //Favourites - May not be needed on this page
273 | break;
274 | case tvKey.KEY_BLUE:
275 | GuiMusicPlayer.showMusicPlayer("GuiPage_Search",this.playItems[this.selectedItem2]+this.ItemData.SearchHints[this.selectedItem].ItemId,"guiMusic_TableTd highlight"+Main.highlightColour+"Background");
276 | break;
277 | case tvKey.KEY_EXIT:
278 | alert ("EXIT KEY");
279 | widgetAPI.sendExitEvent();
280 | break;
281 | }
282 | }
283 |
284 | GuiPage_Search.openMenu = function(hasData) {
285 | if (hasData) {
286 | Support.updateURLHistory("GuiPage_Search",this.startParams[0],this.startParams[1],null,null,0,0,null);
287 |
288 | for (var index = 0; index
= this.ItemData.SearchHints.length) {
327 | this.selectedItem--;
328 | if (this.selectedItem >= (this.topLeftItem + this.getMaxDisplay())) {
329 | this.topLeftItem = this.topLeftItem + this.getMaxDisplay();
330 | this.updateDisplayedItems();
331 | }
332 | } else {
333 | if (this.selectedItem >= (this.topLeftItem + this.getMaxDisplay())) {
334 | this.topLeftItem++;
335 | this.updateDisplayedItems();
336 | }
337 | }
338 | this.updateSelectedItems();
339 | }
340 |
341 | GuiPage_Search.processLeftKey = function() {
342 | this.selectedItem2--;
343 | if (this.selectedItem2 == -1) {
344 | this.selectedItem2 = 0;
345 | this.openMenu(true);
346 | } else {
347 | this.updateSelectedItems();
348 | }
349 | }
350 |
351 | GuiPage_Search.processRightKey = function() {
352 | this.selectedItem2++;
353 | if (this.selectedItem2 > this.playItems.length-1) {
354 | this.selectedItem2--;
355 | } else {
356 | this.updateSelectedItems();
357 | }
358 | }
359 |
360 | GuiPage_Search.processChannelUpKey = function() {
361 | if (this.selectedItem > -1) {
362 | this.selectedItem = this.selectedItem - this.getMaxDisplay();
363 | if (this.selectedItem < 0) {
364 | this.selectedItem = 0;
365 | this.topLeftItem = 0;
366 | this.updateDisplayedItems();
367 | } else {
368 | if (this.topLeftItem - this.getMaxDisplay() < 0) {
369 | this.topLeftItem = 0;
370 | } else {
371 | this.topLeftItem = this.topLeftItem - this.getMaxDisplay();
372 | }
373 | this.updateDisplayedItems();
374 | }
375 | this.updateSelectedItems();
376 | }
377 | }
378 |
379 | GuiPage_Search.processChannelDownKey = function() {
380 | if (this.selectedItem > -1) {
381 | this.selectedItem = this.selectedItem + this.getMaxDisplay();
382 | if (this.selectedItem >= this.ItemData.SearchHints.length) {
383 | this.selectedItem = (this.ItemData.SearchHints.length-1);
384 | if (this.selectedItem >= this.topLeftItem + this.getMaxDisplay()) {
385 | this.topLeftItem = this.topLeftItem + this.getMaxDisplay();
386 | }
387 | this.updateDisplayedItems();
388 | } else {
389 | this.topLeftItem = this.topLeftItem + this.getMaxDisplay();
390 | this.updateDisplayedItems();
391 | }
392 | this.updateSelectedItems();
393 | }
394 | }
--------------------------------------------------------------------------------