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) 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); 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 // See if we can save come cpu cycles by avoiding encoding
if (codec.Equals("copy", StringComparison.OrdinalIgnoreCase)) if (codec.Equals("copy", StringComparison.OrdinalIgnoreCase))
{ {
// TOOD: Switch to -bsf dump_extra? return IsH264(state.VideoStream) ? "-codec:v:0 copy -bsf:v h264_mp4toannexb" : "-codec:v:0 copy";
return IsH264(state.VideoStream) ? "-codec:v:0 copy -bsf h264_mp4toannexb" : "-codec:v:0 copy";
} }
var keyFrameArg = string.Format(" -force_key_frames expr:gte(t,n_forced*{0})", 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 // See if we can save come cpu cycles by avoiding encoding
if (codec.Equals("copy", StringComparison.OrdinalIgnoreCase)) if (codec.Equals("copy", StringComparison.OrdinalIgnoreCase))
{ {
// TOOD: Switch to -bsf dump_extra? return IsH264(state.VideoStream) ? "-codec:v:0 copy -bsf:v h264_mp4toannexb" : "-codec:v:0 copy";
return IsH264(state.VideoStream) ? "-codec:v:0 copy -bsf h264_mp4toannexb" : "-codec:v:0 copy";
} }
var keyFrameArg = string.Format(" -force_key_frames expr:gte(t,n_forced*{0})", 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 // See if we can save come cpu cycles by avoiding encoding
if (codec.Equals("copy", StringComparison.OrdinalIgnoreCase)) if (codec.Equals("copy", StringComparison.OrdinalIgnoreCase))
{ {
// TODO: Switch to -bsf dump_extra ? return state.VideoStream != null && IsH264(state.VideoStream) ? args + " -bsf:v h264_mp4toannexb" : args;
return state.VideoStream != null && IsH264(state.VideoStream) ? args + " -bsf h264_mp4toannexb" : args;
} }
var keyFrameArg = string.Format(" -force_key_frames expr:gte(t,n_forced*{0})", 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> /// <value>The type of the location.</value>
LocationType LocationType { get; } LocationType LocationType { get; }
/// <summary>
/// Gets the locked fields.
/// </summary>
/// <value>The locked fields.</value>
List<MetadataFields> LockedFields { get; }
/// <summary> /// <summary>
/// Gets the images. /// Gets the images.
/// </summary> /// </summary>

View File

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

View File

@ -51,6 +51,15 @@ namespace MediaBrowser.Controller.Notifications
/// <returns>Task.</returns> /// <returns>Task.</returns>
Task MarkRead(IEnumerable<string> notificationIdList, string userId, bool isRead, CancellationToken cancellationToken); 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> /// <summary>
/// Gets the notifications summary. /// Gets the notifications summary.
/// </summary> /// </summary>

View File

@ -787,13 +787,6 @@ namespace MediaBrowser.Model.ApiClient
/// <value>The server address.</value> /// <value>The server address.</value>
string ServerAddress { get; } 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> /// <summary>
/// Gets or sets the type of the client. /// Gets or sets the type of the client.
/// </summary> /// </summary>

View File

@ -123,7 +123,7 @@ namespace MediaBrowser.Providers.Manager
foreach (var imageType in images) 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))) if (!item.HasImage(imageType) || (refreshOptions.IsReplacingImage(imageType) && !downloadedImages.Contains(imageType)))
{ {
@ -263,7 +263,7 @@ namespace MediaBrowser.Providers.Manager
foreach (var imageType in _singularImages) 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))) if (!item.HasImage(imageType) || (refreshOptions.IsReplacingImage(imageType) && !downloadedImages.Contains(imageType)))
{ {
@ -277,9 +277,14 @@ namespace MediaBrowser.Providers.Manager
} }
} }
if (!item.LockedFields.Contains(MetadataFields.Backdrops))
{
minWidth = savedOptions.GetMinWidth(ImageType.Backdrop); minWidth = savedOptions.GetMinWidth(ImageType.Backdrop);
await DownloadBackdrops(item, ImageType.Backdrop, backdropLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false); await DownloadBackdrops(item, ImageType.Backdrop, backdropLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false);
}
if (!item.LockedFields.Contains(MetadataFields.Screenshots))
{
var hasScreenshots = item as IHasScreenshots; var hasScreenshots = item as IHasScreenshots;
if (hasScreenshots != null) if (hasScreenshots != null)
{ {
@ -287,6 +292,7 @@ namespace MediaBrowser.Providers.Manager
await DownloadBackdrops(item, ImageType.Screenshot, screenshotLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false); await DownloadBackdrops(item, ImageType.Screenshot, screenshotLimit, provider, result, list, minWidth, cancellationToken).ConfigureAwait(false);
} }
} }
}
catch (OperationCanceledException) catch (OperationCanceledException)
{ {
throw; throw;
@ -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) private void ClearImages(IHasImages item, ImageType type)
{ {
var deleted = false; var deleted = false;

View File

@ -592,5 +592,13 @@
"WebClientTourUserPreferences4": "Configure backdrops, theme songs and external players", "WebClientTourUserPreferences4": "Configure backdrops, theme songs and external players",
"WebClientTourMobile1": "The web client works great on smartphones and tablets...", "WebClientTourMobile1": "The web client works great on smartphones and tablets...",
"WebClientTourMobile2": "and easily controls other devices and Media Browser apps", "WebClientTourMobile2": "and easily controls other devices and Media Browser apps",
"MessageEnjoyYourStay": "Enjoy your stay" "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.", "LabelDisplayTrailersWithinMovieSuggestionsHelp": "Requires installation of the Trailer channel.",
"CinemaModeConfigurationHelp2": "Individual users will have the ability to disable cinema mode within their own preferences.", "CinemaModeConfigurationHelp2": "Individual users will have the ability to disable cinema mode within their own preferences.",
"LabelEnableCinemaMode": "Enable cinema mode", "LabelEnableCinemaMode": "Enable cinema mode",
"HeaderCinemaMode": "Cinema Mode" "HeaderCinemaMode": "Cinema Mode",
"HeaderWelcomeToMediaBrowserServerDashboard": "Welcome to the Media Browser Server Dashboard"
} }

View File

@ -33,6 +33,7 @@ namespace MediaBrowser.Server.Implementations.Notifications
private IDbCommand _replaceNotificationCommand; private IDbCommand _replaceNotificationCommand;
private IDbCommand _markReadCommand; private IDbCommand _markReadCommand;
private IDbCommand _markAllReadCommand;
public async Task Initialize() public async Task Initialize()
{ {
@ -78,6 +79,12 @@ namespace MediaBrowser.Server.Implementations.Notifications
_markReadCommand.Parameters.Add(_replaceNotificationCommand, "@UserId"); _markReadCommand.Parameters.Add(_replaceNotificationCommand, "@UserId");
_markReadCommand.Parameters.Add(_replaceNotificationCommand, "@IsRead"); _markReadCommand.Parameters.Add(_replaceNotificationCommand, "@IsRead");
_markReadCommand.Parameters.Add(_replaceNotificationCommand, "@Id"); _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> /// <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) private async Task MarkReadInternal(IEnumerable<Guid> notificationIdList, string userId, bool isRead, CancellationToken cancellationToken)
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();

View File

@ -275,6 +275,30 @@
<Content Include="dashboard-ui\css\images\media\play.png"> <Content Include="dashboard-ui\css\images\media\play.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </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"> <Content Include="dashboard-ui\css\images\tour\enjoy.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>