add activity log feature

This commit is contained in:
Luke Pulverenti 2014-08-10 18:13:17 -04:00
parent 4ca20d409b
commit 69682bd717
13 changed files with 367 additions and 119 deletions

View File

@ -521,6 +521,13 @@
}
}
@media all and (min-width: 1920px) {
.homePageBackdropCard {
width: 20%;
}
}
/** homePageSquareCard */
.homePageSquareCard .cardPadder {
@ -546,6 +553,13 @@
}
}
@media all and (min-width: 1000px) {
.homePageSquareCard {
width: 20%;
}
}
@media all and (min-width: 1200px) {
.homePageSquareCard {
@ -553,6 +567,27 @@
}
}
@media all and (min-width: 1600px) {
.homePageSquareCard {
width: 14.285714285714285714285714285714%;
}
}
@media all and (min-width: 1280px) {
.homePageSquareCard {
width: 14.285714285714285714285714285714%;
}
}
@media all and (min-width: 1920px) {
.homePageSquareCard {
width: 12.5%;
}
}
/** homePagePortraitCard */
.homePagePortraitCard .cardPadder {
@ -592,6 +627,20 @@
}
}
@media all and (min-width: 1600px) {
.homePagePortraitCard {
width: 12.5%;
}
}
@media all and (min-width: 1920px) {
.homePagePortraitCard {
width: 11.111111111111111111111111111111%;
}
}
/** homePageSmallBackdropCard */
.homePageSmallBackdropCard .cardPadder {
@ -630,3 +679,10 @@
width: 16.666666666666666666666666666667%;
}
}
@media all and (min-width: 1600px) {
.homePageSmallBackdropCard {
width: 14.285714285714285714285714285714%;
}
}

View File

@ -114,7 +114,14 @@
@media all and (min-width: 1600px) {
.ehsContent {
width: 1200px;
width: 1280px;
}
}
@media all and (min-width: 1600px) {
.ehsContent {
width: 1500px;
}
}

View File

