Fixed: Bulk UI cleanup, fixes and consistency improvements (#1959)

pull/2/head
James White 7 years ago committed by Leonardo Galli
parent 4d8a270170
commit 0c8e264668

@ -1,4 +1,4 @@
using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
namespace NzbDrone.Core.HealthCheck.Checks namespace NzbDrone.Core.HealthCheck.Checks
@ -17,7 +17,7 @@ namespace NzbDrone.Core.HealthCheck.Checks
if (_appFolderInfo.StartUpFolder.IsParentPath(_appFolderInfo.AppDataFolder) || if (_appFolderInfo.StartUpFolder.IsParentPath(_appFolderInfo.AppDataFolder) ||
_appFolderInfo.StartUpFolder.PathEquals(_appFolderInfo.AppDataFolder)) _appFolderInfo.StartUpFolder.PathEquals(_appFolderInfo.AppDataFolder))
{ {
return new HealthCheck(GetType(), HealthCheckResult.Warning, "Updating will not be possible to prevent deleting AppData on Update"); return new HealthCheck(GetType(), HealthCheckResult.Warning, "Updating will not be possible to prevent deleting AppData on update");
} }
return new HealthCheck(GetType()); return new HealthCheck(GetType());

@ -1,4 +1,4 @@
using System; using System;
using System.Linq; using System.Linq;
using NLog; using NLog;
using NzbDrone.Core.Download; using NzbDrone.Core.Download;
@ -22,7 +22,7 @@ namespace NzbDrone.Core.HealthCheck.Checks
if (!downloadClients.Any()) if (!downloadClients.Any())
{ {
return new HealthCheck(GetType(), HealthCheckResult.Warning, "No download client is available"); return new HealthCheck(GetType(), HealthCheckResult.Warning, "No download client is available.");
} }
foreach (var downloadClient in downloadClients) foreach (var downloadClient in downloadClients)

@ -1,4 +1,4 @@
using NzbDrone.Common.Disk; using NzbDrone.Common.Disk;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
@ -26,12 +26,12 @@ namespace NzbDrone.Core.HealthCheck.Checks
if (!_diskProvider.FolderExists(droneFactoryFolder)) if (!_diskProvider.FolderExists(droneFactoryFolder))
{ {
return new HealthCheck(GetType(), HealthCheckResult.Error, "Drone factory folder does not exist"); return new HealthCheck(GetType(), HealthCheckResult.Error, "Drone Factory folder does not exist.");
} }
if (!_diskProvider.FolderWritable(droneFactoryFolder)) if (!_diskProvider.FolderWritable(droneFactoryFolder))
{ {
return new HealthCheck(GetType(), HealthCheckResult.Error, "Unable to write to drone factory folder"); return new HealthCheck(GetType(), HealthCheckResult.Error, "Unable to write to Drone Factory folder");
} }
//Todo: Unable to import one or more files/folders from //Todo: Unable to import one or more files/folders from

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NzbDrone.Common.Disk; using NzbDrone.Common.Disk;
@ -51,7 +51,7 @@ namespace NzbDrone.Core.HealthCheck.Checks
// Migration helper logic // Migration helper logic
if (!downloadClientIsLocalHost) if (!downloadClientIsLocalHost)
{ {
return new HealthCheck(GetType(), HealthCheckResult.Warning, "Enable Completed Download Handling if possible (Multi-Computer unsupported)", "Migrating-to-Completed-Download-Handling#Unsupported-download-client-on-different-computer"); return new HealthCheck(GetType(), HealthCheckResult.Warning, "Enable completed download handling if possible (Multi-Computer unsupported).", "Migrating-to-Completed-Download-Handling#Unsupported-download-client-on-different-computer");
} }
if (downloadClients.All(v => v.DownloadClient is Sabnzbd)) if (downloadClients.All(v => v.DownloadClient is Sabnzbd))
@ -59,10 +59,10 @@ namespace NzbDrone.Core.HealthCheck.Checks
// With Sabnzbd we can check if the category should be changed. // With Sabnzbd we can check if the category should be changed.
if (downloadClientOutputInDroneFactory) if (downloadClientOutputInDroneFactory)
{ {
return new HealthCheck(GetType(), HealthCheckResult.Warning, "Enable Completed Download Handling if possible (Sabnzbd - Conflicting Category)", "Migrating-to-Completed-Download-Handling#sabnzbd-conflicting-download-client-category"); return new HealthCheck(GetType(), HealthCheckResult.Warning, "Enable completed download handling if possible (SABnzbd - conflicting category).", "Migrating-to-Completed-Download-Handling#sabnzbd-conflicting-download-client-category");
} }
return new HealthCheck(GetType(), HealthCheckResult.Warning, "Enable Completed Download Handling if possible (Sabnzbd)", "Migrating-to-Completed-Download-Handling#sabnzbd-enable-completed-download-handling"); return new HealthCheck(GetType(), HealthCheckResult.Warning, "Enable completed download handling if possible (SABnzbd).", "Migrating-to-Completed-Download-Handling#sabnzbd-enable-completed-download-handling");
} }
if (downloadClients.All(v => v.DownloadClient is Nzbget)) if (downloadClients.All(v => v.DownloadClient is Nzbget))
@ -70,18 +70,18 @@ namespace NzbDrone.Core.HealthCheck.Checks
// With Nzbget we can check if the category should be changed. // With Nzbget we can check if the category should be changed.
if (downloadClientOutputInDroneFactory) if (downloadClientOutputInDroneFactory)
{ {
return new HealthCheck(GetType(), HealthCheckResult.Warning, "Enable Completed Download Handling if possible (Nzbget - Conflicting Category)", "Migrating-to-Completed-Download-Handling#nzbget-conflicting-download-client-category"); return new HealthCheck(GetType(), HealthCheckResult.Warning, "Enable completed download handling if possible (NZBGet - conflicting category).", "Migrating-to-Completed-Download-Handling#nzbget-conflicting-download-client-category");
} }
return new HealthCheck(GetType(), HealthCheckResult.Warning, "Enable Completed Download Handling if possible (Nzbget)", "Migrating-to-Completed-Download-Handling#nzbget-enable-completed-download-handling"); return new HealthCheck(GetType(), HealthCheckResult.Warning, "Enable completed download handling if possible (NZBGet).", "Migrating-to-Completed-Download-Handling#nzbget-enable-completed-download-handling");
} }
return new HealthCheck(GetType(), HealthCheckResult.Warning, "Enable Completed Download Handling if possible", "Migrating-to-Completed-Download-Handling"); return new HealthCheck(GetType(), HealthCheckResult.Warning, "Enable completed download handling if possible.", "Migrating-to-Completed-Download-Handling");
} }
if (!_configService.EnableCompletedDownloadHandling && droneFactoryFolder.IsEmpty) if (!_configService.EnableCompletedDownloadHandling && droneFactoryFolder.IsEmpty)
{ {
return new HealthCheck(GetType(), HealthCheckResult.Warning, "Enable Completed Download Handling or configure Drone factory"); return new HealthCheck(GetType(), HealthCheckResult.Warning, "Enable completed download handling or configure Drone Factory.");
} }
return new HealthCheck(GetType()); return new HealthCheck(GetType());

@ -1,4 +1,4 @@
using System.Linq; using System.Linq;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Indexers; using NzbDrone.Core.Indexers;
@ -19,14 +19,14 @@ namespace NzbDrone.Core.HealthCheck.Checks
if (enabled.Empty()) if (enabled.Empty())
{ {
return new HealthCheck(GetType(), HealthCheckResult.Error, "No indexers available with RSS sync enabled, Radarr will not grab new releases automatically"); return new HealthCheck(GetType(), HealthCheckResult.Error, "No indexers available with RSS sync enabled, Radarr will not grab new releases automatically.");
} }
var active = _indexerFactory.RssEnabled(true); var active = _indexerFactory.RssEnabled(true);
if (active.Empty()) if (active.Empty())
{ {
return new HealthCheck(GetType(), HealthCheckResult.Warning, "All rss-capable indexers are temporarily unavailable due to recent indexer errors"); return new HealthCheck(GetType(), HealthCheckResult.Warning, "All RSS capable indexers are temporarily unavailable due to recent indexer errors.");
} }
return new HealthCheck(GetType()); return new HealthCheck(GetType());

@ -1,4 +1,4 @@
using System.Linq; using System.Linq;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Indexers; using NzbDrone.Core.Indexers;
@ -19,14 +19,14 @@ namespace NzbDrone.Core.HealthCheck.Checks
if (enabled.Empty()) if (enabled.Empty())
{ {
return new HealthCheck(GetType(), HealthCheckResult.Warning, "No indexers available with Search enabled, Radarr will not provide any search results"); return new HealthCheck(GetType(), HealthCheckResult.Warning, "No indexers available with search enabled, Radarr will not provide any search results.");
} }
var active = _indexerFactory.SearchEnabled(true); var active = _indexerFactory.SearchEnabled(true);
if (active.Empty()) if (active.Empty())
{ {
return new HealthCheck(GetType(), HealthCheckResult.Warning, "All search-capable indexers are temporarily unavailable due to recent indexer errors"); return new HealthCheck(GetType(), HealthCheckResult.Warning, "All search-capable indexers are temporarily unavailable due to recent indexer errors.");
} }
return new HealthCheck(GetType()); return new HealthCheck(GetType());

@ -1,4 +1,4 @@
using System; using System;
using System.Linq; using System.Linq;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Indexers; using NzbDrone.Core.Indexers;
@ -33,7 +33,7 @@ namespace NzbDrone.Core.HealthCheck.Checks
if (backOffIndexers.Count == enabledIndexers.Count) if (backOffIndexers.Count == enabledIndexers.Count)
{ {
return new HealthCheck(GetType(), HealthCheckResult.Error, "All indexers are unavailable due to failures", "#indexers-are-unavailable-due-to-failures"); return new HealthCheck(GetType(), HealthCheckResult.Error, "All indexers are unavailable due to failures.", "#indexers-are-unavailable-due-to-failures");
} }
return new HealthCheck(GetType(), HealthCheckResult.Warning, string.Format("Indexers unavailable due to failures: {0}", string.Join(", ", backOffIndexers.Select(v => v.Indexer.Definition.Name))), "#indexers-are-unavailable-due-to-failures"); return new HealthCheck(GetType(), HealthCheckResult.Warning, string.Format("Indexers unavailable due to failures: {0}", string.Join(", ", backOffIndexers.Select(v => v.Indexer.Definition.Name))), "#indexers-are-unavailable-due-to-failures");

@ -1,4 +1,4 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
@ -35,24 +35,24 @@ namespace NzbDrone.Core.HealthCheck.Checks
if (version == new Version(3, 4, 0) && HasMonoBug18599()) if (version == new Version(3, 4, 0) && HasMonoBug18599())
{ {
_logger.Debug("mono version 3.4.0, checking for mono bug #18599 returned positive."); _logger.Debug("Mono version 3.4.0, checking for mono bug #18599 returned positive.");
return new HealthCheck(GetType(), HealthCheckResult.Error, "your mono version 3.4.0 has a critical bug, you should upgrade to a higher version"); return new HealthCheck(GetType(), HealthCheckResult.Error, "your Mono version 3.4.0 has a critical bug, you should upgrade to a higher version.");
} }
if (version == new Version(4, 4, 0) || version == new Version(4, 4, 1)) if (version == new Version(4, 4, 0) || version == new Version(4, 4, 1))
{ {
_logger.Debug("mono version {0}", version); _logger.Debug("Mono version {0}", version);
return new HealthCheck(GetType(), HealthCheckResult.Error, $"your mono version {version} has a bug that causes issues connecting to indexers/download clients"); return new HealthCheck(GetType(), HealthCheckResult.Error, $"your Mono version {version} has a bug that causes issues connecting to indexers/download clients.");
} }
if (version >= new Version(3, 10)) if (version >= new Version(3, 10))
{ {
_logger.Debug("mono version is 3.10 or better: {0}", version.ToString()); _logger.Debug("Mono version is 3.10 or better: {0}.", version.ToString());
return new HealthCheck(GetType()); return new HealthCheck(GetType());
} }
} }
return new HealthCheck(GetType(), HealthCheckResult.Warning, "mono version is less than 3.10, upgrade for improved stability"); return new HealthCheck(GetType(), HealthCheckResult.Warning, "Mono version is less than 3.10, upgrade for improved stability.");
} }
public override bool CheckOnConfigChange => false; public override bool CheckOnConfigChange => false;
@ -61,7 +61,7 @@ namespace NzbDrone.Core.HealthCheck.Checks
private bool HasMonoBug18599() private bool HasMonoBug18599()
{ {
_logger.Debug("mono version 3.4.0, checking for mono bug #18599."); _logger.Debug("Mono version 3.4.0, checking for mono bug #18599.");
var numberFormatterType = Type.GetType("System.NumberFormatter"); var numberFormatterType = Type.GetType("System.NumberFormatter");
if (numberFormatterType == null) if (numberFormatterType == null)

@ -1,4 +1,4 @@
using NLog; using NLog;
using NzbDrone.Common.Http; using NzbDrone.Common.Http;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using System; using System;
@ -32,7 +32,7 @@ namespace NzbDrone.Core.HealthCheck.Checks
var addresses = Dns.GetHostAddresses(_configService.ProxyHostname); var addresses = Dns.GetHostAddresses(_configService.ProxyHostname);
if(!addresses.Any()) if(!addresses.Any())
{ {
return new HealthCheck(GetType(), HealthCheckResult.Error, string.Format("Failed to resolve the IP Address for the Configured Proxy Host {0}", _configService.ProxyHostname)); return new HealthCheck(GetType(), HealthCheckResult.Error, string.Format("Failed to resolve the IP address for the configured proxy host {0}.", _configService.ProxyHostname));
} }
var request = _cloudRequestBuilder.Create() var request = _cloudRequestBuilder.Create()
@ -47,13 +47,13 @@ namespace NzbDrone.Core.HealthCheck.Checks
if (response.StatusCode == HttpStatusCode.BadRequest) if (response.StatusCode == HttpStatusCode.BadRequest)
{ {
_logger.Error("Proxy Health Check failed: {0}", response.StatusCode); _logger.Error("Proxy Health Check failed: {0}", response.StatusCode);
return new HealthCheck(GetType(), HealthCheckResult.Error, string.Format("Failed to test proxy: StatusCode {1}", request.Url, response.StatusCode)); return new HealthCheck(GetType(), HealthCheckResult.Error, string.Format("Failed to test proxy: StatusCode {1}.", request.Url, response.StatusCode));
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.Error(ex, "Proxy Health Check failed: {0}", ex.Message); _logger.Error(ex, "Proxy Health Check failed: {0}", ex.Message);
return new HealthCheck(GetType(), HealthCheckResult.Error, string.Format("Failed to test proxy: {1}", request.Url, ex.Message)); return new HealthCheck(GetType(), HealthCheckResult.Error, string.Format("Failed to test proxy: {1}.", request.Url, ex.Message));
} }
} }

