1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

get channel media info at runtime

This commit is contained in:
Luke Pulverenti 2014-11-18 21:45:12 -05:00
parent b06fdda96d
commit 3f79032731
22 changed files with 164 additions and 79 deletions

View file

@ -693,32 +693,3 @@
width: 16.666666666666666666666666666667%;
}
}
/*.touch .mobileItemsContainer {
white-space: nowrap;
overflow-y: hidden;
overflow-x: scroll;
-ms-overflow-style: none;
overflow: -moz-scrollbars-none;
}
.touch .mobileItemsContainer::-webkit-scrollbar {
height: 0 !important;
display: none;
}
.touch .mobileItemsContainer .card {
width: 80%;
}
.touch .mobileItemsContainer .homePageBackdropCard, .touch .mobileItemsContainer .homePageSmallBackdropCard {
max-width: 320px;
}
.touch .mobileItemsContainer .homePagePortraitCard {
max-width: 150px;
}
.touch .mobileItemsContainer .homePageSquareCard {
max-width: 200px;
}*/

View file

@ -107,6 +107,14 @@
}
}
@media all and (min-width: 600px) {
.itemsContainer:not(.fullWidthItemsContainer):not(.smallItemsContainer) {
padding: 0 1em;
margin-right: 10px;
}
}
@media all and (min-width: 1200px) {
.ehsContent {
@ -907,6 +915,7 @@ a.itemTag:hover {
.itemsContainer {
text-align: center;
margin: 0 auto;
}
.timelineItemsContainer {

View file

@ -17,12 +17,12 @@
<div class="ehsContent">
<div id="activePrograms">
<h1 class="listHeader">${HeaderWhatsOnTV}</h1>
<div class="activeProgramItems mobileItemsContainer"></div>
<div class="activeProgramItems"></div>
<br />
</div>
<div id="upcomingPrograms">
<h1 class="listHeader">${HeaderUpcomingTV}</h1>
<div class="upcomingProgramItems mobileItemsContainer"></div>
<div class="upcomingProgramItems"></div>
<br />
</div>
</div>

View file

@ -22,7 +22,7 @@
<div id="resumableSection" style="display: none;">
<h1 class="listHeader">${HeaderResume}</h1>
<div id="resumableItems" class="mobileItemsContainer">
<div id="resumableItems">
</div>
</div>

View file

@ -18,20 +18,20 @@
<div class="ehsContent squareEhsContent">
<h1 class="listHeader">${HeaderLatestMusic}</h1>
<div id="recentlyAddedSongs" class="mobileItemsContainer">
<div id="recentlyAddedSongs">
</div>
<div id="recentlyPlayed" style="display: none;">
<h1 class="listHeader">${HeaderRecentlyPlayed}</h1>
<div id="recentlyPlayedSongs" class="itemsContainer fullWidthItemsContainer mobileItemsContainer" style="text-align:left;">
<div id="recentlyPlayedSongs" class="itemsContainer fullWidthItemsContainer" style="text-align:left;">
</div>
</div>
<div id="topPlayed" style="display: none;">
<h1 class="listHeader">${HeaderFrequentlyPlayed}</h1>
<div id="topPlayedSongs" class="itemsContainer fullWidthItemsContainer mobileItemsContainer" style="text-align:left;">
<div id="topPlayedSongs" class="itemsContainer fullWidthItemsContainer" style="text-align:left;">
</div>
</div>
</div>

View file

@ -12,7 +12,6 @@
<div data-role="content">
<div class="viewSettings">
<div class="listTopPaging">
&nbsp;
</div>

View file

@ -43,8 +43,8 @@
<div>
<label for="selectView">${LabelView}</label>
<select id="selectView">
<option value="Poster">${OptionPoster}</option>
<option value="List">${OptionList}</option>
<option value="PosterCard">${OptionPosterCard}</option>
</select>
</div>
<br />

View file

@ -38,7 +38,7 @@
<div style="text-align: center; margin: 10px;">${MessageNoAvailablePlugins}</div>
</div>
<div id="pluginTiles" class="itemsContainer" style="text-align:left;"></div>
<div id="pluginTiles" style="text-align:left;"></div>
</div>
</div>

View file

@ -919,6 +919,11 @@
itemCommands.push('queuefromhere');
}
// There's no detail page with a dedicated delete function
if (item.Type == 'Playlist') {
itemCommands.push('delete');
}
return itemCommands;
},

View file

@ -57,7 +57,7 @@
tag: item.ParentLogoImageTag
});
html += '<img src="' + imgUrl + '" style="max-height:' + logoHeight + 'px;max-width:' + maxLogoWidth + 'px;" />';
html += '<img src="' + imgUrl + '" style="max-height:' + logoHeight + 'px;max-width:100%;" />';
}
else if (item.ImageTags.Logo) {
@ -68,7 +68,7 @@
tag: item.ImageTags.Logo
});
html += '<img src="' + imgUrl + '" style="max-height:' + logoHeight + 'px;max-width:' + maxLogoWidth + 'px;" />';
html += '<img src="' + imgUrl + '" style="max-height:' + logoHeight + 'px;max-width:100%;" />';
}
else {
html += parentName || name;
@ -234,6 +234,17 @@
return false;
}
function onDeleteButtonClick() {
var id = this.getAttribute('data-itemid');
closeContextMenu();
LibraryBrowser.deleteItem(id);
return false;
}
function onExternalPlayerButtonClick() {
closeContextMenu();
@ -398,6 +409,10 @@
html += '<li data-icon="delete"><a href="#" class="btnRemoveFromPlaylist" data-playlistitemid="' + playlistItemId + '">' + Globalize.translate('ButtonRemoveFromPlaylist') + '</a></li>';
}
if (commands.indexOf('delete') != -1) {
html += '<li data-icon="delete"><a href="#" class="btnDelete" data-itemId="' + itemId + '">' + Globalize.translate('ButtonDelete') + '</a></li>';
}
html += '</ul>';
html += '</div>';
@ -421,6 +436,7 @@
$('.btnPlayAllFromHere', elem).on('click', onPlayAllFromHereButtonClick);
$('.btnQueueAllFromHere', elem).on('click', onQueueAllFromHereButtonClick);
$('.btnExternalPlayer', elem).on('click', onExternalPlayerButtonClick);
$('.btnDelete', elem).on('click', onDeleteButtonClick);
});
}