@ -756,19 +756,13 @@ progress {
height: 70px;
}
.latestNewsItems {
min-height: 100px;
min-width: 200px;
}
.newsItem {
padding: 1em 0;
border-bottom: 1px solid #ddd;
}
.newsItemDescription {
max-height: 50px;
max-height: 34px;
text-overflow: ellipsis;
overflow: hidden;
}
@ -786,46 +780,54 @@ progress {
@media all and (max-width: 1440px) {
.dashboardHomeRightColumn {
margin-top: 2em;
margin-top: 1em;
}
}
.dashboardContent {
max-width: 1000px;
max-width: 1550px;
margin-top: -10px;
}
.dashboardHomeRightColumn {
vertical-align: top;
}
@media all and (min-width: 1440px) {
.dashboardHomeLeftColumn {
width: 600px;
float: left;
}
.latestNewsItems {
max-width: 280px;
display: inline-block;
vertical-align: top;
}
.dashboardHomeRightColumn {
float: right;
vertical-align: top;
}
.firstDashboardHomeRightColumn {
display: inline-block;
width: 440px;
margin-left: 2em;
}
.firstDashboardHomeRightColumn .ui-collapsible-content {
height: 585px;
min-width: 300px;
}
}
@media all and (min-width: 1500px) {
@media all and (min-width: 1920px) {
.latestNewsItems {
max-width: 300px;
}
.dashboardHomeRightColumn {
display: inline-block;
max-width: 440px;
margin-left: 2em;
min-width: 400px;
}
@media all and (min-width: 1600px) {
.latestNewsItems {
max-width: 400px;
}
.dashboardContent {
max-width: 1100px;
.dashboardHomeRightColumn .ui-collapsible-content {
height: 585px;
}
}

View File

@ -68,7 +68,7 @@
</div>
</div>
<div id="runningTasksCollapsible" data-role="collapsible" data-collapsed="false" style="margin-top: 2em; display: none;">
<div id="runningTasksCollapsible" data-role="collapsible" data-collapsed="false" style="margin-top: 1em; display: none;">
<h3>${HeaderRunningTasks}</h3>
<div>
<div id="divRunningTasks">
@ -76,7 +76,42 @@
</div>
</div>
<div id="contribute" style="margin-top: 4em; display: none;">
<div data-role="collapsible" data-collapsed="true" style="margin-top: 1em;">
<h3>${HeaderLinks}</h3>
<div>
<p><a href="http://mediabrowser.tv/community" target="_blank">${LinkCommunity}</a></p>
<p><a href="https://github.com/MediaBrowser/MediaBrowser" target="_blank">${LinkGithub}</a></p>
<p><a href="../swagger-ui/index.html" target="_blank">${LinkApiDocumentation}</a></p>
</div>
</div>
<div data-role="collapsible" data-collapsed="true">
<h3>${HeaderSystemPaths}</h3>
<div>
<p>
<b>${LabelCache}</b><br />
<span id="cachePath"></span>
</p>
<p>
<b>${LabelImagesByName}</b><br />
<span id="imagesByNamePath"></span>
</p>
<p>
<b>${LabelLogs}</b><br />
<span id="logPath"></span>
</p>
<p>
<b>${LabelMetadata}</b><br />
<span id="metadataPath"></span>
</p>
<p>
<b>${LabelTranscodingTemporaryFiles}</b><br />
<span id="transcodingTemporaryPath"></span>
</p>
</div>
</div>
<div id="contribute" style="margin-top: 2em; display: none;">
<h2 style="margin: 0 0 .35em;">${HeaderHelpImproveMediaBrowser}</h2>
<div>
<a data-role="button" data-icon="mail" data-mini="true" href="supporter.html">
@ -119,6 +154,14 @@
</div>
</div>
<div class="readOnlyContent dashboardHomeRightColumn firstDashboardHomeRightColumn">
<div data-role="collapsible" data-collapsed="false">
<h3>${HeaderActivity}</h3>
<div class="activityItems">
</div>
</div>
</div>
<div class="readOnlyContent dashboardHomeRightColumn">
<div data-role="collapsible" data-collapsed="false">
<h3>${HeaderLatestNews}</h3>
@ -126,44 +169,6 @@
</div>
</div>
</div>
<div class="readOnlyContent" style="clear: left;">
<div data-role="collapsible" data-collapsed="true">
<h3>${HeaderLinks}</h3>
<div>
<p><a href="http://mediabrowser.tv/community" target="_blank">${LinkCommunity}</a></p>
<p><a href="https://github.com/MediaBrowser/MediaBrowser" target="_blank">${LinkGithub}</a></p>
<p><a href="../swagger-ui/index.html" target="_blank">${LinkApiDocumentation}</a></p>
</div>
</div>
<div data-role="collapsible" data-collapsed="true">
<h3>${HeaderSystemPaths}</h3>
<div>
<p>
<b>${LabelCache}</b><br />
<span id="cachePath"></span>
</p>
<p>
<b>${LabelImagesByName}</b><br />
<span id="imagesByNamePath"></span>
</p>
<p>
<b>${LabelLogs}</b><br />
<span id="logPath"></span>
</p>
<p>
<b>${LabelMetadata}</b><br />
<span id="metadataPath"></span>
</p>
<p>
<b>${LabelTranscodingTemporaryFiles}</b><br />
<span id="transcodingTemporaryPath"></span>
</p>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -24,7 +24,7 @@
<div class="listTopPaging">
</div>
<div class="selectionCommands" style="display: none;">
<div data-role="controlgroup" data-type="horizontal" class="selectionCommandsControlGroup">
<div class="selectionCommandsControlGroup">
<button class="btnAddToPlaylist" data-mini="true" data-icon="plus" data-inline="true" title="${ButtonAddToPlaylist}">${ButtonAddToPlaylist}</button>
<button class="btnMergeVersions" data-mini="true" data-icon="recycle" data-inline="true" title="${ButtonGroupVersions}">${ButtonGroupVersions}</button>
</div>

View File

@ -32,6 +32,22 @@
DashboardPage.reloadSystemInfo(page);
DashboardPage.reloadNews(page);
DashboardPage.sessionUpdateTimer = setInterval(DashboardPage.refreshSessionsLocally, 60000);
$('.activityItems', page).activityLogList();
},
onPageHide: function () {
var page = this;
$('.activityItems', page).activityLogList('destroy');
$(ApiClient).off("websocketmessage", DashboardPage.onWebSocketMessage).off("websocketopen", DashboardPage.onWebSocketConnectionChange).off("websocketerror", DashboardPage.onWebSocketConnectionChange).off("websocketclose", DashboardPage.onWebSocketConnectionChange);
DashboardPage.stopInterval();
if (DashboardPage.sessionUpdateTimer) {
clearInterval(DashboardPage.sessionUpdateTimer);
}
},
renderPaths: function (page, systemInfo) {
@ -134,16 +150,6 @@
},
onPageHide: function () {
$(ApiClient).off("websocketmessage", DashboardPage.onWebSocketMessage).off("websocketopen", DashboardPage.onWebSocketConnectionChange).off("websocketerror", DashboardPage.onWebSocketConnectionChange).off("websocketclose", DashboardPage.onWebSocketConnectionChange);
DashboardPage.stopInterval();
if (DashboardPage.sessionUpdateTimer) {
clearInterval(DashboardPage.sessionUpdateTimer);
}
},
startInterval: function () {
if (ApiClient.isWebSocketOpen()) {
@ -1043,3 +1049,150 @@ $(document).on('pagebeforeshow', "#dashboardPage", DashboardPage.onPageShow)
};
})(jQuery, document, window);
(function ($, document, window) {
function getEntryHtml(entry) {
var html = '';
html += '<div class="newsItem" style="padding: .5em 0;">';
html += '<div class="notificationContent" style="display:block;">';
var date = parseISO8601Date(entry.Date, { toLocal: true });
var color = entry.Severity == 'Error' || entry.Severity == 'Fatal' || entry.Severity == 'Warn' ? '#cc0000' : 'green';
html += '<div style="margin: 0;color:' + color + ';">' + date.toLocaleDateString() + ' ' + date.toLocaleTimeString().toLowerCase() + '</div>';
html += '<div class="notificationName" style="margin:.5em 0 0;white-space:nowrap;">';
html += entry.Name;
html += '</div>';
entry.ShortOverview = entry.ShortOverview || '&nbsp;';
if (entry.ShortOverview) {
html += '<div class="newsItemDescription" style="margin: .5em 0 0;">';
if (entry.Overview) {
html += '<a href="#" class="btnShowOverview" style="text-decoration:none;font-weight:500;">';
}
html += entry.ShortOverview;
if (entry.Overview) {
html += '</a>';
}
html += '</div>';
if (entry.Overview) {
html += '<div class="newsItemLongDescription" style="display:none;">' + entry.Overview + '</div>';
}
}
//if (notification.Url) {
// html += '<p style="margin: .25em 0;"><a href="' + notification.Url + '" target="_blank">' + Globalize.translate('ButtonMoreInformation') + '</a></p>';
//}
html += '</div>';
html += '</div>';
return html;
}
function renderList(elem, result, startIndex, limit) {
var html = result.Items.map(getEntryHtml).join('');
if (result.TotalRecordCount > limit) {
var query = { StartIndex: startIndex, Limit: limit };
html += LibraryBrowser.getPagingHtml(query, result.TotalRecordCount, false, limit, false);
}
$(elem).html(html).trigger('create');
$('.btnNextPage', elem).on('click', function () {
reloadData(elem, startIndex + limit, limit);
});
$('.btnPreviousPage', elem).on('click', function () {
reloadData(elem, startIndex - limit, limit);
});
$('.btnShowOverview', elem).on('click', function () {
var item = $(this).parents('.newsItem');
var overview = $('.newsItemLongDescription', item).html();
var name = $('.notificationName', item).html();
Dashboard.alert({
message: overview,
title: name
});
});
}
function reloadData(elem, startIndex, limit) {
if (startIndex == null) {
startIndex = parseInt(elem.getAttribute('data-activitystartindex') || '0');
}
limit = limit || parseInt(elem.getAttribute('data-activitylimit') || '7');
ApiClient.getJSON(ApiClient.getUrl('System/ActivityLog/Entries', {
startIndex: startIndex,
limit: limit
})).done(function (result) {
elem.setAttribute('data-activitystartindex', startIndex);
elem.setAttribute('data-activitylimit', limit);
renderList(elem, result, startIndex, limit);
});
}
function createList(elem) {
elem.each(function () {
reloadData(this);
});
$(ApiClient).on('websocketmessage.activityloglistener', function (e, data) {
var msg = data;
if (msg.MessageType === "ActivityLogEntryCreated") {
elem.each(function () {
reloadData(this);
});
}
});
}
function destroyList(elem) {
$(ApiClient).off('websocketmessage.activityloglistener');
}
$.fn.activityLogList = function (action) {
if (action == 'destroy') {
destroyList(this);
} else {
createList(this);
}
return this;
};
})(jQuery, document, window);

View File

@ -408,8 +408,7 @@
}
if (commands.indexOf('edit') != -1) {
html += '<li><a href="edititemmetadata.html?id=' + itemId + '">Edit metadata</a></li>';
html += '<li><a href="edititemimages.html?id=' + itemId + '">Edit images</a></li>';
html += '<li><a href="edititemmetadata.html?id=' + itemId + '">Edit</a></li>';
}
html += '</ul>';
@ -1788,9 +1787,9 @@
if (showControls) {
html += '<div data-role="controlgroup" data-type="horizontal" style="display:inline-block;">';
html += '<button data-icon="arrow-l" data-iconpos="notext" data-inline="true" data-mini="true" class="btnPreviousPage" ' + (query.StartIndex ? '' : 'disabled') + '>Previous Page</button>';
html += '<button type="button" data-icon="arrow-l" data-iconpos="notext" data-inline="true" data-mini="true" class="btnPreviousPage" ' + (query.StartIndex ? '' : 'disabled') + '>Previous Page</button>';
html += '<button data-icon="arrow-r" data-iconpos="notext" data-inline="true" data-mini="true" class="btnNextPage" ' + (query.StartIndex + query.Limit >= totalRecordCount ? 'disabled' : '') + '>Next Page</button>';
html += '<button type="button" data-icon="arrow-r" data-iconpos="notext" data-inline="true" data-mini="true" class="btnNextPage" ' + (query.StartIndex + query.Limit >= totalRecordCount ? 'disabled' : '') + '>Next Page</button>';
html += '</div>';
if (showLimit !== false) {

View File

@ -168,11 +168,11 @@
var id = this.getAttribute('data-itemid');
PlaylistManager.showPanel([id]);
// Used by the tab menu, not the slide up
$('.tapHoldMenu').popup('close');
PlaylistManager.showPanel([id]);
return false;
}

View File

@ -981,6 +981,16 @@
return true;
};
// Replace audio version
self.cleanup = function (playerElement) {
if (playerElement.tagName.toLowerCase() == 'video') {
currentTimeElement.html('--:--');
unbindEventsForPlayback();
}
};
self.playVideo = function (item, mediaSource, startPosition) {
var mediaStreams = mediaSource.MediaStreams || [];
@ -1197,6 +1207,10 @@
}).one("playing.mediaplayerevent", function () {
// For some reason this is firing at the start, so don't bind until playback has begun
$(this).on("ended.playbackstopped", self.onPlaybackStopped).one('ended.playnext', self.playNextAfterEnded);
self.onPlaybackStart(this, item, mediaSource);
}).on("pause.mediaplayerevent", function (e) {
@ -1265,15 +1279,7 @@
self.toggleFullscreen();
}).on("ended.playbackstopped", function () {
currentTimeElement.html('--:--');
self.onPlaybackStopped.call(this);
unbindEventsForPlayback();
}).one('ended.playnext', self.playNextAfterEnded);
});
bindEventsForPlayback();