@ -1,4 +1,4 @@
using System.Linq; using System.Linq;
using NzbDrone.Common.Disk; using NzbDrone.Common.Disk;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
@ -30,7 +30,7 @@ namespace NzbDrone.Core.HealthCheck.Checks
return new HealthCheck(GetType(), HealthCheckResult.Error, "Missing root folder: " + missingRootFolders.First(), "#missing-root-folder"); return new HealthCheck(GetType(), HealthCheckResult.Error, "Missing root folder: " + missingRootFolders.First(), "#missing-root-folder");
} }
var message = string.Format("Multiple root folders are missing: {0}", string.Join(" | ", missingRootFolders)); var message = string.Format("Multiple root folders are missing: {0}.", string.Join(" | ", missingRootFolders));
return new HealthCheck(GetType(), HealthCheckResult.Error, message, "#missing-root-folder"); return new HealthCheck(GetType(), HealthCheckResult.Error, message, "#missing-root-folder");
} }

@ -1,4 +1,4 @@
using System; using System;
using System.IO; using System.IO;
using NzbDrone.Common.Disk; using NzbDrone.Common.Disk;
using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.EnvironmentInfo;
@ -45,14 +45,14 @@ namespace NzbDrone.Core.HealthCheck.Checks
{ {
return new HealthCheck(GetType(), HealthCheckResult.Error, return new HealthCheck(GetType(), HealthCheckResult.Error,
string.Format("Cannot install update because startup folder '{0}' is not writable by the user '{1}'.", startupFolder, Environment.UserName), string.Format("Cannot install update because startup folder '{0}' is not writable by the user '{1}'.", startupFolder, Environment.UserName),
"Cannot install update because startup folder is not writable by the user"); "Cannot install update because startup folder is not writable by the user.");
} }
if (!_diskProvider.FolderWritable(uiFolder)) if (!_diskProvider.FolderWritable(uiFolder))
{ {
return new HealthCheck(GetType(), HealthCheckResult.Error, return new HealthCheck(GetType(), HealthCheckResult.Error,
string.Format("Cannot install update because UI folder '{0}' is not writable by the user '{1}'.", uiFolder, Environment.UserName), string.Format("Cannot install update because UI folder '{0}' is not writable by the user '{1}'.", uiFolder, Environment.UserName),
"Cannot install update because UI folder is not writable by the user"); "Cannot install update because UI folder is not writable by the user.");
} }
} }
@ -60,7 +60,7 @@ namespace NzbDrone.Core.HealthCheck.Checks
{ {
if (_checkUpdateService.AvailableUpdate() != null) if (_checkUpdateService.AvailableUpdate() != null)
{ {
return new HealthCheck(GetType(), HealthCheckResult.Warning, "New update is available"); return new HealthCheck(GetType(), HealthCheckResult.Warning, "New update is available.");
} }
} }

@ -1,4 +1,4 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
@ -17,7 +17,7 @@ namespace NzbDrone.Core.Notifications.Boxcar
{ {
private static readonly BoxcarSettingsValidator Validator = new BoxcarSettingsValidator(); private static readonly BoxcarSettingsValidator Validator = new BoxcarSettingsValidator();
[FieldDefinition(0, Label = "Access Token", HelpText = "Your Access Token, from your Boxcar account settings: https://new.boxcar.io/account/edit", HelpLink = "https://new.boxcar.io/account/edit")] [FieldDefinition(0, Label = "Access Token", HelpText = "Your access token, from your Boxcar account settings.", HelpLink = "https://new.boxcar.io/account/edit")]
public string Token { get; set; } public string Token { get; set; }
public NzbDroneValidationResult Validate() public NzbDroneValidationResult Validate()

@ -1,4 +1,4 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
@ -21,7 +21,7 @@ namespace NzbDrone.Core.Notifications.CustomScript
[FieldDefinition(0, Label = "Path", Type = FieldType.FilePath)] [FieldDefinition(0, Label = "Path", Type = FieldType.FilePath)]
public string Path { get; set; } public string Path { get; set; }
[FieldDefinition(1, Label = "Arguments", HelpText = "Arguments to pass to the script")] [FieldDefinition(1, Label = "Arguments", HelpText = "Arguments to pass to the script.")]
public string Arguments { get; set; } public string Arguments { get; set; }
public NzbDroneValidationResult Validate() public NzbDroneValidationResult Validate()

@ -1,4 +1,4 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
@ -27,7 +27,7 @@ namespace NzbDrone.Core.Notifications.Email
Ssl = true; Ssl = true;
} }
[FieldDefinition(0, Label = "Server", HelpText = "Hostname or IP of Email server")] [FieldDefinition(0, Label = "Server", HelpText = "Hostname or IP address of the email server")]
public string Server { get; set; } public string Server { get; set; }
[FieldDefinition(1, Label = "Port")] [FieldDefinition(1, Label = "Port")]

@ -1,4 +1,4 @@
using FluentValidation; using FluentValidation;
using Newtonsoft.Json; using Newtonsoft.Json;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.ThingiProvider;
@ -33,10 +33,10 @@ namespace NzbDrone.Core.Notifications.MediaBrowser
[FieldDefinition(2, Label = "API Key")] [FieldDefinition(2, Label = "API Key")]
public string ApiKey { get; set; } public string ApiKey { get; set; }
[FieldDefinition(3, Label = "Send Notifications", HelpText = "Have MediaBrowser send notfications to configured providers", Type = FieldType.Checkbox)] [FieldDefinition(3, Label = "Send Notifications", HelpText = "Should MediaBrowser send notfications to configured providers?", Type = FieldType.Checkbox)]
public bool Notify { get; set; } public bool Notify { get; set; }
[FieldDefinition(4, Label = "Update Library", HelpText = "Update Library on Download & Rename?", Type = FieldType.Checkbox)] [FieldDefinition(4, Label = "Update Library", HelpText = "Update library on download & rename?", Type = FieldType.Checkbox)]
public bool UpdateLibrary { get; set; } public bool UpdateLibrary { get; set; }
[JsonIgnore] [JsonIgnore]

@ -1,4 +1,4 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
@ -40,7 +40,7 @@ namespace NzbDrone.Core.Notifications.Plex
[FieldDefinition(4, Label = "Update Library", Type = FieldType.Checkbox)] [FieldDefinition(4, Label = "Update Library", Type = FieldType.Checkbox)]
public bool UpdateLibrary { get; set; } public bool UpdateLibrary { get; set; }
[FieldDefinition(5, Label = "Use SSL", Type = FieldType.Checkbox, HelpText = "Connect to Plex over HTTPS instead of HTTP")] [FieldDefinition(5, Label = "Use SSL", Type = FieldType.Checkbox, HelpText = "Connect to Plex over HTTPS instead of HTTP?")]
public bool UseSsl { get; set; } public bool UseSsl { get; set; }
public bool IsValid => !string.IsNullOrWhiteSpace(Host); public bool IsValid => !string.IsNullOrWhiteSpace(Host);

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.ThingiProvider;
@ -27,13 +27,13 @@ namespace NzbDrone.Core.Notifications.PushBullet
[FieldDefinition(0, Label = "API Key", HelpLink = "https://www.pushbullet.com/")] [FieldDefinition(0, Label = "API Key", HelpLink = "https://www.pushbullet.com/")]
public string ApiKey { get; set; } public string ApiKey { get; set; }
[FieldDefinition(1, Label = "Device IDs", HelpText = "List of device IDs, use device_iden in the device's URL on pushbullet.com (leave blank to send to all devices)", Type = FieldType.Tag)] [FieldDefinition(1, Label = "Device IDs", HelpText = "List of device IDs, use device_iden in the device's URL on pushbullet.com (leave blank to send to all devices).", Type = FieldType.Tag)]
public IEnumerable<string> DeviceIds { get; set; } public IEnumerable<string> DeviceIds { get; set; }
[FieldDefinition(2, Label = "Channel Tags", HelpText = "List of Channel Tags to send notifications to", Type = FieldType.Tag)] [FieldDefinition(2, Label = "Channel Tags", HelpText = "List of channel tags to send notifications to.", Type = FieldType.Tag)]
public IEnumerable<string> ChannelTags { get; set; } public IEnumerable<string> ChannelTags { get; set; }
[FieldDefinition(3, Label = "Sender ID", HelpText = "The device ID to send notifications from, use device_iden in the device's URL on pushbullet.com (leave blank to send from yourself)")] [FieldDefinition(3, Label = "Sender ID", HelpText = "The device ID to send notifications from, use device_iden in the device's URL on pushbullet.com (leave blank to send from yourself).")]
public string SenderId { get; set; } public string SenderId { get; set; }
public NzbDroneValidationResult Validate() public NzbDroneValidationResult Validate()

@ -1,4 +1,4 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
@ -28,7 +28,7 @@ namespace NzbDrone.Core.Notifications.Pushalot
[FieldDefinition(1, Label = "Priority", Type = FieldType.Select, SelectOptions = typeof(PushalotPriority))] [FieldDefinition(1, Label = "Priority", Type = FieldType.Select, SelectOptions = typeof(PushalotPriority))]
public int Priority { get; set; } public int Priority { get; set; }
[FieldDefinition(2, Label = "Image", Type = FieldType.Checkbox, HelpText = "Include Radarr logo with notifications")] [FieldDefinition(2, Label = "Image", Type = FieldType.Checkbox, HelpText = "Include Radarr logo with notifications?")]
public bool Image { get; set; } public bool Image { get; set; }
public bool IsValid => !string.IsNullOrWhiteSpace(AuthToken); public bool IsValid => !string.IsNullOrWhiteSpace(AuthToken);

@ -1,4 +1,4 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
@ -34,13 +34,13 @@ namespace NzbDrone.Core.Notifications.Pushover
[FieldDefinition(2, Label = "Priority", Type = FieldType.Select, SelectOptions = typeof(PushoverPriority) )] [FieldDefinition(2, Label = "Priority", Type = FieldType.Select, SelectOptions = typeof(PushoverPriority) )]
public int Priority { get; set; } public int Priority { get; set; }
[FieldDefinition(3, Label = "Retry", Type = FieldType.Textbox, HelpText = "Interval to retry Emergency alerts, minimum 30 seconds")] [FieldDefinition(3, Label = "Retry", Type = FieldType.Textbox, HelpText = "Interval to retry emergency alerts, minimum 30 seconds.")]
public int Retry { get; set; } public int Retry { get; set; }
[FieldDefinition(4, Label = "Expire", Type = FieldType.Textbox, HelpText = "Maximum time to retry Emergency alerts, maximum 86400 seconds")] [FieldDefinition(4, Label = "Expire", Type = FieldType.Textbox, HelpText = "Maximum time to retry emergency alerts, maximum 86400 seconds.")]
public int Expire { get; set; } public int Expire { get; set; }
[FieldDefinition(5, Label = "Sound", Type = FieldType.Textbox, HelpText = "Notification sound, leave blank to use the default", HelpLink = "https://pushover.net/api#sounds")] [FieldDefinition(5, Label = "Sound", Type = FieldType.Textbox, HelpText = "Notification sound, leave blank to use the default.", HelpLink = "https://pushover.net/api#sounds")]
public string Sound { get; set; } public string Sound { get; set; }
public bool IsValid => !string.IsNullOrWhiteSpace(UserKey) && Priority >= -1 && Priority <= 2; public bool IsValid => !string.IsNullOrWhiteSpace(UserKey) && Priority >= -1 && Priority <= 2;

