added dashboard tour
This commit is contained in:
parent
e83a3e710b
commit
7a084a589e
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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})",
|
||||||
|
|
|
@ -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})",
|
||||||
|
|
|
@ -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})",
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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."
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user