View File

@ -606,6 +606,8 @@
if (newItem) {
console.log('playing next track');
Dashboard.getCurrentUser().done(function (user) {
self.playInternal(newItem, 0, user);
@ -1092,14 +1094,22 @@
$(self).trigger('volumechange', [state]);
};
self.cleanup = function() {
};
self.onPlaybackStopped = function () {
console.log('playback stopped');
$('body').removeClass('bodyWithPopupOpen');
var playerElement = this;
$(playerElement).off('.mediaplayerevent').off('ended.playbackstopped');
self.cleanup(playerElement);
clearProgressInterval();
var item = self.currentItem;
@ -1253,27 +1263,38 @@
}).on("volumechange.mediaplayerevent", function () {
console.log('audio element event: volumechange');
self.onVolumeChanged(this);
}).one("playing.mediaplayerevent", function () {
console.log('audio element event: playing');
$('.mediaPlayerAudioContainer').hide();
// For some reason this is firing at the start, so don't bind until playback has begun
$(this).on("ended.playbackstopped", self.onPlaybackStopped).one('ended.playnext', self.playNextAfterEnded);
self.onPlaybackStart(this, item, mediaSource);
}).on("pause.mediaplayerevent", function () {
console.log('audio element event: pause');
self.onPlaystateChange(this);
}).on("playing.mediaplayerevent", function () {
console.log('audio element event: playing');
self.onPlaystateChange(this);
}).on("timeupdate.mediaplayerevent", function () {
self.setCurrentTime(self.getCurrentTicks(this));
}).on("ended.playbackstopped", self.onPlaybackStopped).one('ended.playnext', self.playNextAfterEnded)[0];
})[0];
};
function canPlayAudioStreamDirect(audioStream) {

View File

@ -2,13 +2,13 @@
function loadPage(page, config, languages) {
$('#chkSubtitlesMovies', page).checked(config.SubtitleOptions.DownloadMovieSubtitles).checkboxradio("refresh");
$('#chkSubtitlesEpisodes', page).checked(config.SubtitleOptions.DownloadEpisodeSubtitles).checkboxradio("refresh");
$('#chkSubtitlesMovies', page).checked(config.DownloadMovieSubtitles).checkboxradio("refresh");
$('#chkSubtitlesEpisodes', page).checked(config.DownloadEpisodeSubtitles).checkboxradio("refresh");
$('#chkSkipIfGraphicalSubsPresent', page).checked(config.SubtitleOptions.SkipIfGraphicalSubtitlesPresent).checkboxradio("refresh");
$('#chkSkipIfAudioTrackPresent', page).checked(config.SubtitleOptions.SkipIfAudioTrackMatches).checkboxradio("refresh");
$('#chkSkipIfGraphicalSubsPresent', page).checked(config.SkipIfGraphicalSubtitlesPresent).checkboxradio("refresh");
$('#chkSkipIfAudioTrackPresent', page).checked(config.SkipIfAudioTrackMatches).checkboxradio("refresh");
$('#txtOpenSubtitleUsername', page).val(config.SubtitleOptions.OpenSubtitlesUsername);
$('#txtOpenSubtitleUsername', page).val(config.OpenSubtitlesUsername);
$('#txtOpenSubtitlePassword', page).val('');
populateLanguages(page, config, languages);
@ -34,7 +34,7 @@
$('.downloadLanguages', page).html(html).trigger("create");
var langs = config.SubtitleOptions.DownloadLanguages || [];
var langs = config.DownloadLanguages || [];
$('.chkLang', page).each(function () {
@ -49,7 +49,7 @@
var page = this;
var promise1 = ApiClient.getServerConfiguration();
var promise1 = ApiClient.getNamedConfiguration("subtitles");
var promise2 = ApiClient.getCultures();
$.when(promise1, promise2).done(function (response1, response2) {
@ -69,29 +69,29 @@
var form = this;
ApiClient.getServerConfiguration().done(function (config) {
ApiClient.getNamedConfiguration("subtitles").done(function (config) {
config.SubtitleOptions.DownloadMovieSubtitles = $('#chkSubtitlesMovies', form).checked();
config.SubtitleOptions.DownloadEpisodeSubtitles = $('#chkSubtitlesEpisodes', form).checked();
config.DownloadMovieSubtitles = $('#chkSubtitlesMovies', form).checked();
config.DownloadEpisodeSubtitles = $('#chkSubtitlesEpisodes', form).checked();
config.SubtitleOptions.SkipIfGraphicalSubtitlesPresent = $('#chkSkipIfGraphicalSubsPresent', form).checked();
config.SubtitleOptions.SkipIfAudioTrackMatches = $('#chkSkipIfAudioTrackPresent', form).checked();
config.SkipIfGraphicalSubtitlesPresent = $('#chkSkipIfGraphicalSubsPresent', form).checked();
config.SkipIfAudioTrackMatches = $('#chkSkipIfAudioTrackPresent', form).checked();
config.SubtitleOptions.OpenSubtitlesUsername = $('#txtOpenSubtitleUsername', form).val();
config.OpenSubtitlesUsername = $('#txtOpenSubtitleUsername', form).val();
var newPassword = $('#txtOpenSubtitlePassword', form).val();
if (newPassword) {
config.SubtitleOptions.OpenSubtitlesPasswordHash = newPassword;
config.OpenSubtitlesPasswordHash = newPassword;
}
config.SubtitleOptions.DownloadLanguages = $('.chkLang:checked', form).get().map(function (c) {
config.DownloadLanguages = $('.chkLang:checked', form).get().map(function (c) {
return c.getAttribute('data-lang');
});
ApiClient.updateServerConfiguration(config).done(Dashboard.processServerConfigurationUpdateResult);
ApiClient.updateNamedConfiguration("subtitles", config).done(Dashboard.processServerConfigurationUpdateResult);
});
// Disable default form submission

View File

@ -11,7 +11,7 @@
var options = {
IncludeItemTypes: "Audio",
Limit: screenWidth >= 1600 ? 18 : (screenWidth >= 1200 ? 10 : 12),
Limit: screenWidth >= 1600 ? 21 : (screenWidth >= 1200 ? 21 : 12),
Fields: "PrimaryImageAspectRatio",
ParentId: parentId
};
@ -34,7 +34,7 @@
SortBy: "DatePlayed",
SortOrder: "Descending",
IncludeItemTypes: "Audio",
Limit: screenWidth >= 1600 ? 6 : (screenWidth >= 1200 ? 5 : 6),
Limit: screenWidth >= 1600 ? 7 : (screenWidth >= 1200 ? 7 : 6),
Recursive: true,
Fields: "PrimaryImageAspectRatio,AudioInfo",
Filters: "IsPlayed",
@ -64,7 +64,7 @@
SortBy: "PlayCount",
SortOrder: "Descending",
IncludeItemTypes: "Audio",
Limit: screenWidth >= 1600 ? 12 : (screenWidth >= 1200 ? 10 : 12),
Limit: screenWidth >= 1600 ? 14 : (screenWidth >= 1200 ? 14 : 12),
Recursive: true,
Fields: "PrimaryImageAspectRatio,AudioInfo",
Filters: "IsPlayed",

View File

@ -396,7 +396,7 @@ var Dashboard = {
var html = '<div data-role="popup" class="confirmFlyout" style="max-width:500px;" data-theme="a">';
html += '<div class="ui-bar-a" style="text-align:center;">';
html += '<h3>' + title + '</h3>';
html += '<h3 style="padding: 0 1em;">' + title + '</h3>';
html += '</div>';
html += '<div style="padding: 1em;">';
@ -1262,7 +1262,6 @@ $(function () {
$(document).on('contextmenu', '.ui-popup-screen', function (e) {
document.title = '1';
$('.ui-popup').popup('close');
e.preventDefault();