mirror of
https://github.com/Sonarr/Sonarr.git
synced 2024-10-29 23:12:39 +01:00
parent
f45713bff8
commit
aedcd046fc
@ -134,6 +134,12 @@ module.exports = (env) => {
|
|||||||
{
|
{
|
||||||
source: 'frontend/src/Content/robots.txt',
|
source: 'frontend/src/Content/robots.txt',
|
||||||
destination: path.join(distFolder, 'Content/robots.txt')
|
destination: path.join(distFolder, 'Content/robots.txt')
|
||||||
|
},
|
||||||
|
|
||||||
|
// manifest.json and browserconfig.xml
|
||||||
|
{
|
||||||
|
source: 'frontend/src/Content/*.(json|xml)',
|
||||||
|
destination: path.join(distFolder, 'Content')
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<browserconfig>
|
|
||||||
<msapplication>
|
|
||||||
<tile>
|
|
||||||
<square150x150logo src="/Content/Images/Icons/mstile-150x150.png"/>
|
|
||||||
<TileColor>#00ccff</TileColor>
|
|
||||||
</tile>
|
|
||||||
</msapplication>
|
|
||||||
</browserconfig>
|
|
@ -1,19 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Sonarr",
|
|
||||||
"icons": [
|
|
||||||
{
|
|
||||||
"src": "android-chrome-192x192.png",
|
|
||||||
"sizes": "192x192",
|
|
||||||
"type": "image/png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "android-chrome-512x512.png",
|
|
||||||
"sizes": "512x512",
|
|
||||||
"type": "image/png"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"start_url": "../../../../",
|
|
||||||
"theme_color": "#3a3f51",
|
|
||||||
"background_color": "#3a3f51",
|
|
||||||
"display": "standalone"
|
|
||||||
}
|
|
11
frontend/src/Content/browserconfig.xml
Normal file
11
frontend/src/Content/browserconfig.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<browserconfig>
|
||||||
|
<msapplication>
|
||||||
|
<tile>
|
||||||
|
<square150x150logo src="__URL_BASE__/Content/Images/Icons/mstile-150x150.png" />
|
||||||
|
<TileColor>
|
||||||
|
#00ccff
|
||||||
|
</TileColor>
|
||||||
|
</tile>
|
||||||
|
</msapplication>
|
||||||
|
</browserconfig>
|
19
frontend/src/Content/manifest.json
Normal file
19
frontend/src/Content/manifest.json
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"name": "Sonarr",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "android-chrome-192x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "android-chrome-512x512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"start_url": "__URL_BASE__/",
|
||||||
|
"theme_color": "#3a3f51",
|
||||||
|
"background_color": "#3a3f51",
|
||||||
|
"display": "standalone"
|
||||||
|
}
|
@ -33,7 +33,7 @@
|
|||||||
sizes="16x16"
|
sizes="16x16"
|
||||||
href="/Content/Images/Icons/favicon-16x16.png"
|
href="/Content/Images/Icons/favicon-16x16.png"
|
||||||
/>
|
/>
|
||||||
<link rel="manifest" href="/Content/Images/Icons/manifest.json" crossorigin="use-credentials" />
|
<link rel="manifest" href="/Content/manifest.json" crossorigin="use-credentials" />
|
||||||
<link
|
<link
|
||||||
rel="mask-icon"
|
rel="mask-icon"
|
||||||
href="/Content/Images/Icons/safari-pinned-tab.svg"
|
href="/Content/Images/Icons/safari-pinned-tab.svg"
|
||||||
@ -47,7 +47,7 @@
|
|||||||
/>
|
/>
|
||||||
<meta
|
<meta
|
||||||
name="msapplication-config"
|
name="msapplication-config"
|
||||||
content="/Content/Images/Icons/browserconfig.xml"
|
content="/Content/browserconfig.xml"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="/Content/Fonts/fonts.css">
|
<link rel="stylesheet" type="text/css" href="/Content/Fonts/fonts.css">
|
||||||
|
@ -11,8 +11,11 @@
|
|||||||
<!-- Android/Apple Phone -->
|
<!-- Android/Apple Phone -->
|
||||||
<meta name="mobile-web-app-capable" content="yes" />
|
<meta name="mobile-web-app-capable" content="yes" />
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
<meta
|
||||||
<meta name="format-detection" content="telephone=no">
|
name="apple-mobile-web-app-status-bar-style"
|
||||||
|
content="black-translucent"
|
||||||
|
/>
|
||||||
|
<meta name="format-detection" content="telephone=no" />
|
||||||
|
|
||||||
<meta name="description" content="Sonarr" />
|
<meta name="description" content="Sonarr" />
|
||||||
|
|
||||||
@ -33,7 +36,11 @@
|
|||||||
sizes="16x16"
|
sizes="16x16"
|
||||||
href="/Content/Images/Icons/favicon-16x16.png"
|
href="/Content/Images/Icons/favicon-16x16.png"
|
||||||
/>
|
/>
|
||||||
<link rel="manifest" href="/Content/Images/Icons/manifest.json" crossorigin="use-credentials" />
|
<link
|
||||||
|
rel="manifest"
|
||||||
|
href="/Content/manifest.json"
|
||||||
|
crossorigin="use-credentials"
|
||||||
|
/>
|
||||||
<link
|
<link
|
||||||
rel="mask-icon"
|
rel="mask-icon"
|
||||||
href="/Content/Images/Icons/safari-pinned-tab.svg"
|
href="/Content/Images/Icons/safari-pinned-tab.svg"
|
||||||
@ -45,10 +52,7 @@
|
|||||||
href="/favicon.ico"
|
href="/favicon.ico"
|
||||||
data-no-hash
|
data-no-hash
|
||||||
/>
|
/>
|
||||||
<meta
|
<meta name="msapplication-config" content="/Content/browserconfig.xml" />
|
||||||
name="msapplication-config"
|
|
||||||
content="/Content/Images/Icons/browserconfig.xml"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="/Content/styles.css" />
|
<link rel="stylesheet" type="text/css" href="/Content/styles.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="/Content/Fonts/fonts.css" />
|
<link rel="stylesheet" type="text/css" href="/Content/Fonts/fonts.css" />
|
||||||
@ -59,7 +63,7 @@
|
|||||||
body {
|
body {
|
||||||
background-color: var(--pageBackground);
|
background-color: var(--pageBackground);
|
||||||
color: var(--textColor);
|
color: var(--textColor);
|
||||||
font-family: "Roboto", "open sans", "Helvetica Neue", Helvetica, Arial,
|
font-family: 'Roboto', 'open sans', 'Helvetica Neue', Helvetica, Arial,
|
||||||
sans-serif;
|
sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,9 +213,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="sign-in">
|
<div class="sign-in">SIGN IN TO CONTINUE</div>
|
||||||
SIGN IN TO CONTINUE
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form
|
<form
|
||||||
role="form"
|
role="form"
|
||||||
@ -230,8 +232,8 @@
|
|||||||
pattern=".{1,}"
|
pattern=".{1,}"
|
||||||
required
|
required
|
||||||
title="User name is required"
|
title="User name is required"
|
||||||
autoFocus="true"
|
autofocus="true"
|
||||||
autoCapitalize="false"
|
autocapitalize="false"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -282,16 +284,16 @@
|
|||||||
</body>
|
</body>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var yearSpan = document.getElementById("year");
|
var yearSpan = document.getElementById('year');
|
||||||
yearSpan.innerHTML = "2010-" + new Date().getFullYear();
|
yearSpan.innerHTML = '2010-' + new Date().getFullYear();
|
||||||
|
|
||||||
var copyDiv = document.getElementById("copy");
|
var copyDiv = document.getElementById('copy');
|
||||||
copyDiv.classList.remove("hidden");
|
copyDiv.classList.remove('hidden');
|
||||||
|
|
||||||
if (window.location.search.indexOf("loginFailed=true") > -1) {
|
if (window.location.search.indexOf('loginFailed=true') > -1) {
|
||||||
var loginFailedDiv = document.getElementById("login-failed");
|
var loginFailedDiv = document.getElementById('login-failed');
|
||||||
|
|
||||||
loginFailedDiv.classList.remove("hidden");
|
loginFailedDiv.classList.remove('hidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
var light = {
|
var light = {
|
||||||
@ -311,7 +313,7 @@
|
|||||||
primaryHoverBorderColor: '#3483e7',
|
primaryHoverBorderColor: '#3483e7',
|
||||||
failedColor: '#f05050',
|
failedColor: '#f05050',
|
||||||
forgotPasswordColor: '#909fa7',
|
forgotPasswordColor: '#909fa7',
|
||||||
forgotPasswordAltColor: '#748690'
|
forgotPasswordAltColor: '#748690',
|
||||||
};
|
};
|
||||||
|
|
||||||
var dark = {
|
var dark = {
|
||||||
@ -331,21 +333,16 @@
|
|||||||
primaryHoverBorderColor: '#3483e7',
|
primaryHoverBorderColor: '#3483e7',
|
||||||
failedColor: '#f05050',
|
failedColor: '#f05050',
|
||||||
forgotPasswordColor: '#737d83',
|
forgotPasswordColor: '#737d83',
|
||||||
forgotPasswordAltColor: '#546067'
|
forgotPasswordAltColor: '#546067',
|
||||||
};
|
};
|
||||||
|
|
||||||
var theme = "_THEME_";
|
var theme = '_THEME_';
|
||||||
var defaultDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
var defaultDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||||
var finalTheme = theme === 'dark' || (theme === 'auto' && defaultDark) ?
|
var finalTheme =
|
||||||
dark :
|
theme === 'dark' || (theme === 'auto' && defaultDark) ? dark : light;
|
||||||
light;
|
|
||||||
|
|
||||||
Object.entries(finalTheme).forEach(([key, value]) => {
|
Object.entries(finalTheme).forEach(([key, value]) => {
|
||||||
document.documentElement.style.setProperty(
|
document.documentElement.style.setProperty(`--${key}`, value);
|
||||||
`--${key}`,
|
|
||||||
value
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
@ -6,29 +6,22 @@ using NzbDrone.Core.Configuration;
|
|||||||
|
|
||||||
namespace Sonarr.Http.Frontend.Mappers
|
namespace Sonarr.Http.Frontend.Mappers
|
||||||
{
|
{
|
||||||
public class BrowserConfig : StaticResourceMapperBase
|
public class BrowserConfig : UrlBaseReplacementResourceMapperBase
|
||||||
{
|
{
|
||||||
private readonly IAppFolderInfo _appFolderInfo;
|
|
||||||
private readonly IConfigFileProvider _configFileProvider;
|
|
||||||
|
|
||||||
public BrowserConfig(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, IConfigFileProvider configFileProvider, Logger logger)
|
public BrowserConfig(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, IConfigFileProvider configFileProvider, Logger logger)
|
||||||
: base(diskProvider, logger)
|
: base(diskProvider, configFileProvider, logger)
|
||||||
{
|
{
|
||||||
_appFolderInfo = appFolderInfo;
|
FilePath = Path.Combine(appFolderInfo.StartUpFolder, configFileProvider.UiFolder, "Content", "browserconfig.xml");
|
||||||
_configFileProvider = configFileProvider;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Map(string resourceUrl)
|
public override string Map(string resourceUrl)
|
||||||
{
|
{
|
||||||
var path = resourceUrl.Replace('/', Path.DirectorySeparatorChar);
|
return FilePath;
|
||||||
path = path.Trim(Path.DirectorySeparatorChar);
|
|
||||||
|
|
||||||
return Path.ChangeExtension(Path.Combine(_appFolderInfo.StartUpFolder, _configFileProvider.UiFolder, path), "xml");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool CanHandle(string resourceUrl)
|
public override bool CanHandle(string resourceUrl)
|
||||||
{
|
{
|
||||||
return resourceUrl.StartsWith("/content/images/icons/browserconfig");
|
return resourceUrl.StartsWith("/Content/browserconfig");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
@ -6,29 +6,22 @@ using NzbDrone.Core.Configuration;
|
|||||||
|
|
||||||
namespace Sonarr.Http.Frontend.Mappers
|
namespace Sonarr.Http.Frontend.Mappers
|
||||||
{
|
{
|
||||||
public class ManifestMapper : StaticResourceMapperBase
|
public class ManifestMapper : UrlBaseReplacementResourceMapperBase
|
||||||
{
|
{
|
||||||
private readonly IAppFolderInfo _appFolderInfo;
|
|
||||||
private readonly IConfigFileProvider _configFileProvider;
|
|
||||||
|
|
||||||
public ManifestMapper(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, IConfigFileProvider configFileProvider, Logger logger)
|
public ManifestMapper(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, IConfigFileProvider configFileProvider, Logger logger)
|
||||||
: base(diskProvider, logger)
|
: base(diskProvider, configFileProvider, logger)
|
||||||
{
|
{
|
||||||
_appFolderInfo = appFolderInfo;
|
FilePath = Path.Combine(appFolderInfo.StartUpFolder, configFileProvider.UiFolder, "Content", "manifest.json");
|
||||||
_configFileProvider = configFileProvider;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Map(string resourceUrl)
|
public override string Map(string resourceUrl)
|
||||||
{
|
{
|
||||||
var path = resourceUrl.Replace('/', Path.DirectorySeparatorChar);
|
return FilePath;
|
||||||
path = path.Trim(Path.DirectorySeparatorChar);
|
|
||||||
|
|
||||||
return Path.ChangeExtension(Path.Combine(_appFolderInfo.StartUpFolder, _configFileProvider.UiFolder, path), "json");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool CanHandle(string resourceUrl)
|
public override bool CanHandle(string resourceUrl)
|
||||||
{
|
{
|
||||||
return resourceUrl.StartsWith("/Content/Images/Icons/manifest");
|
return resourceUrl.StartsWith("/Content/manifest");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,8 @@ namespace Sonarr.Http.Frontend.Mappers
|
|||||||
{
|
{
|
||||||
resourceUrl = resourceUrl.ToLowerInvariant();
|
resourceUrl = resourceUrl.ToLowerInvariant();
|
||||||
|
|
||||||
if (resourceUrl.StartsWith("/content/images/icons/manifest") ||
|
if (resourceUrl.StartsWith("/content/manifest") ||
|
||||||
resourceUrl.StartsWith("/content/images/icons/browserconfig"))
|
resourceUrl.StartsWith("/content/browserconfig"))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
using System.IO;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
|
using NzbDrone.Core.Configuration;
|
||||||
|
|
||||||
|
namespace Sonarr.Http.Frontend.Mappers
|
||||||
|
{
|
||||||
|
public abstract class UrlBaseReplacementResourceMapperBase : StaticResourceMapperBase
|
||||||
|
{
|
||||||
|
private readonly IDiskProvider _diskProvider;
|
||||||
|
private readonly string _urlBase;
|
||||||
|
|
||||||
|
private string _generatedContent;
|
||||||
|
|
||||||
|
public UrlBaseReplacementResourceMapperBase(IDiskProvider diskProvider, IConfigFileProvider configFileProvider, Logger logger)
|
||||||
|
: base(diskProvider, logger)
|
||||||
|
{
|
||||||
|
_diskProvider = diskProvider;
|
||||||
|
_urlBase = configFileProvider.UrlBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected string FilePath;
|
||||||
|
|
||||||
|
public override string Map(string resourceUrl)
|
||||||
|
{
|
||||||
|
return FilePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Stream GetContentStream(string filePath)
|
||||||
|
{
|
||||||
|
var text = GetFileText();
|
||||||
|
|
||||||
|
var stream = new MemoryStream();
|
||||||
|
var writer = new StreamWriter(stream);
|
||||||
|
writer.Write(text);
|
||||||
|
writer.Flush();
|
||||||
|
stream.Position = 0;
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual string GetFileText()
|
||||||
|
{
|
||||||
|
if (RuntimeInfo.IsProduction && _generatedContent != null)
|
||||||
|
{
|
||||||
|
return _generatedContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
var text = _diskProvider.ReadAllText(FilePath);
|
||||||
|
|
||||||
|
text = text.Replace("__URL_BASE__", _urlBase);
|
||||||
|
|
||||||
|
_generatedContent = text;
|
||||||
|
|
||||||
|
return _generatedContent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user