@ -1,4 +1,4 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
@ -18,13 +18,13 @@ namespace NzbDrone.Core.Notifications.Slack
{ {
private static readonly SlackSettingsValidator Validator = new SlackSettingsValidator(); private static readonly SlackSettingsValidator Validator = new SlackSettingsValidator();
[FieldDefinition(0, Label = "Webhook URL", HelpText = "Slack channel webhook url", Type = FieldType.Url, HelpLink = "https://my.slack.com/services/new/incoming-webhook/")] [FieldDefinition(0, Label = "Webhook URL", HelpText = "Slack channel webhook url.", Type = FieldType.Url, HelpLink = "https://my.slack.com/services/new/incoming-webhook/")]
public string WebHookUrl { get; set; } public string WebHookUrl { get; set; }
[FieldDefinition(1, Label = "Username", HelpText = "Choose the username that this integration will post as", Type = FieldType.Textbox)] [FieldDefinition(1, Label = "Username", HelpText = "Choose the username that this integration will post as.", Type = FieldType.Textbox)]
public string Username { get; set; } public string Username { get; set; }
[FieldDefinition(2, Label = "Icon", HelpText = "Change the icon that is used for messages from this integration (Emoji or URL)", Type = FieldType.Textbox, HelpLink = "http://www.emoji-cheat-sheet.com/")] [FieldDefinition(2, Label = "Icon", HelpText = "Change the icon that is used for messages from this integration (Emoji or URL).", Type = FieldType.Textbox, HelpLink = "http://www.emoji-cheat-sheet.com/")]
public string Icon { get; set; } public string Icon { get; set; }
public NzbDroneValidationResult Validate() public NzbDroneValidationResult Validate()

@ -1,4 +1,4 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
@ -22,7 +22,7 @@ namespace NzbDrone.Core.Notifications.Synology
UpdateLibrary = true; UpdateLibrary = true;
} }
[FieldDefinition(0, Label = "Update Library", Type = FieldType.Checkbox, HelpText = "Call synoindex on localhost to update a library file")] [FieldDefinition(0, Label = "Update Library", Type = FieldType.Checkbox, HelpText = "Call synoindex on localhost to update a library file.")]
public bool UpdateLibrary { get; set; } public bool UpdateLibrary { get; set; }
public NzbDroneValidationResult Validate() public NzbDroneValidationResult Validate()

@ -1,4 +1,4 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
@ -21,7 +21,7 @@ namespace NzbDrone.Core.Notifications.Telegram
[FieldDefinition(0, Label = "Bot Token", HelpLink = "https://core.telegram.org/bots")] [FieldDefinition(0, Label = "Bot Token", HelpLink = "https://core.telegram.org/bots")]
public string BotToken { get; set; } public string BotToken { get; set; }
[FieldDefinition(1, Label = "Chat ID", HelpLink = "http://stackoverflow.com/a/37396871/882971", HelpText = "You must start a conversation with the bot or add it to your group to receive messages")] [FieldDefinition(1, Label = "Chat ID", HelpLink = "http://stackoverflow.com/a/37396871/882971", HelpText = "You must start a conversation with the bot or add it to your group before you can receive messages.")]
public string ChatId { get; set; } public string ChatId { get; set; }
public bool IsValid => !string.IsNullOrWhiteSpace(ChatId) && !string.IsNullOrWhiteSpace(BotToken); public bool IsValid => !string.IsNullOrWhiteSpace(ChatId) && !string.IsNullOrWhiteSpace(BotToken);

@ -1,4 +1,4 @@
using FluentValidation; using FluentValidation;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.ThingiProvider;
@ -18,7 +18,7 @@ namespace NzbDrone.Core.Notifications.Twitter
RuleFor(c => c.Mention).NotEmpty().When(c => c.DirectMessage); RuleFor(c => c.Mention).NotEmpty().When(c => c.DirectMessage);
RuleFor(c => c.DirectMessage).Equal(true) RuleFor(c => c.DirectMessage).Equal(true)
.WithMessage("Using Direct Messaging is recommended, or use a private account.") .WithMessage("Using direct messaging is recommended, or use a private account.")
.AsWarning(); .AsWarning();
RuleFor(c => c.AuthorizeNotification).Empty() RuleFor(c => c.AuthorizeNotification).Empty()
@ -37,10 +37,10 @@ namespace NzbDrone.Core.Notifications.Twitter
AuthorizeNotification = "step1"; AuthorizeNotification = "step1";
} }
[FieldDefinition(0, Label = "Consumer Key", HelpText = "Consumer key from a Twitter application", HelpLink = "https://github.com/Radarr/Radarr/wiki/Twitter-Notifications")] [FieldDefinition(0, Label = "Consumer Key", HelpText = "Consumer key from a Twitter application.", HelpLink = "https://github.com/Radarr/Radarr/wiki/Twitter-Notifications")]
public string ConsumerKey { get; set; } public string ConsumerKey { get; set; }
[FieldDefinition(1, Label = "Consumer Secret", HelpText = "Consumer secret from a Twitter application", HelpLink = "https://github.com/Radarr/Radarr/wiki/Twitter-Notifications")] [FieldDefinition(1, Label = "Consumer Secret", HelpText = "Consumer secret from a Twitter application.", HelpLink = "https://github.com/Radarr/Radarr/wiki/Twitter-Notifications")]
public string ConsumerSecret { get; set; } public string ConsumerSecret { get; set; }
[FieldDefinition(2, Label = "Access Token", Advanced = true)] [FieldDefinition(2, Label = "Access Token", Advanced = true)]
@ -49,10 +49,10 @@ namespace NzbDrone.Core.Notifications.Twitter
[FieldDefinition(3, Label = "Access Token Secret", Advanced = true)] [FieldDefinition(3, Label = "Access Token Secret", Advanced = true)]
public string AccessTokenSecret { get; set; } public string AccessTokenSecret { get; set; }
[FieldDefinition(4, Label = "Mention", HelpText = "Mention this user in sent tweets")] [FieldDefinition(4, Label = "Mention", HelpText = "Mention this user in sent tweets.")]
public string Mention { get; set; } public string Mention { get; set; }
[FieldDefinition(5, Label = "Direct Message", Type = FieldType.Checkbox, HelpText = "Send a direct message instead of a public message")] [FieldDefinition(5, Label = "Direct Message", Type = FieldType.Checkbox, HelpText = "Send a direct message instead of a public message.")]
public bool DirectMessage { get; set; } public bool DirectMessage { get; set; }
[FieldDefinition(6, Label = "Connect to twitter", Type = FieldType.Action)] [FieldDefinition(6, Label = "Connect to twitter", Type = FieldType.Action)]

@ -1,4 +1,4 @@
using System; using System;
using FluentValidation; using FluentValidation;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.ThingiProvider;
@ -26,7 +26,7 @@ namespace NzbDrone.Core.Notifications.Webhook
[FieldDefinition(0, Label = "URL", Type = FieldType.Url)] [FieldDefinition(0, Label = "URL", Type = FieldType.Url)]
public string Url { get; set; } public string Url { get; set; }
[FieldDefinition(1, Label = "Method", Type = FieldType.Select, SelectOptions = typeof(WebhookMethod), HelpText = "Which HTTP method to use submit to the Webservice")] [FieldDefinition(1, Label = "Method", Type = FieldType.Select, SelectOptions = typeof(WebhookMethod), HelpText = "Which HTTP method to use submit to the web service.")]
public int Method { get; set; } public int Method { get; set; }
public NzbDroneValidationResult Validate() public NzbDroneValidationResult Validate()

@ -1,4 +1,4 @@
using System.ComponentModel; using System.ComponentModel;
using FluentValidation; using FluentValidation;
using Newtonsoft.Json; using Newtonsoft.Json;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
@ -39,19 +39,19 @@ namespace NzbDrone.Core.Notifications.Xbmc
public string Password { get; set; } public string Password { get; set; }
[DefaultValue(5)] [DefaultValue(5)]
[FieldDefinition(4, Label = "Display Time", HelpText = "How long the notification will be displayed for (In seconds)")] [FieldDefinition(4, Label = "Display Time", HelpText = "How long the notification will be displayed for (in seconds).")]
public int DisplayTime { get; set; } public int DisplayTime { get; set; }
[FieldDefinition(5, Label = "GUI Notification", Type = FieldType.Checkbox)] [FieldDefinition(5, Label = "GUI Notification", Type = FieldType.Checkbox)]
public bool Notify { get; set; } public bool Notify { get; set; }
[FieldDefinition(6, Label = "Update Library", HelpText = "Update Library on Download & Rename?", Type = FieldType.Checkbox)] [FieldDefinition(6, Label = "Update Library", HelpText = "Update library on download & rename?", Type = FieldType.Checkbox)]
public bool UpdateLibrary { get; set; } public bool UpdateLibrary { get; set; }
[FieldDefinition(7, Label = "Clean Library", HelpText = "Clean Library after update?", Type = FieldType.Checkbox)] [FieldDefinition(7, Label = "Clean Library", HelpText = "Clean library after update?", Type = FieldType.Checkbox)]
public bool CleanLibrary { get; set; } public bool CleanLibrary { get; set; }
[FieldDefinition(8, Label = "Always Update", HelpText = "Update Library even when a video is playing?", Type = FieldType.Checkbox)] [FieldDefinition(8, Label = "Always Update", HelpText = "Update library even when a video is playing?", Type = FieldType.Checkbox)]
public bool AlwaysUpdate { get; set; } public bool AlwaysUpdate { get; set; }
[JsonIgnore] [JsonIgnore]

