added dashboard tour

This commit is contained in:
Luke Pulverenti 2014-10-04 14:05:24 -04:00
parent e83a3e710b
commit 7a084a589e
13 changed files with 190 additions and 62 deletions

View File

@ -157,7 +157,12 @@ namespace MediaBrowser.Api
private Task MarkRead(string idList, string userId, bool read)
{
var ids = idList.Split(',');
var ids = (idList ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
if (ids.Length == 0)
{
return _notificationsRepo.MarkAllRead(userId, read, CancellationToken.None);
}
return _notificationsRepo.MarkRead(ids, userId, read, CancellationToken.None);
}

View File

@ -635,8 +635,7 @@ namespace MediaBrowser.Api.Playback.Hls
// See if we can save come cpu cycles by avoiding encoding
if (codec.Equals("copy", StringComparison.OrdinalIgnoreCase))
{
// TOOD: Switch to -bsf dump_extra?
return IsH264(state.VideoStream) ? "-codec:v:0 copy -bsf h264_mp4toannexb" : "-codec:v:0 copy";
return IsH264(state.VideoStream) ? "-codec:v:0 copy -bsf:v h264_mp4toannexb" : "-codec:v:0 copy";
}
var keyFrameArg = string.Format(" -force_key_frames expr:gte(t,n_forced*{0})",

View File

@ -139,8 +139,7 @@ namespace MediaBrowser.Api.Playback.Hls
// See if we can save come cpu cycles by avoiding encoding
if (codec.Equals("copy", StringComparison.OrdinalIgnoreCase))
{
// TOOD: Switch to -bsf dump_extra?
return IsH264(state.VideoStream) ? "-codec:v:0 copy -bsf h264_mp4toannexb" : "-codec:v:0 copy";
return IsH264(state.VideoStream) ? "-codec:v:0 copy -bsf:v h264_mp4toannexb" : "-codec:v:0 copy";
}
var keyFrameArg = string.Format(" -force_key_frames expr:gte(t,n_forced*{0})",

View File

@ -132,8 +132,7 @@ namespace MediaBrowser.Api.Playback.Progressive
// See if we can save come cpu cycles by avoiding encoding
if (codec.Equals("copy", StringComparison.OrdinalIgnoreCase))
{
// TODO: Switch to -bsf dump_extra ?
return state.VideoStream != null && IsH264(state.VideoStream) ? args + " -bsf h264_mp4toannexb" : args;
return state.VideoStream != null && IsH264(state.VideoStream) ? args + " -bsf:v h264_mp4toannexb" : args;
}
var keyFrameArg = string.Format(" -force_key_frames expr:gte(t,n_forced*{0})",

View File

@ -33,6 +33,12 @@ namespace MediaBrowser.Controller.Entities
/// <value>The type of the location.</value>
LocationType LocationType { get; }
/// <summary>
/// Gets the locked fields.
/// </summary>
/// <value>The locked fields.</value>
List<MetadataFields> LockedFields { get; }
/// <summary>
/// Gets the images.
/// </summary>

View File

@ -1,6 +1,5 @@
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using System;
using System.Collections.Generic;
using System.Threading;
@ -25,12 +24,6 @@ namespace MediaBrowser.Controller.Entities
/// <value>The date modified.</value>
DateTime DateModified { get; }
/// <summary>
/// Gets the locked fields.
/// </summary>
/// <value>The locked fields.</value>
List<MetadataFields> LockedFields { get; }
/// <summary>
/// Gets or sets the date last saved.
/// </summary>

View File

@ -51,6 +51,15 @@ namespace MediaBrowser.Controller.Notifications
/// <returns>Task.</returns>
Task MarkRead(IEnumerable<string> notificationIdList, string userId, bool isRead, CancellationToken cancellationToken);
/// <summary>
/// Marks all read.
/// </summary>
/// <param name="userId">The user identifier.</param>
/// <param name="isRead">if set to <c>true</c> [is read].</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
Task MarkAllRead(string userId, bool isRead, CancellationToken cancellationToken);
/// <summary>
/// Gets the notifications summary.
/// </summary>

View File

@ -787,13 +787,6 @@ namespace MediaBrowser.Model.ApiClient
/// <value>The server address.</value>
string ServerAddress { get; }
/// <summary>
/// Changes the server location.
/// </summary>
/// <param name="address">The address.</param>
/// <param name="keepExistingAuth">Don't clear any existing authentication</param>
void ChangeServerLocation(string address, bool keepExistingAuth = false);
/// <summary>
/// Gets or sets the type of the client.
/// </summary>

View File

@ -123,7 +123,7 @@ namespace MediaBrowser.Providers.Manager
foreach (var imageType in images)
{
if (!savedOptions.IsEnabled(imageType)) continue;
if (!IsEnabled(savedOptions, imageType, item)) continue;
if (!item.HasImage(imageType) || (refreshOptions.IsReplacingImage(imageType) && !downloadedImages.Contains(imageType)))
{
@ -263,7 +263,7 @@ namespace MediaBrowser.Providers.Manager
foreach (var imageType in _singularImages)
{
if (!savedOptions.IsEnabled(imageType)) continue;
if (!IsEnabled(savedOptions, imageType, item)) continue;
if (!item.HasImage(imageType) || (refreshOptions.IsReplacingImage(imageType) && !downloadedImages.Contains(imageType)))
{
@ -277,14 +277,20 @@ namespace MediaBrowser.Providers.Manager
}
}
minWidth = savedOptions.GetMinWidth(ImageType.Backdrop);
await DownloadBackdrops(item, ImageType.Backdrop, backdropLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false);
var hasScreenshots = item as IHasScreenshots;
if (hasScreenshots != null)
if (!item.LockedFields.Contains(MetadataFields.Backdrops))
{
minWidth = savedOptions.GetMinWidth(ImageType.Screenshot);
await DownloadBackdrops(item, ImageType.Screenshot, screenshotLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false);
minWidth = savedOptions.GetMinWidth(ImageType.Backdrop);
await DownloadBackdrops(item, ImageType.Backdrop, backdropLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false);
}
if (!item.LockedFields.Contains(MetadataFields.Screenshots))
{
var hasScreenshots = item as IHasScreenshots;
if (hasScreenshots != null)
{
minWidth = savedOptions.GetMinWidth(ImageType.Screenshot);
await DownloadBackdrops(item, ImageType.Screenshot, screenshotLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false);
}
}
}
catch (OperationCanceledException)
@ -299,6 +305,33 @@ namespace MediaBrowser.Providers.Manager
}
}
private bool IsEnabled(MetadataOptions options, ImageType type, IHasImages item)
{
if (type == ImageType.Backdrop)
{
if (item.LockedFields.Contains(MetadataFields.Backdrops))
{
return false;
}
}
else if (type == ImageType.Screenshot)
{
if (item.LockedFields.Contains(MetadataFields.Screenshots))
{
return false;
}
}
else
{
if (item.LockedFields.Contains(MetadataFields.Images))
{
return false;
}
}
return options.IsEnabled(type);
}
private void ClearImages(IHasImages item, ImageType type)
{
var deleted = false;

View File

@ -579,18 +579,26 @@
"LabelFullReview": "Full review:",
"LabelShortRatingDescription": "Short rating summary:",
"OptionIRecommendThisItem": "I recommend this item",
"WebClientTourContent": "View your recently added media, next episodes, and more. The green circles indicate how many unplayed items you have.",
"WebClientTourMovies": "Play movies, trailers and more from any device with a web browser",
"WebClientTourMouseOver": "Hold the mouse over any poster for quick access to important information",
"WebClientTourTapHold": "Tap and hold or right click any poster for a context menu",
"WebClientTourMetadataManager": "Click edit to open the metadata manager",
"WebClientTourPlaylists": "Easily create playlists and instant mixes, and play them on any device",
"WebClientTourCollections": "Create movie collections to group box sets together",
"WebClientTourUserPreferences1": "User preferences allow you to customize the way your library is presented in all of your Media Browser apps",
"WebClientTourUserPreferences2": "Configure your audio and subtitle language settings once, for every Media Browser app",
"WebClientTourUserPreferences3": "Design the web client home page to your liking",
"WebClientTourUserPreferences4": "Configure backdrops, theme songs and external players",
"WebClientTourMobile1": "The web client works great on smartphones and tablets...",
"WebClientTourMobile2": "and easily controls other devices and Media Browser apps",
"MessageEnjoyYourStay": "Enjoy your stay"
"WebClientTourContent": "View your recently added media, next episodes, and more. The green circles indicate how many unplayed items you have.",
"WebClientTourMovies": "Play movies, trailers and more from any device with a web browser",
"WebClientTourMouseOver": "Hold the mouse over any poster for quick access to important information",
"WebClientTourTapHold": "Tap and hold or right click any poster for a context menu",
"WebClientTourMetadataManager": "Click edit to open the metadata manager",
"WebClientTourPlaylists": "Easily create playlists and instant mixes, and play them on any device",
"WebClientTourCollections": "Create movie collections to group box sets together",
"WebClientTourUserPreferences1": "User preferences allow you to customize the way your library is presented in all of your Media Browser apps",
"WebClientTourUserPreferences2": "Configure your audio and subtitle language settings once, for every Media Browser app",
"WebClientTourUserPreferences3": "Design the web client home page to your liking",
"WebClientTourUserPreferences4": "Configure backdrops, theme songs and external players",
"WebClientTourMobile1": "The web client works great on smartphones and tablets...",
"WebClientTourMobile2": "and easily controls other devices and Media Browser apps",
"MessageEnjoyYourStay": "Enjoy your stay",
"DashboardTourDashboard": "The server dashboard allows you to monitor your server and your users. You'll always know who is doing what and where they are.",
"DashboardTourUsers": "Easily create user accounts for your friends and family, each with their own permissions, library access, parental controls and more.",
"DashboardTourCinemaMode": "Cinema mode brings the theater experience straight to your living room with the ability to play trailers and custom intros before the main feature.",
"DashboardTourChapters": "Enable chapter image generation for your videos for a more pleasing presentation while viewing.",
"DashboardTourSubtitles": "Automatically download subtitles for your videos in any language.",
"DashboardTourPlugins": "Install plugins such as internet video channels, live tv, metadata scanners, and more.",
"DashboardTourNotifications": "Automatically send notifications of server events to your mobile device, email and more.",
"DashboardTourScheduledTasks": "Easily manage long running operations with scheduled tasks. Decide when they run, and how often."
}

View File

@ -1206,5 +1206,6 @@
"LabelDisplayTrailersWithinMovieSuggestionsHelp": "Requires installation of the Trailer channel.",
"CinemaModeConfigurationHelp2": "Individual users will have the ability to disable cinema mode within their own preferences.",
"LabelEnableCinemaMode": "Enable cinema mode",
"HeaderCinemaMode": "Cinema Mode"
"HeaderCinemaMode": "Cinema Mode",
"HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Server Dashboard"
}

View File

@ -15,7 +15,7 @@ namespace MediaBrowser.Server.Implementations.Notifications
{
public class SqliteNotificationsRepository : INotificationsRepository
{
private IDbConnection _connection;
private IDbConnection _connection;
private readonly ILogger _logger;
private readonly IServerApplicationPaths _appPaths;
@ -33,6 +33,7 @@ namespace MediaBrowser.Server.Implementations.Notifications
private IDbCommand _replaceNotificationCommand;
private IDbCommand _markReadCommand;
private IDbCommand _markAllReadCommand;
public async Task Initialize()
{
@ -78,6 +79,12 @@ namespace MediaBrowser.Server.Implementations.Notifications
_markReadCommand.Parameters.Add(_replaceNotificationCommand, "@UserId");
_markReadCommand.Parameters.Add(_replaceNotificationCommand, "@IsRead");
_markReadCommand.Parameters.Add(_replaceNotificationCommand, "@Id");
_markAllReadCommand = _connection.CreateCommand();
_markAllReadCommand.CommandText = "update Notifications set IsRead=@IsRead where UserId=@UserId";
_markAllReadCommand.Parameters.Add(_replaceNotificationCommand, "@UserId");
_markAllReadCommand.Parameters.Add(_replaceNotificationCommand, "@IsRead");
}
/// <summary>
@ -357,6 +364,58 @@ namespace MediaBrowser.Server.Implementations.Notifications
}
}
public async Task MarkAllRead(string userId, bool isRead, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false);
IDbTransaction transaction = null;
try
{
cancellationToken.ThrowIfCancellationRequested();
transaction = _connection.BeginTransaction();
_markAllReadCommand.GetParameter(0).Value = new Guid(userId);
_markAllReadCommand.GetParameter(1).Value = isRead;
_markAllReadCommand.ExecuteNonQuery();
transaction.Commit();
}
catch (OperationCanceledException)
{
if (transaction != null)
{
transaction.Rollback();
}
throw;
}
catch (Exception e)
{
_logger.ErrorException("Failed to save notification:", e);
if (transaction != null)
{
transaction.Rollback();
}
throw;
}
finally
{
if (transaction != null)
{
transaction.Dispose();
}
_writeLock.Release();
}
}
private async Task MarkReadInternal(IEnumerable<Guid> notificationIdList, string userId, bool isRead, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();

View File

@ -275,6 +275,30 @@
<Content Include="dashboard-ui\css\images\media\play.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\css\images\tour\dashboard\chapters.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\css\images\tour\dashboard\cinemamode.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\css\images\tour\dashboard\dashboard.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\css\images\tour\dashboard\notifications.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\css\images\tour\dashboard\plugins.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\css\images\tour\dashboard\scheduledtasks.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\css\images\tour\dashboard\subtitles.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\css\images\tour\dashboard\users.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\css\images\tour\enjoy.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>