View file

@ -543,35 +543,35 @@
self.stop();
}
var mediaElement;
if (item.MediaType === "Video") {
self.currentItem = item;
self.currentMediaSource = getOptimalMediaSource(item.MediaType, item.MediaSources);
ApiClient.getJSON(ApiClient.getUrl('Items/' + item.Id + '/MediaInfo', {
userId: Dashboard.getCurrentUserId()
mediaElement = self.playVideo(item, self.currentMediaSource, startPosition);
})).done(function(result) {
self.currentItem = item;
self.currentMediaSource = getOptimalMediaSource(item.MediaType, result.MediaSources);
self.currentMediaElement = self.playVideo(item, self.currentMediaSource, startPosition);
self.currentDurationTicks = self.currentMediaSource.RunTimeTicks;
self.updateNowPlayingInfo(item);
});
} else if (item.MediaType === "Audio") {
self.currentItem = item;
self.currentMediaSource = getOptimalMediaSource(item.MediaType, item.MediaSources);
mediaElement = playAudio(item, self.currentMediaSource, startPosition);
self.currentMediaElement = playAudio(item, self.currentMediaSource, startPosition);
self.currentDurationTicks = self.currentMediaSource.RunTimeTicks;
} else {
throw new Error("Unrecognized media type");
}
self.currentMediaElement = mediaElement;
if (item.MediaType === "Video") {
self.updateNowPlayingInfo(item);
}
};
self.getNowPlayingNameHtml = function (playerState) {

View file

@ -26,7 +26,7 @@
html += '<h1 class="listHeader">' + title + '</h1>';
html += '<div class="mobileItemsContainer">';
html += '<div>';
html += LibraryBrowser.getPosterViewHtml({
items: recommendation.Items,
lazy: true,

View file

@ -1,6 +1,6 @@
(function ($, document) {
var view = LibraryBrowser.getDefaultItemsView('Poster', 'List');
var view = LibraryBrowser.getDefaultItemsView('PosterCard', 'PosterCard');
// The base query options
var query = {
@ -15,7 +15,7 @@
function getSavedQueryKey() {
return 'playlists' + (query.ParentId || '');
return 'playlists2' + (query.ParentId || '');
}
function showLoadingMessage(page) {
@ -66,7 +66,7 @@
sortBy: query.SortBy
});
}
else if (view == "Poster") {
else if (view == "PosterCard") {
html = LibraryBrowser.getPosterViewHtml({
items: result.Items,
shape: "square",
@ -74,7 +74,8 @@
showTitle: true,
lazy: true,
coverImage: true,
showItemCounts: true
showItemCounts: true,
cardLayout: true
});
}

View file

@ -43,7 +43,7 @@
var cssClass = "card homePageSquareCard bottomPaddedCard";
html += "<div data-id='" + server.Id + "' class='" + cssClass + "'>";
html += "<div data-id='" + server.Id + "' data-connectserverid='" + (server.ConnectServerId || '') + "' class='" + cssClass + "'>";
html += '<div class="cardBox visualCardBox visualCardBox-b">';
html += '<div class="cardScalable">';
@ -69,7 +69,7 @@
html += '<div class="cardText" style="text-align:right; float:right;">';
//html += '<button class="btnServerMenu" type="button" data-inline="true" data-iconpos="notext" data-icon="ellipsis-v" style="margin: 2px 0 0;"></button>';
html += '<button class="btnServerMenu" type="button" data-inline="true" data-iconpos="notext" data-icon="ellipsis-v" style="margin: 2px 0 0;"></button>';
html += "</div>";
@ -147,7 +147,7 @@
});
}
function rejectInvitation(page, id) {
function deleteServer(page, id) {
Dashboard.showLoadingMsg();
@ -164,11 +164,29 @@
});
}
function rejectInvitation(page, id) {
Dashboard.showLoadingMsg();
// Add/Update connect info
ConnectionManager.rejectServer(id).done(function () {
Dashboard.hideLoadingMsg();
loadPage(page);
}).fail(function () {
showGeneralError();
});
}
function showServerMenu(elem) {
var card = $(elem).parents('.card');
var page = $(elem).parents('.page');
var id = card.attr('data-id');
var connectserverid = card.attr('data-connectserverid');
$('.serverMenu', page).popup("close").remove();
@ -177,7 +195,7 @@
html += '<ul data-role="listview" style="min-width: 180px;">';
html += '<li data-role="list-divider">' + Globalize.translate('HeaderMenu') + '</li>';
html += '<li><a href="#" class="btnDelete" data-id="' + id + '">' + Globalize.translate('ButtonDelete') + '</a></li>';
html += '<li><a href="#" class="btnDelete" data-connectserverid="' + connectserverid + '">' + Globalize.translate('ButtonDelete') + '</a></li>';
html += '</ul>';
@ -192,7 +210,7 @@
});
$('.btnDelete', flyout).on('click', function () {
rejectInvitation(page, this.getAttribute('data-id'));
deleteServer(page, this.getAttribute('data-connectserverid'));
$('.serverMenu', page).popup("close").remove();
});
}