@ -82,7 +82,7 @@ module.exports = Marionette.Layout.extend({
storeState : false, storeState : false,
items : [ items : [
{ {
title : 'Clear Blacklist', title : 'Clear blacklist',
icon : 'icon-sonarr-clear', icon : 'icon-sonarr-clear',
command : 'clearBlacklist' command : 'clearBlacklist'
} }

@ -1,11 +1,11 @@
<div id="x-toolbar"/> <div id="x-toolbar"></div>
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div id="x-blacklist" class="table-responsive"/> <div id="x-blacklist" class="table-responsive"></div>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div id="x-pager"/> <div id="x-pager"></div>
</div> </div>
</div> </div>

@ -1,16 +1,10 @@
<div class="modal-content"> <div class="modal-content">
<div class="history-detail-modal"> <div class="history-detail-modal">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <button type="button" class="close" data-dismiss="modal" aria-label="close">&times;</button>
<h3>Blacklisted</h3>
<h3>
Blacklisted
</h3>
</div>
<div class="modal-body">
</div> </div>
<div class="modal-body"></div>
<div class="modal-footer"> <div class="modal-footer">
<button class="btn" data-dismiss="modal">Close</button> <button class="btn" data-dismiss="modal">Close</button>
</div> </div>

@ -1,5 +1,4 @@
<dl class="dl-horizontal info"> <dl class="dl-horizontal info">
<dt>Name:</dt> <dt>Name:</dt>
<dd>{{sourceTitle}}</dd> <dd>{{sourceTitle}}</dd>
@ -15,7 +14,6 @@
<dd>{{indexer}}</dd> <dd>{{indexer}}</dd>
{{/if}} {{/if}}
{{#if message}} {{#if message}}
<dt>Message:</dt> <dt>Message:</dt>
<dd>{{message}}</dd> <dd>{{message}}</dd>

@ -1,21 +1,19 @@
<div class="modal-content"> <div class="modal-content">
<div class="history-detail-modal"> <div class="history-detail-modal">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <button type="button" class="close" data-dismiss="modal" aria-label="close">&times;</button>
<h3> <h3>
{{#if_eq eventType compare="grabbed"}}Grabbed{{/if_eq}} {{#if_eq eventType compare="grabbed"}}Grabbed{{/if_eq}}
{{#if_eq eventType compare="downloadFailed"}}Download Failed{{/if_eq}} {{#if_eq eventType compare="downloadFailed"}}Download failed{{/if_eq}}
{{#if_eq eventType compare="downloadFolderImported"}}Episode Imported{{/if_eq}} {{#if_eq eventType compare="downloadFolderImported"}}Movie imported{{/if_eq}}
{{#if_eq eventType compare="episodeFileDeleted"}}Episode File Deleted{{/if_eq}} {{#if_eq eventType compare="episodeFileDeleted"}}Movie file deleted{{/if_eq}}
</h3> </h3>
</div>
<div class="modal-body">
</div> </div>
<div class="modal-body"></div>
<div class="modal-footer"> <div class="modal-footer">
{{#if_eq eventType compare="grabbed"}}<button class="btn btn-danger x-mark-as-failed">Mark As Failed</button>{{/if_eq}} {{#if_eq eventType compare="grabbed"}}
<button class="btn btn-danger x-mark-as-failed">Mark as failed</button>
{{/if_eq}}
<button class="btn" data-dismiss="modal">Close</button> <button class="btn" data-dismiss="modal">Close</button>
</div> </div>
</div> </div>

@ -1,6 +1,5 @@
{{#if_eq eventType compare="grabbed"}} {{#if_eq eventType compare="grabbed"}}
<dl class="dl-horizontal info"> <dl class="dl-horizontal info">
<dt>Name:</dt> <dt>Name:</dt>
<dd>{{sourceTitle}}</dd> <dd>{{sourceTitle}}</dd>
@ -11,7 +10,7 @@
{{/if}} {{/if}}
{{#if releaseGroup}} {{#if releaseGroup}}
<dt>Release Group:</dt> <dt>Release group:</dt>
<dd>{{releaseGroup}}</dd> <dd>{{releaseGroup}}</dd>
{{/if}} {{/if}}
@ -21,7 +20,7 @@
{{/if}} {{/if}}
{{#if downloadClient}} {{#if downloadClient}}
<dt>Download Client:</dt> <dt>Download client:</dt>
<dd>{{downloadClient}}</dd> <dd>{{downloadClient}}</dd>
{{/if}} {{/if}}
@ -35,7 +34,7 @@
{{/if}} {{/if}}
{{#if publishedDate}} {{#if publishedDate}}
<dt>Published Date:</dt> <dt>Published date:</dt>
<dd>{{ShortDate publishedDate}} {{LTS publishedDate}}</dd> <dd>{{ShortDate publishedDate}} {{LTS publishedDate}}</dd>
{{/if}} {{/if}}
{{/with}} {{/with}}
@ -70,7 +69,7 @@
{{/if}} {{/if}}
{{#if importedPath}} {{#if importedPath}}
<dt>Imported To:</dt> <dt>Imported to:</dt>
<dd>{{importedPath}}</dd> <dd>{{importedPath}}</dd>
{{/if}} {{/if}}
{{/with}} {{/with}}
@ -79,7 +78,6 @@
{{#if_eq eventType compare="episodeFileDeleted"}} {{#if_eq eventType compare="episodeFileDeleted"}}
<dl class="dl-horizontal"> <dl class="dl-horizontal">
<dt>Path:</dt> <dt>Path:</dt>
<dd>{{sourceTitle}}</dd> <dd>{{sourceTitle}}</dd>
@ -87,15 +85,15 @@
<dt>Reason:</dt> <dt>Reason:</dt>
<dd> <dd>
{{#if_eq reason compare="Manual"}} {{#if_eq reason compare="Manual"}}
File was deleted by via UI File was deleted by via UI.
{{/if_eq}} {{/if_eq}}
{{#if_eq reason compare="MissingFromDisk"}} {{#if_eq reason compare="MissingFromDisk"}}
Radarr was unable to find the file on disk so it was removed Radarr was unable to find the file on disk so it was removed.
{{/if_eq}} {{/if_eq}}
{{#if_eq reason compare="Upgrade"}} {{#if_eq reason compare="Upgrade"}}
File was deleted to import an upgrade File was deleted to import an upgrade.
{{/if_eq}} {{/if_eq}}
</dd> </dd>
{{/with}} {{/with}}

@ -28,7 +28,7 @@ module.exports = Marionette.Layout.extend({
}, },
{ {
name : 'movie', name : 'movie',
label : 'Movie Title', label : 'Movie title',
cell : MovieTitleCell, cell : MovieTitleCell,
}, },
{ {

@ -1,11 +1,11 @@
<div id="x-history-toolbar"/> <div id="x-history-toolbar"></div>
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div id="x-history" class="table-responsive"/> <div id="x-history" class="table-responsive"></div>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div id="x-history-pager"/> <div id="x-history-pager"></div>
</div> </div>
</div> </div>

@ -1,12 +1,12 @@
{{#if_eq status compare="Completed"}} {{#if_eq status compare="Completed"}}
{{#if_eq trackedDownloadStatus compare="Warning"}} {{#if_eq trackedDownloadStatus compare="Warning"}}
<i class="icon-sonarr-import-manual x-manual-import" title="Manual import"></i> <i class="icon-sonarr-import-manual x-manual-import" title="Manual import."></i>
{{/if_eq}} {{/if_eq}}
{{/if_eq}} {{/if_eq}}
{{#if_eq status compare="Pending"}} {{#if_eq status compare="Pending"}}
<i class="icon-sonarr-download x-grab" title="Add to download queue (Override Delay Profile)"></i> <i class="icon-sonarr-download x-grab" title="Add to download queue (overrides delay profile)."></i>
<i class="icon-sonarr-delete x-remove" title="Remove pending release"></i> <i class="icon-sonarr-delete x-remove" title="Remove pending release."></i>
{{else}} {{else}}
<i class="icon-sonarr-delete x-remove" title="Remove from download client"></i> <i class="icon-sonarr-delete x-remove" title="Remove from download client."></i>
{{/if_eq}} {{/if_eq}}

@ -56,7 +56,7 @@ module.exports = Marionette.Layout.extend({
}, },
{ {
name : 'timeleft', name : 'timeleft',
label : 'Time Left', label : 'Time left',
cell : TimeleftCell, cell : TimeleftCell,
cellValue : 'this' cellValue : 'this'
}, },

@ -1,11 +1,11 @@
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div id="x-queue" class="queue table-responsive"/> <div id="x-queue" class="queue table-responsive"></div>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div id="x-queue-pager"/> <div id="x-queue-pager"></div>
</div> </div>
</div> </div>

@ -1,37 +1,32 @@
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <button type="button" class="close" data-dismiss="modal" aria-label="close">&times;</button>
<h3>{{title}}</h3> <h3>{{title}}</h3>
</div> </div>
<div class="modal-body remove-from-queue-modal"> <div class="modal-body remove-from-queue-modal">
<div class="row"> <div class="row">
<div class="col-sm-12"> <div class="col-sm-12">
Are you sure you want to remove '{{title}}'? Are you sure you want to remove '{{title}}'?
</div> </div>
</div> </div>
{{#if showBlacklist}} {{#if showBlacklist}}
<div class="row"> <div class="row">
<div class="col-sm-12"> <div class="col-sm-12">
<div class="form-horizontal"> <div class="form-horizontal">
<div class="form-group"> <div class="form-group">
<label class="col-sm-4 control-label">Blacklist release</label> <label class="col-sm-4 control-label">Blacklist release</label>
<div class="col-sm-8"> <div class="col-sm-8">
<div class="input-group"> <div class="input-group">
<label class="checkbox toggle well"> <label class="checkbox toggle well">
<input type="checkbox" class="x-blacklist"/> <input type="checkbox" class="x-blacklist">
<p> <p>
<span>Yes</span> <span>Yes</span>
<span>No</span> <span>No</span>
</p> </p>
<div class="btn slide-button btn-danger"></div>
<div class="btn slide-button btn-danger"/>
</label> </label>
<span class="help-inline-checkbox"> <span class="help-inline-checkbox">
<i class="icon-sonarr-form-info" title="Do you want to blacklist this release?"/> <i class="icon-sonarr-form-info" title="Do you want to blacklist this release?"></i>
</span> </span>
</div> </div>
</div> </div>
@ -42,7 +37,9 @@
{{/if}} {{/if}}
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<span class="indicator x-indicator"><i class="icon-sonarr-spinner fa-spin"></i></span> <span class="indicator x-indicator">
<i class="icon-sonarr-spinner fa-spin" aria-hidden="true"></i>
</span>
<button class="btn" data-dismiss="modal">Cancel</button> <button class="btn" data-dismiss="modal">Cancel</button>
<button class="btn btn-danger x-confirm-remove">Remove</button> <button class="btn btn-danger x-confirm-remove">Remove</button>
</div> </div>

@ -1,10 +1,22 @@
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div class="btn-group add-movies-btn-group btn-group-lg btn-block btn-group-collapse"> <div class="btn-group add-movies-btn-group btn-group-lg btn-block btn-group-collapse">
<button class="btn btn-default col-md-3 col-xs-12 x-bulk-import"><i class="icon-sonarr-view-list hidden-xs"></i> Bulk Import Movies</button> <button class="btn btn-default col-md-3 col-xs-12 x-bulk-import">
<button type="button" class="btn btn-default col-md-4 col-xs-12 add-movies-import-btn x-discover"><i class="icon-sonarr-star"/> Discover new movies</button> <i class="icon-sonarr-view-list hidden-xs"></i>
<button class="btn btn-default col-md-2 col-xs-12 x-add-new"><i class="icon-sonarr-active hidden-xs"></i> Add New Movie</button> Bulk import movies
<button class="btn btn-default col-md-3 col-xs-12 x-add-lists"><i class="icon-sonarr-active hidden-xs"></i> Add Movies from Lists</button> </button>
<button type="button" class="btn btn-default col-md-4 col-xs-12 add-movies-import-btn x-discover">
<i class="icon-sonarr-star hidden-xs" aria-hidden="true"></i>
Discover new movies
</button>
<button class="btn btn-default col-md-2 col-xs-12 x-add-new">
<i class="icon-sonarr-active hidden-xs" aria-hidden="true"></i>
Add new movie
</button>
<button class="btn btn-default col-md-3 col-xs-12 x-add-lists">
<i class="icon-sonarr-active hidden-xs" aria-hidden="true"></i>
Add movies from lists
</button>
</div> </div>
</div> </div>
</div> </div>
@ -13,22 +25,19 @@
<div class="form-horizontal" style="margin-top: 15px;"> <div class="form-horizontal" style="margin-top: 15px;">
<div id="show-existing-movies-toggle"> <div id="show-existing-movies-toggle">
<div class="form-group" style="margin-bottom: 0px;"> <div class="form-group" style="margin-bottom: 0px;">
<label class="col-sm-3 control-label">Display Existing Movies</label> <label class="col-sm-3 control-label">Display existing movies</label>
<div class="col-sm-8"> <div class="col-sm-8">
<div class="input-group"> <div class="input-group">
<label class="checkbox toggle well"> <label class="checkbox toggle well">
<input class="x-show-existing" type="checkbox" checked="checked" name="showExisting"/> <input class="x-show-existing" type="checkbox" checked="checked" name="showExisting">
<p> <p>
<span>Yes</span> <span>Yes</span>
<span>No</span> <span>No</span>
</p> </p>
<div class="btn btn-primary slide-button"></div>
<div class="btn btn-primary slide-button"/>
</label> </label>
<span class="help-inline-checkbox"> <span class="help-inline-checkbox">
<i class="icon-sonarr-form-info" title="Should Radarr display movies already in your collection?"/> <i class="icon-sonarr-form-info" title="Should Radarr display movies already in your collection?"></i>
</span> </span>
</div> </div>
</div> </div>

@ -3,7 +3,8 @@
<div class="col-md-12"> <div class="col-md-12">
{{folder.path}} {{folder.path}}
</div> </div>
</div>{{/if}} </div>
{{/if}}
<div class="x-discover-before"> <div class="x-discover-before">
<ul class="nav nav-tabs nav-justified settings-tabs"> <ul class="nav nav-tabs nav-justified settings-tabs">
@ -18,26 +19,25 @@
</ul> </ul>
</li> </li>
</ul> </ul>
<h2 class="x-discover-header"> <h2 class="x-discover-header">Recommendations by The Movie Database based on your library:</h2>
Recommendations by The Movie Database based on your library:
</h2>
</div> </div>
<div class="x-search-bar"> <div class="x-search-bar">
<div class="input-group input-group-lg add-movies-search"> <div class="input-group input-group-lg add-movies-search">
<span class="input-group-addon"><i class="icon-sonarr-search"/></span> <span class="input-group-addon">
<i class="icon-sonarr-search" title="Search for movie."></i>
</span>
{{#if folder}} {{#if folder}}
<input type="text" class="form-control x-movies-search" value="{{folder.name}}"> <input type="text" class="form-control x-movies-search" value="{{folder.name}}">
{{else}} {{else}}
<input type="text" class="form-control x-movies-search" placeholder="Start typing the name of the movie you want to add ..."> <input type="text" class="form-control x-movies-search" placeholder="Start typing the name of the movie you want to add&hellip;">
{{/if}} {{/if}}
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div id="search-result" class="result-list col-md-12"/> <div id="search-result" class="result-list col-md-12"></div>
</div> </div>
<div class="btn btn-block text-center new-movies-loadmore x-load-more" style="display: none;"> <div class="btn btn-block text-center new-movies-loadmore x-load-more hidden">
<i class="icon-sonarr-load-more"/> <i class="icon-sonarr-load-more" aria-hidden="true"></i>
more more
</div> </div>

@ -85,7 +85,7 @@ module.exports = Marionette.Layout.extend({
}, },
{ {
name : 'tmdbId', name : 'tmdbId',
label : 'Tmdb Id', label : 'TMDb Id',
cell : TmdbIdCell, cell : TmdbIdCell,
cellValue : 'this', cellValue : 'this',
sortable: false sortable: false

@ -1,20 +1,17 @@
<div id="x-toolbar"/> <div id="x-toolbar"></div>
{{> PageSizePartial }} {{> PageSizePartial }}
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<span><b>Disabled movies are possible duplicates. If the match is incorrect, update the Tmdb Id cell to import the proper movie.</b><span> <strong>Disabled movies are possible duplicates. If the match is incorrect, update the TMDb ID cell to import the proper movie.</strong>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div id="x-movies-bulk" class="queue table-responsive"/> <div id="x-movies-bulk" class="queue table-responsive"></div>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div id="x-movies-bulk-pager"/> <div id="x-movies-bulk-pager"></div>
</div> </div>
</div> </div>

@ -1,2 +1,9 @@
{{path}}<br> {{path}}
<span title="{{#if movieFile.relativePath}}&nbsp;{{movieFile.relativePath}}{{/if}}" class="hint" style="font-size: 12px;">{{#if movieFile.relativePath}}&nbsp;{{movieFile.relativePath}}{{else}}&nbsp;Movie File Not Found{{/if}}</span> <br>
<span title="{{#if movieFile.relativePath}}&nbsp;{{movieFile.relativePath}}{{/if}}" class="hint small">
{{#if movieFile.relativePath}}
&nbsp;{{movieFile.relativePath}}
{{else}}
&nbsp;Movie file not found
{{/if}}
</span>

@ -1,5 +1,5 @@
{{#if_gt proper compare="1"}} {{#if_gt proper compare="1"}}
<span class="badge badge-info" title="PROPER">{{movieFile.quality.quality.name}}</span> <span class="badge badge-info" title="Proper">{{movieFile.quality.quality.name}}</span>
{{else}} {{else}}
<span class="badge" title="{{#if movieFile.quality.hardcodedSubs}}Warning: {{movieFile.quality.hardcodedSubs}}{{/if}}">{{movieFile.quality.quality.name}}</span> <span class="badge" title="{{#if movieFile.quality.hardcodedSubs}}Warning: {{movieFile.quality.hardcodedSubs}}{{/if}}">{{movieFile.quality.quality.name}}</span>
{{/if_gt}} {{/if_gt}}

@ -1,6 +1,3 @@
<div class="text-center col-md-12"> <div class="text-center col-md-12">
<h3> <h3>No movies left to discover. Come back at another time</h3>
No movies left to discover. Come back at another time :)
</h3>
</div> </div>

@ -1,3 +1,3 @@
{{#each this}} {{#each this}}
<li value="{{id}}" class="clickable discoverable-list-item">{{name}}</option> <option value="{{id}}" class="clickable discoverable-list-item">{{name}}</option>
{{/each}} {{/each}}

@ -1,3 +1,3 @@
<div class="text-center hint col-md-12"> <div class="text-center hint col-md-12">
<span>You can also search by imdbid using the imdb: prefixes.</span> <p><strong>Hint:</strong> You can also search by IMDb ID using the imdb: prefix. e.g. imdb:tt0829482</p>
</div> </div>

@ -1,7 +1,5 @@
<div class="text-center col-md-12"> <div class="text-center col-md-12">
<h3> <p class="lead">There was an error searching for '{{term}}'.</p>
There was an error searching for '{{term}}'.
</h3>
If the movie title contains non-alphanumeric characters try removing them, otherwise try your search again later. <p>If the movie title contains non-alphanumeric characters try removing them, otherwise try your search again later.</p>
</div> </div>

@ -1,5 +1,5 @@
<div class="x-existing-folders"> <div class="x-existing-folders">
<div class="loading-folders x-loading-folders"> <div class="loading-folders x-loading-folders">
Loading search results from TheTVDB for your movies, this may take a few minutes. Loading search results from TMDb for your movies, this may take a few minutes.
</div> </div>
</div> </div>

@ -1,4 +1,3 @@
<div class="x-list"> <div class="x-list">
<div class="x-loading-list"> <div class="x-loading-list"></div>
</div>
</div> </div>

@ -185,7 +185,7 @@ module.exports = Marionette.Layout.extend({
this.ui.importSelected.addClass('disabled'); this.ui.importSelected.addClass('disabled');
Messenger.show({ Messenger.show({
message: "Importing {0} movies. Don't close this browser window until it has finished".format(selected.length), message: "Importing {0} movies. Don't close this browser window until it has finished.".format(selected.length),
hideOnNavigate: false, hideOnNavigate: false,
hideAfter: 30, hideAfter: 30,
type: "error" type: "error"

@ -1,18 +1,20 @@
<div class="x-search-bar"> <div class="x-search-bar">
<div class="form-group" style="margin-bottom: 0px;"> <div class="form-group" style="margin-bottom: 0px;">
<label class="col-sm-1 control-label">List</label> <label class="col-sm-1 control-label">List</label>
<div class="col-sm-8"> <div class="col-sm-8">
{{> ListSelectionPartial lists}} {{> ListSelectionPartial lists}}
</div> </div>
<div class="col-sm-1"> <div class="col-sm-1">
<button class="btn btn-info x-fetch-list">Fetch List</button> <button class="btn btn-info x-fetch-list">Fetch list</button>
</div> </div>
<div class="col-sm-2"> <div class="col-sm-2">
<button class="btn btn-success x-import-selected"><i class="icon-sonarr-add"></i> Import Selected</button> <button class="btn btn-success x-import-selected">
<i class="icon-sonarr-add" aria-hidden="true"></i>
Import selected
</button>
</div> </div>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div id="fetch-result" class="result-list col-md-12"/> <div id="fetch-result" class="result-list col-md-12"></div>
</div> </div>

@ -11,9 +11,7 @@ require('jquery.dotdotdot');
var view = Marionette.ItemView.extend({ var view = Marionette.ItemView.extend({
template : 'AddMovies/SearchResultViewTemplate', template : 'AddMovies/SearchResultViewTemplate'
}); });

@ -0,0 +1,10 @@
<dl class="minimumavailability-tooltip-contents">
<dt>Announced</dt>
<dd>Consider the movie available after it has been announced.</dd>
<dt>In cinemas</dt>
<dd>Consider the movie available once it is in cinemas/theaters.</dd>
<dt>Physical/web</dt>
<dd>Consider the movie available after physical/web release.</dd>
<dt>PreDB</dt>
<dd>Consider the movie available if PreDB contains at least one entry.</dd>
</dl>

@ -1,10 +0,0 @@
<dl class="minimumavailability-tooltip-contents">
<dt>Announced</dt>
<dd>Consider the movie available after it has been announced</dd>
<dt>In Cinemas</dt>
<dd>Consider the movie available once it is In Cinemas</dd>
<dt>Physical/Web</dt>
<dd>Consider the movie available after Physical/Web release</dd>
<dt>PreDB</dt>
<dd>Consider the movie available if preDB contains at least one entry</dd>
</dl>

@ -1,6 +1,6 @@
<dl class="monitor-tooltip-contents"> <dl class="monitor-tooltip-contents">
<dt>Yes</dt> <dt>Yes</dt>
<dd>Monitor for new releases</dd> <dd>Monitor for new releases.</dd>
<dt>No</dt> <dt>No</dt>
<dd>Do not monitor for new releases</dd> <dd>Do not monitor for new releases.</dd>
</dl> </dl>

@ -1,7 +1,4 @@
<div class="text-center col-md-12"> <div class="text-center col-md-12">
<h3> <h3>Sorry. We couldn't find any movies matching '{{term}}'</h3>
Sorry. We couldn't find any movies matching '{{term}}'
</h3>
<a href="https://github.com/Radarr/Radarr/wiki/FAQ#why-cant-i-add-a-new-movie-to-radarr-its-on-tmdb">Why can't I find my movie?</a> <a href="https://github.com/Radarr/Radarr/wiki/FAQ#why-cant-i-add-a-new-movie-to-radarr-its-on-tmdb">Why can't I find my movie?</a>
</div> </div>

@ -1,12 +1,8 @@
<table class="table table-hover"> <table class="table table-hover">
<thead> <thead>
<tr> <tr>
<th class="col-md-10 "> <th class="col-md-10">Path</th>
Path <th class="col-md-3">Free space</th>
</th>
<th class="col-md-3">
Free Space
</th>
</tr> </tr>
</thead> </thead>
<tbody class="x-root-folders"></tbody> <tbody class="x-root-folders"></tbody>

@ -5,5 +5,5 @@
<span>{{Bytes freeSpace}}</span> <span>{{Bytes freeSpace}}</span>
</td> </td>
<td class="col-md-1"> <td class="col-md-1">
<i class="icon-sonarr-delete x-delete"></i> <i class="icon-sonarr-delete x-delete" title="Delete folder path."></i>
</td> </td>

@ -1,38 +1,41 @@
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <button type="button" class="close" data-dismiss="modal" aria-label="close">&times;</button>
<h3>Select Folder</h3> <h3>Select folder</h3>
</div> </div>
<div class="modal-body root-folders-modal"> <div class="modal-body root-folders-modal">
<div class="validation-errors"></div> <div class="validation-errors"></div>
<div class="alert alert-info">Enter the path that contains some or all of your movies, you will be able to choose which movies you want to import<button type="button" class="close" data-dismiss="alert">×</button></div> <div class="alert alert-info">
Enter the path that contains some or all of your movies, you will be able to choose which movies you want to import.
<button type="button" class="close" data-dismiss="alert" aria-label="close">&times;</button>
</div>
<div class="row"> <div class="row">
<div class="form-group"> <div class="form-group">
<div class="col-md-12"> <div class="col-md-12">
<div class="input-group"> <div class="input-group">
<span class="input-group-addon">&nbsp;<i class="icon-sonarr-folder-open"></i></span> <span class="input-group-addon">
<input class="form-control x-path" type="text" validation-name="path" placeholder="Enter path to folder that contains your movies"> <i class="icon-sonarr-folder-open" title="Browse folder path."></i>
<span class="input-group-btn"><button class="btn btn-success x-add"><i class="icon-sonarr-ok"/></button></span> </span>
<input class="form-control x-path" type="text" validation-name="path" placeholder="Enter the path to the folder that contains your movies.">
<span class="input-group-btn">
<button class="btn btn-success x-add">
<i class="icon-sonarr-ok" title="Add folder path."></i>
</button>
</span>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="row root-folders"> <div class="row root-folders">
<div class="col-md-12"> <div class="col-md-12">
{{#if items}} {{#if items}}
<h4>Recent Folders</h4> <h4>Recent folders</h4>
{{/if}} {{/if}}
<div id="current-dirs" class="root-folders-list"></div> <div id="current-dirs" class="root-folders-list"></div>
</div> </div>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button class="btn" data-dismiss="modal">Close</button> <button class="btn" data-dismiss="modal">Close</button>
</div> </div>
</div> </div>

@ -4,7 +4,7 @@
<option value="{{id}}">{{path}}</option> <option value="{{id}}">{{path}}</option>
{{/each}} {{/each}}
{{else}} {{else}}
<option value="">Select Path</option> <option value="">Select path</option>
{{/if}} {{/if}}
<option value="addNew">Add a different path</option> <option value="addNew">Add a different path</option>
</select> </select>

@ -91,7 +91,7 @@ var view = Marionette.ItemView.extend({
content : content, content : content,
html : true, html : true,
trigger : 'hover', trigger : 'hover',
title : 'Movie Monitoring Options', title : 'Movie monitoring options',
placement : 'right', placement : 'right',
container : this.$el container : this.$el
}); });
@ -103,7 +103,7 @@ var view = Marionette.ItemView.extend({
content : content1, content : content1,
html :true, html :true,
trigger : 'hover', trigger : 'hover',
title : 'When to Consider a Movie Available', title : 'When to consider a movie available',
placement : 'right', placement : 'right',
container : this.$el container : this.$el
}); });

@ -14,30 +14,31 @@
<div class="col-md-12"> <div class="col-md-12">
<h2 class="movies-title"> <h2 class="movies-title">
{{titleWithYear}} {{titleWithYear}}
<span class="labels"> <span class="labels">
<span class="label label-default">{{network}}</span> <span class="label label-default">{{network}}</span>
{{#if_eq status compare="announced"}} {{#if_eq status compare="announced"}}
<span class="label label-default">Announced</span> <span class="label label-default">Announced</span>
{{/if_eq}} {{/if_eq}}
{{#if_eq status compare="released"}} {{#if_eq status compare="released"}}
<span class="label label-success">Released</span> <span class="label label-success">Released</span>
{{/if_eq}} {{/if_eq}}
{{#if_eq status compare="inCinemas"}} {{#if_eq status compare="inCinemas"}}
<span class="label label-warning">In Cinemas</span> <span class="label label-warning">In cinemas</span>
{{/if_eq}} {{/if_eq}}
<span class="label label-default" title="{{ratings.votes}} Vote(s)">{{ratings.value}}</span> <span class="label label-default" title="{{ratings.votes}} Vote(s)">{{ratings.value}}</span>
{{#if youTubeTrailerId}} {{#if youTubeTrailerId}}
<span class="label label-info"><a href="{{youTubeTrailerUrl}}" style="color: white;">Trailer</a></span> <a href="{{youTubeTrailerUrl}}" class="label label-info trailer">Trailer</a>
{{/if}} {{/if}}
{{#if physicalRelease}} {{#if physicalRelease}}
<span class="label label-info" title="{{physicalReleaseNote}}">{{inCinemas}}</span> <span class="label label-info" title="{{physicalReleaseNote}}">{{inCinemas}}</span>
{{/if}} {{/if}}
</span> </span>
</h2> </h2>
</div> </div>
</div> </div>
@ -54,80 +55,61 @@
{{> RootFolderSelectionPartial rootFolders}} {{> RootFolderSelectionPartial rootFolders}}
</div> </div>
{{/unless}} {{/unless}}
<div class="form-group col-md-2"> <div class="form-group col-md-2">
<label>Monitor <i class="icon-sonarr-form-info monitor-tooltip x-monitor-tooltip"></i></label> <label>
<i class="icon-sonarr-form-info monitor-tooltip x-monitor-tooltip" aria-hidden="true"></i>
Monitor
</label>
<select class="form-control col-md-2 x-monitor"> <select class="form-control col-md-2 x-monitor">
<option value="all">Yes</option> <option value="all">Yes</option>
<!-- <option value="missing">Missing</option> -->
<option value="none">No</option> <option value="none">No</option>
</select> </select>
</div> </div>
<div class="form-group col-md-2"> <div class="form-group col-md-2">
<label>Min Availability <i class="icon-sonarr-form-info minimumavailability-tooltip x-minimumavailability-tooltip"></i></label> <label>
<i class="icon-sonarr-form-info minimumavailability-tooltip x-minimumavailability-tooltip" aria-hidden="true"></i>
Availability
</label>
<select class="form-control col-md-2 x-minimumavailability"> <select class="form-control col-md-2 x-minimumavailability">
<option value="announced">Announced</option> <option value="announced">Announced</option>
<option value="inCinemas">In Cinemas</option> <option value="inCinemas">In cinemas</option>
<option value="released">Physical/Web</option> <option value="released">Physical/web</option>
<option value="preDB">PreDB</option> <option value="preDB">PreDB</option>
</select> </select>
</div> </div>
<div class="form-group col-md-2"> <div class="form-group col-md-2">
<label>Profile</label> <label>Profile</label>
{{> ProfileSelectionPartial profiles}} {{> ProfileSelectionPartial profiles}}
</div> </div>
{{!--<div class="form-group col-md-2">
<label>Season Folders</label>
<div class="input-group">
<label class="checkbox toggle well">
<input type="checkbox" class="x-season-folder"/>
<p>
<span>Yes</span>
<span>No</span>
</p>
<div class="btn btn-primary slide-button"/>
</label>
</div>
</div>--}}
{{/unless}} {{/unless}}
{{#unless existing}} {{#unless existing}}
{{#if title}} {{#if title}}
<div class="form-group col-md-2"> <div class="form-group col-md-2">
<!--Uncomment if we need to add even more controls to add Movies--> <label class="invisible">Add</label>
<label style="visibility: hidden">Add</label>
<div class="btn-group"> <div class="btn-group">
<button class="btn btn-success add x-add" title="Add"> <button class="btn btn-success add x-add" title="Add this movie to your library.">
<i class="icon-sonarr-add"></i> <i class="icon-sonarr-add" aria-hidden="true"></i>
</button> </button>
<button class="btn btn-success add x-add-search" title="Add and Search for movie"> <button class="btn btn-success add x-add-search" title="Search for this movie after adding it.">
<i class="icon-sonarr-search"></i> <i class="icon-sonarr-search" aria-hidden="true"></i>
</button> </button>
<button class="btn btn-warning ignore x-ignore" title="Ignore this movie, so it does not show up anymore"> <button class="btn btn-warning ignore x-ignore" title="Ignore this movie, so it does not show up anymore.">
<i class="icon-sonarr-ignore"></i> <i class="icon-sonarr-ignore" aria-hidden="true"></i>
</button> </button>
</div> </div>
</div> </div>
{{else}} {{else}}
<label style="visibility: hidden">Add</label> <label class="invisible">Add</label>
<div class="col-md-2" title="Movies require an English title"> <div class="col-md-2" title="Movies require an English title.">
<button class="btn add-movies disabled"> <button class="btn add-movies disabled">Add</button>
Add
</button>
</div> </div>
{{/if}} {{/if}}
{{else}} {{else}}
<label style="visibility: hidden">Add</label> <label class="invisible">Add</label>
<div class="col-md-2 col-md-offset-10"> <div class="col-md-2 col-md-offset-10">
<a class="btn btn-default" href="{{route}}"> <a class="btn btn-default" href="{{route}}">Already exists</a>
Already Exists
</a>
</div> </div>
{{/unless}} {{/unless}}
</div> </div>

@ -1,6 +1,4 @@
<select class="form-control col-md-2 starting-season x-starting-season"> <select class="form-control col-md-2 starting-season x-starting-season">
{{#each this}} {{#each this}}
{{#if_eq seasonNumber compare="0"}} {{#if_eq seasonNumber compare="0"}}
<option value="{{seasonNumber}}">Specials</option> <option value="{{seasonNumber}}">Specials</option>
@ -8,6 +6,5 @@
<option value="{{seasonNumber}}">Season {{seasonNumber}}</option> <option value="{{seasonNumber}}">Season {{seasonNumber}}</option>
{{/if_eq}} {{/if_eq}}
{{/each}} {{/each}}
<option value="5000000">None</option> <option value="5000000">None</option>
</select> </select>

@ -1,4 +1,4 @@
@import "../Shared/Styles/card.less"; @import "../Shared/Styles/card.less";
@import "../Shared/Styles/clickable.less"; @import "../Shared/Styles/clickable.less";
.inline { .inline {
@ -66,6 +66,10 @@
} }
} }
a.trailer {
color : white;
}
.year { .year {
font-style : italic; font-style : italic;
color : #aaaaaa; color : #aaaaaa;

@ -1,50 +1,49 @@
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <button type="button" class="close" data-dismiss="modal" aria-label="close">&times;</button>
<h3>Radarr Calendar feed</h3> <h3>Movies calendar feed</h3>
</div> </div>
<div class="modal-body edit-series-modal"> <div class="modal-body edit-series-modal">
<div class="form-horizontal"> <div class="form-horizontal">
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">Include Unmonitored</label> <label class="col-sm-3 control-label">Include unmonitored</label>
<div class="col-sm-4"> <div class="col-sm-4">
<div class="input-group"> <div class="input-group">
<label class="checkbox toggle well"> <label class="checkbox toggle well">
<input type="checkbox" name="includeUnmonitored" class="form-control x-includeUnmonitored"/> <input type="checkbox" name="includeUnmonitored" class="form-control x-includeUnmonitored">
<p> <p>
<span>Yes</span> <span>Yes</span>
<span>No</span> <span>No</span>
</p> </p>
<div class="btn btn-primary slide-button"></div>
<div class="btn btn-primary slide-button"/>
</label> </label>
</div> </div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">Tags</label> <label class="col-sm-3 control-label">Tags</label>
<div class="col-sm-1 col-sm-push-5 help-inline"> <div class="col-sm-1 col-sm-push-5 help-inline">
<i class="icon-sonarr-form-info" title="One or more tags only show matching series" /> <i class="icon-sonarr-form-info" title="One or more tags only show matching movies."></i>
</div> </div>
<div class="col-sm-5 col-sm-pull-1"> <div class="col-sm-5 col-sm-pull-1">
<input type="text" class="form-control x-tags"> <input type="text" class="form-control x-tags">
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">iCal feed</label> <label class="col-sm-3 control-label">Calendar feed URL</label>
<div class="col-sm-1 col-sm-push-8 help-inline"> <div class="col-sm-1 col-sm-push-8 help-inline">
<i class="icon-sonarr-form-info" title="Copy this url into your clients subscription form or use the subscribe button if your browser support webcal" /> <i class="icon-sonarr-form-info" title="Copy this URL into your clients subscription form or use the subscribe button if your browser supports webcal."></i>
</div> </div>
<div class="col-sm-8 col-sm-pull-1"> <div class="col-sm-8 col-sm-pull-1">
<div class="input-group ical-url"> <div class="input-group ical-url">
<input type="text" class="form-control x-ical-url" readonly="readonly" /> <input type="text" class="form-control x-ical-url" readonly="readonly">
<div class="input-group-btn"> <div class="input-group-btn">
<button class="btn btn-icon-only x-ical-copy"><i class="icon-sonarr-copy"></i></button> <button class="btn btn-icon-only x-ical-copy" title="Copy calendar feed to clipboard.">
<button class="btn btn-icon-only no-router x-ical-webcal" title="Subscribe" target="_blank"><i class="icon-sonarr-calendar-o"></i></button> <i class="icon-sonarr-copy" aria-hidden="true"></i>
</button>
<button class="btn btn-icon-only no-router x-ical-webcal" title="Subscribe" target="_blank">
<i class="icon-sonarr-calendar-o" aria-hidden="true"></i>
</button>
</div> </div>
</div> </div>
</div> </div>

@ -41,7 +41,7 @@ module.exports = Marionette.Layout.extend({
storeState : false, storeState : false,
items : [ items : [
{ {
title : 'Get iCal Link', title : 'Movies calendar link',
icon : 'icon-sonarr-calendar-o', icon : 'icon-sonarr-calendar-o',
callback : this._showiCal, callback : this._showiCal,
ownerContext : this ownerContext : this
@ -58,14 +58,14 @@ module.exports = Marionette.Layout.extend({
{ {
key : 'all', key : 'all',
title : '', title : '',
tooltip : 'All', tooltip : 'All movies',
icon : 'icon-sonarr-all', icon : 'icon-sonarr-all',
callback : this._setCalendarFilter callback : this._setCalendarFilter
}, },
{ {
key : 'monitored', key : 'monitored',
title : '', title : '',
tooltip : 'Monitored Only', tooltip : 'Monitored only',
icon : 'icon-sonarr-monitored', icon : 'icon-sonarr-monitored',
callback : this._setCalendarFilter callback : this._setCalendarFilter
} }

@ -3,19 +3,37 @@
<div class="pull-left"> <div class="pull-left">
<h4>Upcoming</h4> <h4>Upcoming</h4>
</div> </div>
<div id="x-upcoming"/> <div id="x-upcoming"></div>
</div> </div>
<div class="col-md-9 col-xs-12"> <div class="col-md-9 col-xs-12">
<div id="x-toolbar" class="calendar-toolbar"/> <div id="x-toolbar" class="calendar-toolbar"></div>
<div id="x-calendar" class="calendar"/> <div id="x-calendar" class="calendar"></div>
<div class="legend calendar"> <div class="legend calendar">
<ul class='legend-labels'> <ul class='legend-labels'>
<li class="legend-label"><span class="premiere" title="This Movie is still in cinemas and hasn't been released yet. Only poor qualities will be available"></span>In Cinemas</li> <li class="legend-label">
<li class="legend-label"><span class="primary" title="This movie has only been announced yet."></span>Announced</li> <span class="premiere" title="This movie is still in cinemas and hasn't been released yet. Only poor qualities will be available."></span>
<li class="legend-label"><span class="purple" title="Movie is currently downloading"></span>Downloading</li> In cinemas
<li class="legend-label"><span class="danger" title="Movie file has not been found"></span>Missing</li> </li>
<li class="legend-label"><span class="success" title="Movie was downloaded and sorted"></span>Downloaded</li> <li class="legend-label">
<li class="legend-label"><span class="unmonitored" title="Movie is unmonitored"></span>Unmonitored</li> <span class="primary" title="This movie has only been announced."></span>
Announced
</li>
<li class="legend-label">
<span class="purple" title="Movie is currently downloading."></span>
Downloading
</li>
<li class="legend-label">
<span class="danger" title="Movie file has not been found."></span>
Missing
</li>
<li class="legend-label">
<span class="success" title="Movie was downloaded and sorted."></span>
Downloaded
</li>
<li class="legend-label">
<span class="unmonitored" title="Movie is unmonitored."></span>
Unmonitored
</li>
</ul> </ul>
</div> </div>
</div> </div>

@ -69,11 +69,11 @@ module.exports = Marionette.ItemView.extend({
} }
else if (status === 'failed') { else if (status === 'failed') {
this._addStatusIcon(element, 'icon-sonarr-download-failed', 'Download failed: check download client for more details'); this._addStatusIcon(element, 'icon-sonarr-download-failed', 'Download failed: check download client for more details.');
} }
else if (status === 'warning') { else if (status === 'warning') {
this._addStatusIcon(element, 'icon-sonarr-download-warning', 'Download warning: check download client for more details'); this._addStatusIcon(element, 'icon-sonarr-download-warning', 'Download warning: check download client for more details.');
} }
else { else {

@ -8,11 +8,15 @@
<h4>{{title}}</h4> <h4>{{title}}</h4>
</a> </a>
{{/with}} {{/with}}
<p>{{StartTime airDateUtc}} {{#unless_today airDateUtc}}{{ShortDate airDateUtc}}{{/unless_today}}</p> <p>
{{StartTime airDateUtc}} {{#unless_today airDateUtc}}{{ShortDate airDateUtc}}{{/unless_today}}
</p>
<p> <p>
<span class="episode-title x-episode-title"> <span class="episode-title x-episode-title">
{{title}} {{title}}
</span> </span>
<span class="pull-right">{{seasonNumber}}x{{Pad2 episodeNumber}}</span> <span class="pull-right">
{{seasonNumber}}x{{Pad2 episodeNumber}}
</span>
</p> </p>
</div> </div>

@ -36,6 +36,10 @@
font-size : 17.5px; font-size : 17.5px;
} }
.fc-button {
text-transform: capitalize;
}
.fc-state-highlight { .fc-state-highlight {
background : #dbdbdb; background : #dbdbdb;
} }

@ -1,5 +1,5 @@
{{#if_gt proper compare="1"}} {{#if_gt proper compare="1"}}
<span class="badge badge-info" title="PROPER">{{quality.name}}</span> <span class="badge badge-info" title="Proper">{{quality.name}}</span>
{{else}} {{else}}
<span class="badge" title="{{#if hardcodedSubs}}Warning: {{hardcodedSubs}}{{/if}}">{{quality.name}}</span> <span class="badge" title="{{#if hardcodedSubs}}Warning: {{hardcodedSubs}}{{/if}}">{{quality.name}}</span>
{{/if_gt}} {{/if_gt}}

@ -73,10 +73,23 @@
} }
} }
.btn { /* Capitalise various layout elements */
h3, label, legend, select, .btn, table th, dt,
.advanced-settings-toggle span, option,
.legend-label, .nav-tabs a, .popover-title {
text-transform: capitalize; text-transform: capitalize;
} }
.table-responsive { .table-responsive {
overflow-x: visible; overflow-x: visible;
} }
.navbar-nav {
margin-bottom : 20px;
}
.navbar-brand {
@media (min-width: @screen-md-min) and (max-width: @screen-md-max) {
padding : 22px 15px !important;
}
}

@ -12,6 +12,5 @@ a:focus {
} }
body h1, body h2, body h3, body h4, body h5, body h6 { body h1, body h2, body h3, body h4, body h5, body h6 {
text-transform : capitalize;
font-weight : 300; font-weight : 300;
} }

@ -6,6 +6,7 @@
src: local('Open Sans Light'), src: local('Open Sans Light'),
local('OpenSans-Light'), local('OpenSans-Light'),
url('./fonts/opensans-light.eot?#iefix') format('embedded-opentype'), url('./fonts/opensans-light.eot?#iefix') format('embedded-opentype'),
url('./fonts/opensans-light.woff2') format('woff2'),
url('./fonts/opensans-light.woff') format('woff'), url('./fonts/opensans-light.woff') format('woff'),
url('./fonts/opensans-light.ttf') format('truetype'); url('./fonts/opensans-light.ttf') format('truetype');
} }
@ -18,6 +19,7 @@
src: local('Open Sans'), src: local('Open Sans'),
local('OpenSans'), local('OpenSans'),
url('./fonts/opensans-regular.eot?#iefix') format('embedded-opentype'), url('./fonts/opensans-regular.eot?#iefix') format('embedded-opentype'),
url('./fonts/opensans-regular.woff2') format('woff2'),
url('./fonts/opensans-regular.woff') format('woff'), url('./fonts/opensans-regular.woff') format('woff'),
url('./fonts/opensans-regular.ttf') format('truetype') url('./fonts/opensans-regular.ttf') format('truetype')
} }
@ -30,6 +32,7 @@
src: local('Open Sans SemiBold'), src: local('Open Sans SemiBold'),
local('OpenSans-SemiBold'), local('OpenSans-SemiBold'),
url('./fonts/opensans-semibold.eot?#iefix') format('embedded-opentype'), url('./fonts/opensans-semibold.eot?#iefix') format('embedded-opentype'),
url('./fonts/opensans-semibold.woff2') format('woff2'),
url('./fonts/opensans-semibold.woff') format('woff'), url('./fonts/opensans-semibold.woff') format('woff'),
url('./fonts/opensans-semibold.ttf') format('truetype') url('./fonts/opensans-semibold.ttf') format('truetype')
} }
@ -39,9 +42,9 @@
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
src: url('./fonts/ubuntumono-regular.eot'); src: url('./fonts/ubuntumono-regular.eot');
src: local('Open Sans'), src: local('Ubuntu Mono'),
local('OpenSans'),
url('./fonts/ubuntumono-regular.eot?#iefix') format('embedded-opentype'), url('./fonts/ubuntumono-regular.eot?#iefix') format('embedded-opentype'),
url('./fonts/ubuntumono-regular.woff2') format('woff2'),
url('./fonts/ubuntumono-regular.woff') format('woff'), url('./fonts/ubuntumono-regular.woff') format('woff'),
url('./fonts/ubuntumono-regular.ttf') format('truetype') url('./fonts/ubuntumono-regular.ttf') format('truetype')
} }

@ -1,4 +1,4 @@
@import "prefixer"; @import "prefixer";
@import "variables"; @import "variables";
@grid-float-breakpoint: @screen-xs-min; @grid-float-breakpoint: @screen-xs-min;

@ -1,4 +1,4 @@
@import "Bootstrap/variables"; @import "Bootstrap/variables";
@import "Bootstrap/mixins"; @import "Bootstrap/mixins";
@import "Bootstrap/type"; @import "Bootstrap/type";
@import "font"; @import "font";
@ -20,7 +20,6 @@
@import "../Shared/FileBrowser/filebrowser"; @import "../Shared/FileBrowser/filebrowser";
@import "badges"; @import "badges";
@import "../ManualImport/manualimport"; @import "../ManualImport/manualimport";
@import "../SeasonPass/seasonpass";
.main-region { .main-region {
@media (min-width : @screen-lg-min) { @media (min-width : @screen-lg-min) {
@ -86,7 +85,7 @@
position : fixed; position : fixed;
z-index : 9999; z-index : 9999;
bottom : 30px; bottom : 30px;
right : 0px; right : 0;
display : none; display : none;
font-size : 56px; font-size : 56px;
color : gray; color : gray;

@ -1,15 +1,19 @@
<div class="form-group {{#if advanced}}advanced-setting{{/if}}"> <div class="form-group {{#if advanced}}advanced-setting{{/if}}">
<label class="col-sm-3 control-label">{{label}}</label> <label class="col-sm-3 control-label">{{label}}</label>
<div class="col-sm-5"> <div class="col-sm-5">
<div class="input-group"> <div class="input-group">
<input type="text" name="fields.{{order}}.value" validation-name="{{name}}" spellcheck="false" class="form-control x-captcha" readonly placeholder="(optional)" /> <input type="text" name="fields.{{order}}.value"
<span class="input-group-btn"><button class="btn btn-primary x-captcha-refresh" title="Refresh CAPTCHA Token"><i class="icon-sonarr-refresh" /></button></span> validation-name="{{name}}" spellcheck="false"
class="form-control x-captcha" readonly placeholder="(optional)">
<span class="input-group-btn">
<button class="btn btn-primary x-captcha-refresh" title="Refresh CAPTCHA Token.">
<i class="icon-sonarr-refresh" aria-hidden="true"></i>
</button>
</span>
</div> </div>
</div> </div>
<span class="col-sm-1 help-inline"> <span class="col-sm-1 help-inline">
<i class="icon-sonarr-form-warning" title="Expires periodically and will need to be refreshed."/> <i class="icon-sonarr-form-warning" title="Expires periodically and will need to be refreshed."></i>
<i class="icon-sonarr-form-warning" title="Refreshing the CAPTCHA Token will embed a temporary Google reCaptcha widget on this page."/> <i class="icon-sonarr-form-warning" title="Refreshing the reCAPTCHA token will temporarily embed a Google reCAPTCHA widget on this page."></i>
</span> </span>
</div> </div>

@ -1,21 +1,18 @@
<div class="form-group {{#if advanced}}advanced-setting{{/if}}"> <div class="form-group {{#if advanced}}advanced-setting{{/if}}">
<label class="col-sm-3 control-label">{{label}}</label> <label class="col-sm-3 control-label">{{label}}</label>
<div class="col-sm-5"> <div class="col-sm-5">
<div class="input-group"> <div class="input-group">
<label class="checkbox toggle well"> <label class="checkbox toggle well">
<input type="checkbox" name="fields.{{order}}.value"/> <input type="checkbox" name="fields.{{order}}.value">
<p> <p>
<span>Yes</span> <span>Yes</span>
<span>No</span> <span>No</span>
</p> </p>
<div class="btn btn-primary slide-button"></div>
<div class="btn btn-primary slide-button"/>
</label> </label>
{{#if helpText}} {{#if helpText}}
<span class="help-inline-checkbox"> <span class="help-inline-checkbox">
<i class="icon-sonarr-form-info" title="{{helpText}}"/> <i class="icon-sonarr-form-info" title="{{helpText}}"></i>
</span> </span>
{{/if}} {{/if}}
</div> </div>

@ -1,8 +1,10 @@
<span class="col-sm-1 help-inline"> <span class="col-sm-1 help-inline">
{{#if helpText}} {{#if helpText}}
<i class="icon-sonarr-form-info" title="{{helpText}}"/> <i class="icon-sonarr-form-info" title="{{helpText}}"></i>
{{/if}} {{/if}}
{{#if helpLink}} {{#if helpLink}}
<a href="{{helpLink}}" class="help-link"><i class="icon-sonarr-form-info-link"/></a> <a href="{{helpLink}}" class="help-link">
<i class="icon-sonarr-form-info-link"></i>
</a>
{{/if}} {{/if}}
</span> </span>

@ -1 +1 @@
<input type="hidden" name="fields.{{order}}.value" validation-name="{{name}}" spellcheck="false"/> <input type="hidden" name="fields.{{order}}.value" validation-name="{{name}}" spellcheck="false">

@ -1,8 +1,7 @@
<div class="form-group {{#if advanced}}advanced-setting{{/if}}"> <div class="form-group {{#if advanced}}advanced-setting{{/if}}">
<label class="col-sm-3 control-label">{{label}}</label> <label class="col-sm-3 control-label">{{label}}</label>
<div class="col-sm-5"> <div class="col-sm-5">
<input type="password" name="fields.{{order}}.value" validation-name="{{name}}" autocomplete="new-password" class="form-control"/> <input type="password" name="fields.{{order}}.value" validation-name="{{name}}" autocomplete="new-password" class="form-control">
</div> </div>
{{> FormHelpPartial}} {{> FormHelpPartial}}
</div> </div>

@ -1,8 +1,7 @@
<div class="form-group {{#if advanced}}advanced-setting{{/if}}"> <div class="form-group {{#if advanced}}advanced-setting{{/if}}">
<label class="col-sm-3 control-label">{{label}}</label> <label class="col-sm-3 control-label">{{label}}</label>
<div class="col-sm-5"> <div class="col-sm-5">
<input type="text" name="fields.{{order}}.value" validation-name="{{name}}" class="form-control x-path {{#if_eq type compare="filepath"}}x-filepath{{/if_eq}}"/> <input type="text" name="fields.{{order}}.value" validation-name="{{name}}" class="form-control x-path {{#if_eq type compare="filepath"}}x-filepath{{/if_eq}}">
</div> </div>
{{> FormHelpPartial}} {{> FormHelpPartial}}
</div> </div>

@ -1,6 +1,5 @@
<div class="form-group {{#if advanced}}advanced-setting{{/if}}"> <div class="form-group {{#if advanced}}advanced-setting{{/if}}">
<label class="col-sm-3 control-label">{{label}}</label> <label class="col-sm-3 control-label">{{label}}</label>
<div class="col-sm-5"> <div class="col-sm-5">
<select name="fields.{{order}}.value" class="form-control"> <select name="fields.{{order}}.value" class="form-control">
{{#each selectOptions}} {{#each selectOptions}}

@ -1,9 +1,7 @@
<div class="form-group {{#if advanced}}advanced-setting{{/if}}"> <div class="form-group {{#if advanced}}advanced-setting{{/if}}">
<label class="col-sm-3 control-label">{{label}}</label> <label class="col-sm-3 control-label">{{label}}</label>
<div class="col-sm-5"> <div class="col-sm-5">
<input type="text" name="fields.{{order}}.value" validation-name="{{name}}" tag-source="{{json selectOptions}}" class="form-control x-form-tag"/> <input type="text" name="fields.{{order}}.value" validation-name="{{name}}" tag-source="{{json selectOptions}}" class="form-control x-form-tag">
</div> </div>
{{> FormHelpPartial}} {{> FormHelpPartial}}
</div> </div>

@ -1,8 +1,7 @@
<div class="form-group {{#if advanced}}advanced-setting{{/if}}"> <div class="form-group {{#if advanced}}advanced-setting{{/if}}">
<label class="col-sm-3 control-label">{{label}}</label> <label class="col-sm-3 control-label">{{label}}</label>
<div class="col-sm-5"> <div class="col-sm-5">
<input type="text" name="fields.{{order}}.value" validation-name="{{name}}" spellcheck="false" class="form-control"/> <input type="text" name="fields.{{order}}.value" validation-name="{{name}}" spellcheck="false" class="form-control">
</div> </div>
{{> FormHelpPartial}} {{> FormHelpPartial}}
</div> </div>

@ -1,8 +1,7 @@
<div class="form-group {{#if advanced}}advanced-setting{{/if}}"> <div class="form-group {{#if advanced}}advanced-setting{{/if}}">
<label class="col-sm-3 control-label">{{label}}</label> <label class="col-sm-3 control-label">{{label}}</label>
<div class="col-sm-5"> <div class="col-sm-5">
<input type="url" name="fields.{{order}}.value" validation-name="{{name}}" spellcheck="false" class="form-control"/> <input type="url" name="fields.{{order}}.value" validation-name="{{name}}" spellcheck="false" class="form-control">
</div> </div>
{{> FormHelpPartial}} {{> FormHelpPartial}}
</div> </div>

@ -1,22 +1,22 @@
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <button type="button" class="close" data-dismiss="modal" aria-label="close">&times;</button>
<h3>Keyboard Shortcuts</h3> <h3>Keyboard shortcuts</h3>
</div> </div>
<div class="modal-body hotkeys-modal"> <div class="modal-body hotkeys-modal">
<div class="row hotkey-group"> <div class="row hotkey-group">
<div class="col-md-12"> <div class="col-md-12">
<div class="row"> <div class="row">
<div class="col-md-5 col-md-offset-1"> <div class="col-md-5 col-md-offset-1">
<h3>Focus Search Box</h3> <h3>Focus search box</h3>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
<kbd class="hotkey">t</kbd> <kbd class="hotkey">T</kbd>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-11 col-md-offset-1"> <div class="col-md-11 col-md-offset-1">
Pressing 't' puts the cursor in the search box below the navigation links Pressing 'T' puts the cursor in the search box below the navigation links
</div> </div>
</div> </div>
</div> </div>
@ -25,15 +25,15 @@
<div class="col-md-12"> <div class="col-md-12">
<div class="row"> <div class="row">
<div class="col-md-5 col-md-offset-1"> <div class="col-md-5 col-md-offset-1">
<h3>Save Settings</h3> <h3>Save settings</h3>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
<kbd class="hotkey">ctrl + s</kbd> <kbd class="hotkey">Ctrl + S</kbd>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-11 col-md-offset-1"> <div class="col-md-11 col-md-offset-1">
Pressing ctrl + 's' saves your settings (only in settings) Pressing Ctrl + 'S' saves your settings (only available on the settings page)
</div> </div>
</div> </div>
</div> </div>

@ -8,13 +8,12 @@
</div> </div>
<div class="recent-folders"> <div class="recent-folders">
{{#if recentFolders}} {{#if recentFolders}}
<h4>Recent Folders</h4> <h4>Recent folders</h4>
<table class="table table-hover"> <table class="table table-hover">
<thead> <thead>
<tr> <tr>
<th>Path</th> <th>Path</th>
<th>Last Used</th> <th>Last used</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -31,12 +30,18 @@
<div class="buttons"> <div class="buttons">
<div class="row"> <div class="row">
<div class="col-md-4 col-md-offset-4"> <div class="col-md-4 col-md-offset-4">
<button class="btn btn-primary btn-lg btn-block x-automatic-import x-button"><i class="icon-sonarr-search-automatic"></i> Import File(s) Automatically</button> <button class="btn btn-primary btn-lg btn-block x-automatic-import x-button">
<i class="icon-sonarr-search-automatic" aria-hidden="true"></i>
Import file(s) automatically
</button>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-4 col-md-offset-4"> <div class="col-md-4 col-md-offset-4">
<button class="btn btn-primary btn-lg btn-block x-manual-import x-button"><i class="icon-sonarr-search-manual"></i> Manual Import</button> <button class="btn btn-primary btn-lg btn-block x-manual-import x-button">
<i class="icon-sonarr-search-manual" aria-hidden="true"></i>
Manual import
</button>
</div> </div>
</div> </div>
</div> </div>

@ -1,12 +1,10 @@
<div class="modal-content"> <div class="modal-content">
<div class="manual-import-modal"> <div class="manual-import-modal">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <button type="button" class="close" data-dismiss="modal" aria-label="close">&times;</button>
<h3> <h3>
Manual Import - {{#if title}}{{title}}{{else}}Select Folder{{/if}} Manual import - {{#if title}}{{title}}{{else}}<span>Select folder</span>{{/if}}
</h3> </h3>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="x-workspace"></div> <div class="x-workspace"></div>
@ -15,8 +13,8 @@
<div class="modal-footer"> <div class="modal-footer">
<div class="col-md-2 pull-left"> <div class="col-md-2 pull-left">
<select class="form-control x-importmode"> <select class="form-control x-importmode">
<option value="Move">Move Files</option> <option value="Move">Move files</option>
<option value="Copy">Copy Files</option> <option value="Copy">Copy files</option>
</select> </select>
</div> </div>
<button class="btn btn-default" data-dismiss="modal">Cancel</button> <button class="btn btn-default" data-dismiss="modal">Cancel</button>

@ -1,22 +1,17 @@
<div class="modal-content"> <div class="modal-content">
<div class="manual-import-modal"> <div class="manual-import-modal">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <button type="button" class="close" data-dismiss="modal" aria-label="close">&times;</button>
<h3>Manual import - Select movie</h3>
<h3>
Manual Import - Select Movie
</h3>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div class="form-group"> <div class="form-group">
<input type="text" class="form-control x-filter" placeholder="Filter movies" /> <input type="text" class="form-control x-filter" placeholder="Filter movies">
</div> </div>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-12 x-movie"></div> <div class="col-md-12 x-movie"></div>
</div> </div>

@ -1,19 +1,15 @@
<div class="modal-content"> <div class="modal-content">
<div class="manual-import-modal"> <div class="manual-import-modal">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <button type="button" class="close" data-dismiss="modal" aria-label="close">&times;</button>
<h3>Manual import - Select quality</h3>
<h3>
Manual Import - Select Quality
</h3>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="x-quality"></div> <div class="x-quality"></div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button class="btn btn-default" data-dismiss="modal">Cancel</button> <button class="btn btn-default" data-dismiss="modal">Cancel</button>
<button class="btn btn-success x-select" data-dismiss="modal">Select Quality</button> <button class="btn btn-success x-select" data-dismiss="modal">Select quality</button>
</div> </div>
</div> </div>
</div> </div>

@ -1,31 +1,27 @@
<div class="form-horizontal"> <div class="form-horizontal">
<div class="form-group"> <div class="form-group">
<label class="col-sm-4 control-label">Quality</label> <label class="col-sm-4 control-label">Quality</label>
<div class="col-sm-4"> <div class="col-sm-4">
<select class="form-control x-select-quality"> <select class="form-control x-select-quality">
<option value="-1">Select Quality</option> <option value="-1">Select quality</option>
{{#each qualities}} {{#each qualities}}
<option value="{{id}}">{{name}}</option> <option value="{{id}}">{{name}}</option>
{{/each}} {{/each}}
</select> </select>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-4 control-label">Proper</label> <label class="col-sm-4 control-label">Proper</label>
<div class="col-sm-8"> <div class="col-sm-8">
<div class="input-group"> <div class="input-group">
<label class="checkbox toggle well"> <label class="checkbox toggle well">
<input type="checkbox" class="x-proper"/> <input type="checkbox" class="x-proper">
<p> <p>
<span>Yes</span> <span>Yes</span>
<span>No</span> <span>No</span>
</p> </p>
<div class="btn btn-primary slide-button"></div>
<div class="btn btn-primary slide-button"/>
</label> </label>
</div> </div>
</div> </div>

@ -1,5 +1,4 @@
<dl class="dl-horizontal"> <dl class="dl-horizontal">
<dt>Path:</dt> <dt>Path:</dt>
<dd>{{file}}</dd> <dd>{{file}}</dd>

@ -1,10 +1,9 @@
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <button type="button" class="close" data-dismiss="modal" aria-label="close">&times;</button>
<h3>Delete {{title}}</h3> <h3>Delete {{title}}</h3>
</div> </div>
<div class="modal-body delete-series-modal"> <div class="modal-body delete-series-modal">
<div class="row"> <div class="row">
<div class="col-sm-3 hidden-xs"> <div class="col-sm-3 hidden-xs">
{{poster}} {{poster}}
@ -12,25 +11,21 @@
<div class="col-sm-9"> <div class="col-sm-9">
<div class="form-horizontal"> <div class="form-horizontal">
<h3 class="path">{{path}}</h3> <h3 class="path">{{path}}</h3>
<div class="form-group"> <div class="form-group">
<label class="col-sm-4 control-label">Delete all files</label> <label class="col-sm-4 control-label">Delete all files</label>
<div class="col-sm-8"> <div class="col-sm-8">
<div class="input-group"> <div class="input-group">
<label class="checkbox toggle well"> <label class="checkbox toggle well">
<input type="checkbox" class="x-delete-files"/> <input type="checkbox" class="x-delete-files">
<p> <p>
<span>Yes</span> <span>Yes</span>
<span>No</span> <span>No</span>
</p> </p>
<div class="btn slide-button btn-danger"></div>
<div class="btn slide-button btn-danger"/>
</label> </label>
<span class="help-inline-checkbox"> <span class="help-inline-checkbox">
<i class="icon-sonarr-form-info" title="Do you want to delete all files from disk?"/> <i class="icon-sonarr-form-info" title="Do you want to delete all files from disk?"></i>
<i class="icon-sonarr-form-warning" title="This option is irreversible, use with extreme caution"/> <i class="icon-sonarr-form-warning" title="This option is irreversible, use with extreme caution!"></i>
</span> </span>
</div> </div>
</div> </div>
@ -38,25 +33,21 @@
<div class="col-md-offset-1 col-md-5 delete-files-info x-delete-files-info"> <div class="col-md-offset-1 col-md-5 delete-files-info x-delete-files-info">
{{#if hasFile}}1{{else}}0{{/if}} movie file(s) will be deleted {{#if hasFile}}1{{else}}0{{/if}} movie file(s) will be deleted
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-4 control-label">Exclude movie from Auto List Import?</label> <label class="col-sm-4 control-label">Exclude movie from auto list import?</label>
<div class="col-sm-8"> <div class="col-sm-8">
<div class="input-group"> <div class="input-group">
<label class="checkbox toggle well"> <label class="checkbox toggle well">
<input type="checkbox" class="x-add-exclusion"/> <input type="checkbox" class="x-add-exclusion">
<p> <p>
<span>Yes</span> <span>Yes</span>
<span>No</span> <span>No</span>
</p> </p>
<div class="btn slide-button btn-danger"></div>
<div class="btn slide-button btn-danger"/>
</label> </label>
<span class="help-inline-checkbox"> <span class="help-inline-checkbox">
<i class="icon-sonarr-form-info" title="Do you want to prevent this movie from being readded during Automatic List syncing?"/> <i class="icon-sonarr-form-info" title="Do you want to prevent this movie from being read during automatic list syncing?"></i>
<i class="icon-sonarr-form-info" title="Movies can be removed from the exclusions list via Lists tab in Settings"/> <i class="icon-sonarr-form-info" title="Movies can be removed from the exclusions list via the lists tab in settings."></i>
</span> </span>
</div> </div>
</div> </div>
@ -67,7 +58,9 @@
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<span class="indicator x-indicator"><i class="icon-sonarr-spinner fa-spin"></i></span> <span class="indicator x-indicator">
<i class="icon-sonarr-spinner fa-spin" aria-hidden="true"></i>
</span>
<button class="btn" data-dismiss="modal">Cancel</button> <button class="btn" data-dismiss="modal">Cancel</button>
<button class="btn btn-danger x-confirm-delete">Delete</button> <button class="btn btn-danger x-confirm-delete">Delete</button>
</div> </div>

@ -27,9 +27,11 @@
<div class="col-md-4"> <div class="col-md-4">
<span class="series-info-links"> <span class="series-info-links">
<a href="{{traktUrl}}" class="label label-info">Trakt</a> <a href="{{traktUrl}}" class="label label-info">Trakt</a>
{{#if website}} {{#if website}}
<a href="{{homepage}}" class="label label-info">Homepage</a> <a href="{{homepage}}" class="label label-info">Homepage</a>
{{/if}} {{/if}}
<a href="{{tmdbUrl}}" class="label label-info">The Movie DB</a> <a href="{{tmdbUrl}}" class="label label-info">The Movie DB</a>
{{#if imdbId}} {{#if imdbId}}

@ -292,7 +292,7 @@ module.exports = Marionette.Layout.extend({
}, },
_manualSearchM : function() { _manualSearchM : function() {
console.warn("Manual Search started"); console.warn("Manual search started");
console.warn(this.model.id); console.warn(this.model.id);
console.warn(this.model); console.warn(this.model);
console.warn(this.episodeCollection); console.warn(this.episodeCollection);

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save