View file

@ -1275,7 +1275,7 @@ var Dashboard = {
initializeApiClient(ApiClient);
ConnectionManager.addApiClient(ApiClient, true);
ConnectionManager.addApiClient(ApiClient, true).fail(Dashboard.logout);
}
} else {

View file

@ -26,7 +26,8 @@
$('#chkDisabled', page).checked(user.Configuration.IsDisabled || false).checkboxradio("refresh");
$('#chkIsHidden', page).checked(user.Configuration.IsHidden || false).checkboxradio("refresh");
$('#chkEnableRemoteControlOtherUsers', page).checked(user.Configuration.EnableRemoteControlOfOtherUsers || false).checkboxradio("refresh");
$('#chkRemoteControlSharedDevices', page).checked(user.Configuration.EnableSharedDeviceControl);
$('#chkEnableRemoteControlOtherUsers', page).checked(user.Configuration.EnableRemoteControlOfOtherUsers).checkboxradio("refresh");
$('#chkEnableMediaPlayback', page).checked(user.Configuration.EnableMediaPlayback || false).checkboxradio("refresh");
$('#chkManageLiveTv', page).checked(user.Configuration.EnableLiveTvManagement || false).checkboxradio("refresh");
@ -72,6 +73,7 @@
user.Configuration.EnableLiveTvAccess = $('#chkEnableLiveTvAccess', page).checked();
user.Configuration.EnableContentDeletion = $('#chkEnableContentDeletion', page).checked();
user.Configuration.EnableUserPreferenceAccess = !$('#chkDisableUserPreferences', page).checked();
user.Configuration.EnableSharedDeviceControl = $('#chkRemoteControlSharedDevices', page).checked();
ApiClient.updateUser(user).done(function () {
onSaveComplete(page, user);

View file

@ -402,10 +402,29 @@
function showInvitePopup(page) {
Dashboard.getCurrentUser().done(function (user) {
if (user.ConnectUserId) {
$('#popupInvite', page).popup('open');
$('#txtConnectUsername', page).val('');
} else {
var msg = Globalize.translate('MessageConnectAccountRequiredToInviteGuest');
msg += '<br/>';
msg += '<br/>';
msg += '<a href="useredit.html?userId=' + user.Id + '">' + Globalize.translate('ButtonLinkMyMediaBrowserAccount') + '</a>';
msg += '<br/>';
Dashboard.alert({
message: msg,
title: Globalize.translate('HeaderInviteGuest')
});
}
});
}
$(document).on('pageinit', "#userProfilesPage", function () {

View file

@ -94,7 +94,7 @@
apiClients.push(apiClient);
apiClient.getPublicSystemInfo().done(function (systemInfo) {
return apiClient.getPublicSystemInfo().done(function (systemInfo) {
var server = credentialProvider.credentials().servers.filter(function (s) {
@ -483,6 +483,7 @@
servers = servers.map(function (i) {
return {
ExchangeToken: i.AccessKey,
ConnectServerId: i.Id,
Id: i.SystemId,
Name: i.Name,
RemoteAddress: i.Url,
@ -838,6 +839,40 @@
var url = "https://connect.mediabrowser.tv/service/serverAuthorizations?serverId=" + serverId + "&userId=" + self.connectUserId();
return $.ajax({
type: "DELETE",
url: url,
headers: {
"X-Connect-UserToken": self.connectToken()
}
}).done(function () {
var credentials = credentialProvider.credentials();
credentials.servers = credentials.servers.filter(function (s) {
return s.ConnectServerId != serverId;
});
credentialProvider.credentials(credentials);
});
};
self.rejectServer = function (serverId) {
if (!serverId) {
throw new Error("null serverId");
}
if (!self.connectToken()) {
throw new Error("null connectToken");
}
if (!self.connectUserId()) {
throw new Error("null connectUserId");
}
var url = "https://connect.mediabrowser.tv/service/serverAuthorizations?serverId=" + serverId + "&userId=" + self.connectUserId();
return $.ajax({
type: "DELETE",
url: url,

View file

@ -8,10 +8,11 @@
var self = this;
var credentials;
var key = 'servercredentials3';
function ensure() {
credentials = credentials || JSON.parse(store.getItem('servercredentials') || '{}');
credentials = credentials || JSON.parse(store.getItem(key) || '{}');
credentials.servers = credentials.servers || [];
}
@ -23,12 +24,12 @@
function set(data) {
credentials = data;
store.setItem('servercredentials', JSON.stringify(get()));
store.setItem(key, JSON.stringify(get()));
}
self.clear = function () {
credentials = null;
store.removeItem('servercredentials');
store.removeItem(key);
};
self.credentials = function (data) {

View file

@ -31,14 +31,14 @@
<div id="resumableSection" style="display: none;">
<h1 class="listHeader firstListHeader">${HeaderResume}</h1>
<div id="resumableItems" class="mobileItemsContainer">
<div id="resumableItems">
</div>
</div>
<h1 class="listHeader nextUpHeader firstListHeader">${HeaderNextUp}</h1>
</div>
<div id="nextUpItems" class="mobileItemsContainer">
<div id="nextUpItems">
</div>
<p class="noNextUpItems" style="display: none;">${NoNextUpItemsMessage}</p>
</div>

View file

@ -25,7 +25,7 @@
<label for="txtUserName">${LabelName}</label>
<input id="txtUserName" required="required" type="text" />
</li>
<li id="fldConnectInfo" style="display: none;">
<li id="fldConnectInfo" style="display: none; background: #e8eef7;padding:1em;border-radius:5px;">
<label for="txtConnectUserName">${LabelConnectUserName}</label>
<input id="txtConnectUserName" type="text" />
<div class="fieldDescription">
@ -49,10 +49,19 @@
<label for="chkManageLiveTv">${OptionAllowManageLiveTv}</label>
<input type="checkbox" id="chkEnableContentDeletion" name="chkEnableContentDeletion" />
<label for="chkEnableContentDeletion">${OptionAllowDeleteLibraryContent}</label>
<input type="checkbox" id="chkEnableRemoteControlOtherUsers" name="chkEnableRemoteControlOtherUsers" />
<label for="chkEnableRemoteControlOtherUsers">${OptionAllowRemoteControlOthers}</label>
</fieldset>
<br />
<div>
<fieldset id="remoteControlFields" data-role="controlgroup">
<legend>${HeaderRemoteControl}</legend>
<input type="checkbox" id="chkEnableRemoteControlOtherUsers" name="chkEnableRemoteControlOtherUsers" />
<label for="chkEnableRemoteControlOtherUsers">${OptionAllowRemoteControlOthers}</label>
<input type="checkbox" id="chkRemoteControlSharedDevices" />
<label for="chkRemoteControlSharedDevices">${OptionAllowRemoteSharedDevices}</label>
</fieldset>
<div class="fieldDescription">${OptionAllowRemoteSharedDevicesHelp}</div>
<br />
</div>
<div id="accessControlDiv" data-role="collapsible">
<h2>${HeaderAdvancedControl}</h2>
<div id="fldIsEnabled" style="margin: 1em 0 2em;">

View file

@ -17,7 +17,7 @@
</a>
</h3>
</div>
<div class="itemsContainer localUsers" style="text-align:left;margin-top:.5em;"></div>
<div class="localUsers" style="text-align:left;margin-top:.5em;"></div>
<div class="ui-bar-a" style="padding: 0 1em;margin-top:2.5em;">
<h3 style="margin:.6em 0;font-size:16px;font-weight:500;">
@ -27,7 +27,7 @@
</a>
</h3>
</div>
<div class="itemsContainer connectUsers" style="text-align:left;margin-top:.5em;"></div>
<div class="connectUsers" style="text-align:left;margin-top:.5em;"></div>
<div class="sectionPendingGuests" style="display:none;margin-top:2.5em;">
<div class="ui-bar-a" style="padding: 0 1em;"><h3 style="font-size:16px;font-weight:500;">${HeaderPendingInvitations}</h